|
|
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: * Copyright (c) 1997 Apple Computer, Inc. ! 26: * ! 27: * ! 28: * HISTORY ! 29: * ! 30: * Simon Douglas 22 Oct 97 ! 31: * - first checked in. ! 32: * Simon Douglas 26 Jan 98 ! 33: * - support PCI-PCI bridges ! 34: */ ! 35: ! 36: #import <machdep/ppc/proc_reg.h> ! 37: #import "IOMacRiscPCI.h" ! 38: ! 39: #define INFO if(0) kprintf ! 40: ! 41: enum { ! 42: kPCIConfigSpace = 0, ! 43: kPCIIOSpace = 1, ! 44: kPCI32BitMemorySpace = 2, ! 45: kPCI64BitMemorySpace = 3 ! 46: }; ! 47: ! 48: struct AddressCell { ! 49: unsigned int reloc:1; ! 50: unsigned int prefetch:1; ! 51: unsigned int t:1; ! 52: unsigned int resv:3; ! 53: unsigned int space:2; ! 54: unsigned int busNum:8; ! 55: unsigned int deviceNum:5; ! 56: unsigned int functionNum:3; ! 57: unsigned int registerNum:8; ! 58: unsigned int physMid; ! 59: unsigned int physLo; ! 60: unsigned int lengthHi; ! 61: unsigned int lengthLo; ! 62: }; ! 63: typedef struct AddressCell AddressCell; ! 64: ! 65: #define SWAPLONG(value) ( ((value >> 24) & 0xff) | \ ! 66: ((value >> 8) & 0xff00) | \ ! 67: ((value << 8) & 0xff0000) | \ ! 68: ((value << 24) & 0xff000000) ) ! 69: ! 70: ! 71: @implementation IOPCIBridge ! 72: ! 73: - initFromDeviceDescription:deviceDescription ! 74: { ! 75: IOReturn err; ! 76: UInt32 * prop; ! 77: ByteCount propSize; ! 78: ! 79: do { ! 80: if ([super initFromDeviceDescription:deviceDescription] == nil) ! 81: continue; ! 82: ! 83: // Redo the default ranges so less may be pmap'ed ! 84: err = [self mapRegisters:deviceDescription]; ! 85: if( err) ! 86: continue; ! 87: ! 88: err = [[deviceDescription propertyTable] getProperty:"bus-range" ! 89: flags:kReferenceProperty value:(void **) &prop length:&propSize]; ! 90: ! 91: if( (err == noErr) && (propSize >= sizeof( int))) ! 92: primaryBus = *prop; ! 93: ! 94: if( [deviceDescription isKindOf:[IOPCIDevice class]] ) ! 95: parentBridge = [deviceDescription parent]; ! 96: ! 97: return( self); ! 98: ! 99: } while( false); ! 100: ! 101: return( [super free]); ! 102: } ! 103: ! 104: ! 105: - createDevice:(IOPropertyTable *)newTable ref:ref ! 106: { ! 107: IOReturn err; ! 108: IOPCIDevice * newDev; ! 109: AddressCell * cell; ! 110: ByteCount propSize; ! 111: ! 112: newDev = [IOPCIDevice alloc]; ! 113: ! 114: // If we were really probing PCI we would know the device & function ! 115: // numbers but for now just rely on the tree probe to create our children ! 116: // and get the info necessary from the OpenFirmware probe. ! 117: ! 118: err = [newTable getProperty:"reg" flags:kReferenceProperty ! 119: value:(void **) &cell length:&propSize]; ! 120: if( err || (propSize < sizeof(AddressCell))) ! 121: return( nil); ! 122: ! 123: newDev->busNum = cell->busNum; ! 124: newDev->deviceNum = cell->deviceNum; ! 125: newDev->functionNum = cell->functionNum; ! 126: ! 127: [newDev initAt:newTable parent:self ref:ref]; ! 128: ! 129: return( [newDev publish] ); ! 130: } ! 131: ! 132: #if 0 ! 133: - (BOOL) match:(IOPCIDevice *)device key:(const char *)key location:(const char *)location ! 134: { ! 135: ! 136: // check for vendor, product ID keys and so on... ! 137: ! 138: // otherwise the default device name matching from IODeviceTreeBus ! 139: return( [super match:device key:key location:location]); ! 140: } ! 141: #endif ! 142: ! 143: - (IOReturn) configReadLong:(IOPCIDevice *)device ! 144: offset:(UInt32)offset value:(UInt32 *)value ! 145: { ! 146: volatile UInt32 * access; ! 147: ! 148: access = [self setConfigAddress:device offset:offset]; ! 149: *value = SWAPLONG( *access); ! 150: eieio(); ! 151: return( noErr); ! 152: } ! 153: ! 154: - (IOReturn) configWriteLong:(IOPCIDevice *)device ! 155: offset:(UInt32)offset value:(UInt32)value ! 156: { ! 157: volatile UInt32 * access; ! 158: ! 159: access = [self setConfigAddress:device offset:offset]; ! 160: *access = SWAPLONG( value); ! 161: eieio(); ! 162: return( noErr); ! 163: } ! 164: ! 165: - getDeviceUnitStr:(IOPCIDevice *)device name:(char *)name maxLength:(int)len ! 166: { ! 167: UInt32 * regProp; ! 168: char unitStr[ 20 ]; ! 169: ! 170: if( device->functionNum) ! 171: sprintf( unitStr, "%x,%x", device->deviceNum, device->functionNum ); ! 172: else ! 173: sprintf( unitStr, "%x", device->deviceNum ); ! 174: if( strlen( unitStr) < len) { ! 175: strcpy( name, unitStr); ! 176: return( self); ! 177: } ! 178: // failed ! 179: return( nil); ! 180: } ! 181: ! 182: - (IOReturn) mapRegisters:device ! 183: { ! 184: return( IO_R_SUCCESS); ! 185: } ! 186: ! 187: - (volatile UInt32 *) setConfigAddress:(IOPCIDevice *)device offset:(UInt32)offset; ! 188: { ! 189: if( parentBridge) ! 190: return( [parentBridge setConfigAddress:device offset:offset]); ! 191: ! 192: return( NULL); ! 193: } ! 194: ! 195: - (LogicalAddress) getIOAperture; ! 196: { ! 197: if( parentBridge) ! 198: return( [parentBridge getIOAperture]); ! 199: ! 200: return( NULL); ! 201: } ! 202: ! 203: @end ! 204: ! 205: @implementation IOMacRiscPCIBridge ! 206: ! 207: - registerLoudly ! 208: { ! 209: return( self); ! 210: } ! 211: ! 212: - (BOOL) isVCI ! 213: { ! 214: return( NO); ! 215: } ! 216: ! 217: - (IOReturn) mapRegisters:device ! 218: { ! 219: IOReturn err; ! 220: IORange realRanges[ 3 ]; ! 221: IORange * range; ! 222: UInt32 i; ! 223: vm_address_t * logical; ! 224: static AddressCell ioAddrCell = { 0, 0, 0, 0, kPCIIOSpace, ! 225: 0, 0, 0, 0, 0, 0, 0, 0 }; ! 226: UInt32 ioPhys; ! 227: ! 228: // Look for our IO memory aperture ! 229: err = [self resolveAddressCell:(UInt32 *)&ioAddrCell ! 230: physicalAddress:(PhysicalAddress *)&ioPhys]; ! 231: if( err) ! 232: return( err); ! 233: ! 234: range = realRanges; ! 235: range->start = ioPhys + 0x00800000; // config addr ! 236: range->size = 0x1000; ! 237: range++; ! 238: range->start = ioPhys + 0x00c00000; // config data ! 239: range->size = 0x1000; ! 240: range++; ! 241: ! 242: if( NO == [self isVCI]) { ! 243: range->start = ioPhys; ! 244: range->size = 0x10000; // 64K of non-reloc I/O access !! ! 245: range++; ! 246: } ! 247: ! 248: [device setMemoryRangeList:0 num:0]; ! 249: err = [device setMemoryRangeList:realRanges num:(range - realRanges)]; ! 250: if( err) ! 251: return( err); ! 252: ! 253: range = realRanges; ! 254: logical = (vm_address_t *) &configAddr; ! 255: for( i = 0; i < [device numMemoryRanges]; i++, logical++, range++ ) { ! 256: ! 257: err = [self mapMemoryRange:i to:logical findSpace:YES cache:IO_CacheOff]; ! 258: INFO( "Phys %x = Virt %x\n", range->start, *logical); ! 259: ! 260: if( err) { ! 261: IOLog( "%s: mapMemoryRange failed", [self name]); ! 262: break; ! 263: } ! 264: } ! 265: return( err); ! 266: } ! 267: ! 268: - (volatile UInt32 *) setConfigAddress:(IOPCIDevice *)device offset:(UInt32)offset ! 269: { ! 270: UInt32 addrCycle; ! 271: ! 272: if( device->busNum == primaryBus) { ! 273: // primary config cycle ! 274: addrCycle = SWAPLONG(( (1 << device->deviceNum) ! 275: | (device->functionNum << 8) ! 276: | (offset & 0xfc) )); ! 277: ! 278: } else { ! 279: // pass thru config cycle ! 280: addrCycle = SWAPLONG(( (device->busNum << 16) ! 281: | (device->deviceNum << 11) ! 282: | (device->functionNum << 8) ! 283: | (offset & 0xfc) ! 284: | 1 )); ! 285: } ! 286: ! 287: while( *configAddr != addrCycle) { ! 288: (*configAddr) = addrCycle; ! 289: eieio(); ! 290: } ! 291: ! 292: return( configData); ! 293: } ! 294: ! 295: - (LogicalAddress) getIOAperture ! 296: { ! 297: return( (LogicalAddress) ioAperture); // zero on VCI ! 298: } ! 299: ! 300: @end ! 301: ! 302: @implementation IOMacRiscVCIBridge ! 303: ! 304: - (BOOL) isVCI ! 305: { ! 306: return( YES); ! 307: } ! 308: ! 309: @end ! 310: ! 311: @implementation IOGracklePCIBridge ! 312: ! 313: - (IOReturn) mapRegisters:device ! 314: { ! 315: IOReturn err; ! 316: IORange realRanges[ 3 ]; ! 317: IORange * range; ! 318: UInt32 i; ! 319: vm_address_t * logical; ! 320: static AddressCell ioAddrCell = { 0, 0, 0, 0, kPCIIOSpace, ! 321: 0, 0, 0, 0, 0, 0, 0, 0 }; ! 322: UInt32 ioPhys; ! 323: ! 324: // Look for our IO memory aperture ! 325: err = [self resolveAddressCell:(UInt32 *)&ioAddrCell ! 326: physicalAddress:(PhysicalAddress *)&ioPhys]; ! 327: if( err) ! 328: return( err); ! 329: ! 330: range = realRanges; ! 331: range->start = ioPhys + 0x00c00000; // config addr ! 332: range->size = 0x1000; ! 333: range++; ! 334: range->start = ioPhys + 0x00e00000; // config data ! 335: range->size = 0x1000; ! 336: range++; ! 337: range->start = ioPhys; ! 338: range->size = 0x10000; // 64K of non-reloc I/O access !! ! 339: range++; ! 340: ! 341: [device setMemoryRangeList:0 num:0]; ! 342: err = [device setMemoryRangeList:realRanges num:3]; ! 343: if( err) ! 344: return( err); ! 345: ! 346: range = realRanges; ! 347: logical = (vm_address_t *) &configAddr; ! 348: for( i = 0; i < 3; i++, logical++, range++ ) { ! 349: ! 350: err = [self mapMemoryRange:i to:logical findSpace:YES cache:IO_CacheOff]; ! 351: INFO( "Phys %x = Virt %x\n", range->start, *logical); ! 352: ! 353: if( err) { ! 354: IOLog( "%s: mapMemoryRange failed", [self name]); ! 355: break; ! 356: } ! 357: } ! 358: return( err); ! 359: } ! 360: ! 361: - (volatile UInt32 *) setConfigAddress:(IOPCIDevice *)device offset:(UInt32)offset ! 362: { ! 363: *configAddr = (SWAPLONG(( (0x80000000) ! 364: | (device->busNum << 16) ! 365: | (device->deviceNum << 11) ! 366: | (device->functionNum << 8) ! 367: | (offset & 0xfc)))); ! 368: eieio(); ! 369: return( configData); ! 370: } ! 371: ! 372: - (LogicalAddress) getIOAperture ! 373: { ! 374: return( (LogicalAddress) ioAperture); ! 375: } ! 376: ! 377: @end ! 378: ! 379:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.