1 #include <aros/macros.h>
2 #include "devicetree.h"
9 of_node_t
*root
= NULL
;
13 of_node_t
* dt_build_node(of_node_t
*parent
)
15 of_node_t
*e
= malloc(sizeof(of_node_t
));
21 ADDTAIL(&parent
->on_children
, e
);
23 NEWLIST(&e
->on_children
);
24 NEWLIST(&e
->on_properties
);
25 e
->on_name
= (char *)data
;
26 data
+= (strlen((char *)data
) + 4) / 4;
28 D(kprintf("[BOOT] new node %s\n", e
->on_name
));
32 switch (AROS_BE2LONG(*data
++))
42 of_property_t
*p
= malloc(sizeof(of_property_t
));
43 p
->op_length
= AROS_BE2LONG(*data
++);
44 p
->op_name
= &strings
[AROS_BE2LONG(*data
++)];
49 ADDTAIL(&e
->on_properties
, p
);
50 data
+= (p
->op_length
+ 3)/4;
51 D(kprintf("[BOOT] prop %s with length %d\n", p
->op_name
, p
->op_length
));
66 static struct fdt_header
*hdr
;
71 return AROS_BE2LONG(hdr
->totalsize
);
76 of_node_t
* dt_parse(void *dt
)
82 D(kprintf("[BOOT] Checking device tree at %p\n", hdr
));
83 D(kprintf("[BOOT] magic=%08x\n", AROS_LONG2BE(hdr
->magic
)));
85 if (hdr
->magic
== AROS_LONG2BE(FDT_MAGIC
))
87 D(kprintf("[BOOT] Appears to be a valid device tree\n"));
88 D(kprintf("[BOOT] size=%d\n", AROS_BE2LONG(hdr
->totalsize
)));
89 D(kprintf("[BOOT] off_dt_struct=%d\n", AROS_BE2LONG(hdr
->off_dt_struct
)));
90 D(kprintf("[BOOT] off_dt_strings=%d\n", AROS_BE2LONG(hdr
->off_dt_strings
)));
91 D(kprintf("[BOOT] off_mem_rsvmap=%d\n", AROS_BE2LONG(hdr
->off_mem_rsvmap
)));
93 strings
= dt
+ AROS_BE2LONG(hdr
->off_dt_strings
);
94 data
= dt
+ AROS_BE2LONG(hdr
->off_dt_struct
);
96 if (hdr
->off_mem_rsvmap
)
98 struct fdt_reserve_entry
*rsrvd
= dt
+ AROS_BE2LONG(hdr
->off_mem_rsvmap
);
100 while (rsrvd
->address
!= 0 || rsrvd
->size
!= 0) {
101 D(kprintf("[BOOT] reserved: %08x-%08x\n",
102 (uint32_t)AROS_BE2QUAD(rsrvd
->address
),
103 (uint32_t)(AROS_BE2QUAD(rsrvd
->address
) + AROS_BE2QUAD(rsrvd
->size
- 1)))
111 token
= AROS_BE2LONG(*data
++);
116 root
= dt_build_node(NULL
);
120 kprintf("[BOOT] Property outside root node?");
124 } while (token
!= FDT_END
);
134 static of_node_t
* dt_find_by_phandle(uint32_t phandle
, of_node_t
*root
)
136 of_property_t
*p
= dt_find_property(root
, "phandle");
138 if (p
&& *((uint32_t *)p
->op_value
) == AROS_LONG2BE(phandle
))
142 ForeachNode(&root
->on_children
, c
)
144 of_node_t
*found
= dt_find_by_phandle(phandle
, c
);
152 of_node_t
* dt_find_node_by_phandle(uint32_t phandle
)
154 return dt_find_by_phandle(phandle
, root
);
157 #define MAX_KEY_SIZE 64
160 of_node_t
* dt_find_node(char *key
)
163 of_node_t
*node
, *ret
= NULL
;
172 for (i
=0; i
< 63; i
++)
174 if (*key
== '/' || *key
== 0)
182 ForeachNode(&ret
->on_children
, node
)
184 if (!strcmp(node
->on_name
, ptrbuf
))
196 of_property_t
*dt_find_property(void *key
, char *propname
)
198 of_node_t
*node
= (of_node_t
*)key
;
199 of_property_t
*p
, *prop
= NULL
;
203 ForeachNode(&node
->on_properties
, p
)
205 if (!strcmp(p
->op_name
, propname
))
217 void dt_dump_node(of_node_t
*n
, int level
)
222 kprintf("[BOOT] %s%s\n", &fill
[25-2*level
], n
->on_name
);
223 ForeachNode(&n
->on_properties
, p
)
225 kprintf("[BOOT] %s %s=", &fill
[25-2*level
], p
->op_name
);
226 for (int i
=0; i
< p
->op_length
; i
++) {
227 char *pchar
= p
->op_value
+ i
;
228 if (*pchar
>= ' ' && *pchar
<= 'z')
229 kprintf("%c", *pchar
);
237 if (max
> p
->op_length
)
240 for (int i
=0; i
< p
->op_length
; i
++) {
241 char *pchar
= p
->op_value
+ i
;
242 kprintf("%02x", *pchar
);
249 ForeachNode(&n
->on_children
, c
)
251 dt_dump_node(c
, level
+1);
257 kprintf("[BOOT] Device Tree dump:\n");
259 dt_dump_node(root
, 0);