1 // Copyright 2015 Citra Emulator Project 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <array> 8 #include <cstddef> 9 #include <list> 10 #include <string> 11 #include <unordered_map> 12 #include <vector> 13 #include "common/common_types.h" 14 #include "core/hle/kernel/address_arbiter.h" 15 #include "core/hle/kernel/handle_table.h" 16 #include "core/hle/kernel/mutex.h" 17 #include "core/hle/kernel/process_capability.h" 18 #include "core/hle/kernel/synchronization_object.h" 19 #include "core/hle/result.h" 20 21 namespace Core { 22 class System; 23 } 24 25 namespace FileSys { 26 class ProgramMetadata; 27 } 28 29 namespace Kernel { 30 31 class KernelCore; 32 class ResourceLimit; 33 class Thread; 34 class TLSPage; 35 36 struct CodeSet; 37 38 namespace Memory { 39 class PageTable; 40 } 41 42 enum class MemoryRegion : u16 { 43 APPLICATION = 1, 44 SYSTEM = 2, 45 BASE = 3, 46 }; 47 48 /** 49 * Indicates the status of a Process instance. 50 * 51 * @note These match the values as used by kernel, 52 * so new entries should only be added if RE 53 * shows that a new value has been introduced. 54 */ 55 enum class ProcessStatus { 56 Created, 57 CreatedWithDebuggerAttached, 58 Running, 59 WaitingForDebuggerToAttach, 60 DebuggerAttached, 61 Exiting, 62 Exited, 63 DebugBreak, 64 }; 65 66 class Process final : public SynchronizationObject { 67 public: 68 explicit Process(Core::System& system); 69 ~Process() override; 70 71 enum : u64 { 72 /// Lowest allowed process ID for a kernel initial process. 73 InitialKIPIDMin = 1, 74 /// Highest allowed process ID for a kernel initial process. 75 InitialKIPIDMax = 80, 76 77 /// Lowest allowed process ID for a userland process. 78 ProcessIDMin = 81, 79 /// Highest allowed process ID for a userland process. 80 ProcessIDMax = 0xFFFFFFFFFFFFFFFF, 81 }; 82 83 // Used to determine how process IDs are assigned. 84 enum class ProcessType { 85 KernelInternal, 86 Userland, 87 }; 88 89 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; 90 91 static std::shared_ptr<Process> Create(Core::System& system, std::string name, 92 ProcessType type); 93 GetTypeName()94 std::string GetTypeName() const override { 95 return "Process"; 96 } GetName()97 std::string GetName() const override { 98 return name; 99 } 100 101 static constexpr HandleType HANDLE_TYPE = HandleType::Process; GetHandleType()102 HandleType GetHandleType() const override { 103 return HANDLE_TYPE; 104 } 105 106 /// Gets a reference to the process' page table. PageTable()107 Memory::PageTable& PageTable() { 108 return *page_table; 109 } 110 111 /// Gets const a reference to the process' page table. PageTable()112 const Memory::PageTable& PageTable() const { 113 return *page_table; 114 } 115 116 /// Gets a reference to the process' handle table. GetHandleTable()117 HandleTable& GetHandleTable() { 118 return handle_table; 119 } 120 121 /// Gets a const reference to the process' handle table. GetHandleTable()122 const HandleTable& GetHandleTable() const { 123 return handle_table; 124 } 125 126 /// Gets a reference to the process' address arbiter. GetAddressArbiter()127 AddressArbiter& GetAddressArbiter() { 128 return address_arbiter; 129 } 130 131 /// Gets a const reference to the process' address arbiter. GetAddressArbiter()132 const AddressArbiter& GetAddressArbiter() const { 133 return address_arbiter; 134 } 135 136 /// Gets a reference to the process' mutex lock. GetMutex()137 Mutex& GetMutex() { 138 return mutex; 139 } 140 141 /// Gets a const reference to the process' mutex lock GetMutex()142 const Mutex& GetMutex() const { 143 return mutex; 144 } 145 146 /// Gets the address to the process' dedicated TLS region. GetTLSRegionAddress()147 VAddr GetTLSRegionAddress() const { 148 return tls_region_address; 149 } 150 151 /// Gets the current status of the process GetStatus()152 ProcessStatus GetStatus() const { 153 return status; 154 } 155 156 /// Gets the unique ID that identifies this particular process. GetProcessID()157 u64 GetProcessID() const { 158 return process_id; 159 } 160 161 /// Gets the title ID corresponding to this process. GetTitleID()162 u64 GetTitleID() const { 163 return program_id; 164 } 165 166 /// Gets the resource limit descriptor for this process 167 std::shared_ptr<ResourceLimit> GetResourceLimit() const; 168 169 /// Gets the ideal CPU core ID for this process GetIdealCore()170 u8 GetIdealCore() const { 171 return ideal_core; 172 } 173 174 /// Gets the bitmask of allowed cores that this process' threads can run on. GetCoreMask()175 u64 GetCoreMask() const { 176 return capabilities.GetCoreMask(); 177 } 178 179 /// Gets the bitmask of allowed thread priorities. GetPriorityMask()180 u64 GetPriorityMask() const { 181 return capabilities.GetPriorityMask(); 182 } 183 184 /// Gets the amount of secure memory to allocate for memory management. GetSystemResourceSize()185 u32 GetSystemResourceSize() const { 186 return system_resource_size; 187 } 188 189 /// Gets the amount of secure memory currently in use for memory management. GetSystemResourceUsage()190 u32 GetSystemResourceUsage() const { 191 // On hardware, this returns the amount of system resource memory that has 192 // been used by the kernel. This is problematic for Yuzu to emulate, because 193 // system resource memory is used for page tables -- and yuzu doesn't really 194 // have a way to calculate how much memory is required for page tables for 195 // the current process at any given time. 196 // TODO: Is this even worth implementing? Games may retrieve this value via 197 // an SDK function that gets used + available system resource size for debug 198 // or diagnostic purposes. However, it seems unlikely that a game would make 199 // decisions based on how much system memory is dedicated to its page tables. 200 // Is returning a value other than zero wise? 201 return 0; 202 } 203 204 /// Whether this process is an AArch64 or AArch32 process. Is64BitProcess()205 bool Is64BitProcess() const { 206 return is_64bit_process; 207 } 208 209 /// Gets the total running time of the process instance in ticks. GetCPUTimeTicks()210 u64 GetCPUTimeTicks() const { 211 return total_process_running_time_ticks; 212 } 213 214 /// Updates the total running time, adding the given ticks to it. UpdateCPUTimeTicks(u64 ticks)215 void UpdateCPUTimeTicks(u64 ticks) { 216 total_process_running_time_ticks += ticks; 217 } 218 219 /// Gets 8 bytes of random data for svcGetInfo RandomEntropy GetRandomEntropy(std::size_t index)220 u64 GetRandomEntropy(std::size_t index) const { 221 return random_entropy.at(index); 222 } 223 224 /// Retrieves the total physical memory available to this process in bytes. 225 u64 GetTotalPhysicalMemoryAvailable() const; 226 227 /// Retrieves the total physical memory available to this process in bytes, 228 /// without the size of the personal system resource heap added to it. 229 u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource() const; 230 231 /// Retrieves the total physical memory used by this process in bytes. 232 u64 GetTotalPhysicalMemoryUsed() const; 233 234 /// Retrieves the total physical memory used by this process in bytes, 235 /// without the size of the personal system resource heap added to it. 236 u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; 237 238 /// Gets the list of all threads created with this process as their owner. GetThreadList()239 const std::list<const Thread*>& GetThreadList() const { 240 return thread_list; 241 } 242 243 /// Insert a thread into the condition variable wait container 244 void InsertConditionVariableThread(std::shared_ptr<Thread> thread); 245 246 /// Remove a thread from the condition variable wait container 247 void RemoveConditionVariableThread(std::shared_ptr<Thread> thread); 248 249 /// Obtain all condition variable threads waiting for some address 250 std::vector<std::shared_ptr<Thread>> GetConditionVariableThreads(VAddr cond_var_addr); 251 252 /// Registers a thread as being created under this process, 253 /// adding it to this process' thread list. 254 void RegisterThread(const Thread* thread); 255 256 /// Unregisters a thread from this process, removing it 257 /// from this process' thread list. 258 void UnregisterThread(const Thread* thread); 259 260 /// Clears the signaled state of the process if and only if it's signaled. 261 /// 262 /// @pre The process must not be already terminated. If this is called on a 263 /// terminated process, then ERR_INVALID_STATE will be returned. 264 /// 265 /// @pre The process must be in a signaled state. If this is called on a 266 /// process instance that is not signaled, ERR_INVALID_STATE will be 267 /// returned. 268 ResultCode ClearSignalState(); 269 270 /** 271 * Loads process-specifics configuration info with metadata provided 272 * by an executable. 273 * 274 * @param metadata The provided metadata to load process specific info from. 275 * 276 * @returns RESULT_SUCCESS if all relevant metadata was able to be 277 * loaded and parsed. Otherwise, an error code is returned. 278 */ 279 ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size); 280 281 /** 282 * Starts the main application thread for this process. 283 * 284 * @param main_thread_priority The priority for the main thread. 285 * @param stack_size The stack size for the main thread in bytes. 286 */ 287 void Run(s32 main_thread_priority, u64 stack_size); 288 289 /** 290 * Prepares a process for termination by stopping all of its threads 291 * and clearing any other resources. 292 */ 293 void PrepareForTermination(); 294 295 void LoadModule(CodeSet code_set, VAddr base_addr); 296 297 /////////////////////////////////////////////////////////////////////////////////////////////// 298 // Thread-local storage management 299 300 // Marks the next available region as used and returns the address of the slot. 301 [[nodiscard]] VAddr CreateTLSRegion(); 302 303 // Frees a used TLS slot identified by the given address 304 void FreeTLSRegion(VAddr tls_address); 305 306 private: 307 /// Checks if the specified thread should wait until this process is available. 308 bool ShouldWait(const Thread* thread) const override; 309 310 /// Acquires/locks this process for the specified thread if it's available. 311 void Acquire(Thread* thread) override; 312 313 /// Changes the process status. If the status is different 314 /// from the current process status, then this will trigger 315 /// a process signal. 316 void ChangeStatus(ProcessStatus new_status); 317 318 /// Allocates the main thread stack for the process, given the stack size in bytes. 319 ResultCode AllocateMainThreadStack(std::size_t stack_size); 320 321 /// Memory manager for this process 322 std::unique_ptr<Memory::PageTable> page_table; 323 324 /// Current status of the process 325 ProcessStatus status{}; 326 327 /// The ID of this process 328 u64 process_id = 0; 329 330 /// Title ID corresponding to the process 331 u64 program_id = 0; 332 333 /// Specifies additional memory to be reserved for the process's memory management by the 334 /// system. When this is non-zero, secure memory is allocated and used for page table allocation 335 /// instead of using the normal global page tables/memory block management. 336 u32 system_resource_size = 0; 337 338 /// Resource limit descriptor for this process 339 std::shared_ptr<ResourceLimit> resource_limit; 340 341 /// The ideal CPU core for this process, threads are scheduled on this core by default. 342 u8 ideal_core = 0; 343 344 /// The Thread Local Storage area is allocated as processes create threads, 345 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part 346 /// holds the TLS for a specific thread. This vector contains which parts are in use for each 347 /// page as a bitmask. 348 /// This vector will grow as more pages are allocated for new threads. 349 std::vector<TLSPage> tls_pages; 350 351 /// Contains the parsed process capability descriptors. 352 ProcessCapabilities capabilities; 353 354 /// Whether or not this process is AArch64, or AArch32. 355 /// By default, we currently assume this is true, unless otherwise 356 /// specified by metadata provided to the process during loading. 357 bool is_64bit_process = true; 358 359 /// Total running time for the process in ticks. 360 u64 total_process_running_time_ticks = 0; 361 362 /// Per-process handle table for storing created object handles in. 363 HandleTable handle_table; 364 365 /// Per-process address arbiter. 366 AddressArbiter address_arbiter; 367 368 /// The per-process mutex lock instance used for handling various 369 /// forms of services, such as lock arbitration, and condition 370 /// variable related facilities. 371 Mutex mutex; 372 373 /// Address indicating the location of the process' dedicated TLS region. 374 VAddr tls_region_address = 0; 375 376 /// Random values for svcGetInfo RandomEntropy 377 std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{}; 378 379 /// List of threads that are running with this process as their owner. 380 std::list<const Thread*> thread_list; 381 382 /// List of threads waiting for a condition variable 383 std::unordered_map<VAddr, std::list<std::shared_ptr<Thread>>> cond_var_threads; 384 385 /// Address of the top of the main thread's stack 386 VAddr main_thread_stack_top{}; 387 388 /// Size of the main thread's stack 389 std::size_t main_thread_stack_size{}; 390 391 /// Memory usage capacity for the process 392 std::size_t memory_usage_capacity{}; 393 394 /// Process total image size 395 std::size_t image_size{}; 396 397 /// Name of this process 398 std::string name; 399 400 /// System context 401 Core::System& system; 402 }; 403 404 } // namespace Kernel 405