From b9ff206e6bd3f4d67851263a6f2acb5f575cf3b0 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Fri, 10 Jul 2026 11:48:04 +0800 Subject: fix: match all FDT compatible strings Walk the complete NUL-separated compatible property when binding platform devices so the QEMU PLIC probes correctly and UART receive interrupts reach the TTY. Add a boot-time regression assertion for IRQ-chip binding. --- drivers/base/platform.cc | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers/base/platform.cc') diff --git a/drivers/base/platform.cc b/drivers/base/platform.cc index 65ec21e..fae8af6 100644 --- a/drivers/base/platform.cc +++ b/drivers/base/platform.cc @@ -51,14 +51,31 @@ static int platform_match(device* dev, device_driver* drv) if (pdrv->of_match_table == nullptr || pdev->of_node == nullptr) { return 0; } - const char* node_compat = pdev->of_node->get_prop_string("compatible"); - if (node_compat == nullptr) { + const FdtProperty* compat_prop = pdev->of_node->get_prop("compatible"); + if (compat_prop == nullptr || compat_prop->value == nullptr || + compat_prop->len == 0) { return 0; } + + const char* compat_list = static_cast(compat_prop->value); + const uint32 compat_len = static_cast(compat_prop->len); for (const of_device_id* id = pdrv->of_match_table; id->compatible != nullptr; ++id) { - if (strcmp(id->compatible, node_compat) == 0) { - return 1; + uint32 offset = 0; + while (offset < compat_len) { + const char* node_compat = compat_list + offset; + uint32 remaining = compat_len - offset; + uint32 length = 0; + while (length < remaining && node_compat[length] != '\0') { + ++length; + } + if (length == remaining) { + break; /* malformed property without a terminating NUL */ + } + if (strcmp(id->compatible, node_compat) == 0) { + return 1; + } + offset += length + 1; } } return 0; -- cgit v1.2.3