]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgavmware.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / 9 / pc / vgavmware.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8
9 #define Image   IMAGE
10 #include <draw.h>
11 #include <memdraw.h>
12 #include <cursor.h>
13 #include "screen.h"
14
15 enum {
16         PCIVMWARE       = 0x15AD,       /* PCI VID */
17
18         VMWARE1         = 0x0710,       /* PCI DID */
19         VMWARE2         = 0x0405,
20 };
21
22 enum {
23         Rid = 0,
24         Renable,
25         Rwidth,
26         Rheight,
27         Rmaxwidth,
28
29         Rmaxheight,
30         Rdepth,
31         Rbpp,
32         Rpseudocolor,
33         Rrmask,
34
35         Rgmask,
36         Rbmask,
37         Rbpl,
38         Rfbstart,
39         Rfboffset,
40
41         Rfbmaxsize,
42         Rfbsize,
43         Rcap,
44         Rmemstart,
45         Rmemsize,
46
47         Rconfigdone,
48         Rsync,
49         Rbusy,
50         Rguestid,
51         Rcursorid,
52
53         Rcursorx,
54         Rcursory,
55         Rcursoron,
56         Nreg,
57
58         Crectfill = 1<<0,
59         Crectcopy = 1<<1,
60         Crectpatfill = 1<<2,
61         Coffscreen = 1<<3,
62         Crasterop = 1<<4,
63         Ccursor = 1<<5,
64         Ccursorbypass = 1<<6,
65         Ccursorbypass2 = 1<<7,
66         C8bitemulation = 1<<8,
67         Calphacursor = 1<<9,
68
69         FifoMin = 0,
70         FifoMax = 1,
71         FifoNextCmd = 2,
72         FifoStop = 3,
73         FifoUser = 4,
74
75         Xupdate = 1,
76         Xrectfill = 2,
77         Xrectcopy = 3,
78         Xdefinebitmap = 4,
79         Xdefinebitmapscanline = 5,
80         Xdefinepixmap = 6,
81         Xdefinepixmapscanline = 7,
82         Xrectbitmapfill = 8,
83         Xrectpixmapfill = 9,
84         Xrectbitmapcopy = 10,
85         Xrectpixmapcopy = 11,
86         Xfreeobject = 12,
87         Xrectropfill = 13,
88         Xrectropcopy = 14,
89         Xrectropbitmapfill = 15,
90         Xrectroppixmapfill = 16,
91         Xrectropbitmapcopy = 17,
92         Xrectroppixmapcopy = 18,
93         Xdefinecursor = 19,
94         Xdisplaycursor = 20,
95         Xmovecursor = 21,
96         Xdefinealphacursor = 22,
97         Xcmdmax = 23,
98
99         CursorOnHide = 0,
100         CursorOnShow = 1,
101         CursorOnRemoveFromFb = 2,
102         CursorOnRestoreToFb = 3,
103
104         Rpalette = 1024,
105 };
106
107 typedef struct Vmware   Vmware;
108 struct Vmware {
109         ulong   fb;
110
111         ulong   ra;
112         ulong   rd;
113
114         ulong   r[Nreg];
115         ulong   *mmio;
116         ulong   mmiosize;
117
118         char    chan[32];
119         int     depth;
120 };
121
122 Vmware xvm;
123 Vmware *vm=&xvm;
124
125 static ulong
126 vmrd(Vmware *vm, int i)
127 {
128         outl(vm->ra, i);
129         return inl(vm->rd);
130 }
131
132 static void
133 vmwr(Vmware *vm, int i, ulong v)
134 {
135         outl(vm->ra, i);
136         outl(vm->rd, v);
137 }
138
139 static void
140 vmwait(Vmware *vm)
141 {
142         vmwr(vm, Rsync, 1);
143         while(vmrd(vm, Rbusy))
144                 ;
145 }
146
147 static void
148 vmwarelinear(VGAscr* scr, int, int)
149 {
150         char err[64];
151         Pcidev *p;
152
153         err[0] = 0;
154         p = nil;
155         while((p = pcimatch(p, PCIVMWARE, 0)) != nil){
156                 if(p->ccrb != Pcibcdisp)
157                         continue;
158                 switch(p->did){
159                 default:
160                         snprint(err, sizeof err, "unknown vmware pci did %.4ux",
161                                 p->did);
162                         continue;
163                         
164                 case VMWARE1:
165                         vm->ra = 0x4560;
166                         vm->rd = 0x4560 + 4;
167                         break;
168         
169                 case VMWARE2:
170                         vm->ra = p->mem[0].bar & ~3;
171                         vm->rd = vm->ra + 1;
172                         break;
173                 }
174                 break;                  /* found a card, p is set */
175         }
176         if(p == nil)
177                 error(err[0]? err: "no vmware vga card found");
178
179         vgalinearaddr(scr, vmrd(vm, Rfbstart), vmrd(vm, Rfbsize));
180         if(scr->apsize)
181                 addvgaseg("vmwarescreen", scr->paddr, scr->apsize);
182 }
183
184 static void
185 vmfifowr(Vmware *vm, ulong v)
186 {
187         ulong *mm;
188
189         mm = vm->mmio;
190         if(mm == nil){
191                 iprint("!");
192                 return;
193         }
194
195         if(mm[FifoNextCmd]+sizeof(ulong) == mm[FifoStop]
196         || (mm[FifoNextCmd]+sizeof(ulong) == mm[FifoMax]
197             && mm[FifoStop] == mm[FifoMin]))
198                 vmwait(vm);
199
200         mm[mm[FifoNextCmd]/sizeof(ulong)] = v;
201
202         /* must do this way so mm[FifoNextCmd] is never mm[FifoMax] */
203         v = mm[FifoNextCmd] + sizeof(ulong);
204         if(v == mm[FifoMax])
205                 v = mm[FifoMin];
206         mm[FifoNextCmd] = v;
207 }
208
209 static void
210 vmwareflush(VGAscr*, Rectangle r)
211 {
212         if(vm->mmio == nil)
213                 return;
214
215         vmfifowr(vm, Xupdate);
216         vmfifowr(vm, r.min.x);
217         vmfifowr(vm, r.min.y);
218         vmfifowr(vm, r.max.x-r.min.x);
219         vmfifowr(vm, r.max.y-r.min.y);
220         vmwait(vm);
221 }
222
223 static void
224 vmwareload(VGAscr*, Cursor *c)
225 {
226         int i;
227         ulong clr, set;
228         ulong and[16];
229         ulong xor[16];
230
231         if(vm->mmio == nil)
232                 return;
233         vmfifowr(vm, Xdefinecursor);
234         vmfifowr(vm, 1);        /* cursor id */
235         vmfifowr(vm, -c->offset.x);
236         vmfifowr(vm, -c->offset.y);
237
238         vmfifowr(vm, 16);       /* width */
239         vmfifowr(vm, 16);       /* height */
240         vmfifowr(vm, 1);        /* depth for and mask */
241         vmfifowr(vm, 1);        /* depth for xor mask */
242
243         for(i=0; i<16; i++){
244                 clr = (c->clr[i*2+1]<<8) | c->clr[i*2];
245                 set = (c->set[i*2+1]<<8) | c->set[i*2];
246                 and[i] = ~(clr|set);    /* clr and set pixels => black */
247                 xor[i] = clr&~set;              /* clr pixels => white */
248         }
249         for(i=0; i<16; i++)
250                 vmfifowr(vm, and[i]);
251         for(i=0; i<16; i++)
252                 vmfifowr(vm, xor[i]);
253
254         vmwait(vm);
255 }
256
257 static int
258 vmwaremove(VGAscr*, Point p)
259 {
260         vmwr(vm, Rcursorid, 1);
261         vmwr(vm, Rcursorx, p.x);
262         vmwr(vm, Rcursory, p.y);
263         vmwr(vm, Rcursoron, CursorOnShow);
264         return 0;
265 }
266
267 static void
268 vmwaredisable(VGAscr*)
269 {
270         vmwr(vm, Rcursorid, 1);
271         vmwr(vm, Rcursoron, CursorOnHide);
272 }
273
274 static void
275 vmwareenable(VGAscr*)
276 {
277         vmwr(vm, Rcursorid, 1);
278         vmwr(vm, Rcursoron, CursorOnShow);
279 }
280
281 static void
282 vmwareblank(int)
283 {
284 }
285
286 static int
287 vmwarescroll(VGAscr*, Rectangle r, Rectangle sr)
288 {
289         if(vm->mmio == nil)
290                 return 0;
291         vmfifowr(vm, Xrectcopy);
292         vmfifowr(vm, sr.min.x);
293         vmfifowr(vm, sr.min.y);
294         vmfifowr(vm, r.min.x);
295         vmfifowr(vm, r.min.y);
296         vmfifowr(vm, Dx(r));
297         vmfifowr(vm, Dy(r));
298         vmwait(vm);
299         return 1;
300 }
301
302 static int
303 vmwarefill(VGAscr*, Rectangle r, ulong sval)
304 {
305         if(vm->mmio == nil)
306                 return 0;
307         vmfifowr(vm, Xrectfill);
308         vmfifowr(vm, sval);
309         vmfifowr(vm, r.min.x);
310         vmfifowr(vm, r.min.y);
311         vmfifowr(vm, r.max.x-r.min.x);
312         vmfifowr(vm, r.max.y-r.min.y);
313         vmwait(vm);
314         return 1;
315 }
316
317 static void
318 vmwaredrawinit(VGAscr *scr)
319 {
320         ulong offset;
321         ulong mmiobase, mmiosize;
322
323         if(scr->mmio==nil){
324                 mmiobase = vmrd(vm, Rmemstart);
325                 if(mmiobase == 0)
326                         return;
327                 mmiosize = vmrd(vm, Rmemsize);
328                 scr->mmio = vmap(mmiobase, mmiosize);
329                 if(scr->mmio == nil)
330                         return;
331                 vm->mmio = scr->mmio;
332                 vm->mmiosize = mmiosize;
333                 addvgaseg("vmwaremmio", mmiobase, mmiosize);
334         }
335
336         scr->mmio[FifoMin] = 4*sizeof(ulong);
337         scr->mmio[FifoMax] = vm->mmiosize;
338         scr->mmio[FifoNextCmd] = 4*sizeof(ulong);
339         scr->mmio[FifoStop] = 4*sizeof(ulong);
340         vmwr(vm, Rconfigdone, 1);
341
342         scr->scroll = vmwarescroll;
343         scr->fill = vmwarefill;
344
345         offset = vmrd(vm, Rfboffset);
346         scr->gscreendata->bdata += offset;
347 }
348
349 VGAdev vgavmwaredev = {
350         "vmware",
351
352         0,
353         0,
354         0,
355         vmwarelinear,
356         vmwaredrawinit,
357         0,
358         0,
359         0,
360         vmwareflush,
361 };
362
363 VGAcur vgavmwarecur = {
364         "vmwarehwgc",
365
366         vmwareenable,
367         vmwaredisable,
368         vmwareload,
369         vmwaremove,
370 };