blob: 84ab41e931eeee04f5ff24f995b357260097b018 [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
19#include <ppc_asm.tmpl>
20#include <ppc_defs.h>
21
22#include <asm/cache.h>
23#include <asm/mmu.h>
Peter Tyser3a1362d2010-10-14 23:33:24 -050024#include <asm/u-boot.h>
wdenk21136db2003-07-16 21:53:01 +000025
wdenk21136db2003-07-16 21:53:01 +000026/* We don't want the MMU yet.
27*/
28#undef MSR_KERNEL
29/* Floating Point enable, Machine Check and Recoverable Interr. */
30#ifdef DEBUG
31#define MSR_KERNEL (MSR_FP|MSR_RI)
32#else
33#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
34#endif
35
Stefan Roese50b5ac02012-08-16 17:53:18 +020036#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +000037/*
38 * Set up GOT: Global Offset Table
39 *
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +010040 * Use r12 to access the GOT
wdenk21136db2003-07-16 21:53:01 +000041 */
42 START_GOT
43 GOT_ENTRY(_GOT2_TABLE_)
44 GOT_ENTRY(_FIXUP_TABLE_)
45
46 GOT_ENTRY(_start)
47 GOT_ENTRY(_start_of_vectors)
48 GOT_ENTRY(_end_of_vectors)
49 GOT_ENTRY(transfer_to_handler)
50
51 GOT_ENTRY(__init_end)
Simon Glassed70c8f2013-03-14 06:54:53 +000052 GOT_ENTRY(__bss_end)
wdenk21136db2003-07-16 21:53:01 +000053 GOT_ENTRY(__bss_start)
54 END_GOT
Stefan Roese50b5ac02012-08-16 17:53:18 +020055#endif
wdenk21136db2003-07-16 21:53:01 +000056
57/*
58 * Version string
59 */
60 .data
61 .globl version_string
62version_string:
Andreas Bießmann61d01952011-07-18 20:24:04 +020063 .ascii U_BOOT_VERSION_STRING, "\0"
wdenk21136db2003-07-16 21:53:01 +000064
65/*
66 * Exception vectors
67 */
68 .text
69 . = EXC_OFF_SYS_RESET
70 .globl _start
71_start:
Stefan Roese50b5ac02012-08-16 17:53:18 +020072
73#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
74 /*
75 * This is the entry of the real U-Boot from a board port
76 * that supports SPL booting on the MPC5200. We only need
77 * to call board_init_f() here. Everything else has already
78 * been done in the SPL u-boot version.
79 */
80 GET_GOT /* initialize GOT access */
81 bl board_init_f /* run 1st part of board init code (in Flash)*/
82 /* NOTREACHED - board_init_f() does not return */
83#else
wdenk21136db2003-07-16 21:53:01 +000084 mfmsr r5 /* save msr contents */
85
wdenke44b9112004-04-18 23:32:11 +000086 /* Move CSBoot and adjust instruction pointer */
87 /*--------------------------------------------------------------*/
88
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020089#if defined(CONFIG_SYS_LOWBOOT)
90# if defined(CONFIG_SYS_RAMBOOT)
91# error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT
92# endif /* CONFIG_SYS_RAMBOOT */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020093 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
94 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
95 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk0a12b752004-03-11 22:46:36 +000096 stw r3, 0x4(r4) /* CS0 start */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020097 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
98 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk0a12b752004-03-11 22:46:36 +000099 stw r3, 0x8(r4) /* CS0 stop */
wdenk4b16c2e2003-11-07 13:42:26 +0000100 lis r3, 0x02010000@h
101 ori r3, r3, 0x02010000@l
wdenke44b9112004-04-18 23:32:11 +0000102 stw r3, 0x54(r4) /* CS0 and Boot enable */
wdenk4b16c2e2003-11-07 13:42:26 +0000103
wdenke44b9112004-04-18 23:32:11 +0000104 lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
105 ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
wdenk4b16c2e2003-11-07 13:42:26 +0000106 mtlr r3
wdenke44b9112004-04-18 23:32:11 +0000107 blr
wdenk1ebf41e2004-01-02 14:00:00 +0000108
109lowboot_reentry:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200110 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
111 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
wdenk0a12b752004-03-11 22:46:36 +0000112 stw r3, 0x4c(r4) /* Boot start */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200113 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
114 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
wdenk0a12b752004-03-11 22:46:36 +0000115 stw r3, 0x50(r4) /* Boot stop */
wdenk4b16c2e2003-11-07 13:42:26 +0000116 lis r3, 0x02000001@h
117 ori r3, r3, 0x02000001@l
wdenke44b9112004-04-18 23:32:11 +0000118 stw r3, 0x54(r4) /* Boot enable, CS0 disable */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200119#endif /* CONFIG_SYS_LOWBOOT */
wdenk1ebf41e2004-01-02 14:00:00 +0000120
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200121#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
122 lis r3, CONFIG_SYS_MBAR@h
123 ori r3, r3, CONFIG_SYS_MBAR@l
wdenk56ed43e2004-02-22 23:46:08 +0000124 /* MBAR is mirrored into the MBAR SPR */
125 mtspr MBAR,r3
wdenk21136db2003-07-16 21:53:01 +0000126 rlwinm r3, r3, 16, 16, 31
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200127 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
wdenk21136db2003-07-16 21:53:01 +0000128 stw r3, 0(r4)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200129#endif /* CONFIG_SYS_DEFAULT_MBAR */
wdenk21136db2003-07-16 21:53:01 +0000130
131 /* Initialise the MPC5xxx processor core */
132 /*--------------------------------------------------------------*/
133
134 bl init_5xxx_core
135
136 /* initialize some things that are hard to access from C */
137 /*--------------------------------------------------------------*/
138
139 /* set up stack in on-chip SRAM */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200140 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
141 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
142 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
wdenk21136db2003-07-16 21:53:01 +0000143 li r0, 0 /* Make room for stack frame header and */
144 stwu r0, -4(r1) /* clear final stack frame so that */
145 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
146
147 /* let the C-code set up the rest */
148 /* */
149 /* Be careful to keep code relocatable ! */
150 /*--------------------------------------------------------------*/
151
Stefan Roese50b5ac02012-08-16 17:53:18 +0200152#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +0000153 GET_GOT /* initialize GOT access */
Stefan Roese50b5ac02012-08-16 17:53:18 +0200154#endif
Wolfgang Denkb2d36ea2011-04-20 22:11:21 +0200155
wdenk21136db2003-07-16 21:53:01 +0000156 /* r3: IMMR */
157 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
158
wdenk21136db2003-07-16 21:53:01 +0000159 bl board_init_f /* run 1st part of board init code (in Flash)*/
160
Peter Tyser0c44caf2010-09-14 19:13:53 -0500161 /* NOTREACHED - board_init_f() does not return */
Stefan Roese50b5ac02012-08-16 17:53:18 +0200162#endif
Peter Tyser0c44caf2010-09-14 19:13:53 -0500163
Stefan Roese50b5ac02012-08-16 17:53:18 +0200164#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +0000165/*
166 * Vector Table
167 */
168
169 .globl _start_of_vectors
170_start_of_vectors:
171
172/* Machine check */
173 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
174
175/* Data Storage exception. */
176 STD_EXCEPTION(0x300, DataStorage, UnknownException)
177
178/* Instruction Storage exception. */
179 STD_EXCEPTION(0x400, InstStorage, UnknownException)
180
181/* External Interrupt exception. */
182 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
183
184/* Alignment exception. */
185 . = 0x600
186Alignment:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200187 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk21136db2003-07-16 21:53:01 +0000188 mfspr r4,DAR
189 stw r4,_DAR(r21)
190 mfspr r5,DSISR
191 stw r5,_DSISR(r21)
192 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100193 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenk21136db2003-07-16 21:53:01 +0000194
195/* Program check exception */
196 . = 0x700
197ProgramCheck:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200198 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk21136db2003-07-16 21:53:01 +0000199 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100200 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
201 MSR_KERNEL, COPY_EE)
wdenk21136db2003-07-16 21:53:01 +0000202
203 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
204
205 /* I guess we could implement decrementer, and may have
206 * to someday for timekeeping.
207 */
208 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
209
210 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
211 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000212 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk21136db2003-07-16 21:53:01 +0000213 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
214
215 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
216 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
217
218 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
219 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
220 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
221#ifdef DEBUG
222 . = 0x1300
223 /*
224 * This exception occurs when the program counter matches the
225 * Instruction Address Breakpoint Register (IABR).
226 *
227 * I want the cpu to halt if this occurs so I can hunt around
228 * with the debugger and look at things.
229 *
230 * When DEBUG is defined, both machine check enable (in the MSR)
231 * and checkstop reset enable (in the reset mode register) are
232 * turned off and so a checkstop condition will result in the cpu
233 * halting.
234 *
235 * I force the cpu into a checkstop condition by putting an illegal
236 * instruction here (at least this is the theory).
237 *
238 * well - that didnt work, so just do an infinite loop!
239 */
2401: b 1b
241#else
242 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
243#endif
244 STD_EXCEPTION(0x1400, SMI, UnknownException)
245
246 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
247 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
248 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
249 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
250 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
251 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
252 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
253 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
254 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
255 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
256 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
257 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
258 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
259 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
260 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
261 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
262 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
263 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
264 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
265 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
266 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
267 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
268 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
269 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
270 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
271 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
272 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
273
274
275 .globl _end_of_vectors
276_end_of_vectors:
277
278 . = 0x3000
279
280/*
281 * This code finishes saving the registers to the exception frame
282 * and jumps to the appropriate handler for the exception.
283 * Register r21 is pointer into trap frame, r1 has new stack pointer.
284 */
285 .globl transfer_to_handler
286transfer_to_handler:
287 stw r22,_NIP(r21)
288 lis r22,MSR_POW@h
289 andc r23,r23,r22
290 stw r23,_MSR(r21)
291 SAVE_GPR(7, r21)
292 SAVE_4GPRS(8, r21)
293 SAVE_8GPRS(12, r21)
294 SAVE_8GPRS(24, r21)
295 mflr r23
296 andi. r24,r23,0x3f00 /* get vector offset */
297 stw r24,TRAP(r21)
298 li r22,0
299 stw r22,RESULT(r21)
300 lwz r24,0(r23) /* virtual address of handler */
301 lwz r23,4(r23) /* where to go when done */
302 mtspr SRR0,r24
303 mtspr SRR1,r20
304 mtlr r23
305 SYNC
306 rfi /* jump to handler, enable MMU */
307
308int_return:
309 mfmsr r28 /* Disable interrupts */
310 li r4,0
311 ori r4,r4,MSR_EE
312 andc r28,r28,r4
313 SYNC /* Some chip revs need this... */
314 mtmsr r28
315 SYNC
316 lwz r2,_CTR(r1)
317 lwz r0,_LINK(r1)
318 mtctr r2
319 mtlr r0
320 lwz r2,_XER(r1)
321 lwz r0,_CCR(r1)
322 mtspr XER,r2
323 mtcrf 0xFF,r0
324 REST_10GPRS(3, r1)
325 REST_10GPRS(13, r1)
326 REST_8GPRS(23, r1)
327 REST_GPR(31, r1)
328 lwz r2,_NIP(r1) /* Restore environment */
329 lwz r0,_MSR(r1)
330 mtspr SRR0,r2
331 mtspr SRR1,r0
332 lwz r0,GPR0(r1)
333 lwz r2,GPR2(r1)
334 lwz r1,GPR1(r1)
335 SYNC
336 rfi
Stefan Roese50b5ac02012-08-16 17:53:18 +0200337#endif /* CONFIG_SPL_BUILD */
wdenk21136db2003-07-16 21:53:01 +0000338
339/*
340 * This code initialises the MPC5xxx processor core
341 * (conforms to PowerPC 603e spec)
342 * Note: expects original MSR contents to be in r5.
343 */
344
345 .globl init_5xx_core
346init_5xxx_core:
347
348 /* Initialize machine status; enable machine check interrupt */
349 /*--------------------------------------------------------------*/
350
351 li r3, MSR_KERNEL /* Set ME and RI flags */
352 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
353#ifdef DEBUG
354 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
355#endif
356 SYNC /* Some chip revs need this... */
357 mtmsr r3
358 SYNC
359 mtspr SRR1, r3 /* Make SRR1 match MSR */
360
361 /* Initialize the Hardware Implementation-dependent Registers */
362 /* HID0 also contains cache control */
363 /*--------------------------------------------------------------*/
364
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200365 lis r3, CONFIG_SYS_HID0_INIT@h
366 ori r3, r3, CONFIG_SYS_HID0_INIT@l
wdenk21136db2003-07-16 21:53:01 +0000367 SYNC
368 mtspr HID0, r3
369
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200370 lis r3, CONFIG_SYS_HID0_FINAL@h
371 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
wdenk21136db2003-07-16 21:53:01 +0000372 SYNC
373 mtspr HID0, r3
374
375 /* clear all BAT's */
376 /*--------------------------------------------------------------*/
377
378 li r0, 0
379 mtspr DBAT0U, r0
380 mtspr DBAT0L, r0
381 mtspr DBAT1U, r0
382 mtspr DBAT1L, r0
383 mtspr DBAT2U, r0
384 mtspr DBAT2L, r0
385 mtspr DBAT3U, r0
386 mtspr DBAT3L, r0
wdenkfc314ce2003-09-14 19:08:39 +0000387 mtspr DBAT4U, r0
388 mtspr DBAT4L, r0
389 mtspr DBAT5U, r0
390 mtspr DBAT5L, r0
391 mtspr DBAT6U, r0
392 mtspr DBAT6L, r0
393 mtspr DBAT7U, r0
394 mtspr DBAT7L, r0
wdenk21136db2003-07-16 21:53:01 +0000395 mtspr IBAT0U, r0
396 mtspr IBAT0L, r0
397 mtspr IBAT1U, r0
398 mtspr IBAT1L, r0
399 mtspr IBAT2U, r0
400 mtspr IBAT2L, r0
401 mtspr IBAT3U, r0
402 mtspr IBAT3L, r0
wdenkfc314ce2003-09-14 19:08:39 +0000403 mtspr IBAT4U, r0
404 mtspr IBAT4L, r0
405 mtspr IBAT5U, r0
406 mtspr IBAT5L, r0
407 mtspr IBAT6U, r0
408 mtspr IBAT6L, r0
409 mtspr IBAT7U, r0
410 mtspr IBAT7L, r0
wdenk21136db2003-07-16 21:53:01 +0000411 SYNC
412
413 /* invalidate all tlb's */
414 /* */
415 /* From the 603e User Manual: "The 603e provides the ability to */
416 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
417 /* instruction invalidates the TLB entry indexed by the EA, and */
418 /* operates on both the instruction and data TLBs simultaneously*/
419 /* invalidating four TLB entries (both sets in each TLB). The */
420 /* index corresponds to bits 15-19 of the EA. To invalidate all */
421 /* entries within both TLBs, 32 tlbie instructions should be */
422 /* issued, incrementing this field by one each time." */
423 /* */
424 /* "Note that the tlbia instruction is not implemented on the */
425 /* 603e." */
426 /* */
427 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
428 /* incrementing by 0x1000 each time. The code below is sort of */
Stefan Roese88fbf932010-04-15 16:07:28 +0200429 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
wdenk21136db2003-07-16 21:53:01 +0000430 /* */
431 /*--------------------------------------------------------------*/
432
433 li r3, 32
434 mtctr r3
435 li r3, 0
4361: tlbie r3
437 addi r3, r3, 0x1000
438 bdnz 1b
439 SYNC
440
441 /* Done! */
442 /*--------------------------------------------------------------*/
443
444 blr
445
446/* Cache functions.
447 *
448 * Note: requires that all cache bits in
449 * HID0 are in the low half word.
450 */
451 .globl icache_enable
452icache_enable:
453 mfspr r3, HID0
454 ori r3, r3, HID0_ICE
455 lis r4, 0
456 ori r4, r4, HID0_ILOCK
457 andc r3, r3, r4
458 ori r4, r3, HID0_ICFI
459 isync
460 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
461 isync
462 mtspr HID0, r3 /* clears invalidate */
463 blr
464
465 .globl icache_disable
466icache_disable:
467 mfspr r3, HID0
468 lis r4, 0
469 ori r4, r4, HID0_ICE|HID0_ILOCK
470 andc r3, r3, r4
471 ori r4, r3, HID0_ICFI
472 isync
473 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
474 isync
475 mtspr HID0, r3 /* clears invalidate */
476 blr
477
478 .globl icache_status
479icache_status:
480 mfspr r3, HID0
481 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
482 blr
483
484 .globl dcache_enable
485dcache_enable:
486 mfspr r3, HID0
487 ori r3, r3, HID0_DCE
488 lis r4, 0
489 ori r4, r4, HID0_DLOCK
490 andc r3, r3, r4
491 ori r4, r3, HID0_DCI
492 sync
493 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
494 sync
495 mtspr HID0, r3 /* clears invalidate */
496 blr
497
498 .globl dcache_disable
499dcache_disable:
500 mfspr r3, HID0
501 lis r4, 0
502 ori r4, r4, HID0_DCE|HID0_DLOCK
503 andc r3, r3, r4
504 ori r4, r3, HID0_DCI
505 sync
506 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
507 sync
508 mtspr HID0, r3 /* clears invalidate */
509 blr
510
511 .globl dcache_status
512dcache_status:
513 mfspr r3, HID0
514 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
515 blr
516
wdenk2d644822004-06-09 17:45:32 +0000517 .globl get_svr
518get_svr:
519 mfspr r3, SVR
520 blr
521
wdenk21136db2003-07-16 21:53:01 +0000522 .globl get_pvr
523get_pvr:
524 mfspr r3, PVR
525 blr
526
Stefan Roese50b5ac02012-08-16 17:53:18 +0200527#ifndef CONFIG_SPL_BUILD
wdenk21136db2003-07-16 21:53:01 +0000528/*------------------------------------------------------------------------------*/
529
530/*
531 * void relocate_code (addr_sp, gd, addr_moni)
532 *
533 * This "function" does not return, instead it continues in RAM
534 * after relocating the monitor code.
535 *
536 * r3 = dest
537 * r4 = src
538 * r5 = length in bytes
539 * r6 = cachelinesize
540 */
541 .globl relocate_code
542relocate_code:
543 mr r1, r3 /* Set new stack pointer */
544 mr r9, r4 /* Save copy of Global Data pointer */
545 mr r10, r5 /* Save copy of Destination Address */
546
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100547 GET_GOT
wdenk21136db2003-07-16 21:53:01 +0000548 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200549 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
550 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenk21136db2003-07-16 21:53:01 +0000551 lwz r5, GOT(__init_end)
552 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200553 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenk21136db2003-07-16 21:53:01 +0000554
555 /*
556 * Fix GOT pointer:
557 *
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200558 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenk21136db2003-07-16 21:53:01 +0000559 *
560 * Offset:
561 */
562 sub r15, r10, r4
563
564 /* First our own GOT */
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100565 add r12, r12, r15
wdenk21136db2003-07-16 21:53:01 +0000566 /* then the one used by the C code */
567 add r30, r30, r15
568
569 /*
570 * Now relocate code
571 */
572
573 cmplw cr1,r3,r4
574 addi r0,r5,3
575 srwi. r0,r0,2
576 beq cr1,4f /* In place copy is not necessary */
577 beq 7f /* Protect against 0 count */
578 mtctr r0
579 bge cr1,2f
580
581 la r8,-4(r4)
582 la r7,-4(r3)
5831: lwzu r0,4(r8)
584 stwu r0,4(r7)
585 bdnz 1b
586 b 4f
587
5882: slwi r0,r0,2
589 add r8,r4,r0
590 add r7,r3,r0
5913: lwzu r0,-4(r8)
592 stwu r0,-4(r7)
593 bdnz 3b
594
595/*
596 * Now flush the cache: note that we must start from a cache aligned
597 * address. Otherwise we might miss one cache line.
598 */
5994: cmpwi r6,0
600 add r5,r3,r5
601 beq 7f /* Always flush prefetch queue in any case */
602 subi r0,r6,1
603 andc r3,r3,r0
604 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
605 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
606 cmpwi r7,0
607 beq 9f
608 mr r4,r3
6095: dcbst 0,r4
610 add r4,r4,r6
611 cmplw r4,r5
612 blt 5b
613 sync /* Wait for all dcbst to complete on bus */
6149: mfspr r7,HID0 /* don't do icbi if icache is disabled */
615 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
616 cmpwi r7,0
617 beq 7f
618 mr r4,r3
6196: icbi 0,r4
620 add r4,r4,r6
621 cmplw r4,r5
622 blt 6b
6237: sync /* Wait for all icbi to complete on bus */
624 isync
625
626/*
627 * We are done. Do not return, instead branch to second part of board
628 * initialization, now running from RAM.
629 */
630
631 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
632 mtlr r0
633 blr
634
635in_ram:
636
637 /*
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100638 * Relocation Function, r12 point to got2+0x8000
wdenk21136db2003-07-16 21:53:01 +0000639 *
640 * Adjust got2 pointers, no need to check for 0, this code
641 * already puts a few entries in the table.
642 */
643 li r0,__got2_entries@sectoff@l
644 la r3,GOT(_GOT2_TABLE_)
645 lwz r11,GOT(_GOT2_TABLE_)
646 mtctr r0
647 sub r11,r3,r11
648 addi r3,r3,-4
6491: lwzu r0,4(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200650 cmpwi r0,0
651 beq- 2f
wdenk21136db2003-07-16 21:53:01 +0000652 add r0,r0,r11
653 stw r0,0(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +02006542: bdnz 1b
wdenk21136db2003-07-16 21:53:01 +0000655
656 /*
657 * Now adjust the fixups and the pointers to the fixups
658 * in case we need to move ourselves again.
659 */
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200660 li r0,__fixup_entries@sectoff@l
wdenk21136db2003-07-16 21:53:01 +0000661 lwz r3,GOT(_FIXUP_TABLE_)
662 cmpwi r0,0
663 mtctr r0
664 addi r3,r3,-4
665 beq 4f
6663: lwzu r4,4(r3)
667 lwzux r0,r4,r11
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200668 cmpwi r0,0
wdenk21136db2003-07-16 21:53:01 +0000669 add r0,r0,r11
Joakim Tjernlund401b5922010-11-04 19:02:00 +0100670 stw r4,0(r3)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200671 beq- 5f
wdenk21136db2003-07-16 21:53:01 +0000672 stw r0,0(r4)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +02006735: bdnz 3b
wdenk21136db2003-07-16 21:53:01 +00006744:
675clear_bss:
676 /*
677 * Now clear BSS segment
678 */
679 lwz r3,GOT(__bss_start)
Simon Glassed70c8f2013-03-14 06:54:53 +0000680 lwz r4,GOT(__bss_end)
wdenk21136db2003-07-16 21:53:01 +0000681
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 Tjernlund3fbaa4d2010-01-19 14:41:56 +0100705 mflr r4 /* save link register */
706 GET_GOT
wdenk21136db2003-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 */
wdenk21136db2003-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
Stefan Roese50b5ac02012-08-16 17:53:18 +0200765
766#endif /* CONFIG_SPL_BUILD */