diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/init/init_slab_setup.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_resource_limit.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_resource_limit.h | 20 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scoped_resource_reservation.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_shared_memory.cpp | 28 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_shared_memory.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_transfer_memory.h | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 38 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 127 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 19 |
13 files changed, 197 insertions, 122 deletions
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index ce7a24c40..a5ddd7344 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp | |||
| @@ -12,11 +12,12 @@ | |||
| 12 | #include "core/hle/kernel/k_event.h" | 12 | #include "core/hle/kernel/k_event.h" |
| 13 | #include "core/hle/kernel/k_memory_layout.h" | 13 | #include "core/hle/kernel/k_memory_layout.h" |
| 14 | #include "core/hle/kernel/k_memory_manager.h" | 14 | #include "core/hle/kernel/k_memory_manager.h" |
| 15 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 15 | #include "core/hle/kernel/k_session.h" | 16 | #include "core/hle/kernel/k_session.h" |
| 16 | #include "core/hle/kernel/k_shared_memory.h" | 17 | #include "core/hle/kernel/k_shared_memory.h" |
| 17 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 18 | #include "core/hle/kernel/k_system_control.h" | 18 | #include "core/hle/kernel/k_system_control.h" |
| 19 | #include "core/hle/kernel/k_thread.h" | 19 | #include "core/hle/kernel/k_thread.h" |
| 20 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 20 | #include "core/hle/kernel/memory_types.h" | 21 | #include "core/hle/kernel/memory_types.h" |
| 21 | #include "core/hle/kernel/process.h" | 22 | #include "core/hle/kernel/process.h" |
| 22 | #include "core/memory.h" | 23 | #include "core/memory.h" |
| @@ -31,7 +32,8 @@ namespace Kernel::Init { | |||
| 31 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ | 32 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ |
| 32 | HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \ | 33 | HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \ |
| 33 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ | 34 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ |
| 34 | HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) | 35 | HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) \ |
| 36 | HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) | ||
| 35 | 37 | ||
| 36 | namespace { | 38 | namespace { |
| 37 | 39 | ||
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index d05b34ea3..ad5095bfd 100644 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.cpp | |||
| @@ -10,10 +10,16 @@ | |||
| 10 | namespace Kernel { | 10 | namespace Kernel { |
| 11 | constexpr s64 DefaultTimeout = 10000000000; // 10 seconds | 11 | constexpr s64 DefaultTimeout = 10000000000; // 10 seconds |
| 12 | 12 | ||
| 13 | KResourceLimit::KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_) | 13 | KResourceLimit::KResourceLimit(KernelCore& kernel) |
| 14 | : Object{kernel}, lock{kernel}, cond_var{kernel}, core_timing(core_timing_) {} | 14 | : KAutoObjectWithSlabHeapAndContainer{kernel}, lock{kernel}, cond_var{kernel} {} |
| 15 | KResourceLimit::~KResourceLimit() = default; | 15 | KResourceLimit::~KResourceLimit() = default; |
| 16 | 16 | ||
| 17 | void KResourceLimit::Initialize(const Core::Timing::CoreTiming* core_timing_) { | ||
| 18 | core_timing = core_timing_; | ||
| 19 | } | ||
| 20 | |||
| 21 | void KResourceLimit::Finalize() {} | ||
| 22 | |||
| 17 | s64 KResourceLimit::GetLimitValue(LimitableResource which) const { | 23 | s64 KResourceLimit::GetLimitValue(LimitableResource which) const { |
| 18 | const auto index = static_cast<std::size_t>(which); | 24 | const auto index = static_cast<std::size_t>(which); |
| 19 | s64 value{}; | 25 | s64 value{}; |
| @@ -78,7 +84,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { | |||
| 78 | } | 84 | } |
| 79 | 85 | ||
| 80 | bool KResourceLimit::Reserve(LimitableResource which, s64 value) { | 86 | bool KResourceLimit::Reserve(LimitableResource which, s64 value) { |
| 81 | return Reserve(which, value, core_timing.GetGlobalTimeNs().count() + DefaultTimeout); | 87 | return Reserve(which, value, core_timing->GetGlobalTimeNs().count() + DefaultTimeout); |
| 82 | } | 88 | } |
| 83 | 89 | ||
| 84 | bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | 90 | bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { |
| @@ -109,7 +115,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | |||
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | if (current_hints[index] + value <= limit_values[index] && | 117 | if (current_hints[index] + value <= limit_values[index] && |
| 112 | (timeout < 0 || core_timing.GetGlobalTimeNs().count() < timeout)) { | 118 | (timeout < 0 || core_timing->GetGlobalTimeNs().count() < timeout)) { |
| 113 | waiter_count++; | 119 | waiter_count++; |
| 114 | cond_var.Wait(&lock, timeout); | 120 | cond_var.Wait(&lock, timeout); |
| 115 | waiter_count--; | 121 | waiter_count--; |
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index 4542317d0..483c66c33 100644 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h | |||
| @@ -32,10 +32,16 @@ constexpr bool IsValidResourceType(LimitableResource type) { | |||
| 32 | return type < LimitableResource::Count; | 32 | return type < LimitableResource::Count; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | class KResourceLimit final : public Object { | 35 | class KResourceLimit final |
| 36 | : public KAutoObjectWithSlabHeapAndContainer<KResourceLimit, KAutoObjectWithList> { | ||
| 37 | KERNEL_AUTOOBJECT_TRAITS(KResourceLimit, KAutoObject); | ||
| 38 | |||
| 36 | public: | 39 | public: |
| 37 | explicit KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_); | 40 | explicit KResourceLimit(KernelCore& kernel); |
| 38 | ~KResourceLimit(); | 41 | virtual ~KResourceLimit(); |
| 42 | |||
| 43 | void Initialize(const Core::Timing::CoreTiming* core_timing_); | ||
| 44 | virtual void Finalize() override; | ||
| 39 | 45 | ||
| 40 | s64 GetLimitValue(LimitableResource which) const; | 46 | s64 GetLimitValue(LimitableResource which) const; |
| 41 | s64 GetCurrentValue(LimitableResource which) const; | 47 | s64 GetCurrentValue(LimitableResource which) const; |
| @@ -49,6 +55,10 @@ public: | |||
| 49 | void Release(LimitableResource which, s64 value); | 55 | void Release(LimitableResource which, s64 value); |
| 50 | void Release(LimitableResource which, s64 value, s64 hint); | 56 | void Release(LimitableResource which, s64 value, s64 hint); |
| 51 | 57 | ||
| 58 | static void PostDestroy([[maybe_unused]] uintptr_t arg) {} | ||
| 59 | |||
| 60 | // DEPRECATED | ||
| 61 | |||
| 52 | std::string GetTypeName() const override { | 62 | std::string GetTypeName() const override { |
| 53 | return "KResourceLimit"; | 63 | return "KResourceLimit"; |
| 54 | } | 64 | } |
| @@ -61,8 +71,6 @@ public: | |||
| 61 | return HANDLE_TYPE; | 71 | return HANDLE_TYPE; |
| 62 | } | 72 | } |
| 63 | 73 | ||
| 64 | virtual void Finalize() override {} | ||
| 65 | |||
| 66 | private: | 74 | private: |
| 67 | using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>; | 75 | using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>; |
| 68 | ResourceArray limit_values{}; | 76 | ResourceArray limit_values{}; |
| @@ -72,6 +80,6 @@ private: | |||
| 72 | mutable KLightLock lock; | 80 | mutable KLightLock lock; |
| 73 | s32 waiter_count{}; | 81 | s32 waiter_count{}; |
| 74 | KLightConditionVariable cond_var; | 82 | KLightConditionVariable cond_var; |
| 75 | const Core::Timing::CoreTiming& core_timing; | 83 | const Core::Timing::CoreTiming* core_timing{}; |
| 76 | }; | 84 | }; |
| 77 | } // namespace Kernel | 85 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_scoped_resource_reservation.h b/src/core/hle/kernel/k_scoped_resource_reservation.h index c5deca00b..b160587c5 100644 --- a/src/core/hle/kernel/k_scoped_resource_reservation.h +++ b/src/core/hle/kernel/k_scoped_resource_reservation.h | |||
| @@ -15,8 +15,7 @@ namespace Kernel { | |||
| 15 | 15 | ||
| 16 | class KScopedResourceReservation { | 16 | class KScopedResourceReservation { |
| 17 | public: | 17 | public: |
| 18 | explicit KScopedResourceReservation(std::shared_ptr<KResourceLimit> l, LimitableResource r, | 18 | explicit KScopedResourceReservation(KResourceLimit* l, LimitableResource r, s64 v, s64 timeout) |
| 19 | s64 v, s64 timeout) | ||
| 20 | : resource_limit(std::move(l)), value(v), resource(r) { | 19 | : resource_limit(std::move(l)), value(v), resource(r) { |
| 21 | if (resource_limit && value) { | 20 | if (resource_limit && value) { |
| 22 | success = resource_limit->Reserve(resource, value, timeout); | 21 | success = resource_limit->Reserve(resource, value, timeout); |
| @@ -25,8 +24,7 @@ public: | |||
| 25 | } | 24 | } |
| 26 | } | 25 | } |
| 27 | 26 | ||
| 28 | explicit KScopedResourceReservation(std::shared_ptr<KResourceLimit> l, LimitableResource r, | 27 | explicit KScopedResourceReservation(KResourceLimit* l, LimitableResource r, s64 v = 1) |
| 29 | s64 v = 1) | ||
| 30 | : resource_limit(std::move(l)), value(v), resource(r) { | 28 | : resource_limit(std::move(l)), value(v), resource(r) { |
| 31 | if (resource_limit && value) { | 29 | if (resource_limit && value) { |
| 32 | success = resource_limit->Reserve(resource, value); | 30 | success = resource_limit->Reserve(resource, value); |
| @@ -58,7 +56,7 @@ public: | |||
| 58 | } | 56 | } |
| 59 | 57 | ||
| 60 | private: | 58 | private: |
| 61 | std::shared_ptr<KResourceLimit> resource_limit; | 59 | KResourceLimit* resource_limit{}; |
| 62 | s64 value; | 60 | s64 value; |
| 63 | LimitableResource resource; | 61 | LimitableResource resource; |
| 64 | bool success; | 62 | bool success; |
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index 9e20c2350..e91bc94bd 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 8 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 9 | #include "core/hle/kernel/k_shared_memory.h" | 9 | #include "core/hle/kernel/k_shared_memory.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/svc_results.h" | ||
| 11 | 12 | ||
| 12 | namespace Kernel { | 13 | namespace Kernel { |
| 13 | 14 | ||
| @@ -22,12 +23,7 @@ ResultCode KSharedMemory::Initialize(KernelCore& kernel_, Core::DeviceMemory& de | |||
| 22 | KMemoryPermission owner_permission_, | 23 | KMemoryPermission owner_permission_, |
| 23 | KMemoryPermission user_permission_, PAddr physical_address_, | 24 | KMemoryPermission user_permission_, PAddr physical_address_, |
| 24 | std::size_t size_, std::string name_) { | 25 | std::size_t size_, std::string name_) { |
| 25 | 26 | // Set members. | |
| 26 | resource_limit = kernel_.GetSystemResourceLimit(); | ||
| 27 | KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, | ||
| 28 | size_); | ||
| 29 | ASSERT(memory_reservation.Succeeded()); | ||
| 30 | |||
| 31 | owner_process = owner_process_; | 27 | owner_process = owner_process_; |
| 32 | device_memory = &device_memory_; | 28 | device_memory = &device_memory_; |
| 33 | page_list = std::move(page_list_); | 29 | page_list = std::move(page_list_); |
| @@ -36,10 +32,28 @@ ResultCode KSharedMemory::Initialize(KernelCore& kernel_, Core::DeviceMemory& de | |||
| 36 | physical_address = physical_address_; | 32 | physical_address = physical_address_; |
| 37 | size = size_; | 33 | size = size_; |
| 38 | name = name_; | 34 | name = name_; |
| 39 | is_initialized = true; | ||
| 40 | 35 | ||
| 36 | // Get the resource limit. | ||
| 37 | KResourceLimit* reslimit = kernel.GetSystemResourceLimit(); | ||
| 38 | |||
| 39 | // Reserve memory for ourselves. | ||
| 40 | KScopedResourceReservation memory_reservation(reslimit, LimitableResource::PhysicalMemory, | ||
| 41 | size_); | ||
| 42 | R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); | ||
| 43 | |||
| 44 | // Commit our reservation. | ||
| 41 | memory_reservation.Commit(); | 45 | memory_reservation.Commit(); |
| 42 | 46 | ||
| 47 | // Set our resource limit. | ||
| 48 | resource_limit = reslimit; | ||
| 49 | resource_limit->Open(); | ||
| 50 | |||
| 51 | // Mark initialized. | ||
| 52 | is_initialized = true; | ||
| 53 | |||
| 54 | // Clear all pages in the memory. | ||
| 55 | std::memset(device_memory_.GetPointer(physical_address_), 0, size_); | ||
| 56 | |||
| 43 | return RESULT_SUCCESS; | 57 | return RESULT_SUCCESS; |
| 44 | } | 58 | } |
| 45 | 59 | ||
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index aaa773bfc..93153ab20 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h | |||
| @@ -88,7 +88,7 @@ private: | |||
| 88 | KMemoryPermission user_permission{}; | 88 | KMemoryPermission user_permission{}; |
| 89 | PAddr physical_address{}; | 89 | PAddr physical_address{}; |
| 90 | std::size_t size{}; | 90 | std::size_t size{}; |
| 91 | std::shared_ptr<KResourceLimit> resource_limit; | 91 | KResourceLimit* resource_limit{}; |
| 92 | bool is_initialized{}; | 92 | bool is_initialized{}; |
| 93 | }; | 93 | }; |
| 94 | 94 | ||
diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h index f43725c7f..3c3fa401b 100644 --- a/src/core/hle/kernel/k_transfer_memory.h +++ b/src/core/hle/kernel/k_transfer_memory.h | |||
| @@ -27,9 +27,7 @@ class KTransferMemory final | |||
| 27 | 27 | ||
| 28 | public: | 28 | public: |
| 29 | explicit KTransferMemory(KernelCore& kernel); | 29 | explicit KTransferMemory(KernelCore& kernel); |
| 30 | ~KTransferMemory() override; | 30 | virtual ~KTransferMemory() override; |
| 31 | |||
| 32 | static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; | ||
| 33 | 31 | ||
| 34 | ResultCode Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_); | 32 | ResultCode Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_); |
| 35 | 33 | ||
| @@ -67,6 +65,7 @@ public: | |||
| 67 | return GetTypeName(); | 65 | return GetTypeName(); |
| 68 | } | 66 | } |
| 69 | 67 | ||
| 68 | static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; | ||
| 70 | HandleType GetHandleType() const override { | 69 | HandleType GetHandleType() const override { |
| 71 | return HANDLE_TYPE; | 70 | return HANDLE_TYPE; |
| 72 | } | 71 | } |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 472c71cf1..ada993f46 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -74,8 +74,8 @@ struct KernelCore::Impl { | |||
| 74 | Init::InitializeSlabHeaps(system, memory_layout); | 74 | Init::InitializeSlabHeaps(system, memory_layout); |
| 75 | 75 | ||
| 76 | // Initialize kernel memory and resources. | 76 | // Initialize kernel memory and resources. |
| 77 | InitializeMemoryLayout(memory_layout); | ||
| 78 | InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout); | 77 | InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout); |
| 78 | InitializeMemoryLayout(memory_layout); | ||
| 79 | InitializePageSlab(); | 79 | InitializePageSlab(); |
| 80 | InitializeSchedulers(); | 80 | InitializeSchedulers(); |
| 81 | InitializeSuspendThreads(); | 81 | InitializeSuspendThreads(); |
| @@ -126,11 +126,19 @@ struct KernelCore::Impl { | |||
| 126 | 126 | ||
| 127 | exclusive_monitor.reset(); | 127 | exclusive_monitor.reset(); |
| 128 | 128 | ||
| 129 | hid_shared_mem->Close(); | ||
| 129 | hid_shared_mem = nullptr; | 130 | hid_shared_mem = nullptr; |
| 131 | |||
| 132 | font_shared_mem->Close(); | ||
| 130 | font_shared_mem = nullptr; | 133 | font_shared_mem = nullptr; |
| 134 | |||
| 135 | irs_shared_mem->Close(); | ||
| 131 | irs_shared_mem = nullptr; | 136 | irs_shared_mem = nullptr; |
| 137 | |||
| 138 | time_shared_mem->Close(); | ||
| 132 | time_shared_mem = nullptr; | 139 | time_shared_mem = nullptr; |
| 133 | 140 | ||
| 141 | system_resource_limit->Close(); | ||
| 134 | system_resource_limit = nullptr; | 142 | system_resource_limit = nullptr; |
| 135 | 143 | ||
| 136 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others | 144 | // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others |
| @@ -156,7 +164,9 @@ struct KernelCore::Impl { | |||
| 156 | void InitializeSystemResourceLimit(KernelCore& kernel, | 164 | void InitializeSystemResourceLimit(KernelCore& kernel, |
| 157 | const Core::Timing::CoreTiming& core_timing, | 165 | const Core::Timing::CoreTiming& core_timing, |
| 158 | const KMemoryLayout& memory_layout) { | 166 | const KMemoryLayout& memory_layout) { |
| 159 | system_resource_limit = std::make_shared<KResourceLimit>(kernel, core_timing); | 167 | system_resource_limit = KResourceLimit::Create(system.Kernel()); |
| 168 | system_resource_limit->Initialize(&core_timing); | ||
| 169 | |||
| 160 | const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); | 170 | const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); |
| 161 | 171 | ||
| 162 | // If setting the default system values fails, then something seriously wrong has occurred. | 172 | // If setting the default system values fails, then something seriously wrong has occurred. |
| @@ -627,11 +637,11 @@ struct KernelCore::Impl { | |||
| 627 | 637 | ||
| 628 | // Lists all processes that exist in the current session. | 638 | // Lists all processes that exist in the current session. |
| 629 | std::vector<Process*> process_list; | 639 | std::vector<Process*> process_list; |
| 630 | Process* current_process = nullptr; | 640 | Process* current_process{}; |
| 631 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; | 641 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; |
| 632 | Kernel::TimeManager time_manager; | 642 | Kernel::TimeManager time_manager; |
| 633 | 643 | ||
| 634 | std::shared_ptr<KResourceLimit> system_resource_limit; | 644 | KResourceLimit* system_resource_limit{}; |
| 635 | 645 | ||
| 636 | std::shared_ptr<Core::Timing::EventType> preemption_event; | 646 | std::shared_ptr<Core::Timing::EventType> preemption_event; |
| 637 | 647 | ||
| @@ -704,7 +714,11 @@ void KernelCore::Shutdown() { | |||
| 704 | impl->Shutdown(); | 714 | impl->Shutdown(); |
| 705 | } | 715 | } |
| 706 | 716 | ||
| 707 | std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const { | 717 | const KResourceLimit* KernelCore::GetSystemResourceLimit() const { |
| 718 | return impl->system_resource_limit; | ||
| 719 | } | ||
| 720 | |||
| 721 | KResourceLimit* KernelCore::GetSystemResourceLimit() { | ||
| 708 | return impl->system_resource_limit; | 722 | return impl->system_resource_limit; |
| 709 | } | 723 | } |
| 710 | 724 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index f07f0276e..43e49603b 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -92,7 +92,10 @@ public: | |||
| 92 | void Shutdown(); | 92 | void Shutdown(); |
| 93 | 93 | ||
| 94 | /// Retrieves a shared pointer to the system resource limit instance. | 94 | /// Retrieves a shared pointer to the system resource limit instance. |
| 95 | std::shared_ptr<KResourceLimit> GetSystemResourceLimit() const; | 95 | const KResourceLimit* GetSystemResourceLimit() const; |
| 96 | |||
| 97 | /// Retrieves a shared pointer to the system resource limit instance. | ||
| 98 | KResourceLimit* GetSystemResourceLimit(); | ||
| 96 | 99 | ||
| 97 | /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. | 100 | /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. |
| 98 | KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; | 101 | KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; |
| @@ -263,24 +266,26 @@ public: | |||
| 263 | /// Gets the slab heap for the specified kernel object type. | 266 | /// Gets the slab heap for the specified kernel object type. |
| 264 | template <typename T> | 267 | template <typename T> |
| 265 | KSlabHeap<T>& SlabHeap() { | 268 | KSlabHeap<T>& SlabHeap() { |
| 266 | if constexpr (std::is_same_v<T, Process>) { | 269 | if constexpr (std::is_same_v<T, KClientSession>) { |
| 267 | return slab_heap_container->process; | 270 | return slab_heap_container->client_session; |
| 268 | } else if constexpr (std::is_same_v<T, KThread>) { | ||
| 269 | return slab_heap_container->thread; | ||
| 270 | } else if constexpr (std::is_same_v<T, KEvent>) { | 271 | } else if constexpr (std::is_same_v<T, KEvent>) { |
| 271 | return slab_heap_container->event; | 272 | return slab_heap_container->event; |
| 272 | } else if constexpr (std::is_same_v<T, KSharedMemory>) { | ||
| 273 | return slab_heap_container->shared_memory; | ||
| 274 | } else if constexpr (std::is_same_v<T, KLinkedListNode>) { | 273 | } else if constexpr (std::is_same_v<T, KLinkedListNode>) { |
| 275 | return slab_heap_container->linked_list_node; | 274 | return slab_heap_container->linked_list_node; |
| 276 | } else if constexpr (std::is_same_v<T, KWritableEvent>) { | 275 | } else if constexpr (std::is_same_v<T, Process>) { |
| 277 | return slab_heap_container->writeable_event; | 276 | return slab_heap_container->process; |
| 278 | } else if constexpr (std::is_same_v<T, KClientSession>) { | 277 | } else if constexpr (std::is_same_v<T, KResourceLimit>) { |
| 279 | return slab_heap_container->client_session; | 278 | return slab_heap_container->resource_limit; |
| 280 | } else if constexpr (std::is_same_v<T, KSession>) { | 279 | } else if constexpr (std::is_same_v<T, KSession>) { |
| 281 | return slab_heap_container->session; | 280 | return slab_heap_container->session; |
| 281 | } else if constexpr (std::is_same_v<T, KSharedMemory>) { | ||
| 282 | return slab_heap_container->shared_memory; | ||
| 283 | } else if constexpr (std::is_same_v<T, KThread>) { | ||
| 284 | return slab_heap_container->thread; | ||
| 282 | } else if constexpr (std::is_same_v<T, KTransferMemory>) { | 285 | } else if constexpr (std::is_same_v<T, KTransferMemory>) { |
| 283 | return slab_heap_container->transfer_memory; | 286 | return slab_heap_container->transfer_memory; |
| 287 | } else if constexpr (std::is_same_v<T, KWritableEvent>) { | ||
| 288 | return slab_heap_container->writeable_event; | ||
| 284 | } | 289 | } |
| 285 | } | 290 | } |
| 286 | 291 | ||
| @@ -315,15 +320,16 @@ private: | |||
| 315 | private: | 320 | private: |
| 316 | /// Helper to encapsulate all slab heaps in a single heap allocated container | 321 | /// Helper to encapsulate all slab heaps in a single heap allocated container |
| 317 | struct SlabHeapContainer { | 322 | struct SlabHeapContainer { |
| 318 | KSlabHeap<Process> process; | 323 | KSlabHeap<KClientSession> client_session; |
| 319 | KSlabHeap<KThread> thread; | ||
| 320 | KSlabHeap<KEvent> event; | 324 | KSlabHeap<KEvent> event; |
| 321 | KSlabHeap<KSharedMemory> shared_memory; | ||
| 322 | KSlabHeap<KLinkedListNode> linked_list_node; | 325 | KSlabHeap<KLinkedListNode> linked_list_node; |
| 323 | KSlabHeap<KWritableEvent> writeable_event; | 326 | KSlabHeap<Process> process; |
| 324 | KSlabHeap<KClientSession> client_session; | 327 | KSlabHeap<KResourceLimit> resource_limit; |
| 325 | KSlabHeap<KSession> session; | 328 | KSlabHeap<KSession> session; |
| 329 | KSlabHeap<KSharedMemory> shared_memory; | ||
| 330 | KSlabHeap<KThread> thread; | ||
| 326 | KSlabHeap<KTransferMemory> transfer_memory; | 331 | KSlabHeap<KTransferMemory> transfer_memory; |
| 332 | KSlabHeap<KWritableEvent> writeable_event; | ||
| 327 | }; | 333 | }; |
| 328 | 334 | ||
| 329 | std::unique_ptr<SlabHeapContainer> slab_heap_container; | 335 | std::unique_ptr<SlabHeapContainer> slab_heap_container; |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 678037923..315640bea 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -138,10 +138,13 @@ ResultCode Process::Initialize(Process* process, Core::System& system, std::stri | |||
| 138 | 138 | ||
| 139 | kernel.AppendNewProcess(process); | 139 | kernel.AppendNewProcess(process); |
| 140 | 140 | ||
| 141 | // Open a reference to the resource limit. | ||
| 142 | process->resource_limit->Open(); | ||
| 143 | |||
| 141 | return RESULT_SUCCESS; | 144 | return RESULT_SUCCESS; |
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | std::shared_ptr<KResourceLimit> Process::GetResourceLimit() const { | 147 | KResourceLimit* Process::GetResourceLimit() const { |
| 145 | return resource_limit; | 148 | return resource_limit; |
| 146 | } | 149 | } |
| 147 | 150 | ||
| @@ -166,7 +169,10 @@ u64 Process::GetTotalPhysicalMemoryAvailable() const { | |||
| 166 | const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + | 169 | const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + |
| 167 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + | 170 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + |
| 168 | main_thread_stack_size}; | 171 | main_thread_stack_size}; |
| 169 | ASSERT(capacity == kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application)); | 172 | if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application); |
| 173 | capacity != pool_size) { | ||
| 174 | LOG_WARNING(Kernel, "capacity {} != application pool size {}", capacity, pool_size); | ||
| 175 | } | ||
| 170 | if (capacity < memory_usage_capacity) { | 176 | if (capacity < memory_usage_capacity) { |
| 171 | return capacity; | 177 | return capacity; |
| 172 | } | 178 | } |
| @@ -371,6 +377,16 @@ void Process::PrepareForTermination() { | |||
| 371 | ChangeStatus(ProcessStatus::Exited); | 377 | ChangeStatus(ProcessStatus::Exited); |
| 372 | } | 378 | } |
| 373 | 379 | ||
| 380 | void Process::Finalize() { | ||
| 381 | // Release memory to the resource limit. | ||
| 382 | if (resource_limit != nullptr) { | ||
| 383 | resource_limit->Close(); | ||
| 384 | } | ||
| 385 | |||
| 386 | // Perform inherited finalization. | ||
| 387 | KAutoObjectWithSlabHeapAndContainer<Process, KSynchronizationObject>::Finalize(); | ||
| 388 | } | ||
| 389 | |||
| 374 | /** | 390 | /** |
| 375 | * Attempts to find a TLS page that contains a free slot for | 391 | * Attempts to find a TLS page that contains a free slot for |
| 376 | * use by a thread. | 392 | * use by a thread. |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index df3c7997d..35fe16433 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -171,7 +171,7 @@ public: | |||
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | /// Gets the resource limit descriptor for this process | 173 | /// Gets the resource limit descriptor for this process |
| 174 | std::shared_ptr<KResourceLimit> GetResourceLimit() const; | 174 | KResourceLimit* GetResourceLimit() const; |
| 175 | 175 | ||
| 176 | /// Gets the ideal CPU core ID for this process | 176 | /// Gets the ideal CPU core ID for this process |
| 177 | u8 GetIdealCoreId() const { | 177 | u8 GetIdealCoreId() const { |
| @@ -348,9 +348,7 @@ public: | |||
| 348 | 348 | ||
| 349 | static void PostDestroy([[maybe_unused]] uintptr_t arg) {} | 349 | static void PostDestroy([[maybe_unused]] uintptr_t arg) {} |
| 350 | 350 | ||
| 351 | virtual void Finalize() override { | 351 | virtual void Finalize(); |
| 352 | UNIMPLEMENTED(); | ||
| 353 | } | ||
| 354 | 352 | ||
| 355 | virtual u64 GetId() const override final { | 353 | virtual u64 GetId() const override final { |
| 356 | return GetProcessID(); | 354 | return GetProcessID(); |
| @@ -415,7 +413,7 @@ private: | |||
| 415 | u32 system_resource_size = 0; | 413 | u32 system_resource_size = 0; |
| 416 | 414 | ||
| 417 | /// Resource limit descriptor for this process | 415 | /// Resource limit descriptor for this process |
| 418 | std::shared_ptr<KResourceLimit> resource_limit; | 416 | KResourceLimit* resource_limit{}; |
| 419 | 417 | ||
| 420 | /// The ideal CPU core for this process, threads are scheduled on this core by default. | 418 | /// The ideal CPU core for this process, threads are scheduled on this core by default. |
| 421 | u8 ideal_core = 0; | 419 | u8 ideal_core = 0; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9e8184758..a78bfd1da 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -153,9 +153,9 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_ | |||
| 153 | const auto* const current_process = system.Kernel().CurrentProcess(); | 153 | const auto* const current_process = system.Kernel().CurrentProcess(); |
| 154 | ASSERT(current_process != nullptr); | 154 | ASSERT(current_process != nullptr); |
| 155 | 155 | ||
| 156 | const auto resource_limit_object = | 156 | auto resource_limit_object = |
| 157 | current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); | 157 | current_process->GetHandleTable().GetObject<KResourceLimit>(resource_limit); |
| 158 | if (!resource_limit_object) { | 158 | if (resource_limit_object.IsNull()) { |
| 159 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", | 159 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", |
| 160 | resource_limit); | 160 | resource_limit); |
| 161 | return ResultInvalidHandle; | 161 | return ResultInvalidHandle; |
| @@ -843,12 +843,10 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle | |||
| 843 | return RESULT_SUCCESS; | 843 | return RESULT_SUCCESS; |
| 844 | } | 844 | } |
| 845 | 845 | ||
| 846 | const auto table_result = handle_table.Create(resource_limit.get()); | 846 | Handle handle{}; |
| 847 | if (table_result.Failed()) { | 847 | R_TRY(handle_table.Add(&handle, resource_limit)); |
| 848 | return table_result.Code(); | ||
| 849 | } | ||
| 850 | 848 | ||
| 851 | *result = *table_result; | 849 | *result = handle; |
| 852 | return RESULT_SUCCESS; | 850 | return RESULT_SUCCESS; |
| 853 | } | 851 | } |
| 854 | 852 | ||
| @@ -2093,83 +2091,86 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_ | |||
| 2093 | } | 2091 | } |
| 2094 | 2092 | ||
| 2095 | static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { | 2093 | static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { |
| 2096 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 2097 | LOG_DEBUG(Kernel_SVC, "called"); | 2094 | LOG_DEBUG(Kernel_SVC, "called"); |
| 2098 | 2095 | ||
| 2096 | // Create a new resource limit. | ||
| 2099 | auto& kernel = system.Kernel(); | 2097 | auto& kernel = system.Kernel(); |
| 2100 | auto resource_limit = std::make_shared<KResourceLimit>(kernel, system.CoreTiming()); | 2098 | KResourceLimit* resource_limit = KResourceLimit::Create(kernel); |
| 2099 | R_UNLESS(resource_limit != nullptr, ResultOutOfResource); | ||
| 2101 | 2100 | ||
| 2102 | auto* const current_process = kernel.CurrentProcess(); | 2101 | // Ensure we don't leak a reference to the limit. |
| 2103 | ASSERT(current_process != nullptr); | 2102 | SCOPE_EXIT({ resource_limit->Close(); }); |
| 2104 | 2103 | ||
| 2105 | const auto handle = current_process->GetHandleTable().Create(resource_limit.get()); | 2104 | // Initialize the resource limit. |
| 2106 | if (handle.Failed()) { | 2105 | resource_limit->Initialize(&system.CoreTiming()); |
| 2107 | return handle.Code(); | 2106 | |
| 2108 | } | 2107 | // Register the limit. |
| 2108 | KResourceLimit::Register(kernel, resource_limit); | ||
| 2109 | |||
| 2110 | // Add the limit to the handle table. | ||
| 2111 | R_TRY(kernel.CurrentProcess()->GetHandleTable().Add(out_handle, resource_limit)); | ||
| 2109 | 2112 | ||
| 2110 | *out_handle = *handle; | ||
| 2111 | return RESULT_SUCCESS; | 2113 | return RESULT_SUCCESS; |
| 2112 | } | 2114 | } |
| 2113 | 2115 | ||
| 2114 | static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_value, | 2116 | static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, |
| 2115 | Handle resource_limit, u32 resource_type) { | 2117 | Handle resource_limit_handle, |
| 2116 | LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); | 2118 | LimitableResource which) { |
| 2119 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, | ||
| 2120 | which); | ||
| 2117 | 2121 | ||
| 2118 | const auto limit_value = RetrieveResourceLimitValue(system, resource_limit, resource_type, | 2122 | // Validate the resource. |
| 2119 | ResourceLimitValueType::LimitValue); | 2123 | R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); |
| 2120 | if (limit_value.Failed()) { | 2124 | |
| 2121 | return limit_value.Code(); | 2125 | // Get the resource limit. |
| 2122 | } | 2126 | auto& kernel = system.Kernel(); |
| 2127 | KScopedAutoObject resource_limit = | ||
| 2128 | kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle); | ||
| 2129 | R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); | ||
| 2130 | |||
| 2131 | // Get the limit value. | ||
| 2132 | *out_limit_value = resource_limit->GetLimitValue(which); | ||
| 2123 | 2133 | ||
| 2124 | *out_value = static_cast<u64>(*limit_value); | ||
| 2125 | return RESULT_SUCCESS; | 2134 | return RESULT_SUCCESS; |
| 2126 | } | 2135 | } |
| 2127 | 2136 | ||
| 2128 | static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_value, | 2137 | static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, |
| 2129 | Handle resource_limit, u32 resource_type) { | 2138 | Handle resource_limit_handle, |
| 2130 | LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); | 2139 | LimitableResource which) { |
| 2140 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, | ||
| 2141 | which); | ||
| 2131 | 2142 | ||
| 2132 | const auto current_value = RetrieveResourceLimitValue(system, resource_limit, resource_type, | 2143 | // Validate the resource. |
| 2133 | ResourceLimitValueType::CurrentValue); | 2144 | R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); |
| 2134 | if (current_value.Failed()) { | 2145 | |
| 2135 | return current_value.Code(); | 2146 | // Get the resource limit. |
| 2136 | } | 2147 | auto& kernel = system.Kernel(); |
| 2148 | KScopedAutoObject resource_limit = | ||
| 2149 | kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle); | ||
| 2150 | R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); | ||
| 2151 | |||
| 2152 | // Get the current value. | ||
| 2153 | *out_current_value = resource_limit->GetCurrentValue(which); | ||
| 2137 | 2154 | ||
| 2138 | *out_value = static_cast<u64>(*current_value); | ||
| 2139 | return RESULT_SUCCESS; | 2155 | return RESULT_SUCCESS; |
| 2140 | } | 2156 | } |
| 2141 | 2157 | ||
| 2142 | static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit, | 2158 | static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, |
| 2143 | u32 resource_type, u64 value) { | 2159 | LimitableResource which, u64 limit_value) { |
| 2144 | LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, | 2160 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}", |
| 2145 | resource_type, value); | 2161 | resource_limit_handle, which, limit_value); |
| 2146 | 2162 | ||
| 2147 | const auto type = static_cast<LimitableResource>(resource_type); | 2163 | // Validate the resource. |
| 2148 | if (!IsValidResourceType(type)) { | 2164 | R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); |
| 2149 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); | ||
| 2150 | return ResultInvalidEnumValue; | ||
| 2151 | } | ||
| 2152 | |||
| 2153 | auto* const current_process = system.Kernel().CurrentProcess(); | ||
| 2154 | ASSERT(current_process != nullptr); | ||
| 2155 | 2165 | ||
| 2156 | auto resource_limit_object = | 2166 | // Get the resource limit. |
| 2157 | current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); | 2167 | auto& kernel = system.Kernel(); |
| 2158 | if (!resource_limit_object) { | 2168 | KScopedAutoObject resource_limit = |
| 2159 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", | 2169 | kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle); |
| 2160 | resource_limit); | 2170 | R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); |
| 2161 | return ResultInvalidHandle; | ||
| 2162 | } | ||
| 2163 | 2171 | ||
| 2164 | const auto set_result = resource_limit_object->SetLimitValue(type, static_cast<s64>(value)); | 2172 | // Set the limit value. |
| 2165 | if (set_result.IsError()) { | 2173 | R_TRY(resource_limit->SetLimitValue(which, limit_value)); |
| 2166 | LOG_ERROR(Kernel_SVC, | ||
| 2167 | "Attempted to lower resource limit ({}) for category '{}' below its current " | ||
| 2168 | "value ({})", | ||
| 2169 | resource_limit_object->GetLimitValue(type), resource_type, | ||
| 2170 | resource_limit_object->GetCurrentValue(type)); | ||
| 2171 | return set_result; | ||
| 2172 | } | ||
| 2173 | 2174 | ||
| 2174 | return RESULT_SUCCESS; | 2175 | return RESULT_SUCCESS; |
| 2175 | } | 2176 | } |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 61986bb52..d3df25d0f 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -154,15 +154,28 @@ void SvcWrap64(Core::System& system) { | |||
| 154 | FuncReturn(system, retval); | 154 | FuncReturn(system, retval); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | // Used by GetResourceLimitLimitValue. | ||
| 158 | template <ResultCode func(Core::System&, u64*, Handle, LimitableResource)> | ||
| 159 | void SvcWrap64(Core::System& system) { | ||
| 160 | u64 param_1 = 0; | ||
| 161 | const u32 retval = func(system, ¶m_1, static_cast<Handle>(Param(system, 1)), | ||
| 162 | static_cast<LimitableResource>(Param(system, 2))) | ||
| 163 | .raw; | ||
| 164 | |||
| 165 | system.CurrentArmInterface().SetReg(1, param_1); | ||
| 166 | FuncReturn(system, retval); | ||
| 167 | } | ||
| 168 | |||
| 157 | template <ResultCode func(Core::System&, u32, u64)> | 169 | template <ResultCode func(Core::System&, u32, u64)> |
| 158 | void SvcWrap64(Core::System& system) { | 170 | void SvcWrap64(Core::System& system) { |
| 159 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw); | 171 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw); |
| 160 | } | 172 | } |
| 161 | 173 | ||
| 162 | template <ResultCode func(Core::System&, u32, u32, u64)> | 174 | // Used by SetResourceLimitLimitValue |
| 175 | template <ResultCode func(Core::System&, Handle, LimitableResource, u64)> | ||
| 163 | void SvcWrap64(Core::System& system) { | 176 | void SvcWrap64(Core::System& system) { |
| 164 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), | 177 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), |
| 165 | static_cast<u32>(Param(system, 1)), Param(system, 2)) | 178 | static_cast<LimitableResource>(Param(system, 1)), Param(system, 2)) |
| 166 | .raw); | 179 | .raw); |
| 167 | } | 180 | } |
| 168 | 181 | ||