]>
Commit | Line | Data |
---|---|---|
c609719b | 1 | /* |
20f7b1b7 | 2 | * armboot - Startup Code for XScale CPU-core |
c609719b WD |
3 | * |
4 | * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> | |
5 | * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> | |
6 | * Copyright (C) 2000 Wolfgang Denk <wd@denx.de> | |
a8c7c708 | 7 | * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de> |
20f7b1b7 MV |
8 | * Copyright (C) 2001 Marius Groger <mag@sysgo.de> |
9 | * Copyright (C) 2002 Alex Zupke <azu@sysgo.de> | |
10 | * Copyright (C) 2002 Gary Jennejohn <garyj@denx.de> | |
1cb8e980 | 11 | * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net> |
951a954b | 12 | * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de> |
20f7b1b7 MV |
13 | * Copyright (C) 2003 Kshitij <kshitij@ti.com> |
14 | * Copyright (C) 2003 Richard Woodruff <r-woodruff2@ti.com> | |
15 | * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de> | |
16 | * Copyright (C) 2004 Texas Instruments <r-woodruff2@ti.com> | |
17 | * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> | |
c609719b WD |
18 | * |
19 | * See file CREDITS for list of people who contributed to this | |
20 | * project. | |
21 | * | |
22 | * This program is free software; you can redistribute it and/or | |
23 | * modify it under the terms of the GNU General Public License as | |
24 | * published by the Free Software Foundation; either version 2 of | |
25 | * the License, or (at your option) any later version. | |
26 | * | |
27 | * This program is distributed in the hope that it will be useful, | |
28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
384ae025 | 29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
c609719b WD |
30 | * GNU General Public License for more details. |
31 | * | |
32 | * You should have received a copy of the GNU General Public License | |
33 | * along with this program; if not, write to the Free Software | |
34 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
35 | * MA 02111-1307 USA | |
36 | */ | |
37 | ||
25ddd1fb | 38 | #include <asm-offsets.h> |
c609719b WD |
39 | #include <config.h> |
40 | #include <version.h> | |
7f4cfcf4 | 41 | |
abc20aba | 42 | #ifdef CONFIG_CPU_PXA25X |
7f4cfcf4 MV |
43 | #if ((CONFIG_SYS_INIT_SP_ADDR) != 0xfffff800) |
44 | #error "Init SP address must be set to 0xfffff800 for PXA250" | |
45 | #endif | |
46 | #endif | |
47 | ||
c609719b | 48 | .globl _start |
384ae025 | 49 | _start: b reset |
401bb30b | 50 | #ifdef CONFIG_SPL_BUILD |
5ab877b6 MV |
51 | ldr pc, _hang |
52 | ldr pc, _hang | |
53 | ldr pc, _hang | |
54 | ldr pc, _hang | |
55 | ldr pc, _hang | |
56 | ldr pc, _hang | |
57 | ldr pc, _hang | |
58 | ||
59 | _hang: | |
60 | .word do_hang | |
61 | .word 0x12345678 | |
62 | .word 0x12345678 | |
63 | .word 0x12345678 | |
64 | .word 0x12345678 | |
65 | .word 0x12345678 | |
66 | .word 0x12345678 | |
67 | .word 0x12345678 /* now 16*4=64 */ | |
68 | #else | |
c609719b WD |
69 | ldr pc, _undefined_instruction |
70 | ldr pc, _software_interrupt | |
71 | ldr pc, _prefetch_abort | |
72 | ldr pc, _data_abort | |
73 | ldr pc, _not_used | |
74 | ldr pc, _irq | |
75 | ldr pc, _fiq | |
76 | ||
384ae025 | 77 | _undefined_instruction: .word undefined_instruction |
c609719b WD |
78 | _software_interrupt: .word software_interrupt |
79 | _prefetch_abort: .word prefetch_abort | |
80 | _data_abort: .word data_abort | |
81 | _not_used: .word not_used | |
82 | _irq: .word irq | |
83 | _fiq: .word fiq | |
20f7b1b7 | 84 | _pad: .word 0x12345678 /* now 16*4=64 */ |
401bb30b | 85 | #endif /* CONFIG_SPL_BUILD */ |
20f7b1b7 MV |
86 | .global _end_vect |
87 | _end_vect: | |
c609719b WD |
88 | |
89 | .balignl 16,0xdeadbeef | |
c609719b | 90 | /* |
20f7b1b7 MV |
91 | ************************************************************************* |
92 | * | |
c609719b WD |
93 | * Startup Code (reset vector) |
94 | * | |
20f7b1b7 MV |
95 | * do important init only if we don't start from memory! |
96 | * setup Memory and board specific bits prior to relocation. | |
97 | * relocate armboot to ram | |
98 | * setup stack | |
99 | * | |
100 | ************************************************************************* | |
c609719b WD |
101 | */ |
102 | ||
5347f68c | 103 | .globl _TEXT_BASE |
c609719b | 104 | _TEXT_BASE: |
508611bc | 105 | #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE) |
20f7b1b7 MV |
106 | .word CONFIG_SPL_TEXT_BASE |
107 | #else | |
14d0a02a | 108 | .word CONFIG_SYS_TEXT_BASE |
20f7b1b7 | 109 | #endif |
c609719b | 110 | |
c609719b | 111 | /* |
f6e20fc6 | 112 | * These are defined in the board-specific linker script. |
20f7b1b7 MV |
113 | * Subtracting _start from them lets the linker put their |
114 | * relative position in the executable instead of leaving | |
115 | * them null. | |
47cd00fa | 116 | */ |
6e96cf9a MV |
117 | .globl _bss_start_ofs |
118 | _bss_start_ofs: | |
119 | .word __bss_start - _start | |
47cd00fa | 120 | |
7086e91b BT |
121 | .globl _image_copy_end_ofs |
122 | _image_copy_end_ofs: | |
123 | .word __image_copy_end - _start | |
124 | ||
6e96cf9a MV |
125 | .globl _bss_end_ofs |
126 | _bss_end_ofs: | |
3929fb0a | 127 | .word __bss_end - _start |
47cd00fa | 128 | |
f326cbba PYC |
129 | .globl _end_ofs |
130 | _end_ofs: | |
131 | .word _end - _start | |
132 | ||
c609719b WD |
133 | #ifdef CONFIG_USE_IRQ |
134 | /* IRQ stack memory (calculated at run-time) */ | |
135 | .globl IRQ_STACK_START | |
136 | IRQ_STACK_START: | |
137 | .word 0x0badc0de | |
138 | ||
139 | /* IRQ stack memory (calculated at run-time) */ | |
140 | .globl FIQ_STACK_START | |
141 | FIQ_STACK_START: | |
142 | .word 0x0badc0de | |
20f7b1b7 | 143 | #endif |
c609719b | 144 | |
5347f68c HS |
145 | /* IRQ stack memory (calculated at run-time) + 8 bytes */ |
146 | .globl IRQ_STACK_START_IN | |
147 | IRQ_STACK_START_IN: | |
148 | .word 0x0badc0de | |
149 | ||
5347f68c HS |
150 | /* |
151 | * the actual reset code | |
152 | */ | |
153 | ||
154 | reset: | |
155 | /* | |
156 | * set the cpu to SVC32 mode | |
157 | */ | |
158 | mrs r0,cpsr | |
159 | bic r0,r0,#0x1f | |
160 | orr r0,r0,#0xd3 | |
161 | msr cpsr,r0 | |
162 | ||
20f7b1b7 MV |
163 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT |
164 | bl cpu_init_crit | |
165 | #endif | |
5347f68c | 166 | |
abc20aba | 167 | #ifdef CONFIG_CPU_PXA25X |
7f4cfcf4 MV |
168 | bl lock_cache_for_stack |
169 | #endif | |
170 | ||
e05e5de7 | 171 | bl _main |
5347f68c HS |
172 | |
173 | /*------------------------------------------------------------------------------*/ | |
20f7b1b7 | 174 | #ifndef CONFIG_SPL_BUILD |
5347f68c | 175 | /* |
5c6db120 | 176 | * void relocate_code(addr_moni) |
5347f68c | 177 | * |
959eaa74 | 178 | * This function relocates the monitor code. |
5347f68c HS |
179 | */ |
180 | .globl relocate_code | |
181 | relocate_code: | |
5c6db120 | 182 | mov r6, r0 /* save addr of destination */ |
5347f68c | 183 | |
7f4cfcf4 | 184 | /* Disable the Dcache RAM lock for stack now */ |
abc20aba | 185 | #ifdef CONFIG_CPU_PXA25X |
df3ad6c8 | 186 | mov r12, lr |
7f4cfcf4 | 187 | bl cpu_init_crit |
df3ad6c8 | 188 | mov lr, r12 |
7f4cfcf4 MV |
189 | #endif |
190 | ||
5347f68c | 191 | adr r0, _start |
4b3db1cd | 192 | subs r9, r6, r0 /* r9 <- relocation offset */ |
e05e5de7 | 193 | beq relocate_done /* skip relocation */ |
a78fb68f | 194 | mov r1, r6 /* r1 <- scratch for copy_loop */ |
7086e91b | 195 | ldr r3, _image_copy_end_ofs |
6e96cf9a | 196 | add r2, r0, r3 /* r2 <- source end address */ |
5347f68c | 197 | |
5347f68c | 198 | copy_loop: |
4b3db1cd BT |
199 | ldmia r0!, {r10-r11} /* copy from source address [r0] */ |
200 | stmia r1!, {r10-r11} /* copy to target address [r1] */ | |
da90d4ce AA |
201 | cmp r0, r2 /* until source end address [r2] */ |
202 | blo copy_loop | |
5347f68c | 203 | |
401bb30b | 204 | #ifndef CONFIG_SPL_BUILD |
6e96cf9a MV |
205 | /* |
206 | * fix .rel.dyn relocations | |
207 | */ | |
208 | ldr r0, _TEXT_BASE /* r0 <- Text base */ | |
6e96cf9a MV |
209 | ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ |
210 | add r10, r10, r0 /* r10 <- sym table in FLASH */ | |
211 | ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ | |
212 | add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ | |
213 | ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ | |
214 | add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ | |
5347f68c | 215 | fixloop: |
20f7b1b7 MV |
216 | ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ |
217 | add r0, r0, r9 /* r0 <- location to fix up in RAM */ | |
6e96cf9a | 218 | ldr r1, [r2, #4] |
1f52d89f | 219 | and r7, r1, #0xff |
20f7b1b7 | 220 | cmp r7, #23 /* relative fixup? */ |
6e96cf9a | 221 | beq fixrel |
20f7b1b7 | 222 | cmp r7, #2 /* absolute fixup? */ |
6e96cf9a MV |
223 | beq fixabs |
224 | /* ignore unknown type of fixup */ | |
225 | b fixnext | |
226 | fixabs: | |
227 | /* absolute fix: set location to (offset) symbol value */ | |
228 | mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ | |
229 | add r1, r10, r1 /* r1 <- address of symbol in table */ | |
230 | ldr r1, [r1, #4] /* r1 <- symbol value */ | |
3600945b | 231 | add r1, r1, r9 /* r1 <- relocated sym addr */ |
6e96cf9a MV |
232 | b fixnext |
233 | fixrel: | |
234 | /* relative fix: increase location by offset */ | |
235 | ldr r1, [r0] | |
236 | add r1, r1, r9 | |
237 | fixnext: | |
238 | str r1, [r0] | |
20f7b1b7 | 239 | add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ |
5347f68c | 240 | cmp r2, r3 |
6e96cf9a | 241 | blo fixloop |
20f7b1b7 | 242 | #endif |
5347f68c | 243 | |
e05e5de7 | 244 | relocate_done: |
5347f68c | 245 | |
e05e5de7 | 246 | bx lr |
5347f68c | 247 | |
6e96cf9a MV |
248 | _rel_dyn_start_ofs: |
249 | .word __rel_dyn_start - _start | |
250 | _rel_dyn_end_ofs: | |
251 | .word __rel_dyn_end - _start | |
252 | _dynsym_start_ofs: | |
253 | .word __dynsym_start - _start | |
e05e5de7 | 254 | |
2cad92fd | 255 | #endif |
e05e5de7 AA |
256 | |
257 | .globl c_runtime_cpu_setup | |
258 | c_runtime_cpu_setup: | |
259 | ||
260 | bx lr | |
261 | ||
20f7b1b7 MV |
262 | /* |
263 | ************************************************************************* | |
264 | * | |
265 | * CPU_init_critical registers | |
266 | * | |
267 | * setup important registers | |
268 | * setup memory timing | |
269 | * | |
270 | ************************************************************************* | |
271 | */ | |
abc20aba | 272 | #if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_CPU_PXA25X) |
20f7b1b7 MV |
273 | cpu_init_crit: |
274 | /* | |
275 | * flush v4 I/D caches | |
276 | */ | |
277 | mov r0, #0 | |
278 | mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */ | |
279 | mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */ | |
2cad92fd | 280 | |
20f7b1b7 MV |
281 | /* |
282 | * disable MMU stuff and caches | |
283 | */ | |
284 | mrc p15, 0, r0, c1, c0, 0 | |
285 | bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) | |
286 | bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) | |
287 | orr r0, r0, #0x00000002 @ set bit 2 (A) Align | |
288 | orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache | |
289 | mcr p15, 0, r0, c1, c0, 0 | |
47cd00fa | 290 | |
20f7b1b7 | 291 | mov pc, lr /* back to my caller */ |
abc20aba | 292 | #endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */ |
c609719b | 293 | |
401bb30b | 294 | #ifndef CONFIG_SPL_BUILD |
20f7b1b7 MV |
295 | /* |
296 | ************************************************************************* | |
297 | * | |
298 | * Interrupt handling | |
299 | * | |
300 | ************************************************************************* | |
301 | */ | |
302 | @ | |
303 | @ IRQ stack frame. | |
304 | @ | |
c609719b WD |
305 | #define S_FRAME_SIZE 72 |
306 | ||
307 | #define S_OLD_R0 68 | |
308 | #define S_PSR 64 | |
309 | #define S_PC 60 | |
310 | #define S_LR 56 | |
311 | #define S_SP 52 | |
312 | ||
313 | #define S_IP 48 | |
314 | #define S_FP 44 | |
315 | #define S_R10 40 | |
316 | #define S_R9 36 | |
317 | #define S_R8 32 | |
318 | #define S_R7 28 | |
319 | #define S_R6 24 | |
320 | #define S_R5 20 | |
321 | #define S_R4 16 | |
322 | #define S_R3 12 | |
323 | #define S_R2 8 | |
324 | #define S_R1 4 | |
325 | #define S_R0 0 | |
326 | ||
327 | #define MODE_SVC 0x13 | |
20f7b1b7 | 328 | #define I_BIT 0x80 |
c609719b | 329 | |
20f7b1b7 MV |
330 | /* |
331 | * use bad_save_user_regs for abort/prefetch/undef/swi ... | |
332 | * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | |
333 | */ | |
c609719b WD |
334 | |
335 | .macro bad_save_user_regs | |
20f7b1b7 MV |
336 | sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack |
337 | stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 | |
c609719b | 338 | |
20f7b1b7 MV |
339 | ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack |
340 | ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) | |
341 | add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack | |
c609719b WD |
342 | |
343 | add r5, sp, #S_SP | |
344 | mov r1, lr | |
20f7b1b7 MV |
345 | stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr |
346 | mov r0, sp @ save current stack into r0 (param register) | |
c609719b WD |
347 | .endm |
348 | ||
c609719b WD |
349 | .macro irq_save_user_regs |
350 | sub sp, sp, #S_FRAME_SIZE | |
20f7b1b7 MV |
351 | stmia sp, {r0 - r12} @ Calling r0-r12 |
352 | add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. | |
353 | stmdb r8, {sp, lr}^ @ Calling SP, LR | |
354 | str lr, [r8, #0] @ Save calling PC | |
384ae025 | 355 | mrs r6, spsr |
20f7b1b7 MV |
356 | str r6, [r8, #4] @ Save CPSR |
357 | str r0, [r8, #8] @ Save OLD_R0 | |
c609719b WD |
358 | mov r0, sp |
359 | .endm | |
360 | ||
361 | .macro irq_restore_user_regs | |
362 | ldmia sp, {r0 - lr}^ @ Calling r0 - lr | |
363 | mov r0, r0 | |
364 | ldr lr, [sp, #S_PC] @ Get PC | |
365 | add sp, sp, #S_FRAME_SIZE | |
366 | subs pc, lr, #4 @ return & move spsr_svc into cpsr | |
367 | .endm | |
368 | ||
369 | .macro get_bad_stack | |
20f7b1b7 | 370 | ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode) |
c609719b | 371 | |
20f7b1b7 MV |
372 | str lr, [r13] @ save caller lr in position 0 of saved stack |
373 | mrs lr, spsr @ get the spsr | |
374 | str lr, [r13, #4] @ save spsr in position 1 of saved stack | |
c609719b WD |
375 | |
376 | mov r13, #MODE_SVC @ prepare SVC-Mode | |
20f7b1b7 MV |
377 | @ msr spsr_c, r13 |
378 | msr spsr, r13 @ switch modes, make sure moves will execute | |
379 | mov lr, pc @ capture return pc | |
380 | movs pc, lr @ jump to next instruction & switch modes. | |
381 | .endm | |
382 | ||
383 | .macro get_bad_stack_swi | |
384 | sub r13, r13, #4 @ space on current stack for scratch reg. | |
385 | str r0, [r13] @ save R0's value. | |
386 | ldr r0, IRQ_STACK_START_IN @ get data regions start | |
387 | str lr, [r0] @ save caller lr in position 0 of saved stack | |
388 | mrs r0, spsr @ get the spsr | |
389 | str lr, [r0, #4] @ save spsr in position 1 of saved stack | |
390 | ldr r0, [r13] @ restore r0 | |
391 | add r13, r13, #4 @ pop stack entry | |
c609719b WD |
392 | .endm |
393 | ||
394 | .macro get_irq_stack @ setup IRQ stack | |
395 | ldr sp, IRQ_STACK_START | |
396 | .endm | |
397 | ||
398 | .macro get_fiq_stack @ setup FIQ stack | |
399 | ldr sp, FIQ_STACK_START | |
400 | .endm | |
20f7b1b7 | 401 | #endif /* CONFIG_SPL_BUILD */ |
c609719b | 402 | |
20f7b1b7 MV |
403 | /* |
404 | * exception handlers | |
405 | */ | |
401bb30b | 406 | #ifdef CONFIG_SPL_BUILD |
5ab877b6 MV |
407 | .align 5 |
408 | do_hang: | |
20f7b1b7 | 409 | ldr sp, _TEXT_BASE /* use 32 words about stack */ |
5ab877b6 | 410 | bl hang /* hang and never return */ |
20f7b1b7 | 411 | #else /* !CONFIG_SPL_BUILD */ |
384ae025 | 412 | .align 5 |
c609719b WD |
413 | undefined_instruction: |
414 | get_bad_stack | |
415 | bad_save_user_regs | |
384ae025 | 416 | bl do_undefined_instruction |
c609719b WD |
417 | |
418 | .align 5 | |
419 | software_interrupt: | |
20f7b1b7 | 420 | get_bad_stack_swi |
c609719b | 421 | bad_save_user_regs |
384ae025 | 422 | bl do_software_interrupt |
c609719b WD |
423 | |
424 | .align 5 | |
425 | prefetch_abort: | |
426 | get_bad_stack | |
427 | bad_save_user_regs | |
384ae025 | 428 | bl do_prefetch_abort |
c609719b WD |
429 | |
430 | .align 5 | |
431 | data_abort: | |
432 | get_bad_stack | |
433 | bad_save_user_regs | |
384ae025 | 434 | bl do_data_abort |
c609719b WD |
435 | |
436 | .align 5 | |
437 | not_used: | |
438 | get_bad_stack | |
439 | bad_save_user_regs | |
384ae025 | 440 | bl do_not_used |
c609719b WD |
441 | |
442 | #ifdef CONFIG_USE_IRQ | |
443 | ||
444 | .align 5 | |
445 | irq: | |
446 | get_irq_stack | |
447 | irq_save_user_regs | |
384ae025 | 448 | bl do_irq |
c609719b WD |
449 | irq_restore_user_regs |
450 | ||
451 | .align 5 | |
452 | fiq: | |
453 | get_fiq_stack | |
20f7b1b7 MV |
454 | /* someone ought to write a more effiction fiq_save_user_regs */ |
455 | irq_save_user_regs | |
456 | bl do_fiq | |
c609719b WD |
457 | irq_restore_user_regs |
458 | ||
20f7b1b7 | 459 | #else |
c609719b WD |
460 | |
461 | .align 5 | |
462 | irq: | |
463 | get_bad_stack | |
464 | bad_save_user_regs | |
384ae025 | 465 | bl do_irq |
c609719b WD |
466 | |
467 | .align 5 | |
468 | fiq: | |
469 | get_bad_stack | |
470 | bad_save_user_regs | |
384ae025 | 471 | bl do_fiq |
384ae025 | 472 | |
20f7b1b7 MV |
473 | #endif |
474 | .align 5 | |
401bb30b | 475 | #endif /* CONFIG_SPL_BUILD */ |
7f4cfcf4 MV |
476 | |
477 | ||
478 | /* | |
479 | * Enable MMU to use DCache as DRAM. | |
480 | * | |
481 | * This is useful on PXA25x and PXA26x in early bootstages, where there is no | |
482 | * other possible memory available to hold stack. | |
483 | */ | |
abc20aba | 484 | #ifdef CONFIG_CPU_PXA25X |
7f4cfcf4 MV |
485 | .macro CPWAIT reg |
486 | mrc p15, 0, \reg, c2, c0, 0 | |
487 | mov \reg, \reg | |
488 | sub pc, pc, #4 | |
489 | .endm | |
490 | lock_cache_for_stack: | |
491 | /* Domain access -- enable for all CPs */ | |
492 | ldr r0, =0x0000ffff | |
493 | mcr p15, 0, r0, c3, c0, 0 | |
494 | ||
495 | /* Point TTBR to MMU table */ | |
496 | ldr r0, =mmutable | |
497 | mcr p15, 0, r0, c2, c0, 0 | |
498 | ||
499 | /* Kick in MMU, ICache, DCache, BTB */ | |
500 | mrc p15, 0, r0, c1, c0, 0 | |
501 | bic r0, #0x1b00 | |
502 | bic r0, #0x0087 | |
503 | orr r0, #0x1800 | |
504 | orr r0, #0x0005 | |
505 | mcr p15, 0, r0, c1, c0, 0 | |
506 | CPWAIT r0 | |
507 | ||
508 | /* Unlock Icache, Dcache */ | |
509 | mcr p15, 0, r0, c9, c1, 1 | |
510 | mcr p15, 0, r0, c9, c2, 1 | |
511 | ||
512 | /* Flush Icache, Dcache, BTB */ | |
513 | mcr p15, 0, r0, c7, c7, 0 | |
514 | ||
515 | /* Unlock I-TLB, D-TLB */ | |
516 | mcr p15, 0, r0, c10, c4, 1 | |
517 | mcr p15, 0, r0, c10, c8, 1 | |
518 | ||
519 | /* Flush TLB */ | |
520 | mcr p15, 0, r0, c8, c7, 0 | |
521 | ||
522 | /* Allocate 4096 bytes of Dcache as RAM */ | |
523 | ||
524 | /* Drain pending loads and stores */ | |
525 | mcr p15, 0, r0, c7, c10, 4 | |
526 | ||
527 | mov r4, #0x00 | |
528 | mov r5, #0x00 | |
529 | mov r2, #0x01 | |
530 | mcr p15, 0, r0, c9, c2, 0 | |
531 | CPWAIT r0 | |
532 | ||
533 | /* 128 lines reserved (128 x 32bytes = 4096 bytes total) */ | |
534 | mov r0, #128 | |
535 | ldr r1, =0xfffff000 | |
536 | ||
537 | alloc: | |
538 | mcr p15, 0, r1, c7, c2, 5 | |
539 | /* Drain pending loads and stores */ | |
540 | mcr p15, 0, r0, c7, c10, 4 | |
541 | strd r4, [r1], #8 | |
542 | strd r4, [r1], #8 | |
543 | strd r4, [r1], #8 | |
544 | strd r4, [r1], #8 | |
545 | subs r0, #0x01 | |
546 | bne alloc | |
547 | /* Drain pending loads and stores */ | |
548 | mcr p15, 0, r0, c7, c10, 4 | |
549 | mov r2, #0x00 | |
550 | mcr p15, 0, r2, c9, c2, 0 | |
551 | CPWAIT r0 | |
552 | ||
553 | mov pc, lr | |
554 | ||
555 | .section .mmutable, "a" | |
556 | mmutable: | |
557 | .align 14 | |
558 | /* 0x00000000 - 0xffe00000 : 1:1, uncached mapping */ | |
559 | .set __base, 0 | |
560 | .rept 0xfff | |
561 | .word (__base << 20) | 0xc12 | |
562 | .set __base, __base + 1 | |
563 | .endr | |
564 | ||
565 | /* 0xfff00000 : 1:1, cached mapping */ | |
566 | .word (0xfff << 20) | 0x1c1e | |
abc20aba | 567 | #endif /* CONFIG_CPU_PXA25X */ |