common flatdevtree code
Mark A. Greer
mgreer at mvista.com
Fri Sep 8 10:56:31 EST 2006
Hollis, Paul,
I made some more changes that I hope you approve of:
- Added a hdr to the file to try to make it clear that people should
not hack the local copy of the file.
- Fixed a booboo (typo) in my last patch
- Change the interface to ft_next() to pass a struct that contains the
pointers that it sets up. Also moved the p_strings & version code
from the caller to ft_next(). Now, just pass in a NULL value to the
'p' param to start at the top of the tree.
- Cleaned up the callers to ft_next(). I think its much cleaner now.
Mark
--
--- flatdevtree.c 2006-09-07 15:34:39.000000000 -0700
+++ flatdevtree.c.new 2006-09-07 17:40:24.000000000 -0700
@@ -1,4 +1,11 @@
/*
+ * DO NOT EDIT THIS FILE!!
+ *
+ * The master copy is kept in a mercurial repository that you can clone:
+ * "hg clone http://unsanctioned.org/flatdevtree/hgweb.py flatdevtree"
+ * Please send patches to Hollis Blanchard <hollisb at us.ibm.com> and
+ * CC: <Linuxppc-dev at ozlabs.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,7 +22,7 @@
*
* Copyright Pantelis Antoniou 2006
* Copyright (C) IBM Corporation 2006
- * 2006 (c) MontaVista, Software, Inc.
+ * 2006 (c) MontaVista Software, Inc.
*
* Authors: Pantelis Antoniou <pantelis at embeddedalley.com>
* Hollis Blanchard <hollisb at us.ibm.com>
@@ -24,29 +31,42 @@
#include "flatdevtree.h"
+struct ft_entity {
+ u32 *tagp; /* Ptr to tag field */
+ char *name; /* Name of node or property; else NULL */
+ char *datap; /* Ptr to data, if property; else NULL */
+ u32 *sizep; /* Ptr to propery size; else NULL */
+};
+
/* Set ptrs to current one's info; return addr of next one */
-static u32 *ft_next(u32 *p, const u32 *p_strings, const u32 version,
- u32 **tagpp, char **namepp, char **datapp, u32 **sizepp)
+static u32 *ft_next(u32 *p, const void *bphp, struct ft_entity *ftep)
{
+ const struct boot_param_header *bph = bphp;
+ const u32 *p_strings = (const u32 *)
+ ((const char *)bph + be32_to_cpu(bph->off_dt_strings));
+ const u32 version = be32_to_cpu(bph->version);
u32 sz;
- *namepp = NULL;
- *datapp = NULL;
- *sizepp = NULL;
- *tagpp = p;
+ if (p == NULL) /* Start at top of tree */
+ p = (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_struct));
+
+ ftep->name = NULL;
+ ftep->datap = NULL;
+ ftep->sizep = NULL;
+ ftep->tagp = p;
switch (be32_to_cpu(*p++)) { /* Tag */
case OF_DT_BEGIN_NODE:
- *namepp = (char *)p;
+ ftep->name = (char *)p;
p = (u32 *)_ALIGN((unsigned long)p + strlen((char *)p) + 1, 4);
break;
case OF_DT_PROP:
sz = be32_to_cpu(*p);
- *sizepp = p++;
- *namepp = (char *)p_strings + be32_to_cpu(*p++);
+ ftep->sizep = p++;
+ ftep->name = (char *)p_strings + be32_to_cpu(*p++);
if ((version < 0x10) && (sz >= 8))
p = (u32 *)_ALIGN((unsigned long)p, 8);
- *datapp = (char *)p;
+ ftep->datap = (char *)p;
p = (u32 *)_ALIGN((unsigned long)p + sz, 4);
break;
case OF_DT_END_NODE:
@@ -371,13 +391,8 @@ void ft_dump_blob(const void *bphp)
const struct boot_param_header *bph = bphp;
const u64 *p_rsvmap = (const u64 *)
((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
- const u32 *p_struct = (const u32 *)
- ((const char *)bph + be32_to_cpu(bph->off_dt_struct));
- const u32 *p_strings = (const u32 *)
- ((const char *)bph + be32_to_cpu(bph->off_dt_strings));
- const u32 version = be32_to_cpu(bph->version);
- u32 i, *p, *tagp, *sizep;
- char *namep, *datap;
+ struct ft_entity fte;
+ u32 i, *p;
int depth, shift;
u64 addr, size;
@@ -399,12 +414,11 @@ void ft_dump_blob(const void *bphp)
printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size);
}
- p = (u32 *)p_struct;
- while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
- &sizep)) != NULL)
- switch (be32_to_cpu(*tagp)) {
+ p = NULL;
+ while ((p = ft_next(p, bphp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
case OF_DT_BEGIN_NODE:
- printf("%*s%s {\n", depth * shift, "", namep);
+ printf("%*s%s {\n", depth * shift, "", fte.name);
depth++;
break;
case OF_DT_END_NODE:
@@ -417,13 +431,13 @@ void ft_dump_blob(const void *bphp)
case OF_DT_END:
break;
case OF_DT_PROP:
- printf("%*s%s", depth * shift, "", namep);
- print_data(datap, *sizep);
+ printf("%*s%s", depth * shift, "", fte.name);
+ print_data(fte.datap, *fte.sizep);
printf(";\n");
break;
default:
fprintf(stderr, "%*s ** Unknown tag 0x%08x\n",
- depth * shift, "", *tagp);
+ depth * shift, "", *fte.tagp);
return;
}
}
@@ -439,13 +453,8 @@ void ft_backtrack_node(struct ft_cxt *cx
/* note that the root node of the blob is "peeled" off */
void ft_merge_blob(struct ft_cxt *cxt, void *blob)
{
- struct boot_param_header *bph = (struct boot_param_header *)blob;
- u32 *p_struct = (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));
- u32 *p_strings =
- (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));
- const u32 version = be32_to_cpu(bph->version);
- u32 *p, *tagp, *sizep;
- char *namep, *datap;
+ struct ft_entity fte;
+ u32 *p;
int depth;
if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)
@@ -454,13 +463,12 @@ void ft_merge_blob(struct ft_cxt *cxt, v
cxt->p -= 4;
depth = 0;
- p = p_struct;
- while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
- &sizep)) != NULL)
- switch (be32_to_cpu(*tagp)) {
+ p = NULL;
+ while ((p = ft_next(p, blob, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
case OF_DT_BEGIN_NODE:
if (depth++ > 0)
- ft_begin_node(cxt, namep);
+ ft_begin_node(cxt, fte.name);
break;
case OF_DT_END_NODE:
ft_end_node(cxt);
@@ -468,7 +476,7 @@ void ft_merge_blob(struct ft_cxt *cxt, v
return;
break;
case OF_DT_PROP:
- ft_prop(cxt, namep, datap, *sizep);
+ ft_prop(cxt, fte.name, fte.datap, *fte.sizep);
break;
}
}
@@ -477,24 +485,18 @@ void ft_merge_blob(struct ft_cxt *cxt, v
void *ft_find_node(const void *bphp, const char *srch_path)
{
- const struct boot_param_header *bph = bphp;
- u32 *p_struct = (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_struct));
- u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
- u32 version = be32_to_cpu(bph->version);
- u32 *p, *tagp, *sizep;
- char *namep, *datap;
+ struct ft_entity fte;
+ u32 *p;
static char path[MAX_PATH_LEN];
path[0] = '\0';
- p = p_struct;
-
- while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
- &sizep)) != NULL)
- switch (be32_to_cpu(*tagp)) {
+ p = NULL;
+ while ((p = ft_next(p, bphp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
case OF_DT_BEGIN_NODE:
- strcat(path, namep);
+ strcat(path, fte.name);
if (!strcmp(path, srch_path))
- return tagp;
+ return fte.tagp;
strcat(path, "/");
break;
case OF_DT_END_NODE:
@@ -507,26 +509,21 @@ void *ft_find_node(const void *bphp, con
int ft_get_prop(const void *bphp, const void *node, const char *propname,
void *buf, const unsigned int buflen)
{
- const struct boot_param_header *bph = bphp;
- u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
- u32 version = be32_to_cpu(bph->version);
- u32 *p, *tagp, *sizep, size;
- char *namep, *datap;
+ struct ft_entity fte;
+ u32 *p, size;
int depth;
depth = 0;
p = (u32 *)node;
-
- while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
- &sizep)) != NULL)
- switch (be32_to_cpu(*tagp)) {
+ while ((p = ft_next(p, bphp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
case OF_DT_BEGIN_NODE:
depth++;
break;
case OF_DT_PROP:
- if ((depth == 1) && !strcmp(namep, propname)) {
- size = min(be32_to_cpu(*sizep), (u32)buflen);
- memcpy(buf, datap, size);
+ if ((depth == 1) && !strcmp(fte.name, propname)) {
+ size = min(be32_to_cpu(*fte.sizep),(u32)buflen);
+ memcpy(buf, fte.datap, size);
return size;
}
break;
@@ -562,7 +559,7 @@ static void ft_modify_prop(void **bphpp,
old_tailp = (u32 *)(datap + old_prop_data_len);
new_total_size = head_len + new_prop_data_len + tail_len;
- if (!(new_bph = malloc(new_total_size))) {
+ if (!(new_bph = ft_malloc(new_total_size))) {
printf("Can't alloc space for new ft\n");
ft_exit(-ENOSPC);
}
@@ -604,27 +601,22 @@ static void ft_modify_prop(void **bphpp,
int ft_set_prop(void **bphpp, const void *node, const char *propname,
const void *buf, const unsigned int buflen)
{
- struct boot_param_header *bph = *bphpp;
- u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));
- u32 version = be32_to_cpu(bph->version);
- u32 *p, *tagp, *sizep;
- char *namep, *datap;
+ struct ft_entity fte;
+ u32 *p;
int depth;
depth = 0;
p = (u32 *)node;
-
- while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,
- &sizep)) != NULL)
- switch (be32_to_cpu(*tagp)) {
+ while ((p = ft_next(p, *bphpp, &fte)) != NULL)
+ switch (be32_to_cpu(*fte.tagp)) {
case OF_DT_BEGIN_NODE:
depth++;
break;
case OF_DT_PROP:
- if ((depth == 1) && !strcmp(namep, propname)) {
- ft_modify_prop(bphpp, datap, sizep, buf,
+ if ((depth == 1) && !strcmp(fte.name, propname)) {
+ ft_modify_prop(bphpp, fte.datap, fte.sizep, buf,
buflen);
- return be32_to_cpu(*sizep);
+ return be32_to_cpu(*fte.sizep);
}
break;
case OF_DT_END_NODE:
More information about the Linuxppc-dev
mailing list