|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.