* @brief FDT(Flattened Device Tree)解析器 * * 提供对 FDT 的解析功能,包括节点查找、属性读取、设备枚举等。 * * @pre FDT 数据必须是有效的 DTB 格式 * @post 通过各 Get* 方法可获取设备树中的硬件信息 * * @note ForEachNode、ForEachCompatibleNode 和 ForEachDeviceNode * 是模板方法,保留在头文件中 * @note compatible 属性是 stringlist 格式(多个以 '\0' 分隔的字符串), * 回调接收完整的 compatible 数据和长度 */
| 45 | * 回调接收完整的 compatible 数据和长度 |
| 46 | */ |
| 47 | class KernelFdt { |
| 48 | public: |
| 49 | /** |
| 50 | * @brief 获取 CPU 核心数量 |
| 51 | * @return Expected<size_t> 成功返回核心数,失败返回错误 |
| 52 | * @pre fdt_header_ 不为空 |
| 53 | */ |
| 54 | [[nodiscard]] auto GetCoreCount() const -> Expected<size_t> { |
| 55 | assert(fdt_header_ != nullptr && "fdt_header_ is null"); |
| 56 | |
| 57 | return CountNodesByDeviceType("cpu").and_then( |
| 58 | [](size_t count) -> Expected<size_t> { |
| 59 | if (count == 0) { |
| 60 | return std::unexpected(Error(ErrorCode::kFdtNodeNotFound)); |
| 61 | } |
| 62 | return count; |
| 63 | }); |
| 64 | } |
| 65 | |
| 66 | /** |
| 67 | * @brief 判断 PSCI 信息 |
| 68 | * @return Expected<void> 成功返回空,失败返回错误 |
| 69 | * @pre fdt_header_ 不为空 |
| 70 | */ |
| 71 | [[nodiscard]] auto CheckPSCI() const -> Expected<void> { |
| 72 | assert(fdt_header_ != nullptr && "fdt_header_ is null"); |
| 73 | |
| 74 | return FindNode("/psci").and_then([this](int offset) -> Expected<void> { |
| 75 | return GetPsciMethod(offset).and_then( |
| 76 | [this, offset](const char* method) -> Expected<void> { |
| 77 | klog::Debug("PSCI method: {}", method); |
| 78 | if (strcmp(method, "smc") != 0) { |
| 79 | return std::unexpected(Error(ErrorCode::kFdtPropertyNotFound)); |
| 80 | } |
| 81 | return ValidatePsciFunctionIds(offset); |
| 82 | }); |
| 83 | }); |
| 84 | } |
| 85 | |
| 86 | /** |
| 87 | * @brief 获取内存信息 |
| 88 | * @return Expected<std::pair<uint64_t, size_t>> 内存信息<地址,长度> |
| 89 | * @pre fdt_header_ 不为空 |
| 90 | * @post 返回第一个 reg 条目的 base 和 size |
| 91 | */ |
| 92 | [[nodiscard]] auto GetMemory() const |
| 93 | -> Expected<std::pair<uint64_t, size_t>> { |
| 94 | assert(fdt_header_ != nullptr && "fdt_header_ is null"); |
| 95 | |
| 96 | return FindNode("/memory").and_then( |
| 97 | [this](int offset) -> Expected<std::pair<uint64_t, size_t>> { |
| 98 | return GetRegProperty(offset).transform( |
| 99 | [](std::pair<uint64_t, size_t> reg) { return reg; }); |
| 100 | }); |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * @brief 获取串口信息 |
nothing calls this directly
no outgoing calls
no test coverage detected