2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
29 #define __APPLE_API_PRIVATE
34 #include <mach_kgdb.h>
36 #include <ppc/proc_reg.h>
37 #include <ppc/spec_reg.h>
38 #include <machine/cpu_capabilities.h>
39 #include <mach/ppc/vm_param.h>
65 * Interrupt and bootup stack for initial processor
71 * All CPUs start here.
73 * This code is called from SecondaryLoader
75 * Various arguments are passed via a table:
76 * R3 = pointer to other startup parameters
80 ENTRY(resetPOR,TAG_NO_FRAME_USED)
83 stw r12,0xF0(0) ; Make sure the special flag is clear
84 mtmsrd r12 ; Make sure we are in 32-bit mode
85 isync ; Really make sure
86 lwz r3,0xF4(0) ; Get the boot_args pointer
87 b startJoin ; Join up...
90 ENTRY(_start_cpu,TAG_NO_FRAME_USED)
91 crclr bootCPU ; Set non-boot processor
92 crclr firstInit ; Set not first time init
93 mr r30,r3 ; Set current per_proc
96 ; Note that we are just trying to get close. The real TB sync will take
97 ; place later. The value we are loading is set in two places. For the
98 ; main processor, it will be the TB at the last interrupt before we went
99 ; to sleep. For the others, it will be the time just before the main
100 ; processor woke us up.
103 lwz r15,ruptStamp(r3) ; Get the timebase from the other processor
104 li r17,0 ; Clear this out
105 lwz r16,ruptStamp+4(r3) ; Get the timebase from the other processor
106 mtspr tbl,r17 ; Clear bottom so we do not tick
107 mtspr tbu,r15 ; Set top
108 mtspr tbl,r16 ; Then bottom again
111 ENTRY(_start,TAG_NO_FRAME_USED)
114 mflr r2 ; Save the return address
115 lis r30,hi16(EXT(per_proc_info)) ; Set current per_proc
116 ori r30,r30,lo16(EXT(per_proc_info)) ; Set current per_proc
117 crset bootCPU ; Set boot processor
119 lwz r17,pfAvailable(r30) ; Get the available bits
120 rlwinm. r0,r17,0,pfValidb,pfValidb ; Have we initialized the feature flags yet?
121 crmove firstInit,cr0_eq ; Set if we are doing first time init
122 bne allstart ; Yeah, we must be waking up from sleep...
125 ; Here is where we do any one time general low-level initialization
127 lis r20,HIGH_ADDR(fwdisplock) ; Get address of the firmware display lock
128 li r19,0 ; Zorch a register
129 ori r20,r20,LOW_ADDR(fwdisplock) ; Get address of the firmware display lock
130 stw r19,0(r20) ; Make sure the lock is free
133 mr r31,r3 ; Save away arguments
135 crand firstBoot,bootCPU,firstInit ; Indicate if we are on the initial first processor startup
137 mtsprg 0,r30 ; Set the per_proc
139 li r9,0 ; Clear out a register
140 mtsprg 1,r9 ; Clear the SPRGs
144 li r7,MSR_VM_OFF ; Get real mode MSR
145 mtmsr r7 ; Set the real mode SRR
148 lis r26,hi16(processor_types) ; Point to processor table
149 ori r26,r26,lo16(processor_types) ; Other half
150 mfpvr r10 ; Get the PVR
152 nextPVR: lwz r28,ptFilter(r26) ; Get the filter
153 lwz r27,ptVersion(r26) ; Get the version and revision codes
154 and r28,r10,r28 ; Throw away dont care bits
155 cmplw r27,r28 ; Is this the right set?
156 beq donePVR ; We have the right one...
157 addi r26,r26,ptSize ; Point to the next type
158 b nextPVR ; Check it out...
160 donePVR: lwz r20,ptInitRout(r26) ; Grab the special init routine
161 mtlr r20 ; Setup to call the init
163 bf firstBoot,notFirst ; Not first boot, go...
166 ; The following code just does a general initialization of the features just
167 ; after the initial first-time boot. This is not done after waking up or on
168 ; any "secondary" processor. Just after the boot-processor init, we copy the
169 ; features to any possible per_proc.
171 ; We are just setting defaults. The specific initialization code will modify these
174 lis r18,hi16(EXT(_cpu_capabilities)) ; Get the address of _cpu_capabilities
175 ori r18,r18,lo16(EXT(_cpu_capabilities))
176 lwz r17,ptCPUCap(r26) ; Get the default cpu capabilities
177 stw r17, 0(r18) ; Save the default value in _cpu_capabilities
179 lwz r17,ptFeatures(r26) ; Pick up the features
181 lwz r18,ptRptdProc(r26) ; Get the reported processor
182 sth r18,pfrptdProc(r30) ; Set the reported processor
184 lwz r13,ptTempMax(r26) ; Get maximum operating temperature
185 stw r13,thrmmaxTemp(r30) ; Set the maximum
186 lwz r13,ptTempThr(r26) ; Get temprature to throttle down when exceeded
187 stw r13,thrmthrottleTemp(r30) ; Set the temperature that we throttle
189 lwz r13,ptLineSize(r26) ; Get the cache line size
190 sth r13,pflineSize(r30) ; Save it
191 lwz r13,ptl1iSize(r26) ; Get icache size
192 stw r13,pfl1iSize(r30) ; Save it
193 lwz r13,ptl1dSize(r26) ; Get dcache size
194 stw r13,pfl1dSize(r30) ; Save it
195 lwz r13,ptPTEG(r26) ; Get PTEG size address
196 stw r13,pfPTEG(r30) ; Save it
197 lwz r13,ptMaxVAddr(r26) ; Get max virtual address
198 stw r13,pfMaxVAddr(r30) ; Save it
199 lwz r13,ptMaxPAddr(r26) ; Get max physical address
200 stw r13,pfMaxPAddr(r30) ; Save it
201 lis r11,hi16(EXT(patch_table))
202 ori r11,r11,lo16(EXT(patch_table))
203 lwz r19,ptPatch(r26) ; Get ptPatch field
204 li r12,PATCH_TABLE_SIZE
207 lwz r16,patchType(r11) ; Load the patch type
208 lwz r15,patchValue(r11) ; Load the patch value
209 cmplwi cr1,r16,PATCH_FEATURE ; Is it a patch feature entry
210 and. r14,r15,r19 ; Is it set in the patch feature
211 crandc cr0_eq,cr1_eq,cr0_eq ; Do we have a match
212 beq patch_apply ; Yes, patch memory
213 cmplwi cr1,r16,PATCH_PROCESSOR ; Is it a patch processor entry
214 cmplw cr0,r15,r18 ; Check matching processor
215 crand cr0_eq,cr1_eq,cr0_eq ; Do we have a match
216 bne patch_skip ; No, skip patch memory
218 lwz r13,patchAddr(r11) ; Load the address to patch
219 lwz r14,patchData(r11) ; Load the patch data
220 stw r14,0(r13) ; Patch the location
221 dcbf 0,r13 ; Flush the old one
222 sync ; Make sure we see it all
223 icbi 0,r13 ; Flush the i-cache
225 sync ; Hang out some more...
227 addi r11,r11,peSize ; Point to the next patch entry
228 bdnz patch_loop ; Loop if in the range
229 b doOurInit ; Go do processor specific initialization...
231 notFirst: lwz r17,pfAvailable(r30) ; Get our features
233 doOurInit: mr. r20,r20 ; See if initialization routine
234 crand firstBoot,bootCPU,firstInit ; Indicate if we are on the initial first processor startup
235 bnelrl ; Do the initialization
237 ori r17,r17,lo16(pfValid) ; Set the valid bit
238 stw r17,pfAvailable(r30) ; Set the available features
240 bf firstBoot,nofeatcpy ; Skip feature propagate if not first time boot...
242 li r2,NCPUS ; Get number of CPUs
243 lis r23,hi16(EXT(per_proc_info)) ; Set base per_proc
244 ori r23,r23,lo16(EXT(per_proc_info)) ; Set base per_proc
245 addi r6,r23,ppSize ; Point to the next one
247 cpyFCpu: addic. r2,r2,-1 ; Count down
248 la r8,pfAvailable(r23) ; Point to features of boot processor
249 la r7,pfAvailable(r6) ; Point to features of our processor
250 li r9,(pfSize+thrmSize)/4 ; Get size of a features area
251 ble-- nofeatcpy ; Copied all we need
253 cpyFeat: subi r9,r9,1 ; Count word
254 lwz r0,0(r8) ; Get boot cpu features
255 stw r0,0(r7) ; Copy to ours
256 mr. r9,r9 ; Finished?
257 addi r7,r7,4 ; Next out
258 addi r8,r8,4 ; Next in
259 bgt cpyFeat ; Copy all boot cpu features to us...
261 lwz r17,pfAvailable(r6) ; Get our newly initialized features
262 addi r6,r6,ppSize ; Point to the next one
263 b cpyFCpu ; Do the next per_proc...
266 nofeatcpy: rlwinm. r0,r17,0,pf64Bitb,pf64Bitb ; Is this a 64-bit machine?
267 mtsprg 2,r17 ; Remember the feature flags
269 bne++ start64 ; Skip following if 64-bit...
271 mfspr r6,hid0 ; Get the HID0
272 rlwinm r6,r6,0,sleep+1,doze-1 ; Remove any vestiges of sleep
273 mtspr hid0,r6 ; Set the insominac HID0
276 ; Clear the BAT registers
278 li r9,0 ; Clear out a register
281 mtdbatu 0,r9 ; Invalidate maps
282 mtdbatl 0,r9 ; Invalidate maps
283 mtdbatu 1,r9 ; Invalidate maps
284 mtdbatl 1,r9 ; Invalidate maps
285 mtdbatu 2,r9 ; Invalidate maps
286 mtdbatl 2,r9 ; Invalidate maps
287 mtdbatu 3,r9 ; Invalidate maps
288 mtdbatl 3,r9 ; Invalidate maps
291 mtibatu 0,r9 ; Invalidate maps
292 mtibatl 0,r9 ; Invalidate maps
293 mtibatu 1,r9 ; Invalidate maps
294 mtibatl 1,r9 ; Invalidate maps
295 mtibatu 2,r9 ; Invalidate maps
296 mtibatl 2,r9 ; Invalidate maps
297 mtibatu 3,r9 ; Invalidate maps
298 mtibatl 3,r9 ; Invalidate maps
301 b startcommon ; Go join up the common start routine
303 start64: lis r5,hi16(startcommon) ; Get top of address of continue point
304 mfspr r6,hid0 ; Get the HID0
305 ori r5,r5,lo16(startcommon) ; Get low of address of continue point
306 lis r9,hi16(MASK(MSR_HV)) ; ?
307 lis r20,hi16(dozem|napm|sleepm) ; Get mask of power saving features
308 li r7,MSR_VM_OFF ; Get real mode MSR, 64-bit off
309 sldi r9,r9,32 ; Slide into position
310 sldi r20,r20,32 ; Slide power stuff into position
311 or r9,r9,r7 ; Form initial MSR
312 andc r6,r6,r20 ; Remove any vestiges of sleep
314 mtspr hid0,r6 ; Set the insominac HID0
315 mfspr r6,hid0 ; Get it
316 mfspr r6,hid0 ; Get it
317 mfspr r6,hid0 ; Get it
318 mfspr r6,hid0 ; Get it
319 mfspr r6,hid0 ; Get it
320 mfspr r6,hid0 ; Get it
322 mtsrr0 r5 ; Set the continue point
323 mtsrr1 r9 ; Set our normal disabled MSR
329 rlwinm. r0,r17,0,pfFloatb,pfFloatb ; See if there is floating point
330 beq- noFloat ; Nope, this is a really stupid machine...
332 li r0,MSR_VM_OFF|MASK(MSR_FP) ; Enable for floating point
333 mtmsr r0 /* Set the standard MSR values */
336 lis r5,HIGH_ADDR(EXT(FloatInit)) /* Get top of floating point init value */
337 ori r5,r5,LOW_ADDR(EXT(FloatInit)) /* Slam bottom */
338 lfd f0,0(r5) /* Initialize FP0 */
339 fmr f1,f0 /* Ours in not */
340 fmr f2,f0 /* to wonder why, */
341 fmr f3,f0 /* ours is but to */
342 fmr f4,f0 /* do or die! */
371 li r0, MSR_VM_OFF ; Turn off floating point
375 noFloat: rlwinm. r0,r17,0,pfAltivecb,pfAltivecb ; See if there is Altivec
376 beq- noVector ; Nope...
378 li r0,0 ; Clear out a register
380 lis r7,hi16(MSR_VEC_ON) ; Get real mode MSR + Altivec
381 ori r7,r7,lo16(MSR_VM_OFF) ; Get real mode MSR + Altivec
382 mtmsr r7 ; Set the real mode SRR */
383 isync ; Make sure it has happened
385 lis r5,hi16(EXT(QNaNbarbarian)) ; Altivec initializer
386 ori r5,r5,lo16(EXT(QNaNbarbarian)) ; Altivec initializer
388 mtspr vrsave,r0 ; Set that no VRs are used yet */
390 vspltish v1,1 ; Turn on the non-Java bit and saturate
391 vspltisw v0,1 ; Turn on the saturate bit
392 vxor v1,v1,v0 ; Turn off saturate and leave non-Java set
393 lvx v0,br0,r5 ; Initialize VR0
394 mtvscr v1 ; Clear the vector status register
395 vor v2,v0,v0 ; Copy into the next register
396 vor v1,v0,v0 ; Copy into the next register
397 vor v3,v0,v0 ; Copy into the next register
398 vor v4,v0,v0 ; Copy into the next register
399 vor v5,v0,v0 ; Copy into the next register
400 vor v6,v0,v0 ; Copy into the next register
401 vor v7,v0,v0 ; Copy into the next register
402 vor v8,v0,v0 ; Copy into the next register
403 vor v9,v0,v0 ; Copy into the next register
404 vor v10,v0,v0 ; Copy into the next register
405 vor v11,v0,v0 ; Copy into the next register
406 vor v12,v0,v0 ; Copy into the next register
407 vor v13,v0,v0 ; Copy into the next register
408 vor v14,v0,v0 ; Copy into the next register
409 vor v15,v0,v0 ; Copy into the next register
410 vor v16,v0,v0 ; Copy into the next register
411 vor v17,v0,v0 ; Copy into the next register
412 vor v18,v0,v0 ; Copy into the next register
413 vor v19,v0,v0 ; Copy into the next register
414 vor v20,v0,v0 ; Copy into the next register
415 vor v21,v0,v0 ; Copy into the next register
416 vor v22,v0,v0 ; Copy into the next register
417 vor v23,v0,v0 ; Copy into the next register
418 vor v24,v0,v0 ; Copy into the next register
419 vor v25,v0,v0 ; Copy into the next register
420 vor v26,v0,v0 ; Copy into the next register
421 vor v27,v0,v0 ; Copy into the next register
422 vor v28,v0,v0 ; Copy into the next register
423 vor v29,v0,v0 ; Copy into the next register
424 vor v30,v0,v0 ; Copy into the next register
425 vor v31,v0,v0 ; Copy into the next register
427 li r0, MSR_VM_OFF ; Turn off vectors
431 noVector: rlwinm. r0,r17,0,pfSMPcapb,pfSMPcapb ; See if we can do SMP
434 lhz r13,PP_CPU_NUMBER(r30) ; Get the CPU number
435 mtspr pir,r13 ; Set the PIR
437 noSMP: rlwinm. r0,r17,0,pfThermalb,pfThermalb ; See if there is an TAU
438 beq- noThermometer ; Nope...
440 li r13,0 ; Disable thermals for now
441 mtspr thrm3,r13 ; Do it
442 li r13,lo16(thrmtidm|thrmvm) ; Set for lower-than thermal event at 0 degrees
443 mtspr thrm1,r13 ; Do it
444 lis r13,hi16(thrmthrm) ; Set 127 degrees
445 ori r13,r13,lo16(thrmvm) ; Set for higher-than event
446 mtspr thrm2,r13 ; Set it
450 bl EXT(cacheInit) ; Initializes all caches (including the TLB)
452 rlwinm. r0,r17,0,pf64Bitb,pf64Bitb ; Is this a 64-bit machine?
453 beq++ isnot64 ; Skip following if not 64-bit...
455 mfmsr r29 ; Get the MSR
456 rlwinm r29,r29,0,0,31 ; Make sure that 64-bit mode is off
460 isnot64: bf bootCPU,callcpu
462 lis r29,HIGH_ADDR(EXT(intstack_top_ss)) ; move onto interrupt stack
463 ori r29,r29,LOW_ADDR(EXT(intstack_top_ss))
467 stw r28,FM_BACKPTR(r29) ; store a null frame backpointer
470 mr r3,r31 ; Restore any arguments we may have trashed
472 ; Note that we exit from here with translation still off
474 bl EXT(ppc_init) ; Jump into boot init code
478 lwz r29,PP_INTSTACK_TOP_SS(r31) ; move onto interrupt stack
481 stw r28,FM_BACKPTR(r29) ; store a null frame backpointer
484 mr r1,r29 ; move onto new stack
485 mr r3,r31 ; Restore any arguments we may have trashed
487 ; Note that we exit from here with translation still off
489 bl EXT(ppc_init_cpu) ; Jump into cpu init code
490 BREAKPOINT_TRAP ; Should never return
493 ; Specific processor initialization routines
499 bf firstBoot, init750nb ; No init for wakeup....
501 mfspr r13,l2cr ; Get the L2CR
502 rlwinm. r0,r13,0,l2e,l2e ; Any L2?
503 bne+ i750hl2 ; Yes...
504 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature
507 lis r14,hi16(256*1024) ; Base L2 size
508 addis r15,r13,0x3000 ; Hah... Figure this one out...
509 rlwinm r15,r15,4,30,31 ; Isolate
510 rlwinm. r8,r13,0,l2siz,l2sizf ; Was size valid?
511 slw r14,r14,r15 ; Set 256KB, 512KB, or 1MB
512 beq- init750l2none ; Not a valid setting...
514 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
515 stw r13,pfl2cr(r30) ; Shadow the L2CR
516 stw r14,pfl2Size(r30) ; Set the L2 size
517 b init750l2done ; Done with L2
520 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No level 2 cache
523 mfspr r11,hid0 ; Get the current HID0
524 stw r11,pfHID0(r30) ; Save the HID0 value
528 lwz r11,pfHID0(r30) ; Get HID0
530 mtspr hid0,r11 ; Set the HID
538 bf firstBoot, init750 ; No init for wakeup....
539 mfspr r13,hid1 ; Get HID1
540 li r14,lo16(0xFD5F) ; Get valid
541 rlwinm r13,r13,4,28,31 ; Isolate
542 slw r14,r14,r13 ; Position
543 rlwimi r17,r14,15-pfCanNapb,pfCanNapb,pfCanNapb ; Set it
544 b init750 ; Join common...
550 bf firstBoot, init750FXnb
552 stw r11, pfHID1(r30) ; Save the HID1 value
556 lwz r13, pfHID0(r30) ; Get HID0
557 lwz r11, pfHID1(r30) ; Get HID1
559 rlwinm. r0, r11, 0, hid1ps, hid1ps ; Isolate the hid1ps bit
560 beq init750FXnb2 ; Clear BTIC if hid1ps set
561 rlwinm r13, r13, 0, btic+1, btic-1 ; Clear the BTIC bit
565 mtspr hid0, r13 ; Set the HID
569 rlwinm r12, r11, 0, hid1ps+1, hid1ps-1 ; Select PLL0
570 mtspr hid1, r12 ; Restore PLL config
571 mftb r13 ; Wait 5000 ticks (> 200 us)
578 mtspr hid1, r11 ; Select the desired PLL
581 ; 750FX vers 2.0 or later
583 bf firstBoot, init750FXV2nb ; Wake from sleep
586 stw r11, pfHID2(r30) ; Save the HID2 value
587 b init750FX ; Continue with 750FX init
590 lwz r13, pfHID2(r30) ; Get HID2
591 rlwinm r13, r13, 0, hid2vmin+1, hid2vmin-1 ; Clear the vmin bit
592 mtspr hid2, r13 ; Restore HID2 value
593 sync ; Wait for it to be done
598 init7400: bf firstBoot,i7400nb ; Do different if not initial boot...
599 mfspr r13,l2cr ; Get the L2CR
600 rlwinm. r0,r13,0,l2e,l2e ; Any L2?
601 bne+ i7400hl2 ; Yes...
602 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature
604 i7400hl2: lis r14,hi16(256*1024) ; Base L2 size
605 addis r15,r13,0x3000 ; Hah... Figure this one out...
606 rlwinm r15,r15,4,30,31
607 slw r14,r14,r15 ; Set 256KB, 512KB, 1MB, or 2MB
609 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
610 stw r13,pfl2cr(r30) ; Shadow the L2CR
611 stw r14,pfl2Size(r30) ; Set the L2 size
613 mfspr r11,hid0 ; Get the current HID0
614 oris r11,r11,hi16(emcpm|eiecm) ; ?
617 stw r11,pfHID0(r30) ; Save the HID0 value
619 mfspr r11,msscr0 ; Get the msscr0 register
620 stw r11,pfMSSCR0(r30) ; Save the MSSCR0 value
621 mfspr r11,msscr1 ; Get the msscr1 register
622 stw r11,pfMSSCR1(r30) ; Save the MSSCR1 value
627 mtspr l2cr,r11 ; Make sure L2CR is zero
628 lwz r11,pfHID0(r30) ; Get HID0
630 mtspr hid0,r11 ; Set the HID
633 lwz r11,pfMSSCR0(r30) ; Get MSSCR0
636 mtspr msscr0,r11 ; Set the MSSCR0
637 lwz r11,pfMSSCR1(r30) ; Get msscr1
640 mtspr msscr1,r11 ; Set the msscr1
645 ; 7400 (ver 2.0 - ver 2.7)
648 bf firstBoot, init7400
649 mfspr r13, hid0 ; Get the HID0
650 ori r13, r13, nopdstm ; ?
651 mtspr hid0, r13 ; Set the HID0
657 ; Note that this is the same as 7400 except we initialize the l2cr2 register
659 init7410: li r13,0 ; Clear
660 mtspr 1016,r13 ; Turn off direct cache
661 b init7400 ; Join up with common....
664 ; 745X - Any 7450 family processor
667 bf firstBoot,init745Xnb ; Do different if not initial boot...
669 mfspr r13,l2cr ; Get the L2CR
670 rlwinm. r0,r13,0,l2e,l2e ; Any L2?
671 bne+ init745Xhl2 ; Yes...
672 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature
675 mfpvr r14 ; Get processor version
676 rlwinm r14,r14,16,16,31 ; Isolate processor version
677 cmpli cr0, r14, PROCESSOR_VERSION_7457
678 lis r14,hi16(512*1024) ; 512KB L2
681 lis r14,hi16(256*1024) ; Base L2 size
682 rlwinm r15,r13,22,12,13 ; Convert to 256k, 512k, or 768k
683 add r14,r14,r15 ; Add in minimum
686 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
687 stw r13,pfl2cr(r30) ; Shadow the L2CR
688 stw r14,pfl2Size(r30) ; Set the L2 size
690 ; Take care of level 3 cache
692 mfspr r13,l3cr ; Get the L3CR
693 rlwinm. r0,r13,0,l3e,l3e ; Any L3?
694 bne+ init745Xhl3 ; Yes...
695 rlwinm r17,r17,0,pfL3b+1,pfL3b-1 ; No L3, turn off feature
697 init745Xhl3: cmplwi cr0,r13,0 ; No L3 if L3CR is zero
698 beq- init745Xnone ; Go turn off the features...
699 lis r14,hi16(1024*1024) ; Base L3 size
700 rlwinm r15,r13,4,31,31 ; Get size multiplier
701 slw r14,r14,r15 ; Set 1 or 2MB
703 stw r13,pfl3crOriginal(r30) ; Shadow the L3CR
704 stw r13,pfl3cr(r30) ; Shadow the L3CR
705 stw r14,pfl3Size(r30) ; Set the L3 size
706 b init745Xfin ; Return....
709 rlwinm r17,r17,0,pfL3fab+1,pfL3b-1 ; No 3rd level cache or assist
710 rlwinm r11,r17,pfWillNapb-pfCanNapb,pfCanNapb,pfCanNapb ; Set pfCanNap if pfWillNap is set
714 rlwinm r17,r17,0,pfWillNapb+1,pfWillNapb-1 ; Make sure pfWillNap is not set
716 mfspr r11,hid0 ; Get the current HID0
717 stw r11,pfHID0(r30) ; Save the HID0 value
718 mfspr r11,hid1 ; Get the current HID1
719 stw r11,pfHID1(r30) ; Save the HID1 value
720 mfspr r11,msscr0 ; Get the msscr0 register
721 stw r11,pfMSSCR0(r30) ; Save the MSSCR0 value
722 mfspr r11,msscr1 ; Get the msscr1 register
723 stw r11,pfMSSCR1(r30) ; Save the MSSCR1 value
724 mfspr r11,ictrl ; Get the ictrl register
725 stw r11,pfICTRL(r30) ; Save the ICTRL value
726 mfspr r11,ldstcr ; Get the ldstcr register
727 stw r11,pfLDSTCR(r30) ; Save the LDSTCR value
728 mfspr r11,ldstdb ; Get the ldstdb register
729 stw r11,pfLDSTDB(r30) ; Save the LDSTDB value
730 mfspr r11,pir ; Get the pir register
731 stw r11,pfBootConfig(r30) ; Save the BootConfig value
735 init745Xnb: lwz r11,pfHID0(r30) ; Get HID0
737 mtspr hid0,r11 ; Set the HID
739 lwz r11,pfHID1(r30) ; Get HID1
741 mtspr hid1,r11 ; Set the HID
743 lwz r11,pfMSSCR0(r30) ; Get MSSCR0
745 mtspr msscr0,r11 ; Set the MSSCR0
748 lwz r11,pfICTRL(r30) ; Get ICTRL
750 mtspr ictrl,r11 ; Set the ICTRL
753 lwz r11,pfLDSTCR(r30) ; Get LDSTCR
755 mtspr ldstcr,r11 ; Set the LDSTCR
758 lwz r11,pfLDSTDB(r30) ; Get LDSTDB
760 mtspr ldstdb,r11 ; Set the LDSTDB
768 bf firstBoot, init745X ; Not boot, use standard init
770 mfspr r13, pir ; Get BootConfig from PIR
771 rlwinm. r14, r13, 0, 20, 23 ; Is the pdet value zero
772 bne init7450done ; No, done for now
774 ori r13, r13, 0x0400 ; Force pdet value to 4
775 mtspr pir, r13 ; Write back the BootConfig
778 b init745X ; Continue with standard init
782 li r20,0 ; Clear this
783 mtspr hior,r20 ; Make sure that 0 is interrupt prefix
784 bf firstBoot,init970nb ; No init for wakeup or second processor....
787 mfspr r11,hid0 ; Get original hid0
788 std r11,pfHID0(r30) ; Save original
789 mfspr r11,hid1 ; Get original hid1
790 std r11,pfHID1(r30) ; Save original
791 mfspr r11,hid4 ; Get original hid4
792 std r11,pfHID4(r30) ; Save original
793 mfspr r11,hid5 ; Get original hid5
794 std r11,pfHID5(r30) ; Save original
797 ; We can not query or change the L2 size. We will just
798 ; phoney up a L2CR to make sysctl "happy" and set the
802 lis r0,0x8000 ; Synthesize a "valid" but non-existant L2CR
803 stw r0,pfl2crOriginal(r30) ; Set a dummy L2CR
804 stw r0,pfl2cr(r30) ; Set a dummy L2CR
806 stw r0,pfl2Size(r30) ; Set the L2 size
811 ; Start up code for second processor or wake up from sleep
814 init970nb: ld r11,pfHID0(r30) ; Get it
816 mtspr hid0,r11 ; Stuff it
817 mfspr r11,hid0 ; Get it
818 mfspr r11,hid0 ; Get it
819 mfspr r11,hid0 ; Get it
820 mfspr r11,hid0 ; Get it
821 mfspr r11,hid0 ; Get it
822 mfspr r11,hid0 ; Get it
825 ld r11,pfHID1(r30) ; Get it
827 mtspr hid1,r11 ; Stick it
828 mtspr hid1,r11 ; Stick it again
831 ld r11,pfHID4(r30) ; Get it
833 mtspr hid4,r11 ; Stick it
836 ld r11,pfHID5(r30) ; Get it
837 mtspr hid5,r11 ; Set it
842 ; Unsupported Processors
844 mtlr r2 ; Restore the return address
845 blr ; Return to the booter
849 ; Processor to feature table
851 ; .align 2 - Always on word boundary
852 ; .long ptFilter - Mask of significant bits in the Version/Revision code
853 ; - NOTE: Always order from most restrictive to least restrictive matching
854 ; .short ptVersion - Version code from PVR. Always start with 0 which is default
855 ; .short ptRevision - Revision code from PVR. A zero value denotes the generic attributes if not specific
856 ; .long ptFeatures - Available features
857 ; .long ptCPUCap - Default value for _cpu_capabilities
858 ; .long ptPatch - Patch features
859 ; .long ptInitRout - Initilization routine. Can modify any of the other attributes.
860 ; .long ptRptdProc - Processor type reported
861 ; .long ptTempMax - Maximum operating temprature
862 ; .long ptTempThr - Temprature threshold. We throttle if above
863 ; .long ptLineSize - Level 1 cache line size
864 ; .long ptl1iSize - Level 1 instruction cache size
865 ; .long ptl1dSize - Level 1 data cache size
866 ; .long ptPTEG - Size of PTEG
867 ; .long ptMaxVAddr - Maximum effective address
868 ; .long ptMaxPAddr - Maximum physical address
877 .long 0xFFFFFFFF ; Exact match
878 .short PROCESSOR_VERSION_750
880 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL2
881 .long kCache32 | kHasGraphicsOps | kHasStfiwx
884 .long CPU_SUBTYPE_POWERPC_750
897 .long 0xFFFF0F00 ; 2.x vers
898 .short PROCESSOR_VERSION_750
900 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL2
901 .long kCache32 | kHasGraphicsOps | kHasStfiwx
904 .long CPU_SUBTYPE_POWERPC_750
917 .long 0xFFFF0000 ; All revisions
918 .short PROCESSOR_VERSION_750
920 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pf32Byte | pfL2
921 .long kCache32 | kHasGraphicsOps | kHasStfiwx
924 .long CPU_SUBTYPE_POWERPC_750
937 .long 0xFFFF0F00 ; 1.x vers
938 .short PROCESSOR_VERSION_750FX
940 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfSlowNap | pfNoMuMMCK | pf32Byte | pfL2
941 .long kCache32 | kHasGraphicsOps | kHasStfiwx
944 .long CPU_SUBTYPE_POWERPC_750
957 .long 0xFFFF0000 ; All revisions
958 .short PROCESSOR_VERSION_750FX
960 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfSlowNap | pfNoMuMMCK | pf32Byte | pfL2
961 .long kCache32 | kHasGraphicsOps | kHasStfiwx
964 .long CPU_SUBTYPE_POWERPC_750
974 ; 7400 (ver 2.0 - ver 2.7)
977 .long 0xFFFFFFF8 ; ver 2.0 - 2.7
978 .short PROCESSOR_VERSION_7400
980 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
981 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
984 .long CPU_SUBTYPE_POWERPC_7400
997 .long 0xFFFF0000 ; All revisions
998 .short PROCESSOR_VERSION_7400
1000 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
1001 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1004 .long CPU_SUBTYPE_POWERPC_7400
1017 .long 0xFFFFFFFF ; Exact match
1018 .short PROCESSOR_VERSION_7400
1020 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
1021 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1024 .long CPU_SUBTYPE_POWERPC_7400
1037 .long 0xFFFF0000 ; All other revisions
1038 .short PROCESSOR_VERSION_7410
1040 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
1041 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1044 .long CPU_SUBTYPE_POWERPC_7400
1057 .long 0xFFFFFF00 ; Just revisions 1.xx
1058 .short PROCESSOR_VERSION_7450
1060 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1061 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1064 .long CPU_SUBTYPE_POWERPC_7450
1077 .long 0xFFFFFFFF ; Just revision 2.0
1078 .short PROCESSOR_VERSION_7450
1080 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1081 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1084 .long CPU_SUBTYPE_POWERPC_7450
1097 .long 0xFFFF0000 ; All other revisions
1098 .short PROCESSOR_VERSION_7450
1100 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1101 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1104 .long CPU_SUBTYPE_POWERPC_7450
1114 ; 7455 (1.xx) Just like 7450 2.0
1117 .long 0xFFFFFF00 ; Just revisions 1.xx
1118 .short PROCESSOR_VERSION_7455
1120 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1121 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1124 .long CPU_SUBTYPE_POWERPC_7450
1137 .long 0xFFFFFFFF ; Just revision 2.0
1138 .short PROCESSOR_VERSION_7455
1140 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1141 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1144 .long CPU_SUBTYPE_POWERPC_7450
1157 .long 0xFFFF0000 ; All other revisions
1158 .short PROCESSOR_VERSION_7455
1160 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1161 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1164 .long CPU_SUBTYPE_POWERPC_7450
1177 .long 0xFFFF0000 ; All revisions
1178 .short PROCESSOR_VERSION_7457
1180 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1181 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1184 .long CPU_SUBTYPE_POWERPC_7450
1197 .long 0xFFFF0000 ; All versions so far
1198 .short PROCESSOR_VERSION_970
1200 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pf128Byte | pf64Bit | pfL2 | pfSCOMFixUp
1201 .long kHasAltivec | k64Bit | kCache128 | kDataStreamsAvailable | kDcbtStreamsRecommended | kDcbtStreamsAvailable | kHasGraphicsOps | kHasStfiwx | kHasFsqrt
1204 .long CPU_SUBTYPE_POWERPC_970
1214 ; All other processors are not supported
1217 .long 0x00000000 ; Matches everything
1220 .long pfFloat | pf32Byte
1221 .long kCache32 | kHasGraphicsOps | kHasStfiwx
1223 .long initUnsupported
1224 .long CPU_SUBTYPE_POWERPC_ALL