diff options
author | 2021-01-21 02:39:12 +0000 | |
---|---|---|
committer | 2021-01-21 13:18:26 +0100 | |
commit | 4426f26ab0aed70ae2cc433f55ee48f62d7eb46b (patch) | |
tree | 57a88f00c50b1f9d22c368c22ef828b8bd1b7d26 /cortex-m-rt/asm.S | |
parent | 0e82907ca384d10a7fb1f2b8cc70fdb58c0b2fcf (diff) | |
download | cortex-m-4426f26ab0aed70ae2cc433f55ee48f62d7eb46b.tar.gz cortex-m-4426f26ab0aed70ae2cc433f55ee48f62d7eb46b.tar.zst cortex-m-4426f26ab0aed70ae2cc433f55ee48f62d7eb46b.zip |
Update Reset-in-asm.
* Use arm-none-eabi-gcc to assemble, allowing use of preprocessor to
conditionally enable the FPU for eabihf targets.
* Remove has_fpu configuration from build.rs.
* Remove FpuTrampoline as no longer required.
* Remove the Rust Reset method entirely, since the asm Reset can now
enable FPU and jump to user main.
Diffstat (limited to 'cortex-m-rt/asm.S')
-rw-r--r-- | cortex-m-rt/asm.S | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/cortex-m-rt/asm.S b/cortex-m-rt/asm.S new file mode 100644 index 0000000..6254129 --- /dev/null +++ b/cortex-m-rt/asm.S @@ -0,0 +1,105 @@ + .cfi_sections .debug_frame + + # Notes for function attributes: + # .type and .thumb_func are _both_ required, otherwise the Thumb mode bit + # will not be set and an invalid vector table is generated. + # LLD requires that section flags are set explicitly. + + .section .HardFaultTrampoline, "ax" + .global HardFaultTrampoline + .type HardFaultTrampoline,%function + .thumb_func + .cfi_startproc + # HardFault exceptions are bounced through this trampoline which grabs the + # stack pointer at the time of the exception and passes it to the user's + # HardFault handler in r0. +HardFaultTrampoline: + # Depending on the stack mode in EXC_RETURN, fetch stack pointer from + # PSP or MSP. + mov r0, lr + mov r1, #4 + tst r0, r1 + bne 0f + mrs r0, MSP + b HardFault +0: + mrs r0, PSP + b HardFault + .cfi_endproc + .size HardFaultTrampoline, . - HardFaultTrampoline + + .section .Reset, "ax" + .global Reset + .type Reset,%function + .thumb_func + .cfi_startproc + # Main entry point after reset. This jumps to the user __pre_init function, + # which cannot be called from Rust code without invoking UB, then + # initialises RAM. If the target has an FPU, it is enabled. Finally, jumps + # to the user main function. +Reset: + # ARMv6-M does not initialise LR, but many tools expect it to be 0xFFFF_FFFF + # when reaching the first call frame, so we set it at startup. + # ARMv7-M and above initialise LR to 0xFFFF_FFFF at reset. + ldr r4,=0xffffffff + mov lr,r4 + + # Run user pre-init code, which must be executed immediately after startup, + # before the potentially time-consuming memory initialisation takes place. + # Example use cases include disabling default watchdogs or enabling RAM. + bl __pre_init + + # Restore LR after calling __pre_init (r4 is preserved by subroutines). + mov lr,r4 + + # Initialise .bss memory. `__sbss` and `__ebss` come from the linker script. + ldr r0,=__sbss + ldr r1,=__ebss + mov r2,#0 +0: + cmp r1, r0 + beq 1f + stm r0!, {r2} + b 0b +1: + + # Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the + # linker script. Copy from r2 into r0 until r0 reaches r1. + ldr r0,=__sdata + ldr r1,=__edata + ldr r2,=__sidata +2: + cmp r1, r0 + beq 3f + # load 1 word from r2 to r3, inc r2 + ldm r2!, {r3} + # store 1 word from r3 to r0, inc r0 + stm r0!, {r3} + b 2b +3: + +#ifdef HAS_FPU + # Conditionally enable the FPU. + # Address of SCB.CPACR. + ldr r0, =0xE000ED88 + # Enable access to CP10 and CP11 from both privileged and unprivileged mode. + ldr r1, =(0b1111 << 20) + # RMW. + ldr r2, [r0] + orr r2, r2, r1 + str r2, [r0] + # Barrier is required on some processors. + dsb + isb +#endif + +4: + # Jump to user main function. We use bl for the extended range, but the + # user main function may not return. + bl main + + # Trap on return. + udf + + .cfi_endproc + .size Reset, . - Reset |