|
|
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) 1998 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: * 23 Nov 98 sdouglas created from objc version.
27: */
28:
29: #include <IOKit/system.h>
30:
31: #include <libkern/c++/OSContainers.h>
32: #include <IOKit/IODeviceMemory.h>
33: #include <IOKit/IODeviceTreeSupport.h>
34: #include <IOKit/IOLib.h>
35:
36: #include <architecture/i386/kernBootStruct.h>
37: #include <architecture/i386/pio.h>
38:
39: #include "AppleI386PCI.h"
40:
41: #include <assert.h>
42:
43: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
44:
45: #define super IOPCIBridge
46:
47: OSDefineMetaClassAndStructors(AppleI386PCI, IOPCIBridge)
48:
49: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
50:
51: bool AppleI386PCI::start( IOService * provider )
52: {
53: OSData * prop;
54: PCI_bus_info_t * info;
55:
56: prop = (OSData *) provider->getProperty("pci-bus-info");
57: if( 0 == prop)
58: return( false);
59:
60: info = (PCI_bus_info_t *) prop->getBytesNoCopy();
61:
62: maxBusNum = info->maxBusNum;
63: maxDevNum = 0;
64: majorVersion = info->majorVersion;
65: minorVersion = info->minorVersion;
66: BIOS16Present = info->BIOSPresent;
67: BIOS32Present = false;
68: BIOS32Entry = 0x00000000;
69: configMethod1 = info->u_bus.s.configMethod1;
70: configMethod2 = info->u_bus.s.configMethod2;
71: specialCycle1 = info->u_bus.s.specialCycle1;
72: specialCycle2 = info->u_bus.s.specialCycle2;
73:
74: /*
75: if ((BIOS16Present) & !(configMethod1 | configMethod2)) {
76: // This is a PCI system, but neither method is supported
77: // Lets try them both just in case (ala NEC ExpressII P60)
78: if (!(configMethod1 = [self test_M1]))
79: configMethod2 = [self test_M2];
80: }
81: */
82:
83: #define IFYES(b, s) ((b) ? s : "")
84: IOLog("PCI Ver=%x.%02x BusCount=%d Features=[ %s%s%s%s%s%s]\n",
85: majorVersion, minorVersion, maxBusNum+1,
86: IFYES(BIOS16Present, "BIOS16 "), IFYES(BIOS32Present, "BIOS32 "),
87: IFYES(configMethod1, "CM1 "), IFYES(configMethod2, "CM2 "),
88: IFYES(specialCycle1, "SC1 "), IFYES(specialCycle2, "SC2 ") );
89:
90: if (configMethod1)
91: maxDevNum = 31;
92: else if (configMethod2)
93: maxDevNum = 15;
94: else
95: return( false );
96:
97: ioMemory = IODeviceMemory::withRange( 0, 65536 );
98: if( !ioMemory)
99: return( false);
100: ioMemory->setMapping( kernel_task, 0 ); /* mapped to zero in IO space */
101:
102: return( super::start( provider));
103: }
104:
105: bool AppleI386PCI::configure( IOService * provider )
106: {
107: bool ok;
108:
109: ok = addBridgeMemoryRange( 0x80000000, 0x7f000000, true );
110: ok = addBridgeIORange( 0, 0x10000 );
111:
112: return( super::configure( provider ));
113: }
114:
115: void AppleI386PCI::free()
116: {
117: if( ioMemory)
118: ioMemory->release();
119:
120: super::free();
121: }
122:
123: IODeviceMemory * AppleI386PCI::ioDeviceMemory( void )
124: {
125: return( ioMemory);
126: }
127:
128:
129: UInt8 AppleI386PCI::firstBusNum( void )
130: {
131: return( 0 );
132: }
133:
134: UInt8 AppleI386PCI::lastBusNum( void )
135: {
136: return( firstBusNum() );
137: }
138:
139: IOPCIAddressSpace AppleI386PCI::getBridgeSpace( void )
140: {
141: IOPCIAddressSpace space;
142:
143: space.bits = 0;
144:
145: return( space );
146: }
147:
148: /* defines for Configuration Method #1 (PCI 2.0 Spec, sec 3.6.4.1.1) */
149: #define PCI_CONFIG_ADDRESS 0x0cf8
150: #define PCI_CONFIG_DATA 0x0cfc
151:
152: /* defines for Configuration Method #2 (PCI 2.0 Spec, sec 3.6.4.1.3) */
153: #define PCI_CSE_REGISTER 0x0cf8
154: #define PCI_BUS_FORWARD 0x0cfa
155:
156: #define PCI_DEFAULT_DATA 0xffffffff
157:
158: #if 0
159:
160: - (BOOL) test_M1
161: {
162: unsigned long address, data;
163:
164: for (address = 0x80000000; address < 0x80010000; address += 0x800) {
165: outl (PCI_CONFIG_ADDRESS, address);
166: if (inl (PCI_CONFIG_ADDRESS) != address) {
167: return NO;
168: }
169: data = inl(PCI_CONFIG_DATA);
170: if ((data != PCI_DEFAULT_DATA) && (data != 0x00)) {
171: outl (PCI_CONFIG_ADDRESS, 0);
172: return YES;
173: }
174: }
175:
176: outl (PCI_CONFIG_ADDRESS, 0);
177: return NO;
178: }
179:
180: - (BOOL) test_M2
181: {
182: unsigned long address, data;
183:
184: /* Enable configuration space at I/O ports Cxxx. */
185:
186: outb (PCI_CSE_REGISTER, 0xF0);
187: if (inb (PCI_CSE_REGISTER) != 0xF0) {
188: return NO;
189: }
190:
191: outb (PCI_BUS_FORWARD, 0x00);
192: if (inb (PCI_BUS_FORWARD) != 0x00) {
193: return NO;
194: }
195: /* Search all devices on the bus. */
196: for (address = 0xc000; address <= 0xcfff; address += 0x100) {
197: data = inl(address);
198: if ((data != PCI_DEFAULT_DATA) && (data != 0x00)) {
199: outb (PCI_CSE_REGISTER, 0);
200: return YES;
201: }
202: }
203:
204: outb (PCI_CSE_REGISTER, 0);
205: return NO;
206: }
207: #endif
208:
209: UInt32 AppleI386PCI::configRead32Method1( IOPCIAddressSpace space,
210: UInt8 offset )
211: {
212: IOPCIAddressSpace addrCycle;
213: UInt32 data = PCI_DEFAULT_DATA;
214:
215: addrCycle = space;
216: addrCycle.s.reloc = 1;
217: addrCycle.s.registerNum = offset;
218:
219: outl( PCI_CONFIG_ADDRESS, addrCycle.bits);
220: if (inl( PCI_CONFIG_ADDRESS) == addrCycle.bits)
221: data = inl( PCI_CONFIG_DATA);
222:
223: outl( PCI_CONFIG_ADDRESS, 0);
224:
225: return( data );
226: }
227:
228:
229: void AppleI386PCI::configWrite32Method1( IOPCIAddressSpace space,
230: UInt8 offset, UInt32 data )
231: {
232: IOPCIAddressSpace addrCycle;
233:
234: addrCycle = space;
235: addrCycle.s.reloc = 1;
236: addrCycle.s.registerNum = offset;
237:
238: outl( PCI_CONFIG_ADDRESS, addrCycle.bits);
239: if (inl( PCI_CONFIG_ADDRESS) == addrCycle.bits)
240: outl(PCI_CONFIG_DATA, data);
241:
242: outl( PCI_CONFIG_ADDRESS, 0);
243: }
244:
245: UInt32 AppleI386PCI::configRead32Method2( IOPCIAddressSpace space,
246: UInt8 offset )
247: {
248: UInt32 data = PCI_DEFAULT_DATA;
249: UInt8 cse;
250:
251: if( space.s.deviceNum > 15)
252: return( data);
253:
254: cse = 0xf0 | (space.s.functionNum << 1);
255: outb( PCI_CSE_REGISTER, cse);
256: if (inb( PCI_CSE_REGISTER) == cse) {
257: outb( PCI_BUS_FORWARD, space.s.busNum);
258: if (inb( PCI_BUS_FORWARD) == space.s.busNum) {
259: data = inl( 0xc000
260: | (offset & 0xfc)
261: | (space.s.deviceNum << 8));
262: }
263: outb( PCI_BUS_FORWARD, 0x00);
264: }
265: outb( PCI_CSE_REGISTER, 0x00);
266:
267: return( data );
268: }
269:
270:
271: void AppleI386PCI::configWrite32Method2( IOPCIAddressSpace space,
272: UInt8 offset, UInt32 data )
273: {
274: UInt8 cse;
275:
276: if( space.s.deviceNum > 15)
277: return;
278:
279: cse = 0xf0 | (space.s.functionNum << 1);
280: outb( PCI_CSE_REGISTER, cse);
281: if (inb( PCI_CSE_REGISTER) == cse) {
282: outb( PCI_BUS_FORWARD, space.s.busNum);
283: if (inb( PCI_BUS_FORWARD) == space.s.busNum) {
284: outl( 0xc000
285: | (offset & 0xfc)
286: | (space.s.deviceNum << 8), data);
287: }
288: outb( PCI_BUS_FORWARD, 0x00);
289: }
290: outb( PCI_CSE_REGISTER, 0x00);
291: }
292:
293: UInt32 AppleI386PCI::configRead32( IOPCIAddressSpace space,
294: UInt8 offset )
295: {
296: /* should disable ints */
297: if( configMethod1)
298: return( configRead32Method1( space, offset ));
299: else
300: return( configRead32Method2( space, offset ));
301: /* enable ints */
302: }
303:
304: void AppleI386PCI::configWrite32( IOPCIAddressSpace space,
305: UInt8 offset, UInt32 data )
306: {
307: /* should disable ints */
308: if( configMethod1)
309: configWrite32Method1( space, offset, data );
310: else
311: configWrite32Method2( space, offset, data );
312: /* enable ints */
313: }
314:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.