82 lines
2.2 KiB
C
82 lines
2.2 KiB
C
#include <errcode.h>
|
|
#include <dtb.h>
|
|
#include <utils.h>
|
|
#include <string.h>
|
|
#include <uart.h>
|
|
#include <kmalloc.h>
|
|
#include <vector.h>
|
|
|
|
void *dtb_addr;
|
|
|
|
void fdt_callback(const char *path, const vector_t *cbs, const vector_t *props)
|
|
{
|
|
for (int i = 0; i < (int)cbs->size; ++i)
|
|
if (!strcmp(path, VEC_AT(fdt_callback_t, cbs, i)->name))
|
|
VEC_AT(fdt_callback_t, cbs, i)->func(props);
|
|
}
|
|
|
|
uint32_t *fdt_struct_cur;
|
|
|
|
#define nextnode(ptr) (void *)((((uint64_t)(ptr) >> 2) + 1) << 2)
|
|
void traverse(const char *path, const vector_t *cbs)
|
|
{
|
|
vector_t *props = make_vector(0);
|
|
|
|
fdt_prop_t *prop;
|
|
const fdt_prop_header_t *prop_header;
|
|
const char *fdt_node_path = 0x0;
|
|
|
|
for (;;) {
|
|
fdt_struct_cur = ALIGN4(fdt_struct_cur);
|
|
|
|
switch (ntoh32(*fdt_struct_cur)) {
|
|
case FDT_BEGIN_NODE:
|
|
BUMP(uint32_t, uint32_t, fdt_struct_cur);
|
|
fdt_node_path = (void *)fdt_struct_cur;
|
|
do {
|
|
BUMP(uint32_t, char, fdt_struct_cur);
|
|
} while (*(char *)fdt_struct_cur != '\0');
|
|
BUMP(uint32_t, char, fdt_struct_cur); // '\0'
|
|
|
|
fdt_struct_cur = ALIGN4(fdt_struct_cur);
|
|
traverse(fdt_node_path, cbs);
|
|
break;
|
|
case FDT_END_NODE:
|
|
fdt_struct_cur = nextnode(fdt_struct_cur);
|
|
goto traverse_callback;
|
|
case FDT_PROP:
|
|
BUMP(uint32_t, uint32_t, fdt_struct_cur);
|
|
prop_header = BUMP(uint32_t, fdt_prop_header_t, fdt_struct_cur);
|
|
|
|
prop = kmalloc(sizeof(fdt_prop_t));
|
|
prop->len = ntoh32(prop_header->len);
|
|
prop->name = dtb_addr +
|
|
ntoh32(((fdt_header_t *)dtb_addr)->off_dt_strings) +
|
|
ntoh32(prop_header->nameoff);
|
|
prop->value = (void *)fdt_struct_cur;
|
|
VEC_PUSH(props, prop);
|
|
|
|
fdt_struct_cur = (void *)((uint64_t)fdt_struct_cur +
|
|
ntoh32(prop_header->len));
|
|
fdt_struct_cur = ALIGN4(fdt_struct_cur);
|
|
break;
|
|
case FDT_NOP:
|
|
fdt_struct_cur = nextnode(fdt_struct_cur);
|
|
break;
|
|
case FDT_END:
|
|
return;
|
|
default:
|
|
exit(ERR_UNREACHABLE);
|
|
}
|
|
}
|
|
traverse_callback:
|
|
fdt_callback(path, cbs, props);
|
|
}
|
|
|
|
void fdt_traverse(const vector_t *cbs)
|
|
{
|
|
fdt_struct_cur = dtb_addr + ntoh32(((fdt_header_t *)dtb_addr)->off_dt_struct);
|
|
|
|
traverse("", cbs);
|
|
}
|