From: Kevin O'Connor Date: Sat, 14 Jan 2012 03:08:52 +0000 (-0500) Subject: vgabios: Unify cirrus and vbe vesa functions. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=seabios.git;a=commitdiff_plain;h=643290fb1f9bca93084dd485c18397f2f7d3fdd7 vgabios: Unify cirrus and vbe vesa functions. Unify the code for the Cirrus and VBE vesa functions 00-03. Signed-off-by: Kevin O'Connor --- diff --git a/vgasrc/clext.c b/vgasrc/clext.c index 90f37c8..1736843 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -18,25 +18,6 @@ * tables ****************************************************************/ -struct cirrus_mode_s { - u16 mode; - struct vgamode_s info; - - u16 hidden_dac; /* 0x3c6 */ - u16 *seq; /* 0x3c4 */ - u16 *graph; /* 0x3ce */ - u16 *crtc; /* 0x3d4 */ - u8 bitsperpixel; - u8 vesaredmask; - u8 vesaredpos; - u8 vesagreenmask; - u8 vesagreenpos; - u8 vesabluemask; - u8 vesabluepos; - u8 vesareservedmask; - u8 vesareservedpos; -}; - /* VGA */ static u16 cseq_vga[] VAR16 = {0x0007,0xffff}; static u16 cgraph_vga[] VAR16 = {0x0009,0x000a,0x000b,0xffff}; @@ -233,74 +214,115 @@ static u16 ccrtc_1600x1200x8[] VAR16 = { 0xffff }; +struct cirrus_mode_s { + u16 mode; + struct vgamode_s info; + + u16 hidden_dac; /* 0x3c6 */ + u16 *seq; /* 0x3c4 */ + u16 *graph; /* 0x3ce */ + u16 *crtc; /* 0x3d4 */ +}; + static struct cirrus_mode_s cirrus_modes[] VAR16 = { {0x5f,{MM_PACKED,640,480,8},0x00, - cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, - 0,0,0,0,0,0,0,0}, + cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8}, {0x64,{MM_DIRECT,640,480,16},0xe1, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 5,11,6,5,5,0,0,0}, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16}, {0x66,{MM_DIRECT,640,480,15},0xf0, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 5,10,5,5,5,0,1,15}, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16}, {0x71,{MM_DIRECT,640,480,24},0xe5, - cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, - 8,16,8,8,8,0,0,0}, + cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24}, {0x5c,{MM_PACKED,800,600,8},0x00, - cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, - 0,0,0,0,0,0,0,0}, + cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8}, {0x65,{MM_DIRECT,800,600,16},0xe1, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 5,11,6,5,5,0,0,0}, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16}, {0x67,{MM_DIRECT,800,600,15},0xf0, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 5,10,5,5,5,0,1,15}, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16}, {0x60,{MM_PACKED,1024,768,8},0x00, - cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, - 0,0,0,0,0,0,0,0}, + cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8}, {0x74,{MM_DIRECT,1024,768,16},0xe1, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 5,11,6,5,5,0,0,0}, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16}, {0x68,{MM_DIRECT,1024,768,15},0xf0, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 5,10,5,5,5,0,1,15}, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16}, {0x78,{MM_DIRECT,800,600,24},0xe5, - cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, - 8,16,8,8,8,0,0,0}, + cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24}, {0x79,{MM_DIRECT,1024,768,24},0xe5, - cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, - 8,16,8,8,8,0,0,0}, + cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24}, {0x6d,{MM_PACKED,1280,1024,8},0x00, - cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, - 0,0,0,0,0,0,0,0}, + cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8}, {0x69,{MM_DIRECT,1280,1024,15},0xf0, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 5,10,5,5,5,0,1,15}, + cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16}, {0x75,{MM_DIRECT,1280,1024,16},0xe1, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 5,11,6,5,5,0,0,0}, + cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16}, {0x7b,{MM_PACKED,1600,1200,8},0x00, - cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, - 0,0,0,0,0,0,0,0}, + cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8}, }; static struct cirrus_mode_s mode_switchback VAR16 = - {0xfe,{0xff,0,0,0},0,cseq_vga,cgraph_vga,ccrtc_vga,0, - 0,0,0,0,0,0,0,0}; + {0xfe,{0xff},0,cseq_vga,cgraph_vga,ccrtc_vga}; + +static struct { + u16 vesamode, mode; +} cirrus_vesa_modelist[] VAR16 = { + // 640x480x8 + { 0x101, 0x5f }, + // 640x480x15 + { 0x110, 0x66 }, + // 640x480x16 + { 0x111, 0x64 }, + // 640x480x24 + { 0x112, 0x71 }, + // 800x600x8 + { 0x103, 0x5c }, + // 800x600x15 + { 0x113, 0x67 }, + // 800x600x16 + { 0x114, 0x65 }, + // 800x600x24 + { 0x115, 0x78 }, + // 1024x768x8 + { 0x105, 0x60 }, + // 1024x768x15 + { 0x116, 0x68 }, + // 1024x768x16 + { 0x117, 0x74 }, + // 1024x768x24 + { 0x118, 0x79 }, + // 1280x1024x8 + { 0x107, 0x6d }, + // 1280x1024x15 + { 0x119, 0x69 }, + // 1280x1024x16 + { 0x11a, 0x75 }, +}; /**************************************************************** * helper functions ****************************************************************/ +static u16 +cirrus_vesamode_to_mode(u16 vesamode) +{ + int i; + for (i=0; imode); @@ -404,9 +426,12 @@ clext_set_mode(int mode, int flags) struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); if (table_g) { cirrus_switch_mode(table_g); + if (!(flags & MF_LINEARFB)) + cirrus_enable_16k_granularity(); if (!(flags & MF_NOCLEARMEM)) - cirrus_clear_vram(0xffff); + cirrus_clear_vram(0); SET_BDA(video_mode, mode); + SET_BDA(vbe_mode, mode | flags); return 0; } cirrus_switch_mode(&mode_switchback); @@ -531,41 +556,6 @@ cirrus_extbios(struct bregs *regs) * vesa calls ****************************************************************/ -static struct { - u16 vesamode, mode; -} cirrus_vesa_modelist[] VAR16 = { - // 640x480x8 - { 0x101, 0x5f }, - // 640x480x15 - { 0x110, 0x66 }, - // 640x480x16 - { 0x111, 0x64 }, - // 640x480x24 - { 0x112, 0x71 }, - // 800x600x8 - { 0x103, 0x5c }, - // 800x600x15 - { 0x113, 0x67 }, - // 800x600x16 - { 0x114, 0x65 }, - // 800x600x24 - { 0x115, 0x78 }, - // 1024x768x8 - { 0x105, 0x60 }, - // 1024x768x15 - { 0x116, 0x68 }, - // 1024x768x16 - { 0x117, 0x74 }, - // 1024x768x24 - { 0x118, 0x79 }, - // 1280x1024x8 - { 0x107, 0x6d }, - // 1280x1024x15 - { 0x119, 0x69 }, - // 1280x1024x16 - { 0x11a, 0x75 }, -}; - void clext_list_modes(u16 seg, u16 *dest, u16 *last) { @@ -577,16 +567,6 @@ clext_list_modes(u16 seg, u16 *dest, u16 *last) stdvga_list_modes(seg, dest, last); } -static u16 -cirrus_vesamode_to_mode(u16 vesamode) -{ - int i; - for (i=0; icrtc); @@ -692,144 +672,6 @@ cirrus_get_start_addr(void) | ((b4 & 0x80) << 12)); } -static void -cirrus_vesa_00h(struct bregs *regs) -{ - u16 seg = regs->es; - struct vbe_info *info = (void*)(regs->di+0); - - if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { - SET_FARVAR(seg, info->oem_revision, 0x0100); - SET_FARVAR(seg, info->oem_vendor_string, - SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); - SET_FARVAR(seg, info->oem_product_string, - SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); - SET_FARVAR(seg, info->oem_revision_string, - SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); - } - SET_FARVAR(seg, info->signature, VESA_SIGNATURE); - - SET_FARVAR(seg, info->version, 0x0200); - - SET_FARVAR(seg, info->oem_string - , SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); - SET_FARVAR(seg, info->capabilities, 0); - SET_FARVAR(seg, info->total_memory, cirrus_get_memsize()); - - u16 *destmode = (void*)info->reserved; - u16 *last = (void*)&info->reserved[sizeof(info->reserved)]; - SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode)); - clext_list_modes(seg, destmode, last); - - regs->ax = 0x004f; -} - -static u32 cirrus_lfb_addr VAR16; - -static void -cirrus_vesa_01h(struct bregs *regs) -{ - u16 mode = cirrus_vesamode_to_mode(regs->cx & 0x3fff); - if (!mode) { - regs->ax = 0x014f; - return; - } - struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); - u32 lfb = GET_GLOBAL(cirrus_lfb_addr); // XXX - if ((regs->cx & 0x4000) && !lfb) { - regs->ax = 0x014f; - return; - } - - u16 seg = regs->es; - struct vbe_mode_info *info = (void*)(regs->di+0); - memset_far(seg, info, 0, sizeof(*info)); - - SET_FARVAR(seg, info->mode_attributes, lfb ? 0xbb : 0x3b); - SET_FARVAR(seg, info->winA_attributes, 0x07); - SET_FARVAR(seg, info->winB_attributes, 0); - SET_FARVAR(seg, info->win_granularity, 16); - SET_FARVAR(seg, info->win_size, 64); - SET_FARVAR(seg, info->winA_seg, SEG_GRAPH); - SET_FARVAR(seg, info->winB_seg, 0x0); - SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); // XXX - u16 linesize = cirrus_get_line_offset_entry(table_g); - SET_FARVAR(seg, info->bytes_per_scanline, linesize); - SET_FARVAR(seg, info->xres, GET_GLOBAL(table_g->info.width)); - u16 height = GET_GLOBAL(table_g->info.height); - SET_FARVAR(seg, info->yres, height); - SET_FARVAR(seg, info->xcharsize, 8); - SET_FARVAR(seg, info->ycharsize, 16); - SET_FARVAR(seg, info->planes, 1); - SET_FARVAR(seg, info->bits_per_pixel, GET_GLOBAL(table_g->info.depth)); - SET_FARVAR(seg, info->banks, 1); - SET_FARVAR(seg, info->mem_model, GET_GLOBAL(table_g->info.memmodel)); - SET_FARVAR(seg, info->bank_size, 0); - - int pages = (cirrus_get_memsize() * 64 * 1024) / (height * linesize); - SET_FARVAR(seg, info->pages, pages - 1); - SET_FARVAR(seg, info->reserved0, 0); - - SET_FARVAR(seg, info->red_size, GET_GLOBAL(table_g->vesaredmask)); - SET_FARVAR(seg, info->red_pos, GET_GLOBAL(table_g->vesaredpos)); - SET_FARVAR(seg, info->green_size, GET_GLOBAL(table_g->vesagreenmask)); - SET_FARVAR(seg, info->green_pos, GET_GLOBAL(table_g->vesagreenpos)); - SET_FARVAR(seg, info->blue_size, GET_GLOBAL(table_g->vesabluemask)); - SET_FARVAR(seg, info->blue_pos, GET_GLOBAL(table_g->vesabluepos)); - SET_FARVAR(seg, info->alpha_size, GET_GLOBAL(table_g->vesareservedmask)); - SET_FARVAR(seg, info->alpha_pos, GET_GLOBAL(table_g->vesareservedpos)); - u8 directcolor_info = GET_GLOBAL(table_g->bitsperpixel) <= 8; - SET_FARVAR(seg, info->directcolor_info, directcolor_info); - - SET_FARVAR(seg, info->phys_base, lfb); - - regs->ax = 0x004f; -} - -static void -cirrus_vesa_02h(struct bregs *regs) -{ - if (regs->bx & 0x3e00) { - regs->ax = 0x014f; - return; - } - if ((regs->bx & 0x1ff) < 0x100) { - // XXX - call legacy mode switch - regs->ax = 0x004f; - return; - } - - u16 mode = cirrus_vesamode_to_mode(regs->cx & 0x3fff); - if (!mode) { - regs->ax = 0x014f; - return; - } - struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode); - cirrus_switch_mode(table_g); - - if (!(regs->bx & 0x4000)) - cirrus_enable_16k_granularity(); - if (!(regs->bx & 0x8000)) - cirrus_clear_vram(0); - SET_BDA(video_mode, mode); - SET_BDA(vbe_mode, regs->bx); - - regs->ax = 0x004f; -} - -static void -cirrus_vesa_03h(struct bregs *regs) -{ - u16 mode = GET_BDA(vbe_mode); - if (!mode) - mode = GET_BDA(video_mode); - regs->bx = mode; - - regs->ax = 0x004f; -} - -// XXX - add cirrus_vesa_05h_farentry to vgaentry.S - static void cirrus_vesa_05h(struct bregs *regs) { @@ -926,10 +768,6 @@ void cirrus_vesa(struct bregs *regs) { switch (regs->al) { - case 0x00: cirrus_vesa_00h(regs); break; - case 0x01: cirrus_vesa_01h(regs); break; - case 0x02: cirrus_vesa_02h(regs); break; - case 0x03: cirrus_vesa_03h(regs); break; case 0x05: cirrus_vesa_05h(regs); break; case 0x06: cirrus_vesa_06h(regs); break; case 0x07: cirrus_vesa_07h(regs); break; @@ -955,6 +793,10 @@ clext_init(void) return -1; dprintf(1, "cirrus init 2\n"); + u16 totalmem = cirrus_get_memsize(); + SET_VGA(VBE_total_memory, totalmem * 64 * 1024); + SET_VGA(VBE_win_granularity, 16); + // memory setup outb(0x0f, VGAREG_SEQU_ADDRESS); u8 v = inb(VGAREG_SEQU_DATA); diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index d764a0c..ee80e97 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -17,6 +17,7 @@ int VBE_enabled VAR16; u32 VBE_total_memory VAR16 = 256 * 1024; u32 VBE_capabilities VAR16; u32 VBE_framebuffer VAR16; +u16 VBE_win_granularity VAR16 = 64; static void vbe_104f00(struct bregs *regs) @@ -80,14 +81,17 @@ vbe_104f01(struct bregs *regs) return; } + memset_far(seg, info, 0, sizeof(*info)); u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED | VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | VBE_MODE_ATTRIBUTE_COLOR_MODE | - VBE_MODE_ATTRIBUTE_GRAPHICS_MODE; + VBE_MODE_ATTRIBUTE_GRAPHICS_MODE | + VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE; + u32 framebuffer = GET_GLOBAL(VBE_framebuffer); int depth = GET_GLOBAL(vmode_g->depth); if (depth == 4) mode_attr |= VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT; - else + else if (framebuffer) mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; SET_FARVAR(seg, info->mode_attributes, mode_attr); SET_FARVAR(seg, info->winA_attributes, @@ -95,9 +99,9 @@ vbe_104f01(struct bregs *regs) VBE_WINDOW_ATTRIBUTE_READABLE | VBE_WINDOW_ATTRIBUTE_WRITEABLE); SET_FARVAR(seg, info->winB_attributes, 0); - SET_FARVAR(seg, info->win_granularity, 64); /* Bank size 64K */ + SET_FARVAR(seg, info->win_granularity, GET_GLOBAL(VBE_win_granularity)); SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ - SET_FARVAR(seg, info->winA_seg, 0xA000); + SET_FARVAR(seg, info->winA_seg, SEG_GRAPH); SET_FARVAR(seg, info->winB_seg, 0x0); SET_FARVAR(seg, info->win_func_ptr.segoff, 0x0); int width = GET_GLOBAL(vmode_g->width); @@ -113,13 +117,8 @@ vbe_104f01(struct bregs *regs) else SET_FARVAR(seg, info->planes, 1); SET_FARVAR(seg, info->bits_per_pixel, depth); - SET_FARVAR(seg, info->banks, DIV_ROUND_UP(linesize * height, 64*1024)); - if (depth == 4) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PLANAR); - else if (depth == 8) - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_PACKED_PIXEL); - else - SET_FARVAR(seg, info->mem_model, VBE_MEMORYMODEL_DIRECT_COLOR); + SET_FARVAR(seg, info->banks, 1); + SET_FARVAR(seg, info->mem_model, GET_GLOBAL(vmode_g->memmodel)); SET_FARVAR(seg, info->bank_size, 0); u32 pages = GET_GLOBAL(VBE_total_memory) / (height * linesize); if (depth == 4) diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h index 464100b..d0af248 100644 --- a/vgasrc/vgabios.h +++ b/vgasrc/vgabios.h @@ -87,6 +87,7 @@ int VBE_enabled; u32 VBE_total_memory; u32 VBE_capabilities; u32 VBE_framebuffer; +u16 VBE_win_granularity; #define VBE_OEM_STRING "SeaBIOS VBE(C) 2011" #define VBE_VENDOR_STRING "SeaBIOS Developers" #define VBE_PRODUCT_STRING "SeaBIOS VBE Adapter"