diff --git a/fusee/fusee-secondary/src/loader.c b/fusee/fusee-secondary/src/loader.c index 663698432..633275e74 100644 --- a/fusee/fusee-secondary/src/loader.c +++ b/fusee/fusee-secondary/src/loader.c @@ -9,6 +9,12 @@ const char *g_bct0 = NULL; +loader_ctx_t g_loader_ctx = {0}; + +loader_ctx_t *get_loader_ctx(void) { + return &g_loader_ctx; +} + static int loadlist_entry_ini_handler(void *user, const char *section, const char *name, const char *value) { load_file_t *load_file_ctx = (load_file_t *)user; uintptr_t x = 0; @@ -67,6 +73,18 @@ void load_list_entry(const char *key) { if (!read_sd_file((void *)load_file_ctx.load_address, LOADER_FILESIZE_MAX, load_file_ctx.path)) { printk("Error: Failed to read %s!\n", load_file_ctx.path); + generic_panic(); + } + + /* Check for special keys. */ + if (strcmp(key, LOADER_PACKAGE2_KEY) == 0) { + get_loader_ctx()->package2_loadfile = load_file_ctx; + } else if (strcmp(key, LOADER_EXOSPHERE_KEY) == 0) { + get_loader_ctx()->exosphere_loadfile = load_file_ctx; + } else if (strcmp(key, LOADER_TSECFW_KEY) == 0) { + get_loader_ctx()->tsecfw_loadfile = load_file_ctx; + } else if (strcmp(key, LOADER_WARMBOOT_KEY) == 0) { + get_loader_ctx()->warmboot_loadfile = load_file_ctx; } } @@ -117,7 +135,7 @@ static int loadlist_ini_handler(void *user, const char *section, const char *nam } else if (strcmp(name, LOADER_ENTRYPOINT_KEY) == 0) { /* Read in entrypoint as a hex string. */ sscanf(value, "%x", &x); - loader_ctx->entrypoint = (entrypoint_t)x; + loader_ctx->chainload_entrypoint = (entrypoint_t)x; } else { return 0; } @@ -127,21 +145,14 @@ static int loadlist_ini_handler(void *user, const char *section, const char *nam return 1; } -entrypoint_t load_payload(const char *bct0) { - loader_ctx_t loader_ctx = {0}; +void load_payload(const char *bct0) { + loader_ctx_t *ctx = get_loader_ctx(); /* Set BCT0 global. */ - g_bct0 = bct0; + ctx->bct0 = bct0; - if (ini_parse_string(g_bct0, loadlist_ini_handler, &loader_ctx) < 0) { + if (ini_parse_string(ctx->bct0, loadlist_ini_handler, ctx) < 0) { printk("Error: Failed to parse BCT.ini!\n"); generic_panic(); } - - if (loader_ctx.entrypoint == NULL) { - printk("Error: Failed to locate stage3 entrypoint!\n"); - generic_panic(); - } - - return loader_ctx.entrypoint; } \ No newline at end of file diff --git a/fusee/fusee-secondary/src/loader.h b/fusee/fusee-secondary/src/loader.h index a8bc7c7f5..d17e73698 100644 --- a/fusee/fusee-secondary/src/loader.h +++ b/fusee/fusee-secondary/src/loader.h @@ -1,6 +1,8 @@ #ifndef FUSEE_LOADER_H #define FUSEE_LOADER_H +#include "utils.h" + typedef void (*entrypoint_t)(int argc, void **argv); typedef struct { @@ -10,15 +12,27 @@ typedef struct { } load_file_t; typedef struct { - entrypoint_t entrypoint; + const char *bct0; + entrypoint_t chainload_entrypoint; + load_file_t package2_loadfile; + load_file_t exosphere_loadfile; + load_file_t tsecfw_loadfile; + load_file_t warmboot_loadfile; } loader_ctx_t; #define LOADER_ENTRYPOINT_KEY "entrypoint" #define LOADER_LOADLIST_KEY "loadlist" +#define LOADER_PACKAGE2_KEY "package2" +#define LOADER_EXOSPHERE_KEY "exosphere" +#define LOADER_TSECFW_KEY "tsecfw" +#define LOADER_WARMBOOT_KEY "warmboot" + /* TODO: Should we allow files bigger than 16 MB? */ #define LOADER_FILESIZE_MAX 0x01000000 -entrypoint_t load_payload(const char *bct0); +loader_ctx_t *get_loader_ctx(void); + +void load_payload(const char *bct0); #endif \ No newline at end of file diff --git a/fusee/fusee-secondary/src/main.c b/fusee/fusee-secondary/src/main.c index f7aa18981..39cad19d7 100644 --- a/fusee/fusee-secondary/src/main.c +++ b/fusee/fusee-secondary/src/main.c @@ -2,6 +2,7 @@ #include "hwinit.h" #include "loader.h" #include "stage2.h" +#include "nxboot.h" #include "lib/printk.h" #include "display/video_fb.h" @@ -10,8 +11,8 @@ #pragma GCC diagnostic ignored "-Wmain" int main(int argc, void **argv) { - entrypoint_t entrypoint; stage2_args_t *args; + loader_ctx_t *loader_ctx; if (argc != STAGE2_ARGC || ((args = (stage2_args_t *)argv[STAGE2_ARGV_ARGUMENT_STRUCT])->version != 0)) { generic_panic(); @@ -26,10 +27,16 @@ int main(int argc, void **argv) { printk("Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]); /* This will load all remaining binaries off of the SD. */ - entrypoint = load_payload(args->bct0); + load_payload(args->bct0); + loader_ctx = get_loader_ctx(); - /* TODO: What do we want to do in terms of argc/argv? */ - entrypoint(0, NULL); + if (loader_ctx->chainload_entrypoint != NULL) { + /* TODO: What do we want to do in terms of argc/argv? */ + loader_ctx->chainload_entrypoint(0, NULL); + } else { + /* If we don't have a chainload entrypoint set, we're booting Horizon. */ + nxboot_main(); + } return 0; } diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c new file mode 100644 index 000000000..36541f63a --- /dev/null +++ b/fusee/fusee-secondary/src/nxboot.c @@ -0,0 +1,7 @@ +#include "utils.h" +#include "nxboot.h" + +/* This is the main function responsible for booting Horizon. */ +void nxboot_main(void) { + /* TODO: Implement this function. */ +} \ No newline at end of file diff --git a/fusee/fusee-secondary/src/nxboot.h b/fusee/fusee-secondary/src/nxboot.h new file mode 100644 index 000000000..a84e4bdbf --- /dev/null +++ b/fusee/fusee-secondary/src/nxboot.h @@ -0,0 +1,9 @@ +#ifndef FUSEE_NX_BOOT_H +#define FUSEE_NX_BOOT_H + +#include "utils.h" + + +void nxboot_main(void); + +#endif \ No newline at end of file