blob: 55238df45628829ecdf474ffa5a41b98e6e1c77c [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenkc6097192002-11-03 00:24:07 +00007 */
8
9/* U-Boot - Startup Code for PowerPC based Embedded Boards
10 *
11 *
12 * The processor starts at 0x00000100 and the code is executed
13 * from flash. The code is organized to be at an other address
14 * in memory, but as long we don't jump around before relocating.
15 * board_init lies at a quite high address and when the cpu has
16 * jumped there, everything is ok.
17 * This works because the cpu gives the FLASH (CS0) the whole
18 * address space at startup, and board_init lies as a echo of
19 * the flash somewhere up there in the memorymap.
20 *
21 * board_init will change CS0 to be positioned at the correct
22 * address and (s)dram will be positioned at address 0
23 */
Wolfgang Denk0191e472010-10-26 14:34:52 +020024#include <asm-offsets.h>
wdenkc6097192002-11-03 00:24:07 +000025#include <config.h>
26#include <mpc824x.h>
27#include <version.h>
28
wdenkc6097192002-11-03 00:24:07 +000029#include <ppc_asm.tmpl>
30#include <ppc_defs.h>
31
32#include <asm/cache.h>
33#include <asm/mmu.h>
Peter Tyser3a1362d2010-10-14 23:33:24 -050034#include <asm/u-boot.h>
wdenkc6097192002-11-03 00:24:07 +000035
wdenkc6097192002-11-03 00:24:07 +000036/* We don't want the MMU yet.
37*/
38#undef MSR_KERNEL
39/* FP, Machine Check and Recoverable Interr. */
40#define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
41
42/*
43 * Set up GOT: Global Offset Table
44 *
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +010045 * Use r12 to access the GOT
wdenkc6097192002-11-03 00:24:07 +000046 */
47 START_GOT
48 GOT_ENTRY(_GOT2_TABLE_)
49 GOT_ENTRY(_FIXUP_TABLE_)
50
51 GOT_ENTRY(_start)
52 GOT_ENTRY(_start_of_vectors)
53 GOT_ENTRY(_end_of_vectors)
54 GOT_ENTRY(transfer_to_handler)
55
wdenkb9a83a92003-05-30 12:48:29 +000056 GOT_ENTRY(__init_end)
Simon Glassed70c8f2013-03-14 06:54:53 +000057 GOT_ENTRY(__bss_end)
wdenkbf2f8c92003-05-22 22:52:13 +000058 GOT_ENTRY(__bss_start)
wdenkc6097192002-11-03 00:24:07 +000059 END_GOT
60
61/*
62 * r3 - 1st arg to board_init(): IMMP pointer
63 * r4 - 2nd arg to board_init(): boot flag
64 */
65 .text
66 .long 0x27051956 /* U-Boot Magic Number */
67 .globl version_string
68version_string:
Andreas Bießmann61d01952011-07-18 20:24:04 +020069 .ascii U_BOOT_VERSION_STRING, "\0"
wdenkc6097192002-11-03 00:24:07 +000070
71 . = EXC_OFF_SYS_RESET
72 .globl _start
73_start:
wdenkc6097192002-11-03 00:24:07 +000074 /* Initialize machine status; enable machine check interrupt */
75 /*----------------------------------------------------------------------*/
76 li r3, MSR_KERNEL /* Set FP, ME, RI flags */
77 mtmsr r3
78 mtspr SRR1, r3 /* Make SRR1 match MSR */
79
80 addis r0,0,0x0000 /* lets make sure that r0 is really 0 */
81 mtspr HID0, r0 /* disable I and D caches */
82
83 mfspr r3, ICR /* clear Interrupt Cause Register */
84
85 mfmsr r3 /* turn off address translation */
86 addis r4,0,0xffff
87 ori r4,r4,0xffcf
88 and r3,r3,r4
89 mtmsr r3
90 isync
91 sync /* the MMU should be off... */
92
93
94in_flash:
wdenkc6097192002-11-03 00:24:07 +000095 /*
96 * Setup BATs - cannot be done in C since we don't have a stack yet
97 */
98 bl setup_bats
99
100 /* Enable MMU.
101 */
102 mfmsr r3
103 ori r3, r3, (MSR_IR | MSR_DR)
104 mtmsr r3
Stefan Roeseed062042012-09-19 03:18:53 +0000105
wdenkc6097192002-11-03 00:24:07 +0000106 /* Enable and invalidate data cache.
107 */
108 mfspr r3, HID0
109 mr r2, r3
110 ori r3, r3, HID0_DCE | HID0_DCI
111 ori r2, r2, HID0_DCE
112 sync
113 mtspr HID0, r3
114 mtspr HID0, r2
115 sync
116
117 /* Allocate Initial RAM in data cache.
118 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200119 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
120 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
wdenkc6097192002-11-03 00:24:07 +0000121 li r2, 128
122 mtctr r2
1231:
124 dcbz r0, r3
125 addi r3, r3, 32
126 bdnz 1b
127
128 /* Lock way0 in data cache.
129 */
130 mfspr r3, 1011
131 lis r2, 0xffff
132 ori r2, r2, 0xff1f
133 and r3, r3, r2
134 ori r3, r3, 0x0080
135 sync
136 mtspr 1011, r3
Stefan Roeseed062042012-09-19 03:18:53 +0000137
wdenkc6097192002-11-03 00:24:07 +0000138 /*
139 * Thisk the stack pointer *somewhere* sensible. Doesnt
140 * matter much where as we'll move it when we relocate
141 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200142 lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
143 ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
wdenkc6097192002-11-03 00:24:07 +0000144
145 li r0, 0 /* Make room for stack frame header and */
146 stwu r0, -4(r1) /* clear final stack frame so that */
147 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
148
149 /* let the C-code set up the rest */
150 /* */
151 /* Be careful to keep code relocatable ! */
152 /*----------------------------------------------------------------------*/
153
154 GET_GOT /* initialize GOT access */
Wolfgang Denkb2d36ea2011-04-20 22:11:21 +0200155
wdenkc6097192002-11-03 00:24:07 +0000156 /* r3: IMMR */
157 bl cpu_init_f /* run low-level CPU init code (from Flash) */
158
wdenkc6097192002-11-03 00:24:07 +0000159 bl board_init_f /* run 1st part of board init code (from Flash) */
160
Peter Tyser0c44caf2010-09-14 19:13:53 -0500161 /* NOTREACHED - board_init_f() does not return */
162
wdenkc6097192002-11-03 00:24:07 +0000163
wdenkc6097192002-11-03 00:24:07 +0000164 .globl _start_of_vectors
165_start_of_vectors:
166
167/* Machine check */
168 STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
169
170/* Data Storage exception. "Never" generated on the 860. */
171 STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
172
173/* Instruction Storage exception. "Never" generated on the 860. */
174 STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
175
176/* External Interrupt exception. */
177 STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
178
179/* Alignment exception. */
180 . = EXC_OFF_ALIGN
181Alignment:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200182 EXCEPTION_PROLOG(SRR0, SRR1)
wdenkc6097192002-11-03 00:24:07 +0000183 mfspr r4,DAR
184 stw r4,_DAR(r21)
185 mfspr r5,DSISR
186 stw r5,_DSISR(r21)
187 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100188 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenkc6097192002-11-03 00:24:07 +0000189
190/* Program check exception */
191 . = EXC_OFF_PROGRAM
192ProgramCheck:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200193 EXCEPTION_PROLOG(SRR0, SRR1)
wdenkc6097192002-11-03 00:24:07 +0000194 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100195 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
196 MSR_KERNEL, COPY_EE)
wdenkc6097192002-11-03 00:24:07 +0000197
198 /* No FPU on MPC8xx. This exception is not supposed to happen.
199 */
200 STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
201
202 /* I guess we could implement decrementer, and may have
203 * to someday for timekeeping.
204 */
205 STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
206 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
207 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000208 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenkc6097192002-11-03 00:24:07 +0000209
210 STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
211
212 STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
213 STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
214
215 STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
216 STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
217 STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
wdenk4a5c8a72003-03-06 00:02:04 +0000218 STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, DebugException)
wdenkc6097192002-11-03 00:24:07 +0000219 STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
220 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
221 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
222 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
223 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
224 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
225 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
226 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
227 STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
228 STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
229 STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
230 STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
231
232 STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
233
234 .globl _end_of_vectors
235_end_of_vectors:
236
237
238 . = 0x3000
239
240/*
241 * This code finishes saving the registers to the exception frame
242 * and jumps to the appropriate handler for the exception.
243 * Register r21 is pointer into trap frame, r1 has new stack pointer.
244 */
245 .globl transfer_to_handler
246transfer_to_handler:
247 stw r22,_NIP(r21)
248 lis r22,MSR_POW@h
249 andc r23,r23,r22
250 stw r23,_MSR(r21)
251 SAVE_GPR(7, r21)
252 SAVE_4GPRS(8, r21)
253 SAVE_8GPRS(12, r21)
254 SAVE_8GPRS(24, r21)
255#if 0
256 andi. r23,r23,MSR_PR
257 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
258 beq 2f
259 addi r24,r1,STACK_FRAME_OVERHEAD
260 stw r24,PT_REGS(r23)
2612: addi r2,r23,-TSS /* set r2 to current */
262 tovirt(r2,r2,r23)
263#endif
264 mflr r23
265 andi. r24,r23,0x3f00 /* get vector offset */
266 stw r24,TRAP(r21)
267 li r22,0
268 stw r22,RESULT(r21)
269 mtspr SPRG2,r22 /* r1 is now kernel sp */
270#if 0
271 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
272 cmplw 0,r1,r2
273 cmplw 1,r1,r24
274 crand 1,1,4
275 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
276#endif
277 lwz r24,0(r23) /* virtual address of handler */
278 lwz r23,4(r23) /* where to go when done */
279 mtspr SRR0,r24
280 ori r20,r20,0x30 /* enable IR, DR */
281 mtspr SRR1,r20
282 mtlr r23
283 SYNC
284 rfi /* jump to handler, enable MMU */
285
286int_return:
287 mfmsr r28 /* Disable interrupts */
288 li r4,0
289 ori r4,r4,MSR_EE
290 andc r28,r28,r4
291 SYNC /* Some chip revs need this... */
292 mtmsr r28
293 SYNC
294 lwz r2,_CTR(r1)
295 lwz r0,_LINK(r1)
296 mtctr r2
297 mtlr r0
298 lwz r2,_XER(r1)
299 lwz r0,_CCR(r1)
300 mtspr XER,r2
301 mtcrf 0xFF,r0
302 REST_10GPRS(3, r1)
303 REST_10GPRS(13, r1)
304 REST_8GPRS(23, r1)
305 REST_GPR(31, r1)
306 lwz r2,_NIP(r1) /* Restore environment */
307 lwz r0,_MSR(r1)
308 mtspr SRR0,r2
309 mtspr SRR1,r0
310 lwz r0,GPR0(r1)
311 lwz r2,GPR2(r1)
312 lwz r1,GPR1(r1)
313 SYNC
314 rfi
315
316/* Cache functions.
317*/
318 .globl icache_enable
319icache_enable:
320 mfspr r5,HID0 /* turn on the I cache. */
321 ori r5,r5,0x8800 /* Instruction cache only! */
322 addis r6,0,0xFFFF
323 ori r6,r6,0xF7FF
324 and r6,r5,r6 /* clear the invalidate bit */
325 sync
326 mtspr HID0,r5
327 mtspr HID0,r6
328 isync
329 sync
330 blr
331
332 .globl icache_disable
333icache_disable:
334 mfspr r5,HID0
335 addis r6,0,0xFFFF
336 ori r6,r6,0x7FFF
337 and r5,r5,r6
338 sync
339 mtspr HID0,r5
340 isync
341 sync
342 blr
343
344 .globl icache_status
345icache_status:
346 mfspr r3, HID0
347 srwi r3, r3, 15 /* >>15 & 1=> select bit 16 */
348 andi. r3, r3, 1
349 blr
350
351 .globl dcache_enable
352dcache_enable:
353 mfspr r5,HID0 /* turn on the D cache. */
354 ori r5,r5,0x4400 /* Data cache only! */
355 mfspr r4, PVR /* read PVR */
356 srawi r3, r4, 16 /* shift off the least 16 bits */
357 cmpi 0, 0, r3, 0xC /* Check for Max pvr */
358 bne NotMax
359 ori r5,r5,0x0040 /* setting the DCFA bit, for Max rev 1 errata */
360NotMax:
361 addis r6,0,0xFFFF
362 ori r6,r6,0xFBFF
363 and r6,r5,r6 /* clear the invalidate bit */
364 sync
365 mtspr HID0,r5
366 mtspr HID0,r6
367 isync
368 sync
369 blr
370
371 .globl dcache_disable
372dcache_disable:
373 mfspr r5,HID0
374 addis r6,0,0xFFFF
375 ori r6,r6,0xBFFF
376 and r5,r5,r6
377 sync
378 mtspr HID0,r5
379 isync
380 sync
381 blr
382
383 .globl dcache_status
384dcache_status:
385 mfspr r3, HID0
386 srwi r3, r3, 14 /* >>14 & 1=> select bit 17 */
387 andi. r3, r3, 1
388 blr
389
390 .globl dc_read
391dc_read:
392/*TODO : who uses this, what should it do?
393*/
394 blr
395
396
397 .globl get_pvr
398get_pvr:
399 mfspr r3, PVR
400 blr
401
402
403/*------------------------------------------------------------------------------*/
404
405/*
406 * void relocate_code (addr_sp, gd, addr_moni)
407 *
408 * This "function" does not return, instead it continues in RAM
409 * after relocating the monitor code.
410 *
411 * r3 = dest
412 * r4 = src
413 * r5 = length in bytes
414 * r6 = cachelinesize
415 */
416 .globl relocate_code
417relocate_code:
418
419 mr r1, r3 /* Set new stack pointer */
420 mr r9, r4 /* Save copy of Global Data pointer */
421 mr r10, r5 /* Save copy of Destination Address */
422
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100423 GET_GOT
wdenkc6097192002-11-03 00:24:07 +0000424 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200425#ifdef CONFIG_SYS_RAMBOOT
426 lis r4, CONFIG_SYS_SDRAM_BASE@h /* Source Address */
427 ori r4, r4, CONFIG_SYS_SDRAM_BASE@l
wdenkc6097192002-11-03 00:24:07 +0000428#else
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200429 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
430 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenkc6097192002-11-03 00:24:07 +0000431#endif
wdenkb9a83a92003-05-30 12:48:29 +0000432 lwz r5, GOT(__init_end)
433 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200434 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenkc6097192002-11-03 00:24:07 +0000435
436 /*
437 * Fix GOT pointer:
438 *
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200439 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenkc6097192002-11-03 00:24:07 +0000440 *
441 * Offset:
442 */
443 sub r15, r10, r4
444
445 /* First our own GOT */
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100446 add r12, r12, r15
wdenkc6097192002-11-03 00:24:07 +0000447 /* the the one used by the C code */
448 add r30, r30, r15
449
450 /*
451 * Now relocate code
452 */
453
454 cmplw cr1,r3,r4
455 addi r0,r5,3
456 srwi. r0,r0,2
457 beq cr1,4f /* In place copy is not necessary */
458 beq 7f /* Protect against 0 count */
459 mtctr r0
460 bge cr1,2f
461
462 la r8,-4(r4)
463 la r7,-4(r3)
4641: lwzu r0,4(r8)
465 stwu r0,4(r7)
466 bdnz 1b
467 b 4f
468
4692: slwi r0,r0,2
470 add r8,r4,r0
471 add r7,r3,r0
4723: lwzu r0,-4(r8)
473 stwu r0,-4(r7)
474 bdnz 3b
475
wdenk2c9b05d2003-09-10 22:30:53 +00004764:
wdenk2c9b05d2003-09-10 22:30:53 +0000477/* Unlock the data cache and invalidate locked area */
478 xor r0, r0, r0
479 mtspr 1011, r0
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200480 lis r4, CONFIG_SYS_INIT_RAM_ADDR@h
481 ori r4, r4, CONFIG_SYS_INIT_RAM_ADDR@l
wdenk2c9b05d2003-09-10 22:30:53 +0000482 li r0, 128
483 mtctr r0
48441:
485 dcbi r0, r4
486 addi r4, r4, 32
487 bdnz 41b
wdenk2c9b05d2003-09-10 22:30:53 +0000488
wdenkc6097192002-11-03 00:24:07 +0000489/*
490 * Now flush the cache: note that we must start from a cache aligned
491 * address. Otherwise we might miss one cache line.
492 */
wdenk2c9b05d2003-09-10 22:30:53 +0000493 cmpwi r6,0
wdenkc6097192002-11-03 00:24:07 +0000494 add r5,r3,r5
495 beq 7f /* Always flush prefetch queue in any case */
496 subi r0,r6,1
497 andc r3,r3,r0
498 mr r4,r3
4995: dcbst 0,r4
500 add r4,r4,r6
501 cmplw r4,r5
502 blt 5b
503 sync /* Wait for all dcbst to complete on bus */
504 mr r4,r3
5056: icbi 0,r4
506 add r4,r4,r6
507 cmplw r4,r5
508 blt 6b
5097: sync /* Wait for all icbi to complete on bus */
510 isync
511
512/*
513 * We are done. Do not return, instead branch to second part of board
514 * initialization, now running from RAM.
515 */
516
517 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
518 mtlr r0
519 blr
520
521in_ram:
522
523 /*
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100524 * Relocation Function, r12 point to got2+0x8000
wdenkc6097192002-11-03 00:24:07 +0000525 *
526 * Adjust got2 pointers, no need to check for 0, this code
527 * already puts a few entries in the table.
528 */
529 li r0,__got2_entries@sectoff@l
530 la r3,GOT(_GOT2_TABLE_)
531 lwz r11,GOT(_GOT2_TABLE_)
532 mtctr r0
533 sub r11,r3,r11
534 addi r3,r3,-4
5351: lwzu r0,4(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200536 cmpwi r0,0
537 beq- 2f
wdenkc6097192002-11-03 00:24:07 +0000538 add r0,r0,r11
539 stw r0,0(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +02005402: bdnz 1b
wdenkc6097192002-11-03 00:24:07 +0000541
542 /*
543 * Now adjust the fixups and the pointers to the fixups
544 * in case we need to move ourselves again.
545 */
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200546 li r0,__fixup_entries@sectoff@l
wdenkc6097192002-11-03 00:24:07 +0000547 lwz r3,GOT(_FIXUP_TABLE_)
548 cmpwi r0,0
549 mtctr r0
550 addi r3,r3,-4
551 beq 4f
5523: lwzu r4,4(r3)
553 lwzux r0,r4,r11
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200554 cmpwi r0,0
wdenkc6097192002-11-03 00:24:07 +0000555 add r0,r0,r11
Joakim Tjernlund401b5922010-11-04 19:02:00 +0100556 stw r4,0(r3)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200557 beq- 5f
wdenkc6097192002-11-03 00:24:07 +0000558 stw r0,0(r4)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +02005595: bdnz 3b
wdenkc6097192002-11-03 00:24:07 +00005604:
561clear_bss:
562 /*
563 * Now clear BSS segment
564 */
wdenkbf2f8c92003-05-22 22:52:13 +0000565 lwz r3,GOT(__bss_start)
Simon Glassed70c8f2013-03-14 06:54:53 +0000566 lwz r4,GOT(__bss_end)
wdenkc6097192002-11-03 00:24:07 +0000567
568 cmplw 0, r3, r4
569 beq 6f
570
571 li r0, 0
5725:
573 stw r0, 0(r3)
574 addi r3, r3, 4
575 cmplw 0, r3, r4
576 blt 5b
5776:
578
579 mr r3, r9 /* Global Data pointer */
580 mr r4, r10 /* Destination Address */
581 bl board_init_r
582
wdenkc6097192002-11-03 00:24:07 +0000583 /*
584 * Copy exception vector code to low memory
585 *
586 * r3: dest_addr
587 * r7: source address, r8: end address, r9: target address
588 */
589 .globl trap_init
590trap_init:
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100591 mflr r4 /* save link register */
592 GET_GOT
wdenkc6097192002-11-03 00:24:07 +0000593 lwz r7, GOT(_start)
594 lwz r8, GOT(_end_of_vectors)
595
wdenk4e112c12003-06-03 23:54:09 +0000596 li r9, 0x100 /* reset vector always at 0x100 */
wdenkc6097192002-11-03 00:24:07 +0000597
598 cmplw 0, r7, r8
599 bgelr /* return if r7>=r8 - just in case */
wdenkc6097192002-11-03 00:24:07 +00006001:
601 lwz r0, 0(r7)
602 stw r0, 0(r9)
603 addi r7, r7, 4
604 addi r9, r9, 4
605 cmplw 0, r7, r8
606 bne 1b
607
608 /*
609 * relocate `hdlr' and `int_return' entries
610 */
611 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
612 li r8, Alignment - _start + EXC_OFF_SYS_RESET
6132:
614 bl trap_reloc
615 addi r7, r7, 0x100 /* next exception vector */
616 cmplw 0, r7, r8
617 blt 2b
618
619 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
620 bl trap_reloc
621
622 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
623 bl trap_reloc
624
625 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
626 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
6273:
628 bl trap_reloc
629 addi r7, r7, 0x100 /* next exception vector */
630 cmplw 0, r7, r8
631 blt 3b
632
633 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
634 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
6354:
636 bl trap_reloc
637 addi r7, r7, 0x100 /* next exception vector */
638 cmplw 0, r7, r8
639 blt 4b
640
641 mtlr r4 /* restore link register */
642 blr
643
wdenkc6097192002-11-03 00:24:07 +0000644 /* Setup the BAT registers.
645 */
646setup_bats:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200647 lis r4, CONFIG_SYS_IBAT0L@h
648 ori r4, r4, CONFIG_SYS_IBAT0L@l
649 lis r3, CONFIG_SYS_IBAT0U@h
650 ori r3, r3, CONFIG_SYS_IBAT0U@l
wdenkc6097192002-11-03 00:24:07 +0000651 mtspr IBAT0L, r4
652 mtspr IBAT0U, r3
653 isync
654
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200655 lis r4, CONFIG_SYS_DBAT0L@h
656 ori r4, r4, CONFIG_SYS_DBAT0L@l
657 lis r3, CONFIG_SYS_DBAT0U@h
658 ori r3, r3, CONFIG_SYS_DBAT0U@l
wdenkc6097192002-11-03 00:24:07 +0000659 mtspr DBAT0L, r4
660 mtspr DBAT0U, r3
661 isync
662
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200663 lis r4, CONFIG_SYS_IBAT1L@h
664 ori r4, r4, CONFIG_SYS_IBAT1L@l
665 lis r3, CONFIG_SYS_IBAT1U@h
666 ori r3, r3, CONFIG_SYS_IBAT1U@l
wdenkc6097192002-11-03 00:24:07 +0000667 mtspr IBAT1L, r4
668 mtspr IBAT1U, r3
669 isync
670
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200671 lis r4, CONFIG_SYS_DBAT1L@h
672 ori r4, r4, CONFIG_SYS_DBAT1L@l
673 lis r3, CONFIG_SYS_DBAT1U@h
674 ori r3, r3, CONFIG_SYS_DBAT1U@l
wdenkc6097192002-11-03 00:24:07 +0000675 mtspr DBAT1L, r4
676 mtspr DBAT1U, r3
677 isync
678
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200679 lis r4, CONFIG_SYS_IBAT2L@h
680 ori r4, r4, CONFIG_SYS_IBAT2L@l
681 lis r3, CONFIG_SYS_IBAT2U@h
682 ori r3, r3, CONFIG_SYS_IBAT2U@l
wdenkc6097192002-11-03 00:24:07 +0000683 mtspr IBAT2L, r4
684 mtspr IBAT2U, r3
685 isync
686
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200687 lis r4, CONFIG_SYS_DBAT2L@h
688 ori r4, r4, CONFIG_SYS_DBAT2L@l
689 lis r3, CONFIG_SYS_DBAT2U@h
690 ori r3, r3, CONFIG_SYS_DBAT2U@l
wdenkc6097192002-11-03 00:24:07 +0000691 mtspr DBAT2L, r4
692 mtspr DBAT2U, r3
693 isync
694
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200695 lis r4, CONFIG_SYS_IBAT3L@h
696 ori r4, r4, CONFIG_SYS_IBAT3L@l
697 lis r3, CONFIG_SYS_IBAT3U@h
698 ori r3, r3, CONFIG_SYS_IBAT3U@l
wdenkc6097192002-11-03 00:24:07 +0000699 mtspr IBAT3L, r4
700 mtspr IBAT3U, r3
701 isync
702
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200703 lis r4, CONFIG_SYS_DBAT3L@h
704 ori r4, r4, CONFIG_SYS_DBAT3L@l
705 lis r3, CONFIG_SYS_DBAT3U@h
706 ori r3, r3, CONFIG_SYS_DBAT3U@l
wdenkc6097192002-11-03 00:24:07 +0000707 mtspr DBAT3L, r4
708 mtspr DBAT3U, r3
709 isync
710
711 /* Invalidate TLBs.
712 * -> for (val = 0; val < 0x20000; val+=0x1000)
713 * -> tlbie(val);
714 */
715 lis r3, 0
716 lis r5, 2
717
7181:
719 tlbie r3
720 addi r3, r3, 0x1000
721 cmp 0, 0, r3, r5
722 blt 1b
723
724 blr