Skip to content

Commit 20f0a07

Browse files
use ams bpc sane reboot when available
1 parent 20f692d commit 20f0a07

File tree

7 files changed

+131
-51
lines changed

7 files changed

+131
-51
lines changed

applet/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ namespace {
5858
}
5959

6060
extern "C" void userAppInit(void) {
61+
spsmInitialize();
6162
splInitialize();
6263
}
6364

6465
extern "C" void userAppExit(void) {
6566
splExit();
67+
spsmExit();
6668
}
6769

6870
int main(int const argc, char const *argv[]) {
@@ -126,6 +128,9 @@ int main(int const argc, char const *argv[]) {
126128
PadState pad;
127129
padInitializeAny(&pad);
128130

131+
/* Deinit sm to free up our only service slot */
132+
smExit();
133+
129134
while (appletMainLoop()) {
130135
{
131136
/* Update padstate */

common/ams_bpc.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2018-2020 Atmosphère-NX
3+
*
4+
* This program is free software; you can redistribute it and/or modify it
5+
* under the terms and conditions of the GNU General Public License,
6+
* version 2, as published by the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope it will be useful, but WITHOUT
9+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11+
* more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
#include <switch.h>
17+
#include "ams_bpc.h"
18+
19+
static Service g_amsBpcSrv;
20+
21+
Result amsBpcInitialize(void) {
22+
Handle h;
23+
Result rc = svcConnectToNamedPort(&h, "bpc:ams"); /* TODO: ams:bpc */
24+
if (R_SUCCEEDED(rc)) serviceCreate(&g_amsBpcSrv, h);
25+
return rc;
26+
}
27+
28+
void amsBpcExit(void) {
29+
serviceClose(&g_amsBpcSrv);
30+
}
31+
32+
Service *amsBpcGetServiceSession(void) {
33+
return &g_amsBpcSrv;
34+
}
35+
36+
Result amsBpcSetRebootPayload(const void *src, size_t src_size) {
37+
return serviceDispatch(&g_amsBpcSrv, 65001,
38+
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias },
39+
.buffers = { { src, src_size } },
40+
);
41+
}

common/ams_bpc.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2018-2020 Atmosphère-NX
3+
*
4+
* This program is free software; you can redistribute it and/or modify it
5+
* under the terms and conditions of the GNU General Public License,
6+
* version 2, as published by the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope it will be useful, but WITHOUT
9+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11+
* more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
#pragma once
17+
#include <switch.h>
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
23+
Result amsBpcInitialize();
24+
void amsBpcExit();
25+
Service *amsBpcGetServiceSession(void);
26+
27+
Result amsBpcSetRebootPayload(const void *src, size_t src_size);
28+
29+
#ifdef __cplusplus
30+
}
31+
#endif

common/payload.cpp

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
*/
1616
#include "payload.hpp"
1717

18-
#include "ini.h"
1918
#include "reboot_to_payload.h"
19+
#include "ams_bpc.h"
20+
#include "ini.h"
2021

2122
#include <cstdio>
2223
#include <cstring>
@@ -27,10 +28,26 @@ namespace Payload {
2728

2829
namespace {
2930

31+
void RebootToPayload() {
32+
/* Try reboot with safe ams bpc api. */
33+
Result rc = amsBpcInitialize();
34+
if (R_SUCCEEDED(rc)) {
35+
rc = amsBpcSetRebootPayload(g_reboot_payload, IRAM_PAYLOAD_MAX_SIZE);
36+
if (R_SUCCEEDED(rc)) {
37+
spsmShutdown(true);
38+
}
39+
amsBpcExit();
40+
}
41+
42+
/* Fallback to old smc reboot to payload. */
43+
if (R_FAILED(rc))
44+
smc_reboot_to_payload();
45+
}
46+
3047
int HekateConfigHandler(void *user, char const *section, char const *name, char const *value) {
3148
auto const list = reinterpret_cast<HekateConfigList *>(user);
3249

33-
/* ignore pre-config and global config entries. */
50+
/* Ignore pre-config and global config entries. */
3451
if (section[0] == '\0' || std::strcmp(section, "config") == 0) {
3552
return 1;
3653
}
@@ -193,7 +210,8 @@ namespace Payload {
193210
return res;
194211
}
195212

196-
bool RebootToHekate() {
213+
template<typename ConfigureFunction>
214+
bool Reboot(ConfigureFunction func) {
197215
/* Load payload. */
198216
if (!LoadHekatePayload())
199217
return false;
@@ -204,55 +222,38 @@ namespace Payload {
204222
/* Clear boot storage. */
205223
std::memset(storage, 0, sizeof(BootStorage));
206224

225+
/* Configure boot storage */
226+
func(storage);
227+
207228
/* Reboot */
208-
reboot_to_payload();
229+
RebootToPayload();
209230

210231
return true;
211232
}
212233

213-
bool RebootToHekateConfig(HekateConfig const &config, bool const autoboot_list) {
214-
/* Load payload. */
215-
if (!LoadHekatePayload())
216-
return false;
217-
218-
/* Get boot storage pointer. */
219-
auto const storage = reinterpret_cast<BootStorage *>(g_reboot_payload + BootStorageOffset);
220-
221-
/* Clear boot storage. */
222-
std::memset(storage, 0, sizeof(BootStorage));
223-
224-
/* Force autoboot and set boot id. */
225-
storage->boot_cfg = BootCfg_ForceAutoBoot;
226-
storage->autoboot = config.index;
227-
storage->autoboot_list = autoboot_list;
228-
229-
/* Reboot */
230-
reboot_to_payload();
234+
bool RebootToHekate() {
235+
return Reboot([&] (BootStorage *storage) {
236+
/* No-Op */
237+
});
238+
}
231239

232-
return true;
240+
bool RebootToHekateConfig(HekateConfig const &config, bool const autoboot_list) {
241+
return Reboot([&] (BootStorage *storage) {
242+
/* Force autoboot and set boot id. */
243+
storage->boot_cfg = BootCfg_ForceAutoBoot;
244+
storage->autoboot = config.index;
245+
storage->autoboot_list = autoboot_list;
246+
});
233247
}
234248

235249
bool RebootToHekateUMS(UmsTarget const target) {
236-
/* Load payload. */
237-
if (!LoadHekatePayload())
238-
return false;
239-
240-
/* Get boot storage pointer. */
241-
auto const storage = reinterpret_cast<BootStorage *>(g_reboot_payload + BootStorageOffset);
242-
243-
/* Clear boot storage. */
244-
std::memset(storage, 0, sizeof(BootStorage));
245-
246-
/* Force boot to menu, target UMS and select target. */
247-
storage->boot_cfg = BootCfg_ForceAutoBoot;
248-
storage->extra_cfg = ExtraCfg_NyxUms;
249-
storage->autoboot = 0;
250-
storage->ums = target;
251-
252-
/* Reboot */
253-
reboot_to_payload();
254-
255-
return true;
250+
return Reboot([&] (BootStorage *storage) {
251+
/* Force boot to menu, target UMS and select target. */
252+
storage->boot_cfg = BootCfg_ForceAutoBoot;
253+
storage->extra_cfg = ExtraCfg_NyxUms;
254+
storage->autoboot = 0;
255+
storage->ums = target;
256+
});
256257
}
257258

258259
bool RebootToPayload(PayloadConfig const &config) {
@@ -261,7 +262,7 @@ namespace Payload {
261262
return false;
262263

263264
/* Reboot */
264-
reboot_to_payload();
265+
RebootToPayload();
265266

266267
return true;
267268
}

common/reboot_to_payload.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
#include <string.h>
1919
#include <switch.h>
2020

21-
#define IRAM_PAYLOAD_MAX_SIZE 0x2F000
21+
#define IRAM_PAYLOAD_MAX_SIZE 0x24000
2222
#define IRAM_PAYLOAD_BASE 0x40010000
2323

2424
alignas(0x1000) u8 g_reboot_payload[IRAM_PAYLOAD_MAX_SIZE];
2525
static alignas(0x1000) u8 g_ff_page[0x1000];
2626
static alignas(0x1000) u8 g_work_page[0x1000];
2727

28-
void do_iram_dram_copy(void *buf, uintptr_t iram_addr, size_t size, int option) {
28+
static void do_iram_dram_copy(void *buf, uintptr_t iram_addr, size_t size, int option) {
2929
memcpy(g_work_page, buf, size);
3030

3131
SecmonArgs args = {0};
@@ -39,18 +39,18 @@ void do_iram_dram_copy(void *buf, uintptr_t iram_addr, size_t size, int option)
3939
memcpy(buf, g_work_page, size);
4040
}
4141

42-
void copy_to_iram(uintptr_t iram_addr, void *buf, size_t size) {
42+
static void copy_to_iram(uintptr_t iram_addr, void *buf, size_t size) {
4343
do_iram_dram_copy(buf, iram_addr, size, 1);
4444
}
4545

46-
void clear_iram(void) {
46+
static void clear_iram(void) {
4747
memset(g_ff_page, 0xFF, sizeof(g_ff_page));
4848
for (size_t i = 0; i < IRAM_PAYLOAD_MAX_SIZE; i += sizeof(g_ff_page)) {
4949
copy_to_iram(IRAM_PAYLOAD_BASE + i, g_ff_page, sizeof(g_ff_page));
5050
}
5151
}
5252

53-
void reboot_to_payload(void) {
53+
void smc_reboot_to_payload(void) {
5454
clear_iram();
5555

5656
for (size_t i = 0; i < IRAM_PAYLOAD_MAX_SIZE; i += 0x1000) {

common/reboot_to_payload.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
extern "C" {
2222
#endif
2323

24-
#define IRAM_PAYLOAD_MAX_SIZE 0x2F000
24+
#define IRAM_PAYLOAD_MAX_SIZE 0x24000
2525

2626
extern u8 g_reboot_payload[IRAM_PAYLOAD_MAX_SIZE];
2727

28-
void reboot_to_payload(void);
28+
void smc_reboot_to_payload(void);
2929

3030
#ifdef __cplusplus
3131
}

overlay/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,11 @@ class PancakeOverlay final : public tsl::Overlay {
122122
virtual void initServices() override {
123123
fsdevMountSdmc();
124124
splInitialize();
125+
spsmInitialize();
125126
}
126127

127128
virtual void exitServices() override {
129+
spsmExit();
128130
splExit();
129131
fsdevUnmountAll();
130132
}

0 commit comments

Comments
 (0)