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