Jump to content

New ATI Framebuffer Xcode project to start from


dong
 Share

125 posts in this topic

Recommended Posts

ah well... anyway it has wrong values, with virtual too :happymac:

 

This is interesting. It looks like you need "WithRegister" to get correct IO memory map, but "WithIndex" to get correct FB memory map. For my x1400, "WithIndex" works for both IO and FB. Anyway, the FB map base is obviously in fact not needed by rhdAtomInit, thus a wrong value did not cause problems.

 

I have a question, what are the usage of "device->retain();" and "bar[ 0 ]->retain();" in your code? There is no corresponding "release()", would that be a reason that the kext won't be unloaded automatically?

Link to comment
Share on other sites

well... that was in code which I used as example of using IODevicememory, bar->retain is useless yeah :rolleyes:

 

problems with unloading existed before it, it even not unloading problem, the problem is that if X2000 loads durring ATY_init is in memory (maybe not even attached), then OSX cant get to gui

 

 

i just checked instances number of aty_init class after kextloading it, it's 0, means kexts unattached from device, but still present in memory. wtf.

Link to comment
Share on other sites

well... that was in code which I used as example of using IODevicememory, bar->retain is useless yeah :rolleyes:

 

problems with unloading existed before it, it even not unloading problem, the problem is that if X2000 loads durring ATY_init is in memory (maybe not even attached), then OSX cant get to gui

 

 

i just checked instances number of aty_init class after kextloading it, it's 0, means kexts unattached from device, but still present in memory. wtf.

Did you check the instances number of the provider "device"? Maybe Any unreleased class in a kext could cause unload problem. Also I still suggest comment out all atomSaveRegister related codes as it allocates memory but not releases them in rhdAtomInit().

Link to comment
Share on other sites

>Did you check the instances number of the provider "device"?

 

Ahm....how to check ?

ioreg | grep IOPCIDevice

type it before and after kextload ATY_Init.kext

and look for the line corresponding to the video card, for me it's like:

| | | +-o VID@0 <class IOPCIDevice, registered, matched, active, busy 0, retain 13>

check how the retain count changes.

 

You may need release your bar[0] even without retain it. Well, I tested it, still same problem. Even if you load ATY_Init without doing the initialization thing, the gui will be destroyed.

Link to comment
Share on other sites

I played with ATY_Init.cpp a bit and found the only way to prevent its side-effect on GUI is to comment out all "device->retain()", "device->open(this)" and "device->close(this)", and add a "terminate(kIOServiceSynchronous);" right before each "return NULL".

"terminate(kIOServiceSynchronous);" will force waiting for the terminate of this service and avoid to be used again for matching.

I only tested it without the actual initialization of video card.

Update:

Sorry, I can not repeat it. It remains a problem. What I can say is that it seems has no relation with the initialization, we may test to see will a empty kext of this kind doing the same thing to GUI.

Link to comment
Share on other sites

how do you use aty_init so it doesnt hurt gui for you ?

 

I tried installing it to /S/L/E and manual loading in single user, nothing changed.

 

I have an script which makes kextstat dump durring boot, there i can see ATY_init x2000 and Lamna/MOmot loaded at same time, when blue screen arrives, there is no more ATY_Init

Link to comment
Share on other sites

if anyone wanna test, here it is ....

add your bios dump(of unposted carf) into natit as ATY,bin_image key, for your card section, atm it has bioses of 4850/4870/2600xt

add device-id of unposted card to ATY_Init.kext plist (replace 95881002 there)

boot single user, kextload natit

kextlaod aty_init

kextunload aty_init

exit

Thanks.

How get i that "bios dump(of unposted carf) " ?

I have an ATI 3850, running DSDT injection insted of natit, because 3850 natit Lamna FB didnt work at all, i must use megadolon FB by DSDT values below and orig. ATI 10.5.6 drivers.

 

Would it be possible to add things needed (items to iject like atombios,...) also in my dsdt for testing or do i need natit for that test ?

 

Device (PEGP)

{

Name (_ADR, 0x00010000)

Device (GFX0)

{

Name (_ADR, Zero)

Name (_SUN, Zero)

Method (_DSM, 4, NotSerialized)

{

Store (Package (0x4C)

{

"@0,compatible",

Buffer (0x0E)

{

"ATY,Megalodon"

},

"@0,device_type",

Buffer (0x08)

{

"display"

},

"@0,name",

Buffer (0x0E)

{

"ATY,Megalodon"

},

 

"@1,compatible",

Buffer (0x0E)

{

"ATY,Megalodon"

},

"@1,device_type",

Buffer (0x08)

{

"display"

},

"@1,name",

Buffer (0x0E)

{

"ATY,Megalodon"

},

"AAPL,aux-power-connected",

Buffer (0x04)

{

0x01, 0x00, 0x00, 0x00

},

"AAPL,backlight-control",

Buffer (0x04)

{

0x00, 0x00, 0x00, 0x00

},

"AAPL,EMC-Display-List",

Buffer (0x40)

{

/* 0000 */ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0008 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0010 */ 0x06, 0x10, 0x00, 0x00, 0x1B, 0x92, 0x00, 0x00,

/* 0018 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0020 */ 0x06, 0x10, 0x00, 0x00, 0x1C, 0x92, 0x00, 0x00,

/* 0028 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0030 */ 0x06, 0x10, 0x00, 0x00, 0x21, 0x92, 0x00, 0x00,

/* 0038 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

},

 

"AAPL00,blackscreen-preferences",

Buffer (0x04)

{

0x00, 0x00, 0x00, 0x08

},

"AAPL01,blackscreen-preferences",

Buffer (0x04)

{

0x00, 0x00, 0x00, 0x08

},

"AAPL01,Coherency",

Buffer (0x04)

{

0x02, 0x00, 0x00, 0x00

},

"ATY,Card#",

Buffer (0x0E)

{

"109-B148xx-00"

},

"ATY,Copyright",

Buffer (0x32)

{

"Copyright AMD Inc. All Rights Reserved. 2005-2008"

},

"ATY,DeviceID",

Buffer (0x02)

{

0x05, 0x95

},

"ATY,EFICompileDate",

Buffer (0x0C)

{

"Dec 18 2007"

},

"ATY,EFIDriverType",

Buffer (One)

{

0x02

},

"ATY,EFIEnabledMode",

Buffer (One)

{

0x02

},

"ATY,EFIHWInitStatus",

Buffer (0x08)

{

/* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

},

"ATY,EFIOrientation",

Buffer (One)

{

0x01

},

"ATY,EFIVersion",

Buffer (0x10)

{

"01.00.236"

},

"ATY,EFIVersionBios",

Buffer (0x0F)

{

"113-B14801-023"

},

"ATY,FrameBufferOffset",

Buffer (0x08)

{

/* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00

},

"ATY,HWGPIO",

Buffer (0x04)

{

0x23, 0xA8, 0x48, 0x00

},

"ATY,IOSpaceOffset",

Buffer (0x08)

{

/* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00

},

"ATY,MCLK",

Buffer (0x04)

{

0x00, 0x35, 0x0C, 0x00

},

"ATY,MemRevisionID",

Buffer (0x02)

{

0x01, 0x00

},

"ATY,MemVendorID",

Buffer (0x02)

{

0x06, 0x00

},

"ATY,PCIConfigSpace",

Buffer (0x0100)

{

/* 0000 */ 0x02, 0x10, 0x88, 0x95, 0x07, 0x00, 0x10, 0x00,

/* 0008 */ 0x00, 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x00,

/* 0010 */ 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,

/* 0018 */ 0x04, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,

/* 0020 */ 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0028 */ 0x00, 0x00, 0x00, 0x00, 0x6B, 0x10, 0xA6, 0x00,

/* 0030 */ 0x00, 0x00, 0xA0, 0x90, 0x50, 0x00, 0x00, 0x00,

/* 0038 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,

/* 0040 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0048 */ 0x00, 0x00, 0x00, 0x00, 0x6B, 0x10, 0xA6, 0x00,

/* 0050 */ 0x01, 0x58, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00,

/* 0058 */ 0x10, 0xA0, 0x11, 0x00, 0xA0, 0x8F, 0x00, 0x00,

/* 0060 */ 0x10, 0x08, 0x00, 0x00, 0x02, 0x0D, 0x00, 0x08,

/* 0068 */ 0x42, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x00,

/* 0070 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0078 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0080 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0088 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0090 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0098 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00B0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00B8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00C0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00C8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00D0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00D8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 00F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

},

"ATY,PlatformInfo",

Buffer (0x80)

{

/* 0000 */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0008 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0010 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0018 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0020 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0028 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0030 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0038 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0040 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0048 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0050 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0058 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0060 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0068 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0070 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

/* 0078 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

},

"ATY,RefCLK",

Buffer (0x04)

{

0x8C, 0x0A, 0x00, 0x00

},

"ATY,RegisterSpaceOffset",

Buffer (0x08)

{

/* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x90, 0xA2, 0x00, 0x00

},

"ATY,Rom#",

Buffer (0x0F)

{

"113-B1480A-236"

},

"ATY,SCLK",

Buffer (0x04)

{

0x60, 0xAE, 0x0A, 0x00

},

"ATY,VendorID",

Buffer (0x02)

{

0x02, 0x10

},

"VRAM,totalsize",

Buffer (0x04)

{

0x00, 0x00, 0x00, 0x20

},

"device_type",

Buffer (0x14)

{

"ATY,MegalodonParent"

},

"model",

Buffer (0x1A)

{

"ATI Radeon HD 3800 Series"

}

}, Local0)

DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))

Return (Local0)

}

}

}

Link to comment
Share on other sites

I tested with an empty kext: ATY_Test.zipThe result is the same, no matter it was matched to IOPCIDevice or IONDRVDevice.

It make me think that Graphic driver is a special case of IOKit driver, which must has the first matched kext usable, otherwise there is no GUI.

Yeah, natit and IONDRVSupport worked fine before native drivers.

Link to comment
Share on other sites

I compared the code of old Natit with ATY_Test since they are both inherited from IOPCIDevice, found one difference between them, i.e., in Natit.cpp, it contains "#define super IOService" instead of "#define super IOPCIDevice". I changed the one in ATY_Test accordingly, now it works just like Natit. Its existence will no longer affect GUI.

I changed it in ATY_Init and it works too. kextstat shows ATY_Init still loaded even after entering GUI. It seems being solved, don't know whether will it work on unposted card or not.

 

It can be a problem of disparity between init() and free() since they are a pair of functions. A default IOPCIDevice::free() possibly could not work with a IOService::init(). So I guess if you modify init() in ATY_Init.cpp by change "IOService::" into "super::" should also solve the problem.

Link to comment
Share on other sites

Dong, great!

 

fixing a typo in init() didnt help.

 

but changing super to IOService helped !

I wonder why should ATY_Init as well as Natit inherit from IOPCIDevice? If the probe function returns NULL, other functions like start and setPowerState won't get called at all. Are you really sure those helped in solving the panic problem you mentioned before?

IMO, inherit from IOService should be more simple.

Link to comment
Share on other sites

Dong, how do you think, can we enable pcie v2.0 for cards ?

 

default drivers dont enable it so I (and all other with 48x0, and even on MacPro, with flashed cards) have in PCI cards section, for card:

 

Link Speed: 2.5 GT/s

 

while it's supposed to be 5.0 GT/s (my board is pcie v2.0 capable), it;s 5.0 on macpros with vanila 4870 from apple. strange.

Link to comment
Share on other sites

Dong, how do you think, can we enable pcie v2.0 for cards ?

 

default drivers dont enable it so I (and all other with 48x0, and even on MacPro, with flashed cards) have in PCI cards section, for card:

 

Link Speed: 2.5 GT/s

 

while it's supposed to be 5.0 GT/s (my board is pcie v2.0 capable), it;s 5.0 on macpros with vanila 4870 from apple. strange.

 

A couple of pages back, dong posted this decompiled code from the Megalodon Framebuffer

 

OSStatus PCIE_Gen2_Enable(DriverGlobal *aDriverRecPtr) {
UInt32 value, value1;
pciepw32(aDriverRecPtr, 0xA2, pciepr32(aDriverRecPtr, 0xA2) & ~(1 << 13));
value = pciepr32(aDriverRecPtr, 0xA2);
if (value & (1 << 9))
	pciepw32(aDriverRecPtr, 0xA2, ((((value | (1 << 10)) & ~7) | ((value & 0x70) >> 4)) | (1 << 8)) & ~(1 << 7));
else
	pciepw32(aDriverRecPtr, 0xA2, value | (1 << 13));
value = pciepr32(aDriverRecPtr, 0xA4);
if ((value & (1 << 23)) && (value & (1 << 24))) {
	regw32(aDriverRecPtr, 0x5488, regr32(aDriverRecPtr, 5488) & ~(1 << 25));
	regw32(aDriverRecPtr, 0x548C, regr32(aDriverRecPtr, 548C) & ~(1 << 28));
	regw32(aDriverRecPtr, 0x5404, regr32(aDriverRecPtr, 5404) | (1 << 25));
	regw32(aDriverRecPtr, 0x5484, regr32(aDriverRecPtr, 5484) & ~0xF;
	regw32(aDriverRecPtr, 0x5410, regr32(aDriverRecPtr, 5410) | (1 << 23));
	regw32(aDriverRecPtr, 0x548C, regr32(aDriverRecPtr, 548C) & ~0x1E);
	value = (value | 1) & ~2;
	value1 = pciepr32(aDriverRecPtr, 0xA1);
	if (value1 & (1 << 6)) pciepw32(aDriverRecPtr, 0xA1, value1 & ~0x40);
	pciepw32(aDriverRecPtr, 0xA4, ((((value & ~0x300) | 0x300) & ~0x3C000) & ~0x40) | 0x20);
	regw32(aDriverRecPtr, 0x541C, regr32(aDriverRecPtr, 541C) | (1 << 3));
	regw32(aDriverRecPtr, 0x544C, 8);
	regw32(aDriverRecPtr, 0x4088, (regr32(aDriverRecPtr, 4088) & ~0xF) | 2);
	regw32(aDriverRecPtr, 0x544C, 0);
}
return noErr;
}

 

These registers are also visited by ATI_Init, so maybe you could try a stripped down ati_init with only these registers?

Link to comment
Share on other sites

I don't know if "PCIE_Gen2_Enable" is used to enable v2.0 or not. If it is, why native driver do not enable it automatically. Or we can try to apply it from user space by using "radeonPCI" I posted in old ATIFramebuffer topic if it has to be done after native driver loaded.

Link to comment
Share on other sites

  • 3 weeks later...

its first part, getting rom address and size

 

reg = device->configRead32(kIOPCIConfigExpansionROMBase);

 

reg value is 0 O.o

 

#define PCIM_BIOS_ENABLE 0x01
#define PCIM_BIOS_ADDR_MASK 0xfffff800
#define PCIM_CMD_MEMEN 0x0002

uint32_t size, reg, rom_base, rom_size, rom;
rom_size = 0;
rom_base = 0;
reg = device->configRead32(kIOPCIConfigExpansionROMBase);
device->configWrite32(kIOPCIConfigExpansionROMBase, ~PCIM_BIOS_ENABLE);
size = device->configRead32(kIOPCIConfigExpansionROMBase);
device->configWrite32(kIOPCIConfigExpansionROMBase, reg);

LOG11("reg from romheader - 0x%lx\n", reg);
if ((reg & PCIM_BIOS_ADDR_MASK) != 0){
	rom_base = (reg & PCIM_BIOS_ADDR_MASK);
	rom_size = - (size & PCIM_BIOS_ADDR_MASK);
	LOG11("rom_base - 0x%lx\n", rom_base);
	LOG11("rom_size - 0x%lx\n", rom_size);
}

 

 

looks like they knew it may happen

 

	/* If it's a VGA device, set up the rom size for read_rom using the
 * 0xc0000 mapping.
 */
 if ((dev->device_class & 0x00ffff00) ==
((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8))) {
	 dev->rom_size = 64 * 1024;
 }

--------------------------
/* If it's a VGA device, set up the rom size for read_rom */
if ((dev->device_class & 0x00ffff00) ==
((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8)))
{
err = pci_device_cfg_read_u32( dev, &reg, PCIR_BIOS );
if (err)
	return errno;

if (reg == 0) {
	dev->rom_size = 0x10000;
	return 0;
}

err = pci_device_cfg_write_u32( dev, ~PCIM_BIOS_ENABLE, PCIR_BIOS );
if (err)
	return errno;
pci_device_cfg_read_u32( dev, &size, PCIR_BIOS );
pci_device_cfg_write_u32( dev, reg, PCIR_BIOS );

if ((reg & PCIM_BIOS_ADDR_MASK) != 0) {
	priv->rom_base = (reg & PCIM_BIOS_ADDR_MASK);
	dev->rom_size = -(size & PCIM_BIOS_ADDR_MASK);
}
}

return 0;

Link to comment
Share on other sites

xf86-ati-radeonHD contains similar code. I've been trying to port it but failed. From IOPCIFamily code, device->configRead32(IOPCIExpansionRomBase) only works for PowerPC machine.

However, like I mentioned before, some native ATY framebuffer driver contains code to read BIOS, you may want to look at it. Only that I can't test it as no such code exist in Wormy and Carreta.

Link to comment
Share on other sites

it exists in snow leo framebuffer, but it splitted into 3 parts, hard to find anything usefull

 

Btw, here is code to check was card posted or not, (ported from video-ati)

 

#define AVIVO_D1CRTC_CONTROL 0x6080
#		define AVIVO_CRTC_EN (1<<0)
#define AVIVO_D2CRTC_CONTROL 0x6880

bool
radeon_card_posted(RHDPtr RhdPtr)
{
uint32_t reg;

	reg = _RHDRegRead(RhdPtr, AVIVO_D1CRTC_CONTROL) | _RHDRegRead(RhdPtr, AVIVO_D2CRTC_CONTROL);
	if (reg & AVIVO_CRTC_EN)
		return TRUE;

return FALSE;
}

Link to comment
Share on other sites

 Share

×
×
  • Create New...