Annotation of XNU/osfmk/ppc/POWERMAC/mp/MP_2p.s, revision 1.1.1.1

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_INTERNAL_USE_ONLY@
                     24:  */
                     25: 
                     26: /*                                                                                                                                                                                     
                     27:        MP_2p.s 
                     28: 
                     29:        MP low-level signaling, configuration, et all.  This is for a and Apple/Daystar 2p board
                     30: 
                     31:        Lovingly crafted by Bill Angell using traditional methods
                     32: 
                     33: */
                     34: 
                     35: #include <ppc/asm.h>
                     36: #include <ppc/proc_reg.h>
                     37: #include <ppc/POWERMAC/mp/MPPlugIn.h>
                     38: #include <assym.s>
                     39: #include <mach/machine/vm_param.h>
                     40: 
                     41: 
                     42: 
                     43:                        .set    MPPlugInVersion,0                                               /* Current version code */
                     44: 
                     45: /* */
                     46: /*                     Interfaces to hardware */
                     47: /* */
                     48: 
                     49:                        .set    PCI1ARdisp,             0x00800000                              /* Displacement from Bandit to PCI1 address configuiration register */
                     50:                        .set    GrandCdisp,             0x01000000                              /* Displacement from Bandit to Grand Central */
                     51:                        .set    EventsReg,              0x20                                    /* Interruption events register (latched) */
                     52:                        .set    LevelsReg,              0x2C                                    /* Interruption levels register (unlatched) */
                     53:                        .set    MaskReg,                0x24                                    /* Interruption mask register */
                     54:                        .set    ClearReg,               0x28                                    /* Interruption clear register */
                     55:                        .set    TicksPerMic,    11                                              /* We'll use 11 ticks per �S - 120MHz is really 10, 180MHz is 11.24 */
                     56:                        .set    EtherNRdisp,    0x01019000                              /* Displacement into bandit of EtherNet ROM */
                     57: 
                     58: #ifdef __ELF__
                     59:                        .section ".data"
                     60: #else
                     61:                        .data
                     62: #endif
                     63: 
                     64:                        .align  5                                                                       /* Get us out to the end */
                     65: 
                     66:                        .globl MPPIwork
                     67: #ifdef __ELF__
                     68:                        .type  MPPIwork,@function
                     69: #endif
                     70: 
                     71: MPPIwork:
                     72: MPPIstatus:    .byte   0                                                                       /* Global MP board status */
                     73:                        .set    MPPIinit,       0x80                                    /* Global initialization complete */
                     74:                        .set    MPPI2Pv2,       0x40                                    /* Second rev of 2P board (no watchdog and different state machine) */
                     75:                        .byte   0                                                                       /* Reserved */
                     76: MPPIinst:      .byte   0                                                                       /* Mask of CPUs installed */
                     77: MPPIonline:    .byte   0                                                                       /* Mask of CPUs online (i.e., initialized) */
                     78: MPPIlogCPU:    .long   0                                                                       /* Used to configure CPU addresses */
                     79: MPPITBsync:    .long   0                                                                       /* Used to sync time bases */
                     80:                        .long   0
                     81: MPPIHammer:    .long   0                                                                       /* Address of HammerHead */
                     82: MPPIGrandC:    .long   0                                                                       /* Address of GrandCentral */
                     83: MPPIPCI1Adr: .long     0                                                                       /* Address of PCI1's config reg addr */
                     84: MPPIEther:     .long   0                                                                       /* Address of EtherNet ROM */
                     85:                        
                     86:                        .align  5
                     87: MPPISncFght: .fill     4,4,0                                                           /* Space for 9 passes of a TB sync fight + 1 guard pass */
                     88:                        .fill   4,4,0
                     89:                        .fill   4,4,0
                     90:                        .fill   4,4,0
                     91:                        .fill   4,4,0
                     92:                        .fill   4,4,0
                     93:                        .fill   4,4,0
                     94:                        .fill   4,4,0
                     95:                        .fill   4,4,0
                     96:                        .fill   4,4,0
                     97:                        .align  7                                                                       /* Point to the start of the CPU status */
                     98: 
                     99:                        .globl EXT(MPPICPUs)
                    100: #ifdef __ELF__
                    101:                        .type  EXT(MPPICPUs),@function
                    102: #endif
                    103: EXT(MPPICPUs):                                                                                         /* Start of Processor specific areas */
                    104: /*                     There are 8 of these indexed by processor number */
                    105: 
                    106: 
                    107: MPPICPU0:      .fill   8,4,0                                                                   /* First processor */
                    108: MPPICPU1:      .fill   8,4,0                                                                   /* Second processor */
                    109: MPPICPU2:      .fill   8,4,0                                                                   /* Third processor */
                    110: MPPICPU3:      .fill   8,4,0                                                                   /* Fourth processor */
                    111:                        .set    MPPIMaxCPU, (.-EXT(MPPICPUs)-32)/32                     /* Get the maximum CPU address */
                    112: 
                    113: 
                    114:                        .text
                    115: 
                    116: /******************************************************************************************************** */
                    117: /******************************************************************************************************** */
                    118: /* */
                    119: /*                     Here starteth ye stuff */
                    120: /* */
                    121: /******************************************************************************************************** */
                    122: /******************************************************************************************************** */
                    123: 
                    124: /******************************************************************************************************** */
                    125: /* */
                    126: /*                     Validate that the hardware matches with our code.  At this point, we cannot check */
                    127: /*                     for anything other than the possibility of this working.  There's no version code */
                    128: /*                     or nothin'.  So, if we have a second processor and are a 604 or 604e, we'll say */
                    129: /*                     we're capable.  Also we'll check version codes for our code. */
                    130: /* */
                    131: /*                     When we get here, DDAT and IDAT are both on, 'rupts are disabled. */
                    132: /*  */
                    133: /*                     We're called like this:  */
                    134: /*                             OSStatus MP_probe(MPPlugInSpecPtr spec, UInt32 HammerheadAddr); */
                    135: /* */
                    136: /******************************************************************************************************** */
                    137: 
                    138: ENTRY(MPprobe, TAG_NO_FRAME_USED)
                    139: 
                    140:                        
                    141: MPPIbase:      mfpvr   r7                                                                      /* Get the processor version */
                    142:                        rlwinm  r7,r7,16,16,31                                          /* Isolate the processor type */
                    143: 
                    144:                        lbz             r5,ArbConfig(r4)                                        /* See if there is another processor */
                    145:                        
                    146:                        andi.   r5,r5,TwoCPU                                            /* Are we a real live two processor? */
                    147:                        beq             OneWay                                                          /* Nope, we be gone... */
                    148:                        
                    149:                        cmplwi  cr0,r7,4                                                        /* Are we a 604? */
                    150:                        beq             SeemsOK                                                         /* Yeah, we're cool... */
                    151:                        cmplwi  cr0,r7,9                                                        /* Are we a 604E? */
                    152:                        beq             SeemsOK                                                         /* Yeah, go finish up... */
                    153:                        
                    154: OneWay:                li              r3,0                                                            /* Say we can't find the proper CPU */
                    155:                        blr                                                                                     /* Leave... */
                    156:                        
                    157: SeemsOK:       mr              r10,r3                                                          /* Save the parameter list */
                    158:                        
                    159:                        lwz             r4,MPSversionID(r10)                            /* Get the version ID */
                    160:                        cmplwi  cr0,r4,kMPPlugInVersionID                       /* Correct version? */
                    161:                        beq             IsOK                                                            /* Yeah, we think we're ok... */
                    162:                        
                    163:                        li              r3,0                                                            /* Set bad version' */
                    164:                        blr                                                                                     /* Leave... */
                    165:                        
                    166: IsOK:          mflr    r11                                                                     /* Save the LR */
                    167:                        lis             r9,HIGH_ADDR(MPPIwork)                          /* Get the top half of the data area */
                    168:                        bl              SetBase1                                                        /* Jump to the next instruction */
                    169: SetBase1:      mflr    r12                                                                     /* Get the base register */
                    170:                        ori             r9,r9,LOW_ADDR(MPPIwork)                        /* Get the bottom half of the data area */
                    171:                        addi    r12,r12,LOW_ADDR(MPPIbase-SetBase1)     /* Adjust to the start of all our code */
                    172:                        
                    173:                        stw             r12,MPSbaseAddr(r10)                            /* Save off the common base for all functions */
                    174:                        
                    175:                        la              r5,LOW_ADDR(MPPIFunctions-MPPIbase)(r12)        /* Point to the base of all functions */
                    176:                        stw             r5,MPSareaAddr(r10)                                     /* Pass back the code address */
                    177:                        
                    178:                        la              r5,LOW_ADDR(MPPIFuncOffs-MPPIbase)(r12) /* Point to the function offset table */
                    179:                        stw             r5,MPSoffsetTableAddr(r10)                      /* Pass back the pointer to the offset table */
                    180:                        
                    181:                        li              r5,LOW_ADDR(MPPISize-MPPIFunctions)     /* Get our size without data area */
                    182:                        stw             r5,MPSareaSize(r10)                                     /* Save it */
                    183:                        
                    184:                        stw             r9,MPSdataArea(r10)                                     /* Save it */
                    185:                        
                    186:                        la              r5,LOW_ADDR(EXT(MPPICPUs)-MPPIwork)(r9) /* Point to the CPU area base */
                    187:                        stw             r5,MPSCPUArea(r10)                                      /* Save it */
                    188:                        
                    189:                        mtlr    r11                                                                     /* Restore that return address */
                    190:                        li              r3,1                                                            /* Set no error */
                    191:                        blr                                                                                     /* Leave, we're all done... */
                    192: 
                    193: /******************************************************************************************************** */
                    194: /******************************************************************************************************** */
                    195: /* */
                    196: /*                     Here starteth ye code that starteth up ye second prothether. */
                    197: /*                     Yea, though ye prothether executeth asynchronously, it appears unto men */
                    198: /*                     in ye shape of a synchronous process.  By ye instruction of He who gave it */
                    199: /*                     form and being, it stopeth to worship and praise its Lord, to joyously  */
                    200: /*                     receive His blessings and teachings, to guide its way along the path to */
                    201: /*                     righteous execution. */
                    202: /* */
                    203: /******************************************************************************************************** */
                    204: /******************************************************************************************************** */
                    205: 
                    206: 
                    207: /******************************************************************************************************** */
                    208: /* */
                    209: /*                     Initialize the MP hardware.  This will bring the other processor online. */
                    210: /* */
                    211: /*                     First we will tick the board to its 5th state the "TBEN off" state. */
                    212: /* */
                    213: /*                     Just for giggles, here's the states: */
                    214: /* */
                    215: /*                     1) 1st ROM                      - This state exists after motherboard reset */
                    216: /*                     2) Open Firmware        - Transitions here when the SecInt line is first asserted */
                    217: /*                                                               Open Firmware attempts to execute some code on the secondary */
                    218: /*                                                               processor to obtain the PVR register.  It's got some problems */
                    219: /*                                                               and hangs the secondary disabled. */
                    220: /*                     3) Reset (my name)      - Entered when the SecInt line is deasserted. A timer starts and */
                    221: /*                                                               468�S later the reset line is pulled.  I may have this wrong here, */
                    222: /*                                                               it may be that the reset line is held for 468�S.  Either way, */
                    223: /*                                                               this state is invisible to us. */
                    224: /*                     4) 2nd ROM                      - This state exists when the secondary processor begins executing */
                    225: /*                                                               after the reset. */
                    226: /*                     5) TBEN off                     - We transition here when SecInt is asserted in the 2nd ROM state. */
                    227: /*                                                               In this state, the TBEN pin is set to disable the timebase from  */
                    228: /*                                                               running on all processors, thus freezing time. (Performace analysis */
                    229: /*                                                               note: here would be the best time to run stats, all tests would */
                    230: /*                                                               run in 0 time giving us infinite speed.) Also the "primary arbitration" */
                    231: /*                                                               mode is set.  This mode causes the CPU board to arbitrate both processors */
                    232: /*                                                               using a single bus master.  This gets us around the L2 cache dumbness. */
                    233: /*                                                               We should also note that because of this, there is now no way to  */
                    234: /*                                                               tell if we are on the secondary processor, the WhoAmI register will */
                    235: /*                                                               always indicate the primary processor.  We need to have sewn */
                    236: /*                                                               name tags into our underwear before now. */
                    237: /*                                                               Finally, this state is the only way we can tell if we are executing */
                    238: /*                                                               on the older version of the 2-way board.  When it is in this state */
                    239: /*                                                               "primary arbitration" has not been enabled yet.  The WhoAmI register */
                    240: /*                                                               will indicate if we are on the secondary processor on not.  We should */
                    241: /*                                                               check this because we need to do signals differently. */
                    242: /*                     6) TBEN on                      - The next assertion of SecInt brings us to our final destination.  For */
                    243: /*                                                               those of you who will be deplaning, please remember that timebases */
                    244: /*                                                               are running and primary arbitration is enabled.  Always remember: */
                    245: /*                                                               buckle up for safety and if you're tired pull over for a rest. */
                    246: /* */
                    247: /******************************************************************************************************** */
                    248: 
                    249: ENTRY(MPinstall, TAG_NO_FRAME_USED)
                    250: 
                    251: /*                     int MP_install(unsigned int *physAddr, unsigned int band1, unsigned int hammerh, unsigned int grandc,
                    252:  *                     unsigned int pci1ar, unsigned int enetr);
                    253:  */
                    254:        
                    255:                        lis             r11,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    256:                        mflr    r0                                                                      /* Save the LR */
                    257:                        ori             r11,r11,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    258:                        
                    259:                        stw             r5,MPPIHammer-MPPIwork(r11)                     /* Save the HammerHead address for later */
                    260:                        stw             r6,MPPIGrandC-MPPIwork(r11)                     /* Save address of Grand Central */
                    261:                        stw             r7,MPPIPCI1Adr-MPPIwork(r11)            /* Save the PCI1 address register address */
                    262:                        stw             r8,MPPIEther-MPPIwork(r11)                      /* Save Ethernet ROM address */
                    263: 
                    264:                        li              r4,LOW_ADDR(0xC080)                                     /* Set CPU 0&1 installed, CPU 0 online */
                    265:                        lis             r10,(MPPICOnline+MPPICReady)>>16        /* Set CPU 0 online and ready */
                    266:                        
                    267:                        mfspr   r6,pir                                                          /* Get the PIR contents */
                    268:                        
                    269:                        sth             r4,MPPIinst-MPPIwork(r11)                       /* Set 'em for later */
                    270:                        rlwinm  r6,r6,0,0,27                                            /* Clear to use processor 0 */
                    271:                        stw             r10,EXT(MPPICPUs)-MPPIwork(r11)         /* Preset CPU 0 online and ready */
                    272: 
                    273:                        mtspr   pir,r6                                                          /* Set our PIR */
                    274: 
                    275: /* */
                    276: /*                     Ok, ok, enough of this.  Let's really start 'em up. */
                    277: /* */
                    278: 
                    279:                        lis             r9,HIGH_ADDR(CPUInit)                           /* Top of init code */
                    280:                        li              r6,1                                                            /* Get the other guy's CPU address               */
                    281:                        ori             r9,r9,LOW_ADDR(CPUInit)                         /* Get physical address of init code */
                    282:                
                    283:                        mfmsr   r8                                                                      /* Get the MSR */
                    284: 
                    285:                        stw             r6,MPPIlogCPU-MPPIwork(r11)                     /* Set the logical CPU address to assign */
                    286:                                                
                    287:                        rlwinm  r6,r8,0,17,15                                           /* Turn off interruptions */
                    288:                        sync                                                                            /* Make sure the work area is updated */
                    289:                        mtmsr   r6                                                                      /* Flip the EE bit off */
                    290:                        isync                                                                           /* Chill a bit */
                    291:                        
                    292:                        stw             r9,0(r7)                                                        /* Pass the initialization code address to our friend */
                    293:                        sync                                                                            /* Fence off the pig */
                    294:                        
                    295:                        li              r6,0                                                            /* Clear this out */
                    296:                        stb             r6,IntReg(r5)                                           /* Kick the other processor */
                    297:                        eieio                                                                           /* Pig in the sty */
                    298: 
                    299: /*                     At this point we should be in the "TBEN off" state.  The second processor should be starting */
                    300: /*                     to come up. */
                    301: 
                    302: /*                     Note that we are assuming that the secondary processor will reset the interrupt request. */
                    303: /*                     If we are on one of the old boards, we will die in about 256�S if it is not reset, 'cause */
                    304: /*                     of that silly watchchihuahua timer.  We can't use the TB or decrimenter here to set a  */
                    305: /*                     timeout because when we are in "TBEN off" state these guys don't run. */
                    306: 
                    307:                        lis             r4,HIGH_ADDR(SpinTimeOut)                       /* Get about 1 second at 200MHz */
                    308:                                                                                                                /* At 120 MHz this is 1.66 seconds, at 400MHz it is .5 */
                    309:                                                                                                                /* All these are more than enough time for this handshake */
                    310:                        ori             r4,r4,LOW_ADDR(SpinTimeOut)                     /* Get the bottom part */
                    311: 
                    312: WaitReady:     lwz             r9,0(r7)                                                        /* Get this back */
                    313:                        mr.             r9,r9                                                           /* The other processor will set to 0 */
                    314:                                                                                                                /*    when it is ready for the work area address */
                    315:                        beq             CodeUp                                                          /* The code is up on the other side */
                    316:                        subi    r4,r4,1                                                         /* Count the try */
                    317:                        mr.             r4,r4                                                           /* Did we timeout? */
                    318:                        bne+    WaitReady                                                       /* Nope... */
                    319:                        
                    320:                        li              r3,kMPPInitTO1                                          /* Set that we timed out with initial code bringup */
                    321:                        mtmsr   r8                                                                      /* Restore the interrupt state */
                    322:                        mtlr    r0                                                                      /* Restore the return addess */
                    323:                        blr                                                                                     /* Return a failure... */
                    324: 
                    325: CodeUp:                isync                                                                           /* Make sure we don't prefetch past here */
                    326:                        
                    327: /*                     Timebase is stopped here, no need for the funky "get time base right" loop */
                    328: 
                    329:                        mftbu   r4                                                                      /* Get upper timebase half */
                    330:                        mftb    r9                                                                      /* Get bottom  */
                    331:                        stw             r4,MPPITBsync-MPPIwork(r11)                     /* Save the top */
                    332:                        stw             r9,MPPITBsync+4-MPPIwork(r11)           /* Save the second half */
                    333:                        sync                                                                            /* Be very sure it's there */
                    334:                        
                    335:                        stw             r11,0(r7)                                                       /* Set the PCI1 adr reg non-zero - this releases the spin */
                    336:                                                                                                                /*      loop and allows the timebase to be set. */
                    337:                        eieio
                    338: 
                    339:                        lis             r9,HIGH_ADDR(SpinTimeOut)                       /* Get the spin time */
                    340:                        ori             r9,r9,LOW_ADDR(SpinTimeOut)                     /* Get the bottom part */
                    341:                        
                    342: WaitTBset:     lwz             r4,0(r7)                                                        /* Get this back */
                    343:                        mr.             r4,r4                                                           /* When zero, the other guy's TB is set up */
                    344:                        beq-    TBSetUp                                                         /* She's'a all done... */
                    345:                        subi    r9,r9,1                                                         /* Count the try */
                    346:                        mr.             r9,r9                                                           /* Did we timeout? */
                    347:                        bne+    WaitTBset                                                       /* Nope... */
                    348:                        
                    349:                        li              r3,kMPPInitTO3                                          /* Set that we timed out setting clock */
                    350:                        mtmsr   r8                                                                      /* Restore the interrupt state */
                    351:                        isync
                    352:                        mtlr    r0                                                                      /* Restore the return addess */
                    353:                        blr                                                                                     /* Return a failure... */
                    354: 
                    355: TBSetUp:       stb             r6,IntReg(r5)                                           /* Kick the other processor again */
                    356:                                                                                                                /* This will tick us to the next state */
                    357:                        eieio
                    358:                                                
                    359: SpinDelay:     addi    r6,r6,1                                                         /* Bump spin count (we finally are trashing R6) */
                    360:                        cmplwi  cr0,r6,4096                                                     /* Spun enough? */
                    361:                        ble+    SpinDelay                                                       /* Nope... */
                    362:                        
                    363:                        li              r6,SecInt                                                       /* Set the interrupt bit */
                    364:                        stb             r6,IntReg(r5)                                           /* Deassert the external signal */
                    365: /* */
                    366: /*                     Ok, the other processor should be online in a spin waiting for a start signal from */
                    367: /*                     us.  It should be in the reset state with no external interruptions pending.  There may */
                    368: /*                     be a decrimenter pop waiting in the wings though. */
                    369: /* */
                    370:                        
                    371:                        lwz             r7,MPPIGrandC-MPPIwork(r11)                     /* Point to GrandCentral */
                    372:                        lwz             r4,MaskReg(r7)                                          /* Get the grand central mask register (note that this */
                    373:                                                                                                                /* is a little-endian area, but I'm too lazy to access it that way */
                    374:                                                                                                                /* so I'll document what it really should be, but, probably, it would */
                    375:                                                                                                                /* have been much, much easier just to code up the lwbrx and be done */
                    376:                                                                                                                /* with it rather than producing this monograph describing my alternate */
                    377:                                                                                                                /* access method that I really don't explain anyway. */
                    378:                        ori             r4,r4,0x0040                                            /* Flip on bit 30 (hah, figure that one out).  This enables the */
                    379:                                                                                                                /* Ext10 interrupt which is connected to the MACE ethernet chip's */
                    380:                                                                                                                /* chip-select pin. */
                    381:                        stw             r4,MaskReg(r7)                                          /* Stick it on back */
                    382:                        eieio
                    383:                        
                    384:                        mtlr    r0                                                                      /* Get back the original LR */
                    385:                        sync                                                                            /* Make sure all storage ops are done */
                    386:                        mtmsr   r8                                                                      /* Restore the MSR */
                    387:                        isync
                    388:                        li              r3,kSIGPnoErr                                           /* Set that we worked jest fine and dandy */
                    389:                        blr                                                                                     /* Bye now... */
                    390: 
                    391:                        .align  5
                    392: /******************************************************************************************************** */
                    393: /******************************************************************************************************** */
                    394: /* */
                    395: /*                     This is where the individual SIGP function calls reside.  */
                    396: /*                     Also, it is where we cram the second processor's initialization code wo'w we */
                    397: /*                     can use physical addressing. */
                    398: /* */
                    399: /******************************************************************************************************** */
                    400: /******************************************************************************************************** */
                    401: 
                    402: MPPIFunctions:                                                                                 /* Start of all externally called functions and interrupt handling code */
                    403: 
                    404: 
                    405: /******************************************************************************************************** */
                    406: /* */
                    407: /*                     Count the number of processors.  This hardwires to 2 (or 1 if no secondary) */
                    408: /* */
                    409: /******************************************************************************************************** */
                    410: 
                    411: CountProcessors:
                    412:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    413:                        mfmsr   r9                                                                      /* Get the MSR */
                    414:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    415:                        
                    416:                        ori             r10,r9,0x0010                                           /* Turn on DDAT */
                    417:                        
                    418:                        lwz             r8,MPPIHammer-MPPIwork(r12)                     /* Point to the HammerHead controller */
                    419:                        
                    420:                        mtmsr   r10                                                                     /* Turn on DDAT */
                    421:                        isync                                                                           /* Kill speculation */
                    422: 
                    423:                        li              r3,2                                                            /* Assume we have them all */
                    424:                        lbz             r5,ArbConfig(r8)                                        /* Check if we've seen a second processor */
                    425:                        andi.   r5,r5,TwoCPU                                            /* Are we a real live two processor? */
                    426:                        mtmsr   r9                                                                      /* Put back the DDAT */
                    427:                        isync
                    428:                        
                    429:                        bnelr+                                                                          /* Yeah... */
                    430:                        li              r3,1                                                            /* Nope, set a count of 1 */
                    431:                        blr                                                                                     /* Leave, we're inadequate... */
                    432: 
                    433: /******************************************************************************************************** */
                    434: /* */
                    435: /*                     Start up the selected processor (R3=processor; R4=physical start address; R5=pass-thru parm) */
                    436: /* */
                    437: /******************************************************************************************************** */
                    438:                        
                    439: StartProcessor:
                    440: 
                    441:                        mr              r7,r5                                                           /* Copy pass-thru parameter */
                    442:                        mfspr   r10,pir                                                         /* Get our processor number */
                    443:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    444:                        cmplw   cr0,r3,r10                                                      /* Trying to start ourselves? */
                    445:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    446:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    447:                        li              r3,kMPPHairyPalms                                       /* Set trying to do it to ourselves */
                    448:                        beqlr-                                                                          /* Self abuse... */
                    449:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    450:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    451:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    452:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    453:                        mflr    r11                                                                     /* Save the return address */
                    454:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    455:                        
                    456: SPretry:       lwarx   r5,0,r9                                                         /* Pick up the status flags (MPPICStat) and reserve it */
                    457:                        li              r3,kSIGPInterfaceBusyErr                        /* Fill dead space and get busy return code */
                    458:                        rlwinm. r0,r5,0,0,0                                                     /* Are we marked as busy? */
                    459:                        lis             r6,MPPICOnline>>16                                      /* Get the online flag */
                    460:                        bne-    ErrorReturn                                                     /* Yeah, go leave, don't bother me now... */
                    461:                        and.    r0,r5,r6                                                        /* Are we online */
                    462:                        li              r3,kMPPOffline                                          /* Set offline */
                    463:                        beq-    ErrorReturn                                                     /* Ain't online, ain't ready, buzz off... */
                    464:                        li              r3,kMPPBadState                                         /* Set bad state */
                    465:                        oris    r5,r5,(MPPICBusy>>16)&0x0000FFFF        /* Turn on the busy bit */
                    466:                        
                    467:                        stwcx.  r5,0,r9                                                         /* Try to set busy */
                    468:                        bne-    SPretry                                                         
                    469:                        
                    470:                        ori             r6,r10,MPPICfStrt<<8                            /* Put the Start function in front of the processor ID */
                    471:                        rlwimi  r5,r6,0,16,31                                           /* Put these behind the status flags */
                    472:                        stw             r4,MPPICParm0(r9)                                       /* Set the starting physical address parameter */
                    473:                        stw             r7,MPPICParm2(r9)                                       /* Set pass-thru parameter */
                    474:                        
                    475:                        sync                                                                            /* Make sure it's all out there */
                    476:                        b               KickAndGo                                                       /* We're done now... */
                    477: 
                    478: /******************************************************************************************************** */
                    479: /* */
                    480: /*                     Reset the selected processor (R3=processor).  You can't reset yourself or the primary. */
                    481: /*                     We're gonna try, try real hard...  This is not for the faint-of-heart. */
                    482: /*                     If there's ever any way to yank a reset line, we'll do it here. */
                    483: /* */
                    484: /******************************************************************************************************** */
                    485:                        
                    486: ResetProcessor:
                    487:                        mfspr   r10,pir                                                         /* Get our processor number */
                    488:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    489:                        rlwinm  r10,r10,0,28,31                                         /* Clean up the PIR */
                    490:                        cmplw   cr0,r3,r10                                                      /* Trying to start ourselves? */
                    491:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    492:                        li              r3,kMPPHairyPalms                                       /* Set trying to do it to ourselves */
                    493:                        beqlr-                                                                          /* Self abuse... */
                    494:                        mr.             r9,r9                                                           /* Trying to reset the primary?!?  Dude, that's insubordination!!!! */
                    495:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    496:                        li              r3,kMPPInvalCPU                                         /* Say that that's a major offense */
                    497:                        beqlr-                                                                          /* Bye now... */
                    498:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    499:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    500:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    501:                        
                    502:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)           /* Point into the proccessor control area                */
                    503:                        mflr    r11                                                                     /* Save the return address */
                    504:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    505:                        
                    506:                        li              r4,16                                                           /* Try for 16 times to get the busy lock */
                    507: 
                    508: RSlockS:       mftb    r6                                                                      /* Time stamp start */
                    509: 
                    510: RSlock:                lwarx   r5,0,r9                                                         /* Pick up the status flags (MPPICStat) and reserve it */
                    511:                        rlwinm. r0,r5,0,2,2                                                     /* Are we online */
                    512:                        li              r3,kMPPOffline                                          /* Set offline */
                    513:                        cmplwi  cr1,r5,0                                                        /* Check for busy */
                    514:                        beq-    ErrorReturn                                                     /* Ain't online, ain't ready, buzz off... */
                    515:                        bge+    cr1,RSnotBusy                                           /* Not busy, make it so... */
                    516:                        
                    517:                        mftb    r7                                                                      /* Stamp the time */
                    518:                        sub             r7,r7,r6                                                        /* Get elapsed time */
                    519:                        rlwinm. r7,r7,16,16,31                                          /* Divide ticks by microseconds (this is pretty darn "kinda-in-the-ballpark") */
                    520:                        cmplwi  cr0,r7,TicksPerMic                                      /* See if we hit 65536�S yet */
                    521:                        blt+    RSlock                                                          /* Not yet... */
                    522:                        
                    523: RSatmtCnt:     subi    r4,r4,1                                                         /* Count the retries */
                    524:                        mr.             r4,r4                                                           /* Are we done yet? */
                    525:                        bgt+    RSlockS                                                         /* Start the lock attempt again... */
                    526:                        
                    527:                        li              r3,kMPPCantLock                                         /* Say we can't get the lock */
                    528:                        b               ErrorReturn                                                     /* Bye, dude... */
                    529:                        
                    530: RSnotBusy:     rlwinm  r5,r5,0,0,15                                            /* Clear out the function and requestor */
                    531:                        oris    r5,r5,(MPPICBusy>>16)&0x0000FFFF        /* Set busy */
                    532:                        or              r5,r10,r5                                                       /* Add in our processor */
                    533:                        ori             r5,r5,MPPICfReset<<8                            /* Set the reset function */
                    534:                        stwcx.  r5,0,r9                                                         /* Cram it back */
                    535:                        bne-    RSatmtCnt                                                       /* We lost the reservation... */
                    536:                        b               KickAndGo                                                       /* Try to send it across... */
                    537:                        
                    538: 
                    539: /******************************************************************************************************** */
                    540: /* */
                    541: /*                     Here we will try to resume execution of a stopped processor (R3=processor). */
                    542: /* */
                    543: /******************************************************************************************************** */
                    544:                        
                    545: ResumeProcessor:
                    546:                        mfspr   r10,pir                                                         /* Get our processor number */
                    547:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    548:                        cmplw   cr0,r3,r10                                                      /* Trying to resume ourselves? */
                    549:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    550:                        li              r3,kMPPHairyPalms                                       /* Set trying to do it to ourselves */
                    551:                        beqlr-                                                                          /* Self abuse... */
                    552:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    553:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    554:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    555:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    556:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    557:                        mflr    r11                                                                     /* Save the link register */
                    558:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    559:                        
                    560: RPretry:       lwarx   r5,0,r9                                                         /* Pick up the status flags (MPPICStat) and reserve it */
                    561:                        li              r3,kSIGPInterfaceBusyErr                        /* Fill dead space and get busy return code */
                    562:                        rlwinm. r0,r5,0,0,0                                                     /* Are we marked as busy? */
                    563:                        lis             r6,MPPICOnline>>16                                      /* Get the online flag */
                    564:                        bne-    ErrorReturn                                                     /* Yeah, go leave, don't bother me now... */
                    565:                        and.    r0,r5,r6                                                        /* Are we online */
                    566:                        li              r3,kMPPOffline                                          /* Set offline */
                    567:                        lis             r6,MPPICReady>>16                                       /* Get the ready bit */
                    568:                        beq-    ErrorReturn                                                     /* Ain't online, ain't ready, buzz off... */
                    569:                        and.    r0,r5,r6                                                        /* Are we ready? */
                    570:                        li              r3,kMPPNotReady                                         /* Set not ready */
                    571:                        lis             r6,MPPICStop>>16                                        /* Get the stopped bit */
                    572:                        beq-    ErrorReturn                                                     /* Ain't ready, buzz off... */
                    573:                        and.    r0,r5,r6                                                        /* Are we stopped? */
                    574:                        li              r3,kMPPNotStopped                                       /* Set not stopped */
                    575:                        oris    r5,r5,(MPPICBusy>>16)&0x0000FFFF        /* Turn on the busy bit */
                    576:                        beq-    ErrorReturn                                                     /* Nope, not stopped, so how do we resume? */
                    577:                        
                    578:                        stwcx.  r5,0,r9                                                         /* Try to set busy */
                    579:                        bne-    RPretry
                    580:                        
                    581:                        ori             r6,r10,MPPICfResm<<8                            /* Put the resume function in front of the processor ID */
                    582:                        rlwimi  r5,r6,0,16,31                                           /* Put these behind the status flags */
                    583:                        b               KickAndGo                                                       /* We're done now... */
                    584: 
                    585: 
                    586: 
                    587: /******************************************************************************************************** */
                    588: /* */
                    589: /*                     Here we will try to stop execution of a running processor (R3=processor). */
                    590: /* */
                    591: /******************************************************************************************************** */
                    592:                        
                    593: StopProcessor:
                    594:                        mfspr   r10,pir                                                         /* Get our processor number */
                    595:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    596:                        cmplw   cr0,r3,r10                                                      /* Are we doing ourselves? */
                    597:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    598:                        li              r3,kMPPHairyPalms                                       /* Set trying to do it to ourselves */
                    599:                        beqlr-                                                                          /* Self abuse... */
                    600:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    601:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    602:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    603:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    604:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    605:                        mflr    r11                                                                     /* Save the link register */
                    606:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    607:                        
                    608: PPretry:       lwarx   r5,0,r9                                                         /* Pick up the status flags (MPPICStat) and reserve it */
                    609:                        li              r3,kSIGPInterfaceBusyErr                        /* Fill dead space and get busy return code */
                    610:                        rlwinm. r0,r5,0,0,0                                                     /* Are we marked as busy? */
                    611:                        lis             r6,MPPICOnline>>16                                      /* Get the online flag */
                    612:                        bne-    ErrorReturn                                                     /* Yeah, go leave, don't bother me now... */
                    613:                        and.    r0,r5,r6                                                        /* Are we online */
                    614:                        li              r3,kMPPOffline                                          /* Set offline */
                    615:                        lis             r6,MPPICReady>>16                                       /* Get the ready bit */
                    616:                        beq-    ErrorReturn                                                     /* Ain't online, ain't ready, buzz off... */
                    617:                        and.    r0,r5,r6                                                        /* Are we ready? */
                    618:                        li              r3,kMPPNotReady                                         /* Set not ready */
                    619:                        lis             r6,MPPICStop>>16                                        /* Get the stopped bit */
                    620:                        beq-    ErrorReturn                                                     /* Ain't ready, buzz off... */
                    621:                        and.    r0,r5,r6                                                        /* Are we stopped? */
                    622:                        li              r3,kMPPNotRunning                                       /* Set not running */
                    623:                        oris    r5,r5,(MPPICBusy>>16)&0x0000FFFF        /* Turn on the busy bit */
                    624:                        bne-    ErrorReturn                                                     /* Nope, already stopped, so how do we stop? */
                    625:                        
                    626:                        stwcx.  r5,0,r9                                                         /* Try to set busy */
                    627:                        ori             r10,r10,MPPICfStop<<8                           /* Put the stop function in front of the processor ID */
                    628:                        bne-    PPretry
                    629:                        
                    630:                        rlwimi  r5,r10,0,16,31                                          /* Put these behind the status flags */
                    631:                        b               KickAndGo                                                       /* We're done now... */
                    632: 
                    633: 
                    634: /******************************************************************************************************** */
                    635: /* */
                    636: /*                     Here we will try to signal a running processor (R3=processor). */
                    637: /*                     Note that this should have good performace.  Well, actually, seeing as how slow we really are, it */
                    638: /*                     probably is moot anyhow. */
                    639: /*                     Another note: this function (and all most others as well) will return a timeout when the  */
                    640: /*                     second processor tries to do itself on the old version of the board.  This happens because */
                    641: /*                     In order to keep the watchchihuahua from popping (just imagine the scene: that little runt-dog just so */
                    642: /*                     excited that its veins and eyes bulge and then explode) signaling to the secondary  */
                    643: /*                     is done syncronously and disabled.  If the secondary signals the secondary, it will never enable so */
                    644: /*                     it will never see the 'rupt, so it will never clear it, so it will time out, so there... */
                    645: /* */
                    646: /******************************************************************************************************** */
                    647:                        
                    648: SignalProcessor:
                    649:                        mfspr   r10,pir                                                         /* Get our processor number */
                    650:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    651:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    652:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    653:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    654:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    655:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    656:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    657:                        mflr    r11                                                                     /* Save the link register */
                    658:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    659:                        
                    660: SiPretry:      lwarx   r5,0,r9                                                         /* Pick up the status flags (MPPICStat) and reserve it */
                    661:                        li              r3,kSIGPInterfaceBusyErr                        /* Fill dead space and get busy return code */
                    662:                        rlwinm. r0,r5,0,0,0                                                     /* Are we marked as busy? */
                    663:                        lis             r6,MPPICOnline>>16                                      /* Get the online flag */
                    664:                        bne-    ErrorReturn                                                     /* Yeah, go leave, don't bother me now... */
                    665:                        and.    r0,r5,r6                                                        /* Are we online */
                    666:                        li              r3,kMPPOffline                                          /* Set offline */
                    667:                        lis             r6,MPPICReady>>16                                       /* Get the ready bit */
                    668:                        beq-    ErrorReturn                                                     /* Ain't online, ain't ready, buzz off... */
                    669:                        and.    r0,r5,r6                                                        /* Are we ready? */
                    670:                        li              r3,kMPPNotReady                                         /* Set not ready */
                    671:                        oris    r5,r5,(MPPICBusy>>16)&0x0000FFFF        /* Turn on the busy bit */
                    672:                        beq-    ErrorReturn                                                     /* Ain't ready, buzz off... */
                    673:                        
                    674:                        stwcx.  r5,0,r9                                                         /* Try to set busy */
                    675:                        ori             r10,r10,MPPICfSigp<<8                           /* Put the SIGP function in front of the processor ID */
                    676:                        bne-    SiPretry
                    677:                        
                    678:                        stw             r4,MPPICParm0(r9)                                       /* Pass along the SIGP parameter */
                    679:                        
                    680:                        rlwimi  r5,r10,0,16,31                                          /* Put these behind the status flags */
                    681:                        b               KickAndGo                                                       /* We're done now... */
                    682: 
                    683: 
                    684: /******************************************************************************************************** */
                    685: /* */
                    686: /*                     Here we will store the state of a processor (R3=processor; R4=status area). */
                    687: /*                     Self abuse will store the state as is, is not asynchronous, and grows hair on your palms. */
                    688: /* */
                    689: /******************************************************************************************************** */
                    690:                        
                    691: StoreProcessorStatus:
                    692:                        mfspr   r10,pir                                                         /* Get our processor number */
                    693:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    694:                        cmplw   cr0,r3,r10                                                      /* Saving our own state???  Abusing oneself??? */
                    695:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    696:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    697:                        mflr    r11                                                                     /* Save the link register */
                    698:                        beq             Flagellant                                                      /* Oh baby, oh baby... */
                    699:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    700:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    701:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    702:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    703:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    704:                        
                    705: SSretry:       lwarx   r5,0,r9                                                         /* Pick up the status flags (MPPICStat) and reserve it */
                    706:                        li              r3,kSIGPInterfaceBusyErr                        /* Fill dead space and get busy return code */
                    707:                        rlwinm. r0,r5,0,0,0                                                     /* Are we marked as busy? */
                    708:                        lis             r6,MPPICOnline>>16                                      /* Get the online flag */
                    709:                        bne-    ErrorReturn                                                     /* Yeah, go leave, don't bother me now... */
                    710:                        and.    r0,r5,r6                                                        /* Are we online */
                    711:                        li              r3,kMPPOffline                                          /* Set offline */
                    712:                        beq-    ErrorReturn                                                     /* Ain't online, buzz off... */
                    713:                        oris    r5,r5,(MPPICBusy>>16)&0x0000FFFF        /* Turn on the busy bit */
                    714:                        
                    715:                        stwcx.  r5,0,r9                                                         /* Try to set busy */
                    716:                        ori             r10,r10,MPPICfStat<<8                           /* Put the store status function in front of the processor ID */
                    717:                        bne-    SSretry                                                         /* Lost reservation, return busy... */
                    718:                        
                    719:                        li              r0,0                                                            /* Get false */
                    720:                        stb             r0,CSAregsAreValid(r4)                          /* Set that the registers ain't valid */
                    721:                        stw             r4,MPPICParm0(r9)                                       /* Set the status area physical address parameter */
                    722:                        
                    723:                        rlwimi  r5,r10,0,16,31                                          /* Put these behind the status flags */
                    724:                        b               KickAndGo                                                       /* We're done now... */
                    725:                        
                    726: /*                     Spill one's seed upon the soil */
                    727: 
                    728: Flagellant:    bl              StoreStatus                                                     /* Go store off all the registers 'n' stuff */
                    729:                        mtlr    r11                                                                     /* Restore the return address */
                    730:                        li              r3,kSIGPnoErr                                           /* Return no error */
                    731:                        blr                                                                                     /* Leave... */
                    732: 
                    733: 
                    734: /******************************************************************************************************** */
                    735: /* */
                    736: /*                     Here we will attempt to syncronize clocks (R3=processor). */
                    737: /*                     Self abuse will just return with an all-ok code. */
                    738: /* */
                    739: /******************************************************************************************************** */
                    740:                        
                    741: SynchClock:
                    742:                        mfspr   r10,pir                                                         /* Get our processor number */
                    743:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    744:                        cmplw   cr0,r3,r10                                                      /* Cleaning our own clock?? */
                    745:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    746:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    747:                        li              r3,kSIGPnoErr                                           /* Assume self-cleaning clock */
                    748:                        beqlr                                                                           /* Oh baby, oh baby... */
                    749:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    750:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    751:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    752:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    753:                        mflr    r11                                                                     /* Save the link register */
                    754:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    755:                        
                    756: SyCretry:      lwarx   r5,0,r9                                                         /* Pick up the status flags (MPPICStat) and reserve it */
                    757:                        li              r3,kSIGPInterfaceBusyErr                        /* Fill dead space and get busy return code */
                    758:                        rlwinm. r0,r5,0,0,0                                                     /* Are we marked as busy? */
                    759:                        lis             r6,MPPICOnline>>16                                      /* Get the online flag */
                    760:                        bne-    ErrorReturn                                                     /* Yeah, go leave, don't bother me now... */
                    761:                        and.    r0,r5,r6                                                        /* Are we online */
                    762:                        li              r3,kMPPOffline                                          /* Set offline */
                    763:                        beq-    ErrorReturn                                                     /* Ain't online, ain't ready, buzz off... */
                    764:                        oris    r5,r5,(MPPICBusy>>16)&0x0000FFFF        /* Turn on the busy bit */
                    765:                        li              r0,0                                                            /* Clear this */
                    766:                        
                    767:                        stwcx.  r5,0,r9                                                         /* Try to set busy */
                    768:                        ori             r10,r10,MPPICfTBsy<<8                           /* Put the timebase sync function in front of the processor ID */
                    769:                        bne-    SyCretry                                                        /* Lost reservation, return busy... */
                    770: 
                    771:                        stw             r0,MPPITBsync+4-MPPIwork(r12)           /* Make sure the parm area is 0 */
                    772:                        mr              r0,r11                                                          /* Save the LR */
                    773:                        bl              SyCbase                                                         /* Get a base register */
                    774: SyCbase:       rlwimi  r5,r10,0,16,31                                          /* Put these behind the status flags */
                    775:                        mflr    r11                                                                     /* Get the base */
                    776:                        la              r11,(4*4)(r11)                                          /* DON'T MESS WITH THESE INSTRUCTIONS Make up the return point */
                    777:                        b               KickAndGo                                                       /* Go signal the other side */
                    778: 
                    779: SyCKrtrn:      mr              r11,r0                                                          /* Restore the return */
                    780: 
                    781: /* */
                    782: /*                     Start sync'ing 'er up */
                    783: /* */
                    784:                
                    785:                        mftb    r4                                                                      /* Take a timeout stamp (don't need top half, we have at least 13 hours) */
                    786: 
                    787: SyCInP0:       lwz             r5,0(r9)                                                        /* Get the CPU status word */
                    788:                        rlwinm  r5,r5,24,24,31                                          /* Isolate the command byte */
                    789:                        cmplwi  cr0,r5,MPPICfTBsy1                                      /* Have we reached time base sync phase 1 yet? */
                    790:                        beq             SyCInP1                                                         /* Yeah, we're in phase 1... */
                    791:                        mftb    r5                                                                      /* Get the bottom half of the timer again */
                    792:                        sub             r5,r5,r4                                                        /* How long we been messin' around? */
                    793:                        cmplwi  cr0,r5,1000*TicksPerMic                         /* Don't try more'n' a 1000�S */
                    794:                        blt+    SyCInP0                                                         /* We haven't, so wait some more... */
                    795:                        li              r3,kMPPTimeOut                                          /* Signal timeout */
                    796:                        b               ErrorReturn                                                     /* By dude... */
                    797:                        
                    798: /* */
                    799: /*                     Here we make sure there is enough time to sync the clocks before the lower part of the TB ticks */
                    800: /*                     up into the high part.  This eliminates the need for any funky  */
                    801: /*                     "get-the-top-then-get-the-bottom-then-get-the-top-again-to-see-if-it-changed" stuff.  That would */
                    802: /*                     only make the sync harder to do. */
                    803: /*                      */
                    804: /*                     Also, because we use the lower TB value for the signal, we also need to make sure we do not have */
                    805: /*                     a value of 0, we would be ever-so-sorry if it was. */
                    806: /* */
                    807: 
                    808: SyCInP1:       li              r4,lo16(0xC000)                                         /* Get the minimum time left on clock before tick ('bout 1 1/4 ms) */
                    809:                        li              r8,0                                                            /* Get a 0 constant */
                    810:                        
                    811: SyCdelay:      mftb    r5                                                                      /* Get the time left */
                    812:                        cmplw   cr0,r5,r4                                                       /* See if there is sufficient time before carry into high clock */
                    813:                        bgt-    SyCdelay                                                        /* Nope, hang until it is... */
                    814:                        mr.             r5,r5                                                           /* Did we just tick, however? */
                    815:                        beq-    SyCdelay                                                        /* Yeah, wait until it is at least 1... */
                    816:                        
                    817:                        mftbu   r4                                                                      /* Get the upper */
                    818:                        stw             r4,MPPITBsync-MPPIwork(r12)                     /* Make sure the top half is set */
                    819:                        sync                                                                            /* Wait until it is done */
                    820:                        
                    821:                        mftb    r5                                                                      /* Get the lower timebase now */
                    822:                        stw             r5,MPPITBsync+4-MPPIwork(r12)           /* Shove it out for the other processor */
                    823: 
                    824:                        la              r6,MPPISncFght-MPPIwork(r12)            /* Point to the courtroom area */
                    825:                        li              r5,0                                                            /* Point to the first line */
                    826: 
                    827: SyCclear:      dcbz    r5,r6                                                           /* Clear the court */
                    828:                        addi    r5,r5,32                                                        /* Point to the next line */
                    829:                        cmplwi  cr0,r5,10*2*32                                          /* Enough for 9 iterations, 2 chunks at a time */
                    830:                        blt+    SyCclear                                                        /* Clear the whole smear... */
                    831:                        sync                                                                            /* Make sure everyone's out */
                    832: 
                    833:                        mftb    r5                                                                      /* Get the lower timebase now */
                    834:                
                    835: SyCWait:       lwz             r7,MPPITBsync+4-MPPIwork(r12)           /* Get it back */
                    836:                        mftb    r6                                                                      /* Get the bottom half again */
                    837:                        mr.             r7,r7                                                           /* Have they set their clock yet? */
                    838:                        sub             r0,r6,r5                                                        /* See if we're hung up */
                    839:                        beq-    SyCdonesync                                                     /* Clock is set */
                    840:                        cmplwi  cr0,r0,1000*TicksPerMic                         /* Timeout if we spend more than 1000�S doing this */
                    841:                        blt+    SyCWait                                                         /* No timeout, wait some more... */
                    842:                        li              r3,kMPPTimeOut                                          /* Set timeout */
                    843:                        b               ErrorReturn                                                     /* Leave... */
                    844:                        
                    845: /* */
                    846: /*                     Ok, so now we have set a preliminary TB value on the second processor.  It's close, but only */
                    847: /*                     within handgranade range.   */
                    848: /* */
                    849: /*                     What we will do now is to let the processors (starting with the other guy) argue about the time for */
                    850: /*                     a while (10 passes-we use the middle 8).  We'll look at the results and try to adjust the other processor's */
                    851: /*                     time such that the timing windows are overlapping evenly. This should put the TBs close enough together */
                    852: /*                     (0-2 ticks) that the difference is undetectable. */
                    853: /* */
                    854: 
                    855: 
                    856:                        
                    857: SyCdonesync:
                    858:                        li              r4,0                                                            /* Clear this */
                    859:                        la              r5,MPPISncFght-MPPIwork(r12)            /* Point to the squared circle */
                    860: 
                    861: SyCWtArg:      
                    862:                        dcbf    0,r5                                                            /* Make sure of it */
                    863:                        sync                                                                            /* Doubly shure */
                    864:                        lwz             r6,0(r5)                                                        /* Listen for the defence argument */
                    865: 
                    866:                        mr.             r6,r6                                                           /* See if they are done */
                    867:                        beq+    SyCWtArg                                                        /* Nope, still going... */
                    868: 
                    869:                        mftb    r7                                                                      /* They're done, time for rebuttal */
                    870:                        stw             r7,32(r5)                                                       /* Make rebuttle */
                    871:        
                    872:                        addi    r4,r4,1                                                         /* Count rounds */
                    873: 
                    874:                        cmplwi  cr0,r4,10                                                       /* See if we've gone 8 rounds plus an extra one */
                    875:                        addi    r5,r5,64                                                        /* Point to the next round areas */
                    876: 
                    877:                        blt+    SyCWtArg                                                        /* Not yet, come out of your corners fighting... */
                    878:                        
                    879:                        mftb    r5                                                                      /* Stamp the wait */
                    880:                        
                    881: SyCWadj:       lwz             r7,MPPITBsync+4-MPPIwork(r12)           /* Get adjustment flag */
                    882:                        mftb    r6                                                                      /* Get timebase again */
                    883:                        
                    884:                        mr.             r7,r7                                                           /* Have they set their timebase with adjusted time yet? */
                    885:                        sub             r6,r6,r5                                                        /* Get elapsed time */
                    886:                        bne+    SyCdone                                                         /* They say it, sync done... */
                    887:                        cmplwi  cr0,r6,1000*TicksPerMic                         /* Timeout if we spend more than 1000�S doing this */
                    888:                        blt+    SyCWadj                                                         /* Still time, wait until adjustment is done... */
                    889:                        
                    890:                        li              r3,kMPPTimeOut                                          /* Set timeout */
                    891:                        b               ErrorReturn                                                     /* Pass it back... */
                    892:                        
                    893: SyCdone:       li              r3,kSIGPnoErr                                           /* No errors */
                    894:                        mtlr    r11                                                                     /* Restore LR */
                    895:                        blr                                                                                     /* Leave... */
                    896: 
                    897: 
                    898: /******************************************************************************************************** */
                    899: /* */
                    900: /*                     Here we will get the physical address of the interrupt handler. */
                    901: /* */
                    902: /******************************************************************************************************** */
                    903:                        
                    904: GetExtHandlerAddress:
                    905:                        mflr    r11                                                                     /* Save our return */
                    906:                        bl              GEXbase                                                         /* Make a base address */
                    907: GEXbase:       mflr    r3                                                                      /* Get address into our base */
                    908:                        addi    r3,r3,LOW_ADDR(GotSignal-GEXbase)       /* Get the logical address of the 'rupt handler */
                    909: 
                    910:                        mtlr    r11                                                                     /* Restore LR */
                    911:                        blr
                    912: 
                    913: 
                    914: /******************************************************************************************************** */
                    915: /* */
                    916: /*                     Here we will get a snapshot of the processor's current signaling state (R3=processor). */
                    917: /* */
                    918: /******************************************************************************************************** */
                    919:                        
                    920: ProcessorState:
                    921:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    922:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    923:                        cmplwi  cr1,r3,MPPIMaxCPU                                       /* See if we are bigger than max */
                    924:                        li              r3,kSIGPTargetAddrErr                           /* CPU number is too big */
                    925:                        bgtlr-  cr1                                                                     /* Sure are... (Get our address also) */
                    926:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    927:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    928:                        add             r9,r9,r12                                                       /* Point right at the entry */
                    929:                        lwz             r4,MPPICStat(r9)                                        /* Get the status word */
                    930:                        li              r3,kSIGPnoErr                                           /* Set no errors */
                    931:                        rlwinm. r4,r4,0,0,0                                                     /* Test for busy status */
                    932:                        beqlr                                                                           /* Return kSIGPnoErr if not busy */
                    933:                        li              r3,kSIGPInterfaceBusyErr                        /* Otherwise, return busy */
                    934:                        blr                                                                                     /* Return it */
                    935: 
                    936: /******************************************************************************************************** */
                    937: /* */
                    938: /*                     Here we will try to handle any pending messages (just as if an interruption occurred). */
                    939: /*                     The purpose of this function is to assure the message passing system runs even */
                    940: /*                     though external interrupts are disabled. Lacking a separate physical signalling */
                    941: /*                     class, we have to share the external interrupt signal. Unfortunately, there are */
                    942: /*                     times when disabled loops occur (in spin locks, in the debugger, etc.), and when they */
                    943: /*                     happen, a low level message sent to a processor will not get processed, hence this */
                    944: /*                     function exists to be called from those disabled loops. Since the calls are often */
                    945: /*                     from disabled code, all that can be done is to process any pending *message*. Any */
                    946: /*                     pending notification interruption (referred to throughtout this code as a SIGP */
                    947: /*                     interruption) must remain pending. */
                    948: /* */
                    949: /******************************************************************************************************** */
                    950:                        
                    951: RunSIGPRun:
                    952:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                    953:                        mfspr   r3,pir                                                          /* Get our CPU address */
                    954:                        rlwinm  r9,r3,5,23,26                                           /* Get index into CPU array */
                    955:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                    956:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                    957:                        mflr    r11                                                                     /* Save the link register */
                    958:                        add             r9,r9,r12                                                       /* Point right at our entry */
                    959:                        lwz             r3,MPPICPriv(r9)                                        /* Get our privates */
                    960:                        cmplw   cr1,r11,r11                                                     /* Make sure IdleWait doesn't try to clear 'rupt request */
                    961:                        oris    r3,r3,MPPICXRun>>16                                     /* Diddle with them and show we entered here */
                    962:                        stw             r3,MPPICPriv(r9)                                        /* Put away our privates */
                    963:                        b               IdleWait                                                        /* Go pretend there was an interrupt... */
                    964: 
                    965: /******************************************************************************************************** */
                    966: /* */
                    967: /*                     Error return.  We only need this when we leave with a reservation.  We really SHOULD clear it... */
                    968: /* */
                    969: /******************************************************************************************************** */
                    970: 
                    971: ErrorReturn:
                    972:                        mtlr    r11                                                                     /* Restore LR */
                    973:                        blr                                                                                     
                    974: 
                    975: /******************************************************************************************************** */
                    976: /* */
                    977: /*                     Kick the target processor.  Note that we won't set the passing bit until we are ready to exit. */
                    978: /*                     The reason for this is that we have the silly, old watchchihuahua board to deal with.  Because  */
                    979: /*                     we can't just set the interrupt and leave, we gotta wait for it to be seen on the other side. */
                    980: /*                     This means that there could be a timeout and if so, we need to back off the function request else */
                    981: /*                     we'd see busy when they tried to redrive it.  We'll have to deal with a tad of spin on the secondary side. */
                    982: /*                     note that this just applies to a primary to secondary function on the old board. */
                    983: /* */
                    984: /******************************************************************************************************** */
                    985:        
                    986: KickAndGo:
                    987:                        la              r8,MPPICPU0-MPPIwork(r12)                       /* Get the primary work area address */
                    988:                        mtlr    r11                                                                     /* Restore the link register */
                    989:                        cmplw   cr0,r8,r9                                                       /* Which is target?  primary or secondary? */
                    990:                        mfmsr   r11                                                                     /* Save off the MSR */
                    991:                        oris    r5,r5,MPPICPass>>16                                     /* Set the passing bit on */
                    992:                        stw             r5,MPPICStat(r9)                                        /* Store the pass and let the other processor go on */
                    993:                        
                    994:                        beq             KickPrimary                                                     /* The target is the primary... */
                    995:                        
                    996:                        ori             r3,r11,0x0010                                           /* Turn on DDAT bit */
                    997:                        lbz             r4,MPPIstatus-MPPIwork(r12)                     /* Load up the global status byte */
                    998:                        lwz             r8,MPPIHammer-MPPIwork(r12)                     /* Point to the Hammerhead area */
                    999:        
                   1000:                        mtmsr   r3                                                                      /* Turn on DDAT */
                   1001:                        isync
                   1002:                        
                   1003:                        andi.   r4,r4,MPPI2Pv2                                          /* Are we on the new or old board? */
                   1004:                        li              r3,0                                                            /* Set the bit for an interrupt request */
                   1005:                        beq             KickOld                                                         /* Ok, it's the old board... */
                   1006:                        
                   1007:                        sync                                                                            /* Make sure this is out there */
                   1008:                        stb             r3,IntReg(r8)                                           /* Set the interruption signal */
                   1009:                        eieio
                   1010:        
                   1011:                        mtmsr   r11                                                                     /* Set DDAT back to what it was */
                   1012:                        isync
                   1013:                        li              r3,kSIGPnoErr                                           /* Set no errors */
                   1014:                        blr                                                                                     /* Leave... */
                   1015:                        
                   1016: KickOld:       li              r4,8                                                            /* Set the number of tries */
                   1017: 
                   1018: KickAgain:     mftb    r6                                                                      /* Stamp the bottom half of time base */
                   1019:                        stb             r3,IntReg(r8)                                           /* Stick the interrupt */
                   1020:                        eieio                                                                           /* Fence me in */
                   1021:                        
                   1022: CheckKick:     lbz             r10,IntReg(r8)                                          /* Get the interrupt request back again */
                   1023:                        mr.             r10,r10                                                         /* Yes? Got it? */
                   1024:                        bne             FinalDelay                                                      /* Yeah, do the final delay and then go away... */
                   1025:                        
                   1026:                        mftb    r7                                                                      /* Get the time again */
                   1027:                        sub             r7,r7,r6                                                        /* Get time-so-far */
                   1028:                        cmplwi  cr0,r7,75*TicksPerMic                           /* Hold it for 75�S (average disable is supposed to be 100�S or so) */
                   1029:                        blt+    CheckKick                                                       /* Keep waiting the whole time... */
                   1030:                        
                   1031:                        li              r10,SecInt                                                      /* Set the deassert bit */
                   1032:                        mftb    r6                                                                      /* Stamp start of deassert time */
                   1033:                        stb             r10,IntReg(r8)                                          /* Deassert the interrupt request */
                   1034:                        eieio
                   1035:                        
                   1036: DeassertWT:    mftb    r7                                                                      /* Stamp out the time */
                   1037:                        sub             r7,r7,r6                                                        /* Get elapsed */
                   1038:                        cmplwi  cr0,r7,16*TicksPerMic                           /* Hold off 16�S (minimum is 12�S) */
                   1039:                        blt+    DeassertWT                                                      /* Keep spinning... */
                   1040:                        
                   1041:                        subi    r4,r4,1                                                         /* See if we have another retry we can do */
                   1042:                        mr.             r4,r4                                                           /* Are we there yet? */
                   1043:                        blt+    KickAgain                                                       /* Retry one more time... */
                   1044:                        
                   1045:                        rlwinm  r5,r5,0,2,31                                            /* Clear busy and passing bits */
                   1046:                        rlwinm  r5,r5,0,24,15                                           /* Clear the function request to idle */
                   1047:                        
                   1048:                        mtmsr   r11                                                                     /* Restore DDAT stuff */
                   1049:                        isync
                   1050: 
                   1051:                        stw             r5,MPPICStat(r9)                                        /* Rescind the request */
                   1052:                        li              r3,kMPPTimeOut                                          /* Set timeout */
                   1053:                        blr                                                                                     /* Leave... */
                   1054:                        
                   1055: FinalDelay:    mftb    r6                                                                      /* Stamp the start of the final delay */
                   1056: 
                   1057: FinalDelayW:
                   1058:                        mftb    r7                                                                      /* Stamp out the time */
                   1059:                        sub             r7,r7,r6                                                        /* Get elapsed */
                   1060:                        cmplwi  cr0,r7,16*TicksPerMic                           /* Hold off 16�S (minimum is 12�S) */
                   1061:                        blt+    FinalDelayW                                                     /* Keep spinning... */
                   1062: 
                   1063:                        mtmsr   r11                                                                     /* Restore DDAT stuff */
                   1064:                        isync
                   1065:                        li              r3,kSIGPnoErr                                           /* Set no errors */
                   1066:                        blr                                                                                     /* Leave... */
                   1067:                        
                   1068: KickPrimary:
                   1069:                        ori             r3,r11,0x0010                                           /* Turn on the DDAT bit */
                   1070:                        lwz             r8,MPPIEther-MPPIwork(r12)                      /* Get the address of the ethernet ROM */
                   1071:                        
                   1072:                        mtmsr   r3                                                                      /* Turn on DDAT */
                   1073:                        isync
                   1074: 
                   1075:                        li              r4,4                                                            /* Get flip count */
                   1076:                        
                   1077:                        sync                                                                            /* Make sure the status word is out there */
                   1078: 
                   1079: FlipOff:       lbz             r3,0(r8)                                                        /* Reference ethernet ROM to get chip select twiddled */
                   1080:                        eieio                                                                           /* Make sure of this (Hmm, this is chip select, not memory-mapped */
                   1081:                                                                                                                /* storage.  Do we even need the eieio?) */
                   1082:                                                                                                                
                   1083:                        addic.  r4,r4,-1                                                        /* Have we flipped them off enough? */
                   1084:                        bgt+    FlipOff                                                         /* Not yet, they deserve more... */
                   1085:                        
                   1086:                        mtmsr   r11                                                                     /* Restore DDAT stuff */
                   1087:                        isync
                   1088:                        li              r3,kSIGPnoErr                                           /* Set no errors */
                   1089:                        blr                                                                                     /* Return... */
                   1090: 
                   1091: /******************************************************************************************************** */
                   1092: /* */
                   1093: /*                     This is the code for the secondary processor */
                   1094: /* */
                   1095: /******************************************************************************************************** */
                   1096: 
                   1097: /*                     Note that none of this code needs locks because there's kind of a synchronization */
                   1098: /*                     shuffle going on. */
                   1099: 
                   1100: /* */
                   1101: /*                     First, we need to do a bit of initialization of the processor. */
                   1102: /* */
                   1103: 
                   1104: 
                   1105: CPUInit:       
                   1106:                        li              r27,0x3040                                                      /* Set floating point and machine checks on, IP to 0xFFF0xxxx */
                   1107:                        mtmsr   r27                                                                     /* Load 'em on in */
                   1108:                        isync
                   1109:                        
                   1110:                        lis             r28,-32768                                                      /* Turn on machine checks */
                   1111:                                                                                                                /* should be 0x8000 */
                   1112:                        ori             r28,r28,0xCC84                                          /* Enable caches, clear them,  */
                   1113:                                                                                                                /* disable serial execution and turn BHT on */
                   1114:                        sync
                   1115:                        mtspr   HID0,r28                                                        /* Start the cache clear */
                   1116:                        sync
                   1117: 
                   1118: /* */
                   1119: /*                     Clear out the TLB.  They be garbage after hard reset. */
                   1120: /* */
                   1121: 
                   1122:                        li              r0,512                                                          /* Get number of TLB entries (FIX THIS) */
                   1123:                        li              r3,0                                                            /* Start at 0 */
                   1124:                        mtctr   r0                                                                      /* Set the CTR */
                   1125:                        
                   1126: purgeTLB:      tlbie   r3                                                                      /* Purge this entry */
                   1127:                        addi    r3,r3,4096                                                      /* Next page */
                   1128:                        bdnz    purgeTLB                                                        /* Do 'em all... */
                   1129:                                        
                   1130:                        sync                                                                            /* Make sure all TLB purges are done */
                   1131:                        tlbsync                                                                         /* Make sure on other processors also */
                   1132:                        sync                                                                            /* Make sure the TLBSYNC is done */
                   1133: 
                   1134: /* */
                   1135: /*                     Clear out the BATs.  They are garbage after hard reset. */
                   1136: /* */
                   1137: 
                   1138:                        li              r3,0                                                            /* Clear a register */
                   1139:                        
                   1140:                        mtspr   DBAT0L,r3                                                       /* Clear BAT */
                   1141:                        mtspr   DBAT0U,r3                                                       /* Clear BAT */
                   1142:                        mtspr   DBAT1L,r3                                                       /* Clear BAT */
                   1143:                        mtspr   DBAT1U,r3                                                       /* Clear BAT */
                   1144:                        mtspr   DBAT2L,r3                                                       /* Clear BAT */
                   1145:                        mtspr   DBAT2U,r3                                                       /* Clear BAT */
                   1146:                        mtspr   DBAT3L,r3                                                       /* Clear BAT */
                   1147:                        mtspr   DBAT3U,r3                                                       /* Clear BAT */
                   1148:                        
                   1149:                        mtspr   IBAT0L,r3                                                       /* Clear BAT */
                   1150:                        mtspr   IBAT0U,r3                                                       /* Clear BAT */
                   1151:                        mtspr   IBAT1L,r3                                                       /* Clear BAT */
                   1152:                        mtspr   IBAT1U,r3                                                       /* Clear BAT */
                   1153:                        mtspr   IBAT2L,r3                                                       /* Clear BAT */
                   1154:                        mtspr   IBAT2U,r3                                                       /* Clear BAT */
                   1155:                        mtspr   IBAT3L,r3                                                       /* Clear BAT */
                   1156:                        mtspr   IBAT3U,r3                                                       /* Clear BAT */
                   1157: 
                   1158: /* */
                   1159: /*                     Map 0xF0000000 to 0xFFFFFFFF for I/O; make it R/W non-cacheable */
                   1160: /*                     Map     0x00000000 to 0x0FFFFFFF for mainstore; make it R/W cachable */
                   1161: /* */
                   1162: 
                   1163:                        lis             r6,0xF000                                                       /* Set RPN to last segment */
                   1164:                        ori             r6,r6,0x1FFF                                            /* Set up upper BAT for 256M, access both */
                   1165:                        
                   1166:                        lis             r7,0xF000                                                       /* Set RPN to last segment */
                   1167:                        ori             r7,r7,0x0032                                            /* Set up lower BAT for 256M, access both, non-cachable */
                   1168:                
                   1169:                        mtspr   DBAT0L,r7                                                       /* Setup ROM and I/O mapped areas */
                   1170:                        mtspr   DBAT0U,r6                                                       /* Now do the upper DBAT */
                   1171:                        sync
                   1172:        
                   1173:                        li              r6,0x1FFF                                                       /* Set up upper BAT for 256M, access both */
                   1174:                        li              r7,0x0012                                                       /* Set up lower BAT for r/w access */
                   1175:                        
                   1176:                        mtspr   DBAT1L,r7                                                       /* Set up an initial view of mainstore */
                   1177:                        mtspr   DBAT1U,r6                                                       /* Now do the upper DBAT */
                   1178:                        sync
                   1179: 
                   1180: /* */
                   1181: /*                     Clean up SDR and segment registers */
                   1182: /* */
                   1183: 
                   1184:                        li              r3,0                                                            /* Clear a register */
                   1185:                        mtspr   SDR1,r3                                                         /* Clear SDR1 */
                   1186:                        
                   1187:                        li              r4,0                                                            /* Clear index for segment registers */
                   1188:                        lis             r5,0x1000                                                       /* Set the segment indexer */
                   1189:                        
                   1190: clearSR:       mtsrin  r3,r4                                                           /* Zero out the SR */
                   1191:                        add.    r4,r4,r5                                                        /* Point to the next segment */
                   1192:                        bne-    clearSR                                                         /* Keep going until we wrap back to 0 */
                   1193:                        
                   1194:                        lis             r5,HIGH_ADDR(EXT(FloatInit))            /* Get top of floating point init value */
                   1195:                        ori             r5,r5,LOW_ADDR(EXT(FloatInit))          /* Slam bottom */
                   1196:                        lfd             f0,0(r5)                                                        /* Initialize FP0 */
                   1197:                        fmr             f1,f0                                                           /* Ours in not */                                       
                   1198:                        fmr             f2,f0                                                           /* to wonder why, */
                   1199:                        fmr             f3,f0                                                           /* ours is but to */
                   1200:                        fmr             f4,f0                                                           /* do or die! */
                   1201:                        fmr             f5,f0                                           
                   1202:                        fmr             f6,f0                                           
                   1203:                        fmr             f7,f0                                           
                   1204:                        fmr             f8,f0                                           
                   1205:                        fmr             f9,f0                                           
                   1206:                        fmr             f10,f0                                          
                   1207:                        fmr             f11,f0                                          
                   1208:                        fmr             f12,f0                                          
                   1209:                        fmr             f13,f0                                          
                   1210:                        fmr             f14,f0                                          
                   1211:                        fmr             f15,f0                                          
                   1212:                        fmr             f16,f0                                          
                   1213:                        fmr             f17,f0                                          
                   1214:                        fmr             f18,f0                                          
                   1215:                        fmr             f19,f0                                          
                   1216:                        fmr             f20,f0                                          
                   1217:                        fmr             f21,f0                                          
                   1218:                        fmr             f22,f0                                          
                   1219:                        fmr             f23,f0                                          
                   1220:                        fmr             f24,f0                                          
                   1221:                        fmr             f25,f0                                          
                   1222:                        fmr             f26,f0                                          
                   1223:                        fmr             f27,f0                                          
                   1224:                        fmr             f28,f0                                          
                   1225:                        fmr             f29,f0                                          
                   1226:                        fmr             f30,f0                                          
                   1227:                        fmr             f31,f0                                          
                   1228:                        
                   1229: /* */
                   1230: /*                     Whew, that was like, work, man!  What a cleaning job, I should be neater */
                   1231: /*                     when I reset. */
                   1232: /* */
                   1233: /*                     Finally we can get some data DAT turned on and we can reset the interrupt */
                   1234: /*                     (which may have been done before we get here) and get into the bring up */
                   1235: /*                     handshakes. */
                   1236: /*              */
                   1237: /*                     Note that here we need to use the actual V=R addresses for HammerHead */
                   1238: /*                     and PCI1 adr.  There are no virtual mappings set up on this processor. */
                   1239: /*                     We need to switch once the firmware is initialized.  Also, we don't know */
                   1240: /*                     where our control block is yet. */
                   1241: /* */
                   1242:                
                   1243:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                   1244:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                   1245: 
                   1246:                        mfmsr   r3                                                                      /* Get the MSR */
                   1247:                        ori             r3,r3,0x0010                                            /* Turn data DAT on */
                   1248:                        mtmsr   r3                                                                      /* DAT is on (well, almost) */
                   1249:                        isync                                                                           /* Now it is for sure */
                   1250:                
                   1251:                        lis             r8,HammerHead>>16                                       /* Point to the HammerHead controller */
                   1252:                        li              r7,SecInt                                                       /* Get value to reset */
                   1253:                        stb             r7,IntReg(r8)                                           /* Reset the interrupt */
                   1254:                        eieio                                                                           /* Fence it off */
                   1255:                
                   1256: /* */
                   1257: /*                     Now we can plant and harvest some bits. */
                   1258: /* */
                   1259:                
                   1260:                        lwz             r6,MPPIlogCPU-MPPIwork(r12)                     /* Get the logical CPU address to assign */
                   1261:                        mfspr   r7,pir                                                          /* Get the old PIR */
                   1262:                        rlwimi  r7,r6,0,27,31                                           /* Copy all of the reserved parts */
                   1263:                        mtspr   pir,r7                                                          /* Set it */
                   1264:                        
                   1265: /* */
                   1266: /*                     This little piece of code here determines if we are on the first or second version */
                   1267: /*                     of the two processor board.  The old one shouldn't ever be shipped (well, maybe by  */
                   1268: /*                     DayStar) but there are some around here. */
                   1269: /* */
                   1270: /*                     The newer version of the 2P board has a different state machine than the older one. */
                   1271: /*                     When we are in the board state we're in now, primary arbitration is turned on while */
                   1272: /*                     it is not until the next state in the old board.  By checking the our bus address */
                   1273: /*                     (WhoAmI) we can tell. */
                   1274: /* */
                   1275: 
                   1276:                        lbz             r7,WhoAmI(r8)                                           /* Get the current bus master ID */
                   1277:                        andi.   r7,r7,PriCPU                                            /* Do we think we're the primary? */
                   1278:                        beq             On2Pv1                                                          /* No, that means we're on the old 2P board */
                   1279:                        
                   1280:                        lbz             r7,MPPIstatus-MPPIwork(r12)                     /* Get the status byte */
                   1281:                        ori             r7,r7,MPPI2Pv2                                          /* Show we're on the new board */
                   1282:                        stb             r7,MPPIstatus-MPPIwork(r12)                     /* Set the board version */
                   1283:                        
                   1284: On2Pv1:                rlwinm  r9,r6,5,23,26                                           /* Get index into the CPU specific area */
                   1285:                                
                   1286:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Index to processor */
                   1287:                        add             r9,r9,r12                                                       /* Get a base for our CPU specific area */
                   1288:                        
                   1289:                        oris    r6,r6,((MPPICBusy+MPPICOnline+MPPICStop)>>16)&0x0000FFFF        /* Set CPU busy, online, stopped,  */
                   1290:                                                                                                                                                                /*   and busy set by himself */
                   1291:                        stw             r6,MPPICStat(r9)                                        /* Save the whole status word */
                   1292:                        
                   1293:                        li              r4,0x80                                                         /* Get beginnings of a CPU address mask */
                   1294:                        lhz             r11,MPPIinst-MPPIwork(r12)                      /* Get the installed and online status flags */
                   1295:                        srw             r4,r4,r6                                                        /* Make a mask */
                   1296:                        rlwimi  r4,r4,8,16,23                                           /* Double up the mask for both flags */
                   1297:                        or              r11,r11,r4                                                      /* Set that we are installed and online */
                   1298:                        sync                                                                            /* Make sure the main processor sees the rest of the stuff */
                   1299:                        
                   1300:                        sth             r11,MPPIinst-MPPIwork(r12)                      /* We're almost done, just need to set the TB */
                   1301:                        
                   1302:                        lis             r5,PCI1AdrReg>>16                                       /* Point to the PCI1 address register            */
                   1303:                        li              r4,0                                                            /* Clear this out */
                   1304:                        stw             r4,0(r5)                                                        /* Set PCI register to 0 to show we're ready for TB sync */
                   1305:                        eieio                                                                           /* Fence it off */
                   1306: 
                   1307: Wait4TB:       lwz             r7,0(r5)                                                        /* Get the PCI1 reg to see if time to set time */
                   1308:                        mr.             r7,r7                                                           /* Is it ready yet? */
                   1309:                        beq             Wait4TB                                                         /* Nope, wait for it... */
                   1310:                        isync                                                                           /* No peeking... */
                   1311:                        
                   1312:                        lwz             r3,MPPITBsync-MPPIwork(r12)                     /* Get the high word of TB */
                   1313:                        lwz             r4,MPPITBsync+4-MPPIwork(r12)           /* Get the low word */
                   1314:                        
                   1315: /*                     Note that we need no TB magic here 'cause they ain't running */
                   1316: 
                   1317:                        mttbu   r3                                                                      /* Set the high part */
                   1318:                        mttbl   r4                                                                      /* Set the low part */
                   1319:                        
                   1320:                        rlwinm  r6,r6,0,2,31                                            /* Clear the busy bit and passed */
                   1321:                        stw             r6,MPPICStat(r9)                                        /* Store the status word */
                   1322:                        
                   1323:                        sync                                                                            /* Make sure all is right with the world */
                   1324:                        
                   1325:                        li              r3,0                                                            /* Set the init done signal */
                   1326:                        stw             r3,0(r5)                                                        /* Feed the dog and let him out */
                   1327:                        sync                                                                            /* Make sure this is pushed on out */
                   1328: 
                   1329:                        li              r27,0x3040                                                      /* Make MSR the way we likes it */
                   1330:                        mtmsr   r27                                                                     /* Load 'em on in */
                   1331:                        isync
                   1332: 
                   1333: /* */
                   1334: /*                     Jump on to the idle wait loop.  We're online and ready, but we're */
                   1335: /*                     still in the reset state.  We need to wait until we see a start signal. */
                   1336: /* */
                   1337: /*                     Note that the idle loop expects R9 to be our CPU-specific work area; */
                   1338: /*                     R12 is the base of the code and global work area  */
                   1339: /* */
                   1340: 
                   1341:                        cmplw   cr1,r11,r12                                                     /* Make sure IdleWait knows to clear 'rupt request */
                   1342:                        b               IdleWait
                   1343: 
                   1344: 
                   1345: /******************************************************************************************************** */
                   1346: /******************************************************************************************************** */
                   1347: /* */
                   1348: /*                     Here is the interruption handler. */
                   1349: /* */
                   1350: /*                     What we'll do here is to get our registers into a standard state and figure out which */
                   1351: /*                     which processor we are on.  The processors have pretty much the same code.  The primary */
                   1352: /*                     will reset the the secondary to primary interruption bit and the secondary will reset the SecInt */
                   1353: /*                     flags. */
                   1354: /* */
                   1355: /*                     The primary to secondary interrupt is an exception interruption contolled by a bit in the  */
                   1356: /*                     Hammerhead IntReg.  The only bit in here is SecInt which is active low.  Writing a 0 into the */
                   1357: /*                     bit (bit 0) yanks on the external pin on the secondary.  Note that it is the only external */
                   1358: /*                     connected on the secondary.  SecInt must be set to 1 to clear the interruption.  On the old */
                   1359: /*                     2P board, asserting the external interrupt causes a watchdog timer to start which expires unless */
                   1360: /*                     the interrupt request is withdrawn. On a 180Mhz system the time to expire is about 256�S,  */
                   1361: /*                     not very long.  So, what we need to do is to time the assertion and if it has not been reset */
                   1362: /*                     reset, do it ourself.  Unfortunatelty we need to keep it deasserted for at least 12�S or the  */
                   1363: /*                     watchdog will not stop.  This leads to another problem: even if the secondary processor sees */
                   1364: /*                     the interrupt and deasserts the request itself,  we cannot reassert before the 12�S limit, */
                   1365: /*                     else havoc will be wrought.  We just gotta make sure. */
                   1366: /* */
                   1367: /*                     So, the secondary to primary interrupt is megafunky.  The mother board is wired with the  */
                   1368: /*                     MACE ethernet chip's chip-select pin wired to Grand Centeral's external interrrupt #10 pin. */
                   1369: /*                     This causes a transient interrupt whenever MACE is diddled. GC latches the interrupt into the */
                   1370: /*                     events register where we can see it and clear it. */
                   1371: /* */
                   1372: /******************************************************************************************************** */
                   1373: /******************************************************************************************************** */
                   1374: 
                   1375: GotSignal:     mfspr   r9,pir                                                          /* Get our processor ID */
                   1376:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top half of the data area */
                   1377:                        rlwinm  r9,r9,5,23,26                                           /* Clean this up */
                   1378:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get the bottom half of the data area */
                   1379:                        la              r9,EXT(MPPICPUs)-MPPIwork(r9)                   /* Point into the proccessor control area */
                   1380:                        mflr    r11                                                                     /* Save our return */
                   1381:                        add             r9,r9,r12                                                       /* Point right at the entry */
                   1382: 
                   1383: /*                     We'll come in here if we're stopped and found the 'rupt via polling */
                   1384: /*                     or we were kicked off by the PollSIGP call.  We  need */
                   1385: /*                     to wipe out the interrupt request no matter how we got here. */
                   1386: 
                   1387: SimRupt:       mfmsr   r4                                                                      /* Get the MSR */
                   1388: 
                   1389:                        la              r8,MPPICPU0-MPPIwork(r12)                       /* Get address of main processor's work area */
                   1390:                        ori             r5,r4,0x0010                                            /* Turn on the DDAT bit */
                   1391:                        cmplw   cr0,r8,r9                                                       /* Are we on the main? */
                   1392:                        cmplw   cr1,r4,r4                                                       /* Set CR1 to indicate we've cleared any 'rupts */
                   1393:                        bne             SecondarySig                                            /* Go if we are not on main processor... */
                   1394: 
                   1395: /* */
                   1396: /*                     Handle the secondary to primary signal */
                   1397: /* */
                   1398: 
                   1399: PrimarySig:
                   1400: 
                   1401:                        lwz             r8,MPPIGrandC-MPPIwork(r12)                     /* Get the address of the Grand Central area base */
                   1402:                        mtmsr   r5                                                                      /* Turn on DDAT */
                   1403:                        isync                                                                           /* Now don't be usin' dem speculative executions */
                   1404:                        li              r7,EventsReg                                            /* Get address of the interrupt events register */
                   1405:                        lwbrx   r6,r7,r8                                                        /* Grab the interruption events */
                   1406: 
                   1407:                        lis             r5,0x4000                                                       /* Get the mask for the Ext10 pin */
                   1408:                        and.    r0,r6,r5                                                        /* See if our bit is on */
                   1409:                        li              r7,ClearReg                                                     /* Point to the interruption clear register */
                   1410:                
                   1411:                        beq+    SkpClr                                                          /* Skip the clear 'cause it's supposed to be soooo slow... */
                   1412:                        
                   1413:                        stwbrx  r5,r7,r8                                                        /* Reset the interrupt latch */
                   1414:                        eieio                                                                           /* Fence off the last 'rupt */
                   1415: 
                   1416: SkpClr:                mtmsr   r4                                                                      /* Set MSR to entry state */
                   1417:                        isync                                                                           /* Make sure we ain't gunked up no future storage references */
                   1418:                
                   1419:                        bne+    IdleWait                                                        /* Go join up and decode the function... */
                   1420:                        
                   1421:                        mtlr    r11                                                                     /* Restore return address */
                   1422:                        andc.   r0,r6,r5                                                        /* Any other bits on? */
                   1423:                        li              r3,kMPVainInterrupt                                     /* Assume we got nothing */
                   1424:                        beqlr                                                                           /* We got nothing, tell 'em to eat 'rupt... */
                   1425:                        li              r3,kMPIOInterruptPending                        /* Tell them to process an I/O 'rupt */
                   1426:                        blr                                                                                     /* Ignore the interrupt... */
                   1427: 
                   1428: /* */
                   1429: /*                     Handle the primary to secondary signal */
                   1430: /* */
                   1431: 
                   1432: SecondarySig:
                   1433:                        lwz             r3,MPPICStat(r9)                                        /* Pick up our status word */
                   1434:                        lis             r8,HammerHead>>16                                       /* Get the address of the hammerhead (used during INIT on non-main processor) */
                   1435:                        rlwinm. r3,r3,0,3,3                                                     /* Check if we are already "in-the-know" (all started up) */
                   1436:                        beq-    UseAltAddr                                                      /* Nope, use hardcoded Hammerhead address */
                   1437:                        lwz             r8,MPPIHammer-MPPIwork(r12)                     /* Get the kernel's HammerHead area */
                   1438: 
                   1439: UseAltAddr:    mtmsr   r5                                                                      /* Turn on DDAT */
                   1440:                        isync                                                                           /* Now don't be usin' dem speculative executions */
                   1441:                        li              r0,SecInt                                                       /* Get the Secondary interrupt bit */
                   1442:                        stb             r0,IntReg(r8)                                           /* Reset the interrupt request */
                   1443:                        mtmsr   r4                                                                      /* Set MSR to entry state */
                   1444:                        eieio                                                                           /* Fence me in */
                   1445:                        isync                                                                           /* Make sure we ain't gunked up no future storage references */
                   1446:                        
                   1447:                        b               IdleWait                                                        /* Go decode this request... */
                   1448:                        
                   1449: /******************************************************************************************************** */
                   1450: /******************************************************************************************************** */
                   1451: /* */
                   1452: /*                     This is the idle wait.   */
                   1453: /* */
                   1454: /*                     We're stuck in here so long as we are stopped or reset. */
                   1455: /*                     All functions except for "start" pass back through here.  Start is weird because */
                   1456: /*                     it is an initial thing, i.e., we can't have gotten here via any kind of exception, */
                   1457: /*                     so there is no state to restore.  The "started" code is expected to require no know */
                   1458: /*                     state and will take care of all initialization/fixup required. */
                   1459: /* */
                   1460: /******************************************************************************************************** */
                   1461: /******************************************************************************************************** */
                   1462: 
                   1463: BadRuptState:                                                                                  /* We don't do anything special yet for a bad state, just eat request */
                   1464: KillBusy:      rlwinm  r3, r3, 0, 2, 31                                        /* Remove the message pending flags. */
                   1465:                        rlwinm  r3, r3, 0, 24, 16                                       /* Set the function to idle. */
                   1466:                        stw             r3,MPPICStat(r9)                                        /* Update/unlock the status word. */
                   1467: 
                   1468: ReenterWait: cmplwi    cr1,r9,0                                                        /* Turn off the 'rupt cleared flag */
                   1469: 
                   1470: IdleWait:      lis             r4,MPPICBusy>>16                                        /* Get busy status */
                   1471: 
                   1472: SpinIdle:                              
                   1473:                        lwz             r3,MPPICStat(r9)                                        /* Pick up our status word */
                   1474:                
                   1475:                        and.    r5,r3,r4                                                        /* Isolate the busy bit */
                   1476:                        lis             r6,MPPICPass>>16                                        /* Get the passed busy flag */
                   1477:                        bne             TooBusy                                                         /* Work, work, work, that's all we do is work... */
                   1478:                        
                   1479:                        rlwinm. r5,r3,0,4,4                                                     /* See if we are stopped */
                   1480:                        lwz             r8,MPPICPriv(r9)                                        /* Pick up our private flags */
                   1481:                        bne-    SpinIdle                                                        /* Yeah, keep spinning... */
                   1482:                        
                   1483:                        
                   1484: /* */
                   1485: /*                     Restore the state and get outta here.  Now, we shouldn't be in a reset state and not be stopped, */
                   1486: /*                     so we can go ahead and safely return up a level because it exists.  If we are reset, no state exists */
                   1487: /*                     and we should always be stopped. */
                   1488: /* */
                   1489:                        
                   1490:                        rlwinm  r4, r8, 1, 0, 0                                         /* Get the explicit run bit, shifted left one. */
                   1491:                        rlwinm. r5, r8, 0, 0, 0                                         /* See if there is a SIGP signal pending */
                   1492:                        and             r4, r8, r4                                                      /* Turn off the SIGP pending bit if this was not an explicit run */
                   1493:                                                                                                                /* Also the explicit run bit is cleared */
                   1494:                        mtlr    r11                                                                     /* Restore the return point */
                   1495:                        li              r3,kMPVainInterrupt                                     /* Tell the interrupt handler to ignore the interrupt */
                   1496:                        stw             r4,MPPICPriv(r9)                                        /* Set that flag back for later */
                   1497:                        beqlr                                                                           /* Time to leave if we ate the 'rupt... */
                   1498: 
                   1499:                        li              r3,kMPSignalPending                                     /* Set that there is a SIGP interruption pending */
                   1500:                        
                   1501:                        blr                                                                                     /* Go away, let our caller handle this thing... QED!!!!!!!!! */
                   1502: 
                   1503: /* */
                   1504: /*           QQQQQ       EEEEEEEEEE    DDDDDDDDD */
                   1505: /*         QQQQQQQQQ     EEEEEEEEEE    DDDDDDDDDDD */
                   1506: /*        QQQQ   QQQQ    EEEE          DDD     DDD */
                   1507: /*       QQQQ     QQQQ   EEEEEEEEEE    DDD     DDD */
                   1508: /*       QQQQ   Q QQQQ   EEEEEEEEEE    DDD     DDD */
                   1509: /*        QQQQ  QQQQQ    EEEE          DDD     DDD */
                   1510: /*         QQQQQQQQQQQ   EEEEEEEEEE    DDDDDDDDDDD */
                   1511: /*           QQQQQ QQQ   EEEEEEEEEE    DDDDDDDDD */
                   1512: /* */
                   1513: /*                     (I finished here) */
                   1514: /* */
                   1515: 
                   1516:                        
                   1517: /* */
                   1518: /*                     This is where we decode the function and do what's right. */
                   1519: /*                     First we need to check if it's really time to do something. */
                   1520: /* */
                   1521: 
                   1522: TooBusy:       and.    r5,r3,r6                                                        /* See if the passed flag is on */
                   1523:                        beq             SpinIdle                                                        /* No, not yet, try the whole smear again... */
                   1524:                        
                   1525:                        beq+    cr1,KeepRupt                                            /* Don't clear 'rupt if we already did (or entered via RunSIGRun) */
                   1526: 
                   1527:                        lwz             r5,MPPICPriv(r9)                                        /* Get the private flags */
                   1528:                        rlwinm. r5, r5, 0, 1, 1                                         /* Did we enter via RunSIGPRun? */
                   1529:                        beq             SimRupt                                                         /* Nope, 's'ok, go clear physical 'rupt... */
                   1530:                        
                   1531: KeepRupt:
                   1532:                        bl              GetOurBase                                                      /* Get our address */
                   1533: GetOurBase:    rlwinm  r4,r3,26,22,29                                          /* Get the opcode index * 4 */
                   1534:                        mflr    r12                                                                     /* Get the base address */
                   1535:                        la              r7,LOW_ADDR(IFuncTable-GetOurBase)(r12)         /* Point to the function table */
                   1536:                        
                   1537:                        cmplwi  cr0,r4,7*4                                                      /* See if they sent us some bogus junk */
                   1538:                                                                                                                /* Change 7 if we add more functions */
                   1539:                        add             r7,r7,r4                                                        /* Point right at the entry */
                   1540:                        bgt-    KillBusy                                                        /* Bad request code, reset busy and eat it... */
                   1541:                        
                   1542:                        mtlr    r7                                                                      /* Set up the LR */
                   1543:                        
                   1544:                        blr                                                                                     /* Go execute the function... */
                   1545:        
                   1546: IFuncTable:
                   1547:                        b               KillBusy                                                        /* This handles the signal in vain... */
                   1548:                        b               IStart                                                          /* This handles the start function */
                   1549:                        b               IResume                                                         /* This handles the resume function */
                   1550:                        b               IStop                                                           /* This handles the stop function */
                   1551:                        b               ISIGP                                                           /* This handles the SIGP function */
                   1552:                        b               IStatus                                                         /* This handles the store status function */
                   1553:                        b               ITBsync                                                         /* This handles the synchronize timer base function */
                   1554:                        b               IReset                                                          /* This handles the reset function */
                   1555: 
                   1556: /******************************************************************************************************** */
                   1557: /******************************************************************************************************** */
                   1558: /* */
                   1559: /*                     Here are the functions handled at interrupt time */
                   1560: /* */
                   1561: /******************************************************************************************************** */
                   1562: /******************************************************************************************************** */
                   1563: 
                   1564: /******************************************************************************************************** */
                   1565: /* */
                   1566: /*                     The Start function.  This guy requires that the processor be in the reset and online state. */
                   1567: /* */
                   1568: /******************************************************************************************************** */
                   1569: 
                   1570: IStart:                lis             r4,MPPICOnline>>16                                      /* Get bits required to be on */
                   1571:                        isync                                                                           /* Make sure we haven't gone past here */
                   1572:                        and             r6,r3,r4                                                        /* See if they are on */
                   1573:                        cmplw   cr1,r6,r4                                                       /* Are they all on? */
                   1574:                        lwz             r4,MPPICParm0(r9)                                       /* Get the physical address of the code to go to */
                   1575:                        bne-    cr1,BadRuptState                                        /* Some required state bits are off */
                   1576:                        rlwinm  r3,r3,0,2,31                                            /* Kill the busy bits */
                   1577:                        rlwinm  r3,r3,0,24,15                                           /* Set the function to idle */
                   1578:                        oris    r3,r3,MPPICReady>>16                            /* Set ready state */
                   1579:                        rlwinm  r3,r3,0,5,3                                                     /* Clear out the stop bit */
                   1580:                        mtlr    r4                                                                      /* Set the LR */
                   1581:                        stw             r3,MPPICStat(r9)                                        /* Clear out the status flags */
                   1582:                        lwz             r3,MPPICParm2(r9)                                       /* Get pass-thru parameter */
                   1583:                        blrl                                                                            /* Start up the code... */
                   1584: /* */
                   1585: /*                     The rules for coming back here via BLR are just opposite the normal way:  you can trash R0-R3 and */
                   1586: /*                     R13-R31, all the CRs; don't touch SPRG1 or SPRG3, the MSR, the SRs or BATs 0 and 1. */
                   1587: /*                     Follow these simple rules and you allowed back; don't follow them and die. */
                   1588: /*                     We only come back here if there is some kind of startup failure so's we can try again later */
                   1589: /* */
                   1590: 
                   1591:                        lwz             r3,MPPICStat(r9)                                        /* Get back the status word */
                   1592:                        cmplw   cr1,r4,r4                                                       /* Show that we have already taken care of the 'rupt */
                   1593:                        rlwinm  r3,r3,0,4,2                                                     /* Reset the ready bit */
                   1594:                        b               KillBusy                                                        /* Back into the fold... */
                   1595: 
                   1596: /******************************************************************************************************** */
                   1597: /* */
                   1598: /*                     The Resume function.  This guy requires that the processor be online and ready. */
                   1599: /* */
                   1600: /******************************************************************************************************** */
                   1601: 
                   1602: IResume:       lis             r4,(MPPICOnline+MPPICReady)>>16         /* Get states required to be set */
                   1603:                        and             r6,r3,r4                                                        /* See if they are on */
                   1604:                        cmplw   cr0,r6,r4                                                       /* Are they all on? */
                   1605:                        bne-    BadRuptState                                            /* Some required off state bits are on */
                   1606:                        rlwinm  r3,r3,0,5,3                                                     /* Clear out the stop bit */
                   1607:                        b               KillBusy                                                        /* Get going... */
                   1608: 
                   1609: /******************************************************************************************************** */
                   1610: /* */
                   1611: /*                     The Stop function.  All we care about here is that the guy is online. */
                   1612: /* */
                   1613: /******************************************************************************************************** */
                   1614: 
                   1615: IStop:         lis             r4,MPPICOnline>>16                                      /* All we care about is if we are online or not */
                   1616:                        and.    r6,r3,r4                                                        /* See if we are online */
                   1617:                        beq-    BadRuptState                                            /* Some required off state bits are on */
                   1618:                        oris    r3,r3,MPPICStop>>16                                     /* Set the stop bit */
                   1619:                        b               KillBusy                                                        /* Get stopped... */
                   1620: 
                   1621: 
                   1622: /******************************************************************************************************** */
                   1623: /* */
                   1624: /*                     The SIGP function.  All we care about here is that the guy is online. */
                   1625: /* */
                   1626: /******************************************************************************************************** */
                   1627: 
                   1628: ISIGP:         lis             r4,(MPPICOnline+MPPICReady)>>16         /* Get states required to be set */
                   1629:                        and             r6,r3,r4                                                        /* See if they are on */
                   1630:                        lwz             r7,MPPICPriv(r9)                                        /* Get the private flags */
                   1631:                        cmplw   cr0,r6,r4                                                       /* Are they all on? */
                   1632:                        oris    r6,r7,(MPPICSigp>>16)&0x0000FFFF        /* Set the SIGP pending bit */
                   1633:                        bne-    BadRuptState                                            /* Some required off state bits are on */
                   1634:                        lwz             r4,MPPICParm0(r9)                                       /* Get the SIGP parameter */
                   1635:                        stw             r6,MPPICPriv(r9)                                        /* Stick the pending bit back */
                   1636:                        stw             r4,MPPICParm0BU(r9)                                     /* Back up parm 0 so it is safe once we unlock */
                   1637:                        b               KillBusy                                                        /* Get stopped... */
                   1638: 
                   1639: /******************************************************************************************************** */
                   1640: /* */
                   1641: /*                     The store status function.  This guy requires that the processor be in the stopped state. */
                   1642: /* */
                   1643: /******************************************************************************************************** */
                   1644: 
                   1645: IStatus:       lis             r4,MPPICOnline>>16                                      /* All we care about is if we are online or not */
                   1646:                        and.    r6,r3,r4                                                        /* See if we are online */
                   1647:                        isync                                                                           /* Make sure we havn't gone past here */
                   1648:                        beq-    BadRuptState                                            /* Some required off state bits are on */
                   1649:                        lwz             r4,MPPICParm0(r9)                                       /* Get the status area physical address */
                   1650:                        rlwinm. r6,r3,0,3,3                                                     /* Test processor ready */
                   1651:                        
                   1652:                        beq             INotReady                                                       /* Not ready, don't assume valid exception save area */
                   1653:                        bl              StoreStatus                                                     /* Go store off all the registers 'n' stuff */
                   1654:                        b               KillBusy                                                        /* All done... */
                   1655:                        
                   1656: INotReady:
                   1657:                        lis             r7,0xDEAD                                                       /* Get 0xDEAD + 1 */
                   1658:                        ori             r7,r7,0xF1D0                                            /* Get 0xDEADF1D0 */
                   1659:                        stw             r7,CSAgpr+(0*4)(r4)                                     /* Store invalid R0 */
                   1660:                        stw             r7,CSAgpr+(1*4)(r4)                                     /* Store invalid R1 */
                   1661:                        stw             r7,CSAgpr+(2*4)(r4)                                     /* Store invalid R2 */
                   1662:                        stw             r7,CSAgpr+(3*4)(r4)                                     /* Store invalid R3 */
                   1663:                        stw             r7,CSAgpr+(4*4)(r4)                                     /* Store invalid R4 */
                   1664:                        stw             r7,CSAgpr+(5*4)(r4)                                     /* Store invalid R5 */
                   1665:                        stw             r7,CSAgpr+(6*4)(r4)                                     /* Store invalid R6 */
                   1666:                        stw             r7,CSAgpr+(7*4)(r4)                                     /* Store invalid R7 */
                   1667:                        stw             r7,CSAgpr+(8*4)(r4)                                     /* Store invalid R8 */
                   1668:                        stw             r7,CSAgpr+(9*4)(r4)                                     /* Store invalid R9 */
                   1669:                        stw             r7,CSAgpr+(10*4)(r4)                            /* Store invalid R10 */
                   1670:                        stw             r7,CSAgpr+(11*4)(r4)                            /* Store invalid R11 */
                   1671:                        stw             r7,CSAgpr+(12*4)(r4)                            /* Store invalid R12 */
                   1672:                        stw             r13,CSAgpr+(13*4)(r4)                           /* Save general registers */
                   1673:                        stw             r14,CSAgpr+(14*4)(r4)                           /* Save general registers */
                   1674:                        stw             r15,CSAgpr+(15*4)(r4)                           /* Save general registers */
                   1675:                        stw             r16,CSAgpr+(16*4)(r4)                           /* Save general registers */
                   1676:                        stw             r17,CSAgpr+(17*4)(r4)                           /* Save general registers */
                   1677:                        stw             r18,CSAgpr+(18*4)(r4)                           /* Save general registers */
                   1678:                        stw             r19,CSAgpr+(19*4)(r4)                           /* Save general registers */
                   1679:                        stw             r20,CSAgpr+(20*4)(r4)                           /* Save general registers */
                   1680:                        stw             r21,CSAgpr+(21*4)(r4)                           /* Save general registers */
                   1681:                        stw             r22,CSAgpr+(22*4)(r4)                           /* Save general registers */
                   1682:                        stw             r23,CSAgpr+(23*4)(r4)                           /* Save general registers */
                   1683:                        stw             r24,CSAgpr+(24*4)(r4)                           /* Save general registers */
                   1684:                        stw             r25,CSAgpr+(25*4)(r4)                           /* Save general registers */
                   1685:                        stw             r26,CSAgpr+(26*4)(r4)                           /* Save general registers */
                   1686:                        stw             r27,CSAgpr+(27*4)(r4)                           /* Save general registers */
                   1687:                        stw             r28,CSAgpr+(28*4)(r4)                           /* Save general registers */
                   1688:                        stw             r29,CSAgpr+(29*4)(r4)                           /* Save general registers */
                   1689:                        stw             r30,CSAgpr+(30*4)(r4)                           /* Save general registers */
                   1690:                        stw             r31,CSAgpr+(31*4)(r4)                           /* Save general registers */
                   1691:                        bl              StoreLiveStatus
                   1692:                        b               KillBusy
                   1693: 
                   1694: /* */
                   1695: /*                     Save the whole status.  Lot's of busy work. */
                   1696: /*                     Anything marked unclean is of the devil and should be shunned.  Actually, it depends upon  */
                   1697: /*                     knowledge of firmware control areas and is no good for a plug in.  But, we've sacrificed the */
                   1698: /*                     white ram and are standing within a circle made of his skin, so we can dance with the devil */
                   1699: /*                     safely. */
                   1700: /* */
                   1701: 
                   1702: StoreStatus:
                   1703:                        mfspr   r10,sprg0                                                       /* Get the pointer to the exception save area (unclean) */
                   1704:                        
                   1705:                        lwz             r5,saver0(r13)                                          /* Get R0 (unclean) */
                   1706:                        lwz             r6,saver1(r13)                                          /* Get R1 (unclean) */
                   1707:                        lwz             r7,saver2(r13)                                          /* Get R2 (unclean) */
                   1708:                        stw             r5,CSAgpr+(0*4)(r4)                                     /* Save R0 */
                   1709:                        stw             r6,CSAgpr+(1*4)(r4)                                     /* Save R1 */
                   1710:                        stw             r7,CSAgpr+(2*4)(r4)                                     /* Save R2 */
                   1711:                        lwz             r5,saver3(r13)                                          /* Get R3 (unclean) */
                   1712:                        lwz             r6,saver4(r13)                                          /* Get R4 (unclean) */
                   1713:                        lwz             r7,saver5(r13)                                          /* Get R5 (unclean) */
                   1714:                        stw             r5,CSAgpr+(3*4)(r4)                                     /* Save R3 */
                   1715:                        stw             r6,CSAgpr+(4*4)(r4)                                     /* Save R4 */
                   1716:                        stw             r7,CSAgpr+(5*4)(r4)                                     /* Save R5 */
                   1717:                        lwz             r5,saver6(r13)                                          /* Get R6 (unclean) */
                   1718:                        lwz             r6,saver7(r13)                                          /* Get R7 (unclean) */
                   1719:                        lwz             r7,saver8(r13)                                          /* Get R8 (unclean) */
                   1720:                        stw             r5,CSAgpr+(6*4)(r4)                                     /* Save R6 */
                   1721:                        stw             r6,CSAgpr+(7*4)(r4)                                     /* Save R7 */
                   1722:                        stw             r7,CSAgpr+(8*4)(r4)                                     /* Save R8 */
                   1723:                        lwz             r5,saver9(r13)                                          /* Get R9 (unclean) */
                   1724:                        lwz             r6,saver10(r13)                                         /* Get R10 (unclean) */
                   1725:                        lwz             r7,saver11(r13)                                         /* Get R11 (unclean) */
                   1726:                        stw             r5,CSAgpr+(9*4)(r4)                                     /* Save R9 */
                   1727:                        stw             r6,CSAgpr+(10*4)(r4)                            /* Save R10 */
                   1728:                        lwz             r5,saver12(r13)                                         /* Get R12 (unclean) */
                   1729:                        stw             r7,CSAgpr+(11*4)(r4)                            /* Save R11 */
                   1730:                        stw             r5,CSAgpr+(12*4)(r4)                            /* Save R12 */
                   1731:                        
                   1732:                        lwz             r5,saver13(r13)                                         /* Get R13 (unclean) */
                   1733:                        lwz             r6,saver14(r13)                                         /* Get R14 (unclean) */
                   1734:                        lwz             r7,saver15(r13)                                         /* Get R15 (unclean) */
                   1735:                        stw             r5,CSAgpr+(13*4)(r4)                            /* Save R13 */
                   1736:                        stw             r6,CSAgpr+(14*4)(r4)                            /* Save R14 */
                   1737:                        stw             r7,CSAgpr+(15*4)(r4)                            /* Save R15 */
                   1738:                        lwz             r5,saver16(r13)                                         /* Get R16 (unclean) */
                   1739:                        lwz             r6,saver17(r13)                                         /* Get R17 (unclean) */
                   1740:                        lwz             r7,saver18(r13)                                         /* Get R18 (unclean) */
                   1741:                        stw             r5,CSAgpr+(16*4)(r4)                            /* Save R16 */
                   1742:                        stw             r6,CSAgpr+(17*4)(r4)                            /* Save R17 */
                   1743:                        stw             r7,CSAgpr+(18*4)(r4)                            /* Save R18 */
                   1744:                        lwz             r5,saver19(r13)                                         /* Get R19 (unclean) */
                   1745:                        lwz             r6,saver20(r13)                                         /* Get R20 (unclean) */
                   1746:                        lwz             r7,saver21(r13)                                         /* Get R21 (unclean) */
                   1747:                        stw             r5,CSAgpr+(19*4)(r4)                            /* Save R19 */
                   1748:                        stw             r6,CSAgpr+(20*4)(r4)                            /* Save R20 */
                   1749:                        stw             r7,CSAgpr+(21*4)(r4)                            /* Save R21 */
                   1750:                        lwz             r5,saver22(r13)                                         /* Get R22 (unclean) */
                   1751:                        lwz             r6,saver23(r13)                                         /* Get R23 (unclean) */
                   1752:                        lwz             r7,saver24(r13)                                         /* Get R24 (unclean) */
                   1753:                        stw             r5,CSAgpr+(22*4)(r4)                            /* Save R22 */
                   1754:                        stw             r6,CSAgpr+(23*4)(r4)                            /* Save R23*/
                   1755:                        stw             r7,CSAgpr+(24*4)(r4)                            /* Save R24 */
                   1756:                        lwz             r5,saver25(r13)                                         /* Get R25 (unclean) */
                   1757:                        lwz             r6,saver26(r13)                                         /* Get R26 (unclean) */
                   1758:                        lwz             r7,saver27(r13)                                         /* Get R27 (unclean) */
                   1759:                        stw             r5,CSAgpr+(25*4)(r4)                            /* Save R25 */
                   1760:                        stw             r6,CSAgpr+(26*4)(r4)                            /* Save R26 */
                   1761:                        stw             r7,CSAgpr+(27*4)(r4)                            /* Save R27 */
                   1762: 
                   1763:                        lwz             r5,saver28(r13)                                         /* Get R28 (unclean) */
                   1764:                        lwz             r6,saver29(r13)                                         /* Get R29 (unclean) */
                   1765:                        lwz             r7,saver30(r13)                                         /* Get R30 (unclean) */
                   1766:                        stw             r5,CSAgpr+(28*4)(r4)                            /* Save R28 */
                   1767:                        lwz             r5,saver31(r13)                                         /* Get R31(unclean) */
                   1768:                        stw             r6,CSAgpr+(29*4)(r4)                            /* Save R29 */
                   1769:                        stw             r7,CSAgpr+(30*4)(r4)                            /* Save R30 */
                   1770:                        stw             r5,CSAgpr+(31*4)(r4)                            /* Save R31 */
                   1771: 
                   1772: StoreLiveStatus:
                   1773:                        mfmsr   r5                                                                      /* Get the current MSR */
                   1774:                        ori             r6,r5,0x2000                                            /* Turn on floating point instructions */
                   1775:                        mtmsr   r6                                                                      /* Turn them on */
                   1776:                        isync                                                                           /* Make sure they're on */
                   1777:                        
                   1778:                        stfd    f0,CSAfpr+(0*8)(r4)                                     /* Save floating point registers */
                   1779:                        stfd    f1,CSAfpr+(1*8)(r4)                                     /* Save floating point registers */
                   1780:                        stfd    f2,CSAfpr+(2*8)(r4)                                     /* Save floating point registers */
                   1781:                        stfd    f3,CSAfpr+(3*8)(r4)                                     /* Save floating point registers */
                   1782:                        stfd    f4,CSAfpr+(4*8)(r4)                                     /* Save floating point registers */
                   1783:                        stfd    f5,CSAfpr+(5*8)(r4)                                     /* Save floating point registers */
                   1784:                        stfd    f6,CSAfpr+(6*8)(r4)                                     /* Save floating point registers */
                   1785:                        stfd    f7,CSAfpr+(7*8)(r4)                                     /* Save floating point registers */
                   1786:                        stfd    f8,CSAfpr+(8*8)(r4)                                     /* Save floating point registers */
                   1787:                        stfd    f9,CSAfpr+(9*8)(r4)                                     /* Save floating point registers */
                   1788:                        stfd    f10,CSAfpr+(10*8)(r4)                           /* Save floating point registers */
                   1789:                        stfd    f11,CSAfpr+(11*8)(r4)                           /* Save floating point registers */
                   1790:                        stfd    f12,CSAfpr+(12*8)(r4)                           /* Save floating point registers */
                   1791:                        stfd    f13,CSAfpr+(13*8)(r4)                           /* Save floating point registers */
                   1792:                        stfd    f14,CSAfpr+(14*8)(r4)                           /* Save floating point registers */
                   1793:                        stfd    f15,CSAfpr+(15*8)(r4)                           /* Save floating point registers */
                   1794:                        stfd    f16,CSAfpr+(16*8)(r4)                           /* Save floating point registers */
                   1795:                        stfd    f17,CSAfpr+(17*8)(r4)                           /* Save floating point registers */
                   1796:                        stfd    f18,CSAfpr+(18*8)(r4)                           /* Save floating point registers */
                   1797:                        stfd    f19,CSAfpr+(19*8)(r4)                           /* Save floating point registers */
                   1798:                        stfd    f20,CSAfpr+(20*8)(r4)                           /* Save floating point registers */
                   1799:                        stfd    f21,CSAfpr+(21*8)(r4)                           /* Save floating point registers */
                   1800:                        stfd    f22,CSAfpr+(22*8)(r4)                           /* Save floating point registers */
                   1801:                        stfd    f23,CSAfpr+(23*8)(r4)                           /* Save floating point registers */
                   1802:                        stfd    f24,CSAfpr+(24*8)(r4)                           /* Save floating point registers */
                   1803:                        stfd    f25,CSAfpr+(25*8)(r4)                           /* Save floating point registers */
                   1804:                        stfd    f26,CSAfpr+(26*8)(r4)                           /* Save floating point registers */
                   1805:                        stfd    f27,CSAfpr+(27*8)(r4)                           /* Save floating point registers */
                   1806:                        stfd    f28,CSAfpr+(28*8)(r4)                           /* Save floating point registers */
                   1807:                        stfd    f29,CSAfpr+(29*8)(r4)                           /* Save floating point registers */
                   1808:                        stfd    f30,CSAfpr+(30*8)(r4)                           /* Save floating point registers */
                   1809:                        stfd    f31,CSAfpr+(31*8)(r4)                           /* Save floating point registers */
                   1810:                        
                   1811:                        mffs    f1                                                                      /* Get the FPSCR */
                   1812:                        stfd    f1,CSAfpscr-4(r4)                                       /* Save the whole thing (we'll overlay the first half with CR later) */
                   1813:                        
                   1814:                        lfd             f1,CSAfpr+(1*4)(r4)                                     /* Restore F1 */
                   1815:                        
                   1816:                        mtmsr   r5                                                                      /* Put the floating point back to what it was before */
                   1817:                        isync                                                                           /* Wait for it */
                   1818:                        
                   1819:                        lwz             r6,savecr(r13)                                          /* Get the old CR (unclean) */
                   1820:                        stw             r6,CSAcr(r4)                                            /* Save the CR */
                   1821:                        
                   1822:                        mfxer   r6                                                                      /* Get the XER */
                   1823:                        stw             r6,CSAxer(r4)                                           /* Save the XER */
                   1824:                        
                   1825:                        lwz             r6,savelr(r13)                                          /* Get the old LR (unclean) */
                   1826:                        stw             r6,CSAlr(r4)                                            /* Save the LR */
                   1827:                        
                   1828:                        mfctr   r6                                                                      /* Get the CTR */
                   1829:                        stw             r6,CSActr(r4)                                           /* Save the CTR */
                   1830:                        
                   1831: STtbase:       mftbu   r5                                                                      /* Get the upper timebase */
                   1832:                        mftb    r6                                                                      /* Get the lower */
                   1833:                        mftbu   r7                                                                      /* Get the top again */
                   1834:                        cmplw   cr0,r5,r7                                                       /* Did it tick? */
                   1835:                        bne-    STtbase                                                         /* Yeah, do it again... */
                   1836:                        
                   1837:                        mfdec   r7                                                                      /* Get the decrimenter (make it at about the same time as the TB) */
                   1838:                        stw             r7,CSAdec(r4)                                           /* Save the decrimenter */
                   1839:                        
                   1840:                        
                   1841:                        stw             r5,CSAtbu(r4)                                           /* Stash the top part */
                   1842:                        stw             r6,CSAtbl(r4)                                           /* Stash the lower part */
                   1843:                        
                   1844:                        lwz             r5,savesrr1(r13)                                        /* SRR1 at exception is as close as we get to the MSR (unclean) */
                   1845:                        lwz             r6,savesrr0(r13)                                        /* Get SRR0 also */
                   1846:                        stw             r5,CSAmsr(r4)                                           /* Save the MSR */
                   1847:                        stw             r6,CSApc(r4)                                            /* Save the PC */
                   1848:                        stw             r5,CSAsrr1(r4)                                          /* Set SRR1 also */
                   1849:                        stw             r6,CSAsrr0(r4)                                          /* Save SRR0 */
                   1850:                        
                   1851:                        mfpvr   r5                                                                      /* Get the PVR */
                   1852:                        stw             r5,CSApvr(r4)                                           /* Save the PVR */
                   1853:                        
                   1854:                        mfspr   r5,pir                                                          /* Get the PIR */
                   1855:                        stw             r5,CSApir(r4)                                           /* Save the PIR */
                   1856:                        
                   1857:                        mfspr   r5,ibat0u                                                       /* Get the upper IBAT0 */
                   1858:                        mfspr   r6,ibat0l                                                       /* Get the lower IBAT0 */
                   1859:                        stw             r5,CSAibat+(0*8+0)(r4)                          /* Save the upper IBAT0 */
                   1860:                        stw             r6,CSAibat+(0*8+4)(r4)                          /* Save the upper IBAT0 */
                   1861: 
                   1862:                        mfspr   r5,ibat1u                                                       /* Get the upper IBAT1 */
                   1863:                        mfspr   r6,ibat1l                                                       /* Get the lower IBAT1 */
                   1864:                        stw             r5,CSAibat+(1*8+0)(r4)                          /* Save the upper IBAT1 */
                   1865:                        stw             r6,CSAibat+(1*8+4)(r4)                          /* Save the upper IBAT1 */
                   1866: 
                   1867:                        mfspr   r5,ibat2u                                                       /* Get the upper IBAT2 */
                   1868:                        mfspr   r6,ibat2l                                                       /* Get the lower IBAT2 */
                   1869:                        stw             r5,CSAibat+(2*8+0)(r4)                          /* Save the upper IBAT2 */
                   1870:                        stw             r6,CSAibat+(2*8+4)(r4)                          /* Save the upper IBAT2 */
                   1871: 
                   1872:                        mfspr   r5,ibat3u                                                       /* Get the upper IBAT3 */
                   1873:                        mfspr   r6,ibat3l                                                       /* Get the lower IBAT3 */
                   1874:                        stw             r5,CSAibat+(3*8+0)(r4)                          /* Save the upper IBAT3 */
                   1875:                        stw             r6,CSAibat+(3*8+4)(r4)                          /* Save the upper IBAT3 */
                   1876: 
                   1877:                        mfspr   r5,dbat0u                                                       /* Get the upper DBAT0 */
                   1878:                        mfspr   r6,dbat0l                                                       /* Get the lower DBAT0 */
                   1879:                        stw             r5,CSAdbat+(0*8+0)(r4)                          /* Save the upper DBAT0 */
                   1880:                        stw             r6,CSAdbat+(0*8+4)(r4)                          /* Save the upper DBAT0 */
                   1881: 
                   1882:                        mfspr   r5,dbat1u                                                       /* Get the upper DBAT1 */
                   1883:                        mfspr   r6,dbat1l                                                       /* Get the lower DBAT1 */
                   1884:                        stw             r5,CSAdbat+(1*8+0)(r4)                          /* Save the upper DBAT1 */
                   1885:                        stw             r6,CSAdbat+(1*8+4)(r4)                          /* Save the upper DBAT1 */
                   1886: 
                   1887:                        mfspr   r5,dbat2u                                                       /* Get the upper DBAT2 */
                   1888:                        mfspr   r6,dbat2l                                                       /* Get the lower DBAT2 */
                   1889:                        stw             r5,CSAdbat+(2*8+0)(r4)                          /* Save the upper DBAT2 */
                   1890:                        stw             r6,CSAdbat+(2*8+4)(r4)                          /* Save the upper DBAT2 */
                   1891: 
                   1892:                        mfspr   r5,dbat3u                                                       /* Get the upper DBAT3 */
                   1893:                        mfspr   r6,dbat3l                                                       /* Get the lower DBAT3 */
                   1894:                        stw             r5,CSAdbat+(3*8+0)(r4)                          /* Save the upper DBAT3 */
                   1895:                        stw             r6,CSAdbat+(3*8+4)(r4)                          /* Save the upper DBAT3 */
                   1896:                        
                   1897:                        mfsdr1  r5                                                                      /* Get the SDR1 */
                   1898:                        stw             r5,CSAsdr1(r4)                                          /* Save the SDR1 */
                   1899:                        
                   1900:                        mfsr    r5,sr0                                                          /* Get SR 0 */
                   1901:                        mfsr    r6,sr1                                                          /* Get SR 1 */
                   1902:                        mfsr    r7,sr2                                                          /* Get SR 2 */
                   1903:                        stw             r5,CSAsr+(0*4)(r4)                                      /* Save SR 0 */
                   1904:                        stw             r6,CSAsr+(1*4)(r4)                                      /* Save SR 1 */
                   1905:                        mfsr    r5,sr3                                                          /* Get SR 3 */
                   1906:                        mfsr    r6,sr4                                                          /* Get SR 4 */
                   1907:                        stw             r7,CSAsr+(2*4)(r4)                                      /* Save SR 2 */
                   1908:                        mfsr    r7,sr5                                                          /* Get SR 5 */
                   1909:                        stw             r5,CSAsr+(3*4)(r4)                                      /* Save SR 3 */
                   1910:                        stw             r6,CSAsr+(4*4)(r4)                                      /* Save SR 4 */
                   1911:                        mfsr    r5,sr6                                                          /* Get SR 6 */
                   1912:                        mfsr    r6,sr7                                                          /* Get SR 7 */
                   1913:                        stw             r7,CSAsr+(5*4)(r4)                                      /* Save SR 5 */
                   1914:                        mfsr    r7,sr8                                                          /* Get SR 8 */
                   1915:                        stw             r5,CSAsr+(6*4)(r4)                                      /* Save SR 6 */
                   1916:                        stw             r6,CSAsr+(7*4)(r4)                                      /* Save SR 7 */
                   1917:                        mfsr    r5,sr9                                                          /* Get SR 9 */
                   1918:                        mfsr    r6,sr10                                                         /* Get SR 11 */
                   1919:                        stw             r7,CSAsr+(8*4)(r4)                                      /* Save SR 8 */
                   1920:                        mfsr    r7,sr11                                                         /* Get SR 11 */
                   1921:                        stw             r5,CSAsr+(9*4)(r4)                                      /* Save SR 9 */
                   1922:                        stw             r6,CSAsr+(10*4)(r4)                                     /* Save SR 10 */
                   1923:                        mfsr    r5,sr12                                                         /* Get SR 12 */
                   1924:                        mfsr    r6,sr13                                                         /* Get SR 13 */
                   1925:                        stw             r7,CSAsr+(11*4)(r4)                                     /* Save SR 11 */
                   1926:                        mfsr    r7,sr14                                                         /* Get SR 14 */
                   1927:                        stw             r5,CSAsr+(12*4)(r4)                                     /* Save SR 12 */
                   1928:                        stw             r6,CSAsr+(13*4)(r4)                                     /* Save SR 13 */
                   1929:                        mfsr    r5,sr15                                                         /* Get SR 15 */
                   1930:                        stw             r7,CSAsr+(14*4)(r4)                                     /* Save SR 14 */
                   1931:                        stw             r5,CSAsr+(15*4)(r4)                                     /* Save SR 15 */
                   1932:                        
                   1933:                        mfdar   r6                                                                      /* Get the DAR */
                   1934:                        stw             r6,CSAdar(r4)                                           /* Save it */
                   1935:                        
                   1936:                        mfdsisr r5                                                                      /* Get the DSISR */
                   1937:                        stw             r5,CSAdsisr(r4)                                         /* Save it */
                   1938:                        
                   1939:                        stw             r10,CSAsprg+(1*4)(r4)                           /* Save SPRG1 */
                   1940:                        mfspr   r7,sprg0                                                        /* Get SPRG0 */
                   1941:                        mfspr   r6,sprg2                                                        /* Get SPRG2 */
                   1942:                        stw             r7,CSAsprg+(0*4)(r4)                            /* Save SPRG0 */
                   1943:                        mfspr   r5,sprg3                                                        /* Get SPRG3 */
                   1944:                        stw             r6,CSAsprg+(2*4)(r4)                            /* Save SPRG2 */
                   1945:                        stw             r5,CSAsprg+(3*4)(r4)                            /* Save SPRG4 */
                   1946:                        
                   1947:                        mfspr   r6,1013                                                         /* Get the DABR */
                   1948:                        mfspr   r7,1010                                                         /* Get the IABR */
                   1949:                        stw             r6,CSAdabr(r4)                                          /* Save the DABR */
                   1950:                        stw             r7,CSAiabr(r4)                                          /* Save the IABR */
                   1951:                        
                   1952:                        mfspr   r5,282                                                          /* Get the EAR */
                   1953:                        stw             r5,CSAear(r4)                                           /* Save the EAR */
                   1954:                        
                   1955:                        lis             r7,0xDEAD                                                       /* Get 0xDEAD */
                   1956:                        ori             r7,r7,0xF1D0                                            /* Get 0xDEADF1D0 */
                   1957:                        
                   1958:                        mfpvr   r5                                                                      /* Get the processor type */
                   1959:                        rlwinm  r5,r5,16,16,31                                          /* Isolate the processor */
                   1960:                        cmplwi  cr1,r5,4                                                        /* Set CR1_EQ if this is a plain 604, something else if it's a 604E */
                   1961:                        
                   1962:                        mfspr   r6,hid0                                                         /* Get HID0 */
                   1963:                        mr              r5,r7                                                           /* Assume 604 */
                   1964:                        beq             cr1,NoHID1                                                      /* It is... */
                   1965:                        mfspr   r5,hid1                                                         /* Get the HID1 */
                   1966: 
                   1967: NoHID1:                stw             r6,CSAhid+(0*4)(r4)                                     /* Save HID0 */
                   1968:                        stw             r5,CSAhid+(1*4)(r4)                                     /* Save HID1 */
                   1969:                        stw             r7,CSAhid+(2*4)(r4)                                     /* Save HID2 */
                   1970:                        stw             r7,CSAhid+(3*4)(r4)                                     /* Save HID3 */
                   1971:                        stw             r7,CSAhid+(4*4)(r4)                                     /* Save HID4 */
                   1972:                        stw             r7,CSAhid+(5*4)(r4)                                     /* Save HID5 */
                   1973:                        stw             r7,CSAhid+(6*4)(r4)                                     /* Save HID6 */
                   1974:                        stw             r7,CSAhid+(7*4)(r4)                                     /* Save HID7 */
                   1975:                        stw             r7,CSAhid+(8*4)(r4)                                     /* Save HID8 */
                   1976:                        stw             r7,CSAhid+(9*4)(r4)                                     /* Save HID9 */
                   1977:                        stw             r7,CSAhid+(10*4)(r4)                            /* Save HID10 */
                   1978:                        stw             r7,CSAhid+(11*4)(r4)                            /* Save HID11 */
                   1979:                        stw             r7,CSAhid+(12*4)(r4)                            /* Save HID12 */
                   1980:                        stw             r7,CSAhid+(13*4)(r4)                            /* Save HID13 */
                   1981:                        stw             r7,CSAhid+(14*4)(r4)                            /* Save HID14 */
                   1982:                        stw             r7,CSAhid+(15*4)(r4)                            /* Save HID15 */
                   1983:                        
                   1984:                        mfspr   r6,952                                                          /* Get MMCR0 */
                   1985:                        mr              r5,r7                                                           /* Assume 604 */
                   1986:                        beq             NoMMCR1                                                         /* It is... */
                   1987:                        mfspr   r5,956                                                          /* Get the MMCR1 */
                   1988: 
                   1989: NoMMCR1:       stw             r6,CSAmmcr+(0*4)(r4)                            /* Save MMCR0 */
                   1990:                        stw             r5,CSAmmcr+(1*4)(r4)                            /* Save MMCR1 */
                   1991:                        
                   1992:                        mfspr   r6,953                                                          /* Get PMC1 */
                   1993:                        mfspr   r5,954                                                          /* Get PMC2 */
                   1994:                        stw             r6,CSApmc+(0*4)(r4)                                     /* Save PMC1 */
                   1995:                        stw             r5,CSApmc+(1*4)(r4)                                     /* Save PMC2 */
                   1996:                        
                   1997:                        mr              r6,r7                                                           /* Assume 604 */
                   1998:                        mr              r5,r7                                                           /* Assume 604 */
                   1999:                        beq             NoPMC3                                                          /* Yeah... */
                   2000:                        mfspr   r6,957                                                          /* Get the PMC3 for a 604E */
                   2001:                        mfspr   r5,958                                                          /* Get the PMC4 for a 604E */
                   2002:                        
                   2003: NoPMC3:                stw             r6,CSApmc+(2*4)(r4)                                     /* Save PMC3 */
                   2004:                        stw             r5,CSApmc+(3*4)(r4)                                     /* Save PMC4 */
                   2005: 
                   2006:                        mfspr   r6,955                                                          /* Get SIA */
                   2007:                        mfspr   r5,959                                                          /* Get SDA */
                   2008:                        stw             r6,CSAsia(r4)                                           /* Save the SIA */
                   2009:                        stw             r5,CSAsda(r4)                                           /* Save the SDA */
                   2010:                        
                   2011:                        stw             r7,CSAmq(r4)                                            /* There is no MQ on either the 604 or 604E */
                   2012:                        
                   2013:                        
                   2014:                        lwz             r6,MPPICStat(r9)                                        /* Get the status of this processor */
                   2015:                        lis             r10,MPPICReady>>16                                      /* Get the flag for reset or not */
                   2016:                        li              r5,kSIGPResetState                                      /* Assume we're operating */
                   2017:                        and.    r0,r6,r10                                                       /* See if the ready bit is set */
                   2018:                        lis             r10,MPPICStop>>16                                       /* Get the flag for stopped or not */
                   2019:                        beq             SetStateInf                                                     /* Go set that we are reset... */
                   2020:                        and.    r0,r6,r10                                                       /* Are we stopped? */
                   2021:                        li              r5,kSIGPStoppedState                            /* Assume we area */
                   2022:                        bne             SetStateInf                                                     /* We are, go set it... */
                   2023:                        li              r5,kSIGPOperatingState                          /* Not stopped, so we're going */
                   2024:                        
                   2025: SetStateInf: stb               r5,CSAstate(r4)                                 /* Set the state byte */
                   2026:                        
                   2027:                        li              r0,1                                                            /* Set the truth */
                   2028:                        sync                                                                            /* Make sure it's stored */
                   2029:                        
                   2030:                        stb             r0,CSAregsAreValid(r4)                          /* Set that the status is valid */
                   2031: 
                   2032:                        blr                                                                                     /* We're done here... */
                   2033:                        
                   2034: 
                   2035: /******************************************************************************************************** */
                   2036: /* */
                   2037: /*                     The synchronize time base function.  No state requirements for this one. */
                   2038: /* */
                   2039: /******************************************************************************************************** */
                   2040: 
                   2041: ITBsync:                                                                                               /* This handles the synchronize time base function */
                   2042:                        lis             r12,HIGH_ADDR(MPPIwork)                         /* Get the top of work area */
                   2043:                        li              r0,MPPICfTBsy1                                          /* Get the flag for TB sync state 1 */
                   2044:                        li              r7,0                                                            /* Get a 0 */
                   2045:                        ori             r12,r12,LOW_ADDR(MPPIwork)                      /* Get low part of work area */
                   2046:                        mttbl   r7                                                                      /* Clear the bottom of the TB so's there's noupper ticks */
                   2047:                        mttbu   r7                                                                      /* Clear the top part, just 'cause I wanna */
                   2048:                        
                   2049:                        sync                                                                            /* Make sure all is saved */
                   2050:                        stb             r0,MPPICStat+2(r9)                                      /* Tell the main dude to tell us the time */
                   2051:                        isync                                                                           /* Make sure we don't go nowhere's */
                   2052: 
                   2053: /* */
                   2054: /*                     Remember that the sync'ing processor insures that the TB won't tick the high part for at least */
                   2055: /*                     16k ticks.  That should be way longer than we need for the whole process here */
                   2056: /* */
                   2057: 
                   2058: WaitTBLower: lwz       r5,MPPITBsync+4-MPPIwork(r12)           /* Get the lower part of the TB */
                   2059:                        mttbl   r5                                                                      /* Put it in just in case it's set now */
                   2060:                        mr.             r5,r5                                                           /* Was it actually? */
                   2061:                        beq+    WaitTBLower                                                     /* Nope, go check again... */
                   2062:                        lwz             r4,MPPITBsync-MPPIwork(r12)                     /* Get the high order part */
                   2063:                        mttbu   r4                                                                      /* Set the top half also */
                   2064: 
                   2065:                        stw             r7,MPPITBsync+4-MPPIwork(r12)           /* Tell 'em we've got it */
                   2066:                        
                   2067:                        sync
                   2068:                        
                   2069:                        li              r4,0                                                            /* Clear this */
                   2070:                        la              r5,MPPISncFght-32-MPPIwork(r12)         /* Point to the squared circle (our corner) */
                   2071: 
                   2072:                        b               TB1stPnch                                                       /* Go take the first punch... */
                   2073: 
                   2074: TBSargue:      
                   2075:                        dcbf    0,r5                                                            /* *** Fix cache coherency (data integrity) HW bug *** */
                   2076:                        sync                                                                            /* *** Fix cache coherency (data integrity) HW bug *** */
                   2077:                        lwz             r6,0(r5)                                                        /* Listen for the procecution's argument */
                   2078:                        mr.             r6,r6                                                           /* See if they are done */
                   2079:                        beq+    TBSargue                                                        /* Nope, still going... */
                   2080:                        
                   2081: TB1stPnch:     mftb    r7                                                                      /* They're done, time for rebuttal */
                   2082:                        stw             r7,32(r5)                                                       /* Make rebuttle */
                   2083:        
                   2084:                        addi    r4,r4,1                                                         /* Count rounds */
                   2085: 
                   2086:                        cmplwi  cr0,r4,10                                                       /* See if we've gone 9 more rounds */
                   2087:                        addi    r5,r5,64                                                        /* Point to the next round areas */
                   2088:                
                   2089:                        blt+    TBSargue                                                        /* Not yet, come out of your corners fighting... */
                   2090:                        
                   2091: /* */
                   2092: /*                     We'll set the latest-up-to-datest from the other processor now */
                   2093: /* */
                   2094: TBSetTB:               
                   2095:                        dcbf    0,r5                                                            /* *** Fix cache coherency (data integrity) HW bug *** */
                   2096:                        sync                                                                            /* *** Fix cache coherency (data integrity) HW bug *** */
                   2097:                        lwz             r6,0(r5)                                                        /* Listen for the procecution's argument */
                   2098:                        mttbl   r6                                                                      /* Set it just in case it's ok */
                   2099:                        mr.             r6,r6                                                           /* See if they are done */
                   2100:                        beq+    TBSetTB                                                         /* Nope, still going... */
                   2101: 
                   2102: /* */
                   2103: /*                     Get average duration for each processor.  We skip the first pass on the asumption */
                   2104: /*                     that the caches were not warmed up and it would take longer.  In proctice this */
                   2105: /*                     is what was seen. */
                   2106: /* */
                   2107: 
                   2108:                        mr              r0,r11                                                          /* Move return address to a safe register */
                   2109: 
                   2110:                        li              r4,0                                                            /* Clear a counter */
                   2111:                        li              r3,0                                                            /* Clear accumulator for duration */
                   2112:                        li              r10,0                                                           /* Clear start time accumulator top half */
                   2113:                        li              r11,0                                                           /* Clear start time accumulator bottom half */
                   2114:                        li              r1,0                                                            /* Clear start time accumulator top half */
                   2115:                        li              r2,0                                                            /* Clear start time accumulator bottom half */
                   2116:                        li              r10,0                                                           /* Clear accumulator for durations */
                   2117:                        la              r5,MPPISncFght+64-MPPIwork(r12)         /* Get second round start time address */
                   2118:                
                   2119: TBSaccumU:     lwz             r6,0(r5)                                                        /* Get start time */
                   2120:                        lwz             r11,32(r5)                                                      /* Get the other processor's start time */
                   2121:                        lwz             r7,64(r5)                                                       /* Get end time */
                   2122:                        lwz             r8,96(r5)                                                       /* Other proc's end time */
                   2123:                        sub             r7,r7,r6                                                        /* Get duration */
                   2124:                        sub             r8,r8,r11                                                       /* Get other side's duration */
                   2125:                        addi    r4,r4,1                                                         /* Count arguments */
                   2126:                        add             r3,r3,r7                                                        /* Accumulate durations */
                   2127:                        add             r2,r2,r7                                                        /* Accumulate other side's durations */
                   2128:                        cmplwi  cr0,r4,8                                                        /* Have we gotten them all yet? */
                   2129:                        addi    r5,r5,64                                                        /* Step to the next argument */
                   2130:                        blt+    TBSaccumU                                                       /* We're not done yet... */
                   2131: 
                   2132:                        add             r7,r2,r3                                                        /* Sum the two differences */
                   2133:                        addi    r7,r7,0x10                                                      /* Round up */
                   2134:                        rlwinm  r7,r7,27,5,31                                           /* Get the average difference divided in half */
                   2135: 
                   2136:                        mftb    r8                                                                      /* Get the time now */
                   2137:                        add             r8,r8,r7                                                        /* Slide the window */
                   2138:                        mttbl   r8                                                                      /* Set the time */
                   2139:                        
                   2140:                        stw             r12,MPPITBsync+4-MPPIwork(r12)          /* Show that we are done */
                   2141:                        
                   2142:                        lwz             r3,MPPICStat(r9)                                        /* Get back our status */
                   2143:                        mr              r11,r0                                                          /* Restore the return register */
                   2144:                        b               KillBusy                                                        /* We're all done now, done for it, c'est la vie... */
                   2145:                        
                   2146: 
                   2147: /******************************************************************************************************** */
                   2148: /* */
                   2149: /*                     The reset function.  No state requirements for this one. */
                   2150: /*                     This suicides the processor. Our caller is never returned to (good english).  The only way out of  */
                   2151: /*                     this is a start function subsequently.  So, we give a flying f**k about the registers 'n' sutff. */
                   2152: /* */
                   2153: /******************************************************************************************************** */
                   2154: 
                   2155: IReset:                lis             r28,0x8000                                                      /* Turn on machine checks */
                   2156:                        
                   2157:                        ori             r28,r28,0xCC84                                          /* Enable caches, clear them,  */
                   2158:                                                                                                                /* disable serial execution and turn BHT on */
                   2159:                        sync
                   2160:                        mtspr   HID0,r28                                                        /* Start the cache clear */
                   2161:                        sync
                   2162: 
                   2163: /* */
                   2164: /*                     Clear out the TLB.  They be garbage after hard reset. */
                   2165: /* */
                   2166: 
                   2167:                        li              r0,512                                                          /* Get number of TLB entries (FIX THIS) */
                   2168:                        li              r3,0                                                            /* Start at 0 */
                   2169:                        mtctr   r0                                                                      /* Set the CTR */
                   2170:                        
                   2171: IRpurgeTLB:    tlbie   r3                                                                      /* Purge this entry */
                   2172:                        addi    r3,r3,4096                                                      /* Next page */
                   2173:                        bdnz    IRpurgeTLB                                                      /* Do 'em all... */
                   2174:                        
                   2175:                        sync                                                                            /* Make sure all TLB purges are done */
                   2176:                        tlbsync                                                                         /* Make sure on other processors also */
                   2177:                        sync                                                                            /* Make sure the TLBSYNC is done */
                   2178: 
                   2179: /* */
                   2180: /*                     Clear out the BATs. */
                   2181: /* */
                   2182: 
                   2183:                        li              r3,0                                                            /* Clear a register */
                   2184:                        
                   2185:                        mtspr   DBAT0L,r3                                                       /* Clear BAT */
                   2186:                        mtspr   DBAT0U,r3                                                       /* Clear BAT */
                   2187:                        mtspr   DBAT1L,r3                                                       /* Clear BAT */
                   2188:                        mtspr   DBAT1U,r3                                                       /* Clear BAT */
                   2189:                        mtspr   DBAT2L,r3                                                       /* Clear BAT */
                   2190:                        mtspr   DBAT2U,r3                                                       /* Clear BAT */
                   2191:                        mtspr   DBAT3L,r3                                                       /* Clear BAT */
                   2192:                        mtspr   DBAT3U,r3                                                       /* Clear BAT */
                   2193:                        
                   2194:                        mtspr   IBAT0L,r3                                                       /* Clear BAT */
                   2195:                        mtspr   IBAT0U,r3                                                       /* Clear BAT */
                   2196:                        mtspr   IBAT1L,r3                                                       /* Clear BAT */
                   2197:                        mtspr   IBAT1U,r3                                                       /* Clear BAT */
                   2198:                        mtspr   IBAT2L,r3                                                       /* Clear BAT */
                   2199:                        mtspr   IBAT2U,r3                                                       /* Clear BAT */
                   2200:                        mtspr   IBAT3L,r3                                                       /* Clear BAT */
                   2201:                        mtspr   IBAT3U,r3                                                       /* Clear BAT */
                   2202: 
                   2203: /* */
                   2204: /*                     Map 0xF0000000 to 0xFFFFFFFF for I/O; make it R/W non-cacheable */
                   2205: /*                     Map     0x00000000 to 0x0FFFFFFF for mainstore; make it R/W cachable */
                   2206: /* */
                   2207: 
                   2208:                        lis             r6,0xF000                                                       /* Set RPN to last segment */
                   2209:                        ori             r6,r6,0x1FFF                                            /* Set up upper BAT for 256M, access both */
                   2210:                        
                   2211:                        lis             r7,0xF000                                                       /* Set RPN to last segment */
                   2212:                        ori             r7,r7,0x0032                                            /* Set up lower BAT for 256M, access both, non-cachable */
                   2213:                
                   2214:                        mtspr   DBAT0L,r7                                                       /* Setup ROM and I/O mapped areas */
                   2215:                        mtspr   DBAT0U,r6                                                       /* Now do the upper DBAT */
                   2216:                        sync
                   2217:        
                   2218:                        li              r6,0x1FFF                                                       /* Set up upper BAT for 256M, access both */
                   2219:                        li              r7,0x0012                                                       /* Set up lower BAT for r/w access */
                   2220:                        
                   2221:                        mtspr   DBAT1L,r7                                                       /* Set up an initial view of mainstore */
                   2222:                        mtspr   DBAT1U,r6                                                       /* Now do the upper DBAT */
                   2223:                        sync
                   2224: 
                   2225: /* */
                   2226: /*                     Clean up SDR and segment registers */
                   2227: /* */
                   2228: 
                   2229:                        li              r3,0                                                            /* Clear a register */
                   2230:                        mtspr   SDR1,r3                                                         /* Clear SDR1 */
                   2231:                        
                   2232:                        li              r4,0                                                            /* Clear index for segment registers */
                   2233:                        lis             r5,0x1000                                                       /* Set the segment indexer */
                   2234:                        
                   2235: IRclearSR:     mtsrin  r3,r4                                                           /* Zero out the SR */
                   2236:                        add.    r4,r4,r5                                                        /* Point to the next segment */
                   2237:                        bne-    IRclearSR                                                       /* Keep going until we wrap back to 0 */
                   2238:                        
                   2239:                        lis             r3,(MPPICOnline+MPPICStop)>>16          /* Set the reset/online state flags */
                   2240:                        b               KillBusy                                                        /* Go wipe out the busy flags... */
                   2241: 
                   2242: /*     (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG)  */
                   2243: /* */
                   2244: /*                     Here lies the Phoney Firmware used to test SIGPs.  Take this out later. */
                   2245: /* */
                   2246: /*     (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG)  */
                   2247: 
                   2248: mp_PhoneyFirmware:
                   2249: 
                   2250:                        li              r27,0x3040                                                      /* Set floating point and machine checks on, IP to 0xFFF0xxxx */
                   2251:                        mtmsr   r27                                                                     /* Load 'em on in */
                   2252:                        isync
                   2253:                        
                   2254:                        bl              PhoneyBase                                                      /* Make a base register */
                   2255: PhoneyBase:    mflr    r26                                                                     /* Get it */
                   2256:                        addi    r26,r26,LOW_ADDR(MPPIbase-PhoneyBase)   /* Adjust it back */
                   2257: 
                   2258:                        la              r20,LOW_ADDR(rupttab-MPPIbase)(r26)             /* Get the address of the interrupt table */
                   2259:                        la              r21,LOW_ADDR(rupttabend-MPPIbase)(r26)  /* Get the end of the table */
                   2260:                        
                   2261: relocate:      lwz             r22,0(r20)                                                      /* Get the displacement to routine */
                   2262:                        add             r22,r22,r12                                                     /* Relocate to the physical address */
                   2263:                        stw             r22,0(r20)                                                      /* Stick it back */
                   2264:                        addi    r20,r20,4                                                       /* Point to the next one */
                   2265:                        cmplw   cr0,r20,r21                                                     /* Still in table? */
                   2266:                        ble+    cr0,relocate                                            /* Yeah... */
                   2267:                        
                   2268:                        la              r20,LOW_ADDR(rupttab-MPPIbase)(r26)     /* Get the interrupt table back again */
                   2269:                        mtsprg  3,r20                                                           /* Activate the phoney Rupt table */
                   2270:                        
                   2271:                        lis             r24,hi16(HammerHead)                            /* Get the actual hammerhead address */
                   2272:                        ori             r24,r24,0x0032                                          /* Make R/W non-cachable */
                   2273:                        lwz             r23,MPPIHammer-MPPIwork(r12)            /* Get the address mapped on the main processor */
                   2274:                        ori             r23,r23,0x0003                                          /* Set both super and user valid for 128KB */
                   2275:                        
                   2276:                        mtspr   DBAT0L,r24                                                      /* Setup hammerhead's real address */
                   2277:                        mtspr   DBAT0U,r23                                                      /* Map hammerhead to the same virtual address as on the main processor */
                   2278:                        sync                                                                            /* Make sure it is done */
                   2279: 
                   2280:                        la              r25,MPPICPU2-MPPIwork(r12)                      /* Point to a phoney register save area */
                   2281:                        mtsprg  1,r25                                                           /* Phoney up initialized processor state */
                   2282: 
                   2283:                        lis             r24,0xFEED                                                      /* Get 0xFEED */
                   2284:                        ori             r24,r24,0xF1D0                                          /* Get 0xFEEDF1D0 */
                   2285:                        
                   2286:                        stw             r24,CSAgpr+(0*4)(r25)                           /* Store invalid R0 */
                   2287:                        stw             r24,CSAgpr+(1*4)(r25)                           /* Store invalid R1 */
                   2288:                        stw             r24,CSAgpr+(2*4)(r25)                           /* Store invalid R2 */
                   2289:                        stw             r24,CSAgpr+(3*4)(r25)                           /* Store invalid R3 */
                   2290:                        stw             r24,CSAgpr+(4*4)(r25)                           /* Store invalid r4 */
                   2291:                        stw             r24,CSAgpr+(5*4)(r25)                           /* Store invalid R5 */
                   2292:                        stw             r24,CSAgpr+(6*4)(r25)                           /* Store invalid R6 */
                   2293:                        stw             r24,CSAgpr+(7*4)(r25)                           /* Store invalid r7 */
                   2294:                        stw             r24,CSAgpr+(8*4)(r25)                           /* Store invalid R8 */
                   2295:                        stw             r24,CSAgpr+(9*4)(r25)                           /* Store invalid R9 */
                   2296:                        stw             r24,CSAgpr+(10*4)(r25)                          /* Store invalid R10 */
                   2297:                        stw             r24,CSAgpr+(11*4)(r25)                          /* Store invalid R11 */
                   2298:                        stw             r24,CSAgpr+(12*4)(r25)                          /* Store invalid R12 */
                   2299:                        
                   2300: waititout:     lwz             r25,0x30(br0)                                           /* Get wait count */
                   2301:                        mfmsr   r24                                                                     /* Get the MSR */
                   2302:                        addi    r25,r25,1                                                       /* Bounce it up */
                   2303:                        ori             r24,r24,0x8000                                          /* Turn on external interruptions */
                   2304:                        stw             r25,0x30(br0)                                           /* Save back the count */
                   2305:                        mtmsr   r24                                                                     /* Set it */
                   2306:                        isync                                                                           /* Stop until we're here */
                   2307:                        b               waititout                                                       /* Loop forever... */
                   2308:                        
                   2309: /* */
                   2310: /*                     Phoney interrupt handlers */
                   2311: /* */
                   2312: 
                   2313: pexternal:     mflr    r29                                                                     /* Get the LR value */
                   2314:                        lwz             r29,0(r29)                                                      /* Get the rupt code */
                   2315:                        stw             r29,0x0B0(br0)                                          /* Save the code */
                   2316:                        bl              GotSignal                                                       /* Call the signal handler */
                   2317:                        oris    r3,r3,0x8000                                            /* Turn on high bit so we see a code 0 */
                   2318:                        stw             r3,0xA8(br0)                                            /* Save return code in debug area */
                   2319:                        
                   2320: ignorerupt:    mflr    r29                                                                     /* Get the LR value */
                   2321:                        lwz             r29,0(r29)                                                      /* Get the rupt code */
                   2322:                        stw             r29,0x0B0(br0)                                          /* Save the code */
                   2323:                        rfi                                                                                     /* Bail to from whence we commest... */
                   2324:                        .long   0                       
                   2325:                        .long   0                       
                   2326:                        .long   0                       
                   2327:                        .long   0                       
                   2328:                        .long   0                       
                   2329:                        .long   0                       
                   2330:                        .long   0                       
                   2331: 
                   2332: rupttab:       .long   ignorerupt
                   2333:                        .long   ignorerupt
                   2334:                        .long   ignorerupt
                   2335:                        .long   ignorerupt
                   2336:                        .long   ignorerupt
                   2337:                        .long   pexternal                                                       /* Phoney external handler */
                   2338:                        .long   ignorerupt
                   2339:                        .long   ignorerupt
                   2340:                        .long   ignorerupt
                   2341:                        .long   ignorerupt
                   2342:                        .long   ignorerupt
                   2343:                        .long   ignorerupt
                   2344:                        .long   ignorerupt
                   2345:                        .long   ignorerupt
                   2346:                        .long   ignorerupt
                   2347:                        .long   ignorerupt
                   2348:                        .long   ignorerupt
                   2349:                        .long   ignorerupt
                   2350:                        .long   ignorerupt
                   2351:                        .long   ignorerupt
                   2352:                        .long   ignorerupt
                   2353:                        .long   ignorerupt
                   2354:                        .long   ignorerupt
                   2355:                        .long   ignorerupt
                   2356:                        .long   ignorerupt
                   2357:                        .long   ignorerupt
                   2358:                        .long   ignorerupt
                   2359:                        .long   ignorerupt
                   2360:                        .long   ignorerupt
                   2361:                        .long   ignorerupt
                   2362:                        .long   ignorerupt
                   2363:                        .long   ignorerupt
                   2364:                        .long   ignorerupt
                   2365:                        .long   ignorerupt
                   2366:                        .long   ignorerupt
                   2367:                        .long   ignorerupt
                   2368:                        .long   ignorerupt
                   2369:                        .long   ignorerupt
                   2370:                        .long   ignorerupt
                   2371:                        .long   ignorerupt
                   2372:                        .long   ignorerupt
                   2373:                        .long   ignorerupt
                   2374:                        .long   ignorerupt
                   2375:                        .long   ignorerupt
                   2376:                        .long   ignorerupt
                   2377:                        .long   ignorerupt
                   2378:                        .long   ignorerupt
                   2379: rupttabend:    .long   ignorerupt
                   2380: 
                   2381: /*     (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG)  */
                   2382: /* */
                   2383: /*                     Here lies the end of the Phoney Firmware used to test SIGPs.  Take this out later. */
                   2384: /* */
                   2385: /*     (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG) (TEST/DEBUG)  */
                   2386: 
                   2387: 
                   2388: /* */
                   2389: /*                     Table of function offsets */
                   2390: /* */
                   2391: 
                   2392: MPPIFuncOffs:
                   2393: 
                   2394:                        .long   CountProcessors-MPPIFunctions                                   /* Offset to routine */
                   2395:                        .long   StartProcessor-MPPIFunctions                                    /* Offset to routine */
                   2396:                        .long   ResumeProcessor-MPPIFunctions                                   /* Offset to routine */
                   2397:                        .long   StopProcessor-MPPIFunctions                                             /* Offset to routine */
                   2398:                        .long   ResetProcessor-MPPIFunctions                                    /* Offset to routine */
                   2399:                        .long   SignalProcessor-MPPIFunctions                                   /* Offset to routine */
                   2400:                        .long   StoreProcessorStatus-MPPIFunctions                              /* Offset to routine */
                   2401:                        .long   SynchClock-MPPIFunctions                                                /* Offset to routine */
                   2402:                        .long   GetExtHandlerAddress-MPPIFunctions                              /* Offset to routine */
                   2403:                        .long   GotSignal-MPPIFunctions                                                 /* Offset to routine */
                   2404:                        .long   ProcessorState-MPPIFunctions                                    /* Offset to routine */
                   2405:                        .long   RunSIGPRun-MPPIFunctions                                                /* Offset to routine */
                   2406:                        .long   mp_PhoneyFirmware-MPPIFunctions                                 /* (TEST/DEBUG) */
                   2407: 
                   2408: MPPISize:
                   2409:        

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.