From 70ef643fc51c9965719fd299f0ac31e96d2cf3aa Mon Sep 17 00:00:00 2001 From: Adam <424778940z@users.noreply.github.com> Date: Thu, 29 Aug 2024 19:26:10 +0800 Subject: [PATCH] Multiple lowlevel optimizes, check commits for detail (#173) * nrf device key verify no longer blocking update mode (leftover due to "main" rebase) * boardloader update modes enter method change (leftover due to "main" rebase) * debugger script and makefile cleanup * usb descriptor update * adc and hardware version detect support * mpu disallow exec in spi flash range * minor fix and code format * minor hal changes * public keys move to dedicate file * support board without qspi flash * firmware switch to emmc_fs api * legacy user data storage api removal * boardloader mpu config move to dedicate location * emmc provide deinit methods * boardloader flash ecc recovery bug fix * ci build add non-prod boardloader reflash --------- Signed-off-by: Adam BZH --- .github/workflows/build-pro.yml | 3 + core/Makefile | 86 +--- core/SConscript.boardloader | 89 +--- core/SConscript.bootloader | 68 +-- core/SConscript.firmware | 105 ++--- core/embed/boardloader/main.c | 59 +-- core/embed/boardloader_reflash_dev/version.h | 8 +- core/embed/bootloader/main.c | 231 +++++----- core/embed/bootloader/messages.c | 67 +-- .../debugger_scripts/jlink/dump_sdram.jlink | 8 - core/embed/debugger_scripts/jlink/jexec.sh | 3 - .../debugger_scripts/jlink/jlink_erase.sh | 20 + .../debugger_scripts/jlink/jlink_read.sh | 21 + .../jlink/jlink_rebootDevice.sh | 35 ++ .../debugger_scripts/jlink/jlink_write.sh | 20 + .../jlink/reboot_device.jlink | 5 - .../jlink/wipe_bootloader_header.jlink | 7 - .../jlink/wipe_firmware_header.jlink | 7 - .../jlink/write_boardloader.jlink | 7 - .../jlink/write_boardloader_reflash_dev.jlink | 7 - .../jlink/write_bootloader.jlink | 7 - core/embed/emmc_wrapper/emmc_commands.c | 139 ++---- core/embed/emmc_wrapper/emmc_fs.c | 38 +- core/embed/emmc_wrapper/emmc_fs.h | 2 + .../extmod/modtrezorconfig/norcow_config.h | 3 - core/embed/extmod/modtrezorui/mipi_lcd.c | 10 +- core/embed/firmware/main.c | 122 ++---- core/embed/fw_keys/fw_keys.c | 30 ++ core/embed/fw_keys/fw_keys.h | 10 + core/embed/pn532/pn532.c | 4 +- core/embed/trezorhal/adc.c | 153 +++++++ core/embed/trezorhal/adc.h | 15 + core/embed/trezorhal/device.c | 37 +- core/embed/trezorhal/emmc.c | 18 + core/embed/trezorhal/emmc.h | 1 + core/embed/trezorhal/flash.c | 32 +- core/embed/trezorhal/flash.h | 12 +- core/embed/trezorhal/hardware_version.c | 45 ++ core/embed/trezorhal/hardware_version.h | 36 ++ core/embed/trezorhal/image.c | 410 ++++++++++++++---- core/embed/trezorhal/image.h | 61 +-- core/embed/trezorhal/lowlevel.c | 68 +-- core/embed/trezorhal/lowlevel.h | 7 +- core/embed/trezorhal/mpu.c | 213 +++------ core/embed/trezorhal/mpu.h | 1 + core/embed/trezorhal/qspi_flash.c | 57 ++- core/embed/trezorhal/qspi_flash.h | 1 + core/embed/trezorhal/usbd_desc.c | 2 +- core/embed/trezorhal/usbd_desc.h | 2 +- core/embed/trezorhal/usbd_msc_scsi.c | 1 - core/embed/trezorhal/util_macros.h | 38 +- 51 files changed, 1238 insertions(+), 1193 deletions(-) delete mode 100644 core/embed/debugger_scripts/jlink/dump_sdram.jlink delete mode 100755 core/embed/debugger_scripts/jlink/jexec.sh create mode 100755 core/embed/debugger_scripts/jlink/jlink_erase.sh create mode 100755 core/embed/debugger_scripts/jlink/jlink_read.sh create mode 100755 core/embed/debugger_scripts/jlink/jlink_rebootDevice.sh create mode 100755 core/embed/debugger_scripts/jlink/jlink_write.sh delete mode 100644 core/embed/debugger_scripts/jlink/reboot_device.jlink delete mode 100644 core/embed/debugger_scripts/jlink/wipe_bootloader_header.jlink delete mode 100644 core/embed/debugger_scripts/jlink/wipe_firmware_header.jlink delete mode 100644 core/embed/debugger_scripts/jlink/write_boardloader.jlink delete mode 100644 core/embed/debugger_scripts/jlink/write_boardloader_reflash_dev.jlink delete mode 100644 core/embed/debugger_scripts/jlink/write_bootloader.jlink create mode 100644 core/embed/fw_keys/fw_keys.c create mode 100644 core/embed/fw_keys/fw_keys.h create mode 100644 core/embed/trezorhal/adc.c create mode 100644 core/embed/trezorhal/adc.h create mode 100644 core/embed/trezorhal/hardware_version.c create mode 100644 core/embed/trezorhal/hardware_version.h diff --git a/.github/workflows/build-pro.yml b/.github/workflows/build-pro.yml index fc0236969..693a4dfb0 100644 --- a/.github/workflows/build-pro.yml +++ b/.github/workflows/build-pro.yml @@ -56,12 +56,15 @@ jobs: git submodule update --init --recursive nix-shell --run "poetry run make -C core clean" nix-shell --run "poetry run make -C core build_boardloader" + nix-shell --run "poetry run make -C core build_boardloader_reflash_dev" nix-shell --run "poetry run make -C core build_bootloader" nix-shell --run "poetry run make -C core build_firmware" + nix-shell --run "poetry run core/tools/headertool.py -h core/build/boardloader_reflash_dev/pro.boardloader_reflash_dev*Stable*.bin -S 1:${{ secrets.SECRET_QA_KEY_1 }} -S 2:${{ secrets.SECRET_QA_KEY_2 }}" nix-shell --run "poetry run core/tools/headertool.py -h core/build/bootloader/pro.bootloader*Stable*.bin -S 1:${{ secrets.SECRET_QA_KEY_1 }} -S 2:${{ secrets.SECRET_QA_KEY_2 }}" nix-shell --run "poetry run core/tools/headertool.py -h core/build/firmware/pro*Stable*.bin -S 1:${{ secrets.SECRET_QA_KEY_1 }} -S 2:${{ secrets.SECRET_QA_KEY_2 }}" mkdir -p core/build/output/qa cp ./core/build/boardloader/boardloader.bin core/build/output/qa + cp ./core/build/boardloader_reflash_dev/pro.boardloader_reflash_dev*Stable*.bin core/build/output/qa cp ./core/build/bootloader/pro.bootloader*Stable*.bin core/build/output/qa cp ./core/build/firmware/pro*Stable*.bin core/build/output/qa tools/hash.py -t bootloader -f core/build/bootloader/bootloader.bin > core/build/output/qa/bootloader_sha256.txt diff --git a/core/Makefile b/core/Makefile index 4d8e22821..eb5ccc150 100644 --- a/core/Makefile +++ b/core/Makefile @@ -40,9 +40,7 @@ OPENOCD_T1 = openocd -f interface/$(OPENOCD_INTERFACE).cfg -c "transport select BOARDLOADER_START = 0x08000000 BOOTLOADER_START = 0x08020000 FIRMWARE_P1_START = 0x08060000 -FIRMWARE_P2_START = 0x08120000 -PRODTEST_START = 0x08040000 -FIRMWARE_T1_START = 0x08010000 +FIRMWARE_P2_START = 0x90000000 BOARDLOADER_MAXSIZE = 49152 BOOTLOADER_MAXSIZE = 131072 @@ -244,71 +242,37 @@ clean_cross: ## clean mpy-cross build ## flash commands: -flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using OpenOCD - -flash_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash boardloader using OpenOCD - $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit" - -flash_bootloader: $(BOOTLOADER_BUILD_DIR)/bootloader.bin ## flash bootloader using OpenOCD - $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOOTLOADER_START); exit" - -flash_bootloader_ci: $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin ## flash CI bootloader using OpenOCD - $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOOTLOADER_START); exit" - -flash_prodtest: $(PRODTEST_BUILD_DIR)/prodtest.bin ## flash prodtest using OpenOCD - $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(PRODTEST_START); exit" - -flash_firmware: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using OpenOCD - $(OPENOCD) -c "init; reset halt; flash write_image erase $<.p1 $(FIRMWARE_P1_START); flash write_image erase $<.p2 $(FIRMWARE_P2_START); exit" - -flash_firmware_t1: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash T1 core port on T1 using OpenOCD - $(OPENOCD_T1) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_T1_START); exit" - -flash_combine: $(PRODTEST_BUILD_DIR)/combined.bin ## flash combined using OpenOCD - $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit" - -flash_erase: ## erase all sectors in flash bank 0 - $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 0 last; flash erase_check 0; exit" - -flash_read_storage: ## read storage sectors from flash - $(OPENOCD) -c "init; flash read_bank 0 storage1.data 0x10000 65536; flash read_bank 0 storage2.data 0x110000 65536; exit" - -flash_erase_storage: ## erase storage sectors from flash - $(OPENOCD) -c "init; flash erase_sector 0 4 4; flash erase_sector 0 16 16; exit" - flash_boardloader_jlink: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash bootloader using JLink - JLinkExe -nogui 1 -commanderscript embed/debugger_scripts/jlink/write_boardloader.jlink + embed/debugger_scripts/jlink/jlink_write.sh $(BOARDLOADER_BUILD_DIR)/boardloader.bin $(BOARDLOADER_START) flash_boardloader_reflash_dev_jlink: $(BOAR_DEV_REFLASH_BUILD_DIR)/boardloader_reflash_dev.bin ## flash boardloader_reflash_dev using JLink - JLinkExe -nogui 1 -commanderscript embed/debugger_scripts/jlink/write_boardloader_reflash_dev.jlink + embed/debugger_scripts/jlink/jlink_write.sh $(BOAR_DEV_REFLASH_BUILD_DIR)/boardloader_reflash_dev.bin $(BOOTLOADER_START) flash_bootloader_jlink: $(BOOTLOADER_BUILD_DIR)/bootloader.bin ## flash bootloader using JLink - JLinkExe -nogui 1 -commanderscript embed/debugger_scripts/jlink/write_bootloader.jlink - -# flash_bootloader_ci_jlink: $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin ## flash CI bootloader using JLink -# JLinkExe -nogui 1 -commanderscript embed/bootloader_ci/bootloader_flash.jlink + embed/debugger_scripts/jlink/jlink_write.sh $(BOOTLOADER_BUILD_DIR)/bootloader.bin $(BOOTLOADER_START) -erase_firmware_jlink: $(FIRMWARE_BUILD_DIR)/firmware.bin - JLinkExe -nogui 1 -commanderscript embed/debugger_scripts/jlink/wipe_firmware_header.jlink +erase_firmware_jlink: + embed/debugger_scripts/jlink/jlink_erase.sh $(FIRMWARE_P1_START) 0x180000 + embed/debugger_scripts/jlink/jlink_erase.sh $(FIRMWARE_P2_START) 0x200000 flash_firmware_jlink: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using JLink. file names must end in .bin for JLink cp -f $<.p1 $<.p1.bin cp -f $<.p2 $<.p2.bin - JLinkExe -nogui 1 -commanderscript embed/firmware/firmware_flash.jlink - -# flash_firmware_t1_jlink: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash T1 core port via JLink -# JLinkExe -nogui 1 -commanderscript embed/firmware/firmware_flash_t1.jlink - -reboot_device_jlink: ## cause a system reset using JLink - JLinkExe -nogui 1 -commanderscript embed/debugger_scripts/jlink/reboot_device.jlink - -## openocd debug commands: - -openocd: ## start openocd which connects to the device - $(OPENOCD) - -openocd_reset: ## cause a system reset using OpenOCD - $(OPENOCD) -c "init; reset; exit" + embed/debugger_scripts/jlink/jlink_write.sh $<.p1.bin $(FIRMWARE_P1_START) + embed/debugger_scripts/jlink/jlink_write.sh $<.p2.bin $(FIRMWARE_P2_START) + rm $<.p1.bin + rm $<.p2.bin + +dump_firmware_jlink: + embed/debugger_scripts/jlink/jlink_read.sh $(FIRMWARE_BUILD_DIR)/firmware.readback.p1.bin $(FIRMWARE_P1_START) 0x180000 + embed/debugger_scripts/jlink/jlink_read.sh $(FIRMWARE_BUILD_DIR)/firmware.readback.p2.bin $(FIRMWARE_P2_START) 0x200000 + +jlink_device_reboot: ## cause a system reset using JLink + embed/debugger_scripts/jlink/jlink_rebootDevice.sh 0 +jlink_device_enter_board: + embed/debugger_scripts/jlink/jlink_rebootDevice.sh 1 +jlink_device_enter_boot: + embed/debugger_scripts/jlink/jlink_rebootDevice.sh 2 GDB = arm-none-eabi-gdb --nx -ex 'set remotetimeout unlimited' -ex 'set confirm off' -ex 'target remote 127.0.0.1:3333' -ex 'monitor reset halt' @@ -348,11 +312,5 @@ combine: ## combine boardloader + bootloader + prodtest into one combined image $(PRODTEST_START) $(PRODTEST_BUILD_DIR)/prodtest.bin \ > $(PRODTEST_BUILD_DIR)/combined.bin -upload: ## upload firmware using trezorctl - trezorctl firmware_update -f $(FIRMWARE_BUILD_DIR)/firmware.bin - -upload_prodtest: ## upload prodtest using trezorctl - trezorctl firmware_update -f $(PRODTEST_BUILD_DIR)/prodtest.bin - coverage: # generate coverage report ./tools/coverage-report diff --git a/core/SConscript.boardloader b/core/SConscript.boardloader index e0591c185..9dba75c21 100644 --- a/core/SConscript.boardloader +++ b/core/SConscript.boardloader @@ -93,6 +93,7 @@ if PRODUCTION_MODEL == 'H': SOURCE_TREZORHAL = [ 'embed/trezorhal/system_stm32h7xx.c', 'embed/trezorhal/common.c', + 'embed/trezorhal/mpu.c', 'embed/trezorhal/emmc.c', 'embed/trezorhal/sdram.c', 'embed/trezorhal/qspi_flash.c', @@ -127,55 +128,13 @@ if PRODUCTION_MODEL == 'H': 'embed/trezorhal/fatfs/ffunicode.c', 'embed/trezorhal/fatfs/diskio.c', ] -else: - SOURCE_MOD += [ - 'embed/extmod/modtrezorui/display.c', - 'embed/extmod/modtrezorui/fonts/font_bitmap.c', - ] - SOURCE_STMHAL = [ - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c', - ] - - SOURCE_BOARDLOADER = [ - 'embed/boardloader/startup.s', - 'embed/boardloader/main.c', - ] - - SOURCE_TREZORHAL = [ - 'embed/trezorhal/common.c', - 'embed/trezorhal/dma.c', - 'embed/trezorhal/image.c', - 'embed/trezorhal/flash.c', - 'embed/trezorhal/lowlevel.c', - 'embed/trezorhal/mini_printf.c', - 'embed/trezorhal/sdcard.c', - 'embed/trezorhal/stm32.c', - 'embed/trezorhal/systick.c', - 'embed/trezorhal/rng.c', - 'embed/trezorhal/util.s', - 'embed/trezorhal/vectortable.s', - ] env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0'))) +# fw keys +SOURCE_FW_KEYS = [] +SOURCE_FW_KEYS.extend(Glob('embed/fw_keys/fw_keys.c')) + # debug utils SOURCE_DEBUG_UTILS = [] SOURCE_DEBUG_UTILS.extend(Glob('embed/debug_utils/*.c')) @@ -203,10 +162,6 @@ if PRODUCTION_MODEL == 'H': CPU_CCFLAGS = '-mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mtune=cortex-m7 --specs=nano.specs ' CPU_MODEL = 'STM32H747xx' CORE_MODEL = 'CORE_CM7' -elif TREZOR_MODEL in ('T', 'R'): - CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' - CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' - CPU_MODEL = 'STM32F427xx' else: raise ValueError('Unknown Trezor model') @@ -234,6 +189,7 @@ if PRODUCTION_MODEL == 'H': 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Inc', 'vendor/micropython/lib/stm32lib/CMSIS/STM32H7xx/Include', 'vendor/micropython/lib/cmsis/inc', + 'embed/fw_keys', 'embed/debug_utils', 'embed/emmc_wrapper', ] + CPPPATH_MOD, @@ -249,38 +205,6 @@ if PRODUCTION_MODEL == 'H': ASFLAGS=CPU_ASFLAGS, ASPPFLAGS='$CFLAGS $CCFLAGS', ) -else: - LD_FILE = '-T embed/boardloader/memory.ld ' - env.Replace( - COPT=env.get('ENV').get('OPTIMIZE', '-Os'), - CCFLAGS='$COPT ' - '-g3 ' - '-nostdlib ' - '-std=gnu99 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common ' - '-fsingle-precision-constant -fdata-sections -ffunction-sections ' - '-ffreestanding ' - '-fstack-protector-all ' - + CPU_CCFLAGS + CCFLAGS_MOD, - CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', - LINKFLAGS='-T embed/boardloader/memory.ld -Wl,--gc-sections -Wl,-Map=build/boardloader/boardloader.map -Wl,--warn-common', - CPPPATH=[ - 'embed/boardloader', - 'embed/trezorhal', - 'embed/extmod/modtrezorui', - 'vendor/micropython/stmhal', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Inc', - 'vendor/micropython/lib/stm32lib/CMSIS/STM32F4xx/Include', - 'vendor/micropython/lib/cmsis/inc', - ] + CPPPATH_MOD, - CPPDEFINES=[ - 'TREZOR_MODEL_'+TREZOR_MODEL, - CPU_MODEL, - 'USE_HAL_DRIVER', - ('STM32_HAL_H', '""'), - ] + CPPDEFINES_MOD, - ASFLAGS=CPU_ASFLAGS, - ASPPFLAGS='$CFLAGS $CCFLAGS', ) - # # Program objects # @@ -290,6 +214,7 @@ obj_program += env.Object(source=SOURCE_MOD) obj_program += env.Object(source=SOURCE_BOARDLOADER) obj_program += env.Object(source=SOURCE_STMHAL) obj_program += env.Object(source=SOURCE_TREZORHAL) +obj_program += env.Object(source=SOURCE_FW_KEYS) obj_program += env.Object(source=SOURCE_DEBUG_UTILS) obj_program += env.Object(source=SOURCE_EMMC_WRAPPER) diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader index 72ae85143..174c6690b 100644 --- a/core/SConscript.bootloader +++ b/core/SConscript.bootloader @@ -82,6 +82,8 @@ if PRODUCTION_MODEL == 'H': SOURCE_STMHAL = [ 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c', + 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c', + 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dcmi.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c', @@ -175,6 +177,8 @@ SOURCE_NANOPB = [ SOURCE_TREZORHAL = [ 'embed/trezorhal/system_stm32h7xx.c', + 'embed/trezorhal/adc.c', + 'embed/trezorhal/hardware_version.c', 'embed/trezorhal/common.c', 'embed/trezorhal/image.c', 'embed/trezorhal/flash.c', @@ -228,6 +232,10 @@ if TREZOR_MODEL in ('R'): if TREZOR_MODEL in ('T',): SOURCE_TREZORHAL.append('embed/trezorhal/touch.c') +# fw keys +SOURCE_FW_KEYS = [] +SOURCE_FW_KEYS.extend(Glob('embed/fw_keys/fw_keys.c')) + # debug utils SOURCE_DEBUG_UTILS = [] SOURCE_DEBUG_UTILS.extend(Glob('embed/debug_utils/*.c')) @@ -251,6 +259,10 @@ env.Replace( STRIP='arm-none-eabi-strip', OBJCOPY='arm-none-eabi-objcopy', ) +env.Replace( + HEADERTOOL='tools/headertool.py', +) + env.Replace( TREZOR_MODEL=TREZOR_MODEL, PRODUCTION_MODEL=ord(PRODUCTION_MODEL), ) @@ -260,20 +272,6 @@ if PRODUCTION_MODEL == 'H': CPU_CCFLAGS = '-mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mtune=cortex-m7 --specs=nano.specs ' CPU_MODEL = 'STM32H747xx' CORE_MODEL = 'CORE_CM7' -elif TREZOR_MODEL in ('T', 'R'): - CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' - CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' - CPU_MODEL = 'STM32F427xx' - RUST_TARGET = 'thumbv7em-none-eabihf' -elif TREZOR_MODEL in ('1',): - CPU_ASFLAGS = '-mthumb -mcpu=cortex-m3 -mfloat-abi=soft' - CPU_CCFLAGS = '-mthumb -mtune=cortex-m3 -mcpu=cortex-m3 -mfloat-abi=soft ' - CPU_MODEL = 'STM32F405xx' - RUST_TARGET = 'thumbv7m-none-eabi' -else: - raise ValueError('Unknown Trezor model') - -if PRODUCTION_MODEL == 'H': env.Replace( COPT=env.get('ENV').get('OPTIMIZE', '-Os'), CCFLAGS='$COPT ' @@ -297,6 +295,7 @@ if PRODUCTION_MODEL == 'H': 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Inc', 'vendor/micropython/lib/stm32lib/CMSIS/STM32H7xx/Include', 'vendor/micropython/lib/cmsis/inc', + 'embed/fw_keys', 'embed/debug_utils', 'embed/emmc_wrapper', 'embed/pn532', @@ -321,45 +320,9 @@ if PRODUCTION_MODEL == 'H': ] + CPPDEFINES_MOD, ASFLAGS=CPU_ASFLAGS, ASPPFLAGS='$CFLAGS $CCFLAGS', ) -else: - env.Replace( - COPT=env.get('ENV').get('OPTIMIZE', '-Os'), - CCFLAGS='$COPT ' - '-g3 ' - '-nostdlib ' - '-std=gnu99 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common ' - '-fsingle-precision-constant -fdata-sections -ffunction-sections ' - '-ffreestanding ' - '-fstack-protector-all ' - + CPU_CCFLAGS + CCFLAGS_MOD, - CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', - LINKFLAGS='-T embed/bootloader/memory.ld -Wl,--gc-sections -Wl,-Map=build/bootloader/bootloader.map -Wl,--warn-common', - CPPPATH=[ - 'embed/bootloader', - 'embed/bootloader/nanopb', - 'embed/bootloader/protob', - 'embed/trezorhal', - 'embed/extmod/modtrezorui', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Inc', - 'vendor/micropython/lib/stm32lib/CMSIS/STM32F4xx/Include', - 'vendor/micropython/lib/cmsis/inc', - 'vendor/nanopb', - ] + CPPPATH_MOD, - CPPDEFINES=[ - 'TREZOR_MODEL_'+TREZOR_MODEL, - CPU_MODEL, - 'USE_HAL_DRIVER', - ('STM32_HAL_H', '""'), - 'PB_FIELD_16BIT', - 'PB_ENCODE_ARRAYS_UNPACKED', - 'PB_VALIDATE_UTF8', - ] + CPPDEFINES_MOD, - ASFLAGS=CPU_ASFLAGS, - ASPPFLAGS='$CFLAGS $CCFLAGS', ) -env.Replace( - HEADERTOOL='tools/headertool.py', -) +else: + raise ValueError('Unknown Trezor model') # # Program objects @@ -371,6 +334,7 @@ obj_program += env.Object(source=SOURCE_BOOTLOADER) obj_program += env.Object(source=SOURCE_NANOPB) obj_program += env.Object(source=SOURCE_STMHAL) obj_program += env.Object(source=SOURCE_TREZORHAL) +obj_program += env.Object(source=SOURCE_FW_KEYS) obj_program += env.Object(source=SOURCE_DEBUG_UTILS) obj_program += env.Object(source=SOURCE_EMMC_WRAPPER) obj_program += env.Object(source=SOURCE_PN532_WRAPPER) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 627b38cee..b16f7f3b1 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -50,8 +50,8 @@ CPPPATH_MOD += [ ] SOURCE_MOD += [ 'embed/extmod/modtrezorconfig/modtrezorconfig.c', - 'vendor/trezor-storage/norcow.c', - 'vendor/trezor-storage/storage.c', + # 'vendor/trezor-storage/norcow.c', + # 'vendor/trezor-storage/storage.c', ] # modtrezorcrypto @@ -404,6 +404,8 @@ if PRODUCTION_MODEL == 'H': SOURCE_STMHAL = [ 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c', + 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c', + 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dcmi.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c', 'vendor/micropython/lib/stm32lib/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c', @@ -453,6 +455,8 @@ if PRODUCTION_MODEL == 'H': ] SOURCE_TREZORHAL = [ 'embed/trezorhal/system_stm32h7xx.c', + 'embed/trezorhal/adc.c', + 'embed/trezorhal/hardware_version.c', 'embed/trezorhal/common.c', #'embed/trezorhal/dma.c', 'embed/trezorhal/image.c', @@ -562,13 +566,17 @@ elif TREZOR_MODEL in ('1',): 'embed/trezorhal/button.c', ] +# fw keys +SOURCE_FW_KEYS = [] +SOURCE_FW_KEYS.extend(Glob('embed/fw_keys/fw_keys.c')) + # debug utils SOURCE_DEBUG_UTILS = [] SOURCE_DEBUG_UTILS.extend(Glob('embed/debug_utils/*.c')) -# # emmc wrapper -# SOURCE_EMMC_WRAPPER = [] -# SOURCE_EMMC_WRAPPER.extend(Glob('embed/emmc_wrapper/*.c')) +# emmc wrapper +SOURCE_EMMC_WRAPPER = [] +SOURCE_EMMC_WRAPPER.extend(Glob('embed/emmc_wrapper/emmc_fs.c')) # pn532 wrapper SOURCE_PN532_WRAPPER = [] @@ -653,6 +661,17 @@ env.Replace( LVGL_UI=LVGL_UI, PRODUCTION_MODEL=ord(PRODUCTION_MODEL), ) +env.Replace( + HEADERTOOL='tools/headertool.py', + PYTHON='python', + MAKEQSTRDATA='$PYTHON vendor/micropython/py/makeqstrdata.py', + MAKEVERSIONHDR='$PYTHON vendor/micropython/py/makeversionhdr.py', + MAKEMODULEDEFS='$PYTHON vendor/micropython/py/makemoduledefs.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', +) + if PRODUCTION_MODEL == 'H': CPU_ASFLAGS = '-mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 ' CPU_CCFLAGS = '-mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mtune=cortex-m7 --specs=nano.specs ' @@ -660,22 +679,6 @@ if PRODUCTION_MODEL == 'H': CORE_MODEL = 'CORE_CM7' LD_VARIANT = '' RUST_TARGET = 'thumbv7em-none-eabihf' -elif TREZOR_MODEL in ('T', 'R'): - CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' - CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' - CPU_MODEL = 'STM32F427xx' - LD_VARIANT = '' - RUST_TARGET = 'thumbv7em-none-eabihf' -elif TREZOR_MODEL in ('1',): - CPU_ASFLAGS = '-mthumb -mcpu=cortex-m3 -mfloat-abi=soft' - CPU_CCFLAGS = '-mthumb -mtune=cortex-m3 -mcpu=cortex-m3 -mfloat-abi=soft ' - CPU_MODEL = 'STM32F405xx' - LD_VARIANT = '' if EVERYTHING else '_min' - RUST_TARGET = 'thumbv7m-none-eabi' -else: - raise ValueError('Unknown Trezor model') - -if PRODUCTION_MODEL == 'H': env.Replace( COPT=env.get('ENV').get('OPTIMIZE', '-Os'), CCFLAGS='$COPT ' @@ -702,6 +705,7 @@ if PRODUCTION_MODEL == 'H': 'vendor/micropython/lib/stm32lib/CMSIS/STM32H7xx/Include', 'vendor/micropython/lib/cmsis/inc', 'embed/lvgl', + 'embed/fw_keys', 'embed/debug_utils', 'embed/emmc_wrapper', 'embed/pn532', @@ -730,48 +734,7 @@ if PRODUCTION_MODEL == 'H': ASFLAGS=CPU_ASFLAGS, ASPPFLAGS='$CFLAGS $CCFLAGS', ) else: - env.Replace( - COPT=env.get('ENV').get('OPTIMIZE', '-Os'), - CCFLAGS='$COPT ' - '-g3 ' - '-nostdlib ' - '-std=gnu99 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common ' - '-fsingle-precision-constant -fdata-sections -ffunction-sections ' - '-ffreestanding ' - '-fstack-protector-all ' - + CPU_CCFLAGS + CCFLAGS_MOD, - CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB', - LINKFLAGS='-T embed/firmware/memory_${TREZOR_MODEL}%s.ld -Wl,--gc-sections -Wl,-Map=build/firmware/firmware.map -Wl,--warn-common' % LD_VARIANT, - CPPPATH=[ - '.', - 'embed/rust', - 'embed/firmware', - 'embed/trezorhal', - 'embed/extmod/modtrezorui', - 'vendor/micropython', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Inc', - 'vendor/micropython/lib/stm32lib/CMSIS/STM32F4xx/Include', - 'vendor/micropython/lib/cmsis/inc', - ] + CPPPATH_MOD, - CPPDEFINES=[ - 'TREZOR_MODEL_'+TREZOR_MODEL, - CPU_MODEL, - 'USE_HAL_DRIVER', - ('STM32_HAL_H', '""'), - ] + CPPDEFINES_MOD, - ASFLAGS=CPU_ASFLAGS, - ASPPFLAGS='$CFLAGS $CCFLAGS', ) - -env.Replace( - HEADERTOOL='tools/headertool.py', - PYTHON='python', - MAKEQSTRDATA='$PYTHON vendor/micropython/py/makeqstrdata.py', - MAKEVERSIONHDR='$PYTHON vendor/micropython/py/makeversionhdr.py', - MAKEMODULEDEFS='$PYTHON vendor/micropython/py/makemoduledefs.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', -) + raise ValueError('Unknown Trezor model') # # Qstrings @@ -1103,7 +1066,9 @@ env.Append(LINKFLAGS=f' -l{RUST_LIB}') # obj_program = [] +obj_program += env.Object(source=SOURCE_FW_KEYS) obj_program += env.Object(source=SOURCE_DEBUG_UTILS) +obj_program += env.Object(source=SOURCE_EMMC_WRAPPER) obj_program += env.Object(source=SOURCE_FP_SENSOR_WRAPPER) obj_program.extend(env.Object(source=SOURCE_MOD)) @@ -1181,20 +1146,6 @@ if PRODUCTION_MODEL == 'H': '$HEADERTOOL -h $TARGET ' + ('-D' if ARGUMENTS.get('PRODUCTION', '0') == '0' else ''), '$DD if=$TARGET of=${TARGET}.p1 skip=0 bs=128k count=12', ] - -elif TREZOR_MODEL in ('T', 'R'): - action_bin=[ - '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data --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 ARGUMENTS.get('PRODUCTION', '0') == '0' else ''), - '$DD if=$TARGET of=${TARGET}.p1 skip=0 bs=128k count=6', - ] -elif TREZOR_MODEL in ('1',): - action_bin=[ - '$OBJCOPY -O binary -j .header -j .flash -j .data $SOURCE $TARGET', - '../legacy/bootloader/firmware_sign.py -f $TARGET', - ] else: raise ValueError('Unknown Trezor model') diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index 311922b09..9f4a7e618 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -26,11 +26,13 @@ #include "emmc.h" #include "emmc_fs.h" #include "flash.h" +#include "fw_keys.h" #include "i2c.h" #include "image.h" #include "lowlevel.h" #include "memzero.h" #include "mipi_lcd.h" +#include "mpu.h" #include "rng.h" #include "sdcard.h" #include "sdram.h" @@ -38,6 +40,7 @@ #include "touch.h" #include "usart.h" #include "usb.h" +#include "usbd_desc.h" #include "util_macros.h" #include "version.h" @@ -64,35 +67,6 @@ const board_info_t board_info __attribute__((section(".version_section"))) = { .build_id = BUILD_COMMIT, }; -#if PRODUCTION -const uint8_t BOARDLOADER_KEY_M = 4; -const uint8_t BOARDLOADER_KEY_N = 7; -static const uint8_t * const BOARDLOADER_KEYS[] = { - (const uint8_t - *)"\x15\x4b\x8a\xb2\x61\xcc\x88\x79\x48\x3f\x68\x9a\x2d\x41\x24\x3a\xe7\xdb\xc4\x02\x16\x72\xbb\xd2\x5c\x33\x8a\xe8\x4d\x93\x11\x54", - (const uint8_t - *)"\xa9\xe6\x5e\x07\xfe\x6d\x39\xa8\xa8\x4e\x11\xa9\x96\xa0\x28\x3f\x88\x1e\x17\x5c\xba\x60\x2e\xb5\xac\x44\x2f\xb7\x5b\x39\xe8\xe0", - (const uint8_t - *)"\x6c\x88\x05\xab\xb2\xdf\x9d\x36\x79\xf1\xd2\x8a\x40\xcd\x99\x03\x99\xb9\x9f\xc3\xee\x4e\x06\x57\xd8\x1d\x38\x1e\xa1\x48\x8a\x12", - (const uint8_t - *)"\x3e\xd7\x97\x79\x06\x4d\x56\x57\x1b\x29\xbc\xaa\x73\x4c\xbb\x6d\xb6\x1d\x2e\x62\x65\x66\x62\x8e\xcf\x4c\x89\xe1\xdb\x45\xea\xec", - (const uint8_t - *)"\x54\xa4\x06\x33\xbf\xd9\xe6\x0b\x8a\x39\x12\x65\xb2\xe0\x06\x37\x4a\xbe\x63\x1d\x1e\x11\x07\x33\x2b\xca\x56\xbf\x9f\x8c\x5c\x99", - (const uint8_t - *)"\x4b\x71\x13\x4f\x18\xe0\x07\x87\xc5\x83\xd4\x07\x42\xcc\x18\x8e\x17\xfc\x85\xad\xe4\xcb\x47\x2d\xae\x5e\xf8\xe0\x69\xf0\xfe\xc5", - (const uint8_t - *)"\x2e\xcf\x80\xc8\x2b\x44\x98\x48\xc0\x00\x33\x50\x92\x13\x95\x51\xbf\xe4\x7b\x3c\x73\x17\xb4\x99\x50\xf6\x5e\x1d\x82\x43\x20\x24", -}; -#else -const uint8_t BOARDLOADER_KEY_M = 2; -const uint8_t BOARDLOADER_KEY_N = 3; -static const uint8_t * const BOARDLOADER_KEYS[] = { - (const uint8_t *)"\x57\x11\x4f\x0a\xa6\x69\xd2\xf8\x37\xe0\x40\xab\x9b\xb5\x1c\x00\x99\x12\x09\xf8\x4b\xfd\x7b\xf0\xf8\x93\x67\x62\x46\xfb\xa2\x4a", - (const uint8_t *)"\xdc\xae\x8e\x37\xdf\x5c\x24\x60\x27\xc0\x3a\xa9\x51\xbd\x6e\xc6\xca\xa7\xad\x32\xc1\x66\xb1\xf5\x48\xa4\xef\xcd\x88\xca\x3c\xa5", - (const uint8_t *)"\x77\x29\x12\xab\x61\xd1\xdc\x4f\x91\x33\x32\x5e\x57\xe1\x46\xab\x9f\xac\x17\xa4\x57\x2c\x6f\xcd\xf3\x55\xf8\x00\x36\x10\x00\x04", -}; -#endif - // clang-format off static const uint8_t toi_icon_onekey[] = { // magic @@ -121,8 +95,6 @@ extern volatile uint32_t system_reset; // axi ram 512k uint8_t *boardloader_buf = (uint8_t *)0x24000000; -#define USB_SIZ_STRING_SERIAL \ - 0x20 // keep it same as "core/embed/trezorhal/usbd_desc.h" // this is mainly for ignore/supress faults during flash read (for check // purpose). if bus fault enabled, it will catched by BusFault_Handler, then we @@ -183,7 +155,7 @@ void UsageFault_Handler(void) { error_shutdown("Internal error", "(UF)", NULL, NULL); } -const char *STAY_REASON_str[] = { +const char *const STAY_REASON_str[] = { ENUM_NAME_ARRAY_ITEM(STAY_REASON_NONE), ENUM_NAME_ARRAY_ITEM(STAY_REASON_REQUIRED_BY_FLAG), ENUM_NAME_ARRAY_ITEM(STAY_REASON_MANUAL_OVERRIDE), @@ -246,8 +218,7 @@ static secbool validate_bootloader(image_header *const hdr) { secbool boot_hdr_valid = load_image_header( (const uint8_t *)BOOTLOADER_START, BOOTLOADER_IMAGE_MAGIC, - BOOTLOADER_IMAGE_MAXSIZE, BOARDLOADER_KEY_M, BOARDLOADER_KEY_N, - BOARDLOADER_KEYS, hdr); + BOOTLOADER_IMAGE_MAXSIZE, FW_KEY_M, FW_KEY_N, FW_KEYS, hdr); secbool boot_code_valid = check_image_contents( hdr, IMAGE_HEADER_SIZE, BOOTLOADER_SECTORS, BOOTLOADER_SECTORS_COUNT); @@ -299,14 +270,13 @@ static secbool try_bootloader_update(bool do_update, bool auto_reboot) { image_header file_hdr; if (sectrue != load_image_header(boardloader_buf, BOOTLOADER_IMAGE_MAGIC, - BOOTLOADER_IMAGE_MAXSIZE, BOARDLOADER_KEY_M, - BOARDLOADER_KEY_N, BOARDLOADER_KEYS, - &file_hdr)) + BOOTLOADER_IMAGE_MAXSIZE, FW_KEY_M, FW_KEY_N, + FW_KEYS, &file_hdr)) return secfalse; - if (sectrue != check_image_contents_ram(&file_hdr, boardloader_buf, - file_hdr.hdrlen, - BOOTLOADER_SECTORS_COUNT)) + if (sectrue != check_image_contents_ADV(NULL, &file_hdr, + boardloader_buf + file_hdr.hdrlen, 0, + file_hdr.codelen)) return secfalse; // if not actually doing the update, return as update file validate result @@ -316,7 +286,9 @@ static secbool try_bootloader_update(bool do_update, bool auto_reboot) { image_header hdr; #if PRODUCTION - secbool bootloader_valid = validate_bootloader(&hdr); + secbool bootloader_valid = load_image_header( + (const uint8_t *)BOOTLOADER_START, BOOTLOADER_IMAGE_MAGIC, + BOOTLOADER_IMAGE_MAXSIZE, FW_KEY_M, FW_KEY_N, FW_KEYS, &hdr); // handle downgrade or invalid bootloader if (bootloader_valid == sectrue) { if (memcmp(&file_hdr.version, &hdr.version, 4) < 0) { @@ -699,6 +671,9 @@ static secbool get_device_serial(char *serial, size_t len) { return secfalse; } + // make sure last element is '\0' + otp_serial[FLASH_OTP_BLOCK_SIZE - 1] = '\0'; + // check if all is ascii for (uint32_t i = 0; i < sizeof(otp_serial); i++) { if (otp_serial[i] == '\0') { @@ -759,7 +734,7 @@ int main(void) { // enforce protection flash_option_bytes_init(); - mpu_config(); + mpu_config_boardloader(); // user interface lcd_para_init(DISPLAY_RESX, DISPLAY_RESY, LCD_PIXEL_FORMAT_RGB565); diff --git a/core/embed/boardloader_reflash_dev/version.h b/core/embed/boardloader_reflash_dev/version.h index 80a65fa1f..721cbf029 100644 --- a/core/embed/boardloader_reflash_dev/version.h +++ b/core/embed/boardloader_reflash_dev/version.h @@ -1,14 +1,14 @@ #define VERSION_MAJOR 2 -#define VERSION_MINOR 4 -#define VERSION_PATCH 9 +#define VERSION_MINOR 5 +#define VERSION_PATCH 3 #define VERSION_BUILD 0 #define VERSION_UINT32 \ (VERSION_MAJOR | (VERSION_MINOR << 8) | (VERSION_PATCH << 16) | \ (VERSION_BUILD << 24)) #define FIX_VERSION_MAJOR 2 -#define FIX_VERSION_MINOR 4 -#define FIX_VERSION_PATCH 9 +#define FIX_VERSION_MINOR 5 +#define FIX_VERSION_PATCH 3 #define FIX_VERSION_BUILD 0 #define VERSION_MONOTONIC 1 diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index 51e7b4091..459d8801c 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -20,17 +20,19 @@ #include #include +#include "adc.h" #include "common.h" #include "compiler_traits.h" #include "device.h" #include "display.h" #include "flash.h" +#include "fw_keys.h" +#include "hardware_version.h" #include "image.h" #include "lowlevel.h" #include "mini_printf.h" #include "mipi_lcd.h" #include "mpu.h" -#include "nand_flash.h" #include "qspi_flash.h" #include "random_delays.h" #include "se_thd89.h" @@ -38,14 +40,9 @@ #include "systick.h" #include "thd89.h" #include "thd89_boot.h" -#ifdef TREZOR_MODEL_T #include "touch.h" -#endif -#if defined TREZOR_MODEL_R -#include "button.h" -#include "rgb_led.h" -#endif #include "usb.h" +#include "usbd_desc.h" #include "version.h" #include "ble.h" @@ -55,7 +52,6 @@ #include "jpeg_dma.h" #include "messages.h" #include "motor.h" -#include "mpu.h" #include "spi.h" #include "spi_legacy.h" #include "systick.h" @@ -70,30 +66,6 @@ #include "camera.h" #include "emmc_wrapper.h" -#if PRODUCTION -const uint8_t BOOTLOADER_KEY_M = 4; -const uint8_t BOOTLOADER_KEY_N = 7; -#else -const uint8_t BOOTLOADER_KEY_M = 2; -const uint8_t BOOTLOADER_KEY_N = 3; -#endif - -const uint8_t * const BOOTLOADER_KEYS[] = { -#if PRODUCTION - (const uint8_t *)"\x15\x4b\x8a\xb2\x61\xcc\x88\x79\x48\x3f\x68\x9a\x2d\x41\x24\x3a\xe7\xdb\xc4\x02\x16\x72\xbb\xd2\x5c\x33\x8a\xe8\x4d\x93\x11\x54", - (const uint8_t *)"\xa9\xe6\x5e\x07\xfe\x6d\x39\xa8\xa8\x4e\x11\xa9\x96\xa0\x28\x3f\x88\x1e\x17\x5c\xba\x60\x2e\xb5\xac\x44\x2f\xb7\x5b\x39\xe8\xe0", - (const uint8_t *)"\x6c\x88\x05\xab\xb2\xdf\x9d\x36\x79\xf1\xd2\x8a\x40\xcd\x99\x03\x99\xb9\x9f\xc3\xee\x4e\x06\x57\xd8\x1d\x38\x1e\xa1\x48\x8a\x12", - (const uint8_t *)"\x3e\xd7\x97\x79\x06\x4d\x56\x57\x1b\x29\xbc\xaa\x73\x4c\xbb\x6d\xb6\x1d\x2e\x62\x65\x66\x62\x8e\xcf\x4c\x89\xe1\xdb\x45\xea\xec", - (const uint8_t *)"\x54\xa4\x06\x33\xbf\xd9\xe6\x0b\x8a\x39\x12\x65\xb2\xe0\x06\x37\x4a\xbe\x63\x1d\x1e\x11\x07\x33\x2b\xca\x56\xbf\x9f\x8c\x5c\x99", - (const uint8_t *)"\x4b\x71\x13\x4f\x18\xe0\x07\x87\xc5\x83\xd4\x07\x42\xcc\x18\x8e\x17\xfc\x85\xad\xe4\xcb\x47\x2d\xae\x5e\xf8\xe0\x69\xf0\xfe\xc5", - (const uint8_t *)"\x2e\xcf\x80\xc8\x2b\x44\x98\x48\xc0\x00\x33\x50\x92\x13\x95\x51\xbf\xe4\x7b\x3c\x73\x17\xb4\x99\x50\xf6\x5e\x1d\x82\x43\x20\x24", -#else - (const uint8_t *)"\x57\x11\x4f\x0a\xa6\x69\xd2\xf8\x37\xe0\x40\xab\x9b\xb5\x1c\x00\x99\x12\x09\xf8\x4b\xfd\x7b\xf0\xf8\x93\x67\x62\x46\xfb\xa2\x4a", - (const uint8_t *)"\xdc\xae\x8e\x37\xdf\x5c\x24\x60\x27\xc0\x3a\xa9\x51\xbd\x6e\xc6\xca\xa7\xad\x32\xc1\x66\xb1\xf5\x48\xa4\xef\xcd\x88\xca\x3c\xa5", - (const uint8_t *)"\x77\x29\x12\xab\x61\xd1\xdc\x4f\x91\x33\x32\x5e\x57\xe1\x46\xab\x9f\xac\x17\xa4\x57\x2c\x6f\xcd\xf3\x55\xf8\x00\x36\x10\x00\x04", -#endif -}; - #define USB_IFACE_NUM 0 #if !PRODUCTION @@ -192,7 +164,7 @@ void BusFault_Handler(void) { "Firmware reinstall may required", "If the issue persists, contact support."); } else { - error_shutdown("Internal error", "Cleanup failed", + error_shutdown("Internal flash ECC error", "Cleanup failed", "Reboot to try again", "If the issue persists, contact support."); } @@ -207,6 +179,42 @@ void UsageFault_Handler(void) { error_shutdown("Internal error", "(UF)", NULL, NULL); } +static secbool get_device_serial(char* serial, size_t len) { + // init + uint8_t otp_serial[FLASH_OTP_BLOCK_SIZE] = {0}; + memzero(otp_serial, sizeof(otp_serial)); + memzero(serial, len); + + // get OTP serial + if (sectrue != flash_otp_is_locked(FLASH_OTP_DEVICE_SERIAL)) return secfalse; + + if (sectrue != flash_otp_read(FLASH_OTP_DEVICE_SERIAL, 0, otp_serial, + sizeof(otp_serial))) { + return secfalse; + } + + // make sure last element is '\0' + otp_serial[FLASH_OTP_BLOCK_SIZE - 1] = '\0'; + + // check if all is ascii + for (uint32_t i = 0; i < sizeof(otp_serial); i++) { + if (otp_serial[i] == '\0') { + break; + } + if (otp_serial[i] < ' ' || otp_serial[i] > '~') { + return secfalse; + } + } + + // copy to output buffer + memcpy(serial, otp_serial, MIN(len, sizeof(otp_serial))); + + // cutoff by strlen + serial[strlen(serial)] = '\0'; + + return sectrue; +} + static void usb_init_all(secbool usb21_landing) { usb_dev_info_t dev_info = { .device_class = 0x00, @@ -215,7 +223,7 @@ static void usb_init_all(secbool usb21_landing) { .vendor_id = 0x1209, .product_id = 0x4F4A, .release_num = 0x0200, - .manufacturer = "OneKey Ltd.", + .manufacturer = "OneKey Limited", .product = "OneKey Pro", .serial_number = "000000000000000000000000", .interface = "Bootloader Interface", @@ -223,6 +231,12 @@ static void usb_init_all(secbool usb21_landing) { .usb21_landing = usb21_landing, }; + static char serial[USB_SIZ_STRING_SERIAL]; + + if (sectrue == get_device_serial(serial, sizeof(serial))) { + dev_info.serial_number = serial; + } + static uint8_t rx_buffer[USB_PACKET_SIZE]; static const usb_webusb_info_t webusb_info = { @@ -258,7 +272,6 @@ static void usb_switch(void) { usb_opened = true; } } - } else { counter0 = 0; counter1++; @@ -550,8 +563,7 @@ secbool bootloader_usb_loop_factory(const vendor_header* const vhdr, secbool load_vendor_header_keys(const uint8_t* const data, vendor_header* const vhdr) { - return load_vendor_header(data, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, - BOOTLOADER_KEYS, vhdr); + return load_vendor_header(data, FW_KEY_M, FW_KEY_N, FW_KEYS, vhdr); } static secbool check_vendor_header_lock(const vendor_header* const vhdr) { @@ -624,20 +636,10 @@ static secbool validate_firmware_headers(vendor_header* const vhdr, return result; } -static secbool validate_firmware_code(vendor_header* const vhdr, - image_header* const hdr) { - set_handle_flash_ecc_error(sectrue); - secbool result = - check_image_contents(hdr, IMAGE_HEADER_SIZE + vhdr->hdrlen, - FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT); - set_handle_flash_ecc_error(secfalse); - return result; -} - static BOOT_TARGET decide_boot_target(vendor_header* const vhdr, image_header* const hdr, - secbool* headers_validate_result, - secbool* headers_checked) { + secbool* headers_valid, + secbool* firmware_valid) { // get boot target flag BOOT_TARGET boot_target = *BOOT_TARGET_FLAG_ADDR; // cache flag *BOOT_TARGET_FLAG_ADDR = BOOT_TARGET_NORMAL; // consume(reset) flag @@ -658,22 +660,20 @@ static BOOT_TARGET decide_boot_target(vendor_header* const vhdr, } // check firmware - if (sectrue == validate_firmware_headers(vhdr, hdr)) { - if (sectrue == validate_firmware_code(vhdr, hdr)) { - *headers_validate_result = sectrue; - *headers_checked = sectrue; - } else { - boot_target = BOOT_TARGET_BOOTLOADER; - *headers_checked = sectrue; - return boot_target; - } - } else { - *headers_validate_result = secfalse; - *headers_checked = sectrue; + set_handle_flash_ecc_error(sectrue); + *headers_valid = validate_firmware_headers(vhdr, hdr); + char err_msg[64]; + *firmware_valid = verify_firmware(err_msg, sizeof(err_msg)); + set_handle_flash_ecc_error(secfalse); + + if (*headers_valid != sectrue || *firmware_valid != sectrue) { boot_target = BOOT_TARGET_BOOTLOADER; return boot_target; } + // all check passed, manual set, since default ram value will be random + boot_target = BOOT_TARGET_NORMAL; + return boot_target; } @@ -681,12 +681,15 @@ int main(void) { SystemCoreClockUpdate(); dwt_init(); mpu_config_bootloader(); + // user interface - lcd_para_init(DISPLAY_RESX, DISPLAY_RESY, LCD_PIXEL_FORMAT_RGB565); - // lcd_init(DISPLAY_RESX, DISPLAY_RESY, LCD_PIXEL_FORMAT_RGB565); + // lcd_para_init(DISPLAY_RESX, DISPLAY_RESY, LCD_PIXEL_FORMAT_RGB565); + lcd_init(DISPLAY_RESX, DISPLAY_RESY, LCD_PIXEL_FORMAT_RGB565); lcd_pwm_init(); touch_init(); + adc_init(); + // keep the screen but cover the boot bar // display_clear(); display_bar_radius(160, 352, 160, 4, COLOR_BLACK, COLOR_BLACK, 2); @@ -695,11 +698,13 @@ int main(void) { bus_fault_enable(); // it's here since requires user interface // storages - qspi_flash_init(); - qspi_flash_config(); - qspi_flash_memory_mapped(); ensure_emmcfs(emmc_fs_init(), "emmc_fs_init"); ensure_emmcfs(emmc_fs_mount(true, false), "emmc_fs_mount"); + if (get_hw_ver() < HW_VER_3P0A) { + qspi_flash_init(); + qspi_flash_config(); + qspi_flash_memory_mapped(); + } // bt/pm ble_usart_init(); @@ -735,9 +740,9 @@ int main(void) { #if !PRODUCTION - if (!device_serial_set()) { - write_dev_dummy_serial(); - } + // if (!device_serial_set()) { + // write_dev_dummy_serial(); + // } UNUSED(write_dev_dummy_serial); // if (!se_has_cerrificate()) { @@ -766,21 +771,15 @@ int main(void) { vendor_header vhdr; image_header hdr; - secbool headers_valid = secfalse, headers_checked = secfalse; + secbool headers_valid = secfalse; + secbool firmware_valid = secfalse; BOOT_TARGET boot_target = - decide_boot_target(&vhdr, &hdr, &headers_valid, &headers_checked); - - display_clear(); + decide_boot_target(&vhdr, &hdr, &headers_valid, &firmware_valid); if (boot_target == BOOT_TARGET_BOOTLOADER) { - if (headers_checked == secfalse) { - if (sectrue == validate_firmware_headers(&vhdr, &hdr)) { - if (sectrue == validate_firmware_code(&vhdr, &hdr)) { - headers_valid = sectrue; - } - } - } + display_clear(); + if (sectrue == headers_valid) { ui_bootloader_first(&hdr); if (bootloader_usb_loop(&vhdr, &hdr) != sectrue) { @@ -792,47 +791,49 @@ int main(void) { return 1; } } - } - // check if firmware valid again to make sure - ensure(validate_firmware_headers(&vhdr, &hdr), "invalid firmware header"); - ensure(validate_firmware_code(&vhdr, &hdr), "invalid firmware code"); - - // check bluetooth key - device_verify_ble(); - - // if all VTRUST flags are unset = ultimate trust => skip the procedure - if ((vhdr.vtrust & VTRUST_ALL) != VTRUST_ALL) { - // ui_fadeout(); // no fadeout - we start from black screen - ui_screen_boot(&vhdr, &hdr); - ui_fadein(); - - int delay = (vhdr.vtrust & VTRUST_WAIT) ^ VTRUST_WAIT; - if (delay > 1) { - while (delay > 0) { - ui_screen_boot_wait(delay); + } else if (boot_target == BOOT_TARGET_NORMAL) { + // check and load firmware (redundant, no need, since decide_boot_target + // already done this) + // char err_msg[64]; + // ensure(verify_firmware(err_msg, sizeof(err_msg)), err_msg); + + // check bluetooth key + device_verify_ble(); + + // if all VTRUST flags are unset = ultimate trust => skip the procedure + if ((vhdr.vtrust & VTRUST_ALL) != VTRUST_ALL) { + // ui_fadeout(); // no fadeout - we start from black screen + ui_screen_boot(&vhdr, &hdr); + ui_fadein(); + + int delay = (vhdr.vtrust & VTRUST_WAIT) ^ VTRUST_WAIT; + if (delay > 1) { + while (delay > 0) { + ui_screen_boot_wait(delay); + hal_delay(1000); + delay--; + } + } else if (delay == 1) { hal_delay(1000); - delay--; } - } else if (delay == 1) { - hal_delay(1000); - } - - if ((vhdr.vtrust & VTRUST_CLICK) == 0) { - ui_screen_boot_click(); - while (touch_read() == 0) - ; - } - display_clear(); - } + if ((vhdr.vtrust & VTRUST_CLICK) == 0) { + ui_screen_boot_click(); + while (touch_read() == 0) + ; + } - // jump_to_unprivileged(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); + display_clear(); - bus_fault_disable(); + bus_fault_disable(); - mpu_config_off(); + mpu_config_off(); - jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); + jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); + } + } - return 0; + error_shutdown("Internal error", "Boot target invalid", "Tap to restart.", + "If the issue persists, contact support."); + return -1; } diff --git a/core/embed/bootloader/messages.c b/core/embed/bootloader/messages.c index 32ca32aac..2ff32a070 100644 --- a/core/embed/bootloader/messages.c +++ b/core/embed/bootloader/messages.c @@ -601,74 +601,15 @@ secbool load_vendor_header_keys(const uint8_t *const data, vendor_header *const vhdr); int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) { -#if PRODUCTION_MODEL == 'H' - static const uint8_t sectors[] = { - FLASH_SECTOR_STORAGE_1, - FLASH_SECTOR_STORAGE_2, - FLASH_SECTOR_FIRMWARE_START, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - FLASH_SECTOR_FIRMWARE_END, - FLASH_SECTOR_FIRMWARE_EXTRA_START, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - FLASH_SECTOR_FIRMWARE_EXTRA_END, - }; -#else - static const uint8_t sectors[] = { - FLASH_SECTOR_STORAGE_1, - FLASH_SECTOR_STORAGE_2, - // 3, // skip because of MPU protection - FLASH_SECTOR_FIRMWARE_START, - 7, - 8, - 9, - 10, - FLASH_SECTOR_FIRMWARE_END, - FLASH_SECTOR_UNUSED_START, - 13, - 14, - // FLASH_SECTOR_UNUSED_END, // skip because of MPU protection - FLASH_SECTOR_FIRMWARE_EXTRA_START, - 18, - 19, - 20, - 21, - 22, - FLASH_SECTOR_FIRMWARE_EXTRA_END, - }; -#endif -#if PRODUCTION_MODEL == 'H' - se_reset_storage(); -#endif - if (sectrue != - flash_erase_sectors(sectors, sizeof(sectors), ui_screen_wipe_progress)) { + ui_screen_wipe_progress(0, 1000); + if (sectrue != se_reset_storage()) { MSG_SEND_INIT(Failure); MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError); - MSG_SEND_ASSIGN_STRING(message, "Could not erase flash"); + MSG_SEND_ASSIGN_STRING(message, "Wipe device failed"); MSG_SEND(Failure); return -1; } else { + ui_screen_wipe_progress(1000, 1000); MSG_SEND_INIT(Success); MSG_SEND(Success); return 0; diff --git a/core/embed/debugger_scripts/jlink/dump_sdram.jlink b/core/embed/debugger_scripts/jlink/dump_sdram.jlink deleted file mode 100644 index dd97cb4a4..000000000 --- a/core/embed/debugger_scripts/jlink/dump_sdram.jlink +++ /dev/null @@ -1,8 +0,0 @@ -device STM32H747XI_M7 -SelectInterface swd -speed 25000 -Halt -WaitHalt -savebin sdram.bin 0xD0000000 0x10000000000 -go -exit diff --git a/core/embed/debugger_scripts/jlink/jexec.sh b/core/embed/debugger_scripts/jlink/jexec.sh deleted file mode 100755 index de87d55ac..000000000 --- a/core/embed/debugger_scripts/jlink/jexec.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -JLinkExe -nogui 1 -commanderscript $1 \ No newline at end of file diff --git a/core/embed/debugger_scripts/jlink/jlink_erase.sh b/core/embed/debugger_scripts/jlink/jlink_erase.sh new file mode 100755 index 000000000..0527d0630 --- /dev/null +++ b/core/embed/debugger_scripts/jlink/jlink_erase.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# $1 -> address +# $2 -> size in byte + +tee TempFlashScript.jlink > /dev/null << EOT +usb $JLINK_SN +device OneKeyH7 +SelectInterface swd +speed 20000 +RSetType 0 +halt +Erase $1 $2 +rx 100 +g +exit +EOT + +JLinkExe -nogui 1 -commanderscript TempFlashScript.jlink + +rm TempFlashScript.jlink \ No newline at end of file diff --git a/core/embed/debugger_scripts/jlink/jlink_read.sh b/core/embed/debugger_scripts/jlink/jlink_read.sh new file mode 100755 index 000000000..a51b53d5f --- /dev/null +++ b/core/embed/debugger_scripts/jlink/jlink_read.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# $1 -> file path +# $2 -> address +# $3 -> size in byte + +tee TempFlashScript.jlink > /dev/null << EOT +usb $JLINK_SN +device OneKeyH7 +SelectInterface swd +speed 20000 +RSetType 0 +halt +SaveBin $1 $2 $3 +rx 100 +g +exit +EOT + +JLinkExe -nogui 1 -commanderscript TempFlashScript.jlink + +rm TempFlashScript.jlink \ No newline at end of file diff --git a/core/embed/debugger_scripts/jlink/jlink_rebootDevice.sh b/core/embed/debugger_scripts/jlink/jlink_rebootDevice.sh new file mode 100755 index 000000000..e567c8b24 --- /dev/null +++ b/core/embed/debugger_scripts/jlink/jlink_rebootDevice.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# $1 -> target (0=Normal, 1=Board, 2=Boot) + +case $1 in +"0") + export TARGET_FLAG="0x00000000" + ;; +"1") + export TARGET_FLAG="0x64616F62" + ;; +"2") + export TARGET_FLAG="0x746F6F62" + ;; +*) + echo "Invalid boot target $1" + exit -1 + ;; +esac + +tee TempFlashScript.jlink >/dev/null < file path +# $2 -> address + +tee TempFlashScript.jlink > /dev/null << EOT +usb $JLINK_SN +device OneKeyH7 +SelectInterface swd +speed 20000 +RSetType 0 +halt +loadbin $1 $2 +rx 100 +g +exit +EOT + +JLinkExe -nogui 1 -commanderscript TempFlashScript.jlink + +rm TempFlashScript.jlink \ No newline at end of file diff --git a/core/embed/debugger_scripts/jlink/reboot_device.jlink b/core/embed/debugger_scripts/jlink/reboot_device.jlink deleted file mode 100644 index 03c9b5a7c..000000000 --- a/core/embed/debugger_scripts/jlink/reboot_device.jlink +++ /dev/null @@ -1,5 +0,0 @@ -device STM32H747XI_M7 -SelectInterface swd -speed 25000 -rx 100 -exit diff --git a/core/embed/debugger_scripts/jlink/wipe_bootloader_header.jlink b/core/embed/debugger_scripts/jlink/wipe_bootloader_header.jlink deleted file mode 100644 index 7146e6c5a..000000000 --- a/core/embed/debugger_scripts/jlink/wipe_bootloader_header.jlink +++ /dev/null @@ -1,7 +0,0 @@ -device STM32H747XI_M7 -SelectInterface swd -speed 25000 -Erase 0x08020000 0x08020600 -rx 100 -go -exit diff --git a/core/embed/debugger_scripts/jlink/wipe_firmware_header.jlink b/core/embed/debugger_scripts/jlink/wipe_firmware_header.jlink deleted file mode 100644 index 5769466ac..000000000 --- a/core/embed/debugger_scripts/jlink/wipe_firmware_header.jlink +++ /dev/null @@ -1,7 +0,0 @@ -device STM32H747XI_M7 -SelectInterface swd -speed 25000 -Erase 0x08060000 0x08060600 -rx 100 -go -exit diff --git a/core/embed/debugger_scripts/jlink/write_boardloader.jlink b/core/embed/debugger_scripts/jlink/write_boardloader.jlink deleted file mode 100644 index 27ab541e1..000000000 --- a/core/embed/debugger_scripts/jlink/write_boardloader.jlink +++ /dev/null @@ -1,7 +0,0 @@ -device STM32H747XI_M7 -SelectInterface swd -speed 25000 -loadbin build/boardloader/boardloader.bin 0x08000000 -rx 100 -g -exit diff --git a/core/embed/debugger_scripts/jlink/write_boardloader_reflash_dev.jlink b/core/embed/debugger_scripts/jlink/write_boardloader_reflash_dev.jlink deleted file mode 100644 index dea84466c..000000000 --- a/core/embed/debugger_scripts/jlink/write_boardloader_reflash_dev.jlink +++ /dev/null @@ -1,7 +0,0 @@ -device STM32H747XI_M7 -SelectInterface swd -speed 25000 -loadbin build/boardloader_reflash_dev/boardloader_reflash_dev.bin 0x08020000 -rx 100 -g -exit diff --git a/core/embed/debugger_scripts/jlink/write_bootloader.jlink b/core/embed/debugger_scripts/jlink/write_bootloader.jlink deleted file mode 100644 index fb86b537a..000000000 --- a/core/embed/debugger_scripts/jlink/write_bootloader.jlink +++ /dev/null @@ -1,7 +0,0 @@ -device STM32H747XI_M7 -SelectInterface swd -speed 25000 -loadbin build/bootloader/bootloader.bin 0x08020000 -rx 100 -g -exit diff --git a/core/embed/emmc_wrapper/emmc_commands.c b/core/embed/emmc_wrapper/emmc_commands.c index f44e7ff4a..a257f829f 100644 --- a/core/embed/emmc_wrapper/emmc_commands.c +++ b/core/embed/emmc_wrapper/emmc_commands.c @@ -1,6 +1,7 @@ #include "emmc_commands.h" #include "emmc_commands_macros.h" +#include "fw_keys.h" #include "se_thd89.h" #include "thd89_boot.h" @@ -533,14 +534,9 @@ static int check_file_contents(uint8_t iface_num, const uint8_t* buffer, uint32_ if ( memcmp(p_data, "OKTV", 4) == 0 ) { // check firmware header - extern const uint8_t BOOTLOADER_KEY_M; - extern const uint8_t BOOTLOADER_KEY_N; - extern const uint8_t* const BOOTLOADER_KEYS[]; - // check file header ExecuteCheck_MSGS_ADV( - load_vendor_header(p_data, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, BOOTLOADER_KEYS, &file_vhdr), - sectrue, + load_vendor_header(p_data, FW_KEY_M, FW_KEY_N, FW_KEYS, &file_vhdr), sectrue, { send_failure( iface_num, FailureType_Failure_ProcessError, "Update file vender header invalid!" @@ -562,8 +558,8 @@ static int check_file_contents(uint8_t iface_num, const uint8_t* buffer, uint32_ // check file firmware hash ExecuteCheck_MSGS_ADV( - check_image_contents_ram( - &file_hdr, p_data, file_vhdr.hdrlen + file_hdr.hdrlen, FIRMWARE_SECTORS_COUNT + check_image_contents_ADV( + &file_vhdr, &file_hdr, p_data + file_vhdr.hdrlen + file_hdr.hdrlen, 0, file_hdr.codelen ), sectrue, { @@ -892,9 +888,6 @@ int process_msg_FirmwareUpdateEmmc(uint8_t iface_num, uint32_t msg_size, uint8_t { // MCU update // check firmware header - extern const uint8_t BOOTLOADER_KEY_M; - extern const uint8_t BOOTLOADER_KEY_N; - extern const uint8_t* const BOOTLOADER_KEYS[]; vendor_header file_vhdr; image_header file_hdr; @@ -902,8 +895,7 @@ int process_msg_FirmwareUpdateEmmc(uint8_t iface_num, uint32_t msg_size, uint8_t // check file header ExecuteCheck_MSGS_ADV( - load_vendor_header(p_data, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, BOOTLOADER_KEYS, &file_vhdr), - sectrue, + load_vendor_header(p_data, FW_KEY_M, FW_KEY_N, FW_KEYS, &file_vhdr), sectrue, { send_failure( iface_num, FailureType_Failure_ProcessError, "Update file vender header invalid!" @@ -924,9 +916,10 @@ int process_msg_FirmwareUpdateEmmc(uint8_t iface_num, uint32_t msg_size, uint8_t ); // check file firmware hash + ExecuteCheck_MSGS_ADV( - check_image_contents_ram( - &file_hdr, p_data, file_vhdr.hdrlen + file_hdr.hdrlen, FIRMWARE_SECTORS_COUNT + check_image_contents_ADV( + &file_vhdr, &file_hdr, p_data + file_vhdr.hdrlen + file_hdr.hdrlen, 0, file_hdr.codelen ), sectrue, { @@ -959,14 +952,13 @@ int process_msg_FirmwareUpdateEmmc(uint8_t iface_num, uint32_t msg_size, uint8_t // vhdr if ( load_vendor_header( - (const uint8_t*)FIRMWARE_START, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, BOOTLOADER_KEYS, - &temp_vhdr + (const uint8_t*)FIRMWARE_START, FW_KEY_M, FW_KEY_N, FW_KEYS, &temp_vhdr ) == sectrue ) { memcpy(¤t_vhdr, &temp_vhdr, sizeof(current_vhdr)); } - // else if ( load_vendor_header(firmware_headers_backup, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, - // BOOTLOADER_KEYS, &temp_vhdr) == sectrue ) + // else if ( load_vendor_header(firmware_headers_backup, FW_KEY_M, FW_KEY_N, + // FW_KEYS, &temp_vhdr) == sectrue ) // { // memcpy(¤t_vhdr, &temp_vhdr, sizeof(current_vhdr)); // } @@ -1073,113 +1065,36 @@ int process_msg_FirmwareUpdateEmmc(uint8_t iface_num, uint32_t msg_size, uint8_t if ( sectrue == wipe_required ) { se_reset_storage(); - - // erease with retry, max 10 retry allowed, 10ms delay in between - ExecuteCheck_MSGS_ADV_RETRY_DELAY( - flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL), sectrue, - { - send_failure( - iface_num, FailureType_Failure_ProcessError, "Flash storage area erease failed!" - ); - return -1; - }, - 10, 10 - ); } - // write firmware - - size_t processed_bytes = 0; - size_t flash_sectors_index = 0; - while ( processed_bytes < firmware_file_size ) - { - - // wipe firmware area - // erease with retry, max 10 retry allowed, 10ms delay in between - ExecuteCheck_MSGS_ADV_RETRY_DELAY( - flash_erase(FIRMWARE_SECTORS[flash_sectors_index]), sectrue, - { - send_failure( - iface_num, FailureType_Failure_ProcessError, "Flash firmware area erease failed!" - ); - }, - 10, 10 - ); - // update progress (erase) - ui_screen_install_progress_upload( - (250 * flash_sectors_index / (firmware_file_size / flash_sector_size(flash_sectors_index)) - ) + - (750 * processed_bytes / firmware_file_size) - ); + char err_msg[64]; - // unlock - ExecuteCheck_MSGS_ADV(flash_unlock_write(), sectrue, { - send_failure(iface_num, FailureType_Failure_ProcessError, "Flash unlock failed!"); - return -1; - }); - - for ( size_t sector_offset = 0; - sector_offset < flash_sector_size(FIRMWARE_SECTORS[flash_sectors_index]); - sector_offset += 32 ) - { - // write with retry, max 10 retry allowed, 10ms delay in between - ExecuteCheck_MSGS_ADV_RETRY_DELAY( - flash_write_words( - FIRMWARE_SECTORS[flash_sectors_index], sector_offset, - (uint32_t*)(p_data + processed_bytes) - ), - sectrue, - { - send_failure(iface_num, FailureType_Failure_ProcessError, "Flash write failed!"); - return -1; - }, - 10, 10 - ); - - processed_bytes += ((firmware_file_size - processed_bytes) > 32) - ? 32 // since we could only write 32 byte a time - : (firmware_file_size - processed_bytes); - } - - // lock - ExecuteCheck_MSGS_ADV(flash_lock_write(), sectrue, { - send_failure(iface_num, FailureType_Failure_ProcessError, "Flash unlock failed!"); - return -1; - }); - - // update progress (write) - ui_screen_install_progress_upload( - (250 * flash_sectors_index / (firmware_file_size / flash_sector_size(flash_sectors_index)) - ) + - (750 * processed_bytes / firmware_file_size) - ); - - flash_sectors_index++; - } - - // wipe unused sectors - while ( flash_sectors_index < FIRMWARE_SECTORS_COUNT ) - { - flash_erase(FIRMWARE_SECTORS[flash_sectors_index]); - flash_sectors_index++; - } - - // verify flash firmware hash + // write firmware ExecuteCheck_MSGS_ADV( - check_image_contents( - &file_hdr, IMAGE_HEADER_SIZE + file_vhdr.hdrlen, FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT + install_firmware( + p_data, firmware_file_size, err_msg, sizeof(err_msg), NULL, + ui_screen_install_progress_upload ), sectrue, { - send_failure(iface_num, FailureType_Failure_ProcessError, "New firmware hash invalid!"); + send_failure(iface_num, FailureType_Failure_ProcessError, err_msg); // wipe invalid firmware, don't care the result as we cannot control, but we have to try EMMC_WRAPPER_FORCE_IGNORE( - flash_erase_sectors(FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT, NULL) + flash_erase_sectors(FIRMWARE_SECTORS, FIRMWARE_INNER_SECTORS_COUNT, NULL) ); return -1; } ); + ExecuteCheck_MSGS_ADV(verify_firmware(err_msg, sizeof(err_msg)), sectrue, { + send_failure(iface_num, FailureType_Failure_ProcessError, "New firmware hash invalid!"); + // wipe invalid firmware, don't care the result as we cannot control, but we have to try + EMMC_WRAPPER_FORCE_IGNORE( + flash_erase_sectors(FIRMWARE_SECTORS, FIRMWARE_INNER_SECTORS_COUNT, NULL) + ); + return -1; + }); + // backup new firmware header (not used since no where to stroe it) // As the firmware in flash has is the the same as the one from file, and it has been verified, we // could use file_vhdr and file_hdr, instead of read them from flash again. diff --git a/core/embed/emmc_wrapper/emmc_fs.c b/core/embed/emmc_wrapper/emmc_fs.c index ec3bf1684..fa9d41d6d 100644 --- a/core/embed/emmc_wrapper/emmc_fs.c +++ b/core/embed/emmc_wrapper/emmc_fs.c @@ -55,6 +55,21 @@ bool emmc_fs_init() return true; } +bool emmc_fs_uninit() +{ + // status update + OKEMMC_DBG_STATUS_SETUP(); + + if ( !emmc_wrapper_status.is_inited ) + return false; + + emmc_deinit(); + + emmc_wrapper_status.is_inited = false; + + return true; +} + bool emmc_fs_recreate(bool partition_table, bool onekey_data, bool user_data) { // status update @@ -407,18 +422,29 @@ bool emmc_fs_file_write( // open ExecuteCheck_OKEMMC_SIMPLE(f_open(&fhandle, path_buff, fopenmodes)); - // seek - ExecuteCheck_OKEMMC_SIMPLE(f_lseek(&fhandle, offset)); - // read - ExecuteCheck_OKEMMC_SIMPLE(f_write(&fhandle, buff, target_len, (UINT*)processed_len)); - // flush (not needed as f_close should flush the buffer) - // ExecuteCheck_OKEMMC_SIMPLE(f_sync(&fhandle)); + + // for "touch" file, all three params must be set to NULL and zero + if ( !(offset == 0 && buff == NULL && target_len == 0 && processed_len == NULL) ) + { + // seek + ExecuteCheck_OKEMMC_SIMPLE(f_lseek(&fhandle, offset)); + // write + ExecuteCheck_OKEMMC_SIMPLE(f_write(&fhandle, buff, target_len, (UINT*)processed_len)); + // flush (not needed as f_close should flush the buffer) + // ExecuteCheck_OKEMMC_SIMPLE(f_sync(&fhandle)); + } + // close ExecuteCheck_OKEMMC_SIMPLE(f_close(&fhandle)); return true; } +bool emmc_fs_file_touch(const char* path_buff) +{ + return emmc_fs_file_write(path_buff, 0, NULL, 0, NULL, false, true); +} + bool emmc_fs_file_delete(const char* path_buff) { // status update diff --git a/core/embed/emmc_wrapper/emmc_fs.h b/core/embed/emmc_wrapper/emmc_fs.h index 916a7248f..deac71bda 100644 --- a/core/embed/emmc_wrapper/emmc_fs.h +++ b/core/embed/emmc_wrapper/emmc_fs.h @@ -109,6 +109,7 @@ void emmc_fs_dbgex_append(const char* msg); void emmc_fs_dbgex_clr(); void emmc_fs_format_status(char* str, size_t str_len); bool emmc_fs_init(); +bool emmc_fs_uninit(); bool emmc_fs_recreate(bool partition_table, bool onekey_data, bool user_data); bool emmc_fs_is_partitioned(); bool emmc_fs_mount(bool onekey_data, bool user_data); @@ -126,6 +127,7 @@ bool emmc_fs_file_write( const char* path_buff, uint32_t offset, void* buff, uint32_t target_len, uint32_t* processed_len, bool overwrite, bool append ); +bool emmc_fs_file_touch(const char* path_buff); bool emmc_fs_file_delete(const char* path_buff); // bool emmc_fs_dir_list_internal( diff --git a/core/embed/extmod/modtrezorconfig/norcow_config.h b/core/embed/extmod/modtrezorconfig/norcow_config.h index c04717356..6fa47aa5f 100644 --- a/core/embed/extmod/modtrezorconfig/norcow_config.h +++ b/core/embed/extmod/modtrezorconfig/norcow_config.h @@ -35,9 +35,6 @@ #error Unknown Trezor model #endif -#define NORCOW_SECTORS \ - { FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2 } - /* * Current storage version. */ diff --git a/core/embed/extmod/modtrezorui/mipi_lcd.c b/core/embed/extmod/modtrezorui/mipi_lcd.c index b514e19ab..d3781bc57 100644 --- a/core/embed/extmod/modtrezorui/mipi_lcd.c +++ b/core/embed/extmod/modtrezorui/mipi_lcd.c @@ -471,9 +471,7 @@ void st7701_init_sequence(void) { #define LED_PWM_TIM_PERIOD (100) int display_backlight(int val) { -#if TREZOR_MODEL == 1 - val = 255; -#endif + if (val == 0 && DISPLAY_BACKLIGHT != 0) { // clock down __HAL_DSI_DISABLE(&hlcd_dsi); @@ -496,13 +494,7 @@ int display_backlight(int val) { int display_orientation(int degrees) { if (degrees != DISPLAY_ORIENTATION) { -#if defined TREZOR_MODEL_T if (degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270) { -#elif TREZOR_MODEL == 1 - if (degrees == 0 || degrees == 180) { -#else -#error Unknown Trezor model -#endif DISPLAY_ORIENTATION = degrees; // noop } diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 3f87a45c8..d02a2ac50 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -36,15 +36,15 @@ #include "ports/stm32/pendsv.h" #include "debug_utils.h" - +// #include "adc.h" #include "bl_check.h" #include "board_capabilities.h" #include "common.h" #include "compiler_traits.h" #include "display.h" -#include "emmc.h" -#include "ff.h" +#include "emmc_fs.h" #include "flash.h" +#include "hardware_version.h" #include "image.h" #include "mpu.h" #include "random_delays.h" @@ -76,129 +76,61 @@ // from util.s extern void shutdown_privileged(void); -static void copyflash2sdram(void) { - extern int _flash2_load_addr, _flash2_start, _flash2_end; - volatile uint32_t *dst = (volatile uint32_t *)&_flash2_start; - volatile uint32_t *end = (volatile uint32_t *)&_flash2_end; - volatile uint32_t *src = (volatile uint32_t *)&_flash2_load_addr; - - while (dst < end) { - *dst = *src; - if (*dst != *src) { - error_shutdown("Internal error", "(CF2S)", NULL, NULL); - } - dst++; - src++; - } -} - -PARTITION VolToPart[FF_VOLUMES] = { - {0, 1}, - {0, 2}, -}; - int main(void) { extern uint32_t _vector_offset; SCB->VTOR = (uint32_t)&_vector_offset; SystemCoreClockUpdate(); + dwt_init(); + mpu_config_firmware(); sdram_reinit(); - display_backlight(0); lcd_init(DISPLAY_RESX, DISPLAY_RESY, LCD_PIXEL_FORMAT_RGB565); + display_backlight(0); lcd_pwm_init(); + touch_init(); - // Enable MPU - mpu_config_firmware(); + ensure_emmcfs(emmc_fs_init(), "emmc_fs_init"); + ensure_emmcfs(emmc_fs_mount(true, false), "emmc_fs_mount"); + if (get_hw_ver() < HW_VER_3P0A) { + qspi_flash_init(); + qspi_flash_config(); + qspi_flash_memory_mapped(); + } - qspi_flash_init(); - qspi_flash_config(); - qspi_flash_memory_mapped(); + ble_usart_init(); + spi_slave_init(); random_delays_init(); - -#ifdef RDI - rdi_start(); -#endif - - // reinitialize HAL for Trezor One -#if defined TREZOR_MODEL_1 - HAL_Init(); -#endif - collect_hw_entropy(); -#ifdef SYSTEM_VIEW - enable_systemview(); -#endif - - ble_usart_init(); - - // #if !defined TREZOR_MODEL_1 - // parse_boardloader_capabilities(); - -#if PRODUCTION - // check_and_replace_bootloader(); -#endif - // #endif - - // Init peripherals - pendsv_init(); - -#if !PRODUCTION - // enable BUS fault and USAGE fault handlers - SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk); -#endif - -#if defined TREZOR_MODEL_1 - display_init(); - display_clear(); - button_init(); -#endif - display_clear(); - -#if defined TREZOR_MODEL_T - // display_init_seq(); - // sdcard_init(); - dwt_init(); - touch_init(); - spi_slave_init(); - motor_init(); - thd89_init(); - camera_init(); - - emmc_init(); - timer_init(); fingerprint_init(); - nfc_init(); - device_test(false); + timer_init(); + display_clear(); + pendsv_init(); + device_test(false); device_burnin_test(false); device_para_init(); - ensure(se_sync_session_key(), "se start up failed"); - copyflash2sdram(); +#ifdef RDI + rdi_start(); #endif -#if defined TREZOR_MODEL_R - button_init(); - display_clear(); - rgb_led_init(); +#ifdef SYSTEM_VIEW + enable_systemview(); #endif -#if !defined TREZOR_MODEL_1 - // jump to unprivileged mode - // http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html - // __asm__ volatile("msr control, %0" ::"r"(0x1)); - // __asm__ volatile("isb"); - +#if !PRODUCTION + // enable BUS fault and USAGE fault handlers + SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk); #endif #ifdef USE_SECP256K1_ZKP diff --git a/core/embed/fw_keys/fw_keys.c b/core/embed/fw_keys/fw_keys.c new file mode 100644 index 000000000..bb17e88f8 --- /dev/null +++ b/core/embed/fw_keys/fw_keys.c @@ -0,0 +1,30 @@ +#include "fw_keys.h" + +#if PRODUCTION +const uint8_t FW_KEY_M = 4; +const uint8_t FW_KEY_N = 7; +const uint8_t * const FW_KEYS[] = { + (const uint8_t + *)"\x15\x4b\x8a\xb2\x61\xcc\x88\x79\x48\x3f\x68\x9a\x2d\x41\x24\x3a\xe7\xdb\xc4\x02\x16\x72\xbb\xd2\x5c\x33\x8a\xe8\x4d\x93\x11\x54", + (const uint8_t + *)"\xa9\xe6\x5e\x07\xfe\x6d\x39\xa8\xa8\x4e\x11\xa9\x96\xa0\x28\x3f\x88\x1e\x17\x5c\xba\x60\x2e\xb5\xac\x44\x2f\xb7\x5b\x39\xe8\xe0", + (const uint8_t + *)"\x6c\x88\x05\xab\xb2\xdf\x9d\x36\x79\xf1\xd2\x8a\x40\xcd\x99\x03\x99\xb9\x9f\xc3\xee\x4e\x06\x57\xd8\x1d\x38\x1e\xa1\x48\x8a\x12", + (const uint8_t + *)"\x3e\xd7\x97\x79\x06\x4d\x56\x57\x1b\x29\xbc\xaa\x73\x4c\xbb\x6d\xb6\x1d\x2e\x62\x65\x66\x62\x8e\xcf\x4c\x89\xe1\xdb\x45\xea\xec", + (const uint8_t + *)"\x54\xa4\x06\x33\xbf\xd9\xe6\x0b\x8a\x39\x12\x65\xb2\xe0\x06\x37\x4a\xbe\x63\x1d\x1e\x11\x07\x33\x2b\xca\x56\xbf\x9f\x8c\x5c\x99", + (const uint8_t + *)"\x4b\x71\x13\x4f\x18\xe0\x07\x87\xc5\x83\xd4\x07\x42\xcc\x18\x8e\x17\xfc\x85\xad\xe4\xcb\x47\x2d\xae\x5e\xf8\xe0\x69\xf0\xfe\xc5", + (const uint8_t + *)"\x2e\xcf\x80\xc8\x2b\x44\x98\x48\xc0\x00\x33\x50\x92\x13\x95\x51\xbf\xe4\x7b\x3c\x73\x17\xb4\x99\x50\xf6\x5e\x1d\x82\x43\x20\x24", +}; +#else +const uint8_t FW_KEY_M = 2; +const uint8_t FW_KEY_N = 3; +const uint8_t * const FW_KEYS[] = { + (const uint8_t *)"\x57\x11\x4f\x0a\xa6\x69\xd2\xf8\x37\xe0\x40\xab\x9b\xb5\x1c\x00\x99\x12\x09\xf8\x4b\xfd\x7b\xf0\xf8\x93\x67\x62\x46\xfb\xa2\x4a", + (const uint8_t *)"\xdc\xae\x8e\x37\xdf\x5c\x24\x60\x27\xc0\x3a\xa9\x51\xbd\x6e\xc6\xca\xa7\xad\x32\xc1\x66\xb1\xf5\x48\xa4\xef\xcd\x88\xca\x3c\xa5", + (const uint8_t *)"\x77\x29\x12\xab\x61\xd1\xdc\x4f\x91\x33\x32\x5e\x57\xe1\x46\xab\x9f\xac\x17\xa4\x57\x2c\x6f\xcd\xf3\x55\xf8\x00\x36\x10\x00\x04", +}; +#endif diff --git a/core/embed/fw_keys/fw_keys.h b/core/embed/fw_keys/fw_keys.h new file mode 100644 index 000000000..9854a4b85 --- /dev/null +++ b/core/embed/fw_keys/fw_keys.h @@ -0,0 +1,10 @@ +#ifndef _FW_KEYS_H_ +#define _FW_KEYS_H_ + +#include + +extern const uint8_t FW_KEY_M; +extern const uint8_t FW_KEY_N; +extern const uint8_t* const FW_KEYS[]; + +#endif // _FW_KEYS_H_ \ No newline at end of file diff --git a/core/embed/pn532/pn532.c b/core/embed/pn532/pn532.c index 11313be0e..c316a8ac7 100644 --- a/core/embed/pn532/pn532.c +++ b/core/embed/pn532/pn532.c @@ -24,14 +24,16 @@ void pn532_power_ctl(bool on_off) { if ( on_off ) { + pn532_controller.spi_controller->spi_init(); pn532_controller.stub_controller->chip_reset_ctl(false); - pn532_controller.delay_ms(5); + pn532_controller.delay_ms(10); pn532_controller.stub_controller->chip_reset_ctl(true); pn532_controller.delay_ms(20); } else { pn532_controller.stub_controller->chip_reset_ctl(false); + pn532_controller.spi_controller->spi_deinit(); pn532_controller.delay_ms(5); } } diff --git a/core/embed/trezorhal/adc.c b/core/embed/trezorhal/adc.c new file mode 100644 index 000000000..96a271d11 --- /dev/null +++ b/core/embed/trezorhal/adc.c @@ -0,0 +1,153 @@ +#include "adc.h" + +#include STM32_HAL_H + +typedef enum { + ADC_DEVICE_INVALID_MIN = -1, + ADC_DEVICE_HW_VER, + ADC_DEVICE_INVALID_MAX, +} ADC_DEVICE_t; + +// static ADC_TypeDef adc_controllers[ADC_DEVICE_INVALID_MAX]; +// static uint16_t adc_controllers[ADC_DEVICE_INVALID_MAX]; +// static GPIO_TypeDef adc_gpio_ports[ADC_DEVICE_INVALID_MAX]; +// static uint16_t adc_gpio_pins[ADC_DEVICE_INVALID_MAX]; + +static bool adc_device_initialized[ADC_DEVICE_INVALID_MAX] = {0}; +static ADC_HandleTypeDef adc_handles[ADC_DEVICE_INVALID_MAX] = {0}; + +static bool adc_init_device_hw_ver() { + if (adc_device_initialized[ADC_DEVICE_HW_VER]) return false; + + // GPIO INIT + + // PA7 ------> ADC1_INP7 + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + __HAL_RCC_GPIOA_CLK_ENABLE(); + + GPIO_InitStruct.Pin = GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // ADC INIT + + ADC_MultiModeTypeDef multimode = {0}; + ADC_ChannelConfTypeDef sConfig = {0}; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC; + PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_CLKP; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + return false; + } + __HAL_RCC_ADC12_CLK_ENABLE(); + __HAL_RCC_ADC12_FORCE_RESET(); + __HAL_RCC_ADC12_RELEASE_RESET(); + + adc_handles[ADC_DEVICE_HW_VER].Instance = ADC1; + adc_handles[ADC_DEVICE_HW_VER].Init.ScanConvMode = ADC_SCAN_DISABLE; + adc_handles[ADC_DEVICE_HW_VER].Init.EOCSelection = ADC_EOC_SINGLE_CONV; + adc_handles[ADC_DEVICE_HW_VER].Init.LowPowerAutoWait = DISABLE; + adc_handles[ADC_DEVICE_HW_VER].Init.ContinuousConvMode = DISABLE; + adc_handles[ADC_DEVICE_HW_VER].Init.NbrOfConversion = 1; + adc_handles[ADC_DEVICE_HW_VER].Init.DiscontinuousConvMode = DISABLE; + adc_handles[ADC_DEVICE_HW_VER].Init.ExternalTrigConv = ADC_SOFTWARE_START; + adc_handles[ADC_DEVICE_HW_VER].Init.ExternalTrigConvEdge = + ADC_EXTERNALTRIGCONVEDGE_NONE; + adc_handles[ADC_DEVICE_HW_VER].Init.ConversionDataManagement = + ADC_CONVERSIONDATA_DR; + adc_handles[ADC_DEVICE_HW_VER].Init.Overrun = ADC_OVR_DATA_PRESERVED; + adc_handles[ADC_DEVICE_HW_VER].Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; + adc_handles[ADC_DEVICE_HW_VER].Init.OversamplingMode = DISABLE; + adc_handles[ADC_DEVICE_HW_VER].Init.Oversampling.Ratio = 1; + // if ( HAL_ADC_Init(&adc_handles[ADC_DEVICE_HW_VER]) != HAL_OK ) + // { + // return false; + // } + adc_handles[ADC_DEVICE_HW_VER].Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; + adc_handles[ADC_DEVICE_HW_VER].Init.Resolution = ADC_RESOLUTION_16B; + if (HAL_ADC_Init(&adc_handles[ADC_DEVICE_HW_VER]) != HAL_OK) { + return false; + } + + multimode.Mode = ADC_MODE_INDEPENDENT; + if (HAL_ADCEx_MultiModeConfigChannel(&adc_handles[ADC_DEVICE_HW_VER], + &multimode) != HAL_OK) { + return false; + } + + sConfig.Channel = ADC_CHANNEL_7; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; + sConfig.OffsetSignedSaturation = DISABLE; + if (HAL_ADC_ConfigChannel(&adc_handles[ADC_DEVICE_HW_VER], &sConfig) != + HAL_OK) { + return false; + } + + adc_device_initialized[ADC_DEVICE_HW_VER] = true; + return true; +} + +static bool adc_deinit_device_hw_ver() { + if (!adc_device_initialized[ADC_DEVICE_HW_VER]) return false; + + __HAL_RCC_ADC12_FORCE_RESET(); + __HAL_RCC_ADC12_RELEASE_RESET(); + __HAL_RCC_ADC12_CLK_DISABLE(); + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_7); + + adc_device_initialized[ADC_DEVICE_HW_VER] = false; + + return true; +} + +bool adc_read_device_hw_ver(uint16_t* value) { + if (!adc_device_initialized[ADC_DEVICE_HW_VER]) return false; + + /* Run the ADC calibration in single-ended mode */ + if (HAL_ADCEx_Calibration_Start(&adc_handles[ADC_DEVICE_HW_VER], + ADC_CALIB_OFFSET_LINEARITY, + ADC_SINGLE_ENDED) != HAL_OK) { + /* Calibration Error */ + return false; + } + + /*##-3- Start the conversion process*/ + if (HAL_ADC_Start(&adc_handles[ADC_DEVICE_HW_VER]) != HAL_OK) { + /* Start Conversation Error */ + return false; + } + + /*##-4- Wait for the end of conversion*/ + /* For simplicity reasons, this example is just waiting till the end of the + conversion, but application may perform other tasks while conversion + operation is ongoing. */ + if (HAL_ADC_PollForConversion(&adc_handles[ADC_DEVICE_HW_VER], 10) != + HAL_OK) { + /* End Of Conversion flag not set on time */ + return false; + } else { + /* ADC conversion completed */ + /*##-5- Get the converted value of regular channel*/ + *value = HAL_ADC_GetValue(&adc_handles[ADC_DEVICE_HW_VER]); + } + + return true; +} + +bool adc_init() { + if (!adc_init_device_hw_ver()) return false; + return true; +} + +bool adc_deinit() { + if (!adc_deinit_device_hw_ver()) return false; + return true; +} diff --git a/core/embed/trezorhal/adc.h b/core/embed/trezorhal/adc.h new file mode 100644 index 000000000..15a19bc7f --- /dev/null +++ b/core/embed/trezorhal/adc.h @@ -0,0 +1,15 @@ +#ifndef TREZORHAL_ADC_H +#define TREZORHAL_ADC_H + +#include +#include + +bool adc_init(); +bool adc_deinit(); +bool adc_read_device_hw_ver(uint16_t *value); + +// helper functions + +// defines + +#endif \ No newline at end of file diff --git a/core/embed/trezorhal/device.c b/core/embed/trezorhal/device.c index 5ad7ae156..fc2d1a1f7 100644 --- a/core/embed/trezorhal/device.c +++ b/core/embed/trezorhal/device.c @@ -22,6 +22,7 @@ #include "ff.h" #include "fingerprint.h" #include "fp_sensor_wrapper.h" +#include "hardware_version.h" #include "jpeg_dma.h" #include "nfc.h" #include "sdram.h" @@ -683,14 +684,16 @@ void device_test(bool force) { COLOR_BLACK); } - if (qspi_flash_read_id() == 0) { - display_text(0, 50, "SPI-FLASH test faild", -1, FONT_NORMAL, COLOR_RED, - COLOR_BLACK); - while (1) - ; - } else { - display_text(0, 50, "SPI-FLASH test done", -1, FONT_NORMAL, COLOR_WHITE, - COLOR_BLACK); + if (get_hw_ver() < HW_VER_3P0A) { + if (qspi_flash_read_id() == 0) { + display_text(0, 50, "SPI-FLASH test faild", -1, FONT_NORMAL, COLOR_RED, + COLOR_BLACK); + while (1) + ; + } else { + display_text(0, 50, "SPI-FLASH test done", -1, FONT_NORMAL, COLOR_WHITE, + COLOR_BLACK); + } } if (emmc_get_capacity_in_bytes() == 0) { @@ -1022,13 +1025,15 @@ void device_burnin_test(bool force) { while (1) ; } - flash_id = qspi_flash_read_id(); - if (flash_id == 0) { - display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2, - "SPI-FLASH test faild", -1, FONT_NORMAL, COLOR_RED, - COLOR_BLACK); - while (1) - ; + if (get_hw_ver() < HW_VER_3P0A) { + flash_id = qspi_flash_read_id(); + if (flash_id == 0) { + display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2, + "SPI-FLASH test faild", -1, FONT_NORMAL, + COLOR_RED, COLOR_BLACK); + while (1) + ; + } } if (!se_get_rand(rand_buffer, 32)) { @@ -1244,6 +1249,8 @@ bool device_overwrite_serial(char *dev_serial) { if (!device_backup_otp(false)) return false; // change and write back + memset(otp_data_buffer_p->flash_otp[FLASH_OTP_DEVICE_SERIAL], 0x00, + FLASH_OTP_BLOCK_SIZE); strlcpy((char *)(otp_data_buffer_p->flash_otp[FLASH_OTP_DEVICE_SERIAL]), dev_serial, FLASH_OTP_BLOCK_SIZE); diff --git a/core/embed/trezorhal/emmc.c b/core/embed/trezorhal/emmc.c index 8bda7b2d4..868844f33 100644 --- a/core/embed/trezorhal/emmc.c +++ b/core/embed/trezorhal/emmc.c @@ -69,6 +69,24 @@ void emmc_init(void) { } } +void emmc_deinit() { + // deinit + if (HAL_MMC_DeInit(&hmmc1) != HAL_OK) { + ensure(0, "mmc deinit fail"); + } + + // reset and close clock + __HAL_RCC_SDMMC1_FORCE_RESET(); + __HAL_RCC_SDMMC1_RELEASE_RESET(); + __HAL_RCC_SDMMC1_CLK_DISABLE(); + + // release gpios + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_8 | + GPIO_PIN_9 | GPIO_PIN_7 | GPIO_PIN_6); + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9 | GPIO_PIN_8); + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2); +} + uint8_t emmc_get_card_state(void) { return ((HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER) ? MMC_TRANSFER_OK diff --git a/core/embed/trezorhal/emmc.h b/core/embed/trezorhal/emmc.h index e3165ec54..38746b743 100644 --- a/core/embed/trezorhal/emmc.h +++ b/core/embed/trezorhal/emmc.h @@ -17,6 +17,7 @@ #define BOOT_EMMC_BLOCKS (2 * 1024 * 1024) // 1GB void emmc_init(); +void emmc_deinit(); uint8_t emmc_get_card_state(void); void emmc_get_card_info(EMMC_CardInfoTypeDef *card_info); uint8_t emmc_read_blocks(uint8_t *data, uint32_t address, uint32_t nums, diff --git a/core/embed/trezorhal/flash.c b/core/embed/trezorhal/flash.c index 865988078..badccfa6a 100644 --- a/core/embed/trezorhal/flash.c +++ b/core/embed/trezorhal/flash.c @@ -63,10 +63,6 @@ const uint8_t FIRMWARE_SECTORS[FIRMWARE_SECTORS_COUNT] = { 29, 30, FLASH_SECTOR_FIRMWARE_EXTRA_END}; -const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT] = { - FLASH_SECTOR_STORAGE_1, - FLASH_SECTOR_STORAGE_2, -}; #ifdef NOT_USED_pLDNf4fNyLwV1RqEGZub static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 2] = { @@ -148,15 +144,6 @@ const void *flash_get_address(uint8_t sector, uint32_t offset, uint32_t size) { (sector - FLASH_SECTOR_FIRMWARE_EXTRA_START) * FLASH_FIRMWARE_SECTOR_SIZE + offset); - } else if (sector >= FLASH_SECTOR_STORAGE_1 && - sector <= FLASH_SECTOR_STORAGE_2) { - if (offset + size > FLASH_STORAGE_SECTOR_SIZE) { - return NULL; - } - return (const void *)(QSPI_FLASH_BASE_ADDRESS + QSPI_FLASH_STORAG_OFFSET + - (sector - FLASH_SECTOR_STORAGE_1) * - FLASH_STORAGE_SECTOR_SIZE + - offset); } return NULL; } @@ -176,12 +163,7 @@ secbool flash_erase_sectors(const uint8_t *sectors, int len, (sectors[i] - FLASH_SECTOR_FIRMWARE_EXTRA_START) * 2 * QSPI_SECTOR_SIZE + QSPI_SECTOR_SIZE); - } else if (sectors[i] >= FLASH_SECTOR_STORAGE_1 && - sectors[i] <= FLASH_SECTOR_STORAGE_2) { - qspi_flash_erase_block_64k((sectors[i] - FLASH_SECTOR_STORAGE_1) * - QSPI_SECTOR_SIZE + - QSPI_FLASH_STORAG_OFFSET); - } else { + } else if (sectors[i] >= 0 && sectors[i] <= FLASH_INNER_COUNT) { ensure(flash_unlock_write(), NULL); FLASH_EraseInitTypeDef EraseInitStruct; EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; @@ -207,11 +189,7 @@ secbool flash_erase_sectors(const uint8_t *sectors, int len, // check whether the sector was really deleted (contains only 0xFF) const uint32_t addr_start = (uint32_t)flash_get_address(sectors[i], 0, 0); uint32_t addr_end; - if (sectors[i] < FLASH_SECTOR_STORAGE_1) { - addr_end = addr_start + FLASH_FIRMWARE_SECTOR_SIZE; - } else { - addr_end = addr_start + FLASH_STORAGE_SECTOR_SIZE; - } + addr_end = addr_start + FLASH_FIRMWARE_SECTOR_SIZE; for (uint32_t addr = addr_start; addr < addr_end; addr += 4) { if (*((const uint32_t *)addr) != 0xFFFFFFFF) { return secfalse; @@ -320,6 +298,7 @@ secbool flash_write_words(uint8_t sector, uint32_t offset, uint32_t data[8]) { } uint32_t flash_sector_size(uint8_t sector) { + // TODO: clean up / rewrite / really needed? if (sector >= FLASH_SECTOR_COUNT) { return 0; } @@ -328,9 +307,6 @@ uint32_t flash_sector_size(uint8_t sector) { } else if (sector >= FLASH_SECTOR_FIRMWARE_EXTRA_START && sector <= FLASH_SECTOR_FIRMWARE_EXTRA_END) { return FLASH_FIRMWARE_SECTOR_SIZE; - } else if (sector >= FLASH_SECTOR_STORAGE_1 && - sector <= FLASH_SECTOR_STORAGE_2) { - return FLASH_STORAGE_SECTOR_SIZE; } return 0; } @@ -395,7 +371,7 @@ bool flash_fix_ecc_fault_BOOTLOADER(uint32_t address) { // sanity check if (sector != FLASH_SECTOR_BOOTLOADER_1 && - sector != FLASH_SECTOR_BOOTLOADER_1) { + sector != FLASH_SECTOR_BOOTLOADER_2) { return false; } diff --git a/core/embed/trezorhal/flash.h b/core/embed/trezorhal/flash.h index 06a84ba01..3de5ac417 100644 --- a/core/embed/trezorhal/flash.h +++ b/core/embed/trezorhal/flash.h @@ -29,11 +29,10 @@ #define USE_EXTERN_FLASH 1 #if USE_EXTERN_FLASH -// 16 internal + 16 external code(2x64K) + 2 external storage(64K) -#define FLASH_SECTOR_COUNT (34) +// 16 internal + 16 external code(2x64K) +#define FLASH_SECTOR_COUNT (32) #define FLASH_BOOTLOADER_SECTOR_SIZE (128 * 1024) #define FLASH_FIRMWARE_SECTOR_SIZE (128 * 1024) -#define FLASH_STORAGE_SECTOR_SIZE (64 * 1024) #define FLASH_INNER_COUNT 16 #else #define FLASH_SECTOR_COUNT 16 @@ -49,11 +48,7 @@ #define FLASH_SECTOR_FIRMWARE_END 14 #define FLASH_SECTOR_FIRMWARE_EXTRA_START 16 #define FLASH_SECTOR_FIRMWARE_EXTRA_END 31 -#define FLASH_SECTOR_STORAGE_1 32 -#define FLASH_SECTOR_STORAGE_2 33 #else -#define FLASH_SECTOR_STORAGE_1 2 -#define FLASH_SECTOR_STORAGE_2 3 #define FLASH_SECTOR_FIRMWARE_START 4 #define FLASH_SECTOR_FIRMWARE_END 14 #endif @@ -61,11 +56,10 @@ #define BOOTLOADER_SECTORS_COUNT (2) #define FIRMWARE_INNER_SECTORS_COUNT (12) #define FIRMWARE_SECTORS_COUNT (12 + 16) -#define STORAGE_SECTORS_COUNT (2) +// #define STORAGE_SECTORS_COUNT (2) extern const uint8_t BOOTLOADER_SECTORS[BOOTLOADER_SECTORS_COUNT]; extern const uint8_t FIRMWARE_SECTORS[FIRMWARE_SECTORS_COUNT]; -extern const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT]; #define FLASH_STATUS_ALL_FLAGS \ (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR | FLASH_SR_WRPERR | \ diff --git a/core/embed/trezorhal/hardware_version.c b/core/embed/trezorhal/hardware_version.c new file mode 100644 index 000000000..5f9c45b4d --- /dev/null +++ b/core/embed/trezorhal/hardware_version.c @@ -0,0 +1,45 @@ +#include "hardware_version.h" + +#include "adc.h" +#include "util_macros.h" + +const char* const HW_VER_str[] = { + ENUM_NAME_ARRAY_ITEM(HW_VER_INVALID), ENUM_NAME_ARRAY_ITEM(HW_VER_UNKNOWN), + ENUM_NAME_ARRAY_ITEM(HW_VER_LEGACY), ENUM_NAME_ARRAY_ITEM(HW_VER_1P3A), + ENUM_NAME_ARRAY_ITEM(HW_VER_3P0), ENUM_NAME_ARRAY_ITEM(HW_VER_3P0A), +}; + +static bool check_mv_in_range(uint16_t value, uint16_t target, + uint16_t accuracy_percent) { + uint16_t mv_min = target * (100 - accuracy_percent) / 100; + uint16_t mv_max = target * (100 + accuracy_percent) / 100; + + if ((mv_min < value) && (value < mv_max)) + return true; + else + return false; +} + +uint16_t get_hw_ver_adc_raw() { + uint16_t adc_val; + if (!adc_read_device_hw_ver(&adc_val)) return 0; + return adc_val; +} + +uint16_t get_hw_ver_adc_mv() { + return (get_hw_ver_adc_raw() & HW_VER_ADC_RANGE_MAX) * + HW_VER_ADC_VOLTAGE_MAX / HW_VER_ADC_RANGE_MAX; +} + +HW_VER_t get_hw_ver() { + uint16_t adc_mv = get_hw_ver_adc_mv(); + + if (check_mv_in_range(adc_mv, HW_VER_LEGACY, HW_VER_PRECISION_PERCENT)) + return HW_VER_LEGACY; + if (check_mv_in_range(adc_mv, HW_VER_1P3A, HW_VER_PRECISION_PERCENT)) + return HW_VER_1P3A; + if (check_mv_in_range(adc_mv, HW_VER_3P0, HW_VER_PRECISION_PERCENT)) + return HW_VER_3P0; + + return HW_VER_UNKNOWN; +} \ No newline at end of file diff --git a/core/embed/trezorhal/hardware_version.h b/core/embed/trezorhal/hardware_version.h new file mode 100644 index 000000000..203041642 --- /dev/null +++ b/core/embed/trezorhal/hardware_version.h @@ -0,0 +1,36 @@ +#ifndef _HARDWARE_VERSION_H_ +#define _HARDWARE_VERSION_H_ + +#include + +// ADC PA7 for hardware version +// V1.3 and lower -> R82=10K,R83=100K ADCVAL=372; +// V1.3a -> R82=47K,R83=100K ADCVAL=1309; +// V2.0 -> R82=68K,R83=100K ADCVAL=1657; (NOT RELEASED) +// V3.0 -> R82=82K,R83=100K ADCVAL=1845; +// V3.0a -> R82=100K,R83=68K + +typedef enum { + // force compiler use at least 16bit number type + HW_VER_INVALID = 65535, + // values + HW_VER_UNKNOWN = 0, + HW_VER_LEGACY = 300, + HW_VER_1P3A = 1055, + HW_VER_3P0 = 1487, + HW_VER_3P0A = 1964, +} HW_VER_t; + +extern const char* const HW_VER_str[]; + +// max adc voltage 3.3v = 3300mv +#define HW_VER_ADC_VOLTAGE_MAX 3300 +#define HW_VER_ADC_RANGE_MAX 0xffff +// +/- 5% of mv value +#define HW_VER_PRECISION_PERCENT 15 + +uint16_t get_hw_ver_adc_raw(); +uint16_t get_hw_ver_adc_mv(); +HW_VER_t get_hw_ver(); + +#endif //_HARDWARE_VERSION_H_ diff --git a/core/embed/trezorhal/image.c b/core/embed/trezorhal/image.c index 021cb3778..b86a76147 100644 --- a/core/embed/trezorhal/image.c +++ b/core/embed/trezorhal/image.c @@ -23,11 +23,16 @@ #include "ed25519-donna/ed25519.h" #include "common.h" +#include "emmc_fs.h" #include "flash.h" +#include "fw_keys.h" +#include "hardware_version.h" #include "image.h" +#include "qspi_flash.h" +#include "util_macros.h" static secbool compute_pubkey(uint8_t sig_m, uint8_t sig_n, - const uint8_t *const *pub, uint8_t sigmask, + const uint8_t* const* pub, uint8_t sigmask, ed25519_public_key res) { if (0 == sig_m || 0 == sig_n) return secfalse; if (sig_m > sig_n) return secfalse; @@ -50,9 +55,9 @@ static secbool compute_pubkey(uint8_t sig_m, uint8_t sig_n, return sectrue * (0 == ed25519_cosi_combine_publickeys(res, keys, sig_m)); } -secbool load_image_header(const uint8_t *const data, const uint32_t magic, +secbool load_image_header(const uint8_t* const data, const uint32_t magic, const uint32_t maxsize, uint8_t key_m, uint8_t key_n, - const uint8_t *const *keys, image_header *const hdr) { + const uint8_t* const* keys, image_header* const hdr) { memcpy(&hdr->magic, data, 4); if (hdr->magic != magic) return secfalse; @@ -87,7 +92,7 @@ secbool load_image_header(const uint8_t *const data, const uint32_t magic, blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); blake2s_Update(&ctx, data, IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE); for (int i = 0; i < IMAGE_SIG_SIZE; i++) { - blake2s_Update(&ctx, (const uint8_t *)"\x00", 1); + blake2s_Update(&ctx, (const uint8_t*)"\x00", 1); } blake2s_Final(&ctx, hdr->fingerprint, BLAKE2S_DIGEST_LENGTH); @@ -97,11 +102,11 @@ secbool load_image_header(const uint8_t *const data, const uint32_t magic, return sectrue * (0 == ed25519_sign_open(hdr->fingerprint, BLAKE2S_DIGEST_LENGTH, pub, - *(const ed25519_signature *)hdr->sig)); + *(const ed25519_signature*)hdr->sig)); } -secbool load_ble_image_header(const uint8_t *const data, const uint32_t magic, - const uint32_t maxsize, image_header *const hdr) { +secbool load_ble_image_header(const uint8_t* const data, const uint32_t magic, + const uint32_t maxsize, image_header* const hdr) { memcpy(&hdr->magic, data, 4); if (hdr->magic != magic) return secfalse; @@ -133,9 +138,9 @@ secbool load_ble_image_header(const uint8_t *const data, const uint32_t magic, return sectrue; } -secbool load_thd89_image_header(const uint8_t *const data, const uint32_t magic, +secbool load_thd89_image_header(const uint8_t* const data, const uint32_t magic, const uint32_t maxsize, - image_header_th89 *const hdr) { + image_header_th89* const hdr) { memcpy(&hdr->magic, data, 4); if (hdr->magic != magic) return secfalse; @@ -159,8 +164,8 @@ secbool load_thd89_image_header(const uint8_t *const data, const uint32_t magic, return sectrue; } -secbool read_vendor_header(const uint8_t *const data, - vendor_header *const vhdr) { +secbool read_vendor_header(const uint8_t* const data, + vendor_header* const vhdr) { memcpy(&vhdr->magic, data, 4); if (vhdr->magic != 0x56544B4F) return secfalse; // OKTV @@ -189,7 +194,7 @@ secbool read_vendor_header(const uint8_t *const data, memcpy(&vhdr->vstr_len, data + 32 + vhdr->vsig_n * 32, 1); - vhdr->vstr = (const char *)(data + 32 + vhdr->vsig_n * 32 + 1); + vhdr->vstr = (const char*)(data + 32 + vhdr->vsig_n * 32 + 1); vhdr->vimg = data + 32 + vhdr->vsig_n * 32 + 1 + vhdr->vstr_len; // align to 4 bytes @@ -203,9 +208,9 @@ secbool read_vendor_header(const uint8_t *const data, return sectrue; } -secbool load_vendor_header(const uint8_t *const data, uint8_t key_m, - uint8_t key_n, const uint8_t *const *keys, - vendor_header *const vhdr) { +secbool load_vendor_header(const uint8_t* const data, uint8_t key_m, + uint8_t key_n, const uint8_t* const* keys, + vendor_header* const vhdr) { if (sectrue != read_vendor_header(data, vhdr)) { return secfalse; } @@ -217,7 +222,7 @@ secbool load_vendor_header(const uint8_t *const data, uint8_t key_m, blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); blake2s_Update(&ctx, data, vhdr->hdrlen - IMAGE_SIG_SIZE); for (int i = 0; i < IMAGE_SIG_SIZE; i++) { - blake2s_Update(&ctx, (const uint8_t *)"\x00", 1); + blake2s_Update(&ctx, (const uint8_t*)"\x00", 1); } blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH); @@ -227,10 +232,10 @@ secbool load_vendor_header(const uint8_t *const data, uint8_t key_m, return sectrue * (0 == ed25519_sign_open(hash, BLAKE2S_DIGEST_LENGTH, pub, - *(const ed25519_signature *)vhdr->sig)); + *(const ed25519_signature*)vhdr->sig)); } -void vendor_header_hash(const vendor_header *const vhdr, uint8_t *hash) { +void vendor_header_hash(const vendor_header* const vhdr, uint8_t* hash) { BLAKE2S_CTX ctx; blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH); blake2s_Update(&ctx, vhdr->vstr, vhdr->vstr_len); @@ -238,21 +243,20 @@ void vendor_header_hash(const vendor_header *const vhdr, uint8_t *hash) { blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH); } -secbool check_single_hash(const uint8_t *const hash, const uint8_t *const data, +secbool check_single_hash(const uint8_t* const hash, const uint8_t* const data, int len) { uint8_t h[BLAKE2S_DIGEST_LENGTH]; blake2s(data, len, h, BLAKE2S_DIGEST_LENGTH); return sectrue * (0 == memcmp(h, hash, BLAKE2S_DIGEST_LENGTH)); } -#if defined(STM32H747xx) -secbool check_image_contents(const image_header *const hdr, uint32_t firstskip, - const uint8_t *sectors, int blocks) { +secbool check_image_contents(const image_header* const hdr, uint32_t firstskip, + const uint8_t* sectors, int blocks) { if (0 == sectors || blocks < 1) { return secfalse; } - const void *data = + const void* data = flash_get_address(sectors[0], firstskip, IMAGE_CHUNK_SIZE - firstskip); if (!data) { return secfalse; @@ -319,42 +323,41 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip, return sectrue; } -secbool check_image_contents_ram(const image_header *const hdr, - const uint8_t *const buffer, - size_t code_offset, size_t blocks) { - if (hdr == NULL || buffer == NULL || (code_offset <= 0) || (blocks <= 0)) { +secbool check_image_contents_ADV(const vendor_header* const vhdr, + const image_header* const hdr, + const uint8_t* const code_buffer, + const size_t code_len_skipped, + const size_t code_len_check) { + // sanity check + if ( + // vhdr == NULL || // this is allowed since bootloader image have no vhdr + hdr == NULL || // hdr pointer must valid (loose check) + code_buffer == NULL // buffer pointer must valid (loose check) + ) { return false; } - secbool result = secfalse; - - const uint8_t *code_data = buffer + code_offset; - const size_t code_len = hdr->codelen; - const size_t hash_chunk_size = IMAGE_CHUNK_SIZE * 2; + // const vars + const size_t hash_chunk_size = FLASH_FIRMWARE_SECTOR_SIZE * 2; + const size_t first_chunk_skip = + ((vhdr != NULL) ? vhdr->hdrlen : 0) + hdr->hdrlen; + // vars + secbool result = secfalse; size_t processed_size = 0; - size_t block = 0; size_t process_size = 0; + size_t block = (code_len_skipped + first_chunk_skip) / hash_chunk_size; + // checking process while (true) { - if (processed_size >= code_len || block >= blocks) { - // make sure we actually checked something - if (processed_size > 0) - // flag set to valid - result = sectrue; - - // normal exit, no error found - break; - } - - if (processed_size == 0) - process_size = - MIN((code_len - processed_size), (hash_chunk_size - code_offset)); + if (processed_size == 0 && block == 0) + process_size = MIN((code_len_check - processed_size), + (hash_chunk_size - first_chunk_skip)); else - process_size = MIN((code_len - processed_size), (hash_chunk_size)); + process_size = MIN((code_len_check - processed_size), (hash_chunk_size)); if (sectrue == check_single_hash(hdr->hashes + block * 32, - code_data + processed_size, + code_buffer + processed_size, process_size)) { block++; processed_size += process_size; @@ -362,45 +365,298 @@ secbool check_image_contents_ram(const image_header *const hdr, // error exit, hash mismatch break; } + + if (processed_size >= code_len_check) { + // make sure we actually checked something + if (processed_size > 0) + // flag set to valid + result = sectrue; + + // normal exit, no error found + break; + } } return result; } -#else -secbool check_image_contents(const image_header *const hdr, uint32_t firstskip, - const uint8_t *sectors, int blocks) { - if (0 == sectors || blocks < 1) { - return secfalse; - } - const void *data = - flash_get_address(sectors[0], firstskip, IMAGE_CHUNK_SIZE - firstskip); - if (!data) { +secbool install_firmware(const uint8_t* const fw_buffer, const size_t fw_size, + char* error_msg, size_t error_msg_len, + size_t* const processed, + void (*const progress_callback)(int)) { + // sanity check + if (fw_buffer == NULL || // pointer invalid + fw_size <= 0 || // cannot be zero size + fw_size % 4 != 0 || // not 32 bit allined + error_msg == NULL || // must provide error reporting msg buffer + progress_callback == NULL // must provide progress reporting function + ) return secfalse; - } - int remaining = hdr->codelen; - if (sectrue != - check_single_hash(hdr->hashes, data, - MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) { - return secfalse; - } - int block = 1; - remaining -= IMAGE_CHUNK_SIZE - firstskip; - while (remaining > 0) { - if (block >= blocks) { + + // const vars + const size_t fw_internal_size = + FLASH_FIRMWARE_SECTOR_SIZE * FIRMWARE_INNER_SECTORS_COUNT; + + // vars + size_t processed_size = 0; + + // prepare + if (get_hw_ver() >= HW_VER_3P0A) { + // enusure dir exists and remove p2 file + if (!emmc_fs_dir_make("0:/data") || + !emmc_fs_file_delete("0:/data/fw_p2.bin")) { + strncpy(error_msg, "Flash firmware prepare failed! (EMMC)", + error_msg_len); return secfalse; } - data = flash_get_address(sectors[block], 0, IMAGE_CHUNK_SIZE); - if (!data) { - return secfalse; + } else { + // not worth it, take too long (8M for 25s) + // if ( HAL_OK != qspi_flash_erase_chip() ) + // { + // strncpy(error_msg, "Flash firmware prepare failed! (QSPI)", + // error_msg_len); return secfalse; + // } + } + + // install + while (processed_size < fw_size) { + if (processed_size < fw_internal_size) { + // install p1 + + // erase + EXEC_RETRY( + 10, sectrue, {}, + { + return flash_erase( + FIRMWARE_SECTORS[processed_size / FLASH_FIRMWARE_SECTOR_SIZE]); + }, + {}, + { + strncpy(error_msg, "Flash firmware area erease failed!", + error_msg_len); + return secfalse; + }); + + // unlock + EXEC_RETRY( + 10, sectrue, {}, { return flash_unlock_write(); }, {}, + { + strncpy(error_msg, "Flash unlock failed!", error_msg_len); + return secfalse; + }); + + // write + for (size_t sector_offset = 0; sector_offset < FLASH_FIRMWARE_SECTOR_SIZE; + sector_offset += 32) { + // write with retry, max 10 retry allowed + EXEC_RETRY( + 10, sectrue, {}, + { + return flash_write_words( + FIRMWARE_SECTORS[processed_size / FLASH_FIRMWARE_SECTOR_SIZE], + sector_offset, (uint32_t*)(fw_buffer + processed_size)); + }, + {}, + { + strncpy(error_msg, "Flash write failed!", error_msg_len); + return secfalse; + }); + + processed_size += ((fw_size - processed_size) > 32) + ? 32 // since we could only write 32 byte a time + : (fw_size - processed_size); + } + + // lock + EXEC_RETRY( + 10, sectrue, {}, { return flash_lock_write(); }, {}, + { + strncpy(error_msg, "Flash unlock failed!", error_msg_len); + return secfalse; + }); + } else { + // install p2 + + if (get_hw_ver() >= HW_VER_3P0A) { + // EMMC + uint32_t emmc_fs_processed = 0; + EXEC_RETRY( + 10, true, {}, + { + return emmc_fs_file_write( + "0:/data/fw_p2.bin", (processed_size - fw_internal_size), + (uint8_t*)(fw_buffer + processed_size), + MIN((fw_size - processed_size), FLASH_FIRMWARE_SECTOR_SIZE), + &emmc_fs_processed, false, true); + }, + { + processed_size += emmc_fs_processed; + hal_delay(100); // delay for visual + }, + { + strncpy(error_msg, "Flash write failed! (EMMC)", error_msg_len); + return secfalse; + }); + } else { + // QSPI + + // erase + EXEC_RETRY( + 10, sectrue, {}, + { + return flash_erase(FIRMWARE_SECTORS[processed_size / + FLASH_FIRMWARE_SECTOR_SIZE]); + }, + {}, + { + strncpy(error_msg, "Flash firmware area erease failed! (QSPI)", + error_msg_len); + return secfalse; + }); + + // unlock + EXEC_RETRY( + 10, sectrue, {}, { return flash_unlock_write(); }, {}, + { + strncpy(error_msg, "Flash unlock failed! (QSPI)", error_msg_len); + return secfalse; + }); + + // write + for (size_t sector_offset = 0; + sector_offset < FLASH_FIRMWARE_SECTOR_SIZE; sector_offset += 32) { + // write with retry, max 10 retry allowed + EXEC_RETRY( + 10, sectrue, {}, + { + return flash_write_words( + FIRMWARE_SECTORS[processed_size / + FLASH_FIRMWARE_SECTOR_SIZE], + sector_offset, (uint32_t*)(fw_buffer + processed_size)); + }, + {}, + { + strncpy(error_msg, "Flash write failed! (QSPI)", error_msg_len); + return secfalse; + }); + + processed_size += + ((fw_size - processed_size) > 32) + ? 32 // since we could only write 32 byte a time + : (fw_size - processed_size); + } + + // lock + EXEC_RETRY( + 10, sectrue, {}, { return flash_lock_write(); }, {}, + { + strncpy(error_msg, "Flash unlock failed! (QSPI)", error_msg_len); + return secfalse; + }); + } } - if (sectrue != check_single_hash(hdr->hashes + block * 32, data, - MIN(remaining, IMAGE_CHUNK_SIZE))) { - return secfalse; + + // update progress + progress_callback((1000 * processed_size / fw_size)); + if (processed != NULL) *processed = processed_size; + } + + if (get_hw_ver() < HW_VER_3P0A) { + // wipe unused sectors (P1 and P2 QSPI only) + size_t used_sector_count = + (processed_size / FLASH_FIRMWARE_SECTOR_SIZE) + + ((processed_size % FLASH_FIRMWARE_SECTOR_SIZE) != 0 ? 1 : 0); + while (used_sector_count < FIRMWARE_SECTORS_COUNT) { + flash_erase(FIRMWARE_SECTORS[used_sector_count]); + used_sector_count++; } - block++; - remaining -= IMAGE_CHUNK_SIZE; } + + return sectrue; +} + +secbool verify_firmware(char* error_msg, size_t error_msg_len) { + // sanity check + if (error_msg == NULL // must provide error reporting msg buffer + ) + return secfalse; + + // const vars + const size_t fw_internal_size = + FLASH_FIRMWARE_SECTOR_SIZE * FIRMWARE_INNER_SECTORS_COUNT; + const size_t fw_external_size = + FLASH_FIRMWARE_SECTOR_SIZE * + (FIRMWARE_SECTORS_COUNT - FIRMWARE_INNER_SECTORS_COUNT); + + // vars + vendor_header vhdr; + image_header hdr; + + // verify vhdr + ExecuteCheck_ADV(load_vendor_header((const uint8_t*)FIRMWARE_START, FW_KEY_M, + FW_KEY_N, FW_KEYS, &vhdr), + sectrue, { + strncpy(error_msg, "Firmware vender header invalid!", + error_msg_len); + return secfalse; + }); + + // verify hdr + ExecuteCheck_ADV( + load_image_header((const uint8_t*)(FIRMWARE_START + vhdr.hdrlen), + FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, + vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr), + sectrue, { + strncpy(error_msg, "Firmware image header invalid!", error_msg_len); + return secfalse; + }); + + // verify p1 + ExecuteCheck_ADV( + check_image_contents_ADV( + &vhdr, &hdr, + (const uint8_t*)FIRMWARE_START + vhdr.hdrlen + hdr.hdrlen, 0, + fw_internal_size - (vhdr.hdrlen + hdr.hdrlen)), + sectrue, { + strncpy(error_msg, "Firmware code invalid! (P1)", error_msg_len); + return secfalse; + }); + + // verify p2 + + if (get_hw_ver() >= HW_VER_3P0A) { + EMMC_PATH_INFO path_info = {0}; + uint32_t processed_len = 0; + + ExecuteCheck_ADV(emmc_fs_path_info("0:data/fw_p2.bin", &path_info), true, { + strncpy(error_msg, "Firmware code invalid! (P2_EMMC_1)", error_msg_len); + return secfalse; + }); + + ExecuteCheck_ADV(emmc_fs_file_read( + "0:data/fw_p2.bin", 0, (uint32_t*)0xD1C00000, + MAX(path_info.size, fw_external_size), &processed_len), + true, { + strncpy(error_msg, "Firmware code invalid! (P2_EMMC_2)", + error_msg_len); + return secfalse; + }); + } else { + memcpy((uint8_t*)0xD1C00000, (const uint8_t*)0x90000000, + hdr.codelen - (fw_internal_size - (vhdr.hdrlen + hdr.hdrlen))); + } + + ExecuteCheck_ADV( + check_image_contents_ADV( + &vhdr, &hdr, (const uint8_t*)0xD1C00000, + (fw_internal_size - (vhdr.hdrlen + hdr.hdrlen)), + hdr.codelen - (fw_internal_size - (vhdr.hdrlen + hdr.hdrlen))), + sectrue, { + memset((uint8_t*)0xD1C00000, 0x00, + (2 * 1024 * 1024)); // wipe the buffer if fail + strncpy(error_msg, "Firmware code invalid! (P2)", error_msg_len); + return secfalse; + }); + return sectrue; } -#endif diff --git a/core/embed/trezorhal/image.h b/core/embed/trezorhal/image.h index a0742d426..d6c42580e 100644 --- a/core/embed/trezorhal/image.h +++ b/core/embed/trezorhal/image.h @@ -23,15 +23,9 @@ #include #include "secbool.h" -#if PRODUCTION_MODEL == 'H' #define BOARDLOADER_START 0x08000000 #define BOOTLOADER_START 0x08020000 #define FIRMWARE_START 0x08060000 -#else -#define BOARDLOADER_START 0x08000000 -#define BOOTLOADER_START 0x08020000 -#define FIRMWARE_START 0x08040000 -#endif #define BOARDLOADER_SIZE (BOOTLOADER_START - BOARDLOADER_START) @@ -108,47 +102,56 @@ typedef struct { uint8_t vsig_n; uint16_t vtrust; // uint8_t reserved[14]; - const uint8_t *vpub[MAX_VENDOR_PUBLIC_KEYS]; + const uint8_t* vpub[MAX_VENDOR_PUBLIC_KEYS]; uint8_t vstr_len; - const char *vstr; - const uint8_t *vimg; + const char* vstr; + const uint8_t* vimg; uint8_t sigmask; uint8_t sig[64]; } vendor_header; -secbool __wur load_image_header(const uint8_t *const data, const uint32_t magic, +secbool __wur load_image_header(const uint8_t* const data, const uint32_t magic, const uint32_t maxsize, uint8_t key_m, - uint8_t key_n, const uint8_t *const *keys, - image_header *const hdr); + uint8_t key_n, const uint8_t* const* keys, + image_header* const hdr); -secbool __wur load_ble_image_header(const uint8_t *const data, +secbool __wur load_ble_image_header(const uint8_t* const data, const uint32_t magic, const uint32_t maxsize, - image_header *const hdr); + image_header* const hdr); -secbool __wur load_thd89_image_header(const uint8_t *const data, +secbool __wur load_thd89_image_header(const uint8_t* const data, const uint32_t magic, const uint32_t maxsize, - image_header_th89 *const hdr); + image_header_th89* const hdr); -secbool __wur load_vendor_header(const uint8_t *const data, uint8_t key_m, - uint8_t key_n, const uint8_t *const *keys, - vendor_header *const vhdr); +secbool __wur load_vendor_header(const uint8_t* const data, uint8_t key_m, + uint8_t key_n, const uint8_t* const* keys, + vendor_header* const vhdr); -secbool __wur read_vendor_header(const uint8_t *const data, - vendor_header *const vhdr); +secbool __wur read_vendor_header(const uint8_t* const data, + vendor_header* const vhdr); -void vendor_header_hash(const vendor_header *const vhdr, uint8_t *hash); +void vendor_header_hash(const vendor_header* const vhdr, uint8_t* hash); -secbool __wur check_single_hash(const uint8_t *const hash, - const uint8_t *const data, int len); +secbool __wur check_single_hash(const uint8_t* const hash, + const uint8_t* const data, int len); -secbool __wur check_image_contents(const image_header *const hdr, - uint32_t firstskip, const uint8_t *sectors, +secbool __wur check_image_contents(const image_header* const hdr, + uint32_t firstskip, const uint8_t* sectors, int blocks); -secbool __wur check_image_contents_ram(const image_header *const hdr, - const uint8_t *const buffer, - size_t code_offset, size_t blocks); +secbool __wur check_image_contents_ADV(const vendor_header* const vhdr, + const image_header* const hdr, + const uint8_t* const code_buffer, + const size_t code_len_skipped, + const size_t code_len_check); + +// secbool __wur install_bootloader(); +secbool __wur install_firmware(const uint8_t* const fw_buffer, + const size_t fw_size, char* error_msg, + size_t error_msg_len, size_t* const processed, + void (*const progress_callback)(int)); +secbool __wur verify_firmware(char* error_msg, size_t error_msg_len); #endif diff --git a/core/embed/trezorhal/lowlevel.c b/core/embed/trezorhal/lowlevel.c index b770c93bf..efda42043 100644 --- a/core/embed/trezorhal/lowlevel.c +++ b/core/embed/trezorhal/lowlevel.c @@ -211,64 +211,12 @@ void cpu_cache_enable(void) { SCB_EnableDCache(); } -/** - * @brief Configure the MPU attributes as Write Through for External SDRAM. - * @note The Base Address is 0xD0000000 . - * The Configured Region Size is 32MB because same as SDRAM size. - * @param None - * @retval None - */ -void mpu_config(void) { - MPU_Region_InitTypeDef MPU_InitStruct; - - /* Disable the MPU */ - HAL_MPU_Disable(); - - /* Configure the MPU attributes as WT for SDRAM */ - MPU_InitStruct.Enable = MPU_REGION_ENABLE; - MPU_InitStruct.BaseAddress = SDRAM_DEVICE_ADDR; - MPU_InitStruct.Size = MPU_REGION_SIZE_32MB; - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; - MPU_InitStruct.Number = MPU_REGION_NUMBER0; - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; - MPU_InitStruct.SubRegionDisable = 0x00; - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; - - HAL_MPU_ConfigRegion(&MPU_InitStruct); - - // NAND FLASH - // MPU_InitStruct.Enable = MPU_REGION_ENABLE; - // MPU_InitStruct.BaseAddress = 0x80000000; - // MPU_InitStruct.Size = MPU_REGION_SIZE_512MB; // - // MPU_REGION_SIZE_512MB; MPU_InitStruct.AccessPermission = - // MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = - // MPU_ACCESS_BUFFERABLE; MPU_InitStruct.IsCacheable = - // MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = - // MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = - // MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; - // MPU_InitStruct.SubRegionDisable = 0x00; - // MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; - // HAL_MPU_ConfigRegion(&MPU_InitStruct); - - // SPI FLASH - MPU_InitStruct.Enable = MPU_REGION_ENABLE; - MPU_InitStruct.BaseAddress = 0x90000000; - MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; // MPU_REGION_SIZE_512MB; - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; - MPU_InitStruct.Number = MPU_REGION_NUMBER1; - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; - MPU_InitStruct.SubRegionDisable = 0x00; - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; - HAL_MPU_ConfigRegion(&MPU_InitStruct); - - /* Enable the MPU */ - HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); +void cpu_cache_disable(void) { + /* Disable I-Cache */ + SCB_DisableICache(); + + /* Disable D-Cache */ + SCB_DisableDCache(); } /** @@ -473,8 +421,4 @@ void flash_option_bytes_init(void) { void bus_fault_enable(void) { SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk; } void bus_fault_disable(void) { SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTENA_Msk; } -void led_on(void) { HAL_GPIO_WritePin(GPIOI, GPIO_PIN_14, GPIO_PIN_RESET); } - -void led_off(void) { HAL_GPIO_WritePin(GPIOI, GPIO_PIN_14, GPIO_PIN_SET); } - #endif diff --git a/core/embed/trezorhal/lowlevel.h b/core/embed/trezorhal/lowlevel.h index e6038428f..b4cd11d33 100644 --- a/core/embed/trezorhal/lowlevel.h +++ b/core/embed/trezorhal/lowlevel.h @@ -34,19 +34,14 @@ void reset_flags_reset(void); #if defined(STM32H747xx) -#define SDRAM_DEVICE_ADDR 0xD0000000U -#define SDRAM_DEVICE_SIZE 0x2000000U - void cpu_cache_enable(void); -void mpu_config(void); +void cpu_cache_disable(void); void system_clock_config(void); void flash_option_bytes_init(void); void bus_fault_enable(void); void bus_fault_disable(void); -void led_on(void); -void led_off(void); #endif #endif // __TREZORHAL_LOWLEVEL_H__ diff --git a/core/embed/trezorhal/mpu.c b/core/embed/trezorhal/mpu.c index b938f9b5c..c74ab31e9 100644 --- a/core/embed/trezorhal/mpu.c +++ b/core/embed/trezorhal/mpu.c @@ -18,11 +18,8 @@ */ #include STM32_HAL_H -#if defined(STM32H747xx) #include "stm32h7xx_ll_cortex.h" -#else -#include "stm32f4xx_ll_cortex.h" -#endif + // http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html #define MPU_RASR_ATTR_FLASH (MPU_RASR_C_Msk) #define MPU_RASR_ATTR_SRAM (MPU_RASR_C_Msk | MPU_RASR_S_Msk) @@ -35,11 +32,62 @@ void mpu_config_off(void) { HAL_MPU_Disable(); } +void mpu_config_boardloader(void) { + MPU_Region_InitTypeDef MPU_InitStruct; + + /* Disable the MPU */ + HAL_MPU_Disable(); + + /* Configure the MPU attributes as WT for SDRAM */ + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.BaseAddress = 0xD0000000U; + MPU_InitStruct.Size = MPU_REGION_SIZE_32MB; + MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; + MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER0; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + MPU_InitStruct.SubRegionDisable = 0x00; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + // FLASH + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.BaseAddress = 0x80000000; + MPU_InitStruct.Size = MPU_REGION_SIZE_128KB; + MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER1; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + MPU_InitStruct.SubRegionDisable = 0x00; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + // SPI FLASH + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.BaseAddress = 0x90000000; + MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; + MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; + MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER2; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + MPU_InitStruct.SubRegionDisable = 0x00; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /* Enable the MPU */ + HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); +} + void mpu_config_bootloader(void) { // Disable MPU HAL_MPU_Disable(); // Note: later entries overwrite previous ones -#if defined(STM32H747xx) MPU_Region_InitTypeDef MPU_InitStruct; @@ -115,15 +163,15 @@ void mpu_config_bootloader(void) { // SPI FLASH MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x90000000; - MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; // MPU_REGION_SIZE_512MB; + MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER5; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); // AXI SRAM @@ -141,64 +189,12 @@ void mpu_config_bootloader(void) { HAL_MPU_ConfigRegion(&MPU_InitStruct); HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); -#else - - // Everything (0x00000000 - 0xFFFFFFFF, 4 GiB, read-write) - MPU->RNR = MPU_REGION_NUMBER0; - MPU->RBAR = 0; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_4GB | LL_MPU_REGION_FULL_ACCESS; - - // Flash (0x0800C000 - 0x0800FFFF, 16 KiB, no access) - MPU->RNR = MPU_REGION_NUMBER1; - MPU->RBAR = FLASH_BASE + 0xC000; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS; - - // Flash (0x0810C000 - 0x0810FFFF, 16 KiB, no access) - MPU->RNR = MPU_REGION_NUMBER2; - MPU->RBAR = FLASH_BASE + 0x10C000; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS; - - // SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, - // read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER3; - MPU->RBAR = SRAM_BASE; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | - LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0); - - // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) - // External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER4; - MPU->RBAR = PERIPH_BASE; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | - LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk; - -#ifdef STM32F427xx - // CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER5; - MPU->RBAR = CCMDATARAM_BASE; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | - LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk; -#elif STM32F405xx - // no CCMRAM -#else -#error Unsupported MCU -#endif - // Enable MPU - HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); -#endif } void mpu_config_firmware(void) { // Disable MPU HAL_MPU_Disable(); // Note: later entries overwrite previous ones -#if defined(STM32H747xx) MPU_Region_InitTypeDef MPU_InitStruct; // flash ,read only @@ -326,29 +322,17 @@ void mpu_config_firmware(void) { MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); + // SPI FLASH // SPI FLASH MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x90000000; - MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; // MPU_REGION_SIZE_512MB; + MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER9; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; - MPU_InitStruct.SubRegionDisable = 0x80; - MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; - HAL_MPU_ConfigRegion(&MPU_InitStruct); - - MPU_InitStruct.Enable = MPU_REGION_ENABLE; - MPU_InitStruct.BaseAddress = 0x90700000; - MPU_InitStruct.Size = MPU_REGION_SIZE_1MB; // MPU_REGION_SIZE_512MB; - MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; - MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; - MPU_InitStruct.Number = MPU_REGION_NUMBER10; - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); @@ -360,88 +344,13 @@ void mpu_config_firmware(void) { MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; - MPU_InitStruct.Number = MPU_REGION_NUMBER11; + MPU_InitStruct.Number = MPU_REGION_NUMBER10; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); -#else - - /* - // Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never) - MPU->RBAR = FLASH_BASE | MPU_REGION_NUMBER0; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk; - */ - - // Bootloader (0x08020000 - 0x0803FFFF, 64 KiB, read-only) - MPU->RNR = MPU_REGION_NUMBER0; - MPU->RBAR = FLASH_BASE + 0x20000; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO; - - // Storage#1 (0x08010000 - 0x0801FFFF, 64 KiB, read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER1; - MPU->RBAR = FLASH_BASE + 0x10000; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk; - // Storage#2 (0x08110000 - 0x0811FFFF, 64 KiB, read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER2; - MPU->RBAR = FLASH_BASE + 0x110000; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk; - - // Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at - // start = 768 KiB, read-only) - MPU->RNR = MPU_REGION_NUMBER3; - MPU->RBAR = FLASH_BASE; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | - MPU_SUBREGION_DISABLE(0x03); - - // Firmware extra (0x08120000 - 0x081FFFFF, 7 * 128 KiB = 1024 KiB except 1/8 - // at start = 896 KiB, read-only) - MPU->RNR = MPU_REGION_NUMBER4; - MPU->RBAR = FLASH_BASE + 0x100000; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | - LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | - MPU_SUBREGION_DISABLE(0x01); - - // SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, - // read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER5; - MPU->RBAR = SRAM_BASE; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | - LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0); - - // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) - // External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER6; - MPU->RBAR = PERIPH_BASE; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | - LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk; - -#ifdef STM32F427xx - // CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never) - MPU->RNR = MPU_REGION_NUMBER7; - MPU->RBAR = CCMDATARAM_BASE; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | - LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | - MPU_RASR_XN_Msk; -#elif STM32F405xx - // no CCMRAM -#else -#error Unsupported MCU -#endif - // Enable MPU - HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); -#endif __asm__ volatile("dsb"); __asm__ volatile("isb"); diff --git a/core/embed/trezorhal/mpu.h b/core/embed/trezorhal/mpu.h index 9d30af77b..307193900 100644 --- a/core/embed/trezorhal/mpu.h +++ b/core/embed/trezorhal/mpu.h @@ -21,6 +21,7 @@ #define __MPU_H__ void mpu_config_off(void); +void mpu_config_boardloader(void); void mpu_config_bootloader(void); void mpu_config_firmware(void); diff --git a/core/embed/trezorhal/qspi_flash.c b/core/embed/trezorhal/qspi_flash.c index 04bfd9d0b..e80ae19e7 100644 --- a/core/embed/trezorhal/qspi_flash.c +++ b/core/embed/trezorhal/qspi_flash.c @@ -162,7 +162,7 @@ static int qspi_flash_write_enable(void) { return HAL_OK; } -static int qspi_flash_atuo_polling_mem_ready(void) { +static int qspi_flash_atuo_polling_mem_ready(uint32_t timeout) { QSPI_CommandTypeDef command = {0}; QSPI_AutoPollingTypeDef config = {0}; @@ -185,15 +185,14 @@ static int qspi_flash_atuo_polling_mem_ready(void) { config.Interval = 0x10; config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; - if (HAL_QSPI_AutoPolling(&hqspi, &command, &config, - HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + if (HAL_QSPI_AutoPolling(&hqspi, &command, &config, timeout) != HAL_OK) { return HAL_ERROR; } return HAL_OK; } -int qspi_flash_read_status1(uint8_t *status) { +int qspi_flash_read_status1(uint8_t* status) { QSPI_CommandTypeDef command; command.InstructionMode = QSPI_INSTRUCTION_1_LINE; @@ -221,7 +220,7 @@ int qspi_flash_read_status1(uint8_t *status) { return HAL_OK; } -int qspi_flash_read_status2(uint8_t *status) { +int qspi_flash_read_status2(uint8_t* status) { QSPI_CommandTypeDef command; command.InstructionMode = QSPI_INSTRUCTION_1_LINE; @@ -282,7 +281,8 @@ int qspi_flash_write_status(uint8_t status1_val, uint8_t status2_val) { return HAL_ERROR; } - if (qspi_flash_atuo_polling_mem_ready() != HAL_OK) { + if (qspi_flash_atuo_polling_mem_ready(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != + HAL_OK) { return HAL_ERROR; } return HAL_OK; @@ -320,7 +320,8 @@ int qspi_flash_write_status2(uint8_t status2_val) { return HAL_ERROR; } - if (qspi_flash_atuo_polling_mem_ready() != HAL_OK) { + if (qspi_flash_atuo_polling_mem_ready(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != + HAL_OK) { return HAL_ERROR; } return HAL_OK; @@ -473,7 +474,8 @@ int qspi_flash_erase_sector(uint32_t address) { return HAL_ERROR; } - if (qspi_flash_atuo_polling_mem_ready() != HAL_OK) { + if (qspi_flash_atuo_polling_mem_ready(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != + HAL_OK) { return HAL_ERROR; } @@ -509,7 +511,8 @@ int qspi_flash_erase_block_64k(uint32_t address) { return HAL_ERROR; } - if (qspi_flash_atuo_polling_mem_ready() != HAL_OK) { + if (qspi_flash_atuo_polling_mem_ready(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != + HAL_OK) { return HAL_ERROR; } @@ -524,6 +527,10 @@ int qspi_flash_erase_chip(void) { CmdCplt = 0; + if (memory_mapped) { + qspi_flash_quit_memory_mapped(); + } + qspi_flash_write_enable(); command.InstructionMode = QSPI_INSTRUCTION_1_LINE; @@ -534,7 +541,7 @@ int qspi_flash_erase_chip(void) { command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; command.Instruction = BULK_ERASE_CMD; - command.AddressMode = QSPI_DATA_NONE; + command.AddressMode = QSPI_ADDRESS_NONE; command.Address = 0; command.DataMode = QSPI_DATA_NONE; command.DummyCycles = 0; @@ -544,13 +551,20 @@ int qspi_flash_erase_chip(void) { return HAL_ERROR; } - if (qspi_flash_atuo_polling_mem_ready() != HAL_OK) { + // about 4ms per KB on avg. fir gd25q and w25q + if (qspi_flash_atuo_polling_mem_ready(sf_info.capacity_in_kilobyte * 4) != + HAL_OK) { return HAL_ERROR; } + + if (memory_mapped) { + qspi_flash_memory_mapped(); + } + return HAL_OK; } -int qspi_flash_write_page(uint8_t *data, uint32_t address, uint16_t len) { +int qspi_flash_write_page(uint8_t* data, uint32_t address, uint16_t len) { QSPI_CommandTypeDef command = {0}; TxCplt = 0; @@ -588,7 +602,8 @@ int qspi_flash_write_page(uint8_t *data, uint32_t address, uint16_t len) { // ; // TxCplt = 0; - if (qspi_flash_atuo_polling_mem_ready() != HAL_OK) { + if (qspi_flash_atuo_polling_mem_ready(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != + HAL_OK) { return HAL_ERROR; } @@ -599,7 +614,7 @@ int qspi_flash_write_page(uint8_t *data, uint32_t address, uint16_t len) { return HAL_OK; } -int qspi_flash_write_buffer_unsafe(uint8_t *data, uint32_t address, +int qspi_flash_write_buffer_unsafe(uint8_t* data, uint32_t address, uint32_t len) { uint32_t page_remain = 0; @@ -617,7 +632,7 @@ int qspi_flash_write_buffer_unsafe(uint8_t *data, uint32_t address, return HAL_OK; } -int qspi_flash_read_buffer(uint8_t *data, uint32_t address, uint32_t len) { +int qspi_flash_read_buffer(uint8_t* data, uint32_t address, uint32_t len) { QSPI_CommandTypeDef command = {0}; RxCplt = 0; @@ -709,28 +724,28 @@ int qspi_flash_quit_memory_mapped(void) { * @param hqspi: QSPI handle * @retval None */ -void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi) { CmdCplt++; } +void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef* hqspi) { CmdCplt++; } /** * @brief Rx Transfer completed callbacks. * @param hqspi: QSPI handle * @retval None */ -void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi) { RxCplt++; } +void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef* hqspi) { RxCplt++; } /** * @brief Tx Transfer completed callbacks. * @param hqspi: QSPI handle * @retval None */ -void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi) { TxCplt++; } +void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef* hqspi) { TxCplt++; } /** * @brief Status Match callbacks * @param hqspi: QSPI handle * @retval None */ -void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi) { StatusMatch++; } +void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef* hqspi) { StatusMatch++; } /** * @brief This function handles QUADSPI interrupt request. @@ -767,14 +782,14 @@ void qspi_flash_test(void) { display_printf("\n "); uint32_t data = 0x78563412; for (uint8_t i = 0; i < 32; i++) { - qspi_flash_write_page((uint8_t *)&data, address + 4 * i, 4); + qspi_flash_write_page((uint8_t*)&data, address + 4 * i, 4); } memset(buf, 0, 256); // qspi_flash_memory_mapped(); // qspi_flash_read_buffer(buf, address, 256); for (int i = 0; i < 128; i++) { - display_printf("%x ", *(uint8_t *)(0x90000000 + address + i)); + display_printf("%x ", *(uint8_t*)(0x90000000 + address + i)); } while (1) ; diff --git a/core/embed/trezorhal/qspi_flash.h b/core/embed/trezorhal/qspi_flash.h index d1d25a1c2..93853bd26 100644 --- a/core/embed/trezorhal/qspi_flash.h +++ b/core/embed/trezorhal/qspi_flash.h @@ -49,6 +49,7 @@ uint32_t qspi_flash_read_id(void); int qspi_flash_memory_mapped(void); int qspi_flash_quit_memory_mapped(void); int qspi_flash_erase_block_64k(uint32_t address); +int qspi_flash_erase_chip(void); int qspi_flash_write_page(uint8_t *data, uint32_t address, uint16_t len); int qspi_flash_write_buffer_unsafe(uint8_t *data, uint32_t address, uint32_t len); diff --git a/core/embed/trezorhal/usbd_desc.c b/core/embed/trezorhal/usbd_desc.c index 3e97f3aab..17c36b35d 100755 --- a/core/embed/trezorhal/usbd_desc.c +++ b/core/embed/trezorhal/usbd_desc.c @@ -29,7 +29,7 @@ #define USBD_VID 0x1209 #define USBD_PID 0x4f4c #define USBD_LANGID_STRING 0x409 -#define USBD_MANUFACTURER_STRING "OneKey Ltd." +#define USBD_MANUFACTURER_STRING "OneKey Limited" #define USBD_PRODUCT_HS_STRING "OneKey Pro Boardloader HS" #define USBD_PRODUCT_FS_STRING "OneKey Pro Boardloader FS" #define USBD_CONFIGURATION_HS_STRING "MSC Config" diff --git a/core/embed/trezorhal/usbd_desc.h b/core/embed/trezorhal/usbd_desc.h index 51f06ed94..286ceb8a5 100755 --- a/core/embed/trezorhal/usbd_desc.h +++ b/core/embed/trezorhal/usbd_desc.h @@ -28,7 +28,7 @@ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ -#define USB_SIZ_STRING_SERIAL 0x20 +#define USB_SIZ_STRING_SERIAL 0x80 /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ diff --git a/core/embed/trezorhal/usbd_msc_scsi.c b/core/embed/trezorhal/usbd_msc_scsi.c index 7a020e7d2..89838b4b9 100644 --- a/core/embed/trezorhal/usbd_msc_scsi.c +++ b/core/embed/trezorhal/usbd_msc_scsi.c @@ -1201,7 +1201,6 @@ static int8_t SCSI_UserCommand(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p if(hmsc->bot_data[0]==0x5A && hmsc->bot_data[1]==0xA5) { system_reset = 1; - } MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); } diff --git a/core/embed/trezorhal/util_macros.h b/core/embed/trezorhal/util_macros.h index 1860677b1..84e7b18fd 100644 --- a/core/embed/trezorhal/util_macros.h +++ b/core/embed/trezorhal/util_macros.h @@ -1,12 +1,19 @@ #ifndef _UTIL_MACROS_H_ #define _UTIL_MACROS_H_ -#define UNUSED_VAR(X) ((void)(X)) +#define FUN_NO_OPTMIZE __attribute__((optimize("O0"))) + +#define UNUSED_OBJ(X) ((void)(X)) #define JOIN_EXPR(a, b, c) a##_##b##_##c -// regex ->(JOIN_EXPR\((.*), (.*), (.*)\).*,).* +// regex -> (JOIN_EXPR\((.*), (.*), (.*)\).*,).* // replace -> $1 // $2_$3_$4 +// from exisiting enum use following (change "xx") +// #define xx_ENUM_ITEM(CLASS, TYPE) JOIN_EXPR(xx, CLASS, TYPE) +// regex -> ^(\s*)(\S*)(.*), +// replace -> $1xx_ENUM_ITEM(xxCLASS, $2)$3, + #define ENUM_NAME_ARRAY_ITEM(x) [x] = #x #define ExecuteCheck_ADV(expr, expected_result, on_false) \ @@ -19,19 +26,20 @@ #include #include -#define EXEC_RETRY(MAX_RETRY, ON_INIT, ON_LOOP, ON_SUCCESS, ON_FALSE) \ - { \ - bool loop_exec() { (ON_LOOP); } \ - bool loop_result = false; \ - (ON_INIT); \ - for (uint32_t retry = 0; retry < MAX_RETRY; retry++) { \ - loop_result = loop_exec(); \ - if (loop_result) break; \ - } \ - if (loop_result) \ - (ON_SUCCESS); \ - else \ - (ON_FALSE); \ +#define EXEC_RETRY(MAX_RETRY, EXPECTED_RET, ON_INIT, ON_LOOP, ON_SUCCESS, \ + ON_FALSE) \ + { \ + typeof(EXPECTED_RET) loop_result; \ + typeof(EXPECTED_RET) loop_exec() { (ON_LOOP); } \ + (ON_INIT); \ + for (uint32_t retry = 0; retry < MAX_RETRY; retry++) { \ + loop_result = loop_exec(); \ + if (loop_result == EXPECTED_RET) break; \ + } \ + if (loop_result == EXPECTED_RET) \ + (ON_SUCCESS); \ + else \ + (ON_FALSE); \ } #endif // _UTIL_MACROS_H_ \ No newline at end of file