mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
pm: Support for 6.0.0
This commit is contained in:
parent
28e4d4411d
commit
488fc0f119
10 changed files with 143 additions and 88 deletions
|
@ -66,15 +66,15 @@ class HosCondVar {
|
||||||
public:
|
public:
|
||||||
HosCondVar() {
|
HosCondVar() {
|
||||||
mutexInit(&m);
|
mutexInit(&m);
|
||||||
condvarInit(&cv, &m);
|
condvarInit(&cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WaitTimeout(u64 timeout) {
|
Result WaitTimeout(u64 timeout) {
|
||||||
return condvarWaitTimeout(&cv, timeout);
|
return condvarWaitTimeout(&cv, &m, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Wait() {
|
Result Wait() {
|
||||||
return condvarWait(&cv);
|
return condvarWait(&cv, &m);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Wake(int num) {
|
Result Wake(int num) {
|
||||||
|
@ -92,45 +92,25 @@ class HosCondVar {
|
||||||
|
|
||||||
class HosSemaphore {
|
class HosSemaphore {
|
||||||
private:
|
private:
|
||||||
CondVar cv;
|
Semaphore s;
|
||||||
Mutex m;
|
|
||||||
u64 count;
|
|
||||||
public:
|
public:
|
||||||
HosSemaphore() {
|
HosSemaphore() {
|
||||||
count = 0;
|
semaphoreInit(&s, 0);
|
||||||
mutexInit(&m);
|
|
||||||
condvarInit(&cv, &m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HosSemaphore(u64 c) : count(c) {
|
HosSemaphore(u64 c) {
|
||||||
mutexInit(&m);
|
semaphoreInit(&s, c);
|
||||||
condvarInit(&cv, &m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Signal() {
|
void Signal() {
|
||||||
mutexLock(&this->m);
|
semaphoreSignal(&s);
|
||||||
count++;
|
|
||||||
condvarWakeOne(&cv);
|
|
||||||
mutexUnlock(&this->m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wait() {
|
void Wait() {
|
||||||
mutexLock(&this->m);
|
semaphoreWait(&s);
|
||||||
while (!count) {
|
|
||||||
condvarWait(&cv);
|
|
||||||
}
|
|
||||||
count--;
|
|
||||||
mutexUnlock(&this->m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TryWait() {
|
bool TryWait() {
|
||||||
mutexLock(&this->m);
|
return semaphoreTryWait(&s);
|
||||||
bool success = false;
|
|
||||||
if (count) {
|
|
||||||
count--;
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
mutexUnlock(&this->m);
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
"svcOutputDebugString": "0x27",
|
"svcOutputDebugString": "0x27",
|
||||||
"svcReturnFromException": "0x28",
|
"svcReturnFromException": "0x28",
|
||||||
"svcGetInfo": "0x29",
|
"svcGetInfo": "0x29",
|
||||||
|
"svcGetResourceLimitLimitValue": "0x30",
|
||||||
"svcGetResourceLimitCurrentValue": "0x31",
|
"svcGetResourceLimitCurrentValue": "0x31",
|
||||||
"svcWaitForAddress": "0x34",
|
"svcWaitForAddress": "0x34",
|
||||||
"svcSignalToAddress": "0x35",
|
"svcSignalToAddress": "0x35",
|
||||||
|
|
|
@ -107,6 +107,7 @@ static const std::tuple<Boot2KnownTitleId, bool> g_additional_launch_programs[]
|
||||||
{Boot2KnownTitleId::sdb, true}, /* sdb */
|
{Boot2KnownTitleId::sdb, true}, /* sdb */
|
||||||
{Boot2KnownTitleId::migration, true}, /* migration */
|
{Boot2KnownTitleId::migration, true}, /* migration */
|
||||||
{Boot2KnownTitleId::grc, true}, /* grc */
|
{Boot2KnownTitleId::grc, true}, /* grc */
|
||||||
|
{Boot2KnownTitleId::olsc, true}, /* olsc */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void MountSdCard() {
|
static void MountSdCard() {
|
||||||
|
|
|
@ -76,6 +76,7 @@ enum class Boot2KnownTitleId : u64 {
|
||||||
jit = 0x010000000000003BUL,
|
jit = 0x010000000000003BUL,
|
||||||
jpegdec = 0x010000000000003CUL,
|
jpegdec = 0x010000000000003CUL,
|
||||||
safemode = 0x010000000000003DUL,
|
safemode = 0x010000000000003DUL,
|
||||||
|
olsc = 0x010000000000003EUL,
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmbeddedBoot2 {
|
class EmbeddedBoot2 {
|
||||||
|
|
|
@ -41,6 +41,11 @@ Result DebugMonitorService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64
|
||||||
case Dmnt_Cmd_5X_EnableDebugForApplication:
|
case Dmnt_Cmd_5X_EnableDebugForApplication:
|
||||||
rc = WrapIpcCommandImpl<&DebugMonitorService::enable_debug_for_application>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
rc = WrapIpcCommandImpl<&DebugMonitorService::enable_debug_for_application>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||||
break;
|
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:
|
case Dmnt_Cmd_5X_AtmosphereGetProcessHandle:
|
||||||
rc = WrapIpcCommandImpl<&DebugMonitorService::get_process_handle>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
rc = WrapIpcCommandImpl<&DebugMonitorService::get_process_handle>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||||
break;
|
break;
|
||||||
|
@ -141,6 +146,11 @@ std::tuple<Result, CopiedHandle> DebugMonitorService::enable_debug_for_applicati
|
||||||
return {rc, h};
|
return {rc, h};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::tuple<Result> DebugMonitorService::disable_debug(u32 which) {
|
||||||
|
return {Registration::DisableDebug(which)};
|
||||||
|
}
|
||||||
|
|
||||||
std::tuple<Result, CopiedHandle> DebugMonitorService::get_process_handle(u64 pid) {
|
std::tuple<Result, CopiedHandle> DebugMonitorService::get_process_handle(u64 pid) {
|
||||||
std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
|
std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
|
||||||
if(proc == NULL) {
|
if(proc == NULL) {
|
||||||
|
|
|
@ -40,6 +40,8 @@ enum DmntCmd_5X {
|
||||||
Dmnt_Cmd_5X_GetApplicationProcessId = 4,
|
Dmnt_Cmd_5X_GetApplicationProcessId = 4,
|
||||||
Dmnt_Cmd_5X_EnableDebugForApplication = 5,
|
Dmnt_Cmd_5X_EnableDebugForApplication = 5,
|
||||||
|
|
||||||
|
Dmnt_Cmd_6X_DisableDebug = 6,
|
||||||
|
|
||||||
Dmnt_Cmd_5X_AtmosphereGetProcessHandle = 65000
|
Dmnt_Cmd_5X_AtmosphereGetProcessHandle = 65000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ class DebugMonitorService final : public IServiceObject {
|
||||||
std::tuple<Result, CopiedHandle> enable_debug_for_tid(u64 tid);
|
std::tuple<Result, CopiedHandle> enable_debug_for_tid(u64 tid);
|
||||||
std::tuple<Result, u64> get_application_process_id();
|
std::tuple<Result, u64> get_application_process_id();
|
||||||
std::tuple<Result, CopiedHandle> enable_debug_for_application();
|
std::tuple<Result, CopiedHandle> enable_debug_for_application();
|
||||||
|
std::tuple<Result> disable_debug(u32 which);
|
||||||
|
|
||||||
/* Atmosphere commands. */
|
/* Atmosphere commands. */
|
||||||
std::tuple<Result, CopiedHandle> get_process_handle(u64 pid);
|
std::tuple<Result, CopiedHandle> get_process_handle(u64 pid);
|
||||||
|
|
|
@ -45,15 +45,15 @@ extern "C" {
|
||||||
|
|
||||||
|
|
||||||
void __libnx_initheap(void) {
|
void __libnx_initheap(void) {
|
||||||
void* addr = nx_inner_heap;
|
void* addr = nx_inner_heap;
|
||||||
size_t size = nx_inner_heap_size;
|
size_t size = nx_inner_heap_size;
|
||||||
|
|
||||||
/* Newlib */
|
/* Newlib */
|
||||||
extern char* fake_heap_start;
|
extern char* fake_heap_start;
|
||||||
extern char* fake_heap_end;
|
extern char* fake_heap_end;
|
||||||
|
|
||||||
fake_heap_start = (char*)addr;
|
fake_heap_start = (char*)addr;
|
||||||
fake_heap_end = (char*)addr + size;
|
fake_heap_end = (char*)addr + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __appInit(void) {
|
void __appInit(void) {
|
||||||
|
@ -142,6 +142,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* Cleanup. */
|
/* Cleanup. */
|
||||||
delete server_manager;
|
delete server_manager;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -480,3 +480,13 @@ Result Registration::EnableDebugForApplication(Handle *out) {
|
||||||
*out = g_debug_application_event->get_handle();
|
*out = g_debug_application_event->get_handle();
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -133,18 +133,18 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROCESSEVENTTYPE_CRASH = 1,
|
PROCESSEVENTTYPE_CRASH = 1,
|
||||||
PROCESSEVENTTYPE_EXIT = 2, // only fired once, when process enters DebugDetached state (likely creport related)
|
PROCESSEVENTTYPE_EXIT = 2, // only fired once, when process enters DebugDetached state (likely creport related)
|
||||||
PROCESSEVENTTYPE_RUNNING = 3, // debug detached or running
|
PROCESSEVENTTYPE_RUNNING = 3, // debug detached or running
|
||||||
PROCESSEVENTTYPE_SUSPENDED = 4, // debug suspended
|
PROCESSEVENTTYPE_SUSPENDED = 4, // debug suspended
|
||||||
PROCESSEVENTTYPE_DEBUGDETACHED = 5,
|
PROCESSEVENTTYPE_DEBUGDETACHED = 5,
|
||||||
|
|
||||||
|
|
||||||
PROCESSEVENTTYPE_500_EXIT = 1,
|
PROCESSEVENTTYPE_500_EXIT = 1,
|
||||||
PROCESSEVENTTYPE_500_DEBUGDETACHED = 2, // only fired once, when process enters DebugDetached state (likely creport related)
|
PROCESSEVENTTYPE_500_DEBUGDETACHED = 2, // only fired once, when process enters DebugDetached state (likely creport related)
|
||||||
PROCESSEVENTTYPE_500_CRASH = 3,
|
PROCESSEVENTTYPE_500_CRASH = 3,
|
||||||
PROCESSEVENTTYPE_500_RUNNING = 4, // debug detached or running
|
PROCESSEVENTTYPE_500_RUNNING = 4, // debug detached or running
|
||||||
PROCESSEVENTTYPE_500_SUSPENDED = 5, // debug suspended
|
PROCESSEVENTTYPE_500_SUSPENDED = 5, // debug suspended
|
||||||
};
|
};
|
||||||
|
|
||||||
class Registration {
|
class Registration {
|
||||||
|
@ -189,6 +189,7 @@ class Registration {
|
||||||
static void GetProcessEventType(u64 *out_pid, u64 *out_type);
|
static void GetProcessEventType(u64 *out_pid, u64 *out_type);
|
||||||
static Result EnableDebugForTitleId(u64 tid, Handle *out);
|
static Result EnableDebugForTitleId(u64 tid, Handle *out);
|
||||||
static Result EnableDebugForApplication(Handle *out);
|
static Result EnableDebugForApplication(Handle *out);
|
||||||
|
static Result DisableDebug(u32 which);
|
||||||
static Handle GetDebugTitleEventHandle();
|
static Handle GetDebugTitleEventHandle();
|
||||||
static Handle GetDebugApplicationEventHandle();
|
static Handle GetDebugApplicationEventHandle();
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,17 @@ static u64 g_resource_limits_4x[3][5] = {
|
||||||
{0x0, 0x60, 0x0, 0x20, 0x5},
|
{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 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 u64 g_resource_limits[3][5] = {0};
|
||||||
static int g_memory_limit_type;
|
static int g_memory_limit_type;
|
||||||
static u64 g_system_boost_size = 0;
|
static u64 g_system_boost_size = 0;
|
||||||
|
@ -89,44 +96,7 @@ static Result SetNewMemoryResourceLimit(ResourceLimitUtils::ResourceLimitCategor
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceLimitUtils::InitializeLimits() {
|
void ResourceLimitUtils::InitializeLimits() {
|
||||||
/* Set global aliases. */
|
/* Create Resource Limits. */
|
||||||
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. */
|
|
||||||
for (unsigned int i = 0; i < 3; i++) {
|
for (unsigned int i = 0; i < 3; i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (R_FAILED(svcCreateResourceLimit(&g_resource_limit_handles[i]))) {
|
if (R_FAILED(svcCreateResourceLimit(&g_resource_limit_handles[i]))) {
|
||||||
|
@ -139,7 +109,85 @@ void ResourceLimitUtils::InitializeLimits() {
|
||||||
}
|
}
|
||||||
g_resource_limit_handles[i] = (Handle)out;
|
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]))) {
|
if (R_FAILED(SetResourceLimits((ResourceLimitCategory)i, g_memory_resource_limits[g_memory_limit_type][i]))) {
|
||||||
/* TODO: Panic. */
|
/* TODO: Panic. */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue