M alphapc/arch164.c => alphapc/arch164.c +2 -0
@@ 346,6 346,8 @@ PCArch arch164 = {
pcicfg2117x,
pcimem2117x,
intrenable164,
+ nil,
+ nil,
inb2117x,
ins2117x,
M alphapc/clock.c => alphapc/clock.c +13 -0
@@ 89,3 89,16 @@ clock(Ureg *ureg)
portclock(ureg);
}
+
+ulong
+TK2MS(ulong ticks)
+{
+ uvlong t, hz;
+
+ t = ticks;
+ hz = HZ;
+ t *= 1000L;
+ t = t/hz;
+ ticks = t;
+ return ticks;
+}
M alphapc/dat.h => alphapc/dat.h +18 -0
@@ 189,6 189,8 @@ struct PCArch
void *(*pcicfg)(int, int); /* map and point to PCI cfg space */
void *(*pcimem)(int, int); /* map and point to PCI memory space */
int (*intrenable)(Vctl*);
+ int (*intrvecno)(int);
+ int (*intrdisable)(int);
int (*_inb)(int);
ushort (*_ins)(int);
@@ 229,3 231,19 @@ extern Mach mach0;
extern register Mach *m;
extern register Proc *up;
+
+/*
+ * hardware info about a device
+ */
+typedef struct {
+ ulong port;
+ int size;
+} port_t;
+
+struct DevConf
+{
+ ulong interrupt; /* interrupt number */
+ char *type; /* card type, malloced */
+ int nports; /* Number of ports */
+ port_t *ports; /* The ports themselves */
+};
M alphapc/devarch.c => alphapc/devarch.c +15 -0
@@ 51,6 51,8 @@ static Dirtab archdir[] = {
};
Lock archwlock; /* the lock is only for changing archdir */
int narchdir = Qbase;
+int (*_pcmspecial)(char *, ISAConf *);
+void (*_pcmspecialclose)(int);
/*
* Add a file to the #P listing. Once added, you can't delete it.
@@ 479,3 481,16 @@ archinit(void)
addarchfile("cputype", 0444, cputyperead, nil);
}
+
+int
+pcmspecial(char *idstr, ISAConf *isa)
+{
+ return (_pcmspecial != nil)? _pcmspecial(idstr, isa): -1;
+}
+
+void
+pcmspecialclose(int a)
+{
+ if (_pcmspecialclose != nil)
+ _pcmspecialclose(a);
+}
M alphapc/ether2114x.c => alphapc/ether2114x.c +64 -21
@@ 32,17 32,14 @@ enum {
enum { /* CRS0 - Bus Mode */
Swr = 0x00000001, /* Software Reset */
Bar = 0x00000002, /* Bus Arbitration */
- DslMASK = 0x0000007C, /* Descriptor Skip Length */
- DslSHIFT = 2,
+ Dsl = 0x0000007C, /* Descriptor Skip Length (field) */
Ble = 0x00000080, /* Big/Little Endian */
- PblMASK = 0x00003F00, /* Programmable Burst Length (field) */
- PblSHIFT = 8,
+ Pbl = 0x00003F00, /* Programmable Burst Length (field) */
Cal = 0x0000C000, /* Cache Alignment (field) */
Cal8 = 0x00004000, /* 8 longword boundary alignment */
Cal16 = 0x00008000, /* 16 longword boundary alignment */
Cal32 = 0x0000C000, /* 32 longword boundary alignment */
- TapMASK = 0x000E0000, /* Transmit Automatic Polling */
- TapSHIFT = 17,
+ Tap = 0x000E0000, /* Transmit Automatic Polling (field) */
Dbo = 0x00100000, /* Descriptor Byte Ordering Mode */
Rml = 0x00200000, /* Read Multiple */
};
@@ 201,7 198,8 @@ typedef struct Ctlr {
int active;
int id; /* (pcidev->did<<16)|pcidev->vid */
- uchar srom[128];
+ uchar* srom;
+ int sromsz; /* address size in bits */
uchar* sromea; /* MAC address */
uchar* leaf;
int sct; /* selected connection type */
@@ 350,7 348,7 @@ ifstat(Ether* ether, void* a, long n, ulong offset)
n -= len;
l = snprint(p, READSTR, "srom:");
- for(i = 0; i < sizeof(ctlr->srom); i++){
+ for(i = 0; i < (1<<ctlr->sromsz); i++){
if(i && ((i & 0x0F) == 0))
l += snprint(p+l, READSTR-l, "\n ");
l += snprint(p+l, READSTR-l, " %2.2uX", ctlr->srom[i]);
@@ 577,11 575,11 @@ ctlrinit(Ether* ether)
* create and post a setup packet to initialise
* the physical ethernet address.
*/
- ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des));
+ ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0);
for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
des->bp = iallocb(Rbsz);
if(des->bp == nil)
- panic("can't allocate ethernet receive ring");
+ panic("can't allocate ethernet receive ring\n");
des->status = Own;
des->control = Rbsz;
des->addr = PCIWADDR(des->bp->rp);
@@ 614,7 612,7 @@ ctlrinit(Ether* ether)
}
bp = iallocb(Eaddrlen*2*16);
if(bp == nil)
- panic("can't allocate ethernet setup buffer");
+ panic("can't allocate ethernet setup buffer\n");
memset(bp->rp, 0xFF, sizeof(bi));
for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi))
memmove(bp->rp+i, bi, sizeof(bi));
@@ 723,7 721,7 @@ miiw(Ctlr* ctlr, int phyad, int regad, int data)
static int
sromr(Ctlr* ctlr, int r)
{
- int i, op, data;
+ int i, op, data, size;
if(ctlr->id == Pnic){
i = 1000;
@@ 733,6 731,9 @@ sromr(Ctlr* ctlr, int r)
data = csr32r(ctlr, 19);
}while((data & 0x80000000) && --i);
+ if(ctlr->sromsz == 0)
+ ctlr->sromsz = 6;
+
return csr32r(ctlr, 9) & 0xFFFF;
}
@@ 741,6 742,7 @@ sromr(Ctlr* ctlr, int r)
* in the EEPROM is taken straight from Section
* 7.4 of the 21140 Hardware Reference Manual.
*/
+reread:
csr9w(ctlr, Rd|Ss);
csr9w(ctlr, Rd|Ss|Scs);
csr9w(ctlr, Rd|Ss|Sclk|Scs);
@@ 754,11 756,20 @@ sromr(Ctlr* ctlr, int r)
csr9w(ctlr, data);
}
- for(i = 6-1; i >= 0; i--){
- data = Rd|Ss|(((r>>i) & 0x01)<<2)|Scs;
+ /*
+ * First time through must work out the EEPROM size.
+ */
+ if((size = ctlr->sromsz) == 0)
+ size = 8;
+
+ for(size = size-1; size >= 0; size--){
+ data = Rd|Ss|(((r>>size) & 0x01)<<2)|Scs;
csr9w(ctlr, data);
csr9w(ctlr, data|Sclk);
csr9w(ctlr, data);
+ microdelay(1);
+ if(!(csr32r(ctlr, 9) & Sdo))
+ break;
}
data = 0;
@@ 771,6 782,11 @@ sromr(Ctlr* ctlr, int r)
csr9w(ctlr, 0);
+ if(ctlr->sromsz == 0){
+ ctlr->sromsz = 8-size;
+ goto reread;
+ }
+
return data & 0xFFFF;
}
@@ 783,7 799,7 @@ softreset(Ctlr* ctlr)
*/
csr32w(ctlr, 0, Swr);
microdelay(10);
- csr32w(ctlr, 0, Rml|Cal16|(32<<PblSHIFT));
+ csr32w(ctlr, 0, Rml|Cal16);
delay(1);
}
@@ 983,6 999,26 @@ typephymode(Ctlr* ctlr, uchar* block, int wait)
}
static int
+typesymmode(Ctlr *ctlr, uchar *block, int wait)
+{
+ uint gpmode, gpdata, command;
+
+ USED(wait);
+ gpmode = block[3] | ((uint) block[4] << 8);
+ gpdata = block[5] | ((uint) block[6] << 8);
+ command = (block[7] | ((uint) block[8] << 8)) & 0x71;
+ if (command & 0x8000) {
+ print("ether2114x.c: FIXME: handle type 4 mode blocks where cmd.active_invalid != 0\n");
+ return -1;
+ }
+ csr32w(ctlr, 15, gpmode);
+ csr32w(ctlr, 15, gpdata);
+ ctlr->csr6 = (command & 0x71) << 18;
+ csr32w(ctlr, 6, ctlr->csr6);
+ return 0;
+}
+
+static int
type0link(Ctlr* ctlr, uchar* block)
{
int m, polarity, sense;
@@ 1002,8 1038,7 @@ type0mode(Ctlr* ctlr, uchar* block, int wait)
{
int csr6, m, timeo;
-// csr6 = Sc|Mbo|Hbd|Ca|Sb|TrMODE;
- csr6 = Mbo|Hbd|Sb|TrMODE;
+ csr6 = Sc|Mbo|Hbd|Ca|Sb|TrMODE;
debug("type0: medium 0x%uX, fd %d: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n",
ctlr->medium, ctlr->fd, block[0], block[1], block[2], block[3]);
switch(block[0]){
@@ 1078,6 1113,10 @@ mediaxx(Ether* ether, int wait)
if(typephymode(ctlr, block, wait))
return 0;
break;
+ case 4:
+ if(typesymmode(ctlr, block, wait))
+ return 0;
+ break;
}
}
else{
@@ 1221,8 1260,12 @@ srom(Ctlr* ctlr)
* 'Digital Semiconductor 21X4 Serial ROM Format, Version 4.05,
* 2-Mar-98'. Only the 2114[03] are handled, support for other
* controllers can be added as needed.
+ * Do a dummy read first to get the size and allocate ctlr->srom.
*/
- for(i = 0; i < sizeof(ctlr->srom)/2; i++){
+ sromr(ctlr, 0);
+ if(ctlr->srom == nil)
+ ctlr->srom = malloc((1<<ctlr->sromsz)*sizeof(ushort));
+ for(i = 0; i < (1<<ctlr->sromsz); i++){
x = sromr(ctlr, i);
ctlr->srom[2*i] = x;
ctlr->srom[2*i+1] = x>>8;
@@ 1415,9 1458,9 @@ dec2114xpci(void)
switch(ctlr->id){
default:
-// break;
-//
-// case Pnic: /* PNIC */
+ break;
+
+ case Pnic: /* PNIC */
/*
* Turn off the jabber timer.
*/
M alphapc/fns.h => alphapc/fns.h +6 -0
@@ 43,6 43,7 @@ void icflush(void);
void illegal0(void);
void intr0(void);
void intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
+void intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
int ioalloc(int, int, int, char*);
void iofree(int);
void ioinit(void);
@@ 72,11 73,16 @@ int pcicfgr32(Pcidev*, int);
void pcicfgw8(Pcidev*, int, int);
void pcicfgw16(Pcidev*, int, int);
void pcicfgw32(Pcidev*, int, int);
+void pciclrbme(Pcidev*);
void pcihinv(Pcidev*);
Pcidev* pcimatch(Pcidev*, int, int);
Pcidev* pcimatchtbdf(int);
void pcireset(void);
void pcisetbme(Pcidev*);
+int pcmspecial(char*, ISAConf*);
+int (*_pcmspecial)(char *, ISAConf *);
+void pcmspecialclose(int);
+void (*_pcmspecialclose)(int);
void prflush(void);
void printinit(void);
#define procrestore(p)
M alphapc/pci.c => alphapc/pci.c +21 -1
@@ 16,6 16,16 @@ enum {
MaxUBN = 255,
};
+enum
+{ /* command register */
+ IOen = (1<<0),
+ MEMen = (1<<1),
+ MASen = (1<<2),
+ MemWrInv = (1<<4),
+ PErrEn = (1<<6),
+ SErrEn = (1<<8),
+};
+
static Lock pcicfglock;
static Lock pcicfginitlock;
static int pcicfgmode = -1;
@@ 388,6 398,16 @@ pcisetbme(Pcidev* p)
int pcr;
pcr = pcicfgr16(p, PciPCR);
- pcr |= 0x0004;
+ pcr |= MASen;
+ pcicfgw16(p, PciPCR, pcr);
+}
+
+void
+pciclrbme(Pcidev* p)
+{
+ int pcr;
+
+ pcr = pcicfgr16(p, PciPCR);
+ pcr &= ~MASen;
pcicfgw16(p, PciPCR, pcr);
}
M alphapc/trap.c => alphapc/trap.c +31 -0
@@ 73,6 73,37 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
iunlock(&vctllock);
}
+void
+intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
+{
+ Vctl **pv, *v;
+ int vno;
+
+ /*
+ * For now, none of this will work with the APIC code,
+ * there is no mapping between irq and vector as the IRQ
+ * is pretty meaningless.
+ */
+ if(arch->intrvecno == nil)
+ return;
+ vno = arch->intrvecno(irq);
+ ilock(&vctllock);
+ pv = &vctl[vno];
+ while (*pv &&
+ ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a ||
+ strcmp((*pv)->name, name)))
+ pv = &((*pv)->next);
+ assert(*pv);
+
+ v = *pv;
+ *pv = (*pv)->next; /* Link out the entry */
+
+ if (vctl[vno] == nil && arch->intrdisable != nil)
+ arch->intrdisable(irq);
+ iunlock(&vctllock);
+ xfree(v);
+}
+
int
irqallocread(char *buf, long n, vlong offset)
{
M pc/devpccard.c => pc/devpccard.c +2 -0
@@ 13,6 13,7 @@
enum {
TI_vid = 0x104c,
+ TI_1250_did = 0xAC16,
TI_1450_did = 0xAC1B,
TI_1251A_did = 0xAC1D,
@@ 38,6 39,7 @@ typedef struct {
static variant_t variant[] = {
{ Ricoh_vid, Ricoh_476_did, "Ricoh 476 PCI/Cardbus bridge", },
{ Ricoh_vid, Ricoh_478_did, "Ricoh 478 PCI/Cardbus bridge", },
+{ TI_vid, TI_1250_did, "TI PCI-1250 Cardbus Controller", },
{ TI_vid, TI_1450_did, "TI PCI-1450 Cardbus Controller", },
{ TI_vid, TI_1251A_did, "TI PCI-1251A Cardbus Controller", },
{ TI_vid, 0xAC51, "TI 0xAC51 Cardbus Controller", },
M pc/ether2114x.c => pc/ether2114x.c +30 -6
@@ 386,7 386,7 @@ txstart(Ether* ether)
ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
des = &ctlr->tdr[ctlr->tdrh];
des->bp = bp;
- des->addr = PADDR(bp->rp);
+ des->addr = PCIWADDR(bp->rp);
des->control |= control;
ctlr->ntq++;
coherence();
@@ 471,7 471,7 @@ interrupt(Ureg*, void* arg)
des->bp->wp = des->bp->rp+len;
etheriq(ether, des->bp, 1);
des->bp = bp;
- des->addr = PADDR(bp->rp);
+ des->addr = PCIWADDR(bp->rp);
}
des->control &= Er;
@@ 575,24 575,24 @@ ctlrinit(Ether* ether)
* create and post a setup packet to initialise
* the physical ethernet address.
*/
- ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des));
+ ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0);
for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
des->bp = iallocb(Rbsz);
if(des->bp == nil)
panic("can't allocate ethernet receive ring\n");
des->status = Own;
des->control = Rbsz;
- des->addr = PADDR(des->bp->rp);
+ des->addr = PCIWADDR(des->bp->rp);
}
ctlr->rdr[ctlr->nrdr-1].control |= Er;
ctlr->rdrx = 0;
- csr32w(ctlr, 3, PADDR(ctlr->rdr));
+ csr32w(ctlr, 3, PCIWADDR(ctlr->rdr));
ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(Des), 8*sizeof(ulong), 0);
ctlr->tdr[ctlr->ntdr-1].control |= Er;
ctlr->tdrh = 0;
ctlr->tdri = 0;
- csr32w(ctlr, 4, PADDR(ctlr->tdr));
+ csr32w(ctlr, 4, PCIWADDR(ctlr->tdr));
/*
* Clear any bits in the Status Register (CSR5) as
@@ 999,6 999,26 @@ typephymode(Ctlr* ctlr, uchar* block, int wait)
}
static int
+typesymmode(Ctlr *ctlr, uchar *block, int wait)
+{
+ uint gpmode, gpdata, command;
+
+ USED(wait);
+ gpmode = block[3] | ((uint) block[4] << 8);
+ gpdata = block[5] | ((uint) block[6] << 8);
+ command = (block[7] | ((uint) block[8] << 8)) & 0x71;
+ if (command & 0x8000) {
+ print("ether2114x.c: FIXME: handle type 4 mode blocks where cmd.active_invalid != 0\n");
+ return -1;
+ }
+ csr32w(ctlr, 15, gpmode);
+ csr32w(ctlr, 15, gpdata);
+ ctlr->csr6 = (command & 0x71) << 18;
+ csr32w(ctlr, 6, ctlr->csr6);
+ return 0;
+}
+
+static int
type0link(Ctlr* ctlr, uchar* block)
{
int m, polarity, sense;
@@ 1093,6 1113,10 @@ mediaxx(Ether* ether, int wait)
if(typephymode(ctlr, block, wait))
return 0;
break;
+ case 4:
+ if(typesymmode(ctlr, block, wait))
+ return 0;
+ break;
}
}
else{