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"