|
|
1.1 root 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:
30: #include <ppc/asm.h>
31: #include <ppc/proc_reg.h>
32: #include <mach/ppc/vm_param.h>
33: #include <assym.s>
34:
35: /*
36: * Interrupt and bootup stack for initial processor
37: */
38:
39: .file "start.s"
40:
41: .data
42:
43: /* Align on page boundry */
44: .align PPC_PGSHIFT
45: /* Red zone for interrupt stack, one page (will be unmapped)*/
46: .set ., .+PPC_PGBYTES
47: /* intstack itself */
48:
49: .globl EXT(FixedStackStart)
50: EXT(FixedStackStart):
51:
52: .globl EXT(intstack)
53: EXT(intstack):
54: .set ., .+INTSTACK_SIZE*NCPUS
55:
56: /* Debugger stack - used by the debugger if present */
57: /* NOTE!!! Keep the debugger stack right after the interrupt stack */
58:
59: #if MACH_KDP || MACH_KDB
60: .globl EXT(debstack)
61: EXT(debstack):
62: .set ., .+KERNEL_STACK_SIZE*NCPUS
63:
64: .globl EXT(FixedStackEnd)
65: EXT(FixedStackEnd):
66:
67: .align ALIGN
68: .globl EXT(intstack_top_ss)
69: EXT(intstack_top_ss):
70: .long EXT(intstack)+INTSTACK_SIZE-SS_SIZE /* intstack_top_ss points to the top of interrupt stack */
71:
72: .align ALIGN
73: .globl EXT(debstack_top_ss)
74: EXT(debstack_top_ss):
75:
76: .long EXT(debstack)+KERNEL_STACK_SIZE-SS_SIZE /* debstack_top_ss points to the top of debug stack */
77:
78: .globl EXT(debstackptr)
79: EXT(debstackptr):
80: .long EXT(debstack)+KERNEL_STACK_SIZE-SS_SIZE
81:
82: #endif /* MACH_KDP || MACH_KDB */
83:
84: /*
85: * All CPUs start here.
86: *
87: * This code is called from SecondaryLoader
88: *
89: * Various arguments are passed via a table:
90: * ARG0 = pointer to other startup parameters
91: */
92: .text
93:
94: ENTRY(_start_cpu,TAG_NO_FRAME_USED)
95: li r30,1
96: b allstart
97:
98: ENTRY(_start,TAG_NO_FRAME_USED)
99: li r30,0
100: allstart:
101: mr r31,r3 /* Save away arguments */
102:
103: li r7,MSR_VM_OFF /* Get real mode MSR */
104: mtmsr r7 /* Set the real mode SRR */
105: isync
106:
107: ; Map in the first 256Mb in both instruction and data BATs
108:
109: li r7,((0x7FF<<2)|2) ; Set up for V=R 256MB in supervisor space
110: li r8,((2<<3)|2) ; Physical address = 0, coherent, R/W
111: li r9,0 ; Clear out a register
112:
113: mtsprg 0,r9 ; Insure the SPRGs are clear
114: mtsprg 1,r9
115: mtsprg 2,r9
116: mtsprg 3,r9
117:
118: sync
119: isync
120: mtdbatu 0,r7 ; Map bottom 256MB
121: mtdbatl 0,r8 ; Map bottom 256MB
122: mtdbatu 1,r9 ; Invalidate maps
123: mtdbatl 1,r9 ; Invalidate maps
124: mtdbatu 2,r9 ; Invalidate maps
125: mtdbatl 2,r9 ; Invalidate maps
126: mtdbatu 3,r9 ; Invalidate maps
127: mtdbatl 3,r9 ; Invalidate maps
128: sync
129: isync
130: mtibatu 0,r7 ; Map bottom 256MB
131: mtibatl 0,r8 ; Map bottom 256MB
132: mtibatu 1,r9 ; Invalidate maps
133: mtibatl 1,r9 ; Invalidate maps
134: mtibatu 2,r9 ; Invalidate maps
135: mtibatl 2,r9 ; Invalidate maps
136: mtibatu 3,r9 ; Invalidate maps
137: mtibatl 3,r9 ; Invalidate maps
138: sync
139: isync
140:
141: mfpvr r10
142: rlwinm r11,r10,16,16,31
143: cmplwi r11,PROCESSOR_VERSION_Max ; Do we have Altivec?
144: blt novmx ; Nope...
145:
146: ; ?
147: rlwinm r13,r10,0,16,31 ; ?
148: cmplwi r13, 0x0200 ; ?
149: bge notMaxV1 ; ?
150:
151: sync
152: mfspr r11,msscr0 ; ?
153: mfspr r12,msscr1 ; ?
154:
155: oris r11,r11,hi16(shden) ; ?
156:
157: andis. r0,r11,hi16(emodem) ; ?
158: bne inmaxbus ; ?
159: ori r11,r11,lo16(tfstm) ; ?
160: b nomaxbus ; ?
161:
162: inmaxbus: oris r12,r12,hi16(cqdm) ; ?
163:
164: nomaxbus: rlwinm r12,r12,0,csqe+1,csqs-1 ; ?
165: oris r12,r12,0x2000 ; ?
166:
167: sync
168: mtspr msscr0,r11 ; ?
169: mtspr msscr1,r12 ; ?
170: sync
171: isync
172:
173: notMaxV1:
174: ; ?
175: cmplwi r13,0x0202 ; ?
176: bge notMaxV2_0 ; ?
177:
178: lis r11, 0xffff
179: ori r11, r11, 0xfffe
180: mtspr iabr, r11
181: isync
182:
183: notMaxV2_0:
184:
185: li r0,0 ; Clear out a register
186:
187: lis r7,hi16(MSR_VEC_ON) ; Get real mode MSR + FP + Altivec
188: ori r7,r7,lo16(MSR_VM_OFF|MASK(MSR_FP)) ; Get real mode MSR + FP + Altivec
189: mtmsr r7 ; Set the real mode SRR */
190: isync ; Make sure it has happened
191:
192: lis r5,hi16(EXT(QNaNbarbarian)) ; Altivec initializer
193: ori r5,r5,lo16(EXT(QNaNbarbarian)) ; Altivec initializer
194:
195: mtspr vrsave,r0 ; Set that no VRs are used yet */
196:
197: vspltisw v1,0 ; Clear a register
198: lvx v0,br0,r5 ; Initialize VR0
199: mtvscr v1 ; Clear the vector status register
200: vor v2,v0,v0 ; Copy into the next register
201: vor v1,v0,v0 ; Copy into the next register
202: vor v3,v0,v0 ; Copy into the next register
203: vor v4,v0,v0 ; Copy into the next register
204: vor v5,v0,v0 ; Copy into the next register
205: vor v6,v0,v0 ; Copy into the next register
206: vor v7,v0,v0 ; Copy into the next register
207: vor v8,v0,v0 ; Copy into the next register
208: vor v9,v0,v0 ; Copy into the next register
209: vor v10,v0,v0 ; Copy into the next register
210: vor v11,v0,v0 ; Copy into the next register
211: vor v12,v0,v0 ; Copy into the next register
212: vor v13,v0,v0 ; Copy into the next register
213: vor v14,v0,v0 ; Copy into the next register
214: vor v15,v0,v0 ; Copy into the next register
215: vor v16,v0,v0 ; Copy into the next register
216: vor v17,v0,v0 ; Copy into the next register
217: vor v18,v0,v0 ; Copy into the next register
218: vor v19,v0,v0 ; Copy into the next register
219: vor v20,v0,v0 ; Copy into the next register
220: vor v21,v0,v0 ; Copy into the next register
221: vor v22,v0,v0 ; Copy into the next register
222: vor v23,v0,v0 ; Copy into the next register
223: vor v24,v0,v0 ; Copy into the next register
224: vor v25,v0,v0 ; Copy into the next register
225: vor v26,v0,v0 ; Copy into the next register
226: vor v27,v0,v0 ; Copy into the next register
227: vor v28,v0,v0 ; Copy into the next register
228: vor v29,v0,v0 ; Copy into the next register
229: vor v30,v0,v0 ; Copy into the next register
230: vor v31,v0,v0 ; Copy into the next register
231:
232: cmplwi r30,1 ; Are we the boot processor?
233: mfspr r11,msscr0 ; Get the memory system control register
234: dssall ; Force all data stream stuff to stop
235: oris r11,r11,hi16(dl1hwfm) ; Turn on the hardware flush request
236: sync
237: beq invl1 ; Not boot, invalidate L1...
238:
239: mtspr msscr0,r11 ; Start the flush operation
240:
241: rstbsy: mfspr r11,msscr0 ; Get the control register again
242:
243: rlwinm. r11,r11,0,dl1hwf,dl1hwf ; Has the flush request been reset yet?
244: bne rstbsy ; No, flush is still in progress...
245:
246: sync ; Make sure all flushes have been committed
247: b setmck ; Go set mck handling...
248:
249: invl1: mfspr r8,hid0 ; Set the HID0 bits for enable, and invalidate
250: ori r8,r8,lo16(0x0000CC00) ; Do an isync just incase the cache was off
251: sync
252: isync ; Start the invalidate
253: mtspr hid0,r8 ; To finish the invalidate clear the inval bits
254: li r9,lo16(0x00000C00)
255: andc r8,r8,r9 ; End the invalidate
256: mtspr hid0,r8 ; Make sure all is done
257: sync ; Make sure it is really done
258: sync
259:
260: setmck: mfspr r11,hid0 ; ?
261: ori r11,r11,hi16(eiecm) ; ?
262: mtspr hid0,r11 ; ?
263: isync
264:
265: #if 0
266: ; (TEST/DEBUG) Flush and turn off L2 Cache so I can display memory with the durn ESP unit
267: b flushl2 ; (TEST/DEBUG) Jump to start
268:
269: .align 5 ; (TEST/DEBUG) Force alignment to cache
270: nop
271: nop
272: nop
273: nop
274: nop
275: flushl2: mfspr r11,l2cr ; (TEST/DEBUG) Get L2 control register
276: ori r11,r11,0x0800 ; (TEST/DEBUG) Turn on L2 hardware flush request
277: sync ; (TEST/DEBUG)
278:
279: ; Cache boundary here
280: ; The following flush and cache disable are all in the same line
281:
282: mtspr l2cr,r11 ; (TEST/DEBUG) Start the flush
283:
284: flushl2d: mfspr r11,l2cr ; (TEST/DEBUG) Get the control reg again
285: rlwinm. r8,r11,0,20,20 ; (TEST/DEBUG) Have we finished?
286: bne flushl2d ; (TEST/DEBUG) Nope...
287: sync ; (TEST/DEBUG)
288: rlwinm r11,r11,0,1,31 ; (TEST/DEBUG) Turn off L2
289: mtspr l2cr,r11 ; (TEST/DEBUG) Finish it
290: sync ; (TEST/DEBUG) Quiet down
291:
292: ; Cache boundary here
293: ; Invalidate the L2 cache, just for funsies...
294:
295: oris r8,r11,0x0020 ; (TEST/DEBUG) Turn on invalidate request
296: mtspr l2cr,r8 ; (TEST/DEBUG) Start invalidation
297: sync ; (TEST/DEBUG)
298:
299: invl2: mfspr r8,l2cr ; (TEST/DEBUG) Get the L2 control register
300: rlwinm. r8,r8,0,31,31 ; (TEST/DEBUG) Is the invalidation still going on?
301: bne+ invl2 ; (TEST/DEBUG) Yes, keep going...
302:
303: mtspr l2cr,r11 ; (TEST/DEBUG) Turn off invalidate request, leaving L2 disabled
304: sync
305: ; Cache boundary here
306: #endif
307: b invcache ; (TEST/DEBUG) Now, go invalidate level 1...
308:
309:
310: novmx:
311: /*
312: * We need to have our memory coherent, but we may not be here. If we just switch the
313: * BATs, we could end up with memory paradoxes, i.e., cache entries left over from
314: * when the memory was incoherent, just babbling away... To prevent this, we have to get
315: * rid of all non-coherent lines. Since we just loaded the system, we could have tons
316: * of lines with and unknown address ranges, so we would have to do a whole slew of DCBSTs
317: * to force them all out. We can't just flash invalidate, 'cause we'd lose a few lines.
318: * So, we go translate off, load up some safe lines (from the ROM), and then flash invalidate
319: * the caches. We don't do this for a 601 'cause there ain't no DBATs or flash invalidate.
320: */
321:
322:
323: realcode: lis r8,0xFFF0 /* Point to the ROM */
324: addis r9,r8,0x0002 /* Point 128k later */
325: subi r8,r8,32 /* Start back one */
326:
327: readROM: lwz r10,32(r8) /* Get a line into cache */
328: addi r8,r8,32
329: cmplw cr0,r8,r9 /* See if we're done */
330: blt+ readROM /* Do it all... */
331:
332: sync
333:
334:
335: invcache:
336: mfspr r8,hid0 ; Turn on the L1 and invalidate it
337: ori r8,r8,lo16(0x0000CC00) ; Set the HID0 bits for enable, and invalidate
338: isync ; Do an isync just incase the cache was off
339: mtspr hid0,r8 ; Start the invalidate
340: li r9,lo16(0x00000C00) ; To finish the invalidate clear the inval bits
341: andc r8,r8,r9
342: mtspr hid0,r8 ; End the invalidate
343: sync ; Make sure all is done
344: sync ; Make sure it is really done
345:
346: /* */
347: /* Clear out the TLB. They be garbage after hard reset. */
348: /* */
349:
350: lis r12,hi16(EXT(tlb_system_lock)) /* Get the TLBIE lock */
351: li r0,512 /* Get number of TLB entries (overestimate at 512 entries) */
352: ori r12,r12,lo16(EXT(tlb_system_lock)) /* Grab up the bottom part */
353: li r3,0 /* Start at 0 */
354:
355: lwarx r5,0,r12 ; ?
356:
357: itlbhang: lwarx r5,0,r12 /* Get the TLBIE lock */
358: mr. r5,r5 /* Is it locked? */
359: bne- itlbhang /* It's locked, go wait... */
360: stwcx. r0,0,r12 /* Try to get it */
361: bne- itlbhang /* We was beat... */
362:
363: mtctr r0 /* Set the CTR */
364:
365: IRpurgeTLB: tlbie r3 /* Purge this entry */
366: addi r3,r3,4096 /* Next page */
367: bdnz IRpurgeTLB /* Do 'em all... */
368:
369: sync /* Make sure all TLB purges are done */
370:
371: mfpvr r10
372: rlwinm r10,r10,16,16,31
373:
374: eieio /* Make sure that the tlbie happens first */
375:
376: cmplwi r10,PROCESSOR_VERSION_603 /* Got a 603 */
377: beq donttsync /* Yeah, don't sync... */
378:
379: cmplwi r10,PROCESSOR_VERSION_603e /* Got a 603e */
380: beq donttsync /* Yeah, don't sync... */
381:
382: cmplwi r10,PROCESSOR_VERSION_750 /* Got a 750 */
383: beq donttsync /* Yeah, don't sync... */
384:
385: tlbsync /* Make sure on other processors also */
386: sync /* Make sure the TLBSYNC is done */
387:
388: donttsync: stw r5,0(r12) ; Unlock the TLBIE interlock
389:
390: li r0,MSR_SUPERVISOR_INT_OFF|MASK(MSR_FP) /* Make sure we don't have ints enabled */
391: mtmsr r0 /* Set the standard MSR values */
392: isync
393:
394: lis r5,HIGH_ADDR(EXT(FloatInit)) /* Get top of floating point init value */
395: ori r5,r5,LOW_ADDR(EXT(FloatInit)) /* Slam bottom */
396: lfd f0,0(r5) /* Initialize FP0 */
397: fmr f1,f0 /* Ours in not */
398: fmr f2,f0 /* to wonder why, */
399: fmr f3,f0 /* ours is but to */
400: fmr f4,f0 /* do or die! */
401: fmr f5,f0
402: fmr f6,f0
403: fmr f7,f0
404: fmr f8,f0
405: fmr f9,f0
406: fmr f10,f0
407: fmr f11,f0
408: fmr f12,f0
409: fmr f13,f0
410: fmr f14,f0
411: fmr f15,f0
412: fmr f16,f0
413: fmr f17,f0
414: fmr f18,f0
415: fmr f19,f0
416: fmr f20,f0
417: fmr f21,f0
418: fmr f22,f0
419: fmr f23,f0
420: fmr f24,f0
421: fmr f25,f0
422: fmr f26,f0
423: fmr f27,f0
424: fmr f28,f0
425: fmr f29,f0
426: fmr f30,f0
427: fmr f31,f0
428:
429: li r0, MSR_SUPERVISOR_INT_OFF /* Make sure we don't have FP enabled */
430: mtmsr r0 /* Set the standard MSR values */
431: isync
432:
433: #if 0
434: li r3,0 /* (TEST/DEBUG) */
435: bl EXT(fwSCCinit) /* (TEST/DEBUG) */
436: #endif
437: #if 0
438: li r3,1 /* (TEST/DEBUG) */
439: bl EXT(fwSCCinit) /* (TEST/DEBUG) */
440: #endif
441:
442: lis r20,HIGH_ADDR(fwdisplock) /* Get address of the firmware display lock */
443: li r19,0 /* Zorch a register */
444: ori r20,r20,LOW_ADDR(fwdisplock) /* Get address of the firmware display lock */
445: stw r19,0(r20) /* Make sure the lock is free */
446:
447: #if 0
448: li r3,0 /* (TEST/DEBUG) */
449: lis r4,0x6D65 /* (TEST/DEBUG) 'memg' */
450: ori r4,r4,0x6D67 /* (TEST/DEBUG) */
451: li r5,0 /* (TEST/DEBUG) */
452: bl EXT(dbgDispLL) /* (TEST/DEBUG) */
453: #endif
454: cmpi cr0, r30, 1
455: beq callcpu
456: /* move onto interrupt stack */
457:
458: lis r29,HIGH_ADDR(EXT(intstack_top_ss))
459: ori r29,r29,LOW_ADDR(EXT(intstack_top_ss))
460: #if 0
461: li r3,0 /* (TEST/DEBUG) */
462: lis r4,0x7232 /* (TEST/DEBUG) 'r29a' */
463: ori r4,r4,0x3961 /* (TEST/DEBUG) */
464: mr r5,r29 /* (TEST/DEBUG) */
465: bl EXT(dbgDispLL) /* (TEST/DEBUG) */
466: #endif
467: lwz r29,0(r29)
468: #if 0
469: li r3,0 /* (TEST/DEBUG) */
470: lis r4,0x7232 /* (TEST/DEBUG) 'r29b' */
471: ori r4,r4,0x3962 /* (TEST/DEBUG) */
472: mr r5,r29 /* (TEST/DEBUG) */
473: bl EXT(dbgDispLL) /* (TEST/DEBUG) */
474: #endif
475:
476: li r28, 0
477: stw r28, FM_BACKPTR(r29) /* store a null frame backpointer */
478:
479: /* move onto new stack */
480:
481: #if 0
482: li r3,0 /* (TEST/DEBUG) */
483: lis r4,0x676F /* (TEST/DEBUG) 'gogo' */
484: ori r4,r4,0x676F /* (TEST/DEBUG) */
485: mr r5,r29 /* (TEST/DEBUG) */
486: bl EXT(dbgDispLL) /* (TEST/DEBUG) */
487: #endif
488:
489: mr r1,r29
490: mr r3,r31 /* Restore any arguments we may have trashed */
491:
492: bl EXT(ppc_init)
493:
494: /* Should never return */
495:
496: BREAKPOINT_TRAP
497:
498: callcpu:
499: /* move onto interrupt stack */
500: lwz r29,PP_INTSTACK_TOP_SS(r31)
501: li r28, 0
502: stw r28, FM_BACKPTR(r29) /* store a null frame backpointer */
503:
504: /* move onto new stack */
505: mr r1,r29
506: mr r3,r31 /* Restore any arguments we may have trashed */
507:
508: bl EXT(ppc_init_cpu)
509:
510: /* Should never return */
511:
512: BREAKPOINT_TRAP
513:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.