blob: 65510fa760f4e6aca044f1a1ade0c7a2a7cbe35b [file] [log] [blame]
wdenk47d1a6e2002-11-03 00:01:44 +00001/*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de>
5 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenk47d1a6e2002-11-03 00:01:44 +00007 */
8
9/*
10 * U-Boot - Startup Code for MPC8260 PowerPC based Embedded Boards
11 */
Wolfgang Denk0191e472010-10-26 14:34:52 +020012#include <asm-offsets.h>
wdenk47d1a6e2002-11-03 00:01:44 +000013#include <config.h>
14#include <mpc8260.h>
15#include <version.h>
16
17#define CONFIG_8260 1 /* needed for Linux kernel header files */
wdenk47d1a6e2002-11-03 00:01:44 +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>
wdenk47d1a6e2002-11-03 00:01:44 +000025
wdenk47d1a6e2002-11-03 00:01:44 +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
36/*
37 * Set up GOT: Global Offset Table
38 *
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +010039 * Use r12 to access the GOT
wdenk47d1a6e2002-11-03 00:01:44 +000040 */
41 START_GOT
42 GOT_ENTRY(_GOT2_TABLE_)
43 GOT_ENTRY(_FIXUP_TABLE_)
44
45 GOT_ENTRY(_start)
46 GOT_ENTRY(_start_of_vectors)
47 GOT_ENTRY(_end_of_vectors)
48 GOT_ENTRY(transfer_to_handler)
49
wdenkb9a83a92003-05-30 12:48:29 +000050 GOT_ENTRY(__init_end)
Simon Glassed70c8f2013-03-14 06:54:53 +000051 GOT_ENTRY(__bss_end)
wdenkbf2f8c92003-05-22 22:52:13 +000052 GOT_ENTRY(__bss_start)
wdenk47d1a6e2002-11-03 00:01:44 +000053#if defined(CONFIG_HYMOD)
54 GOT_ENTRY(environment)
55#endif
56 END_GOT
57
58/*
59 * Version string - must be in data segment because MPC8260 uses the first
60 * 256 bytes for the Hard Reset Configuration Word table (see below).
61 * Similarly, can't have the U-Boot Magic Number as the first thing in
62 * the image - don't know how this will affect the image tools, but I guess
63 * I'll find out soon
64 */
65 .data
66 .globl version_string
67version_string:
Andreas Bießmann61d01952011-07-18 20:24:04 +020068 .ascii U_BOOT_VERSION_STRING, "\0"
wdenk47d1a6e2002-11-03 00:01:44 +000069
70/*
71 * Hard Reset Configuration Word (HRCW) table
72 *
73 * The Hard Reset Configuration Word (HRCW) sets a number of useful things
74 * such as whether there is an external memory controller, whether the
75 * PowerPC core is disabled (i.e. only the communications processor is
76 * active, accessed by another CPU on the bus), whether using external
77 * arbitration, external bus mode, boot port size, core initial prefix,
78 * internal space base, boot memory space, etc.
79 *
80 * These things dictate where the processor begins execution, where the
81 * boot ROM appears in memory, the memory controller setup when access
82 * boot ROM, etc. The HRCW is *extremely* important.
83 *
84 * The HRCW is read from the bus during reset. One CPU on the bus will
85 * be a hard reset configuration master, any others will be hard reset
86 * configuration slaves. The master reads eight HRCWs from flash during
87 * reset - the first it uses for itself, the other 7 it communicates to
88 * up to 7 configuration slaves by some complicated mechanism, which is
89 * not really important here.
90 *
91 * The configuration master performs 32 successive reads starting at address
92 * 0 and incrementing by 8 each read (i.e. on 64 bit boundaries) but only 8
93 * bits is read, and always from byte lane D[0-7] (so that port size of the
94 * boot device does not matter). The first four reads form the 32 bit HRCW
95 * for the master itself. The second four reads form the HRCW for the first
96 * slave, and so on, up to seven slaves. The 32 bit HRCW is formed by
97 * concatenating the four bytes, with the first read placed in byte 0 (the
98 * most significant byte), and so on with the fourth read placed in byte 3
99 * (the least significant byte).
100 */
101#define _HRCW_TABLE_ENTRY(w) \
102 .fill 8,1,(((w)>>24)&0xff); \
103 .fill 8,1,(((w)>>16)&0xff); \
104 .fill 8,1,(((w)>> 8)&0xff); \
105 .fill 8,1,(((w) )&0xff)
106 .text
107 .globl _hrcw_table
108_hrcw_table:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200109 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_MASTER)
110 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE1)
111 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE2)
112 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE3)
113 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE4)
114 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE5)
115 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE6)
116 _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_SLAVE7)
wdenk47d1a6e2002-11-03 00:01:44 +0000117/*
118 * After configuration, a system reset exception is executed using the
119 * vector at offset 0x100 relative to the base set by MSR[IP]. If MSR[IP]
120 * is 0, the base address is 0x00000000. If MSR[IP] is 1, the base address
121 * is 0xfff00000. In the case of a Power On Reset or Hard Reset, the value
122 * of MSR[IP] is determined by the CIP field in the HRCW.
123 *
124 * Other bits in the HRCW set up the Base Address and Port Size in BR0.
125 * This determines the location of the boot ROM (flash or EPROM) in the
126 * processor's address space at boot time. As long as the HRCW is set up
127 * so that we eventually end up executing the code below when the processor
128 * executes the reset exception, the actual values used should not matter.
129 *
130 * Once we have got here, the address mask in OR0 is cleared so that the
131 * bottom 32K of the boot ROM is effectively repeated all throughout the
132 * processor's address space, after which we can jump to the absolute
133 * address at which the boot ROM was linked at compile time, and proceed
134 * to initialise the memory controller without worrying if the rug will be
135 * pulled out from under us, so to speak (it will be fine as long as we
136 * configure BR0 with the same boot ROM link address).
137 */
138 . = EXC_OFF_SYS_RESET
139
140 .globl _start
141_start:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200142#if defined(CONFIG_MPC8260ADS) && defined(CONFIG_SYS_DEFAULT_IMMR)
143 lis r3, CONFIG_SYS_DEFAULT_IMMR@h
wdenk7539dea2003-06-19 23:01:32 +0000144 nop
145 lwz r4, 0(r3)
146 nop
147 rlwinm r4, r4, 0, 8, 5
148 nop
149 oris r4, r4, 0x0200
150 nop
151 stw r4, 0(r3)
152 nop
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200153#endif /* CONFIG_MPC8260ADS && CONFIG_SYS_DEFAULT_IMMR */
Peter Tyser0c44caf2010-09-14 19:13:53 -0500154
wdenk47d1a6e2002-11-03 00:01:44 +0000155 mfmsr r5 /* save msr contents */
156
157#if defined(CONFIG_COGENT)
158 /* this is what the cogent EPROM does */
159 li r0, 0
160 mtmsr r0
161 isync
162 bl cogent_init_8260
163#endif /* CONFIG_COGENT */
164
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200165#if defined(CONFIG_SYS_DEFAULT_IMMR)
166 lis r3, CONFIG_SYS_IMMR@h
167 ori r3, r3, CONFIG_SYS_IMMR@l
168 lis r4, CONFIG_SYS_DEFAULT_IMMR@h
wdenk47d1a6e2002-11-03 00:01:44 +0000169 stw r3, 0x1A8(r4)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200170#endif /* CONFIG_SYS_DEFAULT_IMMR */
wdenk47d1a6e2002-11-03 00:01:44 +0000171
172 /* Initialise the MPC8260 processor core */
173 /*--------------------------------------------------------------*/
174
175 bl init_8260_core
176
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200177#ifndef CONFIG_SYS_RAMBOOT
wdenk47d1a6e2002-11-03 00:01:44 +0000178 /* When booting from ROM (Flash or EPROM), clear the */
179 /* Address Mask in OR0 so ROM appears everywhere */
180 /*--------------------------------------------------------------*/
181
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200182 lis r3, (CONFIG_SYS_IMMR+IM_REGBASE)@h
wdenk47d1a6e2002-11-03 00:01:44 +0000183 lwz r4, IM_OR0@l(r3)
184 li r5, 0x7fff
185 and r4, r4, r5
186 stw r4, IM_OR0@l(r3)
187
188 /* Calculate absolute address in FLASH and jump there */
189 /*--------------------------------------------------------------*/
190
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200191 lis r3, CONFIG_SYS_MONITOR_BASE@h
192 ori r3, r3, CONFIG_SYS_MONITOR_BASE@l
wdenk47d1a6e2002-11-03 00:01:44 +0000193 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
194 mtlr r3
195 blr
196
197in_flash:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200198#endif /* CONFIG_SYS_RAMBOOT */
wdenk47d1a6e2002-11-03 00:01:44 +0000199
200 /* initialize some things that are hard to access from C */
201 /*--------------------------------------------------------------*/
202
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200203 lis r3, CONFIG_SYS_IMMR@h /* set up stack in internal DPRAM */
204 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
wdenk47d1a6e2002-11-03 00:01:44 +0000205 li r0, 0 /* Make room for stack frame header and */
206 stwu r0, -4(r1) /* clear final stack frame so that */
207 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
208
209 /* let the C-code set up the rest */
210 /* */
211 /* Be careful to keep code relocatable ! */
212 /*--------------------------------------------------------------*/
213
214 GET_GOT /* initialize GOT access */
Wolfgang Denkb2d36ea2011-04-20 22:11:21 +0200215
wdenk47d1a6e2002-11-03 00:01:44 +0000216 /* r3: IMMR */
217 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
218
219#ifdef DEBUG
220 bl init_debug /* set up debugging stuff */
221#endif
222
wdenk47d1a6e2002-11-03 00:01:44 +0000223 bl board_init_f /* run 1st part of board init code (in Flash)*/
224
Peter Tyser0c44caf2010-09-14 19:13:53 -0500225 /* NOTREACHED - board_init_f() does not return */
226
wdenk47d1a6e2002-11-03 00:01:44 +0000227/*
228 * Vector Table
229 */
230
231 .globl _start_of_vectors
232_start_of_vectors:
233
234/* Machine check */
235 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
236
237/* Data Storage exception. */
238 STD_EXCEPTION(0x300, DataStorage, UnknownException)
239
240/* Instruction Storage exception. */
241 STD_EXCEPTION(0x400, InstStorage, UnknownException)
242
243/* External Interrupt exception. */
244 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
245
246/* Alignment exception. */
247 . = 0x600
248Alignment:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200249 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk47d1a6e2002-11-03 00:01:44 +0000250 mfspr r4,DAR
251 stw r4,_DAR(r21)
252 mfspr r5,DSISR
253 stw r5,_DSISR(r21)
254 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100255 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenk47d1a6e2002-11-03 00:01:44 +0000256
257/* Program check exception */
258 . = 0x700
259ProgramCheck:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200260 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk47d1a6e2002-11-03 00:01:44 +0000261 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100262 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
263 MSR_KERNEL, COPY_EE)
wdenk47d1a6e2002-11-03 00:01:44 +0000264
265 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
266
267 /* I guess we could implement decrementer, and may have
268 * to someday for timekeeping.
269 */
270 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
271
272 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
273 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000274 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk47d1a6e2002-11-03 00:01:44 +0000275 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
276
277 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
278 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
279
280 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
281 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
282 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
283#ifdef DEBUG
284 . = 0x1300
285 /*
286 * This exception occurs when the program counter matches the
287 * Instruction Address Breakpoint Register (IABR).
288 *
289 * I want the cpu to halt if this occurs so I can hunt around
290 * with the debugger and look at things.
291 *
292 * When DEBUG is defined, both machine check enable (in the MSR)
293 * and checkstop reset enable (in the reset mode register) are
294 * turned off and so a checkstop condition will result in the cpu
295 * halting.
296 *
297 * I force the cpu into a checkstop condition by putting an illegal
298 * instruction here (at least this is the theory).
299 *
300 * well - that didnt work, so just do an infinite loop!
301 */
3021: b 1b
303#else
304 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
305#endif
306 STD_EXCEPTION(0x1400, SMI, UnknownException)
307
308 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
309 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
310 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
311 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
312 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
313 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
314 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
315 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
316 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
317 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
318 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
319 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
320 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
321 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
322 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
323 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
324 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
325 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
326 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
327 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
328 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
329 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
330 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
331 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
332 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
333 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
334 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
335
336
337 .globl _end_of_vectors
338_end_of_vectors:
339
340 . = 0x3000
341
342/*
343 * This code finishes saving the registers to the exception frame
344 * and jumps to the appropriate handler for the exception.
345 * Register r21 is pointer into trap frame, r1 has new stack pointer.
346 */
347 .globl transfer_to_handler
348transfer_to_handler:
349 stw r22,_NIP(r21)
350 lis r22,MSR_POW@h
351 andc r23,r23,r22
352 stw r23,_MSR(r21)
353 SAVE_GPR(7, r21)
354 SAVE_4GPRS(8, r21)
355 SAVE_8GPRS(12, r21)
356 SAVE_8GPRS(24, r21)
357 mflr r23
358 andi. r24,r23,0x3f00 /* get vector offset */
359 stw r24,TRAP(r21)
360 li r22,0
361 stw r22,RESULT(r21)
362 lwz r24,0(r23) /* virtual address of handler */
363 lwz r23,4(r23) /* where to go when done */
364 mtspr SRR0,r24
365 mtspr SRR1,r20
366 mtlr r23
367 SYNC
368 rfi /* jump to handler, enable MMU */
369
370int_return:
371 mfmsr r28 /* Disable interrupts */
372 li r4,0
373 ori r4,r4,MSR_EE
374 andc r28,r28,r4
375 SYNC /* Some chip revs need this... */
376 mtmsr r28
377 SYNC
378 lwz r2,_CTR(r1)
379 lwz r0,_LINK(r1)
380 mtctr r2
381 mtlr r0
382 lwz r2,_XER(r1)
383 lwz r0,_CCR(r1)
384 mtspr XER,r2
385 mtcrf 0xFF,r0
386 REST_10GPRS(3, r1)
387 REST_10GPRS(13, r1)
388 REST_8GPRS(23, r1)
389 REST_GPR(31, r1)
390 lwz r2,_NIP(r1) /* Restore environment */
391 lwz r0,_MSR(r1)
392 mtspr SRR0,r2
393 mtspr SRR1,r0
394 lwz r0,GPR0(r1)
395 lwz r2,GPR2(r1)
396 lwz r1,GPR1(r1)
397 SYNC
398 rfi
399
400#if defined(CONFIG_COGENT)
401
402/*
403 * This code initialises the MPC8260 processor core
404 * (conforms to PowerPC 603e spec)
405 */
406
407 .globl cogent_init_8260
408cogent_init_8260:
409
410 /* Taken from page 14 of CMA282 manual */
411 /*--------------------------------------------------------------*/
412
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200413 lis r4, (CONFIG_SYS_IMMR+IM_REGBASE)@h
414 lis r3, CONFIG_SYS_IMMR@h
wdenk47d1a6e2002-11-03 00:01:44 +0000415 stw r3, IM_IMMR@l(r4)
416 lwz r3, IM_IMMR@l(r4)
417 stw r3, 0(r0)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200418 lis r3, CONFIG_SYS_SYPCR@h
419 ori r3, r3, CONFIG_SYS_SYPCR@l
wdenk47d1a6e2002-11-03 00:01:44 +0000420 stw r3, IM_SYPCR@l(r4)
421 lwz r3, IM_SYPCR@l(r4)
422 stw r3, 4(r0)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200423 lis r3, CONFIG_SYS_SCCR@h
424 ori r3, r3, CONFIG_SYS_SCCR@l
wdenk47d1a6e2002-11-03 00:01:44 +0000425 stw r3, IM_SCCR@l(r4)
426 lwz r3, IM_SCCR@l(r4)
427 stw r3, 8(r0)
428
429 /* the rest of this was disassembled from the */
430 /* EPROM code that came with my CMA282 CPU module */
431 /*--------------------------------------------------------------*/
432
433 lis r1, 0x1234
434 ori r1, r1, 0x5678
435 stw r1, 0x20(r0)
436 lwz r1, 0x20(r0)
437 stw r1, 0x24(r0)
438 lwz r1, 0x24(r0)
439 lis r3, 0x0e80
440 ori r3, r3, 0
441 stw r1, 4(r3)
442 lwz r1, 4(r3)
443
444 /* Done! */
445 /*--------------------------------------------------------------*/
446
447 blr
448
449#endif /* CONFIG_COGENT */
450
451/*
452 * This code initialises the MPC8260 processor core
453 * (conforms to PowerPC 603e spec)
454 * Note: expects original MSR contents to be in r5.
455 */
456
457 .globl init_8260_core
458init_8260_core:
459
460 /* Initialize machine status; enable machine check interrupt */
461 /*--------------------------------------------------------------*/
462
463 li r3, MSR_KERNEL /* Set ME and RI flags */
464 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
465#ifdef DEBUG
466 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
467#endif
468 SYNC /* Some chip revs need this... */
469 mtmsr r3
470 SYNC
471 mtspr SRR1, r3 /* Make SRR1 match MSR */
472
473 /* Initialise the SYPCR early, and reset the watchdog (if req) */
474 /*--------------------------------------------------------------*/
475
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200476 lis r3, (CONFIG_SYS_IMMR+IM_REGBASE)@h
wdenk47d1a6e2002-11-03 00:01:44 +0000477#if !defined(CONFIG_COGENT)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200478 lis r4, CONFIG_SYS_SYPCR@h
479 ori r4, r4, CONFIG_SYS_SYPCR@l
wdenk47d1a6e2002-11-03 00:01:44 +0000480 stw r4, IM_SYPCR@l(r3)
481#endif /* !CONFIG_COGENT */
482#if defined(CONFIG_WATCHDOG)
483 li r4, 21868 /* = 0x556c */
484 sth r4, IM_SWSR@l(r3)
485 li r4, -21959 /* = 0xaa39 */
486 sth r4, IM_SWSR@l(r3)
487#endif /* CONFIG_WATCHDOG */
488
489 /* Initialize the Hardware Implementation-dependent Registers */
490 /* HID0 also contains cache control */
491 /*--------------------------------------------------------------*/
492
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200493 lis r3, CONFIG_SYS_HID0_INIT@h
494 ori r3, r3, CONFIG_SYS_HID0_INIT@l
wdenk47d1a6e2002-11-03 00:01:44 +0000495 SYNC
496 mtspr HID0, r3
497
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200498 lis r3, CONFIG_SYS_HID0_FINAL@h
499 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
wdenk47d1a6e2002-11-03 00:01:44 +0000500 SYNC
501 mtspr HID0, r3
502
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200503 lis r3, CONFIG_SYS_HID2@h
504 ori r3, r3, CONFIG_SYS_HID2@l
wdenk47d1a6e2002-11-03 00:01:44 +0000505 mtspr HID2, r3
506
507 /* clear all BAT's */
508 /*--------------------------------------------------------------*/
509
510 li r0, 0
511 mtspr DBAT0U, r0
512 mtspr DBAT0L, r0
513 mtspr DBAT1U, r0
514 mtspr DBAT1L, r0
515 mtspr DBAT2U, r0
516 mtspr DBAT2L, r0
517 mtspr DBAT3U, r0
518 mtspr DBAT3L, r0
519 mtspr IBAT0U, r0
520 mtspr IBAT0L, r0
521 mtspr IBAT1U, r0
522 mtspr IBAT1L, r0
523 mtspr IBAT2U, r0
524 mtspr IBAT2L, r0
525 mtspr IBAT3U, r0
526 mtspr IBAT3L, r0
527 SYNC
528
529 /* invalidate all tlb's */
530 /* */
531 /* From the 603e User Manual: "The 603e provides the ability to */
532 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
533 /* instruction invalidates the TLB entry indexed by the EA, and */
534 /* operates on both the instruction and data TLBs simultaneously*/
535 /* invalidating four TLB entries (both sets in each TLB). The */
536 /* index corresponds to bits 15-19 of the EA. To invalidate all */
537 /* entries within both TLBs, 32 tlbie instructions should be */
538 /* issued, incrementing this field by one each time." */
539 /* */
540 /* "Note that the tlbia instruction is not implemented on the */
541 /* 603e." */
542 /* */
543 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
544 /* incrementing by 0x1000 each time. The code below is sort of */
Stefan Roese88fbf932010-04-15 16:07:28 +0200545 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
wdenk47d1a6e2002-11-03 00:01:44 +0000546 /* */
547 /*--------------------------------------------------------------*/
548
549 li r3, 32
550 mtctr r3
551 li r3, 0
5521: tlbie r3
553 addi r3, r3, 0x1000
554 bdnz 1b
555 SYNC
556
557 /* Done! */
558 /*--------------------------------------------------------------*/
559
560 blr
561
562#ifdef DEBUG
563
564/*
565 * initialise things related to debugging.
566 *
567 * must be called after the global offset table (GOT) is initialised
568 * (GET_GOT) and after cpu_init_f() has executed.
569 */
570
571 .globl init_debug
572init_debug:
573
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200574 lis r3, (CONFIG_SYS_IMMR+IM_REGBASE)@h
wdenk47d1a6e2002-11-03 00:01:44 +0000575
576 /* Quick and dirty hack to enable the RAM and copy the */
577 /* vectors so that we can take exceptions. */
578 /*--------------------------------------------------------------*/
579 /* write Memory Refresh Prescaler */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200580 li r4, CONFIG_SYS_MPTPR
wdenk47d1a6e2002-11-03 00:01:44 +0000581 sth r4, IM_MPTPR@l(r3)
582 /* write 60x Refresh Timer */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200583 li r4, CONFIG_SYS_PSRT
wdenk47d1a6e2002-11-03 00:01:44 +0000584 stb r4, IM_PSRT@l(r3)
585 /* init the 60x SDRAM Mode Register */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200586 lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM)@h
587 ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM)@l
wdenk47d1a6e2002-11-03 00:01:44 +0000588 stw r4, IM_PSDMR@l(r3)
589 /* write Precharge All Banks command */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200590 lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_PREA)@h
591 ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_PREA)@l
wdenk47d1a6e2002-11-03 00:01:44 +0000592 stw r4, IM_PSDMR@l(r3)
593 stb r0, 0(0)
594 /* write eight CBR Refresh commands */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200595 lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_CBRR)@h
596 ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_CBRR)@l
wdenk47d1a6e2002-11-03 00:01:44 +0000597 stw r4, IM_PSDMR@l(r3)
598 stb r0, 0(0)
599 stb r0, 0(0)
600 stb r0, 0(0)
601 stb r0, 0(0)
602 stb r0, 0(0)
603 stb r0, 0(0)
604 stb r0, 0(0)
605 stb r0, 0(0)
606 /* write Mode Register Write command */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200607 lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_MRW)@h
608 ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_MRW)@l
wdenk47d1a6e2002-11-03 00:01:44 +0000609 stw r4, IM_PSDMR@l(r3)
610 stb r0, 0(0)
611 /* write Normal Operation command and enable Refresh */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200612 lis r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM|PSDMR_RFEN)@h
613 ori r4, r4, (CONFIG_SYS_PSDMR|PSDMR_OP_NORM|PSDMR_RFEN)@l
wdenk47d1a6e2002-11-03 00:01:44 +0000614 stw r4, IM_PSDMR@l(r3)
615 stb r0, 0(0)
616 /* RAM should now be operational */
617
618#define VEC_WRD_CNT ((_end_of_vectors - _start + EXC_OFF_SYS_RESET) / 4)
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100619 mflr r3
620 GET_GOT
621 mtlr r3
wdenk47d1a6e2002-11-03 00:01:44 +0000622 lwz r3, GOT(_end_of_vectors)
623 rlwinm r4, r3, 0, 18, 31 /* _end_of_vectors & 0x3FFF */
624 lis r5, VEC_WRD_CNT@h
625 ori r5, r5, VEC_WRD_CNT@l
626 mtctr r5
6271:
628 lwzu r5, -4(r3)
629 stwu r5, -4(r4)
630 bdnz 1b
631
632 /* Load the Instruction Address Breakpoint Register (IABR). */
Wolfgang Denk70df7bc2007-06-22 23:59:00 +0200633 /* */
wdenk47d1a6e2002-11-03 00:01:44 +0000634 /* The address to load is stored in the first word of dual port */
635 /* ram and should be preserved while the power is on, so you */
636 /* can plug addresses into that location then reset the cpu and */
637 /* this code will load that address into the IABR after the */
638 /* reset. */
Wolfgang Denk70df7bc2007-06-22 23:59:00 +0200639 /* */
wdenk47d1a6e2002-11-03 00:01:44 +0000640 /* When the program counter matches the contents of the IABR, */
641 /* an exception is generated (before the instruction at that */
642 /* location completes). The vector for this exception is 0x1300 */
643 /*--------------------------------------------------------------*/
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200644 lis r3, CONFIG_SYS_IMMR@h
wdenk47d1a6e2002-11-03 00:01:44 +0000645 lwz r3, 0(r3)
646 mtspr IABR, r3
647
648 /* Set the entire dual port RAM (where the initial stack */
649 /* resides) to a known value - makes it easier to see where */
650 /* the stack has been written */
651 /*--------------------------------------------------------------*/
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200652 lis r3, (CONFIG_SYS_IMMR + CONFIG_SYS_INIT_SP_OFFSET)@h
653 ori r3, r3, (CONFIG_SYS_IMMR + CONFIG_SYS_INIT_SP_OFFSET)@l
654 li r4, ((CONFIG_SYS_INIT_SP_OFFSET - 4) / 4)
wdenk47d1a6e2002-11-03 00:01:44 +0000655 mtctr r4
656 lis r4, 0xdeadbeaf@h
657 ori r4, r4, 0xdeadbeaf@l
6581:
659 stwu r4, -4(r3)
660 bdnz 1b
661
662 /* Done! */
663 /*--------------------------------------------------------------*/
664
665 blr
666#endif
667
668/* Cache functions.
669 *
670 * Note: requires that all cache bits in
671 * HID0 are in the low half word.
672 */
673 .globl icache_enable
674icache_enable:
675 mfspr r3, HID0
676 ori r3, r3, HID0_ICE
677 lis r4, 0
678 ori r4, r4, HID0_ILOCK
679 andc r3, r3, r4
680 ori r4, r3, HID0_ICFI
681 isync
682 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
683 isync
684 mtspr HID0, r3 /* clears invalidate */
685 blr
686
687 .globl icache_disable
688icache_disable:
689 mfspr r3, HID0
690 lis r4, 0
691 ori r4, r4, HID0_ICE|HID0_ILOCK
692 andc r3, r3, r4
693 ori r4, r3, HID0_ICFI
694 isync
695 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
696 isync
697 mtspr HID0, r3 /* clears invalidate */
698 blr
699
700 .globl icache_status
701icache_status:
702 mfspr r3, HID0
703 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
704 blr
705
706 .globl dcache_enable
707dcache_enable:
708 mfspr r3, HID0
709 ori r3, r3, HID0_DCE
710 lis r4, 0
711 ori r4, r4, HID0_DLOCK
712 andc r3, r3, r4
713 ori r4, r3, HID0_DCI
714 sync
715 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
716 sync
717 mtspr HID0, r3 /* clears invalidate */
718 blr
719
720 .globl dcache_disable
721dcache_disable:
722 mfspr r3, HID0
723 lis r4, 0
724 ori r4, r4, HID0_DCE|HID0_DLOCK
725 andc r3, r3, r4
726 ori r4, r3, HID0_DCI
727 sync
728 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
729 sync
730 mtspr HID0, r3 /* clears invalidate */
731 blr
732
733 .globl dcache_status
734dcache_status:
735 mfspr r3, HID0
736 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
737 blr
738
739 .globl get_pvr
740get_pvr:
741 mfspr r3, PVR
742 blr
743
744/*------------------------------------------------------------------------------*/
745
746/*
747 * void relocate_code (addr_sp, gd, addr_moni)
748 *
749 * This "function" does not return, instead it continues in RAM
750 * after relocating the monitor code.
751 *
752 * r3 = dest
753 * r4 = src
754 * r5 = length in bytes
755 * r6 = cachelinesize
756 */
757 .globl relocate_code
758relocate_code:
759 mr r1, r3 /* Set new stack pointer */
760 mr r9, r4 /* Save copy of Global Data pointer */
761 mr r10, r5 /* Save copy of Destination Address */
762
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100763 GET_GOT
wdenk47d1a6e2002-11-03 00:01:44 +0000764 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200765 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
766 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenkb9a83a92003-05-30 12:48:29 +0000767 lwz r5, GOT(__init_end)
768 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200769 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenk47d1a6e2002-11-03 00:01:44 +0000770
771 /*
772 * Fix GOT pointer:
773 *
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200774 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenk47d1a6e2002-11-03 00:01:44 +0000775 *
776 * Offset:
777 */
778 sub r15, r10, r4
779
780 /* First our own GOT */
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100781 add r12, r12, r15
wdenk47d1a6e2002-11-03 00:01:44 +0000782 /* then the one used by the C code */
783 add r30, r30, r15
784
785 /*
786 * Now relocate code
787 */
788
789 cmplw cr1,r3,r4
790 addi r0,r5,3
791 srwi. r0,r0,2
792 beq cr1,4f /* In place copy is not necessary */
793 beq 7f /* Protect against 0 count */
794 mtctr r0
795 bge cr1,2f
796
797 la r8,-4(r4)
798 la r7,-4(r3)
7991: lwzu r0,4(r8)
800 stwu r0,4(r7)
801 bdnz 1b
802 b 4f
803
8042: slwi r0,r0,2
805 add r8,r4,r0
806 add r7,r3,r0
8073: lwzu r0,-4(r8)
808 stwu r0,-4(r7)
809 bdnz 3b
810
811/*
812 * Now flush the cache: note that we must start from a cache aligned
813 * address. Otherwise we might miss one cache line.
814 */
8154: cmpwi r6,0
816 add r5,r3,r5
817 beq 7f /* Always flush prefetch queue in any case */
818 subi r0,r6,1
819 andc r3,r3,r0
820 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
821 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
822 cmpwi r7,0
823 beq 9f
824 mr r4,r3
8255: dcbst 0,r4
826 add r4,r4,r6
827 cmplw r4,r5
828 blt 5b
829 sync /* Wait for all dcbst to complete on bus */
8309: mfspr r7,HID0 /* don't do icbi if icache is disabled */
831 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
832 cmpwi r7,0
833 beq 7f
834 mr r4,r3
8356: icbi 0,r4
836 add r4,r4,r6
837 cmplw r4,r5
838 blt 6b
8397: sync /* Wait for all icbi to complete on bus */
840 isync
841
842/*
843 * We are done. Do not return, instead branch to second part of board
844 * initialization, now running from RAM.
845 */
846
847 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
848 mtlr r0
849 blr
850
851in_ram:
852
853 /*
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100854 * Relocation Function, r12 point to got2+0x8000
wdenk47d1a6e2002-11-03 00:01:44 +0000855 *
wdenk57b2d802003-06-27 21:31:46 +0000856 * Adjust got2 pointers, no need to check for 0, this code
857 * already puts a few entries in the table.
wdenk47d1a6e2002-11-03 00:01:44 +0000858 */
859 li r0,__got2_entries@sectoff@l
860 la r3,GOT(_GOT2_TABLE_)
861 lwz r11,GOT(_GOT2_TABLE_)
862 mtctr r0
863 sub r11,r3,r11
864 addi r3,r3,-4
8651: lwzu r0,4(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200866 cmpwi r0,0
867 beq- 2f
wdenk47d1a6e2002-11-03 00:01:44 +0000868 add r0,r0,r11
869 stw r0,0(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +02008702: bdnz 1b
wdenk47d1a6e2002-11-03 00:01:44 +0000871
872 /*
wdenk57b2d802003-06-27 21:31:46 +0000873 * Now adjust the fixups and the pointers to the fixups
wdenk47d1a6e2002-11-03 00:01:44 +0000874 * in case we need to move ourselves again.
875 */
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200876 li r0,__fixup_entries@sectoff@l
wdenk47d1a6e2002-11-03 00:01:44 +0000877 lwz r3,GOT(_FIXUP_TABLE_)
878 cmpwi r0,0
879 mtctr r0
880 addi r3,r3,-4
881 beq 4f
8823: lwzu r4,4(r3)
883 lwzux r0,r4,r11
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200884 cmpwi r0,0
wdenk47d1a6e2002-11-03 00:01:44 +0000885 add r0,r0,r11
Joakim Tjernlund401b5922010-11-04 19:02:00 +0100886 stw r4,0(r3)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200887 beq- 5f
wdenk47d1a6e2002-11-03 00:01:44 +0000888 stw r0,0(r4)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +02008895: bdnz 3b
wdenk47d1a6e2002-11-03 00:01:44 +00008904:
891clear_bss:
892 /*
893 * Now clear BSS segment
894 */
wdenkbf2f8c92003-05-22 22:52:13 +0000895 lwz r3,GOT(__bss_start)
wdenk47d1a6e2002-11-03 00:01:44 +0000896#if defined(CONFIG_HYMOD)
897 /*
898 * For HYMOD - the environment is the very last item in flash.
899 * The real .bss stops just before environment starts, so only
900 * clear up to that point.
901 *
902 * taken from mods for FADS board
903 */
904 lwz r4,GOT(environment)
905#else
Simon Glassed70c8f2013-03-14 06:54:53 +0000906 lwz r4,GOT(__bss_end)
wdenk47d1a6e2002-11-03 00:01:44 +0000907#endif
908
909 cmplw 0, r3, r4
910 beq 6f
911
912 li r0, 0
9135:
914 stw r0, 0(r3)
915 addi r3, r3, 4
916 cmplw 0, r3, r4
917 bne 5b
9186:
919
920 mr r3, r9 /* Global Data pointer */
921 mr r4, r10 /* Destination Address */
922 bl board_init_r
923
wdenk47d1a6e2002-11-03 00:01:44 +0000924 /*
925 * Copy exception vector code to low memory
926 *
927 * r3: dest_addr
928 * r7: source address, r8: end address, r9: target address
929 */
930 .globl trap_init
931trap_init:
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100932 mflr r4 /* save link register */
933 GET_GOT
wdenk47d1a6e2002-11-03 00:01:44 +0000934 lwz r7, GOT(_start)
935 lwz r8, GOT(_end_of_vectors)
936
wdenk4e112c12003-06-03 23:54:09 +0000937 li r9, 0x100 /* reset vector always at 0x100 */
wdenk47d1a6e2002-11-03 00:01:44 +0000938
939 cmplw 0, r7, r8
940 bgelr /* return if r7>=r8 - just in case */
wdenk47d1a6e2002-11-03 00:01:44 +00009411:
942 lwz r0, 0(r7)
943 stw r0, 0(r9)
944 addi r7, r7, 4
945 addi r9, r9, 4
946 cmplw 0, r7, r8
947 bne 1b
948
949 /*
950 * relocate `hdlr' and `int_return' entries
951 */
952 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
953 li r8, Alignment - _start + EXC_OFF_SYS_RESET
9542:
955 bl trap_reloc
956 addi r7, r7, 0x100 /* next exception vector */
957 cmplw 0, r7, r8
958 blt 2b
959
960 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
961 bl trap_reloc
962
963 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
964 bl trap_reloc
965
966 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
967 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
9683:
969 bl trap_reloc
970 addi r7, r7, 0x100 /* next exception vector */
971 cmplw 0, r7, r8
972 blt 3b
973
974 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
975 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
9764:
977 bl trap_reloc
978 addi r7, r7, 0x100 /* next exception vector */
979 cmplw 0, r7, r8
980 blt 4b
981
982 mfmsr r3 /* now that the vectors have */
983 lis r7, MSR_IP@h /* relocated into low memory */
984 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
985 andc r3, r3, r7 /* (if it was on) */
986 SYNC /* Some chip revs need this... */
987 mtmsr r3
988 SYNC
989
990 mtlr r4 /* restore link register */
991 blr