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