kernel.h 12 KB

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