diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/pc/vgavmware.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/pc/vgavmware.c')
-rwxr-xr-x | sys/src/9/pc/vgavmware.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/sys/src/9/pc/vgavmware.c b/sys/src/9/pc/vgavmware.c new file mode 100755 index 000000000..60c8cfa73 --- /dev/null +++ b/sys/src/9/pc/vgavmware.c @@ -0,0 +1,370 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +#define Image IMAGE +#include <draw.h> +#include <memdraw.h> +#include <cursor.h> +#include "screen.h" + +enum { + PCIVMWARE = 0x15AD, /* PCI VID */ + + VMWARE1 = 0x0710, /* PCI DID */ + VMWARE2 = 0x0405, +}; + +enum { + Rid = 0, + Renable, + Rwidth, + Rheight, + Rmaxwidth, + + Rmaxheight, + Rdepth, + Rbpp, + Rpseudocolor, + Rrmask, + + Rgmask, + Rbmask, + Rbpl, + Rfbstart, + Rfboffset, + + Rfbmaxsize, + Rfbsize, + Rcap, + Rmemstart, + Rmemsize, + + Rconfigdone, + Rsync, + Rbusy, + Rguestid, + Rcursorid, + + Rcursorx, + Rcursory, + Rcursoron, + Nreg, + + Crectfill = 1<<0, + Crectcopy = 1<<1, + Crectpatfill = 1<<2, + Coffscreen = 1<<3, + Crasterop = 1<<4, + Ccursor = 1<<5, + Ccursorbypass = 1<<6, + Ccursorbypass2 = 1<<7, + C8bitemulation = 1<<8, + Calphacursor = 1<<9, + + FifoMin = 0, + FifoMax = 1, + FifoNextCmd = 2, + FifoStop = 3, + FifoUser = 4, + + Xupdate = 1, + Xrectfill = 2, + Xrectcopy = 3, + Xdefinebitmap = 4, + Xdefinebitmapscanline = 5, + Xdefinepixmap = 6, + Xdefinepixmapscanline = 7, + Xrectbitmapfill = 8, + Xrectpixmapfill = 9, + Xrectbitmapcopy = 10, + Xrectpixmapcopy = 11, + Xfreeobject = 12, + Xrectropfill = 13, + Xrectropcopy = 14, + Xrectropbitmapfill = 15, + Xrectroppixmapfill = 16, + Xrectropbitmapcopy = 17, + Xrectroppixmapcopy = 18, + Xdefinecursor = 19, + Xdisplaycursor = 20, + Xmovecursor = 21, + Xdefinealphacursor = 22, + Xcmdmax = 23, + + CursorOnHide = 0, + CursorOnShow = 1, + CursorOnRemoveFromFb = 2, + CursorOnRestoreToFb = 3, + + Rpalette = 1024, +}; + +typedef struct Vmware Vmware; +struct Vmware { + ulong fb; + + ulong ra; + ulong rd; + + ulong r[Nreg]; + ulong *mmio; + ulong mmiosize; + + char chan[32]; + int depth; +}; + +Vmware xvm; +Vmware *vm=&xvm; + +static ulong +vmrd(Vmware *vm, int i) +{ + outl(vm->ra, i); + return inl(vm->rd); +} + +static void +vmwr(Vmware *vm, int i, ulong v) +{ + outl(vm->ra, i); + outl(vm->rd, v); +} + +static void +vmwait(Vmware *vm) +{ + vmwr(vm, Rsync, 1); + while(vmrd(vm, Rbusy)) + ; +} + +static void +vmwarelinear(VGAscr* scr, int, int) +{ + char err[64]; + Pcidev *p; + + err[0] = 0; + p = nil; + while((p = pcimatch(p, PCIVMWARE, 0)) != nil){ + if(p->ccrb != Pcibcdisp) + continue; + switch(p->did){ + default: + snprint(err, sizeof err, "unknown vmware pci did %.4ux", + p->did); + continue; + + case VMWARE1: + vm->ra = 0x4560; + vm->rd = 0x4560 + 4; + break; + + case VMWARE2: + vm->ra = p->mem[0].bar & ~3; + vm->rd = vm->ra + 1; + break; + } + break; /* found a card, p is set */ + } + if(p == nil) + error(err[0]? err: "no vmware vga card found"); + + vgalinearaddr(scr, vmrd(vm, Rfbstart), vmrd(vm, Rfbsize)); + if(scr->apsize) + addvgaseg("vmwarescreen", scr->paddr, scr->apsize); +} + +static void +vmfifowr(Vmware *vm, ulong v) +{ + ulong *mm; + + mm = vm->mmio; + if(mm == nil){ + iprint("!"); + return; + } + + if(mm[FifoNextCmd]+sizeof(ulong) == mm[FifoStop] + || (mm[FifoNextCmd]+sizeof(ulong) == mm[FifoMax] + && mm[FifoStop] == mm[FifoMin])) + vmwait(vm); + + mm[mm[FifoNextCmd]/sizeof(ulong)] = v; + + /* must do this way so mm[FifoNextCmd] is never mm[FifoMax] */ + v = mm[FifoNextCmd] + sizeof(ulong); + if(v == mm[FifoMax]) + v = mm[FifoMin]; + mm[FifoNextCmd] = v; +} + +static void +vmwareflush(VGAscr*, Rectangle r) +{ + if(vm->mmio == nil) + return; + + vmfifowr(vm, Xupdate); + vmfifowr(vm, r.min.x); + vmfifowr(vm, r.min.y); + vmfifowr(vm, r.max.x-r.min.x); + vmfifowr(vm, r.max.y-r.min.y); + vmwait(vm); +} + +static void +vmwareload(VGAscr*, Cursor *c) +{ + int i; + ulong clr, set; + ulong and[16]; + ulong xor[16]; + + if(vm->mmio == nil) + return; + vmfifowr(vm, Xdefinecursor); + vmfifowr(vm, 1); /* cursor id */ + vmfifowr(vm, -c->offset.x); + vmfifowr(vm, -c->offset.y); + + vmfifowr(vm, 16); /* width */ + vmfifowr(vm, 16); /* height */ + vmfifowr(vm, 1); /* depth for and mask */ + vmfifowr(vm, 1); /* depth for xor mask */ + + for(i=0; i<16; i++){ + clr = (c->clr[i*2+1]<<8) | c->clr[i*2]; + set = (c->set[i*2+1]<<8) | c->set[i*2]; + and[i] = ~(clr|set); /* clr and set pixels => black */ + xor[i] = clr&~set; /* clr pixels => white */ + } + for(i=0; i<16; i++) + vmfifowr(vm, and[i]); + for(i=0; i<16; i++) + vmfifowr(vm, xor[i]); + + vmwait(vm); +} + +static int +vmwaremove(VGAscr*, Point p) +{ + vmwr(vm, Rcursorid, 1); + vmwr(vm, Rcursorx, p.x); + vmwr(vm, Rcursory, p.y); + vmwr(vm, Rcursoron, CursorOnShow); + return 0; +} + +static void +vmwaredisable(VGAscr*) +{ + vmwr(vm, Rcursorid, 1); + vmwr(vm, Rcursoron, CursorOnHide); +} + +static void +vmwareenable(VGAscr*) +{ + vmwr(vm, Rcursorid, 1); + vmwr(vm, Rcursoron, CursorOnShow); +} + +static void +vmwareblank(int) +{ +} + +static int +vmwarescroll(VGAscr*, Rectangle r, Rectangle sr) +{ + if(vm->mmio == nil) + return 0; + vmfifowr(vm, Xrectcopy); + vmfifowr(vm, sr.min.x); + vmfifowr(vm, sr.min.y); + vmfifowr(vm, r.min.x); + vmfifowr(vm, r.min.y); + vmfifowr(vm, Dx(r)); + vmfifowr(vm, Dy(r)); + vmwait(vm); + return 1; +} + +static int +vmwarefill(VGAscr*, Rectangle r, ulong sval) +{ + if(vm->mmio == nil) + return 0; + vmfifowr(vm, Xrectfill); + vmfifowr(vm, sval); + vmfifowr(vm, r.min.x); + vmfifowr(vm, r.min.y); + vmfifowr(vm, r.max.x-r.min.x); + vmfifowr(vm, r.max.y-r.min.y); + vmwait(vm); + return 1; +} + +static void +vmwaredrawinit(VGAscr *scr) +{ + ulong offset; + ulong mmiobase, mmiosize; + + if(scr->mmio==nil){ + mmiobase = vmrd(vm, Rmemstart); + if(mmiobase == 0) + return; + mmiosize = vmrd(vm, Rmemsize); + scr->mmio = vmap(mmiobase, mmiosize); + if(scr->mmio == nil) + return; + vm->mmio = scr->mmio; + vm->mmiosize = mmiosize; + addvgaseg("vmwaremmio", mmiobase, mmiosize); + } + + scr->mmio[FifoMin] = 4*sizeof(ulong); + scr->mmio[FifoMax] = vm->mmiosize; + scr->mmio[FifoNextCmd] = 4*sizeof(ulong); + scr->mmio[FifoStop] = 4*sizeof(ulong); + vmwr(vm, Rconfigdone, 1); + + scr->scroll = vmwarescroll; + scr->fill = vmwarefill; + + offset = vmrd(vm, Rfboffset); + scr->gscreendata->bdata += offset; +} + +VGAdev vgavmwaredev = { + "vmware", + + 0, + 0, + 0, + vmwarelinear, + vmwaredrawinit, + 0, + 0, + 0, + vmwareflush, +}; + +VGAcur vgavmwarecur = { + "vmwarehwgc", + + vmwareenable, + vmwaredisable, + vmwareload, + vmwaremove, +}; |