summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-05-26 20:52:00 -0400
committerGravatar bunnei2014-05-26 20:52:00 -0400
commit6448c2f30062c085330ff26a4812c9a91c7b492c (patch)
tree386e32cf3ec053491fb8dfd8459a1c92553241d9 /src/core/hle/kernel/kernel.cpp
parentMerge pull request #4 from archshift/patch-1 (diff)
parentservice: fixed typo that MSVC did not catch as an error (diff)
downloadyuzu-6448c2f30062c085330ff26a4812c9a91c7b492c.tar.gz
yuzu-6448c2f30062c085330ff26a4812c9a91c7b492c.tar.xz
yuzu-6448c2f30062c085330ff26a4812c9a91c7b492c.zip
Merge pull request #9 from bunnei/master
Add initial kernel HLE, includes thread creation and context switching
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
new file mode 100644
index 000000000..de80de893
--- /dev/null
+++ b/src/core/hle/kernel/kernel.cpp
@@ -0,0 +1,158 @@
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 <string.h>
8
9#include "common/common.h"
10
11#include "core/core.h"
12#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/thread.h"
14
15namespace Kernel {
16
17ObjectPool g_object_pool;
18
19ObjectPool::ObjectPool() {
20 memset(occupied, 0, sizeof(bool) * MAX_COUNT);
21 next_id = INITIAL_NEXT_ID;
22}
23
24Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) {
25 if (range_top > MAX_COUNT) {
26 range_top = MAX_COUNT;
27 }
28 if (next_id >= range_bottom && next_id < range_top) {
29 range_bottom = next_id++;
30 }
31 for (int i = range_bottom; i < range_top; i++) {
32 if (!occupied[i]) {
33 occupied[i] = true;
34 pool[i] = obj;
35 pool[i]->handle = i + HANDLE_OFFSET;
36 return i + HANDLE_OFFSET;
37 }
38 }
39 ERROR_LOG(HLE, "Unable to allocate kernel object, too many objects slots in use.");
40 return 0;
41}
42
43bool ObjectPool::IsValid(Handle handle) {
44 int index = handle - HANDLE_OFFSET;
45 if (index < 0)
46 return false;
47 if (index >= MAX_COUNT)
48 return false;
49
50 return occupied[index];
51}
52
53void ObjectPool::Clear() {
54 for (int i = 0; i < MAX_COUNT; i++) {
55 //brutally clear everything, no validation
56 if (occupied[i])
57 delete pool[i];
58 occupied[i] = false;
59 }
60 memset(pool, 0, sizeof(Object*)*MAX_COUNT);
61 next_id = INITIAL_NEXT_ID;
62}
63
64Object* &ObjectPool::operator [](Handle handle)
65{
66 _dbg_assert_msg_(KERNEL, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ");
67 return pool[handle - HANDLE_OFFSET];
68}
69
70void ObjectPool::List() {
71 for (int i = 0; i < MAX_COUNT; i++) {
72 if (occupied[i]) {
73 if (pool[i]) {
74 INFO_LOG(KERNEL, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName(),
75 pool[i]->GetName());
76 }
77 }
78 }
79}
80
81int ObjectPool::GetCount() {
82 int count = 0;
83 for (int i = 0; i < MAX_COUNT; i++) {
84 if (occupied[i])
85 count++;
86 }
87 return count;
88}
89
90Object* ObjectPool::CreateByIDType(int type) {
91 // Used for save states. This is ugly, but what other way is there?
92 switch (type) {
93 //case SCE_KERNEL_TMID_Alarm:
94 // return __KernelAlarmObject();
95 //case SCE_KERNEL_TMID_EventFlag:
96 // return __KernelEventFlagObject();
97 //case SCE_KERNEL_TMID_Mbox:
98 // return __KernelMbxObject();
99 //case SCE_KERNEL_TMID_Fpl:
100 // return __KernelMemoryFPLObject();
101 //case SCE_KERNEL_TMID_Vpl:
102 // return __KernelMemoryVPLObject();
103 //case PPSSPP_KERNEL_TMID_PMB:
104 // return __KernelMemoryPMBObject();
105 //case PPSSPP_KERNEL_TMID_Module:
106 // return __KernelModuleObject();
107 //case SCE_KERNEL_TMID_Mpipe:
108 // return __KernelMsgPipeObject();
109 //case SCE_KERNEL_TMID_Mutex:
110 // return __KernelMutexObject();
111 //case SCE_KERNEL_TMID_LwMutex:
112 // return __KernelLwMutexObject();
113 //case SCE_KERNEL_TMID_Semaphore:
114 // return __KernelSemaphoreObject();
115 //case SCE_KERNEL_TMID_Callback:
116 // return __KernelCallbackObject();
117 //case SCE_KERNEL_TMID_Thread:
118 // return __KernelThreadObject();
119 //case SCE_KERNEL_TMID_VTimer:
120 // return __KernelVTimerObject();
121 //case SCE_KERNEL_TMID_Tlspl:
122 // return __KernelTlsplObject();
123 //case PPSSPP_KERNEL_TMID_File:
124 // return __KernelFileNodeObject();
125 //case PPSSPP_KERNEL_TMID_DirList:
126 // return __KernelDirListingObject();
127
128 default:
129 ERROR_LOG(COMMON, "Unable to load state: could not find object type %d.", type);
130 return NULL;
131 }
132}
133
134void Init() {
135 Kernel::ThreadingInit();
136}
137
138void Shutdown() {
139 Kernel::ThreadingShutdown();
140}
141
142/**
143 * Loads executable stored at specified address
144 * @entry_point Entry point in memory of loaded executable
145 * @return True on success, otherwise false
146 */
147bool LoadExec(u32 entry_point) {
148 Init();
149
150 Core::g_app_core->SetPC(entry_point);
151
152 // 0x30 is the typical main thread priority I've seen used so far
153 Handle thread = Kernel::SetupMainThread(0x30);
154
155 return true;
156}
157
158} // namespace