diff --git a/fusee/fusee-secondary/src/exocfg.h b/fusee/fusee-secondary/src/exocfg.h index 07b904b56..37328b7b7 100644 --- a/fusee/fusee-secondary/src/exocfg.h +++ b/fusee/fusee-secondary/src/exocfg.h @@ -12,7 +12,16 @@ #define EXOSPHERE_TARGET_FIRMWARE_400 4 #define EXOSPHERE_TARGET_FIRMWARE_500 5 -/* TODO: What should this be, for release? */ -#define EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG EXOSPHERE_TARGET_FIRMWARE_400 +#define EXOSPHERE_TARGET_FIRMWARE_MIN EXOSPHERE_TARGET_FIRMWARE_100 +#define EXOSPHERE_TARGET_FIRMWARE_MAX EXOSPHERE_TARGET_FIRMWARE_500 + +typedef struct { + unsigned int magic; + unsigned int target_firmware; +} exosphere_config_t; + +#define MAILBOX_EXOSPHERE_CONFIGURATION ((volatile exosphere_config_t *)(0x40002E40)) + +#define EXOSPHERE_TARGETFW_KEY "target_firmware" #endif \ No newline at end of file diff --git a/fusee/fusee-secondary/src/hwinit/cluster.c b/fusee/fusee-secondary/src/hwinit/cluster.c index 90015205f..545edf3c6 100644 --- a/fusee/fusee-secondary/src/hwinit/cluster.c +++ b/fusee/fusee-secondary/src/hwinit/cluster.c @@ -52,7 +52,7 @@ int _cluster_pmc_enable_partition(u32 part, u32 toggle) return 1; } -void cluster_enable_cpu0(u64 entry, u32 ns_disable) +void cluster_boot_cpu0(u64 entry, u32 ns_disable) { //Set ACTIVE_CLUSER to FAST. FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE; diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 70cb5ea77..9799d9140 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -1,14 +1,82 @@ #include "utils.h" #include "nxboot.h" +#include "key_derivation.h" #include "loader.h" #include "splash_screen.h" +#include "exocfg.h" +#include "lib/printk.h" +#include "display/video_fb.h" +#include "lib/ini.h" +#include "hwinit/cluster.h" + +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; + if (strcmp(section, "exosphere") == 0) { + if (strcmp(name, EXOSPHERE_TARGETFW_KEY) == 0) { + sscanf(value, "%d", &exo_cfg->target_firmware); + } else { + return 0; + } + } else { + return 0; + } + return 1; +} + +void nxboot_configure_exosphere(void) { + exosphere_config_t exo_cfg = {0}; + + exo_cfg.magic = MAGIC_EXOSPHERE_BOOTCONFIG; + exo_cfg.target_firmware = EXOSPHERE_TARGET_FIRMWARE_MAX; + + if (ini_parse_string(get_loader_ctx()->bct0, exosphere_ini_handler, &exo_cfg) < 0) { + printk("Error: Failed to parse BCT.ini!\n"); + generic_panic(); + } + + if (exo_cfg.target_firmware < EXOSPHERE_TARGET_FIRMWARE_MIN || exo_cfg.target_firmware > EXOSPHERE_TARGET_FIRMWARE_MAX) { + printk("Error: Invalid Exosphere target firmware!\n"); + generic_panic(); + } + + *(MAILBOX_EXOSPHERE_CONFIGURATION) = exo_cfg; +} /* This is the main function responsible for booting Horizon. */ void nxboot_main(void) { loader_ctx_t *loader_ctx = get_loader_ctx(); - /* TODO: Implement this function. */ + /* TODO: Validate that we're capable of booting. */ + + /* TODO: Initialize Boot Reason. */ + + /* TODO: How should we deal with bootconfig? */ + + /* Setup boot configuration for Exosphere. */ + nxboot_configure_exosphere(); + + /* Derive keydata. */ + derive_nx_keydata(MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware); + + /* Boot up Exosphere. */ + MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0; + if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware <= EXOSPHERE_TARGET_FIRMWARE_400) { + MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_LOADED_PACKAGE2; + } else { + MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_LOADED_PACKAGE2_4X; + } + cluster_boot_cpu0(loader_ctx->exosphere_loadfile.load_address, 1); + while (MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE == 0) { + /* Wait for Exosphere to wake up. */ + } + if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware <= EXOSPHERE_TARGET_FIRMWARE_400) { + MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_FINISHED; + } else { + MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_FINISHED_4X; + } /* Display splash screen. */ display_splash_screen_bmp(loader_ctx->custom_splash_path); + + /* TODO: Halt ourselves. */ } \ No newline at end of file diff --git a/fusee/fusee-secondary/src/nxboot.h b/fusee/fusee-secondary/src/nxboot.h index a84e4bdbf..aefa651f9 100644 --- a/fusee/fusee-secondary/src/nxboot.h +++ b/fusee/fusee-secondary/src/nxboot.h @@ -3,6 +3,24 @@ #include "utils.h" +#define MAILBOX_NX_BOOTLOADER_BASE ((void *)(0x40002000)) + +#define MAILBOX_NX_BOOTLOADER_SETUP_STATE MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE + 0xEF8ull) + +#define NX_BOOTLOADER_STATE_INIT 0 +#define NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG 1 + +#define NX_BOOTLOADER_STATE_LOADED_PACKAGE2 2 +#define NX_BOOTLOADER_STATE_FINISHED 3 + +#define NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X 2 +#define NX_BOOTLOADER_STATE_LOADED_PACKAGE2_4X 3 +#define NX_BOOTLOADER_STATE_FINISHED_4X 4 + +/* Physaddr 0x40002EFC */ +#define MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE + 0xEFCULL) + +#define MAILBOX_NX_BOOTLOADER_BOOT_REASON (MAILBOX_NX_BOOTLOADER_BASE + 0xE10ULL) void nxboot_main(void); diff --git a/fusee/fusee-secondary/src/splash_screen.c b/fusee/fusee-secondary/src/splash_screen.c index 8015734ff..4768b5d00 100644 --- a/fusee/fusee-secondary/src/splash_screen.c +++ b/fusee/fusee-secondary/src/splash_screen.c @@ -1,4 +1,5 @@ #include "utils.h" +#include "timers.h" #include "splash_screen.h" #include "sd_utils.h" #include "lib/printk.h" @@ -14,4 +15,7 @@ void display_splash_screen_bmp(const char *custom_splash_path) { } /* TODO: Display the splash screen. It should be a pointer to a BMP, at this point. */ + + /* Display the splash screen for three seconds. */ + wait(3000000); } \ No newline at end of file