* simplify some trace statements

* add potential support for IGP chipsets
* igp code is *untested* and should work *in theory*
* potentially resolves #8040 / #8046 ?


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42901 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV
2011-10-24 14:58:27 +00:00
parent edfba0bb03
commit 98421bb887
4 changed files with 66 additions and 51 deletions
@@ -121,6 +121,7 @@ struct radeon_shared_info {
uint16 device_chipset; uint16 device_chipset;
uint8 dceMajor; uint8 dceMajor;
uint8 dceMinor; uint8 dceMinor;
bool isIGP;
char device_identifier[32]; char device_identifier[32];
}; };
@@ -43,7 +43,7 @@ const struct supported_device {
uint8 dceMajor; // Display block family uint8 dceMajor; // Display block family
uint8 dceMinor; // Display block family uint8 dceMinor; // Display block family
uint16 chipset; uint16 chipset;
bool igp; bool isIGP;
const char* name; const char* name;
} kSupportedDevices[] = { } kSupportedDevices[] = {
// R400 Series (Radeon) DCE 0.0 (*very* early AtomBIOS) // R400 Series (Radeon) DCE 0.0 (*very* early AtomBIOS)
@@ -339,6 +339,7 @@ init_driver(void)
gDeviceInfo[found]->device_chipset = kSupportedDevices[type].chipset; gDeviceInfo[found]->device_chipset = kSupportedDevices[type].chipset;
gDeviceInfo[found]->dceMajor = kSupportedDevices[type].dceMajor; gDeviceInfo[found]->dceMajor = kSupportedDevices[type].dceMajor;
gDeviceInfo[found]->dceMinor = kSupportedDevices[type].dceMinor; gDeviceInfo[found]->dceMinor = kSupportedDevices[type].dceMinor;
gDeviceInfo[found]->isIGP = kSupportedDevices[type].isIGP;
dprintf(DEVICE_NAME ": GPU(%ld) %s, revision = 0x%x\n", found, dprintf(DEVICE_NAME ": GPU(%ld) %s, revision = 0x%x\n", found,
kSupportedDevices[type].name, info->revision); kSupportedDevices[type].name, info->revision);
@@ -34,6 +34,7 @@
# define TRACE(x) ; # define TRACE(x) ;
#endif #endif
#define ERROR(x...) dprintf("radeon_hd: " x)
// #pragma mark - // #pragma mark -
@@ -57,99 +58,109 @@ radeon_hd_getbios(radeon_info &info)
{ {
TRACE("card(%ld): %s: called\n", info.id, __func__); TRACE("card(%ld): %s: called\n", info.id, __func__);
// Enable ROM decoding uint32 romBase;
uint32 rom_config = get_pci_config(info.pci, PCI_rom_base, 4); uint32 romSize;
rom_config |= PCI_rom_enable; uint32 romConfig = 0;
set_pci_config(info.pci, PCI_rom_base, 4, rom_config);
uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4); if (info.isIGP == true) {
if (flags & PCI_rom_enable) romBase = info.pci->u.h1.memory_base;
TRACE("%s: PCI ROM decode enabled successfully\n", __func__); romSize = 256 * 1024;
// a complete guess
} else {
// Enable ROM decoding for PCI bar rom
romConfig = get_pci_config(info.pci, PCI_rom_base, 4);
romConfig |= PCI_rom_enable;
set_pci_config(info.pci, PCI_rom_base, 4, romConfig);
uint32 rom_base = info.pci->u.h0.rom_base; uint32 flags = get_pci_config(info.pci, PCI_rom_base, 4);
uint32 rom_size = info.pci->u.h0.rom_size; if (flags & PCI_rom_enable)
TRACE("%s: PCI ROM decode enabled successfully\n", __func__);
if (rom_base == 0) { romBase = info.pci->u.h0.rom_base;
TRACE("%s: no PCI rom, trying shadow rom\n", __func__); romSize = info.pci->u.h0.rom_size;
// ROM has been copied by BIOS
rom_base = 0xC0000; if (romBase == 0) {
if (rom_size == 0) { TRACE("%s: no PCI rom, trying shadow rom\n", __func__);
rom_size = 0x7FFF; // ROM has been copied by BIOS
// A guess at maximum shadow bios size romBase = 0xC0000;
if (romSize == 0) {
romSize = 0x7FFF;
// A guess at maximum shadow bios size
}
} }
} }
TRACE("%s: seeking rom at 0x%" B_PRIX32 " [size: 0x%" B_PRIX32 "]\n", TRACE("%s: seeking rom at 0x%" B_PRIX32 " [size: 0x%" B_PRIX32 "]\n",
__func__, rom_base, rom_size); __func__, romBase, romSize);
uint8* bios; uint8* bios;
status_t result = B_ERROR; status_t result = B_ERROR;
if (rom_base == 0 || rom_size == 0) { if (romBase == 0 || romSize == 0) {
// FAIL: we never found a base to work off of. // FAIL: we never found a base to work off of.
dprintf(DEVICE_NAME ": %s: no rom address located.\n", __func__); ERROR("%s: no rom address located.\n", __func__);
result = B_ERROR; result = B_ERROR;
} else { } else {
area_id rom_area = map_physical_memory("radeon hd rom", area_id rom_area = map_physical_memory("radeon hd rom",
rom_base, rom_size, B_ANY_KERNEL_ADDRESS, B_READ_AREA, romBase, romSize, B_ANY_KERNEL_ADDRESS, B_READ_AREA,
(void **)&bios); (void **)&bios);
if (info.rom_area < B_OK) { if (info.rom_area < B_OK) {
// FAIL : rom area wasn't mapped for access // FAIL : rom area wasn't mapped for access
dprintf(DEVICE_NAME ": failed to map rom\n"); ERROR("%s: failed to map rom\n", __func__);
result = B_ERROR; result = B_ERROR;
} else { } else {
if (bios[0] != 0x55 || bios[1] != 0xAA) { if (bios[0] != 0x55 || bios[1] != 0xAA) {
// FAIL : not a PCI rom // FAIL : not a PCI rom
uint16 id = bios[0] + (bios[1] << 8); uint16 id = bios[0] + (bios[1] << 8);
dprintf(DEVICE_NAME ": %s: this isn't a PCI rom (%X)\n", ERROR("%s: this isn't a PCI rom (%X)\n",
__func__, id); __func__, id);
result = B_ERROR; result = B_ERROR;
} else if (isAtomBIOS(bios)) { } else if (isAtomBIOS(bios)) {
info.rom_area = create_area("radeon hd AtomBIOS", info.rom_area = create_area("radeon hd AtomBIOS",
(void **)&info.atom_buffer, B_ANY_KERNEL_ADDRESS, (void **)&info.atom_buffer, B_ANY_KERNEL_ADDRESS,
rom_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); romSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (info.rom_area < 0) { if (info.rom_area < 0) {
// FAIL : couldn't create kernel AtomBIOS area // FAIL : couldn't create kernel AtomBIOS area
dprintf(DEVICE_NAME ": %s: Error creating kernel" ERROR("%s: Error creating kernel"
" AtomBIOS area!\n", __func__); " AtomBIOS area!\n", __func__);
result = B_ERROR; result = B_ERROR;
} else { } else {
memset((void*)info.atom_buffer, 0, rom_size); memset((void*)info.atom_buffer, 0, romSize);
// Prevent unknown code execution by AtomBIOS parser // Prevent unknown code execution by AtomBIOS parser
memcpy(info.atom_buffer, (void *)bios, rom_size); memcpy(info.atom_buffer, (void *)bios, romSize);
// Copy AtomBIOS to kernel area // Copy AtomBIOS to kernel area
if (isAtomBIOS(info.atom_buffer)) { if (isAtomBIOS(info.atom_buffer)) {
// SUCCESS : bios copied and verified // SUCCESS : bios copied and verified
dprintf(DEVICE_NAME ": %s: AtomBIOS mapped!\n", ERROR("%s: AtomBIOS mapped!\n", __func__);
__func__);
set_area_protection(info.rom_area, B_READ_AREA); set_area_protection(info.rom_area, B_READ_AREA);
// Lock it down // Lock it down
result = B_OK; result = B_OK;
} else { } else {
// FAIL : bios didn't copy properly for some reason // FAIL : bios didn't copy properly for some reason
dprintf(DEVICE_NAME ": %s: AtomBIOS not mapped!\n", ERROR("%s: AtomBIOS not mapped!\n", __func__);
__func__);
result = B_ERROR; result = B_ERROR;
} }
} }
} else { } else {
dprintf(DEVICE_NAME ": %s: rom found wasn't identified" ERROR("%s: rom found wasn't identified"
" as AtomBIOS!\n", __func__); " as AtomBIOS!\n", __func__);
result = B_ERROR; result = B_ERROR;
} }
delete_area(rom_area); delete_area(rom_area);
} }
} }
// Disable ROM decoding if (info.isIGP == false) {
rom_config &= ~PCI_rom_enable; // Disable ROM decoding
set_pci_config(info.pci, PCI_rom_base, 4, rom_config); romConfig &= ~PCI_rom_enable;
set_pci_config(info.pci, PCI_rom_base, 4, romConfig);
}
if (result == B_OK) { if (result == B_OK) {
info.shared_info->rom_phys = rom_base; info.shared_info->rom_phys = romBase;
info.shared_info->rom_size = rom_size; info.shared_info->rom_size = romSize;
} }
return result; return result;
@@ -323,9 +334,9 @@ radeon_hd_init(radeon_info &info)
{ {
TRACE("card(%ld): %s: called\n", info.id, __func__); TRACE("card(%ld): %s: called\n", info.id, __func__);
dprintf(DEVICE_NAME ": card(%ld): " ERROR("%s: card(%ld): "
"Radeon r%" B_PRIX16 " 1002:%" B_PRIX32 "\n", "Radeon r%" B_PRIX16 " 1002:%" B_PRIX32 "\n",
info.id, info.device_chipset, info.device_id); __func__, info.id, info.device_chipset, info.device_id);
// *** Map shared info // *** Map shared info
AreaKeeper sharedCreator; AreaKeeper sharedCreator;
@@ -333,8 +344,8 @@ radeon_hd_init(radeon_info &info)
(void **)&info.shared_info, B_ANY_KERNEL_ADDRESS, (void **)&info.shared_info, B_ANY_KERNEL_ADDRESS,
ROUND_TO_PAGE_SIZE(sizeof(radeon_shared_info)), B_FULL_LOCK, 0); ROUND_TO_PAGE_SIZE(sizeof(radeon_shared_info)), B_FULL_LOCK, 0);
if (info.shared_area < B_OK) { if (info.shared_area < B_OK) {
dprintf(DEVICE_NAME ": card (%ld): couldn't map shared area!\n", ERROR("%s: card (%ld): couldn't map shared area!\n",
info.id); __func__, info.id);
return info.shared_area; return info.shared_area;
} }
@@ -348,8 +359,8 @@ radeon_hd_init(radeon_info &info)
B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
(void **)&info.registers); (void **)&info.registers);
if (mmioMapper.InitCheck() < B_OK) { if (mmioMapper.InitCheck() < B_OK) {
dprintf(DEVICE_NAME ": card (%ld): couldn't map memory I/O!\n", ERROR("%s: card (%ld): couldn't map memory I/O!\n",
info.id); __func__, info.id);
return info.registers_area; return info.registers_area;
} }
@@ -361,8 +372,8 @@ radeon_hd_init(radeon_info &info)
B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
(void **)&info.shared_info->frame_buffer); (void **)&info.shared_info->frame_buffer);
if (frambufferMapper.InitCheck() < B_OK) { if (frambufferMapper.InitCheck() < B_OK) {
dprintf(DEVICE_NAME ": card(%ld): couldn't map framebuffer!\n", ERROR("%s: card(%ld): couldn't map framebuffer!\n",
info.id); __func__, info.id);
return info.framebuffer_area; return info.framebuffer_area;
} }
@@ -380,6 +391,7 @@ radeon_hd_init(radeon_info &info)
info.shared_info->device_chipset = info.device_chipset; info.shared_info->device_chipset = info.device_chipset;
info.shared_info->dceMajor = info.dceMajor; info.shared_info->dceMajor = info.dceMajor;
info.shared_info->dceMinor = info.dceMinor; info.shared_info->dceMinor = info.dceMinor;
info.shared_info->isIGP = info.isIGP;
info.shared_info->registers_area = info.registers_area; info.shared_info->registers_area = info.registers_area;
strcpy(info.shared_info->device_identifier, info.device_identifier); strcpy(info.shared_info->device_identifier, info.device_identifier);
@@ -407,12 +419,12 @@ radeon_hd_init(radeon_info &info)
// Check if a valid AtomBIOS image was found. // Check if a valid AtomBIOS image was found.
if (biosStatus != B_OK) { if (biosStatus != B_OK) {
dprintf(DEVICE_NAME ": card (%ld): couldn't find AtomBIOS rom!\n", ERROR("%s: card (%ld): couldn't find AtomBIOS rom!\n",
info.id); __func__, info.id);
dprintf(DEVICE_NAME ": card (%ld): exiting. Please open a bug ticket" ERROR("%s: card (%ld): exiting. Please open a bug ticket"
" at haiku-os.org with your /var/log/syslog\n", " at haiku-os.org with your /var/log/syslog\n",
info.id); __func__, info.id);
// Fallback to VESA // Fallback to VESA (more likely crash app_server)
return B_ERROR; return B_ERROR;
} }
@@ -46,6 +46,7 @@ struct radeon_info {
uint16 device_chipset; uint16 device_chipset;
uint8 dceMajor; uint8 dceMajor;
uint8 dceMinor; uint8 dceMinor;
bool isIGP;
}; };