summaryrefslogtreecommitdiff
path: root/firmware/target/arm/crt0-pp.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/crt0-pp.S')
-rw-r--r--firmware/target/arm/crt0-pp.S196
1 files changed, 122 insertions, 74 deletions
diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S
index c1ced11cec..971b9e0ac5 100644
--- a/firmware/target/arm/crt0-pp.S
+++ b/firmware/target/arm/crt0-pp.S
@@ -34,6 +34,7 @@ start:
34#if CONFIG_CPU == PP5002 34#if CONFIG_CPU == PP5002
35 .equ PROC_ID, 0xc4000000 35 .equ PROC_ID, 0xc4000000
36 .equ CPU_ICLR, 0xcf001028 36 .equ CPU_ICLR, 0xcf001028
37 .equ CPU_CTRL, 0xcf004054
37 .equ COP_ICLR, 0xcf001038 38 .equ COP_ICLR, 0xcf001038
38 .equ COP_CTRL, 0xcf004058 39 .equ COP_CTRL, 0xcf004058
39 .equ COP_STATUS, 0xcf004050 40 .equ COP_STATUS, 0xcf004050
@@ -44,6 +45,8 @@ start:
44#else 45#else
45 .equ PROC_ID, 0x60000000 46 .equ PROC_ID, 0x60000000
46 .equ CPU_ICLR, 0x60004028 47 .equ CPU_ICLR, 0x60004028
48 .equ CPU_CTRL, 0x60007000
49 .equ CPU_STATUS, 0x60007000
47 .equ COP_ICLR, 0x60004038 50 .equ COP_ICLR, 0x60004038
48 .equ COP_CTRL, 0x60007004 51 .equ COP_CTRL, 0x60007004
49 .equ COP_STATUS, 0x60007004 52 .equ COP_STATUS, 0x60007004
@@ -57,15 +60,16 @@ start:
57 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ 60 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
58 b pad_skip 61 b pad_skip
59 62
60.space 60*4 /* (more than enough) space for exception vectors and mi4 magic */ 63.space 64*4 /* (more than enough) space for exception vectors and mi4 magic */
61 64
62pad_skip: 65pad_skip:
63#if defined(SANSA_E200) || defined(SANSA_C200) 66 /* Find out which processor we are - r0 should be preserved for the
64 /* On the Sansa, copying the vectors fails if the cache is initialised */ 67 * duration of the init to avoid constant reloading of the processor ID.
65 ldr r1, =CACHE_CTRL 68 * For each stage, CPU proceeds first, then COP.
66 mov r2, #0x0 69 */
67 str r2, [r1] 70 ldr r0, =PROC_ID
68#endif 71 ldrb r0, [r0]
72
69 /* We need to remap memory from wherever SDRAM is mapped natively, to 73 /* We need to remap memory from wherever SDRAM is mapped natively, to
70 base address 0, so we can put our exception vectors there. We don't 74 base address 0, so we can put our exception vectors there. We don't
71 want to do this remapping while executing from SDRAM, so we copy the 75 want to do this remapping while executing from SDRAM, so we copy the
@@ -73,70 +77,95 @@ pad_skip:
73 code is compiled for address 0, but is currently executing at either 77 code is compiled for address 0, but is currently executing at either
74 0x28000000 or 0x10000000, depending on chipset version. Do not use any 78 0x28000000 or 0x10000000, depending on chipset version. Do not use any
75 absolute addresses until remapping has been done. */ 79 absolute addresses until remapping has been done. */
76 ldr r1, =0x40000000
77 ldr r2, =remap_start
78 ldr r3, =remap_end
79 80
80 and r5, pc, #0xff000000 /* adjust for execute address */ 81 /* Cores are stepped though the init in turn: CPU then COP. The the remap
81 orr r2, r2, r5 82 stage is completed by each core in turn and then the COP waits for the
82 orr r3, r3, r5 83 CPU to finish initializing its kernel where the CPU will wake the COP
84 and wait for the COP to finish. This ensures no threading activity
85 starts until it is safe. */
86 cmp r0, #0x55
87
88 /* mask all interrupt sources before setting anything up */
89 ldreq r2, =CPU_ICLR
90 ldrne r2, =COP_ICLR
91 mvn r1, #0
92 str r1, [r2]
93
94 /* put us (co-processor) to sleep and wait for CPU to remap */
95 ldrne r2, =COP_CTRL
96 movne r1, #SLEEP
97 strne r1, [r2]
98
99 /* wait for co-processor to sleep then CPU can begin its remapping */
100 ldreq r2, =COP_STATUS
1011:
102 ldreq r1, [r2]
103 tsteq r1, #SLEEPING
104 beq 1b
105
106#ifdef CPU_PP502x
107 /* disable cache and local interrupt vectors - it is really not desireable
108 to have them enabled here */
109 ldr r2, =CACHE_CTRL
110 mov r1, #0
111 str r1, [r2]
112#endif
113
114 mov r2, #0x40000000
115 ldr r3, =remap_start
116 ldr r4, =remap_end
117
118 and r6, pc, #0xff000000 /* adjust for execute address */
119 orr r3, r3, r6
120 orr r4, r4, r6
83 121
84 /* copy the code to 0x40000000 */ 122 /* copy the code to 0x40000000 */
851: 1231:
86 ldr r4, [r2], #4 124 ldr r5, [r3], #4
87 str r4, [r1], #4 125 str r5, [r2], #4
88 cmp r2, r3 126 cmp r3, r4
89 ble 1b 127 blo 1b
90 128
91 ldr r3, =0x3f84 /* r3 and r1 values here are magic, don't touch */ 129 ldr r4, =0x3f84 /* r3 and r1 values here are magic, don't touch */
92 orr r3, r3, r5 /* adjust for execute address */ 130 orr r4, r4, r6 /* adjust for execute address */
93 ldr r2, =0xf000f014 131 ldr r3, =0xf000f014
94#if MEM > 32 132#if MEM > 32
95 mov r1, #0x7400 /* r1 appears to indicate how much memory (not in 133 mov r2, #0x7400 /* r1 appears to indicate how much memory (not in
96 bytes) is remapped */ 134 bytes) is remapped */
97#else 135#else
98 mov r1, #0x3a00 136 mov r2, #0x3a00
99#endif 137#endif
100 ldr r0, =0xf000f010 138 ldr r1, =0xf000f010
101 mov pc, #0x40000000 139 mov pc, #0x40000000
102 140
103remap_start: 141remap_start:
104 str r1, [r0] 142 str r2, [r1]
105 str r3, [r2] 143 str r4, [r3]
106 ldr r0, L_post_remap 144 ldr r1, L_post_remap
107 mov pc, r0 145 mov pc, r1
108L_post_remap: .word remap_end 146L_post_remap:
147 .word remap_end
109remap_end: 148remap_end:
110 149
111 /* After doing the remapping, send the COP to sleep.
112 On wakeup it will go to cop_init */
113
114 /* Find out which processor we are */
115 ldr r0, =PROC_ID
116 ldrb r0, [r0]
117 cmp r0, #0x55 150 cmp r0, #0x55
118 151 ldr r4, =COP_CTRL
119 /* Mask all interrupt sources before setting up modes */ 152 /* Wakeup co-processor to let it do remappings */
120 ldreq r0, =CPU_ICLR 153 moveq r3, #WAKE
121 ldrne r0, =COP_ICLR 154 /* Sleep us (co-processor) and wait for CPU to do kernel initialization */
122 mvn r1, #1
123 str r1, [r0]
124
125 /* put us (co-processor) to sleep */
126 ldrne r4, =COP_CTRL
127 movne r3, #SLEEP 155 movne r3, #SLEEP
128 strne r3, [r4] 156 str r3, [r4]
129 157
158 /* Jump to co-processor init */
130 ldrne pc, =cop_init 159 ldrne pc, =cop_init
131 160
132cpu_init: 161cpu_init:
133 /* Wait for COP to be sleeping */ 162 /* Wait for COP to go to sleep before proceeding */
134 ldr r4, =COP_STATUS 163 ldr r4, =COP_STATUS
1351: 1641:
136 ldr r3, [r4] 165 ldr r3, [r4]
137 tst r3, #SLEEPING 166 tst r3, #SLEEPING
138 beq 1b 167 beq 1b
139 168
140 /* Copy exception handler code to address 0 */ 169 /* Copy exception handler code to address 0 */
141 ldr r2, =_vectorsstart 170 ldr r2, =_vectorsstart
142 ldr r3, =_vectorsend 171 ldr r3, =_vectorsend
@@ -174,17 +203,28 @@ cpu_init:
174 cmp r3, r2 203 cmp r3, r2
175 strhi r4, [r2], #4 204 strhi r4, [r2], #4
176 bhi 1b 205 bhi 1b
177 206
207 /* Load stack munge value */
208 ldr r4, =0xdeadbeef
209
178 /* Set up some stack and munge it with 0xdeadbeef */ 210 /* Set up some stack and munge it with 0xdeadbeef */
179 ldr sp, =stackend
180 mov r3, sp
181 ldr r2, =stackbegin 211 ldr r2, =stackbegin
182 ldr r4, =0xdeadbeef 212 ldr sp, =stackend
2131:
214 cmp sp, r2
215 strhi r4, [r2], #4
216 bhi 1b
217
218#if NUM_CORES > 1
219 /* Set up idle stack and munge it with 0xdeadbeef */
220 ldr r2, =cpu_idlestackbegin
221 ldr r3, =cpu_idlestackend
1831: 2221:
184 cmp r3, r2 223 cmp r3, r2
185 strhi r4, [r2], #4 224 strhi r4, [r2], #4
186 bhi 1b 225 bhi 1b
187 226#endif
227
188 /* Set up stack for IRQ mode */ 228 /* Set up stack for IRQ mode */
189 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */ 229 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
190 ldr sp, =irq_stack 230 ldr sp, =irq_stack
@@ -203,34 +243,41 @@ cpu_init:
203 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */ 243 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
204 ldr sp, =irq_stack 244 ldr sp, =irq_stack
205 245
206 /* Switch to supervisor mode */ 246 /* Switch back to supervisor mode */
207 msr cpsr_c, #0xd3 247 msr cpsr_c, #0xd3
208 ldr sp, =stackend 248
249 /* Delay waking the COP until thread initialization is complete unless dual-core
250 support is not enabled in which case the cop_main function does not perform
251 any kernel or thread initialization. It's just a trivial sleep loop. */
252#if NUM_CORES == 1
253 ldr r4, =COP_CTRL
254 mov r3, #WAKE
255 str r3, [r4]
256#endif
257
209 bl main 258 bl main
210 /* main() should never return */ 259 /* main() should never return */
211 260
212cop_init: 261cop_init:
213#if CONFIG_CPU != PP5002 262#if NUM_CORES > 1
214 /* COP: Invalidate cache */ 263 /* Wait for CPU to go to sleep at the end of its kernel init */
215 ldr r0, =0xf000f044 264 ldr r4, =CPU_STATUS
216 ldr r1, [r0]
217 orr r1, r1, #0x6
218 str r1, [r0]
219
220 ldr r0, =CACHE_CTRL
2211: 2651:
222 ldr r1, [r0] 266 ldr r3, [r4]
223 tst r1, #0x8000 267 tst r3, #SLEEPING
224 bne 1b 268 beq 1b
225#endif
226 269
227 /* Setup stack for COP */ 270 /* Set up idle stack for COP and munge it with 0xdeadbeef */
228 ldr sp, =cop_stackend 271 ldr r2, =cop_idlestackbegin
229 mov r3, sp 272 ldr sp, =cop_idlestackend
273#else
274 /* Setup stack for COP and munge it with 0xdeadbeef */
230 ldr r2, =cop_stackbegin 275 ldr r2, =cop_stackbegin
276 ldr sp, =cop_stackend
277#endif
231 ldr r4, =0xdeadbeef 278 ldr r4, =0xdeadbeef
2322: 2792:
233 cmp r3, r2 280 cmp sp, r2
234 strhi r4, [r2], #4 281 strhi r4, [r2], #4
235 bhi 2b 282 bhi 2b
236 283
@@ -247,13 +294,12 @@ cop_init:
247 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */ 294 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
248 ldr sp, =cop_irq_stack 295 ldr sp, =cop_irq_stack
249 296
250 /* Switch to supervisor mode */ 297 /* Switch back to supervisor mode */
251 msr cpsr_c, #0xd3 298 msr cpsr_c, #0xd3
252 ldr sp, =cop_stackend
253 299
254 /* Run cop_main() in apps/main.c */ 300 /* Run cop_main() in apps/main.c */
255 bl cop_main 301 bl cop_main
256 302
257/* Exception handlers. Will be copied to address 0 after memory remapping */ 303/* Exception handlers. Will be copied to address 0 after memory remapping */
258 .section .vectors,"aw" 304 .section .vectors,"aw"
259 ldr pc, [pc, #24] 305 ldr pc, [pc, #24]
@@ -300,7 +346,6 @@ undef_instr_handler:
300software_int_handler: 346software_int_handler:
301reserved_handler: 347reserved_handler:
302 movs pc, lr 348 movs pc, lr
303
304prefetch_abort_handler: 349prefetch_abort_handler:
305 sub r0, lr, #4 350 sub r0, lr, #4
306 mov r1, #1 351 mov r1, #1
@@ -324,6 +369,9 @@ UIE:
324 b UIE 369 b UIE
325#endif 370#endif
326 371
372/* Align stacks to cache line boundary */
373 .balign 16
374
327/* 256 words of IRQ stack */ 375/* 256 words of IRQ stack */
328 .space 256*4 376 .space 256*4
329irq_stack: 377irq_stack: