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 +++++++++++++++++++++---- test/test_driver_model.cc | 5 +++++ 2 files changed, 26 insertions(+), 4 deletions(-) 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; diff --git a/test/test_driver_model.cc b/test/test_driver_model.cc index 8f105b3..074a84e 100644 --- a/test/test_driver_model.cc +++ b/test/test_driver_model.cc @@ -11,6 +11,7 @@ #include #include #include +#include /* ------------------------------------------------------------------ */ /* Test 1: kref get/put + release fires exactly once */ @@ -206,4 +207,8 @@ void selftest_driver_model() test_kref(); test_kobject_hierarchy(); test_bus_bind(); + + st_begin("driver model: platform IRQ chip probed"); + ST_ASSERT(g_irq_manager.get_chip() != nullptr); + st_pass(); } -- cgit v1.2.3