diff --git a/sys/src/9/pc/vgaigfx.c b/sys/src/9/pc/vgaigfx.c index 30b2096e8..9b03c9bbb 100644 --- a/sys/src/9/pc/vgaigfx.c +++ b/sys/src/9/pc/vgaigfx.c @@ -13,44 +13,67 @@ #include "screen.h" static ulong -preallocsize(Pcidev *p) +stolenmb(Pcidev *p) { switch(p->did){ case 0x0166: /* Ivy Bridge */ switch((pcicfgr16(p, 0x50) >> 3) & 0x1f){ - case 0x01: return 32*MB - 2*MB; - case 0x02: return 64*MB - 2*MB; - case 0x03: return 96*MB - 2*MB; - case 0x04: return 128*MB - 2*MB; - case 0x05: return 32*MB - 2*MB; - case 0x06: return 48*MB - 2*MB; - case 0x07: return 64*MB - 2*MB; - case 0x08: return 128*MB - 2*MB; - case 0x09: return 256*MB - 2*MB; - case 0x0A: return 96*MB - 2*MB; - case 0x0B: return 160*MB - 2*MB; - case 0x0C: return 224*MB - 2*MB; - case 0x0D: return 352*MB - 2*MB; - case 0x0E: return 448*MB - 2*MB; - case 0x0F: return 480*MB - 2*MB; - case 0x10: return 512*MB - 2*MB; + case 0x01: return 32 - 2; + case 0x02: return 64 - 2; + case 0x03: return 96 - 2; + case 0x04: return 128 - 2; + case 0x05: return 32 - 2; + case 0x06: return 48 - 2; + case 0x07: return 64 - 2; + case 0x08: return 128 - 2; + case 0x09: return 256 - 2; + case 0x0A: return 96 - 2; + case 0x0B: return 160 - 2; + case 0x0C: return 224 - 2; + case 0x0D: return 352 - 2; + case 0x0E: return 448 - 2; + case 0x0F: return 480 - 2; + case 0x10: return 512 - 2; } break; case 0x2a42: /* X200 */ + case 0x2a02: /* CF-R7 */ switch((pcicfgr16(p, 0x52) >> 4) & 7){ - case 0x01: return 1*MB; - case 0x02: return 4*MB; - case 0x03: return 8*MB; - case 0x04: return 16*MB; - case 0x05: return 32*MB; - case 0x06: return 48*MB; - case 0x07: return 64*MB; + case 0x01: return 1; + case 0x02: return 4; + case 0x03: return 8; + case 0x04: return 16; + case 0x05: return 32; + case 0x06: return 48; + case 0x07: return 64; } break; } return 0; } +static uintptr +gmsize(Pcidev *pci, void *mmio) +{ + u32int x, i, npg, *gtt; + + npg = stolenmb(pci)<<(20-12); + if(npg == 0) + return 0; + gtt = (u32int*)((uchar*)mmio + pci->mem[0].size/2); + if((gtt[0]&1) == 0) + return 0; + x = (gtt[0]>>12)+1; + for(i=1; i>12) != x) + break; + x++; + } + if(0) print("igfx: graphics memory at %p-%p (%ud MB)\n", + (uintptr)(x-i)<<12, (uintptr)x<<12, (i>>(20-12))); + return (uintptr)i<<12; +} + static void igfxenable(VGAscr* scr) { @@ -69,8 +92,10 @@ igfxenable(VGAscr* scr) vgalinearpci(scr); if(scr->apsize){ addvgaseg("igfxscreen", scr->paddr, scr->apsize); - scr->storage = preallocsize(p); - if(scr->storage > scr->apsize) + scr->storage = gmsize(p, scr->mmio); + if(scr->storage < MB) + scr->storage = 0; + else if(scr->storage > scr->apsize) scr->storage = scr->apsize; if(scr->storage != 0) scr->storage -= PGROUND(64*64*4); @@ -133,6 +158,7 @@ igfxcurregs(VGAscr* scr, int pipe) return nil; break; case 0x2a42: /* X200 */ + case 0x2a02: /* CF-R7 */ if(pipe > 1) return nil; o = pipe*0x40;