[U-Boot] [PATCH 2/3] common/memsize.c: correctly restore all modified memory loations

Wolfgang Denk wd at denx.de
Tue Oct 21 22:14:11 CEST 2014


The original memory sizing code in get_ram_size clobbers the word
at the base address, but forgets to restore it.

Unlike the (reverted) commit b8496cced856ff411f1eb2e4eff20f5abe7080b0
we save and restore the base address value at the start resp. at the
end of the function.  It needs to stay cleared until the detection is
done, otherwise it will fail to detect the same piece of memory being
mapped multiple times into the address space.

Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
Signed-off-by: Wolfgang Denk <wd at denx.de>
Cc: Iwo Mergler <Iwo.Mergler at netcommwireless.com>
---
 common/memsize.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/common/memsize.c b/common/memsize.c
index 0fb9ba5..d5827dd 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2004
+ * (C) Copyright 2004-2014
  * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
  *
  * SPDX-License-Identifier:	GPL-2.0+
@@ -31,7 +31,7 @@ long get_ram_size(long *base, long maxsize)
 	long           cnt;
 	long           val;
 	long           size;
-	int            i = 0;
+	int            i = 0, last;
 
 	for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
 		addr = base + cnt;	/* pointer arith! */
@@ -44,6 +44,7 @@ long get_ram_size(long *base, long maxsize)
 	addr = base;
 	sync();
 	save[i] = *addr;
+	last = i;
 	sync();
 	*addr = 0;
 
@@ -51,7 +52,7 @@ long get_ram_size(long *base, long maxsize)
 	if ((val = *addr) != 0) {
 		/* Restore the original data before leaving the function. */
 		sync();
-		*addr = save[i];
+		*addr = save[last];
 		for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
 			addr  = base + cnt;
 			sync();
@@ -62,7 +63,9 @@ long get_ram_size(long *base, long maxsize)
 
 	for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
 		addr = base + cnt;	/* pointer arith! */
+		sync();
 		val = *addr;
+		sync();
 		*addr = save[--i];
 		if (val != ~cnt) {
 			size = cnt * sizeof(long);
@@ -74,12 +77,19 @@ long get_ram_size(long *base, long maxsize)
 			     cnt < maxsize / sizeof(long);
 			     cnt <<= 1) {
 				addr  = base + cnt;
+				sync();
 				*addr = save[--i];
 			}
+			addr = base;
+			sync();
+			*addr = save[last];
 			return (size);
 		}
 	}
 
+	addr = base;
+	sync();
+	*addr = save[last];
 	return (maxsize);
 }
 
-- 
1.8.3.1



More information about the U-Boot mailing list