1/* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 30 * 31 * DRI: Josh de Cesare 32 */ 33 34#include <IOKit/IOPlatformExpert.h> 35 36#include "GenericInterruptController.h" 37 38/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 39 40#undef super 41#define super IOInterruptController 42 43IODefineMetaClassAndStructors(GenericInterruptController, 44 IOInterruptController); 45 46/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 47 48 49bool GenericInterruptController::start(IOService *provider) 50{ 51 IOInterruptAction handler; 52 IOSymbol *interruptControllerName; 53 54 // If needed call the parents start. 55 if (!super::start(provider)) 56 return false; 57 58 // Map the device's memory and initalize its state. 59 60 // For now you must allocate storage for the vectors. 61 // This will probably changed to something like: initVectors(numVectors). 62 // In the mean time something like this works well. 63#if 0 64 // Allocate the memory for the vectors. 65 vectors = (IOInterruptVector *)IOMalloc(numVectors * 66 sizeof(IOInterruptVector)); 67 if (vectors == NULL) return false; 68 bzero(vectors, numVectors * sizeof(IOInterruptVector)); 69 70 // Allocate locks for the vectors. 71 for (cnt = 0; cnt < numVectors; cnt++) { 72 vectors[cnt].interruptLock = IOLockAlloc(); 73 if (vectors[cnt].interruptLock == NULL) { 74 for (cnt = 0; cnt < numVectors; cnt++) { 75 if (vectors[cnt].interruptLock != NULL) 76 IOLockFree(vectors[cnt].interruptLock); 77 } 78 } 79 } 80#endif 81 82 // If you know that this interrupt controller is the primary 83 // interrupt controller, use this to set it nub properties properly. 84 // This may be done by the nub's creator. 85 getPlatform()->setCPUInterruptProperties(provider); 86 87 // register the interrupt handler so it can receive interrupts. 88 handler = getInterruptHandlerAddress(); 89 provider->registerInterrupt(0, this, handler, 0); 90 91 // Just like any interrupt source, you must enable it to receive interrupts. 92 provider->enableInterrupt(0); 93 94 // Set interruptControllerName to the proper symbol. 95 //interruptControllerName = xxx; 96 97 // Register this interrupt controller so clients can find it. 98 getPlatform()->registerInterruptController(interruptControllerName, this); 99 100 // All done, so return true. 101 return true; 102} 103 104IOReturn GenericInterruptController::getInterruptType(IOService *nub, 105 int source, 106 int *interruptType) 107{ 108 if (interruptType == 0) return kIOReturnBadArgument; 109 110 // Given the nub and source, set interruptType to level or edge. 111 112 return kIOReturnSuccess; 113} 114 115// Sadly this just has to be replicated in every interrupt controller. 116IOInterruptAction GenericInterruptController::getInterruptHandlerAddress(void) 117{ 118 return (IOInterruptAction)handleInterrupt; 119} 120 121// Handle all current interrupts. 122IOReturn GenericInterruptController::handleInterrupt(void * refCon, 123 IOService * nub, 124 int source) 125{ 126 IOInterruptVector *vector; 127 int vectorNumber; 128 129 while (1) { 130 // Get vectorNumber from hardware some how and clear the event. 131 132 // Break if there are no more vectors to handle. 133 if (vectorNumber == 0/*kNoVector*/) break; 134 135 // Get the vector's date from the controller's array. 136 vector = &vectors[vectorNumber]; 137 138 // Set the vector as active. This store must compleat before 139 // moving on to prevent the disableInterrupt fuction from 140 // geting out of sync. 141 vector->interruptActive = 1; 142 //sync(); 143 //isync(); 144 145 // If the vector is not disabled soft, handle it. 146 if (!vector->interruptDisabledSoft) { 147 // Prevent speculative exacution as needed on your processor. 148 //isync(); 149 150 // Call the handler if it exists. 151 if (vector->interruptRegistered) { 152 vector->handler(vector->target, vector->refCon, 153 vector->nub, vector->source); 154 } 155 } else { 156 // Hard disable the vector if is was only soft disabled. 157 vector->interruptDisabledHard = 1; 158 disableVectorHard(vectorNumber, vector); 159 } 160 161 // Done with this vector so, set it back to inactive. 162 vector->interruptActive = 0; 163 } 164 165 return kIOReturnSuccess; 166} 167 168bool GenericInterruptController::vectorCanBeShared(long vectorNumber, 169 IOInterruptVector *vector) 170{ 171 // Given the vector number and the vector data, return if it can be shared. 172 return true; 173} 174 175void GenericInterruptController::initVector(long vectorNumber, 176 IOInterruptVector *vector) 177{ 178 // Given the vector number and the vector data, 179 // get the hardware ready for the vector to generate interrupts. 180 // Make sure the vector is left disabled. 181} 182 183void GenericInterruptController::disableVectorHard(long vectorNumber, 184 IOInterruptVector *vector) 185{ 186 // Given the vector number and the vector data, 187 // disable the vector at the hardware. 188} 189 190void GenericInterruptController::enableVector(long vectorNumber, 191 IOInterruptVector *vector) 192{ 193 // Given the vector number and the vector data, 194 // enable the vector at the hardware. 195} 196 197void GenericInterruptController::causeVector(long vectorNumber, 198 IOInterruptVector *vector) 199{ 200 // Given the vector number and the vector data, 201 // Set the vector pending and cause an interrupt at the parent controller. 202 203 // cause the interrupt at the parent controller. Source is usually zero, 204 // but it could be different for your controller. 205 getPlatform()->causeInterrupt(0); 206} 207