From 6c2b932a519d35113070c6d8fe4ff13bc1b84778 Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Tue, 5 Apr 2005 15:02:01 +0000 Subject: add old detection using lrmi --- vbe.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) (limited to 'vbe.c') diff --git a/vbe.c b/vbe.c index 8f12a3c..c228f24 100644 --- a/vbe.c +++ b/vbe.c @@ -15,6 +15,12 @@ #include "get-edid.h" #include "int10/vbios.h" +#ifdef __i386__ +/* some regressions can occur. e.g. Shuttle S754 with built-in VIA VGA, + in that case default to previous lrmi code */ +#define LRMI +#endif + /* This specifies whether CPU emulation is used or real mode execution */ #ifdef __i386__ #define cpuemu 0 @@ -157,6 +163,124 @@ int vbe_get_edid_info(char *edid) return 1; } +#ifdef LRMI +#include "lrmi.h" + +static int vbe_check_vbe_info__old(void) +{ + int i; + unsigned char *mem; + unsigned char v[0x200]; + struct LRMI_regs regs; + + /* initialize LRMI */ + if (LRMI_init() == 0) { + log_err("VBE: could not initialize LRMI\n"); + return 0; + } + + /* allocate a chunk of memory */ + mem = LRMI_alloc_real(sizeof(v)); + if (mem == NULL) { + log_err("VBE: could allocate real memory\n"); + return 0; + } + memset(mem, 0, sizeof(v)); + + /* set up registers for the interrupt call. */ + memset(®s, 0, sizeof(regs)); + regs.eax = 0x4f00; + regs.es = ((u_int32_t)mem) >> 4; + regs.edi = ((u_int32_t)mem) & 0x0f; + memcpy(mem, "VBE2", 4); + + /* do it. */ + iopl(3); + ioperm(0, 0x400, 1); + if (LRMI_int(0x10, ®s) == 0) { + LRMI_free_real(mem); + return 0; + } + + /* check for successful return code */ + i = regs.eax & 0xffff; + if (i != 0x4f) { + LRMI_free_real(mem); + log_err("VBE: Error (0x4f00): 0x%04x\n", i); + return 0; + } + + /* get memory to return the information */ + memcpy(v, mem, sizeof(v)); + LRMI_free_real(mem); + + parse_vbe_info(v); + return 1; +} + +static int vbe_get_edid_info__old(char *edid) +{ + int i; + unsigned char *mem; + const int EDID_BLOCK_SIZE = 256; + struct LRMI_regs regs; + + /* initialize LRMI */ + if (LRMI_init() == 0) { + log_err("EDID: could not initialize LRMI\n"); + return 0; + } + + /* allocate a chunk of memory */ + mem = LRMI_alloc_real(EDID_BLOCK_SIZE); + if (mem == NULL) { + log_err("EDID: could allocate real memory\n"); + return 0; + } + memset(mem, 0, EDID_BLOCK_SIZE); + + /* set up registers for the interrupt call. */ + memset(®s, 0, sizeof(regs)); + regs.eax = 0x4f15; + regs.ebx = 0x0001; + regs.es = ((u_int32_t)mem) >> 4; + regs.edi = ((u_int32_t)mem) & 0x0f; + + /* do it. */ + iopl(3); + ioperm(0, 0x400, 1); + if (LRMI_int(0x10, ®s) == 0) { + LRMI_free_real(mem); + return 0; + } + + /* check for successful return code */ + i = regs.eax & 0xffff; + if (i != 0x4f) { + LRMI_free_real(mem); + log_err("EDID: Error (0x4f15): 0x%04x\n", i); + return 0; + } + + /* get memory to return the information */ + memcpy(edid, mem, EDID_BLOCK_SIZE); + LRMI_free_real(mem); + return 1; +} + +int get_edid__old(char *edid) +{ + int ok; + /* try with older lrmi interface, we can assume a failure for + one is also bogus for the other */ + log_err("Retrying with old LRMI interface\n"); + ok = + (box_is_xbox() || vbe_check_vbe_info__old()) && + vbe_get_edid_info__old(edid); + return ok; +} +#endif + int get_edid(char *edid) { int pci_config_type = 1; /* Determine PCI configuration type */ @@ -171,6 +295,9 @@ int get_edid(char *edid) vbe_get_edid_info(edid); FreeInt10(); +#ifdef LRMI + if (!ok) ok = get_edid__old(edid); +#endif } else if (getuid() != 0) fprintf(stderr, "you must be root to run this program\n"); -- cgit v1.2.1