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>
66 * Interrupt and bootup stack for initial processor
72 * All CPUs start here.
74 * This code is called from SecondaryLoader
76 * Various arguments are passed via a table:
77 * R3 = pointer to other startup parameters
81 ENTRY(resetPOR,TAG_NO_FRAME_USED)
84 stw r12,0xF0(0) ; Make sure the special flag is clear
85 mtmsrd r12 ; Make sure we are in 32-bit mode
86 isync ; Really make sure
87 lwz r3,0xF4(0) ; Get the boot_args pointer
88 b startJoin ; Join up...
91 ENTRY(_start_cpu,TAG_NO_FRAME_USED)
92 crclr bootCPU ; Set non-boot processor
93 crclr firstInit ; Set not first time init
94 mr r30,r3 ; Set current per_proc
97 ; Note that we are just trying to get close. The real TB sync will take
98 ; place later. The value we are loading is set in two places. For the
99 ; main processor, it will be the TB at the last interrupt before we went
100 ; to sleep. For the others, it will be the time just before the main
101 ; processor woke us up.
104 lwz r15,ruptStamp(r3) ; Get the timebase from the other processor
105 li r17,0 ; Clear this out
106 lwz r16,ruptStamp+4(r3) ; Get the timebase from the other processor
107 mtspr tbl,r17 ; Clear bottom so we do not tick
108 mtspr tbu,r15 ; Set top
109 mtspr tbl,r16 ; Then bottom again
112 ENTRY(_start,TAG_NO_FRAME_USED)
115 mflr r2 ; Save the return address
116 lis r30,hi16(EXT(per_proc_info)) ; Set current per_proc
117 ori r30,r30,lo16(EXT(per_proc_info)) ; Set current per_proc
118 crset bootCPU ; Set boot processor
120 lwz r17,pfAvailable(r30) ; Get the available bits
121 rlwinm. r0,r17,0,pfValidb,pfValidb ; Have we initialized the feature flags yet?
122 crmove firstInit,cr0_eq ; Set if we are doing first time init
123 bne allstart ; Yeah, we must be waking up from sleep...
126 ; Here is where we do any one time general low-level initialization
128 lis r20,HIGH_ADDR(fwdisplock) ; Get address of the firmware display lock
129 li r19,0 ; Zorch a register
130 ori r20,r20,LOW_ADDR(fwdisplock) ; Get address of the firmware display lock
131 stw r19,0(r20) ; Make sure the lock is free
134 mr r31,r3 ; Save away arguments
136 crand firstBoot,bootCPU,firstInit ; Indicate if we are on the initial first processor startup
138 mtsprg 0,r30 ; Set the per_proc
140 li r9,0 ; Clear out a register
141 mtsprg 1,r9 ; Clear the SPRGs
145 li r7,MSR_VM_OFF ; Get real mode MSR
146 mtmsr r7 ; Set the real mode SRR
149 lis r26,hi16(processor_types) ; Point to processor table
150 ori r26,r26,lo16(processor_types) ; Other half
151 mfpvr r10 ; Get the PVR
153 nextPVR: lwz r28,ptFilter(r26) ; Get the filter
154 lwz r27,ptVersion(r26) ; Get the version and revision codes
155 and r28,r10,r28 ; Throw away dont care bits
156 cmplw r27,r28 ; Is this the right set?
157 beq donePVR ; We have the right one...
158 addi r26,r26,ptSize ; Point to the next type
159 b nextPVR ; Check it out...
161 donePVR: lwz r20,ptInitRout(r26) ; Grab the special init routine
162 mtlr r20 ; Setup to call the init
164 bf firstBoot,notFirst ; Not first boot, go...
167 ; The following code just does a general initialization of the features just
168 ; after the initial first-time boot. This is not done after waking up or on
169 ; any "secondary" processor. Just after the boot-processor init, we copy the
170 ; features to any possible per_proc.
172 ; We are just setting defaults. The specific initialization code will modify these
175 lis r18,hi16(EXT(_cpu_capabilities)) ; Get the address of _cpu_capabilities
176 ori r18,r18,lo16(EXT(_cpu_capabilities))
177 lwz r17,ptCPUCap(r26) ; Get the default cpu capabilities
178 stw r17, 0(r18) ; Save the default value in _cpu_capabilities
180 lwz r17,ptFeatures(r26) ; Pick up the features
182 lwz r18,ptRptdProc(r26) ; Get the reported processor
183 sth r18,pfrptdProc(r30) ; Set the reported processor
185 lwz r13,ptPwrModes(r26) ; Get the supported power modes
186 stw r13,pfPowerModes(r30) ; Set the supported power modes
188 lwz r13,ptTempMax(r26) ; Get maximum operating temperature
189 stw r13,thrmmaxTemp(r30) ; Set the maximum
190 lwz r13,ptTempThr(r26) ; Get temprature to throttle down when exceeded
191 stw r13,thrmthrottleTemp(r30) ; Set the temperature that we throttle
193 lwz r13,ptLineSize(r26) ; Get the cache line size
194 sth r13,pflineSize(r30) ; Save it
195 lwz r13,ptl1iSize(r26) ; Get icache size
196 stw r13,pfl1iSize(r30) ; Save it
197 lwz r13,ptl1dSize(r26) ; Get dcache size
198 stw r13,pfl1dSize(r30) ; Save it
199 lwz r13,ptPTEG(r26) ; Get PTEG size address
200 stw r13,pfPTEG(r30) ; Save it
201 lwz r13,ptMaxVAddr(r26) ; Get max virtual address
202 stw r13,pfMaxVAddr(r30) ; Save it
203 lwz r13,ptMaxPAddr(r26) ; Get max physical address
204 stw r13,pfMaxPAddr(r30) ; Save it
205 lis r11,hi16(EXT(patch_table))
206 ori r11,r11,lo16(EXT(patch_table))
207 lwz r19,ptPatch(r26) ; Get ptPatch field
208 li r12,PATCH_TABLE_SIZE
211 lwz r16,patchType(r11) ; Load the patch type
212 lwz r15,patchValue(r11) ; Load the patch value
213 cmplwi cr1,r16,PATCH_FEATURE ; Is it a patch feature entry
214 and. r14,r15,r19 ; Is it set in the patch feature
215 crandc cr0_eq,cr1_eq,cr0_eq ; Do we have a match
216 beq patch_apply ; Yes, patch memory
217 cmplwi cr1,r16,PATCH_PROCESSOR ; Is it a patch processor entry
218 cmplw cr0,r15,r18 ; Check matching processor
219 crand cr0_eq,cr1_eq,cr0_eq ; Do we have a match
220 bne patch_skip ; No, skip patch memory
222 lwz r13,patchAddr(r11) ; Load the address to patch
223 lwz r14,patchData(r11) ; Load the patch data
224 stw r14,0(r13) ; Patch the location
225 dcbf 0,r13 ; Flush the old one
226 sync ; Make sure we see it all
227 icbi 0,r13 ; Flush the i-cache
229 sync ; Hang out some more...
231 addi r11,r11,peSize ; Point to the next patch entry
232 bdnz patch_loop ; Loop if in the range
233 b doOurInit ; Go do processor specific initialization...
235 notFirst: lwz r17,pfAvailable(r30) ; Get our features
237 doOurInit: mr. r20,r20 ; See if initialization routine
238 crand firstBoot,bootCPU,firstInit ; Indicate if we are on the initial first processor startup
239 bnelrl ; Do the initialization
241 ori r17,r17,lo16(pfValid) ; Set the valid bit
242 stw r17,pfAvailable(r30) ; Set the available features
244 bf firstBoot,nofeatcpy ; Skip feature propagate if not first time boot...
246 li r2,NCPUS ; Get number of CPUs
247 lis r23,hi16(EXT(per_proc_info)) ; Set base per_proc
248 ori r23,r23,lo16(EXT(per_proc_info)) ; Set base per_proc
249 addi r6,r23,ppSize ; Point to the next one
251 cpyFCpu: addic. r2,r2,-1 ; Count down
252 la r8,pfAvailable(r23) ; Point to features of boot processor
253 la r7,pfAvailable(r6) ; Point to features of our processor
254 li r9,(pfSize+thrmSize)/4 ; Get size of a features area
255 ble-- nofeatcpy ; Copied all we need
257 cpyFeat: subi r9,r9,1 ; Count word
258 lwz r0,0(r8) ; Get boot cpu features
259 stw r0,0(r7) ; Copy to ours
260 mr. r9,r9 ; Finished?
261 addi r7,r7,4 ; Next out
262 addi r8,r8,4 ; Next in
263 bgt cpyFeat ; Copy all boot cpu features to us...
265 lwz r17,pfAvailable(r6) ; Get our newly initialized features
266 addi r6,r6,ppSize ; Point to the next one
267 b cpyFCpu ; Do the next per_proc...
270 nofeatcpy: rlwinm. r0,r17,0,pf64Bitb,pf64Bitb ; Is this a 64-bit machine?
271 mtsprg 2,r17 ; Remember the feature flags
273 bne++ start64 ; Skip following if 64-bit...
275 mfspr r6,hid0 ; Get the HID0
276 rlwinm r6,r6,0,sleep+1,doze-1 ; Remove any vestiges of sleep
277 mtspr hid0,r6 ; Set the insominac HID0
280 ; Clear the BAT registers
282 li r9,0 ; Clear out a register
285 mtdbatu 0,r9 ; Invalidate maps
286 mtdbatl 0,r9 ; Invalidate maps
287 mtdbatu 1,r9 ; Invalidate maps
288 mtdbatl 1,r9 ; Invalidate maps
289 mtdbatu 2,r9 ; Invalidate maps
290 mtdbatl 2,r9 ; Invalidate maps
291 mtdbatu 3,r9 ; Invalidate maps
292 mtdbatl 3,r9 ; Invalidate maps
295 mtibatu 0,r9 ; Invalidate maps
296 mtibatl 0,r9 ; Invalidate maps
297 mtibatu 1,r9 ; Invalidate maps
298 mtibatl 1,r9 ; Invalidate maps
299 mtibatu 2,r9 ; Invalidate maps
300 mtibatl 2,r9 ; Invalidate maps
301 mtibatu 3,r9 ; Invalidate maps
302 mtibatl 3,r9 ; Invalidate maps
305 b startcommon ; Go join up the common start routine
307 start64: lis r5,hi16(startcommon) ; Get top of address of continue point
308 mfspr r6,hid0 ; Get the HID0
309 ori r5,r5,lo16(startcommon) ; Get low of address of continue point
310 lis r9,hi16(MASK(MSR_HV)) ; ?
311 lis r20,hi16(dozem|napm|sleepm) ; Get mask of power saving features
312 li r7,MSR_VM_OFF ; Get real mode MSR, 64-bit off
313 sldi r9,r9,32 ; Slide into position
314 sldi r20,r20,32 ; Slide power stuff into position
315 or r9,r9,r7 ; Form initial MSR
316 andc r6,r6,r20 ; Remove any vestiges of sleep
318 mtspr hid0,r6 ; Set the insominac HID0
319 mfspr r6,hid0 ; Get it
320 mfspr r6,hid0 ; Get it
321 mfspr r6,hid0 ; Get it
322 mfspr r6,hid0 ; Get it
323 mfspr r6,hid0 ; Get it
324 mfspr r6,hid0 ; Get it
326 mtsrr0 r5 ; Set the continue point
327 mtsrr1 r9 ; Set our normal disabled MSR
333 rlwinm. r0,r17,0,pfFloatb,pfFloatb ; See if there is floating point
334 beq- noFloat ; Nope, this is a really stupid machine...
336 li r0,MSR_VM_OFF|MASK(MSR_FP) ; Enable for floating point
337 mtmsr r0 /* Set the standard MSR values */
340 lis r5,HIGH_ADDR(EXT(FloatInit)) /* Get top of floating point init value */
341 ori r5,r5,LOW_ADDR(EXT(FloatInit)) /* Slam bottom */
342 lfd f0,0(r5) /* Initialize FP0 */
343 fmr f1,f0 /* Ours in not */
344 fmr f2,f0 /* to wonder why, */
345 fmr f3,f0 /* ours is but to */
346 fmr f4,f0 /* do or die! */
375 li r0, MSR_VM_OFF ; Turn off floating point
379 noFloat: rlwinm. r0,r17,0,pfAltivecb,pfAltivecb ; See if there is Altivec
380 beq- noVector ; Nope...
382 li r0,0 ; Clear out a register
384 lis r7,hi16(MSR_VEC_ON) ; Get real mode MSR + Altivec
385 ori r7,r7,lo16(MSR_VM_OFF) ; Get real mode MSR + Altivec
386 mtmsr r7 ; Set the real mode SRR */
387 isync ; Make sure it has happened
389 lis r5,hi16(EXT(QNaNbarbarian)) ; Altivec initializer
390 ori r5,r5,lo16(EXT(QNaNbarbarian)) ; Altivec initializer
392 mtspr vrsave,r0 ; Set that no VRs are used yet */
394 vspltish v1,1 ; Turn on the non-Java bit and saturate
395 vspltisw v0,1 ; Turn on the saturate bit
396 vxor v1,v1,v0 ; Turn off saturate and leave non-Java set
397 lvx v0,br0,r5 ; Initialize VR0
398 mtvscr v1 ; Clear the vector status register
399 vor v2,v0,v0 ; Copy into the next register
400 vor v1,v0,v0 ; Copy into the next register
401 vor v3,v0,v0 ; Copy into the next register
402 vor v4,v0,v0 ; Copy into the next register
403 vor v5,v0,v0 ; Copy into the next register
404 vor v6,v0,v0 ; Copy into the next register
405 vor v7,v0,v0 ; Copy into the next register
406 vor v8,v0,v0 ; Copy into the next register
407 vor v9,v0,v0 ; Copy into the next register
408 vor v10,v0,v0 ; Copy into the next register
409 vor v11,v0,v0 ; Copy into the next register
410 vor v12,v0,v0 ; Copy into the next register
411 vor v13,v0,v0 ; Copy into the next register
412 vor v14,v0,v0 ; Copy into the next register
413 vor v15,v0,v0 ; Copy into the next register
414 vor v16,v0,v0 ; Copy into the next register
415 vor v17,v0,v0 ; Copy into the next register
416 vor v18,v0,v0 ; Copy into the next register
417 vor v19,v0,v0 ; Copy into the next register
418 vor v20,v0,v0 ; Copy into the next register
419 vor v21,v0,v0 ; Copy into the next register
420 vor v22,v0,v0 ; Copy into the next register
421 vor v23,v0,v0 ; Copy into the next register
422 vor v24,v0,v0 ; Copy into the next register
423 vor v25,v0,v0 ; Copy into the next register
424 vor v26,v0,v0 ; Copy into the next register
425 vor v27,v0,v0 ; Copy into the next register
426 vor v28,v0,v0 ; Copy into the next register
427 vor v29,v0,v0 ; Copy into the next register
428 vor v30,v0,v0 ; Copy into the next register
429 vor v31,v0,v0 ; Copy into the next register
431 li r0, MSR_VM_OFF ; Turn off vectors
435 noVector: rlwinm. r0,r17,0,pfSMPcapb,pfSMPcapb ; See if we can do SMP
438 lhz r13,PP_CPU_NUMBER(r30) ; Get the CPU number
439 mtspr pir,r13 ; Set the PIR
441 noSMP: rlwinm. r0,r17,0,pfThermalb,pfThermalb ; See if there is an TAU
442 beq- noThermometer ; Nope...
444 li r13,0 ; Disable thermals for now
445 mtspr thrm3,r13 ; Do it
446 li r13,lo16(thrmtidm|thrmvm) ; Set for lower-than thermal event at 0 degrees
447 mtspr thrm1,r13 ; Do it
448 lis r13,hi16(thrmthrm) ; Set 127 degrees
449 ori r13,r13,lo16(thrmvm) ; Set for higher-than event
450 mtspr thrm2,r13 ; Set it
454 bl EXT(cacheInit) ; Initializes all caches (including the TLB)
456 rlwinm. r0,r17,0,pf64Bitb,pf64Bitb ; Is this a 64-bit machine?
457 beq++ isnot64 ; Skip following if not 64-bit...
459 mfmsr r29 ; Get the MSR
460 rlwinm r29,r29,0,0,31 ; Make sure that 64-bit mode is off
464 isnot64: bf bootCPU,callcpu
466 lis r29,HIGH_ADDR(EXT(intstack_top_ss)) ; move onto interrupt stack
467 ori r29,r29,LOW_ADDR(EXT(intstack_top_ss))
471 stw r28,FM_BACKPTR(r29) ; store a null frame backpointer
474 mr r3,r31 ; Restore any arguments we may have trashed
476 ; Note that we exit from here with translation still off
478 bl EXT(ppc_init) ; Jump into boot init code
482 lwz r29,PP_INTSTACK_TOP_SS(r31) ; move onto interrupt stack
485 stw r28,FM_BACKPTR(r29) ; store a null frame backpointer
488 mr r1,r29 ; move onto new stack
489 mr r3,r31 ; Restore any arguments we may have trashed
491 ; Note that we exit from here with translation still off
493 bl EXT(ppc_init_cpu) ; Jump into cpu init code
494 BREAKPOINT_TRAP ; Should never return
497 ; Specific processor initialization routines
503 bf firstBoot, init750nb ; No init for wakeup....
505 mfspr r13,l2cr ; Get the L2CR
506 rlwinm. r0,r13,0,l2e,l2e ; Any L2?
507 bne+ i750hl2 ; Yes...
508 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature
511 lis r14,hi16(256*1024) ; Base L2 size
512 addis r15,r13,0x3000 ; Hah... Figure this one out...
513 rlwinm r15,r15,4,30,31 ; Isolate
514 rlwinm. r8,r13,0,l2siz,l2sizf ; Was size valid?
515 slw r14,r14,r15 ; Set 256KB, 512KB, or 1MB
516 beq- init750l2none ; Not a valid setting...
518 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
519 stw r13,pfl2cr(r30) ; Shadow the L2CR
520 stw r14,pfl2Size(r30) ; Set the L2 size
521 b init750l2done ; Done with L2
524 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No level 2 cache
527 mfspr r11,hid0 ; Get the current HID0
528 stw r11,pfHID0(r30) ; Save the HID0 value
532 lwz r11,pfHID0(r30) ; Get HID0
534 mtspr hid0,r11 ; Set the HID
542 bf firstBoot, init750 ; No init for wakeup....
543 mfspr r13,hid1 ; Get HID1
544 li r14,lo16(0xFD5F) ; Get valid
545 rlwinm r13,r13,4,28,31 ; Isolate
546 slw r14,r14,r13 ; Position
547 rlwimi r17,r14,15-pfCanNapb,pfCanNapb,pfCanNapb ; Set it
548 b init750 ; Join common...
554 bf firstBoot, init750FXnb
556 stw r11, pfHID1(r30) ; Save the HID1 value
560 lwz r13, pfHID0(r30) ; Get HID0
561 lwz r11, pfHID1(r30) ; Get HID1
563 rlwinm. r0, r11, 0, hid1ps, hid1ps ; Isolate the hid1ps bit
564 beq init750FXnb2 ; Clear BTIC if hid1ps set
565 rlwinm r13, r13, 0, btic+1, btic-1 ; Clear the BTIC bit
569 mtspr hid0, r13 ; Set the HID
573 rlwinm r12, r11, 0, hid1ps+1, hid1ps-1 ; Select PLL0
574 mtspr hid1, r12 ; Restore PLL config
575 mftb r13 ; Wait 5000 ticks (> 200 us)
582 mtspr hid1, r11 ; Select the desired PLL
585 ; 750FX vers 2.0 or later
587 bf firstBoot, init750FXV2nb ; Wake from sleep
590 stw r11, pfHID2(r30) ; Save the HID2 value
591 b init750FX ; Continue with 750FX init
594 lwz r13, pfHID2(r30) ; Get HID2
595 rlwinm r13, r13, 0, hid2vmin+1, hid2vmin-1 ; Clear the vmin bit
596 mtspr hid2, r13 ; Restore HID2 value
597 sync ; Wait for it to be done
602 init7400: bf firstBoot,i7400nb ; Do different if not initial boot...
603 mfspr r13,l2cr ; Get the L2CR
604 rlwinm. r0,r13,0,l2e,l2e ; Any L2?
605 bne+ i7400hl2 ; Yes...
606 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature
608 i7400hl2: lis r14,hi16(256*1024) ; Base L2 size
609 addis r15,r13,0x3000 ; Hah... Figure this one out...
610 rlwinm r15,r15,4,30,31
611 slw r14,r14,r15 ; Set 256KB, 512KB, 1MB, or 2MB
613 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
614 stw r13,pfl2cr(r30) ; Shadow the L2CR
615 stw r14,pfl2Size(r30) ; Set the L2 size
617 mfspr r11,hid0 ; Get the current HID0
618 oris r11,r11,hi16(emcpm|eiecm) ; ?
621 stw r11,pfHID0(r30) ; Save the HID0 value
623 mfspr r11,msscr0 ; Get the msscr0 register
624 stw r11,pfMSSCR0(r30) ; Save the MSSCR0 value
625 mfspr r11,msscr1 ; Get the msscr1 register
626 stw r11,pfMSSCR1(r30) ; Save the MSSCR1 value
631 mtspr l2cr,r11 ; Make sure L2CR is zero
632 lwz r11,pfHID0(r30) ; Get HID0
634 mtspr hid0,r11 ; Set the HID
637 lwz r11,pfMSSCR0(r30) ; Get MSSCR0
640 mtspr msscr0,r11 ; Set the MSSCR0
641 lwz r11,pfMSSCR1(r30) ; Get msscr1
644 mtspr msscr1,r11 ; Set the msscr1
649 ; 7400 (ver 2.0 - ver 2.7)
652 bf firstBoot, init7400
653 mfspr r13, hid0 ; Get the HID0
654 ori r13, r13, nopdstm ; ?
655 mtspr hid0, r13 ; Set the HID0
661 ; Note that this is the same as 7400 except we initialize the l2cr2 register
663 init7410: li r13,0 ; Clear
664 mtspr 1016,r13 ; Turn off direct cache
665 b init7400 ; Join up with common....
668 ; 745X - Any 7450 family processor
671 bf firstBoot,init745Xnb ; Do different if not initial boot...
673 mfspr r13,l2cr ; Get the L2CR
674 rlwinm. r0,r13,0,l2e,l2e ; Any L2?
675 bne+ init745Xhl2 ; Yes...
676 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature
679 mfpvr r14 ; Get processor version
680 rlwinm r14,r14,16,16,31 ; Isolate processor version
681 cmpli cr0, r14, PROCESSOR_VERSION_7457
682 lis r14,hi16(512*1024) ; 512KB L2
685 lis r14,hi16(256*1024) ; Base L2 size
686 rlwinm r15,r13,22,12,13 ; Convert to 256k, 512k, or 768k
687 add r14,r14,r15 ; Add in minimum
690 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
691 stw r13,pfl2cr(r30) ; Shadow the L2CR
692 stw r14,pfl2Size(r30) ; Set the L2 size
694 ; Take care of level 3 cache
696 mfspr r13,l3cr ; Get the L3CR
697 rlwinm. r0,r13,0,l3e,l3e ; Any L3?
698 bne+ init745Xhl3 ; Yes...
699 rlwinm r17,r17,0,pfL3b+1,pfL3b-1 ; No L3, turn off feature
701 init745Xhl3: cmplwi cr0,r13,0 ; No L3 if L3CR is zero
702 beq- init745Xnone ; Go turn off the features...
703 lis r14,hi16(1024*1024) ; Base L3 size
704 rlwinm r15,r13,4,31,31 ; Get size multiplier
705 slw r14,r14,r15 ; Set 1 or 2MB
707 stw r13,pfl3crOriginal(r30) ; Shadow the L3CR
708 stw r13,pfl3cr(r30) ; Shadow the L3CR
709 stw r14,pfl3Size(r30) ; Set the L3 size
710 b init745Xfin ; Return....
713 rlwinm r17,r17,0,pfL3fab+1,pfL3b-1 ; No 3rd level cache or assist
714 rlwinm r11,r17,pfWillNapb-pfCanNapb,pfCanNapb,pfCanNapb ; Set pfCanNap if pfWillNap is set
718 rlwinm r17,r17,0,pfWillNapb+1,pfWillNapb-1 ; Make sure pfWillNap is not set
720 mfspr r11,hid0 ; Get the current HID0
721 stw r11,pfHID0(r30) ; Save the HID0 value
722 mfspr r11,hid1 ; Get the current HID1
723 stw r11,pfHID1(r30) ; Save the HID1 value
724 mfspr r11,msscr0 ; Get the msscr0 register
725 stw r11,pfMSSCR0(r30) ; Save the MSSCR0 value
726 mfspr r11,msscr1 ; Get the msscr1 register
727 stw r11,pfMSSCR1(r30) ; Save the MSSCR1 value
728 mfspr r11,ictrl ; Get the ictrl register
729 stw r11,pfICTRL(r30) ; Save the ICTRL value
730 mfspr r11,ldstcr ; Get the ldstcr register
731 stw r11,pfLDSTCR(r30) ; Save the LDSTCR value
732 mfspr r11,ldstdb ; Get the ldstdb register
733 stw r11,pfLDSTDB(r30) ; Save the LDSTDB value
734 mfspr r11,pir ; Get the pir register
735 stw r11,pfBootConfig(r30) ; Save the BootConfig value
739 init745Xnb: lwz r11,pfHID0(r30) ; Get HID0
741 mtspr hid0,r11 ; Set the HID
743 lwz r11,pfHID1(r30) ; Get HID1
745 mtspr hid1,r11 ; Set the HID
747 lwz r11,pfMSSCR0(r30) ; Get MSSCR0
749 mtspr msscr0,r11 ; Set the MSSCR0
752 lwz r11,pfICTRL(r30) ; Get ICTRL
754 mtspr ictrl,r11 ; Set the ICTRL
757 lwz r11,pfLDSTCR(r30) ; Get LDSTCR
759 mtspr ldstcr,r11 ; Set the LDSTCR
762 lwz r11,pfLDSTDB(r30) ; Get LDSTDB
764 mtspr ldstdb,r11 ; Set the LDSTDB
772 bf firstBoot, init745X ; Not boot, use standard init
774 mfspr r13, pir ; Get BootConfig from PIR
775 rlwinm. r14, r13, 0, 20, 23 ; Is the pdet value zero
776 bne init7450done ; No, done for now
778 ori r13, r13, 0x0400 ; Force pdet value to 4
779 mtspr pir, r13 ; Write back the BootConfig
782 b init745X ; Continue with standard init
786 li r20,0 ; Clear this
787 mtspr hior,r20 ; Make sure that 0 is interrupt prefix
788 bf firstBoot,init970nb ; No init for wakeup or second processor....
791 mfspr r11,hid0 ; Get original hid0
792 std r11,pfHID0(r30) ; Save original
793 mfspr r11,hid1 ; Get original hid1
794 std r11,pfHID1(r30) ; Save original
795 mfspr r11,hid4 ; Get original hid4
796 std r11,pfHID4(r30) ; Save original
797 mfspr r11,hid5 ; Get original hid5
798 std r11,pfHID5(r30) ; Save original
801 ; We can not query or change the L2 size. We will just
802 ; phoney up a L2CR to make sysctl "happy" and set the
806 lis r0,0x8000 ; Synthesize a "valid" but non-existant L2CR
807 stw r0,pfl2crOriginal(r30) ; Set a dummy L2CR
808 stw r0,pfl2cr(r30) ; Set a dummy L2CR
810 stw r0,pfl2Size(r30) ; Set the L2 size
815 ; Start up code for second processor or wake up from sleep
818 init970nb: ld r11,pfHID0(r30) ; Get it
820 mtspr hid0,r11 ; Stuff it
821 mfspr r11,hid0 ; Get it
822 mfspr r11,hid0 ; Get it
823 mfspr r11,hid0 ; Get it
824 mfspr r11,hid0 ; Get it
825 mfspr r11,hid0 ; Get it
826 mfspr r11,hid0 ; Get it
829 ld r11,pfHID1(r30) ; Get it
831 mtspr hid1,r11 ; Stick it
832 mtspr hid1,r11 ; Stick it again
835 ld r11,pfHID4(r30) ; Get it
837 mtspr hid4,r11 ; Stick it
840 ld r11,pfHID5(r30) ; Get it
841 mtspr hid5,r11 ; Set it
846 ; Unsupported Processors
848 mtlr r2 ; Restore the return address
849 blr ; Return to the booter
853 ; Processor to feature table
855 ; .align 2 - Always on word boundary
856 ; .long ptFilter - Mask of significant bits in the Version/Revision code
857 ; - NOTE: Always order from most restrictive to least restrictive matching
858 ; .short ptVersion - Version code from PVR. Always start with 0 which is default
859 ; .short ptRevision - Revision code from PVR. A zero value denotes the generic attributes if not specific
860 ; .long ptFeatures - Available features
861 ; .long ptCPUCap - Default value for _cpu_capabilities
862 ; .long ptPwrModes - Available power management features
863 ; .long ptPatch - Patch features
864 ; .long ptInitRout - Initilization routine. Can modify any of the other attributes.
865 ; .long ptRptdProc - Processor type reported
866 ; .long ptTempMax - Maximum operating temprature
867 ; .long ptTempThr - Temprature threshold. We throttle if above
868 ; .long ptLineSize - Level 1 cache line size
869 ; .long ptl1iSize - Level 1 instruction cache size
870 ; .long ptl1dSize - Level 1 data cache size
871 ; .long ptPTEG - Size of PTEG
872 ; .long ptMaxVAddr - Maximum effective address
873 ; .long ptMaxPAddr - Maximum physical address
882 .long 0xFFFFFFFF ; Exact match
883 .short PROCESSOR_VERSION_750
885 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL2
886 .long kCache32 | kHasGraphicsOps | kHasStfiwx
890 .long CPU_SUBTYPE_POWERPC_750
903 .long 0xFFFF0F00 ; 2.x vers
904 .short PROCESSOR_VERSION_750
906 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL2
907 .long kCache32 | kHasGraphicsOps | kHasStfiwx
911 .long CPU_SUBTYPE_POWERPC_750
924 .long 0xFFFF0000 ; All revisions
925 .short PROCESSOR_VERSION_750
927 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pf32Byte | pfL2
928 .long kCache32 | kHasGraphicsOps | kHasStfiwx
932 .long CPU_SUBTYPE_POWERPC_750
945 .long 0xFFFF0F00 ; 1.x vers
946 .short PROCESSOR_VERSION_750FX
948 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfSlowNap | pfNoMuMMCK | pf32Byte | pfL2
949 .long kCache32 | kHasGraphicsOps | kHasStfiwx
953 .long CPU_SUBTYPE_POWERPC_750
966 .long 0xFFFF0000 ; All revisions
967 .short PROCESSOR_VERSION_750FX
969 .long pfFloat | pfCanSleep | pfCanNap | pfCanDoze | pfSlowNap | pfNoMuMMCK | pf32Byte | pfL2
970 .long kCache32 | kHasGraphicsOps | kHasStfiwx
971 .long pmDualPLL | pmDPLLVmin
974 .long CPU_SUBTYPE_POWERPC_750
984 ; 7400 (ver 2.0 - ver 2.7)
987 .long 0xFFFFFFF8 ; ver 2.0 - 2.7
988 .short PROCESSOR_VERSION_7400
990 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
991 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
995 .long CPU_SUBTYPE_POWERPC_7400
1008 .long 0xFFFF0000 ; All revisions
1009 .short PROCESSOR_VERSION_7400
1011 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pfThermal | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
1012 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1016 .long CPU_SUBTYPE_POWERPC_7400
1029 .long 0xFFFFFFFF ; Exact match
1030 .short PROCESSOR_VERSION_7400
1032 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
1033 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1037 .long CPU_SUBTYPE_POWERPC_7400
1050 .long 0xFFFF0000 ; All other revisions
1051 .short PROCESSOR_VERSION_7410
1053 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfCanDoze | pf32Byte | pfL1fa | pfL2 | pfL2fa | pfHasDcba
1054 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1058 .long CPU_SUBTYPE_POWERPC_7400
1071 .long 0xFFFFFF00 ; Just revisions 1.xx
1072 .short PROCESSOR_VERSION_7450
1074 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1075 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1079 .long CPU_SUBTYPE_POWERPC_7450
1092 .long 0xFFFFFFFF ; Just revision 2.0
1093 .short PROCESSOR_VERSION_7450
1095 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1096 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1100 .long CPU_SUBTYPE_POWERPC_7450
1113 .long 0xFFFF0000 ; All other revisions
1114 .short PROCESSOR_VERSION_7450
1116 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1117 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1121 .long CPU_SUBTYPE_POWERPC_7450
1131 ; 7455 (1.xx) Just like 7450 2.0
1134 .long 0xFFFFFF00 ; Just revisions 1.xx
1135 .short PROCESSOR_VERSION_7455
1137 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1138 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1142 .long CPU_SUBTYPE_POWERPC_7450
1155 .long 0xFFFFFFFF ; Just revision 2.0
1156 .short PROCESSOR_VERSION_7455
1158 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1159 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1163 .long CPU_SUBTYPE_POWERPC_7450
1176 .long 0xFFFF0000 ; All other revisions
1177 .short PROCESSOR_VERSION_7455
1179 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1180 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1184 .long CPU_SUBTYPE_POWERPC_7450
1197 .long 0xFFFF0000 ; All revisions
1198 .short PROCESSOR_VERSION_7457
1200 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfNoMSRir | pfNoL2PFNap | pfLClck | pf32Byte | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfHasDcba
1201 .long kHasAltivec | kCache32 | kDcbaAvailable | kDataStreamsRecommended | kDataStreamsAvailable | kHasGraphicsOps | kHasStfiwx
1205 .long CPU_SUBTYPE_POWERPC_7450
1218 .long 0xFFFFFF00 ; All versions so far
1219 .short PROCESSOR_VERSION_970
1221 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pf128Byte | pf64Bit | pfL2
1222 .long kHasAltivec | k64Bit | kCache128 | kDataStreamsAvailable | kDcbtStreamsRecommended | kDcbtStreamsAvailable | kHasGraphicsOps | kHasStfiwx | kHasFsqrt
1226 .long CPU_SUBTYPE_POWERPC_970
1239 .long 0xFFFF0000 ; All versions so far
1240 .short PROCESSOR_VERSION_970
1242 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pf128Byte | pf64Bit | pfL2 | pfSCOMFixUp
1243 .long kHasAltivec | k64Bit | kCache128 | kDataStreamsAvailable | kDcbtStreamsRecommended | kDcbtStreamsAvailable | kHasGraphicsOps | kHasStfiwx | kHasFsqrt
1247 .long CPU_SUBTYPE_POWERPC_970
1260 .long 0xFFFF0000 ; All versions so far
1261 .short PROCESSOR_VERSION_970FX
1263 .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pf128Byte | pf64Bit | pfL2
1264 .long kHasAltivec | k64Bit | kCache128 | kDataStreamsAvailable | kDcbtStreamsRecommended | kDcbtStreamsAvailable | kHasGraphicsOps | kHasStfiwx | kHasFsqrt
1268 .long CPU_SUBTYPE_POWERPC_970
1278 ; All other processors are not supported
1281 .long 0x00000000 ; Matches everything
1284 .long pfFloat | pf32Byte
1285 .long kCache32 | kHasGraphicsOps | kHasStfiwx
1288 .long initUnsupported
1289 .long CPU_SUBTYPE_POWERPC_ALL