handler->ops = &g2m_portio_ops;
}
+unsigned int hvm_pci_decode_addr(unsigned int cf8, unsigned int addr,
+ unsigned int *bus, unsigned int *slot,
+ unsigned int *func)
+{
+ unsigned int bdf;
+
+ ASSERT(CF8_ENABLED(cf8));
+
+ bdf = CF8_BDF(cf8);
+ *bus = PCI_BUS(bdf);
+ *slot = PCI_SLOT(bdf);
+ *func = PCI_FUNC(bdf);
+ /*
+ * NB: the lower 2 bits of the register address are fetched from the
+ * offset into the 0xcfc register when reading/writing to it.
+ */
+ return CF8_ADDR_LO(cf8) | (addr & 3);
+}
+
/*
* Local variables:
* mode: C
CF8_ENABLED(cf8) )
{
uint32_t sbdf, x86_fam;
+ unsigned int bus, slot, func, reg;
+
+ reg = hvm_pci_decode_addr(cf8, p->addr, &bus, &slot, &func);
/* PCI config data cycle */
- sbdf = XEN_DMOP_PCI_SBDF(0,
- PCI_BUS(CF8_BDF(cf8)),
- PCI_SLOT(CF8_BDF(cf8)),
- PCI_FUNC(CF8_BDF(cf8)));
+ sbdf = XEN_DMOP_PCI_SBDF(0, bus, slot, func);
type = XEN_DMOP_IO_RANGE_PCI;
- addr = ((uint64_t)sbdf << 32) |
- CF8_ADDR_LO(cf8) |
- (p->addr & 3);
+ addr = ((uint64_t)sbdf << 32) | reg;
/* AMD extended configuration space access? */
if ( CF8_ADDR_HI(cf8) &&
d->arch.cpuid->x86_vendor == X86_VENDOR_AMD &&
extern void hvm_dpci_msi_eoi(struct domain *d, int vector);
+/* Decode a PCI port IO access into a bus/slot/func/reg. */
+unsigned int hvm_pci_decode_addr(unsigned int cf8, unsigned int addr,
+ unsigned int *bus, unsigned int *slot,
+ unsigned int *func);
+
/*
* HVM port IO handler that performs forwarding of guest IO ports into machine
* IO ports.