Date: Fri, 23 Oct 2009 18:41:00 +0000 (UTC) From: Jung-uk Kim <jkim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r198419 - head/sys/dev/fb Message-ID: <200910231841.n9NIf0L5069062@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jkim Date: Fri Oct 23 18:41:00 2009 New Revision: 198419 URL: http://svn.freebsd.org/changeset/base/198419 Log: - When we restore VESA state, try BIOS POST earlier. VESA restore state function may not work properly if we don't. Turn off hardware cursor as vesa_set_mode() does. - Add VBE 3.0 specific fields in VESA mode structure and pack it. Note the padding is 190 bytes although VBE 3.0 says 189 bytes. It must be wrong because the size of structure becomes 255 bytes and the specification says it must be 256 bytes in total. In fact, an example code in the spec. does it right, though. While we are at it, fix some i386-isms. - Remove state buffer size limitation. It is no longer necessary since sys/compat/x86bios/x86bios.c r198251. - Move int 0x10 vector test into vesa_bios_post() as we always do it anyway. Modified: head/sys/dev/fb/vesa.c head/sys/dev/fb/vesa.h Modified: head/sys/dev/fb/vesa.c ============================================================================== --- head/sys/dev/fb/vesa.c Fri Oct 23 18:27:34 2009 (r198418) +++ head/sys/dev/fb/vesa.c Fri Oct 23 18:41:00 2009 (r198419) @@ -74,8 +74,7 @@ typedef struct adp_state adp_state_t; /* VESA video adapter */ static video_adapter_t *vesa_adp = NULL; -static int vesa_state_buf_size = 0; -#define VESA_BIOS_BUFSIZE (3 * PAGE_SIZE) +static ssize_t vesa_state_buf_size = -1; /* VESA functions */ #if 0 @@ -188,7 +187,7 @@ static int vesa_bios_load_palette2(int s #define STATE_REG (1<<3) #define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG) #define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG) -static int vesa_bios_state_buf_size(void); +static ssize_t vesa_bios_state_buf_size(void); static int vesa_bios_save_restore(int code, void *p, size_t size); static int vesa_bios_get_line_length(void); static int vesa_bios_set_line_length(int pixel, int *bytes, int *lines); @@ -282,6 +281,10 @@ vesa_bios_post(void) } regs.R_DL = 0x80; x86bios_call(®s, 0xc000, 0x0003); + + if (x86bios_get_intr(0x10) == 0) + return (1); + return (0); } @@ -532,7 +535,7 @@ vesa_bios_load_palette2(int start, int c } #endif -static int +static ssize_t vesa_bios_state_buf_size(void) { x86regs_t regs; @@ -557,9 +560,6 @@ vesa_bios_save_restore(int code, void *p uint32_t offs; void *buf; - if (size > VESA_BIOS_BUFSIZE) - return (1); - if (code != STATE_SAVE && code != STATE_LOAD) return (1); @@ -808,12 +808,11 @@ vesa_bios_init(void) if (x86bios_get_intr(0x10) == 0) { if (vesa_bios_post() != 0) return (1); - offs = x86bios_get_intr(0x10); - if (offs == 0) - return (1); - if (bootverbose) + if (bootverbose) { + offs = x86bios_get_intr(0x10); printf("VESA: interrupt vector installed (0x%x)\n", BIOS_SADDRTOLADDR(offs)); + } } x86bios_init_regs(®s); @@ -879,6 +878,22 @@ vesa_bios_init(void) if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) continue; + vmode.v_modeattr = le16toh(vmode.v_modeattr); + vmode.v_wgran = le16toh(vmode.v_wgran); + vmode.v_wsize = le16toh(vmode.v_wsize); + vmode.v_waseg = le16toh(vmode.v_waseg); + vmode.v_wbseg = le16toh(vmode.v_wbseg); + vmode.v_posfunc = le32toh(vmode.v_posfunc); + vmode.v_bpscanline = le16toh(vmode.v_bpscanline); + vmode.v_width = le16toh(vmode.v_width); + vmode.v_height = le16toh(vmode.v_height); + vmode.v_lfb = le32toh(vmode.v_lfb); + vmode.v_offscreen = le32toh(vmode.v_offscreen); + vmode.v_offscreensize = le16toh(vmode.v_offscreensize); + vmode.v_maxpixelclock = le32toh(vmode.v_maxpixelclock); + vmode.v_linbpscanline = le16toh(vmode.v_linbpscanline); + vmode.v_maxpixelclock = le32toh(vmode.v_maxpixelclock); + /* reject unsupported modes */ #if 0 if ((vmode.v_modeattr & (V_MODESUPP | V_MODEOPTINFO @@ -1417,11 +1432,14 @@ vesa_save_state(video_adapter_t *adp, vo if (adp != vesa_adp) return ((*prevvidsw->save_state)(adp, p, size)); - if (vesa_state_buf_size == 0) + if (vesa_state_buf_size == -1) { vesa_state_buf_size = vesa_bios_state_buf_size(); + if (vesa_state_buf_size == 0) + return (1); + } if (size == 0) - return (sizeof(int) + vesa_state_buf_size); - else if (size < (sizeof(int) + vesa_state_buf_size)) + return (offsetof(adp_state_t, regs) + vesa_state_buf_size); + else if (size < (offsetof(adp_state_t, regs) + vesa_state_buf_size)) return (1); ((adp_state_t *)p)->sig = V_STATE_SIG; @@ -1438,22 +1456,36 @@ vesa_load_state(video_adapter_t *adp, vo if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG)) return ((*prevvidsw->load_state)(adp, p)); + if (vesa_state_buf_size <= 0) + return (1); + + /* + * If the current mode is not the same, probably it was powered down. + * Try BIOS POST to restore a sane state. + */ + mode = vesa_bios_get_current_mode(); + if (mode >= 0 && (mode & 0x1ff) != adp->va_mode && + VESA_MODE(adp->va_mode)) + (void)vesa_bios_post(); + ret = vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, vesa_state_buf_size); /* - * If the current mode is not restored properly, try BIOS POST and - * force setting the mode. + * If the desired mode is not restored, force setting the mode. */ - flags = adp->va_info.vi_flags; - if (!(flags & V_INFO_GRAPHICS)) - flags &= ~V_INFO_LINEAR; - mode = adp->va_mode | ((flags & V_INFO_LINEAR) ? 0x4000 : 0); - if (vesa_bios_get_current_mode() != mode && vesa_bios_post() == 0 && - x86bios_get_intr(0x10) != 0) { - int10_set_mode(adp->va_initial_bios_mode); - vesa_bios_set_mode(mode); + mode = vesa_bios_get_current_mode(); + if (mode >= 0 && (mode & 0x1ff) != adp->va_mode && + VESA_MODE(adp->va_mode)) { + mode = adp->va_mode; + flags = adp->va_info.vi_flags; + if ((flags & V_INFO_GRAPHICS) != 0 && + (flags & V_INFO_LINEAR) != 0) + mode |= 0x4000; + (void)vesa_bios_set_mode(mode); + (void)(*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); } + return (ret); } Modified: head/sys/dev/fb/vesa.h ============================================================================== --- head/sys/dev/fb/vesa.h Fri Oct 23 18:27:34 2009 (r198418) +++ head/sys/dev/fb/vesa.h Fri Oct 23 18:41:00 2009 (r198419) @@ -108,7 +108,21 @@ struct vesa_mode u_int32_t v_lfb; u_int32_t v_offscreen; u_int16_t v_offscreensize; -}; + /* 3.0 implementations */ + u_int16_t v_linbpscanline; + u_int8_t v_bankipages; + u_int8_t v_linipages; + u_int8_t v_linredmasksize; + u_int8_t v_linredfieldpos; + u_int8_t v_lingreenmasksize; + u_int8_t v_lingreenfieldpos; + u_int8_t v_linbluemasksize; + u_int8_t v_linbluefieldpos; + u_int8_t v_linresmasksize; + u_int8_t v_linresfieldpos; + u_int32_t v_maxpixelclock; + u_int8_t v_reserved1[190]; +} __packed; #ifdef _KERNEL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910231841.n9NIf0L5069062>