Skip to content

Commit 9212d26

Browse files
committed
Properties are now fetched through buffers
1 parent 363eb7e commit 9212d26

7 files changed

Lines changed: 41 additions & 59 deletions

File tree

include/debug/debug_stdio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void dprintf(const char* fmt, ...);
2323
#define DEBUG_PUTC(c)
2424
#define DEBUG_PUTS(s)
2525
#define DEBUG_PRINTF(fmt, ...) noop_printf(fmt __VA_OPT__(, ) __VA_ARGS__)
26+
#define DEBUG_PUTGAP(n)
2627

2728
#endif
2829
#endif

include/drivers/dt/dt_props.h

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,12 @@
44
#include <drivers/dt/dt_node.h>
55
#include <stdbigos/types.h>
66

7+
// Can be used to check for bool-type props
78
// Find a property of node by a name, dt_prop_t ptr if success, nullptr if error
89
dt_prop_t* dt_find_prop(const dt_node_t* node, const char* name);
910

10-
// Read a single 32-bit value from a node's name prop and write it to out, 0 if success, <0 if error
11-
int dt_prop_read_u32(const dt_node_t* node, const char* name, u32* out);
12-
13-
// Read a single 64-bit value from a node's name prop and write it to out, 0 if success, <0 if error
14-
int dt_prop_read_u64(const dt_node_t* node, const char* name, u64* out);
15-
16-
// Read a single 32-bit value from a node's name prop's id index and write it to out, 0 if success, <0 if error
17-
int dt_prop_read_by_id_u32(const dt_node_t* node, const char* name, u32 index, u32* out);
18-
19-
// Read an array of up to out_size node's name prop values and write them to out
20-
// number of successfully read values if success, <0 if error
21-
int dt_prop_read_array_u32(const dt_node_t* node, const char* name, u32 out[], u32 out_size);
22-
23-
// Read a null-terminated string from node's name prop, const char ptr if succes, nullptr if error
24-
const char* dt_prop_read_str(const dt_node_t* node, const char* name);
25-
26-
// Read an array of up to out_size node's name prop strings and write them to out
27-
// number of successfully read strings if success, <0 if error
28-
int dt_prop_read_array_str(const dt_node_t* node, const char* name, const char* out[], u32 out_size);
29-
30-
// Read a bool ean value of node's name prop, 1 if exists or prop empty, 0 if doesn't exist, -1 if error
31-
int dt_prop_read_bool(const dt_node_t* node, const char* name);
32-
33-
// Read a node's name phandle (a handle to a different node) and write it to out, 0 if success, -1 if error
34-
int dt_prop_read_phandle(const dt_node_t* node, const char* name, u32* out);
11+
// Get a buffer of node's name value, the buffer's BUFFER_ERROR field will have any potential errors
12+
buffer_t dt_prop_get_buffer(const dt_node_t* node, const char* name);
3513

3614
// Print the node's properties
3715
void dt_print_props(const dt_node_t* node, u8 depth);

include/stdbigos/buffer.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,26 @@
44
#include <stdbigos/types.h>
55

66
// Error codes
7-
#define BUFFER_OK 0
8-
#define BUFFER_OUT_OF_BOUNDS -1
7+
typedef enum : u32 {
8+
BUFFER_OK = 0,
9+
BUFFER_OUT_OF_BOUNDS = 1,
10+
BUFFER_FETCH_ERROR = 2
11+
} BUFFER_ERROR;
912

1013
typedef struct buffer_t {
1114
const void* data;
1215
size_t size;
16+
BUFFER_ERROR error;
1317
} buffer_t;
1418

15-
// Helper to create a buffer
19+
// Helpers to create buffers
1620
static inline buffer_t make_buffer(const void* data, size_t size) {
17-
buffer_t buf = {.data = data, .size = size};
21+
buffer_t buf = {.data = data, .size = size, .error = BUFFER_OK};
22+
return buf;
23+
}
24+
25+
static inline buffer_t make_buffer_err(const void* data, size_t size, BUFFER_ERROR error) {
26+
buffer_t buf = {.data = data, .size = size, .error = error};
1827
return buf;
1928
}
2029

src/drivers/dt/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ SETUP_LIBRARY(dt)
22

33
target_link_libraries(dt PRIVATE stdbigos)
44

5+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
6+
target_link_libraries(dt PRIVATE Debug)
7+
endif()
8+
59

610
target_include_directories(dt
711
PUBLIC

src/drivers/dt/dt_access.c

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <debug/debug_stdio.h>
22
#include <drivers/dt/dt.h>
33
#include <drivers/dt/dt_node.h>
4+
#include <drivers/dt/dt_props.h>
45
#include <stdbigos/bitutils.h>
56
#include <stdbigos/string.h>
67

@@ -87,30 +88,18 @@ dt_prop_t* dt_find_prop(const dt_node_t* node, const char* name) {
8788
return nullptr;
8889
}
8990

90-
int dt_prop_read_u32(const dt_node_t* node, const char* name, u32* out) {
91-
dt_prop_t* prop = dt_find_prop(node, name);
92-
93-
if (!prop || prop->data_length < 4 || !prop->value)
94-
return -1;
95-
96-
u32 val = read_be32(prop->value);
97-
98-
*out = val;
91+
buffer_t dt_prop_get_buffer(const dt_node_t* node, const char* name) {
92+
buffer_t buffer = make_buffer_err(nullptr, 0, BUFFER_FETCH_ERROR);
9993

100-
return 0;
101-
}
102-
103-
int dt_prop_read_u64(const dt_node_t* node, const char* name, u64* out) {
10494
dt_prop_t* prop = dt_find_prop(node, name);
95+
if (!prop || !prop->value)
96+
return buffer;
10597

106-
if (!prop || prop->data_length < 8 || !prop->value)
107-
return -1;
108-
109-
u64 val = read_be64(prop->value);
110-
111-
*out = val;
98+
buffer.data = prop->value;
99+
buffer.size = prop->data_length;
100+
buffer.error = BUFFER_OK;
112101

113-
return 0;
102+
return buffer;
114103
}
115104

116105
void dt_print_props(const dt_node_t* node, u8 depth) {

src/drivers/dt/dt_parser.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
#include "dt_alloc.h"
1010

1111
// FDT token values
12-
typedef enum FdtToken : u32 {
12+
typedef enum : u32 {
1313
FDT_BEGIN_NODE = 0x1,
1414
FDT_END_NODE = 0x2,
1515
FDT_PROP = 0x3,
1616
FDT_NOP = 0x4,
1717
// Unused/Reserved 0x5 - 0x8
1818
FDT_END = 0x9
19-
} FdtToken;
19+
} FDT_TOKEN;
2020

2121
// Function to parse a block of properties starting at props_offset with props_size size in the FDT with fdt
2222
// being a ptr to the start of the flattened device tree blob
@@ -31,7 +31,7 @@ dt_prop_t* parse_props(const buffer_t* fdt_buf, u32 props_offset, u32 props_size
3131
buffer_read_u32_be(*fdt_buf, curr_offset, &tag);
3232

3333
// Because of the separation of parsing properties and nodes, we don't want to parse non-properties
34-
if ((FdtToken)tag != FDT_PROP)
34+
if ((FDT_TOKEN)tag != FDT_PROP)
3535
break;
3636

3737
curr_offset += 4;
@@ -78,8 +78,7 @@ dt_node_t* parse_subtree(const buffer_t* fdt_buf, u32* offset, u32 max_offset, u
7878
u32 curr_offset = *offset;
7979

8080
u32 tag;
81-
82-
if (buffer_read_u32_be(*fdt_buf, curr_offset - 4, &tag) != BUFFER_OK || (FdtToken)tag != FDT_BEGIN_NODE)
81+
if (buffer_read_u32_be(*fdt_buf, curr_offset - 4, &tag) != BUFFER_OK || (FDT_TOKEN)tag != FDT_BEGIN_NODE)
8382
return nullptr;
8483

8584
const char* name;
@@ -98,7 +97,7 @@ dt_node_t* parse_subtree(const buffer_t* fdt_buf, u32* offset, u32 max_offset, u
9897
while (curr_offset < max_offset) {
9998
u32 tag;
10099
buffer_read_u32_be(*fdt_buf, curr_offset, &tag);
101-
if ((FdtToken)tag != FDT_PROP)
100+
if ((FDT_TOKEN)tag != FDT_PROP)
102101
break;
103102

104103
u32 p_len;
@@ -118,7 +117,7 @@ dt_node_t* parse_subtree(const buffer_t* fdt_buf, u32* offset, u32 max_offset, u
118117
buffer_read_u32_be(*fdt_buf, curr_offset, &tag);
119118

120119
curr_offset += 4;
121-
switch ((FdtToken)tag) {
120+
switch ((FDT_TOKEN)tag) {
122121
case FDT_BEGIN_NODE:
123122
dt_node_t* child = parse_subtree(fdt_buf, &curr_offset, max_offset, str_offset, node);
124123

src/example_dtree/entry.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ void main([[maybe_unused]] u32 hartid, const void* fdt) {
2626
} else {
2727
DEBUG_PRINTF("Found UART node: %s\n", dt_node_get_name(uart));
2828

29-
u64 base;
30-
if (dt_prop_read_u64(uart, "reg", &base) == 0) {
31-
DEBUG_PRINTF("UART base: %ld\n", base);
29+
buffer_t buffer = dt_prop_get_buffer(uart, "reg");
30+
if (buffer.error == BUFFER_OK) {
31+
// Or other easy conversion methods, up to user
32+
u64 val = read_be64(buffer.data);
33+
DEBUG_PRINTF("UART base: %lu\n", val);
3234
} else {
3335
DEBUG_PRINTF("\"reg\" prop missing or invalid\n");
3436
}

0 commit comments

Comments
 (0)