M pc/devi82365.c => pc/devi82365.c +39 -54
@@ 356,7 356,7 @@ pcmmap(int slotno, ulong offset, int len, int attr)
umbfree(m->isa, m->len);
m->len = 0;
}
- m->isa = umbmalloc(0, len, Mgran)&~KZERO;
+ m->isa = PADDR(umbmalloc(0, len, Mgran));
if(m->isa == 0){
print("pcmmap: out of isa space\n");
unlock(&pp->mlock);
@@ 515,12 515,12 @@ static char *chipname[] =
static I82365*
i82386probe(int x, int d, int dev)
{
- uchar c;
+ uchar c, id;
I82365 *cp;
outb(x, Rid + (dev<<7));
- c = inb(d);
- if((c & 0xf0) != 0x80)
+ id = inb(d);
+ if((id & 0xf0) != 0x80)
return 0; /* not this family */
cp = xalloc(sizeof(I82365));
@@ 530,9 530,10 @@ i82386probe(int x, int d, int dev)
cp->type = Ti82365;
cp->nslot = 2;
- switch(c){
+ switch(id){
case 0x82:
case 0x83:
+ case 0x84:
/* could be a cirrus */
outb(x, Rchipinfo + (dev<<7));
outb(d, 0);
@@ 559,7 560,8 @@ i82386probe(int x, int d, int dev)
outb(d, c|0xC0);
outb(x, Rid + (dev<<7));
c = inb(d);
- print("ctlr id %uX\n", c & 0xFF);
+ if(c != id && !(c & 0x08))
+ print("#y%d: id %uX changed to %uX\n", ncontroller, id, c);
if(c & 0x08)
cp->type = Tvg46x;
outb(x, 0x3A + (dev<<7));
@@ 567,8 569,7 @@ i82386probe(int x, int d, int dev)
outb(d, c & ~0xC0);
}
- print("pcmcia controller%d is a %d slot %s\n", ncontroller, cp->nslot,
- chipname[cp->type]);
+ print("#y%d: %d slot %s\n", ncontroller, cp->nslot, chipname[cp->type]);
/* low power mode */
outb(x, Rmisc2 + (dev<<7));
@@ 712,7 713,6 @@ pcmread(int slotno, int attr, void *a, long n, ulong offset)
{
int i, len;
PCMmap *m;
- ulong ka;
uchar *ac;
Slot *pp;
@@ 738,8 738,7 @@ pcmread(int slotno, int attr, void *a, long n, ulong offset)
i = m->cea - offset;
else
i = len;
- ka = KZERO|(m->isa + offset - m->ca);
- memmoveb(ac, (void*)ka, i);
+ memmoveb(ac, KADDR(m->isa + offset - m->ca), i);
pcmunmap(pp->slotno, m);
offset += i;
ac += i;
@@ 752,50 751,42 @@ pcmread(int slotno, int attr, void *a, long n, ulong offset)
static long
i82365read(Chan *c, void *a, long n, ulong offset)
{
- char *cp, buf[2048];
- ulong p;
+ char *p;
+ int len;
Slot *pp;
- p = TYPE(c);
- switch(p){
+ switch(TYPE(c)){
case Qdir:
return devdirread(c, a, n, 0, 0, pcmgen);
case Qmem:
case Qattr:
- return pcmread(SLOTNO(c), p==Qattr, a, n, offset);
+ return pcmread(SLOTNO(c), TYPE(c) == Qattr, a, n, offset);
case Qctl:
- cp = buf;
+ p = malloc(READSTR);
+ len = 0;
pp = slot + SLOTNO(c);
+
if(pp->occupied)
- cp += sprint(cp, "occupied\n");
+ len += snprint(p+len, READSTR-len, "occupied\n");
if(pp->enabled)
- cp += sprint(cp, "enabled\n");
+ len += snprint(p+len, READSTR-len, "enabled\n");
if(pp->powered)
- cp += sprint(cp, "powered\n");
+ len += snprint(p+len, READSTR-len, "powered\n");
if(pp->configed)
- cp += sprint(cp, "configed\n");
+ len += snprint(p+len, READSTR-len, "configed\n");
if(pp->wrprot)
- cp += sprint(cp, "write protected\n");
+ len += snprint(p+len, READSTR-len, "write protected\n");
if(pp->busy)
- cp += sprint(cp, "busy\n");
- cp += sprint(cp, "battery lvl %d\n", pp->battery);
-{
- int i;
+ len += snprint(p+len, READSTR-len, "busy\n");
+ snprint(p+len, READSTR-len, "battery lvl %d\n", pp->battery);
- for(i = 0; i < 0x40; i++){
- if((i&0x7) == 0)
- cp += sprint(cp, "\n%ux: ", i);
- cp += sprint(cp, "%ux ", rdreg(pp, i));
- }
- cp += sprint(cp, "\n");
-}
- *cp = 0;
- return readstr(offset, a, n, buf);
- default:
- n=0;
- break;
+ n = readstr(offset, a, n, p);
+ free(p);
+
+ return n;
}
- return n;
+ error(Ebadarg);
+ return -1; /* not reached */
}
static long
@@ 803,7 794,6 @@ pcmwrite(int dev, int attr, void *a, long n, ulong offset)
{
int i, len;
PCMmap *m;
- ulong ka;
uchar *ac;
Slot *pp;
@@ 829,8 819,7 @@ pcmwrite(int dev, int attr, void *a, long n, ulong offset)
i = m->cea - offset;
else
i = len;
- ka = KZERO|(m->isa + offset - m->ca);
- memmoveb((void*)ka, ac, i);
+ memmoveb(KADDR(m->isa + offset - m->ca), ac, i);
pcmunmap(pp->slotno, m);
offset += i;
ac += i;
@@ 843,12 832,10 @@ pcmwrite(int dev, int attr, void *a, long n, ulong offset)
static long
i82365write(Chan *c, void *a, long n, ulong offset)
{
- ulong p;
Slot *pp;
char buf[32];
- p = TYPE(c);
- switch(p){
+ switch(TYPE(c)){
case Qctl:
if(n >= sizeof(buf))
n = sizeof(buf) - 1;
@@ 861,20 848,19 @@ i82365write(Chan *c, void *a, long n, ulong offset)
/* set vpp on card */
if(strncmp(buf, "vpp", 3) == 0)
wrreg(pp, Rpc, vcode(atoi(buf+3))|Fautopower|Foutena|Fcardena);
- break;
+ return n;
case Qmem:
case Qattr:
pp = slot + SLOTNO(c);
if(pp->occupied == 0 || pp->enabled == 0)
error(Eio);
- n = pcmwrite(pp->slotno, p == Qattr, a, n, offset);
+ n = pcmwrite(pp->slotno, TYPE(c) == Qattr, a, n, offset);
if(n < 0)
error(Eio);
- break;
- default:
- error(Ebadusefd);
+ return n;
}
- return n;
+ error(Ebadarg);
+ return -1; /* not reached */
}
Dev i82365devtab = {
@@ 1000,7 986,7 @@ pcmio(int slotno, ISAConf *isa)
if(pp->cpresent & (1<<Rconfig)){
/* Reset adapter */
m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1);
- p = (uchar*)(KZERO|(m->isa + pp->caddr + Rconfig - m->ca));
+ p = KADDR(m->isa + pp->caddr + Rconfig - m->ca);
/* set configuration and interrupt type */
x = ct->index;
@@ 1056,7 1042,7 @@ cisread(Slot *pp)
m = pcmmap(pp->slotno, 0, 0, 1);
if(m == 0)
return;
- pp->cisbase = (uchar*)(KZERO|m->isa);
+ pp->cisbase = KADDR(m->isa);
pp->cispos = 0;
/* loop through all the tuples */
@@ 1381,4 1367,3 @@ tvers1(Slot *pp, int ttype)
}
pp->verstr[i] = 0;
}
-
M pc/ether589.c => pc/ether589.c +93 -44
@@ 1,3 1,10 @@
+/*
+ * 3C589 and 3C562.
+ * To do:
+ * check xcvr10Base2 still works (is GlobalReset necessary?).
+ * pull the station address out of the card space for the 3C562,
+ * it has no EEPROM.
+ */
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
@@ 9,58 16,100 @@
#include "etherif.h"
-enum {
- GlobalReset = 0x00, /* Global Reset */
- SelectWindow = 0x01, /* SelectWindow command */
-
- Command = 0x0E, /* all windows */
- Status = 0x0E,
-
- XcvrTypeMask = 0xC000, /* Transceiver Type Select */
- Xcvr10BaseT = 0x0000,
- XcvrAUI = 0x4000,
- XcvrBNC = 0xC000,
-
- ManufacturerID = 0x00, /* window 0 */
- ProductID = 0x02,
- ConfigControl = 0x04,
- AddressConfig = 0x06,
- ResourceConfig = 0x08,
- EEPROMcmd = 0x0A,
- EEPROMdata = 0x0C,
-
- FIFOdiag = 0x04, /* window 4 */
- MediaStatus = 0x0A,
-
- /* MediaStatus bits */
- JabberEna = 0x0040, /* Jabber Enabled (writeable) */
- LinkBeatEna = 0x0080, /* Link Beat Enabled (writeable) */
- LinkBeatOk = 0x0800, /* Valid link beat detected (ro) */
+enum { /* all windows */
+ CommandR = 0x000E,
+ IntStatusR = 0x000E,
};
-#define COMMAND(port, cmd, a) outs(port+Command, ((cmd)<<11)|(a))
+enum { /* Commands */
+ GlobalReset = 0x0000,
+ SelectRegisterWindow = 0x0001,
+ RxReset = 0x0005,
+ TxReset = 0x000B,
+ AcknowledgeInterrupt = 0x000D,
+};
+
+enum { /* IntStatus bits */
+ commandInProgress = 0x1000,
+};
+
+#define COMMAND(port, cmd, a) outs((port)+CommandR, ((cmd)<<11)|(a))
+#define STATUS(port) ins((port)+IntStatusR)
+
+enum { /* Window 0 - setup */
+ Wsetup = 0x0000,
+ /* registers */
+ ManufacturerID = 0x0000, /* 3C5[08]*, 3C59[27] */
+ ProductID = 0x0002, /* 3C5[08]*, 3C59[27] */
+ ConfigControl = 0x0004, /* 3C5[08]*, 3C59[27] */
+ AddressConfig = 0x0006, /* 3C5[08]*, 3C59[27] */
+ ResourceConfig = 0x0008, /* 3C5[08]*, 3C59[27] */
+ EepromCommand = 0x000A,
+ EepromData = 0x000C,
+ /* AddressConfig Bits */
+ autoSelect9 = 0x0080,
+ xcvrMask9 = 0xC000,
+ /* ConfigControl bits */
+ Ena = 0x0001,
+ base10TAvailable9 = 0x0200,
+ coaxAvailable9 = 0x1000,
+ auiAvailable9 = 0x2000,
+ /* EepromCommand bits */
+ EepromReadRegister = 0x0080,
+ EepromBusy = 0x8000,
+};
+
+enum { /* Window 1 - operating set */
+ Wop = 0x0001,
+};
+
+enum { /* Window 3 - FIFO management */
+ Wfifo = 0x0003,
+ /* registers */
+ InternalConfig = 0x0000, /* 3C509B, 3C589, 3C59[0257] */
+ /* InternalConfig bits */
+ xcvr10BaseT = 0x00000000,
+ xcvr10Base2 = 0x00300000,
+};
+
+enum { /* Window 4 - diagnostic */
+ Wdiagnostic = 0x0004,
+ /* registers */
+ MediaStatus = 0x000A,
+ /* MediaStatus bits */
+ linkBeatDetect = 0x0800,
+};
extern int etherelnk3reset(Ether*);
static int
-configASIC(Ether *ether, int port, int xcvr)
+configASIC(Ether* ether, int port, int xcvr)
{
+ int x;
+
/* set Window 0 configuration registers */
- COMMAND(port, SelectWindow, 0);
- outs(port+ConfigControl, 1);
+ COMMAND(port, SelectRegisterWindow, Wsetup);
+ outs(port+ConfigControl, Ena);
/* IRQ must be 3 on 3C589/3C562 */
outs(port + ResourceConfig, 0x3F00);
- /* ROM size & base - must be set before we can access ROM */
- /* transceiver type is 2 for 'figure it out' */
- outs(port + AddressConfig, xcvr);
+ x = ins(port+AddressConfig) & ~xcvrMask9;
+ x |= (xcvr>>20)<<14;
+ outs(port+AddressConfig, x);
+
+ COMMAND(port, TxReset, 0);
+ while(STATUS(port) & commandInProgress)
+ ;
+ COMMAND(port, RxReset, 0);
+ while(STATUS(port) & commandInProgress)
+ ;
return etherelnk3reset(ether);
}
static int
-reset(Ether *ether)
+reset(Ether* ether)
{
int slot;
int port;
@@ 74,27 123,27 @@ reset(Ether *ether)
if((slot = pcmspecial(ether->type, ether)) < 0)
return -1;
- /* try configuring as a 10baseT */
- if(configASIC(ether, port, Xcvr10BaseT) < 0){
+ /* try configuring as a 10BaseT */
+ if(configASIC(ether, port, xcvr10BaseT) < 0){
pcmspecialclose(slot);
return -1;
}
delay(100);
- COMMAND(port, SelectWindow, 4);
- if(ins(port+MediaStatus) & LinkBeatOk){
- /* reselect window 1 for normal operation */
- COMMAND(port, SelectWindow, 1);
- print("10baseT %s\n", ether->type);
+ COMMAND(port, SelectRegisterWindow, Wdiagnostic);
+ if(ins(port+MediaStatus) & linkBeatDetect){
+ COMMAND(port, SelectRegisterWindow, Wop);
+ print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type);
return 0;
}
/* try configuring as a 10base2 */
COMMAND(port, GlobalReset, 0);
- if(configASIC(ether, port, XcvrBNC) < 0){
+ if(configASIC(ether, port, xcvr10Base2) < 0){
pcmspecialclose(slot);
return -1;
}
- print("BNC %s\n", ether->type);
+ print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type);
+
return 0;
}
M pc/memory.c => pc/memory.c +3 -2
@@ 223,7 223,7 @@ umbscan(void)
* at 0xE0000 then the whole 64KB up to 0xF0000 is theoretically up
* for grabs; check anyway.
*/
- p = KADDR(0xC8000);
+ p = KADDR(0xC0000);
while(p < (uchar*)KADDR(0xE0000)){
p[0] = 0xCC;
p[2*KB-1] = 0xCC;
@@ 235,7 235,8 @@ umbscan(void)
p += p[2]*512;
continue;
}
- mapfree(&rmapumb, PADDR(p), 2*KB);
+ if(p[0] == 0xFF && p[1] == 0xFF)
+ mapfree(&rmapumb, PADDR(p), 2*KB);
}
else
mapfree(&rmapumbrw, PADDR(p), 2*KB);
M pc/pci.c => pc/pci.c +70 -97
@@ 31,8 31,6 @@ static Pcidev* pciroot;
static Pcidev* pcilist;
static Pcidev* pcitail;
-static int pcicfgrw8(int, int, int, int);
-static int pcicfgrw16(int, int, int, int);
static int pcicfgrw32(int, int, int, int);
static int
@@ 40,7 38,7 @@ pciscan(int bno, Pcidev** list)
{
ulong v;
Pcidev *p, *head, *tail;
- int dno, fno, i, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
+ int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
maxubn = bno;
head = nil;
@@ 70,19 68,51 @@ pciscan(int bno, Pcidev** list)
pcilist = p;
pcitail = p;
- p->intl = pcicfgrw8(tbdf, PciINTL, 0, 1);
- p->ccru = pcicfgrw16(tbdf, PciCCRu, 0, 1);
-
- rno = PciBAR0 - 4;
- for(i = 0; i < nelem(p->mem); i++) {
- rno += 4;
- p->mem[i].bar = pcicfgrw32(tbdf, rno, 0, 1);
- if(i > 0 && p->ccru == ((0x06<<8)|0x04))
- continue;
- pcicfgrw32(tbdf, rno, -1, 0);
- v = pcicfgrw32(tbdf, rno, 0, 1);
- pcicfgrw32(tbdf, rno, p->mem[i].bar, 0);
- p->mem[i].size = -(v & ~0xF);
+ p->intl = pcicfgr8(p, PciINTL);
+ p->ccru = pcicfgr16(p, PciCCRu);
+
+ /*
+ * If the device is a multi-function device adjust the
+ * loop count so all possible functions are checked.
+ */
+ hdt = pcicfgr8(p, PciHDT);
+ if(hdt & 0x80)
+ maxfno = MaxFNO;
+
+ /*
+ * If appropriate, read the base address registers
+ * and work out the sizes.
+ */
+ switch(p->ccru>>8){
+
+ case 0x01: /* mass storage controller */
+ case 0x02: /* network controller */
+ case 0x03: /* display controller */
+ case 0x04: /* multimedia device */
+ case 0x07: /* simple communication controllers */
+ case 0x08: /* base system peripherals */
+ case 0x09: /* input devices */
+ case 0x0A: /* docking stations */
+ case 0x0B: /* processors */
+ case 0x0C: /* serial bus controllers */
+ if((hdt & 0x7F) != 0)
+ break;
+ rno = PciBAR0 - 4;
+ for(i = 0; i < nelem(p->mem); i++){
+ rno += 4;
+ p->mem[i].bar = pcicfgr32(p, rno);
+ pcicfgw32(p, rno, -1);
+ v = pcicfgr32(p, rno);
+ pcicfgw32(p, rno, p->mem[i].bar);
+ p->mem[i].size = -(v & ~0xF);
+ }
+ break;
+
+ case 0x00:
+ case 0x05: /* memory controller */
+ case 0x06: /* bridge device */
+ default:
+ break;
}
if(head != nil)
@@ 90,34 120,14 @@ pciscan(int bno, Pcidev** list)
else
head = p;
tail = p;
-
- /*
- * If the device is a multi-function device adjust the
- * loop count so all possible functions are checked.
- */
- l = pcicfgrw8(tbdf, PciHDT, 0, 1);
- if(l & 0x80)
- maxfno = MaxFNO;
}
}
*list = head;
for(p = head; p != nil; p = p->link){
/*
- * Find bridges and recursively descend the tree.
- * Special case the Intel 82454GX Host-to-PCI bridge,
- * there can be two of them.
- * Otherwise, only descend PCI-to-PCI bridges.
+ * Find PCI-PCI bridges and recursively descend the tree.
*/
- if(p->ccru == ((0x06<<8)|0) && p->vid == 0x8086 && p->did == 0x84C4){
- tbdf = p->tbdf;
- if((sbn = pcicfgrw8(tbdf, 0x4A, 0, 1)) == 0)
- continue;
- ubn = pcicfgrw8(tbdf, 0x4B, 0, 1);
- maxubn = ubn;
- pciscan(sbn, &p->bridge);
- continue;
- }
if(p->ccru != ((0x06<<8)|0x04))
continue;
@@ 129,9 139,8 @@ pciscan(int bno, Pcidev** list)
* buses are behind this one; the final value is set on the way
* back up.
*/
- tbdf = p->tbdf;
- sbn = pcicfgrw8(tbdf, PciSBN, 0, 1);
- ubn = pcicfgrw8(tbdf, PciUBN, 0, 1);
+ sbn = pcicfgr8(p, PciSBN);
+ ubn = pcicfgr8(p, PciUBN);
if(sbn == 0 || ubn == 0){
sbn = maxubn+1;
/*
@@ 142,13 151,13 @@ pciscan(int bno, Pcidev** list)
*
* Initialisation of the bridge should be done here.
*/
- pcicfgrw32(tbdf, PciPCR, 0xFFFF0000, 0);
+ pcicfgw32(p, PciPCR, 0xFFFF0000);
l = (MaxUBN<<16)|(sbn<<8)|bno;
- pcicfgrw32(tbdf, PciPBN, l, 0);
- pcicfgrw16(tbdf, PciSPSR, 0xFFFF, 0);
+ pcicfgw32(p, PciPBN, l);
+ pcicfgw16(p, PciSPSR, 0xFFFF);
maxubn = pciscan(sbn, &p->bridge);
l = (maxubn<<16)|(sbn<<8)|bno;
- pcicfgrw32(tbdf, PciPBN, l, 0);
+ pcicfgw32(p, PciPBN, l);
}
else{
maxubn = ubn;
@@ 162,6 171,10 @@ pciscan(int bno, Pcidev** list)
static void
pcicfginit(void)
{
+ char *p;
+ int bno;
+ Pcidev **list;
+
lock(&pcicfginitlock);
if(pcicfgmode == -1){
/*
@@ 169,7 182,7 @@ pcicfginit(void)
* 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
+ * a device behind these addresses so if Mode2 accesses fail try
* for Mode1 (which is preferred, Mode2 is deprecated).
*/
outb(PciCSE, 0);
@@ 185,8 198,18 @@ pcicfginit(void)
}
}
- if(pcicfgmode > 0)
- pciscan(0, &pciroot);
+ if(pcicfgmode > 0){
+ if(p = getconf("*pcimaxdno"))
+ pcimaxdno = strtoul(p, 0, 0);
+
+ list = &pciroot;
+ for(bno = 0; bno < 256; bno++){
+ bno = pciscan(bno, list);
+ while(*list && (*list)->link)
+ list = &(*list)->link;
+ }
+
+ }
}
unlock(&pcicfginitlock);
}
@@ 361,19 384,6 @@ pcicfgw32(Pcidev* pcidev, int rno, int data)
pcicfgrw32(pcidev->tbdf, rno, data, 0);
}
-ulong
-pcibarsize(Pcidev* p, int rno)
-{
- ulong v, size;
-
- v = pcicfgrw32(p->tbdf, rno, 0, 1);
- pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0);
- size = pcicfgrw32(p->tbdf, rno, 0, 1);
- pcicfgrw32(p->tbdf, rno, v, 0);
-
- return -(size & ~0x0F);
-}
-
Pcidev*
pcimatch(Pcidev* prev, int vid, int did)
{
@@ 423,43 433,6 @@ pcihinv(Pcidev* p)
}
}
-/*
- * Hack for now to get SYMBIOS controller on-line.
- */
-void*
-pcimemmap(int tbdf, int rno, ulong *paddr)
-{
- long size;
- ulong p, v;
-
- if(pcicfgmode == -1)
- pcicfginit();
-
- v = pcicfgrw32(tbdf, rno, 0, 1);
- if(v & 1){
- print("pcimemmap: not a memory base register\n");
- return 0;
- }
- if(v & 6){
- print("pcimemmap: only 32 bit relocs supported\n");
- return 0;
- }
- v = 0xFFFFFFFF;
- pcicfgrw32(tbdf, rno, v, 0);
- v = pcicfgrw32(tbdf, rno, 0, 1);
- /*
- * Clear out bottom bits and negate to find size.
- * If none can be found could try for UPA memory here.
- */
- size = -(v & ~0x0F);
- v = umbmalloc(0, size, size);
- p = PADDR(v);
- if(paddr)
- *paddr = p;
- pcicfgrw32(tbdf, rno, p, 0);
- return (void*)v;
-}
-
void
pcireset(void)
{
M pc/vgaclgd542x.c => pc/vgaclgd542x.c +2 -2
@@ 58,8 58,8 @@ clgd542xenable(VGAscr* scr)
/*
* Disable the cursor.
*/
- sr12 = vgaxi(Seqx, 0x12) & ~0x01;
- vgaxo(Seqx, 0x12, sr12);
+ sr12 = vgaxi(Seqx, 0x12);
+ vgaxo(Seqx, 0x12, sr12 & ~0x01);
/*
* Cursor colours.