Annotation of XNU/osfmk/ppc/cpu.c, 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:  *     File:   ppc/cpu.c
                     24:  *
                     25:  *     cpu specific  routines
                     26:  */
                     27: 
                     28: #include <kern/machine.h>
                     29: #include <kern/misc_protos.h>
                     30: #include <kern/thread.h>
                     31: #include <kern/processor.h>
                     32: #include <mach/machine.h>
                     33: #include <mach/processor_info.h>
                     34: #include <mach/mach_types.h>
                     35: #include <ppc/proc_reg.h>
                     36: #include <ppc/misc_protos.h>
                     37: #include <ppc/machine_routines.h>
                     38: #include <ppc/machine_cpu.h>
                     39: #include <ppc/exception.h>
                     40: #include <pexpert/pexpert.h>
                     41: #include <pexpert/ppc/powermac.h>
                     42: 
                     43: /* TODO: BOGUS TO BE REMOVED */
                     44: int real_ncpus = 1;
                     45: 
                     46: int wncpu = NCPUS;
                     47: resethandler_t resethandler_target;
                     48: 
                     49: #define MMCR0_SUPPORT_MASK 0xf83f1fff
                     50: #define MMCR1_SUPPORT_MASK 0xffc00000
                     51: #define MMCR2_SUPPORT_MASK 0x80000000
                     52: 
                     53: extern int debugger_pending[NCPUS];    
                     54: extern int debugger_is_slave[NCPUS];
                     55: extern int debugger_holdoff[NCPUS];
                     56: extern int debugger_sync;
                     57: 
                     58: 
                     59: kern_return_t
                     60: cpu_control(
                     61:        int                     slot_num,
                     62:        processor_info_t        info,
                     63:        unsigned int            count)
                     64: {
                     65:         cpu_type_t        cpu_type;
                     66:         cpu_subtype_t     cpu_subtype;
                     67:        processor_pm_regs_t  perf_regs;
                     68:        processor_control_cmd_t cmd;
                     69:        boolean_t oldlevel;
                     70: 
                     71:        cpu_type = machine_slot[slot_num].cpu_type;
                     72:        cpu_subtype = machine_slot[slot_num].cpu_subtype;
                     73:        cmd = (processor_control_cmd_t) info;
                     74: 
                     75:        if (count < PROCESSOR_CONTROL_CMD_COUNT)
                     76:          return(KERN_FAILURE);
                     77: 
                     78:        if ( cpu_type != cmd->cmd_cpu_type ||
                     79:             cpu_subtype != cmd->cmd_cpu_subtype)
                     80:          return(KERN_FAILURE);
                     81: 
                     82:        switch (cmd->cmd_op)
                     83:          {
                     84:          case PROCESSOR_PM_CLR_PMC:       /* Clear Performance Monitor Counters */
                     85:            switch (cpu_subtype)
                     86:              {
                     87:              case CPU_SUBTYPE_POWERPC_604:
                     88:                {
                     89:                  oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                     90:                  mtpmc1(0x0);
                     91:                  mtpmc2(0x0);
                     92:                  ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                     93:                  return(KERN_SUCCESS);
                     94:                }
                     95:              case CPU_SUBTYPE_POWERPC_604e:
                     96:              case CPU_SUBTYPE_POWERPC_750:
                     97:              case CPU_SUBTYPE_POWERPC_Max:
                     98:                {
                     99:                  oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    100:                  mtpmc1(0x0);
                    101:                  mtpmc2(0x0);
                    102:                  mtpmc3(0x0);
                    103:                  mtpmc4(0x0);
                    104:                  ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    105:                  return(KERN_SUCCESS);
                    106:                }
                    107:              default:
                    108:                return(KERN_FAILURE);
                    109:              } /* cpu_subtype */
                    110:          case PROCESSOR_PM_SET_REGS:      /* Set Performance Monitor Registors */
                    111:            switch (cpu_subtype)
                    112:              {
                    113:              case CPU_SUBTYPE_POWERPC_604:
                    114:                if (count <  (PROCESSOR_CONTROL_CMD_COUNT 
                    115:                               + PROCESSOR_PM_REGS_COUNT_POWERPC_604))
                    116:                  return(KERN_FAILURE);
                    117:                else
                    118:                  {
                    119:                    perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
                    120:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    121:                    mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
                    122:                    mtpmc1(PERFMON_PMC1(perf_regs));
                    123:                    mtpmc2(PERFMON_PMC2(perf_regs));
                    124:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    125:                    return(KERN_SUCCESS);
                    126:                  }
                    127:              case CPU_SUBTYPE_POWERPC_604e:
                    128:              case CPU_SUBTYPE_POWERPC_750:
                    129:                if (count <  (PROCESSOR_CONTROL_CMD_COUNT +
                    130:                       PROCESSOR_PM_REGS_COUNT_POWERPC_750))
                    131:                  return(KERN_FAILURE);
                    132:                else
                    133:                  {
                    134:                    perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
                    135:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    136:                    mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
                    137:                    mtpmc1(PERFMON_PMC1(perf_regs));
                    138:                    mtpmc2(PERFMON_PMC2(perf_regs));
                    139:                    mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
                    140:                    mtpmc3(PERFMON_PMC3(perf_regs));
                    141:                    mtpmc4(PERFMON_PMC4(perf_regs));
                    142:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    143:                    return(KERN_SUCCESS);
                    144:                  }
                    145:              case CPU_SUBTYPE_POWERPC_Max:
                    146:                if (count <  (PROCESSOR_CONTROL_CMD_COUNT +
                    147:                       PROCESSOR_PM_REGS_COUNT_POWERPC_Max))
                    148:                  return(KERN_FAILURE);
                    149:                else
                    150:                  {
                    151:                    perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
                    152:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    153:                    mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
                    154:                    mtpmc1(PERFMON_PMC1(perf_regs));
                    155:                    mtpmc2(PERFMON_PMC2(perf_regs));
                    156:                    mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
                    157:                    mtpmc3(PERFMON_PMC3(perf_regs));
                    158:                    mtpmc4(PERFMON_PMC4(perf_regs));
                    159:                    mtmmcr2(PERFMON_MMCR2(perf_regs) & MMCR2_SUPPORT_MASK);
                    160:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    161:                    return(KERN_SUCCESS);
                    162:                  }
                    163:              default:
                    164:                return(KERN_FAILURE);
                    165:              } /* switch cpu_subtype */
                    166:          case PROCESSOR_PM_SET_MMCR:
                    167:            switch (cpu_subtype)
                    168:              {
                    169:              case CPU_SUBTYPE_POWERPC_604:
                    170:                if (count < (PROCESSOR_CONTROL_CMD_COUNT +
                    171:                       PROCESSOR_PM_REGS_COUNT_POWERPC_604))
                    172:                  return(KERN_FAILURE);
                    173:                else
                    174:                  {
                    175:                    perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
                    176:                    mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
                    177:                    return(KERN_SUCCESS);
                    178:                  }
                    179:              case CPU_SUBTYPE_POWERPC_604e:
                    180:              case CPU_SUBTYPE_POWERPC_750:
                    181:                if (count < (PROCESSOR_CONTROL_CMD_COUNT +
                    182:                      PROCESSOR_PM_REGS_COUNT_POWERPC_750))
                    183:                  return(KERN_FAILURE);
                    184:                else
                    185:                  {
                    186:                    perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
                    187:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    188:                    mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
                    189:                    mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
                    190:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    191:                    return(KERN_SUCCESS);
                    192:                  }
                    193:              case CPU_SUBTYPE_POWERPC_Max:
                    194:                if (count < (PROCESSOR_CONTROL_CMD_COUNT +
                    195:                      PROCESSOR_PM_REGS_COUNT_POWERPC_Max))
                    196:                  return(KERN_FAILURE);
                    197:                else
                    198:                  {
                    199:                    perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
                    200:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    201:                    mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
                    202:                    mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
                    203:                    mtmmcr2(PERFMON_MMCR2(perf_regs) & MMCR2_SUPPORT_MASK);
                    204:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    205:                    return(KERN_SUCCESS);
                    206:                  }
                    207:              default:
                    208:                return(KERN_FAILURE);
                    209:              } /* cpu_subtype */
                    210:          default:
                    211:            return(KERN_FAILURE);
                    212:          } /* switch cmd_op */
                    213: }
                    214: 
                    215: kern_return_t
                    216: cpu_info(
                    217:        processor_flavor_t      flavor,
                    218:        int                     slot_num,
                    219:        processor_info_t        info,
                    220:        unsigned int            *count)
                    221: {
                    222:         cpu_subtype_t     cpu_subtype;
                    223:        processor_pm_regs_t  perf_regs;
                    224:        boolean_t oldlevel;
                    225: 
                    226:        cpu_subtype = machine_slot[slot_num].cpu_subtype;
                    227: 
                    228:        switch (flavor)
                    229:          {
                    230:          case PROCESSOR_PM_REGS_INFO:
                    231:            {
                    232:              perf_regs = (processor_pm_regs_t) info;
                    233: 
                    234:              switch (cpu_subtype)
                    235:                {
                    236:                case CPU_SUBTYPE_POWERPC_604:
                    237:                  {
                    238:                    if (*count < PROCESSOR_PM_REGS_COUNT_POWERPC_604)
                    239:                      return(KERN_FAILURE);
                    240:              
                    241:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    242:                    PERFMON_MMCR0(perf_regs) = mfmmcr0();
                    243:                    PERFMON_PMC1(perf_regs)  = mfpmc1();
                    244:                    PERFMON_PMC2(perf_regs)  = mfpmc2();
                    245:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    246: 
                    247:                    *count = PROCESSOR_PM_REGS_COUNT_POWERPC_604;
                    248:                    return(KERN_SUCCESS);
                    249:                  }
                    250:                case CPU_SUBTYPE_POWERPC_604e:
                    251:                case CPU_SUBTYPE_POWERPC_750:
                    252:                  {
                    253:                    if (*count < PROCESSOR_PM_REGS_COUNT_POWERPC_750)
                    254:                      return(KERN_FAILURE);
                    255:              
                    256:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    257:                    PERFMON_MMCR0(perf_regs) = mfmmcr0();
                    258:                    PERFMON_PMC1(perf_regs)  = mfpmc1();
                    259:                    PERFMON_PMC2(perf_regs)  = mfpmc2();
                    260:                    PERFMON_MMCR1(perf_regs) = mfmmcr1();
                    261:                    PERFMON_PMC3(perf_regs)  = mfpmc3();
                    262:                    PERFMON_PMC4(perf_regs)  = mfpmc4();
                    263:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    264: 
                    265:                    *count = PROCESSOR_PM_REGS_COUNT_POWERPC_750;
                    266:                    return(KERN_SUCCESS);
                    267:                  }
                    268:                case CPU_SUBTYPE_POWERPC_Max:
                    269:                  {
                    270:                    if (*count < PROCESSOR_PM_REGS_COUNT_POWERPC_Max)
                    271:                      return(KERN_FAILURE);
                    272:              
                    273:                    oldlevel = ml_set_interrupts_enabled(FALSE);    /* disable interrupts */
                    274:                    PERFMON_MMCR0(perf_regs) = mfmmcr0();
                    275:                    PERFMON_PMC1(perf_regs)  = mfpmc1();
                    276:                    PERFMON_PMC2(perf_regs)  = mfpmc2();
                    277:                    PERFMON_MMCR1(perf_regs) = mfmmcr1();
                    278:                    PERFMON_PMC3(perf_regs)  = mfpmc3();
                    279:                    PERFMON_PMC4(perf_regs)  = mfpmc4();
                    280:                    PERFMON_MMCR2(perf_regs) = mfmmcr2();
                    281:                    ml_set_interrupts_enabled(oldlevel);     /* enable interrupts */
                    282: 
                    283:                    *count = PROCESSOR_PM_REGS_COUNT_POWERPC_Max;
                    284:                    return(KERN_SUCCESS);
                    285:                  }
                    286:                default:
                    287:                  return(KERN_FAILURE);
                    288:                } /* switch cpu_subtype */
                    289:            } /* PROCESSOR_PM_REGS_INFO */
                    290:          default:
                    291:            return(KERN_INVALID_ARGUMENT);
                    292:          } /* flavor */
                    293: }
                    294: 
                    295: cpu_init()
                    296: {
                    297:        int     cpu;
                    298:        cpu_subtype_t   t;
                    299: 
                    300:        cpu = cpu_number();
                    301: 
                    302:        machine_slot[cpu].running = TRUE;
                    303:        machine_slot[cpu].cpu_type = CPU_TYPE_POWERPC;
                    304: 
                    305:        switch (PROCESSOR_VERSION) {
                    306:                case PROCESSOR_VERSION_601:             /* 601 */
                    307:                        t = CPU_SUBTYPE_POWERPC_601; break;
                    308:                case PROCESSOR_VERSION_603:             /* ? */
                    309:                        t = CPU_SUBTYPE_POWERPC_603; break;
                    310:                case PROCESSOR_VERSION_604:             /* ? */
                    311:                        t = CPU_SUBTYPE_POWERPC_604; break;
                    312:                case 5:                                 /* ? */
                    313:                        t = CPU_SUBTYPE_POWERPC_602; break;
                    314:                case PROCESSOR_VERSION_603e:            /* ? */
                    315:                        t = CPU_SUBTYPE_POWERPC_603e; break;
                    316:                case 7:                                 /* ? */
                    317:                        t = CPU_SUBTYPE_POWERPC_603ev; break;
                    318:                case PROCESSOR_VERSION_604e:            /* ? */
                    319:                case PROCESSOR_VERSION_604ev:           /* ? */
                    320:                        __asm__ volatile("mtspr 1023,%0" : : "r" (cpu));        /* Set logical CPU into the PIR */
                    321:                        t = CPU_SUBTYPE_POWERPC_604e; break;
                    322:                case PROCESSOR_VERSION_750:             /* ? */
                    323:                        t = CPU_SUBTYPE_POWERPC_750; break;
                    324:                case PROCESSOR_VERSION_Max:            /* Max */
                    325:                        __asm__ volatile("mtspr 1023,%0" : : "r" (cpu));        /* Set logical CPU into the PIR */
                    326:                        t = CPU_SUBTYPE_POWERPC_Max; break;
                    327:                default:
                    328:                        t = CPU_SUBTYPE_POWERPC_ALL; break;
                    329:        }
                    330:        machine_slot[cpu].cpu_subtype = t;
                    331: 
                    332: }
                    333: 
                    334: void
                    335: cpu_machine_init(
                    336:        void)
                    337: {
                    338:        /* TODO: realese mutex lock reset_handler_lock */
                    339: 
                    340:        PE_cpu_machine_init(per_proc_info[cpu_number()].cpu_id);
                    341: }
                    342: 
                    343: kern_return_t
                    344: cpu_register(
                    345:        int *target_cpu
                    346: )
                    347: {
                    348:        int cpu;
                    349: 
                    350:        /* 
                    351:         * TODO: 
                    352:         * - Run cpu_register() in exclusion mode 
                    353:         */
                    354: 
                    355:        *target_cpu = -1;
                    356:        for(cpu=0; cpu < wncpu; cpu++) {
                    357:                if(!machine_slot[cpu].is_cpu) {
                    358:                        machine_slot[cpu].is_cpu = TRUE;
                    359:                        *target_cpu = cpu;
                    360:                        break;
                    361:                }
                    362:        }
                    363:        if (*target_cpu != -1) {
                    364:                real_ncpus++;
                    365:                return KERN_SUCCESS;
                    366:        } else
                    367:                return KERN_FAILURE;
                    368: }
                    369: 
                    370: kern_return_t
                    371: cpu_start(
                    372:        int cpu)
                    373: {
                    374:        struct per_proc_info    *proc_info;
                    375:        kern_return_t           ret;
                    376: 
                    377:        extern void (*exception_handlers[])(void);
                    378:        extern vm_offset_t      intstack;
                    379:        extern vm_offset_t      debstack;
                    380: 
                    381:        if (cpu == master_cpu) {
                    382:          PE_cpu_machine_init(per_proc_info[cpu].cpu_id);
                    383:          
                    384:          return KERN_SUCCESS;
                    385:        }
                    386: 
                    387:        proc_info = &per_proc_info[cpu];
                    388: 
                    389:        proc_info->cpu_number = cpu;
                    390:        proc_info->cpu_flags = 0;
                    391:        proc_info->istackptr = (vm_offset_t)&intstack + (INTSTACK_SIZE*(cpu+1)) - sizeof (struct ppc_saved_state);
                    392:        proc_info->intstack_top_ss = proc_info->istackptr;
                    393: #if     MACH_KDP || MACH_KDB
                    394:        proc_info->debstackptr = (vm_offset_t)&debstack + (KERNEL_STACK_SIZE*(cpu+1)) - sizeof (struct ppc_saved_state);
                    395:        proc_info->debstack_top_ss = proc_info->debstackptr;
                    396: #endif  /* MACH_KDP || MACH_KDB */
                    397:        proc_info->phys_exception_handlers = 
                    398:                                kvtophys((vm_offset_t)&exception_handlers);
                    399:        proc_info->get_interrupts_enabled = fake_get_interrupts_enabled;
                    400:        proc_info->set_interrupts_enabled = fake_set_interrupts_enabled;
                    401:        proc_info->virt_per_proc_info = (unsigned int)proc_info;
                    402:        proc_info->active_kloaded = (unsigned int)&active_kloaded[cpu];
                    403:        proc_info->cpu_data = (unsigned int)&cpu_data[cpu];
                    404:        proc_info->active_stacks = (unsigned int)&active_stacks[cpu];
                    405:        proc_info->need_ast = (unsigned int)&need_ast[cpu];
                    406:        proc_info->FPU_thread = 0;
                    407: 
                    408:        if (cpu != cpu_number()) {
                    409:                extern void _start_cpu(void);
                    410: 
                    411:                if (proc_info->start_paddr == EXCEPTION_VECTOR(T_RESET)) {
                    412: 
                    413:                        /* TODO: get mutex lock reset_handler_lock */
                    414: 
                    415:                        resethandler_target.type = RESET_HANDLER_START;
                    416:                        resethandler_target.call_paddr = kvtophys((vm_offset_t)_start_cpu); 
                    417:                        resethandler_target.arg__paddr = kvtophys((vm_offset_t)proc_info);
                    418:                        
                    419:                        ml_phys_write((vm_offset_t)&ResetHandler + 0,
                    420:                                      resethandler_target.type);
                    421:                        ml_phys_write((vm_offset_t)&ResetHandler + 4,
                    422:                                      resethandler_target.call_paddr);
                    423:                        ml_phys_write((vm_offset_t)&ResetHandler + 8,
                    424:                                      resethandler_target.arg__paddr);
                    425:                                          
                    426:                        __asm__ volatile("sync");                               /* Commit to storage */
                    427:                        __asm__ volatile("isync");                              /* Wait a second */
                    428:                }
                    429: 
                    430:                ret = PE_cpu_start(proc_info->cpu_id, 
                    431:                                        proc_info->start_paddr, (vm_offset_t)proc_info);
                    432: 
                    433:                if (ret != KERN_SUCCESS && 
                    434:                    proc_info->start_paddr == EXCEPTION_VECTOR(T_RESET)) {
                    435: 
                    436:                        /* TODO: realese mutex lock reset_handler_lock */
                    437:                }
                    438:        }
                    439:        else
                    440:                ret = KERN_SUCCESS;
                    441: 
                    442:        return(ret);
                    443: }
                    444: 
                    445: kern_return_t
                    446: cpu_signal_handler_register()
                    447: {
                    448: }
                    449: 
                    450: 
                    451: /*
                    452:  *     Here is where we implement the receiver of the signaling protocol.
                    453:  *     We wait for the signal status area to be passed to us. Then we snarf
                    454:  *     up the status, the sender, and the 3 potential parms. Next we release
                    455:  *     the lock and signal the other guy.
                    456:  */
                    457: 
                    458: void cpu_signal_handler(void) {
                    459: 
                    460:        unsigned int holdStat, holdParm0, holdParm1, holdParm2, mtype;
                    461:        struct per_proc_info *pproc;                                    /* Area for my per_proc address */
                    462:        int cpu;
                    463:        
                    464:        cpu = cpu_number();                                                             /* Get the CPU number */
                    465:        pproc = &per_proc_info[cpu];                                    /* Point to our block */
                    466: 
                    467: /*
                    468:  *     Since we've been signaled, wait just under 1ms for the signal lock to pass
                    469:  */
                    470:        if(!hw_lock_mbits(&pproc->MPsigpStat, MPsigpMsgp, (MPsigpBusy | MPsigpPass),
                    471:          (MPsigpBusy | MPsigpPass), (powermac_info.bus_clock_rate_hz >> 7))) {
                    472:                panic("cpu_signal_handler: Lock pass timed out\n");
                    473:        }
                    474:        
                    475:        holdStat = pproc->MPsigpStat;                                   /* Snarf stat word */
                    476:        holdParm0 = pproc->MPsigpParm0;                                 /* Snarf parameter */
                    477:        holdParm1 = pproc->MPsigpParm1;                                 /* Snarf parameter */
                    478:        holdParm2 = pproc->MPsigpParm2;                                 /* Snarf parameter */
                    479:        
                    480:        __asm__ volatile("isync");                                              /* Make sure we don't unlock until memory is in */
                    481: 
                    482:        pproc->MPsigpStat = holdStat & ~(MPsigpMsgp | MPsigpFunc);      /* Release lock */
                    483: 
                    484:        switch ((holdStat & MPsigpFunc) >> 8) {                 /* Decode function code */
                    485: 
                    486:                case MPsigpIdle:                                                        /* Was function cancelled? */
                    487:                        return;                                                                 /* Yup... */
                    488:                        
                    489:                case MPsigpSigp:                                                        /* Signal Processor message? */
                    490:                        
                    491:                        switch (holdParm0) {                                    /* Decode SIGP message order */
                    492: 
                    493:                                case SIGPast:                                           /* Should we do an AST? */
                    494: #if 0
                    495:                                        ast_check();                                    /* Yes, do it */
                    496: #else
                    497:                                        kprintf("cpu_signal_handler: AST request disabled\n");
                    498: #endif
                    499:                                        return;                                                 /* All done... */
                    500:        
                    501:                                case SIGPdebug:                                         /* Enter the debugger? */               
                    502: 
                    503:                                        debugger_is_slave[cpu]++;               /* Bump up the count to show we're here */
                    504:                                        hw_atomic_sub(&debugger_sync, 1);       /* Show we've received the 'rupt */
                    505:                                        __asm__ volatile("tw 4,r3,r3"); /* Enter the debugger */
                    506:                                        return;                                                 /* All done now... */
                    507:                                        
                    508:                                case SIGPwake:                                          /* Wake up CPU */
                    509:                                        return;                                                 /* No need to do anything, the interrupt does it all... */
                    510:                                        
                    511:                                default:
                    512: #if DEBUG
                    513:                                        kprintf("cpu_signal_handler: unknown SIGP message order - %08X\n", holdParm0);
                    514: #endif                 
                    515:                                        return;
                    516:                        
                    517:                        }
                    518:        
                    519:                default:
                    520: #if DEBUG
                    521:                        kprintf("cpu_signal_handler: unknown SIGP function - %08X\n", (holdStat & MPsigpFunc) >> 8);
                    522: #endif                 
                    523:                        return;
                    524:        
                    525:        }
                    526:        panic("cpu_signal_handler: we should never get here\n");
                    527: }
                    528: 
                    529: /*
                    530:  *     Here is where we send a message to another processor.  So far we only have two:
                    531:  *     SIGPast and SIGPdebug.  SIGPast is used to preempt and kick off threads (this is
                    532:  *     currently disabled). SIGPdebug is used to enter the debugger.
                    533:  *
                    534:  *     We set up the SIGP function to indicate that this is a simple message and set the
                    535:  *     order code (MPsigpParm0) to SIGPast or SIGPdebug). After finding the per_processor
                    536:  *     block for the target, we lock the message block. Then we set the parameter(s). 
                    537:  *     Next we change the lock (also called "busy") to "passing" and finally signal
                    538:  *     the other processor. Note that we only wait about 1ms to get the message lock.  
                    539:  *     If we time out, we return failure to our caller. It is their responsibility to
                    540:  *     recover.
                    541:  */
                    542: 
                    543: kern_return_t cpu_signal(int target, int signal) {     /* Signal the target CPU */
                    544: 
                    545:        unsigned int holdStat, holdParm0, holdParm1, holdParm2, mtype;
                    546:        struct per_proc_info *tpproc, *mpproc;                  /* Area for per_proc addresses */
                    547:        int cpu;
                    548: 
                    549: #if DEBUG
                    550:        if(target > NCPUS) panic("cpu_signal: invalid target CPU - %08X\n", target);
                    551: #endif
                    552: 
                    553:        cpu = cpu_number();                                                             /* Get our CPU number */
                    554:        if(target == cpu) return KERN_FAILURE;                  /* Don't play with ourselves */
                    555:        if(!machine_slot[target].running) return KERN_FAILURE;  /* These guys are too young */  
                    556: 
                    557:        mpproc = &per_proc_info[cpu];                                   /* Point to our block */
                    558:        tpproc = &per_proc_info[target];                                /* Point to the target's block */
                    559:        
                    560:        if(!hw_lock_mbits(&tpproc->MPsigpStat, MPsigpMsgp, 0, MPsigpBusy, 
                    561:          (powermac_info.bus_clock_rate_hz >> 7))) {    /* Try to lock the message block */
                    562:                return KERN_FAILURE;                                            /* Timed out, take your ball and go home... */
                    563:        }
                    564: 
                    565:        holdStat = MPsigpBusy | MPsigpPass | (MPsigpSigp << 8) | cpu;   /* Set up the signal status word */
                    566:        tpproc->MPsigpParm0 = signal;                                   /* Set message order */
                    567:        tpproc->MPsigpParm1 = 0;                                                /* Clear additional parms for yuks */
                    568:        tpproc->MPsigpParm2 = 0;                                                /* Clear additional parms for yuks */
                    569:        
                    570:        __asm__ volatile("sync");                                               /* Make sure it's all there */
                    571:        
                    572:        tpproc->MPsigpStat = holdStat;                                  /* Set status and pass the lock */
                    573:        __asm__ volatile("eieio");                                              /* I'm a paraniod freak */
                    574:        
                    575:        PE_cpu_signal(mpproc->cpu_id, tpproc->cpu_id);  /* Kick the other processor */
                    576: 
                    577:        return KERN_SUCCESS;                                                    /* All is goodness and rainbows... */
                    578: }
                    579: 
                    580: /*
                    581:  * TODO
                    582:  */
                    583: void init_ast_check(processor_t processor) 
                    584: {}
                    585: 
                    586: void cause_ast_check(processor_t processor)
                    587: {}       
                    588: 
                    589: void
                    590: switch_to_shutdown_context(
                    591:        thread_t        thread,
                    592:        void            (*doshutdown)(processor_t),
                    593:        processor_t     processor)
                    594: { 
                    595:        printf("switch_to_shutdown_processor: not implemented\n");
                    596: }
                    597:  

unix.superglobalmegacorp.com

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