mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
Merge branch 'master' into emunand_dev
This commit is contained in:
commit
a1512cf30f
31 changed files with 351 additions and 20 deletions
1
Makefile
1
Makefile
|
@ -53,6 +53,7 @@ dist: all
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
|
||||||
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
||||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 8
|
#define ATMOSPHERE_RELEASE_VERSION_MINOR 8
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 6
|
#define ATMOSPHERE_RELEASE_VERSION_MICRO 7
|
||||||
|
|
||||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 7
|
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 7
|
||||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
||||||
|
|
|
@ -1,4 +1,19 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
## 0.8.7
|
||||||
|
+ A few bugs were fixed that could cause fatal to fail to show an error under certain circumstances.
|
||||||
|
+ A bug was fixed that caused an error when launching certain games (e.g. Hellblade: Senua's Sacrifice).
|
||||||
|
+ Loader had support added in ams-0.8.4 for a new (7.0.0+) flag bit in NPDMs during process creation, but forgot to allow this bit to be set when validating the NPDM.
|
||||||
|
+ dmnt's cheat virtual machine received new instructions.
|
||||||
|
+ These allow for saving, restoring, or clearing registers to a secondary bank, effectively doubling the number of values that can be stored.
|
||||||
|
+ SHA256 code has been swapped from linux code to libnx's new hw-accelerated cryptography API.
|
||||||
|
+ Extensions were added to smcGetInfo:
|
||||||
|
+ A ConfigItem was added to detect whether the current unit has the RCM bug patched.
|
||||||
|
+ A ConfigItem was added to retrieve the current Atmosphère build hash.
|
||||||
|
+ Exosphère now tells the kernel to enable user-mode exception handlers, which should allow for better crash reporting/detection from Atmosphère's modules in the future..
|
||||||
|
+ Opt-in support was added for redirecting game save files to directories on the SD card.
|
||||||
|
+ Please note, this feature is **experimental**, and may cause problems. Please use at your own risk (and back up your saves before enabling it), as it still needs testing.
|
||||||
|
+ This can be enabled by setting `atmosphere!fsmitm_redirect_saves_to_sd` to 1 in `system_settings.ini`.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 0.8.6
|
## 0.8.6
|
||||||
+ A number of bugs were fixed, including:
|
+ A number of bugs were fixed, including:
|
||||||
+ A case of inverted logic was fixed in fs.mitm which prevented the flags system from working correctly.
|
+ A case of inverted logic was fixed in fs.mitm which prevented the flags system from working correctly.
|
||||||
|
|
|
@ -123,7 +123,7 @@ uint64_t bootconfig_get_memory_arrangement(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t bootconfig_get_kernel_memory_configuration(void) {
|
uint64_t bootconfig_get_kernel_configuration(void) {
|
||||||
if (bootconfig_is_debug_mode()) {
|
if (bootconfig_is_debug_mode()) {
|
||||||
uint64_t high_val = 0;
|
uint64_t high_val = 0;
|
||||||
if (fuse_get_dram_id() == 4) {
|
if (fuse_get_dram_id() == 4) {
|
||||||
|
|
|
@ -21,6 +21,14 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "memory_map.h"
|
#include "memory_map.h"
|
||||||
|
|
||||||
|
/* This is kind of ConfigItem, but it's stored in BootConfig, so... */
|
||||||
|
typedef enum {
|
||||||
|
KERNELCONFIGFLAG_INITIALIZE_MEMORY_TO_PATTERN = (1 << 0),
|
||||||
|
KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS = (1 << 1),
|
||||||
|
KERNELCONFIGFLAG_ENABLE_USER_PMU_ACCESS = (1 << 2),
|
||||||
|
KERNELCONFIGFLAG_CALL_SMC_PANIC_ON_KERNEL_ERROR = (1 << 8),
|
||||||
|
} KernelConfigFlag;
|
||||||
|
|
||||||
/* This provides management for Switch BootConfig. */
|
/* This provides management for Switch BootConfig. */
|
||||||
|
|
||||||
#define LOADED_BOOTCONFIG (get_loaded_bootconfig())
|
#define LOADED_BOOTCONFIG (get_loaded_bootconfig())
|
||||||
|
@ -78,7 +86,7 @@ bool bootconfig_take_extabt_serror_to_el3(void);
|
||||||
uint64_t bootconfig_get_value_for_sysctr0(void);
|
uint64_t bootconfig_get_value_for_sysctr0(void);
|
||||||
|
|
||||||
uint64_t bootconfig_get_memory_arrangement(void);
|
uint64_t bootconfig_get_memory_arrangement(void);
|
||||||
uint64_t bootconfig_get_kernel_memory_configuration(void);
|
uint64_t bootconfig_get_kernel_configuration(void);
|
||||||
|
|
||||||
bool bootconfig_is_recovery_boot(void);
|
bool bootconfig_is_recovery_boot(void);
|
||||||
uint64_t bootconfig_get_boot_reason(void);
|
uint64_t bootconfig_get_boot_reason(void);
|
||||||
|
|
|
@ -206,8 +206,13 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
|
||||||
*p_outvalue = (int)(bootconfig_is_debug_mode());
|
*p_outvalue = (int)(bootconfig_is_debug_mode());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_KERNELMEMORYCONFIGURATION:
|
case CONFIGITEM_KERNELCONFIGURATION:
|
||||||
*p_outvalue = bootconfig_get_kernel_memory_configuration();
|
{
|
||||||
|
uint64_t config = bootconfig_get_kernel_configuration();
|
||||||
|
/* Always enable usermode exception handlers. */
|
||||||
|
config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS;
|
||||||
|
*p_outvalue = config;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_BATTERYPROFILE:
|
case CONFIGITEM_BATTERYPROFILE:
|
||||||
*p_outvalue = (int)g_battery_profile;
|
*p_outvalue = (int)g_battery_profile;
|
||||||
|
|
|
@ -32,7 +32,7 @@ typedef enum {
|
||||||
CONFIGITEM_BOOTREASON = 9,
|
CONFIGITEM_BOOTREASON = 9,
|
||||||
CONFIGITEM_MEMORYARRANGE = 10,
|
CONFIGITEM_MEMORYARRANGE = 10,
|
||||||
CONFIGITEM_ISDEBUGMODE = 11,
|
CONFIGITEM_ISDEBUGMODE = 11,
|
||||||
CONFIGITEM_KERNELMEMORYCONFIGURATION = 12,
|
CONFIGITEM_KERNELCONFIGURATION = 12,
|
||||||
CONFIGITEM_BATTERYPROFILE = 13,
|
CONFIGITEM_BATTERYPROFILE = 13,
|
||||||
CONFIGITEM_ISQUESTUNIT = 14,
|
CONFIGITEM_ISQUESTUNIT = 14,
|
||||||
CONFIGITEM_NEWHARDWARETYPE_5X = 15,
|
CONFIGITEM_NEWHARDWARETYPE_5X = 15,
|
||||||
|
|
|
@ -90,9 +90,6 @@ static void setup_env(void) {
|
||||||
/* Initialize hardware. */
|
/* Initialize hardware. */
|
||||||
nx_hwinit();
|
nx_hwinit();
|
||||||
|
|
||||||
/* Check for panics. */
|
|
||||||
check_and_display_panic();
|
|
||||||
|
|
||||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||||
video_init(g_framebuffer);
|
video_init(g_framebuffer);
|
||||||
|
|
||||||
|
@ -138,6 +135,9 @@ int main(void) {
|
||||||
|
|
||||||
/* Initialize the display, console, etc. */
|
/* Initialize the display, console, etc. */
|
||||||
setup_env();
|
setup_env();
|
||||||
|
|
||||||
|
/* Check for panics. */
|
||||||
|
check_and_display_panic();
|
||||||
|
|
||||||
/* Load the BCT0 configuration ini off of the SD. */
|
/* Load the BCT0 configuration ini off of the SD. */
|
||||||
bct0 = load_config();
|
bct0 = load_config();
|
||||||
|
|
|
@ -14,15 +14,75 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "di.h"
|
#include "di.h"
|
||||||
#include "pmc.h"
|
#include "pmc.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "fs_utils.h"
|
||||||
|
#include "lib/log.h"
|
||||||
|
|
||||||
static uint32_t g_panic_code = 0;
|
static uint32_t g_panic_code = 0;
|
||||||
|
|
||||||
|
static const char *get_error_desc_str(uint32_t error_desc) {
|
||||||
|
switch (error_desc) {
|
||||||
|
case 0x100:
|
||||||
|
return "Instruction Abort";
|
||||||
|
case 0x101:
|
||||||
|
return "Data Abort";
|
||||||
|
case 0x102:
|
||||||
|
return "PC Misalignment";
|
||||||
|
case 0x103:
|
||||||
|
return "SP Misalignment";
|
||||||
|
case 0x104:
|
||||||
|
return "Trap";
|
||||||
|
case 0x106:
|
||||||
|
return "SError";
|
||||||
|
case 0x301:
|
||||||
|
return "Bad SVC";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _check_and_display_atmosphere_fatal_error(void) {
|
||||||
|
/* Check for valid magic. */
|
||||||
|
if (ATMOSPHERE_FATAL_ERROR_CONTEXT->magic != ATMOSPHERE_REBOOT_TO_FATAL_MAGIC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Copy fatal error context to the stack. */
|
||||||
|
atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT);
|
||||||
|
|
||||||
|
/* Change magic to invalid, to prevent double-display of error/bootlooping. */
|
||||||
|
ATMOSPHERE_FATAL_ERROR_CONTEXT->magic = 0xCCCCCCCC;
|
||||||
|
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "A fatal error occurred when running Atmosph\xe8re.\n");
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Title ID: %016llx\n", ctx.title_id);
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Error Desc: %s (0x%x)\n", get_error_desc_str(ctx.error_desc), ctx.error_desc);
|
||||||
|
|
||||||
|
/* Save context to the SD card. */
|
||||||
|
{
|
||||||
|
char filepath[0x40];
|
||||||
|
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
|
||||||
|
filepath[sizeof(filepath)-1] = 0;
|
||||||
|
write_to_file(&ctx, sizeof(ctx), filepath);
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"Report saved to %s\n", filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display error. */
|
||||||
|
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_button_and_reboot();
|
||||||
|
}
|
||||||
|
|
||||||
void check_and_display_panic(void) {
|
void check_and_display_panic(void) {
|
||||||
|
/* Handle a panic sent via a stratosphere module. */
|
||||||
|
_check_and_display_atmosphere_fatal_error();
|
||||||
|
|
||||||
/* We also handle our own panics. */
|
/* We also handle our own panics. */
|
||||||
/* In the case of our own panics, we assume that the display has already been initialized. */
|
/* In the case of our own panics, we assume that the display has already been initialized. */
|
||||||
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
|
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
|
||||||
|
|
|
@ -28,6 +28,35 @@
|
||||||
|
|
||||||
#define PANIC_CODE_SAFEMODE 0x00000020
|
#define PANIC_CODE_SAFEMODE 0x00000020
|
||||||
|
|
||||||
|
/* Atmosphere reboot-to-fatal-error. */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t error_desc;
|
||||||
|
uint64_t title_id;
|
||||||
|
union {
|
||||||
|
uint64_t gprs[32];
|
||||||
|
struct {
|
||||||
|
uint64_t _gprs[29];
|
||||||
|
uint64_t fp;
|
||||||
|
uint64_t lr;
|
||||||
|
uint64_t sp;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
uint64_t pc;
|
||||||
|
uint64_t padding;
|
||||||
|
uint32_t pstate;
|
||||||
|
uint32_t afsr0;
|
||||||
|
uint32_t afsr1;
|
||||||
|
uint32_t esr;
|
||||||
|
uint64_t far;
|
||||||
|
uint64_t report_identifier; /* Normally just system tick. */
|
||||||
|
} atmosphere_fatal_error_ctx;
|
||||||
|
|
||||||
|
/* "AFE0" */
|
||||||
|
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x30454641
|
||||||
|
|
||||||
|
#define ATMOSPHERE_FATAL_ERROR_CONTEXT ((volatile atmosphere_fatal_error_ctx *)(0x4003E000))
|
||||||
|
|
||||||
void check_and_display_panic(void);
|
void check_and_display_panic(void);
|
||||||
__attribute__ ((noreturn)) void panic(uint32_t code);
|
__attribute__ ((noreturn)) void panic(uint32_t code);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
||||||
"svcUnmapDeviceAddressSpace": "0x5c",
|
"svcUnmapDeviceAddressSpace": "0x5c",
|
||||||
"svcGetSystemInfo": "0x6f",
|
"svcGetSystemInfo": "0x6f",
|
||||||
|
"svcManageNamedPort": "0x71",
|
||||||
"svcCallSecureMonitor": "0x7F"
|
"svcCallSecureMonitor": "0x7F"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,23 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = 0x010041544D530000ul;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) {
|
||||||
|
/* We're bpc-mitm (or ams_mitm, anyway), so manually reboot to fatal error. */
|
||||||
|
Utils::RebootToFatalError(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void __libnx_initheap(void) {
|
void __libnx_initheap(void) {
|
||||||
void* addr = nx_inner_heap;
|
void* addr = nx_inner_heap;
|
||||||
|
|
32
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp
Normal file
32
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "bpc_ams_service.hpp"
|
||||||
|
#include "bpcmitm_reboot_manager.hpp"
|
||||||
|
|
||||||
|
Result BpcAtmosphereService::RebootToFatalError(InBuffer<AtmosphereFatalErrorContext> ctx) {
|
||||||
|
if (ctx.buffer == nullptr || ctx.num_elements != 1) {
|
||||||
|
return ResultKernelConnectionClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reboot to fusee with the input context. */
|
||||||
|
BpcRebootManager::RebootForFatalError(ctx.buffer);
|
||||||
|
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
34
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.hpp
Normal file
34
stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
#include "../utils.hpp"
|
||||||
|
|
||||||
|
enum BpcAtmosphereCmd : u32 {
|
||||||
|
BpcAtmosphereCmd_RebootToFatalError = 65000,
|
||||||
|
};
|
||||||
|
|
||||||
|
class BpcAtmosphereService : public IServiceObject {
|
||||||
|
private:
|
||||||
|
Result RebootToFatalError(InBuffer<AtmosphereFatalErrorContext> ctx);
|
||||||
|
public:
|
||||||
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
|
MakeServiceCommandMeta<BpcAtmosphereCmd_RebootToFatalError, &BpcAtmosphereService::RebootToFatalError>(),
|
||||||
|
};
|
||||||
|
};
|
|
@ -25,7 +25,7 @@ enum BpcCmd : u32 {
|
||||||
BpcCmd_RebootSystem = 1,
|
BpcCmd_RebootSystem = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BpcMitmService : public IMitmServiceObject {
|
class BpcMitmService : public IMitmServiceObject {
|
||||||
public:
|
public:
|
||||||
BpcMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
BpcMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
||||||
/* ... */
|
/* ... */
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "bpcmitm_main.hpp"
|
#include "bpcmitm_main.hpp"
|
||||||
#include "bpc_mitm_service.hpp"
|
#include "bpc_mitm_service.hpp"
|
||||||
|
#include "bpc_ams_service.hpp"
|
||||||
#include "bpcmitm_reboot_manager.hpp"
|
#include "bpcmitm_reboot_manager.hpp"
|
||||||
|
|
||||||
#include "../utils.hpp"
|
#include "../utils.hpp"
|
||||||
|
@ -46,6 +47,10 @@ void BpcMitmMain(void *arg) {
|
||||||
}
|
}
|
||||||
AddMitmServerToManager<BpcMitmService>(server_manager, service_name, 13);
|
AddMitmServerToManager<BpcMitmService>(server_manager, service_name, 13);
|
||||||
|
|
||||||
|
/* Extension: Allow for reboot-to-error. */
|
||||||
|
/* Must be managed port in order for sm to be able to access. */
|
||||||
|
server_manager->AddWaitable(new ManagedPortServer<BpcAtmosphereService>("bpc:ams", 1));
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
/* Loop forever, servicing our services. */
|
||||||
server_manager->Process();
|
server_manager->Process();
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ static void ClearIram() {
|
||||||
memset(g_work_page, 0xFF, sizeof(g_work_page));
|
memset(g_work_page, 0xFF, sizeof(g_work_page));
|
||||||
|
|
||||||
/* Overwrite all of IRAM with FFs. */
|
/* Overwrite all of IRAM with FFs. */
|
||||||
for (size_t ofs = 0; ofs < IRAM_PAYLOAD_MAX_SIZE; ofs += sizeof(g_work_page)) {
|
for (size_t ofs = 0; ofs < IRAM_SIZE; ofs += sizeof(g_work_page)) {
|
||||||
CopyToIram(IRAM_PAYLOAD_BASE + ofs, g_work_page, sizeof(g_work_page));
|
CopyToIram(IRAM_BASE + ofs, g_work_page, sizeof(g_work_page));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,3 +99,24 @@ Result BpcRebootManager::PerformReboot() {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BpcRebootManager::RebootForFatalError(AtmosphereFatalErrorContext *ctx) {
|
||||||
|
/* If we don't actually have a payload loaded, just go to RCM. */
|
||||||
|
if (!g_payload_loaded) {
|
||||||
|
RebootToRcm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure clean IRAM state. */
|
||||||
|
ClearIram();
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy in payload. */
|
||||||
|
for (size_t ofs = 0; ofs < sizeof(g_reboot_payload); ofs += 0x1000) {
|
||||||
|
CopyToIram(IRAM_PAYLOAD_BASE + ofs, &g_reboot_payload[ofs], 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(g_work_page, ctx, sizeof(*ctx));
|
||||||
|
CopyToIram(IRAM_PAYLOAD_BASE + IRAM_PAYLOAD_MAX_SIZE, g_work_page, sizeof(g_work_page));
|
||||||
|
|
||||||
|
RebootToIramPayload();
|
||||||
|
}
|
|
@ -18,7 +18,9 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#define IRAM_PAYLOAD_MAX_SIZE 0x2F000
|
#define IRAM_BASE 0x40000000ull
|
||||||
|
#define IRAM_SIZE 0x40000
|
||||||
|
#define IRAM_PAYLOAD_MAX_SIZE 0x2E000
|
||||||
#define IRAM_PAYLOAD_BASE 0x40010000ull
|
#define IRAM_PAYLOAD_BASE 0x40010000ull
|
||||||
|
|
||||||
enum class BpcRebootType : u32 {
|
enum class BpcRebootType : u32 {
|
||||||
|
@ -31,4 +33,5 @@ class BpcRebootManager {
|
||||||
public:
|
public:
|
||||||
static void Initialize();
|
static void Initialize();
|
||||||
static Result PerformReboot();
|
static Result PerformReboot();
|
||||||
|
static void RebootForFatalError(AtmosphereFatalErrorContext *ctx);
|
||||||
};
|
};
|
|
@ -25,6 +25,7 @@
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
|
|
||||||
#include "set_mitm/setsys_settings_items.hpp"
|
#include "set_mitm/setsys_settings_items.hpp"
|
||||||
|
#include "bpc_mitm/bpcmitm_reboot_manager.hpp"
|
||||||
|
|
||||||
static FsFileSystem g_sd_filesystem = {0};
|
static FsFileSystem g_sd_filesystem = {0};
|
||||||
static HosSignal g_sd_signal;
|
static HosSignal g_sd_signal;
|
||||||
|
@ -652,3 +653,7 @@ Result Utils::GetSettingsItemBooleanValue(const char *name, const char *key, boo
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::RebootToFatalError(AtmosphereFatalErrorContext *ctx) {
|
||||||
|
BpcRebootManager::RebootForFatalError(ctx);
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,9 @@ class Utils {
|
||||||
static Result GetSettingsItemValue(const char *name, const char *key, void *out, size_t max_size, u64 *out_size);
|
static Result GetSettingsItemValue(const char *name, const char *key, void *out, size_t max_size, u64 *out_size);
|
||||||
|
|
||||||
static Result GetSettingsItemBooleanValue(const char *name, const char *key, bool *out);
|
static Result GetSettingsItemBooleanValue(const char *name, const char *key, bool *out);
|
||||||
|
|
||||||
|
/* Error occurred. */
|
||||||
|
static void RebootToFatalError(AtmosphereFatalErrorContext *ctx);
|
||||||
private:
|
private:
|
||||||
static void RefreshConfiguration();
|
static void RefreshConfiguration();
|
||||||
};
|
};
|
|
@ -49,6 +49,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Boot;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __libnx_initheap(void) {
|
void __libnx_initheap(void) {
|
||||||
|
|
|
@ -136,7 +136,7 @@ bool CodeList::TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
guess -= 4;
|
guess = mi.addr - 4;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Creport;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Dmnt;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Eclct;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Fatal;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1f9e2d042cb028cee1777b3d63a7cda06d2cffd0
|
Subproject commit b9724cdcadd5ea5fbead8f1a9c9b7de11daf6b60
|
|
@ -41,6 +41,16 @@ extern "C" {
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Loader;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,9 +113,9 @@ struct LoaderServerOptions {
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
consoleDebugInit(debugDevice_SVC);
|
consoleDebugInit(debugDevice_SVC);
|
||||||
|
|
||||||
auto server_manager = new WaitableManager<LoaderServerOptions>(1);
|
auto server_manager = new WaitableManager<LoaderServerOptions>(1);
|
||||||
|
|
||||||
/* Add services to manager. */
|
/* Add services to manager. */
|
||||||
server_manager->AddWaitable(new ServiceServer<ProcessManagerService>("ldr:pm", 1));
|
server_manager->AddWaitable(new ServiceServer<ProcessManagerService>("ldr:pm", 1));
|
||||||
server_manager->AddWaitable(new ServiceServer<ShellService>("ldr:shel", 3));
|
server_manager->AddWaitable(new ServiceServer<ShellService>("ldr:shel", 3));
|
||||||
|
|
|
@ -117,8 +117,15 @@ Result NpdmUtils::LoadNpdmInternal(FILE *f_npdm, NpdmUtils::NpdmCache *cache) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->header->mmu_flags > 0xF) {
|
/* 7.0.0 added 0x10 as a valid bit to NPDM flags. */
|
||||||
return rc;
|
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_700) {
|
||||||
|
if (info->header->mmu_flags > 0x1F) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (info->header->mmu_flags > 0xF) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->header->aci0_offset < sizeof(NpdmUtils::NpdmHeader) || info->header->aci0_size < sizeof(NpdmUtils::NpdmAci0) || info->header->aci0_offset + info->header->aci0_size > npdm_size) {
|
if (info->header->aci0_offset < sizeof(NpdmUtils::NpdmHeader) || info->header->aci0_size < sizeof(NpdmUtils::NpdmAci0) || info->header->aci0_offset + info->header->aci0_size > npdm_size) {
|
||||||
|
|
|
@ -42,6 +42,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Pm;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,17 @@ extern "C" {
|
||||||
void __libnx_initheap(void);
|
void __libnx_initheap(void);
|
||||||
void __appInit(void);
|
void __appInit(void);
|
||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
|
/* Exception handling. */
|
||||||
|
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||||
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
u64 __stratosphere_title_id = TitleId_Sm;
|
||||||
|
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
|
StratosphereCrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,7 +84,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* TODO: What's a good timeout value to use here? */
|
/* TODO: What's a good timeout value to use here? */
|
||||||
auto server_manager = new WaitableManager(1);
|
auto server_manager = new WaitableManager(1);
|
||||||
|
|
||||||
/* Create sm:, (and thus allow things to register to it). */
|
/* Create sm:, (and thus allow things to register to it). */
|
||||||
server_manager->AddWaitable(new ManagedPortServer<UserService>("sm:", 0x40));
|
server_manager->AddWaitable(new ManagedPortServer<UserService>("sm:", 0x40));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue