kernel.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <memory>
  7. #include <string>
  8. #include <unordered_map>
  9. #include <vector>
  10. #include "core/arm/cpu_interrupt_handler.h"
  11. #include "core/hardware_properties.h"
  12. #include "core/hle/kernel/k_auto_object.h"
  13. #include "core/hle/kernel/k_slab_heap.h"
  14. #include "core/hle/kernel/memory_types.h"
  15. #include "core/hle/kernel/object.h"
  16. namespace Core {
  17. class CPUInterruptHandler;
  18. class ExclusiveMonitor;
  19. class System;
  20. } // namespace Core
  21. namespace Core::Timing {
  22. class CoreTiming;
  23. struct EventType;
  24. } // namespace Core::Timing
  25. namespace Kernel {
  26. class ClientPort;
  27. class GlobalSchedulerContext;
  28. class HandleTable;
  29. class KAutoObjectWithListContainer;
  30. class KClientSession;
  31. class KEvent;
  32. class KLinkedListNode;
  33. class KMemoryManager;
  34. class KResourceLimit;
  35. class KScheduler;
  36. class KSession;
  37. class KSharedMemory;
  38. class KThread;
  39. class KTransferMemory;
  40. class KWritableEvent;
  41. class PhysicalCore;
  42. class Process;
  43. class ServiceThread;
  44. class Synchronization;
  45. class TimeManager;
  46. template <typename T>
  47. class KSlabHeap;
  48. using EmuThreadHandle = uintptr_t;
  49. constexpr EmuThreadHandle EmuThreadHandleInvalid{};
  50. constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63};
  51. /// Represents a single instance of the kernel.
  52. class KernelCore {
  53. private:
  54. using NamedPortTable = std::unordered_map<std::string, std::shared_ptr<ClientPort>>;
  55. public:
  56. /// Constructs an instance of the kernel using the given System
  57. /// instance as a context for any necessary system-related state,
  58. /// such as threads, CPU core state, etc.
  59. ///
  60. /// @post After execution of the constructor, the provided System
  61. /// object *must* outlive the kernel instance itself.
  62. ///
  63. explicit KernelCore(Core::System& system);
  64. ~KernelCore();
  65. KernelCore(const KernelCore&) = delete;
  66. KernelCore& operator=(const KernelCore&) = delete;
  67. KernelCore(KernelCore&&) = delete;
  68. KernelCore& operator=(KernelCore&&) = delete;
  69. /// Sets if emulation is multicore or single core, must be set before Initialize
  70. void SetMulticore(bool is_multicore);
  71. /// Resets the kernel to a clean slate for use.
  72. void Initialize();
  73. /// Initializes the CPU cores.
  74. void InitializeCores();
  75. /// Clears all resources in use by the kernel instance.
  76. void Shutdown();
  77. /// Retrieves a shared pointer to the system resource limit instance.
  78. const KResourceLimit* GetSystemResourceLimit() const;
  79. /// Retrieves a shared pointer to the system resource limit instance.
  80. KResourceLimit* GetSystemResourceLimit();
  81. /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
  82. KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const;
  83. /// Adds the given shared pointer to an internal list of active processes.
  84. void AppendNewProcess(Process* process);
  85. /// Makes the given process the new current process.
  86. void MakeCurrentProcess(Process* process);
  87. /// Retrieves a pointer to the current process.
  88. Process* CurrentProcess();
  89. /// Retrieves a const pointer to the current process.
  90. const Process* CurrentProcess() const;
  91. /// Retrieves the list of processes.
  92. const std::vector<Process*>& GetProcessList() const;
  93. /// Gets the sole instance of the global scheduler
  94. Kernel::GlobalSchedulerContext& GlobalSchedulerContext();
  95. /// Gets the sole instance of the global scheduler
  96. const Kernel::GlobalSchedulerContext& GlobalSchedulerContext() const;
  97. /// Gets the sole instance of the Scheduler assoviated with cpu core 'id'
  98. Kernel::KScheduler& Scheduler(std::size_t id);
  99. /// Gets the sole instance of the Scheduler assoviated with cpu core 'id'
  100. const Kernel::KScheduler& Scheduler(std::size_t id) const;
  101. /// Gets the an instance of the respective physical CPU core.
  102. Kernel::PhysicalCore& PhysicalCore(std::size_t id);
  103. /// Gets the an instance of the respective physical CPU core.
  104. const Kernel::PhysicalCore& PhysicalCore(std::size_t id) const;
  105. /// Gets the sole instance of the Scheduler at the current running core.
  106. Kernel::KScheduler* CurrentScheduler();
  107. /// Gets the an instance of the current physical CPU core.
  108. Kernel::PhysicalCore& CurrentPhysicalCore();
  109. /// Gets the an instance of the current physical CPU core.
  110. const Kernel::PhysicalCore& CurrentPhysicalCore() const;
  111. /// Gets the an instance of the TimeManager Interface.
  112. Kernel::TimeManager& TimeManager();
  113. /// Gets the an instance of the TimeManager Interface.
  114. const Kernel::TimeManager& TimeManager() const;
  115. /// Stops execution of 'id' core, in order to reschedule a new thread.
  116. void PrepareReschedule(std::size_t id);
  117. Core::ExclusiveMonitor& GetExclusiveMonitor();
  118. const Core::ExclusiveMonitor& GetExclusiveMonitor() const;
  119. KAutoObjectWithListContainer& ObjectListContainer();
  120. const KAutoObjectWithListContainer& ObjectListContainer() const;
  121. std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts();
  122. const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const;
  123. void InvalidateAllInstructionCaches();
  124. void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
  125. /// Adds a port to the named port table
  126. void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
  127. /// Finds a port within the named port table with the given name.
  128. NamedPortTable::iterator FindNamedPort(const std::string& name);
  129. /// Finds a port within the named port table with the given name.
  130. NamedPortTable::const_iterator FindNamedPort(const std::string& name) const;
  131. /// Determines whether or not the given port is a valid named port.
  132. bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
  133. /// Gets the current host_thread/guest_thread pointer.
  134. KThread* GetCurrentEmuThread() const;
  135. /// Gets the current host_thread handle.
  136. u32 GetCurrentHostThreadID() const;
  137. /// Register the current thread as a CPU Core Thread.
  138. void RegisterCoreThread(std::size_t core_id);
  139. /// Register the current thread as a non CPU core thread.
  140. void RegisterHostThread();
  141. /// Gets the virtual memory manager for the kernel.
  142. KMemoryManager& MemoryManager();
  143. /// Gets the virtual memory manager for the kernel.
  144. const KMemoryManager& MemoryManager() const;
  145. /// Gets the slab heap allocated for user space pages.
  146. KSlabHeap<Page>& GetUserSlabHeapPages();
  147. /// Gets the slab heap allocated for user space pages.
  148. const KSlabHeap<Page>& GetUserSlabHeapPages() const;
  149. /// Gets the shared memory object for HID services.
  150. Kernel::KSharedMemory& GetHidSharedMem();
  151. /// Gets the shared memory object for HID services.
  152. const Kernel::KSharedMemory& GetHidSharedMem() const;
  153. /// Gets the shared memory object for font services.
  154. Kernel::KSharedMemory& GetFontSharedMem();
  155. /// Gets the shared memory object for font services.
  156. const Kernel::KSharedMemory& GetFontSharedMem() const;
  157. /// Gets the shared memory object for IRS services.
  158. Kernel::KSharedMemory& GetIrsSharedMem();
  159. /// Gets the shared memory object for IRS services.
  160. const Kernel::KSharedMemory& GetIrsSharedMem() const;
  161. /// Gets the shared memory object for Time services.
  162. Kernel::KSharedMemory& GetTimeSharedMem();
  163. /// Gets the shared memory object for Time services.
  164. const Kernel::KSharedMemory& GetTimeSharedMem() const;
  165. /// Suspend/unsuspend the OS.
  166. void Suspend(bool in_suspention);
  167. /// Exceptional exit the OS.
  168. void ExceptionalExit();
  169. bool IsMulticore() const;
  170. void EnterSVCProfile();
  171. void ExitSVCProfile();
  172. /**
  173. * Creates an HLE service thread, which are used to execute service routines asynchronously.
  174. * While these are allocated per ServerSession, these need to be owned and managed outside
  175. * of ServerSession to avoid a circular dependency.
  176. * @param name String name for the ServerSession creating this thread, used for debug
  177. * purposes.
  178. * @returns The a weak pointer newly created service thread.
  179. */
  180. std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name);
  181. /**
  182. * Releases a HLE service thread, instructing KernelCore to free it. This should be called when
  183. * the ServerSession associated with the thread is destroyed.
  184. * @param service_thread Service thread to release.
  185. */
  186. void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread);
  187. /// Workaround for single-core mode when preempting threads while idle.
  188. bool IsPhantomModeForSingleCore() const;
  189. void SetIsPhantomModeForSingleCore(bool value);
  190. Core::System& System();
  191. const Core::System& System() const;
  192. /// Gets the slab heap for the specified kernel object type.
  193. template <typename T>
  194. KSlabHeap<T>& SlabHeap() {
  195. if constexpr (std::is_same_v<T, KClientSession>) {
  196. return slab_heap_container->client_session;
  197. } else if constexpr (std::is_same_v<T, KEvent>) {
  198. return slab_heap_container->event;
  199. } else if constexpr (std::is_same_v<T, KLinkedListNode>) {
  200. return slab_heap_container->linked_list_node;
  201. } else if constexpr (std::is_same_v<T, Process>) {
  202. return slab_heap_container->process;
  203. } else if constexpr (std::is_same_v<T, KResourceLimit>) {
  204. return slab_heap_container->resource_limit;
  205. } else if constexpr (std::is_same_v<T, KSession>) {
  206. return slab_heap_container->session;
  207. } else if constexpr (std::is_same_v<T, KSharedMemory>) {
  208. return slab_heap_container->shared_memory;
  209. } else if constexpr (std::is_same_v<T, KThread>) {
  210. return slab_heap_container->thread;
  211. } else if constexpr (std::is_same_v<T, KTransferMemory>) {
  212. return slab_heap_container->transfer_memory;
  213. } else if constexpr (std::is_same_v<T, KWritableEvent>) {
  214. return slab_heap_container->writeable_event;
  215. }
  216. }
  217. private:
  218. friend class Object;
  219. friend class Process;
  220. friend class KThread;
  221. /// Creates a new object ID, incrementing the internal object ID counter.
  222. u32 CreateNewObjectID();
  223. /// Creates a new process ID, incrementing the internal process ID counter;
  224. u64 CreateNewKernelProcessID();
  225. /// Creates a new process ID, incrementing the internal process ID counter;
  226. u64 CreateNewUserProcessID();
  227. /// Creates a new thread ID, incrementing the internal thread ID counter.
  228. u64 CreateNewThreadID();
  229. /// Provides a reference to the global handle table.
  230. Kernel::HandleTable& GlobalHandleTable();
  231. /// Provides a const reference to the global handle table.
  232. const Kernel::HandleTable& GlobalHandleTable() const;
  233. struct Impl;
  234. std::unique_ptr<Impl> impl;
  235. bool exception_exited{};
  236. private:
  237. /// Helper to encapsulate all slab heaps in a single heap allocated container
  238. struct SlabHeapContainer {
  239. KSlabHeap<KClientSession> client_session;
  240. KSlabHeap<KEvent> event;
  241. KSlabHeap<KLinkedListNode> linked_list_node;
  242. KSlabHeap<Process> process;
  243. KSlabHeap<KResourceLimit> resource_limit;
  244. KSlabHeap<KSession> session;
  245. KSlabHeap<KSharedMemory> shared_memory;
  246. KSlabHeap<KThread> thread;
  247. KSlabHeap<KTransferMemory> transfer_memory;
  248. KSlabHeap<KWritableEvent> writeable_event;
  249. };
  250. std::unique_ptr<SlabHeapContainer> slab_heap_container;
  251. };
  252. } // namespace Kernel