1 #include "kvm/devices.h" 2 #include "kvm/fdt.h" 3 #include "kvm/kvm.h" 4 #include "kvm/of_pci.h" 5 #include "kvm/pci.h" 6 #include "kvm/util.h" 7 8 #include "arm-common/pci.h" 9 10 /* 11 * An entry in the interrupt-map table looks like: 12 * <pci unit address> <pci interrupt pin> <gic phandle> <gic interrupt> 13 */ 14 15 struct of_gic_irq { 16 u32 type, num, flags; 17 } __attribute__((packed)); 18 19 struct of_interrupt_map_entry { 20 struct of_pci_irq_mask pci_irq_mask; 21 u32 gic_phandle; 22 u32 gic_addr_hi; 23 u32 gic_addr_lo; 24 struct of_gic_irq gic_irq; 25 } __attribute__((packed)); 26 27 void pci__generate_fdt_nodes(void *fdt) 28 { 29 struct device_header *dev_hdr; 30 struct of_interrupt_map_entry irq_map[OF_PCI_IRQ_MAP_MAX]; 31 unsigned nentries = 0; 32 /* Bus range */ 33 u32 bus_range[] = { cpu_to_fdt32(0), cpu_to_fdt32(1), }; 34 /* Configuration Space */ 35 u64 cfg_reg_prop[] = { cpu_to_fdt64(KVM_PCI_CFG_AREA), 36 cpu_to_fdt64(ARM_PCI_CFG_SIZE), }; 37 /* Describe the memory ranges */ 38 struct of_pci_ranges_entry ranges[] = { 39 { 40 .pci_addr = { 41 .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_IO)), 42 .mid = 0, 43 .lo = 0, 44 }, 45 .cpu_addr = cpu_to_fdt64(KVM_IOPORT_AREA), 46 .length = cpu_to_fdt64(ARM_IOPORT_SIZE), 47 }, 48 { 49 .pci_addr = { 50 .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_M32)), 51 .mid = cpu_to_fdt32(KVM_PCI_MMIO_AREA >> 32), 52 .lo = cpu_to_fdt32(KVM_PCI_MMIO_AREA), 53 }, 54 .cpu_addr = cpu_to_fdt64(KVM_PCI_MMIO_AREA), 55 .length = cpu_to_fdt64(ARM_PCI_MMIO_SIZE), 56 }, 57 }; 58 59 /* Boilerplate PCI properties */ 60 _FDT(fdt_begin_node(fdt, "pci")); 61 _FDT(fdt_property_string(fdt, "device_type", "pci")); 62 _FDT(fdt_property_cell(fdt, "#address-cells", 0x3)); 63 _FDT(fdt_property_cell(fdt, "#size-cells", 0x2)); 64 _FDT(fdt_property_cell(fdt, "#interrupt-cells", 0x1)); 65 _FDT(fdt_property_string(fdt, "compatible", "pci-host-cam-generic")); 66 _FDT(fdt_property(fdt, "dma-coherent", NULL, 0)); 67 68 _FDT(fdt_property(fdt, "bus-range", bus_range, sizeof(bus_range))); 69 _FDT(fdt_property(fdt, "reg", &cfg_reg_prop, sizeof(cfg_reg_prop))); 70 _FDT(fdt_property(fdt, "ranges", ranges, sizeof(ranges))); 71 _FDT(fdt_property_cell(fdt, "msi-parent", PHANDLE_MSI)); 72 73 /* Generate the interrupt map ... */ 74 dev_hdr = device__first_dev(DEVICE_BUS_PCI); 75 while (dev_hdr && nentries < ARRAY_SIZE(irq_map)) { 76 struct of_interrupt_map_entry *entry = &irq_map[nentries]; 77 struct pci_device_header *pci_hdr = dev_hdr->data; 78 u8 dev_num = dev_hdr->dev_num; 79 u8 pin = pci_hdr->irq_pin; 80 u8 irq = pci_hdr->irq_line; 81 u32 irq_flags = pci_hdr->irq_type; 82 83 *entry = (struct of_interrupt_map_entry) { 84 .pci_irq_mask = { 85 .pci_addr = { 86 .hi = cpu_to_fdt32(of_pci_b_ddddd(dev_num)), 87 .mid = 0, 88 .lo = 0, 89 }, 90 .pci_pin = cpu_to_fdt32(pin), 91 }, 92 .gic_phandle = cpu_to_fdt32(PHANDLE_GIC), 93 .gic_addr_hi = 0, 94 .gic_addr_lo = 0, 95 .gic_irq = { 96 .type = cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI), 97 .num = cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE), 98 .flags = cpu_to_fdt32(irq_flags), 99 }, 100 }; 101 102 nentries++; 103 dev_hdr = device__next_dev(dev_hdr); 104 } 105 106 _FDT(fdt_property(fdt, "interrupt-map", irq_map, 107 sizeof(struct of_interrupt_map_entry) * nentries)); 108 109 /* ... and the corresponding mask. */ 110 if (nentries) { 111 struct of_pci_irq_mask irq_mask = { 112 .pci_addr = { 113 .hi = cpu_to_fdt32(of_pci_b_ddddd(-1)), 114 .mid = 0, 115 .lo = 0, 116 }, 117 .pci_pin = cpu_to_fdt32(7), 118 }; 119 120 _FDT(fdt_property(fdt, "interrupt-map-mask", &irq_mask, 121 sizeof(irq_mask))); 122 } 123 124 _FDT(fdt_end_node(fdt)); 125 } 126