diff options
author | David Dawes <dawes@xfree86.org> | 2000-08-28 15:29:19 +0000 |
---|---|---|
committer | David Dawes <dawes@xfree86.org> | 2000-08-28 15:29:19 +0000 |
commit | 3095deed7701a1a14be85dff4a6994028b5a6d09 (patch) | |
tree | 3e10f8480c8d9aa364d22b04ee4a19dc6739e9f3 | |
parent | f32448679118b77825625aafdc4d6ae4d636cc21 (diff) |
565. Support for multithreaded libraries on NetBSD when used in conjunctionxf-4_0_1c
with the GNU pth library (#4113, Chris Sekiya).
564. Add /usr/pkg/bin to NetBSD's DefaultUserPath (#4112, Bernd Ernesti).
563. Add a (Linux-specific) VESA driver for Keith's small X server (#4111,
Juliusz Chroboczek).
562. Update Hungarian xkb maps (#A.145, Peter Soos). remove koi8-r encoding
file since it's built-in
-rw-r--r-- | hw/kdrive/vesa/Imakefile | 16 | ||||
-rw-r--r-- | hw/kdrive/vesa/Xvesa.man | 63 | ||||
-rw-r--r-- | hw/kdrive/vesa/vbe.c | 775 | ||||
-rw-r--r-- | hw/kdrive/vesa/vbe.h | 166 | ||||
-rw-r--r-- | hw/kdrive/vesa/vesa.c | 313 | ||||
-rw-r--r-- | hw/kdrive/vesa/vesa.h | 56 | ||||
-rw-r--r-- | hw/kdrive/vesa/vesainit.c | 91 |
7 files changed, 1480 insertions, 0 deletions
diff --git a/hw/kdrive/vesa/Imakefile b/hw/kdrive/vesa/Imakefile new file mode 100644 index 000000000..bcf8613cb --- /dev/null +++ b/hw/kdrive/vesa/Imakefile @@ -0,0 +1,16 @@ +XCOMM $XFree86$ + +#include <Server.tmpl> + +SRCS = vesa.c vesainit.c vbe.c + +OBJS = vesa.o vesainit.o vbe.o + +INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \ + -I../../../fb -I../../../mi -I../../../include -I../../../os \ + -I$(EXTINCSRC) -I$(XINCLUDESRC) + +NormalLibraryObjectRule() +NormalLibraryTarget(vesa,$(OBJS)) +InstallManPage(Xvesa,$(MANDIR)) +DependTarget() diff --git a/hw/kdrive/vesa/Xvesa.man b/hw/kdrive/vesa/Xvesa.man new file mode 100644 index 000000000..eafd3539b --- /dev/null +++ b/hw/kdrive/vesa/Xvesa.man @@ -0,0 +1,63 @@ +.\" $XFree86$ +.TH Xvesa 1 +.SH NAME +Xvesa \- VESA VBE tiny X server +.SH SYNOPSIS +.B Xvesa +.RI [ :display ] +.RI [ option ...] +.SH DESCRIPTION +Xvesa is an X server for Linux on the x86 platform. Xvesa manipulates +the video hardware by running the VESA BIOS in VM86 mode. It +therefore runs untrusted code with full priviledges, and is one of the +most insecure X servers available. +.B Run at your own risk. +.SH OPTIONS +In addition to the normal tiny-X server's options (to be described in +a separate man page), +.B Xvesa +accepts the following command line switches: +.TP 8 +.B -mode \fIn\fB +specifies the VESA video mode to use. If mode +.I n +is not supported by your BIOS and hardware, +.B Xvesa +will fail, hang your system, or make your monitor explode. You are on +your own. The list of video modes that your BIOS claims to support +can be obtained by using the +.B -listmodes +option. +.TP 8 +.B -listmodes +tells the server to list all supported video modes. If +.B -force +was specified before +.BR -listmodes , +lists all the modes that your BIOS claims to support, even those that +the +.B Xvesa +server won't be able to use. +.TP 8 +.B -force +tells the server to disable some sanity checks and use the specified +mode even if the BIOS claims not to support it. +.SH KEYBOARD +Xvesa handles the keyboard in the same manner as the +.B Xfbdev +Linux X server. See Xfbdev(1) (not yet written) for more information. +.SH BUGS +.B Xvesa +opens all IO ports and runs your VESA BIOS, which may safely be +assumed to be buggy. Allowing your users to run +.B Xvesa +is a major security hole. Allowing yourself to run +.B Xvesa +is probably a mistake. +.SH SEE ALSO +X(1), Xserver(1), xdm(1), xinit(1), Xfbdev(1). +.SH AUTHORS +The tiny-X server was written by Keith Packard, and the VESA driver +was added by Juliusz Chroboczek who didn't realise what he was doing +until it was too late. Tiny-X uses code from XFree86, which in turn +is based on the Sample Implementation. diff --git a/hw/kdrive/vesa/vbe.c b/hw/kdrive/vesa/vbe.c new file mode 100644 index 000000000..1fdbc288f --- /dev/null +++ b/hw/kdrive/vesa/vbe.c @@ -0,0 +1,775 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86$ */ + +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/vm86.h> +#include <sys/io.h> +#include "vbe.h" + +#ifdef NOT_IN_X_SERVER +#include <stdio.h> +#include <stdarg.h> +#include <malloc.h> +static void ErrorF(char*, ...); +#define xalloc(a) malloc(a) +#define xcalloc(a,b) calloc(a,b) +#define xfree(a) free(a) +#else +#include "X.h" +#include "Xproto.h" +#include "Xos.h" +#include "os.h" +#endif + +static int vm86old(struct vm86_struct *vms); +static int vm86_loop(VbeInfoPtr vi); + +static U8 rev_ints[32] = +{ 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x80, +}; + +static U8 retcode_data[2] = +{ 0xCD, 0xFF }; + +#define LM(vi,i) ((char*)vi->loMem)[i-LOMEM_BASE] +#define LMW(vi,i) (*(U16*)(&LM(vi,i))) +#define MM(vi,i) ((char*)vi->magicMem)[i-MAGICMEM_BASE] +#define MMW(vi,i) (*(U16*)(&MM(vi,i))) +#define HM(vi,i) ((char*)vi->hiMem)[i-HIMEM_BASE] +#define HMW(vi,i) (*(U16*)(&MM(vi,i))) + +#define PUSHW(vi, i) \ +{ vi->vms.regs.esp -= 2;\ + LMW(vi,MAKE_POINTER(vi->vms.regs.ss, vi->vms.regs.esp)) = i;} + +VbeInfoPtr +VbeSetup() +{ + int devmem = -1, devzero = -1; + void *magicMem, *loMem, *hiMem; + U32 stack_base, vib_base, vmib_base, ret_code; + VbeInfoPtr vi = NULL; + + devmem = open("/dev/mem", O_RDWR); + if(devmem < 0) { + perror("open /dev/mem"); + goto fail; + } + + devzero = open("/dev/zero", O_RDWR); + if(devmem < 0) { + perror("open /dev/zero"); + goto fail; + } + + + magicMem = mmap((void*)MAGICMEM_BASE, MAGICMEM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devmem, MAGICMEM_BASE); + if(magicMem == MAP_FAILED) { + ErrorF("Couldn't map magic memory\n"); + goto fail; + } + + loMem = mmap((void*)LOMEM_BASE, LOMEM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devzero, LOMEM_BASE); + if(loMem == MAP_FAILED) { + ErrorF("Couldn't map low memory\n"); + munmap(magicMem, MAGICMEM_SIZE); + goto fail; + } + + hiMem = mmap((void*)HIMEM_BASE, HIMEM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED | MAP_FIXED, + devmem, HIMEM_BASE); + if(hiMem == MAP_FAILED) { + munmap(magicMem, MAGICMEM_SIZE); + munmap(loMem, LOMEM_SIZE); + goto fail; + } + + vi = xalloc(sizeof(VbeInfoRec)); + if (!vi) + goto unmapfail; + + vi->devmem = devmem; + vi->devzero = devzero; + vi->magicMem = magicMem; + vi->loMem = loMem; + vi->hiMem = hiMem; + vi->fb = NULL; + vi->brk = LOMEM_BASE; + + stack_base = VbeAllocateMemory(vi, STACK_SIZE); + if(stack_base == ALLOC_FAIL) + goto unmapfail; + ret_code = VbeAllocateMemory(vi, sizeof(retcode_data)); + if(ret_code == ALLOC_FAIL) + goto unmapfail; + vib_base = VbeAllocateMemory(vi, sizeof(VbeInfoBlock)); + if(vib_base == ALLOC_FAIL) + goto unmapfail; + vmib_base = VbeAllocateMemory(vi, sizeof(VbeModeInfoBlock)); + if(vmib_base == ALLOC_FAIL) + goto unmapfail; + + vi->stack_base = stack_base; + vi->ret_code = ret_code; + vi->vib_base = vib_base; + vi->vmib_base = vmib_base; + vi->statebuffer_base = ~0; + vi->palette_scratch_base = ~0; + vi->palette_format = 6; + vi->palette_wait = 0; + + memset(&vi->vms, 0, sizeof(struct vm86_struct)); + vi->vms.flags = 0; + vi->vms.screen_bitmap = 0; + vi->vms.cpu_type = CPU_586; + memcpy(&vi->vms.int_revectored, rev_ints, sizeof(rev_ints)); + + ioperm(0, 0x400, 1); + iopl(3); + + return vi; + + unmapfail: + munmap(magicMem, MAGICMEM_SIZE); + munmap(loMem, LOMEM_SIZE); + munmap(hiMem, HIMEM_SIZE); + fail: + if(devmem >= 0) + close(devmem); + if(devzero >= 0) + close(devzero); + if(vi) + xfree(vi); + return NULL; +} + +void +VbeCleanup(VbeInfoPtr vi) +{ + if(vi->fb) + VbeUnmapFramebuffer(vi); + munmap(vi->magicMem, MAGICMEM_SIZE); + munmap(vi->loMem, LOMEM_SIZE); + munmap(vi->hiMem, HIMEM_SIZE); + xfree(vi); +} + +VbeInfoBlock * +VbeGetInfo(VbeInfoPtr vi) +{ + int code; + VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base)); + vi->vms.regs.eax = 0x4F00; + vi->vms.regs.es = POINTER_SEGMENT(vi->vib_base); + vi->vms.regs.edi = POINTER_OFFSET(vi->vib_base); + memcpy(vib->VbeSignature, "VBE2", 4); + code = VbeDoInterrupt10(vi); + if(code < 0) + return NULL; + if(memcmp(vib->VbeSignature, "VESA", 4) != 0) { + ErrorF("Int 10 didn't return VESA signature in info block"); + return NULL; + } + return vib; +} + +VbeModeInfoBlock * +VbeGetModeInfo(VbeInfoPtr vi, int mode) +{ + int code; + U32 p; + VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base)); + VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base)); + p = MAKE_POINTER_1(vib->VideoModePtr); + if(!VbeIsMemory(vi, p)) { + ErrorF("VideoModePtr 0x%08X doesn't point at low memory\n", + vib->VideoModePtr); + return NULL; + } + vi->vms.regs.eax = 0x4F01; + vi->vms.regs.ecx = mode&0xFFFF; + vi->vms.regs.es = POINTER_SEGMENT(vi->vmib_base); + vi->vms.regs.edi = POINTER_OFFSET(vi->vmib_base); + code = VbeDoInterrupt10(vi); + if(code < 0) + return NULL; + else + return vmib; +} + +int +VbeSetMode(VbeInfoPtr vi, int mode) +{ + int code; + + vi->vms.regs.eax = 0x4F02; + vi->vms.regs.ebx = (mode & 0xFFFF) | 0xC000; + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + return 0; +} + +int +VbeGetMode(VbeInfoPtr vi, int *mode) +{ + int code; + vi->vms.regs.eax = 0x4F03; + code = VbeDoInterrupt10(vi); + if(code < 0) + return - 1; + *mode = vi->vms.regs.ebx & 0xFFFF; + return 0; +} + +int +VbeSetupStateBuffer(VbeInfoPtr vi) +{ + int code; + if(vi->statebuffer_base != ~0) + return 0; + vi->vms.regs.eax = 0x4F04; + vi->vms.regs.edx = 0x0000; + vi->vms.regs.ecx = 0x000F; + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + vi->statebuffer_base = VbeAllocateMemory(vi, vi->vms.regs.ebx & 0xFFFF); + return 0; +} + +int +VbeSaveState(VbeInfoPtr vi) +{ + int code; + code = VbeSetupStateBuffer(vi); + if(code < 0) + return -1; + vi->vms.regs.eax = 0x4F04; + vi->vms.regs.edx = 0x0001; + vi->vms.regs.ecx = 0x000F; + vi->vms.regs.es = POINTER_SEGMENT(vi->statebuffer_base); + vi->vms.regs.ebx = POINTER_OFFSET(vi->statebuffer_base); + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + return 0; +} + +int +VbeRestoreState(VbeInfoPtr vi) +{ + int code; + vi->vms.regs.eax = 0x4F04; + vi->vms.regs.edx = 0x0002; + vi->vms.regs.ecx = 0x000F; + vi->vms.regs.es = POINTER_SEGMENT(vi->statebuffer_base); + vi->vms.regs.ebx = POINTER_OFFSET(vi->statebuffer_base); + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + return 0; +} + +void * +VbeMapFramebuffer(VbeInfoPtr vi) { + U8 *fb; + VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base)); + int size; + int pagesize = getpagesize(), before, after; + + size = vmib->BytesPerScanLine * vmib->YResolution; + + before = vmib->PhysBasePtr % pagesize; + after = pagesize - ((vmib->PhysBasePtr + size) % pagesize); + if(after == pagesize) + after = 0; + + fb = mmap(0, before + size + after, + PROT_READ | PROT_WRITE, MAP_SHARED, + vi->devmem, vmib->PhysBasePtr - before); + if(fb == MAP_FAILED) { + ErrorF("Failed to map framebuffer: %d\n", errno); + return NULL; + } + + vi->fb = fb; + vi->fb_size = before + size + after; + return fb + before; +} + +int +VbeUnmapFramebuffer(VbeInfoPtr vi) +{ + int code; + if(!vi->fb) + ErrorF("Unmapping frambuffer not mapped\n"); + code = munmap(vi->fb, vi->fb_size); + if(code) { + ErrorF("Couldn't unmap framebuffer: %d\n", errno); + return -1; + } + return 0; +} + +static int +PreparePalette(VbeInfoPtr vi) +{ + int code; + if(vi->palette_scratch_base == ~0) { + vi->palette_scratch_base = VbeAllocateMemory(vi, 4*256); + if(vi->palette_scratch_base == ALLOC_FAIL) { + ErrorF("Couldn't allocate scratch area for palette transfer\n"); + return -1; + } + } + if(!vi->palette_format) { + /* This isn't used currently */ + vi->vms.regs.eax = 0x4F08; + vi->vms.regs.ebx = 0x01; + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + vi->palette_format = vi->vms.regs.ebx & 0xFF; + } + return 0; +} + +int +VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries) +{ + U8 *palette_scratch; + int i, code; + + if(number == 0) + return 0; + + code = PreparePalette(vi); + if(code < 0) + return -1; + + if(first < 0 || number < 0 || first + number > 256) { + ErrorF("Cannot set %d, %d palette entries\n", first, number); + return -1; + } + palette_scratch = &LM(vi, vi->palette_scratch_base); + + if(vi->palette_format < 6 || vi->palette_format > 8) { + ErrorF("Impossible palette format %d\n", vi->palette_format); + return -1; + } + + for(i=0; i<number*4; i++) + palette_scratch[i] = entries[i] >> (8 - vi->palette_format); + + vi->vms.regs.eax = 0x4F09; + if(vi->palette_wait) + vi->vms.regs.ebx = 0x80; + else + vi->vms.regs.ebx = 0x00; + vi->vms.regs.ecx = number; + vi->vms.regs.edx = first; + vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base); + vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base); + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + return 0; +} + +int +VbeGetPalette(VbeInfoPtr vi, int first, int number, U8 *entries) +{ + U8 *palette_scratch; + int i, code; + + code = PreparePalette(vi); + if(code < 0) + return -1; + + if(first< 0 || number < 0 || first + number > 256) { + ErrorF("Cannot get %d, %d palette entries\n", first, number); + return -1; + } + palette_scratch = &LM(vi, vi->palette_scratch_base); + + if(vi->palette_format < 6 || vi->palette_format > 8) { + ErrorF("Impossible palette format %d\n", vi->palette_format); + return -1; + } + + vi->vms.regs.eax = 0x4F09; + vi->vms.regs.ebx = 0x01; + vi->vms.regs.ecx = number; + vi->vms.regs.edx = first; + vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base); + vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base); + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + + for(i=0; i<number*4; i++) + entries[i] = palette_scratch[i] << (8-vi->palette_format); + + return 0; +} + +int +VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait) +{ + int code; + if(bits < 6 || bits > 8) { + ErrorF("Impossible palette format %d\n", vi->palette_format); + return -1; + } + ErrorF("Setting palette format to %d\n", vi->palette_format); + if(bits != vi->palette_format) { + vi->palette_format = 0; + vi->vms.regs.eax = 0x4F08; + vi->vms.regs.ebx = bits << 8; + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + vi->palette_format = bits; + } + vi->palette_wait = wait; + return 0; +} + +int +VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib) +{ + U32 i, p; + unsigned char c; + int error; + ErrorF("VBE version %c.%c (", + ((vib->VbeVersion >> 8) & 0xFF) + '0', + (vib->VbeVersion & 0xFF)+'0'); + p = vib->OemStringPtr; + for(i = 0; 1; i++) { + c = VbeMemory(vi, MAKE_POINTER_1(p+i)); + if(!c) break; + ErrorF("%c", c); + if (i > 32000) { + error = 1; + break; + } + } + ErrorF(")\n"); + ErrorF("DAC is %s, controller is %sVGA compatible%s\n", + (vib->Capabilities[0]&1)?"fixed":"switchable", + (vib->Capabilities[0]&2)?"not ":"", + (vib->Capabilities[0]&3)?", RAMDAC causes snow":""); + ErrorF("Total memory: %lu bytes\n", 64L*vib->TotalMemory); + if(error) + return -1; + return 0; +} + +int +VbeReportModeInfo(VbeInfoPtr vi, U16 mode, VbeModeInfoBlock *vmib) +{ + int supported = (vmib->ModeAttributes&0x1)?1:0; + int colour = (vmib->ModeAttributes&0x8)?1:0; + int graphics = (vmib->ModeAttributes&0x10)?1:0; + int vga_compatible = !((vmib->ModeAttributes&0x20)?1:0); + int linear_fb = (vmib->ModeAttributes&0x80)?1:0; + + ErrorF("0x%04X: %dx%dx%d%s", + (unsigned)mode, + (int)vmib->XResolution, (int)vmib->YResolution, + (int)vmib->BitsPerPixel, + colour?"":" (monochrome)"); + switch(vmib->MemoryModel) { + case 0: + ErrorF(" text mode (%dx%d)", + (int)vmib->XCharSize, (int)vmib->YCharSize); + break; + case 1: + ErrorF(" CGA graphics"); + break; + case 2: + ErrorF(" Hercules graphics"); + break; + case 3: + ErrorF(" Planar (%d planes)", vmib->NumberOfPlanes); + break; + case 4: + ErrorF(" PseudoColor"); + break; + case 5: + ErrorF(" Non-chain 4, 256 colour"); + break; + case 6: + if(vmib->DirectColorModeInfo & 1) + ErrorF(" DirectColor"); + else + ErrorF(" TrueColor"); + ErrorF(" [%d:%d:%d:%d]", + vmib->RedMaskSize, vmib->GreenMaskSize, vmib->BlueMaskSize, + vmib->RsvdMaskSize); + if(vmib->DirectColorModeInfo & 2) + ErrorF(" (reserved bits are reserved)"); + break; + case 7: ErrorF("YUV"); + break; + default: + ErrorF("unknown MemoryModel 0x%X ", vmib->MemoryModel); + } + if(!supported) + ErrorF(" (unsupported)"); + else if(!linear_fb) + ErrorF(" (no linear framebuffer)"); + ErrorF("\n"); + return 0; +} +int +VbeDoInterrupt10(VbeInfoPtr vi) +{ + int code; + int oldax; + + oldax = vi->vms.regs.eax & 0xFFFF; + + code = VbeDoInterrupt(vi, 0x10); + + if(code < 0) + return -1; + + if((vi->vms.regs.eax & 0xFFFF) != 0x4F) { + ErrorF("Int 10h (0x%04X) failed: 0x%04X", + oldax, vi->vms.regs.eax & 0xFFFF); + if((oldax & 0xFF00) == 0x4F00) { + switch((vi->vms.regs.eax & 0xFF00)>>8) { + case 0: + ErrorF(" (success)\n"); + break; + case 1: + ErrorF(" (function call failed)\n"); + break; + case 2: + ErrorF(" (function not supported on this hardware)\n"); + break; + case 3: + ErrorF(" (function call invalid in this video mode)\n"); + break; + default: + ErrorF(" (unknown error)\n"); + break; + } + return -1; + } else { + ErrorF("\n"); + } + } + return code; +} + +int +VbeDoInterrupt(VbeInfoPtr vi, int num) +{ + U16 seg, off; + int code; + + if(num < 0 || num>256) { + ErrorF("Interrupt %d doesn't exist\n"); + return -1; + } + seg = MMW(vi,num * 4 + 2); + off = MMW(vi,num * 4); + if(MAKE_POINTER(seg, off) < ROM_BASE || + MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) { + ErrorF("Interrupt pointer doesn't point at ROM\n"); + return -1; + } + memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data)); + vi->vms.regs.eflags = IF_MASK | IOPL_MASK; + vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base); + vi->vms.regs.esp = STACK_SIZE; + PUSHW(vi, IF_MASK | IOPL_MASK); + PUSHW(vi, POINTER_SEGMENT(vi->ret_code)); + PUSHW(vi, POINTER_OFFSET(vi->ret_code)); + vi->vms.regs.cs = seg; + vi->vms.regs.eip = off; + code = vm86_loop(vi); + if(code < 0) { + perror("vm86 failed"); + return -1; + } else if(code != 0) { + ErrorF("vm86 returned 0x%04X\n", code); + return -1; + } else + return 0; +} + +static int +vm86_loop(VbeInfoPtr vi) +{ + int code; + while(1) { + code = vm86old(&vi->vms); + switch(VM86_TYPE(code)) { + case VM86_SIGNAL: + continue; + case VM86_UNKNOWN: + ErrorF("Unhandled GP fault in VM86 code\n", + VM86_ARG(code)); + return -1; + break; + case VM86_INTx: + if(VM86_ARG(code) == 0xFF) + return 0; + else { + PUSHW(vi, vi->vms.regs.eflags) + PUSHW(vi, vi->vms.regs.cs); + PUSHW(vi, vi->vms.regs.eip); + vi->vms.regs.cs = MMW(vi,VM86_ARG(code) * 4 + 2); + vi->vms.regs.eip = MMW(vi,VM86_ARG(code) * 4); + } + break; + case VM86_STI: + ErrorF("VM86 code enabled interrupts\n"); + return -1; + default: + ErrorF("Unexpected result code 0x%X from vm86\n", code); + } + } +} + +int +VbeIsMemory(VbeInfoPtr vi, U32 i) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + return 1; + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + return 1; + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + return 1; + else + return 0; +} + +U8 +VbeMemory(VbeInfoPtr vi, U32 i) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + return MM(vi, i); + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + return LM(vi, i); + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + return HM(vi, i); + else { + ErrorF("Reading unmapped memory at 0x%08X\n", i); + } +} + +U16 +VbeMemoryW(VbeInfoPtr vi, U32 i) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + return MMW(vi, i); + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + return LMW(vi, i); + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + return HMW(vi, i); + else { + ErrorF("Reading unmapped memory at 0x%08X\n", i); + return 0; + } +} + +void +VbeWriteMemory(VbeInfoPtr vi, U32 i, U8 val) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + MM(vi, i) = val; + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + LM(vi, i) = val; + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + HM(vi, i) = val; + else { + ErrorF("Writing unmapped memory at 0x%08X\n", i); + } +} + +int +VbeAllocateMemory(VbeInfoPtr vi, int n) +{ + int ret; + if(n<0) { + ErrorF("Asked to allocate negative amount of memory\n"); + return vi->brk; + } + + n = (n + 15) & ~15; + if(vi->brk + n > LOMEM_BASE + LOMEM_SIZE) { + ErrorF("Out of low memory\n"); + exit(2); + } + ret = vi->brk; + vi->brk += n; + return ret; +} + +static int +vm86old(struct vm86_struct *vm) +{ + int res; + asm volatile ( + "pushl %%ebx\n\t" + "movl %2, %%ebx\n\t" + "movl %1,%%eax\n\t" + "int $0x80\n\t" + "popl %%ebx" + : "=a" (res) : "n" (113), "r" (vm)); + if(res < 0) { + errno = -res; + res = -1; + } else + errno = 0; + return res; +} + +#ifdef NOT_IN_X_SERVER +static void +ErrorF(char *f, ...) +{ + va_list args; + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); +} +#endif diff --git a/hw/kdrive/vesa/vbe.h b/hw/kdrive/vesa/vbe.h new file mode 100644 index 000000000..1b6c9630e --- /dev/null +++ b/hw/kdrive/vesa/vbe.h @@ -0,0 +1,166 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86$ */ + +#ifndef _VBE_H +#define _VBE_H + +#ifndef U8 +#define U8 unsigned char +#define U16 unsigned short +#define U32 unsigned int +#endif + +/* The whole addressable memory */ +#define SYSMEM_BASE 0x00000 +#define SYSMEM_SIZE 0x100000 + +/* Interrupt vectors and BIOS data area */ +/* This is allocated privately from /dev/mem */ +#define MAGICMEM_BASE 0x00000 +#define MAGICMEM_SIZE 0x01000 + +/* The low memory, allocated privately from /dev/zero */ +/* 64KB should be enough for anyone, as they used to say */ +#define LOMEM_BASE 0x10000 +#define LOMEM_SIZE 0x10000 + +/* The video memory and BIOS ROM, allocated shared from /dev/mem */ +#define HIMEM_BASE 0xA0000 +#define HIMEM_SIZE (SYSMEM_BASE + SYSMEM_SIZE - HIMEM_BASE) + +/* The BIOS ROM */ +#define ROM_BASE 0xC0000 +#define ROM_SIZE 0x30000 + +#define STACK_SIZE 0x1000 + +#define POINTER_SEGMENT(ptr) (((unsigned int)ptr)>>4) +#define POINTER_OFFSET(ptr) (((unsigned int)ptr)&0x000F) +#define MAKE_POINTER(seg, off) (((((unsigned int)(seg))<<4) + (unsigned int)(off))) +#define MAKE_POINTER_1(lw) MAKE_POINTER(((lw)&0xFFFF0000)/0x10000, (lw)&0xFFFF) +#define ALLOC_FAIL ((U32)-1) + +typedef struct _VbeInfoRec { + int devmem, devzero; + void *magicMem, *loMem, *hiMem, *fb; + U32 fb_size; + U32 brk; + struct vm86_struct vms; + U32 ret_code, stack_base, vib_base, vmib_base, statebuffer_base, palette_scratch_base; + U8 palette_format; + int palette_wait; +} VbeInfoRec, *VbeInfoPtr; + +typedef struct _VbeInfoBlock { + U8 VbeSignature[4]; /* VBE Signature */ + U16 VbeVersion; /* VBE Version */ + U32 OemStringPtr; /* Pointer to OEM String */ + U8 Capabilities[4]; /* Capabilities of graphics controller */ + U32 VideoModePtr; /* Pointer to VideoModeList */ + U16 TotalMemory; /* Number of 64kb memory blocks */ +/* Added for VBE 2.0 */ + U16 OemSoftwareRev; /* VBE implementation Software revision */ + U32 OemVendorNamePtr; /* Pointer to Vendor Name String */ + U32 OemProductNamePtr; /* Pointer to Product Name String */ + U32 OemProductRevPtr; /* Pointer to Product Revision String */ + U8 Reserved[222]; /* Reserved for VBE implementation */ + U8 OemData[256]; /* Data Area for OEM Strings*/ +} __attribute__((packed)) VbeInfoBlock; + +typedef struct _VbeModeInfoBlock { +/* Mandatory information for all VBE revisions */ + U16 ModeAttributes; /* mode attributes */ + U8 WinAAttributes; /* window A attributes */ + U8 WinBAttributes; /* window B attributes */ + U16 WinGranularity; /* window granularity */ + U16 WinSize; /* window size */ + U16 WinASegment; /* window A start segment */ + U16 WinBSegment; /* window B start segment */ + U32 WinFuncPtr; /* pointer to window function */ + U16 BytesPerScanLine; /* bytes per scan line */ +/* Mandatory information for VBE 1.2 and above */ + U16 XResolution; /* horizontal resolution */ + U16 YResolution; /* vertical resolution */ + U8 XCharSize; /* character cell width in pixels */ + U8 YCharSize; /* character cell height in pixels */ + U8 NumberOfPlanes; /* number of memory planes */ + U8 BitsPerPixel; /* bits per pixel */ + U8 NumberOfBanks; /* number of banks */ + U8 MemoryModel; /* memory model type */ + U8 BankSize; /* bank size in KB */ + U8 NumberOfImagePages; /* number of images */ + U8 Reserved; /* reserved for page function */ +/* Direct Color fields (required for direct/6 and YUV/7 memory models) */ + U8 RedMaskSize; /* size of direct color red mask in bits */ + U8 RedFieldPosition; /* bit position of lsb of red mask */ + U8 GreenMaskSize; /* size of direct color green mask in bits */ + U8 GreenFieldPosition; /* bit position of lsb of green mask */ + U8 BlueMaskSize; /* size of direct color blue mask in bits */ + U8 BlueFieldPosition; /* bit position of lsb of blue mask */ + U8 RsvdMaskSize; /* size of direct color reserved mask bits*/ + U8 RsvdFieldPosition; /* bit position of lsb of reserved mask */ + U8 DirectColorModeInfo; /* direct color mode attributes */ +/* Mandatory information for VBE 2.0 and above */ + U32 PhysBasePtr; /* physical address for flat memory fb */ + U32 OffScreenMemOffset; /* pointer to start of off screen memory */ + U16 OffScreenMemSize; /* amount of off screen memory in 1k units */ + U8 Reserved2[206]; /* remainder of ModeInfoBlock */ +} __attribute__((packed)) VbeModeInfoBlock; + + +typedef struct _SupVbeInfoBlock { + U8 SupVbeSignature[7]; /* Supplemental VBE Signature */ + U16 SupVbeVersion; /* Supplemental VBE Version*/ + U8 SupVbeSubFunc[8]; /* Bitfield of supported subfunctions */ + U16 OemSoftwareRev; /* OEM Software revision */ + U32 OemVendorNamePtr; /* Pointer to Vendor Name String */ + U32 OemProductNamePtr; /* Pointer to Product Name String */ + U32 OemProductRevPtr; /* Pointer to Product Revision String */ + U32 OemStringPtr; /* Pointer to OEM String */ + U8 Reserved[221]; /* Reserved */ +} __attribute__((packed)) SupVbeInfoBlock; + +VbeInfoPtr VbeSetup(void); +void VbeCleanup(VbeInfoPtr vi); +VbeInfoBlock *VbeGetInfo(VbeInfoPtr vi); +VbeModeInfoBlock *VbeGetModeInfo(VbeInfoPtr vi, int mode); +int VbeSetMode(VbeInfoPtr vi, int mode); +int VbeGetMode(VbeInfoPtr vi, int *mode); +int VbeSetupStateBuffer(VbeInfoPtr vi); +int VbeSaveState(VbeInfoPtr vi); +int VbeRestoreState(VbeInfoPtr vi); +void *VbeMapFramebuffer(VbeInfoPtr vi); +int VbeUnmapFrambuffer(VbeInfoPtr vi); +int VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries); +int VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait); +int VbeReportInfo(VbeInfoPtr, VbeInfoBlock *); +int VbeReportModeInfo(VbeInfoPtr, U16 mode, VbeModeInfoBlock *); + +int VbeDoInterrupt(VbeInfoPtr, int num); +int VbeDoInterrupt10(VbeInfoPtr vi); +int VbeIsMemory(VbeInfoPtr vi, U32 i); +U8 VbeMemory(VbeInfoPtr, U32); +U16 VbeMemoryW(VbeInfoPtr, U32); +void VbeWriteMemory(VbeInfoPtr, U32, U8); +int VbeAllocateMemory(VbeInfoPtr, int); +#endif diff --git a/hw/kdrive/vesa/vesa.c b/hw/kdrive/vesa/vesa.c new file mode 100644 index 000000000..cb72ea74d --- /dev/null +++ b/hw/kdrive/vesa/vesa.c @@ -0,0 +1,313 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86$ */ + +#include "vesa.h" + +#define DEFAULT_MODE 0x115 + +int vesa_video_mode = DEFAULT_MODE; +Bool vesa_force_mode = FALSE; + +static Bool +vesaModeSupported(VbeInfoPtr vi, VbeModeInfoBlock *vmib, Bool complain) +{ + if((vmib->ModeAttributes & 0x10) == 0) { + if(complain) + ErrorF("Text mode specified.\n"); + return FALSE; + } + if(vmib->MemoryModel != 0x06 && vmib->MemoryModel != 0x04) { + if(complain) + ErrorF("Unsupported memory model 0x%X\n", vmib->MemoryModel); + return FALSE; + } + if((vmib->ModeAttributes & 0x80) == 0) { + if(complain) + ErrorF("No linear framebuffer available in this mode\n"); + return FALSE; + } + if(!(vmib->ModeAttributes&1)) { + if(complain) + ErrorF("Mode not supported on this hardware\n"); + return FALSE; + } + return TRUE; +} + +Bool +vesaListModes() +{ + int code; + VbeInfoPtr vi = NULL; + VbeInfoBlock *vib; + VbeModeInfoBlock *vmib; + unsigned i; + + vi = VbeSetup(); + if(!vi) + goto fail; + + vib = VbeGetInfo(vi); + if(!vib) + goto fail; + + VbeReportInfo(vi, vib); + i = MAKE_POINTER_1(vib->VideoModePtr); + + while(VbeMemoryW(vi, i) != 0xFFFF) { + vmib = VbeGetModeInfo(vi, VbeMemoryW(vi, i)); + if(!vmib) + goto fail; + if(vesa_force_mode || vesaModeSupported(vi, vmib, FALSE)) + VbeReportModeInfo(vi, VbeMemoryW(vi, i), vmib); + i+=2; + } + + VbeCleanup(vi); + return TRUE; + + fail: + VbeCleanup(vi); + return FALSE; +} + +Bool +vesaCardInit(KdCardInfo *card) +{ + VesaPrivPtr priv; + int code; + + priv = xalloc(sizeof(VesaPrivRec)); + if(!priv) + goto fail; + + priv->mode = vesa_video_mode; + + priv->vi = VbeSetup(); + if(!priv->vi) + goto fail; + + priv->vib = VbeGetInfo(priv->vi); + if(!priv->vib) + goto fail; + + priv->vmib = VbeGetModeInfo(priv->vi, priv->mode); + if(!priv->vmib) + goto fail; + + if(!vesa_force_mode && !vesaModeSupported(priv->vi, priv->vmib, TRUE)) + goto fail; + + code = VbeSetupStateBuffer(priv->vi); + if(code < 0) + goto fail; + + code = VbeSaveState(priv->vi); + if(code<0) + goto fail; + + priv->fb = VbeMapFramebuffer(priv->vi); + if(!priv->vi) + goto fail; + + card->driver = priv; + + return TRUE; + + fail: + if(priv) { + if(priv->vi) + VbeCleanup(priv->vi); + xfree(priv); + } + return FALSE; +} + +Bool +vesaScreenInit(KdScreenInfo *screen) +{ + VesaPrivPtr priv = screen->card->driver; + Pixel allbits; + int depth; + + screen->width = priv->vmib->XResolution; + screen->height = priv->vmib->YResolution; + screen->fb[0].depth = priv->vmib->BitsPerPixel; + screen->fb[0].bitsPerPixel = priv->vmib->BitsPerPixel; + screen->fb[0].byteStride = priv->vmib->BytesPerScanLine; + screen->fb[0].pixelStride = + (priv->vmib->BytesPerScanLine * 8) / priv->vmib->BitsPerPixel; + + if(priv->vmib->MemoryModel == 0x06) { + /* TrueColor or DirectColor */ + screen->fb[0].visuals = (1 << TrueColor); + screen->fb[0].redMask = + FbStipMask(priv->vmib->RedFieldPosition, priv->vmib->RedMaskSize); + screen->fb[0].greenMask = + FbStipMask(priv->vmib->GreenFieldPosition, priv->vmib->GreenMaskSize); + screen->fb[0].blueMask = + FbStipMask(priv->vmib->BlueFieldPosition, priv->vmib->BlueMaskSize); + allbits = + screen->fb[0].redMask | + screen->fb[0].greenMask | + screen->fb[0].blueMask; + depth = 32; + while (depth && !(allbits & (1 << (depth - 1)))) + depth--; + screen->fb[0].depth = depth; + } else if (priv->vmib->MemoryModel == 0x04) { + /* PseudoColor */ + screen->fb[0].visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor) | + (1 << PseudoColor) | + (1 << TrueColor) | + (1 << DirectColor)); + screen->fb[0].blueMask = 0x00; + screen->fb[0].greenMask = 0x00; + screen->fb[0].redMask = 0x00; + } else { + ErrorF("Unsupported VESA MemoryModel 0x%02X\n", + priv->vmib->MemoryModel); + return FALSE; + } + + screen->rate = 72; + screen->fb[0].frameBuffer = (CARD8 *)(priv->fb); + + return TRUE; +} + +Bool +vesaInitScreen(ScreenPtr pScreen) +{ + return TRUE; +} + +void +vesaEnable(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaPrivPtr priv = pScreenPriv->card->driver; + int code; + int palette_wait = 0, palette_hi = 0; + + code = VbeSetMode(priv->vi, priv->mode); + if(code < 0) + FatalError("Couldn't set mode\n"); + + if(priv->vib->Capabilities[0] & 1) + palette_hi = 1; + if(priv->vib->Capabilities[0] & 4) + palette_wait = 1; + if(palette_hi || palette_wait) + VbeSetPaletteOptions(priv->vi, palette_hi?8:6, palette_wait); + + return; +} + +void +vesaDisable(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaPrivPtr priv = pScreenPriv->card->driver; + +} + +void +vesaPreserve(KdCardInfo *card) +{ + VesaPrivPtr priv = card->driver; + int code; + + code = VbeSaveState(priv->vi); + if(code < 0) + FatalError("Couldn't save state\n"); + + return; +} + +void +vesaRestore(KdCardInfo *card) +{ + VesaPrivPtr priv = card->driver; + VbeRestoreState(priv->vi); + return; +} + +void +vesaCardFini(KdCardInfo *card) +{ + VesaPrivPtr priv = card->driver; + VbeUnmapFramebuffer(priv->vi); + VbeCleanup(priv->vi); + return; +} + +void +vesaScreenFini(KdScreenInfo *screen) +{ + return; +} + +void +vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) +{ + KdScreenPriv(pScreen); + VesaPrivPtr priv = pScreenPriv->card->driver; + int i, j, k; + CARD8 scratch[4*256]; + + i = 0; + while(i < n) { + j = i + 1; + /* For some reason, doing more than one entry at a time breaks */ + while(j < n && pdefs[j].pixel == pdefs[j-1].pixel + 1 && j - i < 1) + j++; + for(k=0; k<(j - i); k++) { + /* The opposite of what the spec says? */ + scratch[k+3] = 0; + scratch[k+2] = pdefs[i+k].red >> 8; + scratch[k+1] = pdefs[i+k].green >> 8; + scratch[k+0] = pdefs[i+k].blue >> 8; + } + VbeSetPalette(priv->vi, pdefs[i].pixel, j - i, scratch); + i = j; + } +} + +void +vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) +{ + KdScreenPriv(pScreen); + VesaPrivPtr priv = pScreenPriv->card->driver; + int first, i, j, k; + CARD8 scratch[4]; + + for(i = 0; i<n; i++) { + VbeGetPalette(priv->vi, pdefs[i].pixel, 1, scratch); + pdefs[i].red = scratch[2]<<8; + pdefs[i].green = scratch[1]<<8; + pdefs[i].blue = scratch[0]<<8; + } +} diff --git a/hw/kdrive/vesa/vesa.h b/hw/kdrive/vesa/vesa.h new file mode 100644 index 000000000..d6306bb56 --- /dev/null +++ b/hw/kdrive/vesa/vesa.h @@ -0,0 +1,56 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86$ */ + +#ifndef _VESA_H_ +#define _VESA_H_ + +#include "kdrive.h" +#include <sys/vm86.h> +#include "vbe.h" + +typedef struct _VesaPriv { + int mode; + VbeInfoPtr vi; + VbeInfoBlock *vib; + VbeModeInfoBlock *vmib; + void *fb; +} VesaPrivRec, *VesaPrivPtr; + +extern int vesa_video_mode; +extern Bool vesa_force_mode; + +Bool vesaListModes(void); +Bool vesaInitialize(KdCardInfo *card, VesaPrivPtr priv); +Bool vesaCardInit(KdCardInfo *card); +Bool vesaScreenInit(KdScreenInfo *screen); +Bool vesaInitScreen(ScreenPtr pScreen); +void vesaEnable(ScreenPtr pScreen); +void vesaDisable(ScreenPtr pScreen); +void vesaPreserve(KdCardInfo *card); +void vesaRestore(KdCardInfo *card); +void vesaCardFini(KdCardInfo *card); +void vesaScreenFini(KdScreenInfo *screen); +void vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs); +void vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs); + +#endif _VESA_H_ diff --git a/hw/kdrive/vesa/vesainit.c b/hw/kdrive/vesa/vesainit.c new file mode 100644 index 000000000..58fe3fed6 --- /dev/null +++ b/hw/kdrive/vesa/vesainit.c @@ -0,0 +1,91 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86$ */ + +#include "vesa.h" + +KdCardFuncs vesaFuncs = { + vesaCardInit, /* cardinit */ + vesaScreenInit, /* scrinit */ + vesaInitScreen, /* initScreen */ + vesaPreserve, /* preserve */ + vesaEnable, /* enable */ + 0, /* dpms */ + vesaDisable, /* disable */ + vesaRestore, /* restore */ + vesaScreenFini, /* scrfini */ + vesaCardFini, /* cardfini */ + + 0, /* initCursor */ + 0, /* enableCursor */ + 0, /* disableCursor */ + 0, /* finiCursor */ + 0, /* recolorCursor */ + + 0, /* initAccel */ + 0, /* enableAccel */ + 0, /* syncAccel */ + 0, /* disableAccel */ + 0, /* finiAccel */ + + vesaGetColors, /* getColors */ + vesaPutColors, /* putColors */ +}; + +void +InitCard(char *name) +{ + KdCardAttr attr; + KdCardInfoAdd(&vesaFuncs, &attr, 0); +} + +void +InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) +{ + KdInitOutput (pScreenInfo, argc, argv); +} + +void +InitInput (int argc, char **argv) +{ + KdInitInput(&Ps2MouseFuncs, &LinuxKeyboardFuncs); +} + +int +ddxProcessArgument (int argc, char **argv, int i) +{ + if(!strcmp(argv[i], "-mode")) { + if(i+1 < argc) { + vesa_video_mode = strtol(argv[i+1], NULL, 0); + } else + UseMsg(); + return 2; + } else if(!strcmp(argv[i], "-force")) { + vesa_force_mode = TRUE; + return 1; + } else if(!strcmp(argv[i], "-listmodes")) { + vesaListModes(); + exit(0); + } + + return KdProcessArgument(argc, argv, i); +} |