diff --git a/legacy/Makefile b/legacy/Makefile index 2f6f9eb503..5fb84a7fff 100644 --- a/legacy/Makefile +++ b/legacy/Makefile @@ -1,6 +1,5 @@ ifneq ($(EMULATOR),1) OBJS += setup.o -OBJS += startup.o OBJS += timer.o endif diff --git a/legacy/bootloader/Makefile b/legacy/bootloader/Makefile index dd8b0b8669..7df46de992 100644 --- a/legacy/bootloader/Makefile +++ b/legacy/bootloader/Makefile @@ -1,5 +1,6 @@ NAME = bootloader-unaligned +OBJS += startup.o OBJS += bootloader.o OBJS += usb.o @@ -18,7 +19,6 @@ OBJS += ../oled.small.o OBJS += ../random_delays.small.o OBJS += ../rng.small.o OBJS += ../setup.small.o -OBJS += ../startup.o OBJS += ../supervise.small.o OBJS += ../timer.small.o OBJS += ../usb21_standard.small.o diff --git a/legacy/bootloader/startup.S b/legacy/bootloader/startup.S new file mode 100644 index 0000000000..4f88c532b8 --- /dev/null +++ b/legacy/bootloader/startup.S @@ -0,0 +1,79 @@ + .syntax unified + + .text + + .global memset_reg + .type memset_reg, STT_FUNC +memset_reg: + // call with the following (note that the arguments are not validated prior to use): + // r0 - address of first word to write (inclusive) + // r1 - address of first word following the address in r0 to NOT write (exclusive) + // r2 - word value to be written + // both addresses in r0 and r1 needs to be divisible by 4! + .L_loop_begin: + str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed + cmp r0, r1 + bne .L_loop_begin + bx lr + + .global reset_handler + .type reset_handler, STT_FUNC +reset_handler: + + ldr r0, =_stay_in_bootloader_flag_addr // r0 - address of storage for "stay in bootloader" flag + ldr r11, [r0] // r11 - keep in register and hope it gets to main + + ldr r0, =_ram_start // r0 - point to beginning of SRAM + ldr r1, =_ram_end // r1 - point to byte after the end of SRAM + ldr r2, =0 // r2 - the byte-sized value to be written + bl memset_reg + + // copy .data section from flash to SRAM + ldr r0, =_data // dst addr + ldr r1, =_data_loadaddr // src addr + ldr r2, =_data_size // length in bytes + bl memcpy + + // enter the application code + bl main + + // shutdown if the application code returns + b shutdown + + .global shutdown + .type shutdown, STT_FUNC +shutdown: + cpsid f + ldr r0, =0 + mov r1, r0 + mov r2, r0 + mov r3, r0 + mov r4, r0 + mov r5, r0 + mov r6, r0 + mov r7, r0 + mov r8, r0 + mov r9, r0 + mov r10, r0 + mov r11, r0 + mov r12, r0 + ldr lr, =0xffffffff + ldr r0, =_ram_start + ldr r1, =_ram_end + // set to value in r2 + bl memset_reg + b . // loop forever + + .ltorg // dump literal pool (for the ldr ...,=... commands above) + + .global sv_call_handler + .type sv_call_handler, STT_FUNC + +sv_call_handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b svc_handler_main + + .end diff --git a/legacy/firmware/Makefile b/legacy/firmware/Makefile index 75a46b6ece..d0bca5aa51 100644 --- a/legacy/firmware/Makefile +++ b/legacy/firmware/Makefile @@ -40,6 +40,7 @@ OBJS += usb.o OBJS += bl_check.o OBJS += otp.o OBJS += header.o +OBJS += startup.o endif OBJS += messages.o diff --git a/legacy/startup.S b/legacy/firmware/startup.S similarity index 75% rename from legacy/startup.S rename to legacy/firmware/startup.S index ee847cf00d..81264a6ac3 100644 --- a/legacy/startup.S +++ b/legacy/firmware/startup.S @@ -20,7 +20,7 @@ memset_reg: .type reset_handler, STT_FUNC reset_handler: -// We need to perform VTOR+stack setup case an old bootloader (<1.8.0) +// We need to perform VTOR setup case an old bootloader (<1.8.0) // is starting the new firmware, these will be set incorrectly. // To make development easier, set only if we are in privileged @@ -31,14 +31,14 @@ reset_handler: // But with devel bootloader we let FW start in privileged mode // and let's do the check if we can set VTOR without fault -// Since this startup code is shared with bootloader and FW, -// a) in case of bootloader MCU starts in privileged mode, -// so the jump to "setup_as_unprivileged" never happens. -// VTOR and stack are set from MCU startup -// b) in case of FW it will attempt to set VTOR and stack -// which will work for both signed bootloader+FW, but -// also for other variants with debug bootloader and -// unsigned FW or official bootloader and usigned FW + // These two instructions are just for debug testing how unprivileged + // FW is handled + //mov r0, 1 + //msr control, r0 // set unprivileged + + ldr sp, =_stack // setup stack + + // are we privileged? if so, fix VTOR, otherwise skip mrs r3, control and r3, r3, #1 cmp r3, #1 @@ -47,15 +47,10 @@ reset_handler: ldr r0, =0xE000ED08 // r0 = VTOR address ldr r1, =0x08010400 // r1 = FLASH_APP_START str r1, [r0] // assign - ldr r0, =_stack // r0 = stack pointer - msr msp, r0 // set stack pointer dsb isb .setup_as_unprivileged: - ldr r0, =_stay_in_bootloader_flag_addr // r0 - address of storage for "stay in bootloader" flag - ldr r11, [r0] // r11 - keep in register and hope it gets to main - ldr r0, =_ram_start // r0 - point to beginning of SRAM ldr r1, =_ram_end // r1 - point to byte after the end of SRAM ldr r2, =0 // r2 - the byte-sized value to be written diff --git a/legacy/intermediate_fw/Makefile b/legacy/intermediate_fw/Makefile index 2e94591a09..35255a2f98 100644 --- a/legacy/intermediate_fw/Makefile +++ b/legacy/intermediate_fw/Makefile @@ -5,6 +5,7 @@ NAME = trezor OBJS += trezor.o OBJS += header.o OBJS += bl_check.o +OBJS += startup.o OBJS += ../vendor/trezor-crypto/memzero.o OBJS += ../vendor/trezor-crypto/sha2.o diff --git a/legacy/intermediate_fw/startup.S b/legacy/intermediate_fw/startup.S new file mode 120000 index 0000000000..379dbac45f --- /dev/null +++ b/legacy/intermediate_fw/startup.S @@ -0,0 +1 @@ +../firmware/startup.S \ No newline at end of file