1/*- 2 * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 *
| 1/*- 2 * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 *
|
29 * $Id$
| 29 * $Id: vesa.c,v 1.1 1998/09/15 18:16:38 sos Exp $
|
30 */ 31 32#include "sc.h" 33#include "opt_vesa.h" 34#include "opt_vm86.h" 35 36#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE) 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/kernel.h> 41#include <sys/malloc.h> 42#include <vm/vm.h> 43#include <vm/pmap.h> 44 45#include <machine/console.h> 46#include <machine/md_var.h> 47#include <machine/vm86.h> 48#include <machine/pc/bios.h> 49#include <machine/pc/vesa.h> 50 51#include <i386/isa/videoio.h> 52 53#ifdef VESA_MODULE 54#include <sys/exec.h> 55#include <sys/sysent.h> 56#include <sys/lkm.h> 57 58MOD_MISC(vesa); 59#endif 60 61/* VESA video adapter state buffer stub */ 62struct adp_state { 63 int sig; 64#define V_STATE_SIG 0x61736576 65 u_char regs[1]; 66}; 67typedef struct adp_state adp_state_t; 68 69/* VESA video adapter */ 70static video_adapter_t *vesa_adp = NULL; 71static int vesa_state_buf_size = 0; 72static void *vesa_state_buf = NULL; 73 74/* VESA functions */ 75static vi_init_t vesa_init; 76static vi_adapter_t vesa_adapter; 77static vi_get_info_t vesa_get_info; 78static vi_query_mode_t vesa_query_mode; 79static vi_set_mode_t vesa_set_mode; 80static vi_save_font_t vesa_save_font; 81static vi_load_font_t vesa_load_font; 82static vi_show_font_t vesa_show_font; 83static vi_save_palette_t vesa_save_palette; 84static vi_load_palette_t vesa_load_palette; 85static vi_set_border_t vesa_set_border; 86static vi_save_state_t vesa_save_state; 87static vi_load_state_t vesa_load_state; 88static vi_set_win_org_t vesa_set_origin; 89static vi_read_hw_cursor_t vesa_read_hw_cursor; 90static vi_set_hw_cursor_t vesa_set_hw_cursor; 91static vi_diag_t vesa_diag; 92 93static struct vidsw vesavidsw = { 94 vesa_init, vesa_adapter, vesa_get_info, vesa_query_mode, 95 vesa_set_mode, vesa_save_font, vesa_load_font, vesa_show_font, 96 vesa_save_palette,vesa_load_palette,vesa_set_border,vesa_save_state, 97 vesa_load_state,vesa_set_origin,vesa_read_hw_cursor,vesa_set_hw_cursor, 98 vesa_diag, 99}; 100 101static struct vidsw prevvidsw; 102 103/* VESA BIOS video modes */ 104#define VESA_MAXMODES 64 105#define EOT (-1) 106#define NA (-2) 107 108static video_info_t vesa_vmode[VESA_MAXMODES + 1] = { 109 { EOT, }, 110}; 111 112static int vesa_init_done = FALSE; 113static int has_vesa_bios = FALSE; 114static struct vesa_info *vesa_adp_info = NULL; 115static u_int16_t *vesa_vmodetab = NULL; 116 117/* local macros and functions */ 118#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) 119 120static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode); 121static int vesa_bios_set_mode(int mode); 122static int vesa_bios_set_dac(int bits); 123static int vesa_bios_save_palette(int start, int colors, u_char *palette); 124static int vesa_bios_load_palette(int start, int colors, u_char *palette); 125#define STATE_SIZE 0 126#define STATE_SAVE 1 127#define STATE_LOAD 2 128#define STATE_HW (1<<0) 129#define STATE_DATA (1<<1) 130#define STATE_DAC (1<<2) 131#define STATE_REG (1<<3) 132#define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG) 133#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG) 134static int vesa_bios_state_buf_size(void); 135static int vesa_bios_save_restore(int code, void *p, size_t size);
| 30 */ 31 32#include "sc.h" 33#include "opt_vesa.h" 34#include "opt_vm86.h" 35 36#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE) 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/kernel.h> 41#include <sys/malloc.h> 42#include <vm/vm.h> 43#include <vm/pmap.h> 44 45#include <machine/console.h> 46#include <machine/md_var.h> 47#include <machine/vm86.h> 48#include <machine/pc/bios.h> 49#include <machine/pc/vesa.h> 50 51#include <i386/isa/videoio.h> 52 53#ifdef VESA_MODULE 54#include <sys/exec.h> 55#include <sys/sysent.h> 56#include <sys/lkm.h> 57 58MOD_MISC(vesa); 59#endif 60 61/* VESA video adapter state buffer stub */ 62struct adp_state { 63 int sig; 64#define V_STATE_SIG 0x61736576 65 u_char regs[1]; 66}; 67typedef struct adp_state adp_state_t; 68 69/* VESA video adapter */ 70static video_adapter_t *vesa_adp = NULL; 71static int vesa_state_buf_size = 0; 72static void *vesa_state_buf = NULL; 73 74/* VESA functions */ 75static vi_init_t vesa_init; 76static vi_adapter_t vesa_adapter; 77static vi_get_info_t vesa_get_info; 78static vi_query_mode_t vesa_query_mode; 79static vi_set_mode_t vesa_set_mode; 80static vi_save_font_t vesa_save_font; 81static vi_load_font_t vesa_load_font; 82static vi_show_font_t vesa_show_font; 83static vi_save_palette_t vesa_save_palette; 84static vi_load_palette_t vesa_load_palette; 85static vi_set_border_t vesa_set_border; 86static vi_save_state_t vesa_save_state; 87static vi_load_state_t vesa_load_state; 88static vi_set_win_org_t vesa_set_origin; 89static vi_read_hw_cursor_t vesa_read_hw_cursor; 90static vi_set_hw_cursor_t vesa_set_hw_cursor; 91static vi_diag_t vesa_diag; 92 93static struct vidsw vesavidsw = { 94 vesa_init, vesa_adapter, vesa_get_info, vesa_query_mode, 95 vesa_set_mode, vesa_save_font, vesa_load_font, vesa_show_font, 96 vesa_save_palette,vesa_load_palette,vesa_set_border,vesa_save_state, 97 vesa_load_state,vesa_set_origin,vesa_read_hw_cursor,vesa_set_hw_cursor, 98 vesa_diag, 99}; 100 101static struct vidsw prevvidsw; 102 103/* VESA BIOS video modes */ 104#define VESA_MAXMODES 64 105#define EOT (-1) 106#define NA (-2) 107 108static video_info_t vesa_vmode[VESA_MAXMODES + 1] = { 109 { EOT, }, 110}; 111 112static int vesa_init_done = FALSE; 113static int has_vesa_bios = FALSE; 114static struct vesa_info *vesa_adp_info = NULL; 115static u_int16_t *vesa_vmodetab = NULL; 116 117/* local macros and functions */ 118#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) 119 120static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode); 121static int vesa_bios_set_mode(int mode); 122static int vesa_bios_set_dac(int bits); 123static int vesa_bios_save_palette(int start, int colors, u_char *palette); 124static int vesa_bios_load_palette(int start, int colors, u_char *palette); 125#define STATE_SIZE 0 126#define STATE_SAVE 1 127#define STATE_LOAD 2 128#define STATE_HW (1<<0) 129#define STATE_DATA (1<<1) 130#define STATE_DAC (1<<2) 131#define STATE_REG (1<<3) 132#define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG) 133#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG) 134static int vesa_bios_state_buf_size(void); 135static int vesa_bios_save_restore(int code, void *p, size_t size);
|
136static int translate_flags(u_int16_t vflags);
| 136static int vesa_map_gen_mode_num(int type, int color, int mode); 137static int vesa_translate_flags(u_int16_t vflags);
|
137static int vesa_bios_init(void);
| 138static int vesa_bios_init(void);
|
138static void clear_modes(video_info_t *info, int color);
| 139static void vesa_clear_modes(video_info_t *info, int color);
|
139 140static void 141dump_buffer(u_char *buf, size_t len) 142{ 143 int i; 144 145 for(i = 0; i < len;) { 146 printf("%02x ", buf[i]); 147 if ((++i % 16) == 0) 148 printf("\n"); 149 } 150} 151 152/* VESA BIOS calls */ 153static int 154vesa_bios_get_mode(int mode, struct vesa_mode *vmode) 155{ 156 struct vm86frame vmf; 157 u_char buf[256]; 158 int err; 159 160 bzero(&vmf, sizeof(vmf)); 161 bzero(buf, sizeof(buf)); 162 vmf.vmf_eax = 0x4f01; 163 vmf.vmf_ecx = mode; 164 err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf), 165 &vmf.vmf_es, &vmf.vmf_di); 166 if ((err != 0) || (vmf.vmf_eax != 0x4f)) 167 return 1; 168 bcopy(buf, vmode, sizeof(*vmode)); 169 return 0; 170} 171 172static int 173vesa_bios_set_mode(int mode) 174{ 175 struct vm86frame vmf; 176 int err; 177 178 bzero(&vmf, sizeof(vmf)); 179 vmf.vmf_eax = 0x4f02; 180 vmf.vmf_ebx = mode; 181 err = vm86_intcall(0x10, &vmf); 182 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 183} 184 185static int 186vesa_bios_set_dac(int bits) 187{ 188 struct vm86frame vmf; 189 int err; 190 191 bzero(&vmf, sizeof(vmf)); 192 vmf.vmf_eax = 0x4f08; 193 vmf.vmf_ebx = (bits << 8); 194 err = vm86_intcall(0x10, &vmf); 195 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 196} 197 198static int 199vesa_bios_save_palette(int start, int colors, u_char *palette) 200{ 201 struct vm86frame vmf; 202 u_char *p; 203 int err; 204 int i; 205 206 p = malloc(colors*4, M_DEVBUF, M_WAITOK); 207 208 bzero(&vmf, sizeof(vmf)); 209 vmf.vmf_eax = 0x4f09; 210 vmf.vmf_ebx = 1; /* get primary palette data */ 211 vmf.vmf_ecx = colors; 212 vmf.vmf_edx = start; 213 err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di); 214 if ((err != 0) || (vmf.vmf_eax != 0x4f)) { 215 free(p, M_DEVBUF); 216 return 1; 217 } 218 219 for (i = 0; i < colors; ++i) { 220 palette[i*3] = p[i*4 + 1]; 221 palette[i*3 + 1] = p[i*4 + 2]; 222 palette[i*3 + 2] = p[i*4 + 3]; 223 } 224 free(p, M_DEVBUF); 225 return 0; 226} 227 228static int 229vesa_bios_load_palette(int start, int colors, u_char *palette) 230{ 231 struct vm86frame vmf; 232 u_char *p; 233 int err; 234 int i; 235 236 p = malloc(colors*4, M_DEVBUF, M_WAITOK); 237 for (i = 0; i < colors; ++i) { 238 p[i*4] = 0; 239 p[i*4 + 1] = palette[i*3]; 240 p[i*4 + 2] = palette[i*3 + 1]; 241 p[i*4 + 3] = palette[i*3 + 2]; 242 } 243 244 bzero(&vmf, sizeof(vmf)); 245 vmf.vmf_eax = 0x4f09; 246 vmf.vmf_ebx = 0; /* set primary palette data */ 247 vmf.vmf_ecx = colors; 248 vmf.vmf_edx = start; 249 err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di); 250 free(p, M_DEVBUF); 251 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 252} 253 254static int 255vesa_bios_state_buf_size(void) 256{ 257 struct vm86frame vmf; 258 int err; 259 260 bzero(&vmf, sizeof(vmf)); 261 vmf.vmf_eax = 0x4f04; 262 vmf.vmf_ecx = STATE_MOST; 263 vmf.vmf_edx = STATE_SIZE; 264 err = vm86_intcall(0x10, &vmf); 265 if ((err != 0) || (vmf.vmf_eax != 0x4f)) 266 return 0; 267 return vmf.vmf_ebx*64; 268} 269 270static int 271vesa_bios_save_restore(int code, void *p, size_t size) 272{ 273 struct vm86frame vmf; 274 int err; 275 276 bzero(&vmf, sizeof(vmf)); 277 vmf.vmf_eax = 0x4f04; 278 vmf.vmf_ecx = STATE_MOST; 279 vmf.vmf_edx = code; /* STATE_SAVE/STATE_LOAD */ 280 err = vm86_datacall(0x10, &vmf, (char *)p, size, 281 &vmf.vmf_es, &vmf.vmf_bx); 282 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 283} 284
| 140 141static void 142dump_buffer(u_char *buf, size_t len) 143{ 144 int i; 145 146 for(i = 0; i < len;) { 147 printf("%02x ", buf[i]); 148 if ((++i % 16) == 0) 149 printf("\n"); 150 } 151} 152 153/* VESA BIOS calls */ 154static int 155vesa_bios_get_mode(int mode, struct vesa_mode *vmode) 156{ 157 struct vm86frame vmf; 158 u_char buf[256]; 159 int err; 160 161 bzero(&vmf, sizeof(vmf)); 162 bzero(buf, sizeof(buf)); 163 vmf.vmf_eax = 0x4f01; 164 vmf.vmf_ecx = mode; 165 err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf), 166 &vmf.vmf_es, &vmf.vmf_di); 167 if ((err != 0) || (vmf.vmf_eax != 0x4f)) 168 return 1; 169 bcopy(buf, vmode, sizeof(*vmode)); 170 return 0; 171} 172 173static int 174vesa_bios_set_mode(int mode) 175{ 176 struct vm86frame vmf; 177 int err; 178 179 bzero(&vmf, sizeof(vmf)); 180 vmf.vmf_eax = 0x4f02; 181 vmf.vmf_ebx = mode; 182 err = vm86_intcall(0x10, &vmf); 183 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 184} 185 186static int 187vesa_bios_set_dac(int bits) 188{ 189 struct vm86frame vmf; 190 int err; 191 192 bzero(&vmf, sizeof(vmf)); 193 vmf.vmf_eax = 0x4f08; 194 vmf.vmf_ebx = (bits << 8); 195 err = vm86_intcall(0x10, &vmf); 196 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 197} 198 199static int 200vesa_bios_save_palette(int start, int colors, u_char *palette) 201{ 202 struct vm86frame vmf; 203 u_char *p; 204 int err; 205 int i; 206 207 p = malloc(colors*4, M_DEVBUF, M_WAITOK); 208 209 bzero(&vmf, sizeof(vmf)); 210 vmf.vmf_eax = 0x4f09; 211 vmf.vmf_ebx = 1; /* get primary palette data */ 212 vmf.vmf_ecx = colors; 213 vmf.vmf_edx = start; 214 err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di); 215 if ((err != 0) || (vmf.vmf_eax != 0x4f)) { 216 free(p, M_DEVBUF); 217 return 1; 218 } 219 220 for (i = 0; i < colors; ++i) { 221 palette[i*3] = p[i*4 + 1]; 222 palette[i*3 + 1] = p[i*4 + 2]; 223 palette[i*3 + 2] = p[i*4 + 3]; 224 } 225 free(p, M_DEVBUF); 226 return 0; 227} 228 229static int 230vesa_bios_load_palette(int start, int colors, u_char *palette) 231{ 232 struct vm86frame vmf; 233 u_char *p; 234 int err; 235 int i; 236 237 p = malloc(colors*4, M_DEVBUF, M_WAITOK); 238 for (i = 0; i < colors; ++i) { 239 p[i*4] = 0; 240 p[i*4 + 1] = palette[i*3]; 241 p[i*4 + 2] = palette[i*3 + 1]; 242 p[i*4 + 3] = palette[i*3 + 2]; 243 } 244 245 bzero(&vmf, sizeof(vmf)); 246 vmf.vmf_eax = 0x4f09; 247 vmf.vmf_ebx = 0; /* set primary palette data */ 248 vmf.vmf_ecx = colors; 249 vmf.vmf_edx = start; 250 err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di); 251 free(p, M_DEVBUF); 252 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 253} 254 255static int 256vesa_bios_state_buf_size(void) 257{ 258 struct vm86frame vmf; 259 int err; 260 261 bzero(&vmf, sizeof(vmf)); 262 vmf.vmf_eax = 0x4f04; 263 vmf.vmf_ecx = STATE_MOST; 264 vmf.vmf_edx = STATE_SIZE; 265 err = vm86_intcall(0x10, &vmf); 266 if ((err != 0) || (vmf.vmf_eax != 0x4f)) 267 return 0; 268 return vmf.vmf_ebx*64; 269} 270 271static int 272vesa_bios_save_restore(int code, void *p, size_t size) 273{ 274 struct vm86frame vmf; 275 int err; 276 277 bzero(&vmf, sizeof(vmf)); 278 vmf.vmf_eax = 0x4f04; 279 vmf.vmf_ecx = STATE_MOST; 280 vmf.vmf_edx = code; /* STATE_SAVE/STATE_LOAD */ 281 err = vm86_datacall(0x10, &vmf, (char *)p, size, 282 &vmf.vmf_es, &vmf.vmf_bx); 283 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 284} 285
|
| 286/* map a generic video mode to a known mode */
|
285static int
| 287static int
|
286translate_flags(u_int16_t vflags)
| 288vesa_map_gen_mode_num(int type, int color, int mode)
|
287{
| 289{
|
| 290 static struct { 291 int from; 292 int to; 293 } mode_map[] = { 294 { M_TEXT_132x25, M_VESA_C132x25 }, 295 { M_TEXT_132x43, M_VESA_C132x43 }, 296 { M_TEXT_132x50, M_VESA_C132x50 }, 297 { M_TEXT_132x60, M_VESA_C132x60 }, 298 }; 299 int i; 300 301 for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { 302 if (mode_map[i].from == mode) 303 return mode_map[i].to; 304 } 305 return mode; 306} 307 308static int 309vesa_translate_flags(u_int16_t vflags) 310{
|
288 static struct { 289 u_int16_t mask; 290 int set; 291 int reset; 292 } ftable[] = { 293 { V_MODECOLOR, V_INFO_COLOR, 0 }, 294 { V_MODEGRAPHICS, V_INFO_GRAPHICS, 0 }, 295 { V_MODELFB, V_INFO_LENEAR, 0 }, 296 }; 297 int flags; 298 int i; 299 300 for (flags = 0, i = 0; i < sizeof(ftable)/sizeof(ftable[0]); ++i) { 301 flags |= (vflags & ftable[i].mask) ? 302 ftable[i].set : ftable[i].reset; 303 } 304 return flags; 305} 306 307static int 308vesa_bios_init(void) 309{ 310 static u_char buf[512]; 311 struct vm86frame vmf; 312 struct vesa_mode vmode; 313 u_int32_t p; 314 int modes; 315 int err; 316 int i; 317 318 if (vesa_init_done) 319 return 0; 320 321 has_vesa_bios = FALSE; 322 vesa_adp_info = NULL; 323 vesa_vmode[0].vi_mode = EOT; 324 325 bzero(&vmf, sizeof(vmf)); /* paranoia */ 326 bzero(buf, sizeof(buf)); 327 bcopy("VBE2", buf, 4); /* try for VBE2 data */ 328 vmf.vmf_eax = 0x4f00; 329 err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf), 330 &vmf.vmf_es, &vmf.vmf_di); 331 if ((err != 0) || (vmf.vmf_eax != 0x4f) || bcmp("VESA", buf, 4)) 332 return 1; 333 vesa_adp_info = (struct vesa_info *)buf; 334 if (bootverbose) 335 dump_buffer(buf, 64); 336 if (vesa_adp_info->v_flags & V_NONVGA) 337 return 1; 338 339 /* obtain video mode information */ 340 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_modetable); 341 vesa_vmodetab = (u_int16_t *)BIOS_PADDRTOVADDR(p); 342 for (i = 0, modes = 0; vesa_vmodetab[i] != 0xffff; ++i) { 343 if (modes >= VESA_MAXMODES) 344 break; 345 if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) 346 continue; 347 348 /* reject unsupported modes */ 349#if 0 350 if ((vmode.v_modeattr & (V_MODESUPP | V_MODEOPTINFO 351 | V_MODENONVGA)) 352 != (V_MODESUPP | V_MODEOPTINFO)) 353 continue; 354#else 355 if ((vmode.v_modeattr & (V_MODEOPTINFO | V_MODENONVGA)) 356 != (V_MODEOPTINFO)) 357 continue; 358#endif 359 360 /* copy some fields */ 361 bzero(&vesa_vmode[modes], sizeof(vesa_vmode[modes])); 362 vesa_vmode[modes].vi_mode = vesa_vmodetab[i]; 363 vesa_vmode[modes].vi_width = vmode.v_width; 364 vesa_vmode[modes].vi_height = vmode.v_height; 365 vesa_vmode[modes].vi_depth = vmode.v_bpp; 366 vesa_vmode[modes].vi_planes = vmode.v_planes; 367 vesa_vmode[modes].vi_cwidth = vmode.v_cwidth; 368 vesa_vmode[modes].vi_cheight = vmode.v_cheight; 369 vesa_vmode[modes].vi_window = (u_int)vmode.v_waseg << 4; 370 /* XXX window B */ 371 vesa_vmode[modes].vi_window_size = vmode.v_wsize; 372 vesa_vmode[modes].vi_window_gran = vmode.v_wgran; 373 vesa_vmode[modes].vi_buffer = vmode.v_lfb; 374 vesa_vmode[modes].vi_buffer_size = vmode.v_offscreen; 375 /* pixel format, memory model... */
| 311 static struct { 312 u_int16_t mask; 313 int set; 314 int reset; 315 } ftable[] = { 316 { V_MODECOLOR, V_INFO_COLOR, 0 }, 317 { V_MODEGRAPHICS, V_INFO_GRAPHICS, 0 }, 318 { V_MODELFB, V_INFO_LENEAR, 0 }, 319 }; 320 int flags; 321 int i; 322 323 for (flags = 0, i = 0; i < sizeof(ftable)/sizeof(ftable[0]); ++i) { 324 flags |= (vflags & ftable[i].mask) ? 325 ftable[i].set : ftable[i].reset; 326 } 327 return flags; 328} 329 330static int 331vesa_bios_init(void) 332{ 333 static u_char buf[512]; 334 struct vm86frame vmf; 335 struct vesa_mode vmode; 336 u_int32_t p; 337 int modes; 338 int err; 339 int i; 340 341 if (vesa_init_done) 342 return 0; 343 344 has_vesa_bios = FALSE; 345 vesa_adp_info = NULL; 346 vesa_vmode[0].vi_mode = EOT; 347 348 bzero(&vmf, sizeof(vmf)); /* paranoia */ 349 bzero(buf, sizeof(buf)); 350 bcopy("VBE2", buf, 4); /* try for VBE2 data */ 351 vmf.vmf_eax = 0x4f00; 352 err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf), 353 &vmf.vmf_es, &vmf.vmf_di); 354 if ((err != 0) || (vmf.vmf_eax != 0x4f) || bcmp("VESA", buf, 4)) 355 return 1; 356 vesa_adp_info = (struct vesa_info *)buf; 357 if (bootverbose) 358 dump_buffer(buf, 64); 359 if (vesa_adp_info->v_flags & V_NONVGA) 360 return 1; 361 362 /* obtain video mode information */ 363 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_modetable); 364 vesa_vmodetab = (u_int16_t *)BIOS_PADDRTOVADDR(p); 365 for (i = 0, modes = 0; vesa_vmodetab[i] != 0xffff; ++i) { 366 if (modes >= VESA_MAXMODES) 367 break; 368 if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) 369 continue; 370 371 /* reject unsupported modes */ 372#if 0 373 if ((vmode.v_modeattr & (V_MODESUPP | V_MODEOPTINFO 374 | V_MODENONVGA)) 375 != (V_MODESUPP | V_MODEOPTINFO)) 376 continue; 377#else 378 if ((vmode.v_modeattr & (V_MODEOPTINFO | V_MODENONVGA)) 379 != (V_MODEOPTINFO)) 380 continue; 381#endif 382 383 /* copy some fields */ 384 bzero(&vesa_vmode[modes], sizeof(vesa_vmode[modes])); 385 vesa_vmode[modes].vi_mode = vesa_vmodetab[i]; 386 vesa_vmode[modes].vi_width = vmode.v_width; 387 vesa_vmode[modes].vi_height = vmode.v_height; 388 vesa_vmode[modes].vi_depth = vmode.v_bpp; 389 vesa_vmode[modes].vi_planes = vmode.v_planes; 390 vesa_vmode[modes].vi_cwidth = vmode.v_cwidth; 391 vesa_vmode[modes].vi_cheight = vmode.v_cheight; 392 vesa_vmode[modes].vi_window = (u_int)vmode.v_waseg << 4; 393 /* XXX window B */ 394 vesa_vmode[modes].vi_window_size = vmode.v_wsize; 395 vesa_vmode[modes].vi_window_gran = vmode.v_wgran; 396 vesa_vmode[modes].vi_buffer = vmode.v_lfb; 397 vesa_vmode[modes].vi_buffer_size = vmode.v_offscreen; 398 /* pixel format, memory model... */
|
376 vesa_vmode[modes].vi_flags = translate_flags(vmode.v_modeattr) 377 | V_INFO_VESA;
| 399 vesa_vmode[modes].vi_flags 400 = vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA;
|
378 ++modes; 379 } 380 vesa_vmode[modes].vi_mode = EOT; 381 if (bootverbose) 382 printf("VESA: %d mode(s) found\n", modes); 383 384 has_vesa_bios = TRUE; 385 return 0; 386} 387 388static void
| 401 ++modes; 402 } 403 vesa_vmode[modes].vi_mode = EOT; 404 if (bootverbose) 405 printf("VESA: %d mode(s) found\n", modes); 406 407 has_vesa_bios = TRUE; 408 return 0; 409} 410 411static void
|
389clear_modes(video_info_t *info, int color)
| 412vesa_clear_modes(video_info_t *info, int color)
|
390{ 391 while (info->vi_mode != EOT) { 392 if ((info->vi_flags & V_INFO_COLOR) != color) 393 info->vi_mode = NA; 394 ++info; 395 } 396} 397 398/* exported functions */ 399 400static int 401vesa_init(void) 402{ 403 int adapters; 404 int i; 405 406 adapters = (*prevvidsw.init)(); 407 for (i = 0; i < adapters; ++i) { 408 if ((vesa_adp = (*prevvidsw.adapter)(i)) == NULL) 409 continue; 410 if (vesa_adp->va_type == KD_VGA) { 411 vesa_adp->va_flags |= V_ADP_VESA; 412 return adapters; 413 } 414 } 415 vesa_adp = NULL; 416 return adapters; 417} 418 419static video_adapter_t 420*vesa_adapter(int ad) 421{ 422 return (*prevvidsw.adapter)(ad); 423} 424 425static int 426vesa_get_info(int ad, int mode, video_info_t *info) 427{ 428 int i; 429 430 if ((*prevvidsw.get_info)(ad, mode, info) == 0) 431 return 0; 432 433 if (ad != vesa_adp->va_index) 434 return 1;
| 413{ 414 while (info->vi_mode != EOT) { 415 if ((info->vi_flags & V_INFO_COLOR) != color) 416 info->vi_mode = NA; 417 ++info; 418 } 419} 420 421/* exported functions */ 422 423static int 424vesa_init(void) 425{ 426 int adapters; 427 int i; 428 429 adapters = (*prevvidsw.init)(); 430 for (i = 0; i < adapters; ++i) { 431 if ((vesa_adp = (*prevvidsw.adapter)(i)) == NULL) 432 continue; 433 if (vesa_adp->va_type == KD_VGA) { 434 vesa_adp->va_flags |= V_ADP_VESA; 435 return adapters; 436 } 437 } 438 vesa_adp = NULL; 439 return adapters; 440} 441 442static video_adapter_t 443*vesa_adapter(int ad) 444{ 445 return (*prevvidsw.adapter)(ad); 446} 447 448static int 449vesa_get_info(int ad, int mode, video_info_t *info) 450{ 451 int i; 452 453 if ((*prevvidsw.get_info)(ad, mode, info) == 0) 454 return 0; 455 456 if (ad != vesa_adp->va_index) 457 return 1;
|
| 458 459 mode = vesa_map_gen_mode_num(vesa_adp->va_type, 460 vesa_adp->va_flags & V_ADP_COLOR, mode);
|
435 for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) { 436 if (vesa_vmode[i].vi_mode == NA) 437 continue; 438 if (vesa_vmode[i].vi_mode == mode) { 439 *info = vesa_vmode[i]; 440 return 0; 441 } 442 } 443 return 1; 444} 445 446static int 447vesa_query_mode(int ad, video_info_t *info) 448{ 449 int i; 450 451 if ((i = (*prevvidsw.query_mode)(ad, info)) != -1) 452 return i; 453 if (ad != vesa_adp->va_index) 454 return -1; 455 456 for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) { 457 if ((info->vi_width != 0) 458 && (info->vi_width != vesa_vmode[i].vi_width)) 459 continue; 460 if ((info->vi_height != 0) 461 && (info->vi_height != vesa_vmode[i].vi_height)) 462 continue; 463 if ((info->vi_cwidth != 0) 464 && (info->vi_cwidth != vesa_vmode[i].vi_cwidth)) 465 continue; 466 if ((info->vi_cheight != 0) 467 && (info->vi_cheight != vesa_vmode[i].vi_cheight)) 468 continue; 469 if ((info->vi_depth != 0) 470 && (info->vi_depth != vesa_vmode[i].vi_depth)) 471 continue; 472 if ((info->vi_planes != 0) 473 && (info->vi_planes != vesa_vmode[i].vi_planes)) 474 continue; 475 /* pixel format, memory model */ 476 if ((info->vi_flags != 0) 477 && (info->vi_flags != vesa_vmode[i].vi_flags)) 478 continue; 479 return vesa_vmode[i].vi_mode; 480 } 481 return -1; 482} 483 484static int 485vesa_set_mode(int ad, int mode) 486{ 487 video_info_t info; 488 size_t len; 489 490 if (ad != vesa_adp->va_index) 491 return (*prevvidsw.set_mode)(ad, mode); 492
| 461 for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) { 462 if (vesa_vmode[i].vi_mode == NA) 463 continue; 464 if (vesa_vmode[i].vi_mode == mode) { 465 *info = vesa_vmode[i]; 466 return 0; 467 } 468 } 469 return 1; 470} 471 472static int 473vesa_query_mode(int ad, video_info_t *info) 474{ 475 int i; 476 477 if ((i = (*prevvidsw.query_mode)(ad, info)) != -1) 478 return i; 479 if (ad != vesa_adp->va_index) 480 return -1; 481 482 for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) { 483 if ((info->vi_width != 0) 484 && (info->vi_width != vesa_vmode[i].vi_width)) 485 continue; 486 if ((info->vi_height != 0) 487 && (info->vi_height != vesa_vmode[i].vi_height)) 488 continue; 489 if ((info->vi_cwidth != 0) 490 && (info->vi_cwidth != vesa_vmode[i].vi_cwidth)) 491 continue; 492 if ((info->vi_cheight != 0) 493 && (info->vi_cheight != vesa_vmode[i].vi_cheight)) 494 continue; 495 if ((info->vi_depth != 0) 496 && (info->vi_depth != vesa_vmode[i].vi_depth)) 497 continue; 498 if ((info->vi_planes != 0) 499 && (info->vi_planes != vesa_vmode[i].vi_planes)) 500 continue; 501 /* pixel format, memory model */ 502 if ((info->vi_flags != 0) 503 && (info->vi_flags != vesa_vmode[i].vi_flags)) 504 continue; 505 return vesa_vmode[i].vi_mode; 506 } 507 return -1; 508} 509 510static int 511vesa_set_mode(int ad, int mode) 512{ 513 video_info_t info; 514 size_t len; 515 516 if (ad != vesa_adp->va_index) 517 return (*prevvidsw.set_mode)(ad, mode); 518
|
| 519 mode = vesa_map_gen_mode_num(vesa_adp->va_type, 520 vesa_adp->va_flags & V_ADP_COLOR, mode);
|
493#ifdef SC_VIDEO_DEBUG 494 printf("VESA: set_mode(): %d(%x) -> %d(%x)\n", 495 vesa_adp->va_mode, vesa_adp->va_mode, mode, mode); 496#endif 497 /* 498 * If the current mode is a VESA mode and the new mode is not, 499 * restore the state of the adapter first, so that non-standard, 500 * extended SVGA registers are set to the state compatible with 501 * the standard VGA modes. Otherwise (*prevvidsw.set_mode)() 502 * may not be able to set up the new mode correctly. 503 */ 504 if (VESA_MODE(vesa_adp->va_mode)) { 505 if ((*prevvidsw.get_info)(ad, mode, &info) == 0) { 506 /* assert(vesa_state_buf != NULL); */ 507 if ((vesa_state_buf == NULL) 508 || vesa_load_state(ad, vesa_state_buf)) 509 return 1; 510 free(vesa_state_buf, M_DEVBUF); 511 vesa_state_buf = NULL; 512#ifdef SC_VIDEO_DEBUG 513 printf("VESA: restored\n"); 514#endif 515 } 516 /* 517 * once (*prevvidsw.get_info)() succeeded, 518 * (*prevvidsw.set_mode)() below won't fail... 519 */ 520 } 521 522 /* we may not need to handle this mode after all... */ 523 if ((*prevvidsw.set_mode)(ad, mode) == 0) 524 return 0; 525 526 /* is the new mode supported? */ 527 if (vesa_get_info(ad, mode, &info)) 528 return 1; 529 /* assert(VESA_MODE(mode)); */ 530 531#ifdef SC_VIDEO_DEBUG 532 printf("VESA: about to set a VESA mode...\n"); 533#endif 534 /* 535 * If the current mode is not a VESA mode, save the current state 536 * so that the adapter state can be restored later when a non-VESA 537 * mode is to be set up. See above. 538 */ 539 if (!VESA_MODE(vesa_adp->va_mode) && (vesa_state_buf == NULL)) { 540 len = vesa_save_state(ad, NULL, 0); 541 vesa_state_buf = malloc(len, M_DEVBUF, M_WAITOK); 542 if (vesa_save_state(ad, vesa_state_buf, len)) { 543#ifdef SC_VIDEO_DEBUG 544 printf("VESA: state save failed! (len=%d)\n", len); 545#endif 546 free(vesa_state_buf, M_DEVBUF); 547 vesa_state_buf = NULL; 548 return 1; 549 } 550#ifdef SC_VIDEO_DEBUG 551 printf("VESA: saved (len=%d)\n", len); 552 dump_buffer(vesa_state_buf, len); 553#endif 554 } 555 556 if (vesa_bios_set_mode(mode)) 557 return 1; 558 559#ifdef SC_VIDEO_DEBUG 560 printf("VESA: mode set!\n"); 561#endif 562 vesa_adp->va_mode = mode; 563 vesa_adp->va_flags &= ~V_ADP_COLOR; 564 vesa_adp->va_flags |= 565 (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; 566 vesa_adp->va_crtc_addr = 567 (vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_BASE : MONO_BASE; 568 vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window); 569 vesa_adp->va_window_size = info.vi_window_size; 570 vesa_adp->va_window_gran = info.vi_window_gran; 571 if (info.vi_buffer_size == 0) { 572 vesa_adp->va_buffer = 0; 573 vesa_adp->va_buffer_size = 0; 574 } else { 575 vesa_adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer); 576 vesa_adp->va_buffer_size = info.vi_buffer_size; 577 } 578 579 return 0; 580} 581 582static int 583vesa_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count) 584{ 585 return (*prevvidsw.save_font)(ad, page, fontsize, data, ch, count); 586} 587 588static int 589vesa_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count) 590{ 591 return (*prevvidsw.load_font)(ad, page, fontsize, data, ch, count); 592} 593 594static int 595vesa_show_font(int ad, int page) 596{ 597 return (*prevvidsw.show_font)(ad, page); 598} 599 600static int 601vesa_save_palette(int ad, u_char *palette) 602{ 603 if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8) 604 || vesa_bios_set_dac(8)) 605 return (*prevvidsw.save_palette)(ad, palette); 606 607 return vesa_bios_save_palette(0, 256, palette); 608} 609 610static int 611vesa_load_palette(int ad, u_char *palette) 612{ 613 if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8) 614 || vesa_bios_set_dac(8)) 615 return (*prevvidsw.load_palette)(ad, palette); 616 617 return vesa_bios_load_palette(0, 256, palette); 618} 619 620static int 621vesa_set_border(int ad, int color) 622{ 623 return (*prevvidsw.set_border)(ad, color); 624} 625 626static int 627vesa_save_state(int ad, void *p, size_t size) 628{ 629 if (ad != vesa_adp->va_index) 630 return (*prevvidsw.save_state)(ad, p, size); 631 632 if (vesa_state_buf_size == 0) 633 vesa_state_buf_size = vesa_bios_state_buf_size(); 634 if (size == 0) 635 return (sizeof(int) + vesa_state_buf_size); 636 else if (size < (sizeof(int) + vesa_state_buf_size)) 637 return 1; 638 639 ((adp_state_t *)p)->sig = V_STATE_SIG; 640 bzero(((adp_state_t *)p)->regs, vesa_state_buf_size); 641 return vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs, 642 vesa_state_buf_size); 643} 644 645static int 646vesa_load_state(int ad, void *p) 647{ 648 if ((ad != vesa_adp->va_index) 649 || (((adp_state_t *)p)->sig != V_STATE_SIG)) 650 return (*prevvidsw.load_state)(ad, p); 651 652 return vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, 653 vesa_state_buf_size); 654} 655 656static int 657vesa_set_origin(int ad, off_t offset) 658{ 659 struct vm86frame vmf; 660 int err; 661 662 /* 663 * This function should return as quickly as possible to 664 * maintain good performance of the system. For this reason, 665 * error checking is kept minimal and let the VESA BIOS to 666 * detect error. 667 */ 668 if (ad != vesa_adp->va_index) 669 return (*prevvidsw.set_win_org)(ad, offset); 670 671 if (vesa_adp->va_window_gran == 0) 672 return 1; 673 bzero(&vmf, sizeof(vmf)); 674 vmf.vmf_eax = 0x4f05; 675 vmf.vmf_ebx = 0; /* WINDOW_A, XXX */ 676 vmf.vmf_edx = offset/vesa_adp->va_window_gran; 677 err = vm86_intcall(0x10, &vmf); 678 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 679} 680 681static int 682vesa_read_hw_cursor(int ad, int *col, int *row) 683{ 684 return (*prevvidsw.read_hw_cursor)(ad, col, row); 685} 686 687static int 688vesa_set_hw_cursor(int ad, int col, int row) 689{ 690 return (*prevvidsw.set_hw_cursor)(ad, col, row); 691} 692 693static int 694vesa_diag(int level) 695{ 696 struct vesa_mode vmode; 697 u_int32_t p; 698 int i; 699
| 521#ifdef SC_VIDEO_DEBUG 522 printf("VESA: set_mode(): %d(%x) -> %d(%x)\n", 523 vesa_adp->va_mode, vesa_adp->va_mode, mode, mode); 524#endif 525 /* 526 * If the current mode is a VESA mode and the new mode is not, 527 * restore the state of the adapter first, so that non-standard, 528 * extended SVGA registers are set to the state compatible with 529 * the standard VGA modes. Otherwise (*prevvidsw.set_mode)() 530 * may not be able to set up the new mode correctly. 531 */ 532 if (VESA_MODE(vesa_adp->va_mode)) { 533 if ((*prevvidsw.get_info)(ad, mode, &info) == 0) { 534 /* assert(vesa_state_buf != NULL); */ 535 if ((vesa_state_buf == NULL) 536 || vesa_load_state(ad, vesa_state_buf)) 537 return 1; 538 free(vesa_state_buf, M_DEVBUF); 539 vesa_state_buf = NULL; 540#ifdef SC_VIDEO_DEBUG 541 printf("VESA: restored\n"); 542#endif 543 } 544 /* 545 * once (*prevvidsw.get_info)() succeeded, 546 * (*prevvidsw.set_mode)() below won't fail... 547 */ 548 } 549 550 /* we may not need to handle this mode after all... */ 551 if ((*prevvidsw.set_mode)(ad, mode) == 0) 552 return 0; 553 554 /* is the new mode supported? */ 555 if (vesa_get_info(ad, mode, &info)) 556 return 1; 557 /* assert(VESA_MODE(mode)); */ 558 559#ifdef SC_VIDEO_DEBUG 560 printf("VESA: about to set a VESA mode...\n"); 561#endif 562 /* 563 * If the current mode is not a VESA mode, save the current state 564 * so that the adapter state can be restored later when a non-VESA 565 * mode is to be set up. See above. 566 */ 567 if (!VESA_MODE(vesa_adp->va_mode) && (vesa_state_buf == NULL)) { 568 len = vesa_save_state(ad, NULL, 0); 569 vesa_state_buf = malloc(len, M_DEVBUF, M_WAITOK); 570 if (vesa_save_state(ad, vesa_state_buf, len)) { 571#ifdef SC_VIDEO_DEBUG 572 printf("VESA: state save failed! (len=%d)\n", len); 573#endif 574 free(vesa_state_buf, M_DEVBUF); 575 vesa_state_buf = NULL; 576 return 1; 577 } 578#ifdef SC_VIDEO_DEBUG 579 printf("VESA: saved (len=%d)\n", len); 580 dump_buffer(vesa_state_buf, len); 581#endif 582 } 583 584 if (vesa_bios_set_mode(mode)) 585 return 1; 586 587#ifdef SC_VIDEO_DEBUG 588 printf("VESA: mode set!\n"); 589#endif 590 vesa_adp->va_mode = mode; 591 vesa_adp->va_flags &= ~V_ADP_COLOR; 592 vesa_adp->va_flags |= 593 (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; 594 vesa_adp->va_crtc_addr = 595 (vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_BASE : MONO_BASE; 596 vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window); 597 vesa_adp->va_window_size = info.vi_window_size; 598 vesa_adp->va_window_gran = info.vi_window_gran; 599 if (info.vi_buffer_size == 0) { 600 vesa_adp->va_buffer = 0; 601 vesa_adp->va_buffer_size = 0; 602 } else { 603 vesa_adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer); 604 vesa_adp->va_buffer_size = info.vi_buffer_size; 605 } 606 607 return 0; 608} 609 610static int 611vesa_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count) 612{ 613 return (*prevvidsw.save_font)(ad, page, fontsize, data, ch, count); 614} 615 616static int 617vesa_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count) 618{ 619 return (*prevvidsw.load_font)(ad, page, fontsize, data, ch, count); 620} 621 622static int 623vesa_show_font(int ad, int page) 624{ 625 return (*prevvidsw.show_font)(ad, page); 626} 627 628static int 629vesa_save_palette(int ad, u_char *palette) 630{ 631 if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8) 632 || vesa_bios_set_dac(8)) 633 return (*prevvidsw.save_palette)(ad, palette); 634 635 return vesa_bios_save_palette(0, 256, palette); 636} 637 638static int 639vesa_load_palette(int ad, u_char *palette) 640{ 641 if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8) 642 || vesa_bios_set_dac(8)) 643 return (*prevvidsw.load_palette)(ad, palette); 644 645 return vesa_bios_load_palette(0, 256, palette); 646} 647 648static int 649vesa_set_border(int ad, int color) 650{ 651 return (*prevvidsw.set_border)(ad, color); 652} 653 654static int 655vesa_save_state(int ad, void *p, size_t size) 656{ 657 if (ad != vesa_adp->va_index) 658 return (*prevvidsw.save_state)(ad, p, size); 659 660 if (vesa_state_buf_size == 0) 661 vesa_state_buf_size = vesa_bios_state_buf_size(); 662 if (size == 0) 663 return (sizeof(int) + vesa_state_buf_size); 664 else if (size < (sizeof(int) + vesa_state_buf_size)) 665 return 1; 666 667 ((adp_state_t *)p)->sig = V_STATE_SIG; 668 bzero(((adp_state_t *)p)->regs, vesa_state_buf_size); 669 return vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs, 670 vesa_state_buf_size); 671} 672 673static int 674vesa_load_state(int ad, void *p) 675{ 676 if ((ad != vesa_adp->va_index) 677 || (((adp_state_t *)p)->sig != V_STATE_SIG)) 678 return (*prevvidsw.load_state)(ad, p); 679 680 return vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, 681 vesa_state_buf_size); 682} 683 684static int 685vesa_set_origin(int ad, off_t offset) 686{ 687 struct vm86frame vmf; 688 int err; 689 690 /* 691 * This function should return as quickly as possible to 692 * maintain good performance of the system. For this reason, 693 * error checking is kept minimal and let the VESA BIOS to 694 * detect error. 695 */ 696 if (ad != vesa_adp->va_index) 697 return (*prevvidsw.set_win_org)(ad, offset); 698 699 if (vesa_adp->va_window_gran == 0) 700 return 1; 701 bzero(&vmf, sizeof(vmf)); 702 vmf.vmf_eax = 0x4f05; 703 vmf.vmf_ebx = 0; /* WINDOW_A, XXX */ 704 vmf.vmf_edx = offset/vesa_adp->va_window_gran; 705 err = vm86_intcall(0x10, &vmf); 706 return ((err != 0) || (vmf.vmf_eax != 0x4f)); 707} 708 709static int 710vesa_read_hw_cursor(int ad, int *col, int *row) 711{ 712 return (*prevvidsw.read_hw_cursor)(ad, col, row); 713} 714 715static int 716vesa_set_hw_cursor(int ad, int col, int row) 717{ 718 return (*prevvidsw.set_hw_cursor)(ad, col, row); 719} 720 721static int 722vesa_diag(int level) 723{ 724 struct vesa_mode vmode; 725 u_int32_t p; 726 int i; 727
|
| 728#ifndef VESA_MODULE 729 /* call the previous handler first */ 730 (*prevvidsw.diag)(level); 731#endif 732
|
700 /* general adapter information */ 701 printf("VESA: v%d.%d, %dk memory, flags:0x%x, mode table:%p (%x)\n", 702 ((vesa_adp_info->v_version & 0xf000) >> 12) * 10 703 + ((vesa_adp_info->v_version & 0x0f00) >> 8), 704 ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10 705 + (vesa_adp_info->v_version & 0x000f), 706 vesa_adp_info->v_memsize * 64, vesa_adp_info->v_flags, 707 vesa_vmodetab, vesa_adp_info->v_modetable); 708 /* OEM string */ 709 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_oemstr); 710 if (p != 0) 711 printf("VESA: %s\n", (char *)BIOS_PADDRTOVADDR(p)); 712 713 if (level <= 0) 714 return 0; 715 716 if (vesa_adp_info->v_version >= 0x0200) { 717 /* vendor name */ 718 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_venderstr); 719 if (p != 0) 720 printf("VESA: %s, ", (char *)BIOS_PADDRTOVADDR(p)); 721 /* product name */ 722 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_prodstr); 723 if (p != 0) 724 printf("%s, ", (char *)BIOS_PADDRTOVADDR(p)); 725 /* product revision */ 726 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_revstr); 727 if (p != 0) 728 printf("%s\n", (char *)BIOS_PADDRTOVADDR(p)); 729 } 730 731 /* mode information */ 732 for (i = 0; vesa_vmodetab[i] != 0xffff; ++i) { 733 if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) 734 continue; 735 736 /* print something for diagnostic purpose */ 737 printf("VESA: mode:0x%03x, flags:0x%04x", 738 vesa_vmodetab[i], vmode.v_modeattr); 739 if (vmode.v_modeattr & V_MODEOPTINFO) { 740 if (vmode.v_modeattr & V_MODEGRAPHICS) { 741 printf(", G %dx%dx%d %d, ", 742 vmode.v_width, vmode.v_height, 743 vmode.v_bpp, vmode.v_planes); 744 } else { 745 printf(", T %dx%d, ", 746 vmode.v_width, vmode.v_height); 747 } 748 printf("font:%dx%d", 749 vmode.v_cwidth, vmode.v_cheight); 750 } 751 if (vmode.v_modeattr & V_MODELFB) { 752 printf(", mem:%d, LFB:0x%x, off:0x%x", 753 vmode.v_memmodel, vmode.v_lfb, 754 vmode.v_offscreen); 755 } 756 printf("\n"); 757 printf("VESA: window A:0x%x (%x), window B:0x%x (%x), ", 758 vmode.v_waseg, vmode.v_waattr, 759 vmode.v_wbseg, vmode.v_wbattr); 760 printf("size:%dk, gran:%dk\n", 761 vmode.v_wsize, vmode.v_wgran); 762 } 763 764 return 0; 765} 766 767/* module loading */ 768 769#ifdef VESA_MODULE 770static int 771vesa_load(struct lkm_table *lkmtp, int cmd) 772#else 773int 774vesa_load(void) 775#endif 776{ 777 int adapters; 778 int error; 779 int s; 780 int i; 781 782 if (vesa_init_done) 783 return 0; 784 785 /* 786 * If the VESA module is statically linked to the kernel, or 787 * it has already been loaded, abort loading this module this time. 788 */ 789 vesa_adp = NULL; 790 adapters = (*biosvidsw.init)(); 791 for (i = 0; i < adapters; ++i) { 792 if ((vesa_adp = (*biosvidsw.adapter)(i)) == NULL) 793 continue; 794 if (vesa_adp->va_flags & V_ADP_VESA) 795 return ENXIO; 796 if (vesa_adp->va_type == KD_VGA) 797 break; 798 } 799 /* if a VGA adapter is not found, abort */ 800 if (i >= adapters) 801 return ENXIO; 802 803 if (vesa_bios_init()) 804 return ENXIO; 805 vesa_adp->va_flags |= V_ADP_VESA; 806 807 /* remove conflicting modes if we have more than one adapter */ 808 if (adapters > 1) {
| 733 /* general adapter information */ 734 printf("VESA: v%d.%d, %dk memory, flags:0x%x, mode table:%p (%x)\n", 735 ((vesa_adp_info->v_version & 0xf000) >> 12) * 10 736 + ((vesa_adp_info->v_version & 0x0f00) >> 8), 737 ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10 738 + (vesa_adp_info->v_version & 0x000f), 739 vesa_adp_info->v_memsize * 64, vesa_adp_info->v_flags, 740 vesa_vmodetab, vesa_adp_info->v_modetable); 741 /* OEM string */ 742 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_oemstr); 743 if (p != 0) 744 printf("VESA: %s\n", (char *)BIOS_PADDRTOVADDR(p)); 745 746 if (level <= 0) 747 return 0; 748 749 if (vesa_adp_info->v_version >= 0x0200) { 750 /* vendor name */ 751 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_venderstr); 752 if (p != 0) 753 printf("VESA: %s, ", (char *)BIOS_PADDRTOVADDR(p)); 754 /* product name */ 755 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_prodstr); 756 if (p != 0) 757 printf("%s, ", (char *)BIOS_PADDRTOVADDR(p)); 758 /* product revision */ 759 p = BIOS_SADDRTOLADDR(vesa_adp_info->v_revstr); 760 if (p != 0) 761 printf("%s\n", (char *)BIOS_PADDRTOVADDR(p)); 762 } 763 764 /* mode information */ 765 for (i = 0; vesa_vmodetab[i] != 0xffff; ++i) { 766 if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) 767 continue; 768 769 /* print something for diagnostic purpose */ 770 printf("VESA: mode:0x%03x, flags:0x%04x", 771 vesa_vmodetab[i], vmode.v_modeattr); 772 if (vmode.v_modeattr & V_MODEOPTINFO) { 773 if (vmode.v_modeattr & V_MODEGRAPHICS) { 774 printf(", G %dx%dx%d %d, ", 775 vmode.v_width, vmode.v_height, 776 vmode.v_bpp, vmode.v_planes); 777 } else { 778 printf(", T %dx%d, ", 779 vmode.v_width, vmode.v_height); 780 } 781 printf("font:%dx%d", 782 vmode.v_cwidth, vmode.v_cheight); 783 } 784 if (vmode.v_modeattr & V_MODELFB) { 785 printf(", mem:%d, LFB:0x%x, off:0x%x", 786 vmode.v_memmodel, vmode.v_lfb, 787 vmode.v_offscreen); 788 } 789 printf("\n"); 790 printf("VESA: window A:0x%x (%x), window B:0x%x (%x), ", 791 vmode.v_waseg, vmode.v_waattr, 792 vmode.v_wbseg, vmode.v_wbattr); 793 printf("size:%dk, gran:%dk\n", 794 vmode.v_wsize, vmode.v_wgran); 795 } 796 797 return 0; 798} 799 800/* module loading */ 801 802#ifdef VESA_MODULE 803static int 804vesa_load(struct lkm_table *lkmtp, int cmd) 805#else 806int 807vesa_load(void) 808#endif 809{ 810 int adapters; 811 int error; 812 int s; 813 int i; 814 815 if (vesa_init_done) 816 return 0; 817 818 /* 819 * If the VESA module is statically linked to the kernel, or 820 * it has already been loaded, abort loading this module this time. 821 */ 822 vesa_adp = NULL; 823 adapters = (*biosvidsw.init)(); 824 for (i = 0; i < adapters; ++i) { 825 if ((vesa_adp = (*biosvidsw.adapter)(i)) == NULL) 826 continue; 827 if (vesa_adp->va_flags & V_ADP_VESA) 828 return ENXIO; 829 if (vesa_adp->va_type == KD_VGA) 830 break; 831 } 832 /* if a VGA adapter is not found, abort */ 833 if (i >= adapters) 834 return ENXIO; 835 836 if (vesa_bios_init()) 837 return ENXIO; 838 vesa_adp->va_flags |= V_ADP_VESA; 839 840 /* remove conflicting modes if we have more than one adapter */ 841 if (adapters > 1) {
|
809 clear_modes(vesa_vmode, 810 (vesa_adp->va_flags & V_ADP_COLOR) ? 811 V_INFO_COLOR : 0);
| 842 vesa_clear_modes(vesa_vmode, 843 (vesa_adp->va_flags & V_ADP_COLOR) ? 844 V_INFO_COLOR : 0);
|
812 } 813 814#ifdef VESA_MODULE 815 s = spltty(); 816#endif 817 if ((error = vesa_load_ioctl()) == 0) { 818 bcopy(&biosvidsw, &prevvidsw, sizeof(prevvidsw)); 819 bcopy(&vesavidsw, &biosvidsw, sizeof(vesavidsw)); 820 vesa_init_done = TRUE; 821 } 822#ifdef VESA_MODULE 823 splx(s); 824 825 if (error == 0) 826 vesa_diag(bootverbose); 827#endif 828 829 return error; 830} 831 832#ifdef VESA_MODULE 833 834static int 835vesa_unload(struct lkm_table *lkmtp, int cmd) 836{ 837 int error; 838 int s; 839 840 /* if the adapter is currently in a VESA mode, don't unload */ 841 if ((vesa_adp != NULL) && VESA_MODE(vesa_adp->va_mode)) 842 return EBUSY; 843 /* 844 * FIXME: if there is at least one vty which is in a VESA mode, 845 * we shouldn't be unloading! XXX 846 */ 847 848 s = spltty(); 849 if ((error = vesa_unload_ioctl()) == 0) { 850 if (vesa_adp) 851 vesa_adp->va_flags &= ~V_ADP_VESA; 852 bcopy(&prevvidsw, &biosvidsw, sizeof(biosvidsw)); 853 } 854 splx(s); 855 856 return error; 857} 858 859int 860vesa_mod(struct lkm_table *lkmtp, int cmd, int ver) 861{ 862 MOD_DISPATCH(vesa, lkmtp, cmd, ver, 863 vesa_load, vesa_unload, lkm_nullcmd); 864} 865 866#endif /* VESA_MODULE */ 867 868#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */
| 845 } 846 847#ifdef VESA_MODULE 848 s = spltty(); 849#endif 850 if ((error = vesa_load_ioctl()) == 0) { 851 bcopy(&biosvidsw, &prevvidsw, sizeof(prevvidsw)); 852 bcopy(&vesavidsw, &biosvidsw, sizeof(vesavidsw)); 853 vesa_init_done = TRUE; 854 } 855#ifdef VESA_MODULE 856 splx(s); 857 858 if (error == 0) 859 vesa_diag(bootverbose); 860#endif 861 862 return error; 863} 864 865#ifdef VESA_MODULE 866 867static int 868vesa_unload(struct lkm_table *lkmtp, int cmd) 869{ 870 int error; 871 int s; 872 873 /* if the adapter is currently in a VESA mode, don't unload */ 874 if ((vesa_adp != NULL) && VESA_MODE(vesa_adp->va_mode)) 875 return EBUSY; 876 /* 877 * FIXME: if there is at least one vty which is in a VESA mode, 878 * we shouldn't be unloading! XXX 879 */ 880 881 s = spltty(); 882 if ((error = vesa_unload_ioctl()) == 0) { 883 if (vesa_adp) 884 vesa_adp->va_flags &= ~V_ADP_VESA; 885 bcopy(&prevvidsw, &biosvidsw, sizeof(biosvidsw)); 886 } 887 splx(s); 888 889 return error; 890} 891 892int 893vesa_mod(struct lkm_table *lkmtp, int cmd, int ver) 894{ 895 MOD_DISPATCH(vesa, lkmtp, cmd, ver, 896 vesa_load, vesa_unload, lkm_nullcmd); 897} 898 899#endif /* VESA_MODULE */ 900 901#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */
|