From 0404f954c130dcf32b605905ad6c8c2ceabe77c9 Mon Sep 17 00:00:00 2001 From: David Karoly Date: Tue, 9 Aug 2022 12:58:46 +0200 Subject: [PATCH] boot/efi/dtb: dump PCI interrupt map see: https://www.kernel.org/doc/Documentation/devicetree/bindings/pci/host-generic-pci.txt https://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf Change-Id: Iba53457384d6330f99ac0b3b6b2894da83471c48 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5537 Tested-by: Commit checker robot Reviewed-by: Fredrik Holmqvist --- src/system/boot/platform/efi/dtb.cpp | 80 +++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/src/system/boot/platform/efi/dtb.cpp b/src/system/boot/platform/efi/dtb.cpp index 8d5c41cfdd..b1a43d483e 100644 --- a/src/system/boot/platform/efi/dtb.cpp +++ b/src/system/boot/platform/efi/dtb.cpp @@ -234,20 +234,76 @@ dump_fdt(const void *fdt) } else if (strcmp(fdt_string(fdt, fdt32_to_cpu(property->nameoff)), "interrupt-map") == 0) { dprintf("\n"); depth++; - for (uint32_t *it = (uint32_t*)property->data; (uint8_t*)it - (uint8_t*)property->data < fdt32_to_cpu(property->len); it += 6) { + + int addressCells = 3; + int interruptCells = 1; + int phandleCells = 1; + + uint32 *prop; + + prop = (uint32*)fdt_getprop(fdt, node, "#address-cells", NULL); + if (prop != NULL) + addressCells = fdt32_to_cpu(*prop); + + prop = (uint32*)fdt_getprop(fdt, node, "#interrupt-cells", NULL); + if (prop != NULL) + interruptCells = fdt32_to_cpu(*prop); + + uint32_t *it = (uint32_t*)property->data; + while ((uint8_t*)it - (uint8_t*)property->data < fdt32_to_cpu(property->len)) { for (int i = 0; i < depth; i++) dprintf(" "); - // child unit address - dprintf("0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 - ", bus: %" PRId32 ", dev: %" PRId32 ", fn: %" PRId32, - fdt32_to_cpu(*(it + 0)), fdt32_to_cpu(*(it + 1)), fdt32_to_cpu(*(it + 2)), fdt32_to_cpu(*(it + 3)), - fdt32_to_cpu(*(it + 0)) / (1 << 16) % (1 << 8), - fdt32_to_cpu(*(it + 0)) / (1 << 11) % (1 << 5), - fdt32_to_cpu(*(it + 0)) % (1 << 3)); - dprintf(", childIrq: %" PRId32 ", parentIrq: (%" PRId32 ", %" PRId32 ")\n", - fdt32_to_cpu(*(it + 3)), fdt32_to_cpu(*(it + 4)), fdt32_to_cpu(*(it + 5))); - if (((it - (uint32_t*)property->data) / 6) % 4 == 3 && ((uint8_t*)(it + 6) - (uint8_t*)property->data < fdt32_to_cpu(property->len))) - dprintf("\n"); + + uint32 childAddr = fdt32_to_cpu(*it); + dprintf("childAddr: "); + for (int i = 0; i < addressCells; i++) { + dprintf("0x%08" PRIx32 " ", fdt32_to_cpu(*it)); + it++; + } + + uint8 bus = childAddr / (1 << 16) % (1 << 8); + uint8 dev = childAddr / (1 << 11) % (1 << 5); + uint8 func = childAddr % (1 << 3); + dprintf("(bus: %" PRId32 ", dev: %" PRId32 ", fn: %" PRId32 "), ", + bus, dev, func); + + dprintf("childIrq: "); + for (int i = 0; i < interruptCells; i++) { + dprintf("%" PRIu32 " ", fdt32_to_cpu(*it)); + it++; + } + + uint32 parentPhandle = fdt32_to_cpu(*it); + it += phandleCells; + dprintf("parentPhandle: %" PRId32 ", ", parentPhandle); + + int parentAddressCells = 0; + int parentInterruptCells = 1; + + int parentNode = fdt_node_offset_by_phandle(fdt, parentPhandle); + if (parentNode >= 0) { + prop = (uint32*)fdt_getprop(fdt, parentNode, "#address-cells", NULL); + if (prop != NULL) + parentAddressCells = fdt32_to_cpu(*prop); + + prop = (uint32*)fdt_getprop(fdt, parentNode, "#interrupt-cells", NULL); + if (prop != NULL) + parentInterruptCells = fdt32_to_cpu(*prop); + } + + dprintf("parentAddress: "); + for (int i = 0; i < parentAddressCells; i++) { + dprintf("%" PRIu32 " ", fdt32_to_cpu(*it)); + it++; + } + + dprintf("parentIrq: "); + for (int i = 0; i < parentInterruptCells; i++) { + dprintf("%" PRIu32 " ", fdt32_to_cpu(*it)); + it++; + } + + dprintf("\n"); } for (int i = 0; i < depth; i++) dprintf(" ");