|
|
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.