summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGwenolé Beauchesne <gbeauchesne@mandriva.org>2004-08-25 05:49:03 +0000
committerGwenolé Beauchesne <gbeauchesne@mandriva.org>2004-08-25 05:49:03 +0000
commitb9e6ef4447684d5786c51ea7b447a6b874f67a9b (patch)
tree125e1eeb01eb19fea42476d4efc2425843781aec
parentcec9fd9a69aa91a6f3de3becfdfe7eb8eeff7e3a (diff)
downloaddrakx-b9e6ef4447684d5786c51ea7b447a6b874f67a9b.tar
drakx-b9e6ef4447684d5786c51ea7b447a6b874f67a9b.tar.gz
drakx-b9e6ef4447684d5786c51ea7b447a6b874f67a9b.tar.bz2
drakx-b9e6ef4447684d5786c51ea7b447a6b874f67a9b.tar.xz
drakx-b9e6ef4447684d5786c51ea7b447a6b874f67a9b.zip
Extensive rewrite and cleanups to use the new int10 interface. Plus add
some 64-bit fixes and a last-resort means to get VBE/EDID information from special -BOOT kernel during early boot.
-rw-r--r--tools/ddcprobe/Makefile41
-rw-r--r--tools/ddcprobe/ddcxinfos.c59
-rw-r--r--tools/ddcprobe/vbe.c600
-rw-r--r--tools/ddcprobe/vbe.h150
4 files changed, 235 insertions, 615 deletions
diff --git a/tools/ddcprobe/Makefile b/tools/ddcprobe/Makefile
index bcbf1464d..0b96f3c44 100644
--- a/tools/ddcprobe/Makefile
+++ b/tools/ddcprobe/Makefile
@@ -1,29 +1,26 @@
-CFLAGS=-Wall -O # -g -DDEBUG
-LDFLAGS = -lm
-TARGETS=ddcxinfos
+CC = gcc
+CFLAGS = -O -Wall # -g -DDEBUG
+INCS = -I.
+LDFLAGS = -lm -L. -lint10 -lx86emu
+OBJS = ddcxinfos.o vesamode.o vbe.o
+LIBS = libint10.a libx86emu.a
+TARGETS = ddcxinfos
-ARCH := $(patsubst i%86,i386,$(shell uname -m))
-ARCH := $(patsubst sparc%,sparc,$(ARCH))
+all: $(TARGETS)
-ifeq (i386,$(ARCH))
+ddcxinfos: $(OBJS) $(LIBS)
+ $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS)
-ddcxinfos: lrmi.o vesamode.o vbe.o ddcxinfos.o
+libx86emu.a:
+ $(MAKE) -C x86emu
-libvbe.a: lrmi.o vesamode.o vbe.o
- $(AR) cru $@ $^
+libint10.a: libx86emu.a
+ $(MAKE) -C int10
-#install: $(DESTDIR)/usr/include/vbe.h $(DESTDIR)/usr/lib/libvbe.a
-
-$(DESTDIR)/usr/include/vbe.h:
- install -m 644 vbe.h $(DESTDIR)/usr/include/vbe.h
-
-$(DESTDIR)/usr/lib/libvbe.a:
- install -m 644 libvbe.a $(DESTDIR)/usr/lib/libvbe.a
-
-else
-ddcxinfos: not_handled.c
- gcc -o $@ $<
-endif
+%.o: %.c
+ $(CC) $(CFLAGS) $(INCS) -c $< -o $@
clean:
- $(RM) $(TARGETS) *.o core
+ $(MAKE) -C int10 clean
+ $(MAKE) -C x86emu clean
+ $(RM) $(TARGETS) $(LIBS) *.o core
diff --git a/tools/ddcprobe/ddcxinfos.c b/tools/ddcprobe/ddcxinfos.c
index 22ed653b8..93352d846 100644
--- a/tools/ddcprobe/ddcxinfos.c
+++ b/tools/ddcprobe/ddcxinfos.c
@@ -2,30 +2,54 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdarg.h>
#include "vbe.h"
#include "vesamode.h"
+#include "int10/vbios.h"
#ident "$Id$"
#define SQR(x) ((x) * (x))
-int main(int argc, char **argv)
+void log_err(char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+}
+
+int main(void)
{
int i, j;
- u_int16_t *mode_list;
unsigned char hmin, hmax, vmin, vmax;
- struct vbe_info *vbe_info;
- struct vbe_edid1_info *edid;
+ struct vbe_info vbe_info_static;
+ struct vbe_info *vbe_info = &vbe_info_static;
+ struct vbe_edid1_info edid_static;
+ struct vbe_edid1_info *edid = &edid_static;
struct vbe_modeline *modelines;
-
+ int pci_config_type = 0;
- if ((vbe_info = vbe_get_vbe_info()) == NULL) return 1;
+ /* Determine PCI configuration type */
+ pci_config_type = 1;
- printf("%dKB of video ram\n", vbe_info->memory_size * 64);
+ /* Initialize Int10 */
+ if (InitInt10(pci_config_type)) return 1;
- /* List supported standard modes. */
- for (mode_list = vbe_info->mode_list.list; *mode_list != 0xffff; mode_list++)
+ /* Get VBE information */
+ if (vbe_get_vbe_info(vbe_info) == 0) {
+ FreeInt10();
+ return 1;
+ }
+ printf("%dKB of video ram\n", vbe_info->memory_size / 1024);
+
+ /* List supported standard modes */
+ for (j = 0; j < vbe_info->modes; j++)
for (i = 0; known_vesa_modes[i].x; i++)
- if (known_vesa_modes[i].number == *mode_list)
+ if (known_vesa_modes[i].number == vbe_info->mode_list[j])
printf("%d %d %d\n",
known_vesa_modes[i].colors,
known_vesa_modes[i].x,
@@ -33,7 +57,14 @@ int main(int argc, char **argv)
);
printf("\n");
- if ((edid = vbe_get_edid_info()) == NULL) return 0;
+ /* Get EDID information */
+ if (vbe_get_edid_info(edid) == 0) {
+ FreeInt10();
+ return 0;
+ }
+ FreeInt10();
+
+ if (edid->manufacturer_name.p == 0 || edid->product_code == 0) return 0;
if (edid->version == 255 && edid->revision == 255) return 0;
vbe_get_edid_ranges(edid, &hmin, &hmax, &vmin, &vmax);
@@ -48,9 +79,9 @@ int main(int argc, char **argv)
char manufacturer[4];
double size = sqrt(SQR(edid->max_size_horizontal) +
SQR(edid->max_size_vertical)) / 2.54;
- manufacturer[0] = edid->manufacturer_name.char1 + 'A' - 1;
- manufacturer[1] = edid->manufacturer_name.char2 + 'A' - 1;
- manufacturer[2] = edid->manufacturer_name.char3 + 'A' - 1;
+ manufacturer[0] = edid->manufacturer_name.u.char1 + 'A' - 1;
+ manufacturer[1] = edid->manufacturer_name.u.char2 + 'A' - 1;
+ manufacturer[2] = edid->manufacturer_name.u.char3 + 'A' - 1;
manufacturer[3] = '\0';
printf(size ? "%3.2f inches monitor (truly %3.2f') EISA ID=%s%04x\n" : "\n", size * 1.08, size, manufacturer, edid->product_code);
}
diff --git a/tools/ddcprobe/vbe.c b/tools/ddcprobe/vbe.c
index a67e56d0b..7b061f213 100644
--- a/tools/ddcprobe/vbe.c
+++ b/tools/ddcprobe/vbe.c
@@ -8,330 +8,168 @@
#include <assert.h>
#include <limits.h>
#include <ctype.h>
-#include "lrmi.h"
+#include <fcntl.h>
+#include <unistd.h>
#include "vesamode.h"
#include "vbe.h"
-#ident "$Id$"
-
-/* Return information about a particular video mode. */
-struct vbe_mode_info *vbe_get_mode_info(u_int16_t mode)
-{
- struct LRMI_regs regs;
- char *mem;
- struct vbe_mode_info *ret = NULL;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return NULL;
- }
-
- /* Allocate a chunk of memory. */
- mem = LRMI_alloc_real(sizeof(struct vbe_mode_info));
- if(mem == NULL) {
- return NULL;
- }
- memset(mem, 0, sizeof(struct vbe_mode_info));
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f01;
- regs.ecx = mode;
- 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 NULL;
- }
-
- /* Check for successful return. */
- if((regs.eax & 0xffff) != 0x004f) {
- LRMI_free_real(mem);
- return NULL;
- }
-
- /* Get memory for return. */
- ret = malloc(sizeof(struct vbe_mode_info));
- if(ret == NULL) {
- LRMI_free_real(mem);
- return NULL;
- }
-
- /* Copy the buffer for return. */
- memcpy(ret, mem, sizeof(struct vbe_mode_info));
+#include "int10/vbios.h"
+
+#define DEBUG 0
+#if DEBUG
+#define bug printf
+#define D(X) X
+#else
+#define D(X)
+#endif
- /* Clean up and return. */
- LRMI_free_real(mem);
- return ret;
-}
+#ifdef __i386__
+#define cpuemu 1
+#else
+#define cpuemu 0
+#endif
-/* Get VBE info. */
-struct vbe_info *vbe_get_vbe_info()
+/*
+ * Create a 'canonical' version, i.e. no spaces at start and end.
+ *
+ * Note: removes chars >= 0x80 as well (due to (char *))! This
+ * is currently considered a feature.
+ */
+static char *canon_str(char *s, int len)
{
- struct LRMI_regs regs;
- unsigned char *mem;
- struct vbe_info *ret = NULL;
- int i;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return NULL;
- }
-
- /* Allocate a chunk of memory. */
- mem = LRMI_alloc_real(sizeof(struct vbe_mode_info));
- if(mem == NULL) {
- return NULL;
- }
- memset(mem, 0, sizeof(struct vbe_mode_info));
-
- /* 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 NULL;
- }
-
- /* Check for successful return code. */
- if((regs.eax & 0xffff) != 0x004f) {
- LRMI_free_real(mem);
- return NULL;
- }
-
- /* Get memory to return the information. */
- ret = malloc(sizeof(struct vbe_info));
- if(ret == NULL) {
- LRMI_free_real(mem);
- return NULL;
- }
- memcpy(ret, mem, sizeof(struct vbe_info));
-
- /* Set up pointers to usable memory. */
- ret->mode_list.list = (u_int16_t*) ((ret->mode_list.addr.seg << 4) +
- (ret->mode_list.addr.ofs));
- ret->oem_name.string = (char*) ((ret->oem_name.addr.seg << 4) +
- (ret->oem_name.addr.ofs));
-
- /* Snip, snip. */
- mem = strdup(ret->oem_name.string); /* leak */
- while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) {
- mem[i - 1] = '\0';
- }
- ret->oem_name.string = mem;
-
- /* Set up pointers for VESA 3.0+ strings. */
- if(ret->version[1] >= 3) {
-
- /* Vendor name. */
- ret->vendor_name.string = (char*)
- ((ret->vendor_name.addr.seg << 4)
- + (ret->vendor_name.addr.ofs));
-
- mem = strdup(ret->vendor_name.string); /* leak */
- while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) {
- mem[i - 1] = '\0';
- }
- ret->vendor_name.string = mem;
-
- /* Product name. */
- ret->product_name.string = (char*)
- ((ret->product_name.addr.seg << 4)
- + (ret->product_name.addr.ofs));
-
- mem = strdup(ret->product_name.string); /* leak */
- while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) {
- mem[i - 1] = '\0';
- }
- ret->product_name.string = mem;
-
- /* Product revision. */
- ret->product_revision.string = (char*)
- ((ret->product_revision.addr.seg << 4)
- + (ret->product_revision.addr.ofs));
-
- mem = strdup(ret->product_revision.string); /* leak */
- while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) {
- mem[i - 1] = '\0';
- }
- ret->product_revision.string = mem;
- }
-
- /* Cleanup. */
- LRMI_free_real(mem);
- return ret;
+ char *m2, *m1, *m0 = malloc(len + 1);
+ int i;
+
+ for(m1 = m0, i = 0; i < len; i++) {
+ if(m1 == m0 && s[i] <= ' ') continue;
+ *m1++ = s[i];
+ }
+ *m1 = 0;
+ while(m1 > m0 && m1[-1] <= ' ') {
+ *--m1 = 0;
+ }
+
+ m2 = strdup(m0);
+ free(m0);
+
+ return m2;
}
-/* Check if EDID queries are suorted. */
-int vbe_get_edid_supported()
+static unsigned segofs2addr(unsigned char *segofs)
{
- struct LRMI_regs regs;
- int ret = 0;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return 0;
- }
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f15;
- regs.ebx = 0x0000;
- regs.es = 0x3000;
- regs.edi = 0x3000;
-
- /* Do it. */
- iopl(3);
- ioperm(0, 0x400, 1);
-
- if(LRMI_int(0x10, &regs) == 0) {
- return 0;
- }
-
- /* Check for successful return. */
- if((regs.eax & 0xff) == 0x4f) {
- /* Supported. */
- ret = 1;
- } else {
- /* Not supported. */
- ret = 0;
- }
-
- /* Clean up and return. */
- return ret;
+ return segofs[0] + (segofs[1] << 8) + (segofs[2] << 4)+ (segofs[3] << 12);
}
-/* Get EDID info. */
-struct vbe_edid1_info *vbe_get_edid_info()
-{
- struct LRMI_regs regs;
- unsigned char *mem;
- struct vbe_edid1_info *ret = NULL;
- u_int16_t man;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return NULL;
- }
-
- /* Allocate a chunk of memory. */
- mem = LRMI_alloc_real(sizeof(struct vbe_edid1_info));
- if(mem == NULL) {
- return NULL;
- }
- memset(mem, 0, sizeof(struct vbe_edid1_info));
-
- 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 NULL;
- }
-
-#if 0
- /* Check for successful return. */
- if((regs.eax & 0xffff) != 0x004f) {
- LRMI_free_real(mem);
- return NULL;
- }
-#elseif
- /* Check for successful return. */
- if((regs.eax & 0xff) != 0x4f) {
- LRMI_free_real(mem);
- return NULL;
- }
-#endif
-
- /* Get memory for return. */
- ret = malloc(sizeof(struct vbe_edid1_info));
- if(ret == NULL) {
- LRMI_free_real(mem);
- return NULL;
- }
-
- /* Copy the buffer for return. */
- memcpy(ret, mem, sizeof(struct vbe_edid1_info));
-
- memcpy(&man, &ret->manufacturer_name, 2);
- man = ntohs(man);
- memcpy(&ret->manufacturer_name, &man, 2);
-
- LRMI_free_real(mem);
- return ret;
-}
-
-/* Figure out what the current video mode is. */
-int32_t vbe_get_mode()
+static unsigned get_data(unsigned char *buf, unsigned buf_size, unsigned addr)
{
- struct LRMI_regs regs;
- int32_t ret = -1;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return -1;
- }
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f03;
+ unsigned bufferaddr = 0x7e00;
+ unsigned len;
+
+ *buf = 0;
+ len = 0;
+
+ if(addr >= bufferaddr && addr < bufferaddr + 0x200) {
+ len = bufferaddr + 0x200 - addr;
+ if(len >= buf_size) len = buf_size - 1;
+ memcpy(buf, addr + (char *) 0, len);
+ }
+ else if(addr >= 0x0c0000 && addr < 0x100000) {
+ len = 0x100000 - addr;
+ if(len >= buf_size) len = buf_size - 1;
+ memcpy(buf, addr + (char *) 0, len);
+ }
+
+ buf[len] = 0;
+
+ return len;
+}
- /* Do it. */
- iopl(3);
- ioperm(0, 0x400, 1);
+#define GET_WORD(ADDR, OFS) ((ADDR)[OFS] + ((ADDR)[(OFS) + 1] << 8))
- if(LRMI_int(0x10, &regs) == 0) {
- return -1;
- }
-
- /* Save the returned value. */
- if((regs.eax & 0xffff) == 0x004f) {
- ret = regs.ebx & 0xffff;
- } else {
- ret = -1;
- }
-
- /* Clean up and return. */
- return ret;
+int vbe_get_vbe_info(struct vbe_info *vbe)
+{
+ int i, l, u;
+ unsigned char v[0x200];
+ unsigned char tmp[1024];
+ int ax, bx, cx;
+
+ if (vbe == NULL)
+ return 0;
+
+ /* Setup registers for the interrupt call */
+ ax = 0x4f00;
+ bx = 0;
+ cx = 0;
+ memset(v, 0, sizeof(v));
+ strcpy(v, "VBE2");
+
+ /* Get VBE block */
+ i = CallInt10(&ax, &bx, &cx, v, sizeof(v), cpuemu) & 0xffff;
+ if (i != 0x4f) {
+ D(bug("VBE: Error (0x4f00): 0x%04x\n", i));
+ return 0;
+ }
+
+ /* Parse VBE block */
+ vbe->version = GET_WORD(v, 0x04);
+ vbe->oem_version = GET_WORD(v, 0x14);
+ vbe->memory_size = GET_WORD(v, 0x12) << 16;
+ D(bug("version = %u.%u, oem version = %u.%u\n",
+ vbe->version >> 8, vbe->version & 0xff, vbe->oem_version >> 8, vbe->oem_version & 0xff));
+ D(bug("memory = %uk\n", vbe->memory_size >> 10));
+
+ l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x06));
+ vbe->oem_name = canon_str(tmp, l);
+ D(bug("oem name [0x%05x] = \"%s\"\n", u, vbe->oem_name));
+
+ l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x16));
+ vbe->vendor_name = canon_str(tmp, l);
+ D(bug("vendor name [0x%05x] = \"%s\"\n", u, vbe->vendor_name));
+
+ l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x1a));
+ vbe->product_name = canon_str(tmp, l);
+ D(bug("product name [0x%05x] = \"%s\"\n", u, vbe->product_name));
+
+ l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x1e));
+ vbe->product_revision = canon_str(tmp, l);
+ D(bug("product revision [0x%05x] = \"%s\"\n", u, vbe->product_revision));
+
+ l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x0e)) >> 1;
+ for(i = vbe->modes = 0; i < l && i < sizeof vbe->mode_list / sizeof *vbe->mode_list; i++) {
+ u = GET_WORD(tmp, 2 * i);
+ if(u != 0xffff)
+ vbe->mode_list[vbe->modes++] = u;
+ else
+ break;
+ }
+ D(bug("%u video modes\n", vbe->modes));
+
+ return 1;
}
-/* Set the video mode. */
-void vbe_set_mode(u_int16_t mode)
+/* Get EDID info. */
+int vbe_get_edid_info(struct vbe_edid1_info *edid)
{
- struct LRMI_regs regs;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return;
- }
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f02;
- regs.ebx = mode;
-
- /* Do it. */
- iopl(3);
- ioperm(0, 0x400, 1);
- LRMI_int(0x10, &regs);
-
- /* Return. */
- return;
+ int i;
+ int ax, bx, cx;
+
+ if (edid == NULL)
+ return 0;
+
+ /* Setup registers for the interrupt call */
+ ax = 0x4f15;
+ bx = 1;
+ cx = 0;
+
+ /* Get EDID block */
+ i = CallInt10(&ax, &bx, &cx, (unsigned char *)edid, sizeof *edid, cpuemu) & 0xffff;
+ if (i != 0x4f) {
+ D(bug("EDID: Error (0x4f15): 0x%04x\n", i));
+ return 0;
+ }
+
+ edid->manufacturer_name.p = ntohs(edid->manufacturer_name.p);
+ return 1;
}
/* Just read ranges from the EDID. */
@@ -364,16 +202,14 @@ static int compare_vbe_modelines(const void *m1, const void *m2)
return 0;
}
-struct vbe_modeline *vbe_get_edid_modelines()
+struct vbe_modeline *vbe_get_edid_modelines(struct vbe_edid1_info *edid)
{
- struct vbe_edid1_info *edid;
struct vbe_modeline *ret;
char buf[LINE_MAX];
int modeline_count = 0, i, j;
- if((edid = vbe_get_edid_info()) == NULL) {
- return NULL;
- }
+ if (edid == NULL)
+ return NULL;
memcpy(buf, &edid->established_timings,
sizeof(edid->established_timings));
@@ -567,143 +403,3 @@ struct vbe_modeline *vbe_get_edid_modelines()
return ret;
}
-
-const void *vbe_save_svga_state()
-{
- struct LRMI_regs regs;
- unsigned char *mem;
- u_int16_t block_size;
- void *data;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return NULL;
- }
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f04;
- regs.ecx = 0xffff;
- regs.edx = 0;
-
- iopl(3);
- ioperm(0, 0x400, 1);
-
- if(LRMI_int(0x10, &regs) == 0) {
- return NULL;
- }
-
- if((regs.eax & 0xff) != 0x4f) {
- fprintf(stderr, "Get SuperVGA Video State not supported.\n");
- return NULL;
- }
-
- if((regs.eax & 0xffff) != 0x004f) {
- fprintf(stderr, "Get SuperVGA Video State Info failed.\n");
- return NULL;
- }
-
- block_size = 64 * (regs.ebx & 0xffff);
-
- /* Allocate a chunk of memory. */
- mem = LRMI_alloc_real(block_size);
- if(mem == NULL) {
- return NULL;
- }
- memset(mem, 0, sizeof(block_size));
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f04;
- regs.ecx = 0x000f;
- regs.edx = 0x0001;
- regs.es = ((u_int32_t)mem) >> 4;
- regs.ebx = ((u_int32_t)mem) & 0x0f;
- memset(mem, 0, block_size);
- iopl(3);
- ioperm(0, 0x400, 1);
-
- if(LRMI_int(0x10, &regs) == 0) {
- LRMI_free_real(mem);
- return NULL;
- }
-
- if((regs.eax & 0xffff) != 0x004f) {
- fprintf(stderr, "Get SuperVGA Video State Save failed.\n");
- return NULL;
- }
-
- data = malloc(block_size);
- if(data == NULL) {
- LRMI_free_real(mem);
- return NULL;
- }
-
- /* Clean up and return. */
- memcpy(data, mem, block_size);
- LRMI_free_real(mem);
- return data;
-}
-
-void vbe_restore_svga_state(const void *state)
-{
- struct LRMI_regs regs;
- unsigned char *mem;
- u_int16_t block_size;
-
- /* Initialize LRMI. */
- if(LRMI_init() == 0) {
- return;
- }
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f04;
- regs.ecx = 0x000f;
- regs.edx = 0;
-
- /* Find out how much memory we need. */
- iopl(3);
- ioperm(0, 0x400, 1);
-
- if(LRMI_int(0x10, &regs) == 0) {
- return;
- }
-
- if((regs.eax & 0xff) != 0x4f) {
- fprintf(stderr, "Get SuperVGA Video State not supported.\n");
- return;
- }
-
- if((regs.eax & 0xffff) != 0x004f) {
- fprintf(stderr, "Get SuperVGA Video State Info failed.\n");
- return;
- }
-
- block_size = 64 * (regs.ebx & 0xffff);
-
- /* Allocate a chunk of memory. */
- mem = LRMI_alloc_real(block_size);
- if(mem == NULL) {
- return;
- }
- memset(mem, 0, sizeof(block_size));
-
- memset(&regs, 0, sizeof(regs));
- regs.eax = 0x4f04;
- regs.ecx = 0x000f;
- regs.edx = 0x0002;
- regs.es = 0x2000;
- regs.ebx = 0x0000;
- memcpy(mem, state, block_size);
-
- iopl(3);
- ioperm(0, 0x400, 1);
-
- if(LRMI_int(0x10, &regs) == 0) {
- LRMI_free_real(mem);
- return;
- }
-
- if((regs.eax & 0xffff) != 0x004f) {
- fprintf(stderr, "Get SuperVGA Video State Restore failed.\n");
- return;
- }
-}
diff --git a/tools/ddcprobe/vbe.h b/tools/ddcprobe/vbe.h
index 338d3bd88..4dd7e70c5 100644
--- a/tools/ddcprobe/vbe.h
+++ b/tools/ddcprobe/vbe.h
@@ -3,113 +3,20 @@
#ident "$Id$"
#include <sys/types.h>
+struct vbe_mode_info;
+
/* Record returned by int 0x10, function 0x4f, subfunction 0x00. */
struct vbe_info {
- unsigned char signature[4];
- unsigned char version[2];
- union {
- struct {
- u_int16_t ofs;
- u_int16_t seg;
- } addr;
- const char *string;
- } oem_name;
- u_int32_t capabilities;
- union {
- struct {
- u_int16_t ofs;
- u_int16_t seg;
- } addr;
- u_int16_t *list;
- } mode_list;
- u_int16_t memory_size;
- /* VESA 3.0+ */
- u_int16_t vbe_revision;
- union {
- struct {
- u_int16_t ofs;
- u_int16_t seg;
- } addr;
- const char *string;
- } vendor_name;
- union {
- struct {
- u_int16_t ofs;
- u_int16_t seg;
- } addr;
- const char *string;
- } product_name;
- union {
- struct {
- u_int16_t ofs;
- u_int16_t seg;
- } addr;
- const char *string;
- } product_revision;
- char reserved1[222];
- char reserved2[256];
-} __attribute__ ((packed));
-
-/* Stuff returned by int 0x10, function 0x4f, subfunction 0x01. */
-struct vbe_mode_info {
- /* required for all VESA versions */
- struct {
- /* VBE 1.0+ */
- u_int16_t supported: 1;
- u_int16_t optional_info_available: 1;
- u_int16_t bios_output_supported: 1;
- u_int16_t color: 1;
- u_int16_t graphics: 1;
- /* VBE 2.0+ */
- u_int16_t not_vga_compatible: 1;
- u_int16_t not_bank_switched: 1;
- u_int16_t lfb: 1;
- /* VBE 1.0+ */
- u_int16_t unknown: 1;
- u_int16_t must_enable_directaccess_in_10: 1;
- } mode_attributes;
- struct {
- unsigned char exists: 1;
- unsigned char readable: 1;
- unsigned char writeable: 1;
- unsigned char reserved: 5;
- } windowa_attributes, windowb_attributes;
- u_int16_t window_granularity;
- u_int16_t window_size;
- u_int16_t windowa_start_segment, windowb_start_segment;
- u_int16_t window_positioning_seg, window_positioning_ofs;
- u_int16_t bytes_per_scanline;
- /* optional for VESA 1.0/1.1, required for OEM modes */
- u_int16_t w, h;
- unsigned char cell_width, cell_height;
- unsigned char memory_planes;
- unsigned char bpp;
- unsigned char banks;
- enum {
- memory_model_text = 0,
- memory_model_cga = 1,
- memory_model_hgc = 2,
- memory_model_ega16 = 3,
- memory_model_packed_pixel = 4,
- memory_model_sequ256 = 5,
- memory_model_direct_color = 6,
- memory_model_yuv = 7,
- } memory_model: 8;
- unsigned char bank_size;
- unsigned char image_pages;
- unsigned char reserved1;
- /* required for VESA 1.2+ */
- unsigned char red_mask, red_field;
- unsigned char green_mask, green_field;
- unsigned char blue_mask, blue_field;
- unsigned char reserved_mask, reserved_field;
- unsigned char direct_color_mode_info;
- /* VESA 2.0+ */
- u_int32_t linear_buffer_address;
- u_int32_t offscreen_memory_address;
- u_int16_t offscreen_memory_size;
- unsigned char reserved2[206];
-} __attribute__ ((packed));
+ unsigned int version;
+ unsigned int oem_version;
+ unsigned int memory_size;
+ char *oem_name;
+ char *vendor_name;
+ char *product_name;
+ char *product_revision;
+ unsigned int modes;
+ unsigned int mode_list[0x100];
+};
/* Modeline information used by XFree86. */
struct vbe_modeline {
@@ -211,12 +118,15 @@ struct vbe_edid_monitor_descriptor {
struct vbe_edid1_info {
unsigned char header[8];
- struct {
- u_int16_t char3: 5;
- u_int16_t char2: 5;
- u_int16_t char1: 5;
- u_int16_t zero: 1;
- } manufacturer_name __attribute__ ((packed));
+ union {
+ u_int16_t p;
+ struct {
+ u_int16_t char3: 5;
+ u_int16_t char2: 5;
+ u_int16_t char1: 5;
+ u_int16_t zero: 1;
+ } u;
+ } manufacturer_name;
u_int16_t product_code;
u_int32_t serial_number;
unsigned char week;
@@ -282,24 +192,10 @@ struct vbe_edid1_info {
#define VBE_LINEAR_FRAMEBUFFER 0x4000
/* Get VESA information. */
-struct vbe_info *vbe_get_vbe_info();
-
-/* Get information about a particular video mode, bitwise or with
- VBE_LINEAR_FRAMEBUFFER to check if LFB version is supported. */
-struct vbe_mode_info *vbe_get_mode_info(u_int16_t mode);
+int vbe_get_vbe_info(struct vbe_info *vbe);
/* Check if EDID reads are supported, and do them. */
-int vbe_get_edid_supported();
-struct vbe_edid1_info *vbe_get_edid_info();
-
-/* Get the current video mode, -1 on error. */
-int32_t vbe_get_mode();
-/* Set a new video mode, bitwise or with VBE_LINEAR_FRAMEBUFFER. */
-void vbe_set_mode(u_int16_t mode);
-
-/* Save/restore the SVGA state. Call free() on the state record when done. */
-const void *vbe_save_svga_state();
-void vbe_restore_svga_state(const void *state);
+int vbe_get_edid_info(struct vbe_edid1_info *edid);
/* Get the ranges of values suitable for the attached monitor. */
void vbe_get_edid_ranges(struct vbe_edid1_info *edid,