The Bochs VGA ROM now return an information
    about a recent WIDE monitor.

    It is constructed from defitions at run time.

    Returning an EDID with decent timings may be necessary
    in case we want to use a resolution
    superior to 1024x768 with Xorg.

Signed-off-by: Hiroshi Miura <[email protected]>
---
 vgasrc/bochsvga.c |  202
++++++++++++++++++++++++++++++++---------------------
 vgasrc/vbe_edid.h |  134 +++++++++++++++++++++++++++++++++++
 2 files changed, 255 insertions(+), 81 deletions(-)
 create mode 100644 vgasrc/vbe_edid.h



diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c
index 93e6818..c12a859 100644
--- a/vgasrc/bochsvga.c
+++ b/vgasrc/bochsvga.c
@@ -15,7 +15,7 @@
 #include "stdvga.h" // VGAREG_SEQU_ADDRESS
 #include "pci.h" // pci_config_readl
 #include "pci_regs.h" // PCI_BASE_ADDRESS_0
-
+#include "vbe_edid.h"
 
 /****************************************************************
  * Mode tables
@@ -83,12 +83,15 @@ static struct bochsvga_mode
     { 0x184, { MM_DIRECT, 1680, 1050, 16, 8, 16, SEG_GRAPH } },
     { 0x185, { MM_DIRECT, 1680, 1050, 24, 8, 16, SEG_GRAPH } },
     { 0x186, { MM_DIRECT, 1680, 1050, 32, 8, 16, SEG_GRAPH } },
-    { 0x187, { MM_DIRECT, 1920, 1200, 16, 8, 16, SEG_GRAPH } },
-    { 0x188, { MM_DIRECT, 1920, 1200, 24, 8, 16, SEG_GRAPH } },
-    { 0x189, { MM_DIRECT, 1920, 1200, 32, 8, 16, SEG_GRAPH } },
-    { 0x18a, { MM_DIRECT, 2560, 1600, 16, 8, 16, SEG_GRAPH } },
-    { 0x18b, { MM_DIRECT, 2560, 1600, 24, 8, 16, SEG_GRAPH } },
-    { 0x18c, { MM_DIRECT, 2560, 1600, 32, 8, 16, SEG_GRAPH } },
+    { 0x187, { MM_DIRECT, 1920, 1080, 16, 8, 16, SEG_GRAPH } },
+    { 0x188, { MM_DIRECT, 1920, 1080, 24, 8, 16, SEG_GRAPH } },
+    { 0x189, { MM_DIRECT, 1920, 1080, 32, 8, 16, SEG_GRAPH } },
+    { 0x18a, { MM_DIRECT, 1920, 1200, 16, 8, 16, SEG_GRAPH } },
+    { 0x18b, { MM_DIRECT, 1920, 1200, 24, 8, 16, SEG_GRAPH } },
+    { 0x18c, { MM_DIRECT, 1920, 1200, 32, 8, 16, SEG_GRAPH } },
+    { 0x18d, { MM_DIRECT, 2560, 1600, 16, 8, 16, SEG_GRAPH } },
+    { 0x18e, { MM_DIRECT, 2560, 1600, 24, 8, 16, SEG_GRAPH } },
+    { 0x18f, { MM_DIRECT, 2560, 1600, 32, 8, 16, SEG_GRAPH } },
 };
 
 static int is_bochsvga_mode(struct vgamode_s *vmode_g)
@@ -323,70 +326,6 @@ 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)
@@ -395,17 +334,123 @@ int bochsvga_get_ddc_capabilities(u16 unit)
     return (1 << 8) | VBE_DDC1_PROTOCOL_SUPPORTED;
 }
 
-int bochsvga_read_edid(u16 unit, u16 block, u16 seg, void *data)
+u8 most_chromaticity[8] VAR16 = {0xA6,0x55,0x48,0x9B,0x26,0x12,0x50,0x54};
+unsigned char vgabios_name[] VAR16 = "Sea VGABIOS";
+struct edid_detailed_timing vbe_edid_dtd_1920x1080 VAR16 = {
+     WORDBE(0x3a02), 0x80, 0x90, 0x72, 0x38, 0x26,
+     0x40, 0x78, 0xD0, 0x13, 0x00, 0x14, 0x2B, 0x21,
+     0x00, 0x00, 0x1E};
+struct edid_detailed_timing vbe_edid_dtd_1280x1024 VAR16 = {
+     WORDBE(0x2a30), 0x00, 0x98, 0x51, 0x00, 0x2A, 
+     0x40, 0x30, 0x70, 0x13, 0x00, 0x2C, 0xE1, 0x10,
+     0x00, 0x00, 0x1E};
+struct edid_detailed_timing vbe_edid_dtd_1152x864 VAR16 = {
+     WORDBE(0x2a30), 0x80, 0xC0, 0x41, 0x60, 0x24,
+     0x30, 0x40, 0x80, 0x13, 0x00, 0x2C, 0xE1, 0x10,
+     0x00, 0x00, 0x1E};
+struct edid_detailed_timing vbe_edid_dtd_1600x1200 VAR16 = {
+     WORDBE(0x3c8c), 0x40, 0x30, 0x62, 0xB0, 0x32,
+     0x40, 0x40, 0xC0, 0x13, 0x00, 0x2C, 0xE1, 0x10,
+     0x00, 0x00, 0x1E};
+
+int bochsvga_read_edid_block0(u16 unit, u16 block, u16 seg, void *data)
 {
-    if (unit != 0 || block != 0)
-        return -1;
+    struct vbe_edid_info  *info = data;
+    int i;
+
+    memset_far(seg, info, 0, sizeof(*info));
+    /* header */
+    SET_FARVAR(seg, info->header[0], 0);
+    for (i = 1; i < 7; i++) {
+        SET_FARVAR(seg, info->header[i], 0xFF);
+    }
+    SET_FARVAR(seg, info->header[7], 0);
+    /* Vendor/Product/Serial/Date */
+    SET_FARVAR(seg, info->vendor, WORDBE(0x0421));
+    SET_FARVAR(seg, info->product,WORDBE(0xABCD));
+    SET_FARVAR(seg, info->serial, DWORDBE(0));
+    /* date/version  */
+    SET_FARVAR(seg, info->week,54);
+    SET_FARVAR(seg, info->year,10); /* 2000 */
+    SET_FARVAR(seg, info->major_version,1);
+    SET_FARVAR(seg, info->minor_version,3); /* 1.3 */
+    /* video prameters */
+    SET_FARVAR(seg, info->video_setup,0x0F);
+    /* Video signal interface (analogue, 0.700 : 0.300 : 1.000 V p-p,
+       Video Setup: Blank Level = Black Level, Separate Sync H & V Signals are
+       supported, Composite Sync Signal on Horizontal is supported, Composite 
+       Sync Signal on Green Video is supported, Serration on the Vertical Sync
+       is supported) */
+    SET_FARVAR(seg, info->screen_width,0x21);
+    SET_FARVAR(seg, info->screen_height,0x19); /* 330 mm * 250 mm */
+    SET_FARVAR(seg, info->gamma,0x78); /* 2.2 */
+    SET_FARVAR(seg, info->feature_flag,0x0D); /* no DMPS states, RGB, display is continuous frequency */
+    SET_FARVAR(seg, info->least_chromaticity[0],0x78);
+    SET_FARVAR(seg, info->least_chromaticity[1],0xF5);
+    memcpy_far(seg, info->most_chromaticity, get_global_seg(), most_chromaticity,
+               sizeof (most_chromaticity));
+
+    SET_FARVAR(seg, info->established_timing[0], 0xFF);
+    SET_FARVAR(seg, info->established_timing[1], 0xEF);
+    SET_FARVAR(seg, info->established_timing[2], 0x80);
+    /* 720x400@70Hz, 720x400@88Hz, 640x480@60Hz, 640x480@67Hz, 640x480@72Hz, 640x480@75Hz,
+       800x600@56Hz, 800x600@60Hz, 800x600@72Hz, 800x600@75Hz, 832x624@75Hz, 1152x870@75Hz,
+       not 1024x768@87Hz(I), 1024x768@60Hz, 1024x768@70Hz, 1024x768@75Hz, 1280x1024@75Hz */
+    /* standard timings */
+    SET_FARVAR(seg, info->standard_timing[0], VBE_EDID_STD_640x480_85Hz);
+    SET_FARVAR(seg, info->standard_timing[1], VBE_EDID_STD_800x600_85Hz);
+    SET_FARVAR(seg, info->standard_timing[2], VBE_EDID_STD_1024x768_85Hz);
+    SET_FARVAR(seg, info->standard_timing[3], VBE_EDID_STD_1280x720_70Hz);
+    SET_FARVAR(seg, info->standard_timing[4], VBE_EDID_STD_1280x960_60Hz);
+    SET_FARVAR(seg, info->standard_timing[5], VBE_EDID_STD_1440x900_60Hz);
+    SET_FARVAR(seg, info->standard_timing[6], VBE_EDID_STD_1600x1200_60Hz);
+    SET_FARVAR(seg, info->standard_timing[7], VBE_EDID_STD_1680x1050_60Hz);
+    /* detailed timing blocks */
+    memcpy_far(seg, &(info->desc[0].dtd), get_global_seg(), &vbe_edid_dtd_1152x864,
+               sizeof (vbe_edid_dtd_1152x864));
+    memcpy_far(seg, &(info->desc[1].dtd), get_global_seg(), &vbe_edid_dtd_1280x1024,
+               sizeof (vbe_edid_dtd_1280x1024));
+    /* serial */
+    for (i = 0; i < 5; i++) {
+        SET_FARVAR(seg, info->desc[2].mtxtd.header[i], 0);
+    }
+    SET_FARVAR(seg, info->desc[2].mtxtd.header[3], 0xFF);
+    for (i = 0; i < 10; i++) {
+        SET_FARVAR(seg, info->desc[2].mtxtd.text[i], i+0x30);
+    }
+    SET_FARVAR(seg, info->desc[2].mtxtd.text[10], 0x0A);
+    SET_FARVAR(seg, info->desc[2].mtxtd.text[11], 0x20);
+    SET_FARVAR(seg, info->desc[2].mtxtd.text[12], 0x20);
+    /* monitor name */
+    for (i = 0; i < 5; i++) {
+         SET_FARVAR(seg, info->desc[3].mtxtd.header[i], 0);
+    }
+    SET_FARVAR(seg, info->desc[3].mtxtd.header[3], 0xFC);
+    memcpy_far(seg, info->desc[3].mtxtd.text, get_global_seg(), vgabios_name, 12);
+    SET_FARVAR(seg, info->desc[3].mtxtd.text[12], 0x0A);
+    /* ext */
+    SET_FARVAR(seg, info->extensions, 0);
 
-    memcpy_far(seg, data, get_global_seg(), bochsvga_edid,
-               sizeof (bochsvga_edid));
+    /* checksum */
+    u8 sum = -checksum_far(get_global_seg(), info, sizeof(info));
+    SET_FARVAR(seg, info->checksum, sum);
 
     return 0;
 }
 
+int bochsvga_read_edid(u16 unit, u16 block, u16 seg, void *data)
+{
+    if (unit != 0)
+        return -1;
+
+    switch (block) {
+    case 0:
+        return bochsvga_read_edid_block0(unit, block, seg, data);
+    default:
+        return -1;
+    }
+}
+
 /****************************************************************
  * Init
  ****************************************************************/
@@ -471,11 +516,6 @@ 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/vbe_edid.h b/vgasrc/vbe_edid.h
new file mode 100644
index 0000000..f15a2af
--- /dev/null
+++ b/vgasrc/vbe_edid.h
@@ -0,0 +1,134 @@
+#ifndef __VBE_EDID_H
+#define __VBE_EDID_H
+
+#define WORDBE(x) ((((x) & 0xff) << 8 ) | (((x) >> 8) & 0xff))
+#define DWORDBE(x) (((x) & 0xff) << 24) | ((((x) >> 8) & 0xff) << 16 ) | ((((x) >> 16) & 0xff) << 8 ) | ((((x) >> 24) & 0xff))
+
+/* EDID infomation definitions */
+/* Detailed Timing Descriptor */
+struct edid_detailed_timing {
+    u16 pixel_clock;
+    u8 horizontal_addressable_low;
+    u8 horizontal_blanking_low;
+    u8 horizontal_high;
+    u8 vertical_addressable_low;
+    u8 vertical_blanking_low;
+    u8 vertical_high;
+    u8 horizontal_front_porch_low;
+    u8 horizontal_sync_pulse_low;
+    u8 vertical_low4;
+    u8 horizontal_vertical_sync_hi;
+    u8 horizontal_video_image_low;
+    u8 vertical_video_image_low;
+    u8 video_image_high;
+    u8 horizontal_border;
+    u8 vertical_border;
+    u8 features;
+} PACKED;
+
+/* Other Monitor Descriptors */
+/*
+  0xFF: Monitor serial number (text)
+  0xFE: Unspecified text (text)
+  0xFC: Monitor name (text)
+ */
+struct edid_monitor_text {
+    u8 header[5];
+    u8 text[13];
+} PACKED;
+
+/* Monitor Range Limits Descriptor */
+/*
+  0xFD: Monitor range limits. 6- or 13-byte binary descriptor.
+ */
+struct edid_monitor_range_limit {
+    u8 header[5];
+    u8 vertical_rate_min;
+    u8 vertical_rate_max;
+    u8 horizontal_rate_min;
+    u8 horizontal_rate_max;
+    u8 pixel_clock_max;
+    u8 extended_timing_type;
+    u8 reserved;
+    u8 start_frequency;
+    u8 gtf_c_val;
+    u16 gtf_m_val;
+    u8 gtf_k_val;
+    u8 gtf_j_val;
+} PACKED;
+
+/* White point Descriptor */
+/*
+  0xFB: Additional white point data. 2× 5-byte descriptors, padded with 0A 20 20.
+  0xFA: Additional standard timing identifiers. 6× 2-byte descriptors, padded with 0A
+ */
+struct edid_wp_desc {
+    u8 index;
+    u8 least;
+    u8 x;
+    u8 y;
+    u8 gamma;
+} PACKED;
+
+struct edid_white_point {
+    u8 header[5];
+    struct edid_wp_desc desc[2];
+    u8 padding[3];
+} PACKED;
+
+struct edid_additional_timing {
+    u8 header[5];
+    u16 standard_timing[6];
+    u8 padding;
+} PACKED;
+
+union edid_descriptors {
+    struct edid_detailed_timing     dtd;
+    struct edid_monitor_range_limit mrld;
+    struct edid_monitor_text        mtxtd;
+    struct edid_white_point         wpd;
+    struct edid_additional_timing   astd;
+} PACKED;
+
+struct vbe_edid_info {
+    u8 header[8];
+    u16 vendor;
+    u16 product;
+    u32 serial;
+    u8 week;
+    u8 year;
+    u8 major_version;
+    u8 minor_version;
+    u8 video_setup;
+    u8 screen_width;
+    u8 screen_height;
+    u8 gamma;
+    u8 feature_flag;
+    u8 least_chromaticity[2];
+    u8 most_chromaticity[8];
+    u8 established_timing[3];
+    u16 standard_timing[8];
+    union edid_descriptors desc[4];
+    u8 extensions;
+    u8 checksum;
+} PACKED;
+
+/* EDID Standard Timing Description */
+
+/* First byte: X resolution, divided by 8, less 31 (256–2288 pixels) */
+/* bit 7-6, X:Y pixel ratio: 00=16:10; 01=4:3; 10=5:4; 11=16:9 */
+/* bit 5-0, Vertical frequency, less 60 (60–123 Hz), nop 01 01 in Big Endian*/
+#define VBE_EDID_STD_640x480_85Hz                        0x5931
+#define VBE_EDID_STD_800x600_85Hz                        0x5945
+#define VBE_EDID_STD_1024x768_85Hz                       0x5961
+#define VBE_EDID_STD_1152x864_70Hz                       0x4A71
+#define VBE_EDID_STD_1280x720_70Hz                       0xCA81
+#define VBE_EDID_STD_1280x800_70Hz                       0x0A81
+#define VBE_EDID_STD_1280x960_60Hz                       0x4081
+#define VBE_EDID_STD_1280x1024_60Hz                      0x8081
+#define VBE_EDID_STD_1440x900_60Hz                       0x0095
+#define VBE_EDID_STD_1600x1200_60Hz                      0x40A9
+#define VBE_EDID_STD_1680x1050_60Hz                      0x00B3
+#define VBE_EDID_STD_NOP                                 0x0101
+
+#endif /* vbe_edid.h */


_______________________________________________
SeaBIOS mailing list
[email protected]
http://www.seabios.org/mailman/listinfo/seabios

Reply via email to