HelenOS sources
This source file includes following definitions.
- ofw_tree_node_alloc
- ofw_tree_properties_alloc
- ofw_tree_space_alloc
- ofw_tree_node_process
- ofw_tree_build
#include <genarch/ofw_tree.h>
#include <genarch/ofw.h>
#include <arch/ofw.h>
#include <stddef.h>
#include <str.h>
#include <balloc.h>
#include <mem.h>
static char path[OFW_TREE_PATH_MAX_LEN + 1];
static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
static ofw_tree_node_t *ofw_tree_node_alloc(void)
{
return balloc(sizeof(ofw_tree_node_t), sizeof(ofw_tree_node_t));
}
static ofw_tree_property_t *ofw_tree_properties_alloc(size_t count)
{
return balloc(count * sizeof(ofw_tree_property_t),
sizeof(ofw_tree_property_t));
}
static void *ofw_tree_space_alloc(size_t size)
{
char *addr = balloc(size + 1, 4);
if (addr)
addr[size] = '\0';
return addr;
}
static void ofw_tree_node_process(ofw_tree_node_t *current_node,
ofw_tree_node_t *parent_node, phandle current)
{
while (current_node) {
current_node->parent = (ofw_tree_node_t *) balloc_rebase(parent_node);
current_node->peer = NULL;
current_node->child = NULL;
current_node->node_handle = current;
current_node->properties = 0;
current_node->property = NULL;
current_node->device = NULL;
size_t len = ofw_package_to_path(current, path, OFW_TREE_PATH_MAX_LEN);
if (len == (size_t) -1)
return;
path[len] = '\0';
size_t i;
i = len;
while (i > 0 && path[i - 1] != '/')
i--;
len -= i;
char *da_name = ofw_tree_space_alloc(len + 1);
if (!da_name)
return;
memcpy(da_name, &path[i], len);
da_name[len] = '\0';
current_node->da_name = (char *) balloc_rebase(da_name);
phandle child = ofw_get_child_node(current);
if ((child != 0) && (child != (phandle) -1)) {
ofw_tree_node_t *child_node = ofw_tree_node_alloc();
if (child_node) {
ofw_tree_node_process(child_node, current_node,
child);
current_node->child =
(ofw_tree_node_t *) balloc_rebase(child_node);
}
}
name[0] = '\0';
while (ofw_next_property(current, name, name2) == 1) {
current_node->properties++;
memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
}
if (!current_node->properties)
return;
ofw_tree_property_t *property =
ofw_tree_properties_alloc(current_node->properties);
if (!property)
return;
name[0] = '\0';
for (i = 0; ofw_next_property(current, name, name2) == 1; i++) {
if (i == current_node->properties)
break;
memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
memcpy(property[i].name, name, OFW_TREE_PROPERTY_MAX_NAMELEN);
property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN - 1] = '\0';
size_t size = ofw_get_proplen(current, name);
property[i].size = size;
if (size) {
void *buf = ofw_tree_space_alloc(size);
if (buf) {
(void) ofw_get_property(current, name, buf, size);
property[i].value = balloc_rebase(buf);
}
} else
property[i].value = NULL;
}
current_node->properties = i;
current_node->property = (ofw_tree_property_t *) balloc_rebase(property);
phandle peer = ofw_get_peer_node(current);
if ((peer != 0) && (peer != (phandle) -1)) {
ofw_tree_node_t *peer_node = ofw_tree_node_alloc();
if (peer_node) {
current_node->peer = (ofw_tree_node_t *) balloc_rebase(peer_node);
current_node = peer_node;
current = peer;
continue;
}
}
break;
}
}
ofw_tree_node_t *ofw_tree_build(void)
{
ofw_tree_node_t *root = ofw_tree_node_alloc();
if (root)
ofw_tree_node_process(root, NULL, ofw_root);
phandle ssm_node = ofw_find_device("/ssm@0,0");
if (ssm_node != (phandle) -1) {
ofw_tree_node_t *ssm = ofw_tree_node_alloc();
if (ssm) {
ofw_tree_node_process(ssm, root,
ofw_find_device("/ssm@0,0"));
ssm->peer = root->child;
root->child = (ofw_tree_node_t *) balloc_rebase(ssm);
}
}
return (ofw_tree_node_t *) balloc_rebase(root);
}
HelenOS homepage, sources at GitHub