Annotation of XNU/iokit/Kernel/IOCPU.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved.
                      3:  *
                      4:  *  DRI: Josh de Cesare
                      5:  *
                      6:  */
                      7: 
                      8: extern "C" {
                      9: #include <machine/machine_routines.h>
                     10: #include <pexpert/pexpert.h>
                     11: }
                     12: 
                     13: #include <IOKit/IOLib.h>
                     14: #include <IOKit/IOPlatformExpert.h>
                     15: #include <IOKit/IOCPU.h>
                     16: 
                     17: 
                     18: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     19: 
                     20: kern_return_t PE_cpu_start(cpu_id_t target,
                     21:                           vm_offset_t start_paddr, vm_offset_t arg_paddr)
                     22: {
                     23:   IOCPU *targetCPU = OSDynamicCast(IOCPU, (OSObject *)target);
                     24:   
                     25:   if (targetCPU == 0) return KERN_FAILURE;
                     26:   return targetCPU->startCPU(start_paddr, arg_paddr);
                     27: }
                     28: 
                     29: void PE_cpu_halt(cpu_id_t target,
                     30:                 vm_offset_t start_paddr, vm_offset_t arg_paddr)
                     31: {
                     32:   IOCPU *targetCPU = OSDynamicCast(IOCPU, (OSObject *)target);
                     33:   
                     34:   if (targetCPU) targetCPU->haltCPU(start_paddr, arg_paddr);
                     35: }
                     36: 
                     37: void PE_cpu_signal(cpu_id_t source, cpu_id_t target)
                     38: {
                     39:   IOCPU *sourceCPU = OSDynamicCast(IOCPU, (OSObject *)source);
                     40:   IOCPU *targetCPU = OSDynamicCast(IOCPU, (OSObject *)target);
                     41:   
                     42:   if (sourceCPU && targetCPU) sourceCPU->signalCPU(targetCPU);
                     43: }
                     44: 
                     45: void PE_cpu_machine_init(cpu_id_t target)
                     46: {
                     47:   IOCPU *targetCPU = OSDynamicCast(IOCPU, (OSObject *)target);
                     48:   
                     49:   if (targetCPU) targetCPU->initCPU();
                     50: }
                     51: 
                     52: 
                     53: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     54: 
                     55: #define super IOService
                     56: 
                     57: OSDefineMetaClass(IOCPU, IOService);
                     58: OSDefineAbstractStructors(IOCPU, IOService);
                     59: 
                     60: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     61: 
                     62: static OSDictionary *gIOCPUs;
                     63: 
                     64: void IOCPU::initCPUs(void)
                     65: {
                     66:   gIOCPUs = OSDictionary::withCapacity(1);
                     67: }
                     68: 
                     69: bool IOCPU::start(IOService *provider)
                     70: {
                     71:   if (!super::start(provider)) return false;
                     72:   
                     73:   cpuGroup = gIOCPUs;  
                     74:   cpuNub = provider;
                     75:   
                     76:   cpuState = kIOCPUStateUnregistered;
                     77:   
                     78:   return true;
                     79: }
                     80: 
                     81: void IOCPU::initCPU(void)
                     82: {
                     83:   // Do default interrupt stuff.
                     84:   
                     85:   
                     86:   cpuState = kIOCPUStateRunning;
                     87: }
                     88: 
                     89: kern_return_t IOCPU::startCPU(vm_offset_t /*start_paddr*/,
                     90:                              vm_offset_t /*arg_paddr*/)
                     91: {
                     92:   return KERN_FAILURE;
                     93: }
                     94: 
                     95: void IOCPU::haltCPU(vm_offset_t /*start_paddr*/,
                     96:                    vm_offset_t /*arg_paddr*/)
                     97: {
                     98: }
                     99: 
                    100: void IOCPU::signalCPU(IOCPU */*target*/)
                    101: {
                    102: }
                    103: 
                    104: int IOCPU::getCPUNumber(void)
                    105: {
                    106:   return physCPU;
                    107: }
                    108: 
                    109: int IOCPU::getCPUState(void)
                    110: {
                    111:   return cpuState;
                    112: }
                    113: 
                    114: OSDictionary *IOCPU::getCPUGroup(void)
                    115: {
                    116:   return cpuGroup;
                    117: }
                    118: 
                    119: int IOCPU::getCPUGroupSize(void)
                    120: {
                    121:   return cpuGroup->getCount();
                    122: }
                    123: 
                    124: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    125: 
                    126: #undef super
                    127: #define super IOInterruptController
                    128: 
                    129: OSDefineMetaClassAndStructors(IOCPUInterruptController, IOInterruptController);
                    130: 
                    131: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    132: 
                    133: 
                    134: IOReturn IOCPUInterruptController::initCPUInterruptController(int sources)
                    135: {
                    136:   int cnt;
                    137:   
                    138:   if (!super::init()) return kIOReturnInvalid;
                    139:   
                    140:   numCPUs = sources;
                    141:   
                    142:   cpus = (IOCPU **)IOMalloc(numCPUs * sizeof(IOCPU *));
                    143:   if (cpus == 0) return kIOReturnNoMemory;
                    144:   bzero(cpus, numCPUs * sizeof(IOCPU *));
                    145:   
                    146:   vectors = (IOInterruptVector *)IOMalloc(numCPUs * sizeof(IOInterruptVector));
                    147:   if (vectors == 0) return kIOReturnNoMemory;
                    148:   bzero(vectors, numCPUs * sizeof(IOInterruptVector));
                    149:   
                    150:   // Allocate locks for the
                    151:   for (cnt = 0; cnt < numCPUs; cnt++) {
                    152:     vectors[cnt].interruptLock = IOLockAlloc();
                    153:     if (vectors[cnt].interruptLock == NULL) {
                    154:       for (cnt = 0; cnt < numCPUs; cnt++) {
                    155:        if (vectors[cnt].interruptLock != NULL)
                    156:          IOLockFree(vectors[cnt].interruptLock);
                    157:       }
                    158:       return kIOReturnNoResources;
                    159:     }
                    160:   }
                    161:   
                    162:   return kIOReturnSuccess;
                    163: }
                    164: 
                    165: void IOCPUInterruptController::registerCPUInterruptController(void)
                    166: {
                    167:   registerService();
                    168:   
                    169:   getPlatform()->registerInterruptController(gPlatformInterruptControllerName,
                    170:                                             this);
                    171: }
                    172: 
                    173: void IOCPUInterruptController::setCPUInterruptProperties(IOService *service)
                    174: {
                    175:   int          cnt;
                    176:   OSArray      *controller;
                    177:   OSArray      *specifier;
                    178:   OSData       *tmpData;
                    179:   long         tmpLong;
                    180:   
                    181:   // Create the interrupt specifer array.
                    182:   specifier = OSArray::withCapacity(numCPUs);
                    183:   for (cnt = 0; cnt < numCPUs; cnt++) {
                    184:     tmpLong = cnt;
                    185:     tmpData = OSData::withBytes(&tmpLong, sizeof(tmpLong));
                    186:     specifier->setObject(tmpData);
                    187:     tmpData->release();
                    188:   };
                    189:   
                    190:   // Create the interrupt controller array.
                    191:   controller = OSArray::withCapacity(numCPUs);
                    192:   for (cnt = 0; cnt < numCPUs; cnt++) {
                    193:     controller->setObject(gPlatformInterruptControllerName);
                    194:   }
                    195:   
                    196:   // Put the two arrays into the property table.
                    197:   service->setProperty(gIOInterruptControllersKey, controller);
                    198:   service->setProperty(gIOInterruptSpecifiersKey, specifier);
                    199:   controller->release();
                    200:   specifier->release();
                    201: }
                    202: 
                    203: void IOCPUInterruptController::enableCPUInterrupt(IOCPU *cpu)
                    204: {
                    205:   ml_install_interrupt_handler(cpu, cpu->getCPUNumber(), this,
                    206:                                (IOInterruptHandler)&IOCPUInterruptController::handleInterrupt, 0);
                    207:   
                    208:   enabledCPUs++;
                    209:   
                    210:   if (enabledCPUs == numCPUs) thread_wakeup(this);
                    211: }
                    212: 
                    213: IOReturn IOCPUInterruptController::registerInterrupt(IOService *nub,
                    214:                                                     int source,
                    215:                                                     void *target,
                    216:                                                     IOInterruptHandler handler,
                    217:                                                     void *refCon)
                    218: {
                    219:   IOInterruptVector *vector;
                    220:   
                    221:   if (source >= numCPUs) return kIOReturnNoResources;
                    222:   
                    223:   vector = &vectors[source];
                    224:   
                    225:   // Get the lock for this vector.
                    226:   IOTakeLock(vector->interruptLock);
                    227:   
                    228:   // Make sure the vector is not in use.
                    229:   if (vector->interruptRegistered) {
                    230:     IOUnlock(vector->interruptLock);
                    231:     return kIOReturnNoResources;
                    232:   }
                    233:   
                    234:   // Fill in vector with the client's info.
                    235:   vector->handler = handler;
                    236:   vector->nub     = nub;
                    237:   vector->source  = source;
                    238:   vector->target  = target;
                    239:   vector->refCon  = refCon;
                    240:   
                    241:   // Get the vector ready.  It starts hard disabled.
                    242:   vector->interruptDisabledHard = 1;
                    243:   vector->interruptDisabledSoft = 1;
                    244:   vector->interruptRegistered   = 1;
                    245:   
                    246:   IOUnlock(vector->interruptLock);
                    247:   
                    248:   if (enabledCPUs != numCPUs) {
                    249:     assert_wait(this, THREAD_UNINT);
                    250:     thread_block(0);
                    251:   }
                    252:   
                    253:   return kIOReturnSuccess;
                    254: }
                    255: 
                    256: IOReturn IOCPUInterruptController::getInterruptType(IOService */*nub*/,
                    257:                                                    int /*source*/,
                    258:                                                    int *interruptType)
                    259: {
                    260:   if (interruptType == 0) return kIOReturnBadArgument;
                    261:   
                    262:   *interruptType = kIOInterruptTypeLevel;
                    263:   
                    264:   return kIOReturnSuccess;
                    265: }
                    266: 
                    267: IOReturn IOCPUInterruptController::enableInterrupt(IOService */*nub*/,
                    268:                                                   int /*source*/)
                    269: {
                    270: //  ml_set_interrupts_enabled(true);
                    271:   return kIOReturnSuccess;
                    272: }
                    273: 
                    274: IOReturn IOCPUInterruptController::disableInterrupt(IOService */*nub*/,
                    275:                                                    int /*source*/)
                    276: {
                    277: //  ml_set_interrupts_enabled(false);
                    278:   return kIOReturnSuccess;
                    279: }
                    280: 
                    281: IOReturn IOCPUInterruptController::causeInterrupt(IOService */*nub*/,
                    282:                                                  int /*source*/)
                    283: {
                    284:   ml_cause_interrupt();
                    285:   return kIOReturnSuccess;
                    286: }
                    287: 
                    288: IOReturn IOCPUInterruptController::handleInterrupt(void */*refCon*/,
                    289:                                                   IOService */*nub*/,
                    290:                                                   int source)
                    291: {
                    292:   IOInterruptVector *vector;
                    293:   
                    294:   vector = &vectors[source];
                    295:   
                    296:   if (!vector->interruptRegistered) return kIOReturnInvalid;
                    297:   
                    298:   vector->handler(vector->target, vector->refCon,
                    299:                  vector->nub, vector->source);
                    300:   
                    301:   return kIOReturnSuccess;
                    302: }
                    303: 
                    304: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

unix.superglobalmegacorp.com

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