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