2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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 License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
34 #include <IOKit/IOPlatformExpert.h>
36 #include "GenericInterruptController.h"
38 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
41 #define super IOInterruptController
43 IODefineMetaClassAndStructors(GenericInterruptController
,
44 IOInterruptController
);
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
50 GenericInterruptController::start(IOService
*provider
)
52 IOInterruptAction handler
;
53 IOSymbol
*interruptControllerName
;
55 // If needed call the parents start.
56 if (!super::start(provider
)) {
60 // Map the device's memory and initalize its state.
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.
66 // Allocate the memory for the vectors.
67 vectors
= (IOInterruptVector
*)IOMalloc(numVectors
*
68 sizeof(IOInterruptVector
));
69 if (vectors
== NULL
) {
72 bzero(vectors
, numVectors
* sizeof(IOInterruptVector
));
74 // Allocate locks for the vectors.
75 for (cnt
= 0; cnt
< numVectors
; cnt
++) {
76 vectors
[cnt
].interruptLock
= IOLockAlloc();
77 if (vectors
[cnt
].interruptLock
== NULL
) {
78 for (cnt
= 0; cnt
< numVectors
; cnt
++) {
79 if (vectors
[cnt
].interruptLock
!= NULL
) {
80 IOLockFree(vectors
[cnt
].interruptLock
);
87 // If you know that this interrupt controller is the primary
88 // interrupt controller, use this to set it nub properties properly.
89 // This may be done by the nub's creator.
90 getPlatform()->setCPUInterruptProperties(provider
);
92 // register the interrupt handler so it can receive interrupts.
93 handler
= getInterruptHandlerAddress();
94 provider
->registerInterrupt(0, this, handler
, 0);
96 // Just like any interrupt source, you must enable it to receive interrupts.
97 provider
->enableInterrupt(0);
99 // Set interruptControllerName to the proper symbol.
100 //interruptControllerName = xxx;
102 // Register this interrupt controller so clients can find it.
103 getPlatform()->registerInterruptController(interruptControllerName
, this);
105 // All done, so return true.
110 GenericInterruptController::getInterruptType(IOService
*nub
,
114 if (interruptType
== 0) {
115 return kIOReturnBadArgument
;
118 // Given the nub and source, set interruptType to level or edge.
120 return kIOReturnSuccess
;
123 // Sadly this just has to be replicated in every interrupt controller.
125 GenericInterruptController::getInterruptHandlerAddress(void)
127 return (IOInterruptAction
)handleInterrupt
;
130 // Handle all current interrupts.
132 GenericInterruptController::handleInterrupt(void * refCon
,
136 IOInterruptVector
*vector
;
140 // Get vectorNumber from hardware some how and clear the event.
142 // Break if there are no more vectors to handle.
143 if (vectorNumber
== 0 /*kNoVector*/) {
147 // Get the vector's date from the controller's array.
148 vector
= &vectors
[vectorNumber
];
150 // Set the vector as active. This store must compleat before
151 // moving on to prevent the disableInterrupt fuction from
152 // geting out of sync.
153 vector
->interruptActive
= 1;
157 // If the vector is not disabled soft, handle it.
158 if (!vector
->interruptDisabledSoft
) {
159 // Prevent speculative exacution as needed on your processor.
162 // Call the handler if it exists.
163 if (vector
->interruptRegistered
) {
164 vector
->handler(vector
->target
, vector
->refCon
,
165 vector
->nub
, vector
->source
);
168 // Hard disable the vector if is was only soft disabled.
169 vector
->interruptDisabledHard
= 1;
170 disableVectorHard(vectorNumber
, vector
);
173 // Done with this vector so, set it back to inactive.
174 vector
->interruptActive
= 0;
177 return kIOReturnSuccess
;
181 GenericInterruptController::vectorCanBeShared(long vectorNumber
,
182 IOInterruptVector
*vector
)
184 // Given the vector number and the vector data, return if it can be shared.
189 GenericInterruptController::initVector(long vectorNumber
,
190 IOInterruptVector
*vector
)
192 // Given the vector number and the vector data,
193 // get the hardware ready for the vector to generate interrupts.
194 // Make sure the vector is left disabled.
198 GenericInterruptController::disableVectorHard(long vectorNumber
,
199 IOInterruptVector
*vector
)
201 // Given the vector number and the vector data,
202 // disable the vector at the hardware.
206 GenericInterruptController::enableVector(long vectorNumber
,
207 IOInterruptVector
*vector
)
209 // Given the vector number and the vector data,
210 // enable the vector at the hardware.
214 GenericInterruptController::causeVector(long vectorNumber
,
215 IOInterruptVector
*vector
)
217 // Given the vector number and the vector data,
218 // Set the vector pending and cause an interrupt at the parent controller.
220 // cause the interrupt at the parent controller. Source is usually zero,
221 // but it could be different for your controller.
222 getPlatform()->causeInterrupt(0);