Re: common flatdevtree code
From: Mark A. Greer <hidden>
Date: 2006-09-08 00:56:31
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@us.ibm.com> and + * CC: <Linuxppc-dev@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@embeddedalley.com> * Hollis Blanchard <hollisb@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: