diff options
Diffstat (limited to 'src/core/hle/kernel/kernel.h')
-rw-r--r-- | src/core/hle/kernel/kernel.h | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h new file mode 100644 index 000000000..7cd79c2c4 --- /dev/null +++ b/src/core/hle/kernel/kernel.h @@ -0,0 +1,154 @@ +// Copyright 2014 Citra Emulator Project / PPSSPP Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "common/common.h" + +typedef u32 Handle; +typedef s32 Result; + +namespace Kernel { + +enum class HandleType : u32 { + Unknown = 0, + Port = 1, + Service = 2, + Event = 3, + Mutex = 4, + SharedMemory = 5, + Redirection = 6, + Thread = 7, + Process = 8, + Arbiter = 9, + File = 10, + Semaphore = 11, +}; + +enum { + MAX_NAME_LENGTH = 0x100, + DEFAULT_STACK_SIZE = 0x4000, +}; + +class ObjectPool; + +class Object : NonCopyable { + friend class ObjectPool; + u32 handle; +public: + virtual ~Object() {} + Handle GetHandle() const { return handle; } + virtual const char *GetTypeName() { return "[BAD KERNEL OBJECT TYPE]"; } + virtual const char *GetName() { return "[UNKNOWN KERNEL OBJECT]"; } + virtual Kernel::HandleType GetHandleType() const = 0; +}; + +class ObjectPool : NonCopyable { +public: + ObjectPool(); + ~ObjectPool() {} + + // Allocates a handle within the range and inserts the object into the map. + Handle Create(Object* obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF); + + static Object* CreateByIDType(int type); + + template <class T> + u32 Destroy(Handle handle) { + u32 error; + if (Get<T>(handle, error)) { + occupied[handle - HANDLE_OFFSET] = false; + delete pool[handle - HANDLE_OFFSET]; + } + return error; + }; + + bool IsValid(Handle handle); + + template <class T> + T* Get(Handle handle, u32& outError) { + if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) { + // Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP + if (handle != 0 && (u32)handle != 0x80020001) { + WARN_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); + } + outError = 0;//T::GetMissingErrorCode(); + return 0; + } else { + // Previously we had a dynamic_cast here, but since RTTI was disabled traditionally, + // it just acted as a static case and everything worked. This means that we will never + // see the Wrong type object error below, but we'll just have to live with that danger. + T* t = static_cast<T*>(pool[handle - HANDLE_OFFSET]); + if (t == 0 || t->GetHandleType() != T::GetStaticHandleType()) { + WARN_LOG(KERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle); + outError = 0;//T::GetMissingErrorCode(); + return 0; + } + outError = 0;//SCE_KERNEL_ERROR_OK; + return t; + } + } + + // ONLY use this when you know the handle is valid. + template <class T> + T *GetFast(Handle handle) { + const Handle realHandle = handle - HANDLE_OFFSET; + _dbg_assert_(KERNEL, realHandle >= 0 && realHandle < MAX_COUNT && occupied[realHandle]); + return static_cast<T*>(pool[realHandle]); + } + + template <class T, typename ArgT> + void Iterate(bool func(T*, ArgT), ArgT arg) { + int type = T::GetStaticIDType(); + for (int i = 0; i < MAX_COUNT; i++) + { + if (!occupied[i]) + continue; + T* t = static_cast<T*>(pool[i]); + if (t->GetIDType() == type) { + if (!func(t, arg)) + break; + } + } + } + + bool GetIDType(Handle handle, HandleType* type) const { + if ((handle < HANDLE_OFFSET) || (handle >= HANDLE_OFFSET + MAX_COUNT) || + !occupied[handle - HANDLE_OFFSET]) { + ERROR_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); + return false; + } + Object* t = pool[handle - HANDLE_OFFSET]; + *type = t->GetHandleType(); + return true; + } + + Object* &operator [](Handle handle); + void List(); + void Clear(); + int GetCount(); + +private: + + enum { + MAX_COUNT = 0x1000, + HANDLE_OFFSET = 0x100, + INITIAL_NEXT_ID = 0x10, + }; + + Object* pool[MAX_COUNT]; + bool occupied[MAX_COUNT]; + int next_id; +}; + +extern ObjectPool g_object_pool; + +/** + * Loads executable stored at specified address + * @entry_point Entry point in memory of loaded executable + * @return True on success, otherwise false + */ +bool LoadExec(u32 entry_point); + +} // namespace |