vgavmware.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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. mm[FifoNextCmd] += sizeof(ulong);
  181. if(mm[FifoNextCmd]==mm[FifoMax])
  182. mm[FifoNextCmd] = mm[FifoMin];
  183. }
  184. static void
  185. vmwareflush(VGAscr*, Rectangle r)
  186. {
  187. if(vm->mmio == nil)
  188. return;
  189. vmfifowr(vm, Xupdate);
  190. vmfifowr(vm, r.min.x);
  191. vmfifowr(vm, r.min.y);
  192. vmfifowr(vm, r.max.x-r.min.x);
  193. vmfifowr(vm, r.max.y-r.min.y);
  194. vmwait(vm);
  195. }
  196. static void
  197. vmwareload(VGAscr*, Cursor *c)
  198. {
  199. int i;
  200. ulong clr, set;
  201. ulong and[16];
  202. ulong xor[16];
  203. if(vm->mmio == nil)
  204. return;
  205. vmfifowr(vm, Xdefinecursor);
  206. vmfifowr(vm, 1); /* cursor id */
  207. vmfifowr(vm, -c->offset.x);
  208. vmfifowr(vm, -c->offset.y);
  209. vmfifowr(vm, 16); /* width */
  210. vmfifowr(vm, 16); /* height */
  211. vmfifowr(vm, 1); /* depth for and mask */
  212. vmfifowr(vm, 1); /* depth for xor mask */
  213. for(i=0; i<16; i++){
  214. clr = (c->clr[i*2+1]<<8) | c->clr[i*2];
  215. set = (c->set[i*2+1]<<8) | c->set[i*2];
  216. and[i] = ~(clr|set); /* clr and set pixels => black */
  217. xor[i] = clr&~set; /* clr pixels => white */
  218. }
  219. for(i=0; i<16; i++)
  220. vmfifowr(vm, and[i]);
  221. for(i=0; i<16; i++)
  222. vmfifowr(vm, xor[i]);
  223. vmwait(vm);
  224. }
  225. static int
  226. vmwaremove(VGAscr*, Point p)
  227. {
  228. vmwr(vm, Rcursorid, 1);
  229. vmwr(vm, Rcursorx, p.x);
  230. vmwr(vm, Rcursory, p.y);
  231. vmwr(vm, Rcursoron, CursorOnShow);
  232. return 0;
  233. }
  234. static void
  235. vmwaredisable(VGAscr*)
  236. {
  237. vmwr(vm, Rcursorid, 1);
  238. vmwr(vm, Rcursoron, CursorOnHide);
  239. }
  240. static void
  241. vmwareenable(VGAscr*)
  242. {
  243. vmwr(vm, Rcursorid, 1);
  244. vmwr(vm, Rcursoron, CursorOnShow);
  245. }
  246. static void
  247. vmwareblank(int)
  248. {
  249. }
  250. static int
  251. vmwarescroll(VGAscr*, Rectangle r, Rectangle sr)
  252. {
  253. if(vm->mmio == nil)
  254. return 0;
  255. vmfifowr(vm, Xrectcopy);
  256. vmfifowr(vm, sr.min.x);
  257. vmfifowr(vm, sr.min.y);
  258. vmfifowr(vm, r.min.x);
  259. vmfifowr(vm, r.min.y);
  260. vmfifowr(vm, Dx(r));
  261. vmfifowr(vm, Dy(r));
  262. vmwait(vm);
  263. return 1;
  264. }
  265. static int
  266. vmwarefill(VGAscr*, Rectangle r, ulong sval)
  267. {
  268. if(vm->mmio == nil)
  269. return 0;
  270. vmfifowr(vm, Xrectfill);
  271. vmfifowr(vm, sval);
  272. vmfifowr(vm, r.min.x);
  273. vmfifowr(vm, r.min.y);
  274. vmfifowr(vm, r.max.x-r.min.x);
  275. vmfifowr(vm, r.max.y-r.min.y);
  276. vmwait(vm);
  277. return 1;
  278. }
  279. static void
  280. vmwaredrawinit(VGAscr *scr)
  281. {
  282. ulong offset;
  283. ulong mmiobase, mmiosize;
  284. if(scr->mmio==nil){
  285. mmiobase = vmrd(vm, Rmemstart);
  286. if(mmiobase == 0)
  287. return;
  288. mmiosize = vmrd(vm, Rmemsize);
  289. scr->mmio = KADDR(upamalloc(mmiobase, mmiosize, 0));
  290. vm->mmio = scr->mmio;
  291. vm->mmiosize = mmiosize;
  292. if(scr->mmio == nil)
  293. return;
  294. addvgaseg("vmwaremmio", mmiobase, mmiosize);
  295. }
  296. scr->mmio[FifoMin] = 4*sizeof(ulong);
  297. scr->mmio[FifoMax] = vm->mmiosize;
  298. scr->mmio[FifoNextCmd] = 4*sizeof(ulong);
  299. scr->mmio[FifoStop] = 4*sizeof(ulong);
  300. vmwr(vm, Rconfigdone, 1);
  301. scr->scroll = vmwarescroll;
  302. scr->fill = vmwarefill;
  303. offset = vmrd(vm, Rfboffset);
  304. scr->gscreendata->bdata += offset;
  305. }
  306. VGAdev vgavmwaredev = {
  307. "vmware",
  308. 0,
  309. 0,
  310. 0,
  311. vmwarelinear,
  312. vmwaredrawinit,
  313. 0,
  314. 0,
  315. 0,
  316. vmwareflush,
  317. };
  318. VGAcur vgavmwarecur = {
  319. "vmwarehwgc",
  320. vmwareenable,
  321. vmwaredisable,
  322. vmwareload,
  323. vmwaremove,
  324. };