Move memory training code into it's own stage (fusee-mtc)

This commit is contained in:
hexkyz 2019-07-26 20:38:15 +01:00
parent 72dd25a99e
commit dc4dbe29ae
38 changed files with 18225 additions and 30 deletions

View file

@ -41,6 +41,7 @@ static char g_bct0_buffer[BCTO_MAX_SIZE];
"BCT0\n"\
"[stage1]\n"\
"stage2_path = atmosphere/fusee-secondary.bin\n"\
"stage2_mtc_path = atmosphere/fusee-mtc.bin\n"\
"stage2_addr = 0xF0000000\n"\
"stage2_entrypoint = 0xF0000000\n"

View file

@ -32,6 +32,9 @@ static int stage2_ini_handler(void *user, const char *section, const char *name,
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_MTC_NAME_KEY) == 0) {
strncpy(config->mtc_path, value, sizeof(config->mtc_path) - 1);
config->mtc_path[sizeof(config->mtc_path) - 1] = '\0';
} else if (strcmp(name, STAGE2_ADDRESS_KEY) == 0) {
/* Read in load address as a hex string. */
sscanf(value, "%x", &x);
@ -52,6 +55,42 @@ static int stage2_ini_handler(void *user, const char *section, const char *name,
return 1;
}
static bool run_mtc(const char *mtc_path, uintptr_t mtc_address) {
FILINFO info;
size_t size;
/* Check if the MTC binary is present. */
if (f_stat(mtc_path, &info) != FR_OK) {
print(SCREEN_LOG_LEVEL_WARNING, "Stage2's MTC binary not found!\n");
return false;
}
size = (size_t)info.fsize;
/* Try to read the MTC binary. */
if (read_from_file((void *)mtc_address, size, mtc_path) != size) {
print(SCREEN_LOG_LEVEL_WARNING, "Failed to read stage2's MTC binary (%s)!\n", mtc_path);
return false;
}
ScreenLogLevel mtc_log_level = log_get_log_level();
bool mtc_res = false;
int mtc_argc = 1;
char mtc_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE] = {0};
stage2_mtc_args_t *mtc_args = (stage2_mtc_args_t *)mtc_arg_data;
/* Setup argument data. */
memcpy(&mtc_args->log_level, &mtc_log_level, sizeof(mtc_log_level));
/* Run the MTC binary. */
mtc_res = (((int (*)(int, void *))mtc_address)(mtc_argc, mtc_arg_data) == 0);
/* Cleanup right away. */
memset((void *)mtc_address, 0, size);
return mtc_res;
}
void load_stage2(const char *bct0) {
stage2_config_t config = {0};
FILINFO info;
@ -77,12 +116,18 @@ void load_stage2(const char *bct0) {
if (!check_32bit_address_loadable(config.load_address)) {
fatal_error("Stage2's load address is invalid!\n");
}
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, " MTC File Path: %s\n", config.mtc_path);
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Load Address: 0x%08x\n", config.load_address);
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Entrypoint: 0x%p\n", config.entrypoint);
/* Run the MTC binary. */
if (!run_mtc(config.mtc_path, config.load_address)) {
print(SCREEN_LOG_LEVEL_WARNING, "DRAM training failed! Continuing with untrained DRAM.\n");
}
if (f_stat(config.path, &info) != FR_OK) {
fatal_error("Failed to stat stage2 (%s)!\n", config.path);
}
@ -108,6 +153,7 @@ void load_stage2(const char *bct0) {
tmp_addr = config.load_address;
}
/* Try to read stage2. */
if (read_from_file((void *)tmp_addr, size, config.path) != size) {
fatal_error("Failed to read stage2 (%s)!\n", config.path);
}

View file

@ -32,6 +32,7 @@
#define STAGE2_ARGC 2
#define STAGE2_NAME_KEY "stage2_path"
#define STAGE2_MTC_NAME_KEY "stage2_mtc_path"
#define STAGE2_ADDRESS_KEY "stage2_addr"
#define STAGE2_ENTRYPOINT_KEY "stage2_entrypoint"
@ -39,6 +40,7 @@
typedef struct {
char path[0x100];
char mtc_path[0x100];
uintptr_t load_address;
uintptr_t entrypoint;
} stage2_config_t;
@ -49,6 +51,10 @@ typedef struct {
char bct0[BCTO_MAX_SIZE];
} stage2_args_t;
typedef struct {
ScreenLogLevel log_level;
} stage2_mtc_args_t;
const char *stage2_get_program_path(void);
void load_stage2(const char *bct0);