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

Method GetPlic

src/include/kernel_fdt.hpp:310–347  ·  view source on GitHub ↗

* @brief 获取 PLIC 信息 * @return Expected > * <地址,长度,中断源数量,上下文数量> * @pre fdt_header_ 不为空 * @see https://github.com/qemu/qemu/blob/master/hw/arm/virt.c */

Source from the content-addressed store, hash-verified

308 * @see https://github.com/qemu/qemu/blob/master/hw/arm/virt.c
309 */
310 [[nodiscard]] auto GetPlic() const
311 -> Expected<std::tuple<uint64_t, uint64_t, uint32_t, uint32_t>> {
312 assert(fdt_header_ != nullptr && "fdt_header_ is null");
313
314 auto offset = FindCompatibleNode("sifive,plic-1.0.0");
315 if (!offset.has_value()) {
316 offset = FindCompatibleNode("riscv,plic0");
317 }
318 if (!offset.has_value()) {
319 return std::unexpected(offset.error());
320 }
321
322 int len = 0;
323
324 const auto* prop = fdt_get_property(fdt_header_, offset.value(),
325 "interrupts-extended", &len);
326 if (prop == nullptr) {
327 return std::unexpected(Error(ErrorCode::kFdtPropertyNotFound));
328 }
329
330 uint32_t num_entries = len / sizeof(uint32_t);
331 uint32_t context_count = num_entries / 2;
332
333 prop = fdt_get_property(fdt_header_, offset.value(), "riscv,ndev", &len);
334 if (prop == nullptr) {
335 return std::unexpected(Error(ErrorCode::kFdtPropertyNotFound));
336 }
337 uint32_t ndev =
338 fdt32_to_cpu(*reinterpret_cast<const uint32_t*>(prop->data));
339
340 auto reg = GetRegProperty(offset.value());
341 if (!reg.has_value()) {
342 return std::unexpected(reg.error());
343 }
344
345 return std::tuple{reg.value().first, reg.value().second, ndev,
346 context_count};
347 }
348
349 /**
350 * @brief 遍历 FDT 中所有设备节点

Callers 1

InterruptInitFunction · 0.80

Calls 1

ErrorClass · 0.85

Tested by

no test coverage detected