mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-03 05:12:34 +00:00
feat(core): allow passing postmortem info in bootargs
[no changelog]
This commit is contained in:
parent
cafed0d02b
commit
1a372b5019
@ -390,6 +390,16 @@ int bootloader_main(void) {
|
||||
|
||||
drivers_init(manufacturing_mode, &touch_initialized);
|
||||
|
||||
#ifdef USE_BOOTARGS_RSOD
|
||||
if (bootargs_get_command() == BOOT_COMMAND_SHOW_RSOD) {
|
||||
// post mortem info was left in bootargs
|
||||
boot_args_t args;
|
||||
bootargs_get_args(&args);
|
||||
rsod_gui(&args.pminfo);
|
||||
reboot_or_halt_after_rsod();
|
||||
}
|
||||
#endif // USE_BOOTARGS_RSOD
|
||||
|
||||
ui_screen_boot_stage_1(false);
|
||||
|
||||
#ifdef TREZOR_EMULATOR
|
||||
|
@ -194,6 +194,16 @@ int main(void) {
|
||||
|
||||
drivers_init();
|
||||
|
||||
#ifdef USE_BOOTARGS_RSOD
|
||||
if (bootargs_get_command() == BOOT_COMMAND_SHOW_RSOD) {
|
||||
// post mortem info was left in bootargs
|
||||
boot_args_t args;
|
||||
bootargs_get_args(&args);
|
||||
rsod_terminal(&args.pminfo);
|
||||
reboot_or_halt_after_rsod();
|
||||
}
|
||||
#endif // USE_BOOTARGS_RSOD
|
||||
|
||||
#if PRODUCTION && !defined STM32U5
|
||||
// for STM32U5, this check is moved to boardloader
|
||||
ensure_bootloader_min_version();
|
||||
|
@ -238,6 +238,8 @@ static void coreapp_init(applet_t *applet) {
|
||||
applet_init(applet, coreapp_header, &coreapp_layout, &coreapp_privileges);
|
||||
}
|
||||
|
||||
#ifndef USE_BOOTARGS_RSOD
|
||||
|
||||
// Shows RSOD (Red Screen of Death)
|
||||
static void show_rsod(const systask_postmortem_t *pminfo) {
|
||||
#ifdef RSOD_IN_COREAPP
|
||||
@ -281,13 +283,19 @@ static void init_and_show_rsod(const systask_postmortem_t *pminfo) {
|
||||
reboot_or_halt_after_rsod();
|
||||
}
|
||||
|
||||
#endif // USE_BOOTARGS_RSOD
|
||||
|
||||
// Kernel panic handler
|
||||
// (may be called from interrupt context)
|
||||
static void kernel_panic(const systask_postmortem_t *pminfo) {
|
||||
// Since the system state is unreliable, enter emergency mode
|
||||
// and show the RSOD.
|
||||
#ifndef USE_BOOTARGS_RSOD
|
||||
system_emergency_rescue(&init_and_show_rsod, pminfo);
|
||||
// The previous function call never returns
|
||||
#else
|
||||
reboot_with_rsod(pminfo);
|
||||
#endif // USE_BOOTARGS_RSOD
|
||||
// We never get here
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
@ -318,11 +326,14 @@ int main(void) {
|
||||
// Release the coreapp resources
|
||||
applet_stop(&coreapp);
|
||||
|
||||
#ifndef USE_BOOTARGS_RSOD
|
||||
// Coreapp crashed, show RSOD
|
||||
show_rsod(&coreapp.task.pminfo);
|
||||
|
||||
// Reboots or halts (if RSOD_INFINITE_LOOP is defined)
|
||||
reboot_or_halt_after_rsod();
|
||||
#else
|
||||
reboot_with_rsod(&coreapp.task.pminfo);
|
||||
#endif // USE_BOOTARGS_RSOD
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -69,10 +69,4 @@ boot_command_t bootargs_get_command();
|
||||
// Copies the boot arguments to the destination buffer
|
||||
void bootargs_get_args(boot_args_t* dest);
|
||||
|
||||
// Returns a pointer to the boot arguments structure.
|
||||
//
|
||||
// This function is intended to be used only in rescue mode, when the MPU
|
||||
// is disabled and the caller has full access to the boot arguments area.
|
||||
boot_args_t* bootargs_ptr(void);
|
||||
|
||||
#endif // TREZORHAL_BOOTARGS_H
|
||||
|
@ -17,10 +17,9 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_BOOTUTILS_H
|
||||
#define TREZORHAL_BOOTUTILS_H
|
||||
#pragma once
|
||||
|
||||
#include <trezor_types.h>
|
||||
#include <sys/systask.h>
|
||||
|
||||
// Immediately resets the device and initiates the normal boot sequence as if
|
||||
// the device was powered on
|
||||
@ -42,6 +41,13 @@ void __attribute__((noreturn)) reboot_to_bootloader(void);
|
||||
// with the firmware installation.
|
||||
void __attribute__((noreturn)) reboot_and_upgrade(const uint8_t hash[32]);
|
||||
|
||||
#ifdef USE_BOOTARGS_RSOD
|
||||
// Resets the device with post-mortem information in bootargs
|
||||
// so that the bootloader can display it.
|
||||
void __attribute__((noreturn))
|
||||
reboot_with_rsod(const systask_postmortem_t *pminfo);
|
||||
#endif
|
||||
|
||||
// Allows the user to read the displayed error message and then
|
||||
// reboots the device or waits for power-off.
|
||||
//
|
||||
@ -57,5 +63,3 @@ void __attribute__((noreturn)) reboot_or_halt_after_rsod(void);
|
||||
// Before jumping, the function disables all interrupts and clears the
|
||||
// memory and registers that could contain sensitive information.
|
||||
void __attribute__((noreturn)) jump_to_next_stage(uint32_t vectbl_address);
|
||||
|
||||
#endif // TREZORHAL_BOOTUTILS_H
|
||||
|
@ -79,14 +79,6 @@ void bootargs_set(boot_command_t command, const void* args, size_t args_size) {
|
||||
mpu_restore(mode);
|
||||
}
|
||||
|
||||
boot_args_t* bootargs_ptr(void) { return &g_boot_args; }
|
||||
|
||||
#ifdef BOOTLOADER
|
||||
// Contains the current boot command saved during bootloader startup.
|
||||
boot_command_t g_boot_command_saved;
|
||||
|
||||
boot_command_t bootargs_get_command() { return g_boot_command_saved; }
|
||||
|
||||
void bootargs_get_args(boot_args_t* dest) {
|
||||
mpu_mode_t mode = mpu_reconfig(MPU_MODE_BOOTARGS);
|
||||
|
||||
@ -95,6 +87,12 @@ void bootargs_get_args(boot_args_t* dest) {
|
||||
mpu_restore(mode);
|
||||
}
|
||||
|
||||
#ifdef BOOTLOADER
|
||||
// Contains the current boot command saved during bootloader startup.
|
||||
boot_command_t g_boot_command_saved;
|
||||
|
||||
boot_command_t bootargs_get_command() { return g_boot_command_saved; }
|
||||
|
||||
void bootargs_init(uint32_t r11_register) {
|
||||
#ifdef STM32U5
|
||||
g_boot_command_saved = g_boot_command;
|
||||
@ -220,6 +218,12 @@ __attribute__((noreturn)) void reboot_to_off(void) {
|
||||
reboot_with_args(BOOT_COMMAND_POWER_OFF, NULL, 0);
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void reboot_with_rsod(
|
||||
const systask_postmortem_t* pminfo) {
|
||||
// Set bootargs area to the new command and arguments
|
||||
reboot_with_args(BOOT_COMMAND_SHOW_RSOD, pminfo, sizeof(*pminfo));
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void reboot_or_halt_after_rsod(void) {
|
||||
#ifndef RSOD_INFINITE_LOOP
|
||||
systick_delay_ms(10 * 1000);
|
||||
|
@ -47,6 +47,11 @@ void system_deinit(void);
|
||||
//
|
||||
// The system will be in a state similar to a reset when `main()` is called
|
||||
// (but with some hardware peripherals still initialized and running).
|
||||
//
|
||||
// If `error_handler` is NULL the system will be reset immediately after
|
||||
// clearing the memory. If `USE_BOOTARGS_RSOD` is defined, the system will
|
||||
// leave the postmortem information in the bootargs allowing the bootloader
|
||||
// to display the RSOD.
|
||||
__attribute__((noreturn)) void system_emergency_rescue(
|
||||
systask_error_handler_t error_handler, const systask_postmortem_t* pminfo);
|
||||
|
||||
|
@ -85,9 +85,12 @@ system_emergency_rescue_phase_2(uint32_t arg1, uint32_t arg2) {
|
||||
// Reset peripherals (so we are sure that no DMA is pending)
|
||||
reset_peripherals_and_interrupts();
|
||||
|
||||
// Copy pminfo from to our stack
|
||||
// MPU is now disable, we have full access to bootargs.
|
||||
systask_postmortem_t pminfo = bootargs_ptr()->pminfo;
|
||||
// Althought MPU is disabled, we need to change MPU driver state
|
||||
mpu_reconfig(MPU_MODE_DISABLED);
|
||||
|
||||
// Copy bootargs to our stack
|
||||
boot_args_t bootargs;
|
||||
bootargs_get_args(&bootargs);
|
||||
|
||||
// Clear unused part of our stack
|
||||
clear_unused_stack();
|
||||
@ -97,10 +100,13 @@ system_emergency_rescue_phase_2(uint32_t arg1, uint32_t arg2) {
|
||||
uint32_t stack_chk_guard = __stack_chk_guard;
|
||||
|
||||
// Clear all memory except our stack.
|
||||
// NOTE: This also clear bootargs, so we don't pass pminfo structure
|
||||
// to the bootloader for now.
|
||||
// NOTE: This also clear bootargs, if the model doesn't support
|
||||
// showing RSOD in the bootloader startup.
|
||||
memregion_t region = MEMREGION_ALL_ACCESSIBLE_RAM;
|
||||
MEMREGION_DEL_SECTION(®ion, _stack_section);
|
||||
#ifdef USE_BOOTARGS_RSOD
|
||||
MEMREGION_DEL_SECTION(®ion, _bootargs_ram);
|
||||
#endif
|
||||
memregion_fill(®ion, 0);
|
||||
|
||||
// Reinitialize .bss, .data, ...
|
||||
@ -119,12 +125,16 @@ system_emergency_rescue_phase_2(uint32_t arg1, uint32_t arg2) {
|
||||
// in C code
|
||||
|
||||
if (error_handler != NULL) {
|
||||
error_handler(&pminfo);
|
||||
error_handler(&bootargs.pminfo);
|
||||
// We reach this point only if error_handler returns that's
|
||||
// not expected to happen. We clear the memory again and reboot.
|
||||
reboot_device();
|
||||
}
|
||||
|
||||
// We reach this point only if error_handler is NULL or
|
||||
// if it returns. Neither is expected to happen.
|
||||
reboot_device();
|
||||
// We reach this point only if error_handler is NULL
|
||||
// (if USE_BOOTARGS_RSOD is defined we leave postmortem info
|
||||
// in bootargs, so it can be used by the bootloader)
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
__attribute((naked, noreturn, no_stack_protector)) void system_emergency_rescue(
|
||||
|
@ -139,7 +139,9 @@ const char* system_fault_message(const system_fault_t* fault) {
|
||||
|
||||
void system_emergency_rescue(systask_error_handler_t error_handler,
|
||||
const systask_postmortem_t* pminfo) {
|
||||
if (error_handler != NULL) {
|
||||
error_handler(pminfo);
|
||||
}
|
||||
|
||||
// We should never reach this point
|
||||
reboot_device();
|
||||
|
@ -39,6 +39,7 @@ def configure(
|
||||
("USE_LSE", "1"),
|
||||
("FIXED_HW_DEINIT", "1"),
|
||||
("LOCKABLE_BOOTLOADER", "1"),
|
||||
("USE_BOOTARGS_RSOD", "1"),
|
||||
("TERMINAL_FONT_SCALE", "2"),
|
||||
("TERMINAL_X_PADDING", "4"),
|
||||
("TERMINAL_Y_PADDING", "12"),
|
||||
|
@ -39,6 +39,7 @@ def configure(
|
||||
("USE_LSE", "1"),
|
||||
("FIXED_HW_DEINIT", "1"),
|
||||
("LOCKABLE_BOOTLOADER", "1"),
|
||||
("USE_BOOTARGS_RSOD", "1"),
|
||||
("TERMINAL_FONT_SCALE", "2"),
|
||||
("TERMINAL_X_PADDING", "4"),
|
||||
("TERMINAL_Y_PADDING", "12"),
|
||||
|
@ -39,6 +39,7 @@ def configure(
|
||||
("USE_LSE", "1"),
|
||||
("FIXED_HW_DEINIT", "1"),
|
||||
("LOCKABLE_BOOTLOADER", "1"),
|
||||
("USE_BOOTARGS_RSOD", "1"),
|
||||
("TERMINAL_FONT_SCALE", "2"),
|
||||
("TERMINAL_X_PADDING", "4"),
|
||||
("TERMINAL_Y_PADDING", "12"),
|
||||
|
Loading…
Reference in New Issue
Block a user