static void mga4xxenable(VGAscr* scr) { Pcidev *pci; int size; int i, n, k; uchar *p; uchar x[16]; uchar crtcext3; if(scr->mmio) return; pci = mgapcimatch(); if(pci == nil) return; scr->mmio = vmap(pci->mem[1].bar&~0x0F, 16*1024); if(scr->mmio == nil) return; addvgaseg("mga4xxmmio", pci->mem[1].bar&~0x0F, pci->mem[1].size); /* need to map frame buffer here too, so vga can find memory size */ if(pci->did == MGA4xx || pci->did == MGA550) size = 32*MB; else size = 8*MB; vgalinearaddr(scr, pci->mem[0].bar&~0x0F, size); if(scr->paddr){ /* Find out how much memory is here, some multiple of 2 MB */ /* First Set MGA Mode ... */ crtcext3 = crtcextset(scr, 3, 0x80, 0x00); p = scr->vaddr; n = (size / MB) / 2; for(i = 0; i < n; i++){ k = (2*i+1)*MB; p[k] = 0; p[k] = i+1; *((uchar*)scr->mmio + CACHEFLUSH) = 0; x[i] = p[k]; } for(i = 1; i < n; i++) if(x[i] != i+1) break; scr->apsize = 2*i*MB; /* sketchy */ addvgaseg("mga4xxscreen", scr->paddr, scr->apsize); crtcextset(scr, 3, crtcext3, 0xff); } }
static void vmwarelinear(VGAscr* scr, int, int) { Pcidev *p; p = scr->pci; if(p == nil || p->vid != PCIVMWARE) return; switch(p->did){ default: return; case VMWARE1: vm->ver = 1; vm->ra = 0x4560; vm->rd = 0x4560 + 4; break; case VMWARE2: vm->ver = 2; vm->ra = p->mem[0].bar & ~3; vm->rd = vm->ra + 1; break; } // vm->fb = vmrd(vm, Rfbstart); vm->fb = p->mem[1].bar & ~0xF; vm->fb += vmrd(vm, Rfboffset); vgalinearaddr(scr, vm->fb, vmrd(vm, Rfbmaxsize)); if(scr->apsize) addvgaseg("vmwarescreen", scr->paddr, scr->apsize); if(scr->mmio==nil){ ulong mmiobase, mmiosize; // mmiobase = vmrd(vm, Rmemstart); mmiobase = p->mem[2].bar & ~0xF; if(mmiobase == 0) return; mmiosize = vmrd(vm, Rmemsize); scr->mmio = vmap(mmiobase, mmiosize); if(scr->mmio == nil) return; vm->mmio = scr->mmio; vm->mmiosize = mmiosize; addvgaseg("vmwaremmio", mmiobase, mmiosize); } scr->mmio[FifoMin] = 4*sizeof(ulong); scr->mmio[FifoMax] = vm->mmiosize; scr->mmio[FifoNextCmd] = 4*sizeof(ulong); scr->mmio[FifoStop] = 4*sizeof(ulong); vmwr(vm, Rconfigdone, 1); }
void vgalinearpci(VGAscr *scr) { uint32_t paddr; int i, size, best; Pcidev *p; p = scr->pci; if(p == nil) return; /* * Scan for largest memory region on card. * Some S3 cards (e.g. Savage) have enormous * mmio regions (but even larger frame buffers). * Some 3dfx cards (e.g., Voodoo3) have mmio * buffers the same size as the frame buffer, * but only the frame buffer is marked as * prefetchable (bar&8). If a card doesn't fit * into these heuristics, its driver will have to * call vgalinearaddr directly. */ best = -1; for(i=0; i<nelem(p->mem); i++){ if(p->mem[i].bar&1) /* not memory */ continue; if(p->mem[i].size < 640*480) /* not big enough */ continue; if(best==-1 || p->mem[i].size > p->mem[best].size || (p->mem[i].size == p->mem[best].size && (p->mem[i].bar&8) && !(p->mem[best].bar&8))) best = i; } if(best >= 0){ paddr = p->mem[best].bar & ~0x0F; size = p->mem[best].size; vgalinearaddr(scr, paddr, size); return; } error("no video memory found on pci card"); }
static void vesalinear(VGAscr *scr, int _1, int _2) { int i, mode, size, havesize; uint8_t *p; uint32_t paddr; Pcidev *pci; if(hardscreen) { scr->vaddr = 0; scr->paddr = scr->apsize = 0; return; } vbecheck(); mode = vbegetmode(); /* * bochs loses the top bits - cannot use this if((mode&(1<<14)) == 0) error("not in linear graphics mode"); */ mode &= 0x3FFF; p = vbemodeinfo(mode); if(!(WORD(p+0) & (1<<4))) error("not in VESA graphics mode"); if(!(WORD(p+0) & (1<<7))) error("not in linear graphics mode"); paddr = LONG(p+40); size = WORD(p+20)*WORD(p+16); size = ROUNDUP(size, PGSZ); /* * figure out max size of memory so that we have * enough if the screen is resized. */ pci = nil; havesize = 0; while(!havesize && (pci = pcimatch(pci, 0, 0)) != nil){ if(pci->ccrb != Pcibcdisp) continue; for(i=0; i<nelem(pci->mem); i++) if(paddr == (pci->mem[i].bar&~0x0F)){ if(pci->mem[i].size > size) size = pci->mem[i].size; havesize = 1; break; } } /* no pci - heuristic guess */ if (!havesize) if(size < 4*1024*1024) size = 4*1024*1024; else size = ROUND(size, 1024*1024); if(size > 16*1024*1024) /* arbitrary */ size = 16*1024*1024; vgalinearaddr(scr, paddr, size); if(scr->apsize) addvgaseg("vesascreen", scr->paddr, scr->apsize); if(Usesoftscreen){ hardscreen = scr->vaddr; scr->vaddr = 0; scr->paddr = scr->apsize = 0; } }