]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/powerpc/cpu/mpc85xx/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / arch / powerpc / cpu / mpc85xx / start.S
CommitLineData
42d1f039 1/*
a4107f86 2 * Copyright 2004, 2007-2012 Freescale Semiconductor, Inc.
42d1f039 3 * Copyright (C) 2003 Motorola,Inc.
42d1f039 4 *
1a459660 5 * SPDX-License-Identifier: GPL-2.0+
42d1f039
WD
6 */
7
8/* U-Boot Startup Code for Motorola 85xx PowerPC based Embedded Boards
9 *
10 * The processor starts at 0xfffffffc and the code is first executed in the
11 * last 4K page(0xfffff000-0xffffffff) in flash/rom.
12 *
13 */
14
25ddd1fb 15#include <asm-offsets.h>
42d1f039
WD
16#include <config.h>
17#include <mpc85xx.h>
18#include <version.h>
19
20#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
21
22#include <ppc_asm.tmpl>
23#include <ppc_defs.h>
24
25#include <asm/cache.h>
26#include <asm/mmu.h>
27
42d1f039 28#undef MSR_KERNEL
61a21e98 29#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
42d1f039 30
4b919725
SW
31#if defined(CONFIG_NAND_SPL) || \
32 (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_INIT_MINIMAL))
33#define MINIMAL_SPL
34#endif
35
36#if !defined(CONFIG_SPL) && !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)
37#define NOR_BOOT
38#endif
39
42d1f039
WD
40/*
41 * Set up GOT: Global Offset Table
42 *
0f8aa159 43 * Use r12 to access the GOT
42d1f039
WD
44 */
45 START_GOT
46 GOT_ENTRY(_GOT2_TABLE_)
47 GOT_ENTRY(_FIXUP_TABLE_)
48
4b919725 49#ifndef MINIMAL_SPL
42d1f039
WD
50 GOT_ENTRY(_start)
51 GOT_ENTRY(_start_of_vectors)
52 GOT_ENTRY(_end_of_vectors)
53 GOT_ENTRY(transfer_to_handler)
7da53351 54#endif
42d1f039
WD
55
56 GOT_ENTRY(__init_end)
3929fb0a 57 GOT_ENTRY(__bss_end)
42d1f039
WD
58 GOT_ENTRY(__bss_start)
59 END_GOT
60
61/*
62 * e500 Startup -- after reset only the last 4KB of the effective
63 * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
64 * section is located at THIS LAST page and basically does three
65 * things: clear some registers, set up exception tables and
66 * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
67 * continue the boot procedure.
68
69 * Once the boot rom is mapped by TLB entries we can proceed
70 * with normal startup.
71 *
72 */
73
61a21e98
AF
74 .section .bootpg,"ax"
75 .globl _start_e500
42d1f039
WD
76
77_start_e500:
5344f7a2
PK
78/* Enable debug exception */
79 li r1,MSR_DE
80 mtmsr r1
97d80fc3 81
33eee330
SW
82#ifdef CONFIG_SYS_FSL_ERRATUM_A004510
83 mfspr r3,SPRN_SVR
84 rlwinm r3,r3,0,0xff
85 li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV
86 cmpw r3,r4
87 beq 1f
88
89#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2
90 li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2
91 cmpw r3,r4
92 beq 1f
93#endif
94
95 /* Not a supported revision affected by erratum */
96 li r27,0
97 b 2f
98
991: li r27,1 /* Remember for later that we have the erratum */
100 /* Erratum says set bits 55:60 to 001001 */
101 msync
102 isync
cd7ad629 103 mfspr r3,SPRN_HDBCR0
33eee330
SW
104 li r4,0x48
105 rlwimi r3,r4,0,0x1f8
cd7ad629 106 mtspr SPRN_HDBCR0,r3
33eee330
SW
107 isync
1082:
109#endif
110
7065b7d4
RG
111#if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC)
112 /* ISBC uses L2 as stack.
113 * Disable L2 cache here so that u-boot can enable it later
114 * as part of it's normal flow
115 */
116
117 /* Check if L2 is enabled */
118 mfspr r3, SPRN_L2CSR0
119 lis r2, L2CSR0_L2E@h
120 ori r2, r2, L2CSR0_L2E@l
121 and. r4, r3, r2
122 beq l2_disabled
123
124 mfspr r3, SPRN_L2CSR0
125 /* Flush L2 cache */
126 lis r2,(L2CSR0_L2FL)@h
127 ori r2, r2, (L2CSR0_L2FL)@l
128 or r3, r2, r3
129 sync
130 isync
131 mtspr SPRN_L2CSR0,r3
132 isync
1331:
134 mfspr r3, SPRN_L2CSR0
135 and. r1, r3, r2
136 bne 1b
137
138 mfspr r3, SPRN_L2CSR0
139 lis r2, L2CSR0_L2E@h
140 ori r2, r2, L2CSR0_L2E@l
141 andc r4, r3, r2
142 sync
143 isync
144 mtspr SPRN_L2CSR0,r4
145 isync
146
147l2_disabled:
148#endif
149
61a21e98 150/* clear registers/arrays not reset by hardware */
42d1f039 151
61a21e98
AF
152 /* L1 */
153 li r0,2
154 mtspr L1CSR0,r0 /* invalidate d-cache */
53677ef1 155 mtspr L1CSR1,r0 /* invalidate i-cache */
42d1f039
WD
156
157 mfspr r1,DBSR
158 mtspr DBSR,r1 /* Clear all valid bits */
159
42d1f039 160
69c78267
YS
161 .macro create_tlb1_entry esel ts tsize epn wimg rpn perm phy_high scratch
162 lis \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@h
163 ori \scratch, \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@l
164 mtspr MAS0, \scratch
165 lis \scratch, FSL_BOOKE_MAS1(1, 1, 0, \ts, \tsize)@h
166 ori \scratch, \scratch, FSL_BOOKE_MAS1(1, 1, 0, \ts, \tsize)@l
167 mtspr MAS1, \scratch
168 lis \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@h
169 ori \scratch, \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@l
170 mtspr MAS2, \scratch
171 lis \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@h
172 ori \scratch, \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@l
173 mtspr MAS3, \scratch
174 lis \scratch, \phy_high@h
175 ori \scratch, \scratch, \phy_high@l
176 mtspr MAS7, \scratch
177 isync
178 msync
179 tlbwe
180 isync
181 .endm
182
183 .macro create_tlb0_entry esel ts tsize epn wimg rpn perm phy_high scratch
184 lis \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@h
185 ori \scratch, \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@l
186 mtspr MAS0, \scratch
187 lis \scratch, FSL_BOOKE_MAS1(1, 0, 0, \ts, \tsize)@h
188 ori \scratch, \scratch, FSL_BOOKE_MAS1(1, 0, 0, \ts, \tsize)@l
189 mtspr MAS1, \scratch
190 lis \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@h
191 ori \scratch, \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@l
192 mtspr MAS2, \scratch
193 lis \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@h
194 ori \scratch, \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@l
195 mtspr MAS3, \scratch
196 lis \scratch, \phy_high@h
197 ori \scratch, \scratch, \phy_high@l
198 mtspr MAS7, \scratch
199 isync
200 msync
201 tlbwe
202 isync
203 .endm
204
205 .macro delete_tlb1_entry esel scratch
206 lis \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@h
207 ori \scratch, \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@l
208 mtspr MAS0, \scratch
209 li \scratch, 0
210 mtspr MAS1, \scratch
211 isync
212 msync
213 tlbwe
214 isync
215 .endm
216
217 .macro delete_tlb0_entry esel epn wimg scratch
218 lis \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@h
219 ori \scratch, \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@l
220 mtspr MAS0, \scratch
221 li \scratch, 0
222 mtspr MAS1, \scratch
223 lis \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@h
224 ori \scratch, \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@l
225 mtspr MAS2, \scratch
226 isync
227 msync
228 tlbwe
229 isync
230 .endm
231
4b919725
SW
232/* Interrupt vectors do not fit in minimal SPL. */
233#if !defined(MINIMAL_SPL)
42d1f039 234 /* Setup interrupt vectors */
0635b09c 235 lis r1,CONFIG_SYS_MONITOR_BASE@h
61a21e98 236 mtspr IVPR,r1
42d1f039 237
a4107f86
PK
238 lis r3,(CONFIG_SYS_MONITOR_BASE & 0xffff)@h
239 ori r3,r3,(CONFIG_SYS_MONITOR_BASE & 0xffff)@l
240
241 addi r4,r3,CriticalInput - _start + _START_OFFSET
242 mtspr IVOR0,r4 /* 0: Critical input */
243 addi r4,r3,MachineCheck - _start + _START_OFFSET
244 mtspr IVOR1,r4 /* 1: Machine check */
245 addi r4,r3,DataStorage - _start + _START_OFFSET
246 mtspr IVOR2,r4 /* 2: Data storage */
247 addi r4,r3,InstStorage - _start + _START_OFFSET
248 mtspr IVOR3,r4 /* 3: Instruction storage */
249 addi r4,r3,ExtInterrupt - _start + _START_OFFSET
250 mtspr IVOR4,r4 /* 4: External interrupt */
251 addi r4,r3,Alignment - _start + _START_OFFSET
252 mtspr IVOR5,r4 /* 5: Alignment */
253 addi r4,r3,ProgramCheck - _start + _START_OFFSET
254 mtspr IVOR6,r4 /* 6: Program check */
255 addi r4,r3,FPUnavailable - _start + _START_OFFSET
256 mtspr IVOR7,r4 /* 7: floating point unavailable */
257 addi r4,r3,SystemCall - _start + _START_OFFSET
258 mtspr IVOR8,r4 /* 8: System call */
42d1f039 259 /* 9: Auxiliary processor unavailable(unsupported) */
a4107f86
PK
260 addi r4,r3,Decrementer - _start + _START_OFFSET
261 mtspr IVOR10,r4 /* 10: Decrementer */
262 addi r4,r3,IntervalTimer - _start + _START_OFFSET
263 mtspr IVOR11,r4 /* 11: Interval timer */
264 addi r4,r3,WatchdogTimer - _start + _START_OFFSET
265 mtspr IVOR12,r4 /* 12: Watchdog timer */
266 addi r4,r3,DataTLBError - _start + _START_OFFSET
267 mtspr IVOR13,r4 /* 13: Data TLB error */
268 addi r4,r3,InstructionTLBError - _start + _START_OFFSET
269 mtspr IVOR14,r4 /* 14: Instruction TLB error */
270 addi r4,r3,DebugBreakpoint - _start + _START_OFFSET
271 mtspr IVOR15,r4 /* 15: Debug */
119a55f9 272#endif
42d1f039 273
42d1f039 274 /* Clear and set up some registers. */
87163180 275 li r0,0x0000
42d1f039
WD
276 lis r1,0xffff
277 mtspr DEC,r0 /* prevent dec exceptions */
278 mttbl r0 /* prevent fit & wdt exceptions */
279 mttbu r0
280 mtspr TSR,r1 /* clear all timer exception status */
281 mtspr TCR,r0 /* disable all */
282 mtspr ESR,r0 /* clear exception syndrome register */
283 mtspr MCSR,r0 /* machine check syndrome register */
284 mtxer r0 /* clear integer exception register */
42d1f039 285
dcc87dd5
SW
286#ifdef CONFIG_SYS_BOOK3E_HV
287 mtspr MAS8,r0 /* make sure MAS8 is clear */
288#endif
289
42d1f039 290 /* Enable Time Base and Select Time Base Clock */
0ac6f8b7 291 lis r0,HID0_EMCP@h /* Enable machine check */
d9b94f28 292#if defined(CONFIG_ENABLE_36BIT_PHYS)
87163180 293 ori r0,r0,HID0_ENMAS7@l /* Enable MAS7 */
d9b94f28 294#endif
1b3e4044 295#ifndef CONFIG_E500MC
87163180 296 ori r0,r0,HID0_TBEN@l /* Enable Timebase */
1b3e4044 297#endif
42d1f039 298 mtspr HID0,r0
42d1f039 299
0f060c3b 300#ifndef CONFIG_E500MC
61a21e98 301 li r0,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */
ff8473e9
SG
302 mfspr r3,PVR
303 andi. r3,r3, 0xff
304 cmpwi r3,0x50@l /* if we are rev 5.0 or greater set MBDD */
305 blt 1f
306 /* Set MBDD bit also */
307 ori r0, r0, HID1_MBDD@l
3081:
42d1f039 309 mtspr HID1,r0
0f060c3b 310#endif
42d1f039 311
43f082bb 312#ifdef CONFIG_SYS_FSL_ERRATUM_CPU_A003999
cd7ad629 313 mfspr r3,SPRN_HDBCR1
43f082bb 314 oris r3,r3,0x0100
cd7ad629 315 mtspr SPRN_HDBCR1,r3
43f082bb
KG
316#endif
317
42d1f039
WD
318 /* Enable Branch Prediction */
319#if defined(CONFIG_BTB)
69bcf5bc
KG
320 lis r0,BUCSR_ENABLE@h
321 ori r0,r0,BUCSR_ENABLE@l
322 mtspr SPRN_BUCSR,r0
42d1f039
WD
323#endif
324
6d0f6bcf 325#if defined(CONFIG_SYS_INIT_DBCR)
42d1f039
WD
326 lis r1,0xffff
327 ori r1,r1,0xffff
0ac6f8b7 328 mtspr DBSR,r1 /* Clear all status bits */
6d0f6bcf
JCPV
329 lis r0,CONFIG_SYS_INIT_DBCR@h /* DBCR0[IDM] must be set */
330 ori r0,r0,CONFIG_SYS_INIT_DBCR@l
0ac6f8b7 331 mtspr DBCR0,r0
42d1f039
WD
332#endif
333
22b6dbc1
HW
334#ifdef CONFIG_MPC8569
335#define CONFIG_SYS_LBC_ADDR (CONFIG_SYS_CCSRBAR_DEFAULT + 0x5000)
336#define CONFIG_SYS_LBCR_ADDR (CONFIG_SYS_LBC_ADDR + 0xd0)
337
338 /* MPC8569 Rev.0 silcon needs to set bit 13 of LBCR to allow elBC to
339 * use address space which is more than 12bits, and it must be done in
340 * the 4K boot page. So we set this bit here.
341 */
342
343 /* create a temp mapping TLB0[0] for LBCR */
69c78267
YS
344 create_tlb0_entry 0, \
345 0, BOOKE_PAGESZ_4K, \
346 CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G, \
347 CONFIG_SYS_LBC_ADDR, MAS3_SW|MAS3_SR, \
348 0, r6
22b6dbc1
HW
349
350 /* Set LBCR register */
351 lis r4,CONFIG_SYS_LBCR_ADDR@h
352 ori r4,r4,CONFIG_SYS_LBCR_ADDR@l
353
354 lis r5,CONFIG_SYS_LBC_LBCR@h
355 ori r5,r5,CONFIG_SYS_LBC_LBCR@l
356 stw r5,0(r4)
357 isync
358
359 /* invalidate this temp TLB */
360 lis r4,CONFIG_SYS_LBC_ADDR@h
361 ori r4,r4,CONFIG_SYS_LBC_ADDR@l
362 tlbivax 0,r4
363 isync
364
365#endif /* CONFIG_MPC8569 */
366
72243c01
TT
367/*
368 * Search for the TLB that covers the code we're executing, and shrink it
369 * so that it covers only this 4K page. That will ensure that any other
370 * TLB we create won't interfere with it. We assume that the TLB exists,
3ea21536
SW
371 * which is why we don't check the Valid bit of MAS1. We also assume
372 * it is in TLB1.
72243c01
TT
373 *
374 * This is necessary, for example, when booting from the on-chip ROM,
375 * which (oddly) creates a single 4GB TLB that covers CCSR and DDR.
72243c01
TT
376 */
377 bl nexti /* Find our address */
378nexti: mflr r1 /* R1 = our PC */
379 li r2, 0
380 mtspr MAS6, r2 /* Assume the current PID and AS are 0 */
381 isync
382 msync
383 tlbsx 0, r1 /* This must succeed */
384
3ea21536
SW
385 mfspr r14, MAS0 /* Save ESEL for later */
386 rlwinm r14, r14, 16, 0xfff
387
72243c01
TT
388 /* Set the size of the TLB to 4KB */
389 mfspr r3, MAS1
31d084dd 390 li r2, 0xF80
72243c01
TT
391 andc r3, r3, r2 /* Clear the TSIZE bits */
392 ori r3, r3, MAS1_TSIZE(BOOKE_PAGESZ_4K)@l
3ea21536 393 oris r3, r3, MAS1_IPROT@h
72243c01
TT
394 mtspr MAS1, r3
395
396 /*
397 * Set the base address of the TLB to our PC. We assume that
398 * virtual == physical. We also assume that MAS2_EPN == MAS3_RPN.
399 */
400 lis r3, MAS2_EPN@h
401 ori r3, r3, MAS2_EPN@l /* R3 = MAS2_EPN */
402
403 and r1, r1, r3 /* Our PC, rounded down to the nearest page */
404
405 mfspr r2, MAS2
406 andc r2, r2, r3
407 or r2, r2, r1
33eee330
SW
408#ifdef CONFIG_SYS_FSL_ERRATUM_A004510
409 cmpwi r27,0
410 beq 1f
411 andi. r15, r2, MAS2_I|MAS2_G /* save the old I/G for later */
412 rlwinm r2, r2, 0, ~MAS2_I
413 ori r2, r2, MAS2_G
4141:
415#endif
72243c01
TT
416 mtspr MAS2, r2 /* Set the EPN to our PC base address */
417
418 mfspr r2, MAS3
419 andc r2, r2, r3
420 or r2, r2, r1
421 mtspr MAS3, r2 /* Set the RPN to our PC base address */
422
423 isync
424 msync
425 tlbwe
426
3ea21536
SW
427/*
428 * Clear out any other TLB entries that may exist, to avoid conflicts.
429 * Our TLB entry is in r14.
430 */
431 li r0, TLBIVAX_ALL | TLBIVAX_TLB0
432 tlbivax 0, r0
433 tlbsync
434
435 mfspr r4, SPRN_TLB1CFG
436 rlwinm r4, r4, 0, TLBnCFG_NENTRY_MASK
437
438 li r3, 0
439 mtspr MAS1, r3
4401: cmpw r3, r14
3ea21536
SW
441 rlwinm r5, r3, 16, MAS0_ESEL_MSK
442 addi r3, r3, 1
443 beq 2f /* skip the entry we're executing from */
444
445 oris r5, r5, MAS0_TLBSEL(1)@h
446 mtspr MAS0, r5
447
448 isync
449 tlbwe
450 isync
451 msync
452
4532: cmpw r3, r4
454 blt 1b
455
f545d300
SW
456#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(MINIMAL_SPL)
457/*
458 * TLB entry for debuggging in AS1
459 * Create temporary TLB entry in AS0 to handle debug exception
460 * As on debug exception MSR is cleared i.e. Address space is changed
461 * to 0. A TLB entry (in AS0) is required to handle debug exception generated
462 * in AS1.
463 */
464
4b919725 465#ifdef NOR_BOOT
f545d300
SW
466/*
467 * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
468 * bacause flash's virtual address maps to 0xff800000 - 0xffffffff.
469 * and this window is outside of 4K boot window.
470 */
471 create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
472 0, BOOKE_PAGESZ_4M, \
473 CONFIG_SYS_MONITOR_BASE & 0xffc00000, MAS2_I|MAS2_G, \
474 0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \
475 0, r6
476
477#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
478 create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
479 0, BOOKE_PAGESZ_1M, \
480 CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
481 CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \
482 0, r6
483#else
484/*
485 * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
486 * because "nexti" will resize TLB to 4K
487 */
488 create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
489 0, BOOKE_PAGESZ_256K, \
490 CONFIG_SYS_MONITOR_BASE & 0xfffc0000, MAS2_I, \
491 CONFIG_SYS_MONITOR_BASE & 0xfffc0000, MAS3_SX|MAS3_SW|MAS3_SR, \
492 0, r6
493#endif
494#endif
495
6ca88b09
TT
496/*
497 * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default
498 * location is not where we want it. This typically happens on a 36-bit
499 * system, where we want to move CCSR to near the top of 36-bit address space.
500 *
501 * To move CCSR, we create two temporary TLBs, one for the old location, and
502 * another for the new location. On CoreNet systems, we also need to create
503 * a special, temporary LAW.
504 *
505 * As a general rule, TLB0 is used for short-term TLBs, and TLB1 is used for
506 * long-term TLBs, so we use TLB0 here.
507 */
508#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS)
509
510#if !defined(CONFIG_SYS_CCSRBAR_PHYS_HIGH) || !defined(CONFIG_SYS_CCSRBAR_PHYS_LOW)
511#error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined."
512#endif
513
6ca88b09
TT
514create_ccsr_new_tlb:
515 /*
516 * Create a TLB for the new location of CCSR. Register R8 is reserved
517 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR).
518 */
3ea21536
SW
519 lis r8, CONFIG_SYS_CCSRBAR@h
520 ori r8, r8, CONFIG_SYS_CCSRBAR@l
521 lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h
522 ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l
69c78267
YS
523 create_tlb0_entry 0, \
524 0, BOOKE_PAGESZ_4K, \
525 CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G, \
526 CONFIG_SYS_CCSRBAR_PHYS_LOW, MAS3_SW|MAS3_SR, \
527 CONFIG_SYS_CCSRBAR_PHYS_HIGH, r3
6ca88b09 528 /*
c2efa0aa 529 * Create a TLB for the current location of CCSR. Register R9 is reserved
6ca88b09
TT
530 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR + 0x1000).
531 */
532create_ccsr_old_tlb:
69c78267
YS
533 create_tlb0_entry 1, \
534 0, BOOKE_PAGESZ_4K, \
535 CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G, \
536 CONFIG_SYS_CCSRBAR_DEFAULT, MAS3_SW|MAS3_SR, \
537 0, r3 /* The default CCSR address is always a 32-bit number */
538
6ca88b09 539
19e43841
TT
540 /*
541 * We have a TLB for what we think is the current (old) CCSR. Let's
542 * verify that, otherwise we won't be able to move it.
543 * CONFIG_SYS_CCSRBAR_DEFAULT is always a 32-bit number, so we only
544 * need to compare the lower 32 bits of CCSRBAR on CoreNet systems.
545 */
546verify_old_ccsr:
547 lis r0, CONFIG_SYS_CCSRBAR_DEFAULT@h
548 ori r0, r0, CONFIG_SYS_CCSRBAR_DEFAULT@l
549#ifdef CONFIG_FSL_CORENET
550 lwz r1, 4(r9) /* CCSRBARL */
551#else
552 lwz r1, 0(r9) /* CCSRBAR, shifted right by 12 */
553 slwi r1, r1, 12
554#endif
555
556 cmpl 0, r0, r1
557
558 /*
559 * If the value we read from CCSRBARL is not what we expect, then
560 * enter an infinite loop. This will at least allow a debugger to
561 * halt execution and examine TLBs, etc. There's no point in going
562 * on.
563 */
564infinite_debug_loop:
565 bne infinite_debug_loop
566
6ca88b09
TT
567#ifdef CONFIG_FSL_CORENET
568
569#define CCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000)
570#define LAW_EN 0x80000000
571#define LAW_SIZE_4K 0xb
572#define CCSRBAR_LAWAR (LAW_EN | (0x1e << 20) | LAW_SIZE_4K)
573#define CCSRAR_C 0x80000000 /* Commit */
574
575create_temp_law:
576 /*
577 * On CoreNet systems, we create the temporary LAW using a special LAW
578 * target ID of 0x1e. LAWBARH is at offset 0xc00 in CCSR.
579 */
580 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h
581 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
582 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
583 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
584 lis r2, CCSRBAR_LAWAR@h
585 ori r2, r2, CCSRBAR_LAWAR@l
586
587 stw r0, 0xc00(r9) /* LAWBARH0 */
588 stw r1, 0xc04(r9) /* LAWBARL0 */
589 sync
590 stw r2, 0xc08(r9) /* LAWAR0 */
591
592 /*
593 * Read back from LAWAR to ensure the update is complete. e500mc
594 * cores also require an isync.
595 */
596 lwz r0, 0xc08(r9) /* LAWAR0 */
597 isync
598
599 /*
600 * Read the current CCSRBARH and CCSRBARL using load word instructions.
601 * Follow this with an isync instruction. This forces any outstanding
602 * accesses to configuration space to completion.
603 */
604read_old_ccsrbar:
605 lwz r0, 0(r9) /* CCSRBARH */
c2efa0aa 606 lwz r0, 4(r9) /* CCSRBARL */
6ca88b09
TT
607 isync
608
609 /*
610 * Write the new values for CCSRBARH and CCSRBARL to their old
611 * locations. The CCSRBARH has a shadow register. When the CCSRBARH
612 * has a new value written it loads a CCSRBARH shadow register. When
613 * the CCSRBARL is written, the CCSRBARH shadow register contents
614 * along with the CCSRBARL value are loaded into the CCSRBARH and
615 * CCSRBARL registers, respectively. Follow this with a sync
616 * instruction.
617 */
618write_new_ccsrbar:
619 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h
620 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
621 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
622 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
623 lis r2, CCSRAR_C@h
624 ori r2, r2, CCSRAR_C@l
625
626 stw r0, 0(r9) /* Write to CCSRBARH */
627 sync /* Make sure we write to CCSRBARH first */
628 stw r1, 4(r9) /* Write to CCSRBARL */
629 sync
630
631 /*
632 * Write a 1 to the commit bit (C) of CCSRAR at the old location.
633 * Follow this with a sync instruction.
634 */
635 stw r2, 8(r9)
636 sync
637
638 /* Delete the temporary LAW */
639delete_temp_law:
640 li r1, 0
641 stw r1, 0xc08(r8)
642 sync
643 stw r1, 0xc00(r8)
644 stw r1, 0xc04(r8)
645 sync
646
647#else /* #ifdef CONFIG_FSL_CORENET */
648
649write_new_ccsrbar:
650 /*
651 * Read the current value of CCSRBAR using a load word instruction
652 * followed by an isync. This forces all accesses to configuration
653 * space to complete.
654 */
655 sync
656 lwz r0, 0(r9)
657 isync
658
659/* CONFIG_SYS_CCSRBAR_PHYS right shifted by 12 */
660#define CCSRBAR_PHYS_RS12 ((CONFIG_SYS_CCSRBAR_PHYS_HIGH << 20) | \
661 (CONFIG_SYS_CCSRBAR_PHYS_LOW >> 12))
662
663 /* Write the new value to CCSRBAR. */
664 lis r0, CCSRBAR_PHYS_RS12@h
665 ori r0, r0, CCSRBAR_PHYS_RS12@l
666 stw r0, 0(r9)
667 sync
668
669 /*
670 * The manual says to perform a load of an address that does not
671 * access configuration space or the on-chip SRAM using an existing TLB,
672 * but that doesn't appear to be necessary. We will do the isync,
673 * though.
674 */
675 isync
676
677 /*
678 * Read the contents of CCSRBAR from its new location, followed by
679 * another isync.
680 */
681 lwz r0, 0(r8)
682 isync
683
684#endif /* #ifdef CONFIG_FSL_CORENET */
685
686 /* Delete the temporary TLBs */
687delete_temp_tlbs:
69c78267
YS
688 delete_tlb0_entry 0, CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G, r3
689 delete_tlb0_entry 1, CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G, r3
6ca88b09 690
6ca88b09
TT
691#endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */
692
6d2b9da1
YS
693#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
694create_ccsr_l2_tlb:
695 /*
696 * Create a TLB for the MMR location of CCSR
697 * to access L2CSR0 register
698 */
699 create_tlb0_entry 0, \
700 0, BOOKE_PAGESZ_4K, \
701 CONFIG_SYS_CCSRBAR + 0xC20000, MAS2_I|MAS2_G, \
702 CONFIG_SYS_CCSRBAR_PHYS_LOW + 0xC20000, MAS3_SW|MAS3_SR, \
703 CONFIG_SYS_CCSRBAR_PHYS_HIGH, r3
704
705enable_l2_cluster_l2:
706 /* enable L2 cache */
707 lis r3, (CONFIG_SYS_CCSRBAR + 0xC20000)@h
708 ori r3, r3, (CONFIG_SYS_CCSRBAR + 0xC20000)@l
709 li r4, 33 /* stash id */
710 stw r4, 4(r3)
711 lis r4, (L2CSR0_L2FI|L2CSR0_L2LFC)@h
712 ori r4, r4, (L2CSR0_L2FI|L2CSR0_L2LFC)@l
713 sync
714 stw r4, 0(r3) /* invalidate L2 */
7151: sync
716 lwz r0, 0(r3)
717 twi 0, r0, 0
718 isync
719 and. r1, r0, r4
720 bne 1b
c416faf8 721 lis r4, (L2CSR0_L2E|L2CSR0_L2PE)@h
9cd95ac7 722 ori r4, r4, (L2CSR0_L2REP_MODE)@l
6d2b9da1 723 sync
3e4c3137 724 stw r4, 0(r3) /* enable L2 */
6d2b9da1
YS
725delete_ccsr_l2_tlb:
726 delete_tlb0_entry 0, CONFIG_SYS_CCSRBAR + 0xC20000, MAS2_I|MAS2_G, r3
727#endif
728
3e4c3137
AF
729 /*
730 * Enable the L1. On e6500, this has to be done
731 * after the L2 is up.
732 */
733
734#ifdef CONFIG_SYS_CACHE_STASHING
735 /* set stash id to (coreID) * 2 + 32 + L1 CT (0) */
736 li r2,(32 + 0)
737 mtspr L1CSR2,r2
738#endif
739
740 /* Enable/invalidate the I-Cache */
741 lis r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@h
742 ori r2,r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@l
743 mtspr SPRN_L1CSR1,r2
7441:
745 mfspr r3,SPRN_L1CSR1
746 and. r1,r3,r2
747 bne 1b
748
749 lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h
750 ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l
751 mtspr SPRN_L1CSR1,r3
752 isync
7532:
754 mfspr r3,SPRN_L1CSR1
755 andi. r1,r3,L1CSR1_ICE@l
756 beq 2b
757
758 /* Enable/invalidate the D-Cache */
759 lis r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@h
760 ori r2,r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@l
761 mtspr SPRN_L1CSR0,r2
7621:
763 mfspr r3,SPRN_L1CSR0
764 and. r1,r3,r2
765 bne 1b
766
767 lis r3,(L1CSR0_CPE|L1CSR0_DCE)@h
768 ori r3,r3,(L1CSR0_CPE|L1CSR0_DCE)@l
769 mtspr SPRN_L1CSR0,r3
770 isync
7712:
772 mfspr r3,SPRN_L1CSR0
773 andi. r1,r3,L1CSR0_DCE@l
774 beq 2b
33eee330
SW
775#ifdef CONFIG_SYS_FSL_ERRATUM_A004510
776#define DCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000)
777#define LAW_SIZE_1M 0x13
778#define DCSRBAR_LAWAR (LAW_EN | (0x1d << 20) | LAW_SIZE_1M)
779
780 cmpwi r27,0
781 beq 9f
782
783 /*
784 * Create a TLB entry for CCSR
785 *
786 * We're executing out of TLB1 entry in r14, and that's the only
787 * TLB entry that exists. To allocate some TLB entries for our
788 * own use, flip a bit high enough that we won't flip it again
789 * via incrementing.
790 */
791
792 xori r8, r14, 32
793 lis r0, MAS0_TLBSEL(1)@h
794 rlwimi r0, r8, 16, MAS0_ESEL_MSK
795 lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@h
796 ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@l
797 lis r7, CONFIG_SYS_CCSRBAR@h
798 ori r7, r7, CONFIG_SYS_CCSRBAR@l
799 ori r2, r7, MAS2_I|MAS2_G
800 lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h
801 ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l
802 lis r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h
803 ori r4, r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
804 mtspr MAS0, r0
805 mtspr MAS1, r1
806 mtspr MAS2, r2
807 mtspr MAS3, r3
808 mtspr MAS7, r4
809 isync
810 tlbwe
811 isync
812 msync
813
814 /* Map DCSR temporarily to physical address zero */
815 li r0, 0
816 lis r3, DCSRBAR_LAWAR@h
817 ori r3, r3, DCSRBAR_LAWAR@l
818
819 stw r0, 0xc00(r7) /* LAWBARH0 */
820 stw r0, 0xc04(r7) /* LAWBARL0 */
821 sync
822 stw r3, 0xc08(r7) /* LAWAR0 */
823
824 /* Read back from LAWAR to ensure the update is complete. */
825 lwz r3, 0xc08(r7) /* LAWAR0 */
826 isync
827
828 /* Create a TLB entry for DCSR at zero */
829
830 addi r9, r8, 1
831 lis r0, MAS0_TLBSEL(1)@h
832 rlwimi r0, r9, 16, MAS0_ESEL_MSK
833 lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@h
834 ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@l
835 li r6, 0 /* DCSR effective address */
836 ori r2, r6, MAS2_I|MAS2_G
837 li r3, MAS3_SW|MAS3_SR
838 li r4, 0
839 mtspr MAS0, r0
840 mtspr MAS1, r1
841 mtspr MAS2, r2
842 mtspr MAS3, r3
843 mtspr MAS7, r4
844 isync
845 tlbwe
846 isync
847 msync
848
849 /* enable the timebase */
850#define CTBENR 0xe2084
851 li r3, 1
852 addis r4, r7, CTBENR@ha
853 stw r3, CTBENR@l(r4)
854 lwz r3, CTBENR@l(r4)
855 twi 0,r3,0
856 isync
857
858 .macro erratum_set_ccsr offset value
859 addis r3, r7, \offset@ha
860 lis r4, \value@h
861 addi r3, r3, \offset@l
862 ori r4, r4, \value@l
863 bl erratum_set_value
864 .endm
865
866 .macro erratum_set_dcsr offset value
867 addis r3, r6, \offset@ha
868 lis r4, \value@h
869 addi r3, r3, \offset@l
870 ori r4, r4, \value@l
871 bl erratum_set_value
872 .endm
873
874 erratum_set_dcsr 0xb0e08 0xe0201800
875 erratum_set_dcsr 0xb0e18 0xe0201800
876 erratum_set_dcsr 0xb0e38 0xe0400000
877 erratum_set_dcsr 0xb0008 0x00900000
878 erratum_set_dcsr 0xb0e40 0xe00a0000
879 erratum_set_ccsr 0x18600 CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY
880 erratum_set_ccsr 0x10f00 0x415e5000
881 erratum_set_ccsr 0x11f00 0x415e5000
882
883 /* Make temp mapping uncacheable again, if it was initially */
884 bl 2f
8852: mflr r3
886 tlbsx 0, r3
887 mfspr r4, MAS2
888 rlwimi r4, r15, 0, MAS2_I
889 rlwimi r4, r15, 0, MAS2_G
890 mtspr MAS2, r4
891 isync
892 tlbwe
893 isync
894 msync
895
896 /* Clear the cache */
897 lis r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@h
898 ori r3,r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@l
899 sync
900 isync
901 mtspr SPRN_L1CSR1,r3
902 isync
9032: sync
904 mfspr r4,SPRN_L1CSR1
905 and. r4,r4,r3
906 bne 2b
907
908 lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h
909 ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l
910 sync
911 isync
912 mtspr SPRN_L1CSR1,r3
913 isync
9142: sync
915 mfspr r4,SPRN_L1CSR1
916 and. r4,r4,r3
917 beq 2b
918
919 /* Remove temporary mappings */
920 lis r0, MAS0_TLBSEL(1)@h
921 rlwimi r0, r9, 16, MAS0_ESEL_MSK
922 li r3, 0
923 mtspr MAS0, r0
924 mtspr MAS1, r3
925 isync
926 tlbwe
927 isync
928 msync
929
930 li r3, 0
931 stw r3, 0xc08(r7) /* LAWAR0 */
932 lwz r3, 0xc08(r7)
933 isync
934
935 lis r0, MAS0_TLBSEL(1)@h
936 rlwimi r0, r8, 16, MAS0_ESEL_MSK
937 li r3, 0
938 mtspr MAS0, r0
939 mtspr MAS1, r3
940 isync
941 tlbwe
942 isync
943 msync
944
945 b 9f
946
947 /* r3 = addr, r4 = value, clobbers r5, r11, r12 */
948erratum_set_value:
949 /* Lock two cache lines into I-Cache */
950 sync
951 mfspr r11, SPRN_L1CSR1
952 rlwinm r11, r11, 0, ~L1CSR1_ICUL
953 sync
954 isync
955 mtspr SPRN_L1CSR1, r11
956 isync
957
958 mflr r12
959 bl 5f
9605: mflr r5
961 addi r5, r5, 2f - 5b
962 icbtls 0, 0, r5
963 addi r5, r5, 64
964
965 sync
966 mfspr r11, SPRN_L1CSR1
9673: andi. r11, r11, L1CSR1_ICUL
968 bne 3b
969
970 icbtls 0, 0, r5
971 addi r5, r5, 64
972
973 sync
974 mfspr r11, SPRN_L1CSR1
9753: andi. r11, r11, L1CSR1_ICUL
976 bne 3b
977
978 b 2f
979 .align 6
980 /* Inside a locked cacheline, wait a while, write, then wait a while */
9812: sync
982
983 mfspr r5, SPRN_TBRL
984 addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */
9854: mfspr r5, SPRN_TBRL
986 subf. r5, r5, r11
987 bgt 4b
988
989 stw r4, 0(r3)
990
991 mfspr r5, SPRN_TBRL
992 addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */
9934: mfspr r5, SPRN_TBRL
994 subf. r5, r5, r11
995 bgt 4b
996
997 sync
998
999 /*
1000 * Fill out the rest of this cache line and the next with nops,
1001 * to ensure that nothing outside the locked area will be
1002 * fetched due to a branch.
1003 */
1004 .rept 19
1005 nop
1006 .endr
1007
1008 sync
1009 mfspr r11, SPRN_L1CSR1
1010 rlwinm r11, r11, 0, ~L1CSR1_ICUL
1011 sync
1012 isync
1013 mtspr SPRN_L1CSR1, r11
1014 isync
1015
1016 mtlr r12
1017 blr
1018
10199:
1020#endif
1021
6ca88b09 1022create_init_ram_area:
87163180
KG
1023 lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h
1024 ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l
1025
4b919725 1026#ifdef NOR_BOOT
7da53351 1027 /* create a temp mapping in AS=1 to the 4M boot window */
69c78267
YS
1028 create_tlb1_entry 15, \
1029 1, BOOKE_PAGESZ_4M, \
1030 CONFIG_SYS_MONITOR_BASE & 0xffc00000, MAS2_I|MAS2_G, \
1031 0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \
1032 0, r6
87163180 1033
7065b7d4
RG
1034#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
1035 /* create a temp mapping in AS = 1 for Flash mapping
1036 * created by PBL for ISBC code
1037 */
69c78267
YS
1038 create_tlb1_entry 15, \
1039 1, BOOKE_PAGESZ_1M, \
7f0a22ff
SW
1040 CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
1041 CONFIG_SYS_PBI_FLASH_WINDOW & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
69c78267 1042 0, r6
7da53351
MH
1043#else
1044 /*
0635b09c
HW
1045 * create a temp mapping in AS=1 to the 1M CONFIG_SYS_MONITOR_BASE space, the main
1046 * image has been relocated to CONFIG_SYS_MONITOR_BASE on the second stage.
7da53351 1047 */
69c78267
YS
1048 create_tlb1_entry 15, \
1049 1, BOOKE_PAGESZ_1M, \
7f0a22ff
SW
1050 CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
1051 CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
69c78267 1052 0, r6
7da53351 1053#endif
87163180 1054
87163180 1055 /* create a temp mapping in AS=1 to the stack */
a3f18529
YS
1056#if defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW) && \
1057 defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH)
69c78267
YS
1058 create_tlb1_entry 14, \
1059 1, BOOKE_PAGESZ_16K, \
1060 CONFIG_SYS_INIT_RAM_ADDR, 0, \
1061 CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, MAS3_SX|MAS3_SW|MAS3_SR, \
1062 CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH, r6
1063
a3f18529 1064#else
69c78267
YS
1065 create_tlb1_entry 14, \
1066 1, BOOKE_PAGESZ_16K, \
1067 CONFIG_SYS_INIT_RAM_ADDR, 0, \
1068 CONFIG_SYS_INIT_RAM_ADDR, MAS3_SX|MAS3_SW|MAS3_SR, \
1069 0, r6
a3f18529 1070#endif
87163180 1071
5344f7a2
PK
1072 lis r6,MSR_IS|MSR_DS|MSR_DE@h
1073 ori r6,r6,MSR_IS|MSR_DS|MSR_DE@l
87163180
KG
1074 lis r7,switch_as@h
1075 ori r7,r7,switch_as@l
1076
1077 mtspr SPRN_SRR0,r7
1078 mtspr SPRN_SRR1,r6
1079 rfi
1080
1081switch_as:
3db0bef5
KG
1082/* L1 DCache is used for initial RAM */
1083
1084 /* Allocate Initial RAM in data cache.
1085 */
6d0f6bcf
JCPV
1086 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
1087 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
b009f3ec
KG
1088 mfspr r2, L1CFG0
1089 andi. r2, r2, 0x1ff
1090 /* cache size * 1024 / (2 * L1 line size) */
1091 slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT)
3db0bef5
KG
1092 mtctr r2
1093 li r0,0
10941:
1095 dcbz r0,r3
1096 dcbtls 0,r0,r3
6d0f6bcf 1097 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
3db0bef5
KG
1098 bdnz 1b
1099
61a21e98 1100 /* Jump out the last 4K page and continue to 'normal' start */
4b919725
SW
1101#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
1102 /* We assume that we're already running at the address we're linked at */
61a21e98 1103 b _start_cont
3db0bef5
KG
1104#else
1105 /* Calculate absolute address in FLASH and jump there */
1106 /*--------------------------------------------------------------*/
6d0f6bcf
JCPV
1107 lis r3,CONFIG_SYS_MONITOR_BASE@h
1108 ori r3,r3,CONFIG_SYS_MONITOR_BASE@l
3db0bef5
KG
1109 addi r3,r3,_start_cont - _start + _START_OFFSET
1110 mtlr r3
1e701e70 1111 blr
3db0bef5 1112#endif
61a21e98 1113
61a21e98
AF
1114 .text
1115 .globl _start
1116_start:
1117 .long 0x27051956 /* U-BOOT Magic Number */
1118 .globl version_string
1119version_string:
09c2e90c 1120 .ascii U_BOOT_VERSION_STRING, "\0"
61a21e98
AF
1121
1122 .align 4
1123 .globl _start_cont
1124_start_cont:
42d1f039 1125 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
89f42899
JT
1126 lis r3,(CONFIG_SYS_INIT_RAM_ADDR)@h
1127 ori r3,r3,((CONFIG_SYS_INIT_SP_OFFSET-16)&~0xf)@l /* Align to 16 */
42d1f039 1128 li r0,0
89f42899
JT
1129 stw r0,0(r3) /* Terminate Back Chain */
1130 stw r0,+4(r3) /* NULL return address. */
1131 mr r1,r3 /* Transfer to SP(r1) */
42d1f039
WD
1132
1133 GET_GOT
87163180
KG
1134 bl cpu_init_early_f
1135
1136 /* switch back to AS = 0 */
1137 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h
1138 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l
1139 mtmsr r3
1140 isync
1141
42d1f039 1142 bl cpu_init_f
42d1f039 1143 bl board_init_f
0ac6f8b7 1144 isync
42d1f039 1145
52ebd9c1
PT
1146 /* NOTREACHED - board_init_f() does not return */
1147
4b919725 1148#ifndef MINIMAL_SPL
61a21e98 1149 . = EXC_OFF_SYS_RESET
42d1f039
WD
1150 .globl _start_of_vectors
1151_start_of_vectors:
61a21e98 1152
42d1f039 1153/* Critical input. */
61a21e98
AF
1154 CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException)
1155
1156/* Machine check */
1157 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
42d1f039
WD
1158
1159/* Data Storage exception. */
1160 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
1161
1162/* Instruction Storage exception. */
1163 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
1164
1165/* External Interrupt exception. */
61a21e98 1166 STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException)
42d1f039
WD
1167
1168/* Alignment exception. */
1169 . = 0x0600
1170Alignment:
02032e8f 1171 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039
WD
1172 mfspr r4,DAR
1173 stw r4,_DAR(r21)
1174 mfspr r5,DSISR
1175 stw r5,_DSISR(r21)
1176 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887 1177 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
42d1f039
WD
1178
1179/* Program check exception */
1180 . = 0x0700
1181ProgramCheck:
02032e8f 1182 EXCEPTION_PROLOG(SRR0, SRR1)
42d1f039 1183 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887
JT
1184 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
1185 MSR_KERNEL, COPY_EE)
42d1f039
WD
1186
1187 /* No FPU on MPC85xx. This exception is not supposed to happen.
1188 */
1189 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
42d1f039 1190
343117bf 1191 . = 0x0900
42d1f039
WD
1192/*
1193 * r0 - SYSCALL number
1194 * r3-... arguments
1195 */
1196SystemCall:
61a21e98
AF
1197 addis r11,r0,0 /* get functions table addr */
1198 ori r11,r11,0 /* Note: this code is patched in trap_init */
1199 addis r12,r0,0 /* get number of functions */
343117bf
WD
1200 ori r12,r12,0
1201
61a21e98 1202 cmplw 0,r0,r12
343117bf
WD
1203 bge 1f
1204
61a21e98 1205 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
343117bf
WD
1206 add r11,r11,r0
1207 lwz r11,0(r11)
1208
61a21e98 1209 li r20,0xd00-4 /* Get stack pointer */
343117bf 1210 lwz r12,0(r20)
61a21e98 1211 subi r12,r12,12 /* Adjust stack pointer */
343117bf 1212 li r0,0xc00+_end_back-SystemCall
61a21e98 1213 cmplw 0,r0,r12 /* Check stack overflow */
343117bf
WD
1214 bgt 1f
1215 stw r12,0(r20)
1216
1217 mflr r0
1218 stw r0,0(r12)
1219 mfspr r0,SRR0
1220 stw r0,4(r12)
1221 mfspr r0,SRR1
1222 stw r0,8(r12)
1223
1224 li r12,0xc00+_back-SystemCall
1225 mtlr r12
1226 mtspr SRR0,r11
1227
12281: SYNC
42d1f039
WD
1229 rfi
1230_back:
1231
343117bf
WD
1232 mfmsr r11 /* Disable interrupts */
1233 li r12,0
1234 ori r12,r12,MSR_EE
1235 andc r11,r11,r12
1236 SYNC /* Some chip revs need this... */
1237 mtmsr r11
42d1f039
WD
1238 SYNC
1239
343117bf
WD
1240 li r12,0xd00-4 /* restore regs */
1241 lwz r12,0(r12)
42d1f039 1242
343117bf
WD
1243 lwz r11,0(r12)
1244 mtlr r11
1245 lwz r11,4(r12)
1246 mtspr SRR0,r11
1247 lwz r11,8(r12)
1248 mtspr SRR1,r11
42d1f039 1249
343117bf
WD
1250 addi r12,r12,12 /* Adjust stack pointer */
1251 li r20,0xd00-4
1252 stw r12,0(r20)
42d1f039
WD
1253
1254 SYNC
1255 rfi
1256_end_back:
1257
343117bf
WD
1258 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt)
1259 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException)
1260 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException)
42d1f039 1261
343117bf
WD
1262 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException)
1263 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException)
42d1f039 1264
343117bf 1265 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException )
42d1f039 1266
343117bf 1267 .globl _end_of_vectors
42d1f039
WD
1268_end_of_vectors:
1269
1270
61a21e98 1271 . = . + (0x100 - ( . & 0xff )) /* align for debug */
42d1f039
WD
1272
1273/*
1274 * This code finishes saving the registers to the exception frame
1275 * and jumps to the appropriate handler for the exception.
1276 * Register r21 is pointer into trap frame, r1 has new stack pointer.
1277 */
1278 .globl transfer_to_handler
1279transfer_to_handler:
1280 stw r22,_NIP(r21)
1281 lis r22,MSR_POW@h
1282 andc r23,r23,r22
1283 stw r23,_MSR(r21)
1284 SAVE_GPR(7, r21)
1285 SAVE_4GPRS(8, r21)
1286 SAVE_8GPRS(12, r21)
1287 SAVE_8GPRS(24, r21)
1288
1289 mflr r23
1290 andi. r24,r23,0x3f00 /* get vector offset */
1291 stw r24,TRAP(r21)
1292 li r22,0
1293 stw r22,RESULT(r21)
1294 mtspr SPRG2,r22 /* r1 is now kernel sp */
1295
1296 lwz r24,0(r23) /* virtual address of handler */
1297 lwz r23,4(r23) /* where to go when done */
1298 mtspr SRR0,r24
1299 mtspr SRR1,r20
1300 mtlr r23
1301 SYNC
1302 rfi /* jump to handler, enable MMU */
1303
1304int_return:
1305 mfmsr r28 /* Disable interrupts */
1306 li r4,0
1307 ori r4,r4,MSR_EE
1308 andc r28,r28,r4
1309 SYNC /* Some chip revs need this... */
1310 mtmsr r28
1311 SYNC
1312 lwz r2,_CTR(r1)
1313 lwz r0,_LINK(r1)
1314 mtctr r2
1315 mtlr r0
1316 lwz r2,_XER(r1)
1317 lwz r0,_CCR(r1)
1318 mtspr XER,r2
1319 mtcrf 0xFF,r0
1320 REST_10GPRS(3, r1)
1321 REST_10GPRS(13, r1)
1322 REST_8GPRS(23, r1)
1323 REST_GPR(31, r1)
1324 lwz r2,_NIP(r1) /* Restore environment */
1325 lwz r0,_MSR(r1)
1326 mtspr SRR0,r2
1327 mtspr SRR1,r0
1328 lwz r0,GPR0(r1)
1329 lwz r2,GPR2(r1)
1330 lwz r1,GPR1(r1)
1331 SYNC
1332 rfi
1333
1334crit_return:
1335 mfmsr r28 /* Disable interrupts */
1336 li r4,0
1337 ori r4,r4,MSR_EE
1338 andc r28,r28,r4
1339 SYNC /* Some chip revs need this... */
1340 mtmsr r28
1341 SYNC
1342 lwz r2,_CTR(r1)
1343 lwz r0,_LINK(r1)
1344 mtctr r2
1345 mtlr r0
1346 lwz r2,_XER(r1)
1347 lwz r0,_CCR(r1)
1348 mtspr XER,r2
1349 mtcrf 0xFF,r0
1350 REST_10GPRS(3, r1)
1351 REST_10GPRS(13, r1)
1352 REST_8GPRS(23, r1)
1353 REST_GPR(31, r1)
1354 lwz r2,_NIP(r1) /* Restore environment */
1355 lwz r0,_MSR(r1)
61a21e98
AF
1356 mtspr SPRN_CSRR0,r2
1357 mtspr SPRN_CSRR1,r0
42d1f039
WD
1358 lwz r0,GPR0(r1)
1359 lwz r2,GPR2(r1)
1360 lwz r1,GPR1(r1)
1361 SYNC
1362 rfci
1363
61a21e98
AF
1364mck_return:
1365 mfmsr r28 /* Disable interrupts */
1366 li r4,0
1367 ori r4,r4,MSR_EE
1368 andc r28,r28,r4
1369 SYNC /* Some chip revs need this... */
1370 mtmsr r28
1371 SYNC
1372 lwz r2,_CTR(r1)
1373 lwz r0,_LINK(r1)
1374 mtctr r2
1375 mtlr r0
1376 lwz r2,_XER(r1)
1377 lwz r0,_CCR(r1)
1378 mtspr XER,r2
1379 mtcrf 0xFF,r0
1380 REST_10GPRS(3, r1)
1381 REST_10GPRS(13, r1)
1382 REST_8GPRS(23, r1)
1383 REST_GPR(31, r1)
1384 lwz r2,_NIP(r1) /* Restore environment */
1385 lwz r0,_MSR(r1)
1386 mtspr SPRN_MCSRR0,r2
1387 mtspr SPRN_MCSRR1,r0
1388 lwz r0,GPR0(r1)
1389 lwz r2,GPR2(r1)
1390 lwz r1,GPR1(r1)
1391 SYNC
1392 rfmci
1393
42d1f039
WD
1394/* Cache functions.
1395*/
0a9fe8ee
MM
1396.globl flush_icache
1397flush_icache:
54e091d3 1398.globl invalidate_icache
42d1f039
WD
1399invalidate_icache:
1400 mfspr r0,L1CSR1
61a21e98
AF
1401 ori r0,r0,L1CSR1_ICFI
1402 msync
1403 isync
42d1f039
WD
1404 mtspr L1CSR1,r0
1405 isync
61a21e98 1406 blr /* entire I cache */
42d1f039 1407
54e091d3 1408.globl invalidate_dcache
42d1f039
WD
1409invalidate_dcache:
1410 mfspr r0,L1CSR0
61a21e98 1411 ori r0,r0,L1CSR0_DCFI
42d1f039
WD
1412 msync
1413 isync
1414 mtspr L1CSR0,r0
1415 isync
1416 blr
1417
1418 .globl icache_enable
1419icache_enable:
1420 mflr r8
1421 bl invalidate_icache
1422 mtlr r8
1423 isync
1424 mfspr r4,L1CSR1
1425 ori r4,r4,0x0001
1426 oris r4,r4,0x0001
1427 mtspr L1CSR1,r4
1428 isync
1429 blr
1430
1431 .globl icache_disable
1432icache_disable:
1433 mfspr r0,L1CSR1
61a21e98
AF
1434 lis r3,0
1435 ori r3,r3,L1CSR1_ICE
1436 andc r0,r0,r3
42d1f039
WD
1437 mtspr L1CSR1,r0
1438 isync
1439 blr
1440
1441 .globl icache_status
1442icache_status:
1443 mfspr r3,L1CSR1
61a21e98 1444 andi. r3,r3,L1CSR1_ICE
42d1f039
WD
1445 blr
1446
1447 .globl dcache_enable
1448dcache_enable:
1449 mflr r8
1450 bl invalidate_dcache
1451 mtlr r8
1452 isync
1453 mfspr r0,L1CSR0
1454 ori r0,r0,0x0001
1455 oris r0,r0,0x0001
1456 msync
1457 isync
1458 mtspr L1CSR0,r0
1459 isync
1460 blr
1461
1462 .globl dcache_disable
1463dcache_disable:
61a21e98
AF
1464 mfspr r3,L1CSR0
1465 lis r4,0
1466 ori r4,r4,L1CSR0_DCE
1467 andc r3,r3,r4
45a68135 1468 mtspr L1CSR0,r3
42d1f039
WD
1469 isync
1470 blr
1471
1472 .globl dcache_status
1473dcache_status:
1474 mfspr r3,L1CSR0
61a21e98 1475 andi. r3,r3,L1CSR0_DCE
42d1f039
WD
1476 blr
1477
1478 .globl get_pir
1479get_pir:
61a21e98 1480 mfspr r3,PIR
42d1f039
WD
1481 blr
1482
1483 .globl get_pvr
1484get_pvr:
61a21e98 1485 mfspr r3,PVR
42d1f039
WD
1486 blr
1487
97d80fc3
WD
1488 .globl get_svr
1489get_svr:
61a21e98 1490 mfspr r3,SVR
97d80fc3
WD
1491 blr
1492
42d1f039
WD
1493 .globl wr_tcr
1494wr_tcr:
61a21e98 1495 mtspr TCR,r3
42d1f039
WD
1496 blr
1497
1498/*------------------------------------------------------------------------------- */
1499/* Function: in8 */
1500/* Description: Input 8 bits */
1501/*------------------------------------------------------------------------------- */
1502 .globl in8
1503in8:
1504 lbz r3,0x0000(r3)
1505 blr
1506
1507/*------------------------------------------------------------------------------- */
1508/* Function: out8 */
1509/* Description: Output 8 bits */
1510/*------------------------------------------------------------------------------- */
1511 .globl out8
1512out8:
1513 stb r4,0x0000(r3)
1487adbd 1514 sync
42d1f039
WD
1515 blr
1516
1517/*------------------------------------------------------------------------------- */
1518/* Function: out16 */
1519/* Description: Output 16 bits */
1520/*------------------------------------------------------------------------------- */
1521 .globl out16
1522out16:
1523 sth r4,0x0000(r3)
1487adbd 1524 sync
42d1f039
WD
1525 blr
1526
1527/*------------------------------------------------------------------------------- */
1528/* Function: out16r */
1529/* Description: Byte reverse and output 16 bits */
1530/*------------------------------------------------------------------------------- */
1531 .globl out16r
1532out16r:
1533 sthbrx r4,r0,r3
1487adbd 1534 sync
42d1f039
WD
1535 blr
1536
1537/*------------------------------------------------------------------------------- */
1538/* Function: out32 */
1539/* Description: Output 32 bits */
1540/*------------------------------------------------------------------------------- */
1541 .globl out32
1542out32:
1543 stw r4,0x0000(r3)
1487adbd 1544 sync
42d1f039
WD
1545 blr
1546
1547/*------------------------------------------------------------------------------- */
1548/* Function: out32r */
1549/* Description: Byte reverse and output 32 bits */
1550/*------------------------------------------------------------------------------- */
1551 .globl out32r
1552out32r:
1553 stwbrx r4,r0,r3
1487adbd 1554 sync
42d1f039
WD
1555 blr
1556
1557/*------------------------------------------------------------------------------- */
1558/* Function: in16 */
1559/* Description: Input 16 bits */
1560/*------------------------------------------------------------------------------- */
1561 .globl in16
1562in16:
1563 lhz r3,0x0000(r3)
1564 blr
1565
1566/*------------------------------------------------------------------------------- */
1567/* Function: in16r */
1568/* Description: Input 16 bits and byte reverse */
1569/*------------------------------------------------------------------------------- */
1570 .globl in16r
1571in16r:
1572 lhbrx r3,r0,r3
1573 blr
1574
1575/*------------------------------------------------------------------------------- */
1576/* Function: in32 */
1577/* Description: Input 32 bits */
1578/*------------------------------------------------------------------------------- */
1579 .globl in32
1580in32:
1581 lwz 3,0x0000(3)
1582 blr
1583
1584/*------------------------------------------------------------------------------- */
1585/* Function: in32r */
1586/* Description: Input 32 bits and byte reverse */
1587/*------------------------------------------------------------------------------- */
1588 .globl in32r
1589in32r:
1590 lwbrx r3,r0,r3
1591 blr
4b919725 1592#endif /* !MINIMAL_SPL */
42d1f039 1593
42d1f039
WD
1594/*------------------------------------------------------------------------------*/
1595
d30f9043
KG
1596/*
1597 * void write_tlb(mas0, mas1, mas2, mas3, mas7)
1598 */
1599 .globl write_tlb
1600write_tlb:
1601 mtspr MAS0,r3
1602 mtspr MAS1,r4
1603 mtspr MAS2,r5
1604 mtspr MAS3,r6
1605#ifdef CONFIG_ENABLE_36BIT_PHYS
1606 mtspr MAS7,r7
1607#endif
1608 li r3,0
1609#ifdef CONFIG_SYS_BOOK3E_HV
1610 mtspr MAS8,r3
1611#endif
1612 isync
1613 tlbwe
1614 msync
1615 isync
1616 blr
1617
42d1f039
WD
1618/*
1619 * void relocate_code (addr_sp, gd, addr_moni)
1620 *
1621 * This "function" does not return, instead it continues in RAM
1622 * after relocating the monitor code.
1623 *
1624 * r3 = dest
1625 * r4 = src
1626 * r5 = length in bytes
1627 * r6 = cachelinesize
1628 */
1629 .globl relocate_code
1630relocate_code:
61a21e98
AF
1631 mr r1,r3 /* Set new stack pointer */
1632 mr r9,r4 /* Save copy of Init Data pointer */
1633 mr r10,r5 /* Save copy of Destination Address */
42d1f039 1634
0f8aa159 1635 GET_GOT
61a21e98 1636 mr r3,r5 /* Destination Address */
6d0f6bcf
JCPV
1637 lis r4,CONFIG_SYS_MONITOR_BASE@h /* Source Address */
1638 ori r4,r4,CONFIG_SYS_MONITOR_BASE@l
42d1f039
WD
1639 lwz r5,GOT(__init_end)
1640 sub r5,r5,r4
6d0f6bcf 1641 li r6,CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
42d1f039
WD
1642
1643 /*
1644 * Fix GOT pointer:
1645 *
6d0f6bcf 1646 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
42d1f039
WD
1647 *
1648 * Offset:
1649 */
61a21e98 1650 sub r15,r10,r4
42d1f039
WD
1651
1652 /* First our own GOT */
0f8aa159 1653 add r12,r12,r15
42d1f039 1654 /* the the one used by the C code */
61a21e98 1655 add r30,r30,r15
42d1f039
WD
1656
1657 /*
1658 * Now relocate code
1659 */
1660
1661 cmplw cr1,r3,r4
1662 addi r0,r5,3
1663 srwi. r0,r0,2
1664 beq cr1,4f /* In place copy is not necessary */
1665 beq 7f /* Protect against 0 count */
1666 mtctr r0
1667 bge cr1,2f
1668
1669 la r8,-4(r4)
1670 la r7,-4(r3)
16711: lwzu r0,4(r8)
1672 stwu r0,4(r7)
1673 bdnz 1b
1674 b 4f
1675
16762: slwi r0,r0,2
1677 add r8,r4,r0
1678 add r7,r3,r0
16793: lwzu r0,-4(r8)
1680 stwu r0,-4(r7)
1681 bdnz 3b
1682
1683/*
1684 * Now flush the cache: note that we must start from a cache aligned
1685 * address. Otherwise we might miss one cache line.
1686 */
16874: cmpwi r6,0
1688 add r5,r3,r5
1689 beq 7f /* Always flush prefetch queue in any case */
1690 subi r0,r6,1
1691 andc r3,r3,r0
1692 mr r4,r3
16935: dcbst 0,r4
1694 add r4,r4,r6
1695 cmplw r4,r5
1696 blt 5b
1697 sync /* Wait for all dcbst to complete on bus */
1698 mr r4,r3
16996: icbi 0,r4
1700 add r4,r4,r6
1701 cmplw r4,r5
1702 blt 6b
17037: sync /* Wait for all icbi to complete on bus */
1704 isync
1705
1706/*
1707 * We are done. Do not return, instead branch to second part of board
1708 * initialization, now running from RAM.
1709 */
1710
61a21e98 1711 addi r0,r10,in_ram - _start + _START_OFFSET
689f00fc
PK
1712
1713 /*
1714 * As IVPR is going to point RAM address,
1715 * Make sure IVOR15 has valid opcode to support debugger
1716 */
1717 mtspr IVOR15,r0
1718
1719 /*
1720 * Re-point the IVPR at RAM
1721 */
1722 mtspr IVPR,r10
1723
42d1f039
WD
1724 mtlr r0
1725 blr /* NEVER RETURNS! */
61a21e98 1726 .globl in_ram
42d1f039
WD
1727in_ram:
1728
1729 /*
0f8aa159 1730 * Relocation Function, r12 point to got2+0x8000
42d1f039
WD
1731 *
1732 * Adjust got2 pointers, no need to check for 0, this code
1733 * already puts a few entries in the table.
1734 */
1735 li r0,__got2_entries@sectoff@l
1736 la r3,GOT(_GOT2_TABLE_)
1737 lwz r11,GOT(_GOT2_TABLE_)
1738 mtctr r0
1739 sub r11,r3,r11
1740 addi r3,r3,-4
17411: lwzu r0,4(r3)
afc3ba0f
JT
1742 cmpwi r0,0
1743 beq- 2f
42d1f039
WD
1744 add r0,r0,r11
1745 stw r0,0(r3)
afc3ba0f 17462: bdnz 1b
42d1f039
WD
1747
1748 /*
1749 * Now adjust the fixups and the pointers to the fixups
1750 * in case we need to move ourselves again.
1751 */
afc3ba0f 1752 li r0,__fixup_entries@sectoff@l
42d1f039
WD
1753 lwz r3,GOT(_FIXUP_TABLE_)
1754 cmpwi r0,0
1755 mtctr r0
1756 addi r3,r3,-4
1757 beq 4f
17583: lwzu r4,4(r3)
1759 lwzux r0,r4,r11
d1e0b10a 1760 cmpwi r0,0
42d1f039 1761 add r0,r0,r11
34bbf618 1762 stw r4,0(r3)
d1e0b10a 1763 beq- 5f
42d1f039 1764 stw r0,0(r4)
d1e0b10a 17655: bdnz 3b
42d1f039
WD
17664:
1767clear_bss:
1768 /*
1769 * Now clear BSS segment
1770 */
1771 lwz r3,GOT(__bss_start)
3929fb0a 1772 lwz r4,GOT(__bss_end)
42d1f039 1773
61a21e98 1774 cmplw 0,r3,r4
42d1f039
WD
1775 beq 6f
1776
61a21e98 1777 li r0,0
42d1f039 17785:
61a21e98
AF
1779 stw r0,0(r3)
1780 addi r3,r3,4
1781 cmplw 0,r3,r4
67ad0d52 1782 blt 5b
42d1f039
WD
17836:
1784
61a21e98
AF
1785 mr r3,r9 /* Init Data pointer */
1786 mr r4,r10 /* Destination Address */
42d1f039
WD
1787 bl board_init_r
1788
4b919725 1789#ifndef MINIMAL_SPL
42d1f039
WD
1790 /*
1791 * Copy exception vector code to low memory
1792 *
1793 * r3: dest_addr
1794 * r7: source address, r8: end address, r9: target address
1795 */
343117bf 1796 .globl trap_init
42d1f039 1797trap_init:
0f8aa159
JT
1798 mflr r4 /* save link register */
1799 GET_GOT
61a21e98
AF
1800 lwz r7,GOT(_start_of_vectors)
1801 lwz r8,GOT(_end_of_vectors)
42d1f039 1802
61a21e98 1803 li r9,0x100 /* reset vector always at 0x100 */
42d1f039 1804
61a21e98 1805 cmplw 0,r7,r8
343117bf 1806 bgelr /* return if r7>=r8 - just in case */
42d1f039 18071:
61a21e98
AF
1808 lwz r0,0(r7)
1809 stw r0,0(r9)
1810 addi r7,r7,4
1811 addi r9,r9,4
1812 cmplw 0,r7,r8
343117bf 1813 bne 1b
42d1f039
WD
1814
1815 /*
1816 * relocate `hdlr' and `int_return' entries
1817 */
61a21e98 1818 li r7,.L_CriticalInput - _start + _START_OFFSET
343117bf 1819 bl trap_reloc
61a21e98 1820 li r7,.L_MachineCheck - _start + _START_OFFSET
343117bf 1821 bl trap_reloc
61a21e98 1822 li r7,.L_DataStorage - _start + _START_OFFSET
343117bf 1823 bl trap_reloc
61a21e98 1824 li r7,.L_InstStorage - _start + _START_OFFSET
343117bf 1825 bl trap_reloc
61a21e98 1826 li r7,.L_ExtInterrupt - _start + _START_OFFSET
343117bf 1827 bl trap_reloc
61a21e98 1828 li r7,.L_Alignment - _start + _START_OFFSET
343117bf 1829 bl trap_reloc
61a21e98 1830 li r7,.L_ProgramCheck - _start + _START_OFFSET
343117bf 1831 bl trap_reloc
61a21e98 1832 li r7,.L_FPUnavailable - _start + _START_OFFSET
343117bf 1833 bl trap_reloc
61a21e98
AF
1834 li r7,.L_Decrementer - _start + _START_OFFSET
1835 bl trap_reloc
1836 li r7,.L_IntervalTimer - _start + _START_OFFSET
1837 li r8,_end_of_vectors - _start + _START_OFFSET
42d1f039 18382:
343117bf 1839 bl trap_reloc
61a21e98
AF
1840 addi r7,r7,0x100 /* next exception vector */
1841 cmplw 0,r7,r8
343117bf
WD
1842 blt 2b
1843
64829baf
PK
1844 /* Update IVORs as per relocated vector table address */
1845 li r7,0x0100
1846 mtspr IVOR0,r7 /* 0: Critical input */
1847 li r7,0x0200
1848 mtspr IVOR1,r7 /* 1: Machine check */
1849 li r7,0x0300
1850 mtspr IVOR2,r7 /* 2: Data storage */
1851 li r7,0x0400
1852 mtspr IVOR3,r7 /* 3: Instruction storage */
1853 li r7,0x0500
1854 mtspr IVOR4,r7 /* 4: External interrupt */
1855 li r7,0x0600
1856 mtspr IVOR5,r7 /* 5: Alignment */
1857 li r7,0x0700
1858 mtspr IVOR6,r7 /* 6: Program check */
1859 li r7,0x0800
1860 mtspr IVOR7,r7 /* 7: floating point unavailable */
1861 li r7,0x0900
1862 mtspr IVOR8,r7 /* 8: System call */
1863 /* 9: Auxiliary processor unavailable(unsupported) */
1864 li r7,0x0a00
1865 mtspr IVOR10,r7 /* 10: Decrementer */
1866 li r7,0x0b00
1867 mtspr IVOR11,r7 /* 11: Interval timer */
1868 li r7,0x0c00
1869 mtspr IVOR12,r7 /* 12: Watchdog timer */
1870 li r7,0x0d00
1871 mtspr IVOR13,r7 /* 13: Data TLB error */
1872 li r7,0x0e00
1873 mtspr IVOR14,r7 /* 14: Instruction TLB error */
1874 li r7,0x0f00
1875 mtspr IVOR15,r7 /* 15: Debug */
1876
343117bf 1877 lis r7,0x0
61a21e98 1878 mtspr IVPR,r7
42d1f039 1879
343117bf 1880 mtlr r4 /* restore link register */
42d1f039
WD
1881 blr
1882
42d1f039
WD
1883.globl unlock_ram_in_cache
1884unlock_ram_in_cache:
1885 /* invalidate the INIT_RAM section */
a38a5b6e
KG
1886 lis r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@h
1887 ori r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@l
b009f3ec
KG
1888 mfspr r4,L1CFG0
1889 andi. r4,r4,0x1ff
1890 slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT)
61a21e98 1891 mtctr r4
2b22fa4b 18921: dcbi r0,r3
a71d45d7 1893 dcblc r0,r3
6d0f6bcf 1894 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
42d1f039 1895 bdnz 1b
2b22fa4b 1896 sync
21fae8b2
AF
1897
1898 /* Invalidate the TLB entries for the cache */
6d0f6bcf
JCPV
1899 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
1900 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
21fae8b2
AF
1901 tlbivax 0,r3
1902 addi r3,r3,0x1000
1903 tlbivax 0,r3
1904 addi r3,r3,0x1000
1905 tlbivax 0,r3
1906 addi r3,r3,0x1000
1907 tlbivax 0,r3
42d1f039
WD
1908 isync
1909 blr
54e091d3
KG
1910
1911.globl flush_dcache
1912flush_dcache:
1913 mfspr r3,SPRN_L1CFG0
1914
1915 rlwinm r5,r3,9,3 /* Extract cache block size */
1916 twlgti r5,1 /* Only 32 and 64 byte cache blocks
1917 * are currently defined.
1918 */
1919 li r4,32
1920 subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -
1921 * log2(number of ways)
1922 */
1923 slw r5,r4,r5 /* r5 = cache block size */
1924
1925 rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */
1926 mulli r7,r7,13 /* An 8-way cache will require 13
1927 * loads per set.
1928 */
1929 slw r7,r7,r6
1930
1931 /* save off HID0 and set DCFA */
1932 mfspr r8,SPRN_HID0
1933 ori r9,r8,HID0_DCFA@l
1934 mtspr SPRN_HID0,r9
1935 isync
1936
1937 lis r4,0
1938 mtctr r7
1939
19401: lwz r3,0(r4) /* Load... */
1941 add r4,r4,r5
1942 bdnz 1b
1943
1944 msync
1945 lis r4,0
1946 mtctr r7
1947
19481: dcbf 0,r4 /* ...and flush. */
1949 add r4,r4,r5
1950 bdnz 1b
1951
1952 /* restore HID0 */
1953 mtspr SPRN_HID0,r8
1954 isync
1955
1956 blr
26f4cdba
KG
1957
1958.globl setup_ivors
1959setup_ivors:
1960
1961#include "fixed_ivor.S"
1962 blr
4b919725 1963#endif /* !MINIMAL_SPL */