Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84c776fa6b | ||
|
|
a21b5d453a | ||
|
|
0ef3368893 | ||
|
|
4827fd71b4 | ||
|
|
00aa283a54 | ||
|
|
ef373d954f | ||
|
|
d452d6f89d | ||
|
|
a51d355707 | ||
|
|
a79f4cf6f6 | ||
|
|
903789cf6e | ||
|
|
49ba3a86e2 | ||
|
|
021d84ff04 | ||
|
|
8ecf68cb65 | ||
|
|
bbed78149c | ||
|
|
3fa973f430 |
4
Makefile
4
Makefile
@@ -42,8 +42,8 @@ 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
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini
|
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/atmosphere/BCT.ini
|
||||||
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini
|
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini
|
||||||
cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
||||||
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
BCT0
|
BCT0
|
||||||
[stage1]
|
[stage1]
|
||||||
stage2_path = fusee-secondary.bin
|
stage2_path = atmosphere/fusee-secondary.bin
|
||||||
stage2_addr = 0xF0000000
|
stage2_addr = 0xF0000000
|
||||||
stage2_entrypoint = 0xF0000000
|
stage2_entrypoint = 0xF0000000
|
||||||
|
|
||||||
[exosphere]
|
[exosphere]
|
||||||
debugmode = 0
|
; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
|
||||||
|
debugmode = 1
|
||||||
debugmode_user = 0
|
debugmode_user = 0
|
||||||
|
|
||||||
[stratosphere]
|
[stratosphere]
|
||||||
|
|||||||
@@ -19,6 +19,6 @@
|
|||||||
|
|
||||||
#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 1
|
#define ATMOSPHERE_RELEASE_VERSION_MICRO 2
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,4 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## 0.8.2
|
||||||
|
+ A number of bugs were fixed causing users to sometimes see `Key Derivation Failed!`.
|
||||||
|
+ KFUSE clock enable timings have been adjusted to allow time to stabilize before TSEC is granted access.
|
||||||
|
+ A race condition was fixed that could cause wrong key data to be used on 6.2.0
|
||||||
|
+ The TSEC firmware is now retried on failure, fixing a failure affecting ~1/50 boots on 6.2.0.
|
||||||
|
+ A bug was fixed causing some modules to not work on firmware 1.0.0.
|
||||||
|
+ A bug was fixed causing sleep mode to not work with debugmode enabled.
|
||||||
|
+ As a result, debugmode is now enabled in the default BCT.ini.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 0.8.1
|
## 0.8.1
|
||||||
+ A bug was fixed causing users to see `Failed to enable SMMU!` if fusee had previously rebooted.
|
+ A bug was fixed causing users to see `Failed to enable SMMU!` if fusee had previously rebooted.
|
||||||
+ This message will still occur sporadically if fusee is not launched from coldboot, but it can never happen twice in a row.
|
+ This message will still occur sporadically if fusee is not launched from coldboot, but it can never happen twice in a row.
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "configitem.h"
|
#include "configitem.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "uart.h"
|
||||||
#include "bpmp.h"
|
#include "bpmp.h"
|
||||||
#include "sysreg.h"
|
#include "sysreg.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
@@ -213,6 +214,11 @@ void bootup_misc_mmio(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!g_has_booted_up) {
|
if (!g_has_booted_up) {
|
||||||
|
/* N doesn't do this, but we should for compatibility. */
|
||||||
|
uart_select(UART_A);
|
||||||
|
clkrst_reboot(CARDEVICE_UARTA);
|
||||||
|
uart_init(UART_A, 115200);
|
||||||
|
|
||||||
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
|
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
|
||||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);
|
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);
|
||||||
|
|||||||
@@ -72,6 +72,15 @@ bool configitem_should_profile_battery(void) {
|
|||||||
return g_battery_profile;
|
return g_battery_profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool configitem_is_debugmode_priv(void) {
|
||||||
|
uint64_t debugmode = 0;
|
||||||
|
if (configitem_get(true, CONFIGITEM_ISDEBUGMODE, &debugmode) != 0) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
return debugmode != 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t configitem_get_hardware_type(void) {
|
uint64_t configitem_get_hardware_type(void) {
|
||||||
uint64_t hardware_type;
|
uint64_t hardware_type;
|
||||||
if (configitem_get(true, CONFIGITEM_HARDWARETYPE, &hardware_type) != 0) {
|
if (configitem_get(true, CONFIGITEM_HARDWARETYPE, &hardware_type) != 0) {
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue);
|
|||||||
bool configitem_is_recovery_boot(void);
|
bool configitem_is_recovery_boot(void);
|
||||||
bool configitem_is_retail(void);
|
bool configitem_is_retail(void);
|
||||||
bool configitem_should_profile_battery(void);
|
bool configitem_should_profile_battery(void);
|
||||||
|
bool configitem_is_debugmode_priv(void);
|
||||||
|
|
||||||
void configitem_set_debugmode_override(bool user, bool priv);
|
void configitem_set_debugmode_override(bool user, bool priv);
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "smc_api.h"
|
#include "smc_api.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "uart.h"
|
||||||
#include "exocfg.h"
|
#include "exocfg.h"
|
||||||
|
|
||||||
#define u8 uint8_t
|
#define u8 uint8_t
|
||||||
@@ -241,7 +242,7 @@ void save_se_and_power_down_cpu(void) {
|
|||||||
save_se_state();
|
save_se_state();
|
||||||
|
|
||||||
if (!configitem_is_retail()) {
|
if (!configitem_is_retail()) {
|
||||||
/* TODO: uart_log("OYASUMI"); */
|
uart_send(UART_A, "OYASUMI", 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize_powerdown();
|
finalize_powerdown();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ static const uint8_t g_seal_key_sources[CRYPTOUSECASE_MAX_5X][0x10] = {
|
|||||||
{0x0E, 0xE0, 0xC4, 0x33, 0x82, 0x66, 0xE8, 0x08, 0x39, 0x13, 0x41, 0x7D, 0x04, 0x64, 0x2B, 0x6D},
|
{0x0E, 0xE0, 0xC4, 0x33, 0x82, 0x66, 0xE8, 0x08, 0x39, 0x13, 0x41, 0x7D, 0x04, 0x64, 0x2B, 0x6D},
|
||||||
{0xE1, 0xA8, 0xAA, 0x6A, 0x2D, 0x9C, 0xDE, 0x43, 0x0C, 0xDE, 0xC6, 0x17, 0xF6, 0xC7, 0xF1, 0xDE},
|
{0xE1, 0xA8, 0xAA, 0x6A, 0x2D, 0x9C, 0xDE, 0x43, 0x0C, 0xDE, 0xC6, 0x17, 0xF6, 0xC7, 0xF1, 0xDE},
|
||||||
{0x74, 0x20, 0xF6, 0x46, 0x77, 0xB0, 0x59, 0x2C, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9},
|
{0x74, 0x20, 0xF6, 0x46, 0x77, 0xB0, 0x59, 0x2C, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9},
|
||||||
{0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9}
|
{0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE6, 0xD8, 0x9A, 0xCF, 0xE5, 0x3F, 0xB3, 0x4B}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool usecase_is_invalid(unsigned int usecase) {
|
bool usecase_is_invalid(unsigned int usecase) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "uart.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
|
|
||||||
#include "pmc.h"
|
#include "pmc.h"
|
||||||
@@ -55,8 +56,16 @@ void __attribute__((noreturn)) warmboot_main(void) {
|
|||||||
|
|
||||||
/* On warmboot (not cpu_on) only */
|
/* On warmboot (not cpu_on) only */
|
||||||
if (VIRT_MC_SECURITY_CFG3 == 0) {
|
if (VIRT_MC_SECURITY_CFG3 == 0) {
|
||||||
|
/* N only does this on dev units, but we will do it unconditionally. */
|
||||||
|
{
|
||||||
|
uart_select(UART_A);
|
||||||
|
clkrst_reboot(CARDEVICE_UARTA);
|
||||||
|
uart_init(UART_A, 115200);
|
||||||
|
}
|
||||||
|
|
||||||
if (!configitem_is_retail()) {
|
if (!configitem_is_retail()) {
|
||||||
/* TODO: uart_log("OHAYO"); */
|
uart_send(UART_A, "OHAYO", 6);
|
||||||
|
uart_wait_idle(UART_A, UART_VENDOR_STATE_TX_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check the Security Engine. */
|
/* Sanity check the Security Engine. */
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
|
#include "timers.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||||
@@ -121,7 +122,15 @@ void clkrst_disable(CarDevice dev) {
|
|||||||
|
|
||||||
void clkrst_reboot(CarDevice dev) {
|
void clkrst_reboot(CarDevice dev) {
|
||||||
clkrst_disable(dev);
|
clkrst_disable(dev);
|
||||||
clkrst_enable(dev);
|
if (dev == CARDEVICE_KFUSE) {
|
||||||
|
/* Workaround for KFUSE clock. */
|
||||||
|
clk_enable(dev);
|
||||||
|
udelay(100);
|
||||||
|
rst_disable(dev);
|
||||||
|
udelay(200);
|
||||||
|
} else {
|
||||||
|
clkrst_enable(dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clkrst_enable_fuse_regs(bool enable) {
|
void clkrst_enable_fuse_regs(bool enable) {
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ static char g_bct0_buffer[BCTO_MAX_SIZE];
|
|||||||
#define DEFAULT_BCT0_FOR_DEBUG \
|
#define DEFAULT_BCT0_FOR_DEBUG \
|
||||||
"BCT0\n"\
|
"BCT0\n"\
|
||||||
"[stage1]\n"\
|
"[stage1]\n"\
|
||||||
"stage2_path = fusee-secondary.bin\n"\
|
"stage2_path = atmosphere/fusee-secondary.bin\n"\
|
||||||
"stage2_addr = 0xF0000000\n"\
|
"stage2_addr = 0xF0000000\n"\
|
||||||
"stage2_entrypoint = 0xF0000000\n"
|
"stage2_entrypoint = 0xF0000000\n"
|
||||||
|
|
||||||
static const char *load_config(void) {
|
static const char *load_config(void) {
|
||||||
if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "BCT.ini")) {
|
if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "atmosphere/BCT.ini")) {
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Failed to read BCT0 from SD!\n");
|
print(SCREEN_LOG_LEVEL_DEBUG, "Failed to read BCT0 from SD!\n");
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Using default BCT0!\n");
|
print(SCREEN_LOG_LEVEL_DEBUG, "Using default BCT0!\n");
|
||||||
memcpy(g_bct0_buffer, DEFAULT_BCT0_FOR_DEBUG, sizeof(DEFAULT_BCT0_FOR_DEBUG));
|
memcpy(g_bct0_buffer, DEFAULT_BCT0_FOR_DEBUG, sizeof(DEFAULT_BCT0_FOR_DEBUG));
|
||||||
@@ -133,6 +133,9 @@ int main(void) {
|
|||||||
uint32_t stage2_version = 0;
|
uint32_t stage2_version = 0;
|
||||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_MANDATORY;
|
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_MANDATORY;
|
||||||
|
|
||||||
|
/* Override the global logging level. */
|
||||||
|
log_set_log_level(log_level);
|
||||||
|
|
||||||
/* Initialize the display, console, etc. */
|
/* Initialize the display, console, etc. */
|
||||||
setup_env();
|
setup_env();
|
||||||
|
|
||||||
@@ -144,9 +147,6 @@ int main(void) {
|
|||||||
fatal_error("Failed to parse BCT.ini!\n");
|
fatal_error("Failed to parse BCT.ini!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Override the global logging level. */
|
|
||||||
log_set_log_level(log_level);
|
|
||||||
|
|
||||||
/* Say hello. */
|
/* Say hello. */
|
||||||
print(SCREEN_LOG_LEVEL_MANDATORY, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
print(SCREEN_LOG_LEVEL_MANDATORY, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
|
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
|
||||||
@@ -159,7 +159,7 @@ int main(void) {
|
|||||||
strcpy(g_chainloader_arg_data, stage2_path);
|
strcpy(g_chainloader_arg_data, stage2_path);
|
||||||
stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */
|
stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */
|
||||||
memcpy(&stage2_args->version, &stage2_version, 4);
|
memcpy(&stage2_args->version, &stage2_version, 4);
|
||||||
stage2_args->log_level = log_level;
|
memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
|
||||||
stage2_args->display_initialized = false;
|
stage2_args->display_initialized = false;
|
||||||
strcpy(stage2_args->bct0, bct0);
|
strcpy(stage2_args->bct0, bct0);
|
||||||
g_chainloader_argc = 2;
|
g_chainloader_argc = 2;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
|
#include "timers.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||||
@@ -121,7 +122,15 @@ void clkrst_disable(CarDevice dev) {
|
|||||||
|
|
||||||
void clkrst_reboot(CarDevice dev) {
|
void clkrst_reboot(CarDevice dev) {
|
||||||
clkrst_disable(dev);
|
clkrst_disable(dev);
|
||||||
clkrst_enable(dev);
|
if (dev == CARDEVICE_KFUSE) {
|
||||||
|
/* Workaround for KFUSE clock. */
|
||||||
|
clk_enable(dev);
|
||||||
|
udelay(100);
|
||||||
|
rst_disable(dev);
|
||||||
|
udelay(200);
|
||||||
|
} else {
|
||||||
|
clkrst_enable(dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clkrst_enable_fuse_regs(bool enable) {
|
void clkrst_enable_fuse_regs(bool enable) {
|
||||||
|
|||||||
@@ -442,6 +442,11 @@ static const kernel_hook_t g_kernel_hooks_600[] = {
|
|||||||
|
|
||||||
/* Kernel Infos. */
|
/* Kernel Infos. */
|
||||||
static const kernel_info_t g_kernel_infos[] = {
|
static const kernel_info_t g_kernel_infos[] = {
|
||||||
|
{ /* 1.0.0-7. */
|
||||||
|
.hash = {0x64, 0x44, 0x07, 0x2F, 0x56, 0x44, 0x73, 0xDD, 0xD5, 0x46, 0x1B, 0x8C, 0xDC, 0xEF, 0x54, 0x98, 0x16, 0xDA, 0x81, 0xDE, 0x5B, 0x1C, 0x9D, 0xD7, 0x5A, 0x13, 0x91, 0xD9, 0x53, 0xAB, 0x8D, 0x8D},
|
||||||
|
.free_code_space_offset = 0x4797C,
|
||||||
|
KERNEL_HOOKS(100)
|
||||||
|
},
|
||||||
{ /* 1.0.0. */
|
{ /* 1.0.0. */
|
||||||
.hash = {0xB8, 0xC5, 0x0C, 0x68, 0x25, 0xA9, 0xB9, 0x5B, 0xD2, 0x4D, 0x2C, 0x7C, 0x81, 0x7F, 0xE6, 0x96, 0xF2, 0x42, 0x4E, 0x1D, 0x78, 0xDF, 0x3B, 0xCA, 0x3D, 0x6B, 0x68, 0x12, 0xDD, 0xA9, 0xCB, 0x9C},
|
.hash = {0xB8, 0xC5, 0x0C, 0x68, 0x25, 0xA9, 0xB9, 0x5B, 0xD2, 0x4D, 0x2C, 0x7C, 0x81, 0x7F, 0xE6, 0x96, 0xF2, 0x42, 0x4E, 0x1D, 0x78, 0xDF, 0x3B, 0xCA, 0x3D, 0x6B, 0x68, 0x12, 0xDD, 0xA9, 0xCB, 0x9C},
|
||||||
.free_code_space_offset = 0x4797C,
|
.free_code_space_offset = 0x4797C,
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "tsec.h"
|
#include "tsec.h"
|
||||||
|
|
||||||
|
#define TSEC_KEYGEN_MAX_RETRIES 25
|
||||||
|
|
||||||
void *smmu_heap = (void *)SMMU_HEAP_BASE_ADDR;
|
void *smmu_heap = (void *)SMMU_HEAP_BASE_ADDR;
|
||||||
|
|
||||||
static void safe_memcpy(void *dst, void *src, uint32_t sz) {
|
static void safe_memcpy(void *dst, void *src, uint32_t sz) {
|
||||||
@@ -168,14 +170,6 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
|
|||||||
/* Copy package1 into IRAM. */
|
/* Copy package1 into IRAM. */
|
||||||
memcpy((void *)0x40010000, package1, package1_size);
|
memcpy((void *)0x40010000, package1, package1_size);
|
||||||
|
|
||||||
/* Load the TSEC firmware from IRAM. */
|
|
||||||
if (tsec_load_fw((void *)(0x40010000 + 0xE00), 0x2900) < 0) {
|
|
||||||
fatal_error("[SMMU]: Failed to load TSEC firmware!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable the aperture since it has precedence over the SMMU. */
|
|
||||||
mc_disable_ahb_redirect();
|
|
||||||
|
|
||||||
/* Setup TSEC's address space. */
|
/* Setup TSEC's address space. */
|
||||||
uint32_t *pdir = smmu_setup_tsec_as(1);
|
uint32_t *pdir = smmu_setup_tsec_as(1);
|
||||||
|
|
||||||
@@ -189,21 +183,6 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
|
|||||||
volatile uint32_t *iram_pages = smmu_alloc_page(48);
|
volatile uint32_t *iram_pages = smmu_alloc_page(48);
|
||||||
volatile uint32_t *expv_page = smmu_alloc_page(1);
|
volatile uint32_t *expv_page = smmu_alloc_page(1);
|
||||||
|
|
||||||
/* Copy CAR, MC and FUSE. */
|
|
||||||
safe_memcpy((void *)car_page, (void *)0x60006000, 0x1000);
|
|
||||||
safe_memcpy((void *)mc_page, (void *)0x70019000, 0x1000);
|
|
||||||
safe_memcpy((void *)&fuse_page[0x800/4], (void *)0x7000F800, 0x400);
|
|
||||||
|
|
||||||
/* Copy IRAM. */
|
|
||||||
memcpy((void *)iram_pages, (void *)0x40010000, 0x30000);
|
|
||||||
|
|
||||||
/* TSEC wants CLK_RST_CONTROLLER_CLK_SOURCE_TSEC_0 to be equal to 2. */
|
|
||||||
car_page[0x1F4/4] = 2;
|
|
||||||
|
|
||||||
/* TSEC wants the aperture fully open. */
|
|
||||||
mc_page[0x65C/4] = 0;
|
|
||||||
mc_page[0x660/4] = 0x80000000;
|
|
||||||
|
|
||||||
/* Map all necessary pages. */
|
/* Map all necessary pages. */
|
||||||
smmu_map(pdir, 0x60006000, (uint32_t)car_page, 1, _READABLE | _WRITABLE | _NONSECURE);
|
smmu_map(pdir, 0x60006000, (uint32_t)car_page, 1, _READABLE | _WRITABLE | _NONSECURE);
|
||||||
smmu_map(pdir, 0x7000F000, (uint32_t)fuse_page, 1, _READABLE | _NONSECURE);
|
smmu_map(pdir, 0x7000F000, (uint32_t)fuse_page, 1, _READABLE | _NONSECURE);
|
||||||
@@ -217,19 +196,69 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
|
|||||||
/* Enable the SMMU. */
|
/* Enable the SMMU. */
|
||||||
smmu_enable();
|
smmu_enable();
|
||||||
|
|
||||||
/* Run the TSEC firmware. */
|
/* Loop retrying TSEC firmware execution, in case we lose the SE keydata race. */
|
||||||
tsec_run_fw();
|
|
||||||
|
|
||||||
/* Extract the keys from SE. */
|
|
||||||
uint32_t key_buf[0x20/4] = {0};
|
uint32_t key_buf[0x20/4] = {0};
|
||||||
volatile uint32_t *key_data = (volatile uint32_t *)((void *)se_page + 0x320);
|
unsigned int retries = 0;
|
||||||
uint32_t old_key_data = *key_data;
|
while (true) {
|
||||||
uint32_t buf_counter = 0;
|
if (retries++ > TSEC_KEYGEN_MAX_RETRIES) {
|
||||||
while (!(tsec->FALCON_CPUCTL & 0x10)) {
|
fatal_error("[SMMU] TSEC key generation race was lost too many times!");
|
||||||
if (*key_data != old_key_data) {
|
}
|
||||||
old_key_data = *key_data;
|
|
||||||
key_buf[buf_counter] = *key_data;
|
/* Load the TSEC firmware from IRAM. */
|
||||||
buf_counter++;
|
if (tsec_load_fw((void *)(0x40010000 + 0xE00), 0x2900) < 0) {
|
||||||
|
fatal_error("[SMMU]: Failed to load TSEC firmware!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable the aperture since it has precedence over the SMMU. */
|
||||||
|
mc_disable_ahb_redirect();
|
||||||
|
|
||||||
|
/* Clear all pages. */
|
||||||
|
memset((void *)car_page, 0, SMMU_PAGE_SIZE);
|
||||||
|
memset((void *)fuse_page, 0, SMMU_PAGE_SIZE);
|
||||||
|
memset((void *)pmc_page, 0, SMMU_PAGE_SIZE);
|
||||||
|
memset((void *)flow_page, 0, SMMU_PAGE_SIZE);
|
||||||
|
memset((void *)se_page, 0, SMMU_PAGE_SIZE);
|
||||||
|
memset((void *)mc_page, 0, SMMU_PAGE_SIZE);
|
||||||
|
memset((void *)iram_pages, 0, 48 * SMMU_PAGE_SIZE);
|
||||||
|
memset((void *)expv_page, 0, SMMU_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Copy CAR, MC and FUSE. */
|
||||||
|
safe_memcpy((void *)car_page, (void *)0x60006000, 0x1000);
|
||||||
|
safe_memcpy((void *)mc_page, (void *)0x70019000, 0x1000);
|
||||||
|
safe_memcpy((void *)&fuse_page[0x800/4], (void *)0x7000F800, 0x400);
|
||||||
|
|
||||||
|
/* Copy IRAM. */
|
||||||
|
memcpy((void *)iram_pages, (void *)0x40010000, 0x30000);
|
||||||
|
|
||||||
|
/* TSEC wants CLK_RST_CONTROLLER_CLK_SOURCE_TSEC_0 to be equal to 2. */
|
||||||
|
car_page[0x1F4/4] = 2;
|
||||||
|
|
||||||
|
/* TSEC wants the aperture fully open. */
|
||||||
|
mc_page[0x65C/4] = 0;
|
||||||
|
mc_page[0x660/4] = 0x80000000;
|
||||||
|
|
||||||
|
|
||||||
|
/* Run the TSEC firmware. */
|
||||||
|
tsec_run_fw();
|
||||||
|
|
||||||
|
/* Extract the keys from SE. */
|
||||||
|
volatile uint32_t *key_data = (volatile uint32_t *)((void *)se_page + 0x320);
|
||||||
|
uint32_t old_key_data = *key_data;
|
||||||
|
uint32_t buf_counter = 0;
|
||||||
|
while (!(tsec->FALCON_CPUCTL & 0x10)) {
|
||||||
|
const uint32_t new_key_data = *key_data;
|
||||||
|
if (new_key_data != old_key_data) {
|
||||||
|
old_key_data = new_key_data;
|
||||||
|
key_buf[buf_counter] = new_key_data;
|
||||||
|
buf_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable back the aperture. */
|
||||||
|
mc_enable_ahb_redirect();
|
||||||
|
|
||||||
|
if (buf_counter == 8) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,9 +277,6 @@ void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_si
|
|||||||
/* Clear TSEC's address space. */
|
/* Clear TSEC's address space. */
|
||||||
smmu_clear_tsec_as(1);
|
smmu_clear_tsec_as(1);
|
||||||
|
|
||||||
/* Enable back the aperture. */
|
|
||||||
mc_enable_ahb_redirect();
|
|
||||||
|
|
||||||
/* Return the decrypted package1 from emulated IRAM. */
|
/* Return the decrypted package1 from emulated IRAM. */
|
||||||
memcpy(package1_dec, (void *)iram_pages, package1_size);
|
memcpy(package1_dec, (void *)iram_pages, package1_size);
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
"title_id_range_min": "0x0100000000000034",
|
"title_id_range_min": "0x0100000000000034",
|
||||||
"title_id_range_max": "0x0100000000000034",
|
"title_id_range_max": "0x0100000000000034",
|
||||||
"main_thread_stack_size": "0x00010000",
|
"main_thread_stack_size": "0x00010000",
|
||||||
"main_thread_priority": 37,
|
"main_thread_priority": 15,
|
||||||
"default_cpu_id": 3,
|
"default_cpu_id": 3,
|
||||||
"process_category": 0,
|
"process_category": 0,
|
||||||
"is_retail": true,
|
"is_retail": true,
|
||||||
"pool_partition": 2,
|
"pool_partition": 2,
|
||||||
"is_64_bit": true,
|
"is_64_bit": true,
|
||||||
"address_space_type": 3,
|
"address_space_type": 1,
|
||||||
"filesystem_access": {
|
"filesystem_access": {
|
||||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||||
},
|
},
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
"type": "min_kernel_version",
|
"type": "min_kernel_version",
|
||||||
"value": "0x0060"
|
"value": "0x0030"
|
||||||
}, {
|
}, {
|
||||||
"type": "handle_table_size",
|
"type": "handle_table_size",
|
||||||
"value": 128
|
"value": 128
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ void Utils::InitializeSdThreadFunc(void *args) {
|
|||||||
|
|
||||||
/* Mount SD. */
|
/* Mount SD. */
|
||||||
while (R_FAILED(fsMountSdcard(&g_sd_filesystem))) {
|
while (R_FAILED(fsMountSdcard(&g_sd_filesystem))) {
|
||||||
svcSleepThread(1000ULL);
|
svcSleepThread(1000000ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Back up CAL0, if it's not backed up already. */
|
/* Back up CAL0, if it's not backed up already. */
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"is_retail": true,
|
"is_retail": true,
|
||||||
"pool_partition": 2,
|
"pool_partition": 2,
|
||||||
"is_64_bit": true,
|
"is_64_bit": true,
|
||||||
"address_space_type": 3,
|
"address_space_type": 1,
|
||||||
"filesystem_access": {
|
"filesystem_access": {
|
||||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||||
},
|
},
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "min_kernel_version",
|
"type": "min_kernel_version",
|
||||||
"value": "0x0060"
|
"value": "0x0030"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user