diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-07-10 11:48:04 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-07-10 11:48:04 +0800 |
| commit | b9ff206e6bd3f4d67851263a6f2acb5f575cf3b0 (patch) | |
| tree | 701314c3aedaa5684e9d4e8f55e261a10b4875f8 /drivers/base | |
| parent | e90b72ec3082588b296956730bd2930cf8d5d671 (diff) | |
| download | lume-b9ff206e6bd3f4d67851263a6f2acb5f575cf3b0.tar.gz lume-b9ff206e6bd3f4d67851263a6f2acb5f575cf3b0.tar.xz | |
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.
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/platform.cc | 25 |
1 files changed, 21 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<const char*>(compat_prop->value); + const uint32 compat_len = static_cast<uint32>(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; |
