]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | /* | |
23 | * @OSF_COPYRIGHT@ | |
24 | */ | |
25 | #include <cpus.h> | |
26 | #include <mach_kdb.h> | |
27 | #include <mach_kdp.h> | |
28 | #include <mach_kgdb.h> | |
29 | #include <ppc/asm.h> | |
30 | #include <ppc/proc_reg.h> | |
31 | #include <mach/ppc/vm_param.h> | |
32 | #include <assym.s> | |
33 | ||
34 | #define ptFilter 0 | |
35 | #define ptVersion 4 | |
36 | #define ptRevision 6 | |
37 | #define ptFeatures 8 | |
38 | #define ptInitRout 12 | |
39 | #define ptRptdProc 16 | |
40 | #define ptTempMax 20 | |
41 | #define ptTempThr 24 | |
42 | #define ptLineSize 28 | |
43 | #define ptl1iSize 32 | |
44 | #define ptl1dSize 36 | |
45 | #define ptSize 40 | |
46 | ||
47 | #define bootCPU 10 | |
48 | #define firstInit 9 | |
49 | #define firstBoot 8 | |
0b4e3aa0 A |
50 | |
51 | /* Defines for PVRs */ | |
52 | #define PROCESSOR_VERSION_601 1 | |
53 | #define PROCESSOR_VERSION_603 3 | |
54 | #define PROCESSOR_VERSION_604 4 | |
55 | #define PROCESSOR_VERSION_603e 6 | |
56 | #define PROCESSOR_VERSION_750 8 | |
57 | #define PROCESSOR_VERSION_604e 9 | |
58 | #define PROCESSOR_VERSION_604ev 10 /* ? */ | |
59 | #define PROCESSOR_VERSION_7400 12 /* ? */ | |
60 | #define PROCESSOR_VERSION_7410 0x800C /* ? */ | |
61 | #define PROCESSOR_VERSION_7450 0x8000 /* ? */ | |
62 | ||
1c79356b A |
63 | /* |
64 | * Interrupt and bootup stack for initial processor | |
65 | */ | |
66 | ||
67 | .file "start.s" | |
68 | ||
69 | .data | |
70 | ||
71 | /* Align on page boundry */ | |
72 | .align PPC_PGSHIFT | |
73 | /* Red zone for interrupt stack, one page (will be unmapped)*/ | |
74 | .set ., .+PPC_PGBYTES | |
75 | /* intstack itself */ | |
76 | ||
77 | .globl EXT(FixedStackStart) | |
78 | EXT(FixedStackStart): | |
79 | ||
80 | .globl EXT(intstack) | |
81 | EXT(intstack): | |
82 | .set ., .+INTSTACK_SIZE*NCPUS | |
83 | ||
84 | /* Debugger stack - used by the debugger if present */ | |
85 | /* NOTE!!! Keep the debugger stack right after the interrupt stack */ | |
86 | #if MACH_KDP || MACH_KDB | |
87 | .globl EXT(debstack) | |
88 | EXT(debstack): | |
89 | .set ., .+KERNEL_STACK_SIZE*NCPUS | |
90 | ||
91 | .globl EXT(FixedStackEnd) | |
92 | EXT(FixedStackEnd): | |
93 | ||
94 | .align ALIGN | |
95 | .globl EXT(intstack_top_ss) | |
96 | EXT(intstack_top_ss): | |
0b4e3aa0 | 97 | .long EXT(intstack)+INTSTACK_SIZE-FM_SIZE /* intstack_top_ss points to the top of interrupt stack */ |
1c79356b A |
98 | |
99 | .align ALIGN | |
100 | .globl EXT(debstack_top_ss) | |
101 | EXT(debstack_top_ss): | |
102 | ||
0b4e3aa0 | 103 | .long EXT(debstack)+KERNEL_STACK_SIZE-FM_SIZE /* debstack_top_ss points to the top of debug stack */ |
1c79356b A |
104 | |
105 | .globl EXT(debstackptr) | |
106 | EXT(debstackptr): | |
0b4e3aa0 | 107 | .long EXT(debstack)+KERNEL_STACK_SIZE-FM_SIZE |
1c79356b A |
108 | |
109 | #endif /* MACH_KDP || MACH_KDB */ | |
110 | ||
111 | /* | |
112 | * All CPUs start here. | |
113 | * | |
114 | * This code is called from SecondaryLoader | |
115 | * | |
116 | * Various arguments are passed via a table: | |
117 | * ARG0 = pointer to other startup parameters | |
118 | */ | |
119 | .text | |
120 | ||
121 | ENTRY(_start_cpu,TAG_NO_FRAME_USED) | |
122 | crclr bootCPU ; Set non-boot processor | |
123 | crclr firstInit ; Set not first time init | |
124 | mr r30,r3 ; Set current per_proc | |
125 | ||
126 | ; | |
127 | ; Note that we are just trying to get close. The real TB sync will take | |
128 | ; place later. The value we are loading is set in two places. For the | |
129 | ; main processor, it will be the TB at the last interrupt before we went | |
130 | ; to sleep. For the others, it will be the time just before the main | |
131 | ; processor woke us up. | |
132 | ; | |
133 | ||
134 | lwz r15,ruptStamp(r3) ; Get the timebase from the other processor | |
135 | li r17,0 ; Clear this out | |
136 | lwz r16,ruptStamp+4(r3) ; Get the timebase from the other processor | |
137 | mtspr tbl,r17 ; Clear bottom so we do not tick | |
138 | mtspr tbu,r15 ; Set top | |
139 | mtspr tbl,r16 ; Then bottom again | |
140 | ||
141 | b allstart | |
142 | ||
143 | ENTRY(_start,TAG_NO_FRAME_USED) | |
144 | ||
145 | lis r30,hi16(EXT(per_proc_info)) ; Set current per_proc | |
146 | ori r30,r30,lo16(EXT(per_proc_info)) ; Set current per_proc | |
147 | crset bootCPU ; Set boot processor | |
148 | ||
149 | lwz r17,pfAvailable(r30) ; Get the available bits | |
150 | rlwinm. r0,r17,0,pfValidb,pfValidb ; Have we initialized the feature flags yet? | |
151 | crmove firstInit,cr0_eq ; Set if we are doing first time init | |
152 | bne allstart ; Yeah, we must be waking up from sleep... | |
153 | ||
154 | ; | |
155 | ; Here is where we do any one time general low-level initialization | |
156 | ||
157 | lis r20,HIGH_ADDR(fwdisplock) ; Get address of the firmware display lock | |
158 | li r19,0 ; Zorch a register | |
159 | ori r20,r20,LOW_ADDR(fwdisplock) ; Get address of the firmware display lock | |
160 | stw r19,0(r20) ; Make sure the lock is free | |
161 | ||
162 | allstart: mr r31,r3 ; Save away arguments | |
163 | lis r23,hi16(EXT(per_proc_info)) ; Set base per_proc | |
164 | ori r23,r23,lo16(EXT(per_proc_info)) ; Set base per_proc | |
165 | ||
166 | mtsprg 0,r30 ; Set the per_proc | |
167 | ||
168 | mfspr r6,hid0 ; Get the HID0 | |
169 | li r7,MSR_VM_OFF ; Get real mode MSR | |
170 | rlwinm r6,r6,0,sleep+1,doze-1 ; Remove any vestiges of sleep | |
171 | mtspr hid0,r6 ; Set the insominac HID0 | |
172 | mtmsr r7 ; Set the real mode SRR | |
173 | isync | |
174 | ||
175 | ; Map in the first 256Mb in both instruction and data BATs | |
176 | ||
177 | li r7,((0x7FF<<2)|2) ; Set up for V=R 256MB in supervisor space | |
178 | li r8,((2<<3)|2) ; Physical address = 0, coherent, R/W | |
179 | li r9,0 ; Clear out a register | |
180 | ||
181 | mtsprg 1,r9 ; Clear the extra SPRGs | |
182 | mtsprg 2,r9 | |
183 | mtsprg 3,r9 | |
184 | ||
185 | sync | |
186 | isync | |
187 | mtdbatu 0,r7 ; Map bottom 256MB | |
188 | mtdbatl 0,r8 ; Map bottom 256MB | |
189 | mtdbatu 1,r9 ; Invalidate maps | |
190 | mtdbatl 1,r9 ; Invalidate maps | |
191 | mtdbatu 2,r9 ; Invalidate maps | |
192 | mtdbatl 2,r9 ; Invalidate maps | |
193 | mtdbatu 3,r9 ; Invalidate maps | |
194 | mtdbatl 3,r9 ; Invalidate maps | |
195 | sync | |
196 | isync | |
197 | mtibatu 0,r7 ; Map bottom 256MB | |
198 | mtibatl 0,r8 ; Map bottom 256MB | |
199 | mtibatu 1,r9 ; Invalidate maps | |
200 | mtibatl 1,r9 ; Invalidate maps | |
201 | mtibatu 2,r9 ; Invalidate maps | |
202 | mtibatl 2,r9 ; Invalidate maps | |
203 | mtibatu 3,r9 ; Invalidate maps | |
204 | mtibatl 3,r9 ; Invalidate maps | |
205 | sync | |
206 | isync | |
207 | ||
208 | lis r26,hi16(processor_types) ; Point to processor table | |
209 | ori r26,r26,lo16(processor_types) ; Other half | |
210 | mfpvr r10 ; Get the PVR | |
211 | ||
212 | nextPVR: lwz r28,ptFilter(r26) ; Get the filter | |
213 | lwz r27,ptVersion(r26) ; Get the version and revision codes | |
214 | and r28,r10,r28 ; Throw away dont care bits | |
215 | cmplw r27,r28 ; Is this the right set? | |
216 | beq donePVR ; We have the right one... | |
217 | addi r26,r26,ptSize ; Point to the next type | |
218 | b nextPVR ; Check it out... | |
219 | ||
220 | donePVR: lwz r20,ptInitRout(r26) ; Grab the special init routine | |
221 | mtlr r20 ; Setup to call the init | |
222 | ||
223 | bf firstInit,notFirst ; Not first boot, go... | |
224 | ||
225 | ; | |
226 | ; The following code just does a general initialization of the features just | |
227 | ; after the initial first-time boot. This is not done after waking up or on | |
228 | ; any "secondary" processor. | |
229 | ; | |
230 | ; We are just setting defaults. The specific initialization code will modify these | |
231 | ; if necessary. | |
232 | ; | |
233 | ||
234 | lwz r17,ptFeatures(r26) ; Pick up the features | |
235 | ||
236 | lwz r13,ptRptdProc(r26) ; Get the reported processor | |
237 | sth r13,pfrptdProc(r30) ; Set the reported processor | |
238 | ||
239 | lwz r13,ptTempMax(r26) ; Get maximum operating temperature | |
240 | stw r13,thrmmaxTemp(r30) ; Set the maximum | |
241 | lwz r13,ptTempThr(r26) ; Get temprature to throttle down when exceeded | |
242 | stw r13,thrmthrottleTemp(r30) ; Set the temperature that we throttle | |
243 | ||
244 | lwz r13,ptLineSize(r26) ; Get the cache line size | |
245 | sth r13,pflineSize(r30) ; Save it | |
246 | lwz r13,ptl1iSize(r26) ; Get icache size | |
247 | stw r13,pfl1iSize(r30) ; Save it | |
248 | lwz r13,ptl1dSize(r26) ; Get dcache size | |
249 | stw r13,pfl1dSize(r30) ; Save it | |
250 | b doOurInit ; Go do processor specific initialization... | |
251 | ||
252 | notFirst: lwz r17,pfAvailable(r30) ; Get our features | |
253 | rlwinm. r0,r17,0,pfValidb,pfValidb ; Have we set up this CPU yet? | |
254 | bne doOurInit ; Yeah, must be wakeup... | |
255 | ||
256 | lis r23,hi16(EXT(per_proc_info)) ; Set base per_proc | |
257 | ori r23,r23,lo16(EXT(per_proc_info)) ; Set base per_proc | |
258 | ||
259 | la r7,pfAvailable(r30) ; Point to features of our processor | |
260 | la r8,pfAvailable(r23) ; Point to features of boot processor | |
261 | li r9,(pfSize+thrmSize)/4 ; Get size of a features area | |
262 | ||
263 | cpyFeat: subi r9,r9,1 ; Count word | |
264 | lwz r0,0(r8) ; Get boot cpu features | |
265 | stw r0,0(r7) ; Copy to ours | |
266 | mr. r9,r9 ; Finished? | |
267 | addi r7,r7,4 ; Next out | |
268 | addi r8,r8,4 ; Next in | |
269 | bgt cpyFeat ; Copy all boot cpu features to us... | |
270 | ||
271 | lwz r17,pfAvailable(r30) ; Get our newly initialized features | |
272 | ||
273 | doOurInit: | |
274 | mr. r20,r20 ; See if initialization routine | |
275 | crand firstBoot,bootCPU,firstInit ; Indicate if we are on the initial first processor startup | |
276 | bnelrl ; Do the initialization | |
277 | ||
278 | ori r17,r17,lo16(pfValid) ; Set the valid bit | |
279 | stw r17,pfAvailable(r30) ; Set the available features | |
280 | mtsprg 2,r17 ; Remember the feature flags | |
281 | ||
282 | rlwinm. r0,r17,0,pfFloatb,pfFloatb ; See if there is floating point | |
283 | beq- noFloat ; Nope, this is a really stupid machine... | |
284 | ||
285 | li r0,MSR_VM_OFF|MASK(MSR_FP) ; Enable for floating point | |
286 | mtmsr r0 /* Set the standard MSR values */ | |
287 | isync | |
288 | ||
289 | lis r5,HIGH_ADDR(EXT(FloatInit)) /* Get top of floating point init value */ | |
290 | ori r5,r5,LOW_ADDR(EXT(FloatInit)) /* Slam bottom */ | |
291 | lfd f0,0(r5) /* Initialize FP0 */ | |
292 | fmr f1,f0 /* Ours in not */ | |
293 | fmr f2,f0 /* to wonder why, */ | |
294 | fmr f3,f0 /* ours is but to */ | |
295 | fmr f4,f0 /* do or die! */ | |
296 | fmr f5,f0 | |
297 | fmr f6,f0 | |
298 | fmr f7,f0 | |
299 | fmr f8,f0 | |
300 | fmr f9,f0 | |
301 | fmr f10,f0 | |
302 | fmr f11,f0 | |
303 | fmr f12,f0 | |
304 | fmr f13,f0 | |
305 | fmr f14,f0 | |
306 | fmr f15,f0 | |
307 | fmr f16,f0 | |
308 | fmr f17,f0 | |
309 | fmr f18,f0 | |
310 | fmr f19,f0 | |
311 | fmr f20,f0 | |
312 | fmr f21,f0 | |
313 | fmr f22,f0 | |
314 | fmr f23,f0 | |
315 | fmr f24,f0 | |
316 | fmr f25,f0 | |
317 | fmr f26,f0 | |
318 | fmr f27,f0 | |
319 | fmr f28,f0 | |
320 | fmr f29,f0 | |
321 | fmr f30,f0 | |
322 | fmr f31,f0 | |
323 | ||
324 | li r0, MSR_VM_OFF ; Turn off floating point | |
325 | mtmsr r0 | |
326 | isync | |
327 | ||
328 | noFloat: rlwinm. r0,r17,0,pfAltivecb,pfAltivecb ; See if there is Altivec | |
329 | beq- noVector ; Nope... | |
330 | ||
331 | li r0,0 ; Clear out a register | |
332 | ||
333 | lis r7,hi16(MSR_VEC_ON) ; Get real mode MSR + Altivec | |
334 | ori r7,r7,lo16(MSR_VM_OFF) ; Get real mode MSR + Altivec | |
335 | mtmsr r7 ; Set the real mode SRR */ | |
336 | isync ; Make sure it has happened | |
337 | ||
338 | lis r5,hi16(EXT(QNaNbarbarian)) ; Altivec initializer | |
339 | ori r5,r5,lo16(EXT(QNaNbarbarian)) ; Altivec initializer | |
340 | ||
341 | mtspr vrsave,r0 ; Set that no VRs are used yet */ | |
342 | ||
343 | vspltisw v1,0 ; Clear a register | |
344 | lvx v0,br0,r5 ; Initialize VR0 | |
345 | mtvscr v1 ; Clear the vector status register | |
346 | vor v2,v0,v0 ; Copy into the next register | |
347 | vor v1,v0,v0 ; Copy into the next register | |
348 | vor v3,v0,v0 ; Copy into the next register | |
349 | vor v4,v0,v0 ; Copy into the next register | |
350 | vor v5,v0,v0 ; Copy into the next register | |
351 | vor v6,v0,v0 ; Copy into the next register | |
352 | vor v7,v0,v0 ; Copy into the next register | |
353 | vor v8,v0,v0 ; Copy into the next register | |
354 | vor v9,v0,v0 ; Copy into the next register | |
355 | vor v10,v0,v0 ; Copy into the next register | |
356 | vor v11,v0,v0 ; Copy into the next register | |
357 | vor v12,v0,v0 ; Copy into the next register | |
358 | vor v13,v0,v0 ; Copy into the next register | |
359 | vor v14,v0,v0 ; Copy into the next register | |
360 | vor v15,v0,v0 ; Copy into the next register | |
361 | vor v16,v0,v0 ; Copy into the next register | |
362 | vor v17,v0,v0 ; Copy into the next register | |
363 | vor v18,v0,v0 ; Copy into the next register | |
364 | vor v19,v0,v0 ; Copy into the next register | |
365 | vor v20,v0,v0 ; Copy into the next register | |
366 | vor v21,v0,v0 ; Copy into the next register | |
367 | vor v22,v0,v0 ; Copy into the next register | |
368 | vor v23,v0,v0 ; Copy into the next register | |
369 | vor v24,v0,v0 ; Copy into the next register | |
370 | vor v25,v0,v0 ; Copy into the next register | |
371 | vor v26,v0,v0 ; Copy into the next register | |
372 | vor v27,v0,v0 ; Copy into the next register | |
373 | vor v28,v0,v0 ; Copy into the next register | |
374 | vor v29,v0,v0 ; Copy into the next register | |
375 | vor v30,v0,v0 ; Copy into the next register | |
376 | vor v31,v0,v0 ; Copy into the next register | |
377 | ||
378 | li r0, MSR_VM_OFF ; Turn off vectors | |
379 | mtmsr r0 | |
380 | isync | |
381 | ||
382 | noVector: rlwinm. r0,r17,0,pfSMPcapb,pfSMPcapb ; See if we can do SMP | |
383 | beq- noSMP ; Nope... | |
384 | ||
385 | lhz r13,PP_CPU_NUMBER(r30) ; Get the CPU number | |
386 | mtspr pir,r13 ; Set the PIR | |
387 | ||
388 | noSMP: rlwinm. r0,r17,0,pfThermalb,pfThermalb ; See if there is an TAU | |
389 | beq- noThermometer ; Nope... | |
390 | ||
391 | li r13,0 ; Disable thermals for now | |
392 | mtspr thrm3,r13 ; Do it | |
393 | li r13,lo16(thrmtidm|thrmvm) ; Set for lower-than thermal event at 0 degrees | |
394 | mtspr thrm1,r13 ; Do it | |
395 | lis r13,hi16(thrmthrm) ; Set 127 degrees | |
396 | ori r13,r13,lo16(thrmvm) ; Set for higher-than event | |
397 | mtspr thrm2,r13 ; Set it | |
398 | ||
399 | noThermometer: | |
400 | ||
401 | bl EXT(cacheInit) ; Initializes all caches (including the TLB) | |
402 | ||
403 | li r0,MSR_SUPERVISOR_INT_OFF ; Make sure we do not have FP enabled | |
404 | mtmsr r0 ; Set the standard MSR values | |
405 | isync | |
406 | ||
407 | bf bootCPU,callcpu ; Not the boot processor... | |
408 | ||
409 | lis r29,HIGH_ADDR(EXT(intstack_top_ss)) ; move onto interrupt stack | |
410 | ori r29,r29,LOW_ADDR(EXT(intstack_top_ss)) | |
411 | lwz r29,0(r29) | |
412 | ||
413 | li r28,0 | |
414 | stw r28,FM_BACKPTR(r29) ; store a null frame backpointer | |
415 | ||
416 | mr r1,r29 | |
417 | mr r3,r31 ; Restore any arguments we may have trashed | |
418 | ||
419 | bl EXT(ppc_init) ; Jump into boot init code | |
420 | BREAKPOINT_TRAP | |
421 | ||
422 | callcpu: | |
423 | lwz r29,PP_INTSTACK_TOP_SS(r31) ; move onto interrupt stack | |
424 | ||
425 | li r28,0 | |
426 | stw r28,FM_BACKPTR(r29) ; store a null frame backpointer | |
427 | ||
428 | ||
429 | mr r1,r29 ; move onto new stack | |
430 | mr r3,r31 ; Restore any arguments we may have trashed | |
431 | ||
432 | bl EXT(ppc_init_cpu) ; Jump into cpu init code | |
433 | BREAKPOINT_TRAP ; Should never return | |
434 | ||
435 | ; | |
436 | ; Specific processor initialization routines | |
437 | ; | |
438 | ||
439 | ; 750CX | |
440 | ||
765c9de3 A |
441 | init750CX: |
442 | bf firstBoot, init750 ; No init for wakeup.... | |
1c79356b A |
443 | mfspr r13,hid1 ; Get HID1 |
444 | li r14,lo16(0xFD5F) ; Get valid | |
445 | rlwinm r13,r13,4,28,31 ; Isolate | |
446 | slw r14,r14,r13 ; Position | |
447 | rlwimi r17,r14,15-pfCanNapb,pfCanNapb,pfCanNapb ; Set it | |
765c9de3 | 448 | b init750 ; Join common... |
1c79356b A |
449 | |
450 | ; 750 | |
451 | ||
765c9de3 A |
452 | init750: |
453 | bf firstBoot, init750nb ; No init for wakeup.... | |
1c79356b | 454 | |
765c9de3 | 455 | mfspr r13,l2cr ; Get the L2CR |
1c79356b A |
456 | rlwinm. r0,r13,0,l2e,l2e ; Any L2? |
457 | bne+ i750hl2 ; Yes... | |
458 | rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature | |
459 | ||
765c9de3 A |
460 | i750hl2: |
461 | lis r14,hi16(256*1024) ; Base L2 size | |
462 | addis r15,r13,0x3000 ; Hah... Figure this one out... | |
463 | rlwinm r15,r15,4,30,31 ; Isolate | |
464 | rlwinm. r8,r13,0,l2siz,l2sizf ; Was size valid? | |
465 | slw r14,r14,r15 ; Set 256KB, 512KB, or 1MB | |
466 | beq- init750l2none ; Not a valid setting... | |
1c79356b | 467 | |
765c9de3 A |
468 | stw r13,pfl2cr(r30) ; Shadow the L2CR |
469 | stw r14,pfl2Size(r30) ; Set the L2 size | |
470 | b init750l2done ; Done with L2 | |
1c79356b | 471 | |
765c9de3 A |
472 | init750l2none: |
473 | rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No level 2 cache | |
474 | ||
475 | init750l2done: | |
476 | mfspr r11,hid0 ; Get the current HID0 | |
477 | stw r11,pfHID0(r30) ; Save the HID0 value | |
478 | blr ; Return... | |
479 | ||
480 | init750nb: | |
481 | lwz r11,pfHID0(r30) ; Get HID0 | |
482 | sync | |
483 | mtspr hid0,r11 ; Set the HID | |
484 | isync | |
485 | sync | |
486 | blr | |
1c79356b A |
487 | |
488 | init7400: bf firstBoot,i7400nb ; Do different if not initial boot... | |
489 | mfspr r13,l2cr ; Get the L2CR | |
490 | rlwinm. r0,r13,0,l2e,l2e ; Any L2? | |
491 | bne+ i7400hl2 ; Yes... | |
492 | rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature | |
493 | ||
494 | i7400hl2: lis r14,hi16(256*1024) ; Base L2 size | |
495 | addis r15,r13,0x3000 ; Hah... Figure this one out... | |
496 | rlwinm r15,r15,4,30,31 | |
497 | slw r14,r14,r15 ; Set 256KB, 512KB, 1MB, or 2MB | |
498 | ||
499 | stw r13,pfl2cr(r30) ; Shadow the L2CR | |
500 | stw r14,pfl2Size(r30) ; Set the L2 size | |
501 | ||
502 | mfspr r11,hid0 ; Get the current HID0 | |
503 | oris r11,r11,hi16(emcpm|eiecm) ; ? | |
504 | mtspr hid0,r11 ; ? | |
505 | isync | |
506 | stw r11,pfHID0(r30) ; Save the HID0 value | |
507 | ||
508 | mfspr r11,msscr0 ; Get the msscr0 register | |
509 | stw r11,pfMSSCR0(r30) ; Save the MSSCR0 value | |
510 | mfspr r11,msscr1 ; Get the msscr1 register | |
511 | stw r11,pfMSSCR1(r30) ; Save the MSSCR1 value | |
512 | blr ; Return... | |
513 | ||
765c9de3 A |
514 | i7400nb: |
515 | lwz r11,pfHID0(r30) ; Get HID0 | |
1c79356b A |
516 | sync |
517 | mtspr hid0,r11 ; Set the HID | |
765c9de3 A |
518 | isync |
519 | sync | |
1c79356b A |
520 | lwz r11,pfMSSCR0(r30) ; Get MSSCR0 |
521 | isync | |
522 | sync | |
523 | mtspr msscr0,r11 ; Set the MSSCR0 | |
524 | lwz r11,pfMSSCR1(r30) ; Get msscr1 | |
525 | isync | |
526 | sync | |
527 | mtspr msscr1,r11 ; Set the msscr1 | |
528 | isync | |
529 | sync | |
530 | blr | |
531 | ||
532 | ; 7410 | |
533 | ; Note that this is the same as 7400 except we initialize the l2cr2 register | |
534 | ||
535 | init7410: li r13,0 ; Clear | |
536 | mtspr 1016,r13 ; Turn off direct cache | |
537 | b init7400 ; Join up with common.... | |
538 | ||
539 | ; 7450 | |
540 | ||
541 | init7450: bf firstBoot,i7450nb ; Do different if not initial boot... | |
1c79356b A |
542 | |
543 | mfspr r13,l2cr ; Get the L2CR | |
544 | rlwinm. r0,r13,0,l2e,l2e ; Any L2? | |
545 | bne+ i7450hl2 ; Yes... | |
546 | rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature | |
547 | ||
548 | i7450hl2: lis r14,hi16(256*1024) ; Base L2 size | |
549 | rlwinm r15,r13,22,12,13 ; Convert to 256k, 512k, or 768k | |
550 | add r14,r14,r15 ; Add in minimum | |
551 | ||
552 | stw r13,pfl2cr(r30) ; Shadow the L2CR | |
553 | stw r14,pfl2Size(r30) ; Set the L2 size | |
554 | ||
555 | ; Take care of level 3 cache | |
556 | ||
557 | mfspr r13,l3cr ; Get the L3CR | |
7b1edb79 | 558 | rlwinm. r0,r13,0,l3e,l3e ; Any L3? |
1c79356b | 559 | bne+ i7450hl3 ; Yes... |
7b1edb79 | 560 | rlwinm r17,r17,0,pfL3b+1,pfL3b-1 ; No L3, turn off feature |
1c79356b A |
561 | |
562 | i7450hl3: cmplwi cr0,r13,0 ; No L3 if L3CR is zero | |
563 | beq- init7450none ; Go turn off the features... | |
564 | lis r14,hi16(1024*1024) ; Base L3 size | |
565 | rlwinm r15,r13,4,31,31 ; Get size multiplier | |
566 | slw r14,r14,r15 ; Set 1 or 2MB | |
567 | ||
568 | stw r13,pfl3cr(r30) ; Shadow the L3CR | |
569 | stw r14,pfl3Size(r30) ; Set the L3 size | |
570 | b init7450fin ; Return.... | |
571 | ||
572 | init7450none: | |
0b4e3aa0 A |
573 | rlwinm r17,r17,0,pfL3fab+1,pfL3b-1 ; No 3rd level cache or assist |
574 | rlwinm r11,r17,pfWillNapb-pfCanNapb,pfCanNapb,pfCanNapb ; Set pfCanNap if pfWillNap is set | |
575 | or r17,r17,r11 | |
1c79356b | 576 | |
0b4e3aa0 A |
577 | init7450fin: |
578 | rlwinm r17,r17,0,pfWillNapb+1,pfWillNapb-1 ; Make sure pfWillNap is not set | |
579 | ||
580 | mfspr r11,hid0 ; Get the current HID0 | |
1c79356b A |
581 | stw r11,pfHID0(r30) ; Save the HID0 value |
582 | mfspr r11,hid1 ; Get the current HID1 | |
583 | stw r11,pfHID1(r30) ; Save the HID1 value | |
584 | mfspr r11,msscr0 ; Get the msscr0 register | |
585 | stw r11,pfMSSCR0(r30) ; Save the MSSCR0 value | |
586 | mfspr r11,msscr1 ; Get the msscr1 register | |
587 | stw r11,pfMSSCR1(r30) ; Save the MSSCR1 value | |
588 | mfspr r11,ictrl ; Get the ictrl register | |
589 | stw r11,pfICTRL(r30) ; Save the ICTRL value | |
590 | mfspr r11,ldstcr ; Get the ldstcr register | |
591 | stw r11,pfLDSTCR(r30) ; Save the LDSTCR value | |
0b4e3aa0 A |
592 | mfspr r11,ldstdb ; Get the ldstdb register |
593 | stw r11,pfLDSTDB(r30) ; Save the LDSTDB value | |
1c79356b A |
594 | blr ; Return.... |
595 | ||
596 | ||
597 | i7450nb: lwz r11,pfHID0(r30) ; Get HID0 | |
598 | sync | |
599 | mtspr hid0,r11 ; Set the HID | |
600 | isync | |
601 | lwz r11,pfHID1(r30) ; Get HID1 | |
602 | sync | |
603 | mtspr hid1,r11 ; Set the HID | |
604 | isync | |
605 | lwz r11,pfMSSCR0(r30) ; Get MSSCR0 | |
606 | sync | |
607 | mtspr msscr0,r11 ; Set the MSSCR0 | |
608 | isync | |
609 | sync | |
610 | lwz r11,pfICTRL(r30) ; Get ICTRL | |
611 | sync | |
612 | mtspr ictrl,r11 ; Set the ICTRL | |
613 | isync | |
614 | sync | |
615 | lwz r11,pfLDSTCR(r30) ; Get LDSTCR | |
616 | sync | |
617 | mtspr ldstcr,r11 ; Set the LDSTCR | |
618 | isync | |
619 | sync | |
0b4e3aa0 A |
620 | lwz r11,pfLDSTDB(r30) ; Get LDSTDB |
621 | sync | |
622 | mtspr ldstdb,r11 ; Set the LDSTDB | |
623 | isync | |
624 | sync | |
1c79356b A |
625 | blr |
626 | ||
627 | ||
628 | ; | |
629 | ; Processor to feature table | |
630 | ||
631 | ; .align 2 - Always on word boundary | |
632 | ; .long ptFilter - Mask of significant bits in the Version/Revision code | |
633 | ; - NOTE: Always order from most restrictive to least restrictive matching | |
634 | ; .short ptVersion - Version code from PVR. Always start with 0 which is default | |
635 | ; .short ptRevision - Revision code from PVR. A zero value denotes the generic attributes if not specific | |
636 | ; .long ptFeatures - Available features | |
637 | ; .long ptInitRout - Initilization routine. Can modify any of the other attributes. | |
638 | ; .long ptRptdProc - Processor type reported | |
639 | ; .long ptTempMax - Maximum operating temprature | |
640 | ; .long ptTempThr - Temprature threshold. We throttle if above | |
641 | ; .long ptLineSize - Level 1 cache line size | |
642 | ; .long ptl1iSize - Level 1 instruction cache size | |
643 | ; .long ptl1dSize - Level 1 data cache size | |
644 | ||
645 | .align 2 | |
646 | processor_types: | |
647 | ||
648 | ||
649 | ; 601 (generic) | |
650 | ||
651 | .align 2 | |
652 | .long 0xFFFF0000 ; All revisions | |
653 | .short PROCESSOR_VERSION_601 | |
654 | .short 0 | |
655 | .long pfFloat | pfSMPcap | pfL1i | pfL1d | |
656 | .long 0 | |
657 | .long CPU_SUBTYPE_POWERPC_ALL | |
658 | .long 0 | |
659 | .long 0 | |
660 | .long 32 | |
661 | .long 32*1024 | |
662 | .long 32*1024 | |
663 | ||
664 | ; 603 (generic) | |
665 | ||
666 | .align 2 | |
667 | .long 0xFFFF0000 ; All revisions | |
668 | .short PROCESSOR_VERSION_603 | |
669 | .short 0 | |
670 | .long pfFloat | pfL1i | pfL1d | |
671 | .long 0 | |
672 | .long CPU_SUBTYPE_POWERPC_603 | |
673 | .long 0 | |
674 | .long 0 | |
675 | .long 32 | |
676 | .long 32*1024 | |
677 | .long 32*1024 | |
678 | ||
679 | ; 603e (generic) | |
680 | ||
681 | .align 2 | |
682 | .long 0xFFFF0000 ; All revisions | |
683 | .short PROCESSOR_VERSION_603e | |
684 | .short 0 | |
685 | .long pfFloat | pfL1i | pfL1d | |
686 | .long 0 | |
687 | .long CPU_SUBTYPE_POWERPC_603e | |
688 | .long 0 | |
689 | .long 0 | |
690 | .long 32 | |
691 | .long 32*1024 | |
692 | .long 32*1024 | |
693 | ||
694 | ; 604 (generic) | |
695 | ||
696 | .align 2 | |
697 | .long 0xFFFF0000 ; All revisions | |
698 | .short PROCESSOR_VERSION_604 | |
699 | .short 0 | |
700 | .long pfFloat | pfSMPcap | pfL1i | pfL1d | |
701 | .long 0 | |
702 | .long CPU_SUBTYPE_POWERPC_604 | |
703 | .long 0 | |
704 | .long 0 | |
705 | .long 32 | |
706 | .long 32*1024 | |
707 | .long 32*1024 | |
708 | ||
709 | ; 604e (generic) | |
710 | ||
711 | .align 2 | |
712 | .long 0xFFFF0000 ; All revisions | |
713 | .short PROCESSOR_VERSION_604e | |
714 | .short 0 | |
715 | .long pfFloat | pfSMPcap | pfL1i | pfL1d | |
716 | .long 0 | |
717 | .long CPU_SUBTYPE_POWERPC_604e | |
718 | .long 0 | |
719 | .long 0 | |
720 | .long 32 | |
721 | .long 32*1024 | |
722 | .long 32*1024 | |
723 | ||
724 | ; 604ev (generic) | |
725 | ||
726 | .align 2 | |
727 | .long 0xFFFF0000 ; All revisions | |
728 | .short PROCESSOR_VERSION_604ev | |
729 | .short 0 | |
730 | .long pfFloat | pfSMPcap | pfL1i | pfL1d | |
731 | .long 0 | |
732 | .long CPU_SUBTYPE_POWERPC_604e | |
733 | .long 0 | |
734 | .long 0 | |
735 | .long 32 | |
736 | .long 32*1024 | |
737 | .long 32*1024 | |
738 | ||
739 | ; 750 (ver 2.2) | |
740 | ||
741 | .align 2 | |
742 | .long 0xFFFFFFFF ; Exact match | |
743 | .short PROCESSOR_VERSION_750 | |
744 | .short 0x4202 | |
745 | .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfL1i | pfL1d | pfL2 | |
746 | .long init750 | |
747 | .long CPU_SUBTYPE_POWERPC_750 | |
748 | .long 105 | |
749 | .long 90 | |
750 | .long 32 | |
751 | .long 32*1024 | |
752 | .long 32*1024 | |
753 | ||
754 | ; 750CX (ver 2.x) | |
755 | ||
756 | .align 2 | |
757 | .long 0xFFFF0F00 ; 2.x vers | |
758 | .short PROCESSOR_VERSION_750 | |
759 | .short 0x0200 | |
760 | .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfL1i | pfL1d | pfL2 | |
761 | .long init750CX | |
762 | .long CPU_SUBTYPE_POWERPC_750 | |
763 | .long 105 | |
764 | .long 90 | |
765 | .long 32 | |
766 | .long 32*1024 | |
767 | .long 32*1024 | |
768 | ||
769 | ; 750 (generic) | |
770 | ||
771 | .align 2 | |
772 | .long 0xFFFF0000 ; All revisions | |
773 | .short PROCESSOR_VERSION_750 | |
774 | .short 0 | |
775 | .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pfL1i | pfL1d | pfL2 | |
776 | .long init750 | |
777 | .long CPU_SUBTYPE_POWERPC_750 | |
778 | .long 105 | |
779 | .long 90 | |
780 | .long 32 | |
781 | .long 32*1024 | |
782 | .long 32*1024 | |
783 | ||
0b4e3aa0 | 784 | |
1c79356b A |
785 | ; 7400 (generic) |
786 | ||
787 | .align 2 | |
788 | .long 0xFFFF0000 ; All revisions | |
789 | .short PROCESSOR_VERSION_7400 | |
790 | .short 0 | |
791 | .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pfL1i | pfL1d | pfL1fa | pfL2 | pfL2fa | |
792 | .long init7400 | |
793 | .long CPU_SUBTYPE_POWERPC_7400 | |
794 | .long 105 | |
795 | .long 90 | |
796 | .long 32 | |
797 | .long 32*1024 | |
798 | .long 32*1024 | |
799 | ||
800 | ; 7410 (ver 1.1) | |
801 | ||
802 | .align 2 | |
803 | .long 0xFFFFFFFF ; Exact match | |
804 | .short PROCESSOR_VERSION_7400 | |
805 | .short 0x1101 | |
806 | .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pfL1i | pfL1d | pfL1fa | pfL2 | pfL2fa | |
807 | .long init7410 | |
808 | .long CPU_SUBTYPE_POWERPC_7400 | |
809 | .long 105 | |
810 | .long 90 | |
811 | .long 32 | |
812 | .long 32*1024 | |
813 | .long 32*1024 | |
814 | ||
815 | ; 7410 (generic) | |
816 | ||
817 | .align 2 | |
818 | .long 0xFFFF0000 ; All other revisions | |
819 | .short PROCESSOR_VERSION_7410 | |
820 | .short 0 | |
821 | .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pfL1i | pfL1d | pfL1fa | pfL2 | pfL2fa | |
822 | .long init7410 | |
823 | .long CPU_SUBTYPE_POWERPC_7400 | |
824 | .long 105 | |
825 | .long 90 | |
826 | .long 32 | |
827 | .long 32*1024 | |
828 | .long 32*1024 | |
829 | ||
830 | ; 7450 (ver 1.xx) | |
831 | ||
832 | .align 2 | |
833 | .long 0xFFFFFF00 ; Just revisions 1.xx | |
834 | .short PROCESSOR_VERSION_7450 | |
835 | .short 0x0100 | |
7b1edb79 | 836 | .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfL3pdet |
1c79356b A |
837 | .long init7450 |
838 | .long CPU_SUBTYPE_POWERPC_7450 | |
839 | .long 105 | |
840 | .long 90 | |
841 | .long 32 | |
842 | .long 32*1024 | |
843 | .long 32*1024 | |
844 | ||
0b4e3aa0 A |
845 | ; 7450 (2.0) |
846 | ||
847 | .align 2 | |
848 | .long 0xFFFFFFFF ; Just revision 2.0 | |
849 | .short PROCESSOR_VERSION_7450 | |
850 | .short 0x0200 | |
7b1edb79 | 851 | .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfL3pdet |
0b4e3aa0 A |
852 | .long init7450 |
853 | .long CPU_SUBTYPE_POWERPC_7450 | |
854 | .long 105 | |
855 | .long 90 | |
856 | .long 32 | |
857 | .long 32*1024 | |
858 | .long 32*1024 | |
859 | ||
860 | ; 7450 (2.1) | |
1c79356b A |
861 | |
862 | .align 2 | |
863 | .long 0xFFFF0000 ; All other revisions | |
864 | .short PROCESSOR_VERSION_7450 | |
865 | .short 0 | |
7b1edb79 | 866 | .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfL3pdet |
1c79356b A |
867 | .long init7450 |
868 | .long CPU_SUBTYPE_POWERPC_7450 | |
869 | .long 105 | |
870 | .long 90 | |
871 | .long 32 | |
872 | .long 32*1024 | |
873 | .long 32*1024 | |
874 | ||
0b4e3aa0 | 875 | |
1c79356b A |
876 | ; Default dumb loser machine |
877 | ||
878 | .align 2 | |
879 | .long 0x00000000 ; Matches everything | |
880 | .short 0 | |
881 | .short 0 | |
882 | .long pfFloat | pfL1i | pfL1d | |
883 | .long 0 | |
884 | .long CPU_SUBTYPE_POWERPC_ALL | |
885 | .long 105 | |
886 | .long 90 | |
887 | .long 32 | |
888 | .long 32*1024 | |
889 | .long 32*1024 |