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;
}
}
+ 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;
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];
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)
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;
}
}
+ 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;
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;
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)
{
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,
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;