summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/crt0.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/crt0.S')
-rw-r--r--firmware/target/arm/imx31/crt0.S236
1 files changed, 125 insertions, 111 deletions
diff --git a/firmware/target/arm/imx31/crt0.S b/firmware/target/arm/imx31/crt0.S
index 9d50888536..4e79cd1352 100644
--- a/firmware/target/arm/imx31/crt0.S
+++ b/firmware/target/arm/imx31/crt0.S
@@ -23,9 +23,16 @@
23 23
24 .global start 24 .global start
25start: 25start:
26 b newstart 26 /* Exception vectors */
27 .space 4*12 /* Space for low vectors */ 27 b newstart
28 28 b undef_instr_handler
29 b software_int_handler
30 b prefetch_abort_handler
31 b data_abort_handler
32 b reserved_handler
33 b irq_handler
34 b fiq_handler
35 .balign 0x40, 0x6B
29 36
30/* Arm bootloader and startup code based on startup.s from the iPodLinux loader 37/* Arm bootloader and startup code based on startup.s from the iPodLinux loader
31 * 38 *
@@ -34,28 +41,41 @@ start:
34 * 41 *
35 */ 42 */
36 43
44/* Initially this code is running at VA 0x8a000000 (PA 0x82000000).
45 * The mapping stub is copied to IRAM (0x1fffc000) and jumps to the final
46 * VA remapping starting at 0x01f00000 because the 1MB section containing
47 * the framebuffer at PA 0x81000000 is skipped in the remapping giving 63MB
48 * of contiguous RAM for the firmware. The TTB is placed at the end of said
49 * section.
50 *
51 * For now this will be done in bootloader, especially if usb will be needed
52 * within the bootloader to load the main firmware file. Interrupts will be
53 * needed for this (whether they be swi or irq).
54 */
37newstart: 55newstart:
38 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ 56 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
39 57
40#ifdef BOOTLOADER 58#ifdef BOOTLOADER
41 ldr r2, =remap_start 59 adr r2, remap_start /* Load PC-relative labels */
42 ldr r3, =remap_end 60 adr r3, remap_end
43 ldr r5, =TTB_BASE_ADDR /* TTB pointer */ 61 ldr r5, =TTB_BASE_ADDR /* TTB pointer */
44 ldr r6, =IRAM_BASE_ADDR 62 ldr r6, =IRAM_BASE_ADDR
45 mov r1, r6 63 mov r1, r6
46 64
471: 651: /* Copy remapping stub to IRAM */
48 cmp r3, r2 66 cmp r3, r2
49 ldrhi r4, [r2], #4 67 ldrhi r4, [r2], #4
50 strhi r4, [r1], #4 68 strhi r4, [r1], #4
51 bhi 1b 69 bhi 1b
52 70
53 mov pc, r6 71 mov pc, r6
54 72
73 /* Remapping stub. No absolute addresses may be used until after the
74 * remapping is complete. */
55remap_start: 75remap_start:
56 mrc p15, 0, r3, c1, c0, 0 /* perform writeback if D cache is enabled */ 76 mrc p15, 0, r3, c1, c0, 0 /* perform writeback if D cache is enabled */
57 tst r3, #(1 << 2) 77 tst r3, #(1 << 2) /* dcache? */
58 tsteq r3, #(1 << 12) 78 tsteq r3, #(1 << 12) /* or icache? */
59 mcrne p15, 0, r0, c7, c10, 0 /* clean dcache */ 79 mcrne p15, 0, r0, c7, c10, 0 /* clean dcache */
60 mov r0, #0 80 mov r0, #0
61 mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ 81 mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */
@@ -77,9 +97,9 @@ remap_start:
77 str r1, [r0, #L2_CACHE_CTL_REG] 97 str r1, [r0, #L2_CACHE_CTL_REG]
78 98
79 /* Disble L1 caches and memory manager */ 99 /* Disble L1 caches and memory manager */
80 bic r3, r3, #(1 << 1) 100 bic r3, r3, #(1 << 12) /* L1 I-cache disabled */
81 bic r3, r3, #(1 << 2) 101 bic r3, r3, #((1 << 2) | /* L1 D-cache disabled */ \
82 bic r3, r3, #(1 << 12) 102 (1 << 0)) /* MMU disabled */
83 mcr p15, 0, r3, c1, c0, 0 103 mcr p15, 0, r3, c1, c0, 0
84 104
85 /* 105 /*
@@ -96,92 +116,97 @@ remap_start:
96 /* Invalidate L2 */ 116 /* Invalidate L2 */
97 mov r1, #0x000000FF 117 mov r1, #0x000000FF
98 str r1, [r0, #L2_CACHE_INV_WAY_REG] 118 str r1, [r0, #L2_CACHE_INV_WAY_REG]
99L2_loop: 1191:
100 /* Poll Invalidate By Way register */ 120 /* Poll Invalidate By Way register */
101 ldr r2, [r0, #L2_CACHE_INV_WAY_REG] 121 ldr r1, [r0, #L2_CACHE_INV_WAY_REG]
102 cmp r2, #0 122 cmp r1, #0
103 bne L2_loop 123 bne 1b
104 124
105 /*** End of L2 operations ***/ 125 /*** End of L2 operations ***/
106 126
107 /*remap memory as well as exception vectors*/
108 /*for now this will be done in bootloader, especially
109 if usb will be needed within the bootloader to load the
110 main firmware file. Interrupts will be needed for this
111 (whether they be swi or irq)*/
112
113 /* TTB Initialisation */ 127 /* TTB Initialisation */
114 mov r3, r5 128 mov r2, r5
115 add r2, r3, #TTB_SIZE 129 add r3, r5, #TTB_SIZE
116 mov r1, #0 130 mov r1, #0
117ttbloop: 1311:
118 str r1, [r3], #4 132 str r1, [r2], #4
119 cmp r3, r2 133 cmp r2, r3
120 bne ttbloop 134 blo 1b
121 135
122 /* Set TTB base address */ 136 /* Set TTB base address */
123 mov r3, r5 137 mcr p15, 0, r5, c2, c0, 0
124 mcr p15, 0, r3, c2, c0, 0 138
125 /* Set all domains to manager status */ 139 /* Set all domains to manager status */
126 mvn r3, #0 140 mvn r0, #0
127 mcr p15, 0, r3, c3, c0, 0 141 mcr p15, 0, r0, c3, c0, 0
128 142
129 /* Set page tables */ 143 /* Set page tables */
130 144
131 /* Map each memory loc to itself, no cache */ 145 /* Map each memory loc to itself, no cache */
132 mov r1, #0 /* Physical address */ 146 /* Physical address = 0x0 */
133 mov r3, r5 147 mov r1, #(1 << 10) /* superuser - r/w, user - no access */
134 add r4, r3, #TTB_SIZE /* End position */ 148 orr r1, r1, #((0 << 5) | /* domain 0th */ \
135maploop1: 149 (1 << 4) | /* should be "1" */ \
136 mov r2, r1 150 (1 << 1)) /* Section signature */
137 orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ 151 mov r2, r5
138 //orr r2, r2, #(0<<5) /* domain 0th */ 152 add r3, r5, #TTB_SIZE /* End position */
139 orr r2, r2, #(1<<4) /* should be "1" */ 1531:
140 orr r2, r2, #(1<<1) /* Section signature */ 154 str r1, [r2], #4
141 str r2, [r3], #4 155 add r1, r1, #(1 << 20) /* Next MB */
142 add r1, r1, #(1<<20) 156 cmp r2, r3
143 cmp r3, r4 157 blo 1b
144 bne maploop1 158 sub r1, r1, #TTB_SIZE/4*(1 << 20) /* Back up */
145 159
146 /* Map 0x80000000 -> 0x0, cached */ 160 /* Map 0x80000000 -> 0x0, cached */
147 mov r1, #0x80000000 /* Physical address */ 161 mov r2, r5 /* TTB pointer */
148 mov r3, r5 /* TTB pointer */ 162 add r3, r5, #63*4 /* End position */
149 add r4, r3, #64*4 /* End position */ 163 orr r1, r1, #0x80000000 /* Physical address */
150maploop2: 164 orr r1, r1, #((1 << 3) | /* cache flag */ \
151 mov r2, r1 165 (1 << 2)) /* buffer flag */
152 orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ 1661:
153 //orr r2, r2, #(0<<5) /* domain 0th */ 167 str r1, [r2], #4
154 orr r2, r2, #(1<<4) /* should be "1" */ 168 add r1, r1, #(1 << 20)
155 orr r2, r2, #(1<<3) /* cache flags */ 169 and r4, r1, #0x0ff00000
156 orr r2, r2, #(1<<2) /* more cache stuff */ 170 cmp r4, #0x00100000 /* Skip framebuffer */
157 orr r2, r2, #(1<<1) /* Section signature */ 171 addeq r1, r1, #(1 << 20)
158 str r2, [r3], #4 172 cmp r2, r3
159 add r1, r1, #(1<<20) 173 blo 1b
160 bic r6, r1, #0xf0000000
161 cmp r6, #0x00100000 /* Skip framebuffer */
162 addeq r1, r1, #(1<<20)
163 cmp r3, r4
164 bne maploop2
165 174
166 /* Enable MMU */ 175 /* Enable MMU */
167 176
168 mov r0, #0 177 mov r0, #0
169 mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */ 178 mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */
170 mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */ 179 mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */
171#if 1 180
181 /* Auxilliary control register */
172 mrc p15, 0, r0, c1, c0, 1 182 mrc p15, 0, r0, c1, c0, 1
173 bic r0, r0, #0x70 183 bic r0, r0, #((1 << 6) | /* Restrict cache size OFF */ \
174 bic r0, r0, #0x07 184 (1 << 5) | /* Enable block tranfer cache operations */ \
185 (1 << 4) | /* Clean+Invalidate cache operation ON */ \
186 (1 << 3)) /* Round-robin micro TLB replacement */
187 orr r0, r0, #((1 << 2) | /* Static branch prediction ON */ \
188 (1 << 1) | /* Dynamic branch prediction ON */ \
189 (1 << 0)) /* Return stack enabled */
175 mcr p15, 0, r0, c1, c0, 1 190 mcr p15, 0, r0, c1, c0, 1
176#endif 191
192 /* Control register */
177 mrc p15, 0, r0, c1, c0, 0 193 mrc p15, 0, r0, c1, c0, 0
178 orr r0, r0, #(1 << 0) /* enable mmu bit */ 194 bic r0, r0, #((1 << 29) | /* AF by AP disabled */ \
179 orr r0, r0, #(1 << 2) /* enable dcache */ 195 (1 << 28) | /* TEX remap disabled */ \
180 bic r0, r0, #(1 << 11) /* no program flow prediction */ 196 (1 << 24) | /* Vectored interrupt OFF */ \
181 orr r0, r0, #(1 << 12) /* enable icache */ 197 (1 << 23) | /* Sub AP bits enabled (compatible) */ \
182 bic r0, r0, #(1 << 13) /* low vectors */ 198 (1 << 22)) /* Unaligned access support disabled */
183 orr r0, r0, #(1 << 14) /* Round-robin */ 199 bic r0, r0, #((1 << 21) | /* All performance features enabled */ \
184 bic r0, r0, #(1 << 21) /* No low latency interrupt */ 200 (1 << 15)) /* Loads to PC set T bit */
201 bic r0, r0, #((1 << 13) | /* Low vectors */ \
202 (1 << 11)) /* Program flow prediction disabled (for now) */
203 orr r0, r0, #((1 << 14) | /* Round-robin replacement for I/D caches */ \
204 (1 << 12) | /* L1 I-cache enabled */ \
205 (1 << 9) | /* ROM protection enabled */ \
206 (1 << 8)) /* MMU protection enabled */
207 orr r0, r0, #((1 << 2) | /* L1 D-cache enabled */ \
208 (1 << 1) | /* Strict alignment enabled */ \
209 (1 << 0)) /* MMU enabled */
185 mcr p15, 0, r0, c1, c0, 0 210 mcr p15, 0, r0, c1, c0, 0
186 nop 211 nop
187 nop 212 nop
@@ -194,8 +219,8 @@ remap_end:
194 219
195#endif /* BOOTLOADER */ 220#endif /* BOOTLOADER */
196 221
197#ifndef BOOTLOADER 222#ifdef BOOTLOADER
198 /* Copy exception handler code to address 0 */ 223 /* Copy bootloader exception handler code to address 0 */
199 ldr r2, =_vectorsstart 224 ldr r2, =_vectorsstart
200 ldr r3, =_vectorsend 225 ldr r3, =_vectorsend
201 ldr r4, =_vectorscopy 226 ldr r4, =_vectorscopy
@@ -204,7 +229,7 @@ remap_end:
204 ldrhi r5, [r4], #4 229 ldrhi r5, [r4], #4
205 strhi r5, [r2], #4 230 strhi r5, [r2], #4
206 bhi 1b 231 bhi 1b
207 232#else
208 /* Zero out IBSS */ 233 /* Zero out IBSS */
209 ldr r2, =_iedata 234 ldr r2, =_iedata
210 ldr r3, =_iend 235 ldr r3, =_iend
@@ -261,47 +286,41 @@ remap_end:
261 msr cpsr_c, #0xd3 286 msr cpsr_c, #0xd3
262 bl main 287 bl main
263 288
264/* Exception handlers. Will be copied to address 0 after memory remapping */ 289#ifdef BOOTLOADER
265_vectorstart: 290 /* Exception vectors with absolute jumps for bootloader */
266 .section .vectors,"aw" 291 .section .vectors,"aw"
267 ldr pc, [pc, #24] 292 ldr pc, [pc, #24]
268 ldr pc, [pc, #24] 293 ldr pc, [pc, #24]
269 ldr pc, [pc, #24] 294 ldr pc, [pc, #24]
270 ldr pc, [pc, #24] 295 ldr pc, [pc, #24]
271 ldr pc, [pc, #24] 296 ldr pc, [pc, #24]
272 ldr pc, [pc, #24] 297 ldr pc, [pc, #24]
273 ldr pc, [pc, #24] 298 ldr pc, [pc, #24]
274 ldr pc, [pc, #24] 299 ldr pc, [pc, #24]
275 300 .word newstart
276 /* Exception vectors */ 301 .word undef_instr_handler
277 .global vectors 302 .word software_int_handler
278vectors: 303 .word prefetch_abort_handler
279 .word start 304 .word data_abort_handler
280 .word undef_instr_handler 305 .word reserved_handler
281 .word software_int_handler 306 .word irq_handler
282 .word prefetch_abort_handler 307 .word fiq_handler
283 .word data_abort_handler 308#endif /* BOOTLOADER */
284 .word reserved_handler
285 .word irq_handler
286 .word fiq_handler
287 309
288 .text 310 .text
289
290 .global UIE 311 .global UIE
291 312
292/* All illegal exceptions call into UIE with exception address as first 313/* All illegal exceptions call into UIE with exception address as first
293 parameter. This is calculated differently depending on which exception 314 * parameter. This is calculated differently depending on which exception
294 we're in. Second parameter is exception number, used for a string lookup 315 * we're in. Second parameter is exception number, used for a string lookup
295 in UIE. 316 * in UIE. */
296 */
297undef_instr_handler: 317undef_instr_handler:
298 mov r0, lr 318 mov r0, lr
299 mov r1, #0 319 mov r1, #0
300 b UIE 320 b UIE
301 321
302/* We run supervisor mode most of the time, and should never see a software 322/* We run supervisor mode most of the time, and should never see a software
303 exception being thrown. Perhaps make it illegal and call UIE? 323 * exception being thrown. Perhaps make it illegal and call UIE? */
304 */
305software_int_handler: 324software_int_handler:
306reserved_handler: 325reserved_handler:
307 movs pc, lr 326 movs pc, lr
@@ -316,11 +335,6 @@ data_abort_handler:
316 mov r1, #2 335 mov r1, #2
317 b UIE 336 b UIE
318 337
319#ifdef BOOTLOADER
320UIE:
321 b UIE
322#endif
323
324/* 256 words of IRQ stack */ 338/* 256 words of IRQ stack */
325 .space 256*4 339 .space 256*4
326irq_stack: 340irq_stack: