[U-Boot] [RFC PATCH] ARM: cache: cp15: Align addresses when initial page_table setup is flushed

Lukasz Majewski l.majewski at majess.pl
Tue Aug 9 10:41:46 CEST 2016


Change made in the commit:
"arm: Show cache warnings in U-Boot proper only"
SHA1: bcc53bf095893fbdae531a9a7b5d4ef4a125a7fc

has revealed that during initial setting of MMU regions in the
mmu_set_region_dcache_behavior() function some addresses are unaligned
to platform cache line size.

As a result we were experiencing following warning messages at early boot:
CACHE: Misaligned operation at range [8fff0000, 8fff0004]
CACHE: Misaligned operation at range [8fff0024, 8fff0028]

Those were caused by an attempt to update single page_table
(gd->arch.tlb_addr) entries with proper TLB cache settings.
Since TLB section covers large area (up to 2MiB), we had to update
very small amount of cache data, very often much smaller than single cache
line size (e.g. 32 or 64 bytes).

This patch squashes this warning by properly aligning start and end addresses.
In fact it does what cache HW would do anyway (flush the whole data cache
lines).
Even without this patch it all worked, because TLB table sections were
initialized to default values earlier.

Signed-off-by: Lukasz Majewski <l.majewski at majess.pl>
---
 arch/arm/lib/cache-cp15.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 1121dc3..913c554 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -62,6 +62,7 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
 				     enum dcache_option option)
 {
 	u32 *page_table = (u32 *)gd->arch.tlb_addr;
+	u32 align_start_addr, align_end_addr;
 	unsigned long upto, end;
 
 	end = ALIGN(start + size, MMU_SECTION_SIZE) >> MMU_SECTION_SHIFT;
@@ -70,7 +71,14 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
 	      option);
 	for (upto = start; upto < end; upto++)
 		set_section_dcache(upto, option);
-	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
+
+	align_start_addr = (u32)&page_table[start]
+		& ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+	align_end_addr = ALIGN((u32)&page_table[end],
+			       CONFIG_SYS_CACHELINE_SIZE);
+	debug("%s: align_start_addr: 0x%x align end_addr: 0x%x\n", __func__,
+	      align_start_addr, align_end_addr);
+	mmu_page_table_flush(align_start_addr, align_end_addr);
 }
 
 __weak void dram_bank_mmu_setup(int bank)
-- 
2.1.4



More information about the U-Boot mailing list