summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/vgavmware.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/9/pc/vgavmware.c370
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,
+};