Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,20 @@
* @ingroup hal_riscv_mem
*/

#include "hal/include/memory_regions.h"

#include <libboot/dt/dt.h>
#include <libcore/buffer.h>
#include <libcore/error.h>

#include "../../hal_internal.h"
#include "../../include/memory_regions.h"

static fdt_t g_hal_riscv_fdt;
static void* g_hal_riscv_fdt_addr = NULL;
#include "hal/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 s_get_fdt(const fdt_t** fdtOUT) {
static fdt_t hal_riscv_fdt;
static void* hal_riscv_fdt_addr = NULL;

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;

Expand All @@ -28,31 +26,18 @@ static error_t hal_riscv_init_fdt(fdt_t* fdtOUT) {
if (err)
return err;

return dt_init(dtb, fdtOUT);
}

static error_t hal_riscv_get_fdt(const fdt_t** fdtOUT) {
if (fdtOUT == nullptr)
return ERR_BAD_ARG;

void* dtb = nullptr;
error_t err = ihal_get_dtb(&dtb);
if (err)
return err;

if (g_hal_riscv_fdt_addr != dtb) {
error_t err = hal_riscv_init_fdt(&g_hal_riscv_fdt);
if (hal_riscv_fdt_addr != dtb) {
err = dt_init(dtb, &hal_riscv_fdt);
if (err)
return err;

g_hal_riscv_fdt_addr = dtb;
hal_riscv_fdt_addr = dtb;
}

*fdtOUT = &g_hal_riscv_fdt;
*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) {
static error_t s_node_is_memory(const fdt_t* fdt, dt_node_t node, bool* isMemoryOUT) {
if (fdt == nullptr || isMemoryOUT == nullptr)
return ERR_BAD_ARG;

Expand Down Expand Up @@ -90,7 +75,7 @@ static error_t hal_riscv_node_is_memory(const fdt_t* fdt, dt_node_t node, bool*
/// \param node Current node (0 to get first memory node, or previous memory node to get next)
/// \param nodeOUT Output parameter for the found memory node
/// \return ERR_NONE on success, error code otherwise
static error_t hal_riscv_find_next_memory_node(const fdt_t* fdt, dt_node_t node, dt_node_t* nodeOUT) {
static error_t s_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;

Expand All @@ -105,7 +90,7 @@ static error_t hal_riscv_find_next_memory_node(const fdt_t* fdt, dt_node_t node,

while (true) {
bool is_memory;
err = hal_riscv_node_is_memory(fdt, node, &is_memory);
err = s_node_is_memory(fdt, node, &is_memory);
if (err)
return err;

Expand All @@ -120,8 +105,30 @@ 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, u32 address_cells,
u32 size_cells, u64* addrOUT, u64* sizeOUT) {
static error_t s_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;
}

static error_t s_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;

Expand All @@ -146,11 +153,11 @@ static error_t hal_riscv_read_reg_entry(const fdt_t* fdt, dt_node_t node, u32 re

u64 addr;
u64 size;
err = hal_riscv_read_u32_cells_be(reg_buf, entry_offset, address_cells, &addr);
err = s_read_u32_cells_be(reg_buf, entry_offset, address_cells, &addr);
if (err)
return err;

err = hal_riscv_read_u32_cells_be(reg_buf, entry_offset + (size_t)address_cells * sizeof(u32), size_cells, &size);
err = s_read_u32_cells_be(reg_buf, entry_offset + (size_t)address_cells * sizeof(u32), size_cells, &size);
if (err)
return err;

Expand All @@ -159,44 +166,26 @@ 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;
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));
} internal_res_mem_iter_t;
static_assert(sizeof(internal_res_mem_iter_t) <= sizeof(hal_reserved_memory_iterator_t));

// ==========================================
// Public
// ==========================================

error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOUT) {
if (iterOUT == nullptr)
return ERR_BAD_ARG;

const fdt_t* fdt;
error_t err = hal_riscv_get_fdt(&fdt);
error_t err = s_get_fdt(&fdt);
if (err)
return err;

Expand All @@ -216,15 +205,15 @@ error_t hal_get_reserved_regions_iterator(hal_reserved_memory_iterator_t* iterOU
if (err)
return err;

const riscv_hal_res_mem_iter_t init = {
const internal_res_mem_iter_t init = {
.memreserve_idx = 0,
.is_in_resmem = false,
.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;
*(internal_res_mem_iter_t*)iterOUT = init;
return ERR_NONE;
}

Expand All @@ -233,11 +222,11 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor
return ERR_BAD_ARG;

const fdt_t* fdt;
error_t err = hal_riscv_get_fdt(&fdt);
error_t err = s_get_fdt(&fdt);
if (err)
return err;

riscv_hal_res_mem_iter_t next_iter = *(riscv_hal_res_mem_iter_t*)iter;
internal_res_mem_iter_t next_iter = *(internal_res_mem_iter_t*)iter;

if (!next_iter.is_in_resmem) {
fdt_rsv_entry entry;
Expand All @@ -248,7 +237,7 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor
.size = entry.size,
};
next_iter.memreserve_idx += 1;
*(riscv_hal_res_mem_iter_t*)iter = next_iter;
*(internal_res_mem_iter_t*)iter = next_iter;
*areaOUT = area;
return ERR_NONE;
}
Expand All @@ -262,8 +251,8 @@ 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,
next_iter.resmem_address_cells, next_iter.resmem_size_cells, &addr, &size);
err = s_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 && err != ERR_NOT_FOUND) {
return err;
}
Expand All @@ -273,7 +262,7 @@ error_t hal_get_next_reserved_region(hal_reserved_memory_iterator_t* iter, memor
.size = size,
};
next_iter.resmem_reg_idx += 1;
*(riscv_hal_res_mem_iter_t*)iter = next_iter;
*(internal_res_mem_iter_t*)iter = next_iter;
*areaOUT = area;
return ERR_NONE;
}
Expand All @@ -297,15 +286,15 @@ typedef struct {
u32 reg_idx;
u32 size_cells;
u32 address_cells;
} riscv_hal_mem_iter_t;
static_assert(sizeof(riscv_hal_mem_iter_t) <= sizeof(hal_memory_iterator_t));
} internal_hal_mem_iter_t;
static_assert(sizeof(internal_hal_mem_iter_t) <= sizeof(hal_memory_iterator_t));

error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) {
if (iterOUT == nullptr)
return ERR_BAD_ARG;

const fdt_t* fdt;
error_t err = hal_riscv_get_fdt(&fdt);
error_t err = s_get_fdt(&fdt);
if (err)
return err;

Expand All @@ -316,28 +305,28 @@ error_t hal_get_memory_regions_iterator(hal_memory_iterator_t* iterOUT) {
return err;

dt_node_t first_memory_node;
err = hal_riscv_find_next_memory_node(fdt, 0, &first_memory_node);
err = s_find_next_memory_node(fdt, 0, &first_memory_node);
if (err)
return err;

const riscv_hal_mem_iter_t init = {
const internal_hal_mem_iter_t init = {
.node = first_memory_node,
.reg_idx = 0,
.size_cells = size_cells,
.address_cells = address_cells,
};
*(riscv_hal_mem_iter_t*)iterOUT = init;
*(internal_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) {
if (iter == nullptr || areaOUT == nullptr)
return ERR_BAD_ARG;

riscv_hal_mem_iter_t next_iter = *(riscv_hal_mem_iter_t*)iter;
internal_hal_mem_iter_t next_iter = *(internal_hal_mem_iter_t*)iter;

const fdt_t* fdt;
error_t err = hal_riscv_get_fdt(&fdt);
error_t err = s_get_fdt(&fdt);
if (err)
return err;

Expand All @@ -347,7 +336,7 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_
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);
err = s_read_reg_entry(fdt, next_iter.node, next_iter.reg_idx, address_cells, size_cells, &addr, &size);
if (err != ERR_NONE && err != ERR_NOT_FOUND) {
return err;
}
Expand All @@ -357,13 +346,13 @@ error_t hal_get_next_memory_region(hal_memory_iterator_t* iter, physical_memory_
.size = size,
};
next_iter.reg_idx += 1;
*(riscv_hal_mem_iter_t*)iter = next_iter;
*(internal_hal_mem_iter_t*)iter = next_iter;
*areaOUT = area;
return ERR_NONE;
}

dt_node_t next_memory_node;
err = hal_riscv_find_next_memory_node(fdt, next_iter.node, &next_memory_node);
err = s_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;
Expand Down
Loading
Loading