diff --git a/core/SConscript.boardloader b/core/SConscript.boardloader
index 8739c28b14..cc31e0b6b8 100644
--- a/core/SConscript.boardloader
+++ b/core/SConscript.boardloader
@@ -68,6 +68,7 @@ CPPPATH_MOD += [
SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',
diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader
index 5f20c9e5c1..889b2d085d 100644
--- a/core/SConscript.bootloader
+++ b/core/SConscript.bootloader
@@ -107,6 +107,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',
diff --git a/core/SConscript.bootloader_ci b/core/SConscript.bootloader_ci
index 87d707c392..56e3b136d7 100644
--- a/core/SConscript.bootloader_ci
+++ b/core/SConscript.bootloader_ci
@@ -98,6 +98,7 @@ SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_draw.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/image.c',
diff --git a/core/SConscript.bootloader_emu b/core/SConscript.bootloader_emu
index 7ec0641d12..67c8588caa 100644
--- a/core/SConscript.bootloader_emu
+++ b/core/SConscript.bootloader_emu
@@ -102,6 +102,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',
@@ -109,6 +110,7 @@ SOURCE_MOD += [
'embed/lib/gfx_bitblt_rgb565.c',
'embed/lib/gfx_bitblt_rgba8888.c',
'embed/lib/image.c',
+ 'embed/lib/mini_printf.c',
'embed/lib/terminal.c',
'embed/lib/touch.c',
'embed/lib/unit_variant.c',
@@ -144,10 +146,10 @@ SOURCE_BOOTLOADER = [
SOURCE_TREZORHAL = [
'embed/trezorhal/unix/boot_args.c',
+ 'embed/trezorhal/unix/common.c',
'embed/trezorhal/unix/fault_handlers.c',
'embed/trezorhal/unix/flash.c',
'embed/trezorhal/unix/flash_otp.c',
- 'embed/trezorhal/unix/common.c',
'embed/trezorhal/unix/touch/touch.c',
'embed/trezorhal/unix/rng.c',
'embed/trezorhal/unix/usb.c',
diff --git a/core/SConscript.firmware b/core/SConscript.firmware
index 32e006a9b1..53a89386e6 100644
--- a/core/SConscript.firmware
+++ b/core/SConscript.firmware
@@ -226,6 +226,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',
diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest
index e31d941896..4e32efdb69 100644
--- a/core/SConscript.prodtest
+++ b/core/SConscript.prodtest
@@ -102,6 +102,7 @@ SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_draw.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/image.c',
diff --git a/core/SConscript.reflash b/core/SConscript.reflash
index 1a9a313f57..a9d343542e 100644
--- a/core/SConscript.reflash
+++ b/core/SConscript.reflash
@@ -74,6 +74,7 @@ SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_draw.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/image.c',
diff --git a/core/SConscript.unix b/core/SConscript.unix
index e4736c0d85..3a9fe3f88b 100644
--- a/core/SConscript.unix
+++ b/core/SConscript.unix
@@ -232,6 +232,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
+ 'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',
@@ -239,6 +240,7 @@ SOURCE_MOD += [
'embed/lib/gfx_bitblt_rgba8888.c',
'embed/lib/gfx_bitblt_mono8.c',
'embed/lib/image.c',
+ 'embed/lib/mini_printf.c',
'embed/lib/terminal.c',
'embed/lib/translations.c',
'embed/lib/unit_variant.c',
diff --git a/core/embed/bootloader/emulator.c b/core/embed/bootloader/emulator.c
index 5b36e1fe93..dd03ba38e3 100644
--- a/core/embed/bootloader/emulator.c
+++ b/core/embed/bootloader/emulator.c
@@ -88,27 +88,6 @@ bool load_firmware(const char *filename, uint8_t *hash) {
return true;
}
-__attribute__((noreturn)) void display_error_and_die(const char *message,
- const char *title,
- const char *footer) {
- if (footer == NULL) {
- footer = "PLEASE VISIT\nTREZOR.IO/RSOD";
- }
- if (title == NULL) {
- title = "INTERNAL ERROR";
- }
- display_init();
- display_backlight(180);
- screen_fatal_error_rust(title, message, footer);
-#if USE_TOUCH
- printf("Click screen to exit.\n");
-#elif USE_BUTTON
- printf("Press both buttons to exit.\n");
-#endif
- ui_click();
- exit(0);
-}
-
__attribute__((noreturn)) int main(int argc, char **argv) {
display_init();
flash_init();
@@ -175,7 +154,7 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
} else {
message = "No message specified";
}
- display_error_and_die(message, title, footer);
+ error_shutdown_ex(title, message, footer);
}
// write variant to OTP
@@ -198,18 +177,13 @@ __attribute__((noreturn)) void jump_to(void *addr) {
if (storage_is_erased) {
printf("STORAGE WAS ERASED\n");
- screen_fatal_error_rust("BOOTLOADER EXIT", "Jumped to firmware",
- "STORAGE WAS ERASED");
+ error_shutdown_ex("BOOTLOADER EXIT", "Jumped to firmware",
+ "STORAGE WAS ERASED");
} else {
printf("storage was retained\n");
- screen_fatal_error_rust("BOOTLOADER EXIT", "Jumped to firmware",
- "STORAGE WAS RETAINED");
+ error_shutdown_ex("BOOTLOADER EXIT", "Jumped to firmware",
+ "STORAGE WAS RETAINED");
}
- display_backlight(180);
- hal_delay(3000);
- exit(0);
}
void ensure_compatible_settings(void) {}
-
-void main_clean_exit(int code) { exit(code); }
diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c
index 042c795516..685c3bfc44 100644
--- a/core/embed/bootloader/main.c
+++ b/core/embed/bootloader/main.c
@@ -192,7 +192,8 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr,
r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf);
if (r < 0 && r != UPLOAD_ERR_USER_ABORT) { // error, but not user abort
if (r == UPLOAD_ERR_BOOTLOADER_LOCKED) {
- secret_show_install_restricted_screen();
+ // This function does not return
+ show_install_restricted_screen();
} else {
ui_screen_fail();
}
@@ -291,9 +292,7 @@ static void check_bootloader_version(void) {
#endif
-void failed_jump_to_firmware(void) {
- error_shutdown("INTERNAL ERROR", "(glitch)");
-}
+void failed_jump_to_firmware(void) { error_shutdown("(glitch)"); }
void real_jump_to_firmware(void) {
const image_header *hdr = NULL;
diff --git a/core/embed/bootloader/messages.c b/core/embed/bootloader/messages.c
index 89bc4e365b..67ee6ebb48 100644
--- a/core/embed/bootloader/messages.c
+++ b/core/embed/bootloader/messages.c
@@ -213,8 +213,9 @@ static void _usb_webusb_read_retry(uint8_t iface_num, uint8_t *buf) {
continue;
} else {
// error
- error_shutdown("USB ERROR",
- "Error reading from USB. Try different USB cable.");
+ error_shutdown_ex("USB ERROR",
+ "Error reading from USB. Try different USB cable.",
+ NULL);
}
}
return; // success
diff --git a/core/embed/bootloader_ci/messages.c b/core/embed/bootloader_ci/messages.c
index 15c5ce22c5..2a7c372785 100644
--- a/core/embed/bootloader_ci/messages.c
+++ b/core/embed/bootloader_ci/messages.c
@@ -200,8 +200,9 @@ static void _usb_webusb_read_retry(uint8_t iface_num, uint8_t *buf) {
// only timeout => let's try again
} else {
// error
- error_shutdown("USB ERROR",
- "Error reading from USB. Try different USB cable.");
+ error_shutdown_ex("USB ERROR",
+ "Error reading from USB. Try different USB cable.",
+ NULL);
}
}
return; // success
diff --git a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c
index 082a58a4bd..13282bd93a 100644
--- a/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c
+++ b/core/embed/extmod/modtrezorcrypto/modtrezorcrypto.c
@@ -161,8 +161,7 @@ void secp256k1_default_illegal_callback_fn(const char *str, void *data) {
void secp256k1_default_error_callback_fn(const char *str, void *data) {
(void)data;
- __fatal_error(NULL, str, __FILE__, __LINE__, __func__);
- return;
+ error_shutdown(str);
}
#endif
diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c
index ba35e7a993..253cc00eec 100644
--- a/core/embed/firmware/main.c
+++ b/core/embed/firmware/main.c
@@ -274,7 +274,7 @@ int main(void) {
mp_deinit();
// Python code shouldn't ever exit, avoid black screen if it does
- error_shutdown("INTERNAL ERROR", "(PE)");
+ error_shutdown("(PE)");
return 0;
}
@@ -282,7 +282,7 @@ int main(void) {
// MicroPython default exception handler
void __attribute__((noreturn)) nlr_jump_fail(void *val) {
- error_shutdown("INTERNAL ERROR", "(UE)");
+ error_shutdown("(UE)");
}
// MicroPython builtin stubs
diff --git a/core/embed/lib/error_handling.c b/core/embed/lib/error_handling.c
new file mode 100644
index 0000000000..ca5f3e73bc
--- /dev/null
+++ b/core/embed/lib/error_handling.c
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "common.h"
+#include "display.h"
+#include "error_handling.h"
+#include "mini_printf.h"
+#ifdef FANCY_FATAL_ERROR
+#include "rust_ui.h"
+#else
+#include "terminal.h"
+#endif
+
+#ifdef RGB16
+#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
+#else
+#define COLOR_FATAL_ERROR COLOR_BLACK
+#endif
+
+void __attribute__((noreturn))
+error_shutdown_ex(const char *title, const char *message, const char *footer) {
+ if (title == NULL) {
+ title = "INTERNAL ERROR";
+ }
+ if (footer == NULL) {
+ footer = "PLEASE VISIT\nTREZOR.IO/RSOD";
+ }
+
+#ifdef FANCY_FATAL_ERROR
+ error_shutdown_rust(title, message, footer);
+#else
+ display_orientation(0);
+ term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
+ term_printf("%s\n", title);
+ if (message) {
+ term_printf("%s\n", message);
+ }
+ term_printf("\n%s\n", footer);
+ display_backlight(255);
+ trezor_shutdown();
+#endif
+}
+
+void __attribute__((noreturn)) error_shutdown(const char *message) {
+ error_shutdown_ex(NULL, message, NULL);
+}
+
+void __attribute__((noreturn))
+__fatal_error(const char *expr, const char *msg, const char *file, int line,
+ const char *func) {
+#ifdef FANCY_FATAL_ERROR
+ char buf[256] = {0};
+ mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
+ error_shutdown(msg != NULL ? msg : buf);
+#else
+ display_orientation(0);
+ term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
+ term_printf("\nINTERNAL ERROR:\n");
+ if (expr) {
+ term_printf("expr: %s\n", expr);
+ }
+ if (msg) {
+ term_printf("msg : %s\n", msg);
+ }
+ if (file) {
+ term_printf("file: %s:%d\n", file, line);
+ }
+ if (func) {
+ term_printf("func: %s\n", func);
+ }
+#ifdef SCM_REVISION
+ const uint8_t *rev = (const uint8_t *)SCM_REVISION;
+ term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
+ rev[4]);
+#endif
+ term_printf("\nPlease contact Trezor support.\n");
+ display_backlight(255);
+ trezor_shutdown();
+#endif
+}
+
+#ifndef NDEBUG
+void __assert_func(const char *file, int line, const char *func,
+ const char *expr) {
+ __fatal_error(expr, "assert failed", file, line, func);
+}
+#endif
+
+void __attribute__((noreturn)) show_wipe_code_screen(void) {
+ error_shutdown_ex("WIPE CODE ENTERED",
+ "All data has been erased from the device",
+ "PLEASE RECONNECT\nTHE DEVICE");
+}
+
+void __attribute__((noreturn)) show_pin_too_many_screen(void) {
+ error_shutdown_ex("TOO MANY PIN ATTEMPTS",
+ "All data has been erased from the device",
+ "PLEASE RECONNECT\nTHE DEVICE");
+}
+
+void __attribute__((noreturn)) show_install_restricted_screen(void) {
+ error_shutdown_ex("INSTALL RESTRICTED",
+ "Installation of custom firmware is currently restricted.",
+ "Please visit\ntrezor.io/bootloader");
+}
diff --git a/core/embed/lib/error_handling.h b/core/embed/lib/error_handling.h
new file mode 100644
index 0000000000..c811600d6b
--- /dev/null
+++ b/core/embed/lib/error_handling.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef LIB_ERROR_HANDLING_H
+#define LIB_ERROR_HANDLING_H
+
+// Shows an error message and shuts down the device.
+//
+// If the title is NULL, it will be set to "INTERNAL ERROR".
+// If the message is NULL, it will be ignored.
+// If the footer is NULL, it will be set to "PLEASE VISIT TREZOR.IO/RSOD".
+void __attribute__((noreturn))
+error_shutdown_ex(const char *title, const char *message, const char *footer);
+
+// Shows an error message and shuts down the device.
+//
+// Same as `error_shutdown_ex()` but with a default header and footer.
+void __attribute__((noreturn)) error_shutdown(const char *message);
+
+// Do not use this function directly, use the `ensure()` macro instead.
+void __attribute__((noreturn))
+__fatal_error(const char *expr, const char *msg, const char *file, int line,
+ const char *func);
+
+// Checks for an expression and if it is false, shows an error message
+// and shuts down the device.
+#define ensure(expr, msg) \
+ (((expr) == sectrue) \
+ ? (void)0 \
+ : __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
+
+// Shows WIPE CODE ENTERED screeen and shuts down the device.
+void __attribute__((noreturn)) show_wipe_code_screen(void);
+
+// Shows TOO MANY PIN ATTEMPTS screen and shuts down the device.
+void __attribute__((noreturn)) show_pin_too_many_screen(void);
+
+// Shows INSTALL RESTRICTED screen and shuts down the device.
+void __attribute__((noreturn)) show_install_restricted_screen(void);
+
+#endif // LIB_ERRORS_H
diff --git a/core/embed/lib/terminal.c b/core/embed/lib/terminal.c
index 13d733acc1..0891fcbedf 100644
--- a/core/embed/lib/terminal.c
+++ b/core/embed/lib/terminal.c
@@ -180,12 +180,18 @@ void term_print(const char *text, int textlen) {
void term_printf(const char *fmt, ...) {
if (!strchr(fmt, '%')) {
term_print(fmt, strlen(fmt));
+#ifdef TREZOR_EMULATOR
+ printf("%s", fmt);
+#endif
} else {
va_list va;
va_start(va, fmt);
char buf[256] = {0};
int len = mini_vsnprintf(buf, sizeof(buf), fmt, va);
term_print(buf, len);
+#ifdef TREZOR_EMULATOR
+ vprintf(fmt, va);
+#endif
va_end(va);
}
}
diff --git a/core/embed/rust/rust_ui_common.h b/core/embed/rust/rust_ui_common.h
index 4297bd39a5..11f03965a8 100644
--- a/core/embed/rust/rust_ui_common.h
+++ b/core/embed/rust/rust_ui_common.h
@@ -1,7 +1,8 @@
#include "common.h"
-void screen_fatal_error_rust(const char* title, const char* msg,
- const char* footer);
+__attribute__((noreturn)) void error_shutdown_rust(const char* title,
+ const char* msg,
+ const char* footer);
void screen_boot_stage_2(void);
diff --git a/core/embed/rust/src/trezorhal/fatal_error.rs b/core/embed/rust/src/trezorhal/fatal_error.rs
index de0e1188fb..64c8fbdc02 100644
--- a/core/embed/rust/src/trezorhal/fatal_error.rs
+++ b/core/embed/rust/src/trezorhal/fatal_error.rs
@@ -5,24 +5,34 @@ mod ffi {
}
}
-use crate::ui::ui_features::{ModelUI, UIFeaturesCommon};
+use crate::ui::{
+ shape,
+ ui_features::{ModelUI, UIFeaturesCommon},
+};
fn shutdown() -> ! {
unsafe { ffi::trezor_shutdown() }
}
-#[cfg(feature = "bootloader")]
-pub fn __fatal_error(_expr: &str, _msg: &str, _file: &str, _line: u32, _func: &str) -> ! {
- ModelUI::screen_fatal_error("BL.rs", "BL.rs", "PLEASE VISIT\nTREZOR.IO/RSOD");
+/// Shows an error message and shuts down the device.
+pub fn error_shutdown(title: &str, msg: &str, footer: &str) -> ! {
+ // SAFETY:
+ // This is the only situation we are allowed use this function
+ // to allow nested calls to `run_with_bumps`/`render_on_display`,
+ // because after the error message is displayed, the application will
+ // shut down.
+ unsafe { shape::unlock_bumps_on_failure() };
+
+ ModelUI::screen_fatal_error(title, msg, footer);
ModelUI::backlight_on();
shutdown()
}
-#[cfg(not(feature = "bootloader"))]
+/// Shows an error message on the screen and shuts down the device.
+/// In debug mode, also prints the error message to the console.
+#[inline(never)] // saves few kilobytes of flash
pub fn __fatal_error(_expr: &str, msg: &str, _file: &str, _line: u32, _func: &str) -> ! {
- ModelUI::screen_fatal_error("INTERNAL_ERROR", msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
- ModelUI::backlight_on();
- shutdown()
+ error_shutdown("INTERNAL_ERROR", msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
}
pub trait UnwrapOrFatalError {
diff --git a/core/embed/rust/src/ui/api/common_c.rs b/core/embed/rust/src/ui/api/common_c.rs
index 4f0b0b55bd..ccbed0d3a3 100644
--- a/core/embed/rust/src/ui/api/common_c.rs
+++ b/core/embed/rust/src/ui/api/common_c.rs
@@ -10,19 +10,19 @@ use crate::ui::{
geometry::{Alignment2D, Point},
};
-use crate::ui::util::from_c_str;
+use crate::{trezorhal::fatal_error, ui::util::from_c_str};
#[no_mangle]
-extern "C" fn screen_fatal_error_rust(
+extern "C" fn error_shutdown_rust(
title: *const cty::c_char,
msg: *const cty::c_char,
footer: *const cty::c_char,
-) {
+) -> ! {
let title = unsafe { from_c_str(title) }.unwrap_or("");
let msg = unsafe { from_c_str(msg) }.unwrap_or("");
let footer = unsafe { from_c_str(footer) }.unwrap_or("");
- ModelUI::screen_fatal_error(title, msg, footer);
+ fatal_error::error_shutdown(title, msg, footer)
}
#[no_mangle]
diff --git a/core/embed/rust/src/ui/shape/display/bumps.rs b/core/embed/rust/src/ui/shape/display/bumps.rs
index 98d0901a72..70e0621347 100644
--- a/core/embed/rust/src/ui/shape/display/bumps.rs
+++ b/core/embed/rust/src/ui/shape/display/bumps.rs
@@ -22,6 +22,9 @@ pub const BUMP_A_SIZE: usize = DrawingCache::get_bump_a_size() + SHAPE_MEM_SIZE;
/// Size of `bump_b` memory that must be accessible by DMA
pub const BUMP_B_SIZE: usize = DrawingCache::get_bump_b_size();
+//
+static mut LOCKED: bool = false;
+
/// Runs a user-defined function with two bump allocators.
///
/// The function is passed two bump allocators, `bump_a` and `bump_b`, which
@@ -32,8 +35,6 @@ pub fn run_with_bumps(func: F)
where
F: for<'a> FnOnce(&'a mut Bump<[u8; BUMP_A_SIZE]>, &'a mut Bump<[u8; BUMP_B_SIZE]>),
{
- static mut LOCKED: bool = false;
-
// SAFETY:
// The application is single-threaded, so we can safely use a
// static variable as a lock against nested calls.
@@ -64,3 +65,20 @@ where
LOCKED = false;
};
}
+
+// This function enables nested invocations of `run_with_bumps()`,
+// which is necessary when the application needs to display a
+// fatal error message and subsequently terminate.
+//
+// SAFETY:
+// This function must be invoked exclusively in failure scenarios
+// where the application is required to display a fatal error
+// message and then shut down. It is safe to call this function
+// only under these specific conditions.
+pub unsafe fn unlock_bumps_on_failure() {
+ // The application is single-threaded, so we can safely use a
+ // static variable as a lock against nested calls.
+ unsafe {
+ LOCKED = false;
+ };
+}
diff --git a/core/embed/rust/src/ui/shape/display/mod.rs b/core/embed/rust/src/ui/shape/display/mod.rs
index bac7929040..f72561bebd 100644
--- a/core/embed/rust/src/ui/shape/display/mod.rs
+++ b/core/embed/rust/src/ui/shape/display/mod.rs
@@ -49,3 +49,5 @@ mod _new_rendering {
}
pub use _new_rendering::render_on_display;
+
+pub use bumps::unlock_bumps_on_failure;
diff --git a/core/embed/rust/src/ui/shape/mod.rs b/core/embed/rust/src/ui/shape/mod.rs
index e448f4577f..7aabc3aebd 100644
--- a/core/embed/rust/src/ui/shape/mod.rs
+++ b/core/embed/rust/src/ui/shape/mod.rs
@@ -28,7 +28,7 @@ pub use canvas::{
};
pub use circle::Circle;
pub use corner_highlight::CornerHighlight;
-pub use display::{render_on_canvas, render_on_display};
+pub use display::{render_on_canvas, render_on_display, unlock_bumps_on_failure};
#[cfg(feature = "ui_jpeg_decoder")]
pub use jpeg::JpegImage;
pub use qrcode::QrImage;
diff --git a/core/embed/trezorhal/common.h b/core/embed/trezorhal/common.h
index 28464b0270..e42dcfd99e 100644
--- a/core/embed/trezorhal/common.h
+++ b/core/embed/trezorhal/common.h
@@ -24,6 +24,7 @@
#include
#include "secbool.h"
+#include "error_handling.h"
#include "platform.h"
#ifndef MIN_8bits
@@ -53,20 +54,6 @@
void __attribute__((noreturn)) trezor_shutdown(void);
-void __attribute__((noreturn))
-__fatal_error(const char *expr, const char *msg, const char *file, int line,
- const char *func);
-void __attribute__((noreturn))
-error_shutdown(const char *label, const char *msg);
-
-void show_wipe_code_screen(void);
-void show_pin_too_many_screen(void);
-
-#define ensure(expr, msg) \
- (((expr) == sectrue) \
- ? (void)0 \
- : __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
-
void hal_delay(uint32_t ms);
uint32_t hal_ticks_ms();
void hal_delay_us(uint16_t delay_us);
diff --git a/core/embed/trezorhal/secret.h b/core/embed/trezorhal/secret.h
index 953a383e08..e22ff9ad71 100644
--- a/core/embed/trezorhal/secret.h
+++ b/core/embed/trezorhal/secret.h
@@ -60,7 +60,3 @@ void secret_bhk_regenerate(void);
// Disables access to the secret storage until next reset, if possible
// This function is called by the bootloader before starting the firmware
void secret_prepare_fw(secbool allow_run_with_secret, secbool trust_all);
-
-// Shows a screen informing the user that installation of custom firmware is
-// currently restricted
-void secret_show_install_restricted_screen(void);
diff --git a/core/embed/trezorhal/stm32f4/board_capabilities.c b/core/embed/trezorhal/stm32f4/board_capabilities.c
index 053987043f..7560aaf3af 100644
--- a/core/embed/trezorhal/stm32f4/board_capabilities.c
+++ b/core/embed/trezorhal/stm32f4/board_capabilities.c
@@ -22,9 +22,6 @@
#include "common.h"
#include "model.h"
-#define handle_fault(msg) \
- (__fatal_error("Fault detected", msg, __FILE__, __LINE__, __func__))
-
static uint32_t board_name = 0;
static struct BoardloaderVersion boardloader_version;
@@ -53,7 +50,7 @@ void parse_boardloader_capabilities() {
pos += 2;
if (pos + length > end) {
- handle_fault("Bad capabilities format.");
+ error_shutdown("Bad capabilities format");
}
switch (tag) {
diff --git a/core/embed/trezorhal/stm32f4/common.c b/core/embed/trezorhal/stm32f4/common.c
index b29cc6b6a5..70e4828c7b 100644
--- a/core/embed/trezorhal/stm32f4/common.c
+++ b/core/embed/trezorhal/stm32f4/common.c
@@ -24,29 +24,18 @@
#include "common.h"
#include "display.h"
#include "model.h"
-#include "terminal.h"
-#ifdef FANCY_FATAL_ERROR
-#include "rust_ui.h"
-#endif
#include "flash_otp.h"
#include "platform.h"
#include "rand.h"
#include "supervise.h"
-#include "mini_printf.h"
#include "stm32f4xx_ll_utils.h"
#ifdef TREZOR_MODEL_T
#include "backlight_pwm.h"
#endif
-#ifdef RGB16
-#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
-#else
-#define COLOR_FATAL_ERROR COLOR_BLACK
-#endif
-
uint32_t systick_val_copy = 0;
// from util.s
@@ -65,92 +54,6 @@ void __attribute__((noreturn)) trezor_shutdown(void) {
;
}
-void __attribute__((noreturn))
-error_uni(const char *label, const char *msg, const char *footer) {
- display_orientation(0);
-
-#ifdef FANCY_FATAL_ERROR
- screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- if (label) {
- term_printf("%s\n", label);
- }
- if (msg) {
- term_printf("%s\n", msg);
- }
- if (footer) {
- term_printf("\n%s\n", footer);
- }
-#endif
- display_backlight(255);
- trezor_shutdown();
-}
-
-void __attribute__((noreturn))
-__fatal_error(const char *expr, const char *msg, const char *file, int line,
- const char *func) {
- display_orientation(0);
- display_backlight(255);
-
-#ifdef FANCY_FATAL_ERROR
- char buf[256] = {0};
- mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
- screen_fatal_error_rust("INTERNAL ERROR", msg != NULL ? msg : buf,
- "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- term_printf("\nINTERNAL ERROR:\n");
- if (expr) {
- term_printf("expr: %s\n", expr);
- }
- if (msg) {
- term_printf("msg : %s\n", msg);
- }
- if (file) {
- term_printf("file: %s:%d\n", file, line);
- }
- if (func) {
- term_printf("func: %s\n", func);
- }
-#ifdef SCM_REVISION
- const uint8_t *rev = (const uint8_t *)SCM_REVISION;
- term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
- rev[4]);
-#endif
- term_printf("\nPlease contact Trezor support.\n");
-#endif
- trezor_shutdown();
-}
-
-void __attribute__((noreturn))
-error_shutdown(const char *label, const char *msg) {
- display_orientation(0);
-
-#ifdef FANCY_FATAL_ERROR
-
- screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- if (label) {
- term_printf("%s\n", label);
- }
- if (msg) {
- term_printf("%s\n", msg);
- }
- term_printf("\nPLEASE VISIT TREZOR.IO/RSOD\n");
-#endif
- display_backlight(255);
- trezor_shutdown();
-}
-
-#ifndef NDEBUG
-void __assert_func(const char *file, int line, const char *func,
- const char *expr) {
- __fatal_error(expr, "assert failed", file, line, func);
-}
-#endif
-
void hal_delay(uint32_t ms) { HAL_Delay(ms); }
uint32_t hal_ticks_ms() { return HAL_GetTick(); }
void hal_delay_us(uint16_t delay_us) {
@@ -185,7 +88,7 @@ void clear_otg_hs_memory(void) {
uint32_t __stack_chk_guard = 0;
void __attribute__((noreturn)) __stack_chk_fail(void) {
- error_shutdown("INTERNAL ERROR", "(SS)");
+ error_shutdown("(SS)");
}
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
@@ -230,15 +133,6 @@ void ensure_compatible_settings(void) {
#endif
}
-void show_wipe_code_screen(void) {
- error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
- "PLEASE RECONNECT\nTHE DEVICE");
-}
-void show_pin_too_many_screen(void) {
- error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
- "PLEASE RECONNECT\nTHE DEVICE");
-}
-
void invalidate_firmware(void) {
// erase start of the firmware (metadata) -> invalidate FW
ensure(flash_unlock_write(), NULL);
diff --git a/core/embed/trezorhal/stm32f4/fault_handlers.c b/core/embed/trezorhal/stm32f4/fault_handlers.c
index ea8b8b471a..f36e286baf 100644
--- a/core/embed/trezorhal/stm32f4/fault_handlers.c
+++ b/core/embed/trezorhal/stm32f4/fault_handlers.c
@@ -5,19 +5,19 @@ void fault_handlers_init(void) {
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
}
-void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
+void HardFault_Handler(void) { error_shutdown("(HF)"); }
-void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
+void MemManage_Handler_MM(void) { error_shutdown("(MM)"); }
-void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
+void MemManage_Handler_SO(void) { error_shutdown("(SO)"); }
-void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
+void BusFault_Handler(void) { error_shutdown("(BF)"); }
-void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
+void UsageFault_Handler(void) { error_shutdown("(UF)"); }
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIR & RCC_CIR_CSSF) != 0) {
- error_shutdown("INTERNAL ERROR", "(CS)");
+ error_shutdown("(CS)");
}
}
diff --git a/core/embed/trezorhal/stm32f4/secret.c b/core/embed/trezorhal/stm32f4/secret.c
index 9a90511fde..e6c5cef2b4 100644
--- a/core/embed/trezorhal/stm32f4/secret.c
+++ b/core/embed/trezorhal/stm32f4/secret.c
@@ -98,21 +98,11 @@ secbool secret_optiga_get(uint8_t dest[SECRET_OPTIGA_KEY_LEN]) {
return secret_read(dest, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
}
-void secret_show_install_restricted_screen(void) {
-#ifdef FANCY_FATAL_ERROR
- display_clear();
- screen_fatal_error_rust(
- "INSTALL RESTRICTED",
- "Installation of custom firmware is currently restricted.",
- "Please visit\ntrezor.io/bootloader");
-#endif
-}
-
void secret_prepare_fw(secbool allow_run_with_secret, secbool _trust_all) {
#ifdef USE_OPTIGA
if (sectrue != allow_run_with_secret && sectrue != secret_wiped()) {
- secret_show_install_restricted_screen();
- trezor_shutdown();
+ // This function does not return
+ show_install_restricted_screen();
}
#endif
}
diff --git a/core/embed/trezorhal/stm32u5/common.c b/core/embed/trezorhal/stm32u5/common.c
index e7406df22e..0541aabbc0 100644
--- a/core/embed/trezorhal/stm32u5/common.c
+++ b/core/embed/trezorhal/stm32u5/common.c
@@ -23,26 +23,15 @@
#include "common.h"
#include "display.h"
-#include "secret.h"
-#include "terminal.h"
-#ifdef FANCY_FATAL_ERROR
-#include "rust_ui.h"
-#endif
#include "flash_otp.h"
#include "model.h"
#include "platform.h"
#include "rand.h"
+#include "secret.h"
#include "supervise.h"
-#include "mini_printf.h"
#include "stm32u5xx_ll_utils.h"
-#ifdef RGB16
-#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
-#else
-#define COLOR_FATAL_ERROR COLOR_BLACK
-#endif
-
uint32_t systick_val_copy = 0;
// from util.s
@@ -66,91 +55,6 @@ void __attribute__((noreturn)) trezor_shutdown(void) {
;
}
-void __attribute__((noreturn))
-error_uni(const char *label, const char *msg, const char *footer) {
- display_orientation(0);
-
-#ifdef FANCY_FATAL_ERROR
- screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- if (label) {
- term_printf("%s\n", label);
- }
- if (msg) {
- term_printf("%s\n", msg);
- }
- if (footer) {
- term_printf("\n%s\n", footer);
- }
-#endif
- display_backlight(255);
- trezor_shutdown();
-}
-
-void __attribute__((noreturn))
-__fatal_error(const char *expr, const char *msg, const char *file, int line,
- const char *func) {
- display_orientation(0);
- display_backlight(255);
-
-#ifdef FANCY_FATAL_ERROR
- char buf[256] = {0};
- mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
- screen_fatal_error_rust("INTERNAL ERROR", msg != NULL ? msg : buf,
- "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- term_printf("\nINTERNAL ERROR:\n");
- if (expr) {
- term_printf("expr: %s\n", expr);
- }
- if (msg) {
- term_printf("msg : %s\n", msg);
- }
- if (file) {
- term_printf("file: %s:%d\n", file, line);
- }
- if (func) {
- term_printf("func: %s\n", func);
- }
-#ifdef SCM_REVISION
- const uint8_t *rev = (const uint8_t *)SCM_REVISION;
- term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
- rev[4]);
-#endif
- term_printf("\nPlease contact Trezor support.\n");
-#endif
- trezor_shutdown();
-}
-
-void __attribute__((noreturn))
-error_shutdown(const char *label, const char *msg) {
- display_orientation(0);
-
-#ifdef FANCY_FATAL_ERROR
- screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- if (label) {
- term_printf("%s\n", label);
- }
- if (msg) {
- term_printf("%s\n", msg);
- }
- term_printf("\nPLEASE VISIT TREZOR.IO/RSOD\n");
-#endif
- display_backlight(255);
- trezor_shutdown();
-}
-
-#ifndef NDEBUG
-void __assert_func(const char *file, int line, const char *func,
- const char *expr) {
- __fatal_error(expr, "assert failed", file, line, func);
-}
-#endif
-
void hal_delay(uint32_t ms) { HAL_Delay(ms); }
uint32_t hal_ticks_ms() { return HAL_GetTick(); }
void hal_delay_us(uint16_t delay_us) {
@@ -168,7 +72,7 @@ void hal_delay_us(uint16_t delay_us) {
uint32_t __stack_chk_guard = 0;
void __attribute__((noreturn)) __stack_chk_fail(void) {
- error_shutdown("INTERNAL ERROR", "(SS)");
+ error_shutdown("(SS)");
}
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
@@ -202,15 +106,6 @@ void collect_hw_entropy(void) {
// where this setting might be unknown
void ensure_compatible_settings(void) {}
-void show_wipe_code_screen(void) {
- error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
- "PLEASE RECONNECT\nTHE DEVICE");
-}
-void show_pin_too_many_screen(void) {
- error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
- "PLEASE RECONNECT\nTHE DEVICE");
-}
-
void invalidate_firmware(void) {
// on stm32u5, we need to disable the instruction cache before erasing the
// firmware - otherwise, the write check will fail
diff --git a/core/embed/trezorhal/stm32u5/fault_handlers.c b/core/embed/trezorhal/stm32u5/fault_handlers.c
index 3da1a16571..bf19c8e8ef 100644
--- a/core/embed/trezorhal/stm32u5/fault_handlers.c
+++ b/core/embed/trezorhal/stm32u5/fault_handlers.c
@@ -5,11 +5,11 @@ void fault_handlers_init(void) {
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
}
-void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
+void HardFault_Handler(void) { error_shutdown("(HF)"); }
-void MemManage_Handler(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
+void MemManage_Handler(void) { error_shutdown("(MM)"); }
-void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
+void BusFault_Handler(void) { error_shutdown("(BF)"); }
void UsageFault_Handler(void) {
if (SCB->CFSR & SCB_CFSR_STKOF_Msk) {
@@ -17,20 +17,20 @@ void UsageFault_Handler(void) {
extern uint8_t _estack; // linker script symbol
// Fix stack pointer
__set_MSP((uint32_t)&_estack);
- error_shutdown("INTERNAL ERROR", "(SO)");
+ error_shutdown("(SO)");
} else {
// Other error
- error_shutdown("INTERNAL ERROR", "(UF)");
+ error_shutdown("(UF)");
}
}
-void SecureFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(SF)"); }
+void SecureFault_Handler(void) { error_shutdown("(SF)"); }
-void GTZC_IRQHandler(void) { error_shutdown("INTERNAL ERROR", "(IA)"); }
+void GTZC_IRQHandler(void) { error_shutdown("(IA)"); }
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIFR & RCC_CIFR_CSSF) != 0) {
- error_shutdown("INTERNAL ERROR", "(CS)");
+ error_shutdown("(CS)");
}
}
diff --git a/core/embed/trezorhal/stm32u5/secret.c b/core/embed/trezorhal/stm32u5/secret.c
index ef2a096dc9..bfa107a965 100644
--- a/core/embed/trezorhal/stm32u5/secret.c
+++ b/core/embed/trezorhal/stm32u5/secret.c
@@ -239,12 +239,6 @@ void secret_erase(void) {
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
}
-void secret_show_install_restricted_screen(void) {
- // this should never happen on U5
- __fatal_error("INTERNAL ERROR", "Install restricted", __FILE__, __LINE__,
- __func__);
-}
-
void secret_prepare_fw(secbool allow_run_with_secret, secbool trust_all) {
/**
* The BHK is copied to the backup registers, which are accessible by the SAES
diff --git a/core/embed/trezorhal/stm32u5/tamper.c b/core/embed/trezorhal/stm32u5/tamper.c
index 68bee8da4a..6b74a54f48 100644
--- a/core/embed/trezorhal/stm32u5/tamper.c
+++ b/core/embed/trezorhal/stm32u5/tamper.c
@@ -238,7 +238,7 @@ void TAMP_IRQHandler(void) {
TAMP->SCR = sr;
#ifdef BOARDLOADER
- error_shutdown("INTERNAL TAMPER", "");
+ error_shutdown_ex("INTERNAL TAMPER", NULL, NULL);
#else
const char* reason = "UNKNOWN";
if (sr & TAMP_SR_TAMP1F) {
@@ -268,6 +268,6 @@ void TAMP_IRQHandler(void) {
} else if (sr & TAMP_SR_ITAMP13F) {
reason = "ANALOG WDG3";
}
- error_shutdown("INTERNAL TAMPER", reason);
+ error_shutdown_ex("INTERNAL TAMPER", reason, NULL);
#endif
}
diff --git a/core/embed/trezorhal/unix/common.c b/core/embed/trezorhal/unix/common.c
index aeeb46acdb..87700b9652 100644
--- a/core/embed/trezorhal/unix/common.c
+++ b/core/embed/trezorhal/unix/common.c
@@ -26,128 +26,16 @@
#include "common.h"
#include "display.h"
-#ifdef FANCY_FATAL_ERROR
-#include "rust_ui.h"
-#endif
#include "memzero.h"
-extern void main_clean_exit(int);
-
void __attribute__((noreturn)) trezor_shutdown(void) {
- display_finish_actions();
printf("SHUTDOWN\n");
- main_clean_exit(3);
- for (;;)
- ;
-}
-#ifdef RGB16
-#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
-#else
-// black on monochromatic displays
-#define COLOR_FATAL_ERROR 0x0000
-#endif
-
-void __attribute__((noreturn))
-error_uni(const char *label, const char *msg, const char *footer) {
- display_orientation(0);
-
-#ifdef FANCY_FATAL_ERROR
- screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- if (label) {
- term_printf("%s\n", label);
- }
- if (msg) {
- term_printf("%s\n", msg);
- }
- if (footer) {
- term_printf("\n%s\n", footer);
- }
-#endif
- display_backlight(255);
+ // Wait some time to let the user see the displayed
+ // message before shutting down
hal_delay(3000);
- trezor_shutdown();
-}
-void __attribute__((noreturn))
-__fatal_error(const char *expr, const char *msg, const char *file, int line,
- const char *func) {
- display_orientation(0);
- display_backlight(255);
-
-#ifdef FANCY_FATAL_ERROR
- if (msg == NULL) {
- msg = "Unknown error";
- char buf[256] = {0};
- snprintf(buf, sizeof(buf), "%s: %d", file, line);
- screen_fatal_error_rust("INTERNAL ERROR", buf,
- "PLEASE VISIT\nTREZOR.IO/RSOD");
- } else {
- screen_fatal_error_rust("INTERNAL ERROR", msg,
- "PLEASE VISIT\nTREZOR.IO/RSOD");
- }
-#else
- term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
- term_printf("\nINTERNAL ERROR:\n");
- printf("\nINTERNAL ERROR:\n");
- if (expr) {
- term_printf("expr: %s\n", expr);
- printf("expr: %s\n", expr);
- }
- if (msg) {
- term_printf("msg : %s\n", msg);
- printf("msg : %s\n", msg);
- }
- if (file) {
- term_printf("file: %s:%d\n", file, line);
- printf("file: %s:%d\n", file, line);
- }
- if (func) {
- term_printf("func: %s\n", func);
- printf("func: %s\n", func);
- }
-#ifdef SCM_REVISION
- const uint8_t *rev = (const uint8_t *)SCM_REVISION;
- term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
- rev[4]);
- printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
- rev[4]);
-#endif
- term_printf("\n\n\nHint:\nIsn't the emulator already running?\n");
- printf("Hint:\nIsn't the emulator already running?\n");
-#endif
- hal_delay(3000);
- trezor_shutdown();
-}
-
-void __attribute__((noreturn))
-error_shutdown(const char *label, const char *msg) {
-#ifdef FANCY_FATAL_ERROR
- screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
-#else
- display_clear();
- display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_FATAL_ERROR);
- int y = 32;
- if (label) {
- display_text(8, y, label, -1, FONT_NORMAL, COLOR_WHITE, COLOR_FATAL_ERROR);
- printf("%s\n", label);
- y += 32;
- }
- if (msg) {
- display_text(8, y, msg, -1, FONT_NORMAL, COLOR_WHITE, COLOR_FATAL_ERROR);
- printf("%s\n", msg);
- y += 32;
- }
- y += 32;
- display_text(8, y, "Please unplug the device.", -1, FONT_NORMAL, COLOR_WHITE,
- COLOR_FATAL_ERROR);
- printf("\nPlease unplug the device.\n");
-#endif
- display_backlight(255);
- hal_delay(5000);
- exit(4);
+ exit(3);
}
void hal_delay(uint32_t ms) { usleep(1000 * ms); }
@@ -161,7 +49,7 @@ uint32_t hal_ticks_ms() {
static int SDLCALL emulator_event_filter(void *userdata, SDL_Event *event) {
switch (event->type) {
case SDL_QUIT:
- trezor_shutdown();
+ exit(3);
return 0;
case SDL_KEYUP:
if (event->key.repeat) {
@@ -169,7 +57,7 @@ static int SDLCALL emulator_event_filter(void *userdata, SDL_Event *event) {
}
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
- trezor_shutdown();
+ exit(3);
return 0;
case SDLK_p:
display_save("emu");
@@ -188,12 +76,3 @@ void emulator_poll_events(void) {
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
void collect_hw_entropy(void) { memzero(HW_ENTROPY_DATA, HW_ENTROPY_LEN); }
-
-void show_wipe_code_screen(void) {
- error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
- "PLEASE RECONNECT\nTHE DEVICE");
-}
-void show_pin_too_many_screen(void) {
- error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
- "PLEASE RECONNECT\nTHE DEVICE");
-}
diff --git a/core/embed/trezorhal/unix/usb.c b/core/embed/trezorhal/unix/usb.c
index 1ae10be153..63fb1c6987 100644
--- a/core/embed/trezorhal/unix/usb.c
+++ b/core/embed/trezorhal/unix/usb.c
@@ -27,20 +27,12 @@
#include
#include
+#include "error_handling.h"
#include "profile.h"
#include "usb.h"
#include "memzero.h"
-void __attribute__((noreturn))
-__fatal_error(const char *expr, const char *msg, const char *file, int line,
- const char *func);
-
-#define ensure(expr, msg) \
- (((expr) == sectrue) \
- ? (void)0 \
- : __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
-
// emulator opens UDP server and emulates HID/WebUSB interfaces
// gracefully ignores all other USB interfaces
diff --git a/core/embed/unix/main.c b/core/embed/unix/main.c
index 2acd5b528b..dac4b1141b 100644
--- a/core/embed/unix/main.c
+++ b/core/embed/unix/main.c
@@ -407,16 +407,6 @@ STATIC void set_sys_argv(char *argv[], int argc, int start_arg) {
}
}
-void main_clean_exit(int status) {
- fflush(stdout);
- fflush(stderr);
- // sys.exit is disabled, so raise a SystemExit exception directly
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_SystemExit,
- MP_OBJ_NEW_SMALL_INT(status)));
- // the above shouldn't return, but make sure we exit just in case
- exit(status);
-}
-
#ifdef _WIN32
#define PATHLIST_SEP_CHAR ';'
#else