diff --git a/bootloader/hos/hos.h b/bootloader/hos/hos.h index d3c82e6..6378738 100644 --- a/bootloader/hos/hos.h +++ b/bootloader/hos/hos.h @@ -97,11 +97,11 @@ typedef struct _launch_ctxt_t bool debugmode; bool stock; bool atmosphere; - bool exo_no_user_exceptions; - bool exo_user_pmu; bool fss0_enable_experimental; bool emummc_forced; + exo_ctxt_t exo_cfg; + ini_sec_t *cfg; } launch_ctxt_t; diff --git a/bootloader/hos/hos_config.c b/bootloader/hos/hos_config.c index a3f8363..4c3d789 100644 --- a/bootloader/hos/hos_config.c +++ b/bootloader/hos/hos_config.c @@ -205,7 +205,7 @@ static int _config_dis_exo_user_exceptions(launch_ctxt_t *ctxt, const char *valu if (*value == '1') { DPRINTF("Disabled exosphere user exception handlers\n"); - ctxt->exo_no_user_exceptions = true; + ctxt->exo_cfg.no_user_exceptions = true; } return 1; } @@ -215,11 +215,38 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value) if (*value == '1') { DPRINTF("Enabled user access to PMU\n"); - ctxt->exo_user_pmu = true; + ctxt->exo_cfg.user_pmu = true; } return 1; } +static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value) +{ + // Override key found. + ctxt->exo_cfg.cal0_blank = calloc(1, 1); + + if (*value == '1') + { + DPRINTF("Enabled prodinfo blanking\n"); + *ctxt->exo_cfg.cal0_blank = true; + } + return 1; +} + +static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value) +{ + // Override key found. + ctxt->exo_cfg.cal0_allow_writes_sys = calloc(1, 1); + + if (*value == '1') + { + DPRINTF("Enabled prodinfo writes\n"); + *ctxt->exo_cfg.cal0_allow_writes_sys = true; + } + + return 1; +} + static int _config_fss(launch_ctxt_t *ctxt, const char *value) { LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link) @@ -254,6 +281,8 @@ static const cfg_handler_t _config_handlers[] = { { "emummcforce", _config_emummc_forced }, { "nouserexceptions", _config_dis_exo_user_exceptions }, { "userpmu", _config_exo_user_pmu_access }, + { "cal0blank", _config_exo_cal0_blanking }, + { "cal0writesys", _config_exo_cal0_writes_enable }, { NULL, NULL }, }; @@ -264,11 +293,15 @@ int parse_boot_config(launch_ctxt_t *ctxt) for(u32 i = 0; _config_handlers[i].key; i++) { if (!strcmp(_config_handlers[i].key, kv->key)) + { if (!_config_handlers[i].handler(ctxt, kv->val)) { + gfx_con.mute = false; EPRINTFARGS("Error while loading %s:\n%s", kv->key, kv->val); + return 0; } + } } } diff --git a/bootloader/hos/secmon_exo.c b/bootloader/hos/secmon_exo.c index b396117..60e062b 100644 --- a/bootloader/hos/secmon_exo.c +++ b/bootloader/hos/secmon_exo.c @@ -130,17 +130,22 @@ typedef struct _atm_fatal_error_ctx // Exosphère mailbox defines. #define EXO_CFG_ADDR 0x8000F000 -#define EXO_MAGIC_VAL 0x304F5845 -#define EXO_FLAG_DBG_PRIV (1 << 1) -#define EXO_FLAG_DBG_USER (1 << 2) -#define EXO_FLAG_NO_USER_EXC (1 << 3) -#define EXO_FLAG_USER_PMU (1 << 4) +#define EXO_MAGIC_VAL 0x304F5845 +#define EXO_FLAG_DBG_PRIV (1 << 1) +#define EXO_FLAG_DBG_USER (1 << 2) +#define EXO_FLAG_NO_USER_EXC (1 << 3) +#define EXO_FLAG_USER_PMU (1 << 4) +#define EXO_FLAG_CAL0_BLANKING (1 << 5) +#define EXO_FLAG_CAL0_WRITES_SYS (1 << 6) void config_exosphere(launch_ctxt_t *ctxt) { u32 exoFwNo = 0; u32 exoFlags = 0; u32 kb = ctxt->pkg1_id->kb; + bool user_debug = false; + bool cal0_blanking = false; + bool cal0_allow_writes_sys = false; memset((exo_cfg_t *)EXO_CFG_ADDR, 0, sizeof(exo_cfg_t)); @@ -166,18 +171,66 @@ void config_exosphere(launch_ctxt_t *ctxt) break; } + if (!ctxt->stock) + { + // Parse exosphere.ini. + LIST_INIT(ini_sections); + if (ini_parse(&ini_sections, "exosphere.ini", false)) + { + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) + { + // Only parse exosphere section. + if (!(ini_sec->type == INI_CHOICE) || strcmp(ini_sec->name, "exosphere")) + continue; + + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + if (!strcmp("debugmode_user", kv->key)) + user_debug = atoi(kv->val); + else if (emu_cfg.enabled && !h_cfg.emummc_force_disable) + { + if (!strcmp("blank_prodinfo_emummc", kv->key)) + cal0_blanking = atoi(kv->val); + } + else + { + if (!strcmp("blank_prodinfo_sysmmc", kv->key)) + cal0_blanking = atoi(kv->val); + else if (!strcmp("allow_writing_to_cal_sysmmc", kv->key)) + cal0_allow_writes_sys = atoi(kv->val); + } + } + break; + } + } + } + // To avoid problems, make private debug mode always on if not semi-stock. if (!ctxt->stock || (emu_cfg.enabled && !h_cfg.emummc_force_disable)) exoFlags |= EXO_FLAG_DBG_PRIV; + // Enable user debug. + if (user_debug) + exoFlags |= EXO_FLAG_DBG_USER; + // Disable proper failure handling. - if (ctxt->exo_no_user_exceptions) + if (ctxt->exo_cfg.no_user_exceptions) exoFlags |= EXO_FLAG_NO_USER_EXC; // Enable user access to PMU. - if (ctxt->exo_user_pmu) + if (ctxt->exo_cfg.user_pmu) exoFlags |= EXO_FLAG_USER_PMU; + // Check if exo ini value is overridden and enable prodinfo blanking. + if ((ctxt->exo_cfg.cal0_blank && *ctxt->exo_cfg.cal0_blank) + || (!ctxt->exo_cfg.cal0_blank && cal0_blanking)) + exoFlags |= EXO_FLAG_CAL0_BLANKING; + + // Check if exo ini value is overridden and allow prodinfo writes. + if ((ctxt->exo_cfg.cal0_allow_writes_sys && *ctxt->exo_cfg.cal0_allow_writes_sys) + || (!ctxt->exo_cfg.cal0_allow_writes_sys && cal0_allow_writes_sys)) + exoFlags |= EXO_FLAG_CAL0_WRITES_SYS; + // Set mailbox values. exo_cfg->magic = EXO_MAGIC_VAL; exo_cfg->fwno = exoFwNo;