pc/ether*: use 64-bit physical addresses and check pci membar types and sizes

This commit is contained in:
cinap_lenrek 2020-06-06 16:04:24 +02:00
parent 3bebd3f5e2
commit 8243b6600f
15 changed files with 98 additions and 71 deletions

View file

@ -350,7 +350,7 @@ enum {
typedef struct Ctlr Ctlr;
typedef struct Ctlr {
int port;
uvlong port;
Pcidev* pcidev;
Ctlr* next;
int active;
@ -1252,11 +1252,14 @@ gc82543pci(void)
void *mem;
Pcidev *p;
Ctlr *ctlr;
uvlong io;
p = nil;
while(p = pcimatch(p, 0, 0)){
if(p->ccrb != 0x02 || p->ccru != 0)
continue;
if(p->mem[0].bar & 1)
continue;
switch((p->did<<16)|p->vid){
case (0x1000<<16)|0x8086: /* LSI L2A1157 (82542) */

View file

@ -502,7 +502,7 @@ typedef void (*Freefn)(Block*);
typedef struct Ctlr Ctlr;
struct Ctlr {
ulong port;
uvlong port;
Pcidev *pcidev;
Ctlr *next;
int active;
@ -1667,7 +1667,10 @@ fload(Ctlr *c)
if(c->pcidev->mem[1].bar == 0)
return fload32(c); /* i219 */
va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
if(c->pcidev->mem[1].bar & 1)
return -1;
va = vmap(c->pcidev->mem[1].bar & ~0xF, c->pcidev->mem[1].size);
if(va == nil)
return -1;
f.reg = va;
@ -2025,6 +2028,8 @@ i82563pci(void)
for(p = nil; p = pcimatch(p, 0x8086, 0);){
hbafixup(p);
if(p->mem[0].bar & 1)
continue;
if((type = didtype(p->did)) == -1)
continue;
ctlr = malloc(sizeof(Ctlr));
@ -2035,7 +2040,7 @@ i82563pci(void)
ctlr->type = type;
ctlr->pcidev = p;
ctlr->rbsz = ROUND(cttab[type].mtu, 1024);
ctlr->port = p->mem[0].bar & ~0x0F;
ctlr->port = p->mem[0].bar & ~0xF;
if(i82563ctlrhead != nil)
i82563ctlrtail->next = ctlr;
else
@ -2052,7 +2057,7 @@ setup(Ctlr *ctlr)
p = ctlr->pcidev;
ctlr->nic = vmap(ctlr->port, p->mem[0].size);
if(ctlr->nic == nil){
print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
print("%s: can't map %llux\n", cname(ctlr), ctlr->port);
return -1;
}
pcienable(p);

View file

@ -267,7 +267,7 @@ enum {
typedef struct {
Pcidev *p;
Ether *edev;
uintptr io;
uvlong io;
u32int *reg;
u32int *regmsi;
uchar flag;
@ -848,7 +848,7 @@ interrupt(Ureg*, void *v)
static void
scan(void)
{
uintptr io, iomsi;
uvlong io, iomsi;
void *mem, *memmsi;
int pciregs, pcimsix;
Ctlr *c;
@ -856,6 +856,7 @@ scan(void)
p = 0;
while(p = pcimatch(p, 0x8086, 0)){
pciregs = 0;
switch(p->did){
case 0x10c6: /* 82598 af dual port */
case 0x10c7: /* 82598 af single port */
@ -868,11 +869,12 @@ scan(void)
case 0x1528: /* T540-T1 */
pcimsix = 4;
break;
default:
continue;
}
pciregs = 0;
if((p->mem[pciregs].bar & 1) != 0
|| (p->mem[pcimsix].bar & 1) != 0)
continue;
if(nctlr == nelem(ctlrtab)){
print("i82598: too many controllers\n");
return;
@ -885,14 +887,14 @@ scan(void)
io = p->mem[pciregs].bar & ~0xf;
mem = vmap(io, p->mem[pciregs].size);
if(mem == nil){
print("i82598: can't map regs %#p\n", io);
print("i82598: can't map regs %llux\n", io);
free(c);
continue;
}
iomsi = p->mem[pcimsix].bar & ~0xf;
memmsi = vmap(iomsi, p->mem[pcimsix].size);
if(memmsi == nil){
print("i82598: can't map msi-x regs %#p\n", iomsi);
print("i82598: can't map msi-x regs %llux\n", iomsi);
vunmap(mem, p->mem[pciregs].size);
free(c);
continue;

View file

@ -23,11 +23,11 @@ typedef struct Ctlr Ctlr;
struct Ctlr {
Lock txlock, imlock;
Ctlr *link;
uvlong port;
Pcidev *pdev;
ulong *nic, *status;
/* One Ring to find them, One Ring to bring them all and in the darkness bind them */
ulong *recvret, *recvprod, *sendr;
ulong port;
ulong recvreti, recvprodi, sendri, sendcleani;
Block **sends, **recvs;
int active, duplex;
@ -704,6 +704,9 @@ bcmpci(void)
continue;
if(pdev->vid != 0x14e4)
continue;
if(pdev->mem[0].bar & 1)
continue;
switch(pdev->did){
default:
continue;
@ -790,7 +793,6 @@ bcmpci(void)
case 0x1670: /* ??? */
break;
}
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil) {
print("bcm: unable to alloc Ctlr\n");
@ -805,16 +807,17 @@ bcmpci(void)
free(ctlr);
continue;
}
mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
ctlr->port = pdev->mem[0].bar & ~0xF;
mem = vmap(ctlr->port, pdev->mem[0].size);
if(mem == nil) {
print("bcm: can't map %8.8luX\n", pdev->mem[0].bar);
print("bcm: can't map %llux\n", ctlr->port);
free(ctlr->sends);
free(ctlr->recvs);
free(ctlr);
continue;
}
ctlr->pdev = pdev;
ctlr->nic = mem;
ctlr->port = pdev->mem[0].bar & ~0x0F;
ctlr->status = xspanalloc(20, 16, 0);
ctlr->recvprod = xspanalloc(32 * RecvProdRingLen, 16, 0);
ctlr->recvret = xspanalloc(32 * RecvRetRingLen, 16, 0);

View file

@ -342,7 +342,7 @@ enum {
typedef struct Ctlr Ctlr;
typedef struct Ctlr {
int port;
uvlong port;
Pcidev* pcidev;
Ctlr* next;
int active;
@ -1148,6 +1148,8 @@ dp83820pci(void)
while(p = pcimatch(p, 0, 0)){
if(p->ccrb != Pcibcnet || p->ccru != Pciscether)
continue;
if(p->mem[1].bar & 1)
continue;
switch((p->did<<16)|p->vid){
default:
@ -1156,9 +1158,9 @@ dp83820pci(void)
break;
}
mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
if(mem == 0){
print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
mem = vmap(p->mem[1].bar & ~0xF, p->mem[1].size);
if(mem == nil){
print("DP83820: can't map %llux\n", p->mem[1].bar & ~0xF);
continue;
}
@ -1167,7 +1169,7 @@ dp83820pci(void)
print("DP83820: can't allocate memory\n");
continue;
}
ctlr->port = p->mem[1].bar & ~0x0F;
ctlr->port = p->mem[1].bar & ~0xF;
ctlr->pcidev = p;
pcienable(p);
ctlr->id = (p->did<<16)|p->vid;

View file

@ -425,7 +425,7 @@ typedef struct Ctlr {
int ts; /* threshold shift */
int upenabled;
int dnenabled;
ulong cbfnpa; /* CardBus functions */
uvlong cbfnpa; /* CardBus functions */
ulong* cbfn;
} Ctlr;
@ -1496,12 +1496,12 @@ tcm59Xpci(void)
case 0x5157:
ctlr->eepromcmd = EepromRead8bRegister;
ctlr->cbfnpa = p->mem[2].bar&~0x0F;
ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
ctlr->cbfn = vmap(ctlr->cbfnpa, p->mem[2].size);
break;
case 0x6056:
ctlr->eepromcmd = EepromReadOffRegister;
ctlr->cbfnpa = p->mem[2].bar&~0x0F;
ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
ctlr->cbfn = vmap(ctlr->cbfnpa, p->mem[2].size);
break;
}
pcisetbme(p);

View file

@ -251,7 +251,7 @@ enum {
typedef struct Ctlr Ctlr;
struct Ctlr {
int port;
uvlong port;
Pcidev* pcidev;
Ctlr* next;
int active;
@ -575,7 +575,7 @@ ga620event(Ether *edev, int eci, int epi)
* 3rd arg of 1 selects gigabit only; 2 10/100 only.
*/
ga620command(ctlr, 0x0B, 0x00, 0x00);
print("#l%d: ga620: port %8.8uX: firmware is up\n",
print("#l%d: ga620: port %8.8lluX: firmware is up\n",
edev->ctlrno, ctlr->port);
break;
case 0x04: /* statistics updated */
@ -1152,6 +1152,8 @@ ga620pci(void)
while(p = pcimatch(p, 0, 0)){
if(p->ccrb != 0x02 || p->ccru != 0)
continue;
if(p->mem[0].bar & 1)
continue;
switch(p->did<<16 | p->vid){
default:
@ -1165,9 +1167,9 @@ ga620pci(void)
break;
}
mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
if(mem == 0){
print("ga620: can't map %8.8luX\n", p->mem[0].bar);
mem = vmap(p->mem[0].bar & ~0xF, p->mem[0].size);
if(mem == nil){
print("ga620: can't map %llux\n", p->mem[0].bar & ~0xF);
continue;
}
@ -1176,7 +1178,7 @@ ga620pci(void)
print("ga620: can't allocate memory\n");
continue;
}
ctlr->port = p->mem[0].bar & ~0x0F;
ctlr->port = p->mem[0].bar & ~0xF;
ctlr->pcidev = p;
pcienable(p);

View file

@ -451,7 +451,7 @@ enum {
typedef struct Ctlr Ctlr;
typedef struct Ctlr {
int port;
uvlong port;
Pcidev* pcidev;
Ctlr* next;
Ether* edev;
@ -1919,6 +1919,8 @@ igbepci(void)
while(p = pcimatch(p, 0, 0)){
if(p->ccrb != 0x02 || p->ccru != 0)
continue;
if(p->mem[0].bar & 1)
continue;
switch((p->did<<16)|p->vid){
default:
@ -1942,9 +1944,9 @@ igbepci(void)
break;
}
mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
mem = vmap(p->mem[0].bar & ~0xF, p->mem[0].size);
if(mem == nil){
print("igbe: can't map %8.8luX\n", p->mem[0].bar);
print("igbe: can't map %llux\n", p->mem[0].bar & ~0xF);
continue;
}
cls = pcicfgr8(p, PciCLS);

View file

@ -321,11 +321,11 @@ struct Ctlr {
QLock;
Ctlr *link;
uvlong port;
Pcidev *pdev;
Wifi *wifi;
int type;
int port;
int power;
int active;
int broken;
@ -2457,6 +2457,8 @@ iwlpci(void)
continue;
if(pdev->vid != 0x8086)
continue;
if(pdev->mem[0].bar & 1)
continue;
switch(pdev->did){
default:
@ -2493,10 +2495,10 @@ iwlpci(void)
print("iwl: unable to alloc Ctlr\n");
continue;
}
ctlr->port = pdev->mem[0].bar & ~0x0F;
mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
ctlr->port = pdev->mem[0].bar & ~0xF;
mem = vmap(ctlr->port, pdev->mem[0].size);
if(mem == nil) {
print("iwl: can't map %8.8luX\n", pdev->mem[0].bar);
print("iwl: can't map %llux\n", ctlr->port);
free(ctlr);
continue;
}

View file

@ -192,11 +192,11 @@ typedef struct {
typedef struct Ctlr Ctlr;
typedef struct Ctlr {
QLock;
int state;
int kprocs;
uvlong port;
Pcidev* pcidev;
Ctlr* next;
int state;
int kprocs;
int active;
int id; /* do we need this? */
@ -808,23 +808,24 @@ ctlrfree(Ctlr *c)
static int
setmem(Pcidev *p, Ctlr *c)
{
ulong i;
uvlong raddr;
Done *d;
void *mem;
Done *d;
ulong i;
c->tx.segsz = 2048;
c->ramsz = 2*MiB - (2*48*KiB + 32*KiB) - 0x100;
if(c->ramsz > p->mem[0].size)
return -1;
raddr = p->mem[0].bar & ~0x0F;
if(p->mem[0].bar & 1)
return -1;
raddr = p->mem[0].bar & ~0xF;
mem = vmap(raddr, p->mem[0].size);
if(mem == nil){
print("m10g: can't map %8.8lux\n", p->mem[0].bar);
print("m10g: can't map %llux\n", raddr);
return -1;
}
dprint("%llux <- vmap(mem[0].size = %ux)\n", raddr, p->mem[0].size);
dprint("%llux <- vmap(mem[0].size = %d)\n", raddr, p->mem[0].size);
c->port = raddr;
c->ram = mem;
c->cmd = malign(sizeof *c->cmd);

View file

@ -925,6 +925,7 @@ struct Ctlr {
QLock;
Ctlr *link;
uvlong port;
Pcidev *pdev;
Wifi *wifi;
@ -967,8 +968,6 @@ struct Ctlr {
u32int txpow40mhz_5ghz[5];
int flags;
int port;
int power;
int active;
int broken;
@ -3480,6 +3479,8 @@ rt2860pci(void)
continue;
if(pdev->vid != 0x1814) /* Ralink */
continue;
if(pdev->mem[0].bar & 1)
continue;
switch(pdev->did){
default:
@ -3494,10 +3495,10 @@ rt2860pci(void)
print("rt2860: unable to alloc Ctlr\n");
continue;
}
ctlr->port = pdev->mem[0].bar & ~0x0F;
mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
ctlr->port = pdev->mem[0].bar & ~0xF;
mem = vmap(ctlr->port, pdev->mem[0].size);
if(mem == nil){
print("rt2860: can't map %8.8luX\n", pdev->mem[0].bar);
print("rt2860: can't map %llux\n", ctlr->port);
free(ctlr);
continue;
}

View file

@ -111,8 +111,9 @@ wavelanpciscan(void)
/*
* On the Prism, bar[0] is the memory-mapped register address (4KB),
*/
if(p->mem[0].size != 4096){
print("wavelanpci: %.4ux %.4ux: unlikely mmio size\n", p->vid, p->did);
if((p->mem[0].bar & 1) != 0 || p->mem[0].size != 4096){
print("wavelanpci: %.4ux %.4ux: unlikely mmio bar %llux size %d\n",
p->vid, p->did, p->mem[0].bar, p->mem[0].size);
continue;
}
@ -124,7 +125,8 @@ wavelanpciscan(void)
ctlr->pcidev = p;
mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);
if(mem == nil){
print("wavelanpci: %.4ux %.4ux: vmap 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
print("wavelanpci: %.4ux %.4ux: vmap %llux %d failed\n",
p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
free(ctlr);
continue;
}

View file

@ -235,10 +235,10 @@ struct Ctlr {
QLock;
Ctlr *link;
uvlong port;
Pcidev *pdev;
Wifi *wifi;
int port;
int power;
int active;
int broken;
@ -1789,6 +1789,9 @@ wpipci(void)
break;
}
if(pdev->mem[0].bar & 1)
continue;
/* Clear device-specific "PCI retry timeout" register (41h). */
if(pcicfgr8(pdev, 0x41) != 0)
pcicfgw8(pdev, 0x41, 0);
@ -1798,10 +1801,10 @@ wpipci(void)
print("wpi: unable to alloc Ctlr\n");
continue;
}
ctlr->port = pdev->mem[0].bar & ~0x0F;
mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
ctlr->port = pdev->mem[0].bar & ~0xF;
mem = vmap(ctlr->port, pdev->mem[0].size);
if(mem == nil) {
print("wpi: can't map %8.8luX\n", pdev->mem[0].bar);
print("wpi: can't map %llux\n", ctlr->port);
free(ctlr);
continue;
}

View file

@ -804,12 +804,10 @@ interrupt(Ureg*, void *v)
iunlock(&c->imlock);
}
extern void addvgaseg(char*, ulong, ulong);
static void
scan(void)
{
uintptr io, iomsi;
uvlong io, iomsi;
void *mem, *memmsi;
int pciregs, pcimsix;
Ctlr *c;
@ -819,6 +817,9 @@ scan(void)
while(p = pcimatch(p, 0x8086, 0x15c8)){ /* X553/X550-AT 10GBASE-T */
pcimsix = 4;
pciregs = 0;
if((p->mem[pciregs].bar & 1) != 0
|| (p->mem[pcimsix].bar & 1) != 0)
continue;
if(nctlr == nelem(ctlrtab)){
print("iX550: too many controllers\n");
return;
@ -828,21 +829,17 @@ scan(void)
print("iX550: can't allocate memory\n");
continue;
}
io = p->mem[pciregs].bar & ~0xf;
io = p->mem[pciregs].bar & ~0xF;
mem = vmap(io, p->mem[pciregs].size);
if(mem == nil){
print("iX550: can't map regs %#p\n", io);
print("iX550: can't map regs %llux\n", io);
free(c);
continue;
}
if (nctlr == 0)
addvgaseg("pci.ctlr0.bar0", p->mem[pciregs].bar & ~0xf, p->mem[pciregs].size);
else if (nctlr == 1)
addvgaseg("pci.ctlr1.bar0", p->mem[pciregs].bar & ~0xf, p->mem[pciregs].size);
iomsi = p->mem[pcimsix].bar & ~0xf;
iomsi = p->mem[pcimsix].bar & ~0xF;
memmsi = vmap(iomsi, p->mem[pcimsix].size);
if(memmsi == nil){
print("iX550: can't map msi-x regs %#p\n", iomsi);
print("iX550: can't map msi-x regs %llux\n", iomsi);
vunmap(mem, p->mem[pciregs].size);
free(c);
continue;
@ -855,9 +852,9 @@ scan(void)
c->rbsz = ROUND(Mtu, 1024);
if(reset(c)){
print("iX550: can't reset\n");
free(c);
vunmap(mem, p->mem[pciregs].size);
vunmap(memmsi, p->mem[pcimsix].size);
free(c);
continue;
}
pcisetbme(p);

View file

@ -680,7 +680,7 @@ struct Ctlr {
uchar rev;
uchar nports;
uchar portno;
uintptr io;
uvlong io;
uchar *reg8;
ushort *reg16;
uint *reg;
@ -2129,10 +2129,12 @@ setup(Ctlr *c)
Pcidev *p;
p = c->p;
if(p->mem[0].bar & 1)
return -1;
c->io = p->mem[0].bar&~0xf;
mem = vmap(c->io, p->mem[0].size);
if(mem == nil){
print("yuk: cant map %#p\n", c->io);
print("yuk: cant map %llux\n", c->io);
return -1;
}
pcienable(p);