vgavmware.c 6.2 KB

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