Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1894 → Rev 1895

/trunk/kernel/genarch/include/ofw/ofw_tree.h
30,6 → 30,7
#define KERN_OFW_TREE_H_
 
#include <arch/types.h>
#include <typedefs.h>
 
#define OFW_TREE_PROPERTY_MAX_NAMELEN 32
 
42,7 → 43,9
ofw_tree_node_t *peer;
ofw_tree_node_t *child;
 
unsigned properties; /**< Number of properties. */
char *da_name; /**< Disambigued name. */
 
unsigned properties; /**< Number of properties. */
ofw_tree_property_t *property;
};
 
53,4 → 56,9
void *value;
};
 
extern void ofw_tree_init(ofw_tree_node_t *root);
extern void ofw_tree_print(void);
extern const char *ofw_tree_node_name(const ofw_tree_node_t *node);
extern ofw_tree_node_t *ofw_tree_lookup(const char *path);
 
#endif
/trunk/kernel/genarch/Makefile.inc
92,5 → 92,5
## OpenFirmware Device Tree
ifeq ($(CONFIG_OFW_TREE), y)
GENARCH_SOURCES += \
genarch/src/ofw/ofw_tree,c
genarch/src/ofw/ofw_tree.c
endif
/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);
}
 
/** @}
*/
/trunk/kernel/arch/sparc64/Makefile.inc
60,7 → 60,11
 
CONFIG_FB = y
 
## Compile with support for OpenFirmware device tree.
#
 
CONFIG_OFW_TREE = y
 
ifeq ($(MACHINE),enterprise)
## Compile with support for z8530 controller.
#
/trunk/kernel/arch/sparc64/src/sparc64.c
45,6 → 45,7
#include <arch/asm.h>
#include <arch/mm/page.h>
#include <arch/stack.h>
#include <genarch/ofw/ofw_tree.h>
#include <userspace.h>
 
bootinfo_t bootinfo;
64,6 → 65,8
/* Copy boot allocations info. */
ballocs.base = bootinfo.ballocs.base;
ballocs.size = bootinfo.ballocs.size;
ofw_tree_init(bootinfo.ofw_root);
}
 
void arch_pre_mm_init(void)
/trunk/boot/genarch/ofw_tree.h
43,6 → 43,8
ofw_tree_node_t *peer;
ofw_tree_node_t *child;
 
char *da_name; /**< Disambigued name. */
 
unsigned properties; /**< Number of properties. */
ofw_tree_property_t *property;
};
/trunk/boot/genarch/ofw.h
102,7 → 102,7
 
extern void ofw_write(const char *str, const int len);
 
extern int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen);
extern int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen);
extern int ofw_get_proplen(const phandle device, const char *name);
extern int ofw_next_property(const phandle device, char *previous, char *buf);
 
110,6 → 110,8
extern phandle ofw_get_peer_node(const phandle node);
extern phandle ofw_find_device(const char *name);
 
extern int ofw_package_to_path(const phandle device, char *buf, const int buflen);
 
extern int ofw(ofw_args_t *arg);
extern unsigned int ofw_get_address_cells(const phandle device);
extern unsigned int ofw_get_size_cells(const phandle device);
/trunk/boot/genarch/ofw_tree.c
31,7 → 31,10
#include <types.h>
#include <string.h>
#include <balloc.h>
#include <asm.h>
 
#define MAX_PATH_LEN 256
 
static ofw_tree_node_t *ofw_tree_node_alloc(void)
{
return balloc(sizeof(ofw_tree_node_t), sizeof(ofw_tree_node_t));
61,10 → 64,13
static void ofw_tree_node_process(ofw_tree_node_t *current_node,
ofw_tree_node_t *parent_node, phandle current)
{
static char path[MAX_PATH_LEN+1];
static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
phandle peer;
phandle child;
unsigned properties = 0;
char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
size_t len;
int i;
 
/*
* Initialize node.
76,6 → 82,26
current_node->property = NULL;
/*
* Get the disambigued name.
*/
len = ofw_package_to_path(current, path, MAX_PATH_LEN);
if (len == -1)
return;
path[len] = '\0';
for (i = len - 1; i >= 0 && path[i] != '/'; i--)
;
i++; /* do not include '/' */
len -= i;
current_node->da_name = ofw_tree_space_alloc(len + 1); /* add space for trailing '\0' */
if (!current_node->da_name)
return;
memcpy(current_node->da_name, &path[i], len);
current_node->da_name[len] = '\0';
/*
* Recursively process the potential peer node.
*/
peer = ofw_get_peer_node(current);
84,7 → 110,7
peer_node = ofw_tree_node_alloc();
if (peer_node) {
ofw_tree_node_process(peer_node, current_node, peer);
ofw_tree_node_process(peer_node, parent_node, peer);
current_node->peer = peer_node;
}
}
120,8 → 146,6
if (!current_node->property)
return;
int i = 0;
 
name[0] = '\0';
for (i = 0; ofw_next_property(current, name, name) == 1; i++) {
size_t size;
/trunk/boot/genarch/ofw.c
114,7 → 114,7
return ofw_call("finddevice", 1, 1, NULL, name);
}
 
int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen)
int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen)
{
return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen);
}
129,6 → 129,11
return ofw_call("nextprop", 3, 1, NULL, device, previous, buf);
}
 
int ofw_package_to_path(const phandle device, char *buf, const int buflen)
{
return ofw_call("package-to-path", 3, 1, NULL, device, buf, buflen);
}
 
unsigned int ofw_get_address_cells(const phandle device)
{
unsigned int ret = 1;