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