|
|
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: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.