blob: 1385869e759bb1165a978c3c633c33c309583194 [file] [log] [blame]
wdenk945af8d2003-07-16 21:53:01 +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 - 2003 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/*
26 * U-Boot - Startup Code for MPC5xxx CPUs
27 */
28#include <config.h>
29#include <mpc5xxx.h>
Peter Tyser561858e2008-11-03 09:30:59 -060030#include <timestamp.h>
wdenk945af8d2003-07-16 21:53:01 +000031#include <version.h>
32
wdenkcbd8a352004-02-24 02:00:03 +000033#define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */
wdenk945af8d2003-07-16 21:53:01 +000034#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
35
36#include <ppc_asm.tmpl>
37#include <ppc_defs.h>
38
39#include <asm/cache.h>
40#include <asm/mmu.h>
41
42#ifndef CONFIG_IDENT_STRING
43#define CONFIG_IDENT_STRING ""
44#endif
45
46/* We don't want the MMU yet.
47*/
48#undef MSR_KERNEL
49/* Floating Point enable, Machine Check and Recoverable Interr. */
50#ifdef DEBUG
51#define MSR_KERNEL (MSR_FP|MSR_RI)
52#else
53#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
54#endif
55
56/*
57 * Set up GOT: Global Offset Table
58 *
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +010059 * Use r12 to access the GOT
wdenk945af8d2003-07-16 21:53:01 +000060 */
61 START_GOT
62 GOT_ENTRY(_GOT2_TABLE_)
63 GOT_ENTRY(_FIXUP_TABLE_)
64
65 GOT_ENTRY(_start)
66 GOT_ENTRY(_start_of_vectors)
67 GOT_ENTRY(_end_of_vectors)
68 GOT_ENTRY(transfer_to_handler)
69
70 GOT_ENTRY(__init_end)
71 GOT_ENTRY(_end)
72 GOT_ENTRY(__bss_start)
73 END_GOT
74
75/*
76 * Version string
77 */
78 .data
79 .globl version_string
80version_string:
81 .ascii U_BOOT_VERSION
Peter Tyser561858e2008-11-03 09:30:59 -060082 .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
wdenk945af8d2003-07-16 21:53:01 +000083 .ascii CONFIG_IDENT_STRING, "\0"
84
85/*
86 * Exception vectors
87 */
88 .text
89 . = EXC_OFF_SYS_RESET
90 .globl _start
91_start:
wdenk945af8d2003-07-16 21:53:01 +000092 mfmsr r5 /* save msr contents */
93
wdenke35745b2004-04-18 23:32:11 +000094 /* Move CSBoot and adjust instruction pointer */
95 /*--------------------------------------------------------------*/
96
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020097#if defined(CONFIG_SYS_LOWBOOT)
98# if defined(CONFIG_SYS_RAMBOOT)
99# error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT
100# endif /* CONFIG_SYS_RAMBOOT */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200101 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
102 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
103 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk79d696f2004-03-11 22:46:36 +0000104 stw r3, 0x4(r4) /* CS0 start */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200105 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
106 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk79d696f2004-03-11 22:46:36 +0000107 stw r3, 0x8(r4) /* CS0 stop */
wdenk5cf9da42003-11-07 13:42:26 +0000108 lis r3, 0x02010000@h
109 ori r3, r3, 0x02010000@l
wdenke35745b2004-04-18 23:32:11 +0000110 stw r3, 0x54(r4) /* CS0 and Boot enable */
wdenk5cf9da42003-11-07 13:42:26 +0000111
wdenke35745b2004-04-18 23:32:11 +0000112 lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
113 ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
wdenk5cf9da42003-11-07 13:42:26 +0000114 mtlr r3
wdenke35745b2004-04-18 23:32:11 +0000115 blr
wdenkd4ca31c2004-01-02 14:00:00 +0000116
117lowboot_reentry:
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200118 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
119 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk79d696f2004-03-11 22:46:36 +0000120 stw r3, 0x4c(r4) /* Boot start */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200121 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
122 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk79d696f2004-03-11 22:46:36 +0000123 stw r3, 0x50(r4) /* Boot stop */
wdenk5cf9da42003-11-07 13:42:26 +0000124 lis r3, 0x02000001@h
125 ori r3, r3, 0x02000001@l
wdenke35745b2004-04-18 23:32:11 +0000126 stw r3, 0x54(r4) /* Boot enable, CS0 disable */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200127#endif /* CONFIG_SYS_LOWBOOT */
wdenkd4ca31c2004-01-02 14:00:00 +0000128
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200129#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
130 lis r3, CONFIG_SYS_MBAR@h
131 ori r3, r3, CONFIG_SYS_MBAR@l
wdenk3c74e322004-02-22 23:46:08 +0000132 /* MBAR is mirrored into the MBAR SPR */
133 mtspr MBAR,r3
wdenk945af8d2003-07-16 21:53:01 +0000134 rlwinm r3, r3, 16, 16, 31
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200135 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
wdenk945af8d2003-07-16 21:53:01 +0000136 stw r3, 0(r4)
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200137#endif /* CONFIG_SYS_DEFAULT_MBAR */
wdenk945af8d2003-07-16 21:53:01 +0000138
139 /* Initialise the MPC5xxx processor core */
140 /*--------------------------------------------------------------*/
141
142 bl init_5xxx_core
143
144 /* initialize some things that are hard to access from C */
145 /*--------------------------------------------------------------*/
146
147 /* set up stack in on-chip SRAM */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200148 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
149 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
150 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
wdenk945af8d2003-07-16 21:53:01 +0000151 li r0, 0 /* Make room for stack frame header and */
152 stwu r0, -4(r1) /* clear final stack frame so that */
153 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
154
155 /* let the C-code set up the rest */
156 /* */
157 /* Be careful to keep code relocatable ! */
158 /*--------------------------------------------------------------*/
159
160 GET_GOT /* initialize GOT access */
161
162 /* r3: IMMR */
163 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
164
wdenk945af8d2003-07-16 21:53:01 +0000165 bl board_init_f /* run 1st part of board init code (in Flash)*/
166
Peter Tyser52ebd9c2010-09-14 19:13:53 -0500167 /* NOTREACHED - board_init_f() does not return */
168
wdenk945af8d2003-07-16 21:53:01 +0000169/*
170 * Vector Table
171 */
172
173 .globl _start_of_vectors
174_start_of_vectors:
175
176/* Machine check */
177 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
178
179/* Data Storage exception. */
180 STD_EXCEPTION(0x300, DataStorage, UnknownException)
181
182/* Instruction Storage exception. */
183 STD_EXCEPTION(0x400, InstStorage, UnknownException)
184
185/* External Interrupt exception. */
186 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
187
188/* Alignment exception. */
189 . = 0x600
190Alignment:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200191 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk945af8d2003-07-16 21:53:01 +0000192 mfspr r4,DAR
193 stw r4,_DAR(r21)
194 mfspr r5,DSISR
195 stw r5,_DSISR(r21)
196 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100197 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenk945af8d2003-07-16 21:53:01 +0000198
199/* Program check exception */
200 . = 0x700
201ProgramCheck:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200202 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk945af8d2003-07-16 21:53:01 +0000203 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100204 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
205 MSR_KERNEL, COPY_EE)
wdenk945af8d2003-07-16 21:53:01 +0000206
207 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
208
209 /* I guess we could implement decrementer, and may have
210 * to someday for timekeeping.
211 */
212 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
213
214 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
215 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk27b207f2003-07-24 23:38:38 +0000216 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk945af8d2003-07-16 21:53:01 +0000217 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
218
219 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
220 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
221
222 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
223 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
224 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
225#ifdef DEBUG
226 . = 0x1300
227 /*
228 * This exception occurs when the program counter matches the
229 * Instruction Address Breakpoint Register (IABR).
230 *
231 * I want the cpu to halt if this occurs so I can hunt around
232 * with the debugger and look at things.
233 *
234 * When DEBUG is defined, both machine check enable (in the MSR)
235 * and checkstop reset enable (in the reset mode register) are
236 * turned off and so a checkstop condition will result in the cpu
237 * halting.
238 *
239 * I force the cpu into a checkstop condition by putting an illegal
240 * instruction here (at least this is the theory).
241 *
242 * well - that didnt work, so just do an infinite loop!
243 */
2441: b 1b
245#else
246 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
247#endif
248 STD_EXCEPTION(0x1400, SMI, UnknownException)
249
250 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
251 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
252 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
253 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
254 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
255 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
256 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
257 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
258 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
259 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
260 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
261 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
262 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
263 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
264 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
265 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
266 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
267 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
268 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
269 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
270 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
271 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
272 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
273 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
274 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
275 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
276 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
277
278
279 .globl _end_of_vectors
280_end_of_vectors:
281
282 . = 0x3000
283
284/*
285 * This code finishes saving the registers to the exception frame
286 * and jumps to the appropriate handler for the exception.
287 * Register r21 is pointer into trap frame, r1 has new stack pointer.
288 */
289 .globl transfer_to_handler
290transfer_to_handler:
291 stw r22,_NIP(r21)
292 lis r22,MSR_POW@h
293 andc r23,r23,r22
294 stw r23,_MSR(r21)
295 SAVE_GPR(7, r21)
296 SAVE_4GPRS(8, r21)
297 SAVE_8GPRS(12, r21)
298 SAVE_8GPRS(24, r21)
299 mflr r23
300 andi. r24,r23,0x3f00 /* get vector offset */
301 stw r24,TRAP(r21)
302 li r22,0
303 stw r22,RESULT(r21)
304 lwz r24,0(r23) /* virtual address of handler */
305 lwz r23,4(r23) /* where to go when done */
306 mtspr SRR0,r24
307 mtspr SRR1,r20
308 mtlr r23
309 SYNC
310 rfi /* jump to handler, enable MMU */
311
312int_return:
313 mfmsr r28 /* Disable interrupts */
314 li r4,0
315 ori r4,r4,MSR_EE
316 andc r28,r28,r4
317 SYNC /* Some chip revs need this... */
318 mtmsr r28
319 SYNC
320 lwz r2,_CTR(r1)
321 lwz r0,_LINK(r1)
322 mtctr r2
323 mtlr r0
324 lwz r2,_XER(r1)
325 lwz r0,_CCR(r1)
326 mtspr XER,r2
327 mtcrf 0xFF,r0
328 REST_10GPRS(3, r1)
329 REST_10GPRS(13, r1)
330 REST_8GPRS(23, r1)
331 REST_GPR(31, r1)
332 lwz r2,_NIP(r1) /* Restore environment */
333 lwz r0,_MSR(r1)
334 mtspr SRR0,r2
335 mtspr SRR1,r0
336 lwz r0,GPR0(r1)
337 lwz r2,GPR2(r1)
338 lwz r1,GPR1(r1)
339 SYNC
340 rfi
341
342/*
343 * This code initialises the MPC5xxx processor core
344 * (conforms to PowerPC 603e spec)
345 * Note: expects original MSR contents to be in r5.
346 */
347
348 .globl init_5xx_core
349init_5xxx_core:
350
351 /* Initialize machine status; enable machine check interrupt */
352 /*--------------------------------------------------------------*/
353
354 li r3, MSR_KERNEL /* Set ME and RI flags */
355 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
356#ifdef DEBUG
357 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
358#endif
359 SYNC /* Some chip revs need this... */
360 mtmsr r3
361 SYNC
362 mtspr SRR1, r3 /* Make SRR1 match MSR */
363
364 /* Initialize the Hardware Implementation-dependent Registers */
365 /* HID0 also contains cache control */
366 /*--------------------------------------------------------------*/
367
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200368 lis r3, CONFIG_SYS_HID0_INIT@h
369 ori r3, r3, CONFIG_SYS_HID0_INIT@l
wdenk945af8d2003-07-16 21:53:01 +0000370 SYNC
371 mtspr HID0, r3
372
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200373 lis r3, CONFIG_SYS_HID0_FINAL@h
374 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
wdenk945af8d2003-07-16 21:53:01 +0000375 SYNC
376 mtspr HID0, r3
377
378 /* clear all BAT's */
379 /*--------------------------------------------------------------*/
380
381 li r0, 0
382 mtspr DBAT0U, r0
383 mtspr DBAT0L, r0
384 mtspr DBAT1U, r0
385 mtspr DBAT1L, r0
386 mtspr DBAT2U, r0
387 mtspr DBAT2L, r0
388 mtspr DBAT3U, r0
389 mtspr DBAT3L, r0
wdenk35656de2003-09-14 19:08:39 +0000390 mtspr DBAT4U, r0
391 mtspr DBAT4L, r0
392 mtspr DBAT5U, r0
393 mtspr DBAT5L, r0
394 mtspr DBAT6U, r0
395 mtspr DBAT6L, r0
396 mtspr DBAT7U, r0
397 mtspr DBAT7L, r0
wdenk945af8d2003-07-16 21:53:01 +0000398 mtspr IBAT0U, r0
399 mtspr IBAT0L, r0
400 mtspr IBAT1U, r0
401 mtspr IBAT1L, r0
402 mtspr IBAT2U, r0
403 mtspr IBAT2L, r0
404 mtspr IBAT3U, r0
405 mtspr IBAT3L, r0
wdenk35656de2003-09-14 19:08:39 +0000406 mtspr IBAT4U, r0
407 mtspr IBAT4L, r0
408 mtspr IBAT5U, r0
409 mtspr IBAT5L, r0
410 mtspr IBAT6U, r0
411 mtspr IBAT6L, r0
412 mtspr IBAT7U, r0
413 mtspr IBAT7L, r0
wdenk945af8d2003-07-16 21:53:01 +0000414 SYNC
415
416 /* invalidate all tlb's */
417 /* */
418 /* From the 603e User Manual: "The 603e provides the ability to */
419 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
420 /* instruction invalidates the TLB entry indexed by the EA, and */
421 /* operates on both the instruction and data TLBs simultaneously*/
422 /* invalidating four TLB entries (both sets in each TLB). The */
423 /* index corresponds to bits 15-19 of the EA. To invalidate all */
424 /* entries within both TLBs, 32 tlbie instructions should be */
425 /* issued, incrementing this field by one each time." */
426 /* */
427 /* "Note that the tlbia instruction is not implemented on the */
428 /* 603e." */
429 /* */
430 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
431 /* incrementing by 0x1000 each time. The code below is sort of */
Stefan Roesea47a12b2010-04-15 16:07:28 +0200432 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
wdenk945af8d2003-07-16 21:53:01 +0000433 /* */
434 /*--------------------------------------------------------------*/
435
436 li r3, 32
437 mtctr r3
438 li r3, 0
4391: tlbie r3
440 addi r3, r3, 0x1000
441 bdnz 1b
442 SYNC
443
444 /* Done! */
445 /*--------------------------------------------------------------*/
446
447 blr
448
449/* Cache functions.
450 *
451 * Note: requires that all cache bits in
452 * HID0 are in the low half word.
453 */
454 .globl icache_enable
455icache_enable:
456 mfspr r3, HID0
457 ori r3, r3, HID0_ICE
458 lis r4, 0
459 ori r4, r4, HID0_ILOCK
460 andc r3, r3, r4
461 ori r4, r3, HID0_ICFI
462 isync
463 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
464 isync
465 mtspr HID0, r3 /* clears invalidate */
466 blr
467
468 .globl icache_disable
469icache_disable:
470 mfspr r3, HID0
471 lis r4, 0
472 ori r4, r4, HID0_ICE|HID0_ILOCK
473 andc r3, r3, r4
474 ori r4, r3, HID0_ICFI
475 isync
476 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
477 isync
478 mtspr HID0, r3 /* clears invalidate */
479 blr
480
481 .globl icache_status
482icache_status:
483 mfspr r3, HID0
484 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
485 blr
486
487 .globl dcache_enable
488dcache_enable:
489 mfspr r3, HID0
490 ori r3, r3, HID0_DCE
491 lis r4, 0
492 ori r4, r4, HID0_DLOCK
493 andc r3, r3, r4
494 ori r4, r3, HID0_DCI
495 sync
496 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
497 sync
498 mtspr HID0, r3 /* clears invalidate */
499 blr
500
501 .globl dcache_disable
502dcache_disable:
503 mfspr r3, HID0
504 lis r4, 0
505 ori r4, r4, HID0_DCE|HID0_DLOCK
506 andc r3, r3, r4
507 ori r4, r3, HID0_DCI
508 sync
509 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
510 sync
511 mtspr HID0, r3 /* clears invalidate */
512 blr
513
514 .globl dcache_status
515dcache_status:
516 mfspr r3, HID0
517 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
518 blr
519
wdenk36c72872004-06-09 17:45:32 +0000520 .globl get_svr
521get_svr:
522 mfspr r3, SVR
523 blr
524
wdenk945af8d2003-07-16 21:53:01 +0000525 .globl get_pvr
526get_pvr:
527 mfspr r3, PVR
528 blr
529
530/*------------------------------------------------------------------------------*/
531
532/*
533 * void relocate_code (addr_sp, gd, addr_moni)
534 *
535 * This "function" does not return, instead it continues in RAM
536 * after relocating the monitor code.
537 *
538 * r3 = dest
539 * r4 = src
540 * r5 = length in bytes
541 * r6 = cachelinesize
542 */
543 .globl relocate_code
544relocate_code:
545 mr r1, r3 /* Set new stack pointer */
546 mr r9, r4 /* Save copy of Global Data pointer */
547 mr r10, r5 /* Save copy of Destination Address */
548
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100549 GET_GOT
wdenk945af8d2003-07-16 21:53:01 +0000550 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200551 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
552 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenk945af8d2003-07-16 21:53:01 +0000553 lwz r5, GOT(__init_end)
554 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200555 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenk945af8d2003-07-16 21:53:01 +0000556
557 /*
558 * Fix GOT pointer:
559 *
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200560 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenk945af8d2003-07-16 21:53:01 +0000561 *
562 * Offset:
563 */
564 sub r15, r10, r4
565
566 /* First our own GOT */
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100567 add r12, r12, r15
wdenk945af8d2003-07-16 21:53:01 +0000568 /* then the one used by the C code */
569 add r30, r30, r15
570
571 /*
572 * Now relocate code
573 */
574
575 cmplw cr1,r3,r4
576 addi r0,r5,3
577 srwi. r0,r0,2
578 beq cr1,4f /* In place copy is not necessary */
579 beq 7f /* Protect against 0 count */
580 mtctr r0
581 bge cr1,2f
582
583 la r8,-4(r4)
584 la r7,-4(r3)
5851: lwzu r0,4(r8)
586 stwu r0,4(r7)
587 bdnz 1b
588 b 4f
589
5902: slwi r0,r0,2
591 add r8,r4,r0
592 add r7,r3,r0
5933: lwzu r0,-4(r8)
594 stwu r0,-4(r7)
595 bdnz 3b
596
597/*
598 * Now flush the cache: note that we must start from a cache aligned
599 * address. Otherwise we might miss one cache line.
600 */
6014: cmpwi r6,0
602 add r5,r3,r5
603 beq 7f /* Always flush prefetch queue in any case */
604 subi r0,r6,1
605 andc r3,r3,r0
606 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
607 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
608 cmpwi r7,0
609 beq 9f
610 mr r4,r3
6115: dcbst 0,r4
612 add r4,r4,r6
613 cmplw r4,r5
614 blt 5b
615 sync /* Wait for all dcbst to complete on bus */
6169: mfspr r7,HID0 /* don't do icbi if icache is disabled */
617 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
618 cmpwi r7,0
619 beq 7f
620 mr r4,r3
6216: icbi 0,r4
622 add r4,r4,r6
623 cmplw r4,r5
624 blt 6b
6257: sync /* Wait for all icbi to complete on bus */
626 isync
627
628/*
629 * We are done. Do not return, instead branch to second part of board
630 * initialization, now running from RAM.
631 */
632
633 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
634 mtlr r0
635 blr
636
637in_ram:
638
639 /*
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100640 * Relocation Function, r12 point to got2+0x8000
wdenk945af8d2003-07-16 21:53:01 +0000641 *
642 * Adjust got2 pointers, no need to check for 0, this code
643 * already puts a few entries in the table.
644 */
645 li r0,__got2_entries@sectoff@l
646 la r3,GOT(_GOT2_TABLE_)
647 lwz r11,GOT(_GOT2_TABLE_)
648 mtctr r0
649 sub r11,r3,r11
650 addi r3,r3,-4
6511: lwzu r0,4(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200652 cmpwi r0,0
653 beq- 2f
wdenk945af8d2003-07-16 21:53:01 +0000654 add r0,r0,r11
655 stw r0,0(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +02006562: bdnz 1b
wdenk945af8d2003-07-16 21:53:01 +0000657
658 /*
659 * Now adjust the fixups and the pointers to the fixups
660 * in case we need to move ourselves again.
661 */
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200662 li r0,__fixup_entries@sectoff@l
wdenk945af8d2003-07-16 21:53:01 +0000663 lwz r3,GOT(_FIXUP_TABLE_)
664 cmpwi r0,0
665 mtctr r0
666 addi r3,r3,-4
667 beq 4f
6683: lwzu r4,4(r3)
669 lwzux r0,r4,r11
670 add r0,r0,r11
671 stw r10,0(r3)
672 stw r0,0(r4)
673 bdnz 3b
6744:
675clear_bss:
676 /*
677 * Now clear BSS segment
678 */
679 lwz r3,GOT(__bss_start)
680 lwz r4,GOT(_end)
681
682 cmplw 0, r3, r4
683 beq 6f
684
685 li r0, 0
6865:
687 stw r0, 0(r3)
688 addi r3, r3, 4
689 cmplw 0, r3, r4
690 bne 5b
6916:
692
693 mr r3, r9 /* Global Data pointer */
694 mr r4, r10 /* Destination Address */
695 bl board_init_r
696
697 /*
698 * Copy exception vector code to low memory
699 *
700 * r3: dest_addr
701 * r7: source address, r8: end address, r9: target address
702 */
703 .globl trap_init
704trap_init:
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100705 mflr r4 /* save link register */
706 GET_GOT
wdenk945af8d2003-07-16 21:53:01 +0000707 lwz r7, GOT(_start)
708 lwz r8, GOT(_end_of_vectors)
709
710 li r9, 0x100 /* reset vector always at 0x100 */
711
712 cmplw 0, r7, r8
713 bgelr /* return if r7>=r8 - just in case */
wdenk945af8d2003-07-16 21:53:01 +00007141:
715 lwz r0, 0(r7)
716 stw r0, 0(r9)
717 addi r7, r7, 4
718 addi r9, r9, 4
719 cmplw 0, r7, r8
720 bne 1b
721
722 /*
723 * relocate `hdlr' and `int_return' entries
724 */
725 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
726 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7272:
728 bl trap_reloc
729 addi r7, r7, 0x100 /* next exception vector */
730 cmplw 0, r7, r8
731 blt 2b
732
733 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
734 bl trap_reloc
735
736 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
737 bl trap_reloc
738
739 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
740 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7413:
742 bl trap_reloc
743 addi r7, r7, 0x100 /* next exception vector */
744 cmplw 0, r7, r8
745 blt 3b
746
747 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
748 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7494:
750 bl trap_reloc
751 addi r7, r7, 0x100 /* next exception vector */
752 cmplw 0, r7, r8
753 blt 4b
754
755 mfmsr r3 /* now that the vectors have */
756 lis r7, MSR_IP@h /* relocated into low memory */
757 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
758 andc r3, r3, r7 /* (if it was on) */
759 SYNC /* Some chip revs need this... */
760 mtmsr r3
761 SYNC
762
763 mtlr r4 /* restore link register */
764 blr