diff options
Diffstat (limited to 'boards/base/RaspberryPi/example-FreeRTOS/startup.s')
-rw-r--r-- | boards/base/RaspberryPi/example-FreeRTOS/startup.s | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/boards/base/RaspberryPi/example-FreeRTOS/startup.s b/boards/base/RaspberryPi/example-FreeRTOS/startup.s new file mode 100644 index 00000000..286f396c --- /dev/null +++ b/boards/base/RaspberryPi/example-FreeRTOS/startup.s @@ -0,0 +1,102 @@ +.extern system_init +.extern __bss_start +.extern __bss_end +.extern vFreeRTOS_ISR +.extern vPortYieldProcessor +.extern DisableInterrupts +.extern main + .section .init + .globl _start +;; +_start: + ;@ All the following instruction should be read as: + ;@ Load the address at symbol into the program counter. + + ldr pc,reset_handler ;@ Processor Reset handler -- we will have to force this on the raspi! + ;@ Because this is the first instruction executed, of cause it causes an immediate branch into reset! + + ldr pc,undefined_handler ;@ Undefined instruction handler -- processors that don't have thumb can emulate thumb! + ldr pc,swi_handler ;@ Software interrupt / TRAP (SVC) -- system SVC handler for switching to kernel mode. + ldr pc,prefetch_handler ;@ Prefetch/abort handler. + ldr pc,data_handler ;@ Data abort handler/ + ldr pc,unused_handler ;@ -- Historical from 26-bit addressing ARMs -- was invalid address handler. + ldr pc,irq_handler ;@ IRQ handler + ldr pc,fiq_handler ;@ Fast interrupt handler. + + ;@ Here we create an exception address table! This means that reset/hang/irq can be absolute addresses +reset_handler: .word reset +undefined_handler: .word undefined_instruction +swi_handler: .word vPortYieldProcessor +prefetch_handler: .word prefetch_abort +data_handler: .word data_abort +unused_handler: .word unused +irq_handler: .word vFreeRTOS_ISR +fiq_handler: .word fiq + +reset: + ;@ In the reset handler, we need to copy our interrupt vector table to 0x0000, its currently at 0x8000 + + mov r0,#0x8000 ;@ Store the source pointer + mov r1,#0x0000 ;@ Store the destination pointer. + + ;@ Here we copy the branching instructions + ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load multiple values from indexed address. ; Auto-increment R0 + stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store multiple values from the indexed address. ; Auto-increment R1 + + ;@ So the branches get the correct address we also need to copy our vector table! + ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load from 4*n of regs (8) as R0 is now incremented. + stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store this extra set of data. + + + ;@ Set up the various STACK pointers for different CPU modes + ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) + mov r0,#0xD2 + msr cpsr_c,r0 + mov sp,#0x8000 + + ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) + mov r0,#0xD1 + msr cpsr_c,r0 + mov sp,#0x4000 + + ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) + mov r0,#0xD3 + msr cpsr_c,r0 + mov sp,#0x8000000 + + ldr r0, =__bss_start + ldr r1, =__bss_end + + mov r2, #0 + +zero_loop: + cmp r0,r1 + it lt + strlt r2,[r0], #4 + blt zero_loop + + bl DisableInterrupts + + + ;@ mov sp,#0x1000000 + b main ;@ We're ready?? Lets start main execution! + .section .text + +undefined_instruction: + b undefined_instruction + +prefetch_abort: + b prefetch_abort + +data_abort: + b data_abort + +unused: + b unused + +fiq: + b fiq + +hang: + b hang + |