IOReturn AppleI386AGP::commitAGPMemory( IOAGPDevice * master, IOMemoryDescriptor * memory, IOByteCount agpOffset, IOOptionBits options ) { IOPCIAddressSpace target = getBridgeSpace(); IOReturn err = kIOReturnSuccess; UInt32 offset = 0, tmp, agpCtrl; IOPhysicalAddress physAddr; IOByteCount len; // ok = agpRange->allocate( memory->getLength(), &agpOffset ); agpCtrl = configRead32(target, kiAGPCTRL); agpCtrl &= ~(1 << 7); configWrite32( target, kiAGPCTRL, agpCtrl ); // b7 gtlb ena if(memory) { assert( agpOffset < systemLength ); agpOffset /= (page_size / 4); while( (physAddr = memory->getPhysicalSegment( offset, &len ))) { offset += len; len = (len + 0xfff) & ~0xfff; while( len > 0) { OSWriteLittleInt32( gartArray, agpOffset, ((physAddr & ~0xfff) | 1)); agpOffset += 4; physAddr += page_size; len -= page_size; } } // Read back from last entry written to flush entry to main memory. tmp = OSReadLittleInt32(gartArray, agpOffset-4); #if 1 // Deal with stupid Pentium 4 8-deeps store queue crap. for(offset = 0; offset < 64*16; offset += 64) { tmp = OSReadLittleInt32(gartArray, offset); OSWriteLittleInt32(gartArray, offset, tmp); } #endif } agpCtrl = configRead32(target, kiAGPCTRL); agpCtrl |= (1 << 7); configWrite32( target, kiAGPCTRL, agpCtrl ); // b7 gtlb ena return( err ); }
IOReturn AppleI386AGP::releaseAGPMemory( IOAGPDevice * master, IOMemoryDescriptor * memory, IOByteCount agpOffset, IOOptionBits options ) { IOPCIAddressSpace target = getBridgeSpace(); IOReturn err = kIOReturnSuccess; IOByteCount length; UInt32 agpCtrl; if( !memory) return( kIOReturnBadArgument ); length = memory->getLength(); if( (agpOffset + length) > systemLength) return( kIOReturnBadArgument ); agpCtrl = configRead32(target, kiAGPCTRL); agpCtrl &= ~(1 << 7); configWrite32( target, kiAGPCTRL, agpCtrl ); // b7 gtlb ena // agpRange->deallocate( agpOffset, length ); length = (length + 0xfff) & ~0xfff; agpOffset /= page_size; while( length > 0) { gartArray[ agpOffset++ ] = 0; length -= page_size; } agpCtrl = configRead32(target, kiAGPCTRL); agpCtrl |= (1 << 7); configWrite32( target, kiAGPCTRL, agpCtrl ); // b7 gtlb ena return( err ); }
IOReturn AppleI386AGP::setAGPEnable( IOAGPDevice * _master, bool enable, IOOptionBits options ) { IOReturn err = kIOReturnSuccess; IOPCIAddressSpace target = getBridgeSpace(); IOPCIAddressSpace master = _master->space; UInt32 command; UInt32 targetStatus, masterStatus; UInt8 masterAGPRegisters = _master->masterAGPRegisters; if( enable) { #if XX configWrite32( target, kUniNGART_CTRL, gartCtrl | 0); #endif targetStatus = configRead32( target, targetAGPRegisters + kIOPCIConfigAGPStatusOffset ); masterStatus = configRead32( master, masterAGPRegisters + kIOPCIConfigAGPStatusOffset ); DEBG("target %08lx, master %08lx\n", targetStatus, masterStatus); command = kIOAGPSideBandAddresssing | kIOAGPFastWrite | kIOAGP4xDataRate | kIOAGP2xDataRate | kIOAGP1xDataRate; command &= targetStatus; command &= masterStatus; if( command & kIOAGP4xDataRate) command &= ~(kIOAGP2xDataRate | kIOAGP1xDataRate); else if( command & kIOAGP2xDataRate) command &= ~(kIOAGP1xDataRate); else if( 0 == (command & kIOAGP1xDataRate)) return( kIOReturnUnsupported ); command |= kIOAGPEnable; command &= agpCommandMask; if( targetStatus > masterStatus) targetStatus = masterStatus; command |= (targetStatus & kIOAGPRequestQueueMask); _master->setProperty(kIOAGPCommandValueKey, &command, sizeof(command)); DEBG("AGPCMD %08lx\n", command); #if XX configWrite32( target, kUniNGART_CTRL, gartCtrl | kGART_EN | kGART_INV ); #endif #if 1 configWrite32( target, targetAGPRegisters + kIOPCIConfigAGPCommandOffset, command ); DEBG("target command %08lx\n", configRead32( target, targetAGPRegisters + kIOPCIConfigAGPCommandOffset)); configWrite32( master, masterAGPRegisters + kIOPCIConfigAGPCommandOffset, command ); DEBG("master command %08lx\n", configRead32( master, masterAGPRegisters + kIOPCIConfigAGPCommandOffset)); #endif UInt32 value = configRead16( target, kiMCHCFG ); DEBG("kiMCHCFG %08lx\n", value); value |= (1 << 9) | (0 << 10); configWrite16( target, kiMCHCFG, value ); DEBG("kiMCHCFG %02x\n", configRead16( target, kiMCHCFG )); #if 0 configWrite32( target, kUniNGART_CTRL, gartCtrl | kGART_EN | kGART_INV ); configWrite32( target, kUniNGART_CTRL, gartCtrl | kGART_EN ); configWrite32( target, kUniNGART_CTRL, gartCtrl | kGART_EN | kGART_2xRESET); configWrite32( target, kUniNGART_CTRL, gartCtrl | kGART_EN ); #endif _master->masterState |= kIOAGPStateEnabled; } else { #if XX while( 0 == (kIOAGPIdle & configRead32( getBridgeSpace(), kUniNINTERNAL_STATUS ))) {} #endif configWrite32( master, masterAGPRegisters + kIOPCIConfigAGPCommandOffset, 0 ); configWrite32( target, targetAGPRegisters + kIOPCIConfigAGPCommandOffset, 0 ); #if 0 configWrite32( target, kUniNGART_CTRL, gartCtrl | kGART_EN | kGART_INV ); configWrite32( target, kUniNGART_CTRL, gartCtrl | 0 ); configWrite32( target, kUniNGART_CTRL, gartCtrl | kGART_2xRESET); configWrite32( target, kUniNGART_CTRL, gartCtrl | 0 ); #endif UInt32 value = configRead16( target, kiMCHCFG ); DEBG("kiMCHCFG %08lx\n", value); value &= ~((1 << 9)|(1 << 10)); configWrite16( target, kiMCHCFG, value ); _master->masterState &= ~kIOAGPStateEnabled; } return( err ); }
IOReturn AppleI386AGP::createAGPSpace( IOAGPDevice * master, IOOptionBits options, IOPhysicalAddress * address, IOPhysicalLength * length ) { IOReturn err; IOPCIAddressSpace target = getBridgeSpace(); IOPhysicalLength agpLength; UInt32 agpCtrl; enum { agpSpacePerPage = 4 * 1024 * 1024 }; enum { agpBytesPerGartByte = 1024 }; enum { alignLen = 4 * 1024 * 1024 - 1 }; destroyAGPSpace( master ); agpCommandMask = 0xffffffff; agpCommandMask &= ~kIOAGPFastWrite; // agpCommandMask &= ~kIOAGPSideBandAddresssing; { // There's an nVidia NV11 ROM (revision 1017) that says that it can do fast writes, // but can't, and can often lock the machine up when fast writes are enabled. #define kNVIDIANV11EntryName "NVDA,NVMac" #define kNVROMRevPropertyName "rom-revision" #define kNVBadRevision '1017' const UInt32 badRev = kNVBadRevision; OSData * data; if( (0 == strcmp( kNVIDIANV11EntryName, master->getName())) && (data = OSDynamicCast(OSData, master->getProperty(kNVROMRevPropertyName))) && (data->isEqualTo( &badRev, sizeof(badRev) ))) agpCommandMask &= ~kIOAGPFastWrite; } agpLength = *length; if( !agpLength) agpLength = 32 * 1024 * 1024; agpLength = (agpLength + alignLen) & ~alignLen; err = kIOReturnVMError; do { gartLength = agpLength / agpBytesPerGartByte; gartArray = (volatile UInt32 *) IOMallocContiguous( gartLength, 4096, &gartPhys ); if( !gartArray) continue; IOSetProcessorCacheMode(kernel_task, (vm_address_t) gartArray, gartLength, kIOInhibitCache); bzero( (void *) gartArray, gartLength); // IOUnmapPages( kernel_map, (vm_address_t) gartArray, gartLength ); // is this std? systemBase = configRead32( target, kiAPBASE ) & 0xfffffff0; DEBG("APSIZE: %08lx\n", (UInt32)configRead8(target, kiAPSIZE)); systemLength = (((configRead8( target, kiAPSIZE ) & 0x3f) ^ 0x3f) + 1) << 22; DEBG("sysB %08lx, sysL %08lx\n", systemBase, systemLength); if( !systemLength) continue; if (systemLength > agpLength) systemLength = agpLength; DEBG("sysB %08lx, sysL %08lx\n", systemBase, systemLength); agpRange = IORangeAllocator::withRange( agpLength, 4096 ); if( !agpRange) continue; *address = systemBase; *length = systemLength; agpCtrl = configRead32(target, kiAGPCTRL); agpCtrl &= ~(1 << 7); configWrite32( target, kiAGPCTRL, agpCtrl ); // b7 gtlb ena // configWrite32( target, kiAGPCTRL, 0 << 7 ); // b7 gtlb ena // assert( 0 == (gartPhys & 0xfff)); configWrite32( target, kiATTBASE, gartPhys ); agpCtrl = configRead32(target, kiAGPCTRL); //agpCtrl |= (1 << 7); configWrite32( target, kiAGPCTRL, agpCtrl ); // b7 gtlb ena DEBG("kiAGPCTRL %08lx, kiATTBASE %08lx\n", configRead32( target, kiAGPCTRL ), configRead32( target, kiATTBASE )); err = kIOReturnSuccess; } while( false ); if( kIOReturnSuccess == err) setAGPEnable( master, true, 0 ); else destroyAGPSpace( master ); return( err ); }
int main(int argc, char **argv) { io_registry_entry_t service; io_connect_t connect; kern_return_t status; service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleACPIPlatformExpert")); assert(service); if (service) { status = IOServiceOpen(service, mach_task_self(), 0, &connect); IOObjectRelease(service); assert(kIOReturnSuccess == status); } uint32_t count = 0; uint32_t segment = 0; uint32_t maxBus = 0; uint32_t bus, device, fn, maxFn; uint32_t vendProd; if (argc > 3) { bus = strtoul(argv[1], NULL, 0); device = strtoul(argv[2], NULL, 0); fn = strtoul(argv[3], NULL, 0); if (argc == 4) { dumpDevice(connect, segment, bus, device, fn, NULL, NULL); count++; } if (argc > 5) { uint32_t offs; uint32_t data; offs = strtoul(argv[4], NULL, 0); data = strtoul(argv[5], NULL, 0); configWrite32(connect, segment, bus, device, fn, offs, data); printf("wrote 0x%08x to [%d, %d, %d]:0x%X\n", data, bus, device, fn, offs); } else if (argc > 4) { uint32_t offs; uint32_t data; offs = strtoul(argv[4], NULL, 0); data = configRead32(connect, segment, bus, device, fn, offs); printf("read 0x%08x from [%d, %d, %d]:0x%X\n", data, bus, device, fn, offs); } } else if (argc > 2) { uint64_t offs; uint32_t data; offs = strtoull(argv[1], NULL, 0); data = strtoul(argv[2], NULL, 0); physWrite32(connect, offs, data); printf("wrote 0x%08x to 0x%llX\n", data, offs); } else if (argc > 1) { uint64_t offs; uint32_t data; offs = strtoull(argv[1], NULL, 0); if (true || (offs > 0x10000ULL)) { data = physRead32(connect, offs); printf("read 0x%08x from mem 0x%llX\n", data, offs); } else { data = ioRead32(connect, offs); printf("read 0x%08x from i/o 0x%llX\n", data, offs); } } else for (bus = 0; bus <= maxBus; bus++) { for (device = 0; device < 32; device++) { maxFn = 0; for (fn = 0; fn <= maxFn; fn++) { vendProd = configRead32(connect, segment, bus, device, fn, kIOPCIConfigVendorID); if ((0xFFFFFFFF == vendProd) || !vendProd) continue; count++; dumpDevice(connect, segment, bus, device, fn, &maxBus, &maxFn); } } } printf("total: %d\n", count); exit(0); }