aboutsummaryrefslogtreecommitdiffstats
path: root/vbe.c
diff options
context:
space:
mode:
authorPascal Rigaux <pixel@mandriva.com>2005-04-05 15:02:01 +0000
committerPascal Rigaux <pixel@mandriva.com>2005-04-05 15:02:01 +0000
commit6c2b932a519d35113070c6d8fe4ff13bc1b84778 (patch)
tree1fac3f995915fa6bbcc0fe3cf44026b5889cb362 /vbe.c
parent07b0aa9a2aeab090bbf284657455f76f41ab47d1 (diff)
downloadmonitor-edid-6c2b932a519d35113070c6d8fe4ff13bc1b84778.tar
monitor-edid-6c2b932a519d35113070c6d8fe4ff13bc1b84778.tar.gz
monitor-edid-6c2b932a519d35113070c6d8fe4ff13bc1b84778.tar.bz2
monitor-edid-6c2b932a519d35113070c6d8fe4ff13bc1b84778.tar.xz
monitor-edid-6c2b932a519d35113070c6d8fe4ff13bc1b84778.zip
add old detection using lrmi
Diffstat (limited to 'vbe.c')
-rw-r--r--vbe.c127
1 files changed, 127 insertions, 0 deletions
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(&regs, 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, &regs) == 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(&regs, 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, &regs) == 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");