From b3b6a55c781305fa10b9d137d927d237e1796c85 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 25 Jul 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-07-25 --- pc/devether.c | 1 + pc/mem.h | 2 +- pc/pci.c | 119 ++++++++++++++++++++++++++++++++++++++++---------- pc/scsi.c | 3 +- 4 files changed, 101 insertions(+), 24 deletions(-) diff --git a/pc/devether.c b/pc/devether.c index d265197ddd6b33fb512a5d483c47bb1e6fec4f75..a7bc7414c6d789a5c0d3a78fedbcbf82d91aa87d 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -246,6 +246,7 @@ etherreset(void) memmove(ctlr->addr, ctlr->ea, sizeof(ctlr->ea)); memmove(ctlr->bcast, etherbcast, sizeof(etherbcast)); + ctlr->ctlrno = ctlrno; ether[ctlrno] = ctlr; ctlr = 0; break; diff --git a/pc/mem.h b/pc/mem.h index d4f16a31089dda898f7d9604e41174548d3b5923..a829ab1ad884b039140be694860506c4881dd46e 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -20,7 +20,7 @@ /* * Time */ -#define HZ (50) /* clock frequency */ +#define HZ (100) /* clock frequency */ #define MS2HZ (1000/HZ) /* millisec per clock tick */ #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ #define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ diff --git a/pc/pci.c b/pc/pci.c index 984aee8cc4a1d3fa57400d252c40214c81174aa1..6a2bec5043f3b1b018ac517dbfa638c1fb82f8e5 100644 --- a/pc/pci.c +++ b/pc/pci.c @@ -1,3 +1,7 @@ +/* + * Trivial PCI configuration code. + * Only deals with bus 0, amongst other glaring omissions. + */ #include "u.h" #include "../port/lib.h" #include "mem.h" @@ -8,6 +12,34 @@ static Lock pcicfglock; +static int pcicfgmode = -1; + +static void +pcicfginit(int) +{ + /* + * Try to determine which PCI configuration mode is implemented. + * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses + * a DWORD at 0xCF8 and another at 0xCFC and will pass through + * any non-DWORD accesses as normal I/O cycles. There shouldn't be + * a device behind theses addresses so if Mode2 accesses fail try + * for Mode1 (which is preferred, Mode2 is deprecated). + */ + outb(PCIcse, 0); + if(inb(PCIcse) == 0){ + pcicfgmode = 2; + return; + } + + outl(PCIaddr, 0); + if(inl(PCIaddr) == 0){ + pcicfgmode = 1; + return; + } + + pcicfgmode = -1; +} + /* * Read a chunk of PCI configuration space. * Assumes arguments are within limits and regno and @@ -16,44 +48,87 @@ static Lock pcicfglock; void pcicfgr(int busno, int devno, int funcno, int regno, void* data, int nbytes) { - ulong* p; + ulong addr, *p; int base, len; lock(&pcicfglock); - outb(PCIcse, 0x80|((funcno & 0x07)<<1)); - outb(PCIforward, busno); - - base = (0xC000|(devno<<8)) + regno; - p = data; - for(len = nbytes/sizeof(ulong); len > 0; len--){ - *p = inl(base); - p++; - base += sizeof(*p); + if(pcicfgmode == -1) + pcicfginit(busno); + + switch(pcicfgmode){ + + case 1: + addr = 0x80000000|((busno & 0xFF)<<16)|((devno & 0x1F)<<11)|((funcno & 0x03)<<8); + p = data; + for(len = nbytes/sizeof(ulong); len > 0; len--){ + outl(PCIaddr, addr|(regno & 0xFF)); + *p = inl(PCIdata); + p++; + regno += sizeof(ulong); + } + + outl(PCIaddr, 0); + break; + + case 2: + outb(PCIcse, 0x80|((funcno & 0x07)<<1)); + outb(PCIforward, busno); + + base = (0xC000|(devno<<8)) + regno; + p = data; + for(len = nbytes/sizeof(ulong); len > 0; len--){ + *p = inl(base); + p++; + base += sizeof(*p); + } + + outb(PCIcse, 0); + break; } - outb(PCIcse, 0x00); unlock(&pcicfglock); } void pcicfgw(int busno, int devno, int funcno, int regno, void* data, int nbytes) { - ulong* p; + ulong addr, *p; int base, len; lock(&pcicfglock); - outb(PCIcse, 0x80|((funcno & 0x07)<<1)); - outb(PCIforward, busno); - - base = (0xC000|(devno<<8)) + regno; - p = data; - for(len = nbytes/sizeof(ulong); len > 0; len--){ - outl(base, *p); - p++; - base += sizeof(*p); + if(pcicfgmode == -1) + pcicfginit(busno); + + switch(pcicfgmode){ + + case 1: + addr = 0x80000000|((busno & 0xFF)<<16)|((devno & 0x1F)<<11)|((funcno & 0x03)<<8); + p = data; + for(len = nbytes/sizeof(ulong); len > 0; len--){ + outl(PCIaddr, addr|(regno & 0xFF)); + outl(PCIdata, *p); + p++; + regno += sizeof(ulong); + } + + outl(PCIaddr, 0); + break; + + case 2: + outb(PCIcse, 0x80|((funcno & 0x07)<<1)); + outb(PCIforward, busno); + + base = (0xC000|(devno<<8)) + regno; + p = data; + for(len = nbytes/sizeof(ulong); len > 0; len--){ + outl(base, *p); + p++; + base += sizeof(*p); + } + + outb(PCIcse, 0); } - outb(PCIcse, 0x00); unlock(&pcicfglock); } diff --git a/pc/scsi.c b/pc/scsi.c index 55463e1aa414f84b1f678e0e9c4683c44a166175..03bac1dde09bdfee958d92e9d09d44e5bfe1e6d3 100644 --- a/pc/scsi.c +++ b/pc/scsi.c @@ -206,7 +206,8 @@ scsiinv(int devno, int *type, Target **rt, uchar **inq, char *id) continue; *rt = t; *inq = t->inq; - sprint(id, "scsi%d: unit %d", ctlr, unit); + if(id) + sprint(id, "scsi%d: unit %d", ctlr, unit); return devno; } }