From 488fc0f119d2297e2a63e7d6894d76c98fb7e1a3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 8 Sep 2018 23:47:15 -0700 Subject: [PATCH] pm: Support for 6.0.0 --- .../include/stratosphere/hossynch.hpp | 40 ++---- stratosphere/pm/pm.json | 1 + stratosphere/pm/source/pm_boot2.cpp | 1 + stratosphere/pm/source/pm_boot2.hpp | 1 + stratosphere/pm/source/pm_debug_monitor.cpp | 10 ++ stratosphere/pm/source/pm_debug_monitor.hpp | 3 + stratosphere/pm/source/pm_main.cpp | 16 +-- stratosphere/pm/source/pm_registration.cpp | 10 ++ stratosphere/pm/source/pm_registration.hpp | 23 ++-- stratosphere/pm/source/pm_resource_limits.cpp | 126 ++++++++++++------ 10 files changed, 143 insertions(+), 88 deletions(-) diff --git a/stratosphere/libstratosphere/include/stratosphere/hossynch.hpp b/stratosphere/libstratosphere/include/stratosphere/hossynch.hpp index 0d2b8e8f6..56facd130 100644 --- a/stratosphere/libstratosphere/include/stratosphere/hossynch.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/hossynch.hpp @@ -66,15 +66,15 @@ class HosCondVar { public: HosCondVar() { mutexInit(&m); - condvarInit(&cv, &m); + condvarInit(&cv); } Result WaitTimeout(u64 timeout) { - return condvarWaitTimeout(&cv, timeout); + return condvarWaitTimeout(&cv, &m, timeout); } Result Wait() { - return condvarWait(&cv); + return condvarWait(&cv, &m); } Result Wake(int num) { @@ -92,45 +92,25 @@ class HosCondVar { class HosSemaphore { private: - CondVar cv; - Mutex m; - u64 count; + Semaphore s; public: HosSemaphore() { - count = 0; - mutexInit(&m); - condvarInit(&cv, &m); + semaphoreInit(&s, 0); } - HosSemaphore(u64 c) : count(c) { - mutexInit(&m); - condvarInit(&cv, &m); + HosSemaphore(u64 c) { + semaphoreInit(&s, c); } void Signal() { - mutexLock(&this->m); - count++; - condvarWakeOne(&cv); - mutexUnlock(&this->m); + semaphoreSignal(&s); } void Wait() { - mutexLock(&this->m); - while (!count) { - condvarWait(&cv); - } - count--; - mutexUnlock(&this->m); + semaphoreWait(&s); } bool TryWait() { - mutexLock(&this->m); - bool success = false; - if (count) { - count--; - success = true; - } - mutexUnlock(&this->m); - return success; + return semaphoreTryWait(&s); } }; diff --git a/stratosphere/pm/pm.json b/stratosphere/pm/pm.json index 4b127d4e8..a7bd7e8a9 100644 --- a/stratosphere/pm/pm.json +++ b/stratosphere/pm/pm.json @@ -49,6 +49,7 @@ "svcOutputDebugString": "0x27", "svcReturnFromException": "0x28", "svcGetInfo": "0x29", + "svcGetResourceLimitLimitValue": "0x30", "svcGetResourceLimitCurrentValue": "0x31", "svcWaitForAddress": "0x34", "svcSignalToAddress": "0x35", diff --git a/stratosphere/pm/source/pm_boot2.cpp b/stratosphere/pm/source/pm_boot2.cpp index f666abce2..2f22c9d11 100644 --- a/stratosphere/pm/source/pm_boot2.cpp +++ b/stratosphere/pm/source/pm_boot2.cpp @@ -107,6 +107,7 @@ static const std::tuple g_additional_launch_programs[] {Boot2KnownTitleId::sdb, true}, /* sdb */ {Boot2KnownTitleId::migration, true}, /* migration */ {Boot2KnownTitleId::grc, true}, /* grc */ + {Boot2KnownTitleId::olsc, true}, /* olsc */ }; static void MountSdCard() { diff --git a/stratosphere/pm/source/pm_boot2.hpp b/stratosphere/pm/source/pm_boot2.hpp index 2f93ac0e8..44c4e1de1 100644 --- a/stratosphere/pm/source/pm_boot2.hpp +++ b/stratosphere/pm/source/pm_boot2.hpp @@ -76,6 +76,7 @@ enum class Boot2KnownTitleId : u64 { jit = 0x010000000000003BUL, jpegdec = 0x010000000000003CUL, safemode = 0x010000000000003DUL, + olsc = 0x010000000000003EUL, }; class EmbeddedBoot2 { diff --git a/stratosphere/pm/source/pm_debug_monitor.cpp b/stratosphere/pm/source/pm_debug_monitor.cpp index e9818911e..95362c1ea 100644 --- a/stratosphere/pm/source/pm_debug_monitor.cpp +++ b/stratosphere/pm/source/pm_debug_monitor.cpp @@ -41,6 +41,11 @@ Result DebugMonitorService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 case Dmnt_Cmd_5X_EnableDebugForApplication: rc = WrapIpcCommandImpl<&DebugMonitorService::enable_debug_for_application>(this, r, out_c, pointer_buffer, pointer_buffer_size); break; + case Dmnt_Cmd_6X_DisableDebug: + if (kernelAbove600()) { + rc = WrapIpcCommandImpl<&DebugMonitorService::disable_debug>(this, r, out_c, pointer_buffer, pointer_buffer_size); + } + break; case Dmnt_Cmd_5X_AtmosphereGetProcessHandle: rc = WrapIpcCommandImpl<&DebugMonitorService::get_process_handle>(this, r, out_c, pointer_buffer, pointer_buffer_size); break; @@ -141,6 +146,11 @@ std::tuple DebugMonitorService::enable_debug_for_applicati return {rc, h}; } + +std::tuple DebugMonitorService::disable_debug(u32 which) { + return {Registration::DisableDebug(which)}; +} + std::tuple DebugMonitorService::get_process_handle(u64 pid) { std::shared_ptr proc = Registration::GetProcess(pid); if(proc == NULL) { diff --git a/stratosphere/pm/source/pm_debug_monitor.hpp b/stratosphere/pm/source/pm_debug_monitor.hpp index a6ae9ca8b..ee6c66b12 100644 --- a/stratosphere/pm/source/pm_debug_monitor.hpp +++ b/stratosphere/pm/source/pm_debug_monitor.hpp @@ -39,6 +39,8 @@ enum DmntCmd_5X { Dmnt_Cmd_5X_EnableDebugForTitleId = 3, Dmnt_Cmd_5X_GetApplicationProcessId = 4, Dmnt_Cmd_5X_EnableDebugForApplication = 5, + + Dmnt_Cmd_6X_DisableDebug = 6, Dmnt_Cmd_5X_AtmosphereGetProcessHandle = 65000 }; @@ -61,6 +63,7 @@ class DebugMonitorService final : public IServiceObject { std::tuple enable_debug_for_tid(u64 tid); std::tuple get_application_process_id(); std::tuple enable_debug_for_application(); + std::tuple disable_debug(u32 which); /* Atmosphere commands. */ std::tuple get_process_handle(u64 pid); diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index 24ef034eb..04200ba15 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -45,15 +45,15 @@ extern "C" { void __libnx_initheap(void) { - void* addr = nx_inner_heap; - size_t size = nx_inner_heap_size; + void* addr = nx_inner_heap; + size_t size = nx_inner_heap_size; - /* Newlib */ - extern char* fake_heap_start; - extern char* fake_heap_end; + /* Newlib */ + extern char* fake_heap_start; + extern char* fake_heap_end; - fake_heap_start = (char*)addr; - fake_heap_end = (char*)addr + size; + fake_heap_start = (char*)addr; + fake_heap_end = (char*)addr + size; } void __appInit(void) { @@ -142,6 +142,6 @@ int main(int argc, char **argv) /* Cleanup. */ delete server_manager; - return 0; + return 0; } diff --git a/stratosphere/pm/source/pm_registration.cpp b/stratosphere/pm/source/pm_registration.cpp index 63c7fbd39..4e3c8cfff 100644 --- a/stratosphere/pm/source/pm_registration.cpp +++ b/stratosphere/pm/source/pm_registration.cpp @@ -480,3 +480,13 @@ Result Registration::EnableDebugForApplication(Handle *out) { *out = g_debug_application_event->get_handle(); return 0; } + +Result Registration::DisableDebug(u32 which) { + if (which & 1) { + g_debug_on_launch_tid = 0; + } + if (which & 2) { + g_debug_next_application = false; + } + return 0; +} diff --git a/stratosphere/pm/source/pm_registration.hpp b/stratosphere/pm/source/pm_registration.hpp index 6749b4c8c..6f0459124 100644 --- a/stratosphere/pm/source/pm_registration.hpp +++ b/stratosphere/pm/source/pm_registration.hpp @@ -133,20 +133,20 @@ enum { }; enum { - PROCESSEVENTTYPE_CRASH = 1, - PROCESSEVENTTYPE_EXIT = 2, // only fired once, when process enters DebugDetached state (likely creport related) - PROCESSEVENTTYPE_RUNNING = 3, // debug detached or running - PROCESSEVENTTYPE_SUSPENDED = 4, // debug suspended - PROCESSEVENTTYPE_DEBUGDETACHED = 5, + PROCESSEVENTTYPE_CRASH = 1, + PROCESSEVENTTYPE_EXIT = 2, // only fired once, when process enters DebugDetached state (likely creport related) + PROCESSEVENTTYPE_RUNNING = 3, // debug detached or running + PROCESSEVENTTYPE_SUSPENDED = 4, // debug suspended + PROCESSEVENTTYPE_DEBUGDETACHED = 5, - PROCESSEVENTTYPE_500_EXIT = 1, - PROCESSEVENTTYPE_500_DEBUGDETACHED = 2, // only fired once, when process enters DebugDetached state (likely creport related) - PROCESSEVENTTYPE_500_CRASH = 3, - PROCESSEVENTTYPE_500_RUNNING = 4, // debug detached or running - PROCESSEVENTTYPE_500_SUSPENDED = 5, // debug suspended + PROCESSEVENTTYPE_500_EXIT = 1, + PROCESSEVENTTYPE_500_DEBUGDETACHED = 2, // only fired once, when process enters DebugDetached state (likely creport related) + PROCESSEVENTTYPE_500_CRASH = 3, + PROCESSEVENTTYPE_500_RUNNING = 4, // debug detached or running + PROCESSEVENTTYPE_500_SUSPENDED = 5, // debug suspended }; - + class Registration { public: struct TidSid { @@ -189,6 +189,7 @@ class Registration { static void GetProcessEventType(u64 *out_pid, u64 *out_type); static Result EnableDebugForTitleId(u64 tid, Handle *out); static Result EnableDebugForApplication(Handle *out); + static Result DisableDebug(u32 which); static Handle GetDebugTitleEventHandle(); static Handle GetDebugApplicationEventHandle(); diff --git a/stratosphere/pm/source/pm_resource_limits.cpp b/stratosphere/pm/source/pm_resource_limits.cpp index af338337f..97c699221 100644 --- a/stratosphere/pm/source/pm_resource_limits.cpp +++ b/stratosphere/pm/source/pm_resource_limits.cpp @@ -55,10 +55,17 @@ static u64 g_resource_limits_4x[3][5] = { {0x0, 0x60, 0x0, 0x20, 0x5}, }; +/* 6.x boosted the number of events and sessions that system modules are allowed to make. */ +static u64 g_resource_limits_6x[3][5] = { + {0x0, 0x260, 0x2BC, 0x80, 0x37E}, + {0x0, 0x60, 0x0, 0x20, 0x1}, + {0x0, 0x60, 0x0, 0x20, 0x5}, +}; + static Handle g_resource_limit_handles[3] = {0}; -static u64 g_memory_resource_limits[5][3] = {0}; +static u64 g_memory_resource_limits[6][3] = {0}; static u64 g_resource_limits[3][5] = {0}; static int g_memory_limit_type; static u64 g_system_boost_size = 0; @@ -89,44 +96,7 @@ static Result SetNewMemoryResourceLimit(ResourceLimitUtils::ResourceLimitCategor } void ResourceLimitUtils::InitializeLimits() { - /* Set global aliases. */ - if (kernelAbove400()) { - memcpy(&g_memory_resource_limits, &g_memory_resource_limits_4x, sizeof(g_memory_resource_limits)); - memcpy(&g_resource_limits, &g_resource_limits_4x, sizeof(g_resource_limits)); - } else { - memcpy(&g_memory_resource_limits, &g_memory_resource_limits_deprecated, sizeof(g_memory_resource_limits)); - memcpy(&g_resource_limits, &g_resource_limits_deprecated, sizeof(g_resource_limits)); - } - /* Atmosphere: Allocate extra memory (24 MiB) to SYSTEM away from Applet. */ - for (unsigned int i = 0; i < 5; i++) { - g_memory_resource_limits[i][0] += ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES; - g_memory_resource_limits[i][2] -= ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES; - } - /* Get memory limits. */ - u64 memory_arrangement; - if (R_FAILED(splGetConfig(SplConfigItem_MemoryArrange, &memory_arrangement))) { - /* TODO: panic. */ - } - memory_arrangement &= 0x3F; - switch (memory_arrangement) { - case 2: - g_memory_limit_type = 1; - break; - case 3: - g_memory_limit_type = 2; - break; - case 17: - g_memory_limit_type = 3; - break; - case 18: - g_memory_limit_type = 4; - break; - default: - g_memory_limit_type = 0; - break; - } - - /* Create resource limits. */ + /* Create Resource Limits. */ for (unsigned int i = 0; i < 3; i++) { if (i > 0) { if (R_FAILED(svcCreateResourceLimit(&g_resource_limit_handles[i]))) { @@ -139,7 +109,85 @@ void ResourceLimitUtils::InitializeLimits() { } g_resource_limit_handles[i] = (Handle)out; } + } + /* Set global aliases. */ + if (kernelAbove600()) { + /* 6.0.0 did away with hardcoded memory resource limit values. */ + memcpy(&g_resource_limits, &g_resource_limits_6x, sizeof(g_resource_limits)); + } else if (kernelAbove400()) { + memcpy(&g_memory_resource_limits, &g_memory_resource_limits_4x, sizeof(g_memory_resource_limits_4x)); + memcpy(&g_resource_limits, &g_resource_limits_4x, sizeof(g_resource_limits)); + } else { + memcpy(&g_memory_resource_limits, &g_memory_resource_limits_deprecated, sizeof(g_memory_resource_limits_deprecated)); + memcpy(&g_resource_limits, &g_resource_limits_deprecated, sizeof(g_resource_limits)); + } + + if (kernelAbove600()) { + /* NOTE: 5 is a fake type, official code does not do this. */ + /* This is done for ease of backwards compatibility. */ + g_memory_limit_type = 5; + /* Starting 6.x, 5 MB of memory is always reserved for system. */ + const u64 reserved_system_size_6x = 0x500000; + + /* Get total memory available. */ + u64 total_memory = 0; + if (R_FAILED(svcGetResourceLimitLimitValue(&total_memory, g_resource_limit_handles[0], LimitableResource_Memory))) { + /* TODO: Panic. */ + } + + /* Get and save application + applet memory. */ + if (R_FAILED(svcGetSystemInfo(&g_memory_resource_limits[g_memory_limit_type][1], 0, 0, 0)) || + R_FAILED(svcGetSystemInfo(&g_memory_resource_limits[g_memory_limit_type][2], 0, 0, 1))) { + /* TODO: Panic. */ + } + + const u64 application_size = g_memory_resource_limits[g_memory_limit_type][1]; + const u64 applet_size = g_memory_resource_limits[g_memory_limit_type][2]; + const u64 reserved_nonsys_size = (application_size + applet_size + reserved_system_size_6x); + + /* Ensure there's enough memory for system region. */ + if (reserved_nonsys_size > total_memory) { + /* TODO: Panic. */ + } + + /* Set System memory. */ + g_memory_resource_limits[g_memory_limit_type][0] = total_memory - (reserved_nonsys_size); + } else { + /* Get memory limits. */ + u64 memory_arrangement; + if (R_FAILED(splGetConfig(SplConfigItem_MemoryArrange, &memory_arrangement))) { + /* TODO: panic. */ + } + memory_arrangement &= 0x3F; + switch (memory_arrangement) { + case 2: + g_memory_limit_type = 1; + break; + case 3: + g_memory_limit_type = 2; + break; + case 17: + g_memory_limit_type = 3; + break; + case 18: + g_memory_limit_type = 4; + break; + default: + g_memory_limit_type = 0; + break; + } + } + + /* Atmosphere: Allocate extra memory (24 MiB) to SYSTEM away from Applet. */ + for (unsigned int i = 0; i < 6; i++) { + g_memory_resource_limits[i][0] += ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES; + g_memory_resource_limits[i][2] -= ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES; + } + + /* Set resource limits. */ + for (unsigned int i = 0; i < 3; i++) { + g_resource_limits[i][LimitableResource_Memory] = g_memory_resource_limits[g_memory_limit_type][i]; if (R_FAILED(SetResourceLimits((ResourceLimitCategory)i, g_memory_resource_limits[g_memory_limit_type][i]))) { /* TODO: Panic. */ }