[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