summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/ipc_helpers.h2
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.cpp3
-rw-r--r--src/core/hle/kernel/k_client_port.cpp2
-rw-r--r--src/core/hle/kernel/k_event.cpp2
-rw-r--r--src/core/hle/kernel/k_memory_block.h12
-rw-r--r--src/core/hle/kernel/k_page_table.cpp14
-rw-r--r--src/core/hle/kernel/k_process.cpp14
-rw-r--r--src/core/hle/kernel/k_resource_limit.cpp11
-rw-r--r--src/core/hle/kernel/k_resource_limit.h11
-rw-r--r--src/core/hle/kernel/k_session.cpp2
-rw-r--r--src/core/hle/kernel/k_shared_memory.cpp6
-rw-r--r--src/core/hle/kernel/k_thread.cpp4
-rw-r--r--src/core/hle/kernel/k_transfer_memory.cpp2
-rw-r--r--src/core/hle/kernel/kernel.cpp18
-rw-r--r--src/core/hle/kernel/service_thread.cpp4
-rw-r--r--src/core/hle/kernel/svc.cpp117
-rw-r--r--src/core/hle/kernel/svc_types.h470
-rw-r--r--src/core/hle/service/kernel_helpers.cpp2
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp4
19 files changed, 563 insertions, 137 deletions
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 3bb111748..a86bec252 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -149,7 +149,7 @@ public:
149 context->AddDomainObject(std::move(iface)); 149 context->AddDomainObject(std::move(iface));
150 } else { 150 } else {
151 kernel.CurrentProcess()->GetResourceLimit()->Reserve( 151 kernel.CurrentProcess()->GetResourceLimit()->Reserve(
152 Kernel::LimitableResource::Sessions, 1); 152 Kernel::LimitableResource::SessionCountMax, 1);
153 153
154 auto* session = Kernel::KSession::Create(kernel); 154 auto* session = Kernel::KSession::Create(kernel);
155 session->Initialize(nullptr, iface->GetServiceName()); 155 session->Initialize(nullptr, iface->GetServiceName());
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index aa2dddcc6..bda098511 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -265,7 +265,8 @@ void KPageBufferSlabHeap::Initialize(Core::System& system) {
265 const size_t slab_size = num_pages * PageSize; 265 const size_t slab_size = num_pages * PageSize;
266 266
267 // Reserve memory from the system resource limit. 267 // Reserve memory from the system resource limit.
268 ASSERT(kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemory, slab_size)); 268 ASSERT(
269 kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemoryMax, slab_size));
269 270
270 // Allocate memory for the slab. 271 // Allocate memory for the slab.
271 constexpr auto AllocateOption = KMemoryManager::EncodeOption( 272 constexpr auto AllocateOption = KMemoryManager::EncodeOption(
diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp
index eaa2e094c..2ec623a58 100644
--- a/src/core/hle/kernel/k_client_port.cpp
+++ b/src/core/hle/kernel/k_client_port.cpp
@@ -61,7 +61,7 @@ bool KClientPort::IsSignaled() const {
61Result KClientPort::CreateSession(KClientSession** out) { 61Result KClientPort::CreateSession(KClientSession** out) {
62 // Reserve a new session from the resource limit. 62 // Reserve a new session from the resource limit.
63 KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(), 63 KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(),
64 LimitableResource::Sessions); 64 LimitableResource::SessionCountMax);
65 R_UNLESS(session_reservation.Succeeded(), ResultLimitReached); 65 R_UNLESS(session_reservation.Succeeded(), ResultLimitReached);
66 66
67 // Update the session counts. 67 // Update the session counts.
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp
index 78ca59463..27f70e5c5 100644
--- a/src/core/hle/kernel/k_event.cpp
+++ b/src/core/hle/kernel/k_event.cpp
@@ -50,7 +50,7 @@ Result KEvent::Clear() {
50void KEvent::PostDestroy(uintptr_t arg) { 50void KEvent::PostDestroy(uintptr_t arg) {
51 // Release the event count resource the owner process holds. 51 // Release the event count resource the owner process holds.
52 KProcess* owner = reinterpret_cast<KProcess*>(arg); 52 KProcess* owner = reinterpret_cast<KProcess*>(arg);
53 owner->GetResourceLimit()->Release(LimitableResource::Events, 1); 53 owner->GetResourceLimit()->Release(LimitableResource::EventCountMax, 1);
54 owner->Close(); 54 owner->Close();
55} 55}
56 56
diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h
index 6f845d675..3b6e7baff 100644
--- a/src/core/hle/kernel/k_memory_block.h
+++ b/src/core/hle/kernel/k_memory_block.h
@@ -216,13 +216,15 @@ struct KMemoryInfo {
216 216
217 constexpr Svc::MemoryInfo GetSvcMemoryInfo() const { 217 constexpr Svc::MemoryInfo GetSvcMemoryInfo() const {
218 return { 218 return {
219 .addr = m_address, 219 .base_address = m_address,
220 .size = m_size, 220 .size = m_size,
221 .state = static_cast<Svc::MemoryState>(m_state & KMemoryState::Mask), 221 .state = static_cast<Svc::MemoryState>(m_state & KMemoryState::Mask),
222 .attr = static_cast<Svc::MemoryAttribute>(m_attribute & KMemoryAttribute::UserMask), 222 .attribute =
223 .perm = static_cast<Svc::MemoryPermission>(m_permission & KMemoryPermission::UserMask), 223 static_cast<Svc::MemoryAttribute>(m_attribute & KMemoryAttribute::UserMask),
224 .ipc_refcount = m_ipc_lock_count, 224 .permission =
225 .device_refcount = m_device_use_count, 225 static_cast<Svc::MemoryPermission>(m_permission & KMemoryPermission::UserMask),
226 .ipc_count = m_ipc_lock_count,
227 .device_count = m_device_use_count,
226 .padding = {}, 228 .padding = {},
227 }; 229 };
228 } 230 }
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index fab55a057..5387bf5fe 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -920,8 +920,8 @@ Result KPageTable::SetupForIpcServer(VAddr* out_addr, size_t size, VAddr src_add
920 920
921 // Reserve space for any partial pages we allocate. 921 // Reserve space for any partial pages we allocate.
922 const size_t unmapped_size = aligned_src_size - mapping_src_size; 922 const size_t unmapped_size = aligned_src_size - mapping_src_size;
923 KScopedResourceReservation memory_reservation(m_resource_limit, 923 KScopedResourceReservation memory_reservation(
924 LimitableResource::PhysicalMemory, unmapped_size); 924 m_resource_limit, LimitableResource::PhysicalMemoryMax, unmapped_size);
925 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); 925 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
926 926
927 // Ensure that we manage page references correctly. 927 // Ensure that we manage page references correctly.
@@ -1227,7 +1227,7 @@ Result KPageTable::CleanupForIpcServer(VAddr address, size_t size, KMemoryState
1227 const VAddr mapping_start = Common::AlignUp((address), PageSize); 1227 const VAddr mapping_start = Common::AlignUp((address), PageSize);
1228 const VAddr mapping_end = Common::AlignDown((address) + size, PageSize); 1228 const VAddr mapping_end = Common::AlignDown((address) + size, PageSize);
1229 const size_t mapping_size = (mapping_start < mapping_end) ? mapping_end - mapping_start : 0; 1229 const size_t mapping_size = (mapping_start < mapping_end) ? mapping_end - mapping_start : 0;
1230 m_resource_limit->Release(LimitableResource::PhysicalMemory, aligned_size - mapping_size); 1230 m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, aligned_size - mapping_size);
1231 1231
1232 R_SUCCEED(); 1232 R_SUCCEED();
1233} 1233}
@@ -1568,7 +1568,7 @@ Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
1568 { 1568 {
1569 // Reserve the memory from the process resource limit. 1569 // Reserve the memory from the process resource limit.
1570 KScopedResourceReservation memory_reservation( 1570 KScopedResourceReservation memory_reservation(
1571 m_resource_limit, LimitableResource::PhysicalMemory, size - mapped_size); 1571 m_resource_limit, LimitableResource::PhysicalMemoryMax, size - mapped_size);
1572 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); 1572 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
1573 1573
1574 // Allocate pages for the new memory. 1574 // Allocate pages for the new memory.
@@ -1908,7 +1908,7 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
1908 1908
1909 // Release the memory resource. 1909 // Release the memory resource.
1910 m_mapped_physical_memory_size -= mapped_size; 1910 m_mapped_physical_memory_size -= mapped_size;
1911 m_resource_limit->Release(LimitableResource::PhysicalMemory, mapped_size); 1911 m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, mapped_size);
1912 1912
1913 // Update memory blocks. 1913 // Update memory blocks.
1914 m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize, 1914 m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize,
@@ -2492,7 +2492,7 @@ Result KPageTable::SetHeapSize(VAddr* out, size_t size) {
2492 OperationType::Unmap)); 2492 OperationType::Unmap));
2493 2493
2494 // Release the memory from the resource limit. 2494 // Release the memory from the resource limit.
2495 m_resource_limit->Release(LimitableResource::PhysicalMemory, num_pages * PageSize); 2495 m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, num_pages * PageSize);
2496 2496
2497 // Apply the memory block update. 2497 // Apply the memory block update.
2498 m_memory_block_manager.Update(std::addressof(allocator), m_heap_region_start + size, 2498 m_memory_block_manager.Update(std::addressof(allocator), m_heap_region_start + size,
@@ -2522,7 +2522,7 @@ Result KPageTable::SetHeapSize(VAddr* out, size_t size) {
2522 2522
2523 // Reserve memory for the heap extension. 2523 // Reserve memory for the heap extension.
2524 KScopedResourceReservation memory_reservation( 2524 KScopedResourceReservation memory_reservation(
2525 m_resource_limit, LimitableResource::PhysicalMemory, allocation_size); 2525 m_resource_limit, LimitableResource::PhysicalMemoryMax, allocation_size);
2526 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); 2526 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
2527 2527
2528 // Allocate pages for the heap extension. 2528 // Allocate pages for the heap extension.
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 4ddeea73b..55a9c5fae 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -38,7 +38,7 @@ namespace {
38 */ 38 */
39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, VAddr stack_top) { 39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, VAddr stack_top) {
40 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); 40 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart();
41 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); 41 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
42 42
43 KThread* thread = KThread::Create(system.Kernel()); 43 KThread* thread = KThread::Create(system.Kernel());
44 SCOPE_EXIT({ thread->Close(); }); 44 SCOPE_EXIT({ thread->Close(); });
@@ -124,7 +124,7 @@ void KProcess::DecrementRunningThreadCount() {
124} 124}
125 125
126u64 KProcess::GetTotalPhysicalMemoryAvailable() { 126u64 KProcess::GetTotalPhysicalMemoryAvailable() {
127 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + 127 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemoryMax) +
128 page_table.GetNormalMemorySize() + GetSystemResourceSize() + image_size + 128 page_table.GetNormalMemorySize() + GetSystemResourceSize() + image_size +
129 main_thread_stack_size}; 129 main_thread_stack_size};
130 if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application); 130 if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application);
@@ -349,8 +349,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
349 // We currently do not support process-specific system resource 349 // We currently do not support process-specific system resource
350 UNIMPLEMENTED_IF(system_resource_size != 0); 350 UNIMPLEMENTED_IF(system_resource_size != 0);
351 351
352 KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, 352 KScopedResourceReservation memory_reservation(
353 code_size + system_resource_size); 353 resource_limit, LimitableResource::PhysicalMemoryMax, code_size + system_resource_size);
354 if (!memory_reservation.Succeeded()) { 354 if (!memory_reservation.Succeeded()) {
355 LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes", 355 LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes",
356 code_size + system_resource_size); 356 code_size + system_resource_size);
@@ -406,8 +406,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
406 406
407void KProcess::Run(s32 main_thread_priority, u64 stack_size) { 407void KProcess::Run(s32 main_thread_priority, u64 stack_size) {
408 AllocateMainThreadStack(stack_size); 408 AllocateMainThreadStack(stack_size);
409 resource_limit->Reserve(LimitableResource::Threads, 1); 409 resource_limit->Reserve(LimitableResource::ThreadCountMax, 1);
410 resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); 410 resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, main_thread_stack_size);
411 411
412 const std::size_t heap_capacity{memory_usage_capacity - (main_thread_stack_size + image_size)}; 412 const std::size_t heap_capacity{memory_usage_capacity - (main_thread_stack_size + image_size)};
413 ASSERT(!page_table.SetMaxHeapSize(heap_capacity).IsError()); 413 ASSERT(!page_table.SetMaxHeapSize(heap_capacity).IsError());
@@ -442,7 +442,7 @@ void KProcess::PrepareForTermination() {
442 plr_address = 0; 442 plr_address = 0;
443 443
444 if (resource_limit) { 444 if (resource_limit) {
445 resource_limit->Release(LimitableResource::PhysicalMemory, 445 resource_limit->Release(LimitableResource::PhysicalMemoryMax,
446 main_thread_stack_size + image_size); 446 main_thread_stack_size + image_size);
447 } 447 }
448 448
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index 010dcf99e..b9d22b414 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -159,12 +159,13 @@ KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical
159 // TODO(bunnei): These values are the system defaults, the limits for service processes are 159 // TODO(bunnei): These values are the system defaults, the limits for service processes are
160 // lower. These should use the correct limit values. 160 // lower. These should use the correct limit values.
161 161
162 ASSERT(resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, physical_memory_size) 162 ASSERT(resource_limit->SetLimitValue(LimitableResource::PhysicalMemoryMax, physical_memory_size)
163 .IsSuccess()); 163 .IsSuccess());
164 ASSERT(resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); 164 ASSERT(resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 800).IsSuccess());
165 ASSERT(resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess()); 165 ASSERT(resource_limit->SetLimitValue(LimitableResource::EventCountMax, 900).IsSuccess());
166 ASSERT(resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200).IsSuccess()); 166 ASSERT(
167 ASSERT(resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess()); 167 resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200).IsSuccess());
168 ASSERT(resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 1133).IsSuccess());
168 169
169 return resource_limit; 170 return resource_limit;
170} 171}
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index 65c98c979..2573d1b7c 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -16,15 +16,8 @@ class CoreTiming;
16 16
17namespace Kernel { 17namespace Kernel {
18class KernelCore; 18class KernelCore;
19enum class LimitableResource : u32 { 19
20 PhysicalMemory = 0, 20using LimitableResource = Svc::LimitableResource;
21 Threads = 1,
22 Events = 2,
23 TransferMemory = 3,
24 Sessions = 4,
25
26 Count,
27};
28 21
29constexpr bool IsValidResourceType(LimitableResource type) { 22constexpr bool IsValidResourceType(LimitableResource type) {
30 return type < LimitableResource::Count; 23 return type < LimitableResource::Count;
diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp
index 7a6534ac3..b6f6fe9d9 100644
--- a/src/core/hle/kernel/k_session.cpp
+++ b/src/core/hle/kernel/k_session.cpp
@@ -76,7 +76,7 @@ void KSession::OnClientClosed() {
76void KSession::PostDestroy(uintptr_t arg) { 76void KSession::PostDestroy(uintptr_t arg) {
77 // Release the session count resource the owner process holds. 77 // Release the session count resource the owner process holds.
78 KProcess* owner = reinterpret_cast<KProcess*>(arg); 78 KProcess* owner = reinterpret_cast<KProcess*>(arg);
79 owner->GetResourceLimit()->Release(LimitableResource::Sessions, 1); 79 owner->GetResourceLimit()->Release(LimitableResource::SessionCountMax, 1);
80 owner->Close(); 80 owner->Close();
81} 81}
82 82
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index a039cc591..10cd4c43d 100644
--- a/src/core/hle/kernel/k_shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -14,7 +14,7 @@ namespace Kernel {
14KSharedMemory::KSharedMemory(KernelCore& kernel_) : KAutoObjectWithSlabHeapAndContainer{kernel_} {} 14KSharedMemory::KSharedMemory(KernelCore& kernel_) : KAutoObjectWithSlabHeapAndContainer{kernel_} {}
15 15
16KSharedMemory::~KSharedMemory() { 16KSharedMemory::~KSharedMemory() {
17 kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size); 17 kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, size);
18} 18}
19 19
20Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, 20Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_,
@@ -35,7 +35,7 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
35 KResourceLimit* reslimit = kernel.GetSystemResourceLimit(); 35 KResourceLimit* reslimit = kernel.GetSystemResourceLimit();
36 36
37 // Reserve memory for ourselves. 37 // Reserve memory for ourselves.
38 KScopedResourceReservation memory_reservation(reslimit, LimitableResource::PhysicalMemory, 38 KScopedResourceReservation memory_reservation(reslimit, LimitableResource::PhysicalMemoryMax,
39 size_); 39 size_);
40 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); 40 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
41 41
@@ -57,7 +57,7 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
57 57
58void KSharedMemory::Finalize() { 58void KSharedMemory::Finalize() {
59 // Release the memory reservation. 59 // Release the memory reservation.
60 resource_limit->Release(LimitableResource::PhysicalMemory, size); 60 resource_limit->Release(LimitableResource::PhysicalMemoryMax, size);
61 resource_limit->Close(); 61 resource_limit->Close();
62 62
63 // Perform inherited finalization. 63 // Perform inherited finalization.
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 78076a346..21207fe99 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -303,7 +303,7 @@ void KThread::PostDestroy(uintptr_t arg) {
303 const bool resource_limit_release_hint = (arg & 1); 303 const bool resource_limit_release_hint = (arg & 1);
304 const s64 hint_value = (resource_limit_release_hint ? 0 : 1); 304 const s64 hint_value = (resource_limit_release_hint ? 0 : 1);
305 if (owner != nullptr) { 305 if (owner != nullptr) {
306 owner->GetResourceLimit()->Release(LimitableResource::Threads, 1, hint_value); 306 owner->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1, hint_value);
307 owner->Close(); 307 owner->Close();
308 } 308 }
309} 309}
@@ -1054,7 +1054,7 @@ void KThread::Exit() {
1054 1054
1055 // Release the thread resource hint, running thread count from parent. 1055 // Release the thread resource hint, running thread count from parent.
1056 if (parent != nullptr) { 1056 if (parent != nullptr) {
1057 parent->GetResourceLimit()->Release(Kernel::LimitableResource::Threads, 0, 1); 1057 parent->GetResourceLimit()->Release(Kernel::LimitableResource::ThreadCountMax, 0, 1);
1058 resource_limit_release_hint = true; 1058 resource_limit_release_hint = true;
1059 parent->DecrementRunningThreadCount(); 1059 parent->DecrementRunningThreadCount();
1060 } 1060 }
diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp
index b0320eb73..9f34c2d46 100644
--- a/src/core/hle/kernel/k_transfer_memory.cpp
+++ b/src/core/hle/kernel/k_transfer_memory.cpp
@@ -37,7 +37,7 @@ void KTransferMemory::Finalize() {
37 37
38void KTransferMemory::PostDestroy(uintptr_t arg) { 38void KTransferMemory::PostDestroy(uintptr_t arg) {
39 KProcess* owner = reinterpret_cast<KProcess*>(arg); 39 KProcess* owner = reinterpret_cast<KProcess*>(arg);
40 owner->GetResourceLimit()->Release(LimitableResource::TransferMemory, 1); 40 owner->GetResourceLimit()->Release(LimitableResource::TransferMemoryCountMax, 1);
41 owner->Close(); 41 owner->Close();
42} 42}
43 43
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7f800d860..b77723503 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -229,18 +229,22 @@ struct KernelCore::Impl {
229 const auto kernel_size{sizes.second}; 229 const auto kernel_size{sizes.second};
230 230
231 // If setting the default system values fails, then something seriously wrong has occurred. 231 // If setting the default system values fails, then something seriously wrong has occurred.
232 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size) 232 ASSERT(
233 system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemoryMax, total_size)
234 .IsSuccess());
235 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 800)
233 .IsSuccess()); 236 .IsSuccess());
234 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); 237 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::EventCountMax, 900)
235 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
236 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
237 .IsSuccess()); 238 .IsSuccess());
238 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess()); 239 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200)
239 system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size); 240 .IsSuccess());
241 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 1133)
242 .IsSuccess());
243 system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, kernel_size);
240 244
241 // Reserve secure applet memory, introduced in firmware 5.0.0 245 // Reserve secure applet memory, introduced in firmware 5.0.0
242 constexpr u64 secure_applet_memory_size{4_MiB}; 246 constexpr u64 secure_applet_memory_size{4_MiB};
243 ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 247 ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax,
244 secure_applet_memory_size)); 248 secure_applet_memory_size));
245 } 249 }
246 250
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp
index 7a85be77f..f5c2ab23f 100644
--- a/src/core/hle/kernel/service_thread.cpp
+++ b/src/core/hle/kernel/service_thread.cpp
@@ -193,7 +193,7 @@ ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name)
193 KProcess::ProcessType::KernelInternal, kernel.GetSystemResourceLimit()); 193 KProcess::ProcessType::KernelInternal, kernel.GetSystemResourceLimit());
194 194
195 // Reserve a new event from the process resource limit 195 // Reserve a new event from the process resource limit
196 KScopedResourceReservation event_reservation(m_process, LimitableResource::Events); 196 KScopedResourceReservation event_reservation(m_process, LimitableResource::EventCountMax);
197 ASSERT(event_reservation.Succeeded()); 197 ASSERT(event_reservation.Succeeded());
198 198
199 // Initialize event. 199 // Initialize event.
@@ -204,7 +204,7 @@ ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name)
204 event_reservation.Commit(); 204 event_reservation.Commit();
205 205
206 // Reserve a new thread from the process resource limit 206 // Reserve a new thread from the process resource limit
207 KScopedResourceReservation thread_reservation(m_process, LimitableResource::Threads); 207 KScopedResourceReservation thread_reservation(m_process, LimitableResource::ThreadCountMax);
208 ASSERT(thread_reservation.Succeeded()); 208 ASSERT(thread_reservation.Succeeded());
209 209
210 // Initialize thread. 210 // Initialize thread.
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index ecac97a52..9962ad171 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -267,7 +267,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
267 267
268 // Reserve a new session from the process resource limit. 268 // Reserve a new session from the process resource limit.
269 // FIXME: LimitableResource_SessionCountMax 269 // FIXME: LimitableResource_SessionCountMax
270 KScopedResourceReservation session_reservation(&process, LimitableResource::Sessions); 270 KScopedResourceReservation session_reservation(&process, LimitableResource::SessionCountMax);
271 if (session_reservation.Succeeded()) { 271 if (session_reservation.Succeeded()) {
272 session = T::Create(system.Kernel()); 272 session = T::Create(system.Kernel());
273 } else { 273 } else {
@@ -298,7 +298,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
298 298
299 // We successfully allocated a session, so add the object we allocated to the resource 299 // We successfully allocated a session, so add the object we allocated to the resource
300 // limit. 300 // limit.
301 // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::Sessions, 1); 301 // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::SessionCountMax, 1);
302 } 302 }
303 303
304 // Check that we successfully created a session. 304 // Check that we successfully created a session.
@@ -656,27 +656,12 @@ static Result ArbitrateUnlock32(Core::System& system, u32 address) {
656 return ArbitrateUnlock(system, address); 656 return ArbitrateUnlock(system, address);
657} 657}
658 658
659enum class BreakType : u32 {
660 Panic = 0,
661 AssertionFailed = 1,
662 PreNROLoad = 3,
663 PostNROLoad = 4,
664 PreNROUnload = 5,
665 PostNROUnload = 6,
666 CppException = 7,
667};
668
669struct BreakReason {
670 union {
671 u32 raw;
672 BitField<0, 30, BreakType> break_type;
673 BitField<31, 1, u32> signal_debugger;
674 };
675};
676
677/// Break program execution 659/// Break program execution
678static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { 660static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
679 BreakReason break_reason{reason}; 661 BreakReason break_reason =
662 static_cast<BreakReason>(reason & ~static_cast<u32>(BreakReason::NotificationOnlyFlag));
663 bool notification_only = (reason & static_cast<u32>(BreakReason::NotificationOnlyFlag)) != 0;
664
680 bool has_dumped_buffer{}; 665 bool has_dumped_buffer{};
681 std::vector<u8> debug_buffer; 666 std::vector<u8> debug_buffer;
682 667
@@ -705,57 +690,56 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
705 } 690 }
706 has_dumped_buffer = true; 691 has_dumped_buffer = true;
707 }; 692 };
708 switch (break_reason.break_type) { 693 switch (break_reason) {
709 case BreakType::Panic: 694 case BreakReason::Panic:
710 LOG_CRITICAL(Debug_Emulated, "Signalling debugger, PANIC! info1=0x{:016X}, info2=0x{:016X}", 695 LOG_CRITICAL(Debug_Emulated, "Userspace PANIC! info1=0x{:016X}, info2=0x{:016X}", info1,
711 info1, info2); 696 info2);
712 handle_debug_buffer(info1, info2); 697 handle_debug_buffer(info1, info2);
713 break; 698 break;
714 case BreakType::AssertionFailed: 699 case BreakReason::Assert:
715 LOG_CRITICAL(Debug_Emulated, 700 LOG_CRITICAL(Debug_Emulated, "Userspace Assertion failed! info1=0x{:016X}, info2=0x{:016X}",
716 "Signalling debugger, Assertion failed! info1=0x{:016X}, info2=0x{:016X}",
717 info1, info2); 701 info1, info2);
718 handle_debug_buffer(info1, info2); 702 handle_debug_buffer(info1, info2);
719 break; 703 break;
720 case BreakType::PreNROLoad: 704 case BreakReason::User:
721 LOG_WARNING( 705 LOG_WARNING(Debug_Emulated, "Userspace Break! 0x{:016X} with size 0x{:016X}", info1, info2);
722 Debug_Emulated, 706 handle_debug_buffer(info1, info2);
723 "Signalling debugger, Attempting to load an NRO at 0x{:016X} with size 0x{:016X}",
724 info1, info2);
725 break; 707 break;
726 case BreakType::PostNROLoad: 708 case BreakReason::PreLoadDll:
727 LOG_WARNING(Debug_Emulated, 709 LOG_INFO(Debug_Emulated,
728 "Signalling debugger, Loaded an NRO at 0x{:016X} with size 0x{:016X}", info1, 710 "Userspace Attempting to load an NRO at 0x{:016X} with size 0x{:016X}", info1,
729 info2); 711 info2);
730 break; 712 break;
731 case BreakType::PreNROUnload: 713 case BreakReason::PostLoadDll:
732 LOG_WARNING( 714 LOG_INFO(Debug_Emulated, "Userspace Loaded an NRO at 0x{:016X} with size 0x{:016X}", info1,
733 Debug_Emulated, 715 info2);
734 "Signalling debugger, Attempting to unload an NRO at 0x{:016X} with size 0x{:016X}",
735 info1, info2);
736 break; 716 break;
737 case BreakType::PostNROUnload: 717 case BreakReason::PreUnloadDll:
738 LOG_WARNING(Debug_Emulated, 718 LOG_INFO(Debug_Emulated,
739 "Signalling debugger, Unloaded an NRO at 0x{:016X} with size 0x{:016X}", info1, 719 "Userspace Attempting to unload an NRO at 0x{:016X} with size 0x{:016X}", info1,
740 info2); 720 info2);
741 break; 721 break;
742 case BreakType::CppException: 722 case BreakReason::PostUnloadDll:
723 LOG_INFO(Debug_Emulated, "Userspace Unloaded an NRO at 0x{:016X} with size 0x{:016X}",
724 info1, info2);
725 break;
726 case BreakReason::CppException:
743 LOG_CRITICAL(Debug_Emulated, "Signalling debugger. Uncaught C++ exception encountered."); 727 LOG_CRITICAL(Debug_Emulated, "Signalling debugger. Uncaught C++ exception encountered.");
744 break; 728 break;
745 default: 729 default:
746 LOG_WARNING( 730 LOG_WARNING(
747 Debug_Emulated, 731 Debug_Emulated,
748 "Signalling debugger, Unknown break reason {}, info1=0x{:016X}, info2=0x{:016X}", 732 "Signalling debugger, Unknown break reason {:#X}, info1=0x{:016X}, info2=0x{:016X}",
749 static_cast<u32>(break_reason.break_type.Value()), info1, info2); 733 reason, info1, info2);
750 handle_debug_buffer(info1, info2); 734 handle_debug_buffer(info1, info2);
751 break; 735 break;
752 } 736 }
753 737
754 system.GetReporter().SaveSvcBreakReport( 738 system.GetReporter().SaveSvcBreakReport(reason, notification_only, info1, info2,
755 static_cast<u32>(break_reason.break_type.Value()), break_reason.signal_debugger.As<bool>(), 739 has_dumped_buffer ? std::make_optional(debug_buffer)
756 info1, info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt); 740 : std::nullopt);
757 741
758 if (!break_reason.signal_debugger) { 742 if (!notification_only) {
759 LOG_CRITICAL( 743 LOG_CRITICAL(
760 Debug_Emulated, 744 Debug_Emulated,
761 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}", 745 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
@@ -1716,13 +1700,13 @@ static Result QueryProcessMemory(Core::System& system, VAddr memory_info_address
1716 auto& memory{system.Memory()}; 1700 auto& memory{system.Memory()};
1717 const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; 1701 const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()};
1718 1702
1719 memory.Write64(memory_info_address + 0x00, memory_info.addr); 1703 memory.Write64(memory_info_address + 0x00, memory_info.base_address);
1720 memory.Write64(memory_info_address + 0x08, memory_info.size); 1704 memory.Write64(memory_info_address + 0x08, memory_info.size);
1721 memory.Write32(memory_info_address + 0x10, static_cast<u32>(memory_info.state) & 0xff); 1705 memory.Write32(memory_info_address + 0x10, static_cast<u32>(memory_info.state) & 0xff);
1722 memory.Write32(memory_info_address + 0x14, static_cast<u32>(memory_info.attr)); 1706 memory.Write32(memory_info_address + 0x14, static_cast<u32>(memory_info.attribute));
1723 memory.Write32(memory_info_address + 0x18, static_cast<u32>(memory_info.perm)); 1707 memory.Write32(memory_info_address + 0x18, static_cast<u32>(memory_info.permission));
1724 memory.Write32(memory_info_address + 0x1c, memory_info.ipc_refcount); 1708 memory.Write32(memory_info_address + 0x1c, memory_info.ipc_count);
1725 memory.Write32(memory_info_address + 0x20, memory_info.device_refcount); 1709 memory.Write32(memory_info_address + 0x20, memory_info.device_count);
1726 memory.Write32(memory_info_address + 0x24, 0); 1710 memory.Write32(memory_info_address + 0x24, 0);
1727 1711
1728 // Page info appears to be currently unused by the kernel and is always set to zero. 1712 // Page info appears to be currently unused by the kernel and is always set to zero.
@@ -1943,7 +1927,7 @@ static Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry
1943 1927
1944 // Reserve a new thread from the process resource limit (waiting up to 100ms). 1928 // Reserve a new thread from the process resource limit (waiting up to 100ms).
1945 KScopedResourceReservation thread_reservation( 1929 KScopedResourceReservation thread_reservation(
1946 kernel.CurrentProcess(), LimitableResource::Threads, 1, 1930 kernel.CurrentProcess(), LimitableResource::ThreadCountMax, 1,
1947 system.CoreTiming().GetGlobalTimeNs().count() + 100000000); 1931 system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
1948 if (!thread_reservation.Succeeded()) { 1932 if (!thread_reservation.Succeeded()) {
1949 LOG_ERROR(Kernel_SVC, "Could not reserve a new thread"); 1933 LOG_ERROR(Kernel_SVC, "Could not reserve a new thread");
@@ -2344,7 +2328,7 @@ static Result CreateTransferMemory(Core::System& system, Handle* out, VAddr addr
2344 2328
2345 // Reserve a new transfer memory from the process resource limit. 2329 // Reserve a new transfer memory from the process resource limit.
2346 KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(), 2330 KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(),
2347 LimitableResource::TransferMemory); 2331 LimitableResource::TransferMemoryCountMax);
2348 R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached); 2332 R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached);
2349 2333
2350 // Create the transfer memory. 2334 // Create the transfer memory.
@@ -2496,7 +2480,7 @@ static Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_r
2496 2480
2497 // Reserve a new event from the process resource limit 2481 // Reserve a new event from the process resource limit
2498 KScopedResourceReservation event_reservation(kernel.CurrentProcess(), 2482 KScopedResourceReservation event_reservation(kernel.CurrentProcess(),
2499 LimitableResource::Events); 2483 LimitableResource::EventCountMax);
2500 R_UNLESS(event_reservation.Succeeded(), ResultLimitReached); 2484 R_UNLESS(event_reservation.Succeeded(), ResultLimitReached);
2501 2485
2502 // Create a new event. 2486 // Create a new event.
@@ -2539,11 +2523,6 @@ static Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out
2539static Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { 2523static Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
2540 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); 2524 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type);
2541 2525
2542 // This function currently only allows retrieving a process' status.
2543 enum class InfoType {
2544 Status,
2545 };
2546
2547 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 2526 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
2548 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); 2527 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
2549 if (process.IsNull()) { 2528 if (process.IsNull()) {
@@ -2552,9 +2531,9 @@ static Result GetProcessInfo(Core::System& system, u64* out, Handle process_hand
2552 return ResultInvalidHandle; 2531 return ResultInvalidHandle;
2553 } 2532 }
2554 2533
2555 const auto info_type = static_cast<InfoType>(type); 2534 const auto info_type = static_cast<ProcessInfoType>(type);
2556 if (info_type != InfoType::Status) { 2535 if (info_type != ProcessInfoType::ProcessState) {
2557 LOG_ERROR(Kernel_SVC, "Expected info_type to be Status but got {} instead", type); 2536 LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead", type);
2558 return ResultInvalidEnumValue; 2537 return ResultInvalidEnumValue;
2559 } 2538 }
2560 2539
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index 9b0305552..33eebcef6 100644
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -8,6 +8,8 @@
8 8
9namespace Kernel::Svc { 9namespace Kernel::Svc {
10 10
11using Handle = u32;
12
11enum class MemoryState : u32 { 13enum class MemoryState : u32 {
12 Free = 0x00, 14 Free = 0x00,
13 Io = 0x01, 15 Io = 0x01,
@@ -55,17 +57,6 @@ enum class MemoryPermission : u32 {
55}; 57};
56DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission); 58DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission);
57 59
58struct MemoryInfo {
59 u64 addr{};
60 u64 size{};
61 MemoryState state{};
62 MemoryAttribute attr{};
63 MemoryPermission perm{};
64 u32 ipc_refcount{};
65 u32 device_refcount{};
66 u32 padding{};
67};
68
69enum class SignalType : u32 { 60enum class SignalType : u32 {
70 Signal = 0, 61 Signal = 0,
71 SignalAndIncrementIfEqual = 1, 62 SignalAndIncrementIfEqual = 1,
@@ -124,7 +115,57 @@ enum class ProcessExitReason : u32 {
124 115
125constexpr inline size_t ThreadLocalRegionSize = 0x200; 116constexpr inline size_t ThreadLocalRegionSize = 0x200;
126 117
127// Debug types. 118struct PageInfo {
119 u32 flags;
120};
121
122// Info Types.
123enum class InfoType : u32 {
124 CoreMask = 0,
125 PriorityMask = 1,
126 AliasRegionAddress = 2,
127 AliasRegionSize = 3,
128 HeapRegionAddress = 4,
129 HeapRegionSize = 5,
130 TotalMemorySize = 6,
131 UsedMemorySize = 7,
132 DebuggerAttached = 8,
133 ResourceLimit = 9,
134 IdleTickCount = 10,
135 RandomEntropy = 11,
136 AslrRegionAddress = 12,
137 AslrRegionSize = 13,
138 StackRegionAddress = 14,
139 StackRegionSize = 15,
140 SystemResourceSizeTotal = 16,
141 SystemResourceSizeUsed = 17,
142 ProgramId = 18,
143 InitialProcessIdRange = 19,
144 UserExceptionContextAddress = 20,
145 TotalNonSystemMemorySize = 21,
146 UsedNonSystemMemorySize = 22,
147 IsApplication = 23,
148 FreeThreadCount = 24,
149 ThreadTickCount = 25,
150 IsSvcPermitted = 26,
151
152 MesosphereMeta = 65000,
153 MesosphereCurrentProcess = 65001,
154};
155
156enum class BreakReason : u32 {
157 Panic = 0,
158 Assert = 1,
159 User = 2,
160 PreLoadDll = 3,
161 PostLoadDll = 4,
162 PreUnloadDll = 5,
163 PostUnloadDll = 6,
164 CppException = 7,
165
166 NotificationOnlyFlag = 0x80000000,
167};
168
128enum class DebugEvent : u32 { 169enum class DebugEvent : u32 {
129 CreateProcess = 0, 170 CreateProcess = 0,
130 CreateThread = 1, 171 CreateThread = 1,
@@ -133,6 +174,14 @@ enum class DebugEvent : u32 {
133 Exception = 4, 174 Exception = 4,
134}; 175};
135 176
177enum class DebugThreadParam : u32 {
178 Priority = 0,
179 State = 1,
180 IdealCore = 2,
181 CurrentCore = 3,
182 AffinityMask = 4,
183};
184
136enum class DebugException : u32 { 185enum class DebugException : u32 {
137 UndefinedInstruction = 0, 186 UndefinedInstruction = 0,
138 InstructionAbort = 1, 187 InstructionAbort = 1,
@@ -146,4 +195,401 @@ enum class DebugException : u32 {
146 MemorySystemError = 9, 195 MemorySystemError = 9,
147}; 196};
148 197
198enum class DebugEventFlag : u32 {
199 Stopped = (1u << 0),
200};
201
202enum class BreakPointType : u32 {
203 HardwareInstruction = 0,
204 HardwareData = 1,
205};
206
207enum class HardwareBreakPointRegisterName : u32 {
208 I0 = 0,
209 I1 = 1,
210 I2 = 2,
211 I3 = 3,
212 I4 = 4,
213 I5 = 5,
214 I6 = 6,
215 I7 = 7,
216 I8 = 8,
217 I9 = 9,
218 I10 = 10,
219 I11 = 11,
220 I12 = 12,
221 I13 = 13,
222 I14 = 14,
223 I15 = 15,
224 D0 = 16,
225 D1 = 17,
226 D2 = 18,
227 D3 = 19,
228 D4 = 20,
229 D5 = 21,
230 D6 = 22,
231 D7 = 23,
232 D8 = 24,
233 D9 = 25,
234 D10 = 26,
235 D11 = 27,
236 D12 = 28,
237 D13 = 29,
238 D14 = 30,
239 D15 = 31,
240};
241
242namespace lp64 {
243struct LastThreadContext {
244 u64 fp;
245 u64 sp;
246 u64 lr;
247 u64 pc;
248};
249
250struct PhysicalMemoryInfo {
251 PAddr physical_address;
252 u64 virtual_address;
253 u64 size;
254};
255
256struct DebugInfoCreateProcess {
257 u64 program_id;
258 u64 process_id;
259 std::array<char, 0xC> name;
260 u32 flags;
261 u64 user_exception_context_address; // 5.0.0+
262};
263
264struct DebugInfoCreateThread {
265 u64 thread_id;
266 u64 tls_address;
267 // Removed in 11.0.0 u64 entrypoint;
268};
269
270struct DebugInfoExitProcess {
271 ProcessExitReason reason;
272};
273
274struct DebugInfoExitThread {
275 ThreadExitReason reason;
276};
277
278struct DebugInfoUndefinedInstructionException {
279 u32 insn;
280};
281
282struct DebugInfoDataAbortException {
283 u64 address;
284};
285
286struct DebugInfoAlignmentFaultException {
287 u64 address;
288};
289
290struct DebugInfoBreakPointException {
291 BreakPointType type;
292 u64 address;
293};
294
295struct DebugInfoUserBreakException {
296 BreakReason break_reason;
297 u64 address;
298 u64 size;
299};
300
301struct DebugInfoDebuggerBreakException {
302 std::array<u64, 4> active_thread_ids;
303};
304
305struct DebugInfoUndefinedSystemCallException {
306 u32 id;
307};
308
309union DebugInfoSpecificException {
310 DebugInfoUndefinedInstructionException undefined_instruction;
311 DebugInfoDataAbortException data_abort;
312 DebugInfoAlignmentFaultException alignment_fault;
313 DebugInfoBreakPointException break_point;
314 DebugInfoUserBreakException user_break;
315 DebugInfoDebuggerBreakException debugger_break;
316 DebugInfoUndefinedSystemCallException undefined_system_call;
317 u64 raw;
318};
319
320struct DebugInfoException {
321 DebugException type;
322 u64 address;
323 DebugInfoSpecificException specific;
324};
325
326union DebugInfo {
327 DebugInfoCreateProcess create_process;
328 DebugInfoCreateThread create_thread;
329 DebugInfoExitProcess exit_process;
330 DebugInfoExitThread exit_thread;
331 DebugInfoException exception;
332};
333
334struct DebugEventInfo {
335 DebugEvent type;
336 u32 flags;
337 u64 thread_id;
338 DebugInfo info;
339};
340static_assert(sizeof(DebugEventInfo) >= 0x40);
341
342struct SecureMonitorArguments {
343 std::array<u64, 8> r;
344};
345static_assert(sizeof(SecureMonitorArguments) == 0x40);
346} // namespace lp64
347
348namespace ilp32 {
349struct LastThreadContext {
350 u32 fp;
351 u32 sp;
352 u32 lr;
353 u32 pc;
354};
355
356struct PhysicalMemoryInfo {
357 PAddr physical_address;
358 u32 virtual_address;
359 u32 size;
360};
361
362struct DebugInfoCreateProcess {
363 u64 program_id;
364 u64 process_id;
365 std::array<char, 0xC> name;
366 u32 flags;
367 u32 user_exception_context_address; // 5.0.0+
368};
369
370struct DebugInfoCreateThread {
371 u64 thread_id;
372 u32 tls_address;
373 // Removed in 11.0.0 u32 entrypoint;
374};
375
376struct DebugInfoExitProcess {
377 ProcessExitReason reason;
378};
379
380struct DebugInfoExitThread {
381 ThreadExitReason reason;
382};
383
384struct DebugInfoUndefinedInstructionException {
385 u32 insn;
386};
387
388struct DebugInfoDataAbortException {
389 u32 address;
390};
391
392struct DebugInfoAlignmentFaultException {
393 u32 address;
394};
395
396struct DebugInfoBreakPointException {
397 BreakPointType type;
398 u32 address;
399};
400
401struct DebugInfoUserBreakException {
402 BreakReason break_reason;
403 u32 address;
404 u32 size;
405};
406
407struct DebugInfoDebuggerBreakException {
408 std::array<u64, 4> active_thread_ids;
409};
410
411struct DebugInfoUndefinedSystemCallException {
412 u32 id;
413};
414
415union DebugInfoSpecificException {
416 DebugInfoUndefinedInstructionException undefined_instruction;
417 DebugInfoDataAbortException data_abort;
418 DebugInfoAlignmentFaultException alignment_fault;
419 DebugInfoBreakPointException break_point;
420 DebugInfoUserBreakException user_break;
421 DebugInfoDebuggerBreakException debugger_break;
422 DebugInfoUndefinedSystemCallException undefined_system_call;
423 u64 raw;
424};
425
426struct DebugInfoException {
427 DebugException type;
428 u32 address;
429 DebugInfoSpecificException specific;
430};
431
432union DebugInfo {
433 DebugInfoCreateProcess create_process;
434 DebugInfoCreateThread create_thread;
435 DebugInfoExitProcess exit_process;
436 DebugInfoExitThread exit_thread;
437 DebugInfoException exception;
438};
439
440struct DebugEventInfo {
441 DebugEvent type;
442 u32 flags;
443 u64 thread_id;
444 DebugInfo info;
445};
446
447struct SecureMonitorArguments {
448 std::array<u32, 8> r;
449};
450static_assert(sizeof(SecureMonitorArguments) == 0x20);
451} // namespace ilp32
452
453struct ThreadContext {
454 std::array<u64, 29> r;
455 u64 fp;
456 u64 lr;
457 u64 sp;
458 u64 pc;
459 u32 pstate;
460 u32 padding;
461 std::array<u128, 32> v;
462 u32 fpcr;
463 u32 fpsr;
464 u64 tpidr;
465};
466static_assert(sizeof(ThreadContext) == 0x320);
467
468struct MemoryInfo {
469 u64 base_address;
470 u64 size;
471 MemoryState state;
472 MemoryAttribute attribute;
473 MemoryPermission permission;
474 u32 ipc_count;
475 u32 device_count;
476 u32 padding;
477};
478
479enum class LimitableResource : u32 {
480 PhysicalMemoryMax = 0,
481 ThreadCountMax = 1,
482 EventCountMax = 2,
483 TransferMemoryCountMax = 3,
484 SessionCountMax = 4,
485 Count,
486};
487
488enum class IoPoolType : u32 {
489 // Not supported.
490 Count = 0,
491};
492
493enum class MemoryMapping : u32 {
494 IoRegister = 0,
495 Uncached = 1,
496 Memory = 2,
497};
498
499enum class KernelDebugType : u32 {
500 Thread = 0,
501 ThreadCallStack = 1,
502 KernelObject = 2,
503 Handle_ = 3,
504 Memory = 4,
505 PageTable = 5,
506 CpuUtilization = 6,
507 Process = 7,
508 SuspendProcess = 8,
509 ResumeProcess = 9,
510 Port = 10,
511};
512
513enum class KernelTraceState : u32 {
514 Disabled = 0,
515 Enabled = 1,
516};
517
518enum class CodeMemoryOperation : u32 {
519 Map = 0,
520 MapToOwner = 1,
521 Unmap = 2,
522 UnmapFromOwner = 3,
523};
524
525enum class InterruptType : u32 {
526 Edge = 0,
527 Level = 1,
528};
529
530enum class DeviceName {
531 Afi = 0,
532 Avpc = 1,
533 Dc = 2,
534 Dcb = 3,
535 Hc = 4,
536 Hda = 5,
537 Isp2 = 6,
538 MsencNvenc = 7,
539 Nv = 8,
540 Nv2 = 9,
541 Ppcs = 10,
542 Sata = 11,
543 Vi = 12,
544 Vic = 13,
545 XusbHost = 14,
546 XusbDev = 15,
547 Tsec = 16,
548 Ppcs1 = 17,
549 Dc1 = 18,
550 Sdmmc1a = 19,
551 Sdmmc2a = 20,
552 Sdmmc3a = 21,
553 Sdmmc4a = 22,
554 Isp2b = 23,
555 Gpu = 24,
556 Gpub = 25,
557 Ppcs2 = 26,
558 Nvdec = 27,
559 Ape = 28,
560 Se = 29,
561 Nvjpg = 30,
562 Hc1 = 31,
563 Se1 = 32,
564 Axiap = 33,
565 Etr = 34,
566 Tsecb = 35,
567 Tsec1 = 36,
568 Tsecb1 = 37,
569 Nvdec1 = 38,
570 Count,
571};
572
573enum class SystemInfoType : u32 {
574 TotalPhysicalMemorySize = 0,
575 UsedPhysicalMemorySize = 1,
576 InitialProcessIdRange = 2,
577};
578
579enum class ProcessInfoType : u32 {
580 ProcessState = 0,
581};
582
583struct CreateProcessParameter {
584 std::array<char, 12> name;
585 u32 version;
586 u64 program_id;
587 u64 code_address;
588 s32 code_num_pages;
589 u32 flags;
590 Handle reslimit;
591 s32 system_resource_num_pages;
592};
593static_assert(sizeof(CreateProcessParameter) == 0x30);
594
149} // namespace Kernel::Svc 595} // namespace Kernel::Svc
diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp
index af133af93..42991928e 100644
--- a/src/core/hle/service/kernel_helpers.cpp
+++ b/src/core/hle/service/kernel_helpers.cpp
@@ -31,7 +31,7 @@ ServiceContext::~ServiceContext() {
31Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { 31Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
32 // Reserve a new event from the process resource limit 32 // Reserve a new event from the process resource limit
33 Kernel::KScopedResourceReservation event_reservation(process, 33 Kernel::KScopedResourceReservation event_reservation(process,
34 Kernel::LimitableResource::Events); 34 Kernel::LimitableResource::EventCountMax);
35 if (!event_reservation.Succeeded()) { 35 if (!event_reservation.Succeeded()) {
36 LOG_CRITICAL(Service, "Resource limit reached!"); 36 LOG_CRITICAL(Service, "Resource limit reached!");
37 return {}; 37 return {};
diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp
index 69e0fe808..1cf9dd1c4 100644
--- a/src/core/hle/service/sm/sm_controller.cpp
+++ b/src/core/hle/service/sm/sm_controller.cpp
@@ -34,8 +34,8 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
34 // once this is a proper process 34 // once this is a proper process
35 35
36 // Reserve a new session from the process resource limit. 36 // Reserve a new session from the process resource limit.
37 Kernel::KScopedResourceReservation session_reservation(&process, 37 Kernel::KScopedResourceReservation session_reservation(
38 Kernel::LimitableResource::Sessions); 38 &process, Kernel::LimitableResource::SessionCountMax);
39 ASSERT(session_reservation.Succeeded()); 39 ASSERT(session_reservation.Succeeded());
40 40
41 // Create the session. 41 // Create the session.