Beispiel #1
0
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 );
}
Beispiel #2
0
IOOptionBits AppleI386AGP::getAGPStatus( IOAGPDevice * master,
					    IOOptionBits options )
{
    IOPCIAddressSpace 	target = getBridgeSpace();

#if XXX
    return( configRead32( target, kUniNINTERNAL_STATUS ) );
#else
    return( 0 );
#endif
}
Beispiel #3
0
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 );
}
Beispiel #4
0
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 );
}
Beispiel #5
0
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);    
}
static void
dumpDevice(io_connect_t connect, uint32_t segment,
                                uint32_t bus, uint32_t device, uint32_t fn,
                                uint32_t * maxBus, uint32_t * maxFn)
{
    io_registry_entry_t service;
    kern_return_t       status;
    io_name_t           name;
    uint64_t     		entryID;
    uint32_t off;
    uint32_t vendProd;
    uint32_t vend;
    uint32_t prod;
    uint32_t headerType;
    uint32_t priBusNum;
    uint32_t secBusNum;
    uint32_t subBusNum;
    uint32_t data[256/sizeof(uint32_t)];
    uint8_t *bytes = (uint8_t *)&data[0];

    for(off = 0; off < 256; off += 4)
        data[off >> 2] = configRead32(connect, segment, bus, device, fn, off);

    vendProd = data[0];
    vend = vendProd & 0xffff;
    prod = vendProd >> 16;
    printf("[%d, %d, %d] 0x%04x, 0x%04x - ", bus, device, fn, vend, prod);

    service = lookService(segment, bus, device, fn);
    if (service)
    {
        status = IORegistryEntryGetName(service, name);
        assert(kIOReturnSuccess == status);
        status = IORegistryEntryGetRegistryEntryID(service, &entryID);
        assert(kIOReturnSuccess == status);
        printf("\"%s\", 0x%qx - ", name, entryID);
        IOObjectRelease(service);
    }

    headerType = bytes[kIOPCIConfigHeaderType];
    if (maxFn && (0x80 & headerType))
        *maxFn = 7;
    headerType &= 0x7f;
    if (!headerType)
    {
        // device dump
        printf("class: 0x%x, 0x%x, 0x%x\n", 
                bytes[kIOPCIConfigRevisionID + 3],
                bytes[kIOPCIConfigRevisionID + 2],
                bytes[kIOPCIConfigRevisionID + 1]);
    }
    else
    {
        priBusNum = bytes[kPCI2PCIPrimaryBus];
        secBusNum = bytes[kPCI2PCISecondaryBus];
        subBusNum = bytes[kPCI2PCISubordinateBus];
        printf("bridge: [%d, %d, %d]\n", priBusNum, secBusNum, subBusNum);
        if (maxBus && (subBusNum > *maxBus))
            *maxBus = subBusNum;
    }

    dump(bytes, sizeof(data));
    printf("\n");
}