Fusee stage 2: Fix up loader (no stage 3!). Skeleton chainload behavior.

This commit is contained in:
Michael Scire 2018-04-09 15:34:23 -06:00
parent b85567dff3
commit a05bf5b4ce
5 changed files with 66 additions and 18 deletions

View file

@ -9,6 +9,12 @@
const char *g_bct0 = NULL; 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) { 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; load_file_t *load_file_ctx = (load_file_t *)user;
uintptr_t x = 0; 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)) { 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); 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) { } else if (strcmp(name, LOADER_ENTRYPOINT_KEY) == 0) {
/* Read in entrypoint as a hex string. */ /* Read in entrypoint as a hex string. */
sscanf(value, "%x", &x); sscanf(value, "%x", &x);
loader_ctx->entrypoint = (entrypoint_t)x; loader_ctx->chainload_entrypoint = (entrypoint_t)x;
} else { } else {
return 0; return 0;
} }
@ -127,21 +145,14 @@ static int loadlist_ini_handler(void *user, const char *section, const char *nam
return 1; return 1;
} }
entrypoint_t load_payload(const char *bct0) { void load_payload(const char *bct0) {
loader_ctx_t loader_ctx = {0}; loader_ctx_t *ctx = get_loader_ctx();
/* Set BCT0 global. */ /* 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"); printk("Error: Failed to parse BCT.ini!\n");
generic_panic(); generic_panic();
} }
if (loader_ctx.entrypoint == NULL) {
printk("Error: Failed to locate stage3 entrypoint!\n");
generic_panic();
}
return loader_ctx.entrypoint;
} }

View file

@ -1,6 +1,8 @@
#ifndef FUSEE_LOADER_H #ifndef FUSEE_LOADER_H
#define FUSEE_LOADER_H #define FUSEE_LOADER_H
#include "utils.h"
typedef void (*entrypoint_t)(int argc, void **argv); typedef void (*entrypoint_t)(int argc, void **argv);
typedef struct { typedef struct {
@ -10,15 +12,27 @@ typedef struct {
} load_file_t; } load_file_t;
typedef struct { 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; } loader_ctx_t;
#define LOADER_ENTRYPOINT_KEY "entrypoint" #define LOADER_ENTRYPOINT_KEY "entrypoint"
#define LOADER_LOADLIST_KEY "loadlist" #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? */ /* TODO: Should we allow files bigger than 16 MB? */
#define LOADER_FILESIZE_MAX 0x01000000 #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 #endif

View file

@ -2,6 +2,7 @@
#include "hwinit.h" #include "hwinit.h"
#include "loader.h" #include "loader.h"
#include "stage2.h" #include "stage2.h"
#include "nxboot.h"
#include "lib/printk.h" #include "lib/printk.h"
#include "display/video_fb.h" #include "display/video_fb.h"
@ -10,8 +11,8 @@
#pragma GCC diagnostic ignored "-Wmain" #pragma GCC diagnostic ignored "-Wmain"
int main(int argc, void **argv) { int main(int argc, void **argv) {
entrypoint_t entrypoint;
stage2_args_t *args; stage2_args_t *args;
loader_ctx_t *loader_ctx;
if (argc != STAGE2_ARGC || ((args = (stage2_args_t *)argv[STAGE2_ARGV_ARGUMENT_STRUCT])->version != 0)) { if (argc != STAGE2_ARGC || ((args = (stage2_args_t *)argv[STAGE2_ARGV_ARGUMENT_STRUCT])->version != 0)) {
generic_panic(); 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]); printk("Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]);
/* This will load all remaining binaries off of the SD. */ /* This will load all remaining binaries off of the SD. */
entrypoint = load_payload(args->bct0); load_payload(args->bct0);
loader_ctx = get_loader_ctx();
if (loader_ctx->chainload_entrypoint != NULL) {
/* TODO: What do we want to do in terms of argc/argv? */ /* TODO: What do we want to do in terms of argc/argv? */
entrypoint(0, NULL); loader_ctx->chainload_entrypoint(0, NULL);
} else {
/* If we don't have a chainload entrypoint set, we're booting Horizon. */
nxboot_main();
}
return 0; return 0;
} }

View file

@ -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. */
}

View file

@ -0,0 +1,9 @@
#ifndef FUSEE_NX_BOOT_H
#define FUSEE_NX_BOOT_H
#include "utils.h"
void nxboot_main(void);
#endif