Hi Patrick,
On 03/17/2017 01:49 PM, Patrick Rudolph wrote:
Advertise compatible VESA modes, that are smaller or equal to coreboot's active framebuffer. Only modes that have the same Bpp are advertise and can be selected.
Allows the Windows 7 bootloader NTLDR to show up in VESA mode. Allows to show the Windows 7 boot logo. Allows Windows to boot in safe mode and in normal boot using VgaSave driver with resolution up to 1600x1200.
This fixes most likely other bootloader and operating systems as well, in case the are relying on VESA framebuffer support.
Known issues: Windows replaces int 15h handler, resulting in memcpy_far not being available. The call will prematurely exit and Windows won't show any picture at all. All tests were done with clear screen on mode change disabled.
NTLDR is aware of the framebuffer's pitch, but the internal clear screen method isn't. Some text artifacts might stay on screen. That's nothing SeaVGABios can fix.
Signed-off-by: Patrick Rudolph siro@das-labor.org
vgasrc/cbvga.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+)
diff --git a/vgasrc/cbvga.c b/vgasrc/cbvga.c index 4c349c5..6be6936 100644 --- a/vgasrc/cbvga.c +++ b/vgasrc/cbvga.c @@ -18,8 +18,73 @@ static struct vgamode_s CBmodeinfo VAR16; static struct vgamode_s CBemulinfo VAR16; static u32 CBlinelength VAR16;
+static struct cbvga_mode_s
static "const" struct cbvga_mode_s
+{
- u16 mode;
- struct vgamode_s info;
+} cbvesa_modes[] VAR16 = {
- /* VESA 1.0 modes */
- { 0x110, { MM_DIRECT, 640, 480, 15, 8, 16, SEG_GRAPH } },
- { 0x111, { MM_DIRECT, 640, 480, 16, 8, 16, SEG_GRAPH } },
- { 0x112, { MM_DIRECT, 640, 480, 24, 8, 16, SEG_GRAPH } },
- { 0x113, { MM_DIRECT, 800, 600, 15, 8, 16, SEG_GRAPH } },
- { 0x114, { MM_DIRECT, 800, 600, 16, 8, 16, SEG_GRAPH } },
- { 0x115, { MM_DIRECT, 800, 600, 24, 8, 16, SEG_GRAPH } },
- { 0x116, { MM_DIRECT, 1024, 768, 15, 8, 16, SEG_GRAPH } },
- { 0x117, { MM_DIRECT, 1024, 768, 16, 8, 16, SEG_GRAPH } },
- { 0x118, { MM_DIRECT, 1024, 768, 24, 8, 16, SEG_GRAPH } },
- { 0x119, { MM_DIRECT, 1280, 1024, 15, 8, 16, SEG_GRAPH } },
- { 0x11A, { MM_DIRECT, 1280, 1024, 16, 8, 16, SEG_GRAPH } },
- { 0x11B, { MM_DIRECT, 1280, 1024, 24, 8, 16, SEG_GRAPH } },
- { 0x11D, { MM_DIRECT, 1600, 1200, 15, 8, 16, SEG_GRAPH } },
- { 0x11E, { MM_DIRECT, 1600, 1200, 16, 8, 16, SEG_GRAPH } },
- { 0x11F, { MM_DIRECT, 1600, 1200, 24, 8, 16, SEG_GRAPH } },
- /* VESA 2.0 modes */
- { 0x141, { MM_DIRECT, 640, 400, 32, 8, 16, SEG_GRAPH } },
- { 0x142, { MM_DIRECT, 640, 480, 32, 8, 16, SEG_GRAPH } },
- { 0x143, { MM_DIRECT, 800, 600, 32, 8, 16, SEG_GRAPH } },
- { 0x144, { MM_DIRECT, 1024, 768, 32, 8, 16, SEG_GRAPH } },
- { 0x145, { MM_DIRECT, 1280, 1024, 32, 8, 16, SEG_GRAPH } },
- { 0x147, { MM_DIRECT, 1600, 1200, 32, 8, 16, SEG_GRAPH } },
- { 0x149, { MM_DIRECT, 1152, 864, 15, 8, 16, SEG_GRAPH } },
- { 0x14a, { MM_DIRECT, 1152, 864, 16, 8, 16, SEG_GRAPH } },
- { 0x14b, { MM_DIRECT, 1152, 864, 24, 8, 16, SEG_GRAPH } },
- { 0x14c, { MM_DIRECT, 1152, 864, 32, 8, 16, SEG_GRAPH } },
- { 0x175, { MM_DIRECT, 1280, 768, 16, 8, 16, SEG_GRAPH } },
- { 0x176, { MM_DIRECT, 1280, 768, 24, 8, 16, SEG_GRAPH } },
- { 0x177, { MM_DIRECT, 1280, 768, 32, 8, 16, SEG_GRAPH } },
- { 0x178, { MM_DIRECT, 1280, 800, 16, 8, 16, SEG_GRAPH } },
- { 0x179, { MM_DIRECT, 1280, 800, 24, 8, 16, SEG_GRAPH } },
- { 0x17a, { MM_DIRECT, 1280, 800, 32, 8, 16, SEG_GRAPH } },
- { 0x17b, { MM_DIRECT, 1280, 960, 16, 8, 16, SEG_GRAPH } },
- { 0x17c, { MM_DIRECT, 1280, 960, 24, 8, 16, SEG_GRAPH } },
- { 0x17d, { MM_DIRECT, 1280, 960, 32, 8, 16, SEG_GRAPH } },
- { 0x17e, { MM_DIRECT, 1440, 900, 16, 8, 16, SEG_GRAPH } },
- { 0x17f, { MM_DIRECT, 1440, 900, 24, 8, 16, SEG_GRAPH } },
- { 0x180, { MM_DIRECT, 1440, 900, 32, 8, 16, SEG_GRAPH } },
- { 0x181, { MM_DIRECT, 1400, 1050, 16, 8, 16, SEG_GRAPH } },
- { 0x182, { MM_DIRECT, 1400, 1050, 24, 8, 16, SEG_GRAPH } },
- { 0x183, { MM_DIRECT, 1400, 1050, 32, 8, 16, SEG_GRAPH } },
- { 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 } },
- { 0x18d, { MM_DIRECT, 1280, 720, 16, 8, 16, SEG_GRAPH } },
- { 0x18e, { MM_DIRECT, 1280, 720, 24, 8, 16, SEG_GRAPH } },
- { 0x18f, { MM_DIRECT, 1280, 720, 32, 8, 16, SEG_GRAPH } },
- { 0x190, { MM_DIRECT, 1920, 1080, 16, 8, 16, SEG_GRAPH } },
- { 0x191, { MM_DIRECT, 1920, 1080, 24, 8, 16, SEG_GRAPH } },
- { 0x192, { MM_DIRECT, 1920, 1080, 32, 8, 16, SEG_GRAPH } },
+};
struct vgamode_s *cbvga_find_mode(int mode) {
- int i; /* Assume VGA compatible hardware in text-mode. */ if (GET_GLOBAL(CBmode) == 0x3) return stdvga_find_mode(mode);
@@ -28,16 +93,61 @@ struct vgamode_s *cbvga_find_mode(int mode) return &CBmodeinfo; if (mode == 0x03) return &CBemulinfo;
- /* Advertise compatible VESA VGA modes. */
- for (i = 0; i < ARRAY_SIZE(cbvesa_modes); i++) {
struct cbvga_mode_s *cbmode_g = &cbvesa_modes[i];
/* Skip VBE modes that doesn't fit into coreboot's framebuffer */
if (GET_GLOBAL(cbmode_g->info.height) > GET_GLOBAL(CBmodeinfo.height))
continue;
if (GET_GLOBAL(cbmode_g->info.width) > GET_GLOBAL(CBmodeinfo.width))
continue;
if (GET_GLOBAL(cbmode_g->info.depth) != GET_GLOBAL(CBmodeinfo.depth))
continue;
if (GET_GLOBAL(cbmode_g->mode) == mode)
return &cbmode_g->info;
- } return NULL;
}
void cbvga_list_modes(u16 seg, u16 *dest, u16 *last) {
int i;
u8 found = 0;
/* Assume VGA compatible hardware in text-mode. */ if (GET_GLOBAL(CBmode) == 0x3) { stdvga_list_modes(seg, dest, last);
} else {
/* Advertise additional SVGA modes for Microsoft NTLDR graphical mode.
* Microsoft NTLDR:
* * Graphical mode uses a maximum resolution of 1600x1200.
* * Expects to find VESA mode with 800x600 or 1024x768.
* * 24 Bpp and 32 Bpp are supported
*/
for (i = 0; i < ARRAY_SIZE(cbvesa_modes) && dest < last; i++) {
struct cbvga_mode_s *cbmode_g = &cbvesa_modes[i];
u16 mode = GET_GLOBAL(cbmode_g->mode);
/* Skip VBE modes that doesn't fit into coreboot's framebuffer */
if (GET_GLOBAL(cbmode_g->info.height) > GET_GLOBAL(CBmodeinfo.height))
continue;
if (GET_GLOBAL(cbmode_g->info.width) > GET_GLOBAL(CBmodeinfo.width))
continue;
/* Skip VBE modes with unsupported Bpp */
if (GET_GLOBAL(cbmode_g->info.depth) != GET_GLOBAL(CBmodeinfo.depth))
continue;
if ((GET_GLOBAL(cbmode_g->info.height) == GET_GLOBAL(CBmodeinfo.height)) &&
(GET_GLOBAL(cbmode_g->info.width) == GET_GLOBAL(CBmodeinfo.width)))
found = 1;
SET_FARVAR(seg, *dest, mode);
dest++;
}
if ((dest < last) && !found) {
SET_FARVAR(seg, *dest, GET_GLOBAL(CBmode));
dest++;
}
SET_FARVAR(seg, *dest, 0xffff);
}
}