Skip to content

Commit

Permalink
dt_node_parent
Browse files Browse the repository at this point in the history
  • Loading branch information
Siguza committed Oct 12, 2024
1 parent f5258af commit 5d4695b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 9 deletions.
10 changes: 5 additions & 5 deletions src/drivers/dt/dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ int dt_check(void *mem, size_t size, size_t *offp)
return 0;
}

int dt_parse(dt_node_t *node, int depth, size_t *offp, int (*cb_node)(void*, dt_node_t*), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, size_t), void *cbp_arg)
int dt_parse(dt_node_t *node, int depth, size_t *offp, int (*cb_node)(void*, dt_node_t*, int), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, size_t), void *cbp_arg)
{
if(cb_node)
{
int r = cb_node(cbn_arg, node);
int r = cb_node(cbn_arg, node, depth);
if(r != 0) return r;
}
if(depth >= 0 || cb_prop)
Expand Down Expand Up @@ -198,7 +198,7 @@ typedef struct
size_t size;
} dt_arg_t;

static int dt_cbn(void *a, dt_node_t *node)
static int dt_cbn(void *a, dt_node_t *node, int depth)
{
if(a != node)
{
Expand Down Expand Up @@ -430,7 +430,7 @@ int dt_print(dt_node_t *node, int argc, const char **argv)
// ========== Legacy/Compat ==========

int dt_check_32(void *mem, uint32_t size, uint32_t *offp) __asm__("_dt_check$32");
int dt_parse_32(dt_node_t *node, int depth, uint32_t *offp, int (*cb_node)(void*, dt_node_t*), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, uint32_t), void *cbp_arg) __asm__("_dt_parse$32");
int dt_parse_32(dt_node_t *node, int depth, uint32_t *offp, int (*cb_node)(void*, dt_node_t*, int), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, uint32_t), void *cbp_arg) __asm__("_dt_parse$32");
void* dt_prop_32(dt_node_t *node, const char *key, uint32_t *lenp) __asm__("_dt_prop$32");

int dt_check_32(void *mem, uint32_t size, uint32_t *offp)
Expand All @@ -453,7 +453,7 @@ static int dt_parse_32_cbp(void *a, dt_node_t *node, int depth, const char *key,
return args->cb(args->arg, node, depth, key, val, (uint32_t)len);
}

int dt_parse_32(dt_node_t *node, int depth, uint32_t *offp, int (*cb_node)(void*, dt_node_t*), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, uint32_t), void *cbp_arg)
int dt_parse_32(dt_node_t *node, int depth, uint32_t *offp, int (*cb_node)(void*, dt_node_t*, int), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, uint32_t), void *cbp_arg)
{
dt_parse_32_cbp_t cbp_arg_32 =
{
Expand Down
5 changes: 3 additions & 2 deletions src/drivers/dt/dt.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* pongoOS - https://checkra.in
*
* Copyright (C) 2019-2023 checkra1n team
* Copyright (C) 2019-2024 checkra1n team
*
* This file is part of pongoOS.
*
Expand Down Expand Up @@ -49,7 +49,7 @@ typedef struct
} dt_prop_t;

extern int dt_check(void *mem, size_t size, size_t *offp) __asm__("_dt_check$64");
extern int dt_parse(dt_node_t *node, int depth, size_t *offp, int (*cb_node)(void*, dt_node_t*), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, size_t), void *cbp_arg) __asm__("_dt_parse$64");
extern int dt_parse(dt_node_t *node, int depth, size_t *offp, int (*cb_node)(void*, dt_node_t*, int), void *cbn_arg, int (*cb_prop)(void*, dt_node_t*, int, const char*, void*, size_t), void *cbp_arg) __asm__("_dt_parse$64");
extern dt_node_t* dt_find(dt_node_t *node, const char *name);
extern void* dt_prop(dt_node_t *node, const char *key, size_t *lenp) __asm__("_dt_prop$64");
extern int dt_print(dt_node_t *node, int argc, const char **argv);
Expand All @@ -65,6 +65,7 @@ struct memmap
};

extern dt_node_t* dt_node(dt_node_t *node, const char *name);
extern dt_node_t* dt_node_parent(dt_node_t *node);
extern dt_node_t* dt_get(const char *name);
extern void* dt_node_prop(dt_node_t *node, const char *prop, size_t *size);
extern void* dt_get_prop(const char *device, const char *prop, size_t *size) __asm__("_dt_get_prop$64");
Expand Down
42 changes: 41 additions & 1 deletion src/drivers/dt/dt_get.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* pongoOS - https://checkra.in
*
* Copyright (C) 2019-2023 checkra1n team
* Copyright (C) 2019-2024 checkra1n team
*
* This file is part of pongoOS.
*
Expand Down Expand Up @@ -41,6 +41,46 @@ dt_node_t* dt_node(dt_node_t *node, const char *name)
return dev;
}

typedef struct
{
dt_node_t *path[8];
dt_node_t *target;
dt_node_t *parent;
} dt_node_parent_cb_t;

static int dt_node_parent_cb(void *a, dt_node_t *node, int depth)
{
dt_node_parent_cb_t *arg = a;
if(node == arg->target)
{
if(depth < 1)
{
panic("DeviceTree parent depth underflow: %d", depth);
}
arg->parent = arg->path[depth - 1];
return 1;
}
if(depth < 0 || depth >= 8)
{
panic("DeviceTree parent depth out of bunds: %d", depth);
}
arg->path[depth] = node;
return 0;
}

dt_node_t* dt_node_parent(dt_node_t *node)
{
// Parsing the tree again just to find the parent node is really ugly and inefficient, but for now we're stuck with this.
// Ideally we'd parse the DeviceTree entirely into heap memory, so we can:
// a) traverse it faster and in either direction
// b) overwrite/relocate the original DeviceTree in memory (e.g. for loading a bigger kernel)
// The problem is that we currently allow clients to directly modify DeviceTree velues and we will need that
// in one form or another regardless, so we'd have to think about how to design such a writeback.
dt_node_parent_cb_t arg = { .target = node };
dt_parse(gDeviceTree, 0, NULL, &dt_node_parent_cb, &arg, NULL, NULL);
return arg.parent;
}

dt_node_t* dt_get(const char *name)
{
return dt_node(gDeviceTree, name);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/hal/hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct hal_device* gRootDevice, * gDeviceTreeDevice;

void hal_probe_hal_services(struct hal_device* device) ;

static int hal_load_dtree_child_node(void* arg, dt_node_t* node) {
static int hal_load_dtree_child_node(void* arg, dt_node_t* node, int depth) {
struct hal_device* parentDevice = arg;
if (parentDevice->node == node) return 0;

Expand Down

0 comments on commit 5d4695b

Please sign in to comment.