* [PATCH V4 0/2] fix pci device can't alloc irq from fdt
@ 2025-11-20 12:18 Xianglai Li
2025-11-20 12:18 ` [PATCH V4 1/2] Modify the interrupt trigger type in loongarch virt fdt to macro definition Xianglai Li
2025-11-20 12:18 ` [PATCH V4 2/2] fix pci device can't alloc irq from fdt Xianglai Li
0 siblings, 2 replies; 4+ messages in thread
From: Xianglai Li @ 2025-11-20 12:18 UTC (permalink / raw)
To: qemu-devel, lixianglai; +Cc: Bibo Mao, Jiaxun Yang, Song Gao
When we use the -kernel parameter to start an elf format kernel relying on
fdt, we get the following error:
pcieport 0000:00:01.0: of_irq_parse_pci: failed with rc=-22
pcieport 0000:00:01.0: enabling device (0000 -> 0003)
pcieport 0000:00:01.0: PME: Signaling with IRQ 19
pcieport 0000:00:01.0: AER: enabled with IRQ 19
pcieport 0000:00:01.1: of_irq_parse_pci: failed with rc=-22
pcieport 0000:00:01.1: enabling device (0000 -> 0003)
pcieport 0000:00:01.1: PME: Signaling with IRQ 20
pcieport 0000:00:01.1: AER: enabled with IRQ 20
pcieport 0000:00:01.2: of_irq_parse_pci: failed with rc=-22
pcieport 0000:00:01.2: enabling device (0000 -> 0003)
pcieport 0000:00:01.2: PME: Signaling with IRQ 21
pcieport 0000:00:01.2: AER: enabled with IRQ 21
pcieport 0000:00:01.3: of_irq_parse_pci: failed with rc=-22
pcieport 0000:00:01.3: enabling device (0000 -> 0003)
pcieport 0000:00:01.3: PME: Signaling with IRQ 22
pcieport 0000:00:01.3: AER: enabled with IRQ 22
pcieport 0000:00:01.4: of_irq_parse_pci: failed with rc=-22
This is because the description of interrupt-cell is missing in the pcie
irq map. And there is a lack of a description of the interrupt trigger
type. Now it is corrected and the correct interrupt-cell is added in the
pcie irq map.
Refer to the implementation in arm and add some comments.
changes:
V3->V4:
1.Delete the incorrect byte order conversion
changes:
V2->V3:
1.Delete unnecessary changes
2.Replace some magic numbers with macro definitions
V1->V2:
1.Fallback the incorrect modification of pch_pic interrupt-cells and add
the interrupt trigger type in the pcie irq map
2.Add macro definitions for the interrupt trigger types of fdt
3.Refer to the implementation in arm and add some comments.
Cc: Bibo Mao <maobibo@loongson.cn>
Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
Cc: Song Gao <gaosong@loongson.cn>
Xianglai Li (2):
Modify the interrupt trigger type in loongarch virt fdt to macro
definition
fix pci device can't alloc irq from fdt
hw/loongarch/virt-fdt-build.c | 55 +++++++++++++++++++++++------------
1 file changed, 37 insertions(+), 18 deletions(-)
--
2.39.1
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH V4 1/2] Modify the interrupt trigger type in loongarch virt fdt to macro definition 2025-11-20 12:18 [PATCH V4 0/2] fix pci device can't alloc irq from fdt Xianglai Li @ 2025-11-20 12:18 ` Xianglai Li 2025-11-20 12:18 ` [PATCH V4 2/2] fix pci device can't alloc irq from fdt Xianglai Li 1 sibling, 0 replies; 4+ messages in thread From: Xianglai Li @ 2025-11-20 12:18 UTC (permalink / raw) To: qemu-devel, lixianglai; +Cc: Bibo Mao, Jiaxun Yang, Song Gao In the loongarch virt fdt file, the interrupt trigger type directly uses magic numbers. Now, refer to the definitions in the linux kernel and use macro definitions. Signed-off-by: Xianglai Li <lixianglai@loongson.cn> Reviewed-by: Bibo Mao <maobibo@loongson.cn> --- Cc: Bibo Mao <maobibo@loongson.cn> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> Cc: Song Gao <gaosong@loongson.cn> hw/loongarch/virt-fdt-build.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c index 1f0ba01f71..7333019cf7 100644 --- a/hw/loongarch/virt-fdt-build.c +++ b/hw/loongarch/virt-fdt-build.c @@ -16,6 +16,11 @@ #include "system/reset.h" #include "target/loongarch/cpu.h" +#define FDT_IRQ_TYPE_EDGE_RISING 1 +#define FDT_IRQ_TYPE_EDGE_FALLING 2 +#define FDT_IRQ_TYPE_LEVEL_HIGH 4 +#define FDT_IRQ_TYPE_LEVEL_LOW 8 + static void create_fdt(LoongArchVirtMachineState *lvms) { MachineState *ms = MACHINE(lvms); @@ -415,7 +420,8 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, if (chosen) { qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); } - qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, + FDT_IRQ_TYPE_LEVEL_HIGH); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); g_free(nodename); @@ -435,7 +441,8 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, "loongson,ls7a-rtc"); qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", - VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4); + VIRT_RTC_IRQ - VIRT_GSI_BASE , + FDT_IRQ_TYPE_LEVEL_HIGH); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); g_free(nodename); -- 2.39.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH V4 2/2] fix pci device can't alloc irq from fdt 2025-11-20 12:18 [PATCH V4 0/2] fix pci device can't alloc irq from fdt Xianglai Li 2025-11-20 12:18 ` [PATCH V4 1/2] Modify the interrupt trigger type in loongarch virt fdt to macro definition Xianglai Li @ 2025-11-20 12:18 ` Xianglai Li 2025-11-21 3:41 ` Bibo Mao 1 sibling, 1 reply; 4+ messages in thread From: Xianglai Li @ 2025-11-20 12:18 UTC (permalink / raw) To: qemu-devel, lixianglai; +Cc: Bibo Mao, Jiaxun Yang, Song Gao When we use the -kernel parameter to start an elf format kernel relying on fdt, we get the following error: pcieport 0000:00:01.0: of_irq_parse_pci: failed with rc=-22 pcieport 0000:00:01.0: enabling device (0000 -> 0003) pcieport 0000:00:01.0: PME: Signaling with IRQ 19 pcieport 0000:00:01.0: AER: enabled with IRQ 19 pcieport 0000:00:01.1: of_irq_parse_pci: failed with rc=-22 pcieport 0000:00:01.1: enabling device (0000 -> 0003) pcieport 0000:00:01.1: PME: Signaling with IRQ 20 pcieport 0000:00:01.1: AER: enabled with IRQ 20 pcieport 0000:00:01.2: of_irq_parse_pci: failed with rc=-22 pcieport 0000:00:01.2: enabling device (0000 -> 0003) pcieport 0000:00:01.2: PME: Signaling with IRQ 21 pcieport 0000:00:01.2: AER: enabled with IRQ 21 pcieport 0000:00:01.3: of_irq_parse_pci: failed with rc=-22 pcieport 0000:00:01.3: enabling device (0000 -> 0003) pcieport 0000:00:01.3: PME: Signaling with IRQ 22 pcieport 0000:00:01.3: AER: enabled with IRQ 22 pcieport 0000:00:01.4: of_irq_parse_pci: failed with rc=-22 This is because the description of interrupt-cell is missing in the pcie irq map. And there is a lack of a description of the interrupt trigger type. Now it is corrected and the correct interrupt-cell is added in the pcie irq map. Refer to the implementation in arm and add some comments. Signed-off-by: Xianglai Li <lixianglai@loongson.cn> --- Cc: Bibo Mao <maobibo@loongson.cn> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> Cc: Song Gao <gaosong@loongson.cn> hw/loongarch/virt-fdt-build.c | 44 ++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c index 7333019cf7..e597b19dc3 100644 --- a/hw/loongarch/virt-fdt-build.c +++ b/hw/loongarch/virt-fdt-build.c @@ -321,6 +321,8 @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms, uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * 10] = {}; uint32_t *irq_map = full_irq_map; const MachineState *ms = MACHINE(lvms); + uint32_t pin_mask; + uint32_t devfn_mask; /* * This code creates a standard swizzle of interrupts such that @@ -333,37 +335,45 @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms, */ for (dev = 0; dev < PCI_NUM_PINS; dev++) { - int devfn = dev * 0x8; + int devfn = PCI_DEVFN(dev, 0); for (pin = 0; pin < PCI_NUM_PINS; pin++) { - int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS); + int irq_nr = VIRT_DEVICE_IRQS + \ + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS); int i = 0; - /* Fill PCI address cells */ - irq_map[i] = cpu_to_be32(devfn << 8); - i += 3; - - /* Fill PCI Interrupt cells */ - irq_map[i] = cpu_to_be32(pin + 1); - i += 1; - - /* Fill interrupt controller phandle and cells */ - irq_map[i++] = cpu_to_be32(*pch_pic_phandle); - irq_map[i++] = cpu_to_be32(irq_nr); + uint32_t map[] = { + devfn << 8, 0, 0, /* devfn */ + pin + 1, /* PCI pin */ + *pch_pic_phandle, /* interrupt controller handle */ + irq_nr, /* irq number */ + FDT_IRQ_TYPE_LEVEL_HIGH }; /* irq trigger level */ if (!irq_map_stride) { - irq_map_stride = i; + irq_map_stride = sizeof(map) / sizeof(uint32_t); } + + /* Convert map to big endian */ + for (i = 0; i < irq_map_stride; i++) { + irq_map[i] = cpu_to_be32(map[i]); + } + irq_map += irq_map_stride; } } - qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map, PCI_NUM_PINS * PCI_NUM_PINS * irq_map_stride * sizeof(uint32_t)); + + /* Only need to match the pci slot bit */ + devfn_mask = PCI_DEVFN((PCI_NUM_PINS - 1), 0) << 8; + /* The pci interrupt only needs to match the specified low bit */ + pin_mask = (1 << ((PCI_NUM_PINS - 1))) - 1; + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask", - 0x1800, 0, 0, 0x7); + devfn_mask, 0, 0, /* address cells */ + pin_mask); } static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, @@ -400,6 +410,8 @@ static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, 2, base_mmio, 2, size_mmio); qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map", 0, *pch_msi_phandle, 0, 0x10000); + + qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1); fdt_add_pcie_irq_map_node(lvms, nodename, pch_pic_phandle); g_free(nodename); } -- 2.39.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH V4 2/2] fix pci device can't alloc irq from fdt 2025-11-20 12:18 ` [PATCH V4 2/2] fix pci device can't alloc irq from fdt Xianglai Li @ 2025-11-21 3:41 ` Bibo Mao 0 siblings, 0 replies; 4+ messages in thread From: Bibo Mao @ 2025-11-21 3:41 UTC (permalink / raw) To: Xianglai Li, qemu-devel; +Cc: Jiaxun Yang, Song Gao On 2025/11/20 下午8:18, Xianglai Li wrote: > When we use the -kernel parameter to start an elf format kernel relying on > fdt, we get the following error: > > pcieport 0000:00:01.0: of_irq_parse_pci: failed with rc=-22 > pcieport 0000:00:01.0: enabling device (0000 -> 0003) > pcieport 0000:00:01.0: PME: Signaling with IRQ 19 > pcieport 0000:00:01.0: AER: enabled with IRQ 19 > pcieport 0000:00:01.1: of_irq_parse_pci: failed with rc=-22 > pcieport 0000:00:01.1: enabling device (0000 -> 0003) > pcieport 0000:00:01.1: PME: Signaling with IRQ 20 > pcieport 0000:00:01.1: AER: enabled with IRQ 20 > pcieport 0000:00:01.2: of_irq_parse_pci: failed with rc=-22 > pcieport 0000:00:01.2: enabling device (0000 -> 0003) > pcieport 0000:00:01.2: PME: Signaling with IRQ 21 > pcieport 0000:00:01.2: AER: enabled with IRQ 21 > pcieport 0000:00:01.3: of_irq_parse_pci: failed with rc=-22 > pcieport 0000:00:01.3: enabling device (0000 -> 0003) > pcieport 0000:00:01.3: PME: Signaling with IRQ 22 > pcieport 0000:00:01.3: AER: enabled with IRQ 22 > pcieport 0000:00:01.4: of_irq_parse_pci: failed with rc=-22 > > This is because the description of interrupt-cell is missing in the pcie > irq map. And there is a lack of a description of the interrupt trigger > type. Now it is corrected and the correct interrupt-cell is added in the > pcie irq map. > > Refer to the implementation in arm and add some comments. > > Signed-off-by: Xianglai Li <lixianglai@loongson.cn> > --- > Cc: Bibo Mao <maobibo@loongson.cn> > Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> > Cc: Song Gao <gaosong@loongson.cn> > > hw/loongarch/virt-fdt-build.c | 44 ++++++++++++++++++++++------------- > 1 file changed, 28 insertions(+), 16 deletions(-) > > diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c > index 7333019cf7..e597b19dc3 100644 > --- a/hw/loongarch/virt-fdt-build.c > +++ b/hw/loongarch/virt-fdt-build.c > @@ -321,6 +321,8 @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms, > uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * 10] = {}; > uint32_t *irq_map = full_irq_map; > const MachineState *ms = MACHINE(lvms); > + uint32_t pin_mask; > + uint32_t devfn_mask; > > /* > * This code creates a standard swizzle of interrupts such that > @@ -333,37 +335,45 @@ static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms, > */ > > for (dev = 0; dev < PCI_NUM_PINS; dev++) { > - int devfn = dev * 0x8; > + int devfn = PCI_DEVFN(dev, 0); > > for (pin = 0; pin < PCI_NUM_PINS; pin++) { > - int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS); > + int irq_nr = VIRT_DEVICE_IRQS + \ > + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS); > int i = 0; > > - /* Fill PCI address cells */ > - irq_map[i] = cpu_to_be32(devfn << 8); > - i += 3; > - > - /* Fill PCI Interrupt cells */ > - irq_map[i] = cpu_to_be32(pin + 1); > - i += 1; > - > - /* Fill interrupt controller phandle and cells */ > - irq_map[i++] = cpu_to_be32(*pch_pic_phandle); > - irq_map[i++] = cpu_to_be32(irq_nr); > + uint32_t map[] = { > + devfn << 8, 0, 0, /* devfn */ > + pin + 1, /* PCI pin */ > + *pch_pic_phandle, /* interrupt controller handle */ > + irq_nr, /* irq number */ > + FDT_IRQ_TYPE_LEVEL_HIGH }; /* irq trigger level */ > > if (!irq_map_stride) { > - irq_map_stride = i; > + irq_map_stride = sizeof(map) / sizeof(uint32_t); > } > + > + /* Convert map to big endian */ > + for (i = 0; i < irq_map_stride; i++) { > + irq_map[i] = cpu_to_be32(map[i]); > + } > + > irq_map += irq_map_stride; > } > } > > - > qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map, > PCI_NUM_PINS * PCI_NUM_PINS * > irq_map_stride * sizeof(uint32_t)); > + > + /* Only need to match the pci slot bit */ > + devfn_mask = PCI_DEVFN((PCI_NUM_PINS - 1), 0) << 8; > + /* The pci interrupt only needs to match the specified low bit */ > + pin_mask = (1 << ((PCI_NUM_PINS - 1))) - 1; > + > qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask", > - 0x1800, 0, 0, 0x7); > + devfn_mask, 0, 0, /* address cells */ > + pin_mask); > } > > static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, > @@ -400,6 +410,8 @@ static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, > 2, base_mmio, 2, size_mmio); > qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map", > 0, *pch_msi_phandle, 0, 0x10000); > + > + qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1); > fdt_add_pcie_irq_map_node(lvms, nodename, pch_pic_phandle); > g_free(nodename); > } > Reviewed-by: Bibo Mao <maobibo@loongson.cn> ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-11-21 3:44 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-11-20 12:18 [PATCH V4 0/2] fix pci device can't alloc irq from fdt Xianglai Li 2025-11-20 12:18 ` [PATCH V4 1/2] Modify the interrupt trigger type in loongarch virt fdt to macro definition Xianglai Li 2025-11-20 12:18 ` [PATCH V4 2/2] fix pci device can't alloc irq from fdt Xianglai Li 2025-11-21 3:41 ` Bibo Mao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).