diff mbox

[U-Boot,8/9] fdt_support: fix an endian bug of fdt_initrd()

Message ID 1392384629-18771-9-git-send-email-yamada.m@jp.panasonic.com
State Superseded
Delegated to: Jerry Van Baren
Headers show

Commit Message

Masahiro Yamada Feb. 14, 2014, 1:30 p.m. UTC
Data written to DTB must be converted to big endian order.
It is usually done by using cpu_to_fdt32(), cpu_to_fdt64(), etc.

fdt_initrd() invoked write_cell(), which always swaps byte order.
It means the function only worked on little endian architectures.
(On big endian architectures, the byte order should be kept as it is)

This commit uses cpu_to_fdt32() and cpu_to_fdt64()
and deletes write_cell().

Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
---

 common/fdt_support.c | 41 ++++++++++++++++++++---------------------
 1 file changed, 20 insertions(+), 21 deletions(-)
diff mbox

Patch

diff --git a/common/fdt_support.c b/common/fdt_support.c
index 58d1ef7..5631f16 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -32,18 +32,6 @@  static int get_cells_len(const void *fdt, const char *nr_cells_name)
 	return 4;
 }
 
-/*
- * Write a 4 or 8 byte big endian cell
- */
-static void write_cell(u8 *addr, u64 val, int size)
-{
-	int shift = (size - 1) * 8;
-	while (size-- > 0) {
-		*addr++ = (val >> shift) & 0xff;
-		shift -= 8;
-	}
-}
-
 /**
  * fdt_getprop_u32_default - Find a node and return it's property or a default
  *
@@ -186,11 +174,21 @@  static int fdt_fixup_stdout(void *fdt, int chosenoff)
 }
 #endif
 
+static inline int fdt_setprop_uxx(void *fdt, int nodeoffset, const char *name,
+				  uint64_t val, int is_u64)
+{
+	if (is_u64)
+		return fdt_setprop_u64(fdt, nodeoffset, name, val);
+	else
+		return fdt_setprop_u32(fdt, nodeoffset, name, (uint32_t)val);
+}
+
+
 int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
 {
-	int   nodeoffset, addr_cell_len;
+	int   nodeoffset;
 	int   err, j, total;
-	fdt64_t  tmp;
+	int is_u64;
 	uint64_t addr, size;
 
 	/* find or create "/chosen" node. */
@@ -222,19 +220,20 @@  int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
 		return err;
 	}
 
-	addr_cell_len = get_cells_len(fdt, "#address-cells");
+	is_u64 = (get_cells_len(fdt, "#address-cells") == 8);
+
+	err = fdt_setprop_uxx(fdt, nodeoffset, "linux,initrd-start",
+			      (uint64_t)initrd_start, is_u64);
 
-	write_cell((u8 *)&tmp, initrd_start, addr_cell_len);
-	err = fdt_setprop(fdt, nodeoffset,
-			  "linux,initrd-start", &tmp, addr_cell_len);
 	if (err < 0) {
 		printf("WARNING: could not set linux,initrd-start %s.\n",
 		       fdt_strerror(err));
 		return err;
 	}
-	write_cell((u8 *)&tmp, initrd_end, addr_cell_len);
-	err = fdt_setprop(fdt, nodeoffset,
-			"linux,initrd-end", &tmp, addr_cell_len);
+
+	err = fdt_setprop_uxx(fdt, nodeoffset, "linux,initrd-end",
+			      (uint64_t)initrd_end, is_u64);
+
 	if (err < 0) {
 		printf("WARNING: could not set linux,initrd-end %s.\n",
 		       fdt_strerror(err));