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