blob: 517b5808fecf00f65091d4d1736cfb0e2d5e6f01 [file] [log] [blame]
wdenk21136db2003-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 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenk21136db2003-07-16 21:53:01 +00007 */
8
9/*
10 * U-Boot - Startup Code for MPC5xxx CPUs
11 */
Wolfgang Denk0191e472010-10-26 14:34:52 +020012#include <asm-offsets.h>
wdenk21136db2003-07-16 21:53:01 +000013#include <config.h>
14#include <mpc5xxx.h>
15#include <version.h>
16
wdenkbe9c1cb2004-02-24 02:00:03 +000017#define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */
wdenk21136db2003-07-16 21:53:01 +000018#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
19
20#include <ppc_asm.tmpl>
21#include <ppc_defs.h>
22
23#include <asm/cache.h>
24#include <asm/mmu.h>
Peter Tyser3a1362d2010-10-14 23:33:24 -050025#include <asm/u-boot.h>
wdenk21136db2003-07-16 21:53:01 +000026
wdenk21136db2003-07-16 21:53:01 +000027/* We don't want the MMU yet.
28*/
29#undef MSR_KERNEL
30/* Floating Point enable, Machine Check and Recoverable Interr. */
31#ifdef DEBUG
32#define MSR_KERNEL (MSR_FP|MSR_RI)
33#else
34#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
35#endif
36
Stefan Roese50b5ac02012-08-16 17:53:18 +020037#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +000038/*
39 * Set up GOT: Global Offset Table
40 *
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +010041 * Use r12 to access the GOT
wdenk21136db2003-07-16 21:53:01 +000042 */
43 START_GOT
44 GOT_ENTRY(_GOT2_TABLE_)
45 GOT_ENTRY(_FIXUP_TABLE_)
46
47 GOT_ENTRY(_start)
48 GOT_ENTRY(_start_of_vectors)
49 GOT_ENTRY(_end_of_vectors)
50 GOT_ENTRY(transfer_to_handler)
51
52 GOT_ENTRY(__init_end)
Simon Glassed70c8f2013-03-14 06:54:53 +000053 GOT_ENTRY(__bss_end)
wdenk21136db2003-07-16 21:53:01 +000054 GOT_ENTRY(__bss_start)
55 END_GOT
Stefan Roese50b5ac02012-08-16 17:53:18 +020056#endif
wdenk21136db2003-07-16 21:53:01 +000057
58/*
59 * Version string
60 */
61 .data
62 .globl version_string
63version_string:
Andreas Bießmann61d01952011-07-18 20:24:04 +020064 .ascii U_BOOT_VERSION_STRING, "\0"
wdenk21136db2003-07-16 21:53:01 +000065
66/*
67 * Exception vectors
68 */
69 .text
70 . = EXC_OFF_SYS_RESET
71 .globl _start
72_start:
Stefan Roese50b5ac02012-08-16 17:53:18 +020073
74#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
75 /*
76 * This is the entry of the real U-Boot from a board port
77 * that supports SPL booting on the MPC5200. We only need
78 * to call board_init_f() here. Everything else has already
79 * been done in the SPL u-boot version.
80 */
81 GET_GOT /* initialize GOT access */
82 bl board_init_f /* run 1st part of board init code (in Flash)*/
83 /* NOTREACHED - board_init_f() does not return */
84#else
wdenk21136db2003-07-16 21:53:01 +000085 mfmsr r5 /* save msr contents */
86
wdenke44b9112004-04-18 23:32:11 +000087 /* Move CSBoot and adjust instruction pointer */
88 /*--------------------------------------------------------------*/
89
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020090#if defined(CONFIG_SYS_LOWBOOT)
91# if defined(CONFIG_SYS_RAMBOOT)
92# error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT
93# endif /* CONFIG_SYS_RAMBOOT */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020094 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
95 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
96 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk0a12b752004-03-11 22:46:36 +000097 stw r3, 0x4(r4) /* CS0 start */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020098 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
99 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk0a12b752004-03-11 22:46:36 +0000100 stw r3, 0x8(r4) /* CS0 stop */
wdenk4b16c2e2003-11-07 13:42:26 +0000101 lis r3, 0x02010000@h
102 ori r3, r3, 0x02010000@l
wdenke44b9112004-04-18 23:32:11 +0000103 stw r3, 0x54(r4) /* CS0 and Boot enable */
wdenk4b16c2e2003-11-07 13:42:26 +0000104
wdenke44b9112004-04-18 23:32:11 +0000105 lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
106 ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
wdenk4b16c2e2003-11-07 13:42:26 +0000107 mtlr r3
wdenke44b9112004-04-18 23:32:11 +0000108 blr
wdenk1ebf41e2004-01-02 14:00:00 +0000109
110lowboot_reentry:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200111 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
112 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk0a12b752004-03-11 22:46:36 +0000113 stw r3, 0x4c(r4) /* Boot start */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200114 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
115 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk0a12b752004-03-11 22:46:36 +0000116 stw r3, 0x50(r4) /* Boot stop */
wdenk4b16c2e2003-11-07 13:42:26 +0000117 lis r3, 0x02000001@h
118 ori r3, r3, 0x02000001@l
wdenke44b9112004-04-18 23:32:11 +0000119 stw r3, 0x54(r4) /* Boot enable, CS0 disable */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200120#endif /* CONFIG_SYS_LOWBOOT */
wdenk1ebf41e2004-01-02 14:00:00 +0000121
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200122#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
123 lis r3, CONFIG_SYS_MBAR@h
124 ori r3, r3, CONFIG_SYS_MBAR@l
wdenk56ed43e2004-02-22 23:46:08 +0000125 /* MBAR is mirrored into the MBAR SPR */
126 mtspr MBAR,r3
wdenk21136db2003-07-16 21:53:01 +0000127 rlwinm r3, r3, 16, 16, 31
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200128 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
wdenk21136db2003-07-16 21:53:01 +0000129 stw r3, 0(r4)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200130#endif /* CONFIG_SYS_DEFAULT_MBAR */
wdenk21136db2003-07-16 21:53:01 +0000131
132 /* Initialise the MPC5xxx processor core */
133 /*--------------------------------------------------------------*/
134
135 bl init_5xxx_core
136
137 /* initialize some things that are hard to access from C */
138 /*--------------------------------------------------------------*/
139
140 /* set up stack in on-chip SRAM */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200141 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
142 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
143 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
wdenk21136db2003-07-16 21:53:01 +0000144 li r0, 0 /* Make room for stack frame header and */
145 stwu r0, -4(r1) /* clear final stack frame so that */
146 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
147
148 /* let the C-code set up the rest */
149 /* */
150 /* Be careful to keep code relocatable ! */
151 /*--------------------------------------------------------------*/
152
Stefan Roese50b5ac02012-08-16 17:53:18 +0200153#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +0000154 GET_GOT /* initialize GOT access */
Stefan Roese50b5ac02012-08-16 17:53:18 +0200155#endif
Wolfgang Denkb2d36ea2011-04-20 22:11:21 +0200156
wdenk21136db2003-07-16 21:53:01 +0000157 /* r3: IMMR */
158 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
159
wdenk21136db2003-07-16 21:53:01 +0000160 bl board_init_f /* run 1st part of board init code (in Flash)*/
161
Peter Tyser0c44caf2010-09-14 19:13:53 -0500162 /* NOTREACHED - board_init_f() does not return */
Stefan Roese50b5ac02012-08-16 17:53:18 +0200163#endif
Peter Tyser0c44caf2010-09-14 19:13:53 -0500164
Stefan Roese50b5ac02012-08-16 17:53:18 +0200165#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +0000166/*
167 * Vector Table
168 */
169
170 .globl _start_of_vectors
171_start_of_vectors:
172
173/* Machine check */
174 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
175
176/* Data Storage exception. */
177 STD_EXCEPTION(0x300, DataStorage, UnknownException)
178
179/* Instruction Storage exception. */
180 STD_EXCEPTION(0x400, InstStorage, UnknownException)
181
182/* External Interrupt exception. */
183 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
184
185/* Alignment exception. */
186 . = 0x600
187Alignment:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200188 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk21136db2003-07-16 21:53:01 +0000189 mfspr r4,DAR
190 stw r4,_DAR(r21)
191 mfspr r5,DSISR
192 stw r5,_DSISR(r21)
193 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100194 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenk21136db2003-07-16 21:53:01 +0000195
196/* Program check exception */
197 . = 0x700
198ProgramCheck:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200199 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk21136db2003-07-16 21:53:01 +0000200 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100201 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
202 MSR_KERNEL, COPY_EE)
wdenk21136db2003-07-16 21:53:01 +0000203
204 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
205
206 /* I guess we could implement decrementer, and may have
207 * to someday for timekeeping.
208 */
209 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
210
211 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
212 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000213 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk21136db2003-07-16 21:53:01 +0000214 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
215
216 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
217 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
218
219 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
220 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
221 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
222#ifdef DEBUG
223 . = 0x1300
224 /*
225 * This exception occurs when the program counter matches the
226 * Instruction Address Breakpoint Register (IABR).
227 *
228 * I want the cpu to halt if this occurs so I can hunt around
229 * with the debugger and look at things.
230 *
231 * When DEBUG is defined, both machine check enable (in the MSR)
232 * and checkstop reset enable (in the reset mode register) are
233 * turned off and so a checkstop condition will result in the cpu
234 * halting.
235 *
236 * I force the cpu into a checkstop condition by putting an illegal
237 * instruction here (at least this is the theory).
238 *
239 * well - that didnt work, so just do an infinite loop!
240 */
2411: b 1b
242#else
243 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
244#endif
245 STD_EXCEPTION(0x1400, SMI, UnknownException)
246
247 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
248 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
249 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
250 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
251 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
252 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
253 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
254 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
255 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
256 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
257 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
258 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
259 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
260 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
261 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
262 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
263 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
264 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
265 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
266 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
267 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
268 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
269 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
270 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
271 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
272 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
273 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
274
275
276 .globl _end_of_vectors
277_end_of_vectors:
278
279 . = 0x3000
280
281/*
282 * This code finishes saving the registers to the exception frame
283 * and jumps to the appropriate handler for the exception.
284 * Register r21 is pointer into trap frame, r1 has new stack pointer.
285 */
286 .globl transfer_to_handler
287transfer_to_handler:
288 stw r22,_NIP(r21)
289 lis r22,MSR_POW@h
290 andc r23,r23,r22
291 stw r23,_MSR(r21)
292 SAVE_GPR(7, r21)
293 SAVE_4GPRS(8, r21)
294 SAVE_8GPRS(12, r21)
295 SAVE_8GPRS(24, r21)
296 mflr r23
297 andi. r24,r23,0x3f00 /* get vector offset */
298 stw r24,TRAP(r21)
299 li r22,0
300 stw r22,RESULT(r21)
301 lwz r24,0(r23) /* virtual address of handler */
302 lwz r23,4(r23) /* where to go when done */
303 mtspr SRR0,r24
304 mtspr SRR1,r20
305 mtlr r23
306 SYNC
307 rfi /* jump to handler, enable MMU */
308
309int_return:
310 mfmsr r28 /* Disable interrupts */
311 li r4,0
312 ori r4,r4,MSR_EE
313 andc r28,r28,r4
314 SYNC /* Some chip revs need this... */
315 mtmsr r28
316 SYNC
317 lwz r2,_CTR(r1)
318 lwz r0,_LINK(r1)
319 mtctr r2
320 mtlr r0
321 lwz r2,_XER(r1)
322 lwz r0,_CCR(r1)
323 mtspr XER,r2
324 mtcrf 0xFF,r0
325 REST_10GPRS(3, r1)
326 REST_10GPRS(13, r1)
327 REST_8GPRS(23, r1)
328 REST_GPR(31, r1)
329 lwz r2,_NIP(r1) /* Restore environment */
330 lwz r0,_MSR(r1)
331 mtspr SRR0,r2
332 mtspr SRR1,r0
333 lwz r0,GPR0(r1)
334 lwz r2,GPR2(r1)
335 lwz r1,GPR1(r1)
336 SYNC
337 rfi
Stefan Roese50b5ac02012-08-16 17:53:18 +0200338#endif /* CONFIG_SPL_BUILD */
wdenk21136db2003-07-16 21:53:01 +0000339
340/*
341 * This code initialises the MPC5xxx processor core
342 * (conforms to PowerPC 603e spec)
343 * Note: expects original MSR contents to be in r5.
344 */
345
346 .globl init_5xx_core
347init_5xxx_core:
348
349 /* Initialize machine status; enable machine check interrupt */
350 /*--------------------------------------------------------------*/
351
352 li r3, MSR_KERNEL /* Set ME and RI flags */
353 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
354#ifdef DEBUG
355 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
356#endif
357 SYNC /* Some chip revs need this... */
358 mtmsr r3
359 SYNC
360 mtspr SRR1, r3 /* Make SRR1 match MSR */
361
362 /* Initialize the Hardware Implementation-dependent Registers */
363 /* HID0 also contains cache control */
364 /*--------------------------------------------------------------*/
365
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200366 lis r3, CONFIG_SYS_HID0_INIT@h
367 ori r3, r3, CONFIG_SYS_HID0_INIT@l
wdenk21136db2003-07-16 21:53:01 +0000368 SYNC
369 mtspr HID0, r3
370
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200371 lis r3, CONFIG_SYS_HID0_FINAL@h
372 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
wdenk21136db2003-07-16 21:53:01 +0000373 SYNC
374 mtspr HID0, r3
375
376 /* clear all BAT's */
377 /*--------------------------------------------------------------*/
378
379 li r0, 0
380 mtspr DBAT0U, r0
381 mtspr DBAT0L, r0
382 mtspr DBAT1U, r0
383 mtspr DBAT1L, r0
384 mtspr DBAT2U, r0
385 mtspr DBAT2L, r0
386 mtspr DBAT3U, r0
387 mtspr DBAT3L, r0
wdenkfc314ce2003-09-14 19:08:39 +0000388 mtspr DBAT4U, r0
389 mtspr DBAT4L, r0
390 mtspr DBAT5U, r0
391 mtspr DBAT5L, r0
392 mtspr DBAT6U, r0
393 mtspr DBAT6L, r0
394 mtspr DBAT7U, r0
395 mtspr DBAT7L, r0
wdenk21136db2003-07-16 21:53:01 +0000396 mtspr IBAT0U, r0
397 mtspr IBAT0L, r0
398 mtspr IBAT1U, r0
399 mtspr IBAT1L, r0
400 mtspr IBAT2U, r0
401 mtspr IBAT2L, r0
402 mtspr IBAT3U, r0
403 mtspr IBAT3L, r0
wdenkfc314ce2003-09-14 19:08:39 +0000404 mtspr IBAT4U, r0
405 mtspr IBAT4L, r0
406 mtspr IBAT5U, r0
407 mtspr IBAT5L, r0
408 mtspr IBAT6U, r0
409 mtspr IBAT6L, r0
410 mtspr IBAT7U, r0
411 mtspr IBAT7L, r0
wdenk21136db2003-07-16 21:53:01 +0000412 SYNC
413
414 /* invalidate all tlb's */
415 /* */
416 /* From the 603e User Manual: "The 603e provides the ability to */
417 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
418 /* instruction invalidates the TLB entry indexed by the EA, and */
419 /* operates on both the instruction and data TLBs simultaneously*/
420 /* invalidating four TLB entries (both sets in each TLB). The */
421 /* index corresponds to bits 15-19 of the EA. To invalidate all */
422 /* entries within both TLBs, 32 tlbie instructions should be */
423 /* issued, incrementing this field by one each time." */
424 /* */
425 /* "Note that the tlbia instruction is not implemented on the */
426 /* 603e." */
427 /* */
428 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
429 /* incrementing by 0x1000 each time. The code below is sort of */
Stefan Roese88fbf932010-04-15 16:07:28 +0200430 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
wdenk21136db2003-07-16 21:53:01 +0000431 /* */
432 /*--------------------------------------------------------------*/
433
434 li r3, 32
435 mtctr r3
436 li r3, 0
4371: tlbie r3
438 addi r3, r3, 0x1000
439 bdnz 1b
440 SYNC
441
442 /* Done! */
443 /*--------------------------------------------------------------*/
444
445 blr
446
447/* Cache functions.
448 *
449 * Note: requires that all cache bits in
450 * HID0 are in the low half word.
451 */
452 .globl icache_enable
453icache_enable:
454 mfspr r3, HID0
455 ori r3, r3, HID0_ICE
456 lis r4, 0
457 ori r4, r4, HID0_ILOCK
458 andc r3, r3, r4
459 ori r4, r3, HID0_ICFI
460 isync
461 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
462 isync
463 mtspr HID0, r3 /* clears invalidate */
464 blr
465
466 .globl icache_disable
467icache_disable:
468 mfspr r3, HID0
469 lis r4, 0
470 ori r4, r4, HID0_ICE|HID0_ILOCK
471 andc r3, r3, r4
472 ori r4, r3, HID0_ICFI
473 isync
474 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
475 isync
476 mtspr HID0, r3 /* clears invalidate */
477 blr
478
479 .globl icache_status
480icache_status:
481 mfspr r3, HID0
482 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
483 blr
484
485 .globl dcache_enable
486dcache_enable:
487 mfspr r3, HID0
488 ori r3, r3, HID0_DCE
489 lis r4, 0
490 ori r4, r4, HID0_DLOCK
491 andc r3, r3, r4
492 ori r4, r3, HID0_DCI
493 sync
494 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
495 sync
496 mtspr HID0, r3 /* clears invalidate */
497 blr
498
499 .globl dcache_disable
500dcache_disable:
501 mfspr r3, HID0
502 lis r4, 0
503 ori r4, r4, HID0_DCE|HID0_DLOCK
504 andc r3, r3, r4
505 ori r4, r3, HID0_DCI
506 sync
507 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
508 sync
509 mtspr HID0, r3 /* clears invalidate */
510 blr
511
512 .globl dcache_status
513dcache_status:
514 mfspr r3, HID0
515 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
516 blr
517
wdenk2d644822004-06-09 17:45:32 +0000518 .globl get_svr
519get_svr:
520 mfspr r3, SVR
521 blr
522
wdenk21136db2003-07-16 21:53:01 +0000523 .globl get_pvr
524get_pvr:
525 mfspr r3, PVR
526 blr
527
Stefan Roese50b5ac02012-08-16 17:53:18 +0200528#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +0000529/*------------------------------------------------------------------------------*/
530
531/*
532 * void relocate_code (addr_sp, gd, addr_moni)
533 *
534 * This "function" does not return, instead it continues in RAM
535 * after relocating the monitor code.
536 *
537 * r3 = dest
538 * r4 = src
539 * r5 = length in bytes
540 * r6 = cachelinesize
541 */
542 .globl relocate_code
543relocate_code:
544 mr r1, r3 /* Set new stack pointer */
545 mr r9, r4 /* Save copy of Global Data pointer */
546 mr r10, r5 /* Save copy of Destination Address */
547
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100548 GET_GOT
wdenk21136db2003-07-16 21:53:01 +0000549 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200550 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
551 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenk21136db2003-07-16 21:53:01 +0000552 lwz r5, GOT(__init_end)
553 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200554 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenk21136db2003-07-16 21:53:01 +0000555
556 /*
557 * Fix GOT pointer:
558 *
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200559 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenk21136db2003-07-16 21:53:01 +0000560 *
561 * Offset:
562 */
563 sub r15, r10, r4
564
565 /* First our own GOT */
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100566 add r12, r12, r15
wdenk21136db2003-07-16 21:53:01 +0000567 /* then the one used by the C code */
568 add r30, r30, r15
569
570 /*
571 * Now relocate code
572 */
573
574 cmplw cr1,r3,r4
575 addi r0,r5,3
576 srwi. r0,r0,2
577 beq cr1,4f /* In place copy is not necessary */
578 beq 7f /* Protect against 0 count */
579 mtctr r0
580 bge cr1,2f
581
582 la r8,-4(r4)
583 la r7,-4(r3)
5841: lwzu r0,4(r8)
585 stwu r0,4(r7)
586 bdnz 1b
587 b 4f
588
5892: slwi r0,r0,2
590 add r8,r4,r0
591 add r7,r3,r0
5923: lwzu r0,-4(r8)
593 stwu r0,-4(r7)
594 bdnz 3b
595
596/*
597 * Now flush the cache: note that we must start from a cache aligned
598 * address. Otherwise we might miss one cache line.
599 */
6004: cmpwi r6,0
601 add r5,r3,r5
602 beq 7f /* Always flush prefetch queue in any case */
603 subi r0,r6,1
604 andc r3,r3,r0
605 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
606 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
607 cmpwi r7,0
608 beq 9f
609 mr r4,r3
6105: dcbst 0,r4
611 add r4,r4,r6
612 cmplw r4,r5
613 blt 5b
614 sync /* Wait for all dcbst to complete on bus */
6159: mfspr r7,HID0 /* don't do icbi if icache is disabled */
616 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
617 cmpwi r7,0
618 beq 7f
619 mr r4,r3
6206: icbi 0,r4
621 add r4,r4,r6
622 cmplw r4,r5
623 blt 6b
6247: sync /* Wait for all icbi to complete on bus */
625 isync
626
627/*
628 * We are done. Do not return, instead branch to second part of board
629 * initialization, now running from RAM.
630 */
631
632 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
633 mtlr r0
634 blr
635
636in_ram:
637
638 /*
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100639 * Relocation Function, r12 point to got2+0x8000
wdenk21136db2003-07-16 21:53:01 +0000640 *
641 * Adjust got2 pointers, no need to check for 0, this code
642 * already puts a few entries in the table.
643 */
644 li r0,__got2_entries@sectoff@l
645 la r3,GOT(_GOT2_TABLE_)
646 lwz r11,GOT(_GOT2_TABLE_)
647 mtctr r0
648 sub r11,r3,r11
649 addi r3,r3,-4
6501: lwzu r0,4(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200651 cmpwi r0,0
652 beq- 2f
wdenk21136db2003-07-16 21:53:01 +0000653 add r0,r0,r11
654 stw r0,0(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +02006552: bdnz 1b
wdenk21136db2003-07-16 21:53:01 +0000656
657 /*
658 * Now adjust the fixups and the pointers to the fixups
659 * in case we need to move ourselves again.
660 */
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200661 li r0,__fixup_entries@sectoff@l
wdenk21136db2003-07-16 21:53:01 +0000662 lwz r3,GOT(_FIXUP_TABLE_)
663 cmpwi r0,0
664 mtctr r0
665 addi r3,r3,-4
666 beq 4f
6673: lwzu r4,4(r3)
668 lwzux r0,r4,r11
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200669 cmpwi r0,0
wdenk21136db2003-07-16 21:53:01 +0000670 add r0,r0,r11
Joakim Tjernlund401b5922010-11-04 19:02:00 +0100671 stw r4,0(r3)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200672 beq- 5f
wdenk21136db2003-07-16 21:53:01 +0000673 stw r0,0(r4)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +02006745: bdnz 3b
wdenk21136db2003-07-16 21:53:01 +00006754:
676clear_bss:
677 /*
678 * Now clear BSS segment
679 */
680 lwz r3,GOT(__bss_start)
Simon Glassed70c8f2013-03-14 06:54:53 +0000681 lwz r4,GOT(__bss_end)
wdenk21136db2003-07-16 21:53:01 +0000682
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 Tjernlund3fbaa4d2010-01-19 14:41:56 +0100706 mflr r4 /* save link register */
707 GET_GOT
wdenk21136db2003-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 */
wdenk21136db2003-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
Stefan Roese50b5ac02012-08-16 17:53:18 +0200766
767#endif /* CONFIG_SPL_BUILD */