From 1c991339ce5c29869cd82a68d51da655cda24801 Mon Sep 17 00:00:00 2001 From: cepetr Date: Tue, 13 Aug 2024 07:47:59 +0200 Subject: [PATCH] refactor(core/embed): split firmware into kernel & coreapp [no changelog] --- core/Makefile | 36 + core/SConscript.boardloader | 1 + core/SConscript.bootloader | 1 + core/SConscript.bootloader_ci | 1 + core/SConscript.bootloader_emu | 1 + core/SConscript.coreapp | 941 ++++++++++++++++++ core/SConscript.firmware | 5 +- core/SConscript.kernel | 502 ++++++++++ core/SConscript.prodtest | 1 + core/SConscript.reflash | 4 + core/SConscript.unix | 2 + core/SConstruct | 2 + core/embed/coreapp/header.S | 54 + core/embed/coreapp/main.c | 105 ++ core/embed/coreapp/memory_DISC1.ld | 1 + core/embed/coreapp/memory_DISC2.ld | 130 +++ core/embed/coreapp/memory_R.ld | 1 + core/embed/coreapp/memory_T.ld | 109 ++ core/embed/coreapp/memory_T3B1.ld | 1 + core/embed/coreapp/memory_T3T1.ld | 115 +++ core/embed/coreapp/mpconfigport.h | 224 +++++ core/embed/coreapp/mphalport.c | 57 ++ core/embed/coreapp/mphalport.h | 24 + core/embed/coreapp/nlrthumb.c | 166 +++ core/embed/coreapp/startup_stm32f4.S | 42 + core/embed/coreapp/startup_stm32u5.S | 58 ++ core/embed/coreapp/version.h | 11 + core/embed/firmware/memory_T3T1.ld | 1 - core/embed/kernel/header.S | 54 + core/embed/kernel/main.c | 188 ++++ core/embed/kernel/memory_T3T1.ld | 122 +++ core/embed/kernel/startup_stm32u5.S | 72 ++ core/embed/kernel/version.h | 11 + core/embed/lib/sizedefs.h | 3 + core/embed/lib/translations.c | 4 + core/embed/lib/unit_variant.c | 4 + core/embed/lib/unit_variant.h | 5 + core/embed/models/D002/model_D002.h | 3 + core/embed/models/T3T1/model_T3T1.h | 3 + core/embed/trezorhal/bg_copy.h | 4 + core/embed/trezorhal/board_capabilities.h | 4 + core/embed/trezorhal/button.h | 5 + core/embed/trezorhal/consumption_mask.h | 24 +- core/embed/trezorhal/entropy.h | 6 +- core/embed/trezorhal/flash.h | 3 +- core/embed/trezorhal/flash_otp.h | 4 + core/embed/trezorhal/fwutils.h | 4 + core/embed/trezorhal/haptic.h | 4 + core/embed/trezorhal/hash_processor.h | 4 + core/embed/trezorhal/i2c_bus.h | 4 + core/embed/trezorhal/lowlevel.h | 4 + core/embed/trezorhal/monoctr.h | 4 + core/embed/trezorhal/mpu.h | 4 + core/embed/trezorhal/optiga/optiga.c | 4 + core/embed/trezorhal/optiga/optiga_commands.c | 4 + .../embed/trezorhal/optiga/optiga_transport.c | 4 + core/embed/trezorhal/random_delays.h | 12 +- core/embed/trezorhal/rgb_led.h | 29 + core/embed/trezorhal/rng.h | 6 + core/embed/trezorhal/sdcard.h | 5 + core/embed/trezorhal/secret.h | 18 +- .../trezorhal/stm32f4/board_capabilities.c | 4 + core/embed/trezorhal/stm32f4/bootutils.c | 6 + core/embed/trezorhal/stm32f4/button.c | 4 + core/embed/trezorhal/stm32f4/common.c | 4 + .../trezorhal/stm32f4/consumption_mask.c | 4 + core/embed/trezorhal/stm32f4/entropy.c | 6 + core/embed/trezorhal/stm32f4/fault_handlers.c | 34 +- core/embed/trezorhal/stm32f4/flash.c | 4 + core/embed/trezorhal/stm32f4/flash_otp.c | 4 + core/embed/trezorhal/stm32f4/fwutils.c | 4 + core/embed/trezorhal/stm32f4/i2c_bus.c | 17 + .../{limited_util.s => limited_util.S} | 0 core/embed/trezorhal/stm32f4/lowlevel.c | 4 + core/embed/trezorhal/stm32f4/monoctr.c | 4 + core/embed/trezorhal/stm32f4/mpu.c | 4 + core/embed/trezorhal/stm32f4/optiga_hal.c | 4 + core/embed/trezorhal/stm32f4/platform.c | 4 + core/embed/trezorhal/stm32f4/random_delays.c | 4 + core/embed/trezorhal/stm32f4/rgb_led.c | 4 + core/embed/trezorhal/stm32f4/rng.c | 4 + core/embed/trezorhal/stm32f4/sdcard.c | 9 +- core/embed/trezorhal/stm32f4/secret.c | 6 +- core/embed/trezorhal/stm32f4/syscall.c | 205 ++++ core/embed/trezorhal/stm32f4/syscall.h | 209 ++++ .../trezorhal/stm32f4/syscall_dispatch.c | 499 ++++++++++ .../embed/trezorhal/stm32f4/syscall_numbers.h | 146 +++ core/embed/trezorhal/stm32f4/syscall_stubs.c | 616 ++++++++++++ core/embed/trezorhal/stm32f4/systick.c | 7 + core/embed/trezorhal/stm32f4/systimer.c | 4 + core/embed/trezorhal/stm32f4/touch/ft6x36.c | 4 + core/embed/trezorhal/stm32f4/usb/usb.c | 4 + .../trezorhal/stm32f4/usb/usb_class_hid.c | 4 + .../trezorhal/stm32f4/usb/usb_class_vcp.c | 4 + .../trezorhal/stm32f4/usb/usb_class_webusb.c | 4 + core/embed/trezorhal/stm32f4/usb/usbd_conf.c | 14 + core/embed/trezorhal/stm32f4/usb/usbd_core.c | 4 + .../embed/trezorhal/stm32f4/usb/usbd_ctlreq.c | 4 + core/embed/trezorhal/stm32f4/usb/usbd_ioreq.c | 4 + .../trezorhal/stm32f4/{util.s => util.S} | 0 .../stm32f4/{vectortable.s => vectortable.S} | 12 + .../stm32f4/xdisplay/st-7789/display_driver.c | 4 + .../stm32f4/xdisplay/st-7789/display_fb.c | 13 +- .../stm32f4/xdisplay/st-7789/display_io.c | 4 + .../stm32f4/xdisplay/st-7789/display_nofb.c | 4 + .../stm32f4/xdisplay/st-7789/display_panel.c | 4 + core/embed/trezorhal/stm32u5/bg_copy.c | 9 + .../trezorhal/stm32u5/consumption_mask.c | 4 + core/embed/trezorhal/stm32u5/entropy.c | 4 + core/embed/trezorhal/stm32u5/fault_handlers.c | 31 +- core/embed/trezorhal/stm32u5/flash.c | 4 + core/embed/trezorhal/stm32u5/flash_otp.c | 4 + .../stm32u5/haptic/drv2625/drv2625.c | 4 + core/embed/trezorhal/stm32u5/hash_processor.c | 11 +- core/embed/trezorhal/stm32u5/i2c_bus.c | 17 + .../{limited_util.s => limited_util.S} | 0 core/embed/trezorhal/stm32u5/lowlevel.c | 4 + core/embed/trezorhal/stm32u5/monoctr.c | 4 + core/embed/trezorhal/stm32u5/mpu.c | 6 + core/embed/trezorhal/stm32u5/platform.c | 4 + core/embed/trezorhal/stm32u5/sdcard.c | 7 + core/embed/trezorhal/stm32u5/secret.c | 4 + core/embed/trezorhal/stm32u5/secure_aes.c | 4 + core/embed/trezorhal/stm32u5/syscall.c | 1 + core/embed/trezorhal/stm32u5/syscall.h | 1 + .../trezorhal/stm32u5/syscall_dispatch.c | 1 + .../embed/trezorhal/stm32u5/syscall_numbers.h | 1 + core/embed/trezorhal/stm32u5/syscall_stubs.c | 1 + core/embed/trezorhal/stm32u5/tamper.c | 7 + .../trezorhal/stm32u5/{util.s => util.S} | 4 + .../stm32u5/{vectortable.s => vectortable.S} | 11 + core/embed/trezorhal/systick.h | 4 + core/embed/trezorhal/systimer.h | 4 + core/embed/trezorhal/tamper.h | 4 + core/embed/trezorhal/touch.h | 4 + core/embed/trezorhal/xdisplay.h | 4 + core/site_scons/models/stm32f4_common.py | 9 +- core/site_scons/models/stm32u5_common.py | 11 +- 138 files changed, 5284 insertions(+), 40 deletions(-) create mode 100644 core/SConscript.coreapp create mode 100644 core/SConscript.kernel create mode 100644 core/embed/coreapp/header.S create mode 100644 core/embed/coreapp/main.c create mode 120000 core/embed/coreapp/memory_DISC1.ld create mode 100644 core/embed/coreapp/memory_DISC2.ld create mode 120000 core/embed/coreapp/memory_R.ld create mode 100644 core/embed/coreapp/memory_T.ld create mode 120000 core/embed/coreapp/memory_T3B1.ld create mode 100644 core/embed/coreapp/memory_T3T1.ld create mode 100644 core/embed/coreapp/mpconfigport.h create mode 100644 core/embed/coreapp/mphalport.c create mode 100644 core/embed/coreapp/mphalport.h create mode 100644 core/embed/coreapp/nlrthumb.c create mode 100644 core/embed/coreapp/startup_stm32f4.S create mode 100644 core/embed/coreapp/startup_stm32u5.S create mode 100644 core/embed/coreapp/version.h create mode 100644 core/embed/kernel/header.S create mode 100644 core/embed/kernel/main.c create mode 100644 core/embed/kernel/memory_T3T1.ld create mode 100644 core/embed/kernel/startup_stm32u5.S create mode 100644 core/embed/kernel/version.h rename core/embed/trezorhal/stm32f4/{limited_util.s => limited_util.S} (100%) create mode 100644 core/embed/trezorhal/stm32f4/syscall.c create mode 100644 core/embed/trezorhal/stm32f4/syscall.h create mode 100644 core/embed/trezorhal/stm32f4/syscall_dispatch.c create mode 100644 core/embed/trezorhal/stm32f4/syscall_numbers.h create mode 100644 core/embed/trezorhal/stm32f4/syscall_stubs.c rename core/embed/trezorhal/stm32f4/{util.s => util.S} (100%) rename core/embed/trezorhal/stm32f4/{vectortable.s => vectortable.S} (96%) rename core/embed/trezorhal/stm32u5/{limited_util.s => limited_util.S} (100%) create mode 120000 core/embed/trezorhal/stm32u5/syscall.c create mode 120000 core/embed/trezorhal/stm32u5/syscall.h create mode 120000 core/embed/trezorhal/stm32u5/syscall_dispatch.c create mode 120000 core/embed/trezorhal/stm32u5/syscall_numbers.h create mode 120000 core/embed/trezorhal/stm32u5/syscall_stubs.c rename core/embed/trezorhal/stm32u5/{util.s => util.S} (99%) rename core/embed/trezorhal/stm32u5/{vectortable.s => vectortable.S} (97%) diff --git a/core/Makefile b/core/Makefile index 6bea0e20fb..4f5703e2b6 100644 --- a/core/Makefile +++ b/core/Makefile @@ -18,6 +18,8 @@ BOOTLOADER_CI_BUILD_DIR = $(BUILD_DIR)/bootloader_ci BOOTLOADER_EMU_BUILD_DIR = $(BUILD_DIR)/bootloader_emu PRODTEST_BUILD_DIR = $(BUILD_DIR)/prodtest REFLASH_BUILD_DIR = $(BUILD_DIR)/reflash +KERNEL_BUILD_DIR = $(BUILD_DIR)/kernel +COREAPP_BUILD_DIR = $(BUILD_DIR)/coreapp FIRMWARE_BUILD_DIR = $(BUILD_DIR)/firmware UNIX_BUILD_DIR = $(BUILD_DIR)/unix RUST_BUILD_DIR = $(BUILD_DIR)/rust @@ -78,6 +80,9 @@ endif FLASH_START = $(shell layout_parser ${TREZOR_MODEL} FLASH_START) BOARDLOADER_START = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_START) BOOTLOADER_START = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_START) +KERNEL_START = $(shell layout_parser ${TREZOR_MODEL} KERNEL_START) +COREAPP_START = $(shell layout_parser ${TREZOR_MODEL} COREAPP_START) +COREAPP_P2_START = $(shell layout_parser ${TREZOR_MODEL} COREAPP_P2_START) FIRMWARE_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_START) FIRMWARE_P2_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_START) STORAGE_1_OFFSET = $(shell layout_parser ${TREZOR_MODEL} STORAGE_1_OFFSET) @@ -270,6 +275,20 @@ build_reflash: ## build reflash firmware + reflash image dd if=build/boardloader/boardloader.bin of=$(REFLASH_BUILD_DIR)/sdimage.bin bs=1 seek=0 dd if=build/bootloader/bootloader.bin of=$(REFLASH_BUILD_DIR)/sdimage.bin bs=1 seek=49152 +build_kernel: ## build kernel image + $(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" \ + TREZOR_MODEL="$(TREZOR_MODEL)" \ + BOOTLOADER_QA="$(BOOTLOADER_QA)" BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \ + $(KERNEL_BUILD_DIR)/kernel.bin + +build_coreapp: templates build_cross ## build coreapp with frozen modules + $(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" \ + TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \ + PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" \ + BOOTLOADER_QA="$(BOOTLOADER_QA)" BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \ + DISABLE_OPTIGA="$(DISABLE_OPTIGA)" THP="$(THP)" NEW_RENDERING="$(NEW_RENDERING)" \ + $(COREAPP_BUILD_DIR)/coreapp.bin + build_firmware: templates build_cross ## build firmware with frozen modules $(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" \ TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \ @@ -322,6 +341,12 @@ clean_prodtest: ## clean prodtest build clean_reflash: ## clean reflash build rm -rf $(REFLASH_BUILD_DIR) +clean_kernel: ## clean kernel build + rm -rf $(KERNEL_BUILD_DIR) + +clean_coreapp: ## clean coreapp build + rm -rf $(COREAPP_BUILD_DIR) $(RUST_BUILD_DIR) + clean_firmware: ## clean firmware build rm -rf $(FIRMWARE_BUILD_DIR) $(RUST_BUILD_DIR) @@ -347,6 +372,17 @@ flash_bootloader_ci: $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin ## flash CI bootl flash_prodtest: $(PRODTEST_BUILD_DIR)/prodtest.bin ## flash prodtest using OpenOCD $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_START); exit" +flash_kernel: $(KERNEL_BUILD_DIR)/kernel.bin ## flash kernel using OpenOCD + $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(KERNEL_START); exit" + +flash_coreapp: $(COREAPP_BUILD_DIR)/coreapp.bin ## flash coreapp using OpenOCD +ifeq ($(MCU),$(filter $(MCU),STM32F4)) + $(OPENOCD) -c "init; reset halt; flash write_image erase $<.p1 $(COREAPP_START); flash write_image erase $<.p2 $(COREAPP_P2_START); exit" + +else + $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(COREAPP_START); exit" +endif + flash_firmware: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using OpenOCD ifeq ($(MCU),$(filter $(MCU),STM32F4)) $(OPENOCD) -c "init; reset halt; flash write_image erase $<.p1 $(FIRMWARE_START); flash write_image erase $<.p2 $(FIRMWARE_P2_START); exit" diff --git a/core/SConscript.boardloader b/core/SConscript.boardloader index 70cf6ae167..056d11adee 100644 --- a/core/SConscript.boardloader +++ b/core/SConscript.boardloader @@ -41,6 +41,7 @@ CPPPATH_MOD += [ 'vendor/trezor-storage', ] CPPDEFINES_MOD += [ + 'KERNEL_MODE', 'AES_128', 'AES_192', 'USE_KECCAK', diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader index 52897b3d42..b79bd06f53 100644 --- a/core/SConscript.bootloader +++ b/core/SConscript.bootloader @@ -71,6 +71,7 @@ CPPPATH_MOD += [ 'vendor/trezor-storage', ] CPPDEFINES_MOD += [ + 'KERNEL_MODE', 'AES_128', 'AES_192', 'USE_KECCAK', diff --git a/core/SConscript.bootloader_ci b/core/SConscript.bootloader_ci index 9bdb258ba4..d01be32d2a 100644 --- a/core/SConscript.bootloader_ci +++ b/core/SConscript.bootloader_ci @@ -69,6 +69,7 @@ CPPPATH_MOD += [ 'vendor/trezor-storage', ] CPPDEFINES_MOD += [ + 'KERNEL_MODE', 'AES_128', 'AES_192', 'USE_KECCAK', diff --git a/core/SConscript.bootloader_emu b/core/SConscript.bootloader_emu index a3462cc885..fb3e3ed2f2 100644 --- a/core/SConscript.bootloader_emu +++ b/core/SConscript.bootloader_emu @@ -68,6 +68,7 @@ CPPPATH_MOD += [ 'vendor/trezor-storage', ] CPPDEFINES_MOD += [ + 'KERNEL_MODE', 'AES_128', 'AES_192', 'USE_KECCAK', diff --git a/core/SConscript.coreapp b/core/SConscript.coreapp new file mode 100644 index 0000000000..2550ef94e3 --- /dev/null +++ b/core/SConscript.coreapp @@ -0,0 +1,941 @@ +# pylint: disable=E0602 +# fmt: off + +import os +import tools, models + +BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0') +PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1' +BOOTLOADER_QA = ARGUMENTS.get('BOOTLOADER_QA', '0') == '1' +BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1' +EVERYTHING = BITCOIN_ONLY != '1' +TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') +CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) +PYOPT = ARGUMENTS.get('PYOPT', '1') +DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1' +HW_REVISION = ARGUMENTS.get('HW_REVISION', None) +THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol +NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1' or TREZOR_MODEL in ('T3T1',) + + +FEATURE_FLAGS = { + "RDI": True, + "SECP256K1_ZKP": True, # required for trezor.crypto.curve.bip340 (BIP340/Taproot) + "AES_GCM": False, +} + +FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic"] +if DISABLE_OPTIGA and PYOPT == '0': + FEATURES_WANTED.remove("optiga") +if NEW_RENDERING: + FEATURES_WANTED.append("new_rendering") + +CCFLAGS_MOD = '' +CPPPATH_MOD = [] +CPPDEFINES_MOD = [] +SOURCE_MOD = [] +SOURCE_MOD_CRYPTO = [] +CPPDEFINES_HAL = [] +SOURCE_HAL = [] +PATH_HAL = [] + +FROZEN = True + +if TREZOR_MODEL in ('1', 'R', 'T3B1'): + FONT_NORMAL='Font_PixelOperator_Regular_8' + FONT_DEMIBOLD='Font_Unifont_Bold_16' + FONT_BOLD='Font_PixelOperator_Bold_8' + FONT_MONO='Font_PixelOperatorMono_Regular_8' + FONT_BIG='Font_Unifont_Regular_16' + FONT_NORMAL_UPPER='Font_PixelOperator_Regular_8_upper' + FONT_BOLD_UPPER='Font_PixelOperator_Bold_8_upper' + FONT_SUB=None +elif TREZOR_MODEL in ('T', 'DISC1', 'DISC2'): + FONT_NORMAL='Font_TTHoves_Regular_21' + FONT_DEMIBOLD='Font_TTHoves_DemiBold_21' + FONT_BOLD=None + FONT_MONO='Font_RobotoMono_Medium_20' + FONT_BIG=None + FONT_NORMAL_UPPER=None + FONT_BOLD_UPPER='Font_TTHoves_Bold_17_upper' + FONT_SUB=None +elif TREZOR_MODEL in ('T3T1',): + FONT_NORMAL='Font_TTSatoshi_DemiBold_21' + FONT_DEMIBOLD='Font_TTSatoshi_DemiBold_21' + FONT_BOLD='Font_TTSatoshi_DemiBold_21' + FONT_MONO='Font_RobotoMono_Medium_21' + FONT_BIG='Font_TTSatoshi_DemiBold_42' + FONT_NORMAL_UPPER=None + FONT_BOLD_UPPER=None + FONT_SUB='Font_TTSatoshi_DemiBold_18' + +# modtrezorconfig +CPPPATH_MOD += [ + 'embed/extmod/modtrezorconfig', + 'vendor/trezor-storage', +] +SOURCE_MOD += [ + 'embed/extmod/modtrezorconfig/modtrezorconfig.c', + 'vendor/trezor-storage/norcow.c', + 'vendor/trezor-storage/storage.c', + 'vendor/trezor-storage/storage_utils.c', + 'vendor/trezor-storage/flash_area.c', +] + +# modtrezorcrypto +CCFLAGS_MOD += '-Wno-sequence-point ' +CPPPATH_MOD += [ + 'vendor/trezor-crypto', +] +CPPDEFINES_MOD += [ + 'AES_128', + 'AES_192', + ('USE_BIP32_CACHE', '0'), + ('USE_KECCAK', '1'), + ('USE_ETHEREUM', '1' if EVERYTHING else '0'), + ('USE_MONERO', '1' if EVERYTHING else '0'), + ('USE_CARDANO', '1' if EVERYTHING else '0'), + ('USE_NEM', '1' if (EVERYTHING and TREZOR_MODEL == "T") else '0'), + ('USE_EOS', '1' if (EVERYTHING and TREZOR_MODEL == "T") else '0'), +] +SOURCE_MOD += [ + 'embed/extmod/trezorobj.c', + 'embed/extmod/modtrezorcrypto/crc.c', + 'embed/extmod/modtrezorcrypto/modtrezorcrypto.c', + 'embed/extmod/modtrezorcrypto/rand.c', +] +SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/address.c', + 'vendor/trezor-crypto/aes/aes_modes.c', + 'vendor/trezor-crypto/aes/aesccm.c', + 'vendor/trezor-crypto/aes/aescrypt.c', + 'vendor/trezor-crypto/aes/aeskey.c', + 'vendor/trezor-crypto/aes/aestab.c', + 'vendor/trezor-crypto/base32.c', + 'vendor/trezor-crypto/base58.c', + 'vendor/trezor-crypto/bignum.c', + 'vendor/trezor-crypto/bip32.c', + 'vendor/trezor-crypto/bip39.c', + 'vendor/trezor-crypto/bip39_english.c', + 'vendor/trezor-crypto/blake256.c', + 'vendor/trezor-crypto/blake2b.c', + 'vendor/trezor-crypto/blake2s.c', + 'vendor/trezor-crypto/buffer.c', + 'vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.c', + 'vendor/trezor-crypto/chacha20poly1305/chacha_merged.c', + 'vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c', + 'vendor/trezor-crypto/chacha20poly1305/rfc7539.c', + 'vendor/trezor-crypto/chacha_drbg.c', + 'vendor/trezor-crypto/curves.c', + 'vendor/trezor-crypto/der.c', + 'vendor/trezor-crypto/ecdsa.c', + 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c', + 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c', + 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-keccak.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-sha3.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519.c', + 'vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.c', + 'vendor/trezor-crypto/groestl.c', + 'vendor/trezor-crypto/hasher.c', + 'vendor/trezor-crypto/hmac.c', + 'vendor/trezor-crypto/hmac_drbg.c', + 'vendor/trezor-crypto/memzero.c', + 'vendor/trezor-crypto/nem.c', + 'vendor/trezor-crypto/nist256p1.c', + 'vendor/trezor-crypto/pbkdf2.c', + 'vendor/trezor-crypto/rand.c', + 'vendor/trezor-crypto/rfc6979.c', + 'vendor/trezor-crypto/ripemd160.c', + 'vendor/trezor-crypto/secp256k1.c', + 'vendor/trezor-crypto/segwit_addr.c', + 'vendor/trezor-crypto/sha2.c', + 'vendor/trezor-crypto/sha3.c', + 'vendor/trezor-crypto/shamir.c', + 'vendor/trezor-crypto/slip39.c', + 'vendor/trezor-crypto/slip39_english.c', + 'vendor/trezor-crypto/tls_prf.c', +] +if EVERYTHING: + SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/cardano.c', + 'vendor/trezor-crypto/monero/base58.c', + 'vendor/trezor-crypto/monero/serialize.c', + 'vendor/trezor-crypto/monero/xmr.c', + ] + +# libsecp256k1-zkp +if FEATURE_FLAGS["SECP256K1_ZKP"]: + CPPPATH_MOD += [ + 'vendor/secp256k1-zkp', + 'vendor/secp256k1-zkp/src', + 'vendor/secp256k1-zkp/include', + ] + CPPDEFINES_MOD += [ + 'USE_SECP256K1_ZKP', + 'USE_SECP256K1_ZKP_ECDSA', + ('SECP256K1_CONTEXT_SIZE', '180'), + 'USE_ASM_ARM', + 'USE_EXTERNAL_ASM', + 'USE_EXTERNAL_DEFAULT_CALLBACKS', + ('ECMULT_GEN_PREC_BITS', '2'), + ('ECMULT_WINDOW_SIZE', '2'), + 'ENABLE_MODULE_GENERATOR', + 'ENABLE_MODULE_RECOVERY', + 'ENABLE_MODULE_SCHNORRSIG', + 'ENABLE_MODULE_EXTRAKEYS', + 'ENABLE_MODULE_ECDH', + ] + SOURCE_MOD_SECP256K1_ZKP = [ + 'vendor/secp256k1-zkp/src/secp256k1.c', + 'vendor/secp256k1-zkp/src/precomputed_ecmult.c', + 'vendor/secp256k1-zkp/src/precomputed_ecmult_gen.c', + 'vendor/secp256k1-zkp/src/asm/field_10x26_arm.s' + ] + SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/zkp_context.c', + 'vendor/trezor-crypto/zkp_ecdsa.c', + 'vendor/trezor-crypto/zkp_bip340.c', + ] + +# AES-GCM +if FEATURE_FLAGS["AES_GCM"]: + CPPDEFINES_MOD += [ + 'USE_AES_GCM', + 'AES_VAR', + ] + SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/aes/gf128mul.c', + 'vendor/trezor-crypto/aes/aesgcm.c', + ] + +# modtrezorio +SOURCE_MOD += [ + 'embed/extmod/modtrezorio/modtrezorio.c', +] + +# modtrezorui +CPPPATH_MOD += [ + 'vendor/micropython/lib/uzlib', +] +SOURCE_MOD += [ + 'embed/extmod/modtrezorui/modtrezorui.c', + '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', + 'embed/lib/gfx_bitblt_rgb565.c', + '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', + 'vendor/micropython/lib/uzlib/adler32.c', + 'vendor/micropython/lib/uzlib/crc32.c', + 'vendor/micropython/lib/uzlib/tinflate.c', +] + +if NEW_RENDERING: + CPPDEFINES_MOD += ['NEW_RENDERING'] + SOURCE_MOD += [ + 'embed/lib/gfx_draw.c', + ] +else: + SOURCE_MOD += [ + 'embed/lib/display_draw.c', + ] + + +CPPDEFINES_MOD += [ + 'TREZOR_UI2', + 'TRANSLATIONS', +] + +if TREZOR_MODEL not in ('1', ): + CPPDEFINES_MOD += [ + 'FANCY_FATAL_ERROR', + ] + +# modtrezorutils +SOURCE_MOD += [ + 'embed/extmod/modtrezorutils/modtrezorutils.c', +] + +# rust mods +SOURCE_MOD += [ + 'embed/extmod/rustmods.c', +] + +# modutime +SOURCE_MOD += [ + 'embed/extmod/modutime.c', +] + +SOURCE_MICROPYTHON = [ + 'vendor/micropython/extmod/modubinascii.c', + 'vendor/micropython/extmod/moductypes.c', + 'vendor/micropython/extmod/moduheapq.c', + 'vendor/micropython/extmod/modutimeq.c', + 'vendor/micropython/extmod/utime_mphal.c', + 'vendor/micropython/shared/libc/abort_.c', + 'vendor/micropython/shared/libc/printf.c', + 'vendor/micropython/shared/runtime/gchelper_m3.s', + 'vendor/micropython/shared/runtime/gchelper_native.c', + 'vendor/micropython/shared/runtime/interrupt_char.c', + 'vendor/micropython/shared/runtime/pyexec.c', + 'vendor/micropython/shared/runtime/stdout_helpers.c', + 'vendor/micropython/shared/timeutils/timeutils.c', + 'vendor/micropython/ports/stm32/gccollect.c', + 'vendor/micropython/py/argcheck.c', + 'vendor/micropython/py/asmarm.c', + 'vendor/micropython/py/asmbase.c', + 'vendor/micropython/py/asmthumb.c', + 'vendor/micropython/py/asmx64.c', + 'vendor/micropython/py/asmx86.c', + 'vendor/micropython/py/asmxtensa.c', + 'vendor/micropython/py/bc.c', + 'vendor/micropython/py/binary.c', + 'vendor/micropython/py/builtinevex.c', + 'vendor/micropython/py/builtinhelp.c', + 'vendor/micropython/py/builtinimport.c', + 'vendor/micropython/py/compile.c', + 'vendor/micropython/py/emitbc.c', + 'vendor/micropython/py/emitcommon.c', + 'vendor/micropython/py/emitglue.c', + 'vendor/micropython/py/emitinlinethumb.c', + 'vendor/micropython/py/emitinlinextensa.c', + 'vendor/micropython/py/formatfloat.c', + 'vendor/micropython/py/frozenmod.c', + 'vendor/micropython/py/lexer.c', + 'vendor/micropython/py/malloc.c', + 'vendor/micropython/py/map.c', + 'vendor/micropython/py/modarray.c', + 'vendor/micropython/py/modbuiltins.c', + 'vendor/micropython/py/modgc.c', + 'vendor/micropython/py/modmath.c', + 'vendor/micropython/py/modmicropython.c', + 'vendor/micropython/py/modstruct.c', + 'vendor/micropython/py/modsys.c', + 'vendor/micropython/py/mpprint.c', + 'vendor/micropython/py/mpstate.c', + 'vendor/micropython/py/mpz.c', + 'vendor/micropython/py/nativeglue.c', + 'vendor/micropython/py/obj.c', + 'vendor/micropython/py/objarray.c', + 'vendor/micropython/py/objattrtuple.c', + 'vendor/micropython/py/objbool.c', + 'vendor/micropython/py/objboundmeth.c', + 'vendor/micropython/py/objcell.c', + 'vendor/micropython/py/objclosure.c', + 'vendor/micropython/py/objcomplex.c', + 'vendor/micropython/py/objdict.c', + 'vendor/micropython/py/objenumerate.c', + 'vendor/micropython/py/objexcept.c', + 'vendor/micropython/py/objfilter.c', + 'vendor/micropython/py/objfloat.c', + 'vendor/micropython/py/objfun.c', + 'vendor/micropython/py/objgenerator.c', + 'vendor/micropython/py/objgetitemiter.c', + 'vendor/micropython/py/objint.c', + 'vendor/micropython/py/objint_longlong.c', + 'vendor/micropython/py/objint_mpz.c', + 'vendor/micropython/py/objlist.c', + 'vendor/micropython/py/objmap.c', + 'vendor/micropython/py/objmodule.c', + 'vendor/micropython/py/objnamedtuple.c', + 'vendor/micropython/py/objnone.c', + 'vendor/micropython/py/objobject.c', + 'vendor/micropython/py/objpolyiter.c', + 'vendor/micropython/py/objproperty.c', + 'vendor/micropython/py/objrange.c', + 'vendor/micropython/py/objreversed.c', + 'vendor/micropython/py/objset.c', + 'vendor/micropython/py/objsingleton.c', + 'vendor/micropython/py/objslice.c', + 'vendor/micropython/py/objstr.c', + 'vendor/micropython/py/objstringio.c', + 'vendor/micropython/py/objstrunicode.c', + 'vendor/micropython/py/objtuple.c', + 'vendor/micropython/py/objtype.c', + 'vendor/micropython/py/objzip.c', + 'vendor/micropython/py/opmethods.c', + 'vendor/micropython/py/pairheap.c', + 'vendor/micropython/py/parse.c', + 'vendor/micropython/py/parsenum.c', + 'vendor/micropython/py/parsenumbase.c', + 'vendor/micropython/py/persistentcode.c', + 'vendor/micropython/py/qstr.c', + 'vendor/micropython/py/reader.c', + 'vendor/micropython/py/repl.c', + 'vendor/micropython/py/runtime.c', + 'vendor/micropython/py/runtime_utils.c', + 'vendor/micropython/py/scheduler.c', + 'vendor/micropython/py/scope.c', + 'vendor/micropython/py/sequence.c', + 'vendor/micropython/py/showbc.c', + 'vendor/micropython/py/smallint.c', + 'vendor/micropython/py/stackctrl.c', + 'vendor/micropython/py/stream.c', + 'vendor/micropython/py/unicode.c', + 'vendor/micropython/py/vstr.c', + 'vendor/micropython/py/warning.c', +] + +SOURCE_MICROPYTHON_SPEED = [ + 'vendor/micropython/py/gc.c', + 'vendor/micropython/py/pystack.c', + 'vendor/micropython/py/vm.c', +] + +CPPDEFINES_MOD += ['USE_SVC_SHUTDOWN'] + +if FEATURE_FLAGS["RDI"]: + CPPDEFINES_MOD += ['RDI'] + +TRANSLATION_DATA = [ + "translations/en.json", + "translations/order.json", +] + +if THP: + CPPDEFINES_MOD += ['USE_THP'] + SOURCE_MOD += [ + 'vendor/trezor-crypto/elligator2.c', + ] + +# fonts +tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('DEMIBOLD', FONT_DEMIBOLD, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('BIG', FONT_BIG, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('NORMAL_UPPER', FONT_NORMAL_UPPER, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('BOLD_UPPER', FONT_BOLD_UPPER, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('SUB', FONT_SUB, CPPDEFINES_MOD, SOURCE_MOD) + +SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_MICROPYTHON_SPEED + +env = Environment( + ENV=os.environ, + CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY}", + CPPDEFINES_IMPLICIT=[] + ) + +FEATURES_AVAILABLE = models.configure_board(TREZOR_MODEL, HW_REVISION, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL) + +FILE_SUFFIX= env.get('ENV')['SUFFIX'] + +SOURCE_FIRMWARE = [ + 'embed/coreapp/header.S', + 'embed/coreapp/main.c', + 'embed/coreapp/mphalport.c', + 'embed/coreapp/nlrthumb.c', + f'embed/coreapp/startup_{FILE_SUFFIX}.S', +] + + +if TREZOR_MODEL in ('T', 'DISC1', 'DISC2'): + UI_LAYOUT = 'UI_LAYOUT_TT' + ui_layout_feature = 'model_tt' +elif TREZOR_MODEL in ('1', 'R', 'T3B1'): + UI_LAYOUT = 'UI_LAYOUT_TR' + ui_layout_feature = 'model_tr' +elif TREZOR_MODEL in ('T3T1',): + UI_LAYOUT = 'UI_LAYOUT_MERCURY' + ui_layout_feature = 'model_mercury' +else: + raise ValueError('Unknown Trezor model') + +if 'sd_card' in FEATURES_AVAILABLE: + SDCARD = True +else: + SDCARD = False + +env.Tool('micropython') + +env.Replace( + CAT='cat', + DD='dd', + CP='cp', + SED='sed', + AS='arm-none-eabi-as', + AR='arm-none-eabi-ar', + CC='arm-none-eabi-gcc', + LINK='arm-none-eabi-gcc', + SIZE='arm-none-eabi-size', + STRIP='arm-none-eabi-strip', + OBJCOPY='arm-none-eabi-objcopy', ) + +env.Replace( + TREZOR_MODEL=TREZOR_MODEL,) + +if TREZOR_MODEL in ('1',): + LD_VARIANT = '' if EVERYTHING else '_min' +else: + LD_VARIANT = '' + +ALLPATHS = [ + '.', + 'embed/rust', + 'embed/coreapp', + 'embed/lib', + 'embed/models', + 'embed/trezorhal', + 'embed/extmod/modtrezorui', + 'vendor/micropython', + ] + CPPPATH_MOD + PATH_HAL + +env.Replace( + COPT=env.get('ENV').get('OPTIMIZE', '-Os'), + CCFLAGS='$COPT ' + '-g3 ' + '-nostdlib ' + '-std=gnu11 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common ' + '-fsingle-precision-constant -fdata-sections -ffunction-sections ' + '-ffreestanding ' + '-fstack-protector-all ' + + env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD, + CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', + LINKFLAGS='-T embed/coreapp/memory_${TREZOR_MODEL}%s.ld -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-Map=build/coreapp/coreapp.map -Wl,--warn-common' % LD_VARIANT, + CPPPATH=ALLPATHS, + CPPDEFINES=[ + 'FIRMWARE', + 'TREZOR_MODEL_'+TREZOR_MODEL, + 'USE_HAL_DRIVER', + 'ARM_USER_MODE', + UI_LAYOUT, + ] + CPPDEFINES_MOD + CPPDEFINES_HAL, + ASFLAGS=env.get('ENV')['CPU_ASFLAGS'], + ASPPFLAGS='$CFLAGS $CCFLAGS', + ) + +env.Replace( + HEADERTOOL='headertool', + PYTHON='python', + MAKEQSTRDATA='$PYTHON vendor/micropython/py/makeqstrdata.py', + MAKEVERSIONHDR='$PYTHON vendor/micropython/py/makeversionhdr.py', + MAKEMODULEDEFS='$PYTHON vendor/micropython/py/makemoduledefs.py', + MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py', + MPY_TOOL='$PYTHON vendor/micropython/tools/mpy-tool.py', + MPY_CROSS='vendor/micropython/mpy-cross/mpy-cross -O' + PYOPT, + PB2PY='$PYTHON ../common/protob/pb2py', +) + +# +# Qstrings +# + +PROTO_SOURCES_DIR = '../../../common/protob/' +PROTO_SOURCES = Glob(PROTO_SOURCES_DIR + '*.proto', + exclude=[PROTO_SOURCES_DIR + 'messages-bootloader.proto'] +) +qstr_protobuf = env.Command( + target=[ + 'genhdr/qstrdefs.protobuf.h', + ], + source=PROTO_SOURCES, + action='$PB2PY $SOURCES --qstr-out ${TARGET} --bitcoin-only=%s' % BITCOIN_ONLY, +) + +qstr_micropython = 'vendor/micropython/py/qstrdefs.h' + +micropy_defines = env.MicroPyDefines(source=SOURCE_QSTR) + +qstr_collected = env.CollectQstr( + target='genhdr/qstrdefs.collected.h', source=micropy_defines) + +qstr_preprocessed = env.PreprocessQstr( + target='genhdr/qstrdefs.preprocessed.h', + source=[qstr_micropython, qstr_protobuf, qstr_collected]) + +qstr_generated = env.GenerateQstrDefs( + target='genhdr/qstrdefs.generated.h', source=qstr_preprocessed) + +env.Ignore(qstr_collected, qstr_generated) + +# +# Micropython module declarations +# + +moduledefs_collected = env.CollectModules( + target='genhdr/moduledefs.collected.h', source=micropy_defines) + +hdr_moduledefs = env.Command( + target='genhdr/moduledefs.h', + source=moduledefs_collected, + action='$MAKEMODULEDEFS $SOURCE > $TARGET', ) + +env.Ignore(micropy_defines, micropy_defines) +env.Ignore(micropy_defines, qstr_generated) +env.Ignore(micropy_defines, hdr_moduledefs) + +# +# Micropython version +# + +hdr_version = env.Command( + target='genhdr/mpversion.h', + source='', + action='$MAKEVERSIONHDR $TARGET', ) + +env.Ignore(hdr_moduledefs, hdr_moduledefs) +env.Ignore(hdr_moduledefs, qstr_collected) +env.Ignore(hdr_moduledefs, qstr_preprocessed) +env.Ignore(hdr_moduledefs, qstr_generated) + +# +# Frozen modules +# + +if FROZEN: + SOURCE_PY_DIR = 'src/' + + SOURCE_PY = Glob(SOURCE_PY_DIR + '*.py') + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/*.py', + exclude=[ + SOURCE_PY_DIR + 'trezor/sdcard.py', + ] if not SDCARD else [] + )) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/crypto/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/*.py')) + + # UI layouts - common files and then model-specific. Exclude FIDO when BTC-only. + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/*.py', + exclude=[ + SOURCE_PY_DIR + 'trezor/ui/layouts/fido.py', + ] if not EVERYTHING else [] + )) + if UI_LAYOUT == 'UI_LAYOUT_TT': + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt/*.py', + exclude=[ + SOURCE_PY_DIR + 'trezor/ui/layouts/tt/fido.py', + ] if not EVERYTHING else [] + )) + elif UI_LAYOUT == 'UI_LAYOUT_TR': + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tr/*.py', + exclude=[ + SOURCE_PY_DIR + 'trezor/ui/layouts/tr/fido.py', + ] if not EVERYTHING else [] + )) + elif UI_LAYOUT == 'UI_LAYOUT_MERCURY': + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/mercury/*.py', + exclude=[ + SOURCE_PY_DIR + 'trezor/ui/layouts/mercury/fido.py', + ] if not EVERYTHING else [] + )) + else: + raise ValueError('Unknown layout') + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/wire/*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'storage/*.py', + exclude=[ + SOURCE_PY_DIR + 'storage/sd_salt.py', + ] if not SDCARD else [] + )) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/messages/__init__.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/*.py', + exclude=[ + SOURCE_PY_DIR + 'trezor/enums/Binance*.py', + SOURCE_PY_DIR + 'trezor/enums/Cardano*.py', + SOURCE_PY_DIR + 'trezor/enums/DebugMonero*.py', + SOURCE_PY_DIR + 'trezor/enums/Eos*.py', + SOURCE_PY_DIR + 'trezor/enums/Ethereum*.py', + SOURCE_PY_DIR + 'trezor/enums/Monero*.py', + SOURCE_PY_DIR + 'trezor/enums/NEM*.py', + SOURCE_PY_DIR + 'trezor/enums/Ripple*.py', + SOURCE_PY_DIR + 'trezor/enums/Solana*.py', + SOURCE_PY_DIR + 'trezor/enums/Stellar*.py', + SOURCE_PY_DIR + 'trezor/enums/Tezos*.py', + SOURCE_PY_DIR + 'trezor/enums/Zcash*.py', + ]) + ) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/common/*.py', + exclude=[ + SOURCE_PY_DIR + 'apps/common/sdcard.py', + ] if not SDCARD else [] + )) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/debug/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py', + exclude=[ + SOURCE_PY_DIR + 'apps/management/sd_protect.py', + ] if not SDCARD else []) + ) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/misc/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*/*.py', + exclude=[ + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash_v4.py', + ]) + ) + + if EVERYTHING: + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/binance/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Binance*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/cardano/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/cardano/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Cardano*.py')) + + if TREZOR_MODEL == "T": + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/eos/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/eos/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Eos*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/ethereum/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Ethereum*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/monero/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/monero/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/monero/*/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/DebugMonero*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Monero*.py')) + + if TREZOR_MODEL == "T": + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/nem/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/nem/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/NEM*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/ripple/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Ripple*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/solana/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/solana/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Solana*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/stellar/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/stellar/*/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Stellar*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/tezos/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Tezos*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/*.py')) + + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/webauthn/*.py')) + + if TREZOR_MODEL == "T": + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash_v4.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Zcash*.py')) + + source_mpy = env.FrozenModule( + source=SOURCE_PY, + source_dir=SOURCE_PY_DIR, + bitcoin_only=BITCOIN_ONLY, + backlight='backlight' in FEATURES_AVAILABLE, + optiga='optiga' in FEATURES_AVAILABLE, + ui_layout=UI_LAYOUT, + thp=THP, + ) + + source_mpyc = env.FrozenCFile( + target='frozen_mpy.c', source=source_mpy, qstr_header=qstr_preprocessed) + + env.Depends(source_mpyc, qstr_generated) + + +# +# Program objects +# + +source_files = SOURCE_MOD + SOURCE_MOD_CRYPTO + SOURCE_FIRMWARE + SOURCE_MICROPYTHON + SOURCE_MICROPYTHON_SPEED + SOURCE_HAL +obj_program = [] +obj_program.extend(env.Object(source=SOURCE_MOD)) +obj_program.extend(env.Object(source=SOURCE_MOD_CRYPTO, CCFLAGS='$CCFLAGS -ftrivial-auto-var-init=zero')) +if FEATURE_FLAGS["SECP256K1_ZKP"]: + obj_program.extend(env.Object(source=SOURCE_MOD_SECP256K1_ZKP, CCFLAGS='$CCFLAGS -Wno-unused-function')) + source_files.extend(SOURCE_MOD_SECP256K1_ZKP) +obj_program.extend(env.Object(source=SOURCE_FIRMWARE)) +obj_program.extend(env.Object(source=SOURCE_MICROPYTHON)) +obj_program.extend(env.Object(source=SOURCE_MICROPYTHON_SPEED, COPT='-O3')) +obj_program.extend(env.Object(source=SOURCE_HAL)) +if FROZEN: + obj_program.extend(env.Object(source=source_mpyc)) + +env.Replace( + ALLSOURCES=source_files, + ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES'] + env['CPPDEFINES_IMPLICIT'] + [f"PRODUCTION={int(PRODUCTION)}", f"BOOTLOADER_QA={int(BOOTLOADER_QA)}", f"PYOPT={PYOPT}", f"BITCOIN_ONLY={BITCOIN_ONLY}"])) + + +cmake_gen = env.Command( + target='CMakeLists.txt', + source='', + action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS', +) + +# +# Rust library +# + +protobuf_blobs = env.Command( + target=[ + 'rust/proto_enums.data', + 'rust/proto_msgs.data', + 'rust/proto_names.data', + 'rust/proto_wire.data', + ], + source=PROTO_SOURCES, + action='$PB2PY --bitcoin-only=%s --blob-outdir ${TARGET.dir} $SOURCES --qstr-defs build/coreapp/genhdr/qstrdefs.generated.h' % BITCOIN_ONLY, +) +env.Depends(protobuf_blobs, qstr_generated) + +RUST_PROFILE = 'release' +RUST_LIB = 'trezor_lib' +RUST_LIBDIR = f'build/coreapp/rust/{env.get("ENV")["RUST_TARGET"]}/{RUST_PROFILE}' +RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a' + +def cargo_build(): + # Determine the profile build flags. + if RUST_PROFILE == 'release': + profile = '--release' + else: + profile = '' + + features = ['micropython', 'protobuf', ui_layout_feature] + if EVERYTHING: + features.append('universal_fw') + features.append('ui') + features.append('translations') + + if NEW_RENDERING: + features.append('new_rendering') + + if PYOPT == '0': + features.append('debug') + features.append('ui_debug') + if TREZOR_MODEL in ('T', 'T3T1', 'DISC1', 'DISC2'): + features.append('ui_blurring') + features.append('ui_jpeg_decoder') + + if NEW_RENDERING and TREZOR_MODEL in ('T3T1', 'DISC2'): + features.append('ui_image_buffer') + features.append('ui_overlay') + + features.extend(FEATURES_AVAILABLE) + + cargo_opts = [ + f'--target={env.get("ENV")["RUST_TARGET"]}', + f'--target-dir=../../build/coreapp/rust', + '--no-default-features', + '--features ' + ','.join(features), + '-Z build-std=core', + '-Z build-std-features=panic_immediate_abort', + ] + + env.get('ENV')['TREZOR_MODEL'] = TREZOR_MODEL + + bindgen_macros = tools.get_bindgen_defines(env.get("CPPDEFINES"), ALLPATHS) + build_dir = str(Dir('.').abspath) + + return f'export BINDGEN_MACROS=\'{bindgen_macros}\'; export BUILD_DIR=\'{build_dir}\'; cd embed/rust; cargo build {profile} ' + ' '.join(cargo_opts) + +rust = env.Command( + target=RUST_LIBPATH, + source='', + action=cargo_build(), ) +env.Depends(rust, protobuf_blobs) +env.Depends(rust, TRANSLATION_DATA) + +env.Append(LINKFLAGS=f' -L{RUST_LIBDIR}') +env.Append(LINKFLAGS=f' -l{RUST_LIB}') + + +MODEL_IDENTIFIER = models.get_model_identifier(TREZOR_MODEL) +BOOTLOADER_SUFFIX = MODEL_IDENTIFIER +if BOOTLOADER_QA or BOOTLOADER_DEVEL: + BOOTLOADER_SUFFIX += '_qa' + +# select vendor header +if BOOTLOADER_QA or BOOTLOADER_DEVEL: + vendor = "dev_DO_NOT_SIGN_signed_dev" +elif not PRODUCTION: + vendor = "unsafe_signed_prod" +else: + if TREZOR_MODEL in ('T',): + vendor = "satoshilabs_signed_prod" + elif BITCOIN_ONLY == '1': + vendor = "trezor_btconly_signed_prod" + else: + vendor = "trezor_signed_prod" + +VENDORHEADER = f'embed/models/{MODEL_IDENTIFIER}/vendorheader/vendorheader_{vendor}.bin' + + +if TREZOR_MODEL not in ('1',): + obj_program.extend( + env.Command( + target='embed/coreapp/vendorheader.o', + source=VENDORHEADER, + action='$OBJCOPY -I binary -O elf32-littlearm -B arm' + ' --rename-section .data=.vendorheader,alloc,load,readonly,contents' + ' $SOURCE $TARGET', )) + +env.Depends(obj_program, qstr_generated) + +program_elf = env.Command( + target='coreapp.elf', + source=obj_program, + action= + '$LINK -o $TARGET $CCFLAGS $CFLAGS $SOURCES $LINKFLAGS -lc_nano -lm -lgcc', +) + +if CMAKELISTS != 0: + env.Depends(program_elf, cmake_gen) +env.Depends(program_elf, rust) + +BINARY_NAME = f"build/coreapp/coreapp-{models.get_model_identifier(TREZOR_MODEL)}" +if not EVERYTHING: + BINARY_NAME += "-btconly" +BINARY_NAME += "-" + tools.get_version('embed/coreapp/version.h') +BINARY_NAME += "-" + tools.get_git_revision_short_hash() +BINARY_NAME += "-dirty" if tools.get_git_modified() else "" +BINARY_NAME += ".bin" + + +if TREZOR_MODEL in ('1'): + action_bin=[ + '$OBJCOPY -O binary -j .header -j .flash -j .data -j .confidential $SOURCE $TARGET', + '../legacy/bootloader/firmware_sign.py -f $TARGET', + '$CP $TARGET ' + BINARY_NAME, + ] +else: + if 'STM32F427xx' in CPPDEFINES_HAL or 'STM32F429xx' in CPPDEFINES_HAL: + action_bin=[ + '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .confidential --pad-to 0x08100000 $SOURCE ${TARGET}.p1', + '$OBJCOPY -O binary -j .flash2 $SOURCE ${TARGET}.p2', + '$CAT ${TARGET}.p1 ${TARGET}.p2 > $TARGET', + '$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''), + '$DD if=$TARGET of=${TARGET}.p1 skip=0 bs=128k count=6', + '$CP $TARGET ' + BINARY_NAME, + ] + elif 'STM32U5A9xx' in CPPDEFINES_HAL or 'STM32U585xx' in CPPDEFINES_HAL: + action_bin=[ + '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .confidential $SOURCE ${TARGET}', + '$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''), + '$CP $TARGET ' + BINARY_NAME, + ] + else: + raise Exception("Unknown MCU") + +program_bin = env.Command( + target='coreapp.bin', + source=program_elf, + action=action_bin, +) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 41e6677273..74a2e634cd 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -77,10 +77,6 @@ CPPPATH_MOD += [ ] SOURCE_MOD += [ 'embed/extmod/modtrezorconfig/modtrezorconfig.c', - 'vendor/trezor-storage/norcow.c', - 'vendor/trezor-storage/storage.c', - 'vendor/trezor-storage/storage_utils.c', - 'vendor/trezor-storage/flash_area.c', ] # modtrezorcrypto @@ -89,6 +85,7 @@ CPPPATH_MOD += [ 'vendor/trezor-crypto', ] CPPDEFINES_MOD += [ + 'KERNEL_MODE', 'AES_128', 'AES_192', ('USE_BIP32_CACHE', '0'), diff --git a/core/SConscript.kernel b/core/SConscript.kernel new file mode 100644 index 0000000000..2be27fc7f5 --- /dev/null +++ b/core/SConscript.kernel @@ -0,0 +1,502 @@ +# pylint: disable=E0602 +# fmt: off + +import os +import tools, models + +BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0') +PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1' +BOOTLOADER_QA = ARGUMENTS.get('BOOTLOADER_QA', '0') == '1' +BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1' +EVERYTHING = BITCOIN_ONLY != '1' +TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') +CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) +PYOPT = ARGUMENTS.get('PYOPT', '1') +DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1' +HW_REVISION = ARGUMENTS.get('HW_REVISION', None) +THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol +NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1' or TREZOR_MODEL in ('T3T1',) + + +FEATURE_FLAGS = { + "RDI": True, + "SECP256K1_ZKP": True, # required for trezor.crypto.curve.bip340 (BIP340/Taproot) + "SYSTEM_VIEW": False, + "AES_GCM": False, +} + +FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic"] +if DISABLE_OPTIGA and PYOPT == '0': + FEATURES_WANTED.remove("optiga") +if NEW_RENDERING: + FEATURES_WANTED.append("new_rendering") + +CCFLAGS_MOD = '' +CPPPATH_MOD = [] +CPPDEFINES_MOD = [] +SOURCE_MOD = [] +SOURCE_MOD_CRYPTO = [] +CPPDEFINES_HAL = [] +SOURCE_HAL = [] +PATH_HAL = [] + +FROZEN = True + +if TREZOR_MODEL in ('1', 'R'): + FONT_NORMAL='Font_PixelOperator_Regular_8' + FONT_DEMIBOLD='Font_Unifont_Bold_16' + FONT_BOLD='Font_PixelOperator_Bold_8' + FONT_MONO='Font_PixelOperatorMono_Regular_8' + FONT_BIG='Font_Unifont_Regular_16' + FONT_NORMAL_UPPER='Font_PixelOperator_Regular_8_upper' + FONT_BOLD_UPPER='Font_PixelOperator_Bold_8_upper' + FONT_SUB=None +elif TREZOR_MODEL in ('T', 'DISC1', 'DISC2'): + FONT_NORMAL='Font_TTHoves_Regular_21' + FONT_DEMIBOLD='Font_TTHoves_DemiBold_21' + FONT_BOLD=None + FONT_MONO='Font_RobotoMono_Medium_20' + FONT_BIG=None + FONT_NORMAL_UPPER=None + FONT_BOLD_UPPER='Font_TTHoves_Bold_17_upper' + FONT_SUB=None +elif TREZOR_MODEL in ('T3T1',): + FONT_NORMAL='Font_TTSatoshi_DemiBold_21' + FONT_DEMIBOLD='Font_TTSatoshi_DemiBold_21' + FONT_BOLD='Font_TTSatoshi_DemiBold_21' + FONT_MONO='Font_RobotoMono_Medium_21' + FONT_BIG='Font_TTSatoshi_DemiBold_42' + FONT_NORMAL_UPPER=None + FONT_BOLD_UPPER=None + FONT_SUB='Font_TTSatoshi_DemiBold_18' + +# modtrezorconfig +CPPPATH_MOD += [ + 'embed/extmod/modtrezorconfig', + 'vendor/trezor-storage', +] +SOURCE_MOD += [ +# 'embed/extmod/modtrezorconfig/modtrezorconfig.c', + 'vendor/trezor-storage/norcow.c', + 'vendor/trezor-storage/storage.c', + 'vendor/trezor-storage/storage_utils.c', + 'vendor/trezor-storage/flash_area.c', +] + +# modtrezorcrypto +CCFLAGS_MOD += '-Wno-sequence-point ' +CPPPATH_MOD += [ + 'vendor/trezor-crypto', +] +CPPDEFINES_MOD += [ + 'KERNEL_MODE', + 'SYSCALL_DISPATCH', + 'AES_128', + 'AES_192', + ('USE_BIP32_CACHE', '0'), + ('USE_KECCAK', '1'), + ('USE_ETHEREUM', '1' if EVERYTHING else '0'), + ('USE_MONERO', '1' if EVERYTHING else '0'), + ('USE_CARDANO', '1' if EVERYTHING else '0'), + ('USE_NEM', '1' if (EVERYTHING and TREZOR_MODEL == "T") else '0'), + ('USE_EOS', '1' if (EVERYTHING and TREZOR_MODEL == "T") else '0'), +] +SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/address.c', + 'vendor/trezor-crypto/aes/aes_modes.c', + 'vendor/trezor-crypto/aes/aesccm.c', + 'vendor/trezor-crypto/aes/aescrypt.c', + 'vendor/trezor-crypto/aes/aeskey.c', + 'vendor/trezor-crypto/aes/aestab.c', + 'vendor/trezor-crypto/base32.c', + 'vendor/trezor-crypto/base58.c', + 'vendor/trezor-crypto/bignum.c', + 'vendor/trezor-crypto/bip32.c', + 'vendor/trezor-crypto/bip39.c', + 'vendor/trezor-crypto/bip39_english.c', + 'vendor/trezor-crypto/blake256.c', + 'vendor/trezor-crypto/blake2b.c', + 'vendor/trezor-crypto/blake2s.c', + 'vendor/trezor-crypto/buffer.c', + 'vendor/trezor-crypto/chacha20poly1305/chacha20poly1305.c', + 'vendor/trezor-crypto/chacha20poly1305/chacha_merged.c', + 'vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c', + 'vendor/trezor-crypto/chacha20poly1305/rfc7539.c', + 'vendor/trezor-crypto/chacha_drbg.c', + 'vendor/trezor-crypto/curves.c', + 'vendor/trezor-crypto/der.c', + 'vendor/trezor-crypto/ecdsa.c', + 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c', + 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c', + 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-keccak.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519-sha3.c', + 'vendor/trezor-crypto/ed25519-donna/ed25519.c', + 'vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.c', + 'vendor/trezor-crypto/groestl.c', + 'vendor/trezor-crypto/hasher.c', + 'vendor/trezor-crypto/hmac.c', + 'vendor/trezor-crypto/hmac_drbg.c', + 'vendor/trezor-crypto/memzero.c', + 'vendor/trezor-crypto/nem.c', + 'vendor/trezor-crypto/nist256p1.c', + 'vendor/trezor-crypto/pbkdf2.c', + 'vendor/trezor-crypto/rand.c', + 'vendor/trezor-crypto/rfc6979.c', + 'vendor/trezor-crypto/ripemd160.c', + 'vendor/trezor-crypto/secp256k1.c', + 'vendor/trezor-crypto/segwit_addr.c', + 'vendor/trezor-crypto/sha2.c', + 'vendor/trezor-crypto/sha3.c', + 'vendor/trezor-crypto/shamir.c', + 'vendor/trezor-crypto/slip39.c', + 'vendor/trezor-crypto/slip39_english.c', + 'vendor/trezor-crypto/tls_prf.c', +] +if EVERYTHING: + SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/cardano.c', + 'vendor/trezor-crypto/monero/base58.c', + 'vendor/trezor-crypto/monero/serialize.c', + 'vendor/trezor-crypto/monero/xmr.c', + ] + +# libsecp256k1-zkp +if FEATURE_FLAGS["SECP256K1_ZKP"]: + CPPPATH_MOD += [ + 'vendor/secp256k1-zkp', + 'vendor/secp256k1-zkp/src', + 'vendor/secp256k1-zkp/include', + ] + CPPDEFINES_MOD += [ + 'USE_SECP256K1_ZKP', + 'USE_SECP256K1_ZKP_ECDSA', + ('SECP256K1_CONTEXT_SIZE', '180'), + 'USE_ASM_ARM', + 'USE_EXTERNAL_ASM', + 'USE_EXTERNAL_DEFAULT_CALLBACKS', + ('ECMULT_GEN_PREC_BITS', '2'), + ('ECMULT_WINDOW_SIZE', '2'), + 'ENABLE_MODULE_GENERATOR', + 'ENABLE_MODULE_RECOVERY', + 'ENABLE_MODULE_SCHNORRSIG', + 'ENABLE_MODULE_EXTRAKEYS', + 'ENABLE_MODULE_ECDH', + ] + SOURCE_MOD_SECP256K1_ZKP = [ + 'vendor/secp256k1-zkp/src/secp256k1.c', + 'vendor/secp256k1-zkp/src/precomputed_ecmult.c', + 'vendor/secp256k1-zkp/src/precomputed_ecmult_gen.c', + 'vendor/secp256k1-zkp/src/asm/field_10x26_arm.s' + ] + SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/zkp_context.c', + 'vendor/trezor-crypto/zkp_ecdsa.c', + 'vendor/trezor-crypto/zkp_bip340.c', + ] + +# AES-GCM +if FEATURE_FLAGS["AES_GCM"]: + CPPDEFINES_MOD += [ + 'USE_AES_GCM', + 'AES_VAR', + ] + SOURCE_MOD_CRYPTO += [ + 'vendor/trezor-crypto/aes/gf128mul.c', + 'vendor/trezor-crypto/aes/aesgcm.c', + ] + +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', + 'embed/lib/gfx_bitblt_rgb565.c', + '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', + 'embed/extmod/modtrezorcrypto/rand.c', +] + +if NEW_RENDERING: + CPPDEFINES_MOD += ['NEW_RENDERING'] + SOURCE_MOD += [ + 'embed/lib/gfx_draw.c', + ] +else: + SOURCE_MOD += [ + 'embed/lib/display_draw.c', + ] + + +CPPDEFINES_MOD += [ + 'TREZOR_UI2', + 'TRANSLATIONS', +] + +if TREZOR_MODEL not in ('1', ): + CPPDEFINES_MOD += [ + # 'FANCY_FATAL_ERROR', + ] + +CPPDEFINES_MOD += ['USE_SVC_SHUTDOWN'] + +if FEATURE_FLAGS["RDI"]: + CPPDEFINES_MOD += ['RDI'] + +if FEATURE_FLAGS["SYSTEM_VIEW"]: + SOURCE_FIRMWARE += [ + 'embed/segger/SEGGER/SEGGER_SYSVIEW_Config_NoOS.c', + 'embed/segger/SEGGER/SEGGER_SYSVIEW.c', + 'embed/segger/SEGGER/SEGGER_RTT.c', + 'embed/segger/SEGGER/SEGGER_RTT_ASM_ARMv7M.S', + 'embed/segger/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c', + 'embed/firmware/systemview.c', + ] + CPPPATH_MOD += [ + 'embed/segger/SEGGER/', + 'embed/segger/Config/', + ] + CPPDEFINES_MOD += ['SYSTEM_VIEW'] + CCFLAGS_MOD += '-DSYSTEM_VIEW ' + +TRANSLATION_DATA = [ + "translations/en.json", + "translations/order.json", +] + +if THP: + CPPDEFINES_MOD += ['USE_THP'] + SOURCE_MOD += [ + 'vendor/trezor-crypto/elligator2.c', + ] + +# fonts +tools.add_font('NORMAL', FONT_NORMAL, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('BOLD', FONT_BOLD, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('DEMIBOLD', FONT_DEMIBOLD, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('MONO', FONT_MONO, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('BIG', FONT_BIG, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('NORMAL_UPPER', FONT_NORMAL_UPPER, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('BOLD_UPPER', FONT_BOLD_UPPER, CPPDEFINES_MOD, SOURCE_MOD) +tools.add_font('SUB', FONT_SUB, CPPDEFINES_MOD, SOURCE_MOD) + +env = Environment( + ENV=os.environ, + CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY}", + CPPDEFINES_IMPLICIT=[] + ) + +FEATURES_AVAILABLE = models.configure_board(TREZOR_MODEL, HW_REVISION, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL) + +FILE_SUFFIX= env.get('ENV')['SUFFIX'] + +SOURCE_FIRMWARE = [ + 'embed/kernel/header.S', + 'embed/kernel/main.c', + f'embed/kernel/startup_{FILE_SUFFIX}.S', +] + + +if TREZOR_MODEL in ('T', 'DISC1', 'DISC2'): + UI_LAYOUT = 'UI_LAYOUT_TT' + ui_layout_feature = 'model_tt' +elif TREZOR_MODEL in ('1', 'R'): + UI_LAYOUT = 'UI_LAYOUT_TR' + ui_layout_feature = 'model_tr' +elif TREZOR_MODEL in ('T3T1',): + UI_LAYOUT = 'UI_LAYOUT_MERCURY' + ui_layout_feature = 'model_mercury' +else: + raise ValueError('Unknown Trezor model') + +if 'sd_card' in FEATURES_AVAILABLE: + SDCARD = True +else: + SDCARD = False + +env.Replace( + CAT='cat', + DD='dd', + CP='cp', + SED='sed', + AS='arm-none-eabi-as', + AR='arm-none-eabi-ar', + CC='arm-none-eabi-gcc', + LINK='arm-none-eabi-gcc', + SIZE='arm-none-eabi-size', + STRIP='arm-none-eabi-strip', + OBJCOPY='arm-none-eabi-objcopy', ) + +env.Replace( + TREZOR_MODEL=TREZOR_MODEL,) + +if TREZOR_MODEL in ('1',): + LD_VARIANT = '' if EVERYTHING else '_min' +else: + LD_VARIANT = '' + +ALLPATHS = [ + '.', + 'embed/firmware', + 'embed/lib', + 'embed/models', + 'embed/trezorhal', + ] + CPPPATH_MOD + PATH_HAL + +env.Replace( + COPT=env.get('ENV').get('OPTIMIZE', '-Os'), + CCFLAGS='$COPT ' + '-g3 ' + '-nostdlib ' + '-std=gnu11 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common ' + '-fsingle-precision-constant -fdata-sections -ffunction-sections ' + '-ffreestanding ' + '-fstack-protector-all ' + + env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD, + LINKFLAGS='-T embed/kernel/memory_${TREZOR_MODEL}%s.ld -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-Map=build/kernel/kernel.map -Wl,--warn-common' % LD_VARIANT, + CPPPATH=ALLPATHS, + CPPDEFINES=[ + 'FIRMWARE', + 'TREZOR_MODEL_'+TREZOR_MODEL, + 'USE_HAL_DRIVER', + 'ARM_USER_MODE', + UI_LAYOUT, + ] + CPPDEFINES_MOD + CPPDEFINES_HAL, + ASFLAGS=env.get('ENV')['CPU_ASFLAGS'], + ASPPFLAGS='$CFLAGS $CCFLAGS', + ) + +env.Replace( + HEADERTOOL='headertool', + PYTHON='python', + MAKEVERSIONHDR='$PYTHON vendor/micropython/py/makeversionhdr.py', + MAKEMODULEDEFS='$PYTHON vendor/micropython/py/makemoduledefs.py', + MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py', +) + + +# +# Program objects +# + +source_files = SOURCE_MOD + SOURCE_MOD_CRYPTO + SOURCE_FIRMWARE + SOURCE_HAL +obj_program = [] +obj_program.extend(env.Object(source=SOURCE_MOD)) +obj_program.extend(env.Object(source=SOURCE_MOD_CRYPTO, CCFLAGS='$CCFLAGS -ftrivial-auto-var-init=zero')) +if FEATURE_FLAGS["SECP256K1_ZKP"]: + obj_program.extend(env.Object(source=SOURCE_MOD_SECP256K1_ZKP, CCFLAGS='$CCFLAGS -Wno-unused-function')) + source_files.extend(SOURCE_MOD_SECP256K1_ZKP) +obj_program.extend(env.Object(source=SOURCE_FIRMWARE)) +obj_program.extend(env.Object(source=SOURCE_HAL)) + +env.Replace( + ALLSOURCES=source_files, + ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES'] + env['CPPDEFINES_IMPLICIT'] + [f"PRODUCTION={int(PRODUCTION)}", f"BOOTLOADER_QA={int(BOOTLOADER_QA)}", f"PYOPT={PYOPT}", f"BITCOIN_ONLY={BITCOIN_ONLY}"])) + + +cmake_gen = env.Command( + target='CMakeLists.txt', + source='', + action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS', +) + +MODEL_IDENTIFIER = models.get_model_identifier(TREZOR_MODEL) +BOOTLOADER_SUFFIX = MODEL_IDENTIFIER +if BOOTLOADER_QA: + BOOTLOADER_SUFFIX += '_qa' + +# select vendor header +if BOOTLOADER_QA or BOOTLOADER_DEVEL: + vendor = "dev_DO_NOT_SIGN_signed_dev" +elif not PRODUCTION: + vendor = "unsafe_signed_prod" +else: + if TREZOR_MODEL in ('T',): + vendor = "satoshilabs_signed_prod" + elif BITCOIN_ONLY == '1': + vendor = "trezor_btconly_signed_prod" + else: + vendor = "trezor_signed_prod" + +VENDORHEADER = f'embed/models/{MODEL_IDENTIFIER}/vendorheader/vendorheader_{vendor}.bin' + + +if TREZOR_MODEL not in ('1',): + obj_program.extend( + env.Command( + target='embed/kernel/vendorheader.o', + source=VENDORHEADER, + action='$OBJCOPY -I binary -O elf32-littlearm -B arm' + ' --rename-section .data=.vendorheader,alloc,load,readonly,contents' + ' $SOURCE $TARGET', )) + +if False: # TREZOR_MODEL not in ('DISC1', 'DISC2'): + tools.embed_binary( + obj_program, + env, + 'bootloader', + 'embed/firmware/bootloaders/bootloader.o', + f'embed/firmware/bootloaders/bootloader_{BOOTLOADER_SUFFIX}.bin', + ) + + +program_elf = env.Command( + target='kernel.elf', + source=obj_program, + action= + '$LINK -o $TARGET $CCFLAGS $CFLAGS $SOURCES $LINKFLAGS -lc_nano -lm -lgcc', +) + +if CMAKELISTS != 0: + env.Depends(program_elf, cmake_gen) + +BINARY_NAME = f"build/kernel/kernel-{models.get_model_identifier(TREZOR_MODEL)}" +if not EVERYTHING: + BINARY_NAME += "-btconly" +BINARY_NAME += "-" + tools.get_version('embed/kernel/version.h') +BINARY_NAME += "-" + tools.get_git_revision_short_hash() +BINARY_NAME += "-dirty" if tools.get_git_modified() else "" +BINARY_NAME += ".bin" + + +if TREZOR_MODEL in ('1'): + action_bin=[ + '$OBJCOPY -O binary -j .header -j .flash -j .data -j .confidential $SOURCE $TARGET', + '../legacy/bootloader/firmware_sign.py -f $TARGET', + '$CP $TARGET ' + BINARY_NAME, + ] +else: + if 'STM32F427xx' in CPPDEFINES_HAL or 'STM32F429xx' in CPPDEFINES_HAL: + action_bin=[ + '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .confidential --pad-to 0x08100000 $SOURCE ${TARGET}.p1', + '$OBJCOPY -O binary -j .flash2 $SOURCE ${TARGET}.p2', + '$CAT ${TARGET}.p1 ${TARGET}.p2 > $TARGET', + '$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''), + '$DD if=$TARGET of=${TARGET}.p1 skip=0 bs=128k count=6', + '$CP $TARGET ' + BINARY_NAME, + ] + elif 'STM32U5A9xx' in CPPDEFINES_HAL or 'STM32U585xx' in CPPDEFINES_HAL: + action_bin=[ + '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data -j .confidential $SOURCE ${TARGET}', + '$HEADERTOOL -h $TARGET ' + ('-D' if not PRODUCTION else ''), + '$CP $TARGET ' + BINARY_NAME, + ] + else: + raise Exception("Unknown MCU") + +program_bin = env.Command( + target='kernel.bin', + source=program_elf, + action=action_bin, +) diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest index 91c9f5bf2b..3ae2a8c825 100644 --- a/core/SConscript.prodtest +++ b/core/SConscript.prodtest @@ -29,6 +29,7 @@ if NEW_RENDERING: CCFLAGS_MOD = '' CPPPATH_MOD = [] CPPDEFINES_MOD = [ + 'KERNEL_MODE', 'AES_128', 'USE_INSECURE_PRNG', ] diff --git a/core/SConscript.reflash b/core/SConscript.reflash index 1567744f8f..481450e22a 100644 --- a/core/SConscript.reflash +++ b/core/SConscript.reflash @@ -61,6 +61,10 @@ elif TREZOR_MODEL in ('T3T1',): FONT_BOLD_UPPER=None FONT_SUB=None +CPPDEFINES_MOD += [ + 'KERNEL_MODE', +] + # modtrezorcrypto CPPPATH_MOD += [ 'vendor/trezor-crypto', diff --git a/core/SConscript.unix b/core/SConscript.unix index 728ebc5d26..43cf493609 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -94,6 +94,7 @@ CPPPATH_MOD += [ 'vendor/trezor-crypto', ] CPPDEFINES_MOD += [ + 'KERNEL_MODE', 'AES_128', 'AES_192', 'USE_INSECURE_PRNG', @@ -420,6 +421,7 @@ SOURCE_MICROPYTHON = [ SOURCE_UNIX = [ 'embed/trezorhal/unix/bootutils.c', 'embed/trezorhal/unix/common.c', + 'embed/trezorhal/unix/entropy.c', 'embed/trezorhal/unix/flash_otp.c', 'embed/trezorhal/unix/flash.c', 'embed/trezorhal/unix/fwutils.c', diff --git a/core/SConstruct b/core/SConstruct index d4c5aae455..4bca3b7423 100644 --- a/core/SConstruct +++ b/core/SConstruct @@ -7,6 +7,8 @@ SConscript('SConscript.boardloader', variant_dir='build/boardloader', duplicate= SConscript('SConscript.bootloader', variant_dir='build/bootloader', duplicate=False) SConscript('SConscript.bootloader_ci', variant_dir='build/bootloader_ci', duplicate=False) SConscript('SConscript.bootloader_emu', variant_dir='build/bootloader_emu', duplicate=False) +SConscript('SConscript.kernel', variant_dir='build/kernel', duplicate=False) +SConscript('SConscript.coreapp', variant_dir='build/coreapp', duplicate=False) SConscript('SConscript.firmware', variant_dir='build/firmware', duplicate=False) SConscript('SConscript.prodtest', variant_dir='build/prodtest', duplicate=False) SConscript('SConscript.reflash', variant_dir='build/reflash', duplicate=False) diff --git a/core/embed/coreapp/header.S b/core/embed/coreapp/header.S new file mode 100644 index 0000000000..3531e23955 --- /dev/null +++ b/core/embed/coreapp/header.S @@ -0,0 +1,54 @@ + .syntax unified + +#include "version.h" + + .section .header, "a" + + .type g_header, %object + .size g_header, .-g_header + +// Firmware header for both Trezor One and Trezor T. +// Trezor One must have bootloader version >= 1.8.0 (before that version the hdrlen used to be reset vector) + +g_header: + .byte 'T','R','Z','F' // magic + .word g_header_end - g_header // hdrlen +#ifdef TREZOR_MODEL_T + .word 0 // expiry +#else + .word 1 // expiry +#endif + .word _codelen // codelen + .byte VERSION_MAJOR // vmajor + .byte VERSION_MINOR // vminor + .byte VERSION_PATCH // vpatch + .byte VERSION_BUILD // vbuild + .byte FIX_VERSION_MAJOR // fix_vmajor + .byte FIX_VERSION_MINOR // fix_vminor + .byte FIX_VERSION_PATCH // fix_vpatch + .byte FIX_VERSION_BUILD // fix_vbuild + .word HW_MODEL // type of the designated hardware + .byte HW_REVISION // revision of the designated hardware + .byte VERSION_MONOTONIC // monotonic version of the binary + . = . + 2 // reserved + . = . + 512 // hash1 ... hash16 + +#if !defined TREZOR_MODEL_1 +// trezor-core header style + . = . + 415 // reserved + .byte 0 // sigmask + . = . + 64 // sig +#else +// model 1 compatibility header + . = . + 64 // sig1 + . = . + 64 // sig2 + . = . + 64 // sig3 + .byte 0 // sigindex1 + .byte 0 // sigindex2 + .byte 0 // sigindex3 + . = . + 220 // reserved + . = . + 65 // reserved +#endif + +g_header_end: + diff --git a/core/embed/coreapp/main.c b/core/embed/coreapp/main.c new file mode 100644 index 0000000000..8ea6f269bb --- /dev/null +++ b/core/embed/coreapp/main.c @@ -0,0 +1,105 @@ +/* + * 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 STM32_HAL_H + +#include +#include +#include + +#include "py/builtin.h" +#include "py/compile.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/nlr.h" +#include "py/repl.h" +#include "py/runtime.h" +#include "py/stackctrl.h" +#include "shared/runtime/pyexec.h" + +#include "ports/stm32/gccollect.h" +#include "ports/stm32/pendsv.h" + +#include "error_handling.h" +#include "rust_ui_common.h" +#include "secbool.h" + +#ifdef USE_SECP256K1_ZKP +#include "zkp_context.h" +#endif + +int main(void) { + screen_boot_stage_2(); + +#ifdef USE_SECP256K1_ZKP + ensure(sectrue * (zkp_context_init() == 0), NULL); +#endif + + printf("CORE: Preparing stack\n"); + // Stack limit should be less than real stack size, so we have a chance + // to recover from limit hit. + mp_stack_set_top(&_estack); + mp_stack_set_limit((char *)&_estack - (char *)&_sstack - 1024); + +#if MICROPY_ENABLE_PYSTACK + static mp_obj_t pystack[1024]; + mp_pystack_init(pystack, &pystack[MP_ARRAY_SIZE(pystack)]); +#endif + + // GC init + printf("CORE: Starting GC\n"); + gc_init(&_heap_start, &_heap_end); + + // Interpreter init + printf("CORE: Starting interpreter\n"); + mp_init(); + mp_obj_list_init(mp_sys_argv, 0); + mp_obj_list_init(mp_sys_path, 0); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); + + // Execute the main script + printf("CORE: Executing main script\n"); + pyexec_frozen_module("main.py"); + + // Clean up + printf("CORE: Main script finished, cleaning up\n"); + mp_deinit(); + + // Python code shouldn't ever exit, avoid black screen if it does + error_shutdown("(PE)"); + + return 0; +} + +// MicroPython default exception handler + +void __attribute__((noreturn)) nlr_jump_fail(void *val) { + error_shutdown("(UE)"); +} + +// MicroPython builtin stubs + +mp_import_stat_t mp_import_stat(const char *path) { + return MP_IMPORT_STAT_NO_EXIST; +} + +mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) { + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); diff --git a/core/embed/coreapp/memory_DISC1.ld b/core/embed/coreapp/memory_DISC1.ld new file mode 120000 index 0000000000..3f68ec99f6 --- /dev/null +++ b/core/embed/coreapp/memory_DISC1.ld @@ -0,0 +1 @@ +memory_T.ld \ No newline at end of file diff --git a/core/embed/coreapp/memory_DISC2.ld b/core/embed/coreapp/memory_DISC2.ld new file mode 100644 index 0000000000..ae6d127292 --- /dev/null +++ b/core/embed/coreapp/memory_DISC2.ld @@ -0,0 +1,130 @@ +/* TREZORv2 firmware linker script */ + +ENTRY(reset_handler) + +MEMORY { + FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K + SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - 0x100 + BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100 + SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K + SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K + SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K + SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 0 + SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K +} + +main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ +_sstack = ORIGIN(SRAM2); +_estack = main_stack_base; + +/* used by the startup code to populate variables used by the C code */ +data_lma = LOADADDR(.data); +data_vma = ADDR(.data); +data_size = SIZEOF(.data); + +/* used by the startup code to populate variables used by the C code */ +confidential_lma = LOADADDR(.confidential); +confidential_vma = ADDR(.confidential); +confidential_size = SIZEOF(.confidential); + +/* used by the startup code to wipe memory */ +sram1_start = ORIGIN(SRAM1); +sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1); +sram2_start = ORIGIN(SRAM2); +sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2); +sram3_start = ORIGIN(SRAM3); +sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3); +sram4_start = ORIGIN(SRAM4); +sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4); +sram5_start = ORIGIN(SRAM5); +sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5); +sram6_start = ORIGIN(SRAM6); +sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6); + +/* reserve 256 bytes for bootloader arguments */ +boot_args_start = ORIGIN(BOOT_ARGS); +boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS); + +_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential); +_flash_start = ORIGIN(FLASH); +_flash_end = ORIGIN(FLASH) + LENGTH(FLASH); +_heap_start = ADDR(.heap); +_heap_end = ADDR(.heap) + SIZEOF(.heap); + +SECTIONS { + .vendorheader : ALIGN(4) { + KEEP(*(.vendorheader)) + } >FLASH AT>FLASH + + .header : ALIGN(4) { + KEEP(*(.header)); + } >FLASH AT>FLASH + + .flash : ALIGN(1024) { + KEEP(*(.vector_table)); + . = ALIGN(4); + *(.text*); + . = ALIGN(4); + *(.rodata*); + . = ALIGN(4); + KEEP(*(.bootloader)); + *(.bootloader*); + . = ALIGN(512); + } >FLASH AT>FLASH + + .data : ALIGN(4) { + *(.data*); + . = ALIGN(512); + } >SRAM1 AT>FLASH + + /DISCARD/ : { + *(.ARM.exidx*); + } + + .bss : ALIGN(4) { + *(.bss*); + . = ALIGN(4); + } >SRAM1 + + .data_ccm : ALIGN(4) { + *(.no_dma_buffers*); + . = ALIGN(4); + *(.buf*); + . = ALIGN(4); + } >SRAM1 + + .heap : ALIGN(4) { + . = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */ + . = ABSOLUTE(sram1_end); /* this explicitly sets the end of the heap */ + } >SRAM1 + + .stack : ALIGN(8) { + . = 16K; /* Overflow causes UsageFault */ + } >SRAM2 + + .confidential : ALIGN(512) { + *(.confidential*); + . = ALIGN(512); + } >SRAM2 AT>FLASH + + .fb1 : ALIGN(4) { + __fb_start = .; + *(.fb1*); + *(.gfxmmu_table*); + *(.framebuffer_select*); + . = ALIGN(4); + } >SRAM3 + + .fb2 : ALIGN(4) { + *(.fb2*); + __fb_end = .; + . = ALIGN(4); + } >SRAM5 + + .boot_args : ALIGN(8) { + *(.boot_command*); + . = ALIGN(8); + *(.boot_args*); + . = ALIGN(8); + } >BOOT_ARGS +} diff --git a/core/embed/coreapp/memory_R.ld b/core/embed/coreapp/memory_R.ld new file mode 120000 index 0000000000..3f68ec99f6 --- /dev/null +++ b/core/embed/coreapp/memory_R.ld @@ -0,0 +1 @@ +memory_T.ld \ No newline at end of file diff --git a/core/embed/coreapp/memory_T.ld b/core/embed/coreapp/memory_T.ld new file mode 100644 index 0000000000..9affc00a90 --- /dev/null +++ b/core/embed/coreapp/memory_T.ld @@ -0,0 +1,109 @@ +/* TREZORv2 firmware linker script */ + +ENTRY(reset_handler) + +MEMORY { + FLASH (rx) : ORIGIN = 0x08040000, LENGTH = 768K + FLASH2 (r) : ORIGIN = 0x08120000, LENGTH = 896K + CCMRAM (wal) : ORIGIN = 0x10000000, LENGTH = 64K - 0x100 + BOOT_ARGS (wal) : ORIGIN = 0x1000FF00, LENGTH = 0x100 + SRAM (wal) : ORIGIN = 0x20000000, LENGTH = 192K +} + +main_stack_base = ORIGIN(SRAM) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ +_sstack = ORIGIN(SRAM); +_estack = main_stack_base; + +/* used by the startup code to populate variables used by the C code */ +data_lma = LOADADDR(.data); +data_vma = ADDR(.data); +data_size = SIZEOF(.data); + +/* used by the startup code to wipe memory */ +ccmram_start = ORIGIN(CCMRAM); +ccmram_end = ORIGIN(CCMRAM) + LENGTH(CCMRAM); + +/* reserve 256 bytes for bootloader arguments */ +boot_args_start = ORIGIN(BOOT_ARGS); +boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS); + +/* used by the startup code to wipe memory */ +sram_start = ORIGIN(SRAM); +sram_end = ORIGIN(SRAM) + LENGTH(SRAM); +_ram_start = sram_start; +_ram_end = sram_end; + +_codelen = LENGTH(FLASH) - SIZEOF(.vendorheader) - SIZEOF(.header) + SIZEOF(.flash2); +_flash_start = ORIGIN(FLASH); +_flash_end = ORIGIN(FLASH) + LENGTH(FLASH); +_heap_start = ADDR(.heap); +_heap_end = ADDR(.heap) + SIZEOF(.heap); + +SECTIONS { + .vendorheader : ALIGN(4) { + KEEP(*(.vendorheader)) + } >FLASH AT>FLASH + + .header : ALIGN(4) { + KEEP(*(.header)); + } >FLASH AT>FLASH + + .flash2 : ALIGN(512) { + build/firmware/frozen_mpy.o(.rodata*); + build/firmware/vendor/secp256k1-zkp/src/secp256k1.o(.rodata*); + build/firmware/vendor/secp256k1-zkp/src/precomputed_ecmult.o(.rodata*); + build/firmware/vendor/secp256k1-zkp/src/precomputed_ecmult_gen.o(.rodata*); + build/firmware/vendor/trezor-crypto/aes/aestab.o(.rodata*); + . = ALIGN(4); + */libtrezor_lib.a:(.text*); + . = ALIGN(4); + */libtrezor_lib.a:(.rodata*); + . = ALIGN(512); + } >FLASH2 AT>FLASH2 + + .flash : ALIGN(512) { + KEEP(*(.vector_table)); + . = ALIGN(4); + *(.text*); + . = ALIGN(4); + *(.rodata*); + . = ALIGN(4); + KEEP(*(.bootloader)); + *(.bootloader*); + . = ALIGN(512); + } >FLASH AT>FLASH + + .stack : ALIGN(8) { + . = 16K; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */ + } >SRAM + + .data : ALIGN(4) { + *(.data*); + . = ALIGN(512); + } >SRAM AT>FLASH + + .bss : ALIGN(4) { + *(.bss*); + . = ALIGN(4); + } >SRAM + + .buf : ALIGN(4) { + *(.buf*); + . = ALIGN(4); + } >SRAM + + .heap : ALIGN(4) { + . = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */ + . = ABSOLUTE(sram_end); /* this explicitly sets the end of the heap */ + } >SRAM + + .data_ccm : ALIGN(4) { + *(.no_dma_buffers*); + . = ALIGN(4); + } >CCMRAM + + .boot_args : ALIGN(8) { + *(.boot_args*); + . = ALIGN(8); + } >BOOT_ARGS +} diff --git a/core/embed/coreapp/memory_T3B1.ld b/core/embed/coreapp/memory_T3B1.ld new file mode 120000 index 0000000000..b5bfd3715e --- /dev/null +++ b/core/embed/coreapp/memory_T3B1.ld @@ -0,0 +1 @@ +memory_T3T1.ld \ No newline at end of file diff --git a/core/embed/coreapp/memory_T3T1.ld b/core/embed/coreapp/memory_T3T1.ld new file mode 100644 index 0000000000..3fc9d3fae2 --- /dev/null +++ b/core/embed/coreapp/memory_T3T1.ld @@ -0,0 +1,115 @@ +/* TREZORv2 firmware linker script */ + +ENTRY(reset_handler) + +MEMORY { + FLASH (rx) : ORIGIN = 0x0C050000 + 0x28000, LENGTH = 1664K - 0x28000 + SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 192K - 16K + BOOT_ARGS (wal) : ORIGIN = 0x3002FF00, LENGTH = 0x100 + SRAM2 (wal) : ORIGIN = 0x30030000 + 8K, LENGTH = 64K - 8K + SRAM3 (wal) : ORIGIN = 0x30040000 + 0x38400, LENGTH = 512K - 0x38400 + SRAM5 (wal) : ORIGIN = 0x30080000, LENGTH = 0K /* SRAM5 is not available */ + SRAM6 (wal) : ORIGIN = 0x30080000, LENGTH = 0K /* SRAM6 is not available */ + SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K +} + +main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ +_sstack = ORIGIN(SRAM2); +_estack = main_stack_base; + +/* used by the startup code to populate variables used by the C code */ +data_lma = LOADADDR(.data); +data_vma = ADDR(.data); +data_size = SIZEOF(.data); + +bss_start = ADDR(.bss); +bss_end = ADDR(.bss) + SIZEOF(.bss); + +/* used by the startup code to populate variables used by the C code */ +confidential_lma = LOADADDR(.confidential); +confidential_vma = ADDR(.confidential); +confidential_size = SIZEOF(.confidential); + +/* used by the startup code to wipe memory */ +sram1_start = ORIGIN(SRAM1); +sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1); +sram2_start = ORIGIN(SRAM2); +sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2); +sram3_start = ORIGIN(SRAM3); +sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3); +sram4_start = ORIGIN(SRAM4); +sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4); +sram5_start = ORIGIN(SRAM5); +sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5); +sram6_start = ORIGIN(SRAM6); +sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6); + +/* reserve 256 bytes for bootloader arguments */ +boot_args_start = ORIGIN(BOOT_ARGS); +boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS); + +_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential); +_flash_start = ORIGIN(FLASH); +_flash_end = ORIGIN(FLASH) + LENGTH(FLASH); +_heap_start = ADDR(.heap); +_heap_end = ADDR(.heap) + SIZEOF(.heap); + +SECTIONS { + .vendorheader : ALIGN(4) { + KEEP(*(.vendorheader)) + } >FLASH AT>FLASH + + .header : ALIGN(4) { + KEEP(*(.header)); + } >FLASH AT>FLASH + + .flash : ALIGN(512) { + KEEP(*(.vector_table)); + . = ALIGN(4); + *(.text*); + . = ALIGN(4); + *(.rodata*); + . = ALIGN(512); + } >FLASH AT>FLASH + + .data : ALIGN(4) { + *(.data*); + . = ALIGN(512); + } >SRAM1 AT>FLASH + + /DISCARD/ : { + *(.ARM.exidx*); + } + + .bss : ALIGN(4) { + *(.no_dma_buffers*); + *(.bss*); + . = ALIGN(4); + } >SRAM1 + + .stack : ALIGN(8) { + . = 32K; /* Overflow causes UsageFault */ + } >SRAM2 + + .confidential : ALIGN(512) { + *(.confidential*); + . = ALIGN(512); + } >SRAM2 AT>FLASH + + .buf : ALIGN(4) { + *(.buf*); + . = ALIGN(4); + } >SRAM3 + + .heap : ALIGN(4) { + . = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */ + . = ABSOLUTE(sram3_end); /* this explicitly sets the end of the heap */ + } >SRAM3 + + .boot_args : ALIGN(8) { + *(.boot_command*); + . = ALIGN(8); + *(.boot_args*); + . = ALIGN(8); + } >BOOT_ARGS +} diff --git a/core/embed/coreapp/mpconfigport.h b/core/embed/coreapp/mpconfigport.h new file mode 100644 index 0000000000..0e9e990b1b --- /dev/null +++ b/core/embed/coreapp/mpconfigport.h @@ -0,0 +1,224 @@ +// clang-format off + +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2017 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Options to control how MicroPython is built for this port, +// overriding defaults in py/mpconfig.h. + +#pragma once +#ifndef __INCLUDED_MPCONFIGPORT_H +#define __INCLUDED_MPCONFIGPORT_H + +// frozen modules +#define MICROPY_MODULE_FROZEN_MPY (1) +#define MICROPY_QSTR_EXTRA_POOL (mp_qstr_frozen_const_pool) + +// memory allocation policies +#define MICROPY_ALLOC_PATH_MAX (128) +#define MICROPY_ENABLE_PYSTACK (1) +#define MICROPY_LOADED_MODULES_DICT_SIZE (160) + +// emitters +#define MICROPY_PERSISTENT_CODE_LOAD (0) +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_INLINE_THUMB (0) + +// compiler configuration +#define MICROPY_ENABLE_COMPILER (0) +#define MICROPY_COMP_MODULE_CONST (1) +#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) +#define MICROPY_COMP_RETURN_IF_EXPR (1) + +// optimisations +#define MICROPY_OPT_COMPUTED_GOTO (1) +#define MICROPY_OPT_MPZ_BITWISE (1) +#define MICROPY_OPT_MATH_FACTORIAL (0) +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) +#define MICROPY_OPT_MAP_LOOKUP_CACHE (1) + +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES) + +// Python internal features +#define MICROPY_READER_VFS (0) +#define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_STACK_CHECK (1) +#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) +#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0) +#define MICROPY_KBD_EXCEPTION (1) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_REPL_EMACS_KEYS (1) +#define MICROPY_REPL_AUTO_INDENT (1) +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) +#define MICROPY_ENABLE_SOURCE_LINE (1) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#define MICROPY_STREAMS_NON_BLOCK (1) +#define MICROPY_MODULE_WEAK_LINKS (1) +#define MICROPY_CAN_OVERRIDE_BUILTINS (0) +#define MICROPY_USE_INTERNAL_ERRNO (1) +#define MICROPY_ENABLE_SCHEDULER (0) +#define MICROPY_SCHEDULER_DEPTH (0) +#define MICROPY_VFS (0) + +// control over Python builtins +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_DESCRIPTORS (0) +#define MICROPY_PY_DELATTR_SETATTR (0) +#define MICROPY_PY_BUILTINS_STR_UNICODE (1) +#define MICROPY_PY_BUILTINS_STR_CENTER (1) +#define MICROPY_PY_BUILTINS_STR_PARTITION (1) +#define MICROPY_PY_BUILTINS_STR_SPLITLINES (0) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) +#define MICROPY_PY_BUILTINS_FROZENSET (0) +#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) +#define MICROPY_PY_BUILTINS_SLICE_INDICES (0) +#define MICROPY_PY_BUILTINS_ROUND_INT (0) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) +#define MICROPY_PY_ALL_SPECIAL_METHODS (0) +#define MICROPY_PY_BUILTINS_COMPILE (MICROPY_ENABLE_COMPILER) +#define MICROPY_PY_BUILTINS_EXECFILE (MICROPY_ENABLE_COMPILER) +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) +#define MICROPY_PY_BUILTINS_INPUT (0) +#define MICROPY_PY_BUILTINS_POW3 (0) +#define MICROPY_PY_BUILTINS_HELP (0) +#define MICROPY_PY_BUILTINS_HELP_TEXT stm32_help_text +#define MICROPY_PY_BUILTINS_HELP_MODULES (0) +#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) +#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) +#define MICROPY_PY_COLLECTIONS (0) +#define MICROPY_PY_COLLECTIONS_DEQUE (0) +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0) +#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (0) +#define MICROPY_PY_MATH_ISCLOSE (0) +#define MICROPY_PY_MATH_FACTORIAL (0) +#define MICROPY_PY_CMATH (0) +#define MICROPY_PY_IO (0) +#define MICROPY_PY_IO_IOBASE (0) +#define MICROPY_PY_IO_FILEIO (MICROPY_VFS_FAT) // because mp_type_fileio/textio point to fatfs impl +#define MICROPY_PY_SYS_MAXSIZE (0) +#define MICROPY_PY_SYS_EXIT (0) +#define MICROPY_PY_SYS_STDFILES (0) +#define MICROPY_PY_SYS_STDIO_BUFFER (0) +#define MICROPY_PY_SYS_PLATFORM "trezor" +#define MICROPY_PY_UERRNO (0) +#define MICROPY_PY_THREAD (0) +#define MICROPY_PY_FSTRINGS (1) + +// extended modules +#define MICROPY_PY_UCTYPES (1) +#define MICROPY_PY_UZLIB (0) +#define MICROPY_PY_UJSON (0) +#define MICROPY_PY_UOS (0) +#define MICROPY_PY_URE (0) +#define MICROPY_PY_URE_SUB (0) +#define MICROPY_PY_UHEAPQ (0) +#define MICROPY_PY_UHASHLIB (0) +#define MICROPY_PY_UHASHLIB_MD5 (0) +#define MICROPY_PY_UHASHLIB_SHA1 (0) +#define MICROPY_PY_UCRYPTOLIB (0) +#define MICROPY_PY_UBINASCII (1) +#define MICROPY_PY_UBINASCII_CRC32 (0) +#define MICROPY_PY_URANDOM (0) +#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) +#define MICROPY_PY_USELECT (0) +#define MICROPY_PY_UTIME (1) +#define MICROPY_PY_UTIMEQ (1) +#define MICROPY_PY_UTIME_MP_HAL (1) +#define MICROPY_PY_OS_DUPTERM (0) +#define MICROPY_PY_LWIP_SOCK_RAW (0) +#define MICROPY_PY_MACHINE (0) +#define MICROPY_PY_UWEBSOCKET (0) +#define MICROPY_PY_WEBREPL (0) +#define MICROPY_PY_FRAMEBUF (0) +#define MICROPY_PY_USOCKET (0) +#define MICROPY_PY_NETWORK (0) + +#define MICROPY_PY_TREZORCONFIG (1) +#define MICROPY_PY_TREZORCRYPTO (1) +#define MICROPY_PY_TREZORIO (1) +#define MICROPY_PY_TREZORUI (1) +#define MICROPY_PY_TREZORUTILS (1) +#define MICROPY_PY_TREZORPROTO (1) +#define MICROPY_PY_TREZORTRANSLATE (1) +#define MICROPY_PY_TREZORUI2 (1) + +#ifdef SYSTEM_VIEW +#define MP_PLAT_PRINT_STRN(str, len) segger_print(str, len) +// uncomment DEST_RTT and comment DEST_SYSTEMVIEW +// if you want to print to RTT instead of SystemView +// OpenOCD supports only the RTT output method +// #define SYSTEMVIEW_DEST_RTT (1) +#define SYSTEMVIEW_DEST_SYSTEMVIEW (1) +#endif + +#define MP_STATE_PORT MP_STATE_VM + +// ============= this ends common config section =================== + + +// type definitions for the specific machine + +#define BYTES_PER_WORD (4) + +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1)) + +#define MP_SSIZE_MAX (0x0fffffff) + +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size +typedef long mp_off_t; + +#include "irq.h" + +#define MICROPY_BEGIN_ATOMIC_SECTION() irq_lock() +#define MICROPY_END_ATOMIC_SECTION(state) irq_unlock(state) +#define MICROPY_EVENT_POLL_HOOK \ + do { \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ + __WFI(); \ + } while (0); + +#define MICROPY_HW_BOARD_NAME "TREZORv2" +#define MICROPY_HW_MCU_NAME "STM32F427xx" +#define MICROPY_HW_HAS_SDCARD 1 + +// There is no classical C heap in bare-metal ports, only Python +// garbage-collected heap. For completeness, emulate C heap via +// GC heap. Note that MicroPython core never uses malloc() and friends, +// so these defines are mostly to help extension module writers. +#define malloc(n) m_malloc(n) +#define free(p) m_free(p) +#define realloc(p, n) m_realloc(p, n) + +#define MICROPY_PORT_ROOT_POINTERS \ + mp_obj_t trezorconfig_ui_wait_callback; \ + +// We need to provide a declaration/definition of alloca() +#include + +#endif // __INCLUDED_MPCONFIGPORT_H diff --git a/core/embed/coreapp/mphalport.c b/core/embed/coreapp/mphalport.c new file mode 100644 index 0000000000..9509ca37d5 --- /dev/null +++ b/core/embed/coreapp/mphalport.c @@ -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 . + */ + +#include "common.h" +#include "py/mphal.h" + +#include "systick.h" +#include "usb.h" + +static int vcp_iface_num = -1; + +int mp_hal_stdin_rx_chr(void) { + ensure(sectrue * (vcp_iface_num >= 0), "vcp stdio is not configured"); + uint8_t c = 0; + int r = usb_vcp_read_blocking(vcp_iface_num, &c, 1, -1); + (void)r; + return c; +} + +void mp_hal_stdout_tx_strn(const char *str, size_t len) { + if (vcp_iface_num >= 0) { + // The write timeout is set to 0, because otherwise when the VCP receive + // buffer on the host gets full, the timeout will block device operation. + int r = usb_vcp_write_blocking(vcp_iface_num, (const uint8_t *)str, len, 0); + (void)r; + } +} + +void mp_hal_set_vcp_iface(int iface_num) { vcp_iface_num = iface_num; } + +// Dummy implementation required by ports/stm32/gccollect.c. +// The normal version requires MICROPY_ENABLE_SCHEDULER which we don't use. +void soft_timer_gc_mark_all(void) {} + +void mp_hal_delay_ms(mp_uint_t Delay) { systick_delay_ms(Delay); } + +void mp_hal_delay_us(mp_uint_t usec) { systick_delay_us(usec); } + +mp_uint_t mp_hal_ticks_ms(void) { return systick_ms(); } + +mp_uint_t mp_hal_ticks_us(void) { return systick_ms() * 1000; } diff --git a/core/embed/coreapp/mphalport.h b/core/embed/coreapp/mphalport.h new file mode 100644 index 0000000000..8954eec631 --- /dev/null +++ b/core/embed/coreapp/mphalport.h @@ -0,0 +1,24 @@ +/* + * 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 "shared/runtime/interrupt_char.h" + +static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; } + +void mp_hal_set_vcp_iface(int iface_num); diff --git a/core/embed/coreapp/nlrthumb.c b/core/embed/coreapp/nlrthumb.c new file mode 100644 index 0000000000..8fdaba88b2 --- /dev/null +++ b/core/embed/coreapp/nlrthumb.c @@ -0,0 +1,166 @@ +// clang-format off + +/* + * 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 . + */ + +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma GCC optimize("no-stack-protector") // applies to all functions in this file + +#include "py/mpstate.h" +#include "py/nlr.h" + +#if (!defined(MICROPY_NLR_SETJMP) || !MICROPY_NLR_SETJMP) && (defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) + +#undef nlr_push + +// We only need the functions here if we are on arm/thumb, and we are not +// using setjmp/longjmp. +// +// For reference, arm/thumb callee save regs are: +// r4-r11, r13=sp + +__attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { + + __asm volatile ( + "str r4, [r0, #12] \n" // store r4 into nlr_buf + "str r5, [r0, #16] \n" // store r5 into nlr_buf + "str r6, [r0, #20] \n" // store r6 into nlr_buf + "str r7, [r0, #24] \n" // store r7 into nlr_buf + +#if defined(__ARM_ARCH_6M__) + "mov r1, r8 \n" + "str r1, [r0, #28] \n" // store r8 into nlr_buf + "mov r1, r9 \n" + "str r1, [r0, #32] \n" // store r9 into nlr_buf + "mov r1, r10 \n" + "str r1, [r0, #36] \n" // store r10 into nlr_buf + "mov r1, r11 \n" + "str r1, [r0, #40] \n" // store r11 into nlr_buf + "mov r1, r13 \n" + "str r1, [r0, #44] \n" // store r13=sp into nlr_buf + "mov r1, lr \n" + "str r1, [r0, #8] \n" // store lr into nlr_buf +#else + "str r8, [r0, #28] \n" // store r8 into nlr_buf + "str r9, [r0, #32] \n" // store r9 into nlr_buf + "str r10, [r0, #36] \n" // store r10 into nlr_buf + "str r11, [r0, #40] \n" // store r11 into nlr_buf + "str r13, [r0, #44] \n" // store r13=sp into nlr_buf + "str lr, [r0, #8] \n" // store lr into nlr_buf +#endif + +#if defined(__ARM_ARCH_6M__) + "ldr r1, nlr_push_tail_var \n" + "bx r1 \n" // do the rest in C + ".align 2 \n" + "nlr_push_tail_var: .word nlr_push_tail \n" +#else + "b nlr_push_tail \n" // do the rest in C +#endif + ); + + return 0; // needed to silence compiler warning +} + +__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr) { + nlr_buf_t **top = &MP_STATE_THREAD(nlr_top); + nlr->prev = *top; + *top = nlr; + return 0; // normal return +} + +void nlr_pop(void) { + nlr_buf_t **top = &MP_STATE_THREAD(nlr_top); + *top = (*top)->prev; +} + +NORETURN __attribute__((naked)) void nlr_jump(void *val) { + nlr_buf_t **top_ptr = &MP_STATE_THREAD(nlr_top); + nlr_buf_t *top = *top_ptr; + if (top == NULL) { + nlr_jump_fail(val); + } + + top->ret_val = val; + *top_ptr = top->prev; + + __asm volatile ( + "mov r0, %0 \n" // r0 points to nlr_buf + "ldr r4, [r0, #12] \n" // load r4 from nlr_buf + "ldr r5, [r0, #16] \n" // load r5 from nlr_buf + "ldr r6, [r0, #20] \n" // load r6 from nlr_buf + "ldr r7, [r0, #24] \n" // load r7 from nlr_buf + +#if defined(__ARM_ARCH_6M__) + "ldr r1, [r0, #28] \n" // load r8 from nlr_buf + "mov r8, r1 \n" + "ldr r1, [r0, #32] \n" // load r9 from nlr_buf + "mov r9, r1 \n" + "ldr r1, [r0, #36] \n" // load r10 from nlr_buf + "mov r10, r1 \n" + "ldr r1, [r0, #40] \n" // load r11 from nlr_buf + "mov r11, r1 \n" + "ldr r1, [r0, #44] \n" // load r13=sp from nlr_buf + "mov r13, r1 \n" + "ldr r1, [r0, #8] \n" // load lr from nlr_buf + "mov lr, r1 \n" +#else + "ldr r8, [r0, #28] \n" // load r8 from nlr_buf + "ldr r9, [r0, #32] \n" // load r9 from nlr_buf + "ldr r10, [r0, #36] \n" // load r10 from nlr_buf + "ldr r11, [r0, #40] \n" // load r11 from nlr_buf + "ldr r13, [r0, #44] \n" // load r13=sp from nlr_buf + "ldr lr, [r0, #8] \n" // load lr from nlr_buf +#endif + "movs r0, #1 \n" // return 1, non-local return + "bx lr \n" // return + : // output operands + : "r"(top) // input operands + : // clobbered registers + ); + + for (;;); // needed to silence compiler warning +} + +#endif // (!defined(MICROPY_NLR_SETJMP) || !MICROPY_NLR_SETJMP) && (defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) diff --git a/core/embed/coreapp/startup_stm32f4.S b/core/embed/coreapp/startup_stm32f4.S new file mode 100644 index 0000000000..f1a8a6784e --- /dev/null +++ b/core/embed/coreapp/startup_stm32f4.S @@ -0,0 +1,42 @@ + .syntax unified + + .text + + .global reset_handler + .type reset_handler, STT_FUNC +reset_handler: + + // setup environment for subsequent stage of code + ldr r0, =ccmram_start // r0 - point to beginning of CCMRAM + ldr r1, =ccmram_end // r1 - point to byte after the end of CCMRAM + ldr r2, =0 // r2 - the word-sized value to be written + bl memset_reg + + ldr r0, =boot_args_start // r0 - point to beginning of BOOT_ARGS + ldr r1, =boot_args_end // r1 - point to byte after the end of BOOT_ARGS + ldr r2, =0 // r2 - the word-sized value to be written + bl memset_reg + + ldr r0, =sram_start // r0 - point to beginning of SRAM + ldr r1, =sram_end // r1 - point to byte after the end of SRAM + ldr r2, =0 // r2 - the word-sized value to be written + bl memset_reg + + // copy data in from flash + ldr r0, =data_vma // dst addr + ldr r1, =data_lma // src addr + ldr r2, =data_size // size in bytes + bl memcpy + + // setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value + bl rng_get + ldr r1, = __stack_chk_guard + str r0, [r1] + + // enter the application code + bl main + + b secure_shutdown + + + .end diff --git a/core/embed/coreapp/startup_stm32u5.S b/core/embed/coreapp/startup_stm32u5.S new file mode 100644 index 0000000000..6d94c656d7 --- /dev/null +++ b/core/embed/coreapp/startup_stm32u5.S @@ -0,0 +1,58 @@ + .syntax unified + + .text + + .global reset_handler + .type reset_handler, STT_FUNC +reset_handler: + + // set the stack protection + ldr r0, =_sstack + add r0, r0, #128 // safety margin for the exception frame + msr PSPLIM, r0 + + ldr r0, =bss_start + ldr r1, =bss_end + ldr r2, =0 + bl memset_reg + + // copy data in from flash + ldr r0, =data_vma // dst addr + ldr r1, =data_lma // src addr + ldr r2, =data_size // size in bytes + bl memcpy + + // copy confidential data in from flash + ldr r0, =confidential_vma // dst addr + ldr r1, =confidential_lma // src addr + ldr r2, =confidential_size // size in bytes + bl memcpy + + // setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value + bl rng_get + ldr r1, = __stack_chk_guard + str r0, [r1] + + // enter the application code + bl main + + b secure_shutdown + + +memset_reg: + // call with the following (note that the arguments are not validated prior to use): + // r0 - address of first word to write (inclusive) + // r1 - address of first word following the address in r0 to NOT write (exclusive) + // r2 - word value to be written + // both addresses in r0 and r1 needs to be divisible by 4! + cmp r0, r1 + beq .L_loop_end + .L_loop_begin: + str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed + cmp r0, r1 + bne .L_loop_begin + .L_loop_end: + bx lr + + + .end diff --git a/core/embed/coreapp/version.h b/core/embed/coreapp/version.h new file mode 100644 index 0000000000..b1b21300ce --- /dev/null +++ b/core/embed/coreapp/version.h @@ -0,0 +1,11 @@ +#define VERSION_MAJOR 2 +#define VERSION_MINOR 8 +#define VERSION_PATCH 2 +#define VERSION_BUILD 0 + +#define FIX_VERSION_MAJOR 2 +#define FIX_VERSION_MINOR 8 +#define FIX_VERSION_PATCH 0 +#define FIX_VERSION_BUILD 0 + +#define VERSION_MONOTONIC 1 diff --git a/core/embed/firmware/memory_T3T1.ld b/core/embed/firmware/memory_T3T1.ld index 35674f169d..4e3a2a88cd 100644 --- a/core/embed/firmware/memory_T3T1.ld +++ b/core/embed/firmware/memory_T3T1.ld @@ -100,7 +100,6 @@ SECTIONS { __fb_start = .; *(.fb1*); *(.fb2*); - *(.framebuffer_select*); __fb_end = .; . = ALIGN(4); } >SRAM3 diff --git a/core/embed/kernel/header.S b/core/embed/kernel/header.S new file mode 100644 index 0000000000..3531e23955 --- /dev/null +++ b/core/embed/kernel/header.S @@ -0,0 +1,54 @@ + .syntax unified + +#include "version.h" + + .section .header, "a" + + .type g_header, %object + .size g_header, .-g_header + +// Firmware header for both Trezor One and Trezor T. +// Trezor One must have bootloader version >= 1.8.0 (before that version the hdrlen used to be reset vector) + +g_header: + .byte 'T','R','Z','F' // magic + .word g_header_end - g_header // hdrlen +#ifdef TREZOR_MODEL_T + .word 0 // expiry +#else + .word 1 // expiry +#endif + .word _codelen // codelen + .byte VERSION_MAJOR // vmajor + .byte VERSION_MINOR // vminor + .byte VERSION_PATCH // vpatch + .byte VERSION_BUILD // vbuild + .byte FIX_VERSION_MAJOR // fix_vmajor + .byte FIX_VERSION_MINOR // fix_vminor + .byte FIX_VERSION_PATCH // fix_vpatch + .byte FIX_VERSION_BUILD // fix_vbuild + .word HW_MODEL // type of the designated hardware + .byte HW_REVISION // revision of the designated hardware + .byte VERSION_MONOTONIC // monotonic version of the binary + . = . + 2 // reserved + . = . + 512 // hash1 ... hash16 + +#if !defined TREZOR_MODEL_1 +// trezor-core header style + . = . + 415 // reserved + .byte 0 // sigmask + . = . + 64 // sig +#else +// model 1 compatibility header + . = . + 64 // sig1 + . = . + 64 // sig2 + . = . + 64 // sig3 + .byte 0 // sigindex1 + .byte 0 // sigindex2 + .byte 0 // sigindex3 + . = . + 220 // reserved + . = . + 65 // reserved +#endif + +g_header_end: + diff --git a/core/embed/kernel/main.c b/core/embed/kernel/main.c new file mode 100644 index 0000000000..4b3f97e3b5 --- /dev/null +++ b/core/embed/kernel/main.c @@ -0,0 +1,188 @@ +/* + * 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 STM32_HAL_H + +#include "image.h" +#include "irq.h" +#include "syscall.h" + +#include "board_capabilities.h" +#include "display.h" +#include "dma2d.h" +#include "entropy.h" +#include "fault_handlers.h" +#include "haptic.h" +#include "image.h" +#include "irq.h" +#include "memzero.h" +#include "mpu.h" +#include "optiga_commands.h" +#include "optiga_transport.h" +#include "random_delays.h" +#include "sdcard.h" +#include "secret.h" +#include "secure_aes.h" +#include "systick.h" +#include "systimer.h" +#include "tamper.h" +#include "touch.h" +#include "unit_variant.h" + +#ifdef USE_OPTIGA +#if !PYOPT +#include +#if 1 // color log +#define OPTIGA_LOG_FORMAT \ + "%" PRIu32 " \x1b[35moptiga\x1b[0m \x1b[32mDEBUG\x1b[0m %s: " +#else +#define OPTIGA_LOG_FORMAT "%" PRIu32 " optiga DEBUG %s: " +#endif +static void optiga_log_hex(const char *prefix, const uint8_t *data, + size_t data_size) { + printf(OPTIGA_LOG_FORMAT, hal_ticks_ms() * 1000, prefix); + for (size_t i = 0; i < data_size; i++) { + printf("%02x", data[i]); + } + printf("\n"); +} +#endif +#endif + +void drivers_init() { + syscall_init(); + + systick_init(); + systimer_init(); + + fault_handlers_init(); + + systick_delay_ms(10); + +#if defined TREZOR_MODEL_T + set_core_clock(CLOCK_180_MHZ); +#endif + +#ifdef STM32U5 + tamper_init(); +#endif + + rdi_init(); + +#ifdef RDI + rdi_start(); +#endif + +#ifdef SYSTEM_VIEW + enable_systemview(); +#endif + +#ifdef USE_HASH_PROCESSOR + hash_processor_init(); +#endif + +#ifdef USE_DMA2D + dma2d_init(); +#endif + + display_init(DISPLAY_RETAIN_CONTENT); + +#ifdef STM32U5 + check_oem_keys(); +#endif + + parse_boardloader_capabilities(); + + unit_variant_init(); + +#ifdef STM32U5 + secure_aes_init(); +#endif + +#ifdef USE_OPTIGA + uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0}; + secbool secret_ok = secret_optiga_get(secret); +#endif + + entropy_init(); + +#if PRODUCTION || BOOTLOADER_QA + // check_and_replace_bootloader(); +#endif + +#ifdef USE_BUTTON + button_init(); +#endif + +#ifdef USE_RGB_LED + rgb_led_init(); +#endif + +#ifdef USE_CONSUMPTION_MASK + consumption_mask_init(); +#endif + +#ifdef USE_TOUCH + touch_init(); +#endif + +#ifdef USE_SD_CARD + sdcard_init(); +#endif + +#ifdef USE_HAPTIC + haptic_init(); +#endif + +#ifdef USE_OPTIGA + +#if !PYOPT + // command log is relatively quiet so we enable it in debug builds + optiga_command_set_log_hex(optiga_log_hex); + // transport log can be spammy, uncomment if you want it: + // optiga_transport_set_log_hex(optiga_log_hex); +#endif + + optiga_init(); + if (sectrue == secret_ok) { + // If the shielded connection cannot be established, reset Optiga and + // continue without it. In this case, OID_KEY_FIDO and OID_KEY_DEV cannot be + // used, which means device and FIDO attestation will not work. + if (optiga_sec_chan_handshake(secret, sizeof(secret)) != OPTIGA_SUCCESS) { + optiga_soft_reset(); + } + } + memzero(secret, sizeof(secret)); + ensure(sectrue * (optiga_open_application() == OPTIGA_SUCCESS), + "Cannot initialize optiga."); + +#endif +} + +int main(void) { + mpu_init(); + + // Initialize hardware drivers + drivers_init(); + + // Start unprivileged application + start_unprivileged_app(); + + return 0; +} diff --git a/core/embed/kernel/memory_T3T1.ld b/core/embed/kernel/memory_T3T1.ld new file mode 100644 index 0000000000..f799bf4927 --- /dev/null +++ b/core/embed/kernel/memory_T3T1.ld @@ -0,0 +1,122 @@ +/* TREZORv2 firmware linker script */ + +ENTRY(reset_handler) + +MEMORY { + FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 160K + SRAM1 (wal) : ORIGIN = 0x3002C000, LENGTH = 16K - 0x100 + BOOT_ARGS (wal) : ORIGIN = 0x3002FF00, LENGTH = 0x100 + SRAM2 (wal) : ORIGIN = 0x30030000, LENGTH = 8K + SRAM3 (wal) : ORIGIN = 0x30040000, LENGTH = 0x38400 + SRAM5 (wal) : ORIGIN = 0x30080000, LENGTH = 0K /* SRAM5 is not available */ + SRAM6 (wal) : ORIGIN = 0x30080000, LENGTH = 0K /* SRAM6 is not available */ + SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K +} + +main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ +_sstack = ORIGIN(SRAM2); +_estack = main_stack_base; + +/* used by the startup code to populate variables used by the C code */ +data_lma = LOADADDR(.data); +data_vma = ADDR(.data); +data_size = SIZEOF(.data); + +/* used by the startup code to populate variables used by the C code */ +confidential_lma = LOADADDR(.confidential); +confidential_vma = ADDR(.confidential); +confidential_size = SIZEOF(.confidential); + +/* used by the startup code to wipe memory */ +sram1_start = ORIGIN(SRAM1); +sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1); +sram2_start = ORIGIN(SRAM2); +sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2); +sram3_start = ORIGIN(SRAM3); +sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3); +sram4_start = ORIGIN(SRAM4); +sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4); +sram5_start = ORIGIN(SRAM5); +sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5); +sram6_start = ORIGIN(SRAM6); +sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6); + +/* reserve 256 bytes for bootloader arguments */ +boot_args_start = ORIGIN(BOOT_ARGS); +boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS); + +_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential); +_flash_start = ORIGIN(FLASH); +_flash_end = ORIGIN(FLASH) + LENGTH(FLASH); +_heap_start = ADDR(.heap); +_heap_end = ADDR(.heap) + SIZEOF(.heap); + +SECTIONS { + .vendorheader : ALIGN(4) { + KEEP(*(.vendorheader)) + } >FLASH AT>FLASH + + .header : ALIGN(4) { + KEEP(*(.header)); + } >FLASH AT>FLASH + + .flash : ALIGN(512) { + KEEP(*(.vector_table)); + . = ALIGN(4); + *(.text*); + . = ALIGN(4); + *(.rodata*); + . = ALIGN(4); + KEEP(*(.bootloader)); + *(.bootloader*); + . = ALIGN(512); + } >FLASH AT>FLASH + + .data : ALIGN(4) { + *(.data*); + . = ALIGN(512); + } >SRAM1 AT>FLASH + + /DISCARD/ : { + *(.ARM.exidx*); + } + + .bss : ALIGN(4) { + *(.no_dma_buffers*); + *(.bss*); + . = ALIGN(4); + } >SRAM1 + + .stack : ALIGN(8) { + . = 4K; /* Overflow causes UsageFault */ + } >SRAM2 + + .confidential : ALIGN(512) { + *(.confidential*); + . = ALIGN(512); + } >SRAM2 AT>FLASH + + .fb : ALIGN(4) { + __fb_start = .; + *(.fb1*); + *(.fb2*); + *(.framebuffer_select*); + __fb_end = .; + . = ALIGN(4); + } >SRAM3 + + .buf : ALIGN(4) { + *(.buf*); + . = ALIGN(4); + } >SRAM3 + + .heap : ALIGN(4) { + } >SRAM3 + + .boot_args : ALIGN(8) { + *(.boot_command*); + . = ALIGN(8); + *(.boot_args*); + . = ALIGN(8); + } >BOOT_ARGS +} diff --git a/core/embed/kernel/startup_stm32u5.S b/core/embed/kernel/startup_stm32u5.S new file mode 100644 index 0000000000..db9a204c31 --- /dev/null +++ b/core/embed/kernel/startup_stm32u5.S @@ -0,0 +1,72 @@ + .syntax unified + + .text + + .global reset_handler + .type reset_handler, STT_FUNC +reset_handler: + // set the stack protection + ldr r0, =_sstack + add r0, r0, #128 // safety margin for the exception frame + msr MSPLIM, r0 + + // setup environment for subsequent stage of code + ldr r2, =0 // r2 - the word-sized value to be written + + ldr r0, =sram1_start // r0 - point to beginning of SRAM + ldr r1, =sram1_end // r1 - point to byte after the end of SRAM + bl memset_reg + + ldr r0, =sram2_start // r0 - point to beginning of SRAM + ldr r1, =sram2_end // r1 - point to byte after the end of SRAM + bl memset_reg + + ldr r0, =sram4_start // r0 - point to beginning of SRAM + ldr r1, =sram4_end // r1 - point to byte after the end of SRAM + bl memset_reg + + ldr r0, =sram6_start // r0 - point to beginning of SRAM + ldr r1, =sram6_end // r1 - point to byte after the end of SRAM + bl memset_reg + + ldr r0, =boot_args_start // r0 - point to beginning of boot args + ldr r1, =boot_args_end // r1 - point to byte after the end of boot args + bl memset_reg + + ldr r0, =sram3_start // r0 - point to beginning of SRAM + ldr r1, =__fb_start // r1 - point to beginning of framebuffer + bl memset_reg + + ldr r0, =__fb_end // r0 - point to end of framebuffer + ldr r1, =sram5_end // r1 - point to byte after the end of SRAM + bl memset_reg + + // copy data in from flash + ldr r0, =data_vma // dst addr + ldr r1, =data_lma // src addr + ldr r2, =data_size // size in bytes + bl memcpy + + // copy confidential data in from flash + ldr r0, =confidential_vma // dst addr + ldr r1, =confidential_lma // src addr + ldr r2, =confidential_size // size in bytes + bl memcpy + + // setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value + bl rng_get + ldr r1, = __stack_chk_guard + str r0, [r1] + + // re-enable exceptions + // according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7: + // "If it is not necessary to ensure that a pended interrupt is recognized immediately before + // subsequent operations, it is not necessary to insert a memory barrier instruction." + cpsie f + + // enter the application code + bl main + + b shutdown_privileged + + .end diff --git a/core/embed/kernel/version.h b/core/embed/kernel/version.h new file mode 100644 index 0000000000..4a3ed90d59 --- /dev/null +++ b/core/embed/kernel/version.h @@ -0,0 +1,11 @@ +#define VERSION_MAJOR 2 +#define VERSION_MINOR 8 +#define VERSION_PATCH 1 +#define VERSION_BUILD 0 + +#define FIX_VERSION_MAJOR 2 +#define FIX_VERSION_MINOR 8 +#define FIX_VERSION_PATCH 0 +#define FIX_VERSION_BUILD 0 + +#define VERSION_MONOTONIC 1 diff --git a/core/embed/lib/sizedefs.h b/core/embed/lib/sizedefs.h index 9f8bb7a6c5..07889e1abc 100644 --- a/core/embed/lib/sizedefs.h +++ b/core/embed/lib/sizedefs.h @@ -2,7 +2,10 @@ #define SIZEDEFS_H_ #define SIZE_2K (2 * 1024) +#define SIZE_3K (3 * 1024) +#define SIZE_8K (8 * 1024) #define SIZE_16K (16 * 1024) +#define SIZE_24K (24 * 1024) #define SIZE_48K (48 * 1024) #define SIZE_64K (64 * 1024) #define SIZE_128K (128 * 1024) diff --git a/core/embed/lib/translations.c b/core/embed/lib/translations.c index 191bcd989b..9f68a29b3a 100644 --- a/core/embed/lib/translations.c +++ b/core/embed/lib/translations.c @@ -7,6 +7,8 @@ #include "model.h" #include "mpu.h" +#ifdef KERNEL_MODE + bool translations_write(const uint8_t* data, uint32_t offset, uint32_t len) { uint32_t size = translations_area_bytesize(); if (offset > size || size - offset < len) { @@ -44,3 +46,5 @@ void translations_erase(void) { uint32_t translations_area_bytesize(void) { return flash_area_get_size(&TRANSLATIONS_AREA); } + +#endif // KERNEL_MODE diff --git a/core/embed/lib/unit_variant.c b/core/embed/lib/unit_variant.c index 8170d19e02..6fffb7049d 100644 --- a/core/embed/lib/unit_variant.c +++ b/core/embed/lib/unit_variant.c @@ -6,6 +6,8 @@ #include "unit_variant.h" #include TREZOR_BOARD +#ifdef KERNEL_MODE + static uint8_t unit_variant_color = 0; static uint8_t unit_variant_packaging = 0; static bool unit_variant_btconly = false; @@ -94,3 +96,5 @@ bool unit_variant_is_sd_hotswap_enabled(void) { #endif #endif } + +#endif // KERNEL_MODE diff --git a/core/embed/lib/unit_variant.h b/core/embed/lib/unit_variant.h index 3d08974e75..fea6d77b0c 100644 --- a/core/embed/lib/unit_variant.h +++ b/core/embed/lib/unit_variant.h @@ -4,7 +4,12 @@ #include #include +#ifdef KERNEL_MODE + void unit_variant_init(void); + +#endif // KERNEL_MODE + bool unit_variant_present(void); uint8_t unit_variant_get_color(void); uint8_t unit_variant_get_packaging(void); diff --git a/core/embed/models/D002/model_D002.h b/core/embed/models/D002/model_D002.h index 217974ca69..6b0712631b 100644 --- a/core/embed/models/D002/model_D002.h +++ b/core/embed/models/D002/model_D002.h @@ -32,6 +32,9 @@ #define FLASH_START 0x0C000000 #define BOARDLOADER_START 0x0C004000 #define BOOTLOADER_START 0x0C010000 +#define KERNEL_START 0x0C050000 +#define KERNEL_SIZE 0x00028000 +#define COREAPP_START 0x0C078000 #define FIRMWARE_START 0x0C050000 #define STORAGE_1_OFFSET 0x30000 #define STORAGE_2_OFFSET 0x50000 diff --git a/core/embed/models/T3T1/model_T3T1.h b/core/embed/models/T3T1/model_T3T1.h index cbada112e4..35af3e6d20 100644 --- a/core/embed/models/T3T1/model_T3T1.h +++ b/core/embed/models/T3T1/model_T3T1.h @@ -32,6 +32,9 @@ #define FLASH_START 0x0C000000 #define BOARDLOADER_START 0x0C004000 #define BOOTLOADER_START 0x0C010000 +#define KERNEL_START 0x0C050000 +#define KERNEL_SIZE 0x00028000 +#define COREAPP_START 0x0C078000 #define FIRMWARE_START 0x0C050000 #define STORAGE_1_OFFSET 0x30000 #define STORAGE_2_OFFSET 0x50000 diff --git a/core/embed/trezorhal/bg_copy.h b/core/embed/trezorhal/bg_copy.h index be40c25428..dac9383d79 100644 --- a/core/embed/trezorhal/bg_copy.h +++ b/core/embed/trezorhal/bg_copy.h @@ -6,6 +6,8 @@ #include #include +#ifdef KERNEL_MODE + /** * Callback function invoked from the IRQ context * when the transfer is complete @@ -38,4 +40,6 @@ void bg_copy_wait(void); void bg_copy_abort(void); +#endif // KERNEL_MODE + #endif diff --git a/core/embed/trezorhal/board_capabilities.h b/core/embed/trezorhal/board_capabilities.h index 66a4c28f59..6bf820dfc9 100644 --- a/core/embed/trezorhal/board_capabilities.h +++ b/core/embed/trezorhal/board_capabilities.h @@ -35,6 +35,8 @@ Last tag must be terminator or all space used. #include +#ifdef KERNEL_MODE + #define BOARD_CAPABILITIES_SIZE 256 #define CAPABILITIES_HEADER "TRZC" @@ -77,4 +79,6 @@ void parse_boardloader_capabilities(); const uint32_t get_board_name(); const boardloader_version_t* get_boardloader_version(); +#endif // KERNEL_MODE + #endif diff --git a/core/embed/trezorhal/button.h b/core/embed/trezorhal/button.h index f1389f7f4e..fa54013bcb 100644 --- a/core/embed/trezorhal/button.h +++ b/core/embed/trezorhal/button.h @@ -28,7 +28,12 @@ #define BTN_LEFT 0 #define BTN_RIGHT 1 +#ifdef KERNEL_MODE + void button_init(void); + +#endif + uint32_t button_read(void); char button_state_left(void); char button_state_right(void); diff --git a/core/embed/trezorhal/consumption_mask.h b/core/embed/trezorhal/consumption_mask.h index d11fdabf9d..fdf1abb95f 100644 --- a/core/embed/trezorhal/consumption_mask.h +++ b/core/embed/trezorhal/consumption_mask.h @@ -1,9 +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 . + */ #ifndef CORE_CONSUMPTION_MASK_H #define CORE_CONSUMPTION_MASK_H -void consumption_mask_randomize(); +#ifdef KERNEL_MODE void consumption_mask_init(void); +void consumption_mask_randomize(); + +#endif + #endif // CORE_CONSUMPTION_MASK_H diff --git a/core/embed/trezorhal/entropy.h b/core/embed/trezorhal/entropy.h index bd50b48e3a..c71d0aab4f 100644 --- a/core/embed/trezorhal/entropy.h +++ b/core/embed/trezorhal/entropy.h @@ -22,10 +22,14 @@ #include +#ifdef KERNEL_MODE + void entropy_init(void); +#endif + #define HW_ENTROPY_LEN (12 + 32) void entropy_get(uint8_t *buf); -#endif \ No newline at end of file +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/flash.h b/core/embed/trezorhal/flash.h index 2918b11ee5..ae0169af78 100644 --- a/core/embed/trezorhal/flash.h +++ b/core/embed/trezorhal/flash.h @@ -23,11 +23,10 @@ #include #include +#include "flash_ll.h" #include "platform.h" #include "secbool.h" -#include "flash_ll.h" - void flash_init(void); #endif // TREZORHAL_FLASH_H diff --git a/core/embed/trezorhal/flash_otp.h b/core/embed/trezorhal/flash_otp.h index c3f8705ab4..56d05a237a 100644 --- a/core/embed/trezorhal/flash_otp.h +++ b/core/embed/trezorhal/flash_otp.h @@ -3,6 +3,8 @@ #include +#ifdef KERNEL_MODE + #define FLASH_OTP_NUM_BLOCKS 16 #define FLASH_OTP_BLOCK_SIZE 32 @@ -15,4 +17,6 @@ secbool __wur flash_otp_write(uint8_t block, uint8_t offset, secbool __wur flash_otp_lock(uint8_t block); secbool __wur flash_otp_is_locked(uint8_t block); +#endif // KERNEL_MODE + #endif // TREZORHAL_FLASH_OTP_H diff --git a/core/embed/trezorhal/fwutils.h b/core/embed/trezorhal/fwutils.h index b4c13626f9..f29bc5ff63 100644 --- a/core/embed/trezorhal/fwutils.h +++ b/core/embed/trezorhal/fwutils.h @@ -54,9 +54,13 @@ secbool firmware_calc_hash(const uint8_t* challenge, size_t challenge_len, // otherwise. secbool firmware_get_vendor(char* buff, size_t buff_size); +#ifdef KERNEL_MODE + // Invalidates the firmware by erasing the first 1KB of the firmware area. // // Note: only works when write access to firmware area is enabled by MPU void firmware_invalidate_header(void); +#endif // KERNEL_MODE + #endif // TREZORHAL_FWUTILS_H diff --git a/core/embed/trezorhal/haptic.h b/core/embed/trezorhal/haptic.h index ca7223b658..6cb60ee9bb 100644 --- a/core/embed/trezorhal/haptic.h +++ b/core/embed/trezorhal/haptic.h @@ -30,6 +30,8 @@ typedef enum { HAPTIC_HOLD_TO_CONFIRM = 1, } haptic_effect_t; +#ifdef KERNEL_MODE + // Initializes the haptic driver // // The function initializes the GPIO pins and the hardware @@ -44,6 +46,8 @@ bool haptic_init(void); // haptic driver so the device can be eventually put into a low-power mode. void haptic_deinit(void); +#endif // KERNEL_MODE + // Enables or disables the haptic driver // // When the driver is disabled, it does not play any haptic effects diff --git a/core/embed/trezorhal/hash_processor.h b/core/embed/trezorhal/hash_processor.h index 1ebc9bb94d..66c85653b9 100644 --- a/core/embed/trezorhal/hash_processor.h +++ b/core/embed/trezorhal/hash_processor.h @@ -10,9 +10,13 @@ typedef struct { uint8_t buffer[HASH_SHA256_BUFFER_SIZE]; /*!< data being processed */ } hash_sha265_context_t; +#ifdef KERNEL_MODE + // Initialize the hash processor void hash_processor_init(void); +#endif + // Calculate SHA256 hash of data // for best performance, data should be 32-bit aligned - as this allows DMA to // be used diff --git a/core/embed/trezorhal/i2c_bus.h b/core/embed/trezorhal/i2c_bus.h index 3203fcaa06..2296a4d2c4 100644 --- a/core/embed/trezorhal/i2c_bus.h +++ b/core/embed/trezorhal/i2c_bus.h @@ -24,6 +24,8 @@ #include #include +#ifdef KERNEL_MODE + // I2C bus abstraction typedef struct i2c_bus i2c_bus_t; // I2C packet (series of I2C operations) @@ -182,4 +184,6 @@ void example() { } */ +#endif // KERNEL_MODE + #endif // TREZORHAL_I2C_BUS_H diff --git a/core/embed/trezorhal/lowlevel.h b/core/embed/trezorhal/lowlevel.h index 49757aeac9..7d6cf78916 100644 --- a/core/embed/trezorhal/lowlevel.h +++ b/core/embed/trezorhal/lowlevel.h @@ -22,6 +22,8 @@ #include "secbool.h" +#ifdef KERNEL_MODE + secbool flash_check_option_bytes(void); void flash_lock_option_bytes(void); void flash_unlock_option_bytes(void); @@ -31,4 +33,6 @@ void periph_init(void); secbool reset_flags_check(void); void reset_flags_reset(void); +#endif // KERNEL_MODE + #endif // __TREZORHAL_LOWLEVEL_H__ diff --git a/core/embed/trezorhal/monoctr.h b/core/embed/trezorhal/monoctr.h index 296b573dbf..e6394583f1 100644 --- a/core/embed/trezorhal/monoctr.h +++ b/core/embed/trezorhal/monoctr.h @@ -20,6 +20,8 @@ #ifndef TREZORHAL_MONOCTR #define TREZORHAL_MONOCTR +#ifdef KERNEL_MODE + // Monoctr module provides monotonic counter functionality #define MONOCTR_MAX_VALUE 63 @@ -40,4 +42,6 @@ secbool monoctr_write(monoctr_type_t type, uint8_t value); // Read the current value of the monotonic counter secbool monoctr_read(monoctr_type_t type, uint8_t* value); +#endif // KERNEL_MODE + #endif diff --git a/core/embed/trezorhal/mpu.h b/core/embed/trezorhal/mpu.h index 989d622c30..c8486767a3 100644 --- a/core/embed/trezorhal/mpu.h +++ b/core/embed/trezorhal/mpu.h @@ -20,6 +20,8 @@ #ifndef TREZORHAL_MPU_H #define TREZORHAL_MPU_H +#ifdef KERNEL_MODE + // The MPU driver can be set to on of the following modes. // // In each mode, the MPU is configured to allow access to specific @@ -62,4 +64,6 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode); // Same as `mpu_reconfig()`, but with a more descriptive name. void mpu_restore(mpu_mode_t mode); +#endif // KERNEL_MODE + #endif // TREZORHAL_MPU_H diff --git a/core/embed/trezorhal/optiga/optiga.c b/core/embed/trezorhal/optiga/optiga.c index 2189fc8dd9..d4fa2e2391 100644 --- a/core/embed/trezorhal/optiga/optiga.c +++ b/core/embed/trezorhal/optiga/optiga.c @@ -27,6 +27,8 @@ #include "rand.h" #include "storage.h" +#ifdef KERNEL_MODE + // Counter-protected PIN secret and reset key for OID_STRETCHED_PIN_CTR (OID // 0xF1D0). #define OID_PIN_SECRET (OPTIGA_OID_DATA + 0) @@ -973,3 +975,5 @@ bool optiga_pin_decrease_rem(uint32_t count) { optiga_count_data_object(OID_STRETCHED_PIN_CTR, count) == OPTIGA_SUCCESS; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/optiga/optiga_commands.c b/core/embed/trezorhal/optiga/optiga_commands.c index a77d795915..1041adc887 100644 --- a/core/embed/trezorhal/optiga/optiga_commands.c +++ b/core/embed/trezorhal/optiga/optiga_commands.c @@ -33,6 +33,8 @@ #include "optiga_transport.h" #include "sha2.h" +#ifdef KERNEL_MODE + // Static buffer for commands and responses. static uint8_t tx_buffer[OPTIGA_MAX_APDU_SIZE] = {0}; static size_t tx_size = 0; @@ -959,3 +961,5 @@ optiga_result optiga_set_priv_key(uint16_t oid, const uint8_t priv_key[32]) { return process_output_fixedlen(NULL, 0); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/optiga/optiga_transport.c b/core/embed/trezorhal/optiga/optiga_transport.c index 8876c190ed..3ac1d82054 100644 --- a/core/embed/trezorhal/optiga/optiga_transport.c +++ b/core/embed/trezorhal/optiga/optiga_transport.c @@ -31,6 +31,8 @@ #include "optiga_hal.h" #include "tls_prf.h" +#ifdef KERNEL_MODE + #include TREZOR_BOARD // Maximum possible packet size that can be transmitted. @@ -812,3 +814,5 @@ optiga_result optiga_sec_chan_handshake(const uint8_t *secret, sec_chan_established = true; return OPTIGA_SUCCESS; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/random_delays.h b/core/embed/trezorhal/random_delays.h index 19e136c4eb..ecdd6d44bd 100644 --- a/core/embed/trezorhal/random_delays.h +++ b/core/embed/trezorhal/random_delays.h @@ -17,16 +17,22 @@ * along with this program. If not, see . */ -#ifndef __TREZORHAL_RANDOM_DELAYS_H__ -#define __TREZORHAL_RANDOM_DELAYS_H__ +#ifndef TREZORHAL_RANDOM_DELAYS_H +#define TREZORHAL_RANDOM_DELAYS_H #include +#ifdef KERNEL_MODE + void rdi_init(void); void rdi_start(void); void rdi_stop(void); + +#endif + void rdi_refresh_session_delay(void); void wait_random(void); -#endif + +#endif // TREZORHAL_RANDOM_DELAYS_H diff --git a/core/embed/trezorhal/rgb_led.h b/core/embed/trezorhal/rgb_led.h index a342b9a858..1ad62d9b80 100644 --- a/core/embed/trezorhal/rgb_led.h +++ b/core/embed/trezorhal/rgb_led.h @@ -1,4 +1,33 @@ +/* + * 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 TREZORHAL_RGB_LED_H +#define TREZORHAL_RGB_LED_H + +#include + +#ifdef KERNEL_MODE void rgb_led_init(void); +#endif + void rgb_led_set_color(uint32_t color); + +#endif // TREZORHAL_RGB_LED_H diff --git a/core/embed/trezorhal/rng.h b/core/embed/trezorhal/rng.h index 083b2c1508..7c9dc69a18 100644 --- a/core/embed/trezorhal/rng.h +++ b/core/embed/trezorhal/rng.h @@ -22,8 +22,14 @@ #include +#ifdef KERNEL_MODE + void rng_init(void); + uint32_t rng_read(const uint32_t previous, const uint32_t compare_previous); + +#endif // KERNEL_MODE + uint32_t rng_get(void); #endif diff --git a/core/embed/trezorhal/sdcard.h b/core/embed/trezorhal/sdcard.h index e2f1bf4b8a..730b33210f 100644 --- a/core/embed/trezorhal/sdcard.h +++ b/core/embed/trezorhal/sdcard.h @@ -52,8 +52,13 @@ // this is a fixed size and should not be changed #define SDCARD_BLOCK_SIZE (512) +#ifdef KERNEL_MODE + void sdcard_init(void); secbool __wur sdcard_power_on_unchecked(bool low_speed); + +#endif + secbool __wur sdcard_power_on(void); void sdcard_power_off(void); secbool __wur sdcard_is_present(void); diff --git a/core/embed/trezorhal/secret.h b/core/embed/trezorhal/secret.h index 8c85ac9e5a..288e98f7f9 100644 --- a/core/embed/trezorhal/secret.h +++ b/core/embed/trezorhal/secret.h @@ -1,7 +1,11 @@ +#ifndef TREZORHAL_SECRET_H +#define TREZORHAL_SECRET_H #include #include "secbool.h" +#ifdef KERNEL_MODE + #define SECRET_HEADER_MAGIC "TRZS" #define SECRET_HEADER_LEN 16 #define SECRET_OPTIGA_KEY_OFFSET 16 @@ -14,11 +18,6 @@ #define SECRET_BHK_OFFSET (1024 * 8) #define SECRET_BHK_LEN 32 -// Checks if bootloader is locked, that is the secret storage contains optiga -// pairing secret on platforms where access to the secret storage cannot be -// restricted for unofficial firmware -secbool secret_bootloader_locked(void); - // Writes data to the secret storage void secret_write(const uint8_t* data, uint32_t offset, uint32_t len); @@ -70,3 +69,12 @@ 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); + +#endif // KERNEL_MODE + +// Checks if bootloader is locked, that is the secret storage contains optiga +// pairing secret on platforms where access to the secret storage cannot be +// restricted for unofficial firmware +secbool secret_bootloader_locked(void); + +#endif // TREZORHAL_SECRET_H diff --git a/core/embed/trezorhal/stm32f4/board_capabilities.c b/core/embed/trezorhal/stm32f4/board_capabilities.c index 461fbaa15c..68757bbe9e 100644 --- a/core/embed/trezorhal/stm32f4/board_capabilities.c +++ b/core/embed/trezorhal/stm32f4/board_capabilities.c @@ -24,6 +24,8 @@ #include "model.h" #include "mpu.h" +#ifdef KERNEL_MODE + static uint32_t board_name = 0; static struct BoardloaderVersion boardloader_version; @@ -86,3 +88,5 @@ void parse_boardloader_capabilities() { mpu_restore(mpu_mode); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/bootutils.c b/core/embed/trezorhal/stm32f4/bootutils.c index 2fdd3f9afd..4e57390562 100644 --- a/core/embed/trezorhal/stm32f4/bootutils.c +++ b/core/embed/trezorhal/stm32f4/bootutils.c @@ -23,9 +23,13 @@ #include "bootutils.h" #include "common.h" #include "display.h" +#include "image.h" #include "irq.h" +#include "model.h" #include "mpu.h" +#ifdef KERNEL_MODE + #ifdef STM32U5 // Persistent variable that holds the 'command' for the next reboot. boot_command_t __attribute__((section(".boot_command"))) g_boot_command; @@ -131,3 +135,5 @@ void __attribute__((noreturn)) secure_shutdown(void) { for (;;) ; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/button.c b/core/embed/trezorhal/stm32f4/button.c index b8ca256b7f..544b8ba482 100644 --- a/core/embed/trezorhal/stm32f4/button.c +++ b/core/embed/trezorhal/stm32f4/button.c @@ -2,6 +2,8 @@ #include "button.h" #include TREZOR_BOARD +#ifdef KERNEL_MODE + static char last_left = 0, last_right = 0; void button_init(void) { @@ -45,3 +47,5 @@ uint32_t button_read(void) { char button_state_left(void) { return last_left; } char button_state_right(void) { return last_right; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/common.c b/core/embed/trezorhal/stm32f4/common.c index 17395f7208..7ac11fe6ac 100644 --- a/core/embed/trezorhal/stm32f4/common.c +++ b/core/embed/trezorhal/stm32f4/common.c @@ -36,6 +36,8 @@ #include "backlight_pwm.h" #endif +#ifdef KERNEL_MODE + // reference RM0090 section 35.12.1 Figure 413 #define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U) #define USB_OTG_HS_DATA_FIFO_SIZE (4096U) @@ -52,3 +54,5 @@ void clear_otg_hs_memory(void) { __HAL_RCC_USB_OTG_HS_CLK_DISABLE(); // disable USB OTG_HS peripheral clock as // the peripheral is not needed right now } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/consumption_mask.c b/core/embed/trezorhal/stm32f4/consumption_mask.c index 1da8191508..3252fdaece 100644 --- a/core/embed/trezorhal/stm32f4/consumption_mask.c +++ b/core/embed/trezorhal/stm32f4/consumption_mask.c @@ -20,6 +20,8 @@ #include STM32_HAL_H #include "rng.h" +#ifdef KERNEL_MODE + #define SAMPLES 110 #define TIMER_PERIOD 16640 // cca 10 KHz @ 180MHz @@ -106,3 +108,5 @@ void consumption_mask_init(void) { HAL_TIM_Base_Start(&TIM8_Handle); HAL_TIM_PWM_Start(&TIM8_Handle, TIM_CHANNEL_1); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/entropy.c b/core/embed/trezorhal/stm32f4/entropy.c index 4aec016ab8..99fb0d6974 100644 --- a/core/embed/trezorhal/stm32f4/entropy.c +++ b/core/embed/trezorhal/stm32f4/entropy.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#include + #include "entropy.h" #include "entropy.h" @@ -27,6 +29,8 @@ #include "stm32f4xx_ll_utils.h" +#ifdef KERNEL_MODE + static uint8_t g_hw_entropy[HW_ENTROPY_LEN]; void entropy_init(void) { @@ -58,3 +62,5 @@ void entropy_init(void) { } void entropy_get(uint8_t *buf) { memcpy(buf, g_hw_entropy, HW_ENTROPY_LEN); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/fault_handlers.c b/core/embed/trezorhal/stm32f4/fault_handlers.c index 5c6d43152c..35fc0ed030 100644 --- a/core/embed/trezorhal/stm32f4/fault_handlers.c +++ b/core/embed/trezorhal/stm32f4/fault_handlers.c @@ -1,34 +1,58 @@ #include TREZOR_BOARD + #include "common.h" +#include "mpu.h" + +#ifdef KERNEL_MODE void fault_handlers_init(void) { // Enable BUS fault and USAGE fault handlers SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk); } -void HardFault_Handler(void) { error_shutdown("(HF)"); } +void HardFault_Handler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(HF)"); +} -void MemManage_Handler_MM(void) { error_shutdown("(MM)"); } +void MemManage_Handler_MM(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(MM)"); +} -void MemManage_Handler_SO(void) { error_shutdown("(SO)"); } +void MemManage_Handler_SO(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(SO)"); +} -void BusFault_Handler(void) { error_shutdown("(BF)"); } +void BusFault_Handler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(BF)"); +} -void UsageFault_Handler(void) { error_shutdown("(UF)"); } +void UsageFault_Handler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(UF)"); +} void NMI_Handler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); // Clock Security System triggered NMI if ((RCC->CIR & RCC_CIR_CSSF) != 0) { error_shutdown("(CS)"); } + mpu_restore(mpu_mode); } // from util.s extern void shutdown_privileged(void); void PVD_IRQHandler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); #ifdef BACKLIGHT_PWM_TIM BACKLIGHT_PWM_TIM->BACKLIGHT_PWM_TIM_CCR = 0; // turn off display backlight #endif shutdown_privileged(); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/flash.c b/core/embed/trezorhal/stm32f4/flash.c index 8a34cc6947..5a0b2c5cb4 100644 --- a/core/embed/trezorhal/stm32f4/flash.c +++ b/core/embed/trezorhal/stm32f4/flash.c @@ -24,6 +24,8 @@ #include "common.h" #include "flash.h" +#ifdef KERNEL_MODE + #if defined STM32F427xx || defined STM32F429xx #define FLASH_SECTOR_COUNT 24 #elif defined STM32F405x @@ -198,3 +200,5 @@ secbool flash_write_block(uint16_t sector, uint32_t offset, const flash_block_t block) { return flash_write_word(sector, offset, block[0]); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/flash_otp.c b/core/embed/trezorhal/stm32f4/flash_otp.c index 53672c36f2..6260426994 100644 --- a/core/embed/trezorhal/stm32f4/flash_otp.c +++ b/core/embed/trezorhal/stm32f4/flash_otp.c @@ -24,6 +24,8 @@ #include "flash.h" #include "mpu.h" +#ifdef KERNEL_MODE + #define FLASH_OTP_LOCK_BASE 0x1FFF7A00U void flash_otp_init() { @@ -102,3 +104,5 @@ secbool flash_otp_is_locked(uint8_t block) { return is_locked; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/fwutils.c b/core/embed/trezorhal/stm32f4/fwutils.c index e583203d7f..e2a6a5a39d 100644 --- a/core/embed/trezorhal/stm32f4/fwutils.c +++ b/core/embed/trezorhal/stm32f4/fwutils.c @@ -27,6 +27,8 @@ #include "image.h" #include "model.h" +#ifdef KERNEL_MODE + #define FW_HASHING_CHUNK_SIZE 1024 secbool firmware_calc_hash(const uint8_t* challenge, size_t challenge_len, @@ -110,3 +112,5 @@ void firmware_invalidate_header(void) { } ensure(flash_lock_write(), NULL); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/i2c_bus.c b/core/embed/trezorhal/stm32f4/i2c_bus.c index 2dfacc3abe..5b4c11e52c 100644 --- a/core/embed/trezorhal/stm32f4/i2c_bus.c +++ b/core/embed/trezorhal/stm32f4/i2c_bus.c @@ -25,8 +25,11 @@ #include "common.h" #include "i2c_bus.h" #include "irq.h" +#include "mpu.h" #include "systimer.h" +#ifdef KERNEL_MODE + // I2C bus SCL clock frequency #define I2C_BUS_SCL_FREQ 200000 // Hz @@ -907,30 +910,44 @@ static void i2c_bus_er_handler(i2c_bus_t* bus) { #ifdef I2C_INSTANCE_0 void I2C_INSTANCE_0_EV_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_ev_handler(&g_i2c_bus_driver[0]); + mpu_restore(mpu_mode); } void I2C_INSTANCE_0_ER_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_er_handler(&g_i2c_bus_driver[0]); + mpu_restore(mpu_mode); } #endif #ifdef I2C_INSTANCE_1 void I2C_INSTANCE_1_EV_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_ev_handler(&g_i2c_bus_driver[1]); + mpu_restore(mpu_mode); } void I2C_INSTANCE_1_ER_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_er_handler(&g_i2c_bus_driver[1]); + mpu_restore(mpu_mode); } #endif #ifdef I2C_INSTANCE_2 void I2C_INSTANCE_2_EV_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_ev_handler(&g_i2c_bus_driver[2]); + mpu_restore(mpu_mode); } void I2C_INSTANCE_2_ER_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_er_handler(&g_i2c_bus_driver[2]); + mpu_restore(mpu_mode); } #endif + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/limited_util.s b/core/embed/trezorhal/stm32f4/limited_util.S similarity index 100% rename from core/embed/trezorhal/stm32f4/limited_util.s rename to core/embed/trezorhal/stm32f4/limited_util.S diff --git a/core/embed/trezorhal/stm32f4/lowlevel.c b/core/embed/trezorhal/stm32f4/lowlevel.c index 188142f21a..1174991f19 100644 --- a/core/embed/trezorhal/stm32f4/lowlevel.c +++ b/core/embed/trezorhal/stm32f4/lowlevel.c @@ -25,6 +25,8 @@ #include "flash_otp.h" +#ifdef KERNEL_MODE + #pragma GCC optimize( \ "no-stack-protector") // applies to all functions in this file @@ -197,3 +199,5 @@ secbool reset_flags_check(void) { void reset_flags_reset(void) { RCC->CSR |= RCC_CSR_RMVF; // clear the reset flags } + +#endif // #ifdef KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/monoctr.c b/core/embed/trezorhal/stm32f4/monoctr.c index c05bc04647..119b2070bf 100644 --- a/core/embed/trezorhal/stm32f4/monoctr.c +++ b/core/embed/trezorhal/stm32f4/monoctr.c @@ -23,6 +23,8 @@ #include "mpu.h" #include "string.h" +#ifdef KERNEL_MODE + #if !PRODUCTION // we don't want to override OTP on development boards // lets mock this functionality @@ -139,3 +141,5 @@ secbool monoctr_read(monoctr_type_t type, uint8_t* value) { return sectrue; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/mpu.c b/core/embed/trezorhal/stm32f4/mpu.c index 23a1f208d9..72f593d721 100644 --- a/core/embed/trezorhal/stm32f4/mpu.c +++ b/core/embed/trezorhal/stm32f4/mpu.c @@ -29,6 +29,8 @@ #include "stm32f4xx_ll_cortex.h" +#ifdef KERNEL_MODE + // http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html #define MPU_RASR_ATTR_FLASH_CODE (MPU_RASR_C_Msk) #define MPU_RASR_ATTR_FLASH_DATA (MPU_RASR_C_Msk | MPU_RASR_XN_Msk) @@ -354,3 +356,5 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) { } void mpu_restore(mpu_mode_t mode) { mpu_reconfig(mode); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/optiga_hal.c b/core/embed/trezorhal/stm32f4/optiga_hal.c index ec7a309119..b3d659fcf1 100644 --- a/core/embed/trezorhal/stm32f4/optiga_hal.c +++ b/core/embed/trezorhal/stm32f4/optiga_hal.c @@ -2,6 +2,8 @@ #include "common.h" #include TREZOR_BOARD +#ifdef KERNEL_MODE + void optiga_hal_init(void) { OPTIGA_RST_CLK_EN(); // init reset pin @@ -27,3 +29,5 @@ void optiga_reset(void) { // warm reset startup time min 15ms hal_delay(20); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/platform.c b/core/embed/trezorhal/stm32f4/platform.c index 47aaa72e93..8d801d507f 100644 --- a/core/embed/trezorhal/stm32f4/platform.c +++ b/core/embed/trezorhal/stm32f4/platform.c @@ -24,6 +24,8 @@ #include "systick.h" #include TREZOR_BOARD +#ifdef KERNEL_MODE + const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; @@ -204,3 +206,5 @@ void set_core_clock(clock_settings_t settings) { ; } #endif + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/random_delays.c b/core/embed/trezorhal/stm32f4/random_delays.c index afc8079fc1..9dbbe0a9d5 100644 --- a/core/embed/trezorhal/stm32f4/random_delays.c +++ b/core/embed/trezorhal/stm32f4/random_delays.c @@ -46,6 +46,8 @@ https://link.springer.com/content/pdf/10.1007%2F978-3-540-72354-7_3.pdf #include "rand.h" #include "systimer.h" +#ifdef KERNEL_MODE + // from util.s extern void shutdown_privileged(void); @@ -220,3 +222,5 @@ void wait_random(void) { } #endif } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/rgb_led.c b/core/embed/trezorhal/stm32f4/rgb_led.c index a6e8768d2f..8d0fbd3799 100644 --- a/core/embed/trezorhal/stm32f4/rgb_led.c +++ b/core/embed/trezorhal/stm32f4/rgb_led.c @@ -39,6 +39,8 @@ #include "common.h" +#ifdef KERNEL_MODE + #include STM32_HAL_H #define RESET_DATA_LEN 18 // >80us no pulse before sending data @@ -166,3 +168,5 @@ void rgb_led_init(void) { // turns off the LED rgb_led_set_color(0x000000); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/rng.c b/core/embed/trezorhal/stm32f4/rng.c index 29a98c1218..a6ae2b57c3 100644 --- a/core/embed/trezorhal/stm32f4/rng.c +++ b/core/embed/trezorhal/stm32f4/rng.c @@ -21,6 +21,8 @@ #include "rng.h" +#if KERNEL_MODE + #pragma GCC optimize( \ "no-stack-protector") // applies to all functions in this file @@ -56,3 +58,5 @@ uint32_t rng_get(void) { current = rng_read(previous, 1); return current; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/sdcard.c b/core/embed/trezorhal/stm32f4/sdcard.c index 21c7b099ec..386ccef036 100644 --- a/core/embed/trezorhal/stm32f4/sdcard.c +++ b/core/embed/trezorhal/stm32f4/sdcard.c @@ -49,9 +49,12 @@ #include #include "irq.h" +#include "mpu.h" #include "sdcard-set_clr_card_detect.h" #include "sdcard.h" +#ifdef KERNEL_MODE + #define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC1_CLK_ENABLE() #define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC1_CLK_DISABLE() #define SDMMC_IRQn SDMMC1_IRQn @@ -61,9 +64,9 @@ static DMA_HandleTypeDef sd_dma = {0}; void DMA2_Stream3_IRQHandler(void) { IRQ_ENTER(DMA2_Stream3_IRQn); - + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); HAL_DMA_IRQHandler(&sd_dma); - + mpu_restore(mpu_mode); IRQ_EXIT(DMA2_Stream3_IRQn); } @@ -231,9 +234,11 @@ uint64_t sdcard_get_capacity_in_bytes(void) { void SDIO_IRQHandler(void) { IRQ_ENTER(SDIO_IRQn); + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); if (sd_handle.Instance) { HAL_SD_IRQHandler(&sd_handle); } + mpu_restore(mpu_mode); IRQ_EXIT(SDIO_IRQn); } diff --git a/core/embed/trezorhal/stm32f4/secret.c b/core/embed/trezorhal/stm32f4/secret.c index a02df26360..0f6f92ef63 100644 --- a/core/embed/trezorhal/stm32f4/secret.c +++ b/core/embed/trezorhal/stm32f4/secret.c @@ -6,9 +6,7 @@ #include "model.h" #include "mpu.h" -#ifdef FANCY_FATAL_ERROR -#include "rust_ui.h" -#endif +#ifdef KERNEL_MODE static secbool bootloader_locked_set = secfalse; static secbool bootloader_locked = secfalse; @@ -134,3 +132,5 @@ void secret_prepare_fw(secbool allow_run_with_secret, secbool _trust_all) { } #endif } + +#endif // KERNEL_MODE \ No newline at end of file diff --git a/core/embed/trezorhal/stm32f4/syscall.c b/core/embed/trezorhal/stm32f4/syscall.c new file mode 100644 index 0000000000..8fde6b42ac --- /dev/null +++ b/core/embed/trezorhal/stm32f4/syscall.c @@ -0,0 +1,205 @@ +/* + * 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 STM32_HAL_H + +#include "syscall.h" +#include "image.h" +#include "irq.h" +#include "mpu.h" + +#ifdef SYSCALL_DISPATCH + +void syscall_init(void) { + // SVCall priority should be the lowest since it is + // generally a blocking operation + NVIC_SetPriority(SVCall_IRQn, IRQ_PRI_LOWEST); +} + +__attribute__((naked, no_stack_protector)) static uint32_t _invoke_app_callback( + uint32_t arg1, uint32_t arg2, uint32_t arg3, void *callback) { + __asm__ volatile( + "push {r1-r12, lr} \n" + + "mrs r12, PSP \n" // reserved frame on unprivileged stack (!@# + // TODO check PSP value???) + "push {r12} \n" + "sub r12, r12, #32 \n" + "msr PSP, r12 \n" + + "str r0, [r12, #0] \n" // r0 + "str r1, [r12, #4] \n" // r1" + "str r2, [r12, #8] \n" // r2" + + "mov r1, #0 \n" + "str r1, [r12, #12] \n" // r3" + "str r1, [r12, #16] \n" // r12" + "str r1, [r12, #20] \n" // lr" + + "bic r3, r3, #1 \n" + "str r3, [r12, #24] \n" // return address + + "ldr r1, = 0x01000000 \n" + "str r1, [r12, #28] \n" // xPSR + + "ldr r1, = 0xE000EF34 \n" // FPU->FPPCCR + "ldr r0, [r1] \n" + "bic r0, r0, #1 \n" // Clear LSPACT to suppress lazy stacking to + "str r0, [r1] \n" // avoid potential PSP stack overwrite. + + "mrs r1, CONTROL \n" + "bic r1, r1, #4 \n" // Clear FPCA to suppress lazy stacking to + "msr CONTROL, r1 \n" // avoid potential PSP stack overwrite. + + // return to Secure Thread mode (use Secure PSP) + "ldr lr, = 0xFFFFFFFD \n" + "bx lr \n"); +} + +uint32_t invoke_app_callback(uint32_t args1, uint32_t arg2, uint32_t arg3, + void *callback) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_APP); + uint32_t retval = _invoke_app_callback(args1, arg2, arg3, callback); + mpu_reconfig(mpu_mode); + return retval; +} + +// Jumps to reset vector of unprivileged application code +// +// Can be called only from an exception handler +__attribute__((naked, no_stack_protector)) static void start_app( + uint32_t app_start) { + __asm__ volatile( + "ldr r12, [r0, #0] \n" // stack pointer + "sub r12, r12, #32 \n" + "msr PSP, r12 \n" + + "mov r1, #0 \n" + "str r1, [r12, #0] \n" // r0 + "str r1, [r12, #4] \n" // r1" + "str r1, [r12, #8] \n" // r2" + "str r1, [r12, #12] \n" // r3" + "str r1, [r12, #16] \n" // r12" + "str r1, [r12, #20] \n" // lr" + + "ldr r1, [r0, #4] \n" // reset vector + "bic r1, r1, #1 \n" + "str r1, [r12, #24] \n" // return address + + "ldr r1, = 0x01000000 \n" + "str r1, [r12, #28] \n" // xPSR + + "ldr r1, = 0xE000EF34 \n" // FPU->FPPCCR + "ldr r0, [r1] \n" + "bic r0, r0, #1 \n" // Clear LSPACT to suppress lazy stacking to + "str r0, [r1] \n" // avoid potential PSP stack overwrite. + + "mrs r1, CONTROL \n" + "bic r1, r1, #4 \n" // Clear FPCA to suppress lazy stacking to + "msr CONTROL, r1 \n" // avoid potential PSP stack overwrite. + + "mrs r1, CONTROL \n" // Switch thread mode to unprivileged + "orr r1, r1, #1 \n" // by setting nPRIV bit in CONTROL register. + "msr CONTROL, r1 \n" // This applies after return from this + // handler. + + // return to Secure Thread mode (use Secure PSP) + "ldr lr, = 0xFFFFFFFD \n" + "bx lr \n"); +} + +void SVC_C_Handler(uint32_t *stack, uint32_t r4, uint32_t r5, uint32_t r6) { + uint8_t svc_number = ((uint8_t *)stack[6])[-2]; + uint32_t args[6] = {stack[0], stack[1], stack[2], stack[3], r4, r5}; + + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); + + switch (svc_number) { +#ifdef SYSTEM_VIEW + case SVC_GET_DWT_CYCCNT: + cyccnt_cycles = *DWT_CYCCNT_ADDR; + break; +#endif + case SVC_START_APP: + mpu_reconfig(MPU_MODE_APP); + start_app(args[0]); + break; + case SVC_SYSCALL: + syscall_handler(args, r6); + stack[0] = args[0]; + stack[1] = args[1]; + break; + default: + stack[0] = 0xffffffff; + stack[1] = 0xffffffff; + break; + } + + mpu_restore(mpu_mode); +} + +__attribute__((naked, no_stack_protector)) void SVC_Handler(void) { + __asm__ volatile( + " tst lr, #4 \n" // Bit #3 tells which stack pointer should we + // use + " ite eq \n" // Next 2 instructions are if-then-else + " mrseq r0, msp \n" // Make R0 point to main stack pointer + " mrsne r0, psp \n" // Make R0 point to process stack pointer + + " ldr r1, [r0, #24] \n" // Load the PC of the SVC handler + " ldrb r1, [r1, #-2] \n" // Load the instruction at the PC + " cmp r1, #2 \n" // SVC_CALLBACK_RETURN + " beq svc_callback_return \n" + + " mov r1, r4 \n" // pass R4 (arg5), R5 (arg6) and + " mov r2, r5 \n" // R6 (sycall_number) as arguments + " mov r3, r6 \n" // to SCV_C_Handler + " b SVC_C_Handler \n" // + + "svc_callback_return: \n" + + " ldr r0, [r0] \n" + " pop {r1} \n" + " msr PSP, r1 \n" + " pop {r1-r12, lr} \n" + " bx lr \n"); +} + +void __attribute__((no_stack_protector, noreturn)) +start_unprivileged_app(void) { + //!@# TODO calculate better + static const uint32_t app_start = COREAPP_START + IMAGE_HEADER_SIZE + 0x0400; + + mpu_reconfig(MPU_MODE_APP); + + register uint32_t ret __asm__("r0") = app_start; + + // SVC_START_APP is the only SVC that is allowed to be invoked from kernel + // itself and it is used to start the unprivileged application code + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_START_APP), "r"(ret) + : "memory"); + + // We never get here, just to supress compiler warning + while (1) { + } +} + +#endif // SYSCALL_DISPATCH diff --git a/core/embed/trezorhal/stm32f4/syscall.h b/core/embed/trezorhal/stm32f4/syscall.h new file mode 100644 index 0000000000..32da335d90 --- /dev/null +++ b/core/embed/trezorhal/stm32f4/syscall.h @@ -0,0 +1,209 @@ +/* + * 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 TREZORHAL_SYSCALL_H +#define TREZORHAL_SYSCALL_H + +#include + +#include "syscall_numbers.h" + +// Reserved SVC numbers +#define SVC_SYSCALL 0 +#define SVC_START_APP 1 +#define SVC_CALLBACK_RETURN 2 + +#ifdef KERNEL_MODE + +// Initializes the SVC/Syscall handlers +void syscall_init(void); + +// Handles all syscall requests. +// +// `args` points to an array of six 32-bit arguments. +// `syscall` is the syscall number, which is one of the `SYSCALL_XXX` constants. +// +// Input parameters are passed in `args[0]` to `args[5]`, +// and unused arguments may have undefined values. +// +// Return values must be copied to `args[0]` and +// `args[1]` (if returning a 64-bit value). +void syscall_handler(uint32_t *args, uint32_t syscall); + +// Invokes application callback from the syscall handler +uint32_t invoke_app_callback(uint32_t args1, uint32_t arg2, uint32_t arg3, + void *callback); + +// Jumps to reset vector in the unprivileged application +void __attribute__((noreturn)) start_unprivileged_app(void); + +#else // KERNEL_MODE + +static inline uint32_t __attribute__((no_stack_protector)) +syscall_invoke0(uint32_t syscall) { + register uint32_t ret __asm__("r0"); + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_SYSCALL), "r"(r6) + : "memory"); + + return ret; +} + +static inline uint64_t __attribute__((no_stack_protector)) +syscall_invoke0_ret64(uint32_t syscall) { + register uint32_t ret_lo __asm__("r0"); + register uint32_t ret_hi __asm__("r1"); + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret_lo), "=r"(ret_hi) + : [svid] "i"(SVC_SYSCALL), "r"(r6) + : "memory"); + + return ((uint64_t)ret_hi << 32) | ret_lo; +} + +static inline uint32_t __attribute__((no_stack_protector)) +syscall_invoke1(uint32_t arg1, uint32_t syscall) { + register uint32_t ret __asm__("r0") = arg1; + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_SYSCALL), "r"(ret), "r"(r6) + : "memory"); + return ret; +} + +static inline uint32_t __attribute__((no_stack_protector)) +syscall_invoke2(uint32_t arg1, uint32_t arg2, uint32_t syscall) { + register uint32_t ret __asm__("r0") = arg1; + register uint32_t r1 __asm__("r1") = arg2; + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_SYSCALL), "r"(ret), "r"(r1), "r"(r6) + : "memory"); + + return ret; +} + +static inline uint64_t __attribute__((no_stack_protector)) +syscall_invoke2_ret64(uint32_t arg1, uint32_t arg2, uint32_t syscall) { + register uint32_t ret_lo __asm__("r0") = arg1; + register uint32_t ret_hi __asm__("r1") = arg2; + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret_lo), "=r"(ret_hi) + : [svid] "i"(SVC_SYSCALL), "r"(ret_lo), "r"(ret_hi), "r"(r6) + : "memory"); + + return ((uint64_t)ret_hi << 32) | ret_lo; +} + +static inline uint32_t __attribute__((no_stack_protector)) +syscall_invoke3(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t syscall) { + register uint32_t ret __asm__("r0") = arg1; + register uint32_t r1 __asm__("r1") = arg2; + register uint32_t r2 __asm__("r2") = arg3; + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_SYSCALL), "r"(ret), "r"(r1), "r"(r2), + "r"(r6) + : "memory"); + + return ret; +} + +static inline uint32_t __attribute__((no_stack_protector)) +syscall_invoke4(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, + uint32_t syscall) { + register uint32_t ret __asm__("r0") = arg1; + register uint32_t r1 __asm__("r1") = arg2; + register uint32_t r2 __asm__("r2") = arg3; + register uint32_t r3 __asm__("r3") = arg4; + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_SYSCALL), "r"(ret), "r"(r1), "r"(r2), + "r"(r3), "r"(r6) + : "memory"); + + return ret; +} + +static inline uint32_t __attribute__((no_stack_protector)) +syscall_invoke5(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, + uint32_t arg5, uint32_t syscall) { + register uint32_t ret __asm__("r0") = arg1; + register uint32_t r1 __asm__("r1") = arg2; + register uint32_t r2 __asm__("r2") = arg3; + register uint32_t r3 __asm__("r3") = arg4; + register uint32_t r4 __asm__("r4") = arg5; + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_SYSCALL), "r"(ret), "r"(r1), "r"(r2), + "r"(r3), "r"(r4), "r"(r6) + : "memory"); + + return ret; +} + +static inline uint32_t __attribute__((no_stack_protector)) +syscall_invoke6(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, + uint32_t arg5, uint32_t arg6, uint32_t syscall) { + register uint32_t ret __asm__("r0") = arg1; + register uint32_t r1 __asm__("r1") = arg2; + register uint32_t r2 __asm__("r2") = arg3; + register uint32_t r3 __asm__("r3") = arg4; + register uint32_t r4 __asm__("r4") = arg5; + register uint32_t r5 __asm__("r5") = arg6; + register uint32_t r6 __asm__("r6") = syscall; + + __asm__ volatile("svc %[svid]\n" + : "=r"(ret) + : [svid] "i"(SVC_SYSCALL), "r"(ret), "r"(r1), "r"(r2), + "r"(r3), "r"(r4), "r"(r5), "r"(r6) + : "memory"); + + return ret; +} + +static inline void __attribute__((no_stack_protector)) +syscall_return_from_callback(uint32_t retval) { + register uint32_t r0 __asm__("r0") = retval; + __asm__ volatile("svc %[svid]\n" + : + : [svid] "i"(SVC_CALLBACK_RETURN), "r"(r0) + : "memory"); +} + +#endif // KERNEL_MODE + +#endif // TREZORHAL_SYSCALL_H diff --git a/core/embed/trezorhal/stm32f4/syscall_dispatch.c b/core/embed/trezorhal/stm32f4/syscall_dispatch.c new file mode 100644 index 0000000000..3e4510f989 --- /dev/null +++ b/core/embed/trezorhal/stm32f4/syscall_dispatch.c @@ -0,0 +1,499 @@ +/* + * 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 STM32_HAL_H + +#include "syscall.h" + +#include "bootutils.h" +#include "button.h" +#include "display.h" +#include "entropy.h" +#include "fwutils.h" +#include "haptic.h" +#include "hash_processor.h" +#include "irq.h" +#include "mpu.h" +#include "optiga.h" +#include "rng.h" +#include "sdcard.h" +#include "secret.h" +#include "systick.h" +#include "touch.h" +#include "translations.h" +#include "unit_variant.h" +#include "usb.h" +#include "usb_hid.h" +#include "usb_vcp.h" +#include "usb_webusb.h" + +#ifdef SYSCALL_DISPATCH + +static PIN_UI_WAIT_CALLBACK storage_init_callback = NULL; + +static secbool storage_init_callback_wrapper( + uint32_t wait, uint32_t progress, enum storage_ui_message_t message) { + return (secbool)invoke_app_callback(wait, progress, message, + storage_init_callback); +} + +static firmware_hash_callback_t firmware_hash_callback = NULL; + +static void firmware_hash_callback_wrapper(void *context, uint32_t progress, + uint32_t total) { + invoke_app_callback((uint32_t)context, progress, total, + firmware_hash_callback); +} + +void syscall_handler(uint32_t *args, uint32_t syscall) { + switch (syscall) { + case SYSCALL_SYSTICK_CYCLES: { + uint64_t cycles = systick_cycles(); + args[0] = cycles & 0xFFFFFFFF; + args[1] = cycles >> 32; + } break; + + case SYSCALL_SYSTICK_US: { + uint64_t cycles = systick_us(); + args[0] = cycles & 0xFFFFFFFF; + args[1] = cycles >> 32; + } break; + + case SYSCALL_SYSTICK_MS: + args[0] = systick_ms(); + break; + + case SYSCALL_SYSTICK_US_TO_CYCLES: { + uint64_t us = args[0] + ((uint64_t)args[1] << 32); + uint64_t cycles = systick_us_to_cycles(us); + args[0] = cycles & 0xFFFFFFFF; + args[1] = cycles >> 32; + } break; + + case SYSCALL_SECURE_SHUTDOWN: + secure_shutdown(); + break; + case SYSCALL_REBOOT: + reboot(); + break; + case SYSCALL_REBOOT_TO_BOOTLOADER: + reboot_to_bootloader(); + break; + case SYSCALL_REBOOT_AND_UPGRADE: + reboot_and_upgrade((uint8_t *)args[0]); + break; + +#ifdef STM32U5 + case SYSCALL_SHA256_INIT: { + hash_sha265_context_t *ctx = (hash_sha265_context_t *)args[0]; + hash_processor_sha256_init(ctx); + } break; + case SYSCALL_SHA256_UPDATE: { + hash_sha265_context_t *ctx = (hash_sha265_context_t *)args[0]; + const uint8_t *data = (const uint8_t *)args[1]; + uint32_t len = args[2]; + hash_processor_sha256_update(ctx, data, len); + } break; + case SYSCALL_SHA256_FINAL: { + hash_sha265_context_t *ctx = (hash_sha265_context_t *)args[0]; + uint8_t *output = (uint8_t *)args[1]; + hash_processor_sha256_final(ctx, output); + } break; + case SYSCALL_SHA256_CALC: { + const uint8_t *data = (const uint8_t *)args[0]; + uint32_t len = args[1]; + uint8_t *hash = (uint8_t *)args[2]; + hash_processor_sha256_calc(data, len, hash); + } break; +#endif // STM32U5 + + case SYSCALL_DISPLAY_SET_BACKLIGHT: { + args[0] = display_set_backlight((int)args[0]); + } break; + case SYSCALL_DISPLAY_GET_BACKLIGHT: { + args[0] = display_get_backlight(); + } break; + case SYSCALL_DISPLAY_SET_ORIENTATION: { + args[0] = display_set_orientation((int)args[0]); + } break; + case SYSCALL_DISPLAY_GET_ORIENTATION: { + args[0] = display_get_orientation(); + + } break; +#if XFRAMEBUFFER + case SYSCALL_DISPLAY_GET_FB_INFO: { + display_fb_info_t *info = (display_fb_info_t *)args[0]; + *info = display_get_frame_buffer(); + } break; +#else + case SYSCALL_DISPLAY_WAIT_FOR_SYNC: { + display_wait_for_sync(); + } break; +#endif + case SYSCALL_DISPLAY_REFRESH: { + display_refresh(); + } break; + case SYSCALL_USB_INIT: { + const usb_dev_info_t *dev_info = (const usb_dev_info_t *)args[0]; + args[0] = usb_init(dev_info); + } break; + case SYSCALL_USB_DEINIT: { + usb_deinit(); + } break; + case SYSCALL_USB_START: { + args[0] = usb_start(); + } break; + case SYSCALL_USB_STOP: { + usb_stop(); + } break; + case SYSCALL_USB_CONFIGURED: { + args[0] = usb_configured(); + } break; + case SYSCALL_USB_HID_ADD: { + args[0] = usb_hid_add((const usb_hid_info_t *)args[0]); + } break; + case SYSCALL_USB_HID_CAN_READ: { + args[0] = usb_hid_can_read((uint8_t)args[0]); + } break; + case SYSCALL_USB_HID_CAN_WRITE: { + args[0] = usb_hid_can_write((uint8_t)args[0]); + } break; + case SYSCALL_USB_HID_READ: { + args[0] = usb_hid_read((uint8_t)args[0], (uint8_t *)args[1], args[2]); + } break; + case SYSCALL_USB_HID_WRITE: { + args[0] = + usb_hid_write((uint8_t)args[0], (const uint8_t *)args[1], args[2]); + } break; + case SYSCALL_USB_HID_READ_SELECT: { + args[0] = usb_hid_read_select((uint32_t)args[0]); + } break; + case SYSCALL_USB_HID_READ_BLOCKING: { + args[0] = usb_hid_read_blocking((uint8_t)args[0], (uint8_t *)args[1], + args[2], (int)args[3]); + } break; + case SYSCALL_USB_HID_WRITE_BLOCKING: { + args[0] = usb_hid_write_blocking( + (uint8_t)args[0], (const uint8_t *)args[1], args[2], (int)args[3]); + } break; + case SYSCALL_USB_VCP_ADD: { + args[0] = usb_vcp_add((const usb_vcp_info_t *)args[0]); + } break; + case SYSCALL_USB_VCP_CAN_READ: { + args[0] = usb_vcp_can_read((uint8_t)args[0]); + } break; + case SYSCALL_USB_VCP_CAN_WRITE: { + args[0] = usb_vcp_can_write((uint8_t)args[0]); + } break; + case SYSCALL_USB_VCP_READ: { + args[0] = usb_vcp_read((uint8_t)args[0], (uint8_t *)args[1], args[2]); + } break; + case SYSCALL_USB_VCP_WRITE: { + args[0] = + usb_vcp_write((uint8_t)args[0], (const uint8_t *)args[1], args[2]); + } break; + case SYSCALL_USB_VCP_READ_BLOCKING: { + args[0] = usb_vcp_read_blocking((uint8_t)args[0], (uint8_t *)args[1], + args[2], (int)args[3]); + } break; + case SYSCALL_USB_VCP_WRITE_BLOCKING: { + args[0] = usb_vcp_write_blocking( + (uint8_t)args[0], (const uint8_t *)args[1], args[2], (int)args[3]); + } break; + case SYSCALL_USB_WEBUSB_ADD: { + args[0] = usb_webusb_add((const usb_webusb_info_t *)args[0]); + } break; + case SYSCALL_USB_WEBUSB_CAN_READ: { + args[0] = usb_webusb_can_read((uint8_t)args[0]); + } break; + case SYSCALL_USB_WEBUSB_CAN_WRITE: { + args[0] = usb_webusb_can_write((uint8_t)args[0]); + } break; + case SYSCALL_USB_WEBUSB_READ: { + args[0] = usb_webusb_read((uint8_t)args[0], (uint8_t *)args[1], args[2]); + } break; + case SYSCALL_USB_WEBUSB_WRITE: { + args[0] = + usb_webusb_write((uint8_t)args[0], (const uint8_t *)args[1], args[2]); + } break; + case SYSCALL_USB_WEBUSB_READ_SELECT: { + args[0] = usb_webusb_read_select((uint32_t)args[0]); + } break; + case SYSCALL_USB_WEBUSB_READ_BLOCKING: { + args[0] = usb_webusb_read_blocking((uint8_t)args[0], (uint8_t *)args[1], + args[2], (int)args[3]); + } break; + case SYSCALL_USB_WEBUSB_WRITE_BLOCKING: { + args[0] = usb_webusb_write_blocking( + (uint8_t)args[0], (const uint8_t *)args[1], args[2], (int)args[3]); + } break; +#ifdef USE_SD_CARD + case SYSCALL_SDCARD_POWER_ON: { + args[0] = sdcard_power_on(); + } break; + case SYSCALL_SDCARD_POWER_OFF: { + sdcard_power_off(); + } break; + case SYSCALL_SDCARD_IS_PRESENT: { + args[0] = sdcard_is_present(); + } break; + case SYSCALL_SDCARD_GET_CAPACITY: { + args[0] = sdcard_get_capacity_in_bytes(); + } break; + case SYSCALL_SDCARD_READ_BLOCKS: { + args[0] = sdcard_read_blocks((uint32_t *)args[0], args[1], args[2]); + } break; + case SYSCALL_SDCARD_WRITE_BLOCKS: { + args[0] = + sdcard_write_blocks((const uint32_t *)args[0], args[1], args[2]); + } break; +#endif + + case SYSCALL_UNIT_VARIANT_PRESENT: { + args[0] = unit_variant_present(); + } break; + case SYSCALL_UNIT_VARIANT_GET_COLOR: { + args[0] = unit_variant_get_color(); + } break; + case SYSCALL_UNIT_VARIANT_GET_PACKAGING: { + args[0] = unit_variant_get_packaging(); + } break; + case SYSCALL_UNIT_VARIANT_GET_BTCONLY: { + args[0] = unit_variant_get_btconly(); + } break; + case SYSCALL_UNIT_VARIANT_IS_SD_HOTSWAP_ENABLED: { + args[0] = unit_variant_is_sd_hotswap_enabled(); + } break; + case SYSCALL_SECRET_BOOTLOADER_LOCKED: { + args[0] = secret_bootloader_locked(); + } break; +#ifdef USE_BUTTON + case SYSCALL_BUTTON_READ: { + args[0] = button_read(); + } break; + case SYSCALL_BUTTON_STATE_LEFT: { + args[0] = button_state_left(); + } break; + case SYSCALL_BUTTON_STATE_RIGHT: { + args[0] = button_state_right(); + } break; +#endif +#ifdef USE_TOUCH + case SYSCALL_TOUCH_GET_EVENT: { + args[0] = touch_get_event(); + } break; +#endif +#ifdef USE_HAPTIC + case SYSCALL_HAPTIC_SET_ENABLED: { + haptic_set_enabled(args[0]); + } break; + case SYSCALL_HAPTIC_GET_ENABLED: { + args[0] = haptic_get_enabled(); + } break; + case SYSCALL_HAPTIC_TEST: { + args[0] = haptic_test(args[0]); + } break; + case SYSCALL_HAPTIC_PLAY: { + args[0] = haptic_play(args[0]); + } break; + case SYSCALL_HAPTIC_PLAY_CUSTOM: { + args[0] = haptic_play_custom(args[0], args[1]); + } break; +#endif + +#ifdef USE_OPTIGA + /*optiga_sign_result optiga_sign(uint8_t index, const uint8_t *digest, + size_t digest_size, uint8_t + *signature, size_t max_sig_size, size_t *sig_size); + + */ + case SYSCALL_OPTIGA_CERT_SIZE: { + uint8_t index = args[0]; + size_t *cert_size = (size_t *)args[1]; + args[0] = optiga_cert_size(index, cert_size); + } break; + case SYSCALL_OPTIGA_READ_CERT: { + uint8_t index = args[0]; + uint8_t *cert = (uint8_t *)args[1]; + size_t max_cert_size = args[2]; + size_t *cert_size = (size_t *)args[3]; + args[0] = optiga_read_cert(index, cert, max_cert_size, cert_size); + } break; + case SYSCALL_OPTIGA_READ_SEC: { + uint8_t *sec = (uint8_t *)args[0]; + args[0] = optiga_read_sec(sec); + } break; + case SYSCALL_OPTIGA_RANDOM_BUFFER: { + uint8_t *dest = (uint8_t *)args[0]; + size_t size = args[1]; + args[0] = optiga_random_buffer(dest, size); + } break; +#if PYOPT == 0 + case SYSCALL_OPTIGA_SET_SEC_MAX: { + optiga_set_sec_max(); + } break; +#endif +#endif + case SYSCALL_STORAGE_INIT: { + storage_init_callback = (PIN_UI_WAIT_CALLBACK)args[0]; + const uint8_t *salt = (const uint8_t *)args[1]; + uint16_t salt_len = args[2]; + mpu_reconfig(MPU_MODE_STORAGE); + storage_init(storage_init_callback_wrapper, salt, salt_len); + } break; + case SYSCALL_STORAGE_WIPE: { + mpu_reconfig(MPU_MODE_STORAGE); + storage_wipe(); + } break; + case SYSCALL_STORAGE_IS_UNLOCKED: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_is_unlocked(); + } break; + case SYSCALL_STORAGE_LOCK: { + mpu_reconfig(MPU_MODE_STORAGE); + storage_lock(); + } break; + case SYSCALL_STORAGE_UNLOCK: { + const uint8_t *pin = (const uint8_t *)args[0]; + size_t pin_len = args[1]; + const uint8_t *ext_salt = (const uint8_t *)args[2]; + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_unlock(pin, pin_len, ext_salt); + } break; + case SYSCALL_STORAGE_HAS_PIN: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_has_pin(); + } break; + case SYSCALL_STORAGE_PIN_FAILS_INCREASE: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_pin_fails_increase(); + } break; + case SYSCALL_STORAGE_GET_PIN_REM: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_get_pin_rem(); + } break; + case SYSCALL_STORAGE_CHANGE_PIN: { + const uint8_t *oldpin = (const uint8_t *)args[0]; + size_t oldpin_len = args[1]; + const uint8_t *newpin = (const uint8_t *)args[2]; + size_t newpin_len = args[3]; + const uint8_t *old_ext_salt = (const uint8_t *)args[4]; + const uint8_t *new_ext_salt = (const uint8_t *)args[5]; + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_change_pin(oldpin, oldpin_len, newpin, newpin_len, + old_ext_salt, new_ext_salt); + } break; + case SYSCALL_STORAGE_ENSURE_NOT_WIPE_CODE: { + const uint8_t *pin = (const uint8_t *)args[0]; + size_t pin_len = args[1]; + mpu_reconfig(MPU_MODE_STORAGE); + storage_ensure_not_wipe_code(pin, pin_len); + } break; + case SYSCALL_STORAGE_HAS_WIPE_CODE: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_has_wipe_code(); + } break; + case SYSCALL_STORAGE_CHANGE_WIPE_CODE: { + const uint8_t *pin = (const uint8_t *)args[0]; + size_t pin_len = args[1]; + const uint8_t *ext_salt = (const uint8_t *)args[2]; + const uint8_t *wipe_code = (const uint8_t *)args[3]; + size_t wipe_code_len = args[4]; + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_change_wipe_code(pin, pin_len, ext_salt, wipe_code, + wipe_code_len); + } break; + case SYSCALL_STORAGE_HAS: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_has((uint16_t)args[0]); + } break; + + case SYSCALL_STORAGE_GET: { + uint16_t key = (uint16_t)args[0]; + void *val = (void *)args[1]; + uint16_t max_len = (uint16_t)args[2]; + uint16_t *len = (uint16_t *)args[3]; + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_get(key, val, max_len, len); + } break; + case SYSCALL_STORAGE_SET: { + uint16_t key = (uint16_t)args[0]; + const void *val = (const void *)args[1]; + uint16_t len = (uint16_t)args[2]; + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_set(key, val, len); + } break; + case SYSCALL_STORAGE_DELETE: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_delete((uint16_t)args[0]); + } break; + case SYSCALL_STORAGE_SET_COUNTER: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_set_counter((uint16_t)args[0], args[1]); + } break; + case SYSCALL_STORAGE_NEXT_COUNTER: { + mpu_reconfig(MPU_MODE_STORAGE); + args[0] = storage_next_counter((uint16_t)args[0], (uint32_t *)args[1]); + } break; + case SYSCALL_ENTROPY_GET: { + uint8_t *buf = (uint8_t *)args[0]; + entropy_get(buf); + } break; + case SYSCALL_TRANSLATIONS_WRITE: { + const uint8_t *data = (const uint8_t *)args[0]; + uint32_t offset = args[1]; + uint32_t len = args[2]; + args[0] = translations_write(data, offset, len); + } break; + case SYSCALL_TRANSLATIONS_READ: { + uint32_t *len = (uint32_t *)args[0]; + uint32_t offset = args[1]; + args[0] = (uint32_t)translations_read(len, offset); + } break; + case SYSCALL_TRANSLATIONS_ERASE: { + translations_erase(); + } break; + case SYSCALL_TRANSLATIONS_AREA_BYTESIZE: { + args[0] = translations_area_bytesize(); + } break; + case SYSCALL_RNG_GET: { + args[0] = rng_get(); + } break; + case SYSCALL_FIRMWARE_GET_VENDOR: { + args[0] = firmware_get_vendor((char *)args[0], args[1]); + } break; + case SYSCALL_FIRMWARE_CALC_HASH: { + const uint8_t *challenge = (const uint8_t *)args[0]; + size_t challenge_len = args[1]; + uint8_t *hash = (uint8_t *)args[2]; + size_t hash_len = args[3]; + firmware_hash_callback = (firmware_hash_callback_t)args[4]; + void *callback_context = (void *)args[5]; + + args[0] = + firmware_calc_hash(challenge, challenge_len, hash, hash_len, + firmware_hash_callback_wrapper, callback_context); + } break; + default: + args[0] = 0xffffffff; + break; + } +} + +#endif // SYSCALL_DISPATCH diff --git a/core/embed/trezorhal/stm32f4/syscall_numbers.h b/core/embed/trezorhal/stm32f4/syscall_numbers.h new file mode 100644 index 0000000000..adc0d5b563 --- /dev/null +++ b/core/embed/trezorhal/stm32f4/syscall_numbers.h @@ -0,0 +1,146 @@ +/* + * 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 SYSCALL_NUMBERS_H +#define SYSCALL_NUMBERS_H + +typedef enum { + + // Syscalls numbers + SYSCALL_SYSTICK_CYCLES = 1, + SYSCALL_SYSTICK_MS, + SYSCALL_SYSTICK_US, + SYSCALL_SYSTICK_US_TO_CYCLES, + + SYSCALL_SECURE_SHUTDOWN, + SYSCALL_REBOOT, + SYSCALL_REBOOT_TO_BOOTLOADER, + SYSCALL_REBOOT_AND_UPGRADE, + + SYSCALL_SHA256_INIT, + SYSCALL_SHA256_UPDATE, + SYSCALL_SHA256_FINAL, + SYSCALL_SHA256_CALC, + + SYSCALL_DISPLAY_SET_BACKLIGHT, + SYSCALL_DISPLAY_GET_BACKLIGHT, + SYSCALL_DISPLAY_SET_ORIENTATION, + SYSCALL_DISPLAY_GET_ORIENTATION, + SYSCALL_DISPLAY_GET_FB_INFO, + SYSCALL_DISPLAY_WAIT_FOR_SYNC, + SYSCALL_DISPLAY_REFRESH, + + SYSCALL_USB_INIT, + SYSCALL_USB_DEINIT, + SYSCALL_USB_START, + SYSCALL_USB_STOP, + SYSCALL_USB_CONFIGURED, + + SYSCALL_USB_HID_ADD, + SYSCALL_USB_HID_CAN_READ, + SYSCALL_USB_HID_CAN_WRITE, + SYSCALL_USB_HID_READ, + SYSCALL_USB_HID_WRITE, + SYSCALL_USB_HID_READ_SELECT, + SYSCALL_USB_HID_READ_BLOCKING, + SYSCALL_USB_HID_WRITE_BLOCKING, + SYSCALL_USB_VCP_ADD, + SYSCALL_USB_VCP_CAN_READ, + SYSCALL_USB_VCP_CAN_WRITE, + SYSCALL_USB_VCP_READ, + SYSCALL_USB_VCP_WRITE, + SYSCALL_USB_VCP_READ_BLOCKING, + SYSCALL_USB_VCP_WRITE_BLOCKING, + SYSCALL_USB_WEBUSB_ADD, + SYSCALL_USB_WEBUSB_CAN_READ, + SYSCALL_USB_WEBUSB_CAN_WRITE, + SYSCALL_USB_WEBUSB_READ, + SYSCALL_USB_WEBUSB_WRITE, + SYSCALL_USB_WEBUSB_READ_SELECT, + SYSCALL_USB_WEBUSB_READ_BLOCKING, + SYSCALL_USB_WEBUSB_WRITE_BLOCKING, + + SYSCALL_SDCARD_POWER_ON, + SYSCALL_SDCARD_POWER_OFF, + SYSCALL_SDCARD_IS_PRESENT, + SYSCALL_SDCARD_GET_CAPACITY, + SYSCALL_SDCARD_READ_BLOCKS, + SYSCALL_SDCARD_WRITE_BLOCKS, + + SYSCALL_UNIT_VARIANT_PRESENT, + SYSCALL_UNIT_VARIANT_GET_COLOR, + SYSCALL_UNIT_VARIANT_GET_PACKAGING, + SYSCALL_UNIT_VARIANT_GET_BTCONLY, + SYSCALL_UNIT_VARIANT_IS_SD_HOTSWAP_ENABLED, + + SYSCALL_SECRET_BOOTLOADER_LOCKED, + + SYSCALL_BUTTON_READ, + SYSCALL_BUTTON_STATE_LEFT, + SYSCALL_BUTTON_STATE_RIGHT, + + SYSCALL_TOUCH_GET_EVENT, + + SYSCALL_HAPTIC_SET_ENABLED, + SYSCALL_HAPTIC_GET_ENABLED, + SYSCALL_HAPTIC_TEST, + SYSCALL_HAPTIC_PLAY, + SYSCALL_HAPTIC_PLAY_CUSTOM, + + SYSCALL_OPTIGA_SIGN, + SYSCALL_OPTIGA_CERT_SIZE, + SYSCALL_OPTIGA_READ_CERT, + SYSCALL_OPTIGA_READ_SEC, + SYSCALL_OPTIGA_RANDOM_BUFFER, + SYSCALL_OPTIGA_SET_SEC_MAX, + + SYSCALL_STORAGE_INIT, + SYSCALL_STORAGE_WIPE, + SYSCALL_STORAGE_IS_UNLOCKED, + SYSCALL_STORAGE_LOCK, + SYSCALL_STORAGE_UNLOCK, + SYSCALL_STORAGE_HAS_PIN, + SYSCALL_STORAGE_PIN_FAILS_INCREASE, + SYSCALL_STORAGE_GET_PIN_REM, + SYSCALL_STORAGE_CHANGE_PIN, + SYSCALL_STORAGE_ENSURE_NOT_WIPE_CODE, + SYSCALL_STORAGE_HAS_WIPE_CODE, + SYSCALL_STORAGE_CHANGE_WIPE_CODE, + SYSCALL_STORAGE_HAS, + SYSCALL_STORAGE_GET, + SYSCALL_STORAGE_SET, + SYSCALL_STORAGE_DELETE, + SYSCALL_STORAGE_SET_COUNTER, + SYSCALL_STORAGE_NEXT_COUNTER, + + SYSCALL_ENTROPY_GET, + + SYSCALL_TRANSLATIONS_WRITE, + SYSCALL_TRANSLATIONS_READ, + SYSCALL_TRANSLATIONS_ERASE, + SYSCALL_TRANSLATIONS_AREA_BYTESIZE, + + SYSCALL_RNG_GET, + + SYSCALL_FIRMWARE_GET_VENDOR, + SYSCALL_FIRMWARE_CALC_HASH, + +} syscall_number_t; + +#endif // SYSCALL_NUMBERS_H \ No newline at end of file diff --git a/core/embed/trezorhal/stm32f4/syscall_stubs.c b/core/embed/trezorhal/stm32f4/syscall_stubs.c new file mode 100644 index 0000000000..1da1d3ef17 --- /dev/null +++ b/core/embed/trezorhal/stm32f4/syscall_stubs.c @@ -0,0 +1,616 @@ +/* + * 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 "syscall.h" + +#ifndef KERNEL_MODE + +// ============================================================================= +// systick.h +// ============================================================================= + +#include "systick.h" + +uint64_t __attribute__((no_stack_protector)) systick_cycles(void) { + return syscall_invoke0_ret64(SYSCALL_SYSTICK_CYCLES); +} + +uint64_t systick_us(void) { return syscall_invoke0_ret64(SYSCALL_SYSTICK_US); } + +uint32_t systick_ms(void) { return syscall_invoke0(SYSCALL_SYSTICK_MS); } + +uint64_t systick_us_to_cycles(uint64_t us) { + uint32_t arg0 = us & 0xFFFFFFFF; + uint32_t arg1 = us >> 32; + return syscall_invoke2_ret64(arg0, arg1, SYSCALL_SYSTICK_US_TO_CYCLES); +} + +// ============================================================================= +// bootutils.h +// ============================================================================= + +#include "bootutils.h" + +void secure_shutdown(void) { + syscall_invoke0(SYSCALL_SECURE_SHUTDOWN); + while (1) + ; +} + +void reboot_to_bootloader(void) { + syscall_invoke0(SYSCALL_REBOOT_TO_BOOTLOADER); + while (1) + ; +} + +void reboot_and_upgrade(const uint8_t hash[32]) { + syscall_invoke1(SYSCALL_REBOOT_AND_UPGRADE, (uint32_t)hash); + while (1) + ; +} + +void reboot(void) { + syscall_invoke0(SYSCALL_REBOOT); + while (1) + ; +} + +// ============================================================================= +// hash_processor.h +// ============================================================================= + +#include "hash_processor.h" + +void hash_processor_sha256_init(hash_sha265_context_t *ctx) { + syscall_invoke1((uint32_t)ctx, SYSCALL_SHA256_INIT); +} + +// Feed the hash next chunk of data +void hash_processor_sha256_update(hash_sha265_context_t *ctx, + const uint8_t *data, uint32_t len) { + syscall_invoke3((uint32_t)ctx, (uint32_t)data, len, SYSCALL_SHA256_UPDATE); +} + +// Finalize the hash calculation, retrieve the digest +void hash_processor_sha256_final(hash_sha265_context_t *ctx, uint8_t *output) { + syscall_invoke2((uint32_t)ctx, (uint32_t)output, SYSCALL_SHA256_FINAL); +} + +void hash_processor_sha256_calc(const uint8_t *data, uint32_t len, + uint8_t *hash) { + syscall_invoke3((uint32_t)data, len, (uint32_t)hash, SYSCALL_SHA256_CALC); +} + +// ============================================================================= +// xdisplay.h +// ============================================================================= + +#include "display.h" + +int display_set_backlight(int level) { + return (int)syscall_invoke1((uint32_t)level, SYSCALL_DISPLAY_SET_BACKLIGHT); +} + +int display_get_backlight(void) { + return (int)syscall_invoke0(SYSCALL_DISPLAY_GET_BACKLIGHT); +} + +int display_set_orientation(int angle) { + return (int)syscall_invoke1((uint32_t)angle, SYSCALL_DISPLAY_SET_ORIENTATION); +} + +int display_get_orientation(void) { + return (int)syscall_invoke0(SYSCALL_DISPLAY_GET_ORIENTATION); +} + +#ifdef XFRAMEBUFFER + +display_fb_info_t display_get_frame_buffer(void) { + display_fb_info_t info; + syscall_invoke1((uint32_t)&info, SYSCALL_DISPLAY_GET_FB_INFO); + return info; +} + +#else // XFRAMEBUFFER + +void display_wait_for_sync(void) { + syscall_invoke0(SYSCALL_DISPLAY_WAIT_FOR_SYNC); +} +#endif + +void display_refresh(void) { syscall_invoke0(SYSCALL_DISPLAY_REFRESH); } + +// ============================================================================= +// usb.h +// ============================================================================= + +#include "usb.h" + +secbool usb_init(const usb_dev_info_t *dev_info) { + return (secbool)syscall_invoke1((uint32_t)dev_info, SYSCALL_USB_INIT); +} + +void usb_deinit(void) { syscall_invoke0(SYSCALL_USB_DEINIT); } + +secbool usb_start(void) { return (secbool)syscall_invoke0(SYSCALL_USB_START); } + +void usb_stop(void) { syscall_invoke0(SYSCALL_USB_STOP); } + +secbool usb_configured(void) { + return (secbool)syscall_invoke0(SYSCALL_USB_CONFIGURED); +} + +// ============================================================================= +// usb_hid.h +// ============================================================================= + +#include "usb_hid.h" + +secbool usb_hid_add(const usb_hid_info_t *hid_info) { + return (secbool)syscall_invoke1((uint32_t)hid_info, SYSCALL_USB_HID_ADD); +} + +secbool usb_hid_can_read(uint8_t iface_num) { + return (secbool)syscall_invoke1((uint32_t)iface_num, + SYSCALL_USB_HID_CAN_READ); +} + +secbool usb_hid_can_write(uint8_t iface_num) { + return (secbool)syscall_invoke1((uint32_t)iface_num, + SYSCALL_USB_HID_CAN_WRITE); +} + +int usb_hid_read(uint8_t iface_num, uint8_t *buf, uint32_t len) { + return (int)syscall_invoke3((uint32_t)iface_num, (uint32_t)buf, len, + SYSCALL_USB_HID_READ); +} + +int usb_hid_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { + return (int)syscall_invoke3((uint32_t)iface_num, (uint32_t)buf, len, + SYSCALL_USB_HID_WRITE); +} + +int usb_hid_read_select(uint32_t timeout) { + return (int)syscall_invoke1(timeout, SYSCALL_USB_HID_READ_SELECT); +} + +int usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, + int timeout) { + return (int)syscall_invoke4((uint32_t)iface_num, (uint32_t)buf, len, timeout, + SYSCALL_USB_HID_READ_BLOCKING); +} + +int usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, + int timeout) { + return (int)syscall_invoke4((uint32_t)iface_num, (uint32_t)buf, len, timeout, + SYSCALL_USB_HID_WRITE_BLOCKING); +} + +// ============================================================================= +// usb_vcp.h +// ============================================================================= + +#include "usb_vcp.h" + +secbool usb_vcp_add(const usb_vcp_info_t *vcp_info) { + return (secbool)syscall_invoke1((uint32_t)vcp_info, SYSCALL_USB_VCP_ADD); +} + +secbool usb_vcp_can_read(uint8_t iface_num) { + return (secbool)syscall_invoke1((uint32_t)iface_num, + SYSCALL_USB_VCP_CAN_READ); +} + +secbool usb_vcp_can_write(uint8_t iface_num) { + return (secbool)syscall_invoke1((uint32_t)iface_num, + SYSCALL_USB_VCP_CAN_WRITE); +} + +int usb_vcp_read(uint8_t iface_num, uint8_t *buf, uint32_t len) { + return (int)syscall_invoke3((uint32_t)iface_num, (uint32_t)buf, len, + SYSCALL_USB_VCP_READ); +} + +int usb_vcp_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { + return (int)syscall_invoke3((uint32_t)iface_num, (uint32_t)buf, len, + SYSCALL_USB_VCP_WRITE); +} + +int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, + int timeout) { + return (int)syscall_invoke4((uint32_t)iface_num, (uint32_t)buf, len, timeout, + SYSCALL_USB_VCP_READ_BLOCKING); +} + +int usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, + int timeout) { + return (int)syscall_invoke4((uint32_t)iface_num, (uint32_t)buf, len, timeout, + SYSCALL_USB_VCP_WRITE_BLOCKING); +} + +// ============================================================================= +// usb_webusb.h +// ============================================================================= + +#include "usb_webusb.h" + +secbool usb_webusb_add(const usb_webusb_info_t *webusb_info) { + return (secbool)syscall_invoke1((uint32_t)webusb_info, + SYSCALL_USB_WEBUSB_ADD); +} + +secbool usb_webusb_can_read(uint8_t iface_num) { + return (secbool)syscall_invoke1((uint32_t)iface_num, + SYSCALL_USB_WEBUSB_CAN_READ); +} + +secbool usb_webusb_can_write(uint8_t iface_num) { + return (secbool)syscall_invoke1((uint32_t)iface_num, + SYSCALL_USB_WEBUSB_CAN_WRITE); +} + +int usb_webusb_read(uint8_t iface_num, uint8_t *buf, uint32_t len) { + return (int)syscall_invoke3((uint32_t)iface_num, (uint32_t)buf, len, + SYSCALL_USB_WEBUSB_READ); +} + +int usb_webusb_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { + return (int)syscall_invoke3((uint32_t)iface_num, (uint32_t)buf, len, + SYSCALL_USB_WEBUSB_WRITE); +} + +int usb_webusb_read_select(uint32_t timeout) { + return (int)syscall_invoke1(timeout, SYSCALL_USB_WEBUSB_READ_SELECT); +} + +int usb_webusb_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, + int timeout) { + return (int)syscall_invoke4((uint32_t)iface_num, (uint32_t)buf, len, timeout, + SYSCALL_USB_WEBUSB_READ_BLOCKING); +} + +int usb_webusb_write_blocking(uint8_t iface_num, const uint8_t *buf, + uint32_t len, int timeout) { + return (int)syscall_invoke4((uint32_t)iface_num, (uint32_t)buf, len, timeout, + SYSCALL_USB_WEBUSB_WRITE_BLOCKING); +} + +// ============================================================================= +// sdcard.h +// ============================================================================= + +#include "sdcard.h" + +secbool sdcard_power_on(void) { + return (secbool)syscall_invoke0(SYSCALL_SDCARD_POWER_ON); +} + +void sdcard_power_off(void) { syscall_invoke0(SYSCALL_SDCARD_POWER_OFF); } + +secbool sdcard_is_present(void) { + return (secbool)syscall_invoke0(SYSCALL_SDCARD_IS_PRESENT); +} + +uint64_t sdcard_get_capacity_in_bytes(void) { + return syscall_invoke0_ret64(SYSCALL_SDCARD_GET_CAPACITY); +} + +secbool __wur sdcard_read_blocks(uint32_t *dest, uint32_t block_num, + uint32_t num_blocks) { + return (secbool)syscall_invoke3((uint32_t)dest, block_num, num_blocks, + SYSCALL_SDCARD_READ_BLOCKS); +} + +secbool __wur sdcard_write_blocks(const uint32_t *src, uint32_t block_num, + uint32_t num_blocks) { + return (secbool)syscall_invoke3((uint32_t)src, block_num, num_blocks, + SYSCALL_SDCARD_WRITE_BLOCKS); +} + +// ============================================================================= +// unit_variant.h +// ============================================================================= + +bool unit_variant_present(void) { + return (bool)syscall_invoke0(SYSCALL_UNIT_VARIANT_PRESENT); +} +uint8_t unit_variant_get_color(void) { + return (uint8_t)syscall_invoke0(SYSCALL_UNIT_VARIANT_GET_COLOR); +} + +uint8_t unit_variant_get_packaging(void) { + return (uint8_t)syscall_invoke0(SYSCALL_UNIT_VARIANT_GET_PACKAGING); +} + +bool unit_variant_get_btconly(void) { + return (bool)syscall_invoke0(SYSCALL_UNIT_VARIANT_GET_BTCONLY); +} + +bool unit_variant_is_sd_hotswap_enabled(void) { + return (bool)syscall_invoke0(SYSCALL_UNIT_VARIANT_IS_SD_HOTSWAP_ENABLED); +} + +// ============================================================================= +// secret.h +// ============================================================================= + +secbool secret_bootloader_locked(void) { + return (secbool)syscall_invoke0(SYSCALL_SECRET_BOOTLOADER_LOCKED); +} + +// ============================================================================= +// button.h +// ============================================================================= + +#include "button.h" + +uint32_t button_read(void) { return syscall_invoke0(SYSCALL_BUTTON_READ); } + +char button_state_left(void) { + return (char)syscall_invoke0(SYSCALL_BUTTON_STATE_LEFT); +} +char button_state_right(void) { + return (char)syscall_invoke0(SYSCALL_BUTTON_STATE_RIGHT); +} + +// ============================================================================= +// touch.h +// ============================================================================= + +#include "touch.h" + +uint32_t touch_get_event(void) { + return syscall_invoke0(SYSCALL_TOUCH_GET_EVENT); +} + +// ============================================================================= +// haptic.h +// ============================================================================= + +#include "haptic.h" + +void haptic_set_enabled(bool enabled) { + syscall_invoke1((uint32_t)enabled, SYSCALL_HAPTIC_SET_ENABLED); +} + +bool haptic_get_enabled(void) { + return (bool)syscall_invoke0(SYSCALL_HAPTIC_GET_ENABLED); +} + +bool haptic_test(uint16_t duration_ms) { + return (bool)syscall_invoke1(duration_ms, SYSCALL_HAPTIC_TEST); +} + +bool haptic_play(haptic_effect_t effect) { + return (bool)syscall_invoke1((uint32_t)effect, SYSCALL_HAPTIC_PLAY); +} + +bool haptic_play_custom(int8_t amplitude_pct, uint16_t duration_ms) { + return (bool)syscall_invoke2((uint32_t)amplitude_pct, duration_ms, + SYSCALL_HAPTIC_PLAY_CUSTOM); +} + +// ============================================================================= +// optiga.h +// ============================================================================= + +#include "optiga.h" + +optiga_sign_result optiga_sign(uint8_t index, const uint8_t *digest, + size_t digest_size, uint8_t *signature, + size_t max_sig_size, size_t *sig_size) { + return (optiga_sign_result)syscall_invoke6( + index, (uint32_t)digest, digest_size, (uint32_t)signature, max_sig_size, + (uint32_t)sig_size, SYSCALL_OPTIGA_SIGN); +} + +bool optiga_cert_size(uint8_t index, size_t *cert_size) { + return (bool)syscall_invoke2(index, (uint32_t)cert_size, + SYSCALL_OPTIGA_CERT_SIZE); +} + +bool optiga_read_cert(uint8_t index, uint8_t *cert, size_t max_cert_size, + size_t *cert_size) { + return (bool)syscall_invoke4(index, (uint32_t)cert, max_cert_size, + (uint32_t)cert_size, SYSCALL_OPTIGA_READ_CERT); +} + +bool optiga_read_sec(uint8_t *sec) { + return (bool)syscall_invoke1((uint32_t)sec, SYSCALL_OPTIGA_READ_SEC); +} + +bool optiga_random_buffer(uint8_t *dest, size_t size) { + return (bool)syscall_invoke2((uint32_t)dest, size, + SYSCALL_OPTIGA_RANDOM_BUFFER); +} + +#if PYOPT == 0 +void optiga_set_sec_max(void) { syscall_invoke0(SYSCALL_OPTIGA_SET_SEC_MAX); } + +#endif + +// ============================================================================= +// storage.h +// ============================================================================= + +#include "storage.h" + +static PIN_UI_WAIT_CALLBACK storage_init_callback = NULL; + +static void storage_init_callback_wrapper(uint32_t wait, uint32_t progress, + enum storage_ui_message_t message) { + secbool retval = storage_init_callback(wait, progress, message); + syscall_return_from_callback(retval); +} + +void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt, + const uint16_t salt_len) { + storage_init_callback = callback; + + syscall_invoke3((uint32_t)storage_init_callback_wrapper, (uint32_t)salt, + salt_len, SYSCALL_STORAGE_INIT); +} + +void storage_wipe(void) { syscall_invoke0(SYSCALL_STORAGE_WIPE); } +secbool storage_is_unlocked(void) { + return (secbool)syscall_invoke0(SYSCALL_STORAGE_IS_UNLOCKED); +} + +void storage_lock(void) { syscall_invoke0(SYSCALL_STORAGE_LOCK); } + +secbool storage_unlock(const uint8_t *pin, size_t pin_len, + const uint8_t *ext_salt) { + return (secbool)syscall_invoke3((uint32_t)pin, pin_len, (uint32_t)ext_salt, + SYSCALL_STORAGE_UNLOCK); +} + +secbool storage_has_pin(void) { + return (secbool)syscall_invoke0(SYSCALL_STORAGE_HAS_PIN); +} +secbool storage_pin_fails_increase(void) { + return (secbool)syscall_invoke0(SYSCALL_STORAGE_PIN_FAILS_INCREASE); +} + +uint32_t storage_get_pin_rem(void) { + return syscall_invoke0(SYSCALL_STORAGE_GET_PIN_REM); +} + +secbool storage_change_pin(const uint8_t *oldpin, size_t oldpin_len, + const uint8_t *newpin, size_t newpin_len, + const uint8_t *old_ext_salt, + const uint8_t *new_ext_salt) { + return (secbool)syscall_invoke6( + (uint32_t)oldpin, oldpin_len, (uint32_t)newpin, newpin_len, + (uint32_t)old_ext_salt, (uint32_t)new_ext_salt, + SYSCALL_STORAGE_CHANGE_PIN); +} + +void storage_ensure_not_wipe_code(const uint8_t *pin, size_t pin_len) { + syscall_invoke2((uint32_t)pin, pin_len, SYSCALL_STORAGE_ENSURE_NOT_WIPE_CODE); +} + +secbool storage_has_wipe_code(void) { + return (secbool)syscall_invoke0(SYSCALL_STORAGE_HAS_WIPE_CODE); +} + +secbool storage_change_wipe_code(const uint8_t *pin, size_t pin_len, + const uint8_t *ext_salt, + const uint8_t *wipe_code, + size_t wipe_code_len) { + return (secbool)syscall_invoke5((uint32_t)pin, pin_len, (uint32_t)ext_salt, + (uint32_t)wipe_code, wipe_code_len, + SYSCALL_STORAGE_CHANGE_WIPE_CODE); +} + +secbool storage_has(const uint16_t key) { + return (secbool)syscall_invoke1(key, SYSCALL_STORAGE_HAS); +} + +secbool storage_get(const uint16_t key, void *val, const uint16_t max_len, + uint16_t *len) { + return (secbool)syscall_invoke4(key, (uint32_t)val, max_len, (uint32_t)len, + SYSCALL_STORAGE_GET); +} + +secbool storage_set(const uint16_t key, const void *val, const uint16_t len) { + return (secbool)syscall_invoke3(key, (uint32_t)val, len, SYSCALL_STORAGE_SET); +} + +secbool storage_delete(const uint16_t key) { + return (secbool)syscall_invoke1(key, SYSCALL_STORAGE_DELETE); +} + +secbool storage_set_counter(const uint16_t key, const uint32_t count) { + return (secbool)syscall_invoke2(key, count, SYSCALL_STORAGE_SET_COUNTER); +} + +secbool storage_next_counter(const uint16_t key, uint32_t *count) { + return (secbool)syscall_invoke2(key, (uint32_t)count, + SYSCALL_STORAGE_NEXT_COUNTER); +} + +// ============================================================================= +// entropy.h +// ============================================================================= + +void entropy_get(uint8_t *buf) { + syscall_invoke1((uint32_t)buf, SYSCALL_ENTROPY_GET); +} + +// ============================================================================= +// translations.h +// ============================================================================= + +#include "translations.h" + +bool translations_write(const uint8_t *data, uint32_t offset, uint32_t len) { + return (bool)syscall_invoke3((uint32_t)data, offset, len, + SYSCALL_TRANSLATIONS_WRITE); +} + +const uint8_t *translations_read(uint32_t *len, uint32_t offset) { + return (const uint8_t *)syscall_invoke2((uint32_t)len, offset, + SYSCALL_TRANSLATIONS_READ); +} + +void translations_erase(void) { syscall_invoke0(SYSCALL_TRANSLATIONS_ERASE); } + +uint32_t translations_area_bytesize(void) { + return syscall_invoke0(SYSCALL_TRANSLATIONS_AREA_BYTESIZE); +} + +// ============================================================================= +// rng.h +// ============================================================================= + +#include "rng.h" + +uint32_t rng_get(void) { return syscall_invoke0(SYSCALL_RNG_GET); } + +// ============================================================================= +// fwutils.h +// ============================================================================= + +#include "fwutils.h" + +secbool firmware_get_vendor(char *buff, size_t buff_size) { + return syscall_invoke2((uint32_t)buff, buff_size, + SYSCALL_FIRMWARE_GET_VENDOR); +} + +static firmware_hash_callback_t firmware_hash_callback = NULL; + +static void firmware_hash_callback_wrapper(void *context, uint32_t progress, + uint32_t total) { + firmware_hash_callback(context, progress, total); + syscall_return_from_callback(0); +} + +secbool firmware_calc_hash(const uint8_t *challenge, size_t challenge_len, + uint8_t *hash, size_t hash_len, + firmware_hash_callback_t callback, + void *callback_context) { + firmware_hash_callback = callback; + + return syscall_invoke6((uint32_t)challenge, challenge_len, (uint32_t)hash, + hash_len, (uint32_t)firmware_hash_callback_wrapper, + (uint32_t)callback_context, + SYSCALL_FIRMWARE_CALC_HASH); +} +#endif diff --git a/core/embed/trezorhal/stm32f4/systick.c b/core/embed/trezorhal/stm32f4/systick.c index 13a1b71eb4..5bfbe2cac2 100644 --- a/core/embed/trezorhal/stm32f4/systick.c +++ b/core/embed/trezorhal/stm32f4/systick.c @@ -21,6 +21,7 @@ #include #include "irq.h" +#include "mpu.h" #include "platform.h" #include "systemview.h" @@ -28,6 +29,8 @@ #include "systick_internal.h" #include "systimer.h" +#ifdef KERNEL_MODE + // SysTick driver state typedef struct { // Set if the driver is initialized @@ -158,6 +161,7 @@ uint64_t systick_us(void) { void SysTick_Handler(void) { SEGGER_SYSVIEW_RecordEnterISR(); + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); systick_driver_t* drv = &g_systick_driver; @@ -178,9 +182,12 @@ void SysTick_Handler(void) { systimer_dispatch_expired_timers(drv->cycles); } + mpu_restore(mpu_mode); SEGGER_SYSVIEW_RecordExitISR(); } +#endif // KERNEL_MODE + void systick_delay_us(uint64_t us) { uint64_t delay_cycles = systick_us_to_cycles(us); int64_t cycles_per_ms = systick_us_to_cycles(1000); diff --git a/core/embed/trezorhal/stm32f4/systimer.c b/core/embed/trezorhal/stm32f4/systimer.c index ca7ae63d28..10736a5b77 100644 --- a/core/embed/trezorhal/stm32f4/systimer.c +++ b/core/embed/trezorhal/stm32f4/systimer.c @@ -25,6 +25,8 @@ #include "systick_internal.h" #include "systimer.h" +#ifdef KERNEL_MODE + // Maximum number of registered user timer // // Consider different implementation (i.e. priority queue @@ -235,3 +237,5 @@ void systimer_dispatch_expired_timers(uint64_t cycles) { timer->callback(timer->context); } } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/touch/ft6x36.c b/core/embed/trezorhal/stm32f4/touch/ft6x36.c index f03ac46a33..e107bbf8ab 100644 --- a/core/embed/trezorhal/stm32f4/touch/ft6x36.c +++ b/core/embed/trezorhal/stm32f4/touch/ft6x36.c @@ -20,6 +20,8 @@ #include STM32_HAL_H #include TREZOR_BOARD +#ifdef KERNEL_MODE + #include #include #include @@ -554,3 +556,5 @@ uint32_t touch_get_event(void) { return event; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/usb/usb.c b/core/embed/trezorhal/stm32f4/usb/usb.c index 7b0bd295e1..b4e7a974fd 100644 --- a/core/embed/trezorhal/stm32f4/usb/usb.c +++ b/core/embed/trezorhal/stm32f4/usb/usb.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#ifdef KERNEL_MODE + #include STM32_HAL_H #include "usb.h" @@ -736,3 +738,5 @@ static const USBD_ClassTypeDef usb_class = { .GetDeviceQualifierDescriptor = NULL, .GetUsrStrDescriptor = usb_class_get_usrstr_desc, }; + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/usb/usb_class_hid.c b/core/embed/trezorhal/stm32f4/usb/usb_class_hid.c index 48feb58866..67512153af 100644 --- a/core/embed/trezorhal/stm32f4/usb/usb_class_hid.c +++ b/core/embed/trezorhal/stm32f4/usb/usb_class_hid.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#ifdef KERNEL_MODE + #include "common.h" #include "random_delays.h" @@ -444,3 +446,5 @@ static const USBD_ClassTypeDef usb_hid_class = { .GetDeviceQualifierDescriptor = NULL, .GetUsrStrDescriptor = NULL, }; + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/usb/usb_class_vcp.c b/core/embed/trezorhal/stm32f4/usb/usb_class_vcp.c index 7905d884f4..4559fef33b 100644 --- a/core/embed/trezorhal/stm32f4/usb/usb_class_vcp.c +++ b/core/embed/trezorhal/stm32f4/usb/usb_class_vcp.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#ifdef KERNEL_MODE + #include "common.h" #include "usb_internal.h" @@ -586,3 +588,5 @@ static const USBD_ClassTypeDef usb_vcp_class = { }; static const USBD_ClassTypeDef usb_vcp_data_class = {}; + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/usb/usb_class_webusb.c b/core/embed/trezorhal/stm32f4/usb/usb_class_webusb.c index 5d326517c3..8d9765829f 100644 --- a/core/embed/trezorhal/stm32f4/usb/usb_class_webusb.c +++ b/core/embed/trezorhal/stm32f4/usb/usb_class_webusb.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#ifdef KERNEL_MODE + #include "common.h" #include "random_delays.h" @@ -354,3 +356,5 @@ static const USBD_ClassTypeDef usb_webusb_class = { .GetDeviceQualifierDescriptor = NULL, .GetUsrStrDescriptor = NULL, }; + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/usb/usbd_conf.c b/core/embed/trezorhal/stm32f4/usb/usbd_conf.c index 598b47e128..2db2a64884 100644 --- a/core/embed/trezorhal/stm32f4/usb/usbd_conf.c +++ b/core/embed/trezorhal/stm32f4/usb/usbd_conf.c @@ -50,11 +50,15 @@ * ****************************************************************************** */ + +#ifdef KERNEL_MODE + /* Includes ------------------------------------------------------------------*/ #include STM32_HAL_H #include "usbd_core.h" #include "usb.h" #include "irq.h" +#include "mpu.h" #include "systemview.h" /* Private typedef -----------------------------------------------------------*/ @@ -796,9 +800,11 @@ void OTG_FS_IRQHandler(void) { #endif SEGGER_SYSVIEW_RecordEnterISR(); IRQ_ENTER(OTG_FS_IRQn); + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); if (pcd_fs_handle.Instance) { HAL_PCD_IRQHandler(&pcd_fs_handle); } + mpu_restore(mpu_mode); IRQ_EXIT(OTG_FS_IRQn); SEGGER_SYSVIEW_RecordExitISR(); } @@ -807,9 +813,11 @@ void OTG_FS_IRQHandler(void) { void OTG_HS_IRQHandler(void) { SEGGER_SYSVIEW_RecordEnterISR(); IRQ_ENTER(OTG_HS_IRQn); + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); if (pcd_hs_handle.Instance) { HAL_PCD_IRQHandler(&pcd_hs_handle); } + mpu_restore(mpu_mode); IRQ_EXIT(OTG_HS_IRQn); SEGGER_SYSVIEW_RecordExitISR(); } @@ -862,25 +870,31 @@ static void OTG_CMD_WKUP_Handler(PCD_HandleTypeDef *pcd_handle) { #if defined(USE_USB_FS) void OTG_FS_WKUP_IRQHandler(void) { IRQ_ENTER(OTG_FS_WKUP_IRQn); + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); if (pcd_fs_handle.Instance) { OTG_CMD_WKUP_Handler(&pcd_fs_handle); } /* Clear EXTI pending Bit*/ __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG(); + mpu_restore(mpu_mode); IRQ_EXIT(OTG_FS_WKUP_IRQn); } #endif #if defined(USE_USB_HS) void OTG_HS_WKUP_IRQHandler(void) { IRQ_ENTER(OTG_HS_WKUP_IRQn); + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); if (pcd_hs_handle.Instance) { OTG_CMD_WKUP_Handler(&pcd_hs_handle); } /* Clear EXTI pending Bit*/ __HAL_USB_HS_EXTI_CLEAR_FLAG(); + mpu_restore(mpu_mode); IRQ_EXIT(OTG_HS_WKUP_IRQn); } #endif #endif +#endif // KERNEL_MODE + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/core/embed/trezorhal/stm32f4/usb/usbd_core.c b/core/embed/trezorhal/stm32f4/usb/usbd_core.c index 2663a6d88c..5188125601 100644 --- a/core/embed/trezorhal/stm32f4/usb/usbd_core.c +++ b/core/embed/trezorhal/stm32f4/usb/usbd_core.c @@ -27,6 +27,8 @@ ****************************************************************************** */ +#ifdef KERNEL_MODE + /* Includes ------------------------------------------------------------------*/ #include "usbd_core.h" @@ -576,5 +578,7 @@ USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) * @} */ +#endif // KERNEL_MODE + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/core/embed/trezorhal/stm32f4/usb/usbd_ctlreq.c b/core/embed/trezorhal/stm32f4/usb/usbd_ctlreq.c index 31c97e5f63..6b4d2177c8 100644 --- a/core/embed/trezorhal/stm32f4/usb/usbd_ctlreq.c +++ b/core/embed/trezorhal/stm32f4/usb/usbd_ctlreq.c @@ -27,6 +27,8 @@ ****************************************************************************** */ +#ifdef KERNEL_MODE + /* Includes ------------------------------------------------------------------*/ #include "usbd_ctlreq.h" #include "usbd_ioreq.h" @@ -784,4 +786,6 @@ static uint8_t USBD_GetLen(const uint8_t *buf) * @} */ +#endif // KERNEL_MODE + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/core/embed/trezorhal/stm32f4/usb/usbd_ioreq.c b/core/embed/trezorhal/stm32f4/usb/usbd_ioreq.c index ebbdd3b152..c22e0eef62 100644 --- a/core/embed/trezorhal/stm32f4/usb/usbd_ioreq.c +++ b/core/embed/trezorhal/stm32f4/usb/usbd_ioreq.c @@ -27,6 +27,8 @@ ****************************************************************************** */ +#ifdef KERNEL_MODE + /* Includes ------------------------------------------------------------------*/ #include "usbd_ioreq.h" @@ -235,4 +237,6 @@ uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , uint8_t ep_addr) * @} */ +#endif // KERNEL_MODE + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/core/embed/trezorhal/stm32f4/util.s b/core/embed/trezorhal/stm32f4/util.S similarity index 100% rename from core/embed/trezorhal/stm32f4/util.s rename to core/embed/trezorhal/stm32f4/util.S diff --git a/core/embed/trezorhal/stm32f4/vectortable.s b/core/embed/trezorhal/stm32f4/vectortable.S similarity index 96% rename from core/embed/trezorhal/stm32f4/vectortable.s rename to core/embed/trezorhal/stm32f4/vectortable.S index 08b34f99f8..1cfec8c262 100644 --- a/core/embed/trezorhal/stm32f4/vectortable.s +++ b/core/embed/trezorhal/stm32f4/vectortable.S @@ -2,6 +2,8 @@ .text +#ifdef KERNEL_MODE + .global default_handler .type default_handler, STT_FUNC default_handler: @@ -126,4 +128,14 @@ vector_table: add_handler LTDC_ER_IRQHandler add_handler DMA2D_IRQHandler +#else + + .section .vector_table, "a" +vector_table: + .word main_stack_base // defined in linker script + .word reset_handler + + +#endif + .end diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c index 34de6abaee..d08911ae8c 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c @@ -39,6 +39,8 @@ #error "Incompatible display resolution" #endif +#ifdef KERNEL_MODE + // Display driver instance display_driver_t g_display_driver = { .initialized = false, @@ -170,3 +172,5 @@ int display_get_orientation(void) { return drv->orientation_angle; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c index 889c79545d..af3ff91e44 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c @@ -32,6 +32,7 @@ #include "gfx_bitblt.h" #include "irq.h" +#include "mpu.h" #ifndef BOARDLOADER #include "bg_copy.h" @@ -41,6 +42,8 @@ #error Framebuffer only supported on STM32U5 for now #endif +#ifdef KERNEL_MODE + // The following code supports only 1 or 2 frame buffers _Static_assert(FRAME_BUFFER_COUNT == 1 || FRAME_BUFFER_COUNT == 2); @@ -95,7 +98,7 @@ static void bg_copy_callback(void) { } // Interrupt routing handling TE signal -void DISPLAY_TE_INTERRUPT_HANDLER(void) { +static void display_te_interrupt_handler(void) { display_driver_t *drv = &g_display_driver; __HAL_GPIO_EXTI_CLEAR_FLAG(DISPLAY_TE_PIN); @@ -133,6 +136,12 @@ void DISPLAY_TE_INTERRUPT_HANDLER(void) { break; } } + +void DISPLAY_TE_INTERRUPT_HANDLER(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); + display_te_interrupt_handler(); + mpu_restore(mpu_mode); +} #endif display_fb_info_t display_get_frame_buffer(void) { @@ -277,6 +286,8 @@ void display_ensure_refreshed(void) { #endif } +#endif // KERNEL_MODE + void display_fill(const gfx_bitblt_t *bb) { display_fb_info_t fb = display_get_frame_buffer(); diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_io.c b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_io.c index fec5bf3c37..8976f552bc 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_io.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_io.c @@ -24,6 +24,8 @@ #include "irq.h" #include "mpu.h" +#ifdef KERNEL_MODE + __IO DISP_MEM_TYPE *const DISPLAY_CMD_ADDRESS = (__IO DISP_MEM_TYPE *const)((uint32_t)DISPLAY_MEMORY_BASE); __IO DISP_MEM_TYPE *const DISPLAY_DATA_ADDRESS = @@ -148,3 +150,5 @@ void display_io_init_te_interrupt(void) { NVIC_EnableIRQ(DISPLAY_TE_INTERRUPT_NUM); } #endif + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_nofb.c b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_nofb.c index 412427a0b9..c2f4c7e166 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_nofb.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_nofb.c @@ -24,6 +24,8 @@ #include "display_io.h" #include "display_panel.h" +#ifdef KERNEL_MODE + void display_refresh(void) { // If the framebuffer is not used the, we do not need // to refresh the display explicitly as we write the data @@ -49,6 +51,8 @@ static inline void set_window(const gfx_bitblt_t* bb) { bb->dst_y + bb->height + 1); } +#endif // KERNEL_MODE + // For future notice, if we ever want to do a new model using progressive // rendering. // diff --git a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_panel.c b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_panel.c index 0d9bcf4151..bfe0405702 100644 --- a/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_panel.c +++ b/core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_panel.c @@ -34,6 +34,8 @@ #include "panels/lx154a2482.h" #endif +#ifdef KERNEL_MODE + // using const volatile instead of #define results in binaries that change // only in 1-byte when the flag changes. // using #define leads compiler to over-optimize the code leading to bigger @@ -248,3 +250,5 @@ void display_panel_rotate(int angle) { lx154a2482_rotate(angle, &g_window_padding); #endif } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/bg_copy.c b/core/embed/trezorhal/stm32u5/bg_copy.c index a3d66d415f..ba54494bf6 100644 --- a/core/embed/trezorhal/stm32u5/bg_copy.c +++ b/core/embed/trezorhal/stm32u5/bg_copy.c @@ -1,8 +1,11 @@ #include "bg_copy.h" #include "irq.h" +#include "mpu.h" #include STM32_HAL_H +#ifdef KERNEL_MODE + #define MAX_DATA_SIZE 0xFFF0 static volatile uint32_t dma_transfer_remaining = 0; @@ -33,6 +36,8 @@ void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) { } void GPDMA1_Channel0_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); + if ((DMA_Handle.Instance->CSR & DMA_CSR_TCF) == 0) { // error, abort the transfer and allow the next one to start dma_data_transferred = 0; @@ -53,6 +58,8 @@ void GPDMA1_Channel0_IRQHandler(void) { bg_copy_callback(); } } + + mpu_restore(mpu_mode); } bool bg_copy_pending(void) { return dma_transfer_remaining > 0; } @@ -116,3 +123,5 @@ void bg_copy_abort(void) { data_src = NULL; data_dst = NULL; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/consumption_mask.c b/core/embed/trezorhal/stm32u5/consumption_mask.c index fcc51b3f32..3d81dc184e 100644 --- a/core/embed/trezorhal/stm32u5/consumption_mask.c +++ b/core/embed/trezorhal/stm32u5/consumption_mask.c @@ -20,6 +20,8 @@ #include STM32_HAL_H #include "rng.h" +#ifdef KERNEL_MODE + #define SAMPLES 119 #define TIMER_PERIOD 16000 // cca 10 KHz @ 160MHz @@ -138,3 +140,5 @@ void consumption_mask_init(void) { HAL_DMAEx_List_Start(&dma_handle); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/entropy.c b/core/embed/trezorhal/stm32u5/entropy.c index c05f2762ee..695371d304 100644 --- a/core/embed/trezorhal/stm32u5/entropy.c +++ b/core/embed/trezorhal/stm32u5/entropy.c @@ -27,6 +27,8 @@ #include "stm32u5xx_ll_utils.h" +#ifdef KERNEL_MODE + static uint8_t g_hw_entropy[HW_ENTROPY_LEN]; void entropy_init(void) { @@ -58,3 +60,5 @@ void entropy_init(void) { } void entropy_get(uint8_t *buf) { memcpy(buf, g_hw_entropy, HW_ENTROPY_LEN); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/fault_handlers.c b/core/embed/trezorhal/stm32u5/fault_handlers.c index d2cfd3bbd0..2e4bbc78f8 100644 --- a/core/embed/trezorhal/stm32u5/fault_handlers.c +++ b/core/embed/trezorhal/stm32u5/fault_handlers.c @@ -1,4 +1,7 @@ #include "common.h" +#include "mpu.h" + +#ifdef KERNEL_MODE void fault_handlers_init(void) { // Enable BUS fault and USAGE fault handlers @@ -13,12 +16,19 @@ void HardFault_Handler(void) { // Fix stack pointer __set_MSP((uint32_t)&_estack); + mpu_reconfig(MPU_MODE_DEFAULT); error_shutdown("(HF)"); } -void MemManage_Handler(void) { error_shutdown("(MM)"); } +void MemManage_Handler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(MM)"); +} -void BusFault_Handler(void) { error_shutdown("(BF)"); } +void BusFault_Handler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(BF)"); +} void UsageFault_Handler(void) { if (SCB->CFSR & SCB_CFSR_STKOF_Msk) { @@ -26,28 +36,41 @@ void UsageFault_Handler(void) { extern uint8_t _estack; // linker script symbol // Fix stack pointer __set_MSP((uint32_t)&_estack); + mpu_reconfig(MPU_MODE_DEFAULT); error_shutdown("(SO)"); } else { // Other error + mpu_reconfig(MPU_MODE_DEFAULT); error_shutdown("(UF)"); } } -void SecureFault_Handler(void) { error_shutdown("(SF)"); } +void SecureFault_Handler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(SF)"); +} -void GTZC_IRQHandler(void) { error_shutdown("(IA)"); } +void GTZC_IRQHandler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + error_shutdown("(IA)"); +} void NMI_Handler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); // Clock Security System triggered NMI if ((RCC->CIFR & RCC_CIFR_CSSF) != 0) { error_shutdown("(CS)"); } + mpu_restore(mpu_mode); } // from util.s extern void shutdown_privileged(void); void PVD_PVM_IRQHandler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); TIM1->CCR1 = 0; // turn off display backlight shutdown_privileged(); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/flash.c b/core/embed/trezorhal/stm32u5/flash.c index 3f72031cf7..f25c2ba6c8 100644 --- a/core/embed/trezorhal/stm32u5/flash.c +++ b/core/embed/trezorhal/stm32u5/flash.c @@ -26,6 +26,8 @@ #include "flash.h" #include "model.h" +#ifdef KERNEL_MODE + #ifdef STM32U585xx #define FLASH_BANK_PAGES 128 #define FLASH_SECTOR_COUNT (FLASH_BANK_PAGES * 2) @@ -213,3 +215,5 @@ secbool flash_write_block(uint16_t sector, uint32_t offset, const flash_block_t block) { return flash_write_quadword(sector, offset, block); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/flash_otp.c b/core/embed/trezorhal/stm32u5/flash_otp.c index f3c6163e01..9486ccf7a4 100644 --- a/core/embed/trezorhal/stm32u5/flash_otp.c +++ b/core/embed/trezorhal/stm32u5/flash_otp.c @@ -24,6 +24,8 @@ #include "flash.h" #include "mpu.h" +#ifdef KERNEL_MODE + void flash_otp_init() { // intentionally left empty } @@ -125,3 +127,5 @@ secbool flash_otp_is_locked(uint8_t block) { return is_locked; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c b/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c index d87ace2fdd..7b1168c50b 100644 --- a/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c +++ b/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c @@ -29,6 +29,8 @@ #include STM32_HAL_H +#ifdef KERNEL_MODE + // Maximum amplitude of the vibration effect // (DRV2625 supports 7-bit amplitude) #define MAX_AMPLITUDE 127 @@ -324,3 +326,5 @@ bool haptic_play_custom(int8_t amplitude_pct, uint16_t duration_ms) { bool haptic_test(uint16_t duration_ms) { return haptic_play_rtp(PRODTEST_EFFECT_AMPLITUDE, duration_ms); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/hash_processor.c b/core/embed/trezorhal/stm32u5/hash_processor.c index b9be38dbd9..6d048abfb5 100644 --- a/core/embed/trezorhal/stm32u5/hash_processor.c +++ b/core/embed/trezorhal/stm32u5/hash_processor.c @@ -4,8 +4,11 @@ #include STM32_HAL_H #include "irq.h" #include "memzero.h" +#include "mpu.h" #include "sha2.h" +#ifdef KERNEL_MODE + HASH_HandleTypeDef hhash = {0}; DMA_HandleTypeDef DMA_Handle = {0}; @@ -44,7 +47,11 @@ void hash_processor_init(void) { NVIC_EnableIRQ(GPDMA1_Channel12_IRQn); } -void GPDMA1_Channel12_IRQHandler(void) { HAL_DMA_IRQHandler(&DMA_Handle); } +void GPDMA1_Channel12_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); + HAL_DMA_IRQHandler(&DMA_Handle); + mpu_restore(mpu_mode); +} static void hash_processor_sha256_calc_dma(const uint8_t *data, uint32_t len, uint8_t *hash) { @@ -125,3 +132,5 @@ void hash_processor_sha256_final(hash_sha265_context_t *ctx, uint8_t *output) { memcpy(output, tmp_out, SHA256_DIGEST_LENGTH); memzero(tmp_out, sizeof(tmp_out)); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/i2c_bus.c b/core/embed/trezorhal/stm32u5/i2c_bus.c index 127aabed7f..2a0a1211aa 100644 --- a/core/embed/trezorhal/stm32u5/i2c_bus.c +++ b/core/embed/trezorhal/stm32u5/i2c_bus.c @@ -25,8 +25,11 @@ #include "common.h" #include "i2c_bus.h" #include "irq.h" +#include "mpu.h" #include "systimer.h" +#ifdef KERNEL_MODE + // Using calculation from STM32CubeMX // PCLKx as source, assumed 160MHz // Fast mode, freq = 400kHz, Rise time = 250ns, Fall time = 100ns @@ -865,30 +868,44 @@ static void i2c_bus_er_handler(i2c_bus_t* bus) { #ifdef I2C_INSTANCE_0 void I2C_INSTANCE_0_EV_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_ev_handler(&g_i2c_bus_driver[0]); + mpu_restore(mpu_mode); } void I2C_INSTANCE_0_ER_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_er_handler(&g_i2c_bus_driver[0]); + mpu_restore(mpu_mode); } #endif #ifdef I2C_INSTANCE_1 void I2C_INSTANCE_1_EV_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_ev_handler(&g_i2c_bus_driver[1]); + mpu_restore(mpu_mode); } void I2C_INSTANCE_1_ER_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_er_handler(&g_i2c_bus_driver[1]); + mpu_restore(mpu_mode); } #endif #ifdef I2C_INSTANCE_2 void I2C_INSTANCE_2_EV_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_ev_handler(&g_i2c_bus_driver[2]); + mpu_restore(mpu_mode); } void I2C_INSTANCE_2_ER_IRQHandler(void) { + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); i2c_bus_er_handler(&g_i2c_bus_driver[2]); + mpu_restore(mpu_mode); } #endif + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/limited_util.s b/core/embed/trezorhal/stm32u5/limited_util.S similarity index 100% rename from core/embed/trezorhal/stm32u5/limited_util.s rename to core/embed/trezorhal/stm32u5/limited_util.S diff --git a/core/embed/trezorhal/stm32u5/lowlevel.c b/core/embed/trezorhal/stm32u5/lowlevel.c index e30aa52673..7270180782 100644 --- a/core/embed/trezorhal/stm32u5/lowlevel.c +++ b/core/embed/trezorhal/stm32u5/lowlevel.c @@ -19,6 +19,8 @@ #include STM32_HAL_H +#ifdef KERNEL_MODE + #include "lowlevel.h" #include "common.h" #include "flash.h" @@ -310,3 +312,5 @@ secbool reset_flags_check(void) { void reset_flags_reset(void) { RCC->CSR |= RCC_CSR_RMVF; // clear the reset flags } + +#endif // #ifdef KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/monoctr.c b/core/embed/trezorhal/stm32u5/monoctr.c index 24171eab85..f44711b4ad 100644 --- a/core/embed/trezorhal/stm32u5/monoctr.c +++ b/core/embed/trezorhal/stm32u5/monoctr.c @@ -23,6 +23,8 @@ #include "mpu.h" #include "secret.h" +#ifdef KERNEL_MODE + static int32_t get_offset(monoctr_type_t type) { switch (type) { case MONOCTR_BOOTLOADER_VERSION: @@ -129,3 +131,5 @@ secbool monoctr_read(monoctr_type_t type, uint8_t *value) { return sectrue; } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/mpu.c b/core/embed/trezorhal/stm32u5/mpu.c index 5b3c1671fd..e0ab0adf1b 100644 --- a/core/embed/trezorhal/stm32u5/mpu.c +++ b/core/embed/trezorhal/stm32u5/mpu.c @@ -21,11 +21,14 @@ #include #include "common.h" +#include "irq.h" #include "model.h" #include "mpu.h" #include "stm32u5xx_ll_cortex.h" +#ifdef KERNEL_MODE + // region type #define MPUX_TYPE_FLASH_CODE 0 #define MPUX_TYPE_SRAM 1 @@ -115,6 +118,7 @@ static void mpu_set_attributes(void) { #define BOARDLOADER_SIZE SIZE_48K #define BOOTLOADER_SIZE BOOTLOADER_IMAGE_MAXSIZE #define FIRMWARE_SIZE FIRMWARE_IMAGE_MAXSIZE +#define COREAPP_SIZE (FIRMWARE_IMAGE_MAXSIZE - KERNEL_SIZE) #define STORAGE_START \ (FLASH_BASE + SECRET_SIZE + BOARDLOADER_SIZE + BOOTLOADER_SIZE) #define STORAGE_SIZE NORCOW_SECTOR_SIZE* STORAGE_AREAS_COUNT @@ -335,3 +339,5 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) { } void mpu_restore(mpu_mode_t mode) { mpu_reconfig(mode); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/platform.c b/core/embed/trezorhal/stm32u5/platform.c index 19feb4d5a4..393a43b530 100644 --- a/core/embed/trezorhal/stm32u5/platform.c +++ b/core/embed/trezorhal/stm32u5/platform.c @@ -23,6 +23,8 @@ #include "rng.h" #include TREZOR_BOARD +#ifdef KERNEL_MODE + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; @@ -213,3 +215,5 @@ void SystemInit(void) { // enable instruction cache in default 2-way mode ICACHE->CR = ICACHE_CR_EN; } + +#endif // #ifdef KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/sdcard.c b/core/embed/trezorhal/stm32u5/sdcard.c index 714a48d4e1..4d83000ae1 100644 --- a/core/embed/trezorhal/stm32u5/sdcard.c +++ b/core/embed/trezorhal/stm32u5/sdcard.c @@ -49,12 +49,15 @@ #include #include "irq.h" +#include "mpu.h" #include "sdcard.h" #define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC1_CLK_ENABLE() #define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC1_CLK_DISABLE() #define SDMMC_IRQn SDMMC1_IRQn +#ifdef KERNEL_MODE + static SD_HandleTypeDef sd_handle = {0}; // this function is inspired by functions in stm32f4xx_ll_sdmmc.c @@ -234,9 +237,11 @@ uint64_t sdcard_get_capacity_in_bytes(void) { void SDMMC1_IRQHandler(void) { IRQ_ENTER(SDIO_IRQn); + mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT); if (sd_handle.Instance) { HAL_SD_IRQHandler(&sd_handle); } + mpu_restore(mpu_mode); IRQ_EXIT(SDIO_IRQn); } @@ -333,3 +338,5 @@ secbool sdcard_write_blocks(const uint32_t *src, uint32_t block_num, return sectrue * (err == HAL_OK); } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/secret.c b/core/embed/trezorhal/stm32u5/secret.c index 17fb93d08b..47602e50b8 100644 --- a/core/embed/trezorhal/stm32u5/secret.c +++ b/core/embed/trezorhal/stm32u5/secret.c @@ -11,6 +11,8 @@ #include "rng.h" #include "secure_aes.h" +#ifdef KERNEL_MODE + static secbool bootloader_locked = secfalse; secbool secret_verify_header(void) { @@ -349,3 +351,5 @@ void secret_prepare_fw(secbool allow_run_with_secret, secbool trust_all) { secret_disable_access(); } } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/secure_aes.c b/core/embed/trezorhal/stm32u5/secure_aes.c index 61fa3cd8a0..94f8afe5c8 100644 --- a/core/embed/trezorhal/stm32u5/secure_aes.c +++ b/core/embed/trezorhal/stm32u5/secure_aes.c @@ -25,6 +25,8 @@ #include #include "memzero.h" +#ifdef KERNEL_MODE + #define AES_BLOCK_SIZE 16 secbool secure_aes_init(void) { @@ -199,3 +201,5 @@ secbool secure_aes_ecb_decrypt_hw(const uint8_t* input, size_t size, return sectrue; } + +#endif // KERNEL_MODE \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/syscall.c b/core/embed/trezorhal/stm32u5/syscall.c new file mode 120000 index 0000000000..4995488e2a --- /dev/null +++ b/core/embed/trezorhal/stm32u5/syscall.c @@ -0,0 +1 @@ +../stm32f4/syscall.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/syscall.h b/core/embed/trezorhal/stm32u5/syscall.h new file mode 120000 index 0000000000..8563747ddf --- /dev/null +++ b/core/embed/trezorhal/stm32u5/syscall.h @@ -0,0 +1 @@ +../stm32f4/syscall.h \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/syscall_dispatch.c b/core/embed/trezorhal/stm32u5/syscall_dispatch.c new file mode 120000 index 0000000000..f7542fb99e --- /dev/null +++ b/core/embed/trezorhal/stm32u5/syscall_dispatch.c @@ -0,0 +1 @@ +../stm32f4/syscall_dispatch.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/syscall_numbers.h b/core/embed/trezorhal/stm32u5/syscall_numbers.h new file mode 120000 index 0000000000..f2e572e964 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/syscall_numbers.h @@ -0,0 +1 @@ +../stm32f4/syscall_numbers.h \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/syscall_stubs.c b/core/embed/trezorhal/stm32u5/syscall_stubs.c new file mode 120000 index 0000000000..877f2904f0 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/syscall_stubs.c @@ -0,0 +1 @@ +../stm32f4/syscall_stubs.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/tamper.c b/core/embed/trezorhal/stm32u5/tamper.c index a2bbba546e..4f6cfb605d 100644 --- a/core/embed/trezorhal/stm32u5/tamper.c +++ b/core/embed/trezorhal/stm32u5/tamper.c @@ -19,9 +19,12 @@ #include #include +#include #include #include STM32_HAL_H +#ifdef KERNEL_MODE + // Fixes a typo in CMSIS Device library for STM32U5 #undef TAMP_CR3_ITAMP7NOER_Msk #undef TAMP_CR3_ITAMP7NOER @@ -234,6 +237,8 @@ void tamper_init(void) { // Interrupt handle for all tamper events // It displays an error message void TAMP_IRQHandler(void) { + mpu_reconfig(MPU_MODE_DEFAULT); + uint32_t sr = TAMP->SR; TAMP->SCR = sr; @@ -271,3 +276,5 @@ void TAMP_IRQHandler(void) { error_shutdown_ex("INTERNAL TAMPER", reason, NULL); #endif } + +#endif // KERNEL_MODE diff --git a/core/embed/trezorhal/stm32u5/util.s b/core/embed/trezorhal/stm32u5/util.S similarity index 99% rename from core/embed/trezorhal/stm32u5/util.s rename to core/embed/trezorhal/stm32u5/util.S index 827451624a..06258ded40 100644 --- a/core/embed/trezorhal/stm32u5/util.s +++ b/core/embed/trezorhal/stm32u5/util.S @@ -2,6 +2,8 @@ .text +#ifdef KERNEL_MODE + .global memset_reg .type memset_reg, STT_FUNC memset_reg: @@ -134,4 +136,6 @@ shutdown_privileged: ldr r0, =0 b . // loop forever +#endif + .end diff --git a/core/embed/trezorhal/stm32u5/vectortable.s b/core/embed/trezorhal/stm32u5/vectortable.S similarity index 97% rename from core/embed/trezorhal/stm32u5/vectortable.s rename to core/embed/trezorhal/stm32u5/vectortable.S index 2a9e9cb653..472414caeb 100644 --- a/core/embed/trezorhal/stm32u5/vectortable.s +++ b/core/embed/trezorhal/stm32u5/vectortable.S @@ -2,6 +2,8 @@ .text +#ifdef KERNEL_MODE + .global default_handler .type default_handler, STT_FUNC default_handler: @@ -174,4 +176,13 @@ vector_table: add_handler DSI_IRQHandler add_handler DCACHE2_IRQHandler +#else + + .section .vector_table, "a" +vector_table: + .word main_stack_base // defined in linker script + .word reset_handler + +#endif + .end diff --git a/core/embed/trezorhal/systick.h b/core/embed/trezorhal/systick.h index af2cb67793..71403c06f7 100644 --- a/core/embed/trezorhal/systick.h +++ b/core/embed/trezorhal/systick.h @@ -23,6 +23,8 @@ #include #include +#ifdef KERNEL_MODE + // Initializes systick subsystem // // Before calling this function, none of the other functions @@ -41,6 +43,8 @@ void systick_deinit(void); // has been changed. void systick_update_freq(void); +#endif // KERNEL_MODE + // ---------------------------------------------------------------------------- // Tick functions diff --git a/core/embed/trezorhal/systimer.h b/core/embed/trezorhal/systimer.h index cca0c27899..058e585b20 100644 --- a/core/embed/trezorhal/systimer.h +++ b/core/embed/trezorhal/systimer.h @@ -23,6 +23,8 @@ #include #include +#ifdef KERNEL_MODE + // Initializes systimer subsystem // // Before calling this function, none of the other functions @@ -90,4 +92,6 @@ systimer_key_t systimer_suspend(systimer_t* timer); // be the same as returned by `timer_suspend()`. void systimer_resume(systimer_t* timer, systimer_key_t key); +#endif // KERNEL_MODE + #endif // TREZORHAL_SYSTIMER_H diff --git a/core/embed/trezorhal/tamper.h b/core/embed/trezorhal/tamper.h index 5d3fe12b09..abfbe81266 100644 --- a/core/embed/trezorhal/tamper.h +++ b/core/embed/trezorhal/tamper.h @@ -22,6 +22,8 @@ #include +#ifdef KERNEL_MODE + // Tamper module enables the internal tamper detection on STM32 microcontroller // as well as external tamper input if it's available on the device @@ -35,4 +37,6 @@ void tamper_init(void); // are supported void tamper_test(uint32_t tamper_type); +#endif // KERNEL_MODE + #endif // TREZOR_HAL_TAMPER_H diff --git a/core/embed/trezorhal/touch.h b/core/embed/trezorhal/touch.h index 7b28534a7f..05843d1e36 100644 --- a/core/embed/trezorhal/touch.h +++ b/core/embed/trezorhal/touch.h @@ -4,6 +4,8 @@ #include #include "secbool.h" +#ifdef KERNEL_MODE + // Initializes the touch driver // // Powers on and initializes touch driver controller. @@ -48,6 +50,8 @@ secbool touch_set_sensitivity(uint8_t value); // The function should not be used together with `touch_get_event()`. secbool touch_activity(void); +#endif // KERNEL_MODE + // Returns the last event in packed 32-bit format // // Returns `0` if there's no event or the driver is not initialized. diff --git a/core/embed/trezorhal/xdisplay.h b/core/embed/trezorhal/xdisplay.h index 28f09485d9..80cdcb04d8 100644 --- a/core/embed/trezorhal/xdisplay.h +++ b/core/embed/trezorhal/xdisplay.h @@ -46,6 +46,8 @@ // MIPI - // - STM32U5A9J-DK Discovery Board +#ifdef KERNEL_MODE + // Specifies how display content should be handled during // initialization or deinitialization. typedef enum { @@ -69,6 +71,8 @@ void display_init(display_content_mode_t mode); // `display_init(DISPLAY_RETAIN_CONTENT)`. void display_deinit(display_content_mode_t mode); +#endif // KERNEL_MODE + // Sets display backlight level ranging from 0 (off)..255 (maximum). // // The default backligt level is 0. Without settings it diff --git a/core/site_scons/models/stm32f4_common.py b/core/site_scons/models/stm32f4_common.py index b778ea860d..c38b12e01f 100644 --- a/core/site_scons/models/stm32f4_common.py +++ b/core/site_scons/models/stm32f4_common.py @@ -53,12 +53,15 @@ def stm32f4_common_files(env, defines, sources, paths): "embed/trezorhal/stm32f4/mpu.c", "embed/trezorhal/stm32f4/platform.c", "embed/trezorhal/stm32f4/secret.c", + "embed/trezorhal/stm32f4/syscall.c", + "embed/trezorhal/stm32f4/syscall_dispatch.c", + "embed/trezorhal/stm32f4/syscall_stubs.c", "embed/trezorhal/stm32f4/systick.c", "embed/trezorhal/stm32f4/systimer.c", "embed/trezorhal/stm32f4/time_estimate.c", "embed/trezorhal/stm32f4/random_delays.c", "embed/trezorhal/stm32f4/rng.c", - "embed/trezorhal/stm32f4/vectortable.s", + "embed/trezorhal/stm32f4/vectortable.S", ] # boardloader needs separate assembler for some function unencumbered by various FW+bootloader hacks @@ -66,11 +69,11 @@ def stm32f4_common_files(env, defines, sources, paths): env_constraints = env.get("CONSTRAINTS") if env_constraints and "limited_util_s" in env_constraints: sources += [ - "embed/trezorhal/stm32f4/limited_util.s", + "embed/trezorhal/stm32f4/limited_util.S", ] else: sources += [ - "embed/trezorhal/stm32f4/util.s", + "embed/trezorhal/stm32f4/util.S", ] env.get("ENV")["SUFFIX"] = "stm32f4" diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py index 7d9c465673..0eea378cf6 100644 --- a/core/site_scons/models/stm32u5_common.py +++ b/core/site_scons/models/stm32u5_common.py @@ -64,14 +64,17 @@ def stm32u5_common_files(env, defines, sources, paths): "embed/trezorhal/stm32u5/platform.c", "embed/trezorhal/stm32u5/secret.c", "embed/trezorhal/stm32u5/secure_aes.c", + "embed/trezorhal/stm32u5/syscall.c", + "embed/trezorhal/stm32u5/syscall_dispatch.c", + "embed/trezorhal/stm32u5/syscall_stubs.c", "embed/trezorhal/stm32u5/systick.c", - "embed/trezorhal/stm32f4/systimer.c", + "embed/trezorhal/stm32u5/systimer.c", "embed/trezorhal/stm32u5/random_delays.c", "embed/trezorhal/stm32u5/rng.c", "embed/trezorhal/stm32u5/tamper.c", "embed/trezorhal/stm32u5/time_estimate.c", "embed/trezorhal/stm32u5/trustzone.c", - "embed/trezorhal/stm32u5/vectortable.s", + "embed/trezorhal/stm32u5/vectortable.S", ] # boardloader needs separate assembler for some function unencumbered by various FW+bootloader hacks @@ -79,11 +82,11 @@ def stm32u5_common_files(env, defines, sources, paths): env_constraints = env.get("CONSTRAINTS") if env_constraints and "limited_util_s" in env_constraints: sources += [ - "embed/trezorhal/stm32u5/limited_util.s", + "embed/trezorhal/stm32u5/limited_util.S", ] else: sources += [ - "embed/trezorhal/stm32u5/util.s", + "embed/trezorhal/stm32u5/util.S", ] env.get("ENV")["SUFFIX"] = "stm32u5"