vesa: report BIOS manufacturer (visible in screen preferences)
Get the OEM string from the VESA info block (and also get the memory size from there while we are at it). If the string is empty, use the BIOS type (identified in other ways) to still report something. Change-Id: I8cbd75d19f624a43db05e82d1e1b2a536cc418b6 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4625 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
1005a27603
commit
6a175a5ddc
@@ -52,6 +52,9 @@ struct vesa_shared_info {
|
|||||||
// Atombios only: offset to the table of video modes in the bios, used for patching in
|
// Atombios only: offset to the table of video modes in the bios, used for patching in
|
||||||
// extra video modes.
|
// extra video modes.
|
||||||
uint32 dpms_capabilities;
|
uint32 dpms_capabilities;
|
||||||
|
|
||||||
|
char name[32];
|
||||||
|
uint32 vram_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------- ioctl() interface ----------------
|
//----------------- ioctl() interface ----------------
|
||||||
|
|||||||
@@ -184,13 +184,31 @@ status_t
|
|||||||
vesa_get_accelerant_device_info(accelerant_device_info *info)
|
vesa_get_accelerant_device_info(accelerant_device_info *info)
|
||||||
{
|
{
|
||||||
info->version = B_ACCELERANT_VERSION;
|
info->version = B_ACCELERANT_VERSION;
|
||||||
strcpy(info->name, "VESA Driver");
|
|
||||||
strcpy(info->chipset, "VESA");
|
strcpy(info->name, "VESA driver");
|
||||||
// ToDo: provide some more insight here...
|
if (gInfo->shared_info->name[0] != '\0') {
|
||||||
|
strlcpy(info->chipset, gInfo->shared_info->name, 32);
|
||||||
|
} else {
|
||||||
|
switch (gInfo->shared_info->bios_type) {
|
||||||
|
case kIntelBiosType:
|
||||||
|
strcpy(info->chipset, "Intel");
|
||||||
|
break;
|
||||||
|
case kNVidiaBiosType:
|
||||||
|
strcpy(info->chipset, "nVidia");
|
||||||
|
break;
|
||||||
|
case kAtomBiosType1:
|
||||||
|
case kAtomBiosType2:
|
||||||
|
strcpy(info->chipset, "AMD/ATI Atombios");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcpy(info->chipset, "Generic VESA");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
strcpy(info->serial_no, "None");
|
strcpy(info->serial_no, "None");
|
||||||
|
|
||||||
|
info->memory = gInfo->shared_info->vram_size;
|
||||||
#if 0
|
#if 0
|
||||||
info->memory = ???
|
|
||||||
info->dac_speed = ???
|
info->dac_speed = ???
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,12 @@
|
|||||||
#include "atombios.h"
|
#include "atombios.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define LINEAR_ADDRESS(segment, offset) \
|
||||||
|
(((addr_t)(segment) << 4) + (addr_t)(offset))
|
||||||
|
#define SEGMENTED_TO_LINEAR(segmented) \
|
||||||
|
LINEAR_ADDRESS((addr_t)(segmented) >> 16, (addr_t)(segmented) & 0xffff)
|
||||||
|
|
||||||
|
|
||||||
static bios_module_info* sBIOSModule;
|
static bios_module_info* sBIOSModule;
|
||||||
|
|
||||||
|
|
||||||
@@ -194,43 +200,33 @@ vbe_to_system_dpms(uint8 vbeMode)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vbe_get_dpms_capabilities(uint32& vbeMode, uint32& mode)
|
vbe_get_dpms_capabilities(bios_state* state, uint32& vbeMode, uint32& mode)
|
||||||
{
|
{
|
||||||
// we always return a valid mode
|
// we always return a valid mode
|
||||||
vbeMode = 0;
|
vbeMode = 0;
|
||||||
mode = B_DPMS_ON;
|
mode = B_DPMS_ON;
|
||||||
|
|
||||||
// Prepare BIOS environment
|
|
||||||
bios_state* state;
|
|
||||||
status_t status = vbe_call_prepare(&state);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
bios_regs regs = {};
|
bios_regs regs = {};
|
||||||
regs.eax = 0x4f10;
|
regs.eax = 0x4f10;
|
||||||
regs.ebx = 0;
|
regs.ebx = 0;
|
||||||
regs.esi = 0;
|
regs.esi = 0;
|
||||||
regs.edi = 0;
|
regs.edi = 0;
|
||||||
|
|
||||||
status = sBIOSModule->interrupt(state, 0x10, ®s);
|
status_t status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS failed: %s\n",
|
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS failed: %s\n",
|
||||||
strerror(status));
|
strerror(status));
|
||||||
goto out;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned "
|
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned "
|
||||||
"0x%04" B_PRIx32 "\n", regs.eax & 0xffff);
|
"0x%04" B_PRIx32 "\n", regs.eax & 0xffff);
|
||||||
status = B_ERROR;
|
return B_ERROR;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vbeMode = regs.ebx >> 8;
|
vbeMode = regs.ebx >> 8;
|
||||||
mode = vbe_to_system_dpms(vbeMode);
|
mode = vbe_to_system_dpms(vbeMode);
|
||||||
|
|
||||||
out:
|
|
||||||
vbe_call_finish(state);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,18 +259,33 @@ vbe_set_bits_per_gun(bios_state* state, vesa_info& info, uint8 bits)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vbe_set_bits_per_gun(vesa_info& info, uint8 bits)
|
vbe_get_vesa_info(bios_state* state, vesa_info& info)
|
||||||
{
|
{
|
||||||
info.bits_per_gun = 6;
|
vbe_info_block* infoHeader = (vbe_info_block*)sBIOSModule->allocate_mem(state, 256);
|
||||||
|
phys_addr_t physicalAddress = sBIOSModule->physical_address(state, infoHeader);
|
||||||
|
|
||||||
bios_state* state;
|
bios_regs regs = {};
|
||||||
status_t status = vbe_call_prepare(&state);
|
regs.eax = 0x4f00;
|
||||||
if (status != B_OK)
|
regs.es = physicalAddress >> 4;
|
||||||
|
regs.edi = physicalAddress - (regs.es << 4);
|
||||||
|
|
||||||
|
status_t status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME ": vbe_get_vesa_info(): BIOS failed: %s\n",
|
||||||
|
strerror(status));
|
||||||
return status;
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
status = vbe_set_bits_per_gun(state, info, bits);
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
|
dprintf(DEVICE_NAME ": vbe_get_vesa_info(): BIOS returned "
|
||||||
|
"0x%04" B_PRIx32 "\n", regs.eax & 0xffff);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.shared_info->vram_size = infoHeader->total_memory * 65536;
|
||||||
|
strlcpy(info.shared_info->name, (char*)sBIOSModule->virtual_address(state,
|
||||||
|
SEGMENTED_TO_LINEAR(infoHeader->oem_string)), 32);
|
||||||
|
|
||||||
vbe_call_finish(state);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,15 +295,8 @@ vbe_set_bits_per_gun(vesa_info& info, uint8 bits)
|
|||||||
* manufacturer didn't allow.
|
* manufacturer didn't allow.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vbe_identify_bios(vesa_shared_info* sharedInfo)
|
vbe_identify_bios(bios_state* state, vesa_shared_info* sharedInfo)
|
||||||
{
|
{
|
||||||
// TODO vbe_call_prepare/vbe_call_finish is a costly operation (loading and unloading the
|
|
||||||
// BIOS module all the time). We should try to do it less often.
|
|
||||||
bios_state* state;
|
|
||||||
status_t status = vbe_call_prepare(&state);
|
|
||||||
if (status != B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Get a pointer to the BIOS
|
// Get a pointer to the BIOS
|
||||||
const uintptr_t kBiosBase = 0xc0000;
|
const uintptr_t kBiosBase = 0xc0000;
|
||||||
uint8_t* bios = (uint8_t*)sBIOSModule->virtual_address(state, kBiosBase);
|
uint8_t* bios = (uint8_t*)sBIOSModule->virtual_address(state, kBiosBase);
|
||||||
@@ -333,8 +337,6 @@ vbe_identify_bios(vesa_shared_info* sharedInfo)
|
|||||||
} else {
|
} else {
|
||||||
dprintf(DEVICE_NAME ": unknown BIOS type, custom video modes will not be available\n");
|
dprintf(DEVICE_NAME ": unknown BIOS type, custom video modes will not be available\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
vbe_call_finish(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -464,12 +466,19 @@ vesa_init(vesa_info& info)
|
|||||||
memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info));
|
memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
vbe_identify_bios(&sharedInfo);
|
bios_state* state;
|
||||||
|
status_t status = vbe_call_prepare(&state);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
vbe_get_dpms_capabilities(info.vbe_dpms_capabilities,
|
vbe_identify_bios(state, &sharedInfo);
|
||||||
|
|
||||||
|
vbe_get_dpms_capabilities(state, info.vbe_dpms_capabilities,
|
||||||
sharedInfo.dpms_capabilities);
|
sharedInfo.dpms_capabilities);
|
||||||
if (bufferInfo->depth <= 8)
|
if (bufferInfo->depth <= 8)
|
||||||
vbe_set_bits_per_gun(info, 8);
|
vbe_set_bits_per_gun(state, info, 8);
|
||||||
|
|
||||||
|
vbe_call_finish(state);
|
||||||
|
|
||||||
dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n");
|
dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user