Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 22 additions & 0 deletions include/dt/dt.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,20 @@ typedef struct {
dt_node_t root_node; /**< Root node offset. */
u32 total_size; /**< Total size of the FDT. */
u32 struct_off; /**< Structure block offset. */
u32 rsvmap_off; /**< Memory reservation map offset. */
u32 strings_off; /**< Strings block offset. */
u32 struct_size; /**< Structure block size. */
u32 fdt_version; /**< FDT version. */
} fdt_t;

/**
* @brief Reserved memory entry structure.
*/
typedef struct {
u64 address; /**< Entry address. */
u64 size; /**< Entry size. */
} fdt_rsv_entry;

/**
* @brief Read the header at fdt and set fields of obj.
* @param fdt Pointer to the flattened device tree data.
Expand Down Expand Up @@ -214,6 +223,19 @@ error_t dt_get_prop_name_ptr(const fdt_t* fdt, dt_prop_t prop, const char** ptrO
[[gnu::nonnull(3)]]
error_t dt_get_prop_buffer(const fdt_t* fdt, dt_prop_t prop, buffer_t* bufOUT);

/**
* @brief Get a reserved memory entry at index from the Memory Reservation Block.
* @param fdt Pointer to the fdt object.
* @param index Index of the entry to get.
* @param[out] entryOUT Entry at index.
* @retval ERR_NONE on success
* @retval ERR_BAD_ARG on nullptr args
* @retval ERR_NOT_VALID if the FDT is invalid
* @retval ERR_OUT_OF_BOUNDS if index is out of bounds or the Memory Reservation Block is malformed
*/
[[gnu::nonnull(3)]]
error_t dt_get_rsv_mem_entry(const fdt_t* fdt, u32 index, fdt_rsv_entry* entryOUT);

/// @}

#endif // !DT_DT
10 changes: 10 additions & 0 deletions src/example_dtree/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,14 @@ void main([[maybe_unused]] u32 hartid, const void* fdt) {
DEBUG_PRINTF("First prop: %s\n", prop_name);
error = dt_get_prop_name_ptr(&fdt_obj, next_prop, &prop_name);
DEBUG_PRINTF("Next prop: %s\n", prop_name);

fdt_rsv_entry entry;
error = dt_get_rsv_mem_entry(&fdt_obj, 0, &entry);

if (error != ERR_NONE) {
// To show that there's only one (terminating) entry in the rsvmap
DEBUG_PRINTF("%u %u\n", fdt_obj.rsvmap_off, fdt_obj.struct_off);
DEBUG_PRINTF("Failed to get reserved memory entry: %d\n", error);
return;
}
}
37 changes: 37 additions & 0 deletions src/lib/dt/dt_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,40 @@ error_t dt_get_prop_buffer(const fdt_t* fdt, dt_prop_t prop, buffer_t* bufOUT) {

return ERR_NONE;
}

error_t dt_get_rsv_mem_entry(const fdt_t* fdt, u32 index, fdt_rsv_entry* entryOUT) {
if (fdt == nullptr)
return ERR_BAD_ARG;

buffer_t fdt_buf = fdt->fdt_buffer;

u32 curr_index = 0;

u32 curr_offset = fdt->rsvmap_off;

u32 max_offset = fdt->struct_off + fdt->struct_size;
Comment thread
Kamilosok marked this conversation as resolved.
Outdated
fdt_rsv_entry entry;

do {
Comment thread
Kamilosok marked this conversation as resolved.
Outdated
if (!buffer_read_u64_be(fdt_buf, curr_offset, &entry.address) ||
!buffer_read_u64_be(fdt_buf, curr_offset + sizeof(u64), &entry.size)) {
return ERR_NOT_VALID;
}

if (entry.address == 0 && entry.size == 0) {
return ERR_OUT_OF_BOUNDS;
}

if (curr_index == index) {
entryOUT->address = entry.address;
Comment thread
Kamilosok marked this conversation as resolved.
Outdated
entryOUT->size = entry.size;
return ERR_NONE;
}

curr_index += 1;
curr_offset += 2 * sizeof(u64);
Comment thread
frogrammer9 marked this conversation as resolved.
Outdated

} while (curr_offset < max_offset);
Comment thread
Kamilosok marked this conversation as resolved.
Outdated

return ERR_OUT_OF_BOUNDS;
}
2 changes: 1 addition & 1 deletion src/lib/dt/dt_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define FDT_OFF_TOTAL_SIZE 0x04 /**< Offset to total size. */
#define FDT_OFF_OFF_DT_STRUCT 0x08 /**< Offset to structure block offset. */
#define FDT_OFF_OFF_DT_STRINGS 0x0C /**< Offset to strings block offset. */
#define FDT_OFF_MEM_RSVMAP 0x10 /**< Offset to memory reservation map. */
#define FDT_OFF_OFF_MEM_RSVMAP 0x10 /**< Offset to memory reservation map offset. */
Comment thread
Kamilosok marked this conversation as resolved.
#define FDT_OFF_VERSION 0x14 /**< Offset to version. */
#define FDT_OFF_LAST_COMP_VERSION 0x18 /**< Offset to last compatible version. */
#define FDT_OFF_BOOT_CPUID_PHYS 0x1C /**< Offset to boot CPU physical ID. */
Expand Down
3 changes: 2 additions & 1 deletion src/lib/dt/dt_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ error_t dt_init(const void* fdt, fdt_t* obj) {
if (!buffer_read_u32_be(fdt_buf, FDT_OFF_TOTAL_SIZE, &obj->total_size) ||
!buffer_read_u32_be(fdt_buf, FDT_OFF_OFF_DT_STRUCT, &obj->struct_off) ||
!buffer_read_u32_be(fdt_buf, FDT_OFF_OFF_DT_STRINGS, &obj->strings_off) ||
!buffer_read_u32_be(fdt_buf, FDT_OFF_OFF_MEM_RSVMAP, &obj->rsvmap_off) ||
!buffer_read_u32_be(fdt_buf, FDT_OFF_SIZE_DT_STRUCT, &obj->struct_size) ||
!buffer_read_u32_be(fdt_buf, FDT_OFF_VERSION, &obj->fdt_version) ||
!buffer_read_u32_be(fdt_buf, FDT_OFF_VERSION, &last_comp_version)) {
!buffer_read_u32_be(fdt_buf, FDT_OFF_LAST_COMP_VERSION, &last_comp_version)) {
obj->fdt_buffer = make_buffer(nullptr, 0);
return ERR_NOT_VALID;
}
Expand Down
Loading