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