arm64: Update memcpy_{from, to}io() helpers

At early U-Boot stage, before relocation, MMU is not yet configured
and disabled. DDR may not be configured with the correct memory
attributes (can be configured in MT_DEVICE instead of MT_MEMORY).

In this case, usage of memcpy_{from, to}io() may leads to synchronous
abort in AARCH64 in case the normal memory address is not 64Bits aligned.

To avoid such situation, forbid usage of normal memory cast to (u64 *) in
case MMU is not enabled.

Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Cc: mark.kettenis@xs4all.nl
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
This commit is contained in:
Patrice Chotard 2021-07-19 11:21:51 +02:00 committed by Tom Rini
parent 558e699d15
commit 268f6ac1f9
3 changed files with 26 additions and 10 deletions

View file

@ -719,6 +719,11 @@ int icache_status(void)
return (get_sctlr() & CR_I) != 0;
}
int mmu_status(void)
{
return (get_sctlr() & CR_M) != 0;
}
void invalidate_icache_all(void)
{
__asm_invalidate_icache_all();
@ -740,6 +745,11 @@ int icache_status(void)
return 0;
}
int mmu_status(void)
{
return 0;
}
void invalidate_icache_all(void)
{
}

View file

@ -338,6 +338,7 @@ extern void __readwrite_bug(const char *fn);
/* Optimized copy functions to read from/write to IO sapce */
#ifdef CONFIG_ARM64
#include <cpu_func.h>
/*
* Copy data from IO memory space to "real" memory space.
*/
@ -351,12 +352,14 @@ void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
count--;
}
if (mmu_status()) {
while (count >= 8) {
*(u64 *)to = __raw_readq(from);
from += 8;
to += 8;
count -= 8;
}
}
while (count) {
*(u8 *)to = __raw_readb(from);
@ -379,12 +382,14 @@ void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
count--;
}
if (mmu_status()) {
while (count >= 8) {
__raw_writeq(*(u64 *)from, to);
from += 8;
to += 8;
count -= 8;
}
}
while (count) {
__raw_writeb(*(u8 *)from, to);

View file

@ -59,6 +59,7 @@ int dcache_status(void);
void dcache_enable(void);
void dcache_disable(void);
void mmu_disable(void);
int mmu_status(void);
/* arch/$(ARCH)/lib/cache.c */
void enable_caches(void);