MCPcopy Create free account
hub / github.com/Simple-XX/SimpleKernel / ForEachCompatibleNode

Method ForEachCompatibleNode

src/include/kernel_fdt.hpp:451–500  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

449 */
450 template <typename Callback>
451 [[nodiscard]] auto ForEachCompatibleNode(const char* compatible,
452 Callback&& callback) const
453 -> Expected<void> {
454 assert(fdt_header_ != nullptr && "fdt_header_ is null");
455
456 int offset = -1;
457 while (true) {
458 offset = fdt_node_offset_by_compatible(fdt_header_, offset, compatible);
459 if (offset < 0) {
460 if (offset == -FDT_ERR_NOTFOUND) {
461 break;
462 }
463 return std::unexpected(Error(ErrorCode::kFdtParseFailed));
464 }
465
466 const char* node_name = fdt_get_name(fdt_header_, offset, nullptr);
467 if (node_name == nullptr) {
468 continue;
469 }
470
471 uint64_t mmio_base = 0;
472 size_t mmio_size = 0;
473 int reg_len = 0;
474 const auto* reg_prop =
475 fdt_get_property(fdt_header_, offset, "reg", &reg_len);
476 if (reg_prop != nullptr &&
477 static_cast<size_t>(reg_len) >= 2 * sizeof(uint64_t)) {
478 const auto* reg = reinterpret_cast<const uint64_t*>(reg_prop->data);
479 mmio_base = fdt64_to_cpu(reg[0]);
480 mmio_size = fdt64_to_cpu(reg[1]);
481 }
482
483 uint32_t irq = 0;
484 int irq_len = 0;
485 const auto* irq_prop =
486 fdt_get_property(fdt_header_, offset, "interrupts", &irq_len);
487 if (irq_prop != nullptr &&
488 static_cast<size_t>(irq_len) >= sizeof(uint32_t)) {
489 const auto* interrupts =
490 reinterpret_cast<const uint32_t*>(irq_prop->data);
491 irq = fdt32_to_cpu(interrupts[0]);
492 }
493
494 if (!callback(offset, node_name, mmio_base, mmio_size, irq)) {
495 break;
496 }
497 }
498
499 return {};
500 }
501
502 /**
503 * @brief 遍历 FDT 中所有"叶设备"节点,自动跳过基础设施节点。

Callers 1

TEST_FFunction · 0.80

Calls 1

ErrorClass · 0.85

Tested by 1

TEST_FFunction · 0.64