fusee: cleanup and optimize boot sequence

This commit is contained in:
hexkyz 2019-07-06 20:58:01 +01:00
parent 2225b86eea
commit 85bf7c86e0
23 changed files with 143 additions and 111 deletions

View file

@ -79,7 +79,7 @@ typedef enum {
CARDEVICE_UARTC = ((1 << 5) | 0x17), CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC), CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF), CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_UNK = ((3 << 5) | 0x1E), CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F), CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C), CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13), CARDEVICE_TSEC = ((2 << 5) | 0x13),

View file

@ -25,7 +25,7 @@ static inline uint32_t get_clk_source_reg(CarDevice dev) {
case CARDEVICE_UARTC: return 0x1A0; case CARDEVICE_UARTC: return 0x1A0;
case CARDEVICE_I2C1: return 0x124; case CARDEVICE_I2C1: return 0x124;
case CARDEVICE_I2C5: return 0x128; case CARDEVICE_I2C5: return 0x128;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0x42C; case CARDEVICE_SE: return 0x42C;
case CARDEVICE_HOST1X: return 0x180; case CARDEVICE_HOST1X: return 0x180;
case CARDEVICE_TSEC: return 0x1F4; case CARDEVICE_TSEC: return 0x1F4;
@ -48,7 +48,7 @@ static inline uint32_t get_clk_source_val(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 6; case CARDEVICE_I2C1: return 6;
case CARDEVICE_I2C5: return 6; case CARDEVICE_I2C5: return 6;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 4; case CARDEVICE_HOST1X: return 4;
case CARDEVICE_TSEC: return 0; case CARDEVICE_TSEC: return 0;
@ -71,7 +71,7 @@ static inline uint32_t get_clk_source_div(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 0; case CARDEVICE_I2C1: return 0;
case CARDEVICE_I2C5: return 0; case CARDEVICE_I2C5: return 0;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 3; case CARDEVICE_HOST1X: return 3;
case CARDEVICE_TSEC: return 2; case CARDEVICE_TSEC: return 2;

View file

@ -42,7 +42,7 @@ typedef enum {
CARDEVICE_UARTC = ((1 << 5) | 0x17), CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC), CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF), CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_UNK = ((3 << 5) | 0x1E), CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F), CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C), CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13), CARDEVICE_TSEC = ((2 << 5) | 0x13),

View file

@ -236,8 +236,8 @@ void nx_hwinit()
/* NOTE: [4.0.0+] This was removed. */ /* NOTE: [4.0.0+] This was removed. */
/* clkrst_reboot(CARDEVICE_SE); */ /* clkrst_reboot(CARDEVICE_SE); */
/* Reboot unknown device. */ /* Reboot TZRAM. */
clkrst_reboot(CARDEVICE_UNK); clkrst_reboot(CARDEVICE_TZRAM);
/* Initialize I2C1. */ /* Initialize I2C1. */
/* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */ /* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */

View file

@ -84,12 +84,9 @@ static int config_ini_handler(void *user, const char *section, const char *name,
return 1; return 1;
} }
static void setup_env(void) { static void setup_display(void) {
g_framebuffer = (void *)0xC0000000; g_framebuffer = (void *)0xC0000000;
/* Initialize hardware. */
nx_hwinit();
/* Zero-fill the framebuffer and register it as printk provider. */ /* Zero-fill the framebuffer and register it as printk provider. */
video_init(g_framebuffer); video_init(g_framebuffer);
@ -102,6 +99,19 @@ static void setup_env(void) {
/* Turn on the backlight after initializing the lfb */ /* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */ /* to avoid flickering. */
display_backlight(true); display_backlight(true);
}
static void cleanup_display(void) {
/* Turn off the backlight. */
display_backlight(false);
/* Terminate the display. */
display_end();
}
static void setup_env(void) {
/* Initialize hardware. */
nx_hwinit();
/* Set up the exception handlers. */ /* Set up the exception handlers. */
setup_exception_handlers(); setup_exception_handlers();
@ -113,9 +123,6 @@ static void setup_env(void) {
static void cleanup_env(void) { static void cleanup_env(void) {
/* Unmount the SD card. */ /* Unmount the SD card. */
unmount_sd(); unmount_sd();
display_backlight(false);
display_end();
} }
static void exit_callback(int rc) { static void exit_callback(int rc) {
@ -128,12 +135,9 @@ int main(void) {
const char *stage2_path; const char *stage2_path;
stage2_args_t *stage2_args; stage2_args_t *stage2_args;
uint32_t stage2_version = 0; uint32_t stage2_version = 0;
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_MANDATORY; ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
/* Override the global logging level. */ /* Initialize the boot environment. */
log_set_log_level(log_level);
/* Initialize the display, console, etc. */
setup_env(); setup_env();
/* Check for panics. */ /* Check for panics. */
@ -147,8 +151,16 @@ int main(void) {
fatal_error("Failed to parse BCT.ini!\n"); fatal_error("Failed to parse BCT.ini!\n");
} }
/* Override the global logging level. */
log_set_log_level(log_level);
if (log_level != SCREEN_LOG_LEVEL_NONE) {
/* Initialize the display for debugging. */
setup_display();
}
/* Say hello. */ /* Say hello. */
print(SCREEN_LOG_LEVEL_MANDATORY, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n"); 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", g_framebuffer); print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
/* Load the loader payload into DRAM. */ /* Load the loader payload into DRAM. */
@ -160,15 +172,19 @@ int main(void) {
stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */ stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */
memcpy(&stage2_args->version, &stage2_version, 4); memcpy(&stage2_args->version, &stage2_version, 4);
memcpy(&stage2_args->log_level, &log_level, sizeof(log_level)); memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
stage2_args->display_initialized = false;
strcpy(stage2_args->bct0, bct0); strcpy(stage2_args->bct0, bct0);
g_chainloader_argc = 2; g_chainloader_argc = 2;
/* Wait a while. */ /* Terminate the boot environment. */
mdelay(1000);
/* Deinitialize the display, console, etc. */
cleanup_env(); cleanup_env();
if (log_level != SCREEN_LOG_LEVEL_NONE) {
/* Wait a while for debugging. */
mdelay(1000);
/* Terminate the display for debugging. */
cleanup_display();
}
/* 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;

View file

@ -22,6 +22,7 @@
#include "utils.h" #include "utils.h"
#include "fs_utils.h" #include "fs_utils.h"
#include "lib/log.h" #include "lib/log.h"
#include "display/video_fb.h"
static uint32_t g_panic_code = 0; static uint32_t g_panic_code = 0;
@ -56,6 +57,22 @@ static void _check_and_display_atmosphere_fatal_error(void) {
} }
{ {
/* Zero-fill the framebuffer and register it as printk provider. */
video_init((void *)0xC0000000);
/* Initialize the display. */
display_init();
/* Set the framebuffer. */
display_init_framebuffer((void *)0xC0000000);
/* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */
display_backlight(true);
/* Override the global logging level. */
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
/* Copy fatal error context to the stack. */ /* Copy fatal error context to the stack. */
atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT); atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT);
@ -79,6 +96,7 @@ static void _check_and_display_atmosphere_fatal_error(void) {
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n"); print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
} }
/* Wait for button and reboot. */
wait_for_button_and_reboot(); wait_for_button_and_reboot();
} }
@ -87,11 +105,9 @@ void check_and_display_panic(void) {
_check_and_display_atmosphere_fatal_error(); _check_and_display_atmosphere_fatal_error();
/* We also handle our own panics. */ /* We also handle our own panics. */
/* In the case of our own panics, we assume that the display has already been initialized. */ bool has_panic = ((APBDEV_PMC_RST_STATUS_0 != 0) || (g_panic_code != 0));
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0; uint32_t code = (g_panic_code == 0) ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
uint32_t code = g_panic_code == 0 ? APBDEV_PMC_SCRATCH200_0 : g_panic_code; has_panic = has_panic && !((APBDEV_PMC_RST_STATUS_0 != 1) && (code == PANIC_CODE_SAFEMODE));
has_panic = has_panic && !(APBDEV_PMC_RST_STATUS_0 != 1 && code == PANIC_CODE_SAFEMODE);
if (has_panic) { if (has_panic) {
uint32_t color; uint32_t color;
@ -134,11 +150,13 @@ void check_and_display_panic(void) {
break; break;
} }
if (g_panic_code == 0) { /* Initialize the display. */
display_init(); display_init();
}
/* Fill the screen. */
display_color_screen(color); display_color_screen(color);
/* Wait for button and reboot. */
wait_for_button_and_reboot(); wait_for_button_and_reboot();
} else { } else {
g_panic_code = 0; g_panic_code = 0;

View file

@ -28,7 +28,6 @@
#define PANIC_CODE_SAFEMODE 0x00000020 #define PANIC_CODE_SAFEMODE 0x00000020
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20 #define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100 #define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100

View file

@ -34,6 +34,7 @@
#define STAGE2_NAME_KEY "stage2_path" #define STAGE2_NAME_KEY "stage2_path"
#define STAGE2_ADDRESS_KEY "stage2_addr" #define STAGE2_ADDRESS_KEY "stage2_addr"
#define STAGE2_ENTRYPOINT_KEY "stage2_entrypoint" #define STAGE2_ENTRYPOINT_KEY "stage2_entrypoint"
#define BCTO_MAX_SIZE 0x5800 #define BCTO_MAX_SIZE 0x5800
typedef struct { typedef struct {
@ -45,7 +46,6 @@ typedef struct {
typedef struct { typedef struct {
uint32_t version; uint32_t version;
ScreenLogLevel log_level; ScreenLogLevel log_level;
bool display_initialized;
char bct0[BCTO_MAX_SIZE]; char bct0[BCTO_MAX_SIZE];
} stage2_args_t; } stage2_args_t;

View file

@ -25,7 +25,7 @@ static inline uint32_t get_clk_source_reg(CarDevice dev) {
case CARDEVICE_UARTC: return 0x1A0; case CARDEVICE_UARTC: return 0x1A0;
case CARDEVICE_I2C1: return 0x124; case CARDEVICE_I2C1: return 0x124;
case CARDEVICE_I2C5: return 0x128; case CARDEVICE_I2C5: return 0x128;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0x42C; case CARDEVICE_SE: return 0x42C;
case CARDEVICE_HOST1X: return 0x180; case CARDEVICE_HOST1X: return 0x180;
case CARDEVICE_TSEC: return 0x1F4; case CARDEVICE_TSEC: return 0x1F4;
@ -48,7 +48,7 @@ static inline uint32_t get_clk_source_val(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 6; case CARDEVICE_I2C1: return 6;
case CARDEVICE_I2C5: return 6; case CARDEVICE_I2C5: return 6;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 4; case CARDEVICE_HOST1X: return 4;
case CARDEVICE_TSEC: return 0; case CARDEVICE_TSEC: return 0;
@ -71,7 +71,7 @@ static inline uint32_t get_clk_source_div(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 0; case CARDEVICE_I2C1: return 0;
case CARDEVICE_I2C5: return 0; case CARDEVICE_I2C5: return 0;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 3; case CARDEVICE_HOST1X: return 3;
case CARDEVICE_TSEC: return 2; case CARDEVICE_TSEC: return 2;

View file

@ -42,7 +42,7 @@ typedef enum {
CARDEVICE_UARTC = ((1 << 5) | 0x17), CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC), CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF), CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_UNK = ((3 << 5) | 0x1E), CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F), CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C), CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13), CARDEVICE_TSEC = ((2 << 5) | 0x13),

View file

@ -97,26 +97,23 @@ static ssize_t decode_utf8(uint32_t *out, const uint8_t *in) {
} }
static void console_init_display(void) { static void console_init_display(void) {
if (!g_display_initialized) { /* Initialize the display. */
/* Initialize the display. */ display_init();
display_init();
}
/* Set the framebuffer. */ /* Set the framebuffer. */
display_init_framebuffer(g_framebuffer); display_init_framebuffer(g_framebuffer);
/* Turn on the backlight after initializing the lfb */ /* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */ /* to avoid flickering. */
if (!g_display_initialized) { display_backlight(true);
display_backlight(true);
}
/* Display is initialized. */
g_display_initialized = true; g_display_initialized = true;
} }
static ssize_t console_write(struct _reent *r, void *fd, const char *ptr, size_t len) { static ssize_t console_write(struct _reent *r, void *fd, const char *ptr, size_t len) {
size_t i = 0; size_t i = 0;
if (!g_display_initialized) { if (!g_display_initialized && (g_framebuffer != NULL)) {
console_init_display(); console_init_display();
} }
while (i < len) { while (i < len) {
@ -138,6 +135,8 @@ static int console_create(void) {
errno = EEXIST; errno = EEXIST;
return -1; return -1;
} }
/* Allocate memory for the framebuffer. */
g_framebuffer = memalign(0x1000, CONFIG_VIDEO_VISIBLE_ROWS * CONFIG_VIDEO_COLS * CONFIG_VIDEO_PIXEL_SIZE); g_framebuffer = memalign(0x1000, CONFIG_VIDEO_VISIBLE_ROWS * CONFIG_VIDEO_COLS * CONFIG_VIDEO_PIXEL_SIZE);
if (g_framebuffer == NULL) { if (g_framebuffer == NULL) {
@ -154,9 +153,7 @@ static int console_create(void) {
return 0; return 0;
} }
int console_init(bool display_initialized) { int console_init(void) {
g_display_initialized = display_initialized;
if (console_create() == -1) { if (console_create() == -1) {
return -1; return -1;
} }
@ -171,15 +168,15 @@ int console_init(bool display_initialized) {
return 0; return 0;
} }
void *console_get_framebuffer(bool enable_display) { void *console_get_framebuffer(void) {
if (g_framebuffer != NULL && enable_display) { if (!g_display_initialized && (g_framebuffer != NULL)) {
console_init_display(); console_init_display();
} }
return g_framebuffer; return g_framebuffer;
} }
int console_display(const void *framebuffer) { int console_display(const void *framebuffer) {
if (!g_display_initialized) { if (!g_display_initialized && (g_framebuffer != NULL)) {
console_init_display(); console_init_display();
} }
display_init_framebuffer((void *)framebuffer); display_init_framebuffer((void *)framebuffer);
@ -187,7 +184,7 @@ int console_display(const void *framebuffer) {
} }
int console_resume(void) { int console_resume(void) {
if (!g_display_initialized) { if (!g_display_initialized && (g_framebuffer != NULL)) {
console_init_display(); console_init_display();
} else { } else {
display_init_framebuffer(g_framebuffer); display_init_framebuffer(g_framebuffer);
@ -196,10 +193,15 @@ int console_resume(void) {
} }
int console_end(void) { int console_end(void) {
/* Deinitialize the framebuffer and display */ if (g_display_initialized) {
if (g_display_initialized) { /* Turn off the backlight. */
display_backlight(false); display_backlight(false);
/* Terminate the display. */
display_end(); display_end();
/* Display is terminated. */
g_display_initialized = false;
} }
free(g_framebuffer); free(g_framebuffer);
g_framebuffer = NULL; g_framebuffer = NULL;

View file

@ -24,8 +24,8 @@
#include <malloc.h> #include <malloc.h>
#include <sys/iosupport.h> #include <sys/iosupport.h>
int console_init(bool display_initialized); int console_init(void);
void *console_get_framebuffer(bool enable_display); void *console_get_framebuffer(void);
int console_display(const void *framebuffer); /* Must be page-aligned */ int console_display(const void *framebuffer); /* Must be page-aligned */
int console_resume(void); int console_resume(void);
int console_end(void); int console_end(void);

View file

@ -44,28 +44,26 @@ static stage2_args_t *g_stage2_args;
static bool g_do_nxboot; static bool g_do_nxboot;
static void setup_env(void) { static void setup_env(void) {
/* Set the console up. */ /* Initialize the display and console. */
if (console_init(g_stage2_args->display_initialized) == -1) { if (console_init() < 0) {
generic_panic(); generic_panic();
} }
/* Set up exception handlers. */ /* Set up exception handlers. */
setup_exception_handlers(); setup_exception_handlers();
/* Train DRAM. */
train_dram();
/* Initialize the file system by mounting the SD card. */ /* Initialize the file system by mounting the SD card. */
if (nxfs_init() < 0) { if (nxfs_init() < 0) {
fatal_error("Failed to initialize the file system: %s\n", strerror(errno)); fatal_error("Failed to initialize the file system: %s\n", strerror(errno));
} }
/* Train DRAM. */
train_dram();
} }
static void cleanup_env(void) { static void cleanup_env(void) {
/* Unmount everything (this causes all open files to be flushed and closed) */ /* Terminate the file system. */
nxfs_end(); nxfs_end();
//console_end();
} }
static void exit_callback(int rc) { static void exit_callback(int rc) {
@ -83,6 +81,7 @@ static void exit_callback(int rc) {
int main(int argc, void **argv) { int main(int argc, void **argv) {
loader_ctx_t *loader_ctx = get_loader_ctx(); loader_ctx_t *loader_ctx = get_loader_ctx();
/* Check argc. */
if (argc != STAGE2_ARGC) { if (argc != STAGE2_ARGC) {
generic_panic(); generic_panic();
} }
@ -90,6 +89,7 @@ int main(int argc, void **argv) {
g_stage2_args = &g_stage2_args_store; g_stage2_args = &g_stage2_args_store;
memcpy(g_stage2_args, (stage2_args_t *)argv[STAGE2_ARGV_ARGUMENT_STRUCT], sizeof(*g_stage2_args)); memcpy(g_stage2_args, (stage2_args_t *)argv[STAGE2_ARGV_ARGUMENT_STRUCT], sizeof(*g_stage2_args));
/* Check stage2 version field. */
if (g_stage2_args->version != 0) { if (g_stage2_args->version != 0) {
generic_panic(); generic_panic();
} }
@ -97,9 +97,9 @@ int main(int argc, void **argv) {
/* Override the global logging level. */ /* Override the global logging level. */
log_set_log_level(g_stage2_args->log_level); log_set_log_level(g_stage2_args->log_level);
/* Initialize the display, console, FS, etc. */ /* Initialize the boot environment. */
setup_env(); setup_env();
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, u8"Welcome to Atmosphère Fusée Stage 2!\n"); print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, u8"Welcome to Atmosphère Fusée Stage 2!\n");
print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]); print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]);
@ -114,17 +114,21 @@ int main(int argc, void **argv) {
/* This will load all remaining binaries off of the SD. */ /* This will load all remaining binaries off of the SD. */
load_payload(g_stage2_args->bct0); load_payload(g_stage2_args->bct0);
print(SCREEN_LOG_LEVEL_INFO, "Loaded payloads!\n"); print(SCREEN_LOG_LEVEL_INFO, "Loaded payloads!\n");
g_do_nxboot = loader_ctx->chainload_entrypoint == 0; g_do_nxboot = (loader_ctx->chainload_entrypoint == 0);
if (g_do_nxboot) { if (g_do_nxboot) {
print(SCREEN_LOG_LEVEL_INFO, "Now performing nxboot.\n"); print(SCREEN_LOG_LEVEL_INFO, "Now performing nxboot.\n");
/* Start boot. */
uint32_t boot_memaddr = nxboot_main(); uint32_t boot_memaddr = nxboot_main();
/* Wait for the splash screen to have been displayed as long as it should be. */ /* Wait for the splash screen to have been displayed as long as it should be. */
splash_screen_wait_delay(); splash_screen_wait_delay();
/* Cleanup environment. */
/* Terminate the boot environment. */
cleanup_env(); cleanup_env();
/* Finish boot. */ /* Finish boot. */
nxboot_finish(boot_memaddr); nxboot_finish(boot_memaddr);
} else { } else {
@ -133,11 +137,11 @@ int main(int argc, void **argv) {
print(SCREEN_LOG_LEVEL_MANDATORY, "Now chainloading.\n"); print(SCREEN_LOG_LEVEL_MANDATORY, "Now chainloading.\n");
g_chainloader_argc = 1; g_chainloader_argc = 1;
strcpy(g_chainloader_arg_data, path); strcpy(g_chainloader_arg_data, path);
/* Terminate the boot environment. */
cleanup_env();
} }
/* Deinitialize the display, console, FS, etc. */
cleanup_env();
/* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, chainload or halt ourselves. */ /* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, chainload or halt ourselves. */
__program_exit_callback = exit_callback; __program_exit_callback = exit_callback;

View file

@ -650,7 +650,6 @@ uint32_t nxboot_main(void) {
} }
} }
//fatal_error("Ran sept!");
/* Display splash screen. */ /* Display splash screen. */
display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000); display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000);
@ -801,9 +800,6 @@ uint32_t nxboot_main(void) {
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Powering on the CCPLEX...\n"); print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Powering on the CCPLEX...\n");
/* Unmount everything. */
nxfs_end();
/* Return the memory address for booting CPU0. */ /* Return the memory address for booting CPU0. */
return (uint32_t)exosphere_memaddr; return (uint32_t)exosphere_memaddr;
} }

View file

@ -24,11 +24,9 @@ static uint32_t g_panic_code = 0;
void check_and_display_panic(void) { void check_and_display_panic(void) {
/* We also handle our own panics. */ /* We also handle our own panics. */
/* In the case of our own panics, we assume that the display has already been initialized. */ bool has_panic = ((APBDEV_PMC_RST_STATUS_0 != 0) || (g_panic_code != 0));
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0; uint32_t code = (g_panic_code == 0) ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
uint32_t code = g_panic_code == 0 ? APBDEV_PMC_SCRATCH200_0 : g_panic_code; has_panic = has_panic && !((APBDEV_PMC_RST_STATUS_0 != 1) && (code == PANIC_CODE_SAFEMODE));
has_panic = has_panic && !(APBDEV_PMC_RST_STATUS_0 != 1 && code == PANIC_CODE_SAFEMODE);
if (has_panic) { if (has_panic) {
uint32_t color; uint32_t color;
@ -71,11 +69,13 @@ void check_and_display_panic(void) {
break; break;
} }
if (g_panic_code == 0) { /* Initialize the display. */
display_init(); display_init();
}
/* Fill the screen. */
display_color_screen(color); display_color_screen(color);
/* Wait for button and reboot. */
wait_for_button_and_reboot(); wait_for_button_and_reboot();
} else { } else {
g_panic_code = 0; g_panic_code = 0;

View file

@ -30,7 +30,6 @@
typedef struct { typedef struct {
uint32_t version; uint32_t version;
ScreenLogLevel log_level; ScreenLogLevel log_level;
bool display_initialized;
char bct0[BCTO_MAX_SIZE]; char bct0[BCTO_MAX_SIZE];
} stage2_args_t; } stage2_args_t;

View file

@ -25,7 +25,7 @@ static inline uint32_t get_clk_source_reg(CarDevice dev) {
case CARDEVICE_UARTC: return 0x1A0; case CARDEVICE_UARTC: return 0x1A0;
case CARDEVICE_I2C1: return 0x124; case CARDEVICE_I2C1: return 0x124;
case CARDEVICE_I2C5: return 0x128; case CARDEVICE_I2C5: return 0x128;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0x42C; case CARDEVICE_SE: return 0x42C;
case CARDEVICE_HOST1X: return 0x180; case CARDEVICE_HOST1X: return 0x180;
case CARDEVICE_TSEC: return 0x1F4; case CARDEVICE_TSEC: return 0x1F4;
@ -48,7 +48,7 @@ static inline uint32_t get_clk_source_val(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 6; case CARDEVICE_I2C1: return 6;
case CARDEVICE_I2C5: return 6; case CARDEVICE_I2C5: return 6;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 4; case CARDEVICE_HOST1X: return 4;
case CARDEVICE_TSEC: return 0; case CARDEVICE_TSEC: return 0;
@ -71,7 +71,7 @@ static inline uint32_t get_clk_source_div(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 0; case CARDEVICE_I2C1: return 0;
case CARDEVICE_I2C5: return 0; case CARDEVICE_I2C5: return 0;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 3; case CARDEVICE_HOST1X: return 3;
case CARDEVICE_TSEC: return 2; case CARDEVICE_TSEC: return 2;

View file

@ -42,7 +42,7 @@ typedef enum {
CARDEVICE_UARTC = ((1 << 5) | 0x17), CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC), CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF), CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_UNK = ((3 << 5) | 0x1E), CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F), CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C), CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13), CARDEVICE_TSEC = ((2 << 5) | 0x13),

View file

@ -25,7 +25,7 @@ static inline uint32_t get_clk_source_reg(CarDevice dev) {
case CARDEVICE_UARTC: return 0x1A0; case CARDEVICE_UARTC: return 0x1A0;
case CARDEVICE_I2C1: return 0x124; case CARDEVICE_I2C1: return 0x124;
case CARDEVICE_I2C5: return 0x128; case CARDEVICE_I2C5: return 0x128;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0x42C; case CARDEVICE_SE: return 0x42C;
case CARDEVICE_HOST1X: return 0x180; case CARDEVICE_HOST1X: return 0x180;
case CARDEVICE_TSEC: return 0x1F4; case CARDEVICE_TSEC: return 0x1F4;
@ -48,7 +48,7 @@ static inline uint32_t get_clk_source_val(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 6; case CARDEVICE_I2C1: return 6;
case CARDEVICE_I2C5: return 6; case CARDEVICE_I2C5: return 6;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 4; case CARDEVICE_HOST1X: return 4;
case CARDEVICE_TSEC: return 0; case CARDEVICE_TSEC: return 0;
@ -71,7 +71,7 @@ static inline uint32_t get_clk_source_div(CarDevice dev) {
case CARDEVICE_UARTC: return 0; case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 0; case CARDEVICE_I2C1: return 0;
case CARDEVICE_I2C5: return 0; case CARDEVICE_I2C5: return 0;
case CARDEVICE_UNK: return 0; case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0; case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 3; case CARDEVICE_HOST1X: return 3;
case CARDEVICE_TSEC: return 2; case CARDEVICE_TSEC: return 2;

View file

@ -42,7 +42,7 @@ typedef enum {
CARDEVICE_UARTC = ((1 << 5) | 0x17), CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC), CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF), CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_UNK = ((3 << 5) | 0x1E), CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F), CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C), CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13), CARDEVICE_TSEC = ((2 << 5) | 0x13),

View file

@ -236,8 +236,8 @@ void nx_hwinit()
/* NOTE: [4.0.0+] This was removed. */ /* NOTE: [4.0.0+] This was removed. */
/* clkrst_reboot(CARDEVICE_SE); */ /* clkrst_reboot(CARDEVICE_SE); */
/* Reboot unknown device. */ /* Reboot TZRAM. */
clkrst_reboot(CARDEVICE_UNK); clkrst_reboot(CARDEVICE_TZRAM);
/* Initialize I2C1. */ /* Initialize I2C1. */
/* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */ /* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */

View file

@ -48,7 +48,6 @@ static void set_has_rebooted(bool rebooted) {
MAKE_REG32(0x4003FFFC) = rebooted ? 0xFAFAFAFA : 0x00000000; MAKE_REG32(0x4003FFFC) = rebooted ? 0xFAFAFAFA : 0x00000000;
} }
static void exfiltrate_keys_and_reboot_if_needed(uint32_t version) { static void exfiltrate_keys_and_reboot_if_needed(uint32_t version) {
volatile tegra_pmc_t *pmc = pmc_get_regs(); volatile tegra_pmc_t *pmc = pmc_get_regs();
uint8_t *enc_se_state = (uint8_t *)0x4003E000; uint8_t *enc_se_state = (uint8_t *)0x4003E000;
@ -124,7 +123,10 @@ static void cleanup_env(void) {
/* Unmount the SD card. */ /* Unmount the SD card. */
unmount_sd(); unmount_sd();
/* Turn off the backlight. */
display_backlight(false); display_backlight(false);
/* Terminate the display. */
display_end(); display_end();
} }
@ -150,7 +152,7 @@ int sept_main(uint32_t version) {
/* Override the global logging level. */ /* Override the global logging level. */
log_set_log_level(log_level); log_set_log_level(log_level);
/* Initialize the display, console, etc. */ /* Initialize the boot environment. */
setup_env(); setup_env();
/* Mark EMC scratch to say that sept has run. */ /* Mark EMC scratch to say that sept has run. */
@ -166,14 +168,10 @@ int sept_main(uint32_t version) {
stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */ stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */
memcpy(&stage2_args->version, &stage2_version, 4); memcpy(&stage2_args->version, &stage2_version, 4);
memcpy(&stage2_args->log_level, &log_level, sizeof(log_level)); memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
stage2_args->display_initialized = false;
strcpy(stage2_args->bct0, ""); strcpy(stage2_args->bct0, "");
g_chainloader_argc = 2; g_chainloader_argc = 2;
/* Wait a while. */ /* Terminate the boot environment. */
mdelay(1500);
/* Deinitialize the display, console, etc. */
cleanup_env(); cleanup_env();
/* 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. */

View file

@ -34,6 +34,7 @@
#define STAGE2_NAME_KEY "stage2_path" #define STAGE2_NAME_KEY "stage2_path"
#define STAGE2_ADDRESS_KEY "stage2_addr" #define STAGE2_ADDRESS_KEY "stage2_addr"
#define STAGE2_ENTRYPOINT_KEY "stage2_entrypoint" #define STAGE2_ENTRYPOINT_KEY "stage2_entrypoint"
#define BCTO_MAX_SIZE 0x5800 #define BCTO_MAX_SIZE 0x5800
typedef struct { typedef struct {
@ -45,7 +46,6 @@ typedef struct {
typedef struct { typedef struct {
uint32_t version; uint32_t version;
ScreenLogLevel log_level; ScreenLogLevel log_level;
bool display_initialized;
char bct0[BCTO_MAX_SIZE]; char bct0[BCTO_MAX_SIZE];
} stage2_args_t; } stage2_args_t;