FreeBSD/Linux Kernel Cross Reference
sys/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 };
Cache object: 209d95d07600c23d9eb431a77c8de08a
|