Skip to contentSkip to conversation

Add common memory fixup function

PATCH New Kumar Gala 2 participants 7 messages Nov 28, 2007

lore
Share & tools
lore

Kumar Gala

author
#0 lore raw

PATCH 1/1 Add common memory fixup function

Add the function fdt_fixup_memory() to fixup the /memory node of the fdt

---

Had a copy/paste error with start & size

(I've update reset & updated my libfdt_testing branch)

 common/fdt_support.c  |   78 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/fdt_support.h |    1 +
 2 files changed, 79 insertions(+), 0 deletions(-)
common/fdt_support.c +78 -0
index 69f4dd5..808ec70 100644
@@ -438,6 +438,84 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat,
 	do_fixup_by_compat(fdt, compat, prop, &val, 4, create);
 }
 
+int fdt_fixup_memory(void *blob, u64 start, u64 size)
+{
+	int err, nodeoffset, len = 0;
+	u8 tmp[16];
+	const u32 *addrcell, *sizecell;
+
+	err = fdt_check_header(blob);
+	if (err < 0) {
+		printf("%s: %s\n", __FUNCTION__, fdt_strerror(err));
+		return err;
+	}
+
+	/* update, or add and update /memory node */
+	nodeoffset = fdt_path_offset(blob, "/memory");
+	if (nodeoffset < 0) {
+		nodeoffset = fdt_add_subnode(blob, 0, "memory");
+		if (nodeoffset < 0)
+			printf("WARNING: could not create /memory: %s.\n",
+					fdt_strerror(nodeoffset));
+		return nodeoffset;
+	}
+	err = fdt_setprop(blob, nodeoffset, "device_type", "memory",
+			sizeof("memory"));
+	if (err < 0) {
+		printf("WARNING: could not set %s %s.\n", "device_type",
+				fdt_strerror(err));
+		return err;
+	}
+
+	addrcell = fdt_getprop(blob, 0, "#address-cells", NULL);
+	/* use shifts and mask to ensure endianness */
+	if ((addrcell) && (*addrcell == 2)) {
+		tmp[0] = (start >> 56) & 0xff;
+		tmp[1] = (start >> 48) & 0xff;
+		tmp[2] = (start >> 40) & 0xff;
+		tmp[3] = (start >> 32) & 0xff;
+		tmp[4] = (start >> 24) & 0xff;
+		tmp[5] = (start >> 16) & 0xff;
+		tmp[6] = (start >>  8) & 0xff;
+		tmp[7] = (start      ) & 0xff;
+		len = 8;
+	} else {
+		tmp[0] = (start >> 24) & 0xff;
+		tmp[1] = (start >> 16) & 0xff;
+		tmp[2] = (start >>  8) & 0xff;
+		tmp[3] = (start      ) & 0xff;
+		len = 4;
+	}
+
+	sizecell = fdt_getprop(blob, 0, "#size-cells", NULL);
+	/* use shifts and mask to ensure endianness */
+	if ((sizecell) && (*sizecell == 2)) {
+		tmp[0+len] = (size >> 56) & 0xff;
+		tmp[1+len] = (size >> 48) & 0xff;
+		tmp[2+len] = (size >> 40) & 0xff;
+		tmp[3+len] = (size >> 32) & 0xff;
+		tmp[4+len] = (size >> 24) & 0xff;
+		tmp[5+len] = (size >> 16) & 0xff;
+		tmp[6+len] = (size >>  8) & 0xff;
+		tmp[7+len] = (size      ) & 0xff;
+		len += 8;
+	} else {
+		tmp[0+len] = (size >> 24) & 0xff;
+		tmp[1+len] = (size >> 16) & 0xff;
+		tmp[2+len] = (size >>  8) & 0xff;
+		tmp[3+len] = (size      ) & 0xff;
+		len += 4;
+	}
+
+	err = fdt_setprop(blob, nodeoffset, "reg", tmp, len);
+	if (err < 0) {
+		printf("WARNING: could not set %s %s.\n",
+				"reg", fdt_strerror(err));
+		return err;
+	}
+	return 0;
+}
+
 void fdt_fixup_ethernet(void *fdt, bd_t *bd)
 {
 	int node;
include/fdt_support.h +1 -0
index 8f781d4..3d6c1a8 100644
@@ -44,6 +44,7 @@ void do_fixup_by_compat(void *fdt, const char *compat,
 			const char *prop, const void *val, int len, int create);
 void do_fixup_by_compat_u32(void *fdt, const char *compat,
 			    const char *prop, u32 val, int create);
+int fdt_fixup_memory(void *blob, u64 start, u64 size);
 void fdt_fixup_ethernet(void *fdt, bd_t *bd);
 
 #ifdef CONFIG_OF_HAS_UBOOT_ENV
Signature · 1 line
1.5.3.4
#1 lore raw

PATCH 1/1 Add common memory fixup function

Quoted 9 lines · Kumar Gala
common/fdt_support.c +9 -0
+	addrcell = fdt_getprop(blob, 0, "#address-cells", NULL);
+	/* use shifts and mask to ensure endianness */
+	if ((addrcell) && (*addrcell == 2)) {
+		tmp[0] = (start >> 56) & 0xff;
+		tmp[1] = (start >> 48) & 0xff;
+		tmp[2] = (start >> 40) & 0xff;
+		tmp[3] = (start >> 32) & 0xff;
+		tmp[4] = (start >> 24) & 0xff;
+		tmp[5] = (start >> 16) & 0xff;

common/fdt_support.c void do_fixup_by_compat_u32(void *fdt, const char *compat, · line 488

Quoted 10 lines
common/fdt_support.c +10 -0
+		tmp[6] = (start >>  8) & 0xff;
+		tmp[7] = (start      ) & 0xff;
+		len = 8;
+	} else {
+		tmp[0] = (start >> 24) & 0xff;
+		tmp[1] = (start >> 16) & 0xff;
+		tmp[2] = (start >>  8) & 0xff;
+		tmp[3] = (start      ) & 0xff;
+		len = 4;
+	}

Could we please use the existing byteswapping functions?

-Scott

author
#2 lore raw

PATCH 1/1 Add common memory fixup function

Quoted 14 lines · Scott Wood
Quoted 13 lines · Kumar Gala
common/fdt_support.c +13 -0
+	addrcell = fdt_getprop(blob, 0, "#address-cells", NULL);
+	/* use shifts and mask to ensure endianness */
+	if ((addrcell) && (*addrcell == 2)) {
+		tmp[0] = (start >> 56) & 0xff;
+		tmp[1] = (start >> 48) & 0xff;
+		tmp[2] = (start >> 40) & 0xff;
+		tmp[3] = (start >> 32) & 0xff;
+		tmp[4] = (start >> 24) & 0xff;
+		tmp[5] = (start >> 16) & 0xff;
+		tmp[6] = (start >>  8) & 0xff;
+		tmp[7] = (start      ) & 0xff;
+		len = 8;
+	} else {
Quoted 8 lines

common/fdt_support.c void do_fixup_by_compat_u32(void *fdt, const char *compat, · line 488

Quoted 6 lines
common/fdt_support.c +6 -0
+		tmp[0] = (start >> 24) & 0xff;
+		tmp[1] = (start >> 16) & 0xff;
+		tmp[2] = (start >>  8) & 0xff;
+		tmp[3] = (start      ) & 0xff;
+		len = 4;
+	}

Could we please use the existing byteswapping functions?

I don't see how to use them w/o going through an additional memcpy.

If you can provide a better solution I'm all for it. But I don't see any reason to hold up the patch at this point.

- k

#3 lore raw

PATCH 1/1 Add common memory fixup function

Quoted 24 lines · Kumar Gala
Quoted 21 lines · Scott Wood
Quoted 19 lines · Kumar Gala
common/fdt_support.c +19 -0
+    addrcell = fdt_getprop(blob, 0, "#address-cells", NULL);
+    /* use shifts and mask to ensure endianness */
+    if ((addrcell) && (*addrcell == 2)) {
+        tmp[0] = (start >> 56) & 0xff;
+        tmp[1] = (start >> 48) & 0xff;
+        tmp[2] = (start >> 40) & 0xff;
+        tmp[3] = (start >> 32) & 0xff;
+        tmp[4] = (start >> 24) & 0xff;
+        tmp[5] = (start >> 16) & 0xff;
+        tmp[6] = (start >>  8) & 0xff;
+        tmp[7] = (start      ) & 0xff;
+        len = 8;
+    } else {
+        tmp[0] = (start >> 24) & 0xff;
+        tmp[1] = (start >> 16) & 0xff;
+        tmp[2] = (start >>  8) & 0xff;
+        tmp[3] = (start      ) & 0xff;
+        len = 4;
+    }
Quoted 6 lines
Quoted 1 line

Could we please use the existing byteswapping functions?

I don't see how to use them w/o going through an additional memcpy.

If you can provide a better solution I'm all for it. But I don't see any reason to hold up the patch at this point.

union {
	uint8_t tmp[8];
	uint64_t mem64;
	uint32_t mem32;
}

int len;

if (addrcell && *addrcell == 2) {
	mem64 = cpu_to_fdt64(memsize);
	len = 8;
} else {
	mem32 = cpu_to_fdt32(memsize);
	len = 4;
}

fdt_setprop(..., tmp, len);

-Scott

author
#4 lore raw

PATCH 1/1 Add common memory fixup function

Quoted 36 lines · Scott Wood
Quoted 22 lines · Kumar Gala
Quoted 21 lines · Scott Wood
Quoted 19 lines · Kumar Gala
common/fdt_support.c +19 -0
+    addrcell = fdt_getprop(blob, 0, "#address-cells", NULL);
+    /* use shifts and mask to ensure endianness */
+    if ((addrcell) && (*addrcell == 2)) {
+        tmp[0] = (start >> 56) & 0xff;
+        tmp[1] = (start >> 48) & 0xff;
+        tmp[2] = (start >> 40) & 0xff;
+        tmp[3] = (start >> 32) & 0xff;
+        tmp[4] = (start >> 24) & 0xff;
+        tmp[5] = (start >> 16) & 0xff;
+        tmp[6] = (start >>  8) & 0xff;
+        tmp[7] = (start      ) & 0xff;
+        len = 8;
+    } else {
+        tmp[0] = (start >> 24) & 0xff;
+        tmp[1] = (start >> 16) & 0xff;
+        tmp[2] = (start >>  8) & 0xff;
+        tmp[3] = (start      ) & 0xff;
+        len = 4;
+    }
Quoted 4 lines
Quoted 1 line

Could we please use the existing byteswapping functions?

I don't see how to use them w/o going through an additional memcpy. If you can provide a better solution I'm all for it. But I don't see any reason to hold up the patch at this point.

union {
	uint8_t tmp[8];
	uint64_t mem64;
	uint32_t mem32;
}

int len;

Quoted 7 lines
if (addrcell && *addrcell == 2) {
	mem64 = cpu_to_fdt64(memsize);
	len = 8;
} else {
	mem32 = cpu_to_fdt32(memsize);
	len = 4;
}

This gets more complicated with finishing off the rest of temp since you have to use len to figure out an index.

I'm keeping the code as is since its the simplest version.

- k

#5 lore raw

PATCH 1/1 Add common memory fixup function

Quoted 22 lines · Kumar Gala
Quoted 13 lines · Scott Wood
Quoted 3 lines · Kumar Gala

I don't see how to use them w/o going through an additional memcpy. If you can provide a better solution I'm all for it. But I don't see any reason to hold up the patch at this point.

union {
    uint8_t tmp[8];
    uint64_t mem64;
    uint32_t mem32;
}

int len;

Quoted 7 lines
if (addrcell && *addrcell == 2) {
    mem64 = cpu_to_fdt64(memsize);
    len = 8;
} else {
    mem32 = cpu_to_fdt32(memsize);
    len = 4;
}
Quoted 2 lines

This gets more complicated with finishing off the rest of temp since you have to use len to figure out an index.

OK, so make mem64/mem32 arrays. :-P

Quoted 1 line

I'm keeping the code as is since its the simplest version.

Fine, if you don't mind making people's eyes bleed...

Maybe a generic function that takes a buffer pointer, a uint64_t, and a numcells? This is hardly going to be the only place that needs to write out a quantity that might be one or two cells.

-Scott

author
#6 lore raw

PATCH 1/1 Add common memory fixup function

Quoted 22 lines · Scott Wood
Quoted 21 lines · Kumar Gala
Quoted 20 lines · Scott Wood
Quoted 3 lines · Kumar Gala

I don't see how to use them w/o going through an additional memcpy. If you can provide a better solution I'm all for it. But I don't see any reason to hold up the patch at this point.

union {
   uint8_t tmp[8];
   uint64_t mem64;
   uint32_t mem32;
}

int len;

if (addrcell && *addrcell == 2) {
   mem64 = cpu_to_fdt64(memsize);
   len = 8;
} else {
   mem32 = cpu_to_fdt32(memsize);
   len = 4;
}
Quoted 8 lines
Quoted 2 lines

This gets more complicated with finishing off the rest of temp since you have to use len to figure out an index.

OK, so make mem64/mem32 arrays. :-P

Quoted 1 line

I'm keeping the code as is since its the simplest version.

Fine, if you don't mind making people's eyes bleed...

:)

Quoted 3 lines

Maybe a generic function that takes a buffer pointer, a uint64_t, and a numcells? This is hardly going to be the only place that needs to write out a quantity that might be one or two cells.

Agreed, but I leave that as an exercise for the reader... when we get the second case of this we can figure out a better helper.

- k