Skip to content

Commit 363eb7e

Browse files
committed
Improved encapsulation and logic
1 parent 89cc155 commit 363eb7e

17 files changed

Lines changed: 120 additions & 153 deletions

File tree

include/debug/debug_stdio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
void dputc(char c);
55
void dputs(const char* s);
6+
void dputgap(unsigned int gap_size);
67

78
[[gnu::format(printf, 1, 2)]]
89
void dprintf(const char* fmt, ...);
@@ -12,6 +13,7 @@ void dprintf(const char* fmt, ...);
1213
#define DEBUG_PUTC(c) dputc(c)
1314
#define DEBUG_PUTS(s) dputs(s)
1415
#define DEBUG_PRINTF(fmt, ...) dprintf(fmt __VA_OPT__(, ) __VA_ARGS__)
16+
#define DEBUG_PUTGAP(n) dputgap(n)
1517

1618
#else
1719

include/drivers/dt/dt.h

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

4+
#include <drivers/dt/dt_node.h>
45
#include <stdbigos/buffer.h>
56
#include <stdbigos/types.h>
67

7-
// I don't think there's an other way than a forward declaration
8-
typedef struct dt_node_t dt_node_t;
9-
typedef struct dt_prop_t dt_prop_t;
10-
118
// Initializes the device tree driver, the second argument specifies, whether the machine operates on big endian numbers
129
// natively
1310
// TODO: Currently parses the entire FDT at init, maybe change to lazy parsing later
1411
// Builds the actual tree structure handleable by the driver, 0 if success, <0 if error
15-
int dt_init(buffer_t fdt_buf, endianness_t machine_big_endian);
12+
int dt_init(const void* fdt, endianness_t machine_big_endian);
1613

1714
// Frees all memory used by the arena
1815
void dt_cleanup(void);
@@ -26,10 +23,12 @@ const char* dt_node_get_name(const dt_node_t* node);
2623
// Get node's child count, >=0 if success, <0 if error
2724
int dt_node_child_count(const dt_node_t* node);
2825

29-
// Get a node's index-th in order child, dt_node_t ptr if success, nullptr if error
30-
dt_node_t* dt_node_get_child(const dt_node_t* node, int index);
26+
// Get a node's next sibling, dt_node_t ptr if success, nullptr if error or node is the last child
27+
dt_node_t* dt_get_next_child(const dt_node_t* node);
3128

3229
// Returns the pointer to the root of the parsed device tree if success, nullptr if error
3330
dt_node_t* dt_get_root(void);
3431

32+
void dt_reset_root(void);
33+
3534
#endif

include/drivers/dt/dt_props.h

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

4+
#include <drivers/dt/dt_node.h>
45
#include <stdbigos/types.h>
56

6-
typedef struct dt_node_t dt_node_t;
7-
typedef struct dt_prop_t dt_prop_t;
8-
97
// Find a property of node by a name, dt_prop_t ptr if success, nullptr if error
108
dt_prop_t* dt_find_prop(const dt_node_t* node, const char* name);
119

include/stdbigos/buffer.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@ typedef struct buffer_t {
1414

1515
// Helper to create a buffer
1616
static inline buffer_t make_buffer(const void* data, size_t size) {
17-
buffer_t buf = {data, size};
17+
buffer_t buf = {.data = data, .size = size};
1818
return buf;
1919
}
2020

2121
// Read big-endian 32-bit from buffer at given offset
22-
int buffer_read_u32_be(const buffer_t* buf, size_t offset, u32* out);
22+
int buffer_read_u32_be(buffer_t buf, size_t offset, u32* out);
2323

2424
// Read big-endian 64-bit from buffer at given offset
25-
int buffer_read_u64_be(const buffer_t* buf, size_t offset, u64* out);
25+
int buffer_read_u64_be(buffer_t buf, size_t offset, u64* out);
2626

2727
// Read little-endian 32-bit from buffer at given offset
28-
int buffer_read_u32_le(const buffer_t* buf, size_t offset, u32* out);
28+
int buffer_read_u32_le(buffer_t buf, size_t offset, u32* out);
2929

3030
// Read little-endian 64-bit from buffer at given offset
31-
int buffer_read_u64_le(const buffer_t* buf, size_t offset, u64* out);
31+
int buffer_read_u64_le(buffer_t buf, size_t offset, u64* out);
3232

3333
// Read a zero-terminated C-string from buf at offset
34-
int buffer_read_cstring(const buffer_t* buf, size_t offset, const char** out_str);
34+
int buffer_read_cstring(buffer_t buf, size_t offset, const char** out_str);
3535

3636
#endif

src/drivers/dt/dt_access.c

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,12 @@
1+
#include <debug/debug_stdio.h>
12
#include <drivers/dt/dt.h>
3+
#include <drivers/dt/dt_node.h>
24
#include <stdbigos/bitutils.h>
3-
#include <stdbigos/sbi.h>
45
#include <stdbigos/string.h>
56

67
#include "dt_alloc.h"
7-
#include "dt_node.h"
88
#include "dt_parser.h"
99

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-
19-
dt_node_t* dt_get_root(void) {
20-
return root_node;
21-
}
22-
2310
static dt_node_t* find_child_by_name(dt_node_t* parent, const char* name) {
2411
for (dt_node_t* child = parent->first_child; child; child = child->next_sibling) {
2512
if (strcmp(child->name, name) == 0) {
@@ -30,6 +17,8 @@ static dt_node_t* find_child_by_name(dt_node_t* parent, const char* name) {
3017
}
3118

3219
dt_node_t* dt_node_find(const char* path) {
20+
dt_node_t* root_node = dt_get_root();
21+
3322
if (!path || path[0] != '/' || !root_node)
3423
return nullptr;
3524

@@ -77,10 +66,12 @@ int dt_node_child_count(const dt_node_t* n) {
7766
return c;
7867
}
7968

80-
dt_node_t* dt_node_get_child(const dt_node_t* n, int idx) {
81-
dt_node_t* ch = n ? n->first_child : NULL;
82-
for (; ch && idx > 0; ch = ch->next_sibling, idx--);
83-
return ch;
69+
dt_node_t* dt_get_next_child(const dt_node_t* node) {
70+
if (!node)
71+
return nullptr;
72+
73+
// If there's no next sibling, it will automatically return a nullptr, as per documentation
74+
return node->next_sibling;
8475
}
8576

8677
dt_prop_t* dt_find_prop(const dt_node_t* node, const char* name) {
@@ -125,22 +116,21 @@ int dt_prop_read_u64(const dt_node_t* node, const char* name, u64* out) {
125116
void dt_print_props(const dt_node_t* node, u8 depth) {
126117
dt_prop_t* next = node->props;
127118
while (next) {
128-
gap(depth);
129-
sbi_puts(next->name);
130-
sbi_puts("\n");
119+
DEBUG_PUTGAP(depth);
120+
DEBUG_PRINTF("%s\n", next->name);
131121
next = next->next_prop;
132122
}
133123
}
134124

125+
// Use only in debug preset
135126
void dt_print_tree(const dt_node_t* 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");
127+
DEBUG_PUTGAP(depth);
128+
DEBUG_PRINTF("NODE: %s\n", node->name);
129+
DEBUG_PUTGAP(depth);
130+
131+
DEBUG_PRINTF("PROPERTIES:\n");
142132
dt_print_props(node, depth + 1);
143-
sbi_puts("\n");
133+
DEBUG_PUTC('\n');
144134
dt_node_t* next = node->first_child;
145135
while (next) {
146136
dt_print_tree(next, depth + 1);

src/drivers/dt/dt_alloc.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <stdbigos/types.h>
66

77
// Arena proper
8-
u8 dt_arena_buffer[DT_ARENA_SIZE];
8+
static u8 dt_arena_buffer[DT_ARENA_SIZE];
99

1010
static u32* arena_start = nullptr;
1111

@@ -15,6 +15,10 @@ static u32 arena_size;
1515
// Used area size in bytes
1616
static u32 arena_offset;
1717

18+
u8* dt_get_arena_buffer(void) {
19+
return dt_arena_buffer;
20+
}
21+
1822
int dt_arena_init(void* start, u32 size) {
1923
if (start == nullptr || size == 0)
2024
return -1;

src/drivers/dt/dt_alloc.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#ifndef DT_ALLOC_H
22
#define DT_ALLOC_H
33

4+
#include <drivers/dt/dt_node.h>
45
#include <stdbigos/types.h>
56

6-
#include "dt_node.h"
7-
87
#define DT_ARENA_SIZE 32760
9-
extern u8 dt_arena_buffer[DT_ARENA_SIZE];
108

11-
extern dt_node_t* root_node;
9+
u8* dt_get_arena_buffer(void);
1210

1311
// Initialize the arena allocator with the start ptr at the start of the memory block of size bytes for allocations
1412
int dt_arena_init(void* start, u32 size);

src/drivers/dt/dt_cleanup.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@
44

55
void dt_cleanup(void) {
66
dt_arena_reset();
7-
8-
root_node = nullptr;
7+
dt_reset_root();
98
}

src/drivers/dt/dt_init.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
#include <drivers/dt/dt.h>
2+
#include <stdbigos/bitutils.h>
23
#include <stdbigos/buffer.h>
34
#include <stdbigos/types.h>
45

56
#include "dt_alloc.h"
67
#include "dt_parser.h"
78

8-
dt_node_t* root_node = nullptr;
9+
static dt_node_t* root_node = nullptr;
10+
11+
dt_node_t* dt_get_root(void) {
12+
return root_node;
13+
}
14+
15+
void dt_reset_root(void) {
16+
root_node = nullptr;
17+
}
918

1019
#define FDT_MAGIC 0xd00dfeed
1120
#define FDT_OFF_MAGIC 0x00
@@ -19,34 +28,40 @@ dt_node_t* root_node = nullptr;
1928
#define FDT_OFF_SIZE_DT_STRINGS 0x20
2029
#define FDT_OFF_SIZE_DT_STRUCT 0x24
2130

22-
// HACK: WARNING, the handling on big endian native machines not implemented, the second argument is ignored for now
23-
int dt_init(buffer_t fdt_buf, [[maybe_unused]] endianness_t machine_big_endian) {
24-
if (!fdt_buf.data || fdt_buf.size < (FDT_OFF_OFF_DT_STRINGS + 4))
31+
// TODO: implement reading dependent on endianness of the machine
32+
int dt_init(const void* fdt, [[maybe_unused]] endianness_t machine_big_endian) {
33+
u32 magic = read_be32(fdt);
34+
if (magic != FDT_MAGIC)
2535
return -1;
2636

27-
u32 magic;
28-
if (buffer_read_u32_be(&fdt_buf, 0, &magic) != BUFFER_OK || magic != FDT_MAGIC)
29-
return -2;
37+
u32 fdt_size = read_be32((u8*)fdt + 4);
38+
39+
buffer_t fdt_buf = make_buffer(fdt, fdt_size);
40+
41+
if (fdt_buf.size < (FDT_OFF_OFF_DT_STRINGS + 4))
42+
return -1;
3043

3144
u32 total_size;
32-
if (buffer_read_u32_be(&fdt_buf, FDT_OFF_TOTAL_SIZE, &total_size) != BUFFER_OK)
45+
if (buffer_read_u32_be(fdt_buf, FDT_OFF_TOTAL_SIZE, &total_size) != BUFFER_OK)
3346
return -2;
3447

3548
u32 struct_off;
36-
if (buffer_read_u32_be(&fdt_buf, FDT_OFF_OFF_DT_STRUCT, &struct_off) != BUFFER_OK)
49+
if (buffer_read_u32_be(fdt_buf, FDT_OFF_OFF_DT_STRUCT, &struct_off) != BUFFER_OK)
3750
return -2;
3851

3952
u32 strings_off;
40-
if (buffer_read_u32_be(&fdt_buf, FDT_OFF_OFF_DT_STRINGS, &strings_off) != BUFFER_OK)
53+
if (buffer_read_u32_be(fdt_buf, FDT_OFF_OFF_DT_STRINGS, &strings_off) != BUFFER_OK)
4154
return -2;
4255

4356
u32 struct_size;
44-
if (buffer_read_u32_be(&fdt_buf, FDT_OFF_SIZE_DT_STRUCT, &struct_size) != BUFFER_OK)
57+
if (buffer_read_u32_be(fdt_buf, FDT_OFF_SIZE_DT_STRUCT, &struct_size) != BUFFER_OK)
4558
return -2;
4659

4760
if (struct_off + struct_size > total_size)
4861
return -3;
4962

63+
u8* dt_arena_buffer = dt_get_arena_buffer();
64+
5065
if (dt_arena_init(dt_arena_buffer, DT_ARENA_SIZE) < 0)
5166
return -4;
5267

0 commit comments

Comments
 (0)