@@ -1,6 +1,7 @@
#ifndef ARM_COMMON__PCI_H
#define ARM_COMMON__PCI_H
+void pci__arm_init(struct kvm *kvm);
void pci__generate_fdt_nodes(void *fdt);
#endif /* ARM_COMMON__PCI_H */
@@ -6,6 +6,7 @@
#include "kvm/fdt.h"
#include "arm-common/gic.h"
+#include "arm-common/pci.h"
#include <linux/kernel.h>
#include <linux/kvm.h>
@@ -86,6 +87,8 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
/* Create the virtual GIC. */
if (gic__create(kvm, kvm->cfg.arch.irqchip))
die("Failed to create virtual GIC");
+
+ pci__arm_init(kvm);
}
#define FDT_ALIGN SZ_2M
@@ -1,3 +1,5 @@
+#include "linux/sizes.h"
+
#include "kvm/devices.h"
#include "kvm/fdt.h"
#include "kvm/kvm.h"
@@ -7,6 +9,11 @@
#include "arm-common/pci.h"
+#define ARM_PCI_IO_START ALIGN(PCI_IOPORT_START, SZ_4K)
+
+/* Must be a multiple of 4k */
+#define ARM_PCI_IO_SIZE ((ARM_MMIO_AREA - ARM_PCI_IO_START) & ~(SZ_4K - 1))
+
/*
* An entry in the interrupt-map table looks like:
* <pci unit address> <pci interrupt pin> <gic phandle> <gic interrupt>
@@ -24,6 +31,14 @@ struct of_interrupt_map_entry {
struct of_gic_irq gic_irq;
} __attribute__((packed));
+void pci__arm_init(struct kvm *kvm)
+{
+ u32 align_pad = ARM_PCI_IO_START - PCI_IOPORT_START;
+
+ /* Make PCI port allocation start at a properly aligned address */
+ pci_get_io_port_block(align_pad);
+}
+
void pci__generate_fdt_nodes(void *fdt)
{
struct device_header *dev_hdr;
@@ -40,10 +55,10 @@ void pci__generate_fdt_nodes(void *fdt)
.pci_addr = {
.hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_IO)),
.mid = 0,
- .lo = 0,
+ .lo = cpu_to_fdt32(ARM_PCI_IO_START),
},
- .cpu_addr = cpu_to_fdt64(KVM_IOPORT_AREA),
- .length = cpu_to_fdt64(ARM_IOPORT_SIZE),
+ .cpu_addr = cpu_to_fdt64(ARM_PCI_IO_START),
+ .length = cpu_to_fdt64(ARM_PCI_IO_SIZE),
},
{
.pci_addr = {