|
|
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.