1
0
Fork 0
mirror of https://github.com/HamletDuFromage/aio-switch-updater.git synced 2024-11-08 11:31:43 +00:00
AIO-switch-updater/source/reboot_payload.c

88 lines
2.2 KiB
C
Raw Normal View History

2020-09-20 01:21:28 +01:00
#include "reboot_payload.h"
2021-09-11 14:48:13 +01:00
2021-06-17 21:40:54 +01:00
#include "ams_bpc.h"
2020-09-20 01:21:28 +01:00
2021-09-11 14:48:13 +01:00
#define IRAM_PAYLOAD_MAX_SIZE 0x2F000
#define IRAM_PAYLOAD_BASE 0x40010000
2020-09-20 01:21:28 +01:00
static alignas(0x1000) u8 g_reboot_payload[IRAM_PAYLOAD_MAX_SIZE];
static alignas(0x1000) u8 g_ff_page[0x1000];
static alignas(0x1000) u8 g_work_page[0x1000];
2021-09-11 14:48:13 +01:00
void do_iram_dram_copy(void* buf, uintptr_t iram_addr, size_t size, int option)
{
2020-09-20 01:21:28 +01:00
memcpy(g_work_page, buf, size);
2021-05-28 14:51:30 +01:00
2020-09-20 01:21:28 +01:00
SecmonArgs args = {0};
args.X[0] = 0xF0000201; /* smcAmsIramCopy */
2021-09-11 14:48:13 +01:00
args.X[1] = (uintptr_t)g_work_page; /* DRAM Address */
2020-09-20 01:21:28 +01:00
args.X[2] = iram_addr; /* IRAM Address */
args.X[3] = size; /* Copy size */
args.X[4] = option; /* 0 = Read, 1 = Write */
svcCallSecureMonitor(&args);
2021-09-11 14:48:13 +01:00
2020-09-20 01:21:28 +01:00
memcpy(buf, g_work_page, size);
}
2021-09-11 14:48:13 +01:00
void copy_to_iram(uintptr_t iram_addr, void* buf, size_t size)
{
2020-09-20 01:21:28 +01:00
do_iram_dram_copy(buf, iram_addr, size, 1);
}
2021-09-11 14:48:13 +01:00
void copy_from_iram(void* buf, uintptr_t iram_addr, size_t size)
{
2020-09-20 01:21:28 +01:00
do_iram_dram_copy(buf, iram_addr, size, 0);
}
2021-09-11 14:48:13 +01:00
static void clear_iram(void)
{
2020-09-20 01:21:28 +01:00
memset(g_ff_page, 0xFF, sizeof(g_ff_page));
for (size_t i = 0; i < IRAM_PAYLOAD_MAX_SIZE; i += sizeof(g_ff_page)) {
copy_to_iram(IRAM_PAYLOAD_BASE + i, g_ff_page, sizeof(g_ff_page));
}
}
2021-09-11 14:48:13 +01:00
static void inject_payload(void)
{
2021-06-17 21:40:54 +01:00
printf("injecting\n");
spsmInitialize();
smExit();
if (R_SUCCEEDED(amsBpcInitialize()) && R_SUCCEEDED(amsBpcSetRebootPayload(g_reboot_payload, 0x24000))) {
spsmShutdown(true);
}
}
2021-09-11 14:48:13 +01:00
static void inject_payload_legacy(void)
{
2021-06-17 21:40:54 +01:00
printf("injecting (legacy)\n");
2020-09-20 01:21:28 +01:00
clear_iram();
for (size_t i = 0; i < IRAM_PAYLOAD_MAX_SIZE; i += 0x1000) {
copy_to_iram(IRAM_PAYLOAD_BASE + i, &g_reboot_payload[i], 0x1000);
}
splSetConfig((SplConfigItem)65001, 2);
}
2021-09-11 14:48:13 +01:00
int reboot_to_payload(const char* path, bool legacy)
{
2020-09-20 01:21:28 +01:00
bool can_reboot = true;
2021-09-11 14:48:13 +01:00
FILE* f;
2020-09-20 01:21:28 +01:00
f = fopen(path, "rb");
2021-09-11 14:48:13 +01:00
if (f == NULL)
can_reboot = false;
2020-09-20 01:21:28 +01:00
else {
fread(g_reboot_payload, 1, sizeof(g_reboot_payload), f);
fclose(f);
}
if (can_reboot) {
2021-09-11 14:48:13 +01:00
if (legacy)
inject_payload_legacy();
else
inject_payload();
2020-09-20 01:21:28 +01:00
}
2021-05-28 14:51:30 +01:00
if (can_reboot)
splExit();
2020-09-20 01:21:28 +01:00
return 0;
}