diff options
| author | 2015-05-15 09:42:36 -0400 | |
|---|---|---|
| committer | 2015-05-15 09:42:36 -0400 | |
| commit | ef8d0e9823e0ac61624002b89912e8995a3588e4 (patch) | |
| tree | dfaee1cefb39e627bd90562c416d19fe6002209c /src | |
| parent | Merge pull request #675 from jroweboy/windows-build-fixes (diff) | |
| parent | Core/ResourceLimits: Implemented the basic structure of ResourceLimits. (diff) | |
| download | yuzu-ef8d0e9823e0ac61624002b89912e8995a3588e4.tar.gz yuzu-ef8d0e9823e0ac61624002b89912e8995a3588e4.tar.xz yuzu-ef8d0e9823e0ac61624002b89912e8995a3588e4.zip | |
Merge pull request #761 from Subv/resource_limits
Core/ResourceLimits: Implemented the basic structure of ResourceLimits.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/function_wrappers.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/resource_limit.cpp | 157 | ||||
| -rw-r--r-- | src/core/hle/kernel/resource_limit.h | 119 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 49 | ||||
| -rw-r--r-- | src/core/loader/3dsx.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/elf.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/ncch.cpp | 5 |
12 files changed, 341 insertions, 14 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e8d8c96d7..5caaee474 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -30,6 +30,7 @@ set(SRCS | |||
| 30 | hle/kernel/kernel.cpp | 30 | hle/kernel/kernel.cpp |
| 31 | hle/kernel/mutex.cpp | 31 | hle/kernel/mutex.cpp |
| 32 | hle/kernel/process.cpp | 32 | hle/kernel/process.cpp |
| 33 | hle/kernel/resource_limit.cpp | ||
| 33 | hle/kernel/semaphore.cpp | 34 | hle/kernel/semaphore.cpp |
| 34 | hle/kernel/session.cpp | 35 | hle/kernel/session.cpp |
| 35 | hle/kernel/shared_memory.cpp | 36 | hle/kernel/shared_memory.cpp |
| @@ -141,6 +142,7 @@ set(HEADERS | |||
| 141 | hle/kernel/kernel.h | 142 | hle/kernel/kernel.h |
| 142 | hle/kernel/mutex.h | 143 | hle/kernel/mutex.h |
| 143 | hle/kernel/process.h | 144 | hle/kernel/process.h |
| 145 | hle/kernel/resource_limit.h | ||
| 144 | hle/kernel/semaphore.h | 146 | hle/kernel/semaphore.h |
| 145 | hle/kernel/session.h | 147 | hle/kernel/session.h |
| 146 | hle/kernel/shared_memory.h | 148 | hle/kernel/shared_memory.h |
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h index eb52c8fb1..0e5ae29ae 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h | |||
| @@ -102,8 +102,8 @@ template<ResultCode func(u32)> void Wrap() { | |||
| 102 | FuncReturn(func(PARAM(0)).raw); | 102 | FuncReturn(func(PARAM(0)).raw); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | template<ResultCode func(s64*, u32, void*, s32)> void Wrap(){ | 105 | template<ResultCode func(s64*, u32, u32*, s32)> void Wrap(){ |
| 106 | FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), Memory::GetPointer(PARAM(2)), | 106 | FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)), |
| 107 | (s32)PARAM(3)).raw); | 107 | (s32)PARAM(3)).raw); |
| 108 | } | 108 | } |
| 109 | 109 | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b5c98b249..726e4d2ff 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "core/arm/arm_interface.h" | 10 | #include "core/arm/arm_interface.h" |
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 13 | #include "core/hle/kernel/resource_limit.h" | ||
| 13 | #include "core/hle/kernel/process.h" | 14 | #include "core/hle/kernel/process.h" |
| 14 | #include "core/hle/kernel/thread.h" | 15 | #include "core/hle/kernel/thread.h" |
| 15 | #include "core/hle/kernel/timer.h" | 16 | #include "core/hle/kernel/timer.h" |
| @@ -134,6 +135,7 @@ void HandleTable::Clear() { | |||
| 134 | 135 | ||
| 135 | /// Initialize the kernel | 136 | /// Initialize the kernel |
| 136 | void Init() { | 137 | void Init() { |
| 138 | Kernel::ResourceLimitsInit(); | ||
| 137 | Kernel::ThreadingInit(); | 139 | Kernel::ThreadingInit(); |
| 138 | Kernel::TimersInit(); | 140 | Kernel::TimersInit(); |
| 139 | 141 | ||
| @@ -147,6 +149,7 @@ void Init() { | |||
| 147 | void Shutdown() { | 149 | void Shutdown() { |
| 148 | Kernel::ThreadingShutdown(); | 150 | Kernel::ThreadingShutdown(); |
| 149 | Kernel::TimersShutdown(); | 151 | Kernel::TimersShutdown(); |
| 152 | Kernel::ResourceLimitsShutdown(); | ||
| 150 | g_handle_table.Clear(); // Free all kernel objects | 153 | g_handle_table.Clear(); // Free all kernel objects |
| 151 | g_current_process = nullptr; | 154 | g_current_process = nullptr; |
| 152 | } | 155 | } |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 7c106d37c..28748c8f5 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -46,7 +46,8 @@ enum class HandleType : u32 { | |||
| 46 | Process = 8, | 46 | Process = 8, |
| 47 | AddressArbiter = 9, | 47 | AddressArbiter = 9, |
| 48 | Semaphore = 10, | 48 | Semaphore = 10, |
| 49 | Timer = 11 | 49 | Timer = 11, |
| 50 | ResourceLimit = 12, | ||
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| 52 | enum { | 53 | enum { |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 0cdfa58d7..b5c87e883 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | 8 | ||
| 9 | #include "core/hle/kernel/process.h" | 9 | #include "core/hle/kernel/process.h" |
| 10 | #include "core/hle/kernel/resource_limit.h" | ||
| 10 | #include "core/hle/kernel/thread.h" | 11 | #include "core/hle/kernel/thread.h" |
| 11 | #include "core/memory.h" | 12 | #include "core/memory.h" |
| 12 | 13 | ||
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 90881054c..7b8a68610 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -45,6 +45,8 @@ union ProcessFlags { | |||
| 45 | BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). | 45 | BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | class ResourceLimit; | ||
| 49 | |||
| 48 | class Process final : public Object { | 50 | class Process final : public Object { |
| 49 | public: | 51 | public: |
| 50 | static SharedPtr<Process> Create(std::string name, u64 program_id); | 52 | static SharedPtr<Process> Create(std::string name, u64 program_id); |
| @@ -61,6 +63,8 @@ public: | |||
| 61 | std::string name; | 63 | std::string name; |
| 62 | /// Title ID corresponding to the process | 64 | /// Title ID corresponding to the process |
| 63 | u64 program_id; | 65 | u64 program_id; |
| 66 | /// Resource limit descriptor for this process | ||
| 67 | SharedPtr<ResourceLimit> resource_limit; | ||
| 64 | 68 | ||
| 65 | /// The process may only call SVCs which have the corresponding bit set. | 69 | /// The process may only call SVCs which have the corresponding bit set. |
| 66 | std::bitset<0x80> svc_access_mask; | 70 | std::bitset<0x80> svc_access_mask; |
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp new file mode 100644 index 000000000..94b3e3298 --- /dev/null +++ b/src/core/hle/kernel/resource_limit.cpp | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <cstring> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | |||
| 9 | #include "core/mem_map.h" | ||
| 10 | #include "core/hle/kernel/resource_limit.h" | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | |||
| 14 | static SharedPtr<ResourceLimit> resource_limits[4]; | ||
| 15 | |||
| 16 | ResourceLimit::ResourceLimit() {} | ||
| 17 | ResourceLimit::~ResourceLimit() {} | ||
| 18 | |||
| 19 | SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) { | ||
| 20 | SharedPtr<ResourceLimit> resource_limit(new ResourceLimit); | ||
| 21 | |||
| 22 | resource_limit->name = std::move(name); | ||
| 23 | return resource_limit; | ||
| 24 | } | ||
| 25 | |||
| 26 | SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) { | ||
| 27 | switch (category) | ||
| 28 | { | ||
| 29 | case ResourceLimitCategory::APPLICATION: | ||
| 30 | case ResourceLimitCategory::SYS_APPLET: | ||
| 31 | case ResourceLimitCategory::LIB_APPLET: | ||
| 32 | case ResourceLimitCategory::OTHER: | ||
| 33 | return resource_limits[static_cast<u8>(category)]; | ||
| 34 | default: | ||
| 35 | LOG_CRITICAL(Kernel, "Unknown resource limit category"); | ||
| 36 | UNREACHABLE(); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const { | ||
| 41 | switch (resource) { | ||
| 42 | case COMMIT: | ||
| 43 | return current_commit; | ||
| 44 | case THREAD: | ||
| 45 | return current_threads; | ||
| 46 | case EVENT: | ||
| 47 | return current_events; | ||
| 48 | case MUTEX: | ||
| 49 | return current_mutexes; | ||
| 50 | case SEMAPHORE: | ||
| 51 | return current_semaphores; | ||
| 52 | case TIMER: | ||
| 53 | return current_timers; | ||
| 54 | case SHARED_MEMORY: | ||
| 55 | return current_shared_mems; | ||
| 56 | case ADDRESS_ARBITER: | ||
| 57 | return current_address_arbiters; | ||
| 58 | case CPU_TIME: | ||
| 59 | return current_cpu_time; | ||
| 60 | default: | ||
| 61 | LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); | ||
| 62 | UNIMPLEMENTED(); | ||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { | ||
| 68 | switch (resource) { | ||
| 69 | case COMMIT: | ||
| 70 | return max_commit; | ||
| 71 | case THREAD: | ||
| 72 | return max_threads; | ||
| 73 | case EVENT: | ||
| 74 | return max_events; | ||
| 75 | case MUTEX: | ||
| 76 | return max_mutexes; | ||
| 77 | case SEMAPHORE: | ||
| 78 | return max_semaphores; | ||
| 79 | case TIMER: | ||
| 80 | return max_timers; | ||
| 81 | case SHARED_MEMORY: | ||
| 82 | return max_shared_mems; | ||
| 83 | case ADDRESS_ARBITER: | ||
| 84 | return max_address_arbiters; | ||
| 85 | case CPU_TIME: | ||
| 86 | return max_cpu_time; | ||
| 87 | default: | ||
| 88 | LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); | ||
| 89 | UNIMPLEMENTED(); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | void ResourceLimitsInit() { | ||
| 95 | // Create the four resource limits that the system uses | ||
| 96 | // Create the APPLICATION resource limit | ||
| 97 | SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications"); | ||
| 98 | resource_limit->max_priority = 0x18; | ||
| 99 | resource_limit->max_commit = 0x4000000; | ||
| 100 | resource_limit->max_threads = 0x20; | ||
| 101 | resource_limit->max_events = 0x20; | ||
| 102 | resource_limit->max_mutexes = 0x20; | ||
| 103 | resource_limit->max_semaphores = 0x8; | ||
| 104 | resource_limit->max_timers = 0x8; | ||
| 105 | resource_limit->max_shared_mems = 0x10; | ||
| 106 | resource_limit->max_address_arbiters = 0x2; | ||
| 107 | resource_limit->max_cpu_time = 0x1E; | ||
| 108 | resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit; | ||
| 109 | |||
| 110 | // Create the SYS_APPLET resource limit | ||
| 111 | resource_limit = ResourceLimit::Create("System Applets"); | ||
| 112 | resource_limit->max_priority = 0x4; | ||
| 113 | resource_limit->max_commit = 0x5E00000; | ||
| 114 | resource_limit->max_threads = 0x1D; | ||
| 115 | resource_limit->max_events = 0xB; | ||
| 116 | resource_limit->max_mutexes = 0x8; | ||
| 117 | resource_limit->max_semaphores = 0x4; | ||
| 118 | resource_limit->max_timers = 0x4; | ||
| 119 | resource_limit->max_shared_mems = 0x8; | ||
| 120 | resource_limit->max_address_arbiters = 0x3; | ||
| 121 | resource_limit->max_cpu_time = 0x2710; | ||
| 122 | resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit; | ||
| 123 | |||
| 124 | // Create the LIB_APPLET resource limit | ||
| 125 | resource_limit = ResourceLimit::Create("Library Applets"); | ||
| 126 | resource_limit->max_priority = 0x4; | ||
| 127 | resource_limit->max_commit = 0x600000; | ||
| 128 | resource_limit->max_threads = 0xE; | ||
| 129 | resource_limit->max_events = 0x8; | ||
| 130 | resource_limit->max_mutexes = 0x8; | ||
| 131 | resource_limit->max_semaphores = 0x4; | ||
| 132 | resource_limit->max_timers = 0x4; | ||
| 133 | resource_limit->max_shared_mems = 0x8; | ||
| 134 | resource_limit->max_address_arbiters = 0x1; | ||
| 135 | resource_limit->max_cpu_time = 0x2710; | ||
| 136 | resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit; | ||
| 137 | |||
| 138 | // Create the OTHER resource limit | ||
| 139 | resource_limit = ResourceLimit::Create("Others"); | ||
| 140 | resource_limit->max_priority = 0x4; | ||
| 141 | resource_limit->max_commit = 0x2180000; | ||
| 142 | resource_limit->max_threads = 0xE1; | ||
| 143 | resource_limit->max_events = 0x108; | ||
| 144 | resource_limit->max_mutexes = 0x25; | ||
| 145 | resource_limit->max_semaphores = 0x43; | ||
| 146 | resource_limit->max_timers = 0x2C; | ||
| 147 | resource_limit->max_shared_mems = 0x1F; | ||
| 148 | resource_limit->max_address_arbiters = 0x2D; | ||
| 149 | resource_limit->max_cpu_time = 0x3E8; | ||
| 150 | resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit; | ||
| 151 | } | ||
| 152 | |||
| 153 | void ResourceLimitsShutdown() { | ||
| 154 | |||
| 155 | } | ||
| 156 | |||
| 157 | } // namespace | ||
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h new file mode 100644 index 000000000..201ec0db9 --- /dev/null +++ b/src/core/hle/kernel/resource_limit.h | |||
| @@ -0,0 +1,119 @@ | |||
| 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 "common/common_types.h" | ||
| 8 | |||
| 9 | #include "core/hle/kernel/kernel.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | enum class ResourceLimitCategory : u8 { | ||
| 14 | APPLICATION = 0, | ||
| 15 | SYS_APPLET = 1, | ||
| 16 | LIB_APPLET = 2, | ||
| 17 | OTHER = 3 | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum ResourceTypes { | ||
| 21 | PRIORITY = 0, | ||
| 22 | COMMIT = 1, | ||
| 23 | THREAD = 2, | ||
| 24 | EVENT = 3, | ||
| 25 | MUTEX = 4, | ||
| 26 | SEMAPHORE = 5, | ||
| 27 | TIMER = 6, | ||
| 28 | SHARED_MEMORY = 7, | ||
| 29 | ADDRESS_ARBITER = 8, | ||
| 30 | CPU_TIME = 9, | ||
| 31 | }; | ||
| 32 | |||
| 33 | class ResourceLimit final : public Object { | ||
| 34 | public: | ||
| 35 | /** | ||
| 36 | * Creates a resource limit object. | ||
| 37 | */ | ||
| 38 | static SharedPtr<ResourceLimit> Create(std::string name = "Unknown"); | ||
| 39 | |||
| 40 | /** | ||
| 41 | * Retrieves the resource limit associated with the specified resource limit category. | ||
| 42 | * @param category The resource limit category | ||
| 43 | * @returns The resource limit associated with the category | ||
| 44 | */ | ||
| 45 | static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category); | ||
| 46 | |||
| 47 | std::string GetTypeName() const override { return "ResourceLimit"; } | ||
| 48 | std::string GetName() const override { return name; } | ||
| 49 | |||
| 50 | static const HandleType HANDLE_TYPE = HandleType::ResourceLimit; | ||
| 51 | HandleType GetHandleType() const override { return HANDLE_TYPE; } | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Gets the current value for the specified resource. | ||
| 55 | * @param resource Requested resource type | ||
| 56 | * @returns The current value of the resource type | ||
| 57 | */ | ||
| 58 | s32 GetCurrentResourceValue(u32 resource) const; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Gets the max value for the specified resource. | ||
| 62 | * @param resource Requested resource type | ||
| 63 | * @returns The max value of the resource type | ||
| 64 | */ | ||
| 65 | s32 GetMaxResourceValue(u32 resource) const; | ||
| 66 | |||
| 67 | /// Name of resource limit object. | ||
| 68 | std::string name; | ||
| 69 | |||
| 70 | /// Max thread priority that a process in this category can create | ||
| 71 | s32 max_priority = 0; | ||
| 72 | |||
| 73 | /// Max memory that processes in this category can use | ||
| 74 | s32 max_commit = 0; | ||
| 75 | |||
| 76 | ///< Max number of objects that can be collectively created by the processes in this category | ||
| 77 | s32 max_threads = 0; | ||
| 78 | s32 max_events = 0; | ||
| 79 | s32 max_mutexes = 0; | ||
| 80 | s32 max_semaphores = 0; | ||
| 81 | s32 max_timers = 0; | ||
| 82 | s32 max_shared_mems = 0; | ||
| 83 | s32 max_address_arbiters = 0; | ||
| 84 | |||
| 85 | /// Max CPU time that the processes in this category can utilize | ||
| 86 | s32 max_cpu_time = 0; | ||
| 87 | |||
| 88 | // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that | ||
| 89 | // APPLICATION resource limits should not be affected by the objects created by service modules. | ||
| 90 | // Currently we have no way of distinguishing if a Create was called by the running application, | ||
| 91 | // or by a service module. Approach this once we have separated the service modules into their own processes | ||
| 92 | |||
| 93 | /// Current memory that the processes in this category are using | ||
| 94 | s32 current_commit = 0; | ||
| 95 | |||
| 96 | ///< Current number of objects among all processes in this category | ||
| 97 | s32 current_threads = 0; | ||
| 98 | s32 current_events = 0; | ||
| 99 | s32 current_mutexes = 0; | ||
| 100 | s32 current_semaphores = 0; | ||
| 101 | s32 current_timers = 0; | ||
| 102 | s32 current_shared_mems = 0; | ||
| 103 | s32 current_address_arbiters = 0; | ||
| 104 | |||
| 105 | /// Current CPU time that the processes in this category are utilizing | ||
| 106 | s32 current_cpu_time = 0; | ||
| 107 | |||
| 108 | private: | ||
| 109 | ResourceLimit(); | ||
| 110 | ~ResourceLimit() override; | ||
| 111 | }; | ||
| 112 | |||
| 113 | /// Initializes the resource limits | ||
| 114 | void ResourceLimitsInit(); | ||
| 115 | |||
| 116 | // Destroys the resource limits | ||
| 117 | void ResourceLimitsShutdown(); | ||
| 118 | |||
| 119 | } // namespace | ||
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 9bf886256..654ee2bf6 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include "core/hle/kernel/event.h" | 17 | #include "core/hle/kernel/event.h" |
| 18 | #include "core/hle/kernel/mutex.h" | 18 | #include "core/hle/kernel/mutex.h" |
| 19 | #include "core/hle/kernel/process.h" | 19 | #include "core/hle/kernel/process.h" |
| 20 | #include "core/hle/kernel/resource_limit.h" | ||
| 20 | #include "core/hle/kernel/semaphore.h" | 21 | #include "core/hle/kernel/semaphore.h" |
| 21 | #include "core/hle/kernel/shared_memory.h" | 22 | #include "core/hle/kernel/shared_memory.h" |
| 22 | #include "core/hle/kernel/thread.h" | 23 | #include "core/hle/kernel/thread.h" |
| @@ -301,21 +302,47 @@ static void OutputDebugString(const char* string) { | |||
| 301 | } | 302 | } |
| 302 | 303 | ||
| 303 | /// Get resource limit | 304 | /// Get resource limit |
| 304 | static ResultCode GetResourceLimit(Handle* resource_limit, Handle process) { | 305 | static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) { |
| 305 | // With regards to proceess values: | 306 | LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); |
| 306 | // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for | 307 | |
| 307 | // the current KThread. | 308 | SharedPtr<Kernel::Process> process = Kernel::g_handle_table.Get<Kernel::Process>(process_handle); |
| 308 | *resource_limit = 0xDEADBEEF; | 309 | if (process == nullptr) |
| 309 | LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called process=0x%08X", process); | 310 | return ERR_INVALID_HANDLE; |
| 311 | |||
| 312 | CASCADE_RESULT(*resource_limit, Kernel::g_handle_table.Create(process->resource_limit)); | ||
| 313 | |||
| 310 | return RESULT_SUCCESS; | 314 | return RESULT_SUCCESS; |
| 311 | } | 315 | } |
| 312 | 316 | ||
| 313 | /// Get resource limit current values | 317 | /// Get resource limit current values |
| 314 | static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit, void* names, | 318 | static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names, |
| 319 | s32 name_count) { | ||
| 320 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", | ||
| 321 | resource_limit_handle, names, name_count); | ||
| 322 | |||
| 323 | SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); | ||
| 324 | if (resource_limit == nullptr) | ||
| 325 | return ERR_INVALID_HANDLE; | ||
| 326 | |||
| 327 | for (unsigned int i = 0; i < name_count; ++i) | ||
| 328 | values[i] = resource_limit->GetCurrentResourceValue(names[i]); | ||
| 329 | |||
| 330 | return RESULT_SUCCESS; | ||
| 331 | } | ||
| 332 | |||
| 333 | /// Get resource limit max values | ||
| 334 | static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names, | ||
| 315 | s32 name_count) { | 335 | s32 name_count) { |
| 316 | LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called resource_limit=%08X, names=%p, name_count=%d", | 336 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", |
| 317 | resource_limit, names, name_count); | 337 | resource_limit_handle, names, name_count); |
| 318 | values[0] = 0; // Normmatt: Set used memory to 0 for now | 338 | |
| 339 | SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); | ||
| 340 | if (resource_limit == nullptr) | ||
| 341 | return ERR_INVALID_HANDLE; | ||
| 342 | |||
| 343 | for (unsigned int i = 0; i < name_count; ++i) | ||
| 344 | values[i] = resource_limit->GetMaxResourceValue(names[i]); | ||
| 345 | |||
| 319 | return RESULT_SUCCESS; | 346 | return RESULT_SUCCESS; |
| 320 | } | 347 | } |
| 321 | 348 | ||
| @@ -707,7 +734,7 @@ static const FunctionDef SVC_Table[] = { | |||
| 707 | {0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"}, | 734 | {0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"}, |
| 708 | {0x37, HLE::Wrap<GetThreadId>, "GetThreadId"}, | 735 | {0x37, HLE::Wrap<GetThreadId>, "GetThreadId"}, |
| 709 | {0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"}, | 736 | {0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"}, |
| 710 | {0x39, nullptr, "GetResourceLimitLimitValues"}, | 737 | {0x39, HLE::Wrap<GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"}, |
| 711 | {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, | 738 | {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, |
| 712 | {0x3B, nullptr, "GetThreadContext"}, | 739 | {0x3B, nullptr, "GetThreadContext"}, |
| 713 | {0x3C, nullptr, "Break"}, | 740 | {0x3C, nullptr, "Break"}, |
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 84b13ee52..ad5e929ce 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "core/file_sys/archive_romfs.h" | 10 | #include "core/file_sys/archive_romfs.h" |
| 11 | #include "core/hle/kernel/process.h" | 11 | #include "core/hle/kernel/process.h" |
| 12 | #include "core/hle/kernel/resource_limit.h" | ||
| 12 | #include "core/hle/service/fs/archive.h" | 13 | #include "core/hle/service/fs/archive.h" |
| 13 | #include "core/loader/elf.h" | 14 | #include "core/loader/elf.h" |
| 14 | #include "core/loader/ncch.h" | 15 | #include "core/loader/ncch.h" |
| @@ -233,6 +234,9 @@ ResultStatus AppLoader_THREEDSX::Load() { | |||
| 233 | Kernel::g_current_process = Kernel::Process::Create(filename, 0); | 234 | Kernel::g_current_process = Kernel::Process::Create(filename, 0); |
| 234 | Kernel::g_current_process->svc_access_mask.set(); | 235 | Kernel::g_current_process->svc_access_mask.set(); |
| 235 | Kernel::g_current_process->address_mappings = default_address_mappings; | 236 | Kernel::g_current_process->address_mappings = default_address_mappings; |
| 237 | |||
| 238 | // Attach the default resource limit (APPLICATION) to the process | ||
| 239 | Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | ||
| 236 | 240 | ||
| 237 | Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR); | 241 | Load3DSXFile(*file, Memory::PROCESS_IMAGE_VADDR); |
| 238 | 242 | ||
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index a951bc80f..f00753a79 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "common/symbols.h" | 11 | #include "common/symbols.h" |
| 12 | 12 | ||
| 13 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/resource_limit.h" | ||
| 14 | #include "core/loader/elf.h" | 15 | #include "core/loader/elf.h" |
| 15 | #include "core/memory.h" | 16 | #include "core/memory.h" |
| 16 | 17 | ||
| @@ -354,6 +355,9 @@ ResultStatus AppLoader_ELF::Load() { | |||
| 354 | Kernel::g_current_process->svc_access_mask.set(); | 355 | Kernel::g_current_process->svc_access_mask.set(); |
| 355 | Kernel::g_current_process->address_mappings = default_address_mappings; | 356 | Kernel::g_current_process->address_mappings = default_address_mappings; |
| 356 | 357 | ||
| 358 | // Attach the default resource limit (APPLICATION) to the process | ||
| 359 | Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | ||
| 360 | |||
| 357 | ElfReader elf_reader(&buffer[0]); | 361 | ElfReader elf_reader(&buffer[0]); |
| 358 | elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); | 362 | elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); |
| 359 | // TODO: Fill application title | 363 | // TODO: Fill application title |
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 36e341fd4..08993c4fa 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 12 | 12 | ||
| 13 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/resource_limit.h" | ||
| 14 | #include "core/loader/ncch.h" | 15 | #include "core/loader/ncch.h" |
| 15 | #include "core/memory.h" | 16 | #include "core/memory.h" |
| 16 | 17 | ||
| @@ -126,6 +127,10 @@ ResultStatus AppLoader_NCCH::LoadExec() const { | |||
| 126 | u64 program_id = *reinterpret_cast<u64_le const*>(&ncch_header.program_id[0]); | 127 | u64 program_id = *reinterpret_cast<u64_le const*>(&ncch_header.program_id[0]); |
| 127 | Kernel::g_current_process = Kernel::Process::Create(process_name, program_id); | 128 | Kernel::g_current_process = Kernel::Process::Create(process_name, program_id); |
| 128 | 129 | ||
| 130 | // Attach a resource limit to the process based on the resource limit category | ||
| 131 | Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory( | ||
| 132 | static_cast<Kernel::ResourceLimitCategory>(exheader_header.arm11_system_local_caps.resource_limit_category)); | ||
| 133 | |||
| 129 | // Copy data while converting endianess | 134 | // Copy data while converting endianess |
| 130 | std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps; | 135 | std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps; |
| 131 | std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps)); | 136 | std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps)); |