pc, pc64: lookup pci device for bootscreen() and maximize framebuffer aperture so can change screen resolution

This commit is contained in:
cinap_lenrek 2014-10-19 21:00:34 +02:00
parent d7785060fb
commit bcc65db171

View file

@ -472,16 +472,65 @@ blankscreen(int blank)
} }
} }
void static char*
vgalinearpci(VGAscr *scr) vgalinearaddr0(VGAscr *scr, ulong paddr, int size)
{
int x, nsize;
ulong npaddr;
/*
* new approach. instead of trying to resize this
* later, let's assume that we can just allocate the
* entire window to start with.
*/
if(scr->paddr == paddr && size <= scr->apsize)
return nil;
if(scr->paddr){
/*
* could call vunmap and vmap,
* but worried about dangling pointers in devdraw
*/
return "cannot grow vga frame buffer";
}
/* round to page boundary, just in case */
x = paddr&(BY2PG-1);
npaddr = paddr-x;
nsize = PGROUND(size+x);
/*
* Don't bother trying to map more than 4000x4000x32 = 64MB.
* We only have a 256MB window.
*/
if(nsize > 64*MB)
nsize = 64*MB;
scr->vaddr = vmap(npaddr, nsize);
if(scr->vaddr == 0)
return "cannot allocate vga frame buffer";
scr->vaddr = (char*)scr->vaddr+x;
scr->paddr = paddr;
scr->apsize = nsize;
if(up != nil){
/* let mtrr harmlessly fail on old CPUs, e.g., P54C */
if(!waserror()){
mtrr(npaddr, nsize, "wc");
poperror();
}
}
return nil;
}
static char*
vgalinearpci0(VGAscr *scr)
{ {
ulong paddr; ulong paddr;
int i, size, best; int i, size, best;
Pcidev *p; Pcidev *p;
p = scr->pci; p = scr->pci;
if(p == nil)
return;
/* /*
* Scan for largest memory region on card. * Scan for largest memory region on card.
@ -510,57 +559,51 @@ vgalinearpci(VGAscr *scr)
if(best >= 0){ if(best >= 0){
paddr = p->mem[best].bar & ~0x0F; paddr = p->mem[best].bar & ~0x0F;
size = p->mem[best].size; size = p->mem[best].size;
vgalinearaddr(scr, paddr, size); return vgalinearaddr0(scr, paddr, size);
return;
} }
error("no video memory found on pci card"); return "no video memory found on pci card";
}
void
vgalinearpci(VGAscr *scr)
{
char *err;
if(scr->pci == nil)
return;
if((err = vgalinearpci0(scr)) != nil)
error(err);
} }
void void
vgalinearaddr(VGAscr *scr, ulong paddr, int size) vgalinearaddr(VGAscr *scr, ulong paddr, int size)
{ {
int x, nsize; char *err;
ulong npaddr;
/* if((err = vgalinearaddr0(scr, paddr, size)) != nil)
* new approach. instead of trying to resize this error(err);
* later, let's assume that we can just allocate the }
* entire window to start with.
*/
if(scr->paddr == paddr && size <= scr->apsize)
return;
if(scr->paddr){ static char*
/* bootmapfb(VGAscr *scr, ulong pa, ulong sz)
* could call vunmap and vmap, {
* but worried about dangling pointers in devdraw ulong start, end;
*/ Pcidev *p;
error("cannot grow vga frame buffer"); int i;
}
for(p = pcimatch(nil, 0, 0); p != nil; p = pcimatch(p, 0, 0)){
/* round to page boundary, just in case */ for(i=0; i<nelem(p->mem); i++){
x = paddr&(BY2PG-1); if(p->mem[i].bar & 1)
npaddr = paddr-x; continue;
nsize = PGROUND(size+x); start = p->mem[i].bar & ~0xF;
end = start + p->mem[i].size;
/* if(pa == start && (pa + sz) <= end){
* Don't bother trying to map more than 4000x4000x32 = 64MB. scr->pci = p;
* We only have a 256MB window. return vgalinearpci0(scr);
*/ }
if(nsize > 64*MB) }
nsize = 64*MB;
scr->vaddr = vmap(npaddr, nsize);
if(scr->vaddr == 0)
error("cannot allocate vga frame buffer");
scr->vaddr = (char*)scr->vaddr+x;
scr->paddr = paddr;
scr->apsize = nsize;
/* let mtrr harmlessly fail on old CPUs, e.g., P54C */
if(!waserror()){
mtrr(npaddr, nsize, "wc");
poperror();
} }
return vgalinearaddr0(scr, pa, sz);
} }
/* /*
@ -574,7 +617,7 @@ bootscreeninit(void)
VGAscr *scr; VGAscr *scr;
int x, y, z; int x, y, z;
ulong chan, pa, sz; ulong chan, pa, sz;
char *s, *p; char *s, *p, *err;
/* *bootscreen=WIDTHxHEIGHTxDEPTH CHAN PA [SZ] */ /* *bootscreen=WIDTHxHEIGHTxDEPTH CHAN PA [SZ] */
s = getconf("*bootscreen"); s = getconf("*bootscreen");
@ -609,21 +652,12 @@ bootscreeninit(void)
if(sz < x * y * (z+7)/8) if(sz < x * y * (z+7)/8)
sz = x * y * (z+7)/8; sz = x * y * (z+7)/8;
/* round to pages */
z = pa&(BY2PG-1);
pa -= z;
sz += z;
/* map framebuffer */ /* map framebuffer */
scr = &vgascreen[0]; scr = &vgascreen[0];
scr->apsize = PGROUND(sz); if((err = bootmapfb(scr, pa, sz)) != nil){
scr->vaddr = vmap(pa, scr->apsize); print("bootmapfb: %s\n", err);
if(scr->vaddr == 0){
scr->apsize = 0;
return; return;
} }
scr->vaddr = (char*)scr->vaddr + z;
scr->paddr = pa + z;
if(memimageinit() < 0) if(memimageinit() < 0)
return; return;