Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
	/*
180
	 * empirically, 2*fbsize enables 1280x1024x32, not just 1024x768x32.
181
	 * is fbsize in bytes or pixels?
182
	 */
183
	vgalinearaddr(scr, vmrd(vm, Rfbstart), 2*vmrd(vm, Rfbsize));
184
	if(scr->apsize)
185
		addvgaseg("vmwarescreen", scr->paddr, scr->apsize);
186
}
187
 
188
static void
189
vmfifowr(Vmware *vm, ulong v)
190
{
191
	ulong *mm;
192
 
193
	mm = vm->mmio;
194
	if(mm == nil){
195
		iprint("!");
196
		return;
197
	}
198
 
199
	if(mm[FifoNextCmd]+sizeof(ulong) == mm[FifoStop]
200
	|| (mm[FifoNextCmd]+sizeof(ulong) == mm[FifoMax]
201
	    && mm[FifoStop] == mm[FifoMin]))
202
		vmwait(vm);
203
 
204
	mm[mm[FifoNextCmd]/sizeof(ulong)] = v;
205
 
206
	/* must do this way so mm[FifoNextCmd] is never mm[FifoMax] */
207
	v = mm[FifoNextCmd] + sizeof(ulong);
208
	if(v == mm[FifoMax])
209
		v = mm[FifoMin];
210
	mm[FifoNextCmd] = v;
211
}
212
 
213
static void
214
vmwareflush(VGAscr*, Rectangle r)
215
{
216
	if(vm->mmio == nil)
217
		return;
218
 
219
	vmfifowr(vm, Xupdate);
220
	vmfifowr(vm, r.min.x);
221
	vmfifowr(vm, r.min.y);
222
	vmfifowr(vm, r.max.x-r.min.x);
223
	vmfifowr(vm, r.max.y-r.min.y);
224
	vmwait(vm);
225
}
226
 
227
static void
228
vmwareload(VGAscr*, Cursor *c)
229
{
230
	int i;
231
	ulong clr, set;
232
	ulong and[16];
233
	ulong xor[16];
234
 
235
	if(vm->mmio == nil)
236
		return;
237
	vmfifowr(vm, Xdefinecursor);
238
	vmfifowr(vm, 1);	/* cursor id */
239
	vmfifowr(vm, -c->offset.x);
240
	vmfifowr(vm, -c->offset.y);
241
 
242
	vmfifowr(vm, 16);	/* width */
243
	vmfifowr(vm, 16);	/* height */
244
	vmfifowr(vm, 1);	/* depth for and mask */
245
	vmfifowr(vm, 1);	/* depth for xor mask */
246
 
247
	for(i=0; i<16; i++){
248
		clr = (c->clr[i*2+1]<<8) | c->clr[i*2];
249
		set = (c->set[i*2+1]<<8) | c->set[i*2];
250
		and[i] = ~(clr|set);	/* clr and set pixels => black */
251
		xor[i] = clr&~set;		/* clr pixels => white */
252
	}
253
	for(i=0; i<16; i++)
254
		vmfifowr(vm, and[i]);
255
	for(i=0; i<16; i++)
256
		vmfifowr(vm, xor[i]);
257
 
258
	vmwait(vm);
259
}
260
 
261
static int
262
vmwaremove(VGAscr*, Point p)
263
{
264
	vmwr(vm, Rcursorid, 1);
265
	vmwr(vm, Rcursorx, p.x);
266
	vmwr(vm, Rcursory, p.y);
267
	vmwr(vm, Rcursoron, CursorOnShow);
268
	return 0;
269
}
270
 
271
static void
272
vmwaredisable(VGAscr*)
273
{
274
	vmwr(vm, Rcursorid, 1);
275
	vmwr(vm, Rcursoron, CursorOnHide);
276
}
277
 
278
static void
279
vmwareenable(VGAscr*)
280
{
281
	vmwr(vm, Rcursorid, 1);
282
	vmwr(vm, Rcursoron, CursorOnShow);
283
}
284
 
285
static void
286
vmwareblank(int)
287
{
288
}
289
 
290
static int
291
vmwarescroll(VGAscr*, Rectangle r, Rectangle sr)
292
{
293
	if(vm->mmio == nil)
294
		return 0;
295
	vmfifowr(vm, Xrectcopy);
296
	vmfifowr(vm, sr.min.x);
297
	vmfifowr(vm, sr.min.y);
298
	vmfifowr(vm, r.min.x);
299
	vmfifowr(vm, r.min.y);
300
	vmfifowr(vm, Dx(r));
301
	vmfifowr(vm, Dy(r));
302
	vmwait(vm);
303
	return 1;
304
}
305
 
306
static int
307
vmwarefill(VGAscr*, Rectangle r, ulong sval)
308
{
309
	if(vm->mmio == nil)
310
		return 0;
311
	vmfifowr(vm, Xrectfill);
312
	vmfifowr(vm, sval);
313
	vmfifowr(vm, r.min.x);
314
	vmfifowr(vm, r.min.y);
315
	vmfifowr(vm, r.max.x-r.min.x);
316
	vmfifowr(vm, r.max.y-r.min.y);
317
	vmwait(vm);
318
	return 1;
319
}
320
 
321
static void
322
vmwaredrawinit(VGAscr *scr)
323
{
324
	ulong offset;
325
	ulong mmiobase, mmiosize;
326
 
327
	if(scr->mmio==nil){
328
		mmiobase = vmrd(vm, Rmemstart);
329
		if(mmiobase == 0)
330
			return;
331
		mmiosize = vmrd(vm, Rmemsize);
332
		scr->mmio = vmap(mmiobase, mmiosize);
333
		if(scr->mmio == nil)
334
			return;
335
		vm->mmio = scr->mmio;
336
		vm->mmiosize = mmiosize;
337
		addvgaseg("vmwaremmio", mmiobase, mmiosize);
338
	}
339
 
340
	scr->mmio[FifoMin] = 4*sizeof(ulong);
341
	scr->mmio[FifoMax] = vm->mmiosize;
342
	scr->mmio[FifoNextCmd] = 4*sizeof(ulong);
343
	scr->mmio[FifoStop] = 4*sizeof(ulong);
344
	vmwr(vm, Rconfigdone, 1);
345
 
346
	scr->scroll = vmwarescroll;
347
	scr->fill = vmwarefill;
348
 
349
	offset = vmrd(vm, Rfboffset);
350
	scr->gscreendata->bdata += offset;
351
}
352
 
353
VGAdev vgavmwaredev = {
354
	"vmware",
355
 
356
	0,
357
	0,
358
	0,
359
	vmwarelinear,
360
	vmwaredrawinit,
361
	0,
362
	0,
363
	0,
364
	vmwareflush,
365
};
366
 
367
VGAcur vgavmwarecur = {
368
	"vmwarehwgc",
369
 
370
	vmwareenable,
371
	vmwaredisable,
372
	vmwareload,
373
	vmwaremove,
374
};