Add custom pm sysmodule
This commit is contained in:
56
sysmodules/pm/source/firmlaunch.c
Normal file
56
sysmodules/pm/source/firmlaunch.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include "firmlaunch.h"
|
||||
#include "termination.h"
|
||||
#include "task_runner.h"
|
||||
#include "util.h"
|
||||
|
||||
static void *const g_firmlaunchParameters = (void *)0x12000000;
|
||||
|
||||
void mapFirmlaunchParameters(void)
|
||||
{
|
||||
assertSuccess(svcKernelSetState(3, 0, g_firmlaunchParameters));
|
||||
}
|
||||
|
||||
Result GetFirmlaunchParams(void *outParams, size_t size)
|
||||
{
|
||||
size = size >= 0x1000 ? 0x1000 : size;
|
||||
memcpy(outParams, g_firmlaunchParameters, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result SetFirmlaunchParams(const void *params, size_t size)
|
||||
{
|
||||
size = size >= 0x1000 ? 0x1000 : size;
|
||||
memcpy(g_firmlaunchParameters, params, size);
|
||||
if (size < 0x1000) {
|
||||
memset(g_firmlaunchParameters + size, 0, 0x1000 - size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LaunchFirmAsync(void *argdata)
|
||||
{
|
||||
struct {
|
||||
u32 firmTidLow;
|
||||
} *args = argdata;
|
||||
|
||||
terminateAllProcesses((u32)-1, 4 * 1000 * 1000 * 1000LL);
|
||||
// pm has dead code there (notification 0x179, but there's no 'caller process'... (-1))
|
||||
|
||||
u64 firmTid = args->firmTidLow; // note: tidHigh doesn't matter
|
||||
firmTid = IS_N3DS ? (firmTid & ~N3DS_TID_MASK) | N3DS_TID_BIT : firmTid;
|
||||
assertSuccess(svcKernelSetState(0, firmTid));
|
||||
}
|
||||
|
||||
Result LaunchFirm(u32 firmTidLow, const void *params, size_t size)
|
||||
{
|
||||
struct {
|
||||
u32 firmTidLow;
|
||||
} args = { firmTidLow };
|
||||
|
||||
SetFirmlaunchParams(params, size);
|
||||
TaskRunner_RunTask(LaunchFirmAsync, &args, sizeof(args));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user