aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2016-02-02 22:34:27 -0500
committerKevin O'Connor <kevin@koconnor.net>2016-02-02 23:16:41 -0500
commitf46739b1a819750c63fb5849844d99cc2ab001e8 (patch)
treee2aa9fff0258ed3755a09403407097e9a177d62a
parentc53953ac568fa4501f1a619240eecd4bd38cbb21 (diff)
downloadseabios-hppa-f46739b1a819750c63fb5849844d99cc2ab001e8.zip
seabios-hppa-f46739b1a819750c63fb5849844d99cc2ab001e8.tar.gz
seabios-hppa-f46739b1a819750c63fb5849844d99cc2ab001e8.tar.bz2
virtio: Convert to new PCI BAR helper functions
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@koconnor.net>
-rw-r--r--src/hw/virtio-pci.c36
-rw-r--r--src/hw/virtio-pci.h32
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;
}
}