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