Implement the pci device.
Not sure if we want this. We have pci. OTOH,
ls /dev/pci
is a more unix approach than
lspci
Signed-off-by: Ron Minnich <rminnich@gmail.com>
diff --git a/kern/arch/x86/pci.c b/kern/arch/x86/pci.c
index 0871507..32e7e8e 100644
--- a/kern/arch/x86/pci.c
+++ b/kern/arch/x86/pci.c
@@ -492,6 +492,30 @@
return NULL;
}
+// The plan 9 semantics we use here are actually very handy for iterators on
+// pci devices.
+struct pci_device *pci_match_vd(struct pci_device *start, int ven_id, int dev_id)
+{
+ struct pci_device *search;
+ struct pcidev_stailq *first = &pci_devices;
+ int bus, dev, func;
+
+ // TODO: teach ron about these macros.
+ if (start) {
+ first = (struct pcidev_stailq *)(&start->all_dev);
+ }
+
+ STAILQ_FOREACH(search, first, all_dev) {
+ if (ven_id == 0 && dev_id == 0)
+ return search;
+
+ if ((search->ven_id == ven_id) &&
+ (search->dev_id == dev_id))
+ return search;
+ }
+ return NULL;
+}
+
/* Helper to get the membar value for BAR index bir */
uintptr_t pci_get_membar(struct pci_device *pcidev, int bir)
{
diff --git a/kern/arch/x86/pci.h b/kern/arch/x86/pci.h
index 6d18084..28bca17 100644
--- a/kern/arch/x86/pci.h
+++ b/kern/arch/x86/pci.h
@@ -253,6 +253,7 @@
void pci_set_bus_master(struct pci_device *pcidev);
void pci_clr_bus_master(struct pci_device *pcidev);
struct pci_device *pci_match_tbdf(int tbdf);
+struct pci_device *pci_match_vd(struct pci_device *start, int ven_id, int dev_id);
uintptr_t pci_get_membar(struct pci_device *pcidev, int bir);
uintptr_t pci_get_iobar(struct pci_device *pcidev, int bir);
uint32_t pci_get_membar_sz(struct pci_device *pcidev, int bir);
@@ -282,6 +283,14 @@
#define explode_tbdf(tbdf) {pcidev.bus = tbdf >> 16;\
pcidev.dev = (tbdf>>11)&0x1f;\
pcidev.func = (tbdf>>8)&3;}
+/* Other plan 9 functions to compose and decompose */
+#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
+#define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
+#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
+#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
+#define BUSTYPE(tbdf) ((tbdf)>>24)
+#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00)
+
static inline void pci_set_drvdata(struct pci_device *pcidev, void *data)
{
diff --git a/kern/drivers/dev/Kbuild b/kern/drivers/dev/Kbuild
index 0b9dd7a..057adf4 100644
--- a/kern/drivers/dev/Kbuild
+++ b/kern/drivers/dev/Kbuild
@@ -5,7 +5,7 @@
obj-y += ether.o
obj-y += kprof.o
obj-y += mnt.o
-#obj-y += pci.o
+obj-y += pci.o
obj-y += pipe.o
obj-y += proc.o
obj-$(CONFIG_REGRESS) += regress.o
diff --git a/kern/drivers/dev/pci.c b/kern/drivers/dev/pci.c
index 74c635a..6f41af5 100644
--- a/kern/drivers/dev/pci.c
+++ b/kern/drivers/dev/pci.c
@@ -62,11 +62,11 @@
}
static int
-pcigen(struct chan *c, char *, struct dirtab *, int unused_int, int s,
+pcigen(struct chan *c, char *unused, struct dirtab *unuseddirtab, int unused_int, int s,
struct dir *dp)
{
int tbdf;
- Pcidev *p;
+ struct pci_device *p = NULL;
struct qid q;
switch (TYPE(c->qid)) {
@@ -87,18 +87,18 @@
devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
return 1;
}
- p = pcimatch(NULL, 0, 0);
+ p = pci_match_vd(NULL, 0, 0);
while (s >= 2 && p != NULL) {
- p = pcimatch(p, 0, 0);
+ p = pci_match_vd(p, 0, 0);
s -= 2;
}
if (p == NULL)
return -1;
- return pcidirgen(c, s + Qpcictl, p->tbdf, dp);
+ return pcidirgen(c, s + Qpcictl, MKBUS(0,p->bus,p->dev,p->func), dp);
case Qpcictl:
case Qpciraw:
tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
- p = pcimatchtbdf(tbdf);
+ p = pci_match_tbdf(tbdf);
if (p == NULL)
return -1;
return pcidirgen(c, TYPE(c->qid), tbdf, dp);
@@ -118,7 +118,7 @@
return devwalk(c, nc, name, nname, (struct dirtab *)0, 0, pcigen);
}
-static long pcistat(struct chan *c, uint8_t * dp, long n)
+static int pcistat(struct chan *c, uint8_t * dp, int n)
{
return devstat(c, dp, n, (struct dirtab *)0, 0L, pcigen);
}
@@ -133,7 +133,7 @@
return c;
}
-static void pciclose(struct chan *)
+static void pciclose(struct chan *unused)
{
}
@@ -142,7 +142,7 @@
char buf[256], *ebuf, *w, *a;
int i, tbdf, r;
uint32_t x;
- Pcidev *p;
+ struct pci_device *p;
a = va;
switch (TYPE(c->qid)) {
@@ -151,24 +151,22 @@
return devdirread(c, a, n, (struct dirtab *)0, 0L, pcigen);
case Qpcictl:
tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
- p = pcimatchtbdf(tbdf);
+ p = pci_match_tbdf(tbdf);
if (p == NULL)
error(Egreg);
ebuf = buf + sizeof buf - 1; /* -1 for newline */
w = seprintf(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d",
- p->ccrb, p->ccru, p->ccrp, p->vid, p->did, p->intl);
- for (i = 0; i < ARRAY_SIZE(p->mem); i++) {
- if (p->mem[i].size == 0)
- continue;
- w = seprintf(w, ebuf, " %d:%.8lux %d", i, p->mem[i].bar,
- p->mem[i].size);
+ p->class, p->subclass, p->progif, p->ven_id, p->dev_id, p->irqline);
+ for (i = 0; i < p->nr_bars; i++) {
+ w = seprintf(w, ebuf, " %d:%.8lux %d", i, p->bar[i].raw_bar,
+ p->bar[i].mmio_sz);
}
*w++ = '\n';
*w = '\0';
return readstr(offset, a, n, buf);
case Qpciraw:
tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
- p = pcimatchtbdf(tbdf);
+ p = pci_match_tbdf(tbdf);
if (p == NULL)
error(Egreg);
if (n + offset > 256)
@@ -177,17 +175,17 @@
return 0;
r = offset;
if (!(r & 3) && n == 4) {
- x = pcicfgr32(p, r);
+ x = pcidev_read32(p, r);
PBIT32(a, x);
return 4;
}
if (!(r & 1) && n == 2) {
- x = pcicfgr16(p, r);
+ x = pcidev_read16(p, r);
PBIT16(a, x);
return 2;
}
for (i = 0; i < n; i++) {
- x = pcicfgr8(p, r);
+ x = pcidev_read8(p, r);
PBIT8(a, x);
a++;
r++;
@@ -205,18 +203,18 @@
uint8_t *a;
int i, r, tbdf;
uint32_t x;
- Pcidev *p;
+ struct pci_device *p;
if (n >= sizeof(buf))
n = sizeof(buf) - 1;
a = va;
- strncpy(buf, (char *unused_char_p_t)a, n);
+ strncpy(buf, (char *)a, n);
buf[n] = 0;
switch (TYPE(c->qid)) {
case Qpciraw:
tbdf = MKBUS(BusPCI, 0, 0, 0) | BUSBDF((uint32_t) c->qid.path);
- p = pcimatchtbdf(tbdf);
+ p = pci_match_tbdf(tbdf);
if (p == NULL)
error(Egreg);
if (offset > 256)
@@ -226,17 +224,17 @@
r = offset;
if (!(r & 3) && n == 4) {
x = GBIT32(a);
- pcicfgw32(p, r, x);
+ pcidev_write32(p, r, x);
return 4;
}
if (!(r & 1) && n == 2) {
x = GBIT16(a);
- pcicfgw16(p, r, x);
+ pcidev_write16(p, r, x);
return 2;
}
for (i = 0; i < n; i++) {
x = GBIT8(a);
- pcicfgw8(p, r, x);
+ pcidev_write8(p, r, x);
a++;
r++;
}
@@ -247,7 +245,7 @@
return n;
}
-struct dev pcidevtab = {
+struct dev pcidevtab __devtab = {
'$',
"pci",