summaryrefslogtreecommitdiff
path: root/src/main.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.s')
-rw-r--r--src/main.s132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/main.s b/src/main.s
new file mode 100644
index 0000000..e45da64
--- /dev/null
+++ b/src/main.s
@@ -0,0 +1,132 @@
+@ Tiny bare metal example
+@ vim:ft=armv5
+
+.section .init
+
+_start:
+ LDR PC, [PC, #24] @ Reset
+ LDR PC, [PC, #24] @ Undefined
+ LDR PC, [PC, #24] @ SWI
+ LDR PC, [PC, #24] @ Prefetch abort
+ LDR PC, [PC, #24] @ Data abort
+ LDR PC, [PC, #24] @ Reserved
+ LDR PC, [PC, #24] @ IRQ
+ LDR PC, [PC, #24] @ FIQ
+ .word reset @ Reset
+ .word hang @ Undefined
+ .word swi_handler @ SWI
+ .word hang @ Prefetch abort
+ .word hang @ Data abort
+ .word hang @ Reserved
+ .word hang @ IRQ
+ .word hang @ FIQ
+
+hang:
+ B hang
+
+reset:
+
+ @ Hang all except one of the processors
+ MRC P15, 0, R0, C0, C0, 5
+ AND R0, R0, #3
+ CMP R0, #0
+ BNE hang
+
+ @ Get out of HYP mode
+ MRS R0, CPSR
+ BIC R0, R0, #0x1f
+ ORR R0, R0, #0x13
+ MSR SPSR_cxsf, R0
+ ADD R0, PC, #4
+ MSR ELR_hyp,r0
+ ERET
+
+ LDR R13, =stack_svc @ Set up stack for SVC mode
+
+ @ Relocate vector table
+ MOV R10, #0x8000
+ MOV R11, #0
+ LDMIA R10!, {R0-R7}
+ STMIA R11!, {R0-R7}
+ LDMIA R10!, {R0-R7}
+ STMIA R11!, {R0-R7}
+
+ LDR R8, =0x3f200000
+ LDR R1, [R8, #0x04] @ GPFSEL1
+ ORR R1, R1, #1<<18 @ GPIO pin 16 is output
+ BIC R1, R1, #3<<21 @ GPIO pin 17 is input
+ ORR R1, R1, #1<<24 @ GPIO pin 18 is output
+ STR R1, [R8, #0x04] @ GPFSEL1
+
+ @ Flash green LED
+ MOV R1, #1<<18
+ STR R1, [R8, #0x1c] @ GPSET0
+ BL pause
+ MOV R1, #1<<18
+ STR R1, [R8, #0x28] @ GPCLR0
+ BL pause
+
+ @ Switch to USR mode and set up stack
+ MRS R0, CPSR
+ BIC R0, R0, #0x1f
+ ORR R0, R0, #0x10
+ MSR CPSR_c, R0
+ LDR R13, =stack_usr
+
+repeat:
+ MOV R0, #0
+ SWI 0
+ TST R0, #1<<17
+ MOVNE R0, #1
+ SWINE 0
+ B repeat
+
+
+swi_handler:
+ STMDB R13!, {R8, LR}
+ LDR R8, =0x3f200000
+ CMP R0, #0
+ BEQ get_gpio
+ CMP R0, #1
+ BLEQ flash
+ LDMIA R13!, {R8, PC}^
+
+get_gpio:
+ LDR R0, [R8, #0x34] @ GPLEV0
+ LDMIA R13!, {R8, PC}^
+
+
+flash:
+ STMDB R13!, {R1, R2, R4, LR}
+ MOV R4, #5
+
+flashloop:
+ MOV R1, #1<<16
+ STR R1, [R8, #0x28] @ GPCLR0
+ MOV R1, #1<<18
+ STR R1, [R8, #0x1c] @ GPSET0
+
+ BL pause
+
+ MOV R1, #1<<18
+ STR R1, [R8, #0x28] @ GPCLR0
+ MOV R1, #1<<16
+ STR R1, [R8, #0x1c] @ GPSET0
+
+ BL pause
+
+ MOV R1, #1<<18
+ ORR R1, #1<<16
+ STR R1, [R8, #0x28] @ GPCLR0
+
+ SUBS R4, R4, #1
+ BNE flashloop
+
+ LDMIA R13!, {R1, R2, R4, PC}
+
+pause:
+ MOV R2, #0x3f000
+wait:
+ SUBS R2, R2, #1
+ BNE wait
+ MOV PC, LR