Skip to content

Commit 3d9f5b8

Browse files
committed
Addressed most problems that appeared in the main repo
That includes actual null pointers, corrected the location of headers, some formatting, unnecessary copying of data, moved functions to more appropriate places, additional failsafes, and some additional access features
1 parent fbb4056 commit 3d9f5b8

15 files changed

Lines changed: 1848 additions & 1764 deletions

File tree

external/include/stb_sprintf.h

Lines changed: 1621 additions & 1648 deletions
Large diffs are not rendered by default.

include/drivers/dt/dt.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
#ifndef DT_H
22
#define DT_H
33

4-
#include <drivers/dt/dt_node.h>
54
#include <stdbigos/types.h>
65

7-
#define DT_ARENA_SIZE 16384
8-
9-
extern u8 dt_arena_buffer[DT_ARENA_SIZE];
10-
11-
// Root of the parsed device tree
12-
extern struct dt_node* root_node;
6+
struct dt_node;
7+
struct dt_prop;
138

149
// Initializes the device tree driver
1510
// TODO: Currently parses the entire FDT at init, maybe change to lazy parsing later
@@ -20,7 +15,16 @@ int dt_init(const void* fdt_blob, u32 blob_size);
2015
void dt_cleanup(void);
2116

2217
// Find a node by full path in the tree, dt_node ptr if success, nullptr if error
23-
struct dt_node* dt_find_node(const char* path);
18+
struct dt_node* dt_node_find(const char* path);
19+
20+
// Get a node's name, const char ptr name if success, nullptr if error
21+
const char* dt_node_get_name(const struct dt_node* node);
22+
23+
// Get node's child count, >=0 if success, <0 if error
24+
int dt_node_child_count(const struct dt_node* node);
25+
26+
// Get a node's index-th in order child, dt_node ptr if success, nullptr if error
27+
struct dt_node* dt_node_get_child(const struct dt_node* node, int index);
2428

2529
// Returns the pointer to the root of the parsed device tree if success, nullptr if error
2630
struct dt_node* dt_get_root(void);

include/drivers/dt/dt_props.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#ifndef DT_PROPS_H
22
#define DT_PROPS_H
33

4-
#include <drivers/dt/dt_node.h>
54
#include <stdbigos/types.h>
65

6+
struct dt_node;
7+
struct dt_prop;
8+
79
// Find a property of node by a name, dt_prop ptr if success, nullptr if error
810
struct dt_prop* dt_find_prop(const struct dt_node* node, const char* name);
911

@@ -33,4 +35,10 @@ int dt_prop_read_bool(const struct dt_node* node, const char* name);
3335
// Read a node's name phandle (a handle to a different node) and write it to out, 0 if success, -1 if error
3436
int dt_prop_read_phandle(const struct dt_node* node, const char* name, u32* out);
3537

38+
// Print the node's properties
39+
void dt_print_props(const struct dt_node* node, u8 depth);
40+
41+
// Print the entire subtree with properties
42+
void dt_print_tree(const struct dt_node* node, u8 depth);
43+
3644
#endif

include/stdbigos/bitutils.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef BITUTILS_H
2+
#define BITUTILS_H
3+
4+
#include <stdbigos/types.h>
5+
6+
// Reads a single 32-bit unsigned integer value from the specified address
7+
static inline u32 read_be32(const void* addr) {
8+
const u8* bytes = (const u8*)addr;
9+
return ((u32)bytes[0] << 24) | ((u32)bytes[1] << 16) | ((u32)bytes[2] << 8) | ((u32)bytes[3] << 0);
10+
};
11+
12+
// Reads a single 64-bit unsigned integer value from the specified address
13+
static inline u64 read_be64(const void* addr) {
14+
const u8* bytes = (const u8*)addr;
15+
return ((u64)bytes[0] << 56) | ((u64)bytes[1] << 48) | ((u64)bytes[2] << 40) | ((u64)bytes[3] << 32) |
16+
((u64)bytes[4] << 24) | ((u64)bytes[5] << 16) | ((u64)bytes[6] << 8) | ((u64)bytes[7] << 0);
17+
};
18+
19+
// Helper for aligning to 4 bytes
20+
static inline u32 align4(u32 off) {
21+
return (off + 3) & ~3u;
22+
}
23+
24+
// Helper for aligning to 8 bytes
25+
static inline u32 align8(u32 off) {
26+
return (off + 7) & ~7u;
27+
}
28+
29+
// Helper for aligning to 16 bytes
30+
static inline u32 align16(u32 off) {
31+
return (off + 15) & ~15u;
32+
}
33+
34+
// Helper for aligning to 32 bytes
35+
static inline u32 align32(u32 off) {
36+
return (off + 31) & ~31u;
37+
}
38+
39+
#endif

src/drivers/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
add_subdirectory(dt)
22

3-
SETUP_LIBRARY(drivers)
4-
target_link_libraries(drivers PRIVATE stdbigos)
3+
add_library(drivers INTERFACE)
4+
target_link_libraries(drivers INTERFACE dt)
5+
6+
target_include_directories(drivers
7+
INTERFACE
8+
${CMAKE_SOURCE_DIR}/include/drivers
9+
)

src/drivers/dt/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
SETUP_LIBRARY(dt)
22

3-
target_link_libraries(dt PRIVATE stdbigos)
3+
target_link_libraries(dt PRIVATE stdbigos)
4+
5+
6+
target_include_directories(dt
7+
PUBLIC
8+
${CMAKE_SOURCE_DIR}/include/drivers/dt # for dt.h / dt_props.h
9+
PRIVATE
10+
${CMAKE_CURRENT_SOURCE_DIR} # for dt_node.h, dt_alloc.h, dt_parser.h
11+
)

src/drivers/dt/dt_access.c

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
#include <drivers/dt/dt.h>
2-
#include <drivers/dt/dt_node.h>
3-
#include <drivers/dt/dt_parser.h>
4-
#include <drivers/dt/dt_props.h>
2+
#include <stdbigos/bitutils.h>
3+
#include <stdbigos/sbi.h>
54
#include <stdbigos/string.h>
65

6+
#include "dt_alloc.h"
7+
#include "dt_node.h"
8+
#include "dt_parser.h"
9+
10+
static void sbi_puts(const char* str) {
11+
while (*str) sbi_debug_console_write_byte(*str++);
12+
}
13+
14+
// There has to be a better way to do this
15+
static void gap(u8 size) {
16+
for (u8 i = 0; i < size; i++) sbi_puts("\t");
17+
}
18+
719
struct dt_node* dt_get_root(void) {
820
return root_node;
921
}
@@ -14,12 +26,12 @@ static struct dt_node* find_child_by_name(struct dt_node* parent, const char* na
1426
return child;
1527
}
1628
}
17-
return ((void*)0);
29+
return nullptr;
1830
}
1931

20-
struct dt_node* dt_find_node(const char* path) {
32+
struct dt_node* dt_node_find(const char* path) {
2133
if (!path || path[0] != '/' || !root_node)
22-
return ((void*)0);
34+
return nullptr;
2335

2436
if (strcmp(path, "/") == 0)
2537
return root_node;
@@ -37,32 +49,51 @@ struct dt_node* dt_find_node(const char* path) {
3749

3850
char segment[64];
3951
if (len >= (int)sizeof(segment))
40-
return ((void*)0);
52+
return nullptr;
4153

4254
memcpy(segment, p, len);
4355
segment[len] = '\0';
4456

4557
current = find_child_by_name(current, segment);
4658
if (!current)
47-
return ((void*)0);
59+
return nullptr;
4860

4961
p = (*slash == '/') ? slash + 1 : slash;
5062
}
5163

5264
return current;
5365
}
5466

67+
const char* dt_node_get_name(const struct dt_node* node) {
68+
if (!node)
69+
return nullptr;
70+
71+
return node->name;
72+
}
73+
74+
int dt_node_child_count(const struct dt_node* n) {
75+
int c = 0;
76+
for (struct dt_node* ch = n->first_child; ch; ch = ch->next_sibling) c++;
77+
return c;
78+
}
79+
80+
struct dt_node* dt_node_get_child(const struct dt_node* n, int idx) {
81+
struct dt_node* ch = n ? n->first_child : NULL;
82+
for (; ch && idx > 0; ch = ch->next_sibling, idx--);
83+
return ch;
84+
}
85+
5586
struct dt_prop* dt_find_prop(const struct dt_node* node, const char* name) {
5687
if (!node || !name)
57-
return ((void*)0);
88+
return nullptr;
5889

5990
for (struct dt_prop* prop = node->props; prop; prop = prop->next_prop) {
6091
if (strcmp(prop->name, name) == 0) {
6192
return prop;
6293
}
6394
}
6495

65-
return ((void*)0);
96+
return nullptr;
6697
}
6798

6899
int dt_prop_read_u32(const struct dt_node* node, const char* name, u32* out) {
@@ -84,11 +115,35 @@ int dt_prop_read_u64(const struct dt_node* node, const char* name, u64* out) {
84115
if (!prop || prop->data_length < 8 || !prop->value)
85116
return -1;
86117

87-
const u8* val = (const u8*)prop->value;
118+
u64 val = read_be64(prop->value);
88119

89-
u32 high = read_be32(val);
90-
u32 low = read_be32(val + 4);
120+
*out = val;
91121

92-
*out = ((u64)high << 32) | (u64)low;
93122
return 0;
94123
}
124+
125+
void dt_print_props(const struct dt_node* node, u8 depth) {
126+
struct dt_prop* next = node->props;
127+
while (next) {
128+
gap(depth);
129+
sbi_puts(next->name);
130+
sbi_puts("\n");
131+
next = next->next_prop;
132+
}
133+
}
134+
135+
void dt_print_tree(const struct dt_node* node, u8 depth) {
136+
gap(depth);
137+
sbi_puts("NODE: ");
138+
sbi_puts(node->name);
139+
sbi_puts("\n");
140+
gap(depth);
141+
sbi_puts("PROPERTIES:\n");
142+
dt_print_props(node, depth + 1);
143+
sbi_puts("\n");
144+
struct dt_node* next = node->first_child;
145+
while (next) {
146+
dt_print_tree(next, depth + 1);
147+
next = next->next_sibling;
148+
}
149+
}

src/drivers/dt/dt_alloc.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
1-
#include <drivers/dt/dt_alloc.h>
1+
#include "dt_alloc.h"
2+
3+
#include <stdbigos/bitutils.h>
24
#include <stdbigos/types.h>
35

6+
// Arena
7+
u8 dt_arena_buffer[DT_ARENA_SIZE];
8+
49
// Ptr to start of arena area
5-
static u32* arena_start = ((void*)0);
10+
static u32* arena_start = nullptr;
611

712
// Arena size in bytes
813
static u32 arena_size;
914

1015
// Used area size in bytes
1116
static u32 arena_offset;
1217

13-
// Helper for aligning to 4 bytes
14-
u32 align4(u32 off) {
15-
return (off + 3) & ~3u;
16-
}
17-
18-
// Helper for aligning to 32 bytes
19-
u32 align32(u32 off) {
20-
return (off + 31) & ~31u;
21-
}
22-
2318
int dt_arena_init(void* start, u32 size) {
24-
if (start == ((void*)0) || size == 0)
19+
if (start == nullptr || size == 0)
2520
return -1;
2621

2722
arena_start = (u32*)start;
@@ -32,23 +27,23 @@ int dt_arena_init(void* start, u32 size) {
3227
}
3328

3429
void* dt_alloc(u32 size) {
35-
// Idk if needed
30+
// May not be needed
3631
if (size == 0)
37-
return ((void*)0);
32+
return nullptr;
3833

3934
// Align to 4 bytes
4035
u32 align = align4(size);
4136

4237
if (arena_offset + align > arena_size)
43-
return ((void*)0);
38+
return nullptr;
4439

4540
void* new_block = arena_start + arena_offset;
4641
arena_offset += align;
4742

4843
return new_block;
4944
}
5045

46+
// Invalidates previously allocated blocks by ignoring them
5147
void dt_arena_reset(void) {
52-
// Invalidates previously allocated blocks by ignoring them
5348
arena_offset = 0;
5449
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
#include <stdbigos/types.h>
55

6+
#define DT_ARENA_SIZE 32760
7+
extern u8 dt_arena_buffer[DT_ARENA_SIZE];
8+
9+
extern struct dt_node* root_node;
10+
611
// Initialize the arena allocator with the start ptr at the start of the memory block of size bytes for allocations
712
int dt_arena_init(void* start, u32 size);
813

src/drivers/dt/dt_cleanup.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#include <drivers/dt/dt.h>
2-
#include <drivers/dt/dt_alloc.h>
2+
3+
#include "dt_alloc.h"
34

45
void dt_cleanup(void) {
56
dt_arena_reset();
67

7-
root_node = ((void*)0);
8+
root_node = nullptr;
89
}

0 commit comments

Comments
 (0)