e500_mpsubr.S revision 1.1 1
2 /*
3 * r3 = fdt pointer (ignored)
4 * r4 = 0
5 * r5 = 0
6 * r6 = EPAPR magic (0x45505150)
7 * r7 = TLB1[0] entry size (64MB)
8 * r8 = 0
9 * r9 = 0
10 */
11 _ENTRY(e500_spinup_trampoline)
12
13 /*
14 * First thing we need to do is to set SPRG0 with our cpu_info
15 * and get our initial stack pointer (this must be within the
16 * bounds of the TLB1[0] entry U-boot setup for us).
17 *
18 * cpu_hatch will return a new SP to use.
19 *
20 * All the caller-saved register are ours to use. So we will.
21 */
22 lis %r20, _C_LABEL(cpu_hatch_data)@ha
23 addi %r20, %r20, _C_LABEL(cpu_hatch_data)@l
24
25 lwz %r21, HATCH_CI(%r20) /* get cpu_info */
26 mtsprg0 %r21 /* save cpu_info */
27 lwz %r1, HATCH_SP(%r20) /* get hatch SP */
28
29 /*
30 * We have to setup the IVOR SPRs since the ones u-boot setup
31 * don't work for us.
32 */
33 bl _C_LABEL(exception_init) /* setup IVORs */
34
35 /*
36 * U-boot has mapped the bottom 64MB in TLB1[0]. We are going to need
37 * change this entry and it's not safe to do so while running out of it.
38 * So we copy TLB1[0] to TLB1[1] but set it for AS1. We then switch
39 * to AS1 and reload TLB1[0] with its correct value, and we switch
40 * back to AS0. Then we can load the rest of the TLB1 entries.
41 */
42
43 /*
44 * Fetch TLB1[0]
45 */
46 lis %r16, (MASX_TLBSEL_MAKE(1)|MAS0_ESEL_MAKE(0))@h
47 mtspr SPR_MAS0, %r16
48 tlbre
49
50 /*
51 * Copy TLB1[0] to TLB[1] and set it to use AS1
52 */
53 mfspr %r3, SPR_MAS0
54 addis %r3, %r3, MAS0_ESEL@h /* advance to next TLB entry */
55 mtspr SPR_MAS0, %r3 /* place into SPR */
56 mfspr %r4, SPR_MAS1
57 ori %r4, %r4, MAS1_TS@l /* Make it use AS1 */
58 mtspr SPR_MAS1, %r4
59 tlbwe /* write the TLB entry */
60
61 /*
62 * Let's find out what TLB1[0] entry we are supposed to use.
63 */
64 li %r3, 0
65 bl _C_LABEL(e500_tlb1_fetch)
66 lwz %r28, 0(%r3) /* load the saved TLB1 entry */
67 mtspr SPR_MAS0, %r28 /* place into SPRs */
68 mtspr SPR_MAS1, %r29
69 mtspr SPR_MAS2, %r30
70 mtspr SPR_MAS3, %r31
71
72 /*
73 * Now to switch to running in AS1
74 */
75 mfmsr %r3
76 ori %r4,%r3,(PSL_DS|PSL_IS)@l
77 mtsrr1 %r4
78
79 bl 1f
80 1: mflr %r11
81 addi %r4,%r11,.Las1start-1b
82 addi %r5,%r11,.Las1end-1b
83 mtsrr0 %r4
84 rfi /* switch to AS1, context synchronizing */
85
86 .Las1start:
87 /*
88 * We are now running in AS1, update TLB1[0]
89 */
90 tlbwe
91
92 mtsrr0 %r5
93 mtsrr1 %r3
94 rfi /* switch back to AS0, context synchronizing */
95
96 .Las1end:
97 /*
98 * We now have our TLB1[0] in place. Now we need to load the rest of
99 * TLB1 with our entries. After this is done, we should have access
100 * to everything.
101 */
102 bl _C_LABEL(e500_tlb1_sync)
103
104 /*
105 * We've gotten the low level stuff done.
106 * Now to do more advanced stuff.
107 */
108 bl _C_LABEL(cpu_hatch)
109 mr %r1, %r3 /* our new SP */
110
111 wrteei 1 /* allow interrupts */
112
113 b _C_LABEL(idle_loop)
114