Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/cmd/aux/vga/vmware.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
 
5
#include "pci.h"
6
#include "vga.h"
7
 
8
enum {
9
	Rid = 0,
10
	Renable,
11
	Rwidth,
12
	Rheight,
13
	Rmaxwidth,
14
	Rmaxheight,
15
	Rdepth,
16
	Rbpp,
17
	Rpseudocolor,
18
	Rrmask,
19
	Rgmask,
20
	Rbmask,
21
	Rbpl,
22
	Rfbstart,
23
	Rfboffset,
24
	Rfbmaxsize,
25
	Rfbsize,
26
	Rcap,
27
	Rmemstart,
28
	Rmemsize,
29
	Rconfigdone,
30
	Rsync,
31
	Rbusy,
32
	Rguestid,
33
	Rcursorid,
34
	Rcursorx,
35
	Rcursory,
36
	Rcursoron,
37
	Rhostbpp,
38
	Nreg,
39
 
40
	Crectfill = 1<<0,
41
	Crectcopy = 1<<1,
42
	Crectpatfill = 1<<2,
43
	Coffscreen = 1<<3,
44
	Crasterop = 1<<4,
45
	Ccursor = 1<<5,
46
	Ccursorbypass = 1<<6,
47
	Ccursorbypass2 = 1<<7,
48
	C8bitemulation = 1<<8,
49
	Calphacursor = 1<<9,
50
 
51
	Rpalette = 1024,
52
};	
53
 
54
typedef struct Vmware	Vmware;
55
struct Vmware {
56
	ulong	mmio;
57
	ulong	fb;
58
 
59
	ulong	ra;
60
	ulong	rd;
61
 
62
	ulong	r[Nreg];
63
 
64
	char	chan[32];
65
	int	depth;
66
};
67
 
68
static char*
69
rname[Nreg] = {
70
	"ID",
71
	"Enable",
72
	"Width",
73
	"Height",
74
	"MaxWidth",
75
	"MaxHeight",
76
	"Depth",
77
	"Bpp",
78
	"PseudoColor",
79
	"RedMask",
80
	"GreenMask",
81
	"BlueMask",
82
	"Bpl",
83
	"FbStart",
84
	"FbOffset",
85
	"FbMaxSize",
86
	"FbSize",
87
	"Cap",
88
	"MemStart",
89
	"MemSize",
90
	"ConfigDone",
91
	"Sync",
92
	"Busy",
93
	"GuestID",
94
	"CursorID",
95
	"CursorX",
96
	"CursorY",
97
	"CursorOn",
98
	"HostBpp",
99
};
100
 
101
static ulong
102
vmrd(Vmware *vm, int i)
103
{
104
	outportl(vm->ra, i);
105
	return inportl(vm->rd);
106
}
107
 
108
static void
109
vmwr(Vmware *vm, int i, ulong v)
110
{
111
	outportl(vm->ra, i);
112
	outportl(vm->rd, v);
113
}
114
 
115
static uint
116
bits(ulong a)
117
{
118
	int b;
119
 
120
	for(b=0; a; a>>=1)
121
		if(a&1)
122
			b++;
123
	return b;
124
}
125
 
126
static void
127
snarf(Vga* vga, Ctlr* ctlr)
128
{
129
	int extra, i;
130
	Pcidev *p;
131
	Vmware *vm;
132
 
133
	p = vga->pci;
134
	if(p == nil)
135
		error("%s: vga->pci not set\n", ctlr->name);
136
 
137
	vm = alloc(sizeof(Vmware));
138
 
139
	switch(p->did){
140
	case 0x710:	/* VMware video chipset #1 */
141
		vm->ra = 0x4560;
142
		vm->rd = 0x4560+4;
143
		break;
144
 
145
	case 0x405:	/* VMware video chipset #2, untested */
146
		vm->ra = p->mem[0].bar&~3;
147
		vm->rd = vm->ra+1;
148
		break;
149
 
150
	default:
151
		error("%s: unrecognized chipset %.4ux\n", ctlr->name, p->did);
152
	}
153
 
154
	for(i=0; i<Nreg; i++)
155
		vm->r[i] = vmrd(vm, i);
156
 
157
//vmwr(vm, Renable, 0);
158
	/*
159
	 * Figure out color channel.  Delay errors until init,
160
	 * which is after the register dump.
161
	 */
162
	vm->depth = vm->r[Rbpp];
163
	extra = vm->r[Rbpp] - vm->r[Rdepth];
164
	if(vm->r[Rrmask] > vm->r[Rgmask] && vm->r[Rgmask] > vm->r[Rbmask]){
165
		if(extra)
166
			sprint(vm->chan, "x%d", extra);
167
		else
168
			vm->chan[0] = '\0';
169
		sprint(vm->chan+strlen(vm->chan), "r%dg%db%d", bits(vm->r[Rrmask]),
170
			bits(vm->r[Rgmask]), bits(vm->r[Rbmask]));
171
	}else if(vm->r[Rbmask] > vm->r[Rgmask] && vm->r[Rgmask] > vm->r[Rrmask]){
172
		sprint(vm->chan, "b%dg%dr%d", bits(vm->r[Rbmask]),
173
			bits(vm->r[Rgmask]), bits(vm->r[Rrmask]));
174
		if(extra)
175
			sprint(vm->chan+strlen(vm->chan), "x%d", extra);
176
	}else
177
		sprint(vm->chan, "unknown");
178
 
179
	/* Record the frame buffer start, size */
180
	vga->vmb = vm->r[Rfbstart];
181
	vga->apz = vm->r[Rfbmaxsize];
182
 
183
	vga->private = vm;
184
	ctlr->flag |= Fsnarf;
185
}
186
 
187
 
188
static void
189
options(Vga*, Ctlr* ctlr)
190
{
191
	ctlr->flag |= Hlinear|Henhanced|Foptions;
192
}
193
 
194
 
195
static void
196
clock(Vga*, Ctlr*)
197
{
198
	/* BEST CLOCK ROUTINE EVER! */
199
}
200
 
201
static void
202
init(Vga* vga, Ctlr* ctlr)
203
{
204
	Vmware *vm;
205
 
206
	vm = vga->private;
207
 
208
	vmwr(vm, Rid, (0x900000<<8)|2);
209
	if(vmrd(vm, Rid)&0xFF != 2)
210
		error("old vmware svga version %lud; need version 2\n",
211
			vmrd(vm,Rid)&0xFF);
212
 
213
	ctlr->flag |= Ulinear;
214
	if(strcmp(vm->chan, "unknown") == 0)
215
		error("couldn't translate color masks into channel\n");
216
 
217
	/* Always use the screen depth, and clip the screen size */
218
	vga->mode->z = vm->r[Rbpp];
219
	if(vga->mode->x > vm->r[Rmaxwidth])
220
		vga->mode->x = vm->r[Rmaxwidth];
221
	if(vga->mode->y > vm->r[Rmaxheight])
222
		vga->mode->y = vm->r[Rmaxheight];
223
 
224
	vm->r[Rwidth] = vga->mode->x;
225
	vm->r[Rheight] = vga->mode->y;
226
 
227
	/* Figure out the channel string */
228
	strcpy(vga->mode->chan, vm->chan);
229
 
230
	/* Record the bytes per line */
231
	ctlr->flag |= Finit;
232
}
233
 
234
static void
235
load(Vga* vga, Ctlr *ctlr)
236
{
237
	char buf[64];
238
	int x;
239
	Vmware *vm;
240
 
241
	vm = vga->private;
242
	vmwr(vm, Rwidth, vm->r[Rwidth]);
243
	vmwr(vm, Rheight, vm->r[Rheight]);
244
	vmwr(vm, Renable, 1);
245
	vmwr(vm, Rguestid, 0x5010);	/* OS type is "Other" */
246
 
247
	x = vmrd(vm, Rbpl)/(vm->depth/8);
248
	if(x != vga->mode->x){
249
		vga->virtx = x;
250
		sprint(buf, "%ludx%ludx%d %s", vga->virtx, vga->virty,
251
			vga->mode->z, vga->mode->chan);
252
		vgactlw("size", buf);
253
	}
254
	ctlr->flag |= Fload;
255
}
256
 
257
static void
258
dump(Vga* vga, Ctlr* ctlr)
259
{
260
	int i;
261
	Vmware *vm;
262
 
263
	vm = vga->private;
264
 
265
	for(i=0; i<Nreg; i++){
266
		printitem(ctlr->name, rname[i]);
267
		Bprint(&stdout, " %.8lux\n", vm->r[i]);
268
	}
269
 
270
	printitem(ctlr->name, "chan");
271
	Bprint(&stdout, " %s\n", vm->chan);
272
	printitem(ctlr->name, "depth");
273
	Bprint(&stdout, " %d\n", vm->depth);
274
	printitem(ctlr->name, "linear");
275
 
276
}
277
 
278
Ctlr vmware = {
279
	"vmware",			/* name */
280
	snarf,				/* snarf */
281
	options,			/* options */
282
	init,				/* init */
283
	load,				/* load */
284
	dump,				/* dump */
285
};
286
 
287
Ctlr vmwarehwgc = {
288
	"vmwarehwgc",			/* name */
289
	0,				/* snarf */
290
	0,				/* options */
291
	0,				/* init */
292
	0,				/* load */
293
	0,				/* dump */
294
};
295