kernel.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright 2014 Citra Emulator Project / PPSSPP Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include "common/common.h"
  5. #include "core/core.h"
  6. #include "core/hle/kernel/kernel.h"
  7. #include "core/hle/kernel/thread.h"
  8. #include "core/hle/kernel/archive.h"
  9. namespace Kernel {
  10. Handle g_main_thread = 0;
  11. ObjectPool g_object_pool;
  12. ObjectPool::ObjectPool() {
  13. next_id = INITIAL_NEXT_ID;
  14. }
  15. Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) {
  16. if (range_top > MAX_COUNT) {
  17. range_top = MAX_COUNT;
  18. }
  19. if (next_id >= range_bottom && next_id < range_top) {
  20. range_bottom = next_id++;
  21. }
  22. for (int i = range_bottom; i < range_top; i++) {
  23. if (!occupied[i]) {
  24. occupied[i] = true;
  25. pool[i] = obj;
  26. pool[i]->handle = i + HANDLE_OFFSET;
  27. return i + HANDLE_OFFSET;
  28. }
  29. }
  30. ERROR_LOG(HLE, "Unable to allocate kernel object, too many objects slots in use.");
  31. return 0;
  32. }
  33. bool ObjectPool::IsValid(Handle handle) {
  34. int index = handle - HANDLE_OFFSET;
  35. if (index < 0)
  36. return false;
  37. if (index >= MAX_COUNT)
  38. return false;
  39. return occupied[index];
  40. }
  41. void ObjectPool::Clear() {
  42. for (int i = 0; i < MAX_COUNT; i++) {
  43. //brutally clear everything, no validation
  44. if (occupied[i])
  45. delete pool[i];
  46. occupied[i] = false;
  47. }
  48. pool.fill(nullptr);
  49. next_id = INITIAL_NEXT_ID;
  50. }
  51. Object* &ObjectPool::operator [](Handle handle)
  52. {
  53. _dbg_assert_msg_(KERNEL, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ");
  54. return pool[handle - HANDLE_OFFSET];
  55. }
  56. void ObjectPool::List() {
  57. for (int i = 0; i < MAX_COUNT; i++) {
  58. if (occupied[i]) {
  59. if (pool[i]) {
  60. INFO_LOG(KERNEL, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName().c_str(),
  61. pool[i]->GetName().c_str());
  62. }
  63. }
  64. }
  65. }
  66. int ObjectPool::GetCount() {
  67. int count = 0;
  68. for (int i = 0; i < MAX_COUNT; i++) {
  69. if (occupied[i])
  70. count++;
  71. }
  72. return count;
  73. }
  74. Object* ObjectPool::CreateByIDType(int type) {
  75. // Used for save states. This is ugly, but what other way is there?
  76. switch (type) {
  77. //case SCE_KERNEL_TMID_Alarm:
  78. // return __KernelAlarmObject();
  79. //case SCE_KERNEL_TMID_EventFlag:
  80. // return __KernelEventFlagObject();
  81. //case SCE_KERNEL_TMID_Mbox:
  82. // return __KernelMbxObject();
  83. //case SCE_KERNEL_TMID_Fpl:
  84. // return __KernelMemoryFPLObject();
  85. //case SCE_KERNEL_TMID_Vpl:
  86. // return __KernelMemoryVPLObject();
  87. //case PPSSPP_KERNEL_TMID_PMB:
  88. // return __KernelMemoryPMBObject();
  89. //case PPSSPP_KERNEL_TMID_Module:
  90. // return __KernelModuleObject();
  91. //case SCE_KERNEL_TMID_Mpipe:
  92. // return __KernelMsgPipeObject();
  93. //case SCE_KERNEL_TMID_Mutex:
  94. // return __KernelMutexObject();
  95. //case SCE_KERNEL_TMID_LwMutex:
  96. // return __KernelLwMutexObject();
  97. //case SCE_KERNEL_TMID_Semaphore:
  98. // return __KernelSemaphoreObject();
  99. //case SCE_KERNEL_TMID_Callback:
  100. // return __KernelCallbackObject();
  101. //case SCE_KERNEL_TMID_Thread:
  102. // return __KernelThreadObject();
  103. //case SCE_KERNEL_TMID_VTimer:
  104. // return __KernelVTimerObject();
  105. //case SCE_KERNEL_TMID_Tlspl:
  106. // return __KernelTlsplObject();
  107. //case PPSSPP_KERNEL_TMID_File:
  108. // return __KernelFileNodeObject();
  109. //case PPSSPP_KERNEL_TMID_DirList:
  110. // return __KernelDirListingObject();
  111. default:
  112. ERROR_LOG(COMMON, "Unable to load state: could not find object type %d.", type);
  113. return nullptr;
  114. }
  115. }
  116. /// Initialize the kernel
  117. void Init() {
  118. Kernel::ThreadingInit();
  119. Kernel::ArchiveInit();
  120. }
  121. /// Shutdown the kernel
  122. void Shutdown() {
  123. Kernel::ThreadingShutdown();
  124. Kernel::ArchiveShutdown();
  125. g_object_pool.Clear(); // Free all kernel objects
  126. }
  127. /**
  128. * Loads executable stored at specified address
  129. * @entry_point Entry point in memory of loaded executable
  130. * @return True on success, otherwise false
  131. */
  132. bool LoadExec(u32 entry_point) {
  133. Init();
  134. Core::g_app_core->SetPC(entry_point);
  135. // 0x30 is the typical main thread priority I've seen used so far
  136. g_main_thread = Kernel::SetupMainThread(0x30);
  137. return true;
  138. }
  139. } // namespace