]>
Commit | Line | Data |
---|---|---|
0e870980 PA |
1 | /* |
2 | * Copyright 2008-2009 Freescale Semiconductor, Inc. | |
3 | * Kumar Gala <kumar.gala@freescale.com> | |
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 | ||
ec2b74ff KG |
24 | #include <config.h> |
25 | #include <mpc85xx.h> | |
26 | #include <version.h> | |
27 | ||
28 | #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ | |
29 | ||
30 | #include <ppc_asm.tmpl> | |
31 | #include <ppc_defs.h> | |
32 | ||
33 | #include <asm/cache.h> | |
34 | #include <asm/mmu.h> | |
35 | ||
36 | /* To boot secondary cpus, we need a place for them to start up. | |
37 | * Normally, they start at 0xfffffffc, but that's usually the | |
38 | * firmware, and we don't want to have to run the firmware again. | |
39 | * Instead, the primary cpu will set the BPTR to point here to | |
40 | * this page. We then set up the core, and head to | |
41 | * start_secondary. Note that this means that the code below | |
42 | * must never exceed 1023 instructions (the branch at the end | |
43 | * would then be the 1024th). | |
44 | */ | |
45 | .globl __secondary_start_page | |
46 | .align 12 | |
47 | __secondary_start_page: | |
48 | /* First do some preliminary setup */ | |
49 | lis r3, HID0_EMCP@h /* enable machine check */ | |
0f060c3b | 50 | #ifndef CONFIG_E500MC |
ec2b74ff | 51 | ori r3,r3,HID0_TBEN@l /* enable Timebase */ |
0f060c3b | 52 | #endif |
ec2b74ff KG |
53 | #ifdef CONFIG_PHYS_64BIT |
54 | ori r3,r3,HID0_ENMAS7@l /* enable MAS7 updates */ | |
55 | #endif | |
56 | mtspr SPRN_HID0,r3 | |
57 | ||
0f060c3b | 58 | #ifndef CONFIG_E500MC |
ec2b74ff KG |
59 | li r3,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */ |
60 | mtspr SPRN_HID1,r3 | |
0f060c3b | 61 | #endif |
ec2b74ff KG |
62 | |
63 | /* Enable branch prediction */ | |
64 | li r3,0x201 | |
65 | mtspr SPRN_BUCSR,r3 | |
66 | ||
e0ff3d35 KG |
67 | /* Ensure TB is 0 */ |
68 | li r3,0 | |
69 | mttbl r3 | |
70 | mttbu r3 | |
71 | ||
ec2b74ff KG |
72 | /* Enable/invalidate the I-Cache */ |
73 | mfspr r0,SPRN_L1CSR1 | |
74 | ori r0,r0,(L1CSR1_ICFI|L1CSR1_ICE) | |
75 | mtspr SPRN_L1CSR1,r0 | |
76 | isync | |
77 | ||
78 | /* Enable/invalidate the D-Cache */ | |
79 | mfspr r0,SPRN_L1CSR0 | |
80 | ori r0,r0,(L1CSR0_DCFI|L1CSR0_DCE) | |
81 | msync | |
82 | isync | |
83 | mtspr SPRN_L1CSR0,r0 | |
84 | isync | |
85 | ||
86 | #define toreset(x) (x - __secondary_start_page + 0xfffff000) | |
87 | ||
88 | /* get our PIR to figure out our table entry */ | |
89 | lis r3,toreset(__spin_table)@h | |
90 | ori r3,r3,toreset(__spin_table)@l | |
91 | ||
79679d80 | 92 | /* r10 has the base address for the entry */ |
ec2b74ff | 93 | mfspr r0,SPRN_PIR |
0f060c3b KG |
94 | #ifdef CONFIG_E500MC |
95 | rlwinm r4,r0,27,27,31 | |
96 | #else | |
ec2b74ff | 97 | mr r4,r0 |
0f060c3b | 98 | #endif |
79679d80 KG |
99 | slwi r8,r4,5 |
100 | add r10,r3,r8 | |
101 | ||
1b3e4044 KG |
102 | #ifdef CONFIG_BACKSIDE_L2_CACHE |
103 | /* Enable/invalidate the L2 cache */ | |
104 | msync | |
25bacf7a KG |
105 | lis r3,(L2CSR0_L2FI|L2CSR0_L2LFC)@h |
106 | ori r3,r3,(L2CSR0_L2FI|L2CSR0_L2LFC)@l | |
1b3e4044 KG |
107 | mtspr SPRN_L2CSR0,r3 |
108 | 1: | |
109 | mfspr r3,SPRN_L2CSR0 | |
110 | andis. r1,r3,L2CSR0_L2FI@h | |
111 | bne 1b | |
112 | ||
113 | lis r3,CONFIG_SYS_INIT_L2CSR0@h | |
114 | ori r3,r3,CONFIG_SYS_INIT_L2CSR0@l | |
115 | mtspr SPRN_L2CSR0,r3 | |
116 | isync | |
117 | #endif | |
118 | ||
79679d80 KG |
119 | #define EPAPR_MAGIC (0x45504150) |
120 | #define ENTRY_ADDR_UPPER 0 | |
121 | #define ENTRY_ADDR_LOWER 4 | |
122 | #define ENTRY_R3_UPPER 8 | |
123 | #define ENTRY_R3_LOWER 12 | |
124 | #define ENTRY_RESV 16 | |
125 | #define ENTRY_PIR 20 | |
126 | #define ENTRY_R6_UPPER 24 | |
127 | #define ENTRY_R6_LOWER 28 | |
128 | #define ENTRY_SIZE 32 | |
ec2b74ff KG |
129 | |
130 | /* setup the entry */ | |
79679d80 | 131 | li r3,0 |
ec2b74ff | 132 | li r8,1 |
79679d80 KG |
133 | stw r0,ENTRY_PIR(r10) |
134 | stw r3,ENTRY_ADDR_UPPER(r10) | |
135 | stw r8,ENTRY_ADDR_LOWER(r10) | |
136 | stw r3,ENTRY_R3_UPPER(r10) | |
137 | stw r4,ENTRY_R3_LOWER(r10) | |
138 | stw r3,ENTRY_R6_UPPER(r10) | |
139 | stw r3,ENTRY_R6_LOWER(r10) | |
140 | ||
5ccd29c3 PT |
141 | /* load r13 with the address of the 'bootpg' in SDRAM */ |
142 | lis r13,toreset(__bootpg_addr)@h | |
143 | ori r13,r13,toreset(__bootpg_addr)@l | |
144 | lwz r13,0(r13) | |
145 | ||
79679d80 KG |
146 | /* setup mapping for AS = 1, and jump there */ |
147 | lis r11,(MAS0_TLBSEL(1)|MAS0_ESEL(1))@h | |
148 | mtspr SPRN_MAS0,r11 | |
149 | lis r11,(MAS1_VALID|MAS1_IPROT)@h | |
150 | ori r11,r11,(MAS1_TS|MAS1_TSIZE(BOOKE_PAGESZ_4K))@l | |
151 | mtspr SPRN_MAS1,r11 | |
5ccd29c3 PT |
152 | oris r11,r13,(MAS2_I)@h |
153 | ori r11,r13,(MAS2_I)@l | |
79679d80 | 154 | mtspr SPRN_MAS2,r11 |
5ccd29c3 PT |
155 | oris r11,r13,(MAS3_SX|MAS3_SW|MAS3_SR)@h |
156 | ori r11,r13,(MAS3_SX|MAS3_SW|MAS3_SR)@l | |
79679d80 KG |
157 | mtspr SPRN_MAS3,r11 |
158 | tlbwe | |
159 | ||
160 | bl 1f | |
161 | 1: mflr r11 | |
5ccd29c3 PT |
162 | /* |
163 | * OR in 0xfff to create a mask of the bootpg SDRAM address. We use | |
164 | * this mask to fixup the cpu spin table and the address that we want | |
165 | * to jump to, eg change them from 0xfffffxxx to 0x7ffffxxx if the | |
166 | * bootpg is at 0x7ffff000 in SDRAM. | |
167 | */ | |
168 | ori r13,r13,0xfff | |
169 | and r11, r11, r13 | |
170 | and r10, r10, r13 | |
171 | ||
172 | addi r11,r11,(2f-1b) | |
79679d80 KG |
173 | mfmsr r13 |
174 | ori r12,r13,MSR_IS|MSR_DS@l | |
175 | ||
176 | mtspr SPRN_SRR0,r11 | |
177 | mtspr SPRN_SRR1,r12 | |
178 | rfi | |
ec2b74ff KG |
179 | |
180 | /* spin waiting for addr */ | |
79679d80 KG |
181 | 2: |
182 | lwz r4,ENTRY_ADDR_LOWER(r10) | |
ec2b74ff | 183 | andi. r11,r4,1 |
79679d80 | 184 | bne 2b |
cf6cc014 | 185 | isync |
79679d80 | 186 | |
26f4cdba KG |
187 | /* setup IVORs to match fixed offsets */ |
188 | #include "fixed_ivor.S" | |
189 | ||
79679d80 KG |
190 | /* get the upper bits of the addr */ |
191 | lwz r11,ENTRY_ADDR_UPPER(r10) | |
ec2b74ff KG |
192 | |
193 | /* setup branch addr */ | |
79679d80 | 194 | mtspr SPRN_SRR0,r4 |
ec2b74ff KG |
195 | |
196 | /* mark the entry as released */ | |
197 | li r8,3 | |
79679d80 | 198 | stw r8,ENTRY_ADDR_LOWER(r10) |
ec2b74ff KG |
199 | |
200 | /* mask by ~64M to setup our tlb we will jump to */ | |
79679d80 | 201 | rlwinm r12,r4,0,0,5 |
ec2b74ff | 202 | |
79679d80 KG |
203 | /* setup r3, r4, r5, r6, r7, r8, r9 */ |
204 | lwz r3,ENTRY_R3_LOWER(r10) | |
205 | li r4,0 | |
ec2b74ff | 206 | li r5,0 |
79679d80 KG |
207 | lwz r6,ENTRY_R6_LOWER(r10) |
208 | lis r7,(64*1024*1024)@h | |
209 | li r8,0 | |
210 | li r9,0 | |
ec2b74ff KG |
211 | |
212 | /* load up the pir */ | |
79679d80 | 213 | lwz r0,ENTRY_PIR(r10) |
ec2b74ff KG |
214 | mtspr SPRN_PIR,r0 |
215 | mfspr r0,SPRN_PIR | |
79679d80 | 216 | stw r0,ENTRY_PIR(r10) |
ec2b74ff | 217 | |
181a3650 | 218 | mtspr IVPR,r12 |
ec2b74ff KG |
219 | /* |
220 | * Coming here, we know the cpu has one TLB mapping in TLB1[0] | |
221 | * which maps 0xfffff000-0xffffffff one-to-one. We set up a | |
222 | * second mapping that maps addr 1:1 for 64M, and then we jump to | |
223 | * addr | |
224 | */ | |
79679d80 KG |
225 | lis r10,(MAS0_TLBSEL(1)|MAS0_ESEL(0))@h |
226 | mtspr SPRN_MAS0,r10 | |
227 | lis r10,(MAS1_VALID|MAS1_IPROT)@h | |
228 | ori r10,r10,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l | |
229 | mtspr SPRN_MAS1,r10 | |
ec2b74ff | 230 | /* WIMGE = 0b00000 for now */ |
79679d80 KG |
231 | mtspr SPRN_MAS2,r12 |
232 | ori r12,r12,(MAS3_SX|MAS3_SW|MAS3_SR) | |
233 | mtspr SPRN_MAS3,r12 | |
234 | #ifdef CONFIG_ENABLE_36BIT_PHYS | |
235 | mtspr SPRN_MAS7,r11 | |
236 | #endif | |
ec2b74ff KG |
237 | tlbwe |
238 | ||
239 | /* Now we have another mapping for this page, so we jump to that | |
240 | * mapping | |
241 | */ | |
79679d80 KG |
242 | mtspr SPRN_SRR1,r13 |
243 | rfi | |
ec2b74ff | 244 | |
5ccd29c3 PT |
245 | /* |
246 | * Allocate some space for the SDRAM address of the bootpg. | |
247 | * This variable has to be in the boot page so that it can | |
248 | * be accessed by secondary cores when they come out of reset. | |
249 | */ | |
250 | .globl __bootpg_addr | |
251 | __bootpg_addr: | |
252 | .long 0 | |
253 | ||
cf6cc014 | 254 | .align L1_CACHE_SHIFT |
ec2b74ff KG |
255 | .globl __spin_table |
256 | __spin_table: | |
0e870980 | 257 | .space CONFIG_MAX_CPUS*ENTRY_SIZE |
ec2b74ff KG |
258 | |
259 | /* Fill in the empty space. The actual reset vector is | |
260 | * the last word of the page */ | |
261 | __secondary_start_code_end: | |
262 | .space 4092 - (__secondary_start_code_end - __secondary_start_page) | |
263 | __secondary_reset_vector: | |
264 | b __secondary_start_page |