]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
core: ivshmem: Use generic BAR emulation
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 18 May 2015 06:51:27 +0000 (08:51 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 22 May 2015 04:53:48 +0000 (06:53 +0200)
Simplify the code by relying on the PCI core to emulate BAR writes. This
just requires proper settings of the bar_mask fields of ivshmem devices
in configs.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/pci.c
hypervisor/pci_ivshmem.c

index 65d5e258818c7856170e2e3666cdde3043e65763..f31b8d6c72d6f790e4df40a26e3c6ce195ec488e 100644 (file)
@@ -190,11 +190,8 @@ enum pci_access pci_cfg_read_moderate(struct pci_device *device, u16 address,
                return PCI_ACCESS_DONE;
        }
 
-       if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
-               return pci_ivshmem_cfg_read(device, address, size, value);
-
-       /* Emulate BARs for physical devices */
-       if (device->info->type == JAILHOUSE_PCI_TYPE_DEVICE) {
+       /* Emulate BARs for physical and virtual devices */
+       if (device->info->type != JAILHOUSE_PCI_TYPE_BRIDGE) {
                /* Emulate BAR access, always returning the shadow value. */
                if (address >= PCI_CFG_BAR && address <= PCI_CFG_BAR_END) {
                        bar_no = (address - PCI_CFG_BAR) / 4;
@@ -209,6 +206,9 @@ enum pci_access pci_cfg_read_moderate(struct pci_device *device, u16 address,
                }
        }
 
+       if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
+               return pci_ivshmem_cfg_read(device, address, size, value);
+
        if (address < PCI_CONFIG_HEADER_SIZE)
                return PCI_ACCESS_PERFORM;
 
@@ -268,11 +268,8 @@ enum pci_access pci_cfg_write_moderate(struct pci_device *device, u16 address,
 
        value <<= bias_shift;
 
-       if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
-               return pci_ivshmem_cfg_write(device, address / 4, mask, value);
-
-       /* Emulate BARs for physical devices */
-       if (device->info->type == JAILHOUSE_PCI_TYPE_DEVICE &&
+       /* Emulate BARs for physical and virtual devices */
+       if (device->info->type != JAILHOUSE_PCI_TYPE_BRIDGE &&
            address >= PCI_CFG_BAR && address <= PCI_CFG_BAR_END) {
                bar_no = (address - PCI_CFG_BAR) / 4;
                mask &= device->info->bar_mask[bar_no];
@@ -284,7 +281,7 @@ enum pci_access pci_cfg_write_moderate(struct pci_device *device, u16 address,
        if (address < PCI_CONFIG_HEADER_SIZE) {
                if (device->info->type == JAILHOUSE_PCI_TYPE_BRIDGE)
                        cfg_control = bridge_write[address / 4];
-               else /* physical device */
+               else /* physical or virtual device */
                        cfg_control = endpoint_write[address / 4];
 
                if ((cfg_control.mask & mask) != mask)
@@ -292,6 +289,9 @@ enum pci_access pci_cfg_write_moderate(struct pci_device *device, u16 address,
 
                switch (cfg_control.type) {
                case PCI_CONFIG_ALLOW:
+                       if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
+                               return pci_ivshmem_cfg_write(device,
+                                               address / 4, mask, value);
                        return PCI_ACCESS_PERFORM;
                case PCI_CONFIG_RDONLY:
                        return PCI_ACCESS_DONE;
@@ -300,6 +300,9 @@ enum pci_access pci_cfg_write_moderate(struct pci_device *device, u16 address,
                }
        }
 
+       if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
+               return pci_ivshmem_cfg_write(device, address / 4, mask, value);
+
        cap = pci_find_capability(device, address);
        if (!cap || !(cap->flags & JAILHOUSE_PCICAPS_WRITE))
                return PCI_ACCESS_REJECT;
index 84dac3853c7f0f9e82582be057f37ae01c71fc60..c5b2a2c4de8f5b4dfe96484e44276915060819e1 100644 (file)
@@ -100,12 +100,6 @@ static u32 ivshmem_cfg_read32(struct pci_ivshmem_endpoint *ive, u8 reg)
        return ive->cspace[reg / 4];
 }
 
-static u64 ivshmem_cfg_read64(struct pci_ivshmem_endpoint *ive, u8 reg)
-{
-       return ((u64)ivshmem_cfg_read32(ive, reg + 4) << 32) |
-              ivshmem_cfg_read32(ive, reg);
-}
-
 static u16 ivshmem_cfg_read16(struct pci_ivshmem_endpoint *ive, u8 reg)
 {
        unsigned int bias = reg % 4;
@@ -197,20 +191,6 @@ static int ivshmem_write_command(struct pci_ivshmem_endpoint *ive, u16 val)
        return 0;
 }
 
-static void ivshmem_write_bar(struct pci_ivshmem_endpoint *ive, u8 reg, u32 val)
-{
-       int barn = (reg - PCI_CFG_BAR) / 8;
-       struct virt_pci_bar *bar = &(ive->bars[barn]);
-       u32 newval;
-
-       if (reg & 4)
-               newval = val & ((~(bar->sz - 1)) >> 32);
-       else
-               newval = (val & (~(bar->sz - 1) & ~0xf)) | (bar->flags & 0xf);
-
-       ive->cspace[reg / 4] = newval;
-}
-
 static int ivshmem_msix_mmio(struct pci_ivshmem_endpoint *ive, bool is_write,
                             u32 offset, u32 *value)
 {
@@ -392,16 +372,16 @@ int ivshmem_mmio_access_handler(const struct cell *cell, bool is_write,
                if ((ive->cspace[PCI_CFG_COMMAND/4] & PCI_CMD_MEM) == 0)
                        continue;
 
-               /* register BAR access */
-               mem_start = ivshmem_cfg_read64(ive, PCI_CFG_BAR) & ~0xf;
+               /* BAR0: registers */
+               mem_start = (*(u64 *)&device->bar[0]) & ~0xfL;
                mem_sz = ive->bars[0].sz;
                if (addr >= mem_start && addr <= (mem_start + mem_sz - 4))
                        return ivshmem_register_mmio(ive, is_write,
                                                     addr - mem_start,
                                                     value);
 
-               /* MSI-X BAR access */
-               mem_start = ivshmem_cfg_read64(ive, PCI_CFG_BAR + 2 * 8) & ~0xf;
+               /* BAR4: MSI-X */
+               mem_start = (*(u64 *)&device->bar[4]) & ~0xfL;
                mem_sz = ive->bars[2].sz;
                if (addr >= mem_start && addr <= (mem_start + mem_sz - 4))
                        return ivshmem_msix_mmio(ive, is_write,
@@ -437,9 +417,6 @@ enum pci_access pci_ivshmem_cfg_write(struct pci_device *dev, unsigned int row,
                if (ivshmem_write_command(ive, value))
                        return PCI_ACCESS_REJECT;
                break;
-       case PCI_CFG_BAR / 4 ... PCI_CFG_BAR / 4 + 5:
-               ivshmem_write_bar(ive, row * 4, value);
-               break;
        case IVSHMEM_CFG_MSIX_CAP / 4:
                if (ivshmem_write_msix_control(ive, value))
                        return PCI_ACCESS_REJECT;