1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-08-05 13:26:57 +00:00

feat(core/bootloader): add power-off item to the bootloader menu

[no changelog]
This commit is contained in:
tychovrahe 2025-03-17 08:33:30 +01:00 committed by TychoVrahe
parent 37687f1815
commit 70014e103a
11 changed files with 81 additions and 1 deletions

View File

@ -174,7 +174,7 @@ env.Replace(
'-fstack-protector-strong ' '-fstack-protector-strong '
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD, + env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
LINKFLAGS=['-Tbuild/bootloader/memory.ld', '-Wl,--gc-sections', '-Wl,-Map=build/bootloader/bootloader.map', '-Wl,--warn-common', '-Wl,--print-memory-usage'], LINKFLAGS=['-Tbuild/bootloader/memory.ld', '-Wl,--gc-sections', '-Wl,-Map=build/bootloader/bootloader.map', '-Wl,--warn-common', '-Wl,--print-memory-usage', '-Wl,--undefined=__errno'],
CPPPATH=ALLPATHS, CPPPATH=ALLPATHS,
CPPDEFINES=[ CPPDEFINES=[
'BOOTLOADER', 'BOOTLOADER',

View File

@ -65,6 +65,9 @@
#ifdef USE_BLE #ifdef USE_BLE
#include <io/ble.h> #include <io/ble.h>
#endif #endif
#ifdef USE_POWERCTL
#include <sys/powerctl.h>
#endif
#ifdef USE_BLE #ifdef USE_BLE
#include "wire/wire_iface_ble.h" #include "wire/wire_iface_ble.h"
@ -157,6 +160,9 @@ static void drivers_deinit(void) {
#endif #endif
#endif #endif
display_deinit(DISPLAY_JUMP_BEHAVIOR); display_deinit(DISPLAY_JUMP_BEHAVIOR);
#ifdef USE_POWERCTL
powerctl_deinit();
#endif
} }
static secbool check_vendor_header_lock(const vendor_header *const vhdr) { static secbool check_vendor_header_lock(const vendor_header *const vhdr) {
@ -336,6 +342,10 @@ int bootloader_main(void) {
firmware_present_backup = firmware_present; firmware_present_backup = firmware_present;
} }
#ifdef USE_POWERCTL
powerctl_init();
#endif
#if PRODUCTION && !defined STM32U5 #if PRODUCTION && !defined STM32U5
// for STM32U5, this check is moved to boardloader // for STM32U5, this check is moved to boardloader
ensure_bootloader_min_version(); ensure_bootloader_min_version();

View File

@ -23,6 +23,13 @@
#include <sys/types.h> #include <sys/types.h>
#include <util/image.h> #include <util/image.h>
#ifdef USE_POWERCTL
#include <sys/powerctl.h>
#endif
#include <io/display.h>
#include <io/display_utils.h>
#include "antiglitch.h" #include "antiglitch.h"
#include "bootui.h" #include "bootui.h"
#include "rust_ui_bootloader.h" #include "rust_ui_bootloader.h"
@ -53,6 +60,14 @@ workflow_result_t workflow_menu(const vendor_header* const vhdr,
workflow_ble_pairing_request(vhdr, hdr); workflow_ble_pairing_request(vhdr, hdr);
continue; continue;
} }
#endif
#ifdef USE_POWERCTL
if (menu_result == MENU_POWER_OFF) { // reboot
display_fade(display_get_backlight(), 0, 200);
powerctl_hibernate();
// in case hibernation failed, continue with menu
continue;
}
#endif #endif
if (menu_result == MENU_REBOOT) { // reboot if (menu_result == MENU_REBOOT) { // reboot
jump_allow_1(); jump_allow_1();

View File

@ -44,6 +44,7 @@ usb = []
optiga = [] optiga = []
ble = [] ble = []
tropic = [] tropic = []
powerctl = []
translations = ["crypto"] translations = ["crypto"]
test = [ test = [
"backlight", "backlight",

View File

@ -67,6 +67,7 @@ typedef enum {
MENU_REBOOT = 0x11223344, MENU_REBOOT = 0x11223344,
MENU_WIPE = 0x55667788, MENU_WIPE = 0x55667788,
MENU_BLUETOOTH = 0x99AABBCC, MENU_BLUETOOTH = 0x99AABBCC,
MENU_POWER_OFF = 0x751A5BEF,
} menu_result_t; } menu_result_t;
void screen_menu(bool initial_setup, secbool firmware_present, void screen_menu(bool initial_setup, secbool firmware_present,
c_layout_t* layout); c_layout_t* layout);

View File

@ -27,6 +27,7 @@ pub enum MenuMsg {
Reboot = 0x11223344, Reboot = 0x11223344,
FactoryReset = 0x55667788, FactoryReset = 0x55667788,
Bluetooth = 0x99AABBCC, Bluetooth = 0x99AABBCC,
PowerOff = 0x751A5BEF,
} }
pub struct Menu { pub struct Menu {
@ -36,6 +37,7 @@ pub struct Menu {
reboot: Button, reboot: Button,
reset: Button, reset: Button,
bluetooth: Button, bluetooth: Button,
poweroff: Button,
} }
impl Menu { impl Menu {
@ -43,6 +45,7 @@ impl Menu {
let content_reboot = IconText::new("REBOOT TREZOR", Icon::new(REFRESH24)); let content_reboot = IconText::new("REBOOT TREZOR", Icon::new(REFRESH24));
let content_reset = IconText::new("FACTORY RESET", Icon::new(FIRE24)); let content_reset = IconText::new("FACTORY RESET", Icon::new(FIRE24));
let content_bluetooth = IconText::new("BLUETOOTH", Icon::new(FIRE24)); let content_bluetooth = IconText::new("BLUETOOTH", Icon::new(FIRE24));
let content_poweroff = IconText::new("POWER OFF", Icon::new(FIRE24));
let mut instance = Self { let mut instance = Self {
bg: Pad::with_background(BLD_BG), bg: Pad::with_background(BLD_BG),
@ -59,6 +62,7 @@ impl Menu {
reset: Button::with_icon_and_text(content_reset).styled(button_bld()), reset: Button::with_icon_and_text(content_reset).styled(button_bld()),
bluetooth: Button::with_icon_and_text(content_bluetooth).styled(button_bld()), bluetooth: Button::with_icon_and_text(content_bluetooth).styled(button_bld()),
poweroff: Button::with_icon_and_text(content_poweroff).styled(button_bld()),
}; };
instance.bg.clear(); instance.bg.clear();
instance instance
@ -89,6 +93,8 @@ impl Component for Menu {
self.reset.place(self.get_button_pos(1)); self.reset.place(self.get_button_pos(1));
#[cfg(feature = "ble")] #[cfg(feature = "ble")]
self.bluetooth.place(self.get_button_pos(2)); self.bluetooth.place(self.get_button_pos(2));
#[cfg(feature = "powerctl")]
self.poweroff.place(self.get_button_pos(3));
bounds bounds
} }
@ -106,6 +112,10 @@ impl Component for Menu {
if let Some(Clicked) = self.bluetooth.event(ctx, event) { if let Some(Clicked) = self.bluetooth.event(ctx, event) {
return Some(Self::Msg::Bluetooth); return Some(Self::Msg::Bluetooth);
} }
#[cfg(feature = "powerctl")]
if let Some(Clicked) = self.poweroff.event(ctx, event) {
return Some(Self::Msg::PowerOff);
}
None None
} }
@ -118,5 +128,7 @@ impl Component for Menu {
self.reset.render(target); self.reset.render(target);
#[cfg(feature = "ble")] #[cfg(feature = "ble")]
self.bluetooth.render(target); self.bluetooth.render(target);
#[cfg(feature = "powerctl")]
self.poweroff.render(target);
} }
} }

View File

@ -0,0 +1,31 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <trezor_rtl.h>
#include <SDL.h>
bool powerctl_init(void) { return true; }
void powerctl_deinit(void) {}
bool powerctl_hibernate(void) {
exit(1);
return true;
}

View File

@ -105,6 +105,13 @@ def configure(
features_available.append("ble") features_available.append("ble")
defines += [("USE_BLE", "1")] defines += [("USE_BLE", "1")]
sources += [
"embed/sys/powerctl/unix/powerctl.c",
]
defines += [("USE_POWERCTL", "1")]
paths += ["embed/sys/powerctl/inc"]
features_available.append("powerctl")
features_available.append("backlight") features_available.append("backlight")
defines += [("USE_BACKLIGHT", "1")] defines += [("USE_BACKLIGHT", "1")]

View File

@ -243,6 +243,7 @@ def configure(
] ]
paths += ["embed/sys/powerctl/inc"] paths += ["embed/sys/powerctl/inc"]
defines += [("USE_POWERCTL", "1")] defines += [("USE_POWERCTL", "1")]
features_available.append("powerctl")
env.get("ENV")["LINKER_SCRIPT"] = linker_script env.get("ENV")["LINKER_SCRIPT"] = linker_script

View File

@ -250,6 +250,7 @@ def configure(
] ]
paths += ["embed/sys/powerctl/inc"] paths += ["embed/sys/powerctl/inc"]
defines += [("USE_POWERCTL", "1")] defines += [("USE_POWERCTL", "1")]
features_available.append("powerctl")
env.get("ENV")["LINKER_SCRIPT"] = linker_script env.get("ENV")["LINKER_SCRIPT"] = linker_script

View File

@ -250,6 +250,7 @@ def configure(
] ]
paths += ["embed/sys/powerctl/inc"] paths += ["embed/sys/powerctl/inc"]
defines += [("USE_POWERCTL", "1")] defines += [("USE_POWERCTL", "1")]
features_available.append("powerctl")
env.get("ENV")["LINKER_SCRIPT"] = linker_script env.get("ENV")["LINKER_SCRIPT"] = linker_script