mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-22 11:56:40 +00:00
sept-s: First functional version.
This commit is contained in:
parent
f1068d6c3f
commit
ddc5222208
12 changed files with 72 additions and 87 deletions
|
@ -149,7 +149,7 @@ int main(void) {
|
|||
|
||||
/* Say hello. */
|
||||
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);
|
||||
|
||||
/* Load the loader payload into DRAM. */
|
||||
load_stage2(bct0);
|
||||
|
|
|
@ -98,6 +98,14 @@ int main(int argc, void **argv) {
|
|||
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, u8"Welcome to Atmosphère Fusée Stage 2!\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]);
|
||||
|
||||
/* Load BCT0 from SD if needed. */
|
||||
if (strcmp(g_stage2_args->bct0, "") == 0) {
|
||||
read_from_file(g_stage2_args->bct0, sizeof(g_stage2_args->bct0) - 1, "atmosphere/BCT.ini");
|
||||
if (!read_from_file(g_stage2_args->bct0, sizeof(g_stage2_args->bct0) - 1, "atmosphere/BCT.ini")) {
|
||||
fatal_error("Failed to read BCT0 from SD!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* This will load all remaining binaries off of the SD. */
|
||||
load_payload(g_stage2_args->bct0);
|
||||
|
@ -106,10 +114,7 @@ int main(int argc, void **argv) {
|
|||
|
||||
g_do_nxboot = loader_ctx->chainload_entrypoint == 0;
|
||||
if (g_do_nxboot) {
|
||||
/* Display splash screen. */
|
||||
display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000);
|
||||
|
||||
print(SCREEN_LOG_LEVEL_MANDATORY, "Now performing nxboot.\n");
|
||||
print(SCREEN_LOG_LEVEL_INFO, "Now performing nxboot.\n");
|
||||
uint32_t boot_memaddr = nxboot_main();
|
||||
/* Wait for the splash screen to have been displayed as long as it should be. */
|
||||
splash_screen_wait_delay();
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "flow.h"
|
||||
#include "timers.h"
|
||||
#include "key_derivation.h"
|
||||
#include "masterkey.h"
|
||||
#include "package1.h"
|
||||
#include "package2.h"
|
||||
#include "smmu.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include "exocfg.h"
|
||||
#include "display/video_fb.h"
|
||||
#include "lib/ini.h"
|
||||
#include "splash_screen.h"
|
||||
|
||||
#define u8 uint8_t
|
||||
#define u32 uint32_t
|
||||
|
@ -419,7 +421,7 @@ uint32_t nxboot_main(void) {
|
|||
}
|
||||
}
|
||||
|
||||
print(SCREEN_LOG_LEVEL_MANDATORY, "[NXBOOT]: Loaded firmware from eMMC...\n");
|
||||
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Loaded firmware from eMMC...\n");
|
||||
|
||||
/* Get the TSEC keys. */
|
||||
uint8_t tsec_key[0x10] = {0};
|
||||
|
@ -428,7 +430,12 @@ uint32_t nxboot_main(void) {
|
|||
/* Detect whether we need to run sept-secondary in order to derive keys. */
|
||||
if (!get_and_clear_has_run_sept()) {
|
||||
reboot_to_sept(tsec_fw, tsec_fw_size, sept_secondary_enc, sept_secondary_enc_size);
|
||||
} else {
|
||||
if (mkey_detect_revision(fuse_get_retail_type() != 0) != 0) {
|
||||
fatal_error("[NXBOOT]: Sept derived incorrect keys!\n");
|
||||
}
|
||||
}
|
||||
get_and_clear_has_run_sept();
|
||||
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_620) {
|
||||
uint8_t tsec_keys[0x20] = {0};
|
||||
|
||||
|
@ -445,6 +452,10 @@ uint32_t nxboot_main(void) {
|
|||
}
|
||||
}
|
||||
|
||||
//fatal_error("Ran sept!");
|
||||
/* Display splash screen. */
|
||||
display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000);
|
||||
|
||||
/* Derive keydata. If on 7.0.0+, sept has already derived keys for us. */
|
||||
unsigned int keygen_type = 0;
|
||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) {
|
||||
|
@ -528,11 +539,13 @@ uint32_t nxboot_main(void) {
|
|||
pmc->scratch1 = (uint32_t)warmboot_memaddr;
|
||||
}
|
||||
|
||||
print(SCREEN_LOG_LEVEL_MANDATORY, "[NXBOOT]: Rebuilding package2...\n");
|
||||
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Rebuilding package2...\n");
|
||||
|
||||
/* Parse stratosphere config. */
|
||||
nxboot_configure_stratosphere(MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware);
|
||||
|
||||
print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT]: Configured Stratosphere...\n");
|
||||
|
||||
/* Patch package2, adding Thermosphère + custom KIPs. */
|
||||
package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware);
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ void wait_for_button(void) {
|
|||
}
|
||||
|
||||
__attribute__ ((noreturn)) void generic_panic(void) {
|
||||
print(SCREEN_LOG_LEVEL_ERROR, "generic panic from %p", __builtin_return_address(0));
|
||||
panic(0xFF000006);
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ void display_init()
|
|||
|
||||
exec_cfg((uint32_t *)CAR_BASE, _display_config_1, 4);
|
||||
exec_cfg((uint32_t *)DI_BASE, _display_config_2, 94);
|
||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_3, 61);
|
||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_3, 60);
|
||||
|
||||
udelay(10000);
|
||||
|
||||
|
@ -149,8 +149,8 @@ void display_init()
|
|||
|
||||
udelay(20000);
|
||||
|
||||
exec_cfg((uint32_t *)CAR_BASE, _display_config_6, 3);
|
||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_5, 21);
|
||||
exec_cfg((uint32_t *)CAR_BASE, _display_config_6, 3);
|
||||
|
||||
MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
|
||||
exec_cfg((uint32_t *)DSI_BASE, _display_config_7, 10);
|
||||
|
|
|
@ -190,7 +190,6 @@
|
|||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define H_DIRECTION (1 << 0)
|
||||
#define V_DIRECTION (1 << 2)
|
||||
#define SCAN_COLUMN (1 << 4)
|
||||
#define COLOR_EXPAND (1 << 6)
|
||||
#define CSC_ENABLE (1 << 18)
|
||||
#define WIN_ENABLE (1 << 30)
|
||||
|
@ -238,8 +237,6 @@
|
|||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DC_WIN_LINE_STRIDE 0x70A
|
||||
#define LINE_STRIDE(x) (x)
|
||||
#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
|
||||
#define DC_WIN_DV_CONTROL 0x70E
|
||||
|
||||
/* The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
|
||||
|
@ -350,8 +347,6 @@
|
|||
|
||||
#define DSI_PAD_CONTROL_4 0x52
|
||||
|
||||
#define DSI_INIT_SEQ_DATA_15 0x5F
|
||||
|
||||
typedef struct _cfg_op_t
|
||||
{
|
||||
uint32_t off;
|
||||
|
|
|
@ -128,7 +128,7 @@ static const cfg_op_t _display_config_2[94] = {
|
|||
};
|
||||
|
||||
//DSI Init config.
|
||||
static const cfg_op_t _display_config_3[61] = {
|
||||
static const cfg_op_t _display_config_3[60] = {
|
||||
{DSI_WR_DATA, 0},
|
||||
{DSI_INT_ENABLE, 0},
|
||||
{DSI_INT_STATUS, 0},
|
||||
|
@ -137,7 +137,6 @@ static const cfg_op_t _display_config_3[61] = {
|
|||
{DSI_INIT_SEQ_DATA_1, 0},
|
||||
{DSI_INIT_SEQ_DATA_2, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0},
|
||||
{DSI_INIT_SEQ_DATA_15, 0},
|
||||
{DSI_DCS_CMDS, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0},
|
||||
{DSI_PKT_SEQ_1_LO, 0},
|
||||
|
@ -289,7 +288,7 @@ static const cfg_op_t _display_config_7[10] = {
|
|||
static const cfg_op_t _display_config_8[6] = {
|
||||
{0x18, 0},
|
||||
{2, 0xF3F10000},
|
||||
{0x16, 0},
|
||||
{0x16, 1},
|
||||
{0x18, 0},
|
||||
{0x18, 0x10010},
|
||||
{0x17, 0x300}
|
||||
|
@ -475,10 +474,10 @@ static const cfg_op_t _display_config_13[16] = {
|
|||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_PHY_TIMING_2, 0x30109},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
|
||||
{DSI_TO_TALLY, 0},
|
||||
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
|
||||
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
|
||||
|
|
|
@ -185,23 +185,30 @@ void config_se_brom()
|
|||
|
||||
void nx_hwinit()
|
||||
{
|
||||
volatile tegra_car_t *car = car_get_regs();
|
||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||
volatile tegra_car_t *car = car_get_regs();
|
||||
|
||||
/* This stuff was handled by whatever loaded us. */
|
||||
/* Bootrom stuff we skipped by going through RCM. */
|
||||
config_se_brom();
|
||||
|
||||
AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F;
|
||||
pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD);
|
||||
|
||||
/* Apply the memory built-in self test workaround. */
|
||||
mbist_workaround();
|
||||
|
||||
/* Reboot SE. */
|
||||
clkrst_reboot(CARDEVICE_SE);
|
||||
|
||||
/* Initialize the fuse driver. */
|
||||
fuse_init();
|
||||
|
||||
/* Initialize the memory controller. */
|
||||
mc_enable();
|
||||
|
||||
|
||||
/* Configure oscillators. */
|
||||
config_oscillators();
|
||||
|
||||
/* Disable pinmux tristate input clamping. */
|
||||
APB_MISC_PP_PINMUX_GLOBAL_0 = 0;
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ static const uint8_t AL16 new_master_kek_seed_7x[0x10] = {
|
|||
|
||||
void derive_7x_keys(const void *tsec_key, void *tsec_root_key) {
|
||||
uint8_t AL16 work_buffer[0x10];
|
||||
uint8_t AL16 master_kek[0x10];
|
||||
|
||||
/* Set keyslot flags properly in preparation of derivation. */
|
||||
set_aes_keyslot_flags(0xE, 0x15);
|
||||
|
@ -61,15 +60,12 @@ void derive_7x_keys(const void *tsec_key, void *tsec_root_key) {
|
|||
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, keyblob_seed_00, 0x10);
|
||||
decrypt_data_into_keyslot(0xF, 0xE, work_buffer, 0x10);
|
||||
|
||||
/* Derive the master kek. */
|
||||
set_aes_keyslot(0xC, tsec_root_key, 0x10);
|
||||
se_aes_ecb_decrypt_block(0xC, master_kek, 0x10, new_master_kek_seed_7x, 0x10);
|
||||
|
||||
/* Clear the SBK. */
|
||||
clear_aes_keyslot(0xE);
|
||||
|
||||
/* Set master kek. */
|
||||
set_aes_keyslot(0xC, master_kek, 0x10);
|
||||
|
||||
/* Derive the master kek. */
|
||||
set_aes_keyslot(0xC, tsec_root_key, 0x10);
|
||||
decrypt_data_into_keyslot(0xC, 0xC, new_master_kek_seed_7x, 0x10);
|
||||
|
||||
/* Derive keys for exosphere. */
|
||||
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
|
||||
|
@ -78,8 +74,7 @@ void derive_7x_keys(const void *tsec_key, void *tsec_root_key) {
|
|||
decrypt_data_into_keyslot(0xC, 0xC, masterkey_seed, 0x10);
|
||||
|
||||
/* Clear master kek from memory. */
|
||||
for (size_t i = 0; i < sizeof(master_kek); i++) {
|
||||
master_kek[i] = 0xCC;
|
||||
for (size_t i = 0; i < sizeof(work_buffer); i++) {
|
||||
work_buffer[i] = 0xCC;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ static void exfiltrate_keys_and_reboot_if_needed(void) {
|
|||
}
|
||||
|
||||
/* Clear the security engine state. */
|
||||
for (size_t i = 0; i < 0x1000; i += 4) {
|
||||
for (size_t i = 0; i < 0x840; i += 4) {
|
||||
MAKE_REG32((uintptr_t)(enc_se_state) + i) = 0xCCCCCCCC;
|
||||
MAKE_REG32((uintptr_t)(dec_se_state) + i) = 0xCCCCCCCC;
|
||||
}
|
||||
|
@ -140,6 +140,9 @@ static void exit_callback(int rc) {
|
|||
}
|
||||
|
||||
int main(void) {
|
||||
const char *stage2_path;
|
||||
stage2_args_t *stage2_args;
|
||||
uint32_t stage2_version = 0;
|
||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_MANDATORY;
|
||||
|
||||
/* Extract keys from the security engine, which TSEC FW locked down. */
|
||||
|
@ -166,9 +169,18 @@ int main(void) {
|
|||
/* Mark EMC scratch to say that sept has run. */
|
||||
MAKE_EMC_REG(EMC_SCRATCH0) |= 0x80000000;
|
||||
|
||||
while (true) { }
|
||||
|
||||
/* TODO: Chainload to payload. */
|
||||
/* Load the loader payload into DRAM. */
|
||||
load_stage2();
|
||||
|
||||
/* Setup argument data. */
|
||||
stage2_path = stage2_get_program_path();
|
||||
strcpy(g_chainloader_arg_data, stage2_path);
|
||||
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->log_level, &log_level, sizeof(log_level));
|
||||
stage2_args->display_initialized = false;
|
||||
strcpy(stage2_args->bct0, "");
|
||||
g_chainloader_argc = 2;
|
||||
|
||||
/* Wait a while. */
|
||||
mdelay(1000);
|
||||
|
|
|
@ -25,59 +25,17 @@ const char *stage2_get_program_path(void) {
|
|||
return g_stage2_path;
|
||||
}
|
||||
|
||||
static int stage2_ini_handler(void *user, const char *section, const char *name, const char *value) {
|
||||
stage2_config_t *config = (stage2_config_t *)user;
|
||||
uintptr_t x = 0;
|
||||
if (strcmp(section, "stage1") == 0) {
|
||||
if (strcmp(name, STAGE2_NAME_KEY) == 0) {
|
||||
strncpy(config->path, value, sizeof(config->path) - 1);
|
||||
config->path[sizeof(config->path) - 1] = '\0';
|
||||
} else if (strcmp(name, STAGE2_ADDRESS_KEY) == 0) {
|
||||
/* Read in load address as a hex string. */
|
||||
sscanf(value, "%x", &x);
|
||||
config->load_address = x;
|
||||
if (config->entrypoint == 0) {
|
||||
config->entrypoint = config->load_address;
|
||||
}
|
||||
} else if (strcmp(name, STAGE2_ENTRYPOINT_KEY) == 0) {
|
||||
/* Read in entrypoint as a hex string. */
|
||||
sscanf(value, "%x", &x);
|
||||
config->entrypoint = x;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void load_stage2(const char *bct0) {
|
||||
stage2_config_t config = {0};
|
||||
/* We get the luxury of assuming a constant filename/load address. */
|
||||
void load_stage2(void) {
|
||||
FILINFO info;
|
||||
size_t size;
|
||||
uintptr_t tmp_addr;
|
||||
|
||||
if (ini_parse_string(bct0, stage2_ini_handler, &config) < 0) {
|
||||
fatal_error("Failed to parse BCT.ini!\n");
|
||||
}
|
||||
|
||||
if (config.load_address == 0 || config.path[0] == '\x00') {
|
||||
fatal_error("Failed to determine where to load stage2!\n");
|
||||
}
|
||||
|
||||
if (strlen(config.path) + 1 + sizeof(stage2_args_t) > CHAINLOADER_ARG_DATA_MAX_SIZE) {
|
||||
print(SCREEN_LOG_LEVEL_ERROR, "Stage2's path name is too big!\n");
|
||||
}
|
||||
|
||||
if (!check_32bit_address_loadable(config.entrypoint)) {
|
||||
fatal_error("Stage2's entrypoint is invalid!\n");
|
||||
}
|
||||
|
||||
if (!check_32bit_address_loadable(config.load_address)) {
|
||||
fatal_error("Stage2's load address is invalid!\n");
|
||||
}
|
||||
|
||||
stage2_config_t config = {
|
||||
.path = "sept/payload.bin",
|
||||
.load_address = 0xF0000000,
|
||||
.entrypoint = 0xF0000000,
|
||||
};
|
||||
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 Config:\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " File Path: %s\n", config.path);
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Load Address: 0x%08x\n", config.load_address);
|
||||
|
|
|
@ -50,6 +50,6 @@ typedef struct {
|
|||
} stage2_args_t;
|
||||
|
||||
const char *stage2_get_program_path(void);
|
||||
void load_stage2(const char *bct0);
|
||||
void load_stage2(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue