summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/kernel.h')
-rw-r--r--src/core/hle/kernel/kernel.h154
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 @@
1// Copyright 2014 Citra Emulator Project / PPSSPP Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common.h"
8
9typedef u32 Handle;
10typedef s32 Result;
11
12namespace Kernel {
13
14enum class HandleType : u32 {
15 Unknown = 0,
16 Port = 1,
17 Service = 2,
18 Event = 3,
19 Mutex = 4,
20 SharedMemory = 5,
21 Redirection = 6,
22 Thread = 7,
23 Process = 8,
24 Arbiter = 9,
25 File = 10,
26 Semaphore = 11,
27};
28
29enum {
30 MAX_NAME_LENGTH = 0x100,
31 DEFAULT_STACK_SIZE = 0x4000,
32};
33
34class ObjectPool;
35
36class Object : NonCopyable {
37 friend class ObjectPool;
38 u32 handle;
39public:
40 virtual ~Object() {}
41 Handle GetHandle() const { return handle; }
42 virtual const char *GetTypeName() { return "[BAD KERNEL OBJECT TYPE]"; }
43 virtual const char *GetName() { return "[UNKNOWN KERNEL OBJECT]"; }
44 virtual Kernel::HandleType GetHandleType() const = 0;
45};
46
47class ObjectPool : NonCopyable {
48public:
49 ObjectPool();
50 ~ObjectPool() {}
51
52 // Allocates a handle within the range and inserts the object into the map.
53 Handle Create(Object* obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF);
54
55 static Object* CreateByIDType(int type);
56
57 template <class T>
58 u32 Destroy(Handle handle) {
59 u32 error;
60 if (Get<T>(handle, error)) {
61 occupied[handle - HANDLE_OFFSET] = false;
62 delete pool[handle - HANDLE_OFFSET];
63 }
64 return error;
65 };
66
67 bool IsValid(Handle handle);
68
69 template <class T>
70 T* Get(Handle handle, u32& outError) {
71 if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) {
72 // Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP
73 if (handle != 0 && (u32)handle != 0x80020001) {
74 WARN_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle);
75 }
76 outError = 0;//T::GetMissingErrorCode();
77 return 0;
78 } else {
79 // Previously we had a dynamic_cast here, but since RTTI was disabled traditionally,
80 // it just acted as a static case and everything worked. This means that we will never
81 // see the Wrong type object error below, but we'll just have to live with that danger.
82 T* t = static_cast<T*>(pool[handle - HANDLE_OFFSET]);
83 if (t == 0 || t->GetHandleType() != T::GetStaticHandleType()) {
84 WARN_LOG(KERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle);
85 outError = 0;//T::GetMissingErrorCode();
86 return 0;
87 }
88 outError = 0;//SCE_KERNEL_ERROR_OK;
89 return t;
90 }
91 }
92
93 // ONLY use this when you know the handle is valid.
94 template <class T>
95 T *GetFast(Handle handle) {
96 const Handle realHandle = handle - HANDLE_OFFSET;
97 _dbg_assert_(KERNEL, realHandle >= 0 && realHandle < MAX_COUNT && occupied[realHandle]);
98 return static_cast<T*>(pool[realHandle]);
99 }
100
101 template <class T, typename ArgT>
102 void Iterate(bool func(T*, ArgT), ArgT arg) {
103 int type = T::GetStaticIDType();
104 for (int i = 0; i < MAX_COUNT; i++)
105 {
106 if (!occupied[i])
107 continue;
108 T* t = static_cast<T*>(pool[i]);
109 if (t->GetIDType() == type) {
110 if (!func(t, arg))
111 break;
112 }
113 }
114 }
115
116 bool GetIDType(Handle handle, HandleType* type) const {
117 if ((handle < HANDLE_OFFSET) || (handle >= HANDLE_OFFSET + MAX_COUNT) ||
118 !occupied[handle - HANDLE_OFFSET]) {
119 ERROR_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle);
120 return false;
121 }
122 Object* t = pool[handle - HANDLE_OFFSET];
123 *type = t->GetHandleType();
124 return true;
125 }
126
127 Object* &operator [](Handle handle);
128 void List();
129 void Clear();
130 int GetCount();
131
132private:
133
134 enum {
135 MAX_COUNT = 0x1000,
136 HANDLE_OFFSET = 0x100,
137 INITIAL_NEXT_ID = 0x10,
138 };
139
140 Object* pool[MAX_COUNT];
141 bool occupied[MAX_COUNT];
142 int next_id;
143};
144
145extern ObjectPool g_object_pool;
146
147/**
148 * Loads executable stored at specified address
149 * @entry_point Entry point in memory of loaded executable
150 * @return True on success, otherwise false
151 */
152bool LoadExec(u32 entry_point);
153
154} // namespace