From ad02b9039402d2c540e64b9361f68933d3ac76f0 Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 27 Apr 2026 01:29:17 +0200 Subject: [PATCH 01/12] Implement memory regions iterators Co-authored-by: Copilot --- src/lib/hal/arch/riscv/memory_region.c | 295 ++++++++++++++++++++++++- 1 file changed, 284 insertions(+), 11 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index 6b8d22c5..f5c94e72 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -1,35 +1,308 @@ +#include
#include +#include #include +#include "../../hal_internal.h" + +static error_t hal_riscv_init_fdt(fdt_t* fdtOUT) { + if (fdtOUT == nullptr) + return ERR_BAD_ARG; + + if (!ihal_is_init()) + return ERR_NOT_INITIALIZED; + + void* dtb = nullptr; + error_t err = ihal_get_dtb(&dtb); + if (err) + return err; + + return dt_init(dtb, fdtOUT); +} + +static bool hal_riscv_node_name_is_memory(buffer_t node_name) { + if (!buffer_is_valid(node_name)) + return false; + + const buffer_t memory_name = make_buffer("memory", 6); + if (buffer_equal(node_name, memory_name)) + return true; + + if (node_name.size < 7) + return false; + + const buffer_t memory_prefix = make_buffer("memory@", 7); + const buffer_t node_prefix = buffer_sub_buffer(node_name, 0, 7); + return buffer_equal(node_prefix, memory_prefix); +} + +static error_t hal_riscv_node_is_memory(const fdt_t* fdt, dt_node_t node, bool* isMemoryOUT) { + if (fdt == nullptr || isMemoryOUT == nullptr) + return ERR_BAD_ARG; + + *isMemoryOUT = false; + + dt_prop_t device_type_prop; + error_t err = dt_get_prop_by_name(fdt, node, "device_type", &device_type_prop); + if (err == ERR_NONE) { + buffer_t device_type_buf; + err = dt_get_prop_buffer(fdt, device_type_prop, &device_type_buf); + if (err) + return err; + + if (buffer_equal(device_type_buf, make_buffer("memory", 6))) { + *isMemoryOUT = true; + return ERR_NONE; + } + } else if (err != ERR_NOT_FOUND) { + return err; + } + + buffer_t node_name; + err = dt_get_node_name(fdt, node, &node_name); + if (err) + return err; + + *isMemoryOUT = hal_riscv_node_name_is_memory(node_name); + return ERR_NONE; +} + +static error_t hal_riscv_find_first_memory_node(const fdt_t* fdt, dt_node_t* nodeOUT) { + if (fdt == nullptr || nodeOUT == nullptr) + return ERR_BAD_ARG; + + dt_node_t node; + error_t err = dt_get_node_child(fdt, fdt->root_node, &node); + if (err) + return err; + + while (true) { + bool is_memory; + err = hal_riscv_node_is_memory(fdt, node, &is_memory); + if (err) + return err; + + if (is_memory) { + *nodeOUT = node; + return ERR_NONE; + } + + err = dt_get_node_sibling(fdt, node, &node); + if (err) + return err; + } +} + +static error_t hal_riscv_find_next_memory_node(const fdt_t* fdt, dt_node_t node, dt_node_t* nodeOUT) { + if (fdt == nullptr || nodeOUT == nullptr) + return ERR_BAD_ARG; + + error_t err = dt_get_node_sibling(fdt, node, &node); + if (err) + return err; + + while (true) { + bool is_memory; + err = hal_riscv_node_is_memory(fdt, node, &is_memory); + if (err) + return err; + + if (is_memory) { + *nodeOUT = node; + return ERR_NONE; + } + + err = dt_get_node_sibling(fdt, node, &node); + if (err) + return err; + } +} + +static error_t hal_riscv_read_first_reg_entry(const fdt_t* fdt, dt_node_t node, u64* addrOUT, u64* sizeOUT) { + if (fdt == nullptr || addrOUT == nullptr || sizeOUT == nullptr) + return ERR_BAD_ARG; + + dt_prop_t reg_prop; + error_t err = dt_get_prop_by_name(fdt, node, "reg", ®_prop); + if (err) + return err; + + buffer_t reg_buf; + err = dt_get_prop_buffer(fdt, reg_prop, ®_buf); + if (err) + return err; + + u64 addr; + u64 size; + if (!buffer_read_u64_be(reg_buf, 0, &addr) || !buffer_read_u64_be(reg_buf, sizeof(u64), &size)) + return ERR_NOT_VALID; + + *addrOUT = addr; + *sizeOUT = size; + return ERR_NONE; +} + typedef struct { u32 idx; bool is_in_resmem; + dt_node_t node; } riscv_hal_res_mem_iter_t; static_assert(sizeof(riscv_hal_res_mem_iter_t) <= sizeof(hal_reserved_memory_iterator_t)); error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOUT) { - (void)iterOUT; - return ERR_NOT_INITIALIZED; + if (iterOUT == nullptr) + return ERR_BAD_ARG; + + fdt_t fdt; + error_t err = hal_riscv_init_fdt(&fdt); + if (err) + return err; + + const riscv_hal_res_mem_iter_t init = { + .idx = 0, + .is_in_resmem = false, + .node = 0, + }; + *(riscv_hal_res_mem_iter_t*)iterOUT = init; + return ERR_NONE; } error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memory_area_t* areaOUT) { - (void)iter; - (void)areaOUT; - return ERR_NOT_INITIALIZED; + if (iter == nullptr || areaOUT == nullptr) + return ERR_BAD_ARG; + + fdt_t fdt; + error_t err = hal_riscv_init_fdt(&fdt); + if (err) + return err; + + riscv_hal_res_mem_iter_t next_iter = *(riscv_hal_res_mem_iter_t*)iter; + + if (!next_iter.is_in_resmem) { + fdt_rsv_entry entry; + err = dt_get_rsv_mem_entry(&fdt, next_iter.idx, &entry); + if (err == ERR_NONE) { + memory_area_t area = { + .addr = (uintptr_t)entry.address, + .size = entry.size, + }; + next_iter.idx += 1; + *(riscv_hal_res_mem_iter_t*)iter = next_iter; + *areaOUT = area; + return ERR_NONE; + } + + if (err != ERR_OUT_OF_BOUNDS) + return err; + + dt_node_t reserved_mem_root; + err = dt_get_node_by_path(&fdt, "/reserved-memory", &reserved_mem_root); + if (err == ERR_NOT_FOUND) + return ERR_NOT_FOUND; + if (err) + return err; + + err = dt_get_node_child(&fdt, reserved_mem_root, &next_iter.node); + if (err == ERR_NOT_FOUND) + return ERR_NOT_FOUND; + if (err) + return err; + + next_iter.is_in_resmem = true; + } + + if (!next_iter.node) + return ERR_NOT_FOUND; + + u64 addr; + u64 size; + err = hal_riscv_read_first_reg_entry(&fdt, next_iter.node, &addr, &size); + if (err) + return err; + + dt_node_t sibling; + err = dt_get_node_sibling(&fdt, next_iter.node, &sibling); + if (err == ERR_NONE) { + next_iter.node = sibling; + } else if (err == ERR_NOT_FOUND) { + next_iter.node = 0; + } else { + return err; + } + + memory_area_t area = { + .addr = (uintptr_t)addr, + .size = size, + }; + *(riscv_hal_res_mem_iter_t*)iter = next_iter; + *areaOUT = area; + return ERR_NONE; } typedef struct { - u32 idx; + dt_node_t node; + bool has_node; } riscv_hal_mem_iter_t; static_assert(sizeof(riscv_hal_mem_iter_t) <= sizeof(hal_memory_iterator_t)); error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) { - (void)iterOUT; - return ERR_NOT_INITIALIZED; + if (iterOUT == nullptr) + return ERR_BAD_ARG; + + fdt_t fdt; + error_t err = hal_riscv_init_fdt(&fdt); + if (err) + return err; + + dt_node_t first_memory_node; + err = hal_riscv_find_first_memory_node(&fdt, &first_memory_node); + if (err) + return err; + + const riscv_hal_mem_iter_t init = { + .node = first_memory_node, + .has_node = true, + }; + *(riscv_hal_mem_iter_t*)iterOUT = init; + return ERR_NONE; } error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_region_t* areaOUT) { - (void)iter; - (void)areaOUT; - return ERR_NOT_INITIALIZED; + if (iter == nullptr || areaOUT == nullptr) + return ERR_BAD_ARG; + + riscv_hal_mem_iter_t next_iter = *(riscv_hal_mem_iter_t*)iter; + if (!next_iter.has_node) + return ERR_NOT_FOUND; + + fdt_t fdt; + error_t err = hal_riscv_init_fdt(&fdt); + if (err) + return err; + + u64 addr; + u64 size; + err = hal_riscv_read_first_reg_entry(&fdt, next_iter.node, &addr, &size); + if (err) + return err; + + dt_node_t next_memory_node; + err = hal_riscv_find_next_memory_node(&fdt, next_iter.node, &next_memory_node); + if (err == ERR_NONE) { + next_iter.node = next_memory_node; + next_iter.has_node = true; + } else if (err == ERR_NOT_FOUND) { + next_iter.node = 0; + next_iter.has_node = false; + } else { + return err; + } + + const physical_memory_region_t area = { + .addr = (__phys void*)(uintptr_t)addr, + .size = size, + }; + *(riscv_hal_mem_iter_t*)iter = next_iter; + *areaOUT = area; + return ERR_NONE; } From 031526aaa6af467c4dde9a8ad848ff5ce5868a6a Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Sat, 2 May 2026 23:46:37 +0200 Subject: [PATCH 02/12] Allow arbitrary number of pairs in reg property --- src/lib/hal/arch/riscv/memory_region.c | 119 ++++++++++++++++--------- 1 file changed, 77 insertions(+), 42 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index f5c94e72..847a60e3 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -118,7 +118,8 @@ static error_t hal_riscv_find_next_memory_node(const fdt_t* fdt, dt_node_t node, } } -static error_t hal_riscv_read_first_reg_entry(const fdt_t* fdt, dt_node_t node, u64* addrOUT, u64* sizeOUT) { +static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 reg_idx, u64* addrOUT, + u64* sizeOUT) { if (fdt == nullptr || addrOUT == nullptr || sizeOUT == nullptr) return ERR_BAD_ARG; @@ -132,9 +133,15 @@ static error_t hal_riscv_read_first_reg_entry(const fdt_t* fdt, dt_node_t node, if (err) return err; + const size_t entry_offset = (size_t)reg_idx * 2 * sizeof(u64); + if (entry_offset >= reg_buf.size) + return ERR_NOT_FOUND; + if (reg_buf.size - entry_offset < 2 * sizeof(u64)) + return ERR_NOT_VALID; + u64 addr; u64 size; - if (!buffer_read_u64_be(reg_buf, 0, &addr) || !buffer_read_u64_be(reg_buf, sizeof(u64), &size)) + if (!buffer_read_u64_be(reg_buf, entry_offset, &addr) || !buffer_read_u64_be(reg_buf, entry_offset + sizeof(u64), &size)) return ERR_NOT_VALID; *addrOUT = addr; @@ -144,6 +151,7 @@ static error_t hal_riscv_read_first_reg_entry(const fdt_t* fdt, dt_node_t node, typedef struct { u32 idx; + u32 reg_idx; bool is_in_resmem; dt_node_t node; } riscv_hal_res_mem_iter_t; @@ -160,6 +168,7 @@ error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOU const riscv_hal_res_mem_iter_t init = { .idx = 0, + .reg_idx = 0, .is_in_resmem = false, .node = 0, }; @@ -208,39 +217,51 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor if (err) return err; + next_iter.reg_idx = 0; next_iter.is_in_resmem = true; } - if (!next_iter.node) - return ERR_NOT_FOUND; + while (next_iter.node) { + u64 addr; + u64 size; + err = hal_riscv_read_reg_entry(&fdt, next_iter.node, next_iter.reg_idx, &addr, &size); + if (err == ERR_NONE) { + memory_area_t area = { + .addr = (uintptr_t)addr, + .size = size, + }; + next_iter.reg_idx += 1; + *(riscv_hal_res_mem_iter_t*)iter = next_iter; + *areaOUT = area; + return ERR_NONE; + } - u64 addr; - u64 size; - err = hal_riscv_read_first_reg_entry(&fdt, next_iter.node, &addr, &size); - if (err) - return err; + if (err != ERR_NOT_FOUND) + return err; + + dt_node_t sibling; + err = dt_get_node_sibling(&fdt, next_iter.node, &sibling); + if (err == ERR_NONE) { + next_iter.node = sibling; + next_iter.reg_idx = 0; + continue; + } + + if (err == ERR_NOT_FOUND) { + next_iter.node = 0; + break; + } - dt_node_t sibling; - err = dt_get_node_sibling(&fdt, next_iter.node, &sibling); - if (err == ERR_NONE) { - next_iter.node = sibling; - } else if (err == ERR_NOT_FOUND) { - next_iter.node = 0; - } else { return err; } - memory_area_t area = { - .addr = (uintptr_t)addr, - .size = size, - }; *(riscv_hal_res_mem_iter_t*)iter = next_iter; - *areaOUT = area; - return ERR_NONE; + return ERR_NOT_FOUND; } typedef struct { dt_node_t node; + u32 reg_idx; bool has_node; } riscv_hal_mem_iter_t; static_assert(sizeof(riscv_hal_mem_iter_t) <= sizeof(hal_memory_iterator_t)); @@ -261,6 +282,7 @@ error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) { const riscv_hal_mem_iter_t init = { .node = first_memory_node, + .reg_idx = 0, .has_node = true, }; *(riscv_hal_mem_iter_t*)iterOUT = init; @@ -280,29 +302,42 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ if (err) return err; - u64 addr; - u64 size; - err = hal_riscv_read_first_reg_entry(&fdt, next_iter.node, &addr, &size); - if (err) - return err; + while (next_iter.has_node) { + u64 addr; + u64 size; + err = hal_riscv_read_reg_entry(&fdt, next_iter.node, next_iter.reg_idx, &addr, &size); + if (err == ERR_NONE) { + const physical_memory_region_t area = { + .addr = (__phys void*)(uintptr_t)addr, + .size = size, + }; + next_iter.reg_idx += 1; + *(riscv_hal_mem_iter_t*)iter = next_iter; + *areaOUT = area; + return ERR_NONE; + } + + if (err != ERR_NOT_FOUND) + return err; + + dt_node_t next_memory_node; + err = hal_riscv_find_next_memory_node(&fdt, next_iter.node, &next_memory_node); + if (err == ERR_NONE) { + next_iter.node = next_memory_node; + next_iter.reg_idx = 0; + next_iter.has_node = true; + continue; + } + + if (err == ERR_NOT_FOUND) { + next_iter.node = 0; + next_iter.has_node = false; + break; + } - dt_node_t next_memory_node; - err = hal_riscv_find_next_memory_node(&fdt, next_iter.node, &next_memory_node); - if (err == ERR_NONE) { - next_iter.node = next_memory_node; - next_iter.has_node = true; - } else if (err == ERR_NOT_FOUND) { - next_iter.node = 0; - next_iter.has_node = false; - } else { return err; } - const physical_memory_region_t area = { - .addr = (__phys void*)(uintptr_t)addr, - .size = size, - }; *(riscv_hal_mem_iter_t*)iter = next_iter; - *areaOUT = area; - return ERR_NONE; + return ERR_NOT_FOUND; } From c1f74720f621d4ab04b402c370fb00eb5278525c Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Sun, 3 May 2026 01:05:40 +0200 Subject: [PATCH 03/12] Respect address and size cells in reserved memory regions lookup Co-authored-by: Copilot --- include/dt/dt.h | 25 ++++++ include/hal/memory_regions.h | 4 +- src/lib/dt/dt_access.c | 60 ++++++++++++++ src/lib/hal/arch/riscv/memory_region.c | 107 ++++++++++++++++--------- 4 files changed, 157 insertions(+), 39 deletions(-) diff --git a/include/dt/dt.h b/include/dt/dt.h index d964b5bc..54bf8eda 100644 --- a/include/dt/dt.h +++ b/include/dt/dt.h @@ -236,6 +236,31 @@ error_t dt_get_prop_buffer(const fdt_t* fdt, dt_prop_t prop, buffer_t* bufOUT); [[gnu::nonnull(3)]] error_t dt_get_rsv_mem_entry(const fdt_t* fdt, u32 index, fdt_rsv_entry* entryOUT); +/** + * @brief Get #address-cells and #size-cells properties from a node. + * @param fdt Pointer to the fdt object. + * @param node The node to read cell counts from. + * @param[out] address_cellsOUT Number of address cells (default 2). + * @param[out] size_cellsOUT Number of size cells (default 1). + * @retval ERR_NONE on success + * @retval ERR_BAD_ARG on nullptr args + * @retval ERR_NOT_VALID if the FDT is invalid or cell counts exceed 2 + */ +[[gnu::nonnull(3, 4)]] +error_t dt_get_reg_cell_counts(const fdt_t* fdt, dt_node_t node, u32* address_cellsOUT, u32* size_cellsOUT); + +/** + * @brief Read a multi-cell big-endian value from a buffer. + * @param buf Buffer to read from. + * @param offset Byte offset in buffer. + * @param cell_count Number of 32-bit cells to read (1-2). + * @param[out] out Resulting u64 value. + * @retval ERR_NONE on success + * @retval ERR_BAD_ARG on invalid cell_count + * @retval ERR_NOT_VALID if buffer is too small or read fails + */ +error_t dt_read_u32_cells_be(buffer_t buf, size_t offset, u32 cell_count, u64* out); + /// @} #endif // !DT_DT diff --git a/include/hal/memory_regions.h b/include/hal/memory_regions.h index 4c562ae1..3a9369ce 100644 --- a/include/hal/memory_regions.h +++ b/include/hal/memory_regions.h @@ -9,7 +9,7 @@ * Fields of this struct should not be modified directly. * */ typedef struct { - alignas(16) u8 data[16]; + alignas(16) u8 data[32]; } hal_reserved_memory_iterator_t; /** @@ -26,7 +26,7 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor * Fields of this struct should not be modified directly. * */ typedef struct { - alignas(16) u8 data[16]; + alignas(16) u8 data[32]; } hal_memory_iterator_t; /** diff --git a/src/lib/dt/dt_access.c b/src/lib/dt/dt_access.c index 36606efb..d4133ded 100644 --- a/src/lib/dt/dt_access.c +++ b/src/lib/dt/dt_access.c @@ -397,3 +397,63 @@ error_t dt_get_rsv_mem_entry(const fdt_t* fdt, u32 index, fdt_rsv_entry* entryOU return ERR_NOT_VALID; } + +error_t dt_read_u32_cells_be(buffer_t buf, size_t offset, u32 cell_count, u64* out) { + if (out == nullptr || cell_count == 0 || cell_count > 2) + return ERR_BAD_ARG; + + if (buf.size < offset) + return ERR_NOT_VALID; + if (buf.size - offset < (size_t)cell_count * sizeof(u32)) + return ERR_NOT_VALID; + + u64 value = 0; + for (u32 idx = 0; idx < cell_count; ++idx) { + u32 cell = 0; + if (!buffer_read_u32_be(buf, offset + (size_t)idx * sizeof(u32), &cell)) + return ERR_NOT_VALID; + + value = (value << 32) | cell; + } + + *out = value; + return ERR_NONE; +} + +error_t dt_get_reg_cell_counts(const fdt_t* fdt, dt_node_t node, u32* address_cellsOUT, u32* size_cellsOUT) { + *address_cellsOUT = 2; + *size_cellsOUT = 1; + + dt_prop_t address_cells_prop; + error_t err = dt_get_prop_by_name(fdt, node, "#address-cells", &address_cells_prop); + if (err == ERR_NONE) { + buffer_t buf; + err = dt_get_prop_buffer(fdt, address_cells_prop, &buf); + if (err) + return err; + + if (!buffer_read_u32_be(buf, 0, address_cellsOUT) || *address_cellsOUT == 0) + return ERR_NOT_VALID; + } else if (err != ERR_NOT_FOUND) { + return err; + } + + dt_prop_t size_cells_prop; + err = dt_get_prop_by_name(fdt, node, "#size-cells", &size_cells_prop); + if (err == ERR_NONE) { + buffer_t buf; + err = dt_get_prop_buffer(fdt, size_cells_prop, &buf); + if (err) + return err; + + if (!buffer_read_u32_be(buf, 0, size_cellsOUT) || *size_cellsOUT == 0) + return ERR_NOT_VALID; + } else if (err != ERR_NOT_FOUND) { + return err; + } + + if (*address_cellsOUT > 2 || *size_cellsOUT > 2) + return ERR_NOT_VALID; + + return ERR_NONE; +} diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index 847a60e3..8e7cff47 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -118,13 +118,15 @@ static error_t hal_riscv_find_next_memory_node(const fdt_t* fdt, dt_node_t node, } } -static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 reg_idx, u64* addrOUT, - u64* sizeOUT) { +static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 reg_idx, u32 address_cells, + u32 size_cells, u64* addrOUT, u64* sizeOUT) { if (fdt == nullptr || addrOUT == nullptr || sizeOUT == nullptr) return ERR_BAD_ARG; + error_t err; + dt_prop_t reg_prop; - error_t err = dt_get_prop_by_name(fdt, node, "reg", ®_prop); + err = dt_get_prop_by_name(fdt, node, "reg", ®_prop); if (err) return err; @@ -133,16 +135,22 @@ static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 re if (err) return err; - const size_t entry_offset = (size_t)reg_idx * 2 * sizeof(u64); + const size_t reg_entry_size = (size_t)(address_cells + size_cells) * sizeof(u32); + const size_t entry_offset = (size_t)reg_idx * reg_entry_size; if (entry_offset >= reg_buf.size) return ERR_NOT_FOUND; - if (reg_buf.size - entry_offset < 2 * sizeof(u64)) + if (reg_buf.size - entry_offset < reg_entry_size) return ERR_NOT_VALID; u64 addr; u64 size; - if (!buffer_read_u64_be(reg_buf, entry_offset, &addr) || !buffer_read_u64_be(reg_buf, entry_offset + sizeof(u64), &size)) - return ERR_NOT_VALID; + err = dt_read_u32_cells_be(reg_buf, entry_offset, address_cells, &addr); + if (err) + return err; + + err = dt_read_u32_cells_be(reg_buf, entry_offset + (size_t)address_cells * sizeof(u32), size_cells, &size); + if (err) + return err; *addrOUT = addr; *sizeOUT = size; @@ -150,10 +158,12 @@ static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 re } typedef struct { - u32 idx; - u32 reg_idx; + u32 memreserve_idx; bool is_in_resmem; - dt_node_t node; + dt_node_t resmem_current_node; + u32 resmem_address_cells; + u32 resmem_size_cells; + u32 resmem_reg_idx; } riscv_hal_res_mem_iter_t; static_assert(sizeof(riscv_hal_res_mem_iter_t) <= sizeof(hal_reserved_memory_iterator_t)); @@ -166,11 +176,33 @@ error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOU if (err) return err; + dt_node_t reserved_mem_root; + err = dt_get_node_by_path(&fdt, "/reserved-memory", &reserved_mem_root); + if (err == ERR_NOT_FOUND) + return ERR_NOT_FOUND; + if (err) + return err; + + u32 address_cells; + u32 size_cells; + err = dt_get_reg_cell_counts(&fdt, reserved_mem_root, &address_cells, &size_cells); + if (err) + return err; + + dt_node_t resmem_first_node; + err = dt_get_node_child(&fdt, reserved_mem_root, &resmem_first_node); + if (err == ERR_NOT_FOUND) + return ERR_NOT_FOUND; + if (err) + return err; + const riscv_hal_res_mem_iter_t init = { - .idx = 0, - .reg_idx = 0, + .memreserve_idx = 0, .is_in_resmem = false, - .node = 0, + .resmem_current_node = resmem_first_node, + .resmem_address_cells = address_cells, + .resmem_size_cells = size_cells, + .resmem_reg_idx = 0, }; *(riscv_hal_res_mem_iter_t*)iterOUT = init; return ERR_NONE; @@ -189,13 +221,13 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor if (!next_iter.is_in_resmem) { fdt_rsv_entry entry; - err = dt_get_rsv_mem_entry(&fdt, next_iter.idx, &entry); + err = dt_get_rsv_mem_entry(&fdt, next_iter.memreserve_idx, &entry); if (err == ERR_NONE) { memory_area_t area = { .addr = (uintptr_t)entry.address, .size = entry.size, }; - next_iter.idx += 1; + next_iter.memreserve_idx += 1; *(riscv_hal_res_mem_iter_t*)iter = next_iter; *areaOUT = area; return ERR_NONE; @@ -204,33 +236,20 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor if (err != ERR_OUT_OF_BOUNDS) return err; - dt_node_t reserved_mem_root; - err = dt_get_node_by_path(&fdt, "/reserved-memory", &reserved_mem_root); - if (err == ERR_NOT_FOUND) - return ERR_NOT_FOUND; - if (err) - return err; - - err = dt_get_node_child(&fdt, reserved_mem_root, &next_iter.node); - if (err == ERR_NOT_FOUND) - return ERR_NOT_FOUND; - if (err) - return err; - - next_iter.reg_idx = 0; next_iter.is_in_resmem = true; } - while (next_iter.node) { + while (next_iter.resmem_current_node) { u64 addr; u64 size; - err = hal_riscv_read_reg_entry(&fdt, next_iter.node, next_iter.reg_idx, &addr, &size); + err = hal_riscv_read_reg_entry(&fdt, next_iter.resmem_current_node, next_iter.resmem_reg_idx, + next_iter.resmem_address_cells, next_iter.resmem_size_cells, &addr, &size); if (err == ERR_NONE) { memory_area_t area = { .addr = (uintptr_t)addr, .size = size, }; - next_iter.reg_idx += 1; + next_iter.resmem_reg_idx += 1; *(riscv_hal_res_mem_iter_t*)iter = next_iter; *areaOUT = area; return ERR_NONE; @@ -240,15 +259,15 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor return err; dt_node_t sibling; - err = dt_get_node_sibling(&fdt, next_iter.node, &sibling); + err = dt_get_node_sibling(&fdt, next_iter.resmem_current_node, &sibling); if (err == ERR_NONE) { - next_iter.node = sibling; - next_iter.reg_idx = 0; + next_iter.resmem_current_node = sibling; + next_iter.resmem_reg_idx = 0; continue; } if (err == ERR_NOT_FOUND) { - next_iter.node = 0; + next_iter.resmem_current_node = 0; break; } @@ -262,6 +281,8 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor typedef struct { dt_node_t node; u32 reg_idx; + u32 size_cells; + u32 address_cells; bool has_node; } riscv_hal_mem_iter_t; static_assert(sizeof(riscv_hal_mem_iter_t) <= sizeof(hal_memory_iterator_t)); @@ -275,6 +296,12 @@ error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) { if (err) return err; + u32 address_cells; + u32 size_cells; + err = dt_get_reg_cell_counts(&fdt, fdt.root_node, &address_cells, &size_cells); + if (err) + return err; + dt_node_t first_memory_node; err = hal_riscv_find_first_memory_node(&fdt, &first_memory_node); if (err) @@ -283,6 +310,8 @@ error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) { const riscv_hal_mem_iter_t init = { .node = first_memory_node, .reg_idx = 0, + .size_cells = size_cells, + .address_cells = address_cells, .has_node = true, }; *(riscv_hal_mem_iter_t*)iterOUT = init; @@ -302,10 +331,14 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ if (err) return err; + u32 address_cells = next_iter.address_cells; + u32 size_cells = next_iter.size_cells; + while (next_iter.has_node) { u64 addr; u64 size; - err = hal_riscv_read_reg_entry(&fdt, next_iter.node, next_iter.reg_idx, &addr, &size); + err = + hal_riscv_read_reg_entry(&fdt, next_iter.node, next_iter.reg_idx, address_cells, size_cells, &addr, &size); if (err == ERR_NONE) { const physical_memory_region_t area = { .addr = (__phys void*)(uintptr_t)addr, From 23fc0b00822e95b2d69ccc9f8a561fafc843fb86 Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Sun, 3 May 2026 01:11:49 +0200 Subject: [PATCH 04/12] Remove misplaced helper function from dt lib Co-authored-by: Copilot --- include/dt/dt.h | 12 ------------ src/lib/dt/dt_access.c | 22 ---------------------- src/lib/hal/arch/riscv/memory_region.c | 26 ++++++++++++++++++++++++-- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/include/dt/dt.h b/include/dt/dt.h index 54bf8eda..d2cb0ff3 100644 --- a/include/dt/dt.h +++ b/include/dt/dt.h @@ -249,18 +249,6 @@ error_t dt_get_rsv_mem_entry(const fdt_t* fdt, u32 index, fdt_rsv_entry* entryOU [[gnu::nonnull(3, 4)]] error_t dt_get_reg_cell_counts(const fdt_t* fdt, dt_node_t node, u32* address_cellsOUT, u32* size_cellsOUT); -/** - * @brief Read a multi-cell big-endian value from a buffer. - * @param buf Buffer to read from. - * @param offset Byte offset in buffer. - * @param cell_count Number of 32-bit cells to read (1-2). - * @param[out] out Resulting u64 value. - * @retval ERR_NONE on success - * @retval ERR_BAD_ARG on invalid cell_count - * @retval ERR_NOT_VALID if buffer is too small or read fails - */ -error_t dt_read_u32_cells_be(buffer_t buf, size_t offset, u32 cell_count, u64* out); - /// @} #endif // !DT_DT diff --git a/src/lib/dt/dt_access.c b/src/lib/dt/dt_access.c index d4133ded..e0933a12 100644 --- a/src/lib/dt/dt_access.c +++ b/src/lib/dt/dt_access.c @@ -398,28 +398,6 @@ error_t dt_get_rsv_mem_entry(const fdt_t* fdt, u32 index, fdt_rsv_entry* entryOU return ERR_NOT_VALID; } -error_t dt_read_u32_cells_be(buffer_t buf, size_t offset, u32 cell_count, u64* out) { - if (out == nullptr || cell_count == 0 || cell_count > 2) - return ERR_BAD_ARG; - - if (buf.size < offset) - return ERR_NOT_VALID; - if (buf.size - offset < (size_t)cell_count * sizeof(u32)) - return ERR_NOT_VALID; - - u64 value = 0; - for (u32 idx = 0; idx < cell_count; ++idx) { - u32 cell = 0; - if (!buffer_read_u32_be(buf, offset + (size_t)idx * sizeof(u32), &cell)) - return ERR_NOT_VALID; - - value = (value << 32) | cell; - } - - *out = value; - return ERR_NONE; -} - error_t dt_get_reg_cell_counts(const fdt_t* fdt, dt_node_t node, u32* address_cellsOUT, u32* size_cellsOUT) { *address_cellsOUT = 2; *size_cellsOUT = 1; diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index 8e7cff47..fb7bca72 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -144,11 +144,11 @@ static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 re u64 addr; u64 size; - err = dt_read_u32_cells_be(reg_buf, entry_offset, address_cells, &addr); + err = hal_riscv_read_u32_cells_be(reg_buf, entry_offset, address_cells, &addr); if (err) return err; - err = dt_read_u32_cells_be(reg_buf, entry_offset + (size_t)address_cells * sizeof(u32), size_cells, &size); + err = hal_riscv_read_u32_cells_be(reg_buf, entry_offset + (size_t)address_cells * sizeof(u32), size_cells, &size); if (err) return err; @@ -157,6 +157,28 @@ static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 re return ERR_NONE; } +static error_t hal_riscv_read_u32_cells_be(buffer_t buf, size_t offset, u32 cell_count, u64* out) { + if (out == nullptr || cell_count == 0 || cell_count > 2) + return ERR_BAD_ARG; + + if (buf.size < offset) + return ERR_NOT_VALID; + if (buf.size - offset < (size_t)cell_count * sizeof(u32)) + return ERR_NOT_VALID; + + u64 value = 0; + for (u32 idx = 0; idx < cell_count; ++idx) { + u32 cell = 0; + if (!buffer_read_u32_be(buf, offset + (size_t)idx * sizeof(u32), &cell)) + return ERR_NOT_VALID; + + value = (value << 32) | cell; + } + + *out = value; + return ERR_NONE; +} + typedef struct { u32 memreserve_idx; bool is_in_resmem; From 7b41f1c00bd62ce404d013f5c7b18b95e98ca2d6 Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Sun, 3 May 2026 01:16:46 +0200 Subject: [PATCH 05/12] Fix build Co-authored-by: Copilot --- src/lib/hal/arch/riscv/memory_region.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index fb7bca72..e6aa2790 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -5,6 +5,8 @@ #include "../../hal_internal.h" +static error_t hal_riscv_read_u32_cells_be(buffer_t buf, size_t offset, u32 cell_count, u64* out); + static error_t hal_riscv_init_fdt(fdt_t* fdtOUT) { if (fdtOUT == nullptr) return ERR_BAD_ARG; From b4a81ec4dc3893646bb9a400c65288b1b98ebdae Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 4 May 2026 00:56:50 +0200 Subject: [PATCH 06/12] Do not check for node name when determining if memory node Co-authored-by: Copilot --- src/lib/hal/arch/riscv/memory_region.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index e6aa2790..651384fe 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -22,22 +22,6 @@ static error_t hal_riscv_init_fdt(fdt_t* fdtOUT) { return dt_init(dtb, fdtOUT); } -static bool hal_riscv_node_name_is_memory(buffer_t node_name) { - if (!buffer_is_valid(node_name)) - return false; - - const buffer_t memory_name = make_buffer("memory", 6); - if (buffer_equal(node_name, memory_name)) - return true; - - if (node_name.size < 7) - return false; - - const buffer_t memory_prefix = make_buffer("memory@", 7); - const buffer_t node_prefix = buffer_sub_buffer(node_name, 0, 7); - return buffer_equal(node_prefix, memory_prefix); -} - static error_t hal_riscv_node_is_memory(const fdt_t* fdt, dt_node_t node, bool* isMemoryOUT) { if (fdt == nullptr || isMemoryOUT == nullptr) return ERR_BAD_ARG; @@ -56,16 +40,10 @@ static error_t hal_riscv_node_is_memory(const fdt_t* fdt, dt_node_t node, bool* *isMemoryOUT = true; return ERR_NONE; } - } else if (err != ERR_NOT_FOUND) { - return err; } - buffer_t node_name; - err = dt_get_node_name(fdt, node, &node_name); - if (err) + if (err != ERR_NOT_FOUND) return err; - - *isMemoryOUT = hal_riscv_node_name_is_memory(node_name); return ERR_NONE; } From b20a8be7a985e0f5e6f8a121541aa3dda9b9d938 Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 4 May 2026 01:02:18 +0200 Subject: [PATCH 07/12] Remove redundant error checks for reserved memory node retrieval --- src/lib/hal/arch/riscv/memory_region.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index 651384fe..caa49403 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -180,8 +180,6 @@ error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOU dt_node_t reserved_mem_root; err = dt_get_node_by_path(&fdt, "/reserved-memory", &reserved_mem_root); - if (err == ERR_NOT_FOUND) - return ERR_NOT_FOUND; if (err) return err; @@ -193,8 +191,6 @@ error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOU dt_node_t resmem_first_node; err = dt_get_node_child(&fdt, reserved_mem_root, &resmem_first_node); - if (err == ERR_NOT_FOUND) - return ERR_NOT_FOUND; if (err) return err; From 980fd9e00e3fc94b752ff1ae3ac7309e6736f37d Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 4 May 2026 01:15:21 +0200 Subject: [PATCH 08/12] Simplify functions for getting memory regions --- src/lib/hal/arch/riscv/memory_region.c | 34 +++++--------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index caa49403..6af2cd35 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -47,37 +47,15 @@ static error_t hal_riscv_node_is_memory(const fdt_t* fdt, dt_node_t node, bool* return ERR_NONE; } -static error_t hal_riscv_find_first_memory_node(const fdt_t* fdt, dt_node_t* nodeOUT) { - if (fdt == nullptr || nodeOUT == nullptr) - return ERR_BAD_ARG; - - dt_node_t node; - error_t err = dt_get_node_child(fdt, fdt->root_node, &node); - if (err) - return err; - - while (true) { - bool is_memory; - err = hal_riscv_node_is_memory(fdt, node, &is_memory); - if (err) - return err; - - if (is_memory) { - *nodeOUT = node; - return ERR_NONE; - } - - err = dt_get_node_sibling(fdt, node, &node); - if (err) - return err; - } -} - static error_t hal_riscv_find_next_memory_node(const fdt_t* fdt, dt_node_t node, dt_node_t* nodeOUT) { if (fdt == nullptr || nodeOUT == nullptr) return ERR_BAD_ARG; - error_t err = dt_get_node_sibling(fdt, node, &node); + error_t err; + if (node != 0) + err = dt_get_node_sibling(fdt, node, &node); + else + err = dt_get_node_child(fdt, fdt->root_node, &node); if (err) return err; @@ -301,7 +279,7 @@ error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) { return err; dt_node_t first_memory_node; - err = hal_riscv_find_first_memory_node(&fdt, &first_memory_node); + err = hal_riscv_find_next_memory_node(&fdt, 0, &first_memory_node); if (err) return err; From 77a96e8b14bb054a5e726189f37c9730261fc2a4 Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 4 May 2026 01:33:53 +0200 Subject: [PATCH 09/12] Initialize fdt only once --- src/lib/hal/arch/riscv/memory_region.c | 56 +++++++++++++++++--------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index 6af2cd35..c1e41a1a 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -5,6 +5,9 @@ #include "../../hal_internal.h" +static fdt_t hal_riscv_fdt; +static bool hal_riscv_fdt_initialized = false; + static error_t hal_riscv_read_u32_cells_be(buffer_t buf, size_t offset, u32 cell_count, u64* out); static error_t hal_riscv_init_fdt(fdt_t* fdtOUT) { @@ -22,6 +25,22 @@ static error_t hal_riscv_init_fdt(fdt_t* fdtOUT) { return dt_init(dtb, fdtOUT); } +static error_t hal_riscv_get_fdt(const fdt_t** fdtOUT) { + if (fdtOUT == nullptr) + return ERR_BAD_ARG; + + if (!hal_riscv_fdt_initialized) { + error_t err = hal_riscv_init_fdt(&hal_riscv_fdt); + if (err) + return err; + + hal_riscv_fdt_initialized = true; + } + + *fdtOUT = &hal_riscv_fdt; + return ERR_NONE; +} + static error_t hal_riscv_node_is_memory(const fdt_t* fdt, dt_node_t node, bool* isMemoryOUT) { if (fdt == nullptr || isMemoryOUT == nullptr) return ERR_BAD_ARG; @@ -151,24 +170,24 @@ error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOU if (iterOUT == nullptr) return ERR_BAD_ARG; - fdt_t fdt; - error_t err = hal_riscv_init_fdt(&fdt); + const fdt_t* fdt; + error_t err = hal_riscv_get_fdt(&fdt); if (err) return err; dt_node_t reserved_mem_root; - err = dt_get_node_by_path(&fdt, "/reserved-memory", &reserved_mem_root); + err = dt_get_node_by_path(fdt, "/reserved-memory", &reserved_mem_root); if (err) return err; u32 address_cells; u32 size_cells; - err = dt_get_reg_cell_counts(&fdt, reserved_mem_root, &address_cells, &size_cells); + err = dt_get_reg_cell_counts(fdt, reserved_mem_root, &address_cells, &size_cells); if (err) return err; dt_node_t resmem_first_node; - err = dt_get_node_child(&fdt, reserved_mem_root, &resmem_first_node); + err = dt_get_node_child(fdt, reserved_mem_root, &resmem_first_node); if (err) return err; @@ -188,8 +207,8 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor if (iter == nullptr || areaOUT == nullptr) return ERR_BAD_ARG; - fdt_t fdt; - error_t err = hal_riscv_init_fdt(&fdt); + const fdt_t* fdt; + error_t err = hal_riscv_get_fdt(&fdt); if (err) return err; @@ -197,7 +216,7 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor if (!next_iter.is_in_resmem) { fdt_rsv_entry entry; - err = dt_get_rsv_mem_entry(&fdt, next_iter.memreserve_idx, &entry); + err = dt_get_rsv_mem_entry(fdt, next_iter.memreserve_idx, &entry); if (err == ERR_NONE) { memory_area_t area = { .addr = (uintptr_t)entry.address, @@ -218,7 +237,7 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor while (next_iter.resmem_current_node) { u64 addr; u64 size; - err = hal_riscv_read_reg_entry(&fdt, next_iter.resmem_current_node, next_iter.resmem_reg_idx, + err = hal_riscv_read_reg_entry(fdt, next_iter.resmem_current_node, next_iter.resmem_reg_idx, next_iter.resmem_address_cells, next_iter.resmem_size_cells, &addr, &size); if (err == ERR_NONE) { memory_area_t area = { @@ -235,7 +254,7 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor return err; dt_node_t sibling; - err = dt_get_node_sibling(&fdt, next_iter.resmem_current_node, &sibling); + err = dt_get_node_sibling(fdt, next_iter.resmem_current_node, &sibling); if (err == ERR_NONE) { next_iter.resmem_current_node = sibling; next_iter.resmem_reg_idx = 0; @@ -267,19 +286,19 @@ error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) { if (iterOUT == nullptr) return ERR_BAD_ARG; - fdt_t fdt; - error_t err = hal_riscv_init_fdt(&fdt); + const fdt_t* fdt; + error_t err = hal_riscv_get_fdt(&fdt); if (err) return err; u32 address_cells; u32 size_cells; - err = dt_get_reg_cell_counts(&fdt, fdt.root_node, &address_cells, &size_cells); + err = dt_get_reg_cell_counts(fdt, fdt->root_node, &address_cells, &size_cells); if (err) return err; dt_node_t first_memory_node; - err = hal_riscv_find_next_memory_node(&fdt, 0, &first_memory_node); + err = hal_riscv_find_next_memory_node(fdt, 0, &first_memory_node); if (err) return err; @@ -302,8 +321,8 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ if (!next_iter.has_node) return ERR_NOT_FOUND; - fdt_t fdt; - error_t err = hal_riscv_init_fdt(&fdt); + const fdt_t* fdt; + error_t err = hal_riscv_get_fdt(&fdt); if (err) return err; @@ -313,8 +332,7 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ while (next_iter.has_node) { u64 addr; u64 size; - err = - hal_riscv_read_reg_entry(&fdt, next_iter.node, next_iter.reg_idx, address_cells, size_cells, &addr, &size); + err = hal_riscv_read_reg_entry(fdt, next_iter.node, next_iter.reg_idx, address_cells, size_cells, &addr, &size); if (err == ERR_NONE) { const physical_memory_region_t area = { .addr = (__phys void*)(uintptr_t)addr, @@ -330,7 +348,7 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ return err; dt_node_t next_memory_node; - err = hal_riscv_find_next_memory_node(&fdt, next_iter.node, &next_memory_node); + err = hal_riscv_find_next_memory_node(fdt, next_iter.node, &next_memory_node); if (err == ERR_NONE) { next_iter.node = next_memory_node; next_iter.reg_idx = 0; From f826471bbd1d524dff67736bfd8ba3dceaa474e3 Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 4 May 2026 01:40:44 +0200 Subject: [PATCH 10/12] Remove redundant `has_node` flag --- src/lib/hal/arch/riscv/memory_region.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index c1e41a1a..a0249c9f 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -278,7 +278,6 @@ typedef struct { u32 reg_idx; u32 size_cells; u32 address_cells; - bool has_node; } riscv_hal_mem_iter_t; static_assert(sizeof(riscv_hal_mem_iter_t) <= sizeof(hal_memory_iterator_t)); @@ -307,7 +306,6 @@ error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) { .reg_idx = 0, .size_cells = size_cells, .address_cells = address_cells, - .has_node = true, }; *(riscv_hal_mem_iter_t*)iterOUT = init; return ERR_NONE; @@ -318,8 +316,6 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ return ERR_BAD_ARG; riscv_hal_mem_iter_t next_iter = *(riscv_hal_mem_iter_t*)iter; - if (!next_iter.has_node) - return ERR_NOT_FOUND; const fdt_t* fdt; error_t err = hal_riscv_get_fdt(&fdt); @@ -329,7 +325,7 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ u32 address_cells = next_iter.address_cells; u32 size_cells = next_iter.size_cells; - while (next_iter.has_node) { + while (next_iter.node != 0) { u64 addr; u64 size; err = hal_riscv_read_reg_entry(fdt, next_iter.node, next_iter.reg_idx, address_cells, size_cells, &addr, &size); @@ -352,13 +348,11 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ if (err == ERR_NONE) { next_iter.node = next_memory_node; next_iter.reg_idx = 0; - next_iter.has_node = true; continue; } if (err == ERR_NOT_FOUND) { next_iter.node = 0; - next_iter.has_node = false; break; } From a97d936a4e0e5fa681b847414e3ca9675faa93ad Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 4 May 2026 01:49:20 +0200 Subject: [PATCH 11/12] Do not change iter on failure --- src/lib/hal/arch/riscv/memory_region.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index a0249c9f..4fe8ff4f 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -269,7 +269,6 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor return err; } - *(riscv_hal_res_mem_iter_t*)iter = next_iter; return ERR_NOT_FOUND; } @@ -359,6 +358,5 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ return err; } - *(riscv_hal_mem_iter_t*)iter = next_iter; return ERR_NOT_FOUND; } From ce93b8b0234bee27019da2f1ee55af2966febcfe Mon Sep 17 00:00:00 2001 From: Grzegorz Suwaj Date: Mon, 4 May 2026 01:56:52 +0200 Subject: [PATCH 12/12] Simplify error handling --- src/lib/hal/arch/riscv/memory_region.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/lib/hal/arch/riscv/memory_region.c index 4fe8ff4f..e25ef30e 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/lib/hal/arch/riscv/memory_region.c @@ -261,11 +261,6 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor continue; } - if (err == ERR_NOT_FOUND) { - next_iter.resmem_current_node = 0; - break; - } - return err; } @@ -350,11 +345,6 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_ continue; } - if (err == ERR_NOT_FOUND) { - next_iter.node = 0; - break; - } - return err; }