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