]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
core: ivshmem: Refactor pci_ivshmem_cfg_write
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 18 May 2015 05:22:09 +0000 (07:22 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 22 May 2015 04:53:48 +0000 (06:53 +0200)
We can do simpler by passing in the bias-shifted row value to be written
and the access byte-mask. Then pci_ivshmem_cfg_write just needs to
combine the new value with those of the other bytes as needed, and we
can drop all the size-specific dispatching.

This also lays the foundation for reusing generic BAR emulation.

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

index 8d85293661afb32348fda778f4b1348afce958ee..a4afeead5b28b9cf201aae727a0663565425959a 100644 (file)
@@ -249,8 +249,8 @@ int arch_pci_update_msix_vector(struct pci_device *device, unsigned int index);
 int pci_ivshmem_init(struct cell *cell, struct pci_device *dev);
 void pci_ivshmem_exit(struct pci_device *dev);
 int pci_ivshmem_update_msix(struct pci_device *dev);
-enum pci_access pci_ivshmem_cfg_write(struct pci_device *dev, u16 address,
-                                     u8 sz, u32 val);
+enum pci_access pci_ivshmem_cfg_write(struct pci_device *dev, unsigned int row,
+                                     u32 mask, u32 value);
 enum pci_access pci_ivshmem_cfg_read(struct pci_device *dev, u16 address,
                                     u8 sz, u32 *value);
 int ivshmem_mmio_access_handler(const struct cell *cell, bool is_write,
index 0e55119107f1bb6fe8185c9fc59e51a322cebb9a..65d5e258818c7856170e2e3666cdde3043e65763 100644 (file)
@@ -266,11 +266,11 @@ enum pci_access pci_cfg_write_moderate(struct pci_device *device, u16 address,
        if (!device)
                return PCI_ACCESS_REJECT;
 
-       if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
-               return pci_ivshmem_cfg_write(device, address, size, value);
-
        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 &&
            address >= PCI_CFG_BAR && address <= PCI_CFG_BAR_END) {
index 98be7c97a2dcceb28fdd6824a4b8650e7704d9bd..84dac3853c7f0f9e82582be057f37ae01c71fc60 100644 (file)
@@ -299,51 +299,6 @@ static int ivshmem_write_msix_control(struct pci_ivshmem_endpoint *ive, u32 val)
        return 0;
 }
 
-static enum pci_access ivshmem_cfg_write32(struct pci_ivshmem_endpoint *ive,
-                                          u8 reg, u32 val)
-{
-       switch (reg) {
-       case PCI_CFG_COMMAND:
-               if(ivshmem_write_command(ive, val & 0xffff))
-                       return PCI_ACCESS_REJECT;
-               break;
-       case PCI_CFG_BAR ... (PCI_CFG_BAR + 5 * 4):
-               ivshmem_write_bar(ive, reg, val);
-               break;
-       case IVSHMEM_CFG_MSIX_CAP:
-               if (ivshmem_write_msix_control(ive, val))
-                       return PCI_ACCESS_REJECT;
-       }
-       return PCI_ACCESS_DONE;
-}
-
-static enum pci_access ivshmem_cfg_write16(struct pci_ivshmem_endpoint *ive,
-                                          u8 reg, u16 val)
-{
-       u32 row, shift;
-
-       shift = (reg % 4) * 8;
-       row = ive->cspace[reg / 4];
-       row &= ~(BYTE_MASK(2) << shift);
-       row |= val << shift;
-
-       return ivshmem_cfg_write32(ive, reg - (reg % 4), row);
-}
-
-static enum pci_access ivshmem_cfg_write8(struct pci_ivshmem_endpoint *ive,
-                                         u8 reg, u8 val)
-{
-       u32 row;
-       u8 *rowp;
-
-       row = ive->cspace[reg / 4];
-       rowp = (u8 *)&row;
-       rowp[(reg % 4)] = val;
-
-       return ivshmem_cfg_write32(ive, reg - (reg % 4), row);
-}
-
-
 static struct pci_ivshmem_data **ivshmem_find(struct pci_device *d,
                                              int *cellnum)
 {
@@ -458,33 +413,38 @@ int ivshmem_mmio_access_handler(const struct cell *cell, bool is_write,
 
 /**
  * Handler for MMIO-write-accesses to PCI config space of this virtual device.
- * @param dev          The device that access should be performed on.
- * @param address      Config space address accessed.
- * @param sz           The amount of bytes to write.
- * @param value                The value to write to the config space.
+ * @param device       The device that access should be performed on.
+ * @param row          Config space DWORD row of the access.
+ * @param mask         Mask selected the DWORD bytes to write.
+ * @param value                DWORD to write to the config space.
  *
  * @return PCI_ACCESS_REJECT or PCI_ACCESS_DONE.
  *
  * @see pci_cfg_write_moderate
  */
-enum pci_access pci_ivshmem_cfg_write(struct pci_device *dev, u16 address,
-                                     u8 sz, u32 value)
+enum pci_access pci_ivshmem_cfg_write(struct pci_device *dev, unsigned int row,
+                                     u32 mask, u32 value)
 {
        struct pci_ivshmem_endpoint *ive = dev->ivshmem_endpoint;
 
-       if (address > (sizeof(default_cspace) - sz))
+       if (row >= ARRAY_SIZE(default_cspace))
                return PCI_ACCESS_REJECT;
 
-       switch (sz) {
-       case 1:
-               return ivshmem_cfg_write8(ive, address, (u8)value);
-       case 2:
-               return ivshmem_cfg_write16(ive, address, (u16)value);
-       case 4:
-               return ivshmem_cfg_write32(ive, address, value);
-       default:
-               return PCI_ACCESS_REJECT;
+       value |= ive->cspace[row] & ~mask;
+
+       switch (row) {
+       case PCI_CFG_COMMAND / 4:
+               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;
        }
+       return PCI_ACCESS_DONE;
 }
 
 /**