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