blob: 0b9d89828554eed1f3b054f34825863d781b54f3 [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 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
25/* U-Boot - Startup Code for PowerPC based Embedded Boards
26 *
27 *
28 * The processor starts at 0x00000100 and the code is executed
29 * from flash. The code is organized to be at an other address
30 * in memory, but as long we don't jump around before relocating.
31 * board_init lies at a quite high address and when the cpu has
32 * jumped there, everything is ok.
33 * This works because the cpu gives the FLASH (CS0) the whole
34 * address space at startup, and board_init lies as a echo of
35 * the flash somewhere up there in the memorymap.
36 *
37 * board_init will change CS0 to be positioned at the correct
38 * address and (s)dram will be positioned at address 0
39 */
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +020040#include <asm-offsets.h>
wdenkc6097192002-11-03 00:24:07 +000041#include <config.h>
42#include <mpc824x.h>
43#include <version.h>
44
45#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
46
47#include <ppc_asm.tmpl>
48#include <ppc_defs.h>
49
50#include <asm/cache.h>
51#include <asm/mmu.h>
Peter Tyserd98b0522010-10-14 23:33:24 -050052#include <asm/u-boot.h>
wdenkc6097192002-11-03 00:24:07 +000053
wdenkc6097192002-11-03 00:24:07 +000054/* We don't want the MMU yet.
55*/
56#undef MSR_KERNEL
57/* FP, Machine Check and Recoverable Interr. */
58#define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
59
60/*
61 * Set up GOT: Global Offset Table
62 *
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +010063 * Use r12 to access the GOT
wdenkc6097192002-11-03 00:24:07 +000064 */
65 START_GOT
66 GOT_ENTRY(_GOT2_TABLE_)
67 GOT_ENTRY(_FIXUP_TABLE_)
68
69 GOT_ENTRY(_start)
70 GOT_ENTRY(_start_of_vectors)
71 GOT_ENTRY(_end_of_vectors)
72 GOT_ENTRY(transfer_to_handler)
73
wdenk3b57fe02003-05-30 12:48:29 +000074 GOT_ENTRY(__init_end)
Simon Glass3929fb02013-03-14 06:54:53 +000075 GOT_ENTRY(__bss_end)
wdenk5d232d02003-05-22 22:52:13 +000076 GOT_ENTRY(__bss_start)
wdenkc6097192002-11-03 00:24:07 +000077#if defined(CONFIG_FADS)
78 GOT_ENTRY(environment)
79#endif
80 END_GOT
81
82/*
83 * r3 - 1st arg to board_init(): IMMP pointer
84 * r4 - 2nd arg to board_init(): boot flag
85 */
86 .text
87 .long 0x27051956 /* U-Boot Magic Number */
88 .globl version_string
89version_string:
Andreas Bießmann09c2e902011-07-18 20:24:04 +020090 .ascii U_BOOT_VERSION_STRING, "\0"
wdenkc6097192002-11-03 00:24:07 +000091
92 . = EXC_OFF_SYS_RESET
93 .globl _start
94_start:
wdenkc6097192002-11-03 00:24:07 +000095 /* Initialize machine status; enable machine check interrupt */
96 /*----------------------------------------------------------------------*/
97 li r3, MSR_KERNEL /* Set FP, ME, RI flags */
98 mtmsr r3
99 mtspr SRR1, r3 /* Make SRR1 match MSR */
100
101 addis r0,0,0x0000 /* lets make sure that r0 is really 0 */
102 mtspr HID0, r0 /* disable I and D caches */
103
104 mfspr r3, ICR /* clear Interrupt Cause Register */
105
106 mfmsr r3 /* turn off address translation */
107 addis r4,0,0xffff
108 ori r4,r4,0xffcf
109 and r3,r3,r4
110 mtmsr r3
111 isync
112 sync /* the MMU should be off... */
113
114
115in_flash:
wdenkc6097192002-11-03 00:24:07 +0000116 /*
117 * Setup BATs - cannot be done in C since we don't have a stack yet
118 */
119 bl setup_bats
120
121 /* Enable MMU.
122 */
123 mfmsr r3
124 ori r3, r3, (MSR_IR | MSR_DR)
125 mtmsr r3
Stefan Roesebfa5b712012-09-19 03:18:53 +0000126
wdenkc6097192002-11-03 00:24:07 +0000127 /* Enable and invalidate data cache.
128 */
129 mfspr r3, HID0
130 mr r2, r3
131 ori r3, r3, HID0_DCE | HID0_DCI
132 ori r2, r2, HID0_DCE
133 sync
134 mtspr HID0, r3
135 mtspr HID0, r2
136 sync
137
138 /* Allocate Initial RAM in data cache.
139 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200140 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
141 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
wdenkc6097192002-11-03 00:24:07 +0000142 li r2, 128
143 mtctr r2
1441:
145 dcbz r0, r3
146 addi r3, r3, 32
147 bdnz 1b
148
149 /* Lock way0 in data cache.
150 */
151 mfspr r3, 1011
152 lis r2, 0xffff
153 ori r2, r2, 0xff1f
154 and r3, r3, r2
155 ori r3, r3, 0x0080
156 sync
157 mtspr 1011, r3
Stefan Roesebfa5b712012-09-19 03:18:53 +0000158
wdenkc6097192002-11-03 00:24:07 +0000159 /*
160 * Thisk the stack pointer *somewhere* sensible. Doesnt
161 * matter much where as we'll move it when we relocate
162 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200163 lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
164 ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
wdenkc6097192002-11-03 00:24:07 +0000165
166 li r0, 0 /* Make room for stack frame header and */
167 stwu r0, -4(r1) /* clear final stack frame so that */
168 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
169
170 /* let the C-code set up the rest */
171 /* */
172 /* Be careful to keep code relocatable ! */
173 /*----------------------------------------------------------------------*/
174
175 GET_GOT /* initialize GOT access */
Wolfgang Denk8c4734e2011-04-20 22:11:21 +0200176
wdenkc6097192002-11-03 00:24:07 +0000177 /* r3: IMMR */
178 bl cpu_init_f /* run low-level CPU init code (from Flash) */
179
wdenkc6097192002-11-03 00:24:07 +0000180 bl board_init_f /* run 1st part of board init code (from Flash) */
181
Peter Tyser52ebd9c2010-09-14 19:13:53 -0500182 /* NOTREACHED - board_init_f() does not return */
183
wdenkc6097192002-11-03 00:24:07 +0000184
wdenkc6097192002-11-03 00:24:07 +0000185 .globl _start_of_vectors
186_start_of_vectors:
187
188/* Machine check */
189 STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
190
191/* Data Storage exception. "Never" generated on the 860. */
192 STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
193
194/* Instruction Storage exception. "Never" generated on the 860. */
195 STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
196
197/* External Interrupt exception. */
198 STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
199
200/* Alignment exception. */
201 . = EXC_OFF_ALIGN
202Alignment:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200203 EXCEPTION_PROLOG(SRR0, SRR1)
wdenkc6097192002-11-03 00:24:07 +0000204 mfspr r4,DAR
205 stw r4,_DAR(r21)
206 mfspr r5,DSISR
207 stw r5,_DSISR(r21)
208 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100209 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenkc6097192002-11-03 00:24:07 +0000210
211/* Program check exception */
212 . = EXC_OFF_PROGRAM
213ProgramCheck:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200214 EXCEPTION_PROLOG(SRR0, SRR1)
wdenkc6097192002-11-03 00:24:07 +0000215 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100216 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
217 MSR_KERNEL, COPY_EE)
wdenkc6097192002-11-03 00:24:07 +0000218
219 /* No FPU on MPC8xx. This exception is not supposed to happen.
220 */
221 STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
222
223 /* I guess we could implement decrementer, and may have
224 * to someday for timekeeping.
225 */
226 STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
227 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
228 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk27b207f2003-07-24 23:38:38 +0000229 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenkc6097192002-11-03 00:24:07 +0000230
231 STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
232
233 STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
234 STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
235
236 STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
237 STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
238 STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
wdenk43d96162003-03-06 00:02:04 +0000239 STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, DebugException)
wdenkc6097192002-11-03 00:24:07 +0000240 STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
241 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
242 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
243 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
244 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
245 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
246 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
247 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
248 STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
249 STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
250 STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
251 STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
252
253 STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
254
255 .globl _end_of_vectors
256_end_of_vectors:
257
258
259 . = 0x3000
260
261/*
262 * This code finishes saving the registers to the exception frame
263 * and jumps to the appropriate handler for the exception.
264 * Register r21 is pointer into trap frame, r1 has new stack pointer.
265 */
266 .globl transfer_to_handler
267transfer_to_handler:
268 stw r22,_NIP(r21)
269 lis r22,MSR_POW@h
270 andc r23,r23,r22
271 stw r23,_MSR(r21)
272 SAVE_GPR(7, r21)
273 SAVE_4GPRS(8, r21)
274 SAVE_8GPRS(12, r21)
275 SAVE_8GPRS(24, r21)
276#if 0
277 andi. r23,r23,MSR_PR
278 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
279 beq 2f
280 addi r24,r1,STACK_FRAME_OVERHEAD
281 stw r24,PT_REGS(r23)
2822: addi r2,r23,-TSS /* set r2 to current */
283 tovirt(r2,r2,r23)
284#endif
285 mflr r23
286 andi. r24,r23,0x3f00 /* get vector offset */
287 stw r24,TRAP(r21)
288 li r22,0
289 stw r22,RESULT(r21)
290 mtspr SPRG2,r22 /* r1 is now kernel sp */
291#if 0
292 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
293 cmplw 0,r1,r2
294 cmplw 1,r1,r24
295 crand 1,1,4
296 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
297#endif
298 lwz r24,0(r23) /* virtual address of handler */
299 lwz r23,4(r23) /* where to go when done */
300 mtspr SRR0,r24
301 ori r20,r20,0x30 /* enable IR, DR */
302 mtspr SRR1,r20
303 mtlr r23
304 SYNC
305 rfi /* jump to handler, enable MMU */
306
307int_return:
308 mfmsr r28 /* Disable interrupts */
309 li r4,0
310 ori r4,r4,MSR_EE
311 andc r28,r28,r4
312 SYNC /* Some chip revs need this... */
313 mtmsr r28
314 SYNC
315 lwz r2,_CTR(r1)
316 lwz r0,_LINK(r1)
317 mtctr r2
318 mtlr r0
319 lwz r2,_XER(r1)
320 lwz r0,_CCR(r1)
321 mtspr XER,r2
322 mtcrf 0xFF,r0
323 REST_10GPRS(3, r1)
324 REST_10GPRS(13, r1)
325 REST_8GPRS(23, r1)
326 REST_GPR(31, r1)
327 lwz r2,_NIP(r1) /* Restore environment */
328 lwz r0,_MSR(r1)
329 mtspr SRR0,r2
330 mtspr SRR1,r0
331 lwz r0,GPR0(r1)
332 lwz r2,GPR2(r1)
333 lwz r1,GPR1(r1)
334 SYNC
335 rfi
336
337/* Cache functions.
338*/
339 .globl icache_enable
340icache_enable:
341 mfspr r5,HID0 /* turn on the I cache. */
342 ori r5,r5,0x8800 /* Instruction cache only! */
343 addis r6,0,0xFFFF
344 ori r6,r6,0xF7FF
345 and r6,r5,r6 /* clear the invalidate bit */
346 sync
347 mtspr HID0,r5
348 mtspr HID0,r6
349 isync
350 sync
351 blr
352
353 .globl icache_disable
354icache_disable:
355 mfspr r5,HID0
356 addis r6,0,0xFFFF
357 ori r6,r6,0x7FFF
358 and r5,r5,r6
359 sync
360 mtspr HID0,r5
361 isync
362 sync
363 blr
364
365 .globl icache_status
366icache_status:
367 mfspr r3, HID0
368 srwi r3, r3, 15 /* >>15 & 1=> select bit 16 */
369 andi. r3, r3, 1
370 blr
371
372 .globl dcache_enable
373dcache_enable:
374 mfspr r5,HID0 /* turn on the D cache. */
375 ori r5,r5,0x4400 /* Data cache only! */
376 mfspr r4, PVR /* read PVR */
377 srawi r3, r4, 16 /* shift off the least 16 bits */
378 cmpi 0, 0, r3, 0xC /* Check for Max pvr */
379 bne NotMax
380 ori r5,r5,0x0040 /* setting the DCFA bit, for Max rev 1 errata */
381NotMax:
382 addis r6,0,0xFFFF
383 ori r6,r6,0xFBFF
384 and r6,r5,r6 /* clear the invalidate bit */
385 sync
386 mtspr HID0,r5
387 mtspr HID0,r6
388 isync
389 sync
390 blr
391
392 .globl dcache_disable
393dcache_disable:
394 mfspr r5,HID0
395 addis r6,0,0xFFFF
396 ori r6,r6,0xBFFF
397 and r5,r5,r6
398 sync
399 mtspr HID0,r5
400 isync
401 sync
402 blr
403
404 .globl dcache_status
405dcache_status:
406 mfspr r3, HID0
407 srwi r3, r3, 14 /* >>14 & 1=> select bit 17 */
408 andi. r3, r3, 1
409 blr
410
411 .globl dc_read
412dc_read:
413/*TODO : who uses this, what should it do?
414*/
415 blr
416
417
418 .globl get_pvr
419get_pvr:
420 mfspr r3, PVR
421 blr
422
423
424/*------------------------------------------------------------------------------*/
425
426/*
427 * void relocate_code (addr_sp, gd, addr_moni)
428 *
429 * This "function" does not return, instead it continues in RAM
430 * after relocating the monitor code.
431 *
432 * r3 = dest
433 * r4 = src
434 * r5 = length in bytes
435 * r6 = cachelinesize
436 */
437 .globl relocate_code
438relocate_code:
439
440 mr r1, r3 /* Set new stack pointer */
441 mr r9, r4 /* Save copy of Global Data pointer */
442 mr r10, r5 /* Save copy of Destination Address */
443
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100444 GET_GOT
wdenkc6097192002-11-03 00:24:07 +0000445 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200446#ifdef CONFIG_SYS_RAMBOOT
447 lis r4, CONFIG_SYS_SDRAM_BASE@h /* Source Address */
448 ori r4, r4, CONFIG_SYS_SDRAM_BASE@l
wdenkc6097192002-11-03 00:24:07 +0000449#else
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200450 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
451 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenkc6097192002-11-03 00:24:07 +0000452#endif
wdenk3b57fe02003-05-30 12:48:29 +0000453 lwz r5, GOT(__init_end)
454 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200455 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenkc6097192002-11-03 00:24:07 +0000456
457 /*
458 * Fix GOT pointer:
459 *
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200460 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenkc6097192002-11-03 00:24:07 +0000461 *
462 * Offset:
463 */
464 sub r15, r10, r4
465
466 /* First our own GOT */
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100467 add r12, r12, r15
wdenkc6097192002-11-03 00:24:07 +0000468 /* the the one used by the C code */
469 add r30, r30, r15
470
471 /*
472 * Now relocate code
473 */
474
475 cmplw cr1,r3,r4
476 addi r0,r5,3
477 srwi. r0,r0,2
478 beq cr1,4f /* In place copy is not necessary */
479 beq 7f /* Protect against 0 count */
480 mtctr r0
481 bge cr1,2f
482
483 la r8,-4(r4)
484 la r7,-4(r3)
4851: lwzu r0,4(r8)
486 stwu r0,4(r7)
487 bdnz 1b
488 b 4f
489
4902: slwi r0,r0,2
491 add r8,r4,r0
492 add r7,r3,r0
4933: lwzu r0,-4(r8)
494 stwu r0,-4(r7)
495 bdnz 3b
496
wdenk7205e402003-09-10 22:30:53 +00004974:
wdenk7205e402003-09-10 22:30:53 +0000498/* Unlock the data cache and invalidate locked area */
499 xor r0, r0, r0
500 mtspr 1011, r0
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200501 lis r4, CONFIG_SYS_INIT_RAM_ADDR@h
502 ori r4, r4, CONFIG_SYS_INIT_RAM_ADDR@l
wdenk7205e402003-09-10 22:30:53 +0000503 li r0, 128
504 mtctr r0
50541:
506 dcbi r0, r4
507 addi r4, r4, 32
508 bdnz 41b
wdenk7205e402003-09-10 22:30:53 +0000509
wdenkc6097192002-11-03 00:24:07 +0000510/*
511 * Now flush the cache: note that we must start from a cache aligned
512 * address. Otherwise we might miss one cache line.
513 */
wdenk7205e402003-09-10 22:30:53 +0000514 cmpwi r6,0
wdenkc6097192002-11-03 00:24:07 +0000515 add r5,r3,r5
516 beq 7f /* Always flush prefetch queue in any case */
517 subi r0,r6,1
518 andc r3,r3,r0
519 mr r4,r3
5205: dcbst 0,r4
521 add r4,r4,r6
522 cmplw r4,r5
523 blt 5b
524 sync /* Wait for all dcbst to complete on bus */
525 mr r4,r3
5266: icbi 0,r4
527 add r4,r4,r6
528 cmplw r4,r5
529 blt 6b
5307: sync /* Wait for all icbi to complete on bus */
531 isync
532
533/*
534 * We are done. Do not return, instead branch to second part of board
535 * initialization, now running from RAM.
536 */
537
538 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
539 mtlr r0
540 blr
541
542in_ram:
543
544 /*
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100545 * Relocation Function, r12 point to got2+0x8000
wdenkc6097192002-11-03 00:24:07 +0000546 *
547 * Adjust got2 pointers, no need to check for 0, this code
548 * already puts a few entries in the table.
549 */
550 li r0,__got2_entries@sectoff@l
551 la r3,GOT(_GOT2_TABLE_)
552 lwz r11,GOT(_GOT2_TABLE_)
553 mtctr r0
554 sub r11,r3,r11
555 addi r3,r3,-4
5561: lwzu r0,4(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200557 cmpwi r0,0
558 beq- 2f
wdenkc6097192002-11-03 00:24:07 +0000559 add r0,r0,r11
560 stw r0,0(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +02005612: bdnz 1b
wdenkc6097192002-11-03 00:24:07 +0000562
563 /*
564 * Now adjust the fixups and the pointers to the fixups
565 * in case we need to move ourselves again.
566 */
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200567 li r0,__fixup_entries@sectoff@l
wdenkc6097192002-11-03 00:24:07 +0000568 lwz r3,GOT(_FIXUP_TABLE_)
569 cmpwi r0,0
570 mtctr r0
571 addi r3,r3,-4
572 beq 4f
5733: lwzu r4,4(r3)
574 lwzux r0,r4,r11
Joakim Tjernlundd1e0b102010-10-14 11:51:44 +0200575 cmpwi r0,0
wdenkc6097192002-11-03 00:24:07 +0000576 add r0,r0,r11
Joakim Tjernlund34bbf612010-11-04 19:02:00 +0100577 stw r4,0(r3)
Joakim Tjernlundd1e0b102010-10-14 11:51:44 +0200578 beq- 5f
wdenkc6097192002-11-03 00:24:07 +0000579 stw r0,0(r4)
Joakim Tjernlundd1e0b102010-10-14 11:51:44 +02005805: bdnz 3b
wdenkc6097192002-11-03 00:24:07 +00005814:
582clear_bss:
583 /*
584 * Now clear BSS segment
585 */
wdenk5d232d02003-05-22 22:52:13 +0000586 lwz r3,GOT(__bss_start)
Simon Glass3929fb02013-03-14 06:54:53 +0000587 lwz r4,GOT(__bss_end)
wdenkc6097192002-11-03 00:24:07 +0000588
589 cmplw 0, r3, r4
590 beq 6f
591
592 li r0, 0
5935:
594 stw r0, 0(r3)
595 addi r3, r3, 4
596 cmplw 0, r3, r4
597 blt 5b
5986:
599
600 mr r3, r9 /* Global Data pointer */
601 mr r4, r10 /* Destination Address */
602 bl board_init_r
603
wdenkc6097192002-11-03 00:24:07 +0000604 /*
605 * Copy exception vector code to low memory
606 *
607 * r3: dest_addr
608 * r7: source address, r8: end address, r9: target address
609 */
610 .globl trap_init
611trap_init:
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100612 mflr r4 /* save link register */
613 GET_GOT
wdenkc6097192002-11-03 00:24:07 +0000614 lwz r7, GOT(_start)
615 lwz r8, GOT(_end_of_vectors)
616
wdenk682011f2003-06-03 23:54:09 +0000617 li r9, 0x100 /* reset vector always at 0x100 */
wdenkc6097192002-11-03 00:24:07 +0000618
619 cmplw 0, r7, r8
620 bgelr /* return if r7>=r8 - just in case */
wdenkc6097192002-11-03 00:24:07 +00006211:
622 lwz r0, 0(r7)
623 stw r0, 0(r9)
624 addi r7, r7, 4
625 addi r9, r9, 4
626 cmplw 0, r7, r8
627 bne 1b
628
629 /*
630 * relocate `hdlr' and `int_return' entries
631 */
632 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
633 li r8, Alignment - _start + EXC_OFF_SYS_RESET
6342:
635 bl trap_reloc
636 addi r7, r7, 0x100 /* next exception vector */
637 cmplw 0, r7, r8
638 blt 2b
639
640 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
641 bl trap_reloc
642
643 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
644 bl trap_reloc
645
646 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
647 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
6483:
649 bl trap_reloc
650 addi r7, r7, 0x100 /* next exception vector */
651 cmplw 0, r7, r8
652 blt 3b
653
654 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
655 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
6564:
657 bl trap_reloc
658 addi r7, r7, 0x100 /* next exception vector */
659 cmplw 0, r7, r8
660 blt 4b
661
662 mtlr r4 /* restore link register */
663 blr
664
wdenkc6097192002-11-03 00:24:07 +0000665 /* Setup the BAT registers.
666 */
667setup_bats:
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200668 lis r4, CONFIG_SYS_IBAT0L@h
669 ori r4, r4, CONFIG_SYS_IBAT0L@l
670 lis r3, CONFIG_SYS_IBAT0U@h
671 ori r3, r3, CONFIG_SYS_IBAT0U@l
wdenkc6097192002-11-03 00:24:07 +0000672 mtspr IBAT0L, r4
673 mtspr IBAT0U, r3
674 isync
675
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200676 lis r4, CONFIG_SYS_DBAT0L@h
677 ori r4, r4, CONFIG_SYS_DBAT0L@l
678 lis r3, CONFIG_SYS_DBAT0U@h
679 ori r3, r3, CONFIG_SYS_DBAT0U@l
wdenkc6097192002-11-03 00:24:07 +0000680 mtspr DBAT0L, r4
681 mtspr DBAT0U, r3
682 isync
683
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200684 lis r4, CONFIG_SYS_IBAT1L@h
685 ori r4, r4, CONFIG_SYS_IBAT1L@l
686 lis r3, CONFIG_SYS_IBAT1U@h
687 ori r3, r3, CONFIG_SYS_IBAT1U@l
wdenkc6097192002-11-03 00:24:07 +0000688 mtspr IBAT1L, r4
689 mtspr IBAT1U, r3
690 isync
691
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200692 lis r4, CONFIG_SYS_DBAT1L@h
693 ori r4, r4, CONFIG_SYS_DBAT1L@l
694 lis r3, CONFIG_SYS_DBAT1U@h
695 ori r3, r3, CONFIG_SYS_DBAT1U@l
wdenkc6097192002-11-03 00:24:07 +0000696 mtspr DBAT1L, r4
697 mtspr DBAT1U, r3
698 isync
699
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200700 lis r4, CONFIG_SYS_IBAT2L@h
701 ori r4, r4, CONFIG_SYS_IBAT2L@l
702 lis r3, CONFIG_SYS_IBAT2U@h
703 ori r3, r3, CONFIG_SYS_IBAT2U@l
wdenkc6097192002-11-03 00:24:07 +0000704 mtspr IBAT2L, r4
705 mtspr IBAT2U, r3
706 isync
707
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200708 lis r4, CONFIG_SYS_DBAT2L@h
709 ori r4, r4, CONFIG_SYS_DBAT2L@l
710 lis r3, CONFIG_SYS_DBAT2U@h
711 ori r3, r3, CONFIG_SYS_DBAT2U@l
wdenkc6097192002-11-03 00:24:07 +0000712 mtspr DBAT2L, r4
713 mtspr DBAT2U, r3
714 isync
715
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200716 lis r4, CONFIG_SYS_IBAT3L@h
717 ori r4, r4, CONFIG_SYS_IBAT3L@l
718 lis r3, CONFIG_SYS_IBAT3U@h
719 ori r3, r3, CONFIG_SYS_IBAT3U@l
wdenkc6097192002-11-03 00:24:07 +0000720 mtspr IBAT3L, r4
721 mtspr IBAT3U, r3
722 isync
723
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200724 lis r4, CONFIG_SYS_DBAT3L@h
725 ori r4, r4, CONFIG_SYS_DBAT3L@l
726 lis r3, CONFIG_SYS_DBAT3U@h
727 ori r3, r3, CONFIG_SYS_DBAT3U@l
wdenkc6097192002-11-03 00:24:07 +0000728 mtspr DBAT3L, r4
729 mtspr DBAT3U, r3
730 isync
731
732 /* Invalidate TLBs.
733 * -> for (val = 0; val < 0x20000; val+=0x1000)
734 * -> tlbie(val);
735 */
736 lis r3, 0
737 lis r5, 2
738
7391:
740 tlbie r3
741 addi r3, r3, 0x1000
742 cmp 0, 0, r3, r5
743 blt 1b
744
745 blr