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