mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-08-08 09:08:45 +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
|
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) {
|
extern "C" fastboot_return fastboot_enter(const bct0_t *bct0, bool force) {
|
||||||
bool should_enter = bct0->fastboot_force_enable;
|
bool should_enter = force || bct0->fastboot_force_enable;
|
||||||
|
|
||||||
log_setup_display();
|
if(should_enter) {
|
||||||
|
log_setup_display();
|
||||||
if (!should_enter) {
|
} else {
|
||||||
if (bct0->fastboot_button_timeout > 0) {
|
if (bct0->fastboot_button_timeout > 0) {
|
||||||
|
log_setup_display();
|
||||||
|
|
||||||
uint32_t timeout = bct0->fastboot_button_timeout;
|
uint32_t timeout = bct0->fastboot_button_timeout;
|
||||||
uint32_t start_time = get_time_ms();
|
uint32_t start_time = get_time_ms();
|
||||||
uint32_t last_message_secs = 0;
|
uint32_t last_message_secs = 0;
|
||||||
|
|
||||||
while (get_time_ms() - start_time < timeout) {
|
while (get_time_ms() - start_time < timeout) {
|
||||||
uint32_t seconds_remaining = (start_time + timeout - get_time_ms() + 999) / 1000;
|
uint32_t seconds_remaining = (start_time + timeout - get_time_ms() + 999) / 1000;
|
||||||
if (seconds_remaining != last_message_secs) {
|
if (seconds_remaining != last_message_secs) {
|
||||||
|
@ -48,20 +51,25 @@ extern "C" fastboot_return fastboot_enter(const bct0_t *bct0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print((ScreenLogLevel) (SCREEN_LOG_LEVEL_NONE | SCREEN_LOG_LEVEL_NO_PREFIX), "\n\n");
|
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) {
|
print(SCREEN_LOG_LEVEL_DEBUG, "Entering fastboot. (forced = %d)\n", force);
|
||||||
log_cleanup_display();
|
|
||||||
return FASTBOOT_SKIPPED;
|
|
||||||
}
|
|
||||||
|
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Entering fastboot.\n");
|
|
||||||
ams::xusb::Initialize();
|
ams::xusb::Initialize();
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Finished initializing USB hardware.\n");
|
print(SCREEN_LOG_LEVEL_DEBUG, "Finished initializing USB hardware.\n");
|
||||||
ams::xusb::EnableDevice(fastboot_gadget);
|
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), "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), "-------------------------------\n");
|
||||||
print((ScreenLogLevel) (SCREEN_LOG_LEVEL_NONE | SCREEN_LOG_LEVEL_NO_PREFIX), "Volume up: Reboot to RCM.\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();
|
fastboot_return r = fastboot_gadget.Run();
|
||||||
|
|
||||||
log_cleanup_display();
|
log_cleanup_display();
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum fastboot_return {
|
||||||
FASTBOOT_CHAINLOAD,
|
FASTBOOT_CHAINLOAD,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum fastboot_return fastboot_enter(const bct0_t *bct0);
|
enum fastboot_return fastboot_enter(const bct0_t *bct0, bool force);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "lib/vsprintf.h"
|
#include "lib/vsprintf.h"
|
||||||
#include "display/video_fb.h"
|
#include "display/video_fb.h"
|
||||||
#include "fastboot/fastboot.h"
|
#include "fastboot/fastboot.h"
|
||||||
|
#include "btn.h"
|
||||||
|
|
||||||
extern void (*__program_exit_callback)(int rc);
|
extern void (*__program_exit_callback)(int rc);
|
||||||
|
|
||||||
|
@ -79,16 +80,6 @@ static void setup_env(void) {
|
||||||
|
|
||||||
/* Set up the exception handlers. */
|
/* Set up the exception handlers. */
|
||||||
setup_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) {
|
static void exit_callback(int rc) {
|
||||||
|
@ -96,8 +87,8 @@ static void exit_callback(int rc) {
|
||||||
relocate_and_chainload();
|
relocate_and_chainload();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
const char *bct0_string;
|
const char *bct0_string = DEFAULT_BCT0;
|
||||||
stage2_args_t *stage2_args;
|
stage2_args_t *stage2_args;
|
||||||
uint32_t stage2_version = 0;
|
uint32_t stage2_version = 0;
|
||||||
bct0_t bct0;
|
bct0_t bct0;
|
||||||
|
@ -108,46 +99,126 @@ int main(void) {
|
||||||
/* Check for panics. */
|
/* Check for panics. */
|
||||||
check_and_display_panic();
|
check_and_display_panic();
|
||||||
|
|
||||||
/* Load the BCT0 configuration ini off of the SD. */
|
bool should_greet = true;
|
||||||
bct0_string = load_config();
|
bool skip_fastboot = false;
|
||||||
|
bool stage2_loaded = false;
|
||||||
|
bool has_sd_card = false;
|
||||||
|
|
||||||
/* Parse the BCT0 configuration ini. */
|
while (!stage2_loaded) {
|
||||||
if (bct0_parse(bct0_string, &bct0) < 0) {
|
|
||||||
fatal_error("Failed to parse BCT.ini!\n");
|
/* 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. */
|
print(SCREEN_LOG_LEVEL_DEBUG, "Continuing to stage2...\n");
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup argument data. */
|
/* Setup argument data. */
|
||||||
strcpy(g_chainloader_arg_data, bct0.stage2_path);
|
strcpy(g_chainloader_arg_data, bct0.stage2_path);
|
||||||
|
@ -157,8 +228,10 @@ int main(void) {
|
||||||
strcpy(stage2_args->bct0, bct0_string);
|
strcpy(stage2_args->bct0, bct0_string);
|
||||||
g_chainloader_argc = 2;
|
g_chainloader_argc = 2;
|
||||||
|
|
||||||
/* Terminate the boot environment. */
|
/* Cleanup environment. */
|
||||||
cleanup_env();
|
if (has_sd_card) {
|
||||||
|
unmount_sd();
|
||||||
|
}
|
||||||
|
|
||||||
if (bct0.log_level != SCREEN_LOG_LEVEL_NONE) {
|
if (bct0.log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||||
/* Wait a while for debugging. */
|
/* Wait a while for debugging. */
|
||||||
|
@ -168,6 +241,8 @@ int main(void) {
|
||||||
log_cleanup_display();
|
log_cleanup_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print(SCREEN_LOG_LEVEL_DEBUG, "Exiting...\n");
|
||||||
|
|
||||||
/* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, jump to Stage2. */
|
/* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, jump to Stage2. */
|
||||||
__program_exit_callback = exit_callback;
|
__program_exit_callback = exit_callback;
|
||||||
return 0;
|
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);
|
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. */
|
/* Save context to the SD card. */
|
||||||
{
|
if (mount_sd()) {
|
||||||
char filepath[0x40];
|
char filepath[0x40];
|
||||||
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
|
snprintf(filepath, sizeof(filepath) - 1, "/atmosphere/fatal_errors/report_%016llx.bin", ctx.report_identifier);
|
||||||
filepath[sizeof(filepath)-1] = 0;
|
filepath[sizeof(filepath)-1] = 0;
|
||||||
|
@ -157,6 +157,10 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
||||||
} else {
|
} else {
|
||||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "Report saved to %s\n", filepath);
|
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. */
|
/* Try to print a fix suggestion via automatic error detection. */
|
||||||
|
|
|
@ -20,8 +20,13 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
bool stage2_run_mtc(const bct0_t *bct0) {
|
bool stage2_run_mtc(const bct0_t *bct0) {
|
||||||
|
static bool has_run_mtc = false;
|
||||||
FILINFO info;
|
FILINFO info;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
if (has_run_mtc) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the MTC binary is present. */
|
/* Check if the MTC binary is present. */
|
||||||
if (f_stat(bct0->stage2_mtc_path, &info) != FR_OK) {
|
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. */
|
/* Cleanup right away. */
|
||||||
memset((void *)bct0->stage2_load_address, 0, size);
|
memset((void *)bct0->stage2_load_address, 0, size);
|
||||||
|
|
||||||
|
has_run_mtc = true;
|
||||||
|
|
||||||
return mtc_res;
|
return mtc_res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue