exo/fusee: hookup new prodinfo settings

This commit is contained in:
Michael Scire 2020-04-20 11:57:55 -07:00
parent 6ad0f0e7f2
commit 04bbeefd74
8 changed files with 171 additions and 34 deletions

View file

@ -5,16 +5,6 @@ stage2_mtc_path = atmosphere/fusee-mtc.bin
stage2_addr = 0xF0000000
stage2_entrypoint = 0xF0000000
[exosphere]
; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
debugmode = 1
debugmode_user = 0
; Note: Disabling usermode exception handlers will cause atmosphere to not fail gracefully under error conditions.
; Support will not be provided to users who disable these. If you do not know what you are doing, leave them on.
disable_user_exception_handlers = 0
; Note: It's currently unknown what effects enabling the usermode PMU register access may have on official code.
enable_user_pmu_access = 0
[stratosphere]
; To force-enable nogc, add nogc = 1
; To force-disable nogc, add nogc = 0

View file

@ -0,0 +1,45 @@
# Key: debugmode, default: 1.
# Desc: Controls whether kernel is debug mode.
# Disabling this may break Atmosphere's debugger in a future release.
# Key: debugmode_user, default: 0.
# Desc: Controls whether userland is debug mode.
# Key: disable_user_exception_handlers, default: 0.
# Desc: Controls whether user exception handlers are executed on error.
# NOTE: This will cause atmosphere to not fail gracefully.
# Support may not be provided to users tho disable these.
# If you do not know what you are doing, leave them on.
# Key: enable_user_pmu_access, default: 0.
# Desc: Controls whether userland has access to the PMU registers.
# NOTE: It is unknown what effects this has on official code.
# Key: blank_prodinfo_sysmmc, default: 0.
# Desc: Controls whether PRODINFO should be blanked in sysmmc.
# This will cause the system to see dummied out keys and
# serial number information.
# NOTE: This is not known to be safe, as data may be
# cached elsewhere in the system. Usage is not encouraged.
# Key: blank_prodinfo_emummc, default: 0.
# Desc: Controls whether PRODINFO should be blanked in emummc.
# NOTE: This is not known to be safe, as data may be
# cached elsewhere in the system. Usage is not encouraged.
# Key: allow_writing_to_cal_sysmmc, default: 0.
# Desc: Controls whether PRODINFO can be written by homebrew in sysmmc.
# NOTE: Usage of this setting is strongly discouraged without
# a safe backup elsewhere. Turning this on will also cause Atmosphere
# to ensure a safe backup of calibration data is stored in unused
# mmc space, encrypted to prevent detection. This backup can be used
# to prevent unrecoverable edits in emergencies.
[exosphere]
debugmode=1
debugmode_user=0
disable_user_exception_handlers=0
enable_user_pmu_access=0
blank_prodinfo_sysmmc=0
blank_prodinfo_emummc=0
allow_writing_to_cal_sysmmc=0

View file

@ -290,7 +290,15 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_HAS_RCM_BUG_PATCH:
/* UNOFFICIAL: Gets whether this unit has the RCM bug patched. */
*p_outvalue = (int)(fuse_has_rcm_bug_patch());;
*p_outvalue = (int)(fuse_has_rcm_bug_patch());
break;
case CONFIGITEM_SHOULD_BLANK_PRODINFO:
/* UNOFFICIAL: Gets whether this unit should simulate a "blanked" PRODINFO. */
*p_outvalue = exosphere_should_blank_prodinfo();
break;
case CONFIGITEM_ALLOW_CAL_WRITES:
/* UNOFFICIAL: Gets whether this unit should allow writing to the calibration partition. */
*p_outvalue = exosphere_should_allow_writing_to_cal();
break;
default:
result = 2;

View file

@ -45,6 +45,8 @@ typedef enum {
CONFIGITEM_NEEDS_SHUTDOWN = 65002,
CONFIGITEM_EXOSPHERE_VERHASH = 65003,
CONFIGITEM_HAS_RCM_BUG_PATCH = 65004,
CONFIGITEM_SHOULD_BLANK_PRODINFO = 65005,
CONFIGITEM_ALLOW_CAL_WRITES = 65006,
} ConfigItem;
#define REBOOT_KIND_NO_REBOOT 0

View file

@ -27,6 +27,9 @@ static bool g_has_loaded_config = false;
#define EXOSPHERE_CHECK_FLAG(flag) ((g_exosphere_cfg.flags & flag) != 0)
static unsigned int exosphere_is_emummc() {
return g_exosphere_cfg.emummc_cfg.base_cfg.magic == MAGIC_EMUMMC_CONFIG && g_exosphere_cfg.emummc_cfg.base_cfg.type != EMUMMC_TYPE_NONE;
}
/* Read config out of IRAM, return target firmware version. */
unsigned int exosphere_load_config(void) {
@ -92,6 +95,30 @@ unsigned int exosphere_should_enable_usermode_pmu_access(void) {
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS);
}
unsigned int exosphere_should_blank_prodinfo(void) {
if (!g_has_loaded_config) {
generic_panic();
}
if (exosphere_is_emummc()) {
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_BLANK_PRODINFO_EMUMMC);
} else {
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_BLANK_PRODINFO_SYSMMC);
}
}
unsigned int exosphere_should_allow_writing_to_cal(void) {
if (!g_has_loaded_config) {
generic_panic();
}
if (exosphere_is_emummc()) {
return 1;
} else {
return 0;
}
}
const exo_emummc_config_t *exosphere_get_emummc_config(void) {
if (!g_has_loaded_config) {
generic_panic();

View file

@ -41,6 +41,9 @@
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
#define EXOSPHERE_FLAG_BLANK_PRODINFO_SYSMMC (1 << 5u)
#define EXOSPHERE_FLAG_BLANK_PRODINFO_EMUMMC (1 << 6u)
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 7u)
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
typedef struct {
@ -60,6 +63,8 @@ unsigned int exosphere_should_override_debugmode_priv(void);
unsigned int exosphere_should_override_debugmode_user(void);
unsigned int exosphere_should_disable_usermode_exception_handlers(void);
unsigned int exosphere_should_enable_usermode_pmu_access(void);
unsigned int exosphere_should_blank_prodinfo(void);
unsigned int exosphere_should_allow_writing_to_cal(void);
const exo_emummc_config_t *exosphere_get_emummc_config(void);

View file

@ -31,6 +31,9 @@
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
#define EXOSPHERE_FLAG_BLANK_PRODINFO_SYSMMC (1 << 5u)
#define EXOSPHERE_FLAG_BLANK_PRODINFO_EMUMMC (1 << 6u)
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 7u)
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
typedef struct {
@ -50,5 +53,18 @@ _Static_assert(sizeof(exosphere_config_t) == 0x20 + sizeof(exo_emummc_config_t),
#define EXOSPHERE_DEBUGMODE_USER_KEY "debugmode_user"
#define EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY "disable_user_exception_handlers"
#define EXOSPHERE_ENABLE_USERMODE_PMU_ACCESS_KEY "enable_user_pmu_access"
#define EXOSPHERE_BLANK_PRODINFO_SYSMMC_KEY "blank_prodinfo_sysmmc"
#define EXOSPHERE_BLANK_PRODINFO_EMUMMC_KEY "blank_prodinfo_emummc"
#define EXOSPHERE_ALLOW_WRITING_TO_CAL_SYSMMC_KEY "allow_writing_to_cal_sysmmc"
#endif
typedef struct {
int debugmode;
int debugmode_user;
int disable_user_exception_handlers;
int enable_user_pmu_access;
int blank_prodinfo_sysmmc;
int blank_prodinfo_emummc;
int allow_writing_to_cal_sysmmc;
} exosphere_parse_cfg_t;
#endif

View file

@ -134,38 +134,57 @@ static int emummc_ini_handler(void *user, const char *section, const char *name,
}
static int exosphere_ini_handler(void *user, const char *section, const char *name, const char *value) {
exosphere_config_t *exo_cfg = (exosphere_config_t *)user;
exosphere_parse_cfg_t *parse_cfg = (exosphere_parse_cfg_t *)user;
int tmp = 0;
if (strcmp(section, "exosphere") == 0) {
if (strcmp(name, EXOSPHERE_TARGETFW_KEY) == 0) {
sscanf(value, "%ld", &exo_cfg->target_firmware);
} else if (strcmp(name, EXOSPHERE_DEBUGMODE_PRIV_KEY) == 0) {
if (strcmp(name, EXOSPHERE_DEBUGMODE_PRIV_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp) {
exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
} else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV);
if (tmp == 1) {
parse_cfg->debugmode = 1;
} else if (tmp == 0) {
parse_cfg->debugmode = 0;
}
} else if (strcmp(name, EXOSPHERE_DEBUGMODE_USER_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp) {
exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
} else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_IS_DEBUGMODE_USER);
if (tmp == 1) {
parse_cfg->debugmode_user = 1;
} else if (tmp == 0) {
parse_cfg->debugmode_user = 0;
}
} else if (strcmp(name, EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp) {
exo_cfg->flags |= EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS;
} else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
if (tmp == 1) {
parse_cfg->disable_user_exception_handlers = 1;
} else if (tmp == 0) {
parse_cfg->disable_user_exception_handlers = 0;
}
} else if (strcmp(name, EXOSPHERE_ENABLE_USERMODE_PMU_ACCESS_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp) {
exo_cfg->flags |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS;
} else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS);
if (tmp == 1) {
parse_cfg->enable_user_pmu_access = 1;
} else if (tmp == 0) {
parse_cfg->enable_user_pmu_access = 0;
}
} else if (strcmp(name, EXOSPHERE_BLANK_PRODINFO_SYSMMC_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp == 1) {
parse_cfg->enable_user_pmu_access = 1;
} else if (tmp == 0) {
parse_cfg->enable_user_pmu_access = 0;
}
} else if (strcmp(name, EXOSPHERE_BLANK_PRODINFO_EMUMMC_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp == 1) {
parse_cfg->enable_user_pmu_access = 1;
} else if (tmp == 0) {
parse_cfg->enable_user_pmu_access = 0;
}
} else if (strcmp(name, EXOSPHERE_ALLOW_WRITING_TO_CAL_SYSMMC_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp == 1) {
parse_cfg->enable_user_pmu_access = 1;
} else if (tmp == 0) {
parse_cfg->enable_user_pmu_access = 0;
}
} else {
return 0;
@ -354,9 +373,34 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
exo_cfg.flags = EXOSPHERE_FLAGS_DEFAULT;
}
if (ini_parse_string(get_loader_ctx()->bct0, exosphere_ini_handler, &exo_cfg) < 0) {
fatal_error("[NXBOOT] Failed to parse BCT.ini!\n");
/* Setup exosphere parse configuration with defaults. */
exosphere_parse_cfg_t parse_cfg = {
.debugmode = 1,
.debugmode_user = 0,
.disable_user_exception_handlers = 0,
.enable_user_pmu_access = 0,
.blank_prodinfo_sysmmc = 0,
.blank_prodinfo_emummc = 0,
.allow_writing_to_cal_sysmmc = 0,
};
/* If we have an ini to read, parse it. */
char *exosphere_ini = calloc(1, 0x10000);
if (read_from_file(exosphere_ini, 0xFFFF, "exosphere.ini")) {
if (ini_parse_string(exosphere_ini, exosphere_ini_handler, &parse_cfg) < 0) {
fatal_error("[NXBOOT] Failed to parse exosphere.ini!\n");
}
}
free(exosphere_ini);
/* Apply parse config. */
if (parse_cfg.debugmode) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
if (parse_cfg.debugmode_user) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
if (parse_cfg.disable_user_exception_handlers) exo_cfg.flags |= EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS;
if (parse_cfg.enable_user_pmu_access) exo_cfg.flags |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS;
if (parse_cfg.blank_prodinfo_sysmmc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO_SYSMMC;
if (parse_cfg.blank_prodinfo_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO_EMUMMC;
if (parse_cfg.allow_writing_to_cal_sysmmc) exo_cfg.flags |= EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC;
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");