1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-12 18:49:07 +00:00

refactor(core/embed): split firmware into kernel & coreapp

[no changelog]
This commit is contained in:
cepetr 2024-08-13 07:47:59 +02:00
parent b42572a1bc
commit 854c4ae4d7
146 changed files with 5312 additions and 35 deletions

View File

@ -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
@ -77,6 +79,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)
@ -267,6 +272,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)" \
@ -319,6 +338,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)
@ -344,6 +369,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"

View File

@ -41,6 +41,7 @@ CPPPATH_MOD += [
'vendor/trezor-storage',
]
CPPDEFINES_MOD += [
'KERNEL_MODE',
'AES_128',
'AES_192',
'USE_KECCAK',

View File

@ -71,6 +71,7 @@ CPPPATH_MOD += [
'vendor/trezor-storage',
]
CPPDEFINES_MOD += [
'KERNEL_MODE',
'AES_128',
'AES_192',
'USE_KECCAK',

View File

@ -66,6 +66,7 @@ CPPPATH_MOD += [
'vendor/trezor-storage',
]
CPPDEFINES_MOD += [
'KERNEL_MODE',
'AES_128',
'AES_192',
'USE_KECCAK',

View File

@ -68,6 +68,7 @@ CPPPATH_MOD += [
'vendor/trezor-storage',
]
CPPDEFINES_MOD += [
'KERNEL_MODE',
'AES_128',
'AES_192',
'USE_KECCAK',

941
core/SConscript.coreapp Normal file
View File

@ -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,
)

View File

@ -89,6 +89,7 @@ CPPPATH_MOD += [
'vendor/trezor-crypto',
]
CPPDEFINES_MOD += [
'KERNEL_MODE',
'AES_128',
'AES_192',
('USE_BIP32_CACHE', '0'),

502
core/SConscript.kernel Normal file
View File

@ -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,
)

View File

@ -29,6 +29,7 @@ if NEW_RENDERING:
CCFLAGS_MOD = ''
CPPPATH_MOD = []
CPPDEFINES_MOD = [
'KERNEL_MODE',
'AES_128',
'USE_INSECURE_PRNG',
]

View File

@ -57,6 +57,10 @@ elif TREZOR_MODEL in ('T3T1',):
FONT_BOLD_UPPER=None
FONT_SUB=None
CPPDEFINES_MOD += [
'KERNEL_MODE',
]
# modtrezorcrypto
CPPPATH_MOD += [
'vendor/trezor-crypto',

View File

@ -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',

View File

@ -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)

View File

@ -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:

105
core/embed/coreapp/main.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include STM32_HAL_H
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#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);

View File

@ -0,0 +1 @@
memory_T.ld

View File

@ -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
}

View File

@ -0,0 +1 @@
memory_T.ld

View File

@ -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
}

View File

@ -0,0 +1 @@
memory_T3T1.ld

View File

@ -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
}

View File

@ -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 <alloca.h>
#endif // __INCLUDED_MPCONFIGPORT_H

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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; }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/*
* 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__))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -100,7 +100,6 @@ SECTIONS {
__fb_start = .;
*(.fb1*);
*(.fb2*);
*(.framebuffer_select*);
__fb_end = .;
. = ALIGN(4);
} >SRAM3

View File

@ -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:

191
core/embed/kernel/main.c Normal file
View File

@ -0,0 +1,191 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include 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 "i2c.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 <inttypes.h>
#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_I2C
i2c_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;
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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;
@ -98,3 +100,5 @@ bool unit_variant_is_sd_hotswap_enabled(void) {
#endif
#endif
}
#endif // KERNEL_MODE

View File

@ -4,7 +4,12 @@
#include <stdbool.h>
#include <stdint.h>
#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);

View File

@ -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

View File

@ -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

View File

@ -6,6 +6,8 @@
#include <stddef.h>
#include <stdint.h>
#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

View File

@ -35,6 +35,8 @@ Last tag must be terminator or all space used.
#include <stdint.h>
#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

View File

@ -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);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -22,8 +22,12 @@
#include <stdint.h>
#ifdef KERNEL_MODE
void entropy_init(void);
#endif
#define HW_ENTROPY_LEN (12 + 32)
void entropy_get(uint8_t *buf);

View File

@ -26,8 +26,12 @@
#include "platform.h"
#include "secbool.h"
#ifdef KERNEL_MODE
#include "flash_ll.h"
void flash_init(void);
#endif
#endif // TREZORHAL_FLASH_H

View File

@ -3,6 +3,8 @@
#include <common.h>
#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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -22,6 +22,8 @@
#include STM32_HAL_H
#ifdef KERNEL_MODE
void i2c_init(void);
void i2c_cycle(uint16_t idx);
HAL_StatusTypeDef i2c_transmit(uint16_t idx, uint8_t addr, uint8_t *data,
@ -35,4 +37,6 @@ HAL_StatusTypeDef i2c_mem_read(uint16_t idx, uint8_t addr, uint16_t mem_addr,
uint16_t mem_addr_size, uint8_t *data,
uint16_t len, uint32_t timeout);
#endif // KERNEL_MODE
#endif // TREZORHAL_I2C_H

View File

@ -24,6 +24,8 @@
#include <stddef.h>
#include <stdint.h>
#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

View File

@ -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__

View File

@ -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

View File

@ -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
@ -61,4 +63,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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -17,16 +17,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __TREZORHAL_RANDOM_DELAYS_H__
#define __TREZORHAL_RANDOM_DELAYS_H__
#ifndef TREZORHAL_RANDOM_DELAYS_H
#define TREZORHAL_RANDOM_DELAYS_H
#include <stdint.h>
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef TREZORHAL_RGB_LED_H
#define TREZORHAL_RGB_LED_H
#include <stdint.h>
#ifdef KERNEL_MODE
void rgb_led_init(void);
#endif
void rgb_led_set_color(uint32_t color);
#endif // TREZORHAL_RGB_LED_H

View File

@ -22,8 +22,14 @@
#include <stdint.h>
#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

View File

@ -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);

View File

@ -1,7 +1,11 @@
#ifndef TREZORHAL_SECRET_H
#define TREZORHAL_SECRET_H
#include <stdint.h>
#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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#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

View File

@ -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

View File

@ -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

View File

@ -23,6 +23,8 @@
#include "common.h"
#include "flash.h"
#ifdef KERNEL_MODE
#define FLASH_OTP_LOCK_BASE 0x1FFF7A00U
void flash_otp_init() {
@ -74,3 +76,5 @@ secbool flash_otp_lock(uint8_t block) {
secbool flash_otp_is_locked(uint8_t block) {
return sectrue * (0x00 == *(__IO uint8_t *)(FLASH_OTP_LOCK_BASE + block));
}
#endif // KERNEL_MODE

View File

@ -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

View File

@ -5,6 +5,8 @@
#include "i2c.h"
#include "common.h"
#ifdef KERNEL_MODE
static I2C_HandleTypeDef i2c_handle[I2C_COUNT];
typedef struct {
@ -197,3 +199,5 @@ HAL_StatusTypeDef i2c_mem_read(uint16_t idx, uint8_t addr, uint16_t mem_addr,
return HAL_I2C_Mem_Read(&i2c_handle[idx], addr, mem_addr, mem_addr_size, data,
len, timeout);
}
#endif // #ifdef KERNEL_MODE

View File

@ -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 hardware definition
typedef struct {
// I2C controller registers
@ -857,30 +860,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

View File

@ -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

View File

@ -23,6 +23,8 @@
#include "mpu.h"
#include "string.h"
#ifdef KERNEL_MODE
#if PRODUCTION
static int get_otp_block(monoctr_type_t type) {
switch (type) {
@ -136,3 +138,5 @@ secbool monoctr_read(monoctr_type_t type, uint8_t* value) {
return sectrue;
}
#endif // KERNEL_MODE

View File

@ -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)
@ -594,3 +596,5 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
}
void mpu_restore(mpu_mode_t mode) { mpu_reconfig(mode); }
#endif // KERNEL_MODE

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -49,9 +49,12 @@
#include <string.h>
#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);
}

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 args1, 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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef TREZORHAL_SYSCALL_H
#define TREZORHAL_SYSCALL_H
#include <stdint.h>
#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

View File

@ -0,0 +1,494 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include 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;
#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

View File

@ -0,0 +1,145 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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_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

View File

@ -0,0 +1,611 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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);
}
// =============================================================================
// 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

View File

@ -21,6 +21,7 @@
#include <stddef.h>
#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
@ -150,6 +153,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;
@ -170,9 +174,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);

View File

@ -25,6 +25,8 @@
#include "systick_internal.h"
#include "systimer.h"
#ifdef KERNEL_MODE
// Maximum number of registerd user timer
//
// Consider different implementation (i.e. priority queue
@ -229,3 +231,5 @@ void systimer_dispatch_expired_timers(uint64_t cycles) {
}
}
}
#endif // KERNEL_MODE

View File

@ -20,6 +20,8 @@
#include STM32_HAL_H
#include TREZOR_BOARD
#ifdef KERNEL_MODE
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@ -554,3 +556,5 @@ uint32_t touch_get_event(void) {
return event;
}
#endif // KERNEL_MODE

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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****/

View File

@ -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****/

View File

@ -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****/

Some files were not shown because too many files have changed in this diff Show More