summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-01-02 01:19:51 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2013-01-02 01:19:51 +0100
commit2a1b43ad98f0c7e75a1ccc9c2468540cddd0b859 (patch)
tree064d76827a3f48d0a504ae100353090367866df6
parent0e4fc14f7e3de742e45b489d497f052199f390dd (diff)
vga: make kernel vga drivers more stupid
previously, we had to maintain 3 sets of pci vid/did's: 1) in /lib/vgadb for detection 2) in the userspace driver in aux/vga 3) in the kernel mode driver this change makes the kernel mode driver more dumb in the cases where possible. we let userspace do the pci enumeration and if needed, it can set the pci address of the vga card. kernel mode drivers can assume to get the right pci device passed in scr->pci for enable() and linear() functions and just do very basic sanity checking before mapping framebuffer and mmio regions. vgalinearpciid() was removed as userspace is responsible to pick pci device. theres a new vgactl message "pcidev" where userspace can set the bus address. we initialize scr->pci in vgareset() to the first pci graphics card found. this should cover cases when an old aux/vga binary is used that doesnt use the new pcidev message. userspace drivers will now use the pci device that got a match from /lib/vgadb and skip ther own enumeration. this way, vga cards can be made to work by simply adding an entry in vgadb with no need to modify userspace or kernelspace drivers. this is not always possible if the driver derives information from the specific card model.
-rw-r--r--sys/src/9/pc/devvga.c30
-rw-r--r--sys/src/9/pc/screen.c20
-rw-r--r--sys/src/9/pc/screen.h1
-rw-r--r--sys/src/9/pc/vga3dfx.c14
-rw-r--r--sys/src/9/pc/vgaclgd542x.c2
-rw-r--r--sys/src/9/pc/vgaclgd546x.c13
-rw-r--r--sys/src/9/pc/vgacyber938x.c5
-rw-r--r--sys/src/9/pc/vgageode.c6
-rw-r--r--sys/src/9/pc/vgahiqvideo.c44
-rw-r--r--sys/src/9/pc/vgai81x.c25
-rw-r--r--sys/src/9/pc/vgamach64xx.c29
-rw-r--r--sys/src/9/pc/vgamga2164w.c18
-rw-r--r--sys/src/9/pc/vgamga4xx.c16
-rw-r--r--sys/src/9/pc/vganeomagic.c88
-rw-r--r--sys/src/9/pc/vganvidia.c16
-rw-r--r--sys/src/9/pc/vgaradeon.c16
-rw-r--r--sys/src/9/pc/vgas3.c9
-rw-r--r--sys/src/9/pc/vgat2r4.c12
-rw-r--r--sys/src/9/pc/vgavmware.c41
-rw-r--r--sys/src/cmd/aux/vga/3dfx.c4
-rw-r--r--sys/src/cmd/aux/vga/clgd546x.c17
-rw-r--r--sys/src/cmd/aux/vga/geode.c8
-rw-r--r--sys/src/cmd/aux/vga/hiqvideo.c5
-rw-r--r--sys/src/cmd/aux/vga/i81x.c45
-rw-r--r--sys/src/cmd/aux/vga/io.c18
-rw-r--r--sys/src/cmd/aux/vga/mga2164w.c8
-rw-r--r--sys/src/cmd/aux/vga/mga4xx.c25
-rw-r--r--sys/src/cmd/aux/vga/nvidia.c15
-rw-r--r--sys/src/cmd/aux/vga/pci.h2
-rw-r--r--sys/src/cmd/aux/vga/radeon.c4
-rw-r--r--sys/src/cmd/aux/vga/t2r4.c26
-rw-r--r--sys/src/cmd/aux/vga/vmware.c4
32 files changed, 242 insertions, 344 deletions
diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c
index 087088434..bdc59f11d 100644
--- a/sys/src/9/pc/devvga.c
+++ b/sys/src/9/pc/devvga.c
@@ -47,6 +47,7 @@ enum {
CMtype,
CMunblank,
CMsoftscreen,
+ CMpcidev,
};
static Cmdtab vgactlmsg[] = {
@@ -65,16 +66,31 @@ static Cmdtab vgactlmsg[] = {
CMtype, "type", 2,
CMunblank, "unblank", 1,
CMsoftscreen, "softscreen", 2,
+ CMpcidev, "pcidev", 2,
};
static void
vgareset(void)
{
+ Pcidev *pci;
+ VGAscr *scr;
+
/* reserve the 'standard' vga registers */
if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0)
- panic("vga ports already allocated");
+ panic("vga ports already allocated");
if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0)
- panic("vga ports already allocated");
+ panic("vga ports already allocated");
+
+ /* find graphics card pci device */
+ scr = &vgascreen[0];
+ scr->pci = pci = nil;
+ while((pci = pcimatch(pci, 0, 0)) != nil){
+ if(pci->ccrb == Pcibcdisp){
+ scr->pci = pci;
+ break;
+ }
+ }
+
conf.monitor = 1;
}
@@ -276,6 +292,16 @@ vgactl(Cmdbuf *cb)
}
break;
+ case CMpcidev:
+ if(cb->nf == 2){
+ Pcidev *p;
+
+ if((p = pcimatchtbdf(strtoul(cb->f[1], 0, 16))) != nil)
+ scr->pci = p;
+ } else
+ error(Ebadarg);
+ return;
+
case CMtype:
for(i = 0; vgadev[i]; i++){
if(strcmp(cb->f[1], vgadev[i]->name))
diff --git a/sys/src/9/pc/screen.c b/sys/src/9/pc/screen.c
index 9cdf9ae43..f7426b783 100644
--- a/sys/src/9/pc/screen.c
+++ b/sys/src/9/pc/screen.c
@@ -443,26 +443,6 @@ blankscreen(int blank)
}
void
-vgalinearpciid(VGAscr *scr, int vid, int did)
-{
- Pcidev *p;
-
- p = nil;
- while((p = pcimatch(p, vid, 0)) != nil){
- if(p->ccrb != 3) /* video card */
- continue;
- if(did != 0 && p->did != did)
- continue;
- break;
- }
- if(p == nil)
- error("pci video card not found");
-
- scr->pci = p;
- vgalinearpci(scr);
-}
-
-void
vgalinearpci(VGAscr *scr)
{
ulong paddr;
diff --git a/sys/src/9/pc/screen.h b/sys/src/9/pc/screen.h
index 9afb280c6..9cf40bc05 100644
--- a/sys/src/9/pc/screen.h
+++ b/sys/src/9/pc/screen.h
@@ -167,7 +167,6 @@ extern QLock drawlock;
/* vga.c */
extern void vgascreenwin(VGAscr*);
extern void vgaimageinit(ulong);
-extern void vgalinearpciid(VGAscr*, int, int);
extern void vgalinearpci(VGAscr*);
extern void vgalinearaddr(VGAscr*, ulong, int);
diff --git a/sys/src/9/pc/vga3dfx.c b/sys/src/9/pc/vga3dfx.c
index d7a052070..80cec38f3 100644
--- a/sys/src/9/pc/vga3dfx.c
+++ b/sys/src/9/pc/vga3dfx.c
@@ -36,22 +36,12 @@ tdfxenable(VGAscr* scr)
if(scr->mmio)
return;
- if(p = pcimatch(nil, 0x121A, 0)){
- switch(p->did){
- case 0x0003: /* Banshee */
- case 0x0005: /* Avenger (a.k.a. Voodoo3) */
- break;
- default:
- return;
- }
- }
- else
+ p = scr->pci;
+ if(p == nil || p->vid != 0x121A)
return;
-
scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
if(scr->mmio == nil)
return;
- scr->pci = p;
addvgaseg("3dfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size);
vgalinearpci(scr);
diff --git a/sys/src/9/pc/vgaclgd542x.c b/sys/src/9/pc/vgaclgd542x.c
index 2a980c3da..c0b1e95aa 100644
--- a/sys/src/9/pc/vgaclgd542x.c
+++ b/sys/src/9/pc/vgaclgd542x.c
@@ -44,7 +44,7 @@ clgd542xpage(VGAscr* scr, int page)
static void
clgd542xlinear(VGAscr* scr, int, int)
{
- vgalinearpciid(scr, 0x1013, 0);
+ vgalinearpci(scr);
}
static void
diff --git a/sys/src/9/pc/vgaclgd546x.c b/sys/src/9/pc/vgaclgd546x.c
index 7e66a0960..efaccc2a5 100644
--- a/sys/src/9/pc/vgaclgd546x.c
+++ b/sys/src/9/pc/vgaclgd546x.c
@@ -39,18 +39,9 @@ clgd546xenable(VGAscr* scr)
if(scr->mmio)
return;
- if((p = pcimatch(nil, 0x1013, 0)) == nil)
+ p = scr->pci;
+ if(p == nil)
return;
- switch(p->did){
- case 0xD0:
- case 0xD4:
- case 0xD6:
- break;
- default:
- return;
- }
-
- scr->pci = p;
scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
if(scr->mmio == 0)
return;
diff --git a/sys/src/9/pc/vgacyber938x.c b/sys/src/9/pc/vgacyber938x.c
index a27cdc933..ec6acf596 100644
--- a/sys/src/9/pc/vgacyber938x.c
+++ b/sys/src/9/pc/vgacyber938x.c
@@ -46,8 +46,11 @@ cyber938xlinear(VGAscr* scr, int, int)
if(scr->vaddr)
return;
- vgalinearpciid(scr, 0x1023, 0);
p = scr->pci;
+ if(p == nil)
+ return;
+
+ vgalinearpci(scr);
/*
* Heuristic to detect the MMIO space. We're flying blind
diff --git a/sys/src/9/pc/vgageode.c b/sys/src/9/pc/vgageode.c
index 513f942ec..a6346e5b1 100644
--- a/sys/src/9/pc/vgageode.c
+++ b/sys/src/9/pc/vgageode.c
@@ -29,12 +29,12 @@ geodeenable(VGAscr* scr)
{
Pcidev *p;
- if(scr->mmio) return;
- p = pcimatch(0, 0x1022, 0x2081);
+ if(scr->mmio)
+ return;
+ p = scr->pci;
if(!p) return;
scr->mmio = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
if(!scr->mmio) return;
- scr->pci = p;
addvgaseg("geodegp", p->mem[1].bar&~0x0F, p->mem[1].size);
addvgaseg("geodemmio", p->mem[2].bar&~0x0F, p->mem[2].size);
addvgaseg("geodevid", p->mem[3].bar&~0x0F, p->mem[3].size);
diff --git a/sys/src/9/pc/vgahiqvideo.c b/sys/src/9/pc/vgahiqvideo.c
index 6314e7832..9400580b5 100644
--- a/sys/src/9/pc/vgahiqvideo.c
+++ b/sys/src/9/pc/vgahiqvideo.c
@@ -50,37 +50,33 @@ hiqvideoenable(VGAscr* scr)
*/
if(scr->mmio)
return;
- if(p = pcimatch(nil, 0x102C, 0)){
- switch(p->did){
- case 0x00C0: /* 69000 HiQVideo */
- vmsize = 2*1024*1024;
+ p = scr->pci;
+ if(p == nil || p->vid != 0x102C)
+ return;
+ switch(p->did){
+ case 0x00C0: /* 69000 HiQVideo */
+ vmsize = 2*1024*1024;
+ break;
+ case 0x00E0: /* 65550 HiQV32 */
+ case 0x00E4: /* 65554 HiQV32 */
+ case 0x00E5: /* 65555 HiQV32 */
+ switch((hiqvideoxi(Xrx, 0x43)>>1) & 0x03){
+ default:
+ case 0:
+ vmsize = 1*1024*1024;
break;
- case 0x00E0: /* 65550 HiQV32 */
- case 0x00E4: /* 65554 HiQV32 */
- case 0x00E5: /* 65555 HiQV32 */
- switch((hiqvideoxi(Xrx, 0x43)>>1) & 0x03){
- default:
- case 0:
- vmsize = 1*1024*1024;
- break;
- case 1:
- vmsize = 2*1024*1024;
- break;
- }
+ case 1:
+ vmsize = 2*1024*1024;
break;
- default:
- return;
}
- }
- else
+ break;
+ default:
return;
-
- scr->pci = p;
+ }
vgalinearpci(scr);
- if(scr->paddr) {
+ if(scr->paddr)
addvgaseg("hiqvideoscreen", scr->paddr, scr->apsize);
- }
/*
* Find a place for the cursor data in display memory.
diff --git a/sys/src/9/pc/vgai81x.c b/sys/src/9/pc/vgai81x.c
index 1e801c421..ce31f6b50 100644
--- a/sys/src/9/pc/vgai81x.c
+++ b/sys/src/9/pc/vgai81x.c
@@ -50,29 +50,6 @@ i81xblank(VGAscr *scr, int blank)
*dpms = mode;
}
-static Pcidev *
-i81xpcimatch(void)
-{
- Pcidev *p;
-
- p = nil;
- while((p = pcimatch(p, 0x8086, 0)) != nil){
- switch(p->did){
- default:
- continue;
- case 0x7121:
- case 0x7123:
- case 0x7125:
- case 0x1102:
- case 0x1112:
- case 0x1132:
- case 0x3577: /* IBM R31 uses intel 830M chipset */
- return p;
- }
- }
- return nil;
-}
-
static void
i81xenable(VGAscr* scr)
{
@@ -83,7 +60,7 @@ i81xenable(VGAscr* scr)
if(scr->mmio)
return;
- p = i81xpcimatch();
+ p = scr->pci;
if(p == nil)
return;
scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
diff --git a/sys/src/9/pc/vgamach64xx.c b/sys/src/9/pc/vgamach64xx.c
index 801b46219..c31d4534b 100644
--- a/sys/src/9/pc/vgamach64xx.c
+++ b/sys/src/9/pc/vgamach64xx.c
@@ -146,34 +146,27 @@ static int hwfill(VGAscr*, Rectangle, ulong);
static int hwscroll(VGAscr*, Rectangle, Rectangle);
static void initengine(VGAscr*);
-static Pcidev*
-mach64xxpci(void)
+static void
+mach64xxenable(VGAscr* scr)
{
Pcidev *p;
int i;
- if((p = pcimatch(nil, 0x1002, 0)) == nil)
- return nil;
+ if(scr->io)
+ return;
+ p = scr->pci;
+ if(p == nil || p->vid != 0x1002)
+ return;
+ mach64type = nil;
for (i = 0; i != nelem(mach64s); i++)
if (mach64s[i].m64_id == p->did) {
+ scr->id = p->did;
mach64type = &mach64s[i];
- return p;
+ break;
}
- return nil;
-}
-
-static void
-mach64xxenable(VGAscr* scr)
-{
- Pcidev *p;
-
- if(scr->io)
- return;
- if(p = mach64xxpci()){
- scr->id = p->did;
- scr->pci = p;
+ if(mach64type != nil){
/*
* The CT doesn't always have the I/O base address
* in the PCI base registers. There is a way to find
diff --git a/sys/src/9/pc/vgamga2164w.c b/sys/src/9/pc/vgamga2164w.c
index 8144d245f..f2a4e8bce 100644
--- a/sys/src/9/pc/vgamga2164w.c
+++ b/sys/src/9/pc/vgamga2164w.c
@@ -28,20 +28,6 @@ enum {
MGA2164AGP = 0x051F
};
-static Pcidev*
-mgapcimatch(void)
-{
- Pcidev *p;
-
- p = pcimatch(nil, MATROX, MGA2164AGP);
- if(p == nil) {
- p = pcimatch(nil, MATROX, MGA2164);
- if(p == nil)
- p = pcimatch(nil, MATROX, MGA2064);
- }
- return p;
-}
-
static void
mga2164wenable(VGAscr* scr)
{
@@ -50,8 +36,8 @@ mga2164wenable(VGAscr* scr)
if(scr->mmio)
return;
- p = mgapcimatch();
- if(p == nil)
+ p = scr->pci;
+ if(p == nil || p->vid != MATROX)
return;
if(p->did == MGA2064){
diff --git a/sys/src/9/pc/vgamga4xx.c b/sys/src/9/pc/vgamga4xx.c
index d0a902808..23e53631a 100644
--- a/sys/src/9/pc/vgamga4xx.c
+++ b/sys/src/9/pc/vgamga4xx.c
@@ -77,20 +77,6 @@ enum {
FILL_OPERAND = 0x800c7804,
};
-static Pcidev *
-mgapcimatch(void)
-{
- Pcidev *p;
-
- p = pcimatch(nil, MATROX, MGA4xx);
- if(p == nil)
- p = pcimatch(nil, MATROX, MGA550);
- if(p == nil)
- p = pcimatch(nil, MATROX, MGA200);
- return p;
-}
-
-
static void
mgawrite8(VGAscr *scr, int index, uchar val)
{
@@ -129,7 +115,7 @@ mga4xxenable(VGAscr* scr)
if(scr->mmio)
return;
- pci = mgapcimatch();
+ pci = scr->pci;
if(pci == nil)
return;
diff --git a/sys/src/9/pc/vganeomagic.c b/sys/src/9/pc/vganeomagic.c
index ad9c4a29c..0f7bb6354 100644
--- a/sys/src/9/pc/vganeomagic.c
+++ b/sys/src/9/pc/vganeomagic.c
@@ -39,52 +39,50 @@ neomagicenable(VGAscr* scr)
*/
if(scr->mmio)
return;
- if(p = pcimatch(nil, 0x10C8, 0)){
- switch(p->did){
- case 0x0003: /* MagicGraph 128ZV */
- curoff = 0x100;
- vmsize = 1152*1024;
- ioaddr = (p->mem[0].bar & ~0x0F) + 0x200000;
- iosize = 0x200000;
- break;
- case 0x0083: /* MagicGraph 128ZV+ */
- curoff = 0x100;
- vmsize = 1152*1024;
- ioaddr = p->mem[1].bar & ~0x0F;
- iosize = p->mem[1].size;
- break;
- case 0x0004: /* MagicGraph 128XD */
- curoff = 0x100;
- vmsize = 2048*1024;
- ioaddr = p->mem[1].bar & ~0x0F;
- iosize = p->mem[1].size;
- break;
- case 0x0005: /* MagicMedia 256AV */
- curoff = 0x1000;
- vmsize = 2560*1024;
- ioaddr = p->mem[1].bar & ~0x0F;
- iosize = p->mem[1].size;
- break;
- case 0x0006: /* MagicMedia 256ZX */
- curoff = 0x1000;
- vmsize = 4096*1024;
- ioaddr = p->mem[1].bar & ~0x0F;
- iosize = p->mem[1].size;
- break;
- case 0x0016: /* MagicMedia 256XL+ */
- curoff = 0x1000;
- /* Vaio VESA BIOS says 6080, but then hwgc doesn't work */
- vmsize = 4096*1024;
- ioaddr = p->mem[1].bar & ~0x0F;
- iosize = p->mem[1].size;
- break;
- default:
- return;
- }
- }
- else
+ p = scr->pci;
+ if(p == nil || p->vid != 0x10C8)
+ return;
+ switch(p->did){
+ case 0x0003: /* MagicGraph 128ZV */
+ curoff = 0x100;
+ vmsize = 1152*1024;
+ ioaddr = (p->mem[0].bar & ~0x0F) + 0x200000;
+ iosize = 0x200000;
+ break;
+ case 0x0083: /* MagicGraph 128ZV+ */
+ curoff = 0x100;
+ vmsize = 1152*1024;
+ ioaddr = p->mem[1].bar & ~0x0F;
+ iosize = p->mem[1].size;
+ break;
+ case 0x0004: /* MagicGraph 128XD */
+ curoff = 0x100;
+ vmsize = 2048*1024;
+ ioaddr = p->mem[1].bar & ~0x0F;
+ iosize = p->mem[1].size;
+ break;
+ case 0x0005: /* MagicMedia 256AV */
+ curoff = 0x1000;
+ vmsize = 2560*1024;
+ ioaddr = p->mem[1].bar & ~0x0F;
+ iosize = p->mem[1].size;
+ break;
+ case 0x0006: /* MagicMedia 256ZX */
+ curoff = 0x1000;
+ vmsize = 4096*1024;
+ ioaddr = p->mem[1].bar & ~0x0F;
+ iosize = p->mem[1].size;
+ break;
+ case 0x0016: /* MagicMedia 256XL+ */
+ curoff = 0x1000;
+ /* Vaio VESA BIOS says 6080, but then hwgc doesn't work */
+ vmsize = 4096*1024;
+ ioaddr = p->mem[1].bar & ~0x0F;
+ iosize = p->mem[1].size;
+ break;
+ default:
return;
- scr->pci = p;
+ }
scr->mmio = vmap(ioaddr, iosize);
if(scr->mmio == nil)
diff --git a/sys/src/9/pc/vganvidia.c b/sys/src/9/pc/vganvidia.c
index d4ce5b889..d5563ecf1 100644
--- a/sys/src/9/pc/vganvidia.c
+++ b/sys/src/9/pc/vganvidia.c
@@ -77,19 +77,6 @@ static struct {
int dmamax;
} nv;
-static Pcidev*
-nvidiapci(void)
-{
- Pcidev *p;
-
- p = nil;
- while((p = pcimatch(p, 0x10DE, 0)) != nil){
- if(p->did >= 0x20 && p->ccrb == 3) /* video card */
- return p;
- }
- return nil;
-}
-
static void
nvidiaenable(VGAscr* scr)
{
@@ -99,11 +86,10 @@ nvidiaenable(VGAscr* scr)
if(scr->mmio)
return;
- p = nvidiapci();
+ p = scr->pci;
if(p == nil)
return;
scr->id = p->did;
- scr->pci = p;
scr->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
if(scr->mmio == nil)
diff --git a/sys/src/9/pc/vgaradeon.c b/sys/src/9/pc/vgaradeon.c
index 6fb89c8da..50d0bab65 100644
--- a/sys/src/9/pc/vgaradeon.c
+++ b/sys/src/9/pc/vgaradeon.c
@@ -25,19 +25,6 @@ enum {
Meg = Kilo * Kilo,
};
-static Pcidev*
-radeonpci(void)
-{
- static Pcidev *p = nil;
- struct pciids *ids;
-
- while ((p = pcimatch(p, ATI_PCIVID, 0)) != nil)
- for (ids = radeon_pciids; ids->did; ids++)
- if (ids->did == p->did)
- return p;
- return nil;
-}
-
/* mmio access */
static void
@@ -96,11 +83,10 @@ radeonenable(VGAscr *scr)
if (scr->mmio)
return;
- p = radeonpci();
+ p = scr->pci;
if (p == nil)
return;
scr->id = p->did;
- scr->pci = p;
scr->mmio = vmap(p->mem[2].bar & ~0x0f, p->mem[2].size);
if(scr->mmio == 0)
diff --git a/sys/src/9/pc/vgas3.c b/sys/src/9/pc/vgas3.c
index 14dc53840..bbf034560 100644
--- a/sys/src/9/pc/vgas3.c
+++ b/sys/src/9/pc/vgas3.c
@@ -95,12 +95,13 @@ s3linear(VGAscr* scr, int, int)
ulong mmiobase, mmiosize;
Pcidev *p;
- vgalinearpciid(scr, PCIS3, 0);
p = scr->pci;
- if(scr->paddr == 0 || p == nil)
+ if(p == nil)
return;
-
- addvgaseg("s3screen", scr->paddr, scr->apsize);
+ vgalinearpci(scr);
+
+ if(scr->paddr)
+ addvgaseg("s3screen", scr->paddr, scr->apsize);
id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
switch(id){ /* find mmio */
diff --git a/sys/src/9/pc/vgat2r4.c b/sys/src/9/pc/vgat2r4.c
index e106fa3f2..3b5f21472 100644
--- a/sys/src/9/pc/vgat2r4.c
+++ b/sys/src/9/pc/vgat2r4.c
@@ -64,17 +64,9 @@ t2r4enable(VGAscr* scr)
if(scr->mmio)
return;
- if(p = pcimatch(nil, 0x105D, 0)){
- switch(p->did){
- case 0x5348:
- break;
- default:
- return;
- }
- }
- else
+ p = scr->pci;
+ if(p == nil)
return;
- scr->pci = p;
mmio = vmap(p->mem[4].bar & ~0x0F, p->mem[4].size);
if(mmio == nil)
diff --git a/sys/src/9/pc/vgavmware.c b/sys/src/9/pc/vgavmware.c
index ddb7e523e..710da156e 100644
--- a/sys/src/9/pc/vgavmware.c
+++ b/sys/src/9/pc/vgavmware.c
@@ -137,34 +137,25 @@ vmwait(Vmware *vm)
static void
vmwarelinear(VGAscr* scr, int, int)
{
- char err[64];
Pcidev *p;
- err[0] = 0;
- p = nil;
- while((p = pcimatch(p, PCIVMWARE, 0)) != nil){
- if(p->ccrb != Pcibcdisp)
- continue;
- switch(p->did){
- default:
- snprint(err, sizeof err, "unknown vmware pci did %.4ux",
- p->did);
- continue;
- 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;
- }
- break; /* found a card, p is set */
+ 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;
}
- if(p == nil)
- error(err[0]? err: "no vmware vga card found");
// vm->fb = vmrd(vm, Rfbstart);
vm->fb = p->mem[1].bar & ~0xF;
vm->fb += vmrd(vm, Rfboffset);
diff --git a/sys/src/cmd/aux/vga/3dfx.c b/sys/src/cmd/aux/vga/3dfx.c
index e42b7c9c0..d1a4b59f8 100644
--- a/sys/src/cmd/aux/vga/3dfx.c
+++ b/sys/src/cmd/aux/vga/3dfx.c
@@ -51,8 +51,10 @@ snarf(Vga* vga, Ctlr* ctlr)
if(vga->private == nil){
tdfx = alloc(sizeof(Tdfx));
- tdfx->pci = pcimatch(0, 0x121A, 0);
+ tdfx->pci = vga->pci;
if(tdfx->pci == nil)
+ tdfx->pci = pcimatch(0, 0x121A, 0);
+ if(tdfx->pci == nil || tdfx->pci->vid != 0x121A)
error("%s: not found\n", ctlr->name);
switch(tdfx->pci->did){
default:
diff --git a/sys/src/cmd/aux/vga/clgd546x.c b/sys/src/cmd/aux/vga/clgd546x.c
index e46f33b72..653ccd31d 100644
--- a/sys/src/cmd/aux/vga/clgd546x.c
+++ b/sys/src/cmd/aux/vga/clgd546x.c
@@ -73,7 +73,7 @@ mmio32w(Laguna* laguna, int offset, int data)
static void
snarf(Vga* vga, Ctlr* ctlr)
{
- int f, i;
+ int i;
uchar *mmio;
Pcidev *p;
Laguna *laguna;
@@ -93,7 +93,10 @@ snarf(Vga* vga, Ctlr* ctlr)
if(vga->private == nil){
vga->private = alloc(sizeof(Laguna));
- if((p = pcimatch(0, 0x1013, 0)) == nil)
+ p = vga->pci;
+ if(p == nil)
+ p = pcimatch(0, 0x1013, 0);
+ if(p == nil || p->vid != 0x1013)
error("%s: not found\n", ctlr->name);
switch(p->did){
case 0xD0: /* CL-GD5462 */
@@ -104,14 +107,12 @@ snarf(Vga* vga, Ctlr* ctlr)
vga->f[1] = 230000000;
break;
default:
- error("%s: not found\n", ctlr->name);
+ error("%s: DID %4.4uX unsupported\n",
+ ctlr->name, p->did);
}
- if((f = open("#v/vgactl", OWRITE)) < 0)
- error("%s: can't open vgactl\n", ctlr->name);
- if(write(f, "type clgd546x", 13) != 13)
- error("%s: can't set type\n", ctlr->name);
- close(f);
+ vgactlpci(p);
+ vgactlw("type", "clgd546x");
mmio = segattach(0, "clgd546xmmio", 0, p->mem[1].size);
if(mmio == (void*)-1)
diff --git a/sys/src/cmd/aux/vga/geode.c b/sys/src/cmd/aux/vga/geode.c
index 6bae51b68..b83af1ecb 100644
--- a/sys/src/cmd/aux/vga/geode.c
+++ b/sys/src/cmd/aux/vga/geode.c
@@ -66,8 +66,12 @@ snarf(Vga* vga, Ctlr* ctlr)
if(!vga->private) {
geode = alloc(sizeof(Geode));
- geode->pci = pcimatch(0, 0x1022, 0x2081);
- if(!geode->pci) error("%s: not found\n", ctlr->name);
+ geode->pci = vga->pci;
+ if(geode->pci == nil){
+ geode->pci = pcimatch(0, 0x1022, 0x2081);
+ if(!geode->pci) error("%s: not found\n", ctlr->name);
+ }
+ vgactlpci(geode->pci);
vgactlw("type", "geode");
geode->mmio = segattach(0, "geodemmio", 0, geode->pci->mem[2].size);
if(geode->mmio == (ulong*)-1) error("%s: can't attach mmio segment\n", ctlr->name);
diff --git a/sys/src/cmd/aux/vga/hiqvideo.c b/sys/src/cmd/aux/vga/hiqvideo.c
index 6d80ec0d8..de0304986 100644
--- a/sys/src/cmd/aux/vga/hiqvideo.c
+++ b/sys/src/cmd/aux/vga/hiqvideo.c
@@ -52,7 +52,10 @@ snarf(Vga* vga, Ctlr* ctlr)
if(vga->private == nil){
vga->private = alloc(sizeof(HiQVideo));
hqv = vga->private;
- if((p = pcimatch(nil, 0x102C, 0)) == nil)
+ p = vga->pci;
+ if(p == nil)
+ p = pcimatch(nil, 0x102C, 0);
+ if(p == nil || p->vid != 0x102C)
error("%s: not found\n", ctlr->name);
switch(p->did){
case 0x00C0: /* 69000 HiQVideo */
diff --git a/sys/src/cmd/aux/vga/i81x.c b/sys/src/cmd/aux/vga/i81x.c
index b1fdf74be..9ee726b33 100644
--- a/sys/src/cmd/aux/vga/i81x.c
+++ b/sys/src/cmd/aux/vga/i81x.c
@@ -25,7 +25,7 @@ typedef struct {
static void
snarf(Vga* vga, Ctlr* ctlr)
{
- int f, i;
+ int i;
uchar *mmio;
ulong *rp;
Pcidev *p;
@@ -33,31 +33,30 @@ snarf(Vga* vga, Ctlr* ctlr)
if(vga->private == nil){
vga->private = alloc(sizeof(I81x));
- p = nil;
- while((p = pcimatch(p, 0x8086, 0)) != nil) {
- switch(p->did) {
- default:
- continue;
- case 0x7121: /* Vanilla 82810 */
- case 0x7123: /* 810-DC100, DELL OptiPlex GX100 */
- case 0x7125: /* 82810E */
- case 0x1102: /* 82815 FSB limited to 100MHz */
- case 0x1112: /* 82815 no AGP */
- case 0x1132: /* 82815 fully featured Solano */
- case 0x3577: /* IBM R31 uses intel 830M chipset */
- vga->f[1] = 230000000; /* MAX speed of internal DAC (Hz)*/
+ p = vga->pci;
+ if(p == nil){
+ while((p = pcimatch(p, 0x8086, 0)) != nil) {
+ switch(p->did) {
+ default:
+ continue;
+ case 0x7121: /* Vanilla 82810 */
+ case 0x7123: /* 810-DC100, DELL OptiPlex GX100 */
+ case 0x7125: /* 82810E */
+ case 0x1102: /* 82815 FSB limited to 100MHz */
+ case 0x1112: /* 82815 no AGP */
+ case 0x1132: /* 82815 fully featured Solano */
+ case 0x3577: /* IBM R31 uses intel 830M chipset */
+ break;
+ }
break;
}
- break;
+ if(p == nil)
+ error("%s: Intel 81x graphics function not found\n", ctlr->name);
}
- if(p == nil)
- error("%s: Intel 81x graphics function not found\n", ctlr->name);
-
- if((f = open("#v/vgactl", OWRITE)) < 0)
- error("%s: can't open vgactl\n", ctlr->name);
- if(write(f, "type i81x", 9) != 9)
- error("%s: can't set type\n", ctlr->name);
- close(f);
+ vga->f[1] = 230000000; /* MAX speed of internal DAC (Hz)*/
+
+ vgactlpci(p);
+ vgactlw("type", "i81x");
mmio = segattach(0, "i81xmmio", 0, p->mem[1].size);
if(mmio == (void*)-1)
diff --git a/sys/src/cmd/aux/vga/io.c b/sys/src/cmd/aux/vga/io.c
index ed73f6a27..e2a4a460e 100644
--- a/sys/src/cmd/aux/vga/io.c
+++ b/sys/src/cmd/aux/vga/io.c
@@ -214,6 +214,24 @@ vgactlw(char* attr, char* val)
}
void
+vgactlpci(Pcidev *p)
+{
+ char buf[64];
+ int len;
+
+ if(p == nil)
+ return;
+ if(ctlfd == -1)
+ ctlfd = devopen("#v/vgactl", ORDWR);
+ len = snprint(buf, sizeof(buf), "pcidev %lux", (ulong)p->tbdf);
+ seek(ctlfd, 0, 0);
+ /* ignore error for old kernel */
+ write(ctlfd, buf, len);
+
+ ctlclean = 0;
+}
+
+void
setpalette(int p, int r, int g, int b)
{
vgao(PaddrW, p);
diff --git a/sys/src/cmd/aux/vga/mga2164w.c b/sys/src/cmd/aux/vga/mga2164w.c
index 3c2cd48fa..16b0b5088 100644
--- a/sys/src/cmd/aux/vga/mga2164w.c
+++ b/sys/src/cmd/aux/vga/mga2164w.c
@@ -118,7 +118,6 @@ crtcexto(uchar index, uchar data)
static void
mapmga(Vga* vga, Ctlr* ctlr)
{
- int f;
uchar *m;
Mga *mga;
@@ -126,11 +125,8 @@ mapmga(Vga* vga, Ctlr* ctlr)
error("%s: tvp3026io: no *mga\n", ctlr->name);
mga = vga->private;
- f = open("#v/vgactl", OWRITE);
- if(f < 0)
- error("%s: can't open vgactl\n", ctlr->name);
- if(write(f, "type mga2164w", 13) != 13)
- error("%s: can't set mga type\n", ctlr->name);
+ vgactlpci(vga->pci);
+ vgactlw("type", "mga2164w");
m = segattach(0, "mga2164wmmio", 0, 16*1024);
if(m == (void*)-1)
diff --git a/sys/src/cmd/aux/vga/mga4xx.c b/sys/src/cmd/aux/vga/mga4xx.c
index d29d714d9..bb2d59b2f 100644
--- a/sys/src/cmd/aux/vga/mga4xx.c
+++ b/sys/src/cmd/aux/vga/mga4xx.c
@@ -448,27 +448,18 @@ dump(Vga* vga, Ctlr* ctlr)
static void
setpalettedepth(int depth)
{
- int fd;
- char *cmd = strdup("palettedepth X");
+ char buf[12];
if ((depth != 8) && (depth != 6) && (depth != 16))
error("mga: invalid palette depth %d\n", depth);
- fd = open("#v/vgactl", OWRITE);
- if(fd < 0)
- error("mga: can't open vgactl\n");
-
- cmd[13] = '0' + depth;
- if(write(fd, cmd, 14) != 14)
- error("mga: can't set palette depth to %d\n", depth);
-
- close(fd);
+ snprint(buf, sizeof(buf), "%d", depth);
+ vgactlw("palettedepth", buf);
}
static void
mapmga4xx(Vga* vga, Ctlr* ctlr)
{
- int f;
uchar* m;
Mga * mga;
@@ -476,12 +467,8 @@ mapmga4xx(Vga* vga, Ctlr* ctlr)
error("%s: g4xxio: no *mga4xx\n", ctlr->name);
mga = vga->private;
- f = open("#v/vgactl", OWRITE);
- if(f < 0)
- error("%s: can't open vgactl\n", ctlr->name);
-
- if(write(f, "type mga4xx", 11) != 11)
- error("%s: can't set mga type\n", ctlr->name);
+ vgactlpci(vga->pci);
+ vgactlw("type", "mga4xx");
m = segattach(0, "mga4xxmmio", 0, 16*Kilo);
if(m == (void*)-1)
@@ -500,8 +487,6 @@ mapmga4xx(Vga* vga, Ctlr* ctlr)
}
mga->mmfb = m;
trace("%s: frame buffer at %#p\n", ctlr->name, mga->mmfb);
-
- close(f);
}
static void
diff --git a/sys/src/cmd/aux/vga/nvidia.c b/sys/src/cmd/aux/vga/nvidia.c
index f3dd5cf56..a014854ac 100644
--- a/sys/src/cmd/aux/vga/nvidia.c
+++ b/sys/src/cmd/aux/vga/nvidia.c
@@ -136,14 +136,17 @@ snarf(Vga* vga, Ctlr* ctlr)
vga->private = alloc(sizeof(Nvidia));
nv = vga->private;
- p = nil;
- while((p = pcimatch(p, 0x10DE, 0)) != nil){
- if(p->ccrb == 3)
- break;
+ p = vga->pci;
+ if(p == nil){
+ while((p = pcimatch(p, 0x10DE, 0)) != nil){
+ if(p->ccrb == 3)
+ break;
+ }
+ if(p == nil)
+ error("%s: not found\n", ctlr->name);
}
- if(p == nil)
- error("%s: not found\n", ctlr->name);
+ vgactlpci(p);
vgactlw("type", ctlr->name);
mmio = segattach(0, "nvidiammio", 0, p->mem[0].size);
diff --git a/sys/src/cmd/aux/vga/pci.h b/sys/src/cmd/aux/vga/pci.h
index 7d8fe11ea..a245b0f96 100644
--- a/sys/src/cmd/aux/vga/pci.h
+++ b/sys/src/cmd/aux/vga/pci.h
@@ -103,3 +103,5 @@ typedef struct Pcidev {
Pcidev* list;
int rawfd;
};
+
+extern void vgactlpci(Pcidev *);
diff --git a/sys/src/cmd/aux/vga/radeon.c b/sys/src/cmd/aux/vga/radeon.c
index 5f3ce2f40..211b00403 100644
--- a/sys/src/cmd/aux/vga/radeon.c
+++ b/sys/src/cmd/aux/vga/radeon.c
@@ -232,10 +232,14 @@ snarf(Vga *vga, Ctlr *ctlr)
vga->private = alloc(sizeof(Radeon));
radeon = vga->private;
+ isr300 = 0;
p = radeonpci(&isr300);
if (p == nil)
+ p = vga->pci;
+ if (p == nil)
error("%s: not found\n", ctlr->name);
+ vgactlpci(p);
vgactlw("type", ctlr->name);
mmio = (uintptr)segattach(0, "radeonmmio", (void *)0,
diff --git a/sys/src/cmd/aux/vga/t2r4.c b/sys/src/cmd/aux/vga/t2r4.c
index 2ec95c637..bfa78e651 100644
--- a/sys/src/cmd/aux/vga/t2r4.c
+++ b/sys/src/cmd/aux/vga/t2r4.c
@@ -91,27 +91,27 @@ static void
snarf(Vga* vga, Ctlr* ctlr)
{
ulong *mmio;
- int f, i, x;
+ int i, x;
Pcidev *p;
T2r4 *t2r4;
ulong *rp;
if(vga->private == nil){
vga->private = alloc(sizeof(T2r4));
- if((p = pcimatch(0, 0x105D, 0)) == nil)
- error("%s: not found\n", ctlr->name);
- switch(p->did){
- case 0x5348: /* */
- break;
- default:
- error("%s: not found\n", ctlr->name);
+ p = vga->pci;
+ if(p == nil){
+ if((p = pcimatch(0, 0x105D, 0)) == nil)
+ error("%s: not found\n", ctlr->name);
+ switch(p->did){
+ case 0x5348: /* */
+ break;
+ default:
+ error("%s: not found\n", ctlr->name);
+ }
}
- if((f = open("#v/vgactl", OWRITE)) < 0)
- error("%s: can't open vgactl\n", ctlr->name);
- if(write(f, "type t2r4", 9) != 9)
- error("%s: can't set type\n", ctlr->name);
- close(f);
+ vgactlpci(p);
+ vgactlw("type", "t2r4");
mmio = segattach(0, "t2r4mmio", 0, p->mem[4].size);
if(mmio == (void*)-1)
diff --git a/sys/src/cmd/aux/vga/vmware.c b/sys/src/cmd/aux/vga/vmware.c
index 71b35313b..d44c0a0a3 100644
--- a/sys/src/cmd/aux/vga/vmware.c
+++ b/sys/src/cmd/aux/vga/vmware.c
@@ -125,7 +125,6 @@ snarf(Vga* vga, Ctlr* ctlr)
p = vga->pci;
if(p == nil)
error("%s: vga->pci not set\n", ctlr->name);
-
vm = alloc(sizeof(Vmware));
switch(p->did){
case VMWARE1: /* VMware video chipset #1 */
@@ -141,8 +140,9 @@ snarf(Vga* vga, Ctlr* ctlr)
break;
default:
- error("%s: unrecognized chipset %.4ux\n", ctlr->name, p->did);
+ error("%s: unrecognized DID %.4ux\n", ctlr->name, p->did);
}
+ vgactlpci(p);
for(i=0; i<Nreg; i++)
vm->r[i] = vmrd(vm, i);