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