11#include "dt_parser.h"
22
33#include <stdbigos/bitutils.h>
4+ #include <stdbigos/buffer.h>
45#include <stdbigos/string.h>
56#include <stdbigos/types.h>
67
1617
1718// Function to parse a block of properties starting at props_offset with props_size size in the FDT with fdt
1819// being a ptr to the start of the flattened device tree blob
19- struct dt_prop * parse_props (const void * fdt , u32 props_offset , u32 props_size , u32 str_offset ) {
20+ struct dt_prop * parse_props (buffer_t * fdt_buf , u32 props_offset , u32 props_size , u32 str_offset ) {
2021 u32 curr_offset = props_offset ;
21- const u8 * fdt_u8 = ( const u8 * ) fdt ;
22+
2223 struct dt_prop * head = nullptr ;
2324 struct dt_prop * * pp = & head ;
2425
2526 while (curr_offset < props_offset + props_size ) {
26- u32 tag = read_be32 (fdt_u8 + curr_offset );
27+ u32 tag ;
28+ buffer_read_u32_be (fdt_buf , curr_offset , & tag );
2729
2830 // Because of the separation of parsing properties and nodes, we don't want to parse non-properties
2931 if (tag != FDT_PROP )
3032 break ;
3133
3234 curr_offset += 4 ;
33- u32 len = read_be32 (fdt_u8 + curr_offset );
35+ u32 len ;
36+ buffer_read_u32_be (fdt_buf , curr_offset , & len );
3437 curr_offset += 4 ;
35- u32 name_offset = read_be32 (fdt_u8 + curr_offset );
38+ u32 name_offset ;
39+ buffer_read_u32_be (fdt_buf , curr_offset , & name_offset );
3640 curr_offset += 4 ;
3741 struct dt_prop * new_prop = dt_alloc (sizeof (* new_prop ));
3842 new_prop -> data_length = len ;
3943 new_prop -> next_prop = nullptr ;
4044
41- new_prop -> name = ( const char * )( fdt_u8 + str_offset + name_offset );
45+ buffer_read_cstring ( fdt_buf , str_offset + name_offset , & new_prop -> name );
4246 // sbi_puts(new_prop->name);
4347 // sbi_puts("\n");
4448
45- new_prop -> value = fdt_u8 + curr_offset ;
49+ // Forced
50+ new_prop -> value = (const u8 * )fdt_buf -> data + curr_offset ;
4651
4752 // At first it sets the head in the right place, then it sets the next_prop of the previous property to point to
4853 // the current property
4954 * pp = new_prop ;
5055 pp = & new_prop -> next_prop ;
5156
52- curr_offset = align4 (curr_offset + len );
57+ curr_offset = alignN (curr_offset + len , 4 );
5358 }
5459 return head ;
5560}
5661
5762// Function to recursively parse a subtree at the given offset
58- struct dt_node * parse_subtree (const void * fdt , u32 * offset , u32 max_offset , u32 str_offset , struct dt_node * parent ) {
59- const u8 * fdt_u8 = (const u8 * )fdt ;
63+ struct dt_node * parse_subtree (buffer_t * fdt_buf , u32 * offset , u32 max_offset , u32 str_offset , struct dt_node * parent ) {
6064 struct dt_node * node = dt_alloc (sizeof (* node ));
6165
6266 if (!node )
@@ -70,44 +74,50 @@ struct dt_node* parse_subtree(const void* fdt, u32* offset, u32 max_offset, u32
7074
7175 u32 curr_offset = * offset ;
7276
73- if (read_be32 (fdt_u8 + curr_offset - 4 ) != FDT_BEGIN_NODE ) {
74- return nullptr ;
75- }
77+ u32 tag ;
7678
77- const char * name = (const char * )(fdt_u8 + curr_offset );
79+ if (buffer_read_u32_be (fdt_buf , curr_offset - 4 , & tag ) != BUFFER_OK || tag != FDT_BEGIN_NODE )
80+ return nullptr ;
7881
79- if (!name )
82+ const char * name ;
83+ if (buffer_read_cstring (fdt_buf , curr_offset , & name ) != BUFFER_OK )
8084 return nullptr ;
8185
86+ // After this point all reads from the buffer should be correct
87+
8288 u32 name_len = strlen (name ) + 1 ;
8389
8490 node -> name = name ;
8591
86- curr_offset = align4 (curr_offset + name_len );
92+ curr_offset = alignN (curr_offset + name_len , 4 );
8793
8894 u32 props_off = curr_offset ;
8995 while (curr_offset < max_offset ) {
90- u32 tag = read_be32 (fdt_u8 + curr_offset );
96+ u32 tag ;
97+ buffer_read_u32_be (fdt_buf , curr_offset , & tag );
9198 if (tag != FDT_PROP )
9299 break ;
93- u32 p_len = read_be32 (fdt_u8 + curr_offset + 4 );
100+
101+ u32 p_len ;
102+ buffer_read_u32_be (fdt_buf , curr_offset + 4 , & p_len );
94103
95104 curr_offset += 12 ; // Skip tag, length, name_offset
96- curr_offset = align4 (curr_offset + p_len );
105+ curr_offset = alignN (curr_offset + p_len , 4 );
97106 }
98-
99107 u32 props_len = curr_offset - props_off ;
100108
101- node -> props = parse_props (fdt , props_off , props_len , str_offset );
109+ node -> props = parse_props (fdt_buf , props_off , props_len , str_offset );
102110
103- curr_offset = align4 (props_off + props_len );
111+ curr_offset = alignN (props_off + props_len , 4 );
104112
105113 while (curr_offset < max_offset ) {
106- u32 tag = read_be32 (fdt_u8 + curr_offset );
114+ u32 tag ;
115+ buffer_read_u32_be (fdt_buf , curr_offset , & tag );
116+
107117 curr_offset += 4 ;
108118 switch (tag ) {
109119 case FDT_BEGIN_NODE :
110- struct dt_node * child = parse_subtree (fdt , & curr_offset , max_offset , str_offset , node );
120+ struct dt_node * child = parse_subtree (fdt_buf , & curr_offset , max_offset , str_offset , node );
111121
112122 if (child ) {
113123 if (!node -> first_child )
0 commit comments