|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1994 NeXT Computer, Inc.
27: *
28: * Kernel PPC Bus Resource Object(s).
29: *
30: * HISTORY
31: *
32: * 28 June 1994 Curtis Galloway at NeXT
33: * Derived from EISA files.
34: */
35:
36: #import <mach/mach_types.h>
37:
38: #import <driverkit/KernLock.h>
39: #import <driverkit/ppc/PPCKernBus.h>
40: #import <driverkit/ppc/PPCKernBusPrivate.h>
41: #import <driverkit/KernDevice.h>
42: #import <driverkit/ppc/driverTypes.h>
43: #import <driverkit/ppc/driverTypesPrivate.h>
44: #import <kernserv/ppc/spl.h>
45: #import <machdep/ppc/interrupts.h>
46:
47:
48:
49: static void
50: PPCKernBusInterruptDispatch(int deviceIntr, void * ssp, void *_interrupt)
51: {
52: BOOL leave_enabled;
53: PPCKernBusInterrupt_ * interrupt = (PPCKernBusInterrupt_ *)_interrupt;
54:
55: leave_enabled = KernBusInterruptDispatch(_interrupt, ssp);
56: if (!leave_enabled) {
57: KernLockAcquire(interrupt->_PPCLock);
58: pmac_disable_irq(interrupt->_irq);
59: interrupt->_irqEnabled = NO;
60: KernLockRelease(interrupt->_PPCLock);
61: }
62: }
63:
64: @implementation PPCKernBusInterrupt
65:
66: - initForResource: resource
67: item: (unsigned int)item
68: shareable: (BOOL)shareable
69: {
70: [super initForResource:resource item:item shareable:shareable];
71:
72: _irq = item;
73: _irqEnabled = NO;
74: _PPCLock = [[KernLock alloc] initWithLevel:7];
75: _priorityLevel = IPLDEVICE;
76:
77: return self;
78: }
79:
80: - dealloc
81: {
82: [_PPCLock free];
83: return [super dealloc];
84: }
85:
86: - attachDeviceInterrupt: interrupt
87: {
88: unsigned int pmac_device = pmac_int_to_number(_irq);
89:
90: if (!interrupt)
91: return nil;
92:
93: if (pmac_device == (-1))
94: return nil;
95:
96: [_PPCLock acquire];
97:
98: if( NO == _irqAttached) {
99: #warning all PPC driverkit drivers get SPLBIO
100: pmac_register_int(pmac_device, SPLBIO,
101: (void (*)(int, void *, void *))PPCKernBusInterruptDispatch,
102: (void *)self);
103: _irqAttached = YES;
104: }
105: /*
106: * -attachDeviceInterrupt will return nil
107: * if the interrupt is suspended.
108: */
109: if ([super attachDeviceInterrupt:interrupt]) {
110: _irqEnabled = YES;
111: pmac_enable_irq(_irq);
112: } else {
113: pmac_disable_irq(_irq);
114: _irqEnabled = NO;
115: }
116:
117: // _irqAttached = YES;
118:
119: [_PPCLock release];
120:
121: return self;
122: }
123:
124: - attachDeviceInterrupt: interrupt
125: atLevel: (int)level
126: {
127: unsigned int pmac_device = pmac_int_to_number(_irq);
128:
129: if (!interrupt)
130: return nil;
131:
132: if (pmac_device == (-1))
133: return nil;
134:
135: [_PPCLock acquire];
136:
137: if (level < _priorityLevel || level > IPLSCHED) {
138: [_PPCLock release];
139: return nil;
140: }
141:
142: // if (level > _priorityLevel)
143: // intr_change_ipl(irq, level);
144:
145: _priorityLevel = level;
146:
147: if( NO == _irqAttached) {
148: pmac_register_int(pmac_device, SPLBIO,
149: (void (*)(int, void *, void *))PPCKernBusInterruptDispatch,
150: (void *)self);
151: _irqAttached = YES;
152: }
153: /*
154: * -attachDeviceInterrupt will return nil
155: * if the interrupt is suspended.
156: */
157: if ([super attachDeviceInterrupt:interrupt]) {
158: _irqEnabled = YES;
159: pmac_enable_irq(_irq);
160: } else {
161: pmac_disable_irq(_irq);
162: _irqEnabled = NO;
163: }
164:
165: // _irqAttached = YES;
166:
167: [_PPCLock release];
168: return self;
169: }
170:
171: - detachDeviceInterrupt: interrupt
172: {
173: int irq = [self item];
174:
175: [_PPCLock acquire];
176:
177: if ( ![super detachDeviceInterrupt:interrupt]) {
178: pmac_disable_irq(_irq);
179: _irqEnabled = NO;
180: }
181:
182: // _irqAttached = NO;
183:
184: [_PPCLock release];
185: return self;
186: }
187:
188: - suspend
189: {
190: [_PPCLock acquire];
191:
192: [super suspend];
193:
194:
195: if (_irqEnabled) {
196: pmac_disable_irq(_irq);
197: _irqEnabled = NO;
198: }
199:
200: [_PPCLock release];
201:
202: return self;
203: }
204:
205: - resume
206: {
207: [_PPCLock acquire];
208:
209: if ([super resume] && !_irqEnabled) {
210: _irqEnabled = YES;
211: pmac_enable_irq(_irq);
212: }
213:
214: [_PPCLock release];
215:
216: return self;
217: }
218:
219: @end
220:
221:
222:
223: @implementation PPCKernBus
224:
225: static const char *resourceNameStrings[] = {
226: IRQ_LEVELS_KEY,
227: DMA_CHANNELS_KEY,
228: MEM_MAPS_KEY,
229: IO_PORTS_KEY,
230: NULL
231: };
232:
233: + initialize
234: {
235: [self registerBusClass:self name:"PPC"];
236: return self;
237: }
238:
239: - init
240: {
241: [super init];
242:
243: [self _insertResource:[[KernBusItemResource alloc]
244: initWithItemCount:IO_NUM_PPC_INTERRUPTS
245: itemKind:[PPCKernBusInterrupt class]
246: owner:self]
247: withKey:IRQ_LEVELS_KEY];
248:
249: [self _insertResource:[[KernBusRangeResource alloc]
250: initWithExtent:RangeMAX
251: kind:[KernBusMemoryRange class]
252: owner:self]
253: withKey:MEM_MAPS_KEY];
254:
255: [[self class] registerBusInstance:self name:"PPC" busId:[self busId]];
256:
257: printf("PPC bus support enabled\n");
258: return self;
259: }
260:
261: - (const char **)resourceNames
262: {
263: return resourceNameStrings;
264: }
265:
266: - free
267: {
268:
269: if ([self areResourcesActive])
270: return self;
271:
272: [[self _deleteResourceWithKey:IRQ_LEVELS_KEY] free];
273: [[self _deleteResourceWithKey:MEM_MAPS_KEY] free];
274:
275: return [super free];
276: }
277:
278: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.