Annotation of XNU/iokit/Kernel/IOCPU.cpp, revision 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.