]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ppc/start.s
xnu-344.32.tar.gz
[apple/xnu.git] / osfmk / ppc / start.s
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
de355530
A
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.
1c79356b 11 *
de355530
A
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
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
de355530
A
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.
1c79356b
A
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>
9bccf70c 31#include <ppc/spec_reg.h>
1c79356b
A
32#include <mach/ppc/vm_param.h>
33#include <assym.s>
34
de355530
A
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
1c79356b
A
47
48#define bootCPU 10
49#define firstInit 9
50#define firstBoot 8
0b4e3aa0 51
de355530
A
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
1c79356b
A
66/*
67 * Interrupt and bootup stack for initial processor
68 */
69
70 .file "start.s"
71
de355530
A
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)
81EXT(FixedStackStart):
82
83 .globl EXT(intstack)
84EXT(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)
91EXT(debstack):
92 .set ., .+KERNEL_STACK_SIZE*NCPUS
93
94 .globl EXT(FixedStackEnd)
95EXT(FixedStackEnd):
96
97 .align ALIGN
98 .globl EXT(intstack_top_ss)
99EXT(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)
104EXT(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)
109EXT(debstackptr):
110 .long EXT(debstack)+KERNEL_STACK_SIZE-FM_SIZE
111
112#endif /* MACH_KDP || MACH_KDB */
113
1c79356b
A
114/*
115 * All CPUs start here.
116 *
117 * This code is called from SecondaryLoader
118 *
119 * Various arguments are passed via a table:
de355530 120 * ARG0 = pointer to other startup parameters
1c79356b
A
121 */
122 .text
de355530 123
1c79356b
A
124ENTRY(_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
de355530 143
1c79356b
A
144 b allstart
145
146ENTRY(_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
de355530
A
165allstart: 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
1c79356b 168
d7e50217 169 mtsprg 0,r30 ; Set the per_proc
1c79356b 170
de355530 171 mfspr r6,hid0 ; Get the HID0
d7e50217 172 li r7,MSR_VM_OFF ; Get real mode MSR
de355530
A
173 rlwinm r6,r6,0,sleep+1,doze-1 ; Remove any vestiges of sleep
174 mtspr hid0,r6 ; Set the insominac HID0
d7e50217
A
175 mtmsr r7 ; Set the real mode SRR
176 isync
177
de355530
A
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
1c79356b
A
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
215nextPVR: 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
223donePVR: lwz r20,ptInitRout(r26) ; Grab the special init routine
224 mtlr r20 ; Setup to call the init
225
de355530 226 bf firstInit,notFirst ; Not first boot, go...
1c79356b
A
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
de355530 231; any "secondary" processor.
1c79356b
A
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
de355530
A
239 lwz r13,ptRptdProc(r26) ; Get the reported processor
240 sth r13,pfrptdProc(r30) ; Set the reported processor
1c79356b
A
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
255notFirst: lwz r17,pfAvailable(r30) ; Get our features
de355530
A
256 rlwinm. r0,r17,0,pfValidb,pfValidb ; Have we set up this CPU yet?
257 bne doOurInit ; Yeah, must be wakeup...
1c79356b
A
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
de355530 262 la r7,pfAvailable(r30) ; Point to features of our processor
1c79356b
A
263 la r8,pfAvailable(r23) ; Point to features of boot processor
264 li r9,(pfSize+thrmSize)/4 ; Get size of a features area
265
266cpyFeat: 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...
1c79356b 273
de355530 274 lwz r17,pfAvailable(r30) ; Get our newly initialized features
d7e50217 275
de355530
A
276doOurInit:
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
1c79356b 280
de355530
A
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
d7e50217 284
1c79356b
A
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
331noFloat: 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
de355530 346 vspltisw v1,0 ; Clear a register
1c79356b
A
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
385noVector: 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
391noSMP: 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
402noThermometer:
403
404 bl EXT(cacheInit) ; Initializes all caches (including the TLB)
405
de355530
A
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
1c79356b 409
de355530 410 bf bootCPU,callcpu ; Not the boot processor...
1c79356b
A
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
425callcpu:
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
1c79356b
A
442; 750
443
765c9de3
A
444init750:
445 bf firstBoot, init750nb ; No init for wakeup....
1c79356b 446
765c9de3 447 mfspr r13,l2cr ; Get the L2CR
1c79356b
A
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
765c9de3
A
452i750hl2:
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...
1c79356b 459
d52fe63f 460 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
765c9de3
A
461 stw r13,pfl2cr(r30) ; Shadow the L2CR
462 stw r14,pfl2Size(r30) ; Set the L2 size
463 b init750l2done ; Done with L2
1c79356b 464
765c9de3
A
465init750l2none:
466 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No level 2 cache
467
468init750l2done:
469 mfspr r11,hid0 ; Get the current HID0
470 stw r11,pfHID0(r30) ; Save the HID0 value
471 blr ; Return...
472
473init750nb:
d52fe63f 474 lwz r11,pfHID0(r30) ; Get HID0
765c9de3
A
475 sync
476 mtspr hid0,r11 ; Set the HID
477 isync
478 sync
479 blr
1c79356b 480
d52fe63f
A
481; 750CX
482
483init750CX:
484 bf firstBoot, init750 ; No init for wakeup....
485 mfspr r13,hid1 ; Get HID1
486 li r14,lo16(0xFD5F) ; Get valid
de355530
A
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...
d52fe63f
A
491
492
9bccf70c
A
493; 750FX
494
495init750FX:
496 bf firstBoot, init750FXnb
497 mfspr r11, hid1
498 stw r11, pfHID1(r30) ; Save the HID1 value
499 b init750
500
501init750FXnb:
502 lwz r13, pfHID0(r30) ; Get HID0
503 lwz r11, pfHID1(r30) ; Get HID1
504
de355530 505 rlwinm. r0, r11, 0, hid1ps, hid1ps ; Isolate the hid1ps bit
9bccf70c 506 beq init750FXnb2 ; Clear BTIC if hid1ps set
de355530 507 rlwinm r13, r13, 0, btic+1, btic-1 ; Clear the BTIC bit
9bccf70c
A
508
509init750FXnb2:
510 sync
511 mtspr hid0, r13 ; Set the HID
512 isync
513 sync
514
de355530 515 rlwinm r12, r11, 0, hid1ps+1, hid1ps-1 ; Select PLL0
9bccf70c 516 mtspr hid1, r12 ; Restore PLL config
de355530 517 mftb r13 ; Wait 5000 ticks (> 200 us)
9bccf70c
A
518
519init750FXnbloop:
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
d12e1678
A
527; 750FX vers 2.0 or later
528init750FXV2:
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
535init750FXV2nb:
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
d52fe63f
A
542; 7400
543
1c79356b
A
544init7400: 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
550i7400hl2: 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
de355530 555 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
1c79356b
A
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
765c9de3 571i7400nb:
d52fe63f 572 li r11,0
de355530 573 mtspr l2cr,r11 ; Make sure L2CR is zero
765c9de3 574 lwz r11,pfHID0(r30) ; Get HID0
1c79356b
A
575 sync
576 mtspr hid0,r11 ; Set the HID
765c9de3
A
577 isync
578 sync
1c79356b
A
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
9bccf70c
A
590
591; 7400 (ver 2.0 - ver 2.7)
592
593init7400v2_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
1c79356b
A
602; 7410
603; Note that this is the same as 7400 except we initialize the l2cr2 register
604
605init7410: li r13,0 ; Clear
606 mtspr 1016,r13 ; Turn off direct cache
607 b init7400 ; Join up with common....
1c79356b 608
d52fe63f
A
609
610; 745X - Any 7450 family processor
611
612init745X:
de355530 613 bf firstBoot,init745Xnb ; Do different if not initial boot...
1c79356b
A
614
615 mfspr r13,l2cr ; Get the L2CR
616 rlwinm. r0,r13,0,l2e,l2e ; Any L2?
d52fe63f 617 bne+ init745Xhl2 ; Yes...
1c79356b
A
618 rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature
619
de355530 620init745Xhl2: lis r14,hi16(256*1024) ; Base L2 size
1c79356b
A
621 rlwinm r15,r13,22,12,13 ; Convert to 256k, 512k, or 768k
622 add r14,r14,r15 ; Add in minimum
de355530 623
d52fe63f 624 stw r13,pfl2crOriginal(r30) ; Shadow the L2CR
1c79356b
A
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
7b1edb79 631 rlwinm. r0,r13,0,l3e,l3e ; Any L3?
d52fe63f 632 bne+ init745Xhl3 ; Yes...
7b1edb79 633 rlwinm r17,r17,0,pfL3b+1,pfL3b-1 ; No L3, turn off feature
1c79356b 634
de355530
A
635init745Xhl3: cmplwi cr0,r13,0 ; No L3 if L3CR is zero
636 beq- init745Xnone ; Go turn off the features...
1c79356b
A
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
de355530 641 stw r13,pfl3crOriginal(r30) ; Shadow the L3CR
1c79356b
A
642 stw r13,pfl3cr(r30) ; Shadow the L3CR
643 stw r14,pfl3Size(r30) ; Set the L3 size
d52fe63f 644 b init745Xfin ; Return....
1c79356b 645
d52fe63f 646init745Xnone:
de355530 647 rlwinm r17,r17,0,pfL3fab+1,pfL3b-1 ; No 3rd level cache or assist
0b4e3aa0
A
648 rlwinm r11,r17,pfWillNapb-pfCanNapb,pfCanNapb,pfCanNapb ; Set pfCanNap if pfWillNap is set
649 or r17,r17,r11
1c79356b 650
d52fe63f 651init745Xfin:
de355530 652 rlwinm r17,r17,0,pfWillNapb+1,pfWillNapb-1 ; Make sure pfWillNap is not set
0b4e3aa0
A
653
654 mfspr r11,hid0 ; Get the current HID0
1c79356b
A
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
0b4e3aa0
A
666 mfspr r11,ldstdb ; Get the ldstdb register
667 stw r11,pfLDSTDB(r30) ; Save the LDSTDB value
d52fe63f
A
668 mfspr r11,pir ; Get the pir register
669 stw r11,pfBootConfig(r30) ; Save the BootConfig value
1c79356b
A
670 blr ; Return....
671
672
d52fe63f 673init745Xnb: lwz r11,pfHID0(r30) ; Get HID0
1c79356b
A
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
0b4e3aa0
A
696 lwz r11,pfLDSTDB(r30) ; Get LDSTDB
697 sync
698 mtspr ldstdb,r11 ; Set the LDSTDB
699 isync
700 sync
1c79356b
A
701 blr
702
d52fe63f
A
703; 7450 - Specific
704
705init7450:
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
715init7450done:
716 b init745X ; Continue with standard init
717
1c79356b
A
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
737processor_types:
738
de355530
A
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
1c79356b
A
830; 750 (ver 2.2)
831
de355530
A
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
1c79356b
A
844
845; 750CX (ver 2.x)
846
de355530
A
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
1c79356b
A
860; 750 (generic)
861
de355530
A
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
d12e1678
A
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
9bccf70c 890; 750FX (generic)
0b4e3aa0 891
de355530
A
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
d12e1678 897 .long init750FXV2
de355530
A
898 .long CPU_SUBTYPE_POWERPC_750
899 .long 105
900 .long 90
901 .long 32
902 .long 32*1024
903 .long 32*1024
904
9bccf70c
A
905; 7400 (ver 2.0 - ver 2.7)
906
de355530
A
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
1c79356b
A
920; 7400 (generic)
921
de355530
A
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
1c79356b
A
935; 7410 (ver 1.1)
936
de355530
A
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
1c79356b
A
949
950; 7410 (generic)
951
de355530
A
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
1c79356b
A
964
965; 7450 (ver 1.xx)
966
de355530
A
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
1c79356b 979
0b4e3aa0
A
980; 7450 (2.0)
981
de355530
A
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
0b4e3aa0
A
994
995; 7450 (2.1)
1c79356b 996
de355530
A
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
1c79356b 1009
d52fe63f
A
1010; 7455 (1.xx) Just like 7450 2.0
1011
de355530
A
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
d52fe63f
A
1024
1025; 7455 (2.0)
1026
de355530
A
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
d52fe63f
A
1039
1040; 7455 (2.1)
1041
de355530
A
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
1c79356b 1056
de355530
A
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