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