blob: 8b683b1997d3c9a1de7b127d62ea2b1511a406e7 [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>
Peter Tyserd98b0522010-10-14 23:33:24 -050041#include <asm/u-boot.h>
wdenk945af8d2003-07-16 21:53:01 +000042
43#ifndef CONFIG_IDENT_STRING
44#define CONFIG_IDENT_STRING ""
45#endif
46
47/* We don't want the MMU yet.
48*/
49#undef MSR_KERNEL
50/* Floating Point enable, Machine Check and Recoverable Interr. */
51#ifdef DEBUG
52#define MSR_KERNEL (MSR_FP|MSR_RI)
53#else
54#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
55#endif
56
57/*
58 * Set up GOT: Global Offset Table
59 *
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +010060 * Use r12 to access the GOT
wdenk945af8d2003-07-16 21:53:01 +000061 */
62 START_GOT
63 GOT_ENTRY(_GOT2_TABLE_)
64 GOT_ENTRY(_FIXUP_TABLE_)
65
66 GOT_ENTRY(_start)
67 GOT_ENTRY(_start_of_vectors)
68 GOT_ENTRY(_end_of_vectors)
69 GOT_ENTRY(transfer_to_handler)
70
71 GOT_ENTRY(__init_end)
72 GOT_ENTRY(_end)
73 GOT_ENTRY(__bss_start)
74 END_GOT
75
76/*
77 * Version string
78 */
79 .data
80 .globl version_string
81version_string:
82 .ascii U_BOOT_VERSION
Peter Tyser561858e2008-11-03 09:30:59 -060083 .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
wdenk945af8d2003-07-16 21:53:01 +000084 .ascii CONFIG_IDENT_STRING, "\0"
85
86/*
87 * Exception vectors
88 */
89 .text
90 . = EXC_OFF_SYS_RESET
91 .globl _start
92_start:
wdenk945af8d2003-07-16 21:53:01 +000093 mfmsr r5 /* save msr contents */
94
wdenke35745b2004-04-18 23:32:11 +000095 /* Move CSBoot and adjust instruction pointer */
96 /*--------------------------------------------------------------*/
97
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020098#if defined(CONFIG_SYS_LOWBOOT)
99# if defined(CONFIG_SYS_RAMBOOT)
100# error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT
101# endif /* CONFIG_SYS_RAMBOOT */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200102 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
103 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
104 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk79d696f2004-03-11 22:46:36 +0000105 stw r3, 0x4(r4) /* CS0 start */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200106 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
107 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk79d696f2004-03-11 22:46:36 +0000108 stw r3, 0x8(r4) /* CS0 stop */
wdenk5cf9da42003-11-07 13:42:26 +0000109 lis r3, 0x02010000@h
110 ori r3, r3, 0x02010000@l
wdenke35745b2004-04-18 23:32:11 +0000111 stw r3, 0x54(r4) /* CS0 and Boot enable */
wdenk5cf9da42003-11-07 13:42:26 +0000112
wdenke35745b2004-04-18 23:32:11 +0000113 lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
114 ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
wdenk5cf9da42003-11-07 13:42:26 +0000115 mtlr r3
wdenke35745b2004-04-18 23:32:11 +0000116 blr
wdenkd4ca31c2004-01-02 14:00:00 +0000117
118lowboot_reentry:
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200119 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
120 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk79d696f2004-03-11 22:46:36 +0000121 stw r3, 0x4c(r4) /* Boot start */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200122 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
123 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk79d696f2004-03-11 22:46:36 +0000124 stw r3, 0x50(r4) /* Boot stop */
wdenk5cf9da42003-11-07 13:42:26 +0000125 lis r3, 0x02000001@h
126 ori r3, r3, 0x02000001@l
wdenke35745b2004-04-18 23:32:11 +0000127 stw r3, 0x54(r4) /* Boot enable, CS0 disable */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200128#endif /* CONFIG_SYS_LOWBOOT */
wdenkd4ca31c2004-01-02 14:00:00 +0000129
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200130#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
131 lis r3, CONFIG_SYS_MBAR@h
132 ori r3, r3, CONFIG_SYS_MBAR@l
wdenk3c74e322004-02-22 23:46:08 +0000133 /* MBAR is mirrored into the MBAR SPR */
134 mtspr MBAR,r3
wdenk945af8d2003-07-16 21:53:01 +0000135 rlwinm r3, r3, 16, 16, 31
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200136 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
wdenk945af8d2003-07-16 21:53:01 +0000137 stw r3, 0(r4)
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200138#endif /* CONFIG_SYS_DEFAULT_MBAR */
wdenk945af8d2003-07-16 21:53:01 +0000139
140 /* Initialise the MPC5xxx processor core */
141 /*--------------------------------------------------------------*/
142
143 bl init_5xxx_core
144
145 /* initialize some things that are hard to access from C */
146 /*--------------------------------------------------------------*/
147
148 /* set up stack in on-chip SRAM */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200149 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
150 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
151 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
wdenk945af8d2003-07-16 21:53:01 +0000152 li r0, 0 /* Make room for stack frame header and */
153 stwu r0, -4(r1) /* clear final stack frame so that */
154 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
155
156 /* let the C-code set up the rest */
157 /* */
158 /* Be careful to keep code relocatable ! */
159 /*--------------------------------------------------------------*/
160
161 GET_GOT /* initialize GOT access */
162
163 /* r3: IMMR */
164 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
165
wdenk945af8d2003-07-16 21:53:01 +0000166 bl board_init_f /* run 1st part of board init code (in Flash)*/
167
Peter Tyser52ebd9c2010-09-14 19:13:53 -0500168 /* NOTREACHED - board_init_f() does not return */
169
wdenk945af8d2003-07-16 21:53:01 +0000170/*
171 * Vector Table
172 */
173
174 .globl _start_of_vectors
175_start_of_vectors:
176
177/* Machine check */
178 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
179
180/* Data Storage exception. */
181 STD_EXCEPTION(0x300, DataStorage, UnknownException)
182
183/* Instruction Storage exception. */
184 STD_EXCEPTION(0x400, InstStorage, UnknownException)
185
186/* External Interrupt exception. */
187 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
188
189/* Alignment exception. */
190 . = 0x600
191Alignment:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200192 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk945af8d2003-07-16 21:53:01 +0000193 mfspr r4,DAR
194 stw r4,_DAR(r21)
195 mfspr r5,DSISR
196 stw r5,_DSISR(r21)
197 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100198 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenk945af8d2003-07-16 21:53:01 +0000199
200/* Program check exception */
201 . = 0x700
202ProgramCheck:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200203 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk945af8d2003-07-16 21:53:01 +0000204 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100205 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
206 MSR_KERNEL, COPY_EE)
wdenk945af8d2003-07-16 21:53:01 +0000207
208 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
209
210 /* I guess we could implement decrementer, and may have
211 * to someday for timekeeping.
212 */
213 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
214
215 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
216 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk27b207f2003-07-24 23:38:38 +0000217 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk945af8d2003-07-16 21:53:01 +0000218 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
219
220 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
221 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
222
223 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
224 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
225 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
226#ifdef DEBUG
227 . = 0x1300
228 /*
229 * This exception occurs when the program counter matches the
230 * Instruction Address Breakpoint Register (IABR).
231 *
232 * I want the cpu to halt if this occurs so I can hunt around
233 * with the debugger and look at things.
234 *
235 * When DEBUG is defined, both machine check enable (in the MSR)
236 * and checkstop reset enable (in the reset mode register) are
237 * turned off and so a checkstop condition will result in the cpu
238 * halting.
239 *
240 * I force the cpu into a checkstop condition by putting an illegal
241 * instruction here (at least this is the theory).
242 *
243 * well - that didnt work, so just do an infinite loop!
244 */
2451: b 1b
246#else
247 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
248#endif
249 STD_EXCEPTION(0x1400, SMI, UnknownException)
250
251 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
252 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
253 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
254 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
255 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
256 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
257 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
258 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
259 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
260 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
261 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
262 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
263 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
264 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
265 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
266 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
267 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
268 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
269 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
270 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
271 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
272 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
273 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
274 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
275 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
276 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
277 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
278
279
280 .globl _end_of_vectors
281_end_of_vectors:
282
283 . = 0x3000
284
285/*
286 * This code finishes saving the registers to the exception frame
287 * and jumps to the appropriate handler for the exception.
288 * Register r21 is pointer into trap frame, r1 has new stack pointer.
289 */
290 .globl transfer_to_handler
291transfer_to_handler:
292 stw r22,_NIP(r21)
293 lis r22,MSR_POW@h
294 andc r23,r23,r22
295 stw r23,_MSR(r21)
296 SAVE_GPR(7, r21)
297 SAVE_4GPRS(8, r21)
298 SAVE_8GPRS(12, r21)
299 SAVE_8GPRS(24, r21)
300 mflr r23
301 andi. r24,r23,0x3f00 /* get vector offset */
302 stw r24,TRAP(r21)
303 li r22,0
304 stw r22,RESULT(r21)
305 lwz r24,0(r23) /* virtual address of handler */
306 lwz r23,4(r23) /* where to go when done */
307 mtspr SRR0,r24
308 mtspr SRR1,r20
309 mtlr r23
310 SYNC
311 rfi /* jump to handler, enable MMU */
312
313int_return:
314 mfmsr r28 /* Disable interrupts */
315 li r4,0
316 ori r4,r4,MSR_EE
317 andc r28,r28,r4
318 SYNC /* Some chip revs need this... */
319 mtmsr r28
320 SYNC
321 lwz r2,_CTR(r1)
322 lwz r0,_LINK(r1)
323 mtctr r2
324 mtlr r0
325 lwz r2,_XER(r1)
326 lwz r0,_CCR(r1)
327 mtspr XER,r2
328 mtcrf 0xFF,r0
329 REST_10GPRS(3, r1)
330 REST_10GPRS(13, r1)
331 REST_8GPRS(23, r1)
332 REST_GPR(31, r1)
333 lwz r2,_NIP(r1) /* Restore environment */
334 lwz r0,_MSR(r1)
335 mtspr SRR0,r2
336 mtspr SRR1,r0
337 lwz r0,GPR0(r1)
338 lwz r2,GPR2(r1)
339 lwz r1,GPR1(r1)
340 SYNC
341 rfi
342
343/*
344 * This code initialises the MPC5xxx processor core
345 * (conforms to PowerPC 603e spec)
346 * Note: expects original MSR contents to be in r5.
347 */
348
349 .globl init_5xx_core
350init_5xxx_core:
351
352 /* Initialize machine status; enable machine check interrupt */
353 /*--------------------------------------------------------------*/
354
355 li r3, MSR_KERNEL /* Set ME and RI flags */
356 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
357#ifdef DEBUG
358 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
359#endif
360 SYNC /* Some chip revs need this... */
361 mtmsr r3
362 SYNC
363 mtspr SRR1, r3 /* Make SRR1 match MSR */
364
365 /* Initialize the Hardware Implementation-dependent Registers */
366 /* HID0 also contains cache control */
367 /*--------------------------------------------------------------*/
368
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200369 lis r3, CONFIG_SYS_HID0_INIT@h
370 ori r3, r3, CONFIG_SYS_HID0_INIT@l
wdenk945af8d2003-07-16 21:53:01 +0000371 SYNC
372 mtspr HID0, r3
373
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200374 lis r3, CONFIG_SYS_HID0_FINAL@h
375 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
wdenk945af8d2003-07-16 21:53:01 +0000376 SYNC
377 mtspr HID0, r3
378
379 /* clear all BAT's */
380 /*--------------------------------------------------------------*/
381
382 li r0, 0
383 mtspr DBAT0U, r0
384 mtspr DBAT0L, r0
385 mtspr DBAT1U, r0
386 mtspr DBAT1L, r0
387 mtspr DBAT2U, r0
388 mtspr DBAT2L, r0
389 mtspr DBAT3U, r0
390 mtspr DBAT3L, r0
wdenk35656de2003-09-14 19:08:39 +0000391 mtspr DBAT4U, r0
392 mtspr DBAT4L, r0
393 mtspr DBAT5U, r0
394 mtspr DBAT5L, r0
395 mtspr DBAT6U, r0
396 mtspr DBAT6L, r0
397 mtspr DBAT7U, r0
398 mtspr DBAT7L, r0
wdenk945af8d2003-07-16 21:53:01 +0000399 mtspr IBAT0U, r0
400 mtspr IBAT0L, r0
401 mtspr IBAT1U, r0
402 mtspr IBAT1L, r0
403 mtspr IBAT2U, r0
404 mtspr IBAT2L, r0
405 mtspr IBAT3U, r0
406 mtspr IBAT3L, r0
wdenk35656de2003-09-14 19:08:39 +0000407 mtspr IBAT4U, r0
408 mtspr IBAT4L, r0
409 mtspr IBAT5U, r0
410 mtspr IBAT5L, r0
411 mtspr IBAT6U, r0
412 mtspr IBAT6L, r0
413 mtspr IBAT7U, r0
414 mtspr IBAT7L, r0
wdenk945af8d2003-07-16 21:53:01 +0000415 SYNC
416
417 /* invalidate all tlb's */
418 /* */
419 /* From the 603e User Manual: "The 603e provides the ability to */
420 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
421 /* instruction invalidates the TLB entry indexed by the EA, and */
422 /* operates on both the instruction and data TLBs simultaneously*/
423 /* invalidating four TLB entries (both sets in each TLB). The */
424 /* index corresponds to bits 15-19 of the EA. To invalidate all */
425 /* entries within both TLBs, 32 tlbie instructions should be */
426 /* issued, incrementing this field by one each time." */
427 /* */
428 /* "Note that the tlbia instruction is not implemented on the */
429 /* 603e." */
430 /* */
431 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
432 /* incrementing by 0x1000 each time. The code below is sort of */
Stefan Roesea47a12b2010-04-15 16:07:28 +0200433 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
wdenk945af8d2003-07-16 21:53:01 +0000434 /* */
435 /*--------------------------------------------------------------*/
436
437 li r3, 32
438 mtctr r3
439 li r3, 0
4401: tlbie r3
441 addi r3, r3, 0x1000
442 bdnz 1b
443 SYNC
444
445 /* Done! */
446 /*--------------------------------------------------------------*/
447
448 blr
449
450/* Cache functions.
451 *
452 * Note: requires that all cache bits in
453 * HID0 are in the low half word.
454 */
455 .globl icache_enable
456icache_enable:
457 mfspr r3, HID0
458 ori r3, r3, HID0_ICE
459 lis r4, 0
460 ori r4, r4, HID0_ILOCK
461 andc r3, r3, r4
462 ori r4, r3, HID0_ICFI
463 isync
464 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
465 isync
466 mtspr HID0, r3 /* clears invalidate */
467 blr
468
469 .globl icache_disable
470icache_disable:
471 mfspr r3, HID0
472 lis r4, 0
473 ori r4, r4, HID0_ICE|HID0_ILOCK
474 andc r3, r3, r4
475 ori r4, r3, HID0_ICFI
476 isync
477 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
478 isync
479 mtspr HID0, r3 /* clears invalidate */
480 blr
481
482 .globl icache_status
483icache_status:
484 mfspr r3, HID0
485 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
486 blr
487
488 .globl dcache_enable
489dcache_enable:
490 mfspr r3, HID0
491 ori r3, r3, HID0_DCE
492 lis r4, 0
493 ori r4, r4, HID0_DLOCK
494 andc r3, r3, r4
495 ori r4, r3, HID0_DCI
496 sync
497 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
498 sync
499 mtspr HID0, r3 /* clears invalidate */
500 blr
501
502 .globl dcache_disable
503dcache_disable:
504 mfspr r3, HID0
505 lis r4, 0
506 ori r4, r4, HID0_DCE|HID0_DLOCK
507 andc r3, r3, r4
508 ori r4, r3, HID0_DCI
509 sync
510 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
511 sync
512 mtspr HID0, r3 /* clears invalidate */
513 blr
514
515 .globl dcache_status
516dcache_status:
517 mfspr r3, HID0
518 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
519 blr
520
wdenk36c72872004-06-09 17:45:32 +0000521 .globl get_svr
522get_svr:
523 mfspr r3, SVR
524 blr
525
wdenk945af8d2003-07-16 21:53:01 +0000526 .globl get_pvr
527get_pvr:
528 mfspr r3, PVR
529 blr
530
531/*------------------------------------------------------------------------------*/
532
533/*
534 * void relocate_code (addr_sp, gd, addr_moni)
535 *
536 * This "function" does not return, instead it continues in RAM
537 * after relocating the monitor code.
538 *
539 * r3 = dest
540 * r4 = src
541 * r5 = length in bytes
542 * r6 = cachelinesize
543 */
544 .globl relocate_code
545relocate_code:
546 mr r1, r3 /* Set new stack pointer */
547 mr r9, r4 /* Save copy of Global Data pointer */
548 mr r10, r5 /* Save copy of Destination Address */
549
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100550 GET_GOT
wdenk945af8d2003-07-16 21:53:01 +0000551 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200552 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
553 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenk945af8d2003-07-16 21:53:01 +0000554 lwz r5, GOT(__init_end)
555 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200556 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenk945af8d2003-07-16 21:53:01 +0000557
558 /*
559 * Fix GOT pointer:
560 *
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200561 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenk945af8d2003-07-16 21:53:01 +0000562 *
563 * Offset:
564 */
565 sub r15, r10, r4
566
567 /* First our own GOT */
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100568 add r12, r12, r15
wdenk945af8d2003-07-16 21:53:01 +0000569 /* then the one used by the C code */
570 add r30, r30, r15
571
572 /*
573 * Now relocate code
574 */
575
576 cmplw cr1,r3,r4
577 addi r0,r5,3
578 srwi. r0,r0,2
579 beq cr1,4f /* In place copy is not necessary */
580 beq 7f /* Protect against 0 count */
581 mtctr r0
582 bge cr1,2f
583
584 la r8,-4(r4)
585 la r7,-4(r3)
5861: lwzu r0,4(r8)
587 stwu r0,4(r7)
588 bdnz 1b
589 b 4f
590
5912: slwi r0,r0,2
592 add r8,r4,r0
593 add r7,r3,r0
5943: lwzu r0,-4(r8)
595 stwu r0,-4(r7)
596 bdnz 3b
597
598/*
599 * Now flush the cache: note that we must start from a cache aligned
600 * address. Otherwise we might miss one cache line.
601 */
6024: cmpwi r6,0
603 add r5,r3,r5
604 beq 7f /* Always flush prefetch queue in any case */
605 subi r0,r6,1
606 andc r3,r3,r0
607 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
608 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
609 cmpwi r7,0
610 beq 9f
611 mr r4,r3
6125: dcbst 0,r4
613 add r4,r4,r6
614 cmplw r4,r5
615 blt 5b
616 sync /* Wait for all dcbst to complete on bus */
6179: mfspr r7,HID0 /* don't do icbi if icache is disabled */
618 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
619 cmpwi r7,0
620 beq 7f
621 mr r4,r3
6226: icbi 0,r4
623 add r4,r4,r6
624 cmplw r4,r5
625 blt 6b
6267: sync /* Wait for all icbi to complete on bus */
627 isync
628
629/*
630 * We are done. Do not return, instead branch to second part of board
631 * initialization, now running from RAM.
632 */
633
634 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
635 mtlr r0
636 blr
637
638in_ram:
639
640 /*
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100641 * Relocation Function, r12 point to got2+0x8000
wdenk945af8d2003-07-16 21:53:01 +0000642 *
643 * Adjust got2 pointers, no need to check for 0, this code
644 * already puts a few entries in the table.
645 */
646 li r0,__got2_entries@sectoff@l
647 la r3,GOT(_GOT2_TABLE_)
648 lwz r11,GOT(_GOT2_TABLE_)
649 mtctr r0
650 sub r11,r3,r11
651 addi r3,r3,-4
6521: lwzu r0,4(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200653 cmpwi r0,0
654 beq- 2f
wdenk945af8d2003-07-16 21:53:01 +0000655 add r0,r0,r11
656 stw r0,0(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +02006572: bdnz 1b
wdenk945af8d2003-07-16 21:53:01 +0000658
659 /*
660 * Now adjust the fixups and the pointers to the fixups
661 * in case we need to move ourselves again.
662 */
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200663 li r0,__fixup_entries@sectoff@l
wdenk945af8d2003-07-16 21:53:01 +0000664 lwz r3,GOT(_FIXUP_TABLE_)
665 cmpwi r0,0
666 mtctr r0
667 addi r3,r3,-4
668 beq 4f
6693: lwzu r4,4(r3)
670 lwzux r0,r4,r11
671 add r0,r0,r11
672 stw r10,0(r3)
673 stw r0,0(r4)
674 bdnz 3b
6754:
676clear_bss:
677 /*
678 * Now clear BSS segment
679 */
680 lwz r3,GOT(__bss_start)
681 lwz r4,GOT(_end)
682
683 cmplw 0, r3, r4
684 beq 6f
685
686 li r0, 0
6875:
688 stw r0, 0(r3)
689 addi r3, r3, 4
690 cmplw 0, r3, r4
691 bne 5b
6926:
693
694 mr r3, r9 /* Global Data pointer */
695 mr r4, r10 /* Destination Address */
696 bl board_init_r
697
698 /*
699 * Copy exception vector code to low memory
700 *
701 * r3: dest_addr
702 * r7: source address, r8: end address, r9: target address
703 */
704 .globl trap_init
705trap_init:
Joakim Tjernlund0f8aa152010-01-19 14:41:56 +0100706 mflr r4 /* save link register */
707 GET_GOT
wdenk945af8d2003-07-16 21:53:01 +0000708 lwz r7, GOT(_start)
709 lwz r8, GOT(_end_of_vectors)
710
711 li r9, 0x100 /* reset vector always at 0x100 */
712
713 cmplw 0, r7, r8
714 bgelr /* return if r7>=r8 - just in case */
wdenk945af8d2003-07-16 21:53:01 +00007151:
716 lwz r0, 0(r7)
717 stw r0, 0(r9)
718 addi r7, r7, 4
719 addi r9, r9, 4
720 cmplw 0, r7, r8
721 bne 1b
722
723 /*
724 * relocate `hdlr' and `int_return' entries
725 */
726 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
727 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7282:
729 bl trap_reloc
730 addi r7, r7, 0x100 /* next exception vector */
731 cmplw 0, r7, r8
732 blt 2b
733
734 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
735 bl trap_reloc
736
737 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
738 bl trap_reloc
739
740 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
741 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7423:
743 bl trap_reloc
744 addi r7, r7, 0x100 /* next exception vector */
745 cmplw 0, r7, r8
746 blt 3b
747
748 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
749 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7504:
751 bl trap_reloc
752 addi r7, r7, 0x100 /* next exception vector */
753 cmplw 0, r7, r8
754 blt 4b
755
756 mfmsr r3 /* now that the vectors have */
757 lis r7, MSR_IP@h /* relocated into low memory */
758 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
759 andc r3, r3, r7 /* (if it was on) */
760 SYNC /* Some chip revs need this... */
761 mtmsr r3
762 SYNC
763
764 mtlr r4 /* restore link register */
765 blr