|
|
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: * 05 Nov 99 sdouglas added UniNorth AGP based on UniNorthAGPDriver.c * by Fernando Urbina, Kent Miller. ! 28: * ! 29: */ ! 30: ! 31: #include <IOKit/system.h> ! 32: #include <ppc/proc_reg.h> ! 33: ! 34: #include <libkern/c++/OSContainers.h> ! 35: #include <libkern/OSByteOrder.h> ! 36: ! 37: #include <IOKit/IODeviceMemory.h> ! 38: #include <IOKit/IORangeAllocator.h> ! 39: #include <IOKit/IODeviceTreeSupport.h> ! 40: #include <IOKit/IOPlatformExpert.h> ! 41: #include <IOKit/IOLib.h> ! 42: #include <IOKit/assert.h> ! 43: ! 44: #include "AppleMacRiscPCI.h" ! 45: ! 46: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 47: ! 48: #define super IOPCIBridge ! 49: ! 50: OSDefineMetaClassAndStructors(AppleMacRiscPCI, IOPCIBridge) ! 51: ! 52: OSDefineMetaClassAndStructors(AppleMacRiscVCI, AppleMacRiscPCI) ! 53: ! 54: OSDefineMetaClassAndStructors(AppleMacRiscAGP, AppleMacRiscPCI) ! 55: ! 56: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 57: ! 58: bool AppleMacRiscPCI::start( IOService * provider ) ! 59: { ! 60: IOPCIPhysicalAddress ioAddrCell; ! 61: IOPhysicalAddress ioPhys; ! 62: IOPhysicalAddress ioPhysLen; ! 63: OSArray * array; ! 64: IODeviceMemory::InitElement rangeList[ 3 ]; ! 65: IORegistryEntry * bridge; ! 66: OSData * busProp; ! 67: ! 68: if( !IODTMatchNubWithKeys(provider, "('pci', 'vci')")) ! 69: return( false); ! 70: ! 71: if( IODTMatchNubWithKeys(provider, "'uni-north'")) ! 72: configDataOffsetMask = 0x7; ! 73: else ! 74: configDataOffsetMask = 0x3; ! 75: ! 76: if( 0 == (lock = IOSimpleLockAlloc())) ! 77: return( false ); ! 78: ! 79: ioAddrCell.physHi.bits = 0; ! 80: ioAddrCell.physHi.s.space = kIOPCIIOSpace; ! 81: ioAddrCell.physMid = 0; ! 82: ioAddrCell.physLo = 0; ! 83: ioAddrCell.lengthHi = 0; ! 84: ioAddrCell.lengthLo = 0x10000; ! 85: ! 86: bridge = provider; ! 87: ! 88: if( ! IODTResolveAddressCell( bridge, (UInt32 *) &ioAddrCell, ! 89: &ioPhys, &ioPhysLen) ) { ! 90: ! 91: IOLog("%s: couldn't find my base\n", getName()); ! 92: return( false); ! 93: } ! 94: ! 95: /* define more explicit ranges */ ! 96: ! 97: rangeList[0].start = ioPhys; ! 98: rangeList[0].length = ioPhysLen; ! 99: rangeList[1].start = ioPhys + 0x00800000; ! 100: rangeList[1].length = 4; ! 101: rangeList[2].start = ioPhys + 0x00c00000; ! 102: rangeList[2].length = 4; ! 103: ! 104: IORangeAllocator * platformRanges; ! 105: platformRanges = IOService::getPlatform()->getPhysicalRangeAllocator(); ! 106: assert( platformRanges ); ! 107: platformRanges->allocateRange( ioPhys, 0x01000000 ); ! 108: ! 109: array = IODeviceMemory::arrayFromList( rangeList, 3 ); ! 110: if( !array) ! 111: return( false); ! 112: ! 113: provider->setDeviceMemory( array ); ! 114: array->release(); ! 115: ioMemory = (IODeviceMemory *) array->getObject( 0 ); ! 116: ! 117: /* map registers */ ! 118: ! 119: if( (configAddrMap = provider->mapDeviceMemoryWithIndex( 1 ))) ! 120: configAddr = (volatile UInt32 *) configAddrMap->getVirtualAddress(); ! 121: if( (configDataMap = provider->mapDeviceMemoryWithIndex( 2 ))) ! 122: configData = (volatile UInt32 *) configDataMap->getVirtualAddress(); ! 123: ! 124: if( !configAddr || !configData) ! 125: return( false); ! 126: ! 127: busProp = (OSData *) bridge->getProperty("bus-range"); ! 128: if( busProp) ! 129: primaryBus = *((UInt32 *) busProp->getBytesNoCopy()); ! 130: ! 131: return( super::start( provider)); ! 132: } ! 133: ! 134: bool AppleMacRiscPCI::configure( IOService * provider ) ! 135: { ! 136: UInt32 addressSelects; ! 137: UInt32 index; ! 138: bool ok; ! 139: ! 140: addressSelects = configRead32( getBridgeSpace(), kMacRISCAddressSelect ); ! 141: ! 142: coarseAddressMask = addressSelects >> 16; ! 143: fineAddressMask = addressSelects & 0xffff; ! 144: ! 145: for( index = 0; index < 15; index++ ) { ! 146: if( coarseAddressMask & (1 << index)) { ! 147: ok = addBridgeMemoryRange( index << 28, 0x10000000, true ); ! 148: } ! 149: } ! 150: ! 151: // if( coarseAddressMask & (1 << 15)) // F segment ! 152: for( index = 0; index < 15; index++ ) { ! 153: if( fineAddressMask & (1 << index)) { ! 154: ok = addBridgeMemoryRange( (0xf0 | index) << 24, ! 155: 0x01000000, true ); ! 156: } ! 157: } ! 158: ! 159: ok = addBridgeIORange( 0, 0x10000 ); ! 160: ! 161: return( super::configure( provider)); ! 162: } ! 163: ! 164: void AppleMacRiscPCI::free() ! 165: { ! 166: if( configAddrMap) ! 167: configAddrMap->release(); ! 168: if( configDataMap) ! 169: configDataMap->release(); ! 170: if( lock) ! 171: IOSimpleLockFree( lock); ! 172: ! 173: super::free(); ! 174: } ! 175: ! 176: IODeviceMemory * AppleMacRiscPCI::ioDeviceMemory( void ) ! 177: { ! 178: return( ioMemory); ! 179: } ! 180: ! 181: IODeviceMemory * AppleMacRiscVCI::ioDeviceMemory( void ) ! 182: { ! 183: return( 0 ); ! 184: } ! 185: ! 186: bool AppleMacRiscVCI::configure( IOService * provider ) ! 187: { ! 188: addBridgeMemoryRange( 0x90000000, 0x10000000, true ); ! 189: ! 190: return( AppleMacRiscPCI::configure( provider)); ! 191: } ! 192: ! 193: UInt8 AppleMacRiscPCI::firstBusNum( void ) ! 194: { ! 195: return( primaryBus ); ! 196: } ! 197: ! 198: UInt8 AppleMacRiscPCI::lastBusNum( void ) ! 199: { ! 200: return( firstBusNum() ); ! 201: } ! 202: ! 203: IOPCIAddressSpace AppleMacRiscPCI::getBridgeSpace( void ) ! 204: { ! 205: IOPCIAddressSpace space; ! 206: ! 207: space.bits = 0; ! 208: space.s.busNum = primaryBus; ! 209: space.s.deviceNum = kBridgeSelfDevice; ! 210: ! 211: return( space ); ! 212: } ! 213: ! 214: inline bool AppleMacRiscPCI::setConfigSpace( IOPCIAddressSpace space, ! 215: UInt8 offset ) ! 216: { ! 217: UInt32 addrCycle; ! 218: ! 219: if( space.s.busNum == primaryBus) { ! 220: ! 221: if( space.s.deviceNum < kBridgeSelfDevice) ! 222: return( false); ! 223: ! 224: // primary config cycle ! 225: addrCycle = ( (1 << space.s.deviceNum) ! 226: | (space.s.functionNum << 8) ! 227: | offset ); ! 228: ! 229: } else { ! 230: // pass thru config cycle ! 231: addrCycle = ( (space.bits) ! 232: | offset ! 233: | 1 ); ! 234: } ! 235: ! 236: do { ! 237: OSWriteSwapInt32( configAddr, 0, addrCycle); ! 238: eieio(); ! 239: } while( addrCycle != OSReadSwapInt32( configAddr, 0 )); ! 240: eieio(); ! 241: ! 242: return( true ); ! 243: } ! 244: ! 245: ! 246: UInt32 AppleMacRiscPCI::configRead32( IOPCIAddressSpace space, ! 247: UInt8 offset ) ! 248: { ! 249: UInt32 data; ! 250: IOInterruptState ints; ! 251: ! 252: ints = IOSimpleLockLockDisableInterrupt( lock ); ! 253: ! 254: if( setConfigSpace( space, offset )) { ! 255: ! 256: data = OSReadSwapInt32( configData, offset & configDataOffsetMask ); ! 257: eieio(); ! 258: ! 259: } else ! 260: data = 0xffffffff; ! 261: ! 262: IOSimpleLockUnlockEnableInterrupt( lock, ints ); ! 263: ! 264: return( data ); ! 265: } ! 266: ! 267: void AppleMacRiscPCI::configWrite32( IOPCIAddressSpace space, ! 268: UInt8 offset, UInt32 data ) ! 269: { ! 270: IOInterruptState ints; ! 271: ! 272: ints = IOSimpleLockLockDisableInterrupt( lock ); ! 273: ! 274: if( setConfigSpace( space, offset )) { ! 275: ! 276: OSWriteSwapInt32( configData, offset & configDataOffsetMask, data ); ! 277: eieio(); ! 278: /* read to sync (?) */ ! 279: (void) OSReadSwapInt32( configData, offset & configDataOffsetMask ); ! 280: eieio(); ! 281: sync(); ! 282: isync(); ! 283: } ! 284: ! 285: IOSimpleLockUnlockEnableInterrupt( lock, ints ); ! 286: } ! 287: ! 288: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 289: ! 290: #undef super ! 291: #define super AppleMacRiscPCI ! 292: ! 293: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 294: ! 295: bool AppleMacRiscAGP::configure( IOService * provider ) ! 296: { ! 297: if( !findPCICapability( getBridgeSpace(), kIOPCIAGPCapability)) ! 298: return( false ); ! 299: ! 300: return( super::configure( provider)); ! 301: } ! 302: ! 303: IOPCIDevice * AppleMacRiscAGP::createNub( OSDictionary * from ) ! 304: { ! 305: IOPCIDevice * nub; ! 306: IOPCIAddressSpace space; ! 307: bool isAGP; ! 308: ! 309: spaceFromProperties( from, &space); ! 310: ! 311: isAGP = ( (space.s.deviceNum != getBridgeSpace().s.deviceNum) ! 312: && findPCICapability( space, kIOPCIAGPCapability)); ! 313: ! 314: if( isAGP) ! 315: nub = new IOAGPDevice; ! 316: else ! 317: nub = super::createNub( from ); ! 318: ! 319: return( nub ); ! 320: } ! 321: ! 322: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 323: ! 324: IOReturn AppleMacRiscAGP::createAGPSpace( IOPCIAddressSpace master, ! 325: IOOptionBits options, ! 326: IOPhysicalAddress * address, ! 327: IOPhysicalLength * length ) ! 328: { ! 329: IOReturn err; ! 330: IORangeAllocator * platformRanges; ! 331: IOPCIAddressSpace target = getBridgeSpace(); ! 332: IOPhysicalLength agpLength; ! 333: IOPhysicalAddress gartPhys; ! 334: ! 335: enum { agpSpacePerPage = 4 * 1024 * 1024 }; ! 336: enum { agpBytesPerGartByte = 1024 }; ! 337: enum { alignLen = 4 * 1024 * 1024 - 1 }; ! 338: ! 339: destroyAGPSpace( master ); ! 340: ! 341: agpLength = *length; ! 342: if( !agpLength) ! 343: agpLength = 32 * 1024 * 1024; ! 344: ! 345: agpLength = (agpLength + alignLen) & ~alignLen; ! 346: ! 347: err = kIOReturnVMError; ! 348: do { ! 349: ! 350: gartLength = agpLength / agpBytesPerGartByte; ! 351: gartArray = (volatile UInt32 *) IOMallocContiguous( ! 352: gartLength, 4096, &gartPhys ); ! 353: if( !gartArray) ! 354: continue; ! 355: //IOMapPages( kernel_map, gartArray, gartPhys, gartLength, kIOMapInhibitCache ); ! 356: bzero( (void *) gartArray, gartLength); ! 357: ! 358: platformRanges = getPlatform()->getPhysicalRangeAllocator(); ! 359: ! 360: for( agpBaseIndex = 0xf; agpBaseIndex > 0; agpBaseIndex--) { ! 361: systemBase = agpBaseIndex * 0x10000000; ! 362: if( platformRanges->allocateRange( systemBase, agpLength )) { ! 363: systemLength = agpLength; ! 364: break; ! 365: } ! 366: } ! 367: if( !systemLength) ! 368: continue; ! 369: ! 370: agpRange = IORangeAllocator::withRange( agpLength, 4096 ); ! 371: if( !agpRange) ! 372: continue; ! 373: ! 374: *address = systemBase; ! 375: *length = systemLength; ! 376: #if 0 ! 377: coarseAddressMask |= (1 << agpBaseIndex); ! 378: configWrite32( target, kMacRISCAddressSelect, ! 379: (coarseAddressMask << 16) | fineAddressMask ); ! 380: #endif ! 381: configWrite32( target, kUniNAGP_BASE, agpBaseIndex << 28 ); ! 382: ! 383: assert( 0 == (gartPhys & 0xfff)); ! 384: configWrite32( target, kUniNGART_BASE, ! 385: gartPhys | (agpLength / agpSpacePerPage)); ! 386: ! 387: err = kIOReturnSuccess; ! 388: ! 389: } while( false ); ! 390: ! 391: if( kIOReturnSuccess == err) ! 392: setAGPEnable( master, true, 1 ); ! 393: else ! 394: destroyAGPSpace( master ); ! 395: ! 396: return( err ); ! 397: } ! 398: ! 399: IOReturn AppleMacRiscAGP::destroyAGPSpace( IOPCIAddressSpace master ) ! 400: { ! 401: IORangeAllocator * platformRanges; ! 402: ! 403: setAGPEnable( master, false, 0 ); ! 404: ! 405: if( gartArray) { ! 406: IOFreeContiguous( (void *) gartArray, gartLength); ! 407: gartArray = 0; ! 408: } ! 409: if( agpRange) { ! 410: agpRange->release(); ! 411: agpRange = 0; ! 412: } ! 413: if( systemLength) { ! 414: platformRanges = getPlatform()->getPhysicalRangeAllocator(); ! 415: platformRanges->deallocate( systemBase, systemLength); ! 416: systemLength = 0; ! 417: } ! 418: ! 419: return( kIOReturnSuccess ); ! 420: } ! 421: ! 422: IORangeAllocator * AppleMacRiscAGP::getAGPRangeAllocator( ! 423: IOPCIAddressSpace master ) ! 424: { ! 425: // if( agpRange) agpRange->retain(); ! 426: return( agpRange ); ! 427: } ! 428: ! 429: IOOptionBits AppleMacRiscAGP::getAGPStatus( IOPCIAddressSpace master, ! 430: IOOptionBits options = 0 ) ! 431: { ! 432: return( configRead32( getBridgeSpace(), kUniNINTERNAL_STATUS ) ); ! 433: } ! 434: ! 435: IOReturn AppleMacRiscAGP::commitAGPMemory( IOPCIAddressSpace master, ! 436: IOMemoryDescriptor * memory, ! 437: IOByteCount agpOffset, ! 438: IOOptionBits options = 0 ) ! 439: { ! 440: IOPCIAddressSpace target = getBridgeSpace(); ! 441: IOReturn err = kIOReturnSuccess; ! 442: UInt32 offset = 0; ! 443: IOPhysicalAddress physAddr; ! 444: IOByteCount len; ! 445: ! 446: // ok = agpRange->allocate( memory->getLength(), &agpOffset ); ! 447: ! 448: assert( agpOffset < systemLength ); ! 449: agpOffset /= (page_size / 4); ! 450: while( (physAddr = memory->getPhysicalSegment( offset, &len ))) { ! 451: ! 452: offset += len; ! 453: len = (len + 0xfff) & ~0xfff; ! 454: while( len > 0) { ! 455: OSWriteLittleInt32( gartArray, agpOffset, ! 456: ((physAddr & ~0xfff) | 1)); ! 457: agpOffset += 4; ! 458: physAddr += page_size; ! 459: len -= page_size; ! 460: } ! 461: } ! 462: flush_dcache( (vm_offset_t) gartArray, gartLength, false); ! 463: sync(); ! 464: isync(); ! 465: #if 1 ! 466: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV ); ! 467: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 468: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET); ! 469: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 470: #endif ! 471: ! 472: return( err ); ! 473: } ! 474: ! 475: IOReturn AppleMacRiscAGP::releaseAGPMemory( IOPCIAddressSpace master, ! 476: IOMemoryDescriptor * memory, ! 477: IOByteCount agpOffset ) ! 478: { ! 479: IOPCIAddressSpace target = getBridgeSpace(); ! 480: IOReturn err = kIOReturnSuccess; ! 481: IOByteCount length; ! 482: ! 483: if( !memory) ! 484: return( kIOReturnBadArgument ); ! 485: ! 486: length = memory->getLength(); ! 487: ! 488: if( (agpOffset + length) >= systemLength) ! 489: return( kIOReturnBadArgument ); ! 490: ! 491: // agpRange->deallocate( agpOffset, length ); ! 492: ! 493: length = (length + 0xfff) & ~0xfff; ! 494: agpOffset /= page_size; ! 495: while( length > 0) { ! 496: gartArray[ agpOffset++ ] = 0; ! 497: length -= page_size; ! 498: } ! 499: flush_dcache( (vm_offset_t) gartArray, gartLength, false); ! 500: sync(); ! 501: isync(); ! 502: ! 503: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV ); ! 504: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 505: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET); ! 506: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 507: ! 508: return( err ); ! 509: } ! 510: ! 511: IOReturn AppleMacRiscAGP::setAGPEnable( IOPCIAddressSpace master, ! 512: bool enable, IOOptionBits options ) ! 513: { ! 514: IOReturn err = kIOReturnSuccess; ! 515: IOPCIAddressSpace target = getBridgeSpace(); ! 516: UInt32 command; ! 517: UInt32 targetStatus, masterStatus; ! 518: ! 519: if( enable) { ! 520: ! 521: targetStatus = configRead32( target, kIOPCIConfigAGPTargetStatus ); ! 522: masterStatus = configRead32( master, kIOPCIConfigAGPMasterStatus ); ! 523: ! 524: command = kIOAGPSideBandAddresssing ! 525: | kIOAGP4xDataRate | kIOAGP2xDataRate | kIOAGP1xDataRate; ! 526: command &= targetStatus; ! 527: command &= masterStatus; ! 528: ! 529: if( command & kIOAGP4xDataRate) ! 530: command &= ~(kIOAGP2xDataRate | kIOAGP1xDataRate); ! 531: else if( command & kIOAGP2xDataRate) ! 532: command &= ~(kIOAGP1xDataRate); ! 533: ! 534: command |= kIOAGPEnable; ! 535: ! 536: if( targetStatus > masterStatus) ! 537: targetStatus = masterStatus; ! 538: command |= (targetStatus & kIOAGPRequestQueueMask); ! 539: ! 540: #if 1 ! 541: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV ); ! 542: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 543: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET); ! 544: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 545: #endif ! 546: do { ! 547: configWrite32( target, kIOPCIConfigAGPTargetCommand, command ); ! 548: } while( (command & kIOAGPEnable) != ! 549: (kIOAGPEnable & configRead32( target, kIOPCIConfigAGPTargetCommand))); ! 550: ! 551: do { ! 552: configWrite32( master, kIOPCIConfigAGPMasterCommand, command ); ! 553: } while( (command & kIOAGPEnable) != ! 554: (kIOAGPEnable & configRead32( master, kIOPCIConfigAGPMasterCommand))); ! 555: ! 556: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV ); ! 557: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 558: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET); ! 559: configWrite32( target, kUniNGART_CTRL, kGART_EN ); ! 560: ! 561: } else { ! 562: ! 563: configWrite32( master, kIOPCIConfigAGPMasterCommand, 0 ); ! 564: configWrite32( target, kIOPCIConfigAGPTargetCommand, 0 ); ! 565: configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV ); ! 566: configWrite32( target, kUniNGART_CTRL, 0 ); ! 567: configWrite32( target, kUniNGART_CTRL, kGART_2xRESET); ! 568: configWrite32( target, kUniNGART_CTRL, 0 ); ! 569: } ! 570: ! 571: return( err ); ! 572: } ! 573: ! 574: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.