Annotation of XNU/iokit/Examples/drvGenericInterruptController/GenericInterruptController.cpp, revision 1.1.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.