summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tcc77x/crt0.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tcc77x/crt0.S')
-rw-r--r--firmware/target/arm/tcc77x/crt0.S124
1 files changed, 107 insertions, 17 deletions
diff --git a/firmware/target/arm/tcc77x/crt0.S b/firmware/target/arm/tcc77x/crt0.S
index e4ecb05a4e..246d02a1d7 100644
--- a/firmware/target/arm/tcc77x/crt0.S
+++ b/firmware/target/arm/tcc77x/crt0.S
@@ -29,6 +29,11 @@
29 29
30 .section .init.text,"ax",%progbits 30 .section .init.text,"ax",%progbits
31 31
32 .extern irq
33 .extern fiq
34 .extern UIE
35 .extern main
36
32 .global start 37 .global start
33 38
34/* Telechips firmware files start with a 32-byte header, as part of the code. */ 39/* Telechips firmware files start with a 32-byte header, as part of the code. */
@@ -44,7 +49,8 @@ start:
44 .word 0 /* Saved entrypoint of original firmware*/ 49 .word 0 /* Saved entrypoint of original firmware*/
45 .word 0 /* Location in RAM of the start of our bootloader */ 50 .word 0 /* Location in RAM of the start of our bootloader */
46#else 51#else
47 ldr pc, =start_loc /* jump to the main entry point */ 52// ldr pc, =start_loc /* jump to the main entry point */
53 b start_loc
48 54
49 .word 0xffff0601 /* Unknown magic */ 55 .word 0xffff0601 /* Unknown magic */
50 .word 0x3a726556 /* "Ver:" */ 56 .word 0x3a726556 /* "Ver:" */
@@ -65,21 +71,40 @@ start:
65start_loc: 71start_loc:
66 72
67#ifdef BOOTLOADER 73#ifdef BOOTLOADER
74
75/*
76 If we are appended to the OF (i.e. dual-booting), do a simple GPIO
77 button check, and branch to the OF's entry point (saved by mktccboot)
78 if not active
79*/
80
68#ifdef TCCBOOT 81#ifdef TCCBOOT
69#ifdef LOGIK_DAX
70 mov r0, #0x80000000 82 mov r0, #0x80000000
71 ldr r0, [r0, #0x300] /* Read GPIO A */ 83#ifdef LOGIK_DAX
84 ldr r0, [r0, #0x300] /* Hold button is GPIO A, pin 0x2 */
72 tst r0, #0x2 85 tst r0, #0x2
73 ldrne pc, [pc, #-28] /* Jump to original firmware if HOLD button not pressed */ 86#elif defined(SANSA_M200)
87 ldr r0, [r0, #0x310] /* Hold button is GPIO B, pin 0x200 */
88 tst r0, #0x200
74#else 89#else
75 #error No bootup key detection implemented for this target 90 #error No bootup key detection implemented for this target
76#endif 91#endif
77 92
78 /* Copy bootloader to safe area - 0x21000000 (DRAM) */ 93 ldrne pc, [pc, #-28] /* Jump to OF if HOLD button not pressed */
79 /* TODO: Adjust this for other targets - DRAM + DRAMSIZE - 0x100000 */ 94#endif /* TCCBOOT */
80 ldr r0, [pc, #-28] 95
81 mov r1, #0x20000000 96/* We are now definitely executing the bootloader, so we relocate to the
82 add r1, r1, #0x100000 97 linked address (see boot.lds) - 1MB from the end of DRAM.
98*/
99
100#ifdef TCCBOOT
101 ldr r0, [pc, #-28] /* mktccboot fills in the load address */
102#else
103 mov r0, #0x20000000 /* Otherwise, load address is the start of DRAM */
104#endif
105 mov r1, #0x20000000 /* Destination: 1MB from end of DRAM */
106 add r1, r1, #((MEM - 1) * 0x100000)
107
83 ldr r2, =_dataend 108 ldr r2, =_dataend
841: 1091:
85 cmp r2, r1 110 cmp r2, r1
@@ -88,16 +113,14 @@ start_loc:
88 bhi 1b 113 bhi 1b
89 114
90 ldr pc, =copied_start /* jump to the relocated start_loc: */ 115 ldr pc, =copied_start /* jump to the relocated start_loc: */
91
92copied_start: 116copied_start:
93#endif 117#endif /* BOOTLOADER */
94#else
95 /* We don't use interrupts in the bootloader */
96 118
97 /* Set up stack for IRQ mode */ 119 /* Set up stack for IRQ mode */
98 mov r0,#0xd2 120 mov r0,#0xd2
99 msr cpsr, r0 121 msr cpsr, r0
100 ldr sp, =irq_stack 122 ldr sp, =irq_stack
123
101 /* Set up stack for FIQ mode */ 124 /* Set up stack for FIQ mode */
102 mov r0,#0xd1 125 mov r0,#0xd1
103 msr cpsr, r0 126 msr cpsr, r0
@@ -110,13 +133,22 @@ copied_start:
110 mov r0,#0xdb 133 mov r0,#0xdb
111 msr cpsr, r0 134 msr cpsr, r0
112 ldr sp, =irq_stack 135 ldr sp, =irq_stack
113#endif
114 136
115 /* Switch to supervisor mode */ 137 /* Switch to supervisor mode */
116 mov r0,#0xd3 138 mov r0,#0xd3
117 msr cpsr, r0 139 msr cpsr, r0
118 ldr sp, =stackend 140 ldr sp, =stackend
119 141
142 /* Copy exception handler code to address 0 */
143 mov r2, #0x0
144 ldr r3, =vectors_start
145 ldr r4, =vectors_end
1461:
147 cmp r4, r3
148 ldrhi r5, [r3], #4
149 strhi r5, [r2], #4
150 bhi 1b
151
120 /* Initialise bss section to zero */ 152 /* Initialise bss section to zero */
121 ldr r2, =_edata 153 ldr r2, =_edata
122 ldr r3, =_end 154 ldr r3, =_end
@@ -139,9 +171,68 @@ copied_start:
139 bl main 171 bl main
140 /* main() should never return */ 172 /* main() should never return */
141 173
142#ifndef BOOTLOADER 174/* Exception handlers. Will be copied to address 0 after memory remapping */
143 /* We don't use interrupts in the bootloader */ 175vectors_start:
176 ldr pc, [pc, #24]
177 ldr pc, [pc, #24]
178 ldr pc, [pc, #24]
179 ldr pc, [pc, #24]
180 ldr pc, [pc, #24]
181 ldr pc, [pc, #24]
182 ldr pc, [pc, #24]
183 ldr pc, [pc, #24]
184
185 /* Exception vectors */
186 .global vectors
187vectors:
188 .word start
189 .word undef_instr_handler
190 .word software_int_handler
191 .word prefetch_abort_handler
192 .word data_abort_handler
193 .word reserved_handler
194 .word irq_handler
195 .word fiq_handler
196vectors_end:
197
198 .text
199
200/* All illegal exceptions call into UIE with exception address as first
201 parameter. This is calculated differently depending on which exception
202 we're in. Second parameter is exception number, used for a string lookup
203 in UIE.
204 */
205undef_instr_handler:
206 mov r0, lr
207 mov r1, #0
208 b UIE
144 209
210/* We run supervisor mode most of the time, and should never see a software
211 exception being thrown. Perhaps make it illegal and call UIE?
212 */
213software_int_handler:
214reserved_handler:
215 movs pc, lr
216
217prefetch_abort_handler:
218 sub r0, lr, #4
219 mov r1, #1
220 b UIE
221
222data_abort_handler:
223 sub r0, lr, #8
224 mov r1, #2
225 b UIE
226
227irq_handler:
228 stmfd sp!, {r0-r3, r12, lr}
229 bl irq
230 ldmfd sp!, {r0-r3, r12, lr}
231 subs pc, lr, #4
232
233/* Align stacks to cache line boundary */
234 .balign 16
235
145/* 256 words of IRQ stack */ 236/* 256 words of IRQ stack */
146 .space 256*4 237 .space 256*4
147irq_stack: 238irq_stack:
@@ -150,4 +241,3 @@ irq_stack:
150 .space 256*4 241 .space 256*4
151fiq_stack: 242fiq_stack:
152 243
153#endif