Annotation of XNU/osfmk/ppc/MPinterfaces.s, revision 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.