Annotation of XNU/osfmk/ppc/MPinterfaces.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_FREE_COPYRIGHT@
                     24:  */
                     25: /*
                     26:  * @APPLE_FREE_COPYRIGHT@
                     27:  */
                     28: 
                     29: /*                                                                                                                                                                                     
                     30:        MPinterfaces.s 
                     31: 
                     32:        General interface to the MP hardware handlers anonymous
                     33: 
                     34:        Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
                     35:        No animal products are used other than rendered otter bile.
                     36: 
                     37: */
                     38: 
                     39: #include <cpus.h>
                     40: #include <ppc/asm.h>
                     41: #include <ppc/proc_reg.h>
                     42: #include <ppc/POWERMAC/mp/MPPlugIn.h>
                     43: #include <mach/machine/vm_param.h>
                     44: #include <assym.s>
                     45: 
                     46: /*
                     47:  *                     This first section is the glue for the high level C code.
                     48:  *                     Anything that needs any kind of system services (e.g., VM) has to be done here.  The firmware
                     49:  *                     code that implements the SC runs in real mode.
                     50:  */
                     51: 
                     52: 
                     53: 
                     54: /* #define     MPI_DEBUGGING   0 */
                     55: #define                MPI_DEBUGGING   0
                     56: 
                     57: /*
                     58:  *                     The routine that implements cpu_number.
                     59:  */
                     60: 
                     61: ENTRY(cpu_number, TAG_NO_FRAME_USED)
                     62:  
                     63:                        mfmsr   r9                                      /* Save the old MSR */
                     64:                        rlwinm  r8,r9,0,17,15           /* Clear interruptions */
                     65:                        mtmsr   r8                                      /* Interrupts off */
                     66:                        mfsprg  r7,0                            /* Get per-proc block */
                     67:                        lhz             r3,PP_CPU_NUMBER(r7)    /* Get CPU number */
                     68:                        mtmsr   r9                                      /* Restore interruptions to entry */
                     69:                        blr                                                     /* Return... */
                     70: 
                     71: 
                     72: /*
                     73:  *                     The routine glues to the count CPU firmware call
                     74:  */
                     75: 
                     76: ENTRY(MPgetProcCount, TAG_NO_FRAME_USED)
                     77: 
                     78:                        mr              r12,r0                                                                  /* Keep R0 pristene */
                     79:                        lis             r0,HIGH_ADDR(MPgetProcCountCall)                /* Top half of MPgetProcCount firmware call number */
                     80:                        ori             r0,r0,LOW_ADDR(MPgetProcCountCall)              /* Bottom half */
                     81:                        sc                                                                                              /* Go see how many processors we have */
                     82:                        
                     83: #if                    MPI_DEBUGGING
                     84:                        lis             r0,HIGH_ADDR(CutTrace)                                  /* Top half of trace entry maker call */
                     85:                        ori             r0,r0,LOW_ADDR(CutTrace)                                /* Bottom half of trace entry maker call */
                     86:                        sc                                                                                              /* Cut a backend trace entry */
                     87: #endif
                     88: 
                     89:                        mr              r0,r12                                                                  /* Restore R0 */
                     90: 
                     91:                        blr                                                                                             /* Return, pass back R3... */
                     92: 
                     93: /*
                     94:  *                     The routine glues to the start CPU firmware call - actually it's really a boot
                     95:  *                     The first parameter is the CPU number to start
                     96:  *                     The second parameter is the real address of the code used to boot the processor
                     97:  *                     The third parameter is the real addess of the CSA for the subject processor
                     98:  */
                     99: 
                    100: ENTRY(MPstart, TAG_NO_FRAME_USED)
                    101: 
                    102:                        mr              r12,r0                                                                  /* Keep R0 pristene */
                    103:                        lis             r0,HIGH_ADDR(MPstartCall)                               /* Top half of MPstartCall firmware call number */
                    104:                        ori             r0,r0,LOW_ADDR(MPstartCall)                             /* Bottom half */
                    105:                        sc                                                                                              /* Go see how many processors we have */
                    106:                        
                    107: #if                    MPI_DEBUGGING
                    108:                        lis             r0,HIGH_ADDR(CutTrace)                                  /* Top half of trace entry maker call */
                    109:                        ori             r0,r0,LOW_ADDR(CutTrace)                                /* Bottom half of trace entry maker call */
                    110:                        sc                                                                                              /* Cut a backend trace entry */
                    111: #endif
                    112: 
                    113:                        mr              r0,r12                                                                  /* Restore R0 */
                    114:                        blr                                                                                             /* Return... */
                    115: 
                    116: /*
                    117:  *                     This routine glues to the get external interrupt handler physical address
                    118:  */
                    119: 
                    120: ENTRY(MPexternalHook, TAG_NO_FRAME_USED)
                    121: 
                    122:                        mr              r12,r0                                                                  /* Keep R0 pristene */
                    123:                        lis             r0,HIGH_ADDR(MPexternalHookCall)                /* Top half of MPexternalHookCall firmware call number */
                    124:                        ori             r0,r0,LOW_ADDR(MPexternalHookCall)              /* Bottom half */
                    125:                        sc                                                                                              /* Go see how many processors we have */
                    126:                        
                    127: #if                    MPI_DEBUGGING
                    128:                        lis             r0,HIGH_ADDR(CutTrace)                                  /* Top half of trace entry maker call */
                    129:                        ori             r0,r0,LOW_ADDR(CutTrace)                                /* Bottom half of trace entry maker call */
                    130:                        sc                                                                                              /* Cut a backend trace entry */
                    131: #endif
                    132: 
                    133:                        mr              r0,r12                                                                  /* Restore R0 */
                    134:                        blr                                                                                             /* Return... */
                    135: 
                    136: 
                    137: /*
                    138:  *                     This routine glues to the signal processor routine
                    139:  */
                    140: 
                    141: ENTRY(MPsignal, TAG_NO_FRAME_USED)
                    142: 
                    143:                        mr              r12,r0                                                                  /* Keep R0 pristene */
                    144:                        lis             r0,HIGH_ADDR(MPsignalCall)                              /* Top half of MPsignalCall firmware call number */
                    145:                        ori             r0,r0,LOW_ADDR(MPsignalCall)                    /* Bottom half */
                    146:                        sc                                                                                              /* Go kick the other guy */
                    147:                        
                    148: #if                    MPI_DEBUGGING
                    149:                        lis             r0,HIGH_ADDR(CutTrace)                                  /* Top half of trace entry maker call */
                    150:                        ori             r0,r0,LOW_ADDR(CutTrace)                                /* Bottom half of trace entry maker call */
                    151:                        sc                                                                                              /* Cut a backend trace entry */
                    152: #endif
                    153: 
                    154:                        mr              r0,r12                                                                  /* Restore R0 */
                    155:                        blr                                                                                             /* Return... */
                    156: 
                    157: 
                    158: /*
                    159:  *                     This routine glues to the stop processor routine
                    160:  */
                    161: 
                    162: ENTRY(MPstop, TAG_NO_FRAME_USED)
                    163: 
                    164:                        mr              r12,r0                                                                  /* Keep R0 pristene */
                    165:                        lis             r0,HIGH_ADDR(MPstopCall)                                /* Top half of MPsignalCall firmware call number */
                    166:                        ori             r0,r0,LOW_ADDR(MPstopCall)                              /* Bottom half */
                    167:                        sc                                                                                              /* Stop the other guy cold */
                    168:                        
                    169: #if                    MPI_DEBUGGING
                    170:                        lis             r0,HIGH_ADDR(CutTrace)                                  /* Top half of trace entry maker call */
                    171:                        ori             r0,r0,LOW_ADDR(CutTrace)                                /* Bottom half of trace entry maker call */
                    172:                        sc                                                                                              /* Cut a backend trace entry */
                    173: #endif
                    174: 
                    175:                        mr              r0,r12                                                                  /* Restore R0 */
                    176:                        blr                                                                                             /* Return... */
                    177: 
                    178: 
                    179: /* *************************************************************************************************************
                    180:  *
                    181:  *                     This second section is the glue for the low level stuff directly into the MP plugin.
                    182:  *                     At this point every register in existence should be saved.  Well, they're saved,
                    183:  *                     but R13 points to the savearea, and R20 to the trace entry. Please be careful
                    184:  *                     with these. You won't like what happens if they're different when you exit.
                    185:  *
                    186:  ***************************************************************************************************************/
                    187: 
                    188: 
                    189: /*
                    190:  *                     See how many physical processors we have
                    191:  */
                    192:  
                    193: ENTRY(MPgetProcCountLL, TAG_NO_FRAME_USED)
                    194: 
                    195:                        lis             r11,HIGH_ADDR(EXT(MPEntries))                   /* Get the address of the MP entry block  (in the V=R area) */
                    196:                        ori             r11,r11,LOW_ADDR(EXT(MPEntries))                /* Get the bottom of the MP spec area */
                    197:                        lwz             r10,kCountProcessors*4(r11)                             /* Get the routine entry point */
                    198:                        mflr    r14                                                                             /* Save the return in an unused register */
                    199:                        mtlr    r10                                                                             /* Set it */
                    200:                        blrl                                                                                    /* Call the routine */
                    201:                        mtlr    r14                                                                             /* Restore firmware caller address */
                    202:                        blr                                                                                             /* Leave... */
                    203: 
                    204: /*
                    205:  *                     Start up a processor
                    206:  */
                    207: 
                    208: ENTRY(MPstartLL, TAG_NO_FRAME_USED)
                    209: 
                    210:                        lis             r11,HIGH_ADDR(EXT(MPEntries))                   /* Get the address of the MP entry block  (in the V=R area) */
                    211:                        ori             r11,r11,LOW_ADDR(EXT(MPEntries))                /* Get the bottom of the MP spec area */
                    212:                        lwz             r10,kStartProcessor*4(r11)                              /* Get the routine entry point */
                    213:                        mflr    r14                                                                             /* Save the return in an unused register */
                    214:                        mtlr    r10                                                                             /* Set it */
                    215:                        blrl                                                                                    /* Call the routine */
                    216:                        mtlr    r14                                                                             /* Restore firmware caller address */
                    217:                        blr                                                                                             /* Leave... */
                    218: 
                    219: /*
                    220:  *                     Get physical address of SIGP external handler
                    221:  */
                    222: 
                    223: ENTRY(MPexternalHookLL, TAG_NO_FRAME_USED)
                    224: 
                    225:                        lis             r11,HIGH_ADDR(EXT(MPEntries))                   /* Get the address of the MP entry block  (in the V=R area) */
                    226:                        ori             r11,r11,LOW_ADDR(EXT(MPEntries))                /* Get the bottom of the MP spec area */
                    227:                        lwz             r10,kExternalHook*4(r11)                                /* Get the routine entry point */
                    228:                        mflr    r14                                                                             /* Save the return in an unused register */
                    229:                        mtlr    r10                                                                             /* Set it */
                    230:                        blrl                                                                                    /* Call the routine */
                    231:                        mtlr    r14                                                                             /* Restore firmware caller address */
                    232:                        blr                                                                                             /* Leave... */
                    233: 
                    234: 
                    235: 
                    236: /*
                    237:  *                     Send a signal to another processor
                    238:  */
                    239: 
                    240: ENTRY(MPsignalLL, TAG_NO_FRAME_USED)
                    241: 
                    242:                        lis             r11,HIGH_ADDR(EXT(MPEntries))                   /* Get the address of the MP entry block  (in the V=R area) */
                    243:                        ori             r11,r11,LOW_ADDR(EXT(MPEntries))                /* Get the bottom of the MP spec area */
                    244:                        lwz             r10,kSignalProcessor*4(r11)                             /* Get the routine entry point */
                    245:                        mflr    r14                                                                             /* Save the return in an unused register */
                    246:                        mtlr    r10                                                                             /* Set it */
                    247:                        blrl                                                                                    /* Call the routine */
                    248:                        mtlr    r14                                                                             /* Restore firmware caller address */
                    249:                        blr                                                                                             /* Leave... */
                    250: 
                    251: 
                    252: 
                    253: /*
                    254:  *                     Stop another processor
                    255:  */
                    256: 
                    257: ENTRY(MPstopLL, TAG_NO_FRAME_USED)
                    258: 
                    259:                        lis             r11,HIGH_ADDR(EXT(MPEntries))                   /* Get the address of the MP entry block  (in the V=R area) */
                    260:                        ori             r11,r11,LOW_ADDR(EXT(MPEntries))                /* Get the bottom of the MP spec area */
                    261:                        lwz             r10,kStopProcessor*4(r11)                               /* Get the routine entry point */
                    262:                        mflr    r14                                                                             /* Save the return in an unused register */
                    263:                        mtlr    r10                                                                             /* Set it */
                    264:                        blrl                                                                                    /* Call the routine */
                    265:                        mtlr    r14                                                                             /* Restore firmware caller address */
                    266:                        blr                                                                                             /* Leave... */
                    267: 
                    268: 
                    269: /*
                    270:  *                     Third section: Miscellaneous MP related routines
                    271:  */
                    272: 
                    273: 
                    274: 
                    275: /*
                    276:  *                     All non-primary CPUs start here.
                    277:  *                     We are dispatched by the SMP driver. Addressing is real (no DR or IR), 
                    278:  *                     interruptions disabled, etc.  R3 points to the CPUStatusArea (CSA) which contains
                    279:  *                     most of the state for the processor.  This is set up by the primary.  Note that we 
                    280:  *                     do not use everything in the CSA.  Caches should be clear and coherent with 
                    281:  *                     no paradoxies (well, maybe one doxie, a pair would be pushing it).
                    282:  */
                    283:        
                    284: ENTRY(start_secondary,TAG_NO_FRAME_USED)
                    285: 
                    286:                        mr              r31,r3                                                  /* Get the pointer to the CSA */
                    287:                        
                    288:                        lis             r21,HIGH_ADDR(SpinTimeOut)              /* Get the top part of the spin timeout */
                    289:                        ori             r21,r21,LOW_ADDR(SpinTimeOut)   /* Slam in the bottom part */
                    290:                        
                    291: GetValid:      lbz             r10,CSAregsAreValid(r31)                /* Get the CSA validity value */
                    292: 
                    293:                        
                    294:                        mr.             r10,r10                                                 /* Is the area valid yet? */
                    295:                        bne             GotValid                                                /* Yeah... */
                    296:                        addic.  r21,r21,-1                                              /* Count the try */
                    297:                        isync                                                                   /* Make sure we don't prefetch the valid flag */
                    298:                        bge+    GetValid                                                /* Still more tries left... */
                    299:                        blr                                                                             /* Return and cancel startup request... */
                    300:                                
                    301: GotValid:      li              r21,0                                                   /* Set the valid flag off (the won't be after the RFI) */
                    302:                        lwz             r10,CSAdec(r31)                                 /* Get the decrimenter */
                    303:                        stb             r21,CSAregsAreValid(r31)                /* Clear that validity flag */
                    304:                        
                    305:                        lwz             r11,CSAdbat+(0*8)+0(r31)                /* Get the first DBAT */
                    306:                        lwz             r12,CSAdbat+(0*8)+4(r31)                /* Get the first DBAT */
                    307:                        lwz             r13,CSAdbat+(1*8)+0(r31)                /* Get the second DBAT */
                    308:                        mtdec   r10                                                             /* Set the decrimenter */
                    309:                        lwz             r14,CSAdbat+(1*8)+4(r31)                /* Get the second DBAT */
                    310:                        mtdbatu 0,r11                                                   /* Set top part of DBAT 0 */
                    311:                        lwz             r15,CSAdbat+(2*8)+0(r31)                /* Get the third DBAT */
                    312:                        mtdbatl 0,r12                                                   /* Set lower part of DBAT 0 */
                    313:                        lwz             r16,CSAdbat+(2*8)+4(r31)                /* Get the third DBAT */
                    314:                        mtdbatu 1,r13                                                   /* Set top part of DBAT 1 */
                    315:                        lwz             r17,CSAdbat+(3*8)+0(r31)                /* Get the fourth DBAT */
                    316:                        mtdbatl 1,r14                                                   /* Set lower part of DBAT 1 */
                    317:                        lwz             r18,CSAdbat+(3*8)+4(r31)                /* Get the fourth DBAT */
                    318:                        mtdbatu 2,r15                                                   /* Set top part of DBAT 2 */                    
                    319:                        lwz             r11,CSAibat+(0*8)+0(r31)                /* Get the first IBAT */
                    320:                        mtdbatl 2,r16                                                   /* Set lower part of DBAT 2 */
                    321:                        lwz             r12,CSAibat+(0*8)+4(r31)                /* Get the first IBAT */
                    322:                        mtdbatu 3,r17                                                   /* Set top part of DBAT 3 */
                    323:                        lwz             r13,CSAibat+(1*8)+0(r31)                /* Get the second IBAT */
                    324:                        mtdbatl 3,r18                                                   /* Set lower part of DBAT 3 */
                    325:                        lwz             r14,CSAibat+(1*8)+4(r31)                /* Get the second IBAT */
                    326:                        mtibatu 0,r11                                                   /* Set top part of IBAT 0 */
                    327:                        lwz             r15,CSAibat+(2*8)+0(r31)                /* Get the third IBAT */
                    328:                        mtibatl 0,r12                                                   /* Set lower part of IBAT 0 */
                    329:                        lwz             r16,CSAibat+(2*8)+4(r31)                /* Get the third IBAT */
                    330:                        mtibatu 1,r13                                                   /* Set top part of IBAT 1 */
                    331:                        lwz             r17,CSAibat+(3*8)+0(r31)                /* Get the fourth IBAT */
                    332:                        mtibatl 1,r14                                                   /* Set lower part of IBAT 1 */
                    333:                        lwz             r18,CSAibat+(3*8)+4(r31)                /* Get the fourth IBAT */
                    334:                        mtibatu 2,r15                                                   /* Set top part of IBAT 2 */
                    335:                        lwz             r11,CSAsdr1(r31)                                /* Get the SDR1 value */
                    336:                        mtibatl 2,r16                                                   /* Set lower part of IBAT 2 */
                    337:                        lwz             r12,CSAsprg(r31)                                /* Get SPRG0 (the per_proc_info address) */
                    338:                        mtibatu 3,r17                                                   /* Set top part of IBAT 3 */
                    339:                        lwz             r13,CSAmsr(r31)                                 /* Get the MSR */
                    340:                        mtibatl 3,r18                                                   /* Set lower part of IBAT 3 */
                    341:                        lwz             r14,CSApc(r31)                                  /* Get the PC */
                    342:                        sync                                                                    /* Sync up */
                    343:                        mtsdr1  r11                                                             /* Set the SDR1 value */
                    344:                        sync                                                                    /* Sync up */
                    345:                        
                    346:                        la              r10,CSAsr-4(r31)                                /* Point to SR 0  - 4 */
                    347:                        li              r9,0                                                    /* Start at SR 0 */
                    348: 
                    349: LoadSRs:       lwz             r8,4(r10)                                               /* Get the next SR in line */
                    350:                        addi    r10,r10,4
                    351:                        mtsrin  r8,r9                                                   /* Load up the SR */
                    352:                        addis   r9,r9,0x1000                                    /* Bump to the next SR */
                    353:                        mr.             r9,r9                                                   /* See if we wrapped back to 0 */
                    354:                        bne+    LoadSRs                                                 /* Not yet... */
                    355:                                                
                    356:                        lwz             r0,CSAgpr+(0*4)(r31)                    /* Get a GPR */
                    357:                        lwz             r9,CSAsprg+(1*4)(r31)                   /* Get SPRG1 (the initial active savearea) */
                    358:                        mtsrr1  r13                                                             /* Set the MSR to dispatch */
                    359:                        lwz             r1,CSAgpr+(1*4)(r31)                    /* Get a GPR */
                    360:                        mtsprg  0,r12                                                   /* Set the SPRG0 (per_proc_into) value */
                    361:                        lwz             r2,CSAgpr+(2*4)(r31)                    /* Get a GPR */
                    362:                        mtsrr0  r14                                                             /* Set the PC to dispatch */
                    363:                        lwz             r3,CSAgpr+(3*4)(r31)                    /* Get a GPR */
                    364:                        mtsprg  1,r9                                                    /* Set the SPRG1 (the initial active savearea) value */
                    365:                        lwz             r4,CSAgpr+(4*4)(r31)                    /* Get a GPR */
                    366:                        lwz             r5,CSAgpr+(5*4)(r31)                    /* Get a GPR */
                    367:                        lwz             r6,CSAgpr+(6*4)(r31)                    /* Get a GPR */
                    368:                        lwz             r7,CSAgpr+(7*4)(r31)                    /* Get a GPR */
                    369:                        lwz             r8,CSAgpr+(8*4)(r31)                    /* Get a GPR */
                    370:                        lwz             r9,CSAgpr+(9*4)(r31)                    /* Get a GPR */
                    371:                        lwz             r10,CSAgpr+(10*4)(r31)                  /* Get a GPR */
                    372:                        lwz             r11,CSAgpr+(11*4)(r31)                  /* Get a GPR */
                    373:                        lwz             r12,CSAgpr+(12*4)(r31)                  /* Get a GPR */
                    374:                        lwz             r13,CSAgpr+(13*4)(r31)                  /* Get a GPR */
                    375:                        lwz             r14,CSAgpr+(14*4)(r31)                  /* Get a GPR */
                    376:                        lwz             r15,CSAgpr+(15*4)(r31)                  /* Get a GPR */
                    377:                        lwz             r16,CSAgpr+(16*4)(r31)                  /* Get a GPR */
                    378:                        lwz             r17,CSAgpr+(17*4)(r31)                  /* Get a GPR */
                    379:                        lwz             r18,CSAgpr+(18*4)(r31)                  /* Get a GPR */
                    380:                        lwz             r19,CSAgpr+(19*4)(r31)                  /* Get a GPR */
                    381:                        lwz             r20,CSAgpr+(20*4)(r31)                  /* Get a GPR */
                    382:                        lwz             r21,CSAgpr+(21*4)(r31)                  /* Get a GPR */
                    383:                        lwz             r22,CSAgpr+(22*4)(r31)                  /* Get a GPR */
                    384:                        lwz             r23,CSAgpr+(23*4)(r31)                  /* Get a GPR */
                    385:                        lwz             r24,CSAgpr+(24*4)(r31)                  /* Get a GPR */
                    386:                        lwz             r25,CSAgpr+(25*4)(r31)                  /* Get a GPR */
                    387:                        lwz             r26,CSAgpr+(26*4)(r31)                  /* Get a GPR */
                    388:                        lwz             r27,CSAgpr+(27*4)(r31)                  /* Get a GPR */
                    389:                        lwz             r28,CSAgpr+(28*4)(r31)                  /* Get a GPR */
                    390:                        lwz             r29,CSAgpr+(29*4)(r31)                  /* Get a GPR */
                    391:                        lwz             r30,CSAgpr+(30*4)(r31)                  /* Get a GPR */
                    392:                        lwz             r31,CSAgpr+(31*4)(r31)                  /* Get a GPR */
                    393:                        
                    394:                        sync                                                                    /* Make sure we're sunk */
                    395: 
                    396:                        rfi                                                                             /* Get the whole shebang going... */
                    397: 
                    398:                        .long   0
                    399:                        .long   0
                    400:                        .long   0
                    401:                        .long   0
                    402:                        .long   0
                    403:                        .long   0
                    404:                        .long   0
                    405:                        .long   0
                    406: 
                    407: 
                    408: 
                    409: 
                    410: /*
                    411:  *                     This routine handles requests to firmware from another processor.  It is actually the second level
                    412:  *                     of a three level signaling protocol.  The first level is handled in the physical MP driver. It is the 
                    413:  *                     basic physical control for the processor, e.g., physical stop, reset, start.  The second level (this
                    414:  *                     one) handles cross-processor firmware requests, e.g., complete TLB purges.  The last are AST requests
                    415:  *                     which are handled directly by mach.
                    416:  *
                    417:  *                     If this code handles the request (based upon MPPICParm0BU which is valid until the next SIGP happens -
                    418:  *                     actually, don't count on it once you enable) it will RFI back to the 
                    419:  *                     interrupted code.  If not, it will return and let the higher level interrupt handler be called.
                    420:  *
                    421:  *                     We need to worry about registers we use here, check in lowmem_vectors to see what is boten and verboten.
                    422:  *
                    423:  *                     Note that there are no functions implemented yet.
                    424:  */
                    425: 
                    426: 
                    427: ENTRY(MPsignalFW, TAG_NO_FRAME_USED)
                    428: 
                    429: 
                    430:                        mfspr   r7,pir                                                  /* Get the processor address */
                    431:                        lis             r6,HIGH_ADDR(EXT(MPPICPUs))             /* Get high part of CPU control block array */
                    432:                        rlwinm  r7,r7,5,23,26                                   /* Get index into CPU array */
                    433:                        ori             r6,r6,HIGH_ADDR(EXT(MPPICPUs))  /* Get low part of CPU control block array */
                    434:                        add             r7,r7,r6                                                /* Point to the control block for this processor */
                    435:                        lwz             r6,MPPICParm0BU(r7)                             /* Just pick this up for now */
                    436:                        blr                                                                             /* Leave... */
                    437: 
                    438: 
                    439: /*
                    440:  *                     Make space for the maximum supported CPUs in the data section
                    441:  */
                    442:        
                    443: #ifdef __ELF__
                    444:                        .section ".data"
                    445: #else
                    446:                        .data
                    447: #endif
                    448:                        .align  5
                    449: EXT(CSA):
                    450:                        .set    ., .+(CSAsize*NCPUS)
                    451: #ifndef __MACHO__
                    452:                        .type   EXT(CSA), @object
                    453:                        .size   EXT(CSA), CSAsize*NCPUS
                    454: #endif
                    455:                        .globl  EXT(CSA)

unix.superglobalmegacorp.com

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