Index: 2007-02-07/xen/drivers/video/vga.c =================================================================== --- 2007-02-07.orig/xen/drivers/video/vga.c 2007-01-15 09:10:11.000000000 +0100 +++ 2007-02-07/xen/drivers/video/vga.c 2007-02-07 16:31:41.000000000 +0100 @@ -556,7 +556,6 @@ static int vga_load_font(const struct fo */ static int vgacon_enabled = 0; -static int vgacon_keep = 0; static int vgacon_lines = 50; static const struct font_desc *font; @@ -576,13 +575,16 @@ string_param("vga", opt_vga); void vga_init(void) { char *p; + int keep = 0; for ( p = opt_vga; p != NULL; p = strchr(p, ',') ) { if ( *p == ',' ) p++; if ( strncmp(p, "keep", 4) == 0 ) - vgacon_keep = 1; + keep = 1; + else if ( strncmp(p, "yield", 5) == 0 ) + keep = -1; else if ( strncmp(p, "text-80x", 8) == 0 ) vgacon_lines = simple_strtoul(p + 8, NULL, 10); } @@ -621,21 +623,48 @@ void vga_init(void) /* Disable cursor. */ vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, 0x20); - vgacon_enabled = 1; + vgacon_enabled = 3 + keep; } void vga_endboot(void) { + static const char *const str[] = + { + "relinquishing", + "auto-sensing", + "keeping" + }; + if ( !vgacon_enabled ) return; - if ( !vgacon_keep ) - vgacon_enabled = 0; + vgacon_enabled -= 2; + BUG_ON(vgacon_enabled < 0 || vgacon_enabled > 2); - printk("Xen is %s VGA console.\n", - vgacon_keep ? "keeping" : "relinquishing"); + printk("Xen is %s VGA console.\n", str[vgacon_enabled]); } +static int gfx_vga(void) +{ + unsigned char idx, data; + + idx = vga_r(vgabase, VGA_GFX_I); + data = vga_rgfx(vgabase, VGA_GFX_MISC); + vga_w(vgabase, VGA_GFX_I, idx); + + if ( data & 0x01 ) + return 1; + + /* Unfortunately many cards don't reflect their mode in the GDC + * miscellaneous register, bit 0 (and even fewer reflect it in the + * ATC mode control register, bit 0). Therefore we further check + * horizontal display width against our original setting. */ + idx = vga_r(vgabase, VGA_CRT_IC); + data = vga_rcrt(vgabase, VGA_CRTC_H_DISP); + vga_w(vgabase, VGA_CRT_IC, idx); + + return data != COLUMNS - 1; +} static void put_newline(void) { @@ -653,14 +682,25 @@ static void put_newline(void) void vga_putchar(int c) { - if ( !vgacon_enabled ) + static int vga_in_gfx = -1; + + switch ( vgacon_enabled ) + { + case 0: return; + case 1: + if ( vga_in_gfx < 0 ) + vga_in_gfx = gfx_vga(); + break; + } if ( c == '\n' ) { - put_newline(); + if ( vga_in_gfx <= 0 ) + put_newline(); + vga_in_gfx = -1; } - else + else if ( vga_in_gfx <= 0 ) { if ( xpos >= COLUMNS ) put_newline();