mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-04-22 04:24:48 +00:00
fusee-primary: reorganize main to give some options when SD mount fails
This commit is contained in:
parent
182b45b604
commit
5be26c6c92
5 changed files with 160 additions and 66 deletions
|
@ -26,16 +26,19 @@ extern "C" {
|
|||
|
||||
static ams::fastboot::FastbootGadget fastboot_gadget((uint8_t*) 0xf0000000, 1024 * 1024 * 256); // 256 MiB download buffer reaches end of address space
|
||||
|
||||
extern "C" fastboot_return fastboot_enter(const bct0_t *bct0) {
|
||||
bool should_enter = bct0->fastboot_force_enable;
|
||||
extern "C" fastboot_return fastboot_enter(const bct0_t *bct0, bool force) {
|
||||
bool should_enter = force || bct0->fastboot_force_enable;
|
||||
|
||||
log_setup_display();
|
||||
|
||||
if (!should_enter) {
|
||||
if(should_enter) {
|
||||
log_setup_display();
|
||||
} else {
|
||||
if (bct0->fastboot_button_timeout > 0) {
|
||||
log_setup_display();
|
||||
|
||||
uint32_t timeout = bct0->fastboot_button_timeout;
|
||||
uint32_t start_time = get_time_ms();
|
||||
uint32_t last_message_secs = 0;
|
||||
|
||||
while (get_time_ms() - start_time < timeout) {
|
||||
uint32_t seconds_remaining = (start_time + timeout - get_time_ms() + 999) / 1000;
|
||||
if (seconds_remaining != last_message_secs) {
|
||||
|
@ -48,20 +51,25 @@ extern "C" fastboot_return fastboot_enter(const bct0_t *bct0) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print((ScreenLogLevel) (SCREEN_LOG_LEVEL_NONE | SCREEN_LOG_LEVEL_NO_PREFIX), "\n\n");
|
||||
|
||||
if (!should_enter) {
|
||||
log_cleanup_display();
|
||||
return FASTBOOT_SKIPPED;
|
||||
}
|
||||
} else {
|
||||
/* We did not initialize the display, so don't need to clean it up here. */
|
||||
|
||||
return FASTBOOT_SKIPPED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!should_enter) {
|
||||
log_cleanup_display();
|
||||
return FASTBOOT_SKIPPED;
|
||||
}
|
||||
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Entering fastboot.\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Entering fastboot. (forced = %d)\n", force);
|
||||
ams::xusb::Initialize();
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Finished initializing USB hardware.\n");
|
||||
ams::xusb::EnableDevice(fastboot_gadget);
|
||||
|
||||
|
||||
print((ScreenLogLevel) (SCREEN_LOG_LEVEL_NONE | SCREEN_LOG_LEVEL_NO_PREFIX), "Fastboot mode:\n");
|
||||
print((ScreenLogLevel) (SCREEN_LOG_LEVEL_NONE | SCREEN_LOG_LEVEL_NO_PREFIX), "-------------------------------\n");
|
||||
print((ScreenLogLevel) (SCREEN_LOG_LEVEL_NONE | SCREEN_LOG_LEVEL_NO_PREFIX), "Volume up: Reboot to RCM.\n");
|
||||
|
@ -71,6 +79,6 @@ extern "C" fastboot_return fastboot_enter(const bct0_t *bct0) {
|
|||
fastboot_return r = fastboot_gadget.Run();
|
||||
|
||||
log_cleanup_display();
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ enum fastboot_return {
|
|||
FASTBOOT_CHAINLOAD,
|
||||
};
|
||||
|
||||
enum fastboot_return fastboot_enter(const bct0_t *bct0);
|
||||
enum fastboot_return fastboot_enter(const bct0_t *bct0, bool force);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "lib/vsprintf.h"
|
||||
#include "display/video_fb.h"
|
||||
#include "fastboot/fastboot.h"
|
||||
#include "btn.h"
|
||||
|
||||
extern void (*__program_exit_callback)(int rc);
|
||||
|
||||
|
@ -79,16 +80,6 @@ static void setup_env(void) {
|
|||
|
||||
/* Set up the exception handlers. */
|
||||
setup_exception_handlers();
|
||||
|
||||
/* Mount the SD card. */
|
||||
if (!mount_sd()) {
|
||||
fatal_error("Failed to mount SD card!\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanup_env(void) {
|
||||
/* Unmount the SD card. */
|
||||
unmount_sd();
|
||||
}
|
||||
|
||||
static void exit_callback(int rc) {
|
||||
|
@ -96,8 +87,8 @@ static void exit_callback(int rc) {
|
|||
relocate_and_chainload();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const char *bct0_string;
|
||||
int main(void) {
|
||||
const char *bct0_string = DEFAULT_BCT0;
|
||||
stage2_args_t *stage2_args;
|
||||
uint32_t stage2_version = 0;
|
||||
bct0_t bct0;
|
||||
|
@ -108,46 +99,126 @@ int main(void) {
|
|||
/* Check for panics. */
|
||||
check_and_display_panic();
|
||||
|
||||
/* Load the BCT0 configuration ini off of the SD. */
|
||||
bct0_string = load_config();
|
||||
bool should_greet = true;
|
||||
bool skip_fastboot = false;
|
||||
bool stage2_loaded = false;
|
||||
bool has_sd_card = false;
|
||||
|
||||
/* Parse the BCT0 configuration ini. */
|
||||
if (bct0_parse(bct0_string, &bct0) < 0) {
|
||||
fatal_error("Failed to parse BCT.ini!\n");
|
||||
while (!stage2_loaded) {
|
||||
|
||||
/* Try to mount the SD card and load configuration. */
|
||||
if (has_sd_card || mount_sd()) {
|
||||
/* Load the BCT0 configuration ini off of the SD. */
|
||||
bct0_string = load_config();
|
||||
|
||||
/* Parse the BCT0 configuration ini. */
|
||||
if (bct0_parse(bct0_string, &bct0) < 0) {
|
||||
fatal_error("Failed to parse BCT.ini!\n");
|
||||
}
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(bct0.log_level);
|
||||
|
||||
if (should_greet && bct0.log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||
/* Initialize the display for debugging. */
|
||||
log_setup_display();
|
||||
|
||||
/* Say hello. */
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", log_get_display_framebuffer());
|
||||
|
||||
should_greet = false;
|
||||
}
|
||||
|
||||
/* Run the MTC binary, if it hasn't already been run. */
|
||||
if (!stage2_run_mtc(&bct0)) {
|
||||
print(SCREEN_LOG_LEVEL_WARNING, "DRAM training failed! Continuing with untrained DRAM.\n");
|
||||
}
|
||||
|
||||
/* Assert that our configuration is sane. */
|
||||
stage2_validate_config(&bct0);
|
||||
|
||||
has_sd_card = true;
|
||||
} else {
|
||||
/* Initialize the display to show messages. */
|
||||
log_setup_display();
|
||||
|
||||
/* Override logging level. */
|
||||
log_set_log_level(SCREEN_LOG_LEVEL_INFO);
|
||||
|
||||
/* Prompt user for action. */
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Failed to mount SD card!\n");
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " Press Volume Up to retry.\n");
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " Press Volume Down to enter fastboot mode.\n");
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n Press POWER to reboot.\n");
|
||||
|
||||
/* Wait for user action. */
|
||||
uint32_t last_button = btn_read();
|
||||
while (true) {
|
||||
uint32_t button = btn_read();
|
||||
|
||||
if (button & BTN_VOL_UP && !(last_button & BTN_VOL_UP)) {
|
||||
/* Skip the rest of the loop and return to beginning. If we
|
||||
* succeed, don't offer to enter fastboot. */
|
||||
skip_fastboot = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (button & BTN_VOL_DOWN && !(last_button & BTN_VOL_DOWN)) {
|
||||
/* Do not skip entering fastboot mode, even if we were previously requested to. */
|
||||
skip_fastboot = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (button & BTN_POWER) {
|
||||
/* Reboot. */
|
||||
reboot_to_self();
|
||||
}
|
||||
|
||||
last_button = button;
|
||||
}
|
||||
|
||||
log_cleanup_display();
|
||||
}
|
||||
|
||||
if (!skip_fastboot) {
|
||||
/* Try to enter fastboot if we are configured to, or force it if SD mount failed and we reached this point. */
|
||||
switch(fastboot_enter(&bct0, !has_sd_card)) {
|
||||
case FASTBOOT_INVALID:
|
||||
case FASTBOOT_SKIPPED:
|
||||
break;
|
||||
case FASTBOOT_LOAD_STAGE2:
|
||||
/* Return to start of loop to reload configuration and try again. Do
|
||||
not attempt to enter fastboot again if config loads correctly,
|
||||
but do offer to enter fastboot again if SD mount still fails. */
|
||||
skip_fastboot = true;
|
||||
|
||||
continue;
|
||||
case FASTBOOT_CHAINLOAD:
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "fastboot: chainloading\n");
|
||||
|
||||
/* Break out of outer loop. Note that it is possible to reach
|
||||
* this codepath with no SD card, in which case we forward the
|
||||
* default BCT0 string to stage2.. */
|
||||
stage2_loaded = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load stage2 if the SD card mounted successfully and fastboot didn't continue out of the loop. */
|
||||
if (has_sd_card) {
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Loading stage2 from sd card...\n");
|
||||
|
||||
stage2_load(&bct0);
|
||||
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Finished loading stage2.\n");
|
||||
|
||||
stage2_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(bct0.log_level);
|
||||
|
||||
if (bct0.log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||
/* Initialize the display for debugging. */
|
||||
log_setup_display();
|
||||
}
|
||||
|
||||
/* Say hello. */
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", log_get_display_framebuffer());
|
||||
|
||||
/* Run the MTC binary. */
|
||||
if (!stage2_run_mtc(&bct0)) {
|
||||
print(SCREEN_LOG_LEVEL_WARNING, "DRAM training failed! Continuing with untrained DRAM.\n");
|
||||
}
|
||||
|
||||
/* Assert that our configuration is sane. */
|
||||
stage2_validate_config(&bct0);
|
||||
|
||||
/* Try to enter fastboot, if we are configured to. */
|
||||
switch(fastboot_enter(&bct0)) {
|
||||
case FASTBOOT_INVALID:
|
||||
case FASTBOOT_SKIPPED:
|
||||
case FASTBOOT_LOAD_STAGE2:
|
||||
/* Load the loader payload into DRAM. */
|
||||
stage2_load(&bct0);
|
||||
break;
|
||||
case FASTBOOT_CHAINLOAD:
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "fastboot: chainloading\n");
|
||||
break;
|
||||
}
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Continuing to stage2...\n");
|
||||
|
||||
/* Setup argument data. */
|
||||
strcpy(g_chainloader_arg_data, bct0.stage2_path);
|
||||
|
@ -157,8 +228,10 @@ int main(void) {
|
|||
strcpy(stage2_args->bct0, bct0_string);
|
||||
g_chainloader_argc = 2;
|
||||
|
||||
/* Terminate the boot environment. */
|
||||
cleanup_env();
|
||||
/* Cleanup environment. */
|
||||
if (has_sd_card) {
|
||||
unmount_sd();
|
||||
}
|
||||
|
||||
if (bct0.log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||
/* Wait a while for debugging. */
|
||||
|
@ -168,6 +241,8 @@ int main(void) {
|
|||
log_cleanup_display();
|
||||
}
|
||||
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Exiting...\n");
|
||||
|
||||
/* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, jump to Stage2. */
|
||||
__program_exit_callback = exit_callback;
|
||||
return 0;
|
||||
|
|
|
@ -148,7 +148,7 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
|||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Error Desc: %s (0x%x)\n", get_error_desc_str(ctx.error_desc), ctx.error_desc);
|
||||
|
||||
/* Save context to the SD card. */
|
||||
{
|
||||
if (mount_sd()) {
|
||||
char filepath[0x40];
|
||||
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
|
||||
filepath[sizeof(filepath)-1] = 0;
|
||||
|
@ -157,6 +157,10 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
|||
} else {
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Report saved to %s\n", filepath);
|
||||
}
|
||||
|
||||
unmount_sd();
|
||||
} else {
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Failed to mount SD card to save report!\n");
|
||||
}
|
||||
|
||||
/* Try to print a fix suggestion via automatic error detection. */
|
||||
|
|
|
@ -20,8 +20,13 @@
|
|||
#include "utils.h"
|
||||
|
||||
bool stage2_run_mtc(const bct0_t *bct0) {
|
||||
static bool has_run_mtc = false;
|
||||
FILINFO info;
|
||||
size_t size;
|
||||
|
||||
if (has_run_mtc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if the MTC binary is present. */
|
||||
if (f_stat(bct0->stage2_mtc_path, &info) != FR_OK) {
|
||||
|
@ -51,6 +56,8 @@ bool stage2_run_mtc(const bct0_t *bct0) {
|
|||
|
||||
/* Cleanup right away. */
|
||||
memset((void *)bct0->stage2_load_address, 0, size);
|
||||
|
||||
has_run_mtc = true;
|
||||
|
||||
return mtc_res;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue