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 struct of_gic_irq gic_irq; 22 } __attribute__((packed)); 23 24 void pci__generate_fdt_nodes(void *fdt, u32 gic_phandle) 25 { 26 struct device_header *dev_hdr; 27 struct of_interrupt_map_entry irq_map[OF_PCI_IRQ_MAP_MAX]; 28 unsigned nentries = 0; 29 /* Describe the memory ranges (config and memory) */ 30 struct of_pci_ranges_entry ranges[] = { 31 { 32 .pci_addr = { 33 .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_CONFIG)), 34 .mid = 0, 35 .lo = 0, 36 }, 37 .cpu_addr = cpu_to_fdt64(KVM_PCI_CFG_AREA), 38 .length = cpu_to_fdt64(ARM_PCI_CFG_SIZE), 39 }, 40 { 41 .pci_addr = { 42 .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_IO)), 43 .mid = 0, 44 .lo = 0, 45 }, 46 .cpu_addr = cpu_to_fdt64(KVM_IOPORT_AREA), 47 .length = cpu_to_fdt64(ARM_IOPORT_SIZE), 48 }, 49 { 50 .pci_addr = { 51 .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_M32)), 52 .mid = 0, 53 .lo = 0, 54 }, 55 .cpu_addr = cpu_to_fdt64(KVM_PCI_MMIO_AREA), 56 .length = cpu_to_fdt64(ARM_PCI_MMIO_SIZE), 57 }, 58 }; 59 60 /* Boilerplate PCI properties */ 61 _FDT(fdt_begin_node(fdt, "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", "linux,pci-virt")); 66 67 _FDT(fdt_property(fdt, "ranges", ranges, sizeof(ranges))); 68 69 /* Generate the interrupt map ... */ 70 dev_hdr = device__first_dev(DEVICE_BUS_PCI); 71 while (dev_hdr && nentries < ARRAY_SIZE(irq_map)) { 72 struct of_interrupt_map_entry *entry = &irq_map[nentries]; 73 struct pci_device_header *pci_hdr = dev_hdr->data; 74 u8 dev_num = dev_hdr->dev_num; 75 u8 pin = pci_hdr->irq_pin; 76 u8 irq = pci_hdr->irq_line; 77 78 *entry = (struct of_interrupt_map_entry) { 79 .pci_irq_mask = { 80 .pci_addr = { 81 .hi = cpu_to_fdt32(of_pci_b_ddddd(dev_num)), 82 .mid = 0, 83 .lo = 0, 84 }, 85 .pci_pin = cpu_to_fdt32(pin), 86 }, 87 .gic_phandle = cpu_to_fdt32(gic_phandle), 88 .gic_irq = { 89 .type = cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI), 90 .num = cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE), 91 .flags = cpu_to_fdt32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), 92 }, 93 }; 94 95 nentries++; 96 dev_hdr = device__next_dev(dev_hdr); 97 } 98 99 _FDT(fdt_property(fdt, "interrupt-map", irq_map, 100 sizeof(struct of_interrupt_map_entry) * nentries)); 101 102 /* ... and the corresponding mask. */ 103 if (nentries) { 104 struct of_pci_irq_mask irq_mask = { 105 .pci_addr = { 106 .hi = cpu_to_fdt32(of_pci_b_ddddd(-1)), 107 .mid = 0, 108 .lo = 0, 109 }, 110 .pci_pin = cpu_to_fdt32(7), 111 }; 112 113 _FDT(fdt_property(fdt, "interrupt-map-mask", &irq_mask, 114 sizeof(irq_mask))); 115 } 116 117 _FDT(fdt_end_node(fdt)); 118 } 119