2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
28 #include <IOKit/IOPlatformExpert.h>
30 #include "GenericInterruptController.h"
32 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
35 #define super IOInterruptController
37 IODefineMetaClassAndStructors(GenericInterruptController
,
38 IOInterruptController
);
40 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43 bool GenericInterruptController::start(IOService
*provider
)
45 IOInterruptAction handler
;
46 IOSymbol
*interruptControllerName
;
48 // If needed call the parents start.
49 if (!super::start(provider
))
52 // Map the device's memory and initalize its state.
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.
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
));
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
);
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
);
81 // register the interrupt handler so it can receive interrupts.
82 handler
= getInterruptHandlerAddress();
83 provider
->registerInterrupt(0, this, handler
, 0);
85 // Just like any interrupt source, you must enable it to receive interrupts.
86 provider
->enableInterrupt(0);
88 // Set interruptControllerName to the proper symbol.
89 //interruptControllerName = xxx;
91 // Register this interrupt controller so clients can find it.
92 getPlatform()->registerInterruptController(interruptControllerName
, this);
94 // All done, so return true.
98 IOReturn
GenericInterruptController::getInterruptType(IOService
*nub
,
102 if (interruptType
== 0) return kIOReturnBadArgument
;
104 // Given the nub and source, set interruptType to level or edge.
106 return kIOReturnSuccess
;
109 // Sadly this just has to be replicated in every interrupt controller.
110 IOInterruptAction
GenericInterruptController::getInterruptHandlerAddress(void)
112 return (IOInterruptAction
)handleInterrupt
;
115 // Handle all current interrupts.
116 IOReturn
GenericInterruptController::handleInterrupt(void * refCon
,
120 IOInterruptVector
*vector
;
124 // Get vectorNumber from hardware some how and clear the event.
126 // Break if there are no more vectors to handle.
127 if (vectorNumber
== 0/*kNoVector*/) break;
129 // Get the vector's date from the controller's array.
130 vector
= &vectors
[vectorNumber
];
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;
139 // If the vector is not disabled soft, handle it.
140 if (!vector
->interruptDisabledSoft
) {
141 // Prevent speculative exacution as needed on your processor.
144 // Call the handler if it exists.
145 if (vector
->interruptRegistered
) {
146 vector
->handler(vector
->target
, vector
->refCon
,
147 vector
->nub
, vector
->source
);
150 // Hard disable the vector if is was only soft disabled.
151 vector
->interruptDisabledHard
= 1;
152 disableVectorHard(vectorNumber
, vector
);
155 // Done with this vector so, set it back to inactive.
156 vector
->interruptActive
= 0;
159 return kIOReturnSuccess
;
162 bool GenericInterruptController::vectorCanBeShared(long vectorNumber
,
163 IOInterruptVector
*vector
)
165 // Given the vector number and the vector data, return if it can be shared.
169 void GenericInterruptController::initVector(long vectorNumber
,
170 IOInterruptVector
*vector
)
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.
177 void GenericInterruptController::disableVectorHard(long vectorNumber
,
178 IOInterruptVector
*vector
)
180 // Given the vector number and the vector data,
181 // disable the vector at the hardware.
184 void GenericInterruptController::enableVector(long vectorNumber
,
185 IOInterruptVector
*vector
)
187 // Given the vector number and the vector data,
188 // enable the vector at the hardware.
191 void GenericInterruptController::causeVector(long vectorNumber
,
192 IOInterruptVector
*vector
)
194 // Given the vector number and the vector data,
195 // Set the vector pending and cause an interrupt at the parent controller.
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);