2 * vga driver using just vesa bios to set up.
5 #include "../port/lib.h"
10 #include "../port/error.h"
13 #include "/386/include/ureg.h"
14 typedef struct Ureg386 Ureg386;
30 static uchar modebuf[0x1000];
31 static Chan *creg, *cmem;
36 #define WORD(p) ((p)[0] | ((p)[1]<<8))
37 #define LONG(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))
38 #define PWORD(p, v) (p)[0] = (v); (p)[1] = (v)>>8
39 #define PLONG(p, v) (p)[0] = (v); (p)[1] = (v)>>8; (p)[2] = (v)>>16; (p)[3] = (v)>>24
42 vbesetup(Ureg386 *u, int ax)
44 memset(modebuf, 0, sizeof modebuf);
45 memset(u, 0, sizeof *u);
47 u->es = (RealModeBuf>>4)&0xF000;
48 u->di = RealModeBuf&0xFFFF;
55 if(devtab[cmem->type]->write(cmem, modebuf, sizeof(modebuf), RealModeBuf) != sizeof(modebuf))
56 error("write modebuf");
58 if(devtab[creg->type]->write(creg, u, sizeof(*u), 0) != sizeof(*u))
60 if(devtab[creg->type]->read(creg, u, sizeof(*u), 0) != sizeof(*u))
62 if((u->ax&0xFFFF) != 0x004F)
63 error("vesa bios error");
64 if(devtab[cmem->type]->read(cmem, modebuf, sizeof(modebuf), RealModeBuf) != sizeof(modebuf))
65 error("read modebuf");
74 p = vbesetup(&u, 0x4F00);
75 strcpy((char*)p, "VBE2");
77 if(memcmp((char*)p, "VESA", 4) != 0)
78 error("bad vesa signature");
80 error("bad vesa version");
99 p = vbesetup(&u, 0x4F01);
106 vesalinear(VGAscr *scr, int, int)
108 int i, mode, size, havesize;
116 * bochs loses the top bits - cannot use this
117 if((mode&(1<<14)) == 0)
118 error("not in linear graphics mode");
121 p = vbemodeinfo(mode);
122 if(!(WORD(p+0) & (1<<4)))
123 error("not in VESA graphics mode");
124 if(!(WORD(p+0) & (1<<7)))
125 error("not in linear graphics mode");
128 size = WORD(p+20)*WORD(p+16);
131 * figure out max size of memory so that we have
132 * enough if the screen is resized.
136 while(!havesize && (pci = pcimatch(pci, 0, 0)) != nil){
137 if(pci->ccrb != Pcibcdisp)
139 for(i=0; i<nelem(pci->mem); i++){
142 if(pci->mem[i].bar&1) /* not memory */
144 a = pci->mem[i].bar & ~0xF;
145 e = a + pci->mem[i].size;
146 if(paddr >= a && (paddr+size) <= e){
154 /* no pci - heuristic guess */
156 if(size < 4*1024*1024)
159 size = ROUND(size, 1024*1024);
161 vgalinearaddr(scr, paddr, size);
163 addvgaseg("vesascreen", scr->paddr, scr->apsize);
171 return vesactl != *((int*)arg);
181 while(ctl != Cdisable){
183 sleep(&vesar, gotctl, &ctl);
186 vbesetup(&u, 0x4f10);
193 * dont wait forever here. some BIOS get stuck
194 * in i/o poll loop after blank/unblank for some
195 * reason. (Thinkpad A22p)
221 cmem = namec("/dev/realmodemem", Aopen, ORDWR, 0);
227 creg = namec("/dev/realmode", Aopen, ORDWR, 0);
232 kproc("vesa", vesaproc, nil);
236 vesadisable(VGAscr *)
241 /* wait for vesaproc to finish */
247 vesablank(VGAscr *, int blank)
249 if(vesactl != Cdisable){
250 vesactl = blank ? Cblank : Cenable;
256 vesadrawinit(VGAscr *scr)
258 scr->blank = vesablank;
261 VGAdev vgavesadev = {