Annotation of XNU/iokit/Examples/drvGenericInterruptController/GenericInterruptController.cpp, revision 1.1

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: }

unix.superglobalmegacorp.com

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