mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #761 from Subv/resource_limits
Core/ResourceLimits: Implemented the basic structure of ResourceLimits.
This commit is contained in:
		
						commit
						ef8d0e9823
					
				
					 12 changed files with 341 additions and 14 deletions
				
			
		|  | @ -30,6 +30,7 @@ set(SRCS | ||||||
|             hle/kernel/kernel.cpp |             hle/kernel/kernel.cpp | ||||||
|             hle/kernel/mutex.cpp |             hle/kernel/mutex.cpp | ||||||
|             hle/kernel/process.cpp |             hle/kernel/process.cpp | ||||||
|  |             hle/kernel/resource_limit.cpp | ||||||
|             hle/kernel/semaphore.cpp |             hle/kernel/semaphore.cpp | ||||||
|             hle/kernel/session.cpp |             hle/kernel/session.cpp | ||||||
|             hle/kernel/shared_memory.cpp |             hle/kernel/shared_memory.cpp | ||||||
|  | @ -141,6 +142,7 @@ set(HEADERS | ||||||
|             hle/kernel/kernel.h |             hle/kernel/kernel.h | ||||||
|             hle/kernel/mutex.h |             hle/kernel/mutex.h | ||||||
|             hle/kernel/process.h |             hle/kernel/process.h | ||||||
|  |             hle/kernel/resource_limit.h | ||||||
|             hle/kernel/semaphore.h |             hle/kernel/semaphore.h | ||||||
|             hle/kernel/session.h |             hle/kernel/session.h | ||||||
|             hle/kernel/shared_memory.h |             hle/kernel/shared_memory.h | ||||||
|  |  | ||||||
|  | @ -102,8 +102,8 @@ template<ResultCode func(u32)> void Wrap() { | ||||||
|     FuncReturn(func(PARAM(0)).raw); |     FuncReturn(func(PARAM(0)).raw); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<ResultCode func(s64*, u32, void*, s32)> void Wrap(){ | template<ResultCode func(s64*, u32, u32*, s32)> void Wrap(){ | ||||||
|     FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), Memory::GetPointer(PARAM(2)), |     FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)), | ||||||
|         (s32)PARAM(3)).raw); |         (s32)PARAM(3)).raw); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
| #include "core/arm/arm_interface.h" | #include "core/arm/arm_interface.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
|  | #include "core/hle/kernel/resource_limit.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
| #include "core/hle/kernel/timer.h" | #include "core/hle/kernel/timer.h" | ||||||
|  | @ -134,6 +135,7 @@ void HandleTable::Clear() { | ||||||
| 
 | 
 | ||||||
| /// Initialize the kernel
 | /// Initialize the kernel
 | ||||||
| void Init() { | void Init() { | ||||||
|  |     Kernel::ResourceLimitsInit(); | ||||||
|     Kernel::ThreadingInit(); |     Kernel::ThreadingInit(); | ||||||
|     Kernel::TimersInit(); |     Kernel::TimersInit(); | ||||||
| 
 | 
 | ||||||
|  | @ -147,6 +149,7 @@ void Init() { | ||||||
| void Shutdown() { | void Shutdown() { | ||||||
|     Kernel::ThreadingShutdown(); |     Kernel::ThreadingShutdown(); | ||||||
|     Kernel::TimersShutdown(); |     Kernel::TimersShutdown(); | ||||||
|  |     Kernel::ResourceLimitsShutdown(); | ||||||
|     g_handle_table.Clear(); // Free all kernel objects
 |     g_handle_table.Clear(); // Free all kernel objects
 | ||||||
|     g_current_process = nullptr; |     g_current_process = nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -46,7 +46,8 @@ enum class HandleType : u32 { | ||||||
|     Process         = 8, |     Process         = 8, | ||||||
|     AddressArbiter  = 9, |     AddressArbiter  = 9, | ||||||
|     Semaphore       = 10, |     Semaphore       = 10, | ||||||
|     Timer           = 11 |     Timer           = 11, | ||||||
|  |     ResourceLimit   = 12, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| 
 | 
 | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
|  | #include "core/hle/kernel/resource_limit.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -45,6 +45,8 @@ union ProcessFlags { | ||||||
|     BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
 |     BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | class ResourceLimit; | ||||||
|  | 
 | ||||||
| class Process final : public Object { | class Process final : public Object { | ||||||
| public: | public: | ||||||
|     static SharedPtr<Process> Create(std::string name, u64 program_id); |     static SharedPtr<Process> Create(std::string name, u64 program_id); | ||||||
|  | @ -61,6 +63,8 @@ public: | ||||||
|     std::string name; |     std::string name; | ||||||
|     /// Title ID corresponding to the process
 |     /// Title ID corresponding to the process
 | ||||||
|     u64 program_id; |     u64 program_id; | ||||||
|  |     /// Resource limit descriptor for this process
 | ||||||
|  |     SharedPtr<ResourceLimit> resource_limit; | ||||||
| 
 | 
 | ||||||
|     /// The process may only call SVCs which have the corresponding bit set.
 |     /// The process may only call SVCs which have the corresponding bit set.
 | ||||||
|     std::bitset<0x80> svc_access_mask; |     std::bitset<0x80> svc_access_mask; | ||||||
|  |  | ||||||
							
								
								
									
										157
									
								
								src/core/hle/kernel/resource_limit.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/core/hle/kernel/resource_limit.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | ||||||
|  | // Copyright 2015 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include <cstring> | ||||||
|  | 
 | ||||||
|  | #include "common/logging/log.h" | ||||||
|  | 
 | ||||||
|  | #include "core/mem_map.h" | ||||||
|  | #include "core/hle/kernel/resource_limit.h" | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | static SharedPtr<ResourceLimit> resource_limits[4]; | ||||||
|  | 
 | ||||||
|  | ResourceLimit::ResourceLimit() {} | ||||||
|  | ResourceLimit::~ResourceLimit() {} | ||||||
|  | 
 | ||||||
|  | SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) { | ||||||
|  |     SharedPtr<ResourceLimit> resource_limit(new ResourceLimit); | ||||||
|  | 
 | ||||||
|  |     resource_limit->name = std::move(name); | ||||||
|  |     return resource_limit; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) { | ||||||
|  |     switch (category) | ||||||
|  |     { | ||||||
|  |         case ResourceLimitCategory::APPLICATION: | ||||||
|  |         case ResourceLimitCategory::SYS_APPLET: | ||||||
|  |         case ResourceLimitCategory::LIB_APPLET: | ||||||
|  |         case ResourceLimitCategory::OTHER: | ||||||
|  |             return resource_limits[static_cast<u8>(category)]; | ||||||
|  |         default: | ||||||
|  |             LOG_CRITICAL(Kernel, "Unknown resource limit category"); | ||||||
|  |             UNREACHABLE(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const { | ||||||
|  |     switch (resource) { | ||||||
|  |         case COMMIT: | ||||||
|  |             return current_commit; | ||||||
|  |         case THREAD: | ||||||
|  |             return current_threads; | ||||||
|  |         case EVENT: | ||||||
|  |             return current_events; | ||||||
|  |         case MUTEX: | ||||||
|  |             return current_mutexes; | ||||||
|  |         case SEMAPHORE: | ||||||
|  |             return current_semaphores; | ||||||
|  |         case TIMER: | ||||||
|  |             return current_timers; | ||||||
|  |         case SHARED_MEMORY: | ||||||
|  |             return current_shared_mems; | ||||||
|  |         case ADDRESS_ARBITER: | ||||||
|  |             return current_address_arbiters; | ||||||
|  |         case CPU_TIME: | ||||||
|  |             return current_cpu_time; | ||||||
|  |         default: | ||||||
|  |             LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); | ||||||
|  |             UNIMPLEMENTED(); | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { | ||||||
|  |     switch (resource) { | ||||||
|  |         case COMMIT: | ||||||
|  |             return max_commit; | ||||||
|  |         case THREAD: | ||||||
|  |             return max_threads; | ||||||
|  |         case EVENT: | ||||||
|  |             return max_events; | ||||||
|  |         case MUTEX: | ||||||
|  |             return max_mutexes; | ||||||
|  |         case SEMAPHORE: | ||||||
|  |             return max_semaphores; | ||||||
|  |         case TIMER: | ||||||
|  |             return max_timers; | ||||||
|  |         case SHARED_MEMORY: | ||||||
|  |             return max_shared_mems; | ||||||
|  |         case ADDRESS_ARBITER: | ||||||
|  |             return max_address_arbiters; | ||||||
|  |         case CPU_TIME: | ||||||
|  |             return max_cpu_time; | ||||||
|  |         default: | ||||||
|  |             LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); | ||||||
|  |             UNIMPLEMENTED(); | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ResourceLimitsInit() { | ||||||
|  |     // Create the four resource limits that the system uses
 | ||||||
|  |     // Create the APPLICATION resource limit
 | ||||||
|  |     SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications"); | ||||||
|  |     resource_limit->max_priority = 0x18; | ||||||
|  |     resource_limit->max_commit = 0x4000000; | ||||||
|  |     resource_limit->max_threads = 0x20; | ||||||
|  |     resource_limit->max_events = 0x20; | ||||||
|  |     resource_limit->max_mutexes = 0x20; | ||||||
|  |     resource_limit->max_semaphores = 0x8; | ||||||
|  |     resource_limit->max_timers = 0x8; | ||||||
|  |     resource_limit->max_shared_mems = 0x10; | ||||||
|  |     resource_limit->max_address_arbiters = 0x2; | ||||||
|  |     resource_limit->max_cpu_time = 0x1E; | ||||||
|  |     resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit; | ||||||
|  | 
 | ||||||
|  |     // Create the SYS_APPLET resource limit
 | ||||||
|  |     resource_limit = ResourceLimit::Create("System Applets"); | ||||||
|  |     resource_limit->max_priority = 0x4; | ||||||
|  |     resource_limit->max_commit = 0x5E00000; | ||||||
|  |     resource_limit->max_threads = 0x1D; | ||||||
|  |     resource_limit->max_events = 0xB; | ||||||
|  |     resource_limit->max_mutexes = 0x8; | ||||||
|  |     resource_limit->max_semaphores = 0x4; | ||||||
|  |     resource_limit->max_timers = 0x4; | ||||||
|  |     resource_limit->max_shared_mems = 0x8; | ||||||
|  |     resource_limit->max_address_arbiters = 0x3; | ||||||
|  |     resource_limit->max_cpu_time = 0x2710; | ||||||
|  |     resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit; | ||||||
|  | 
 | ||||||
|  |     // Create the LIB_APPLET resource limit
 | ||||||
|  |     resource_limit = ResourceLimit::Create("Library Applets"); | ||||||
|  |     resource_limit->max_priority = 0x4; | ||||||
|  |     resource_limit->max_commit = 0x600000; | ||||||
|  |     resource_limit->max_threads = 0xE; | ||||||
|  |     resource_limit->max_events = 0x8; | ||||||
|  |     resource_limit->max_mutexes = 0x8; | ||||||
|  |     resource_limit->max_semaphores = 0x4; | ||||||
|  |     resource_limit->max_timers = 0x4; | ||||||
|  |     resource_limit->max_shared_mems = 0x8; | ||||||
|  |     resource_limit->max_address_arbiters = 0x1; | ||||||
|  |     resource_limit->max_cpu_time = 0x2710; | ||||||
|  |     resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit; | ||||||
|  | 
 | ||||||
|  |     // Create the OTHER resource limit
 | ||||||
|  |     resource_limit = ResourceLimit::Create("Others"); | ||||||
|  |     resource_limit->max_priority = 0x4; | ||||||
|  |     resource_limit->max_commit = 0x2180000; | ||||||
|  |     resource_limit->max_threads = 0xE1; | ||||||
|  |     resource_limit->max_events = 0x108; | ||||||
|  |     resource_limit->max_mutexes = 0x25; | ||||||
|  |     resource_limit->max_semaphores = 0x43; | ||||||
|  |     resource_limit->max_timers = 0x2C; | ||||||
|  |     resource_limit->max_shared_mems = 0x1F; | ||||||
|  |     resource_limit->max_address_arbiters = 0x2D; | ||||||
|  |     resource_limit->max_cpu_time = 0x3E8; | ||||||
|  |     resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ResourceLimitsShutdown() { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace
 | ||||||
							
								
								
									
										119
									
								
								src/core/hle/kernel/resource_limit.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/core/hle/kernel/resource_limit.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,119 @@ | ||||||
|  | // Copyright 2015 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "common/common_types.h" | ||||||
|  | 
 | ||||||
|  | #include "core/hle/kernel/kernel.h" | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | enum class ResourceLimitCategory : u8 { | ||||||
|  |     APPLICATION = 0, | ||||||
|  |     SYS_APPLET  = 1, | ||||||
|  |     LIB_APPLET  = 2, | ||||||
|  |     OTHER       = 3 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum ResourceTypes { | ||||||
|  |     PRIORITY            = 0, | ||||||
|  |     COMMIT              = 1, | ||||||
|  |     THREAD              = 2, | ||||||
|  |     EVENT               = 3, | ||||||
|  |     MUTEX               = 4, | ||||||
|  |     SEMAPHORE           = 5, | ||||||
|  |     TIMER               = 6, | ||||||
|  |     SHARED_MEMORY       = 7, | ||||||
|  |     ADDRESS_ARBITER     = 8, | ||||||
|  |     CPU_TIME            = 9, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class ResourceLimit final : public Object { | ||||||
|  | public: | ||||||
|  |     /**
 | ||||||
|  |      * Creates a resource limit object. | ||||||
|  |      */ | ||||||
|  |     static SharedPtr<ResourceLimit> Create(std::string name = "Unknown"); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Retrieves the resource limit associated with the specified resource limit category. | ||||||
|  |      * @param category The resource limit category | ||||||
|  |      * @returns The resource limit associated with the category | ||||||
|  |      */ | ||||||
|  |     static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category); | ||||||
|  | 
 | ||||||
|  |     std::string GetTypeName() const override { return "ResourceLimit"; } | ||||||
|  |     std::string GetName() const override { return name; } | ||||||
|  | 
 | ||||||
|  |     static const HandleType HANDLE_TYPE = HandleType::ResourceLimit; | ||||||
|  |     HandleType GetHandleType() const override { return HANDLE_TYPE; } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Gets the current value for the specified resource. | ||||||
|  |      * @param resource Requested resource type | ||||||
|  |      * @returns The current value of the resource type | ||||||
|  |      */ | ||||||
|  |     s32 GetCurrentResourceValue(u32 resource) const; | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Gets the max value for the specified resource. | ||||||
|  |      * @param resource Requested resource type | ||||||
|  |      * @returns The max value of the resource type | ||||||
|  |      */ | ||||||
|  |     s32 GetMaxResourceValue(u32 resource) const; | ||||||
|  | 
 | ||||||
|  |     /// Name of resource limit object.
 | ||||||
|  |     std::string name; | ||||||
|  | 
 | ||||||
|  |     /// Max thread priority that a process in this category can create
 | ||||||
|  |     s32 max_priority = 0; | ||||||
|  | 
 | ||||||
|  |     /// Max memory that processes in this category can use
 | ||||||
|  |     s32 max_commit = 0; | ||||||
|  | 
 | ||||||
|  |     ///< Max number of objects that can be collectively created by the processes in this category
 | ||||||
|  |     s32 max_threads = 0; | ||||||
|  |     s32 max_events = 0; | ||||||
|  |     s32 max_mutexes = 0; | ||||||
|  |     s32 max_semaphores = 0; | ||||||
|  |     s32 max_timers = 0; | ||||||
|  |     s32 max_shared_mems = 0; | ||||||
|  |     s32 max_address_arbiters = 0; | ||||||
|  |      | ||||||
|  |     /// Max CPU time that the processes in this category can utilize
 | ||||||
|  |     s32 max_cpu_time = 0; | ||||||
|  | 
 | ||||||
|  |     // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that 
 | ||||||
|  |     // APPLICATION resource limits should not be affected by the objects created by service modules. 
 | ||||||
|  |     // Currently we have no way of distinguishing if a Create was called by the running application, 
 | ||||||
|  |     // or by a service module. Approach this once we have separated the service modules into their own processes
 | ||||||
|  | 
 | ||||||
|  |     /// Current memory that the processes in this category are using
 | ||||||
|  |     s32 current_commit = 0; | ||||||
|  | 
 | ||||||
|  |     ///< Current number of objects among all processes in this category
 | ||||||
|  |     s32 current_threads = 0; | ||||||
|  |     s32 current_events = 0; | ||||||
|  |     s32 current_mutexes = 0; | ||||||
|  |     s32 current_semaphores = 0; | ||||||
|  |     s32 current_timers = 0; | ||||||
|  |     s32 current_shared_mems = 0; | ||||||
|  |     s32 current_address_arbiters = 0; | ||||||
|  | 
 | ||||||
|  |     /// Current CPU time that the processes in this category are utilizing
 | ||||||
|  |     s32 current_cpu_time = 0; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     ResourceLimit(); | ||||||
|  |     ~ResourceLimit() override; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /// Initializes the resource limits
 | ||||||
|  | void ResourceLimitsInit(); | ||||||
|  | 
 | ||||||
|  | // Destroys the resource limits
 | ||||||
|  | void ResourceLimitsShutdown(); | ||||||
|  | 
 | ||||||
|  | } // namespace
 | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| #include "core/hle/kernel/event.h" | #include "core/hle/kernel/event.h" | ||||||
| #include "core/hle/kernel/mutex.h" | #include "core/hle/kernel/mutex.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
|  | #include "core/hle/kernel/resource_limit.h" | ||||||
| #include "core/hle/kernel/semaphore.h" | #include "core/hle/kernel/semaphore.h" | ||||||
| #include "core/hle/kernel/shared_memory.h" | #include "core/hle/kernel/shared_memory.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
|  | @ -301,21 +302,47 @@ static void OutputDebugString(const char* string) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Get resource limit
 | /// Get resource limit
 | ||||||
| static ResultCode GetResourceLimit(Handle* resource_limit, Handle process) { | static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) { | ||||||
|     // With regards to proceess values:
 |     LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); | ||||||
|     // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for
 | 
 | ||||||
|     // the current KThread.
 |     SharedPtr<Kernel::Process> process = Kernel::g_handle_table.Get<Kernel::Process>(process_handle); | ||||||
|     *resource_limit = 0xDEADBEEF; |     if (process == nullptr) | ||||||
|     LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called process=0x%08X", process); |         return ERR_INVALID_HANDLE; | ||||||
|  | 
 | ||||||
|  |     CASCADE_RESULT(*resource_limit, Kernel::g_handle_table.Create(process->resource_limit)); | ||||||
|  | 
 | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Get resource limit current values
 | /// Get resource limit current values
 | ||||||
| static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit, void* names, | static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names, | ||||||
|     s32 name_count) { |     s32 name_count) { | ||||||
|     LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called resource_limit=%08X, names=%p, name_count=%d", |     LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", | ||||||
|         resource_limit, names, name_count); |         resource_limit_handle, names, name_count); | ||||||
|     values[0] = 0; // Normmatt: Set used memory to 0 for now
 | 
 | ||||||
|  |     SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); | ||||||
|  |     if (resource_limit == nullptr) | ||||||
|  |         return ERR_INVALID_HANDLE; | ||||||
|  | 
 | ||||||
|  |     for (unsigned int i = 0; i < name_count; ++i) | ||||||
|  |         values[i] = resource_limit->GetCurrentResourceValue(names[i]); | ||||||
|  | 
 | ||||||
|  |     return RESULT_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Get resource limit max values
 | ||||||
|  | static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names, | ||||||
|  |     s32 name_count) { | ||||||
|  |     LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", | ||||||
|  |         resource_limit_handle, names, name_count); | ||||||
|  | 
 | ||||||
|  |     SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); | ||||||
|  |     if (resource_limit == nullptr) | ||||||
|  |         return ERR_INVALID_HANDLE; | ||||||
|  | 
 | ||||||
|  |     for (unsigned int i = 0; i < name_count; ++i) | ||||||
|  |         values[i] = resource_limit->GetMaxResourceValue(names[i]); | ||||||
|  | 
 | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -707,7 +734,7 @@ static const FunctionDef SVC_Table[] = { | ||||||
|     {0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"}, |     {0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"}, | ||||||
|     {0x37, HLE::Wrap<GetThreadId>,          "GetThreadId"}, |     {0x37, HLE::Wrap<GetThreadId>,          "GetThreadId"}, | ||||||
|     {0x38, HLE::Wrap<GetResourceLimit>,     "GetResourceLimit"}, |     {0x38, HLE::Wrap<GetResourceLimit>,     "GetResourceLimit"}, | ||||||
|     {0x39, nullptr,                         "GetResourceLimitLimitValues"}, |     {0x39, HLE::Wrap<GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"}, | ||||||
|     {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, |     {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, | ||||||
|     {0x3B, nullptr,                         "GetThreadContext"}, |     {0x3B, nullptr,                         "GetThreadContext"}, | ||||||
|     {0x3C, nullptr,                         "Break"}, |     {0x3C, nullptr,                         "Break"}, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "core/file_sys/archive_romfs.h" | #include "core/file_sys/archive_romfs.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
|  | #include "core/hle/kernel/resource_limit.h" | ||||||
| #include "core/hle/service/fs/archive.h" | #include "core/hle/service/fs/archive.h" | ||||||
| #include "core/loader/elf.h" | #include "core/loader/elf.h" | ||||||
| #include "core/loader/ncch.h" | #include "core/loader/ncch.h" | ||||||
|  | @ -234,6 +235,9 @@ ResultStatus AppLoader_THREEDSX::Load() { | ||||||
|     Kernel::g_current_process->svc_access_mask.set(); |     Kernel::g_current_process->svc_access_mask.set(); | ||||||
|     Kernel::g_current_process->address_mappings = default_address_mappings; |     Kernel::g_current_process->address_mappings = default_address_mappings; | ||||||
|      |      | ||||||
|  |     // Attach the default resource limit (APPLICATION) to the process
 | ||||||
|  |     Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | ||||||
|  | 
 | ||||||
|     Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR); |     Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR); | ||||||
| 
 | 
 | ||||||
|     Kernel::g_current_process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE); |     Kernel::g_current_process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE); | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| #include "common/symbols.h" | #include "common/symbols.h" | ||||||
| 
 | 
 | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
|  | #include "core/hle/kernel/resource_limit.h" | ||||||
| #include "core/loader/elf.h" | #include "core/loader/elf.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
|  | @ -354,6 +355,9 @@ ResultStatus AppLoader_ELF::Load() { | ||||||
|     Kernel::g_current_process->svc_access_mask.set(); |     Kernel::g_current_process->svc_access_mask.set(); | ||||||
|     Kernel::g_current_process->address_mappings = default_address_mappings; |     Kernel::g_current_process->address_mappings = default_address_mappings; | ||||||
| 
 | 
 | ||||||
|  |     // Attach the default resource limit (APPLICATION) to the process
 | ||||||
|  |     Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | ||||||
|  | 
 | ||||||
|     ElfReader elf_reader(&buffer[0]); |     ElfReader elf_reader(&buffer[0]); | ||||||
|     elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); |     elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); | ||||||
|     // TODO: Fill application title
 |     // TODO: Fill application title
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| #include "common/swap.h" | #include "common/swap.h" | ||||||
| 
 | 
 | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
|  | #include "core/hle/kernel/resource_limit.h" | ||||||
| #include "core/loader/ncch.h" | #include "core/loader/ncch.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
|  | @ -126,6 +127,10 @@ ResultStatus AppLoader_NCCH::LoadExec() const { | ||||||
|         u64 program_id = *reinterpret_cast<u64_le const*>(&ncch_header.program_id[0]); |         u64 program_id = *reinterpret_cast<u64_le const*>(&ncch_header.program_id[0]); | ||||||
|         Kernel::g_current_process = Kernel::Process::Create(process_name, program_id); |         Kernel::g_current_process = Kernel::Process::Create(process_name, program_id); | ||||||
| 
 | 
 | ||||||
|  |         // Attach a resource limit to the process based on the resource limit category
 | ||||||
|  |         Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory( | ||||||
|  |             static_cast<Kernel::ResourceLimitCategory>(exheader_header.arm11_system_local_caps.resource_limit_category)); | ||||||
|  | 
 | ||||||
|         // Copy data while converting endianess
 |         // Copy data while converting endianess
 | ||||||
|         std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps; |         std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps; | ||||||
|         std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps)); |         std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps)); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue