Implements VBE function 15h defined in the VBE/DDC standard. Contains a preliminary implementation for bochsvga which returns a hardcoded EDID with some generic informations.
It seems Xorg refuses to use resolutions higher than 1024x768 if the ROM doesn't return an EDID with timing informations to support it.
I think this work can be completed to add support for the Geode vga ROM, as an I2C interface is probably available to extract the EDID from a real monitor.
Julian Pidancet (2): vgasrc: Add skeleton for VBE function 15h (VBE/DDC Standard) bochsvga: Implement vbe 15h function
src/vbe.h | 5 +++ vgasrc/bochsvga.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/bochsvga.h | 2 + vgasrc/stdvga.c | 11 ++++++ vgasrc/stdvga.h | 2 + vgasrc/vbe.c | 34 ++++++++++++++++++++ vgasrc/vgahw.h | 12 +++++++ 7 files changed, 154 insertions(+), 0 deletions(-)
Signed-off-by: Julian Pidancet julian.pidancet@gmail.com --- src/vbe.h | 5 +++++ vgasrc/stdvga.c | 11 +++++++++++ vgasrc/stdvga.h | 2 ++ vgasrc/vbe.c | 34 ++++++++++++++++++++++++++++++++++ vgasrc/vgahw.h | 8 ++++++++ 5 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/src/vbe.h b/src/vbe.h index 386613c..b5aedc6 100644 --- a/src/vbe.h +++ b/src/vbe.h @@ -154,4 +154,9 @@ struct vbe_crtc_info { #define VBE_DIRECTCOLOR_COLOR_RAMP_PROGRAMMABLE 0x01 #define VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE 0x02
+/* Display Data Channel (DDC) */ +#define VBE_DDC1_PROTOCOL_SUPPORTED 0x01 +#define VBE_DDC2_PROTOCOL_SUPPORTED 0x02 +#define VBE_DDC_BLANK_DURING_TRANSFER 0x04 + #endif diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index ae6c0be..270cd65 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -499,3 +499,14 @@ stdvga_init(void)
return 0; } + +int stdvga_get_ddc_capabilities(u16 unit) +{ + return -1; +} + +int stdvga_read_edid(u16 unit, u16 block, u16 seg, void *data) +{ + return -1; +} + diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index c9a9ba1..e3bd447 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -108,5 +108,7 @@ int stdvga_save_state(u16 seg, void *data, int states); int stdvga_restore_state(u16 seg, void *data, int states); void stdvga_enable_video_addressing(u8 disable); int stdvga_init(void); +int stdvga_get_ddc_capabilities(u16 unit); +int stdvga_read_edid(u16 unit, u16 block, u16 seg, void *data);
#endif // stdvga.h diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index 227a244..ed7c6ee 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -384,6 +384,39 @@ vbe_104f10(struct bregs *regs) }
static void +vbe_104f15(struct bregs *regs) +{ + int ret; + u16 seg = regs->es; + void *data = (void *)(regs->di+0); + u16 unit = regs->cx; + u16 block = regs->dx; + + switch (regs->bl) { + case 0x00: /* Report VBE/DDC Capabilities */ + ret = vgahw_get_ddc_capabilities(unit); + if (ret < 0) + goto fail; + regs->bh = ret >> 8; /* Approx. time in seconds, rounded up, to transfer + one EDID block (128 bytes) */ + regs->bl = ret & 0xff; /* DDC level supported */ + break; + case 0x01: /* Read EDID */ + ret = vgahw_read_edid(unit, block, seg, data); + if (ret < 0) + goto fail; + break; + default: + goto fail; + } + regs->ax = 0x004f; + return; + +fail: + regs->ax = 0x014f; +} + +static void vbe_104fXX(struct bregs *regs) { debug_stub(regs); @@ -410,6 +443,7 @@ handle_104f(struct bregs *regs) case 0x08: vbe_104f08(regs); break; case 0x0a: vbe_104f0a(regs); break; case 0x10: vbe_104f10(regs); break; + case 0x15: vbe_104f15(regs); break; default: vbe_104fXX(regs); break; } } diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 044cd32..01d2609 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -129,4 +129,12 @@ static inline int vgahw_restore_state(u16 seg, void *data, int states) { return stdvga_restore_state(seg, data, states); }
+static inline int vgahw_get_ddc_capabilities(u16 unit) { + return stdvga_get_ddc_capabilities(unit); +} + +static inline int vgahw_read_edid(u16 unit, u16 block, u16 seg, void *data) { + return stdvga_read_edid(unit, block, seg, data); +} + #endif // vgahw.h
This patch adds the ability for the Bochs VGA ROM to return information about a generic SVGA monitor.
It uses a hardcoded EDID for now, but we can easily immagine contructing an EDID at run time with the help of some support code.
Returning an EDID with decent timings may be necessary in case we want to use a resolution superior to 1024x768 with Xorg.
Inspired by this patch I digged out from the vgabios mailing list: http://old.nabble.com/VBE-BIOS-support-for-monitor-information-(EDID)-td2295...
Untested with Xorg.
Signed-off-by: Julian Pidancet julian.pidancet@gmail.com --- vgasrc/bochsvga.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/bochsvga.h | 2 + vgasrc/vgahw.h | 4 ++ 3 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 2a8aeb1..93e6818 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -323,6 +323,88 @@ bochsvga_set_mode(struct vgamode_s *vmode_g, int flags) return 0; }
+/**************************************************************** + * EDID + ****************************************************************/ + +u8 bochsvga_edid[128] VAR16 = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* 8-byte header */ + 0x04, 0x21, /* Vendor ID ("AAA") */ + 0xAB, 0xCD, /* Product ID */ + 0x00, 0x00, 0x00, 0x00, /* Serial number */ + 54, /* Week of manufacture (54) */ + 10, /* Year of manufacture (2000) */ + 0x01, 0x01, /* EDID version number (1.1) */ + 0x0F, /* Video signal interface */ + 0x21, 0x19, /* Scren size (330 mm * 250 mm) */ + 0x78, /* Display gamma (2.2) */ + 0x0D, /* Feature flags */ + 0x78, 0xF5, /* Chromaticity LSB */ + 0xA6, 0x55, 0x48, 0x9B, 0x26, 0x12, 0x50, 0x54, /* Chromaticity MSB */ + 0xFF, 0xEF, 0x80, /* Established timings */ + 0x31, 0x59, /* Standard timing #1 (640 x 480 @ 85 Hz) */ + 0x45, 0x59, /* Standard timing #2 (800 x 600 @ 85 Hz) */ + 0x61, 0x59, /* Standard timing #3 (1024 x 768 @ 85 Hz) */ + 0x31, 0x4A, /* Standard timing #4 (640 x 480 @ 70 Hz) */ + 0x81, 0x4A, /* Standard timing #5 (1280 x 960 @ 70 Hz) */ + 0xA9, 0x40, /* Standard timing #6 (1600 x 1200 @ 60 Hz) */ + 0x01, 0x01, /* Standard timing #7 (unused) */ + 0x01, 0x01, /* Standard timing #8 (unused) */ + + /* First timing descriptor (1024 x 768) */ + 0x30, 0x2a, /* Pixel clock */ + 0x80, /* hactive low */ + 0xC0, /* hblank low */ + 0x41, /* hactive high, hblank high */ + 0x60, /* vactive low */ + 0x24, /* vblank low */ + 0x30, /* vactive high, vblank high */ + 0x40, /* hsync offset low */ + 0x80, /* hsync width low */ + 0x13, /* vsync offset low, vsync width low */ + 0x00, /* hsync offset high, hsync width high , vsync offset high, vsync width high */ + 0x2C, /* hsize low */ + 0xE1, /* vsize low */ + 0x10, /* hsize high, vsize high */ + 0x00, /* hborder */ + 0x00, /* vborder */ + 0x1E, /* Features */ + + /* Second descriptor */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Third descriptor - Serial number */ + 0x00, 0x00, 0x00, 0xFF, 0x00, + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\n', ' ', ' ', + + /* Fourth descriptor - Monitor name */ + 0x00,0x00,0x00,0xFC,0x00, + 'B', 'o', 'c', 'h', 's', ' ', 'S', 'c', 'r', 'e', 'e', 'n', '\n', + + 0x00, /* Extensions */ + 0x00, /* Checksum */ +}; + +int bochsvga_get_ddc_capabilities(u16 unit) +{ + if (unit != 0) + return -1; + + return (1 << 8) | VBE_DDC1_PROTOCOL_SUPPORTED; +} + +int bochsvga_read_edid(u16 unit, u16 block, u16 seg, void *data) +{ + if (unit != 0 || block != 0) + return -1; + + memcpy_far(seg, data, get_global_seg(), bochsvga_edid, + sizeof (bochsvga_edid)); + + return 0; +}
/**************************************************************** * Init @@ -389,5 +471,11 @@ bochsvga_init(void) } }
+ // Fixup EDID checksum + u8 sum = -checksum_far(get_global_seg(), bochsvga_edid, + sizeof(bochsvga_edid)); + SET_VGA(bochsvga_edid[sizeof (bochsvga_edid) - 1], sum); + return 0; } + diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index 1c98203..20a28bd 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -67,5 +67,7 @@ int bochsvga_save_state(u16 seg, void *data, int states); int bochsvga_restore_state(u16 seg, void *data, int states); int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags); int bochsvga_init(void); +int bochsvga_get_ddc_capabilities(u16 unit); +int bochsvga_read_edid(u16 unit, u16 block, u16 seg, void *data);
#endif // bochsvga.h diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 01d2609..34945f3 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -130,10 +130,14 @@ static inline int vgahw_restore_state(u16 seg, void *data, int states) { }
static inline int vgahw_get_ddc_capabilities(u16 unit) { + if (CONFIG_VGA_BOCHS) + return bochsvga_get_ddc_capabilities(unit); return stdvga_get_ddc_capabilities(unit); }
static inline int vgahw_read_edid(u16 unit, u16 block, u16 seg, void *data) { + if (CONFIG_VGA_BOCHS) + return bochsvga_read_edid(unit, block, seg, data); return stdvga_read_edid(unit, block, seg, data); }
On Wed, Mar 07, 2012 at 02:41:05AM +0000, Julian Pidancet wrote:
Implements VBE function 15h defined in the VBE/DDC standard. Contains a preliminary implementation for bochsvga which returns a hardcoded EDID with some generic informations.
It seems Xorg refuses to use resolutions higher than 1024x768 if the ROM doesn't return an EDID with timing informations to support it.
I think this work can be completed to add support for the Geode vga ROM, as an I2C interface is probably available to extract the EDID from a real monitor.
I'm okay with the change, but I don't think it should be enabled in the upcoming SeaBIOS v1.7.0 release. Perhaps add a config setting and disable it by default.
Also, the comment on patch 2 seems to indicate it is untested. I think it should be tested before committing.
-Kevin
On Sat, Mar 10, 2012 at 7:01 PM, Kevin O'Connor kevin@koconnor.net wrote:
On Wed, Mar 07, 2012 at 02:41:05AM +0000, Julian Pidancet wrote:
Implements VBE function 15h defined in the VBE/DDC standard. Contains a preliminary implementation for bochsvga which returns a hardcoded EDID with some generic informations.
It seems Xorg refuses to use resolutions higher than 1024x768 if the ROM doesn't return an EDID with timing informations to support it.
I think this work can be completed to add support for the Geode vga ROM, as an I2C interface is probably available to extract the EDID from a real monitor.
I'm okay with the change, but I don't think it should be enabled in the upcoming SeaBIOS v1.7.0 release. Perhaps add a config setting and disable it by default.
Also, the comment on patch 2 seems to indicate it is untested. I think it should be tested before committing.
How about including only the first of this 2-patch set. It only adds the 15h function stub and is a pretty low-risk change.