vgavmware.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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 void
  125. vmwarelinear(VGAscr* scr, int, int)
  126. {
  127. char err[64];
  128. Pcidev *p;
  129. p = pcimatch(nil, PCIVMWARE, 0);
  130. if(p == nil)
  131. error("no vmware card found");
  132. switch(p->did){
  133. default:
  134. snprint(err, sizeof err, "unknown vmware id %.4ux", p->did);
  135. error(err);
  136. case VMWARE1:
  137. vm->ra = 0x4560;
  138. vm->rd = 0x4560+4;
  139. break;
  140. case VMWARE2:
  141. vm->ra = p->mem[0].bar&~3;
  142. vm->rd = vm->ra + 1;
  143. }
  144. vgalinearaddr(scr, vmrd(vm, Rfbstart), vmrd(vm, Rfbsize));
  145. if(scr->apsize)
  146. addvgaseg("vmwarescreen", scr->paddr, scr->apsize);
  147. }
  148. static void
  149. vmfifowr(Vmware *vm, ulong v)
  150. {
  151. ulong *mm;
  152. mm = vm->mmio;
  153. if(mm == nil){
  154. iprint("!");
  155. return;
  156. }
  157. if(mm[FifoNextCmd]+sizeof(ulong) == mm[FifoStop]
  158. || (mm[FifoNextCmd]+sizeof(ulong) == mm[FifoMax]
  159. && mm[FifoStop] == mm[FifoMin]))
  160. vmwait(vm);
  161. mm[mm[FifoNextCmd]/sizeof(ulong)] = v;
  162. /* must do this way so mm[FifoNextCmd] is never mm[FifoMax] */
  163. v = mm[FifoNextCmd] + sizeof(ulong);
  164. if(v == mm[FifoMax])
  165. v = mm[FifoMin];
  166. mm[FifoNextCmd] = v;
  167. }
  168. static void
  169. vmwareflush(VGAscr*, Rectangle r)
  170. {
  171. if(vm->mmio == nil)
  172. return;
  173. vmfifowr(vm, Xupdate);
  174. vmfifowr(vm, r.min.x);
  175. vmfifowr(vm, r.min.y);
  176. vmfifowr(vm, r.max.x-r.min.x);
  177. vmfifowr(vm, r.max.y-r.min.y);
  178. vmwait(vm);
  179. }
  180. static void
  181. vmwareload(VGAscr*, Cursor *c)
  182. {
  183. int i;
  184. ulong clr, set;
  185. ulong and[16];
  186. ulong xor[16];
  187. if(vm->mmio == nil)
  188. return;
  189. vmfifowr(vm, Xdefinecursor);
  190. vmfifowr(vm, 1); /* cursor id */
  191. vmfifowr(vm, -c->offset.x);
  192. vmfifowr(vm, -c->offset.y);
  193. vmfifowr(vm, 16); /* width */
  194. vmfifowr(vm, 16); /* height */
  195. vmfifowr(vm, 1); /* depth for and mask */
  196. vmfifowr(vm, 1); /* depth for xor mask */
  197. for(i=0; i<16; i++){
  198. clr = (c->clr[i*2+1]<<8) | c->clr[i*2];
  199. set = (c->set[i*2+1]<<8) | c->set[i*2];
  200. and[i] = ~(clr|set); /* clr and set pixels => black */
  201. xor[i] = clr&~set; /* clr pixels => white */
  202. }
  203. for(i=0; i<16; i++)
  204. vmfifowr(vm, and[i]);
  205. for(i=0; i<16; i++)
  206. vmfifowr(vm, xor[i]);
  207. vmwait(vm);
  208. }
  209. static int
  210. vmwaremove(VGAscr*, Point p)
  211. {
  212. vmwr(vm, Rcursorid, 1);
  213. vmwr(vm, Rcursorx, p.x);
  214. vmwr(vm, Rcursory, p.y);
  215. vmwr(vm, Rcursoron, CursorOnShow);
  216. return 0;
  217. }
  218. static void
  219. vmwaredisable(VGAscr*)
  220. {
  221. vmwr(vm, Rcursorid, 1);
  222. vmwr(vm, Rcursoron, CursorOnHide);
  223. }
  224. static void
  225. vmwareenable(VGAscr*)
  226. {
  227. vmwr(vm, Rcursorid, 1);
  228. vmwr(vm, Rcursoron, CursorOnShow);
  229. }
  230. static void
  231. vmwareblank(int)
  232. {
  233. }
  234. static int
  235. vmwarescroll(VGAscr*, Rectangle r, Rectangle sr)
  236. {
  237. if(vm->mmio == nil)
  238. return 0;
  239. vmfifowr(vm, Xrectcopy);
  240. vmfifowr(vm, sr.min.x);
  241. vmfifowr(vm, sr.min.y);
  242. vmfifowr(vm, r.min.x);
  243. vmfifowr(vm, r.min.y);
  244. vmfifowr(vm, Dx(r));
  245. vmfifowr(vm, Dy(r));
  246. vmwait(vm);
  247. return 1;
  248. }
  249. static int
  250. vmwarefill(VGAscr*, Rectangle r, ulong sval)
  251. {
  252. if(vm->mmio == nil)
  253. return 0;
  254. vmfifowr(vm, Xrectfill);
  255. vmfifowr(vm, sval);
  256. vmfifowr(vm, r.min.x);
  257. vmfifowr(vm, r.min.y);
  258. vmfifowr(vm, r.max.x-r.min.x);
  259. vmfifowr(vm, r.max.y-r.min.y);
  260. vmwait(vm);
  261. return 1;
  262. }
  263. static void
  264. vmwaredrawinit(VGAscr *scr)
  265. {
  266. ulong offset;
  267. ulong mmiobase, mmiosize;
  268. if(scr->mmio==nil){
  269. mmiobase = vmrd(vm, Rmemstart);
  270. if(mmiobase == 0)
  271. return;
  272. mmiosize = vmrd(vm, Rmemsize);
  273. scr->mmio = vmap(mmiobase, mmiosize);
  274. if(scr->mmio == nil)
  275. return;
  276. vm->mmio = scr->mmio;
  277. vm->mmiosize = mmiosize;
  278. addvgaseg("vmwaremmio", mmiobase, mmiosize);
  279. }
  280. scr->mmio[FifoMin] = 4*sizeof(ulong);
  281. scr->mmio[FifoMax] = vm->mmiosize;
  282. scr->mmio[FifoNextCmd] = 4*sizeof(ulong);
  283. scr->mmio[FifoStop] = 4*sizeof(ulong);
  284. vmwr(vm, Rconfigdone, 1);
  285. scr->scroll = vmwarescroll;
  286. scr->fill = vmwarefill;
  287. offset = vmrd(vm, Rfboffset);
  288. scr->gscreendata->bdata += offset;
  289. }
  290. VGAdev vgavmwaredev = {
  291. "vmware",
  292. 0,
  293. 0,
  294. 0,
  295. vmwarelinear,
  296. vmwaredrawinit,
  297. 0,
  298. 0,
  299. 0,
  300. vmwareflush,
  301. };
  302. VGAcur vgavmwarecur = {
  303. "vmwarehwgc",
  304. vmwareenable,
  305. vmwaredisable,
  306. vmwareload,
  307. vmwaremove,
  308. };