mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-20 09:55:07 -04:00
reboot_to_payload: Use ams:bpc API to set payload, reboot safely and prevent usage on Mariko (#1543)
This commit is contained in:
parent
2ab01ad33c
commit
c02f32f1bf
4 changed files with 173 additions and 47 deletions
|
@ -3,51 +3,26 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include <switch.h>
|
||||
#include "ams_bpc.h"
|
||||
|
||||
#define IRAM_PAYLOAD_MAX_SIZE 0x24000
|
||||
#define IRAM_PAYLOAD_BASE 0x40010000
|
||||
static u8 g_reboot_payload[IRAM_PAYLOAD_MAX_SIZE];
|
||||
|
||||
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];
|
||||
|
||||
void do_iram_dram_copy(void *buf, uintptr_t iram_addr, size_t size, int option) {
|
||||
memcpy(g_work_page, buf, size);
|
||||
|
||||
SecmonArgs args = {0};
|
||||
args.X[0] = 0xF0000201; /* smcAmsIramCopy */
|
||||
args.X[1] = (uintptr_t)g_work_page; /* DRAM Address */
|
||||
args.X[2] = iram_addr; /* IRAM Address */
|
||||
args.X[3] = size; /* Copy size */
|
||||
args.X[4] = option; /* 0 = Read, 1 = Write */
|
||||
svcCallSecureMonitor(&args);
|
||||
|
||||
memcpy(buf, g_work_page, size);
|
||||
}
|
||||
|
||||
void copy_to_iram(uintptr_t iram_addr, void *buf, size_t size) {
|
||||
do_iram_dram_copy(buf, iram_addr, size, 1);
|
||||
}
|
||||
|
||||
void copy_from_iram(void *buf, uintptr_t iram_addr, size_t size) {
|
||||
do_iram_dram_copy(buf, iram_addr, size, 0);
|
||||
}
|
||||
|
||||
static void clear_iram(void) {
|
||||
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));
|
||||
}
|
||||
void userAppExit(void)
|
||||
{
|
||||
amsBpcExit();
|
||||
setsysExit();
|
||||
spsmExit();
|
||||
}
|
||||
|
||||
static void reboot_to_payload(void) {
|
||||
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);
|
||||
Result rc = amsBpcSetRebootPayload(g_reboot_payload, IRAM_PAYLOAD_MAX_SIZE);
|
||||
if (R_FAILED(rc)) {
|
||||
printf("Failed to set reboot payload: 0x%x\n", rc);
|
||||
}
|
||||
else {
|
||||
spsmShutdown(true);
|
||||
}
|
||||
|
||||
splSetConfig((SplConfigItem)65001, 2);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -59,12 +34,36 @@ int main(int argc, char **argv)
|
|||
PadState pad;
|
||||
padInitializeAny(&pad);
|
||||
|
||||
Result rc = 0;
|
||||
bool can_reboot = true;
|
||||
Result rc = splInitialize();
|
||||
if (R_FAILED(rc)) {
|
||||
printf("Failed to initialize spl: 0x%x\n", rc);
|
||||
|
||||
if (R_FAILED(rc = setsysInitialize())) {
|
||||
printf("Failed to initialize set:sys: 0x%x\n", rc);
|
||||
can_reboot = false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
SetSysProductModel model;
|
||||
setsysGetProductModel(&model);
|
||||
if (model != SetSysProductModel_Nx && model != SetSysProductModel_Copper) {
|
||||
printf("Reboot to payload cannot be used on a Mariko system\n");
|
||||
can_reboot = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_reboot && R_FAILED(rc = spsmInitialize())) {
|
||||
printf("Failed to initialize spsm: 0x%x\n", rc);
|
||||
can_reboot = false;
|
||||
}
|
||||
|
||||
if (can_reboot) {
|
||||
smExit(); //Required to connect to ams:bpc
|
||||
if R_FAILED(rc = amsBpcInitialize()) {
|
||||
printf("Failed to initialize ams:bpc: 0x%x\n", rc);
|
||||
can_reboot = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_reboot) {
|
||||
FILE *f = fopen("sdmc:/atmosphere/reboot_payload.bin", "rb");
|
||||
if (f == NULL) {
|
||||
printf("Failed to open atmosphere/reboot_payload.bin!\n");
|
||||
|
@ -92,11 +91,6 @@ int main(int argc, char **argv)
|
|||
consoleUpdate(NULL);
|
||||
}
|
||||
|
||||
if (can_reboot) {
|
||||
splExit();
|
||||
}
|
||||
|
||||
consoleExit(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue