[PATCH] sunxi: restore modified memory

Andrey Skvortsov andrej.skvortzov at gmail.com
Fri Jul 21 16:57:21 CEST 2023


On A64 with 2G of RAM words at following addresses were modified with
'aa55aa55' value:
 - 50000000
 - 60000000
 - 84000000
 - 88000000
 - 90000000
 - A0000000
 - A0000200

That made harder to pick memory range for persistent storage in RAM.

Signed-off-by: Andrey Skvortsov <andrej.skvortzov at gmail.com>
---
 arch/arm/mach-sunxi/dram_helpers.c  | 16 ++++++++++++++--
 arch/arm/mach-sunxi/dram_sunxi_dw.c | 16 ++++++++++++++--
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index 2c873192e6..e3d236a4b3 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -32,12 +32,24 @@ void mctl_await_completion(u32 *reg, u32 mask, u32 val)
 #ifndef CONFIG_MACH_SUNIV
 bool mctl_mem_matches(u32 offset)
 {
+	unsigned long tmp_base;
+	unsigned long tmp_offset;
+	bool ret;
+
+        /* Save original values */
+	tmp_base = readl(CFG_SYS_SDRAM_BASE);
+	tmp_offset = readl((ulong)CFG_SYS_SDRAM_BASE + offset);
+
 	/* Try to write different values to RAM at two addresses */
 	writel(0, CFG_SYS_SDRAM_BASE);
 	writel(0xaa55aa55, (ulong)CFG_SYS_SDRAM_BASE + offset);
 	dsb();
 	/* Check if the same value is actually observed when reading back */
-	return readl(CFG_SYS_SDRAM_BASE) ==
-	       readl((ulong)CFG_SYS_SDRAM_BASE + offset);
+	ret = readl(CFG_SYS_SDRAM_BASE) == readl((ulong)CFG_SYS_SDRAM_BASE + offset);
+
+	/* Restore original values */
+	writel(tmp_base, CFG_SYS_SDRAM_BASE);
+	writel(tmp_offset, (ulong)CFG_SYS_SDRAM_BASE + offset);
+	return ret;
 }
 #endif
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index 9107b114df..6245815fa2 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -657,13 +657,25 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
  */
 static bool mctl_mem_matches_base(u32 offset, ulong base)
 {
+	unsigned long tmp_base;
+	unsigned long tmp_offset;
+	bool ret;
+
+	/* Save original values */
+	tmp_base = readl(base);
+	tmp_offset = readl((ulong)base + offset);
+
 	/* Try to write different values to RAM at two addresses */
 	writel(0, base);
 	writel(0xaa55aa55, base + offset);
 	dsb();
 	/* Check if the same value is actually observed when reading back */
-	return readl(base) ==
-	       readl(base + offset);
+	ret = readl(base) == readl(base + offset);
+
+	/* Restore original values */
+	writel(tmp_base, base);
+	writel(tmp_offset, (ulong)base + offset);
+	return ret;
 }
 
 static void mctl_auto_detect_dram_size_rank(uint16_t socid, struct dram_para *para, ulong base, struct rank_para *rank)
-- 
2.39.2



More information about the U-Boot mailing list