pci: Expose real bar number to pci clients.
authorMoritz Hoffmann <moritz.hoffmann@inf.ethz.ch>
Thu, 6 Aug 2015 16:14:32 +0000 (18:14 +0200)
committerMoritz Hoffmann <moritz.hoffmann@inf.ethz.ch>
Thu, 13 Aug 2015 14:16:34 +0000 (16:16 +0200)
In Barrelfish, the PCI BARs are compacted into a non-sparse array. Some devices
have bars that have gaps between them, for example 0 and 2, or 0 and 5. This
information can be inportant to drivers. In order to address this, this change
returns the bar number on the get_cap RPC call and stores it in the device_mem
struct.

Signed-off-by: Moritz Hoffmann <moritz.hoffmann@inf.ethz.ch>

if/pci.if
include/pci/mem.h
lib/pci/pci_client.c
usr/pci/pci.c
usr/pci/pci.h
usr/pci/pci_service.c

index c5496d2..331e5ed 100644 (file)
--- a/if/pci.if
+++ b/if/pci.if
@@ -36,7 +36,7 @@ interface pci "The PCI Interface" {
 
     /* request the cap for a previously-initialised device */
     rpc get_cap(in uint32 idx, in uint32 cap_nr,
-                out errval err, out cap cap, out uint8 type);
+                out errval err, out cap cap, out uint8 type, out uint8 bar_nr);
 
     /* reregister interrupt for a previously-initialized device */
     rpc reregister_interrupt(in uint32 class_code,
index 601c08f..16b2b9f 100644 (file)
@@ -33,6 +33,7 @@ struct device_mem {
     /* NB: it should be the case that bytes = (1 << bits) * nr_caps */
     struct memobj *memobj;   // valid after map_device()
     struct vregion *vregion; // valid after map_device()
+    uint8_t bar_nr; // BAR number
 };
 
 errval_t map_device(struct device_mem *mem);
index 78f21be..f385937 100644 (file)
@@ -134,7 +134,7 @@ errval_t pci_register_driver_movable_irq(pci_driver_init_fn init_func, uint32_t
             uint8_t type;
 
             err = pci_client->vtbl.get_cap(pci_client, nb, nc, &msgerr, &cap,
-                                           &type);
+                                           &type, &bar->bar_nr);
             if (err_is_fail(err) || err_is_fail(msgerr)) {
                 if (err_is_ok(err)) {
                     err = msgerr;
index 7c201c9..9527c0e 100644 (file)
@@ -122,6 +122,14 @@ int pci_bar_to_caps_index(uint8_t bus,
     return -1;
 }
 
+int pci_get_bar_nr_for_index(uint8_t bus,
+                            uint8_t dev,
+                            uint8_t fun,
+                            uint8_t idx)
+{
+    return (dev_caps[bus][dev][fun][idx].bar_nr);
+}
+
 int pci_get_nr_caps_for_bar(uint8_t bus,
                             uint8_t dev,
                             uint8_t fun,
index 4f08aa6..8c3851b 100644 (file)
@@ -65,6 +65,7 @@ errval_t device_reregister_interrupt(uint8_t coreid, int vector,
                  uint32_t vendor_id, uint32_t device_id, uint32_t *bus,
                  uint32_t *dev,uint32_t *fun);
 int pci_bar_to_caps_index(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t BAR);
+int pci_get_bar_nr_for_index(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t idx);
 int pci_get_nr_caps_for_bar(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t index);
 struct capref pci_get_cap_for_device(uint8_t bus, uint8_t dev, uint8_t fun,
                                      uint8_t index, int cap_nr);
index 69c242a..d621b1c 100644 (file)
@@ -141,10 +141,10 @@ reply:
 static void get_cap_response_resend(void *arg);
 
 static void get_cap_response_cont(struct pci_binding *b, errval_t err,
-                                  struct capref cap, uint8_t type)
+                                  struct capref cap, uint8_t type, uint8_t bar_nr)
 {
     errval_t e;
-    e = b->tx_vtbl.get_cap_response(b, NOP_CONT, err, cap, type);
+    e = b->tx_vtbl.get_cap_response(b, NOP_CONT, err, cap, type, bar_nr);
     if(err_is_fail(e)) {
         if(err_no(e) == FLOUNDER_ERR_TX_BUSY) {
             struct client_state *st = b->st;
@@ -153,6 +153,7 @@ static void get_cap_response_cont(struct pci_binding *b, errval_t err,
             me->err = err;
             me->cap = cap;
             me->type = type;
+            me->bar_nr = bar_nr;
             st->cont_st = me;
 
             e = b->register_send(b, get_default_waitset(),
@@ -169,7 +170,7 @@ static void get_cap_response_resend(void *arg)
     struct pci_binding *b = arg;
     struct client_state *st = b->st;
     struct pci_get_cap_response__args *a = st->cont_st;
-    get_cap_response_cont(b, a->err, a->cap, a->type);
+    get_cap_response_cont(b, a->err, a->cap, a->type, a->bar_nr);
     free(a);
 }
 
@@ -189,6 +190,8 @@ static void get_cap_handler(struct pci_binding *b, uint32_t idx,
                                                    st->fun, idx, cap_nr);
         uint8_t type = pci_get_cap_type_for_device(st->bus, st->dev,
                                                    st->fun, idx);
+        uint8_t bar_nr = pci_get_bar_nr_for_index(st->bus, st->dev,
+                                                   st->fun, idx);
 /*
 XXX: I/O-Cap??
         uint8_t type = st->bar_info[idx].type;
@@ -201,7 +204,7 @@ XXX: I/O-Cap??
         }
 */
 
-        get_cap_response_cont(b, SYS_ERR_OK, cap, type);
+        get_cap_response_cont(b, SYS_ERR_OK, cap, type, bar_nr);
     }
 }