Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1894 → Rev 1895

/trunk/kernel/genarch/src/ofw/ofw_tree.c
35,5 → 35,120
*
*/
 
#include <genarch/ofw/ofw_tree.h>
#include <arch/memstr.h>
#include <func.h>
#include <print.h>
#include <panic.h>
 
#define PATH_MAX_LEN 80
#define NAME_BUF_LEN 50
 
static ofw_tree_node_t *ofw_root;
 
void ofw_tree_init(ofw_tree_node_t *root)
{
ofw_root = root;
}
 
/** Return value of the 'name' property.
*
* @param node Node of interest.
*
* @return Value of the 'name' property belonging to the node.
*/
const char *ofw_tree_node_name(const ofw_tree_node_t *node)
{
int i;
for (i = 0; i < node->properties; i++) {
if (strncmp(node->property[i].name, "name", strlen("name")) == 0) {
if (node->property[i].size < 2)
panic("Invalid name property.\n");
return node->property[i].value;
}
}
panic("Node without name property.\n");
}
 
/** Lookup child of given name.
*
* @param node Node whose child is being looked up.
* @param da_name Disambigued name of the child being looked up.
*
* @return NULL if there is no such child or pointer to the matching child node.
*/
static ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *da_name)
{
ofw_tree_node_t *cur;
for (cur = node->child; cur; cur = cur->peer) {
if (strncmp(cur->da_name, da_name, strlen(da_name)) == 0)
return cur;
}
return NULL;
}
 
/** Lookup OpenFirmware node by its path.
*
* @param path Path to the node.
*
* @return NULL if there is no such node or pointer to the leaf node.
*/
ofw_tree_node_t *ofw_tree_lookup(const char *path)
{
char buf[NAME_BUF_LEN+1];
ofw_tree_node_t *node = ofw_root;
index_t i, j;
if (path[0] != '/')
return NULL;
for (i = 1; i < strlen(path) && node; i = j + 1) {
for (j = i; j < strlen(path) && path[j] != '/'; j++)
;
if (i == j) /* skip extra slashes */
continue;
memcpy(buf, &path[i], j - i);
buf[j - i] = '\0';
node = ofw_tree_find_child(node, buf);
}
return node;
}
 
/** Recursively print subtree rooted in a node.
*
* @param node Root of the subtree.
* @param path Current path, NULL for the very root of the entire tree.
*/
static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path)
{
char p[PATH_MAX_LEN];
if (node->parent) {
snprintf(p, PATH_MAX_LEN, "%s/%s", path, node->da_name);
printf("%s\n", p);
} else {
snprintf(p, PATH_MAX_LEN, "%s", node->da_name);
printf("/\n");
}
 
if (node->child)
ofw_tree_node_print(node->child, p);
if (node->peer)
ofw_tree_node_print(node->peer, path);
}
 
/** Print the structure of the OpenFirmware device tree. */
void ofw_tree_print(void)
{
ofw_tree_node_print(ofw_root, NULL);
}
 
/** @}
*/