|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-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: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 24: * ! 25: * DRI: Josh de Cesare ! 26: */ ! 27: ! 28: #include <IOKit/IOPlatformExpert.h> ! 29: ! 30: #include "GenericInterruptController.h" ! 31: ! 32: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 33: ! 34: #undef super ! 35: #define super IOInterruptController ! 36: ! 37: IODefineMetaClassAndStructors(GenericInterruptController, ! 38: IOInterruptController); ! 39: ! 40: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 41: ! 42: ! 43: bool GenericInterruptController::start(IOService *provider) ! 44: { ! 45: IOInterruptAction handler; ! 46: IOSymbol *interruptControllerName; ! 47: ! 48: // If needed call the parents start. ! 49: if (!super::start(provider)) ! 50: return false; ! 51: ! 52: // Map the device's memory and initalize its state. ! 53: ! 54: // For now you must allocate storage for the vectors. ! 55: // This will probably changed to something like: initVectors(numVectors). ! 56: // In the mean time something like this works well. ! 57: #if 0 ! 58: // Allocate the memory for the vectors. ! 59: vectors = (IOInterruptVector *)IOMalloc(numVectors * ! 60: sizeof(IOInterruptVector)); ! 61: if (vectors == NULL) return false; ! 62: bzero(vectors, numVectors * sizeof(IOInterruptVector)); ! 63: ! 64: // Allocate locks for the vectors. ! 65: for (cnt = 0; cnt < numVectors; cnt++) { ! 66: vectors[cnt].interruptLock = IOLockAlloc(); ! 67: if (vectors[cnt].interruptLock == NULL) { ! 68: for (cnt = 0; cnt < numVectors; cnt++) { ! 69: if (vectors[cnt].interruptLock != NULL) ! 70: IOLockFree(vectors[cnt].interruptLock); ! 71: } ! 72: } ! 73: } ! 74: #endif ! 75: ! 76: // If you know that this interrupt controller is the primary ! 77: // interrupt controller, use this to set it nub properties properly. ! 78: // This may be done by the nub's creator. ! 79: getPlatform()->setCPUInterruptProperties(provider); ! 80: ! 81: // register the interrupt handler so it can receive interrupts. ! 82: handler = getInterruptHandlerAddress(); ! 83: provider->registerInterrupt(0, this, handler, 0); ! 84: ! 85: // Just like any interrupt source, you must enable it to receive interrupts. ! 86: provider->enableInterrupt(0); ! 87: ! 88: // Set interruptControllerName to the proper symbol. ! 89: //interruptControllerName = xxx; ! 90: ! 91: // Register this interrupt controller so clients can find it. ! 92: getPlatform()->registerInterruptController(interruptControllerName, this); ! 93: ! 94: // All done, so return true. ! 95: return true; ! 96: } ! 97: ! 98: IOReturn GenericInterruptController::getInterruptType(IOService *nub, ! 99: int source, ! 100: int *interruptType) ! 101: { ! 102: if (interruptType == 0) return kIOReturnBadArgument; ! 103: ! 104: // Given the nub and source, set interruptType to level or edge. ! 105: ! 106: return kIOReturnSuccess; ! 107: } ! 108: ! 109: // Sadly this just has to be replicated in every interrupt controller. ! 110: IOInterruptAction GenericInterruptController::getInterruptHandlerAddress(void) ! 111: { ! 112: return (IOInterruptAction)handleInterrupt; ! 113: } ! 114: ! 115: // Handle all current interrupts. ! 116: IOReturn GenericInterruptController::handleInterrupt(void * refCon, ! 117: IOService * nub, ! 118: int source) ! 119: { ! 120: IOInterruptVector *vector; ! 121: int vectorNumber; ! 122: ! 123: while (1) { ! 124: // Get vectorNumber from hardware some how and clear the event. ! 125: ! 126: // Break if there are no more vectors to handle. ! 127: if (vectorNumber == 0/*kNoVector*/) break; ! 128: ! 129: // Get the vector's date from the controller's array. ! 130: vector = &vectors[vectorNumber]; ! 131: ! 132: // Set the vector as active. This store must compleat before ! 133: // moving on to prevent the disableInterrupt fuction from ! 134: // geting out of sync. ! 135: vector->interruptActive = 1; ! 136: //sync(); ! 137: //isync(); ! 138: ! 139: // If the vector is not disabled soft, handle it. ! 140: if (!vector->interruptDisabledSoft) { ! 141: // Prevent speculative exacution as needed on your processor. ! 142: //isync(); ! 143: ! 144: // Call the handler if it exists. ! 145: if (vector->interruptRegistered) { ! 146: vector->handler(vector->target, vector->refCon, ! 147: vector->nub, vector->source); ! 148: } ! 149: } else { ! 150: // Hard disable the vector if is was only soft disabled. ! 151: vector->interruptDisabledHard = 1; ! 152: disableVectorHard(vectorNumber, vector); ! 153: } ! 154: ! 155: // Done with this vector so, set it back to inactive. ! 156: vector->interruptActive = 0; ! 157: } ! 158: ! 159: return kIOReturnSuccess; ! 160: } ! 161: ! 162: bool GenericInterruptController::vectorCanBeShared(long vectorNumber, ! 163: IOInterruptVector *vector) ! 164: { ! 165: // Given the vector number and the vector data, return if it can be shared. ! 166: return true; ! 167: } ! 168: ! 169: void GenericInterruptController::initVector(long vectorNumber, ! 170: IOInterruptVector *vector) ! 171: { ! 172: // Given the vector number and the vector data, ! 173: // get the hardware ready for the vector to generate interrupts. ! 174: // Make sure the vector is left disabled. ! 175: } ! 176: ! 177: void GenericInterruptController::disableVectorHard(long vectorNumber, ! 178: IOInterruptVector *vector) ! 179: { ! 180: // Given the vector number and the vector data, ! 181: // disable the vector at the hardware. ! 182: } ! 183: ! 184: void GenericInterruptController::enableVector(long vectorNumber, ! 185: IOInterruptVector *vector) ! 186: { ! 187: // Given the vector number and the vector data, ! 188: // enable the vector at the hardware. ! 189: } ! 190: ! 191: void GenericInterruptController::causeVector(long vectorNumber, ! 192: IOInterruptVector *vector) ! 193: { ! 194: // Given the vector number and the vector data, ! 195: // Set the vector pending and cause an interrupt at the parent controller. ! 196: ! 197: // cause the interrupt at the parent controller. Source is usually zero, ! 198: // but it could be different for your controller. ! 199: getPlatform()->causeInterrupt(0); ! 200: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.