* move create_area for kernel AtomBIOS into radeon_hd_getbios

* only create_area if we found a valid AtomBIOS
* lock down write access to kernel AtomBIOS area after populating
* remove locking on kernel AtomBIOS area as it's not needed


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42573 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV 2011-08-04 15:28:50 +00:00
parent 5e1a7a9299
commit 7949c8cbe4

View File

@ -66,8 +66,18 @@ radeon_hd_getbios(radeon_info &info)
if (flags & PCI_rom_enable)
TRACE("%s: PCI ROM decode enabled successfully\n", __func__);
uint32 rom_base = info.shared_info->rom_phys;
uint32 rom_size = info.shared_info->rom_size;
uint32 rom_base = info.pci->u.h0.rom_base;
uint32 rom_size = info.pci->u.h0.rom_size;
if (rom_base == 0) {
TRACE("%s: no PCI rom, trying shadow rom\n", __func__);
// ROM has been copied by BIOS
rom_base = 0xC0000;
if (rom_size == 0) {
rom_size = 0x7FFF;
// A guess at maximum shadow bios size
}
}
TRACE("%s: seeking rom at 0x%" B_PRIX32 " [size: 0x%" B_PRIX32 "]\n",
__func__, rom_base, rom_size);
@ -75,6 +85,7 @@ radeon_hd_getbios(radeon_info &info)
uint8* bios;
status_t result = B_ERROR;
if (rom_base == 0 || rom_size == 0) {
// FAIL: we never found a base to work off of.
TRACE("%s: no VGA rom located, disabling AtomBIOS\n", __func__);
result = B_ERROR;
} else {
@ -83,26 +94,51 @@ radeon_hd_getbios(radeon_info &info)
(void **)&bios);
if (info.rom_area < B_OK) {
// FAIL : rom area wasn't mapped for access
dprintf(DEVICE_NAME ": failed to map rom\n");
result = B_ERROR;
} else {
if (bios[0] != 0x55 || bios[1] != 0xAA) {
// FAIL : not a PCI rom
uint16 id = bios[0] + (bios[1] << 8);
TRACE("%s: this isn't a PCI rom (%X)\n", __func__, id);
result = B_ERROR;
} else {
memcpy(info.atom_buffer, (void *)bios, rom_size);
if (isAtomBIOS(info.atom_buffer)) {
dprintf(DEVICE_NAME ": %s: AtomBIOS found and mapped!\n",
__func__);
result = B_OK;
} else {
dprintf(DEVICE_NAME ": %s: AtomBIOS not mapped!\n",
__func__);
} else if (isAtomBIOS(bios)) {
info.rom_area = create_area("radeon hd AtomBIOS",
(void **)&info.atom_buffer, B_ANY_KERNEL_ADDRESS,
rom_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (info.rom_area < 0) {
// FAIL : couldn't create kernel AtomBIOS area
dprintf(DEVICE_NAME ": %s: Error creating kernel"
" AtomBIOS area!\n", __func__);
result = B_ERROR;
} else {
memset((void*)info.atom_buffer, 0, rom_size);
// Prevent unknown code execution by AtomBIOS parser
memcpy(info.atom_buffer, (void *)bios, rom_size);
// Copy AtomBIOS to kernel area
if (isAtomBIOS(info.atom_buffer)) {
// SUCCESS : bios copied and verified
dprintf(DEVICE_NAME ": %s: AtomBIOS mapped!\n",
__func__);
set_area_protection(info.rom_area, B_READ_AREA);
// Lock it down
result = B_OK;
} else {
// FAIL : bios didn't copy properly for some reason
dprintf(DEVICE_NAME ": %s: AtomBIOS not mapped!\n",
__func__);
result = B_ERROR;
}
}
} else {
dprintf(DEVICE_NAME ": %s: PCI rom found wasn't identified"
" as AtomBIOS!\n", __func__);
result = B_ERROR;
}
delete_area(rom_area);
delete_area(rom_area);
}
}
@ -110,6 +146,11 @@ radeon_hd_getbios(radeon_info &info)
rom_config &= ~PCI_rom_enable;
set_pci_config(info.pci, PCI_rom_base, 4, rom_config);
if (result == B_OK) {
info.shared_info->rom_phys = rom_base;
info.shared_info->rom_size = rom_size;
}
return result;
}
@ -258,43 +299,20 @@ radeon_hd_init(radeon_info &info)
= read32(info.registers + R6XX_CONFIG_FB_BASE);
// *** AtomBIOS mapping
uint32 rom_base = info.pci->u.h0.rom_base;
uint32 rom_size = info.pci->u.h0.rom_size;
if (rom_base == 0) {
TRACE("%s: no PCI rom, trying shadow rom\n", __func__);
// ROM has been copied by BIOS
rom_base = 0xC0000;
if (rom_size == 0) {
rom_size = 0x7FFF;
// A guess at maximum shadow bios size
}
}
info.shared_info->rom_phys = rom_base;
info.shared_info->rom_size = rom_size;
info.rom_area = create_area("radeon hd AtomBIOS",
(void **)&info.atom_buffer, B_ANY_KERNEL_ADDRESS,
info.shared_info->rom_size, B_FULL_LOCK,
B_READ_AREA | B_WRITE_AREA);
status_t biosStatus = B_ERROR;
if (info.rom_area < 0) {
dprintf("%s: failed to create kernel AtomBIOS area!\n", __func__);
dprintf(DEVICE_NAME ": card(%ld): couldn't map kernel AtomBIOS area!\n",
info.id);
biosStatus = B_ERROR;
} else {
memset((void*)info.atom_buffer, 0, info.shared_info->rom_size);
// First we try an active bios read
biosStatus = radeon_hd_getbios(info);
if (biosStatus != B_OK) {
// If the active read fails, we do a disabled read
if (info.device_chipset > RADEON_R600)
biosStatus = radeon_hd_getbios_r600(info);
}
// First we try an active bios read
status_t biosStatus = radeon_hd_getbios(info);
if (biosStatus != B_OK) {
// If the active read fails, we do a disabled read
if (info.device_chipset > RADEON_R600)
biosStatus = radeon_hd_getbios_r600(info);
}
// TODO : may want to just return B_ERROR if AtomBIOS isn't
// found as we will require it in the future
info.shared_info->has_rom = (biosStatus == B_OK) ? true : false;
info.shared_info->rom_area = info.rom_area;
info.shared_info->rom_area = (biosStatus == B_OK) ? info.rom_area : -1;
// *** Pull active monitor VESA EDID from boot loader
edid1_info* edidInfo