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