[SeaBIOS] [PATCH 13/14] virtio: Convert to new PCI BAR helper functions

Kevin O'Connor kevin at koconnor.net
Wed Feb 3 05:18:56 CET 2016


Use the pci_enable_x() functions.

This patch also converts cap->addr from a 'u32' to a union storing a
'u32' or a 'void*'.  This makes it more clear when the address is a
virtual memory address.

The virtio controller code will now explicitly set PCI_COMMAND_MEMORY
and/or PCI_COMMAND_IO instead of assuming it has already been enabled.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/hw/virtio-pci.c | 36 ++++++++++++++++++++----------------
 src/hw/virtio-pci.h | 32 ++++++++++++++++++--------------
 2 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c
index 6df5194..f1e30a2 100644
--- a/src/hw/virtio-pci.c
+++ b/src/hw/virtio-pci.c
@@ -100,16 +100,14 @@ void vp_reset(struct vp_device *vp)
 void vp_notify(struct vp_device *vp, struct vring_virtqueue *vq)
 {
     if (vp->use_modern) {
-        u32 addr = vp->notify.addr +
-            vq->queue_notify_off *
-            vp->notify_off_multiplier;
+        u32 offset = vq->queue_notify_off * vp->notify_off_multiplier;
         if (vp->notify.is_io) {
-            outw(vq->queue_index, addr);
+            outw(vq->queue_index, vp->notify.ioaddr + offset);
         } else {
-            writew((void*)addr, vq->queue_index);
+            writew(vp->notify.memaddr + offset, vq->queue_index);
         }
         dprintf(9, "vp notify %x (%d) -- 0x%x\n",
-                addr, 2, vq->queue_index);
+                vp->notify.ioaddr, 2, vq->queue_index);
     } else {
         vp_write(&vp->legacy, virtio_pci_legacy, queue_notify, vq->queue_index);
     }
@@ -208,7 +206,7 @@ void vp_init_simple(struct vp_device *vp, struct pci_device *pci)
 {
     u8 cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, 0);
     struct vp_cap *vp_cap;
-    u32 addr, offset, mul;
+    u32 offset, mul;
     u8 type;
 
     memset(vp, 0, sizeof(*vp));
@@ -240,19 +238,24 @@ void vp_init_simple(struct vp_device *vp, struct pci_device *pci)
                                            offsetof(struct virtio_pci_cap, bar));
             offset = pci_config_readl(pci->bdf, cap +
                                       offsetof(struct virtio_pci_cap, offset));
-            addr = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0 + 4 * vp_cap->bar);
-            if (addr & PCI_BASE_ADDRESS_SPACE_IO) {
+            u32 bar = PCI_BASE_ADDRESS_0 + 4 * vp_cap->bar;
+            if (pci_config_readl(pci->bdf, bar) & PCI_BASE_ADDRESS_SPACE_IO) {
                 vp_cap->is_io = 1;
-                addr &= PCI_BASE_ADDRESS_IO_MASK;
+                u32 addr = pci_enable_iobar(pci, bar);
+                if (!addr)
+                    return;
+                vp_cap->ioaddr = addr + offset;
             } else {
                 vp_cap->is_io = 0;
-                addr &= PCI_BASE_ADDRESS_MEM_MASK;
+                void *addr = pci_enable_membar(pci, bar);
+                if (!addr)
+                    return;
+                vp_cap->memaddr = addr + offset;
             }
-            vp_cap->addr = addr + offset;
             dprintf(3, "pci dev %x:%x virtio cap at 0x%x type %d "
                     "bar %d at 0x%08x off +0x%04x [%s]\n",
                     pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
-                    vp_cap->cap, type, vp_cap->bar, addr, offset,
+                    vp_cap->cap, type, vp_cap->bar, vp_cap->ioaddr, offset,
                     vp_cap->is_io ? "io" : "mmio");
         }
 
@@ -267,13 +270,14 @@ void vp_init_simple(struct vp_device *vp, struct pci_device *pci)
         dprintf(1, "pci dev %x:%x using legacy (0.9.5) virtio mode\n",
                 pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf));
         vp->legacy.bar = 0;
-        vp->legacy.addr = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0) &
-            PCI_BASE_ADDRESS_IO_MASK;
+        vp->legacy.ioaddr = pci_enable_iobar(pci, PCI_BASE_ADDRESS_0);
+        if (!vp->legacy.ioaddr)
+            return;
         vp->legacy.is_io = 1;
     }
 
     vp_reset(vp);
-    pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
+    pci_enable_busmaster(pci);
     vp_set_status(vp, VIRTIO_CONFIG_S_ACKNOWLEDGE |
                   VIRTIO_CONFIG_S_DRIVER );
 }
diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h
index b11c355..ff8454e 100644
--- a/src/hw/virtio-pci.h
+++ b/src/hw/virtio-pci.h
@@ -86,7 +86,10 @@ typedef struct virtio_pci_isr {
 /* --- driver structs ----------------------------------------------- */
 
 struct vp_cap {
-    u32 addr;
+    union {
+        void *memaddr;
+        u32 ioaddr;
+    };
     u8 cap;
     u8 bar;
     u8 is_io;
@@ -100,10 +103,10 @@ struct vp_device {
 
 static inline u64 _vp_read(struct vp_cap *cap, u32 offset, u8 size)
 {
-    u32 addr = cap->addr + offset;
     u64 var;
 
     if (cap->is_io) {
+        u32 addr = cap->ioaddr + offset;
         switch (size) {
         case 8:
             var = inl(addr);
@@ -122,34 +125,34 @@ static inline u64 _vp_read(struct vp_cap *cap, u32 offset, u8 size)
             var = 0;
         }
     } else {
+        void *addr = cap->memaddr + offset;
         switch (size) {
         case 8:
-            var = readl((void*)addr);
-            var |= (u64)readl((void*)(addr+4)) << 32;
+            var = readl(addr);
+            var |= (u64)readl(addr+4) << 32;
             break;
         case 4:
-            var = readl((void*)addr);
+            var = readl(addr);
             break;
         case 2:
-            var = readw((void*)addr);
+            var = readw(addr);
             break;
         case 1:
-            var = readb((void*)addr);
+            var = readb(addr);
             break;
         default:
             var = 0;
         }
     }
-    dprintf(9, "vp read   %x (%d) -> 0x%llx\n", addr, size, var);
+    dprintf(9, "vp read   %x (%d) -> 0x%llx\n", cap->ioaddr + offset, size, var);
     return var;
 }
 
 static inline void _vp_write(struct vp_cap *cap, u32 offset, u8 size, u64 var)
 {
-    u32 addr = cap->addr + offset;
-
-    dprintf(9, "vp write  %x (%d) <- 0x%llx\n", addr, size, var);
+    dprintf(9, "vp write  %x (%d) <- 0x%llx\n", cap->ioaddr + offset, size, var);
     if (cap->is_io) {
+        u32 addr = cap->ioaddr + offset;
         switch (size) {
         case 4:
             outl(var, addr);
@@ -162,15 +165,16 @@ static inline void _vp_write(struct vp_cap *cap, u32 offset, u8 size, u64 var)
             break;
         }
     } else {
+        void *addr = cap->memaddr + offset;
         switch (size) {
         case 4:
-            writel((void*)addr, var);
+            writel(addr, var);
             break;
         case 2:
-            writew((void*)addr, var);
+            writew(addr, var);
             break;
         case 1:
-            writeb((void*)addr, var);
+            writeb(addr, var);
             break;
         }
     }
-- 
2.5.0




More information about the SeaBIOS mailing list