hw/pci-host: add a generic PCI host
RFC PATCH 1/2 hw/pci-host: add a generic PCI host
From: Rob Herring <[email protected]>
Add a generic PCI host controller for virtual platforms. This is for ARM virtual platforms at the moment, but has nothing ARM specific. This matches the generic PCI host driver added in the 3.16 kernel.
Functioning with OHCI (usb disk), but not LSI SCSI which doesn't find a disk.
TODO:
- The memory region size and alias offset for the io and memory space are hardcoded and need to be set from the machine and must match the values in the DT ranges. Probably need to make these properties.
- More space for PCI memory space needed?
- MSI support - Needs GICv2M or GICv3 support.
--- hw/pci-host/Makefile.objs | 2 +- hw/pci-host/generic-pci.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 hw/pci-host/generic-pci.c
hw/pci-host/Makefile.objs +1 -1
@@ -1,4 +1,4 @@ -common-obj-y += pam.o +common-obj-y += pam.o generic-pci.o # PPC devices common-obj-$(CONFIG_PREP_PCI) += prep.o
hw/pci-host/generic-pci.c new file +182 -0
182 lines not on this page · raw message
Signature · 1 line
1.9.1
RFC PATCH 2/2 hw/arm/virt: Add generic PCI host device
From: Rob Herring <[email protected]>
Enable the generic PCI host on ARM virt platform.
TODO:
The memory regions aliases are hard coded in the host ATM. These probably need to become QOM properties.
--- hw/arm/virt.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+)
hw/arm/virt.c +57 -0
@@ -37,6 +37,7 @@#include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "hw/boards.h" +#include "hw/pci/pci.h" #include "exec/address-spaces.h" #include "qemu/bitops.h" #include "qemu/error-report.h"
@@ -65,6 +66,7 @@ enum {VIRT_GIC_CPU ,VIRT_UART ,VIRT_MMIO , + VIRT_PCI_CFG, }; typedef struct MemMapEntry {
@@ -104,6 +106,7 @@ static const MemMapEntry a15memmap[] = { [VIRT_MMIO ] = {0xa000000 ,0x200 },/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ /* 0x10000000 .. 0x40000000 reserved for PCI */ + [VIRT_PCI_CFG] = { 0x10000000, 0x01000000 }, [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 }, };
@@ -340,6 +343,58 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)g_free (nodename); } +static void create_pci_host (const VirtBoardInfo *vbi,qemu_irq *pic) +{ +PCIBus *pci_bus; +DeviceState *dev; +SysBusDevice *busdev; +uint32_t gic_phandle; +char *nodename; +hwaddr base = vbi->memmap[VIRT_PCI_CFG ].base; +hwaddr size = vbi->memmap[VIRT_PCI_CFG ].size; + + nodename =g_strdup_printf ("/pci@%" PRIx64, base); +qemu_fdt_add_subnode (vbi->fdt, nodename); +qemu_fdt_setprop_string (vbi->fdt, nodename,"compatible" , +"pci-host-cam-generic" ); +qemu_fdt_setprop_string (vbi->fdt, nodename,"device_type" ,"pci" ); +qemu_fdt_setprop_cell (vbi->fdt, nodename,"#address-cells" ,0x3 ); +qemu_fdt_setprop_cell (vbi->fdt, nodename,"#size-cells" ,0x2 ); +qemu_fdt_setprop_cell (vbi->fdt, nodename,"#interrupt-cells" ,0x1 ); + +qemu_fdt_setprop_sized_cells (vbi->fdt, nodename,"reg" ,2 , base,2 , size); + +qemu_fdt_setprop_sized_cells (vbi->fdt, nodename,"ranges" , +1 ,0x01000000 ,2 ,0x00000000 ,2 ,0x11000000 ,2 ,0x00010000 , +1 ,0x02000000 ,2 ,0x12000000 ,2 ,0x12000000 ,2 ,0x2e000000 ); + + gic_phandle =qemu_fdt_get_phandle (vbi->fdt,"/intc" ); +qemu_fdt_setprop_sized_cells (vbi->fdt, nodename,"interrupt-map-mask" , +1 ,0xf800 ,1 ,0x0 ,1 ,0x0 ,1 ,0x7 ); +qemu_fdt_setprop_sized_cells (vbi->fdt, nodename,"interrupt-map" , +1 ,0x0000 ,2 ,0x00000000 ,1 ,0x1 ,1 , gic_phandle,1 ,0 ,1 ,0x4 ,1 ,0x1 , +1 ,0x0800 ,2 ,0x00000000 ,1 ,0x1 ,1 , gic_phandle,1 ,0 ,1 ,0x5 ,1 ,0x1 , +1 ,0x1000 ,2 ,0x00000000 ,1 ,0x1 ,1 , gic_phandle,1 ,0 ,1 ,0x6 ,1 ,0x1 , +1 ,0x1800 ,2 ,0x00000000 ,1 ,0x1 ,1 , gic_phandle,1 ,0 ,1 ,0x7 ,1 ,0x1 ); + + dev =qdev_create (NULL ,"generic_pci" ); + busdev =SYS_BUS_DEVICE (dev); +qdev_init_nofail (dev); +sysbus_mmio_map (busdev,0 , base);/* PCI config */ +sysbus_mmio_map (busdev,1 ,0x11000000 );/* PCI I/O */ +sysbus_mmio_map (busdev,2 ,0x12000000 );/* PCI memory window */ +sysbus_connect_irq (busdev,0 , pic[4 ]); +sysbus_connect_irq (busdev,1 , pic[5 ]); +sysbus_connect_irq (busdev,2 , pic[6 ]); +sysbus_connect_irq (busdev,3 , pic[7 ]); + + pci_bus = (PCIBus *)qdev_get_child_bus (dev,"pci" ); +pci_create_simple (pci_bus,-1 ,"pci-ohci" ); +pci_create_simple (pci_bus,-1 ,"lsi53c895a" ); + +g_free (nodename); +} +static void create_virtio_devices (const VirtBoardInfo *vbi,qemu_irq *pic) {int i;
@@ -455,6 +510,8 @@ static void machvirt_init(QEMUMachineInitArgs *args)create_uart (vbi, pic); +create_pci_host (vbi, pic); +/* Create mmio transports, so the user can create virtio backends * (which will be automatically plugged in to the transports). If * no backend is created the transport will just sit harmlessly idle.
Signature · 1 line
1.9.1