summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2005-03-04 00:53:03 +0000
committeriedowse <iedowse@FreeBSD.org>2005-03-04 00:53:03 +0000
commit1106efffc31f03d34e70770e615ab94af9858183 (patch)
treeec5dbc413f505cf51e945907c01eab3cca438e8d /sys/i386/isa
parente5ec1f72f19cec4897983b5eea50e5fce3184a2b (diff)
downloadFreeBSD-src-1106efffc31f03d34e70770e615ab94af9858183.zip
FreeBSD-src-1106efffc31f03d34e70770e615ab94af9858183.tar.gz
Allocate and map a 12k data buffer such that it is contiguous in
both the kernel and vm86 virtual address spaces. Use this to increase the maximum VESA save state size we can handle.
Diffstat (limited to 'sys/i386/isa')
-rw-r--r--sys/i386/isa/vesa.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/sys/i386/isa/vesa.c b/sys/i386/isa/vesa.c
index ebb5f93..e70a61f 100644
--- a/sys/i386/isa/vesa.c
+++ b/sys/i386/isa/vesa.c
@@ -76,6 +76,8 @@ 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_VM86_BUFSIZE (3 * PAGE_SIZE)
+static void *vesa_vm86_buf;
/* VESA functions */
#if 0
@@ -187,7 +189,6 @@ static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g,
#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)
-#define STATE_MAXSIZE PAGE_SIZE
static int 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);
@@ -245,7 +246,7 @@ vesa_bios_get_mode(int mode, struct vesa_mode *vmode)
bzero(&vmf, sizeof(vmf));
vmf.vmf_eax = 0x4f01;
vmf.vmf_ecx = mode;
- buf = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ buf = vesa_vm86_buf;
vm86_getptr(&vesa_vmcontext, (vm_offset_t)buf, &vmf.vmf_es, &vmf.vmf_di);
err = vm86_datacall(0x10, &vmf, &vesa_vmcontext);
@@ -311,7 +312,7 @@ vesa_bios_save_palette(int start, int colors, u_char *palette, int bits)
vmf.vmf_ebx = 1; /* get primary palette data */
vmf.vmf_ecx = colors;
vmf.vmf_edx = start;
- p = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ p = vesa_vm86_buf;
vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di);
err = vm86_datacall(0x10, &vmf, &vesa_vmcontext);
@@ -341,7 +342,7 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
vmf.vmf_ebx = 1; /* get primary palette data */
vmf.vmf_ecx = colors;
vmf.vmf_edx = start;
- p = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ p = vesa_vm86_buf;
vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di);
err = vm86_datacall(0x10, &vmf, &vesa_vmcontext);
@@ -365,7 +366,7 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
int err;
int i;
- p = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ p = vesa_vm86_buf;
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
p[i*4] = palette[i*3 + 2] >> bits;
@@ -395,7 +396,7 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
int err;
int i;
- p = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ p = vesa_vm86_buf;
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
p[i*4] = b[i] >> bits;
@@ -439,14 +440,14 @@ vesa_bios_save_restore(int code, void *p, size_t size)
u_char *buf;
int err;
- if (size > STATE_MAXSIZE)
+ if (size > VESA_VM86_BUFSIZE)
return (1);
bzero(&vmf, sizeof(vmf));
vmf.vmf_eax = 0x4f04;
vmf.vmf_ecx = STATE_ALL;
vmf.vmf_edx = code; /* STATE_SAVE/STATE_LOAD */
- buf = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ buf = vesa_vm86_buf;
vm86_getptr(&vesa_vmcontext, (vm_offset_t)buf, &vmf.vmf_es, &vmf.vmf_bx);
bcopy(p, buf, size);
@@ -628,7 +629,15 @@ vesa_bios_init(void)
vesa_vmode_max = 0;
vesa_vmode[0].vi_mode = EOT;
- vmbuf = (u_char *)vm86_addpage(&vesa_vmcontext, 1, 0);
+ /* Allocate a buffer and add each page to the vm86 context. */
+ vesa_vm86_buf = malloc(VESA_VM86_BUFSIZE, M_DEVBUF, M_WAITOK | M_ZERO);
+ KASSERT(((vm_offset_t)vesa_vm86_buf & PAGE_MASK) == 0,
+ ("bad vesa_vm86_buf alignment"));
+ for (i = 0; i < howmany(VESA_VM86_BUFSIZE, PAGE_SIZE); i++)
+ vm86_addpage(&vesa_vmcontext, i + 1,
+ (vm_offset_t)vesa_vm86_buf + PAGE_SIZE * i);
+
+ vmbuf = vesa_vm86_buf;
bzero(&vmf, sizeof(vmf)); /* paranoia */
bcopy("VBE2", vmbuf, 4); /* try for VBE2 data */
vmf.vmf_eax = 0x4f00;
@@ -1648,6 +1657,9 @@ vesa_unload(void)
}
splx(s);
+ if (vesa_vm86_buf != NULL)
+ free(vesa_vm86_buf, M_DEVBUF);
+
return error;
}
OpenPOWER on IntegriCloud