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:

committed by
Tom Rini

parent
558e699d15
commit
268f6ac1f9
@@ -719,6 +719,11 @@ int icache_status(void)
|
|||||||
return (get_sctlr() & CR_I) != 0;
|
return (get_sctlr() & CR_I) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mmu_status(void)
|
||||||
|
{
|
||||||
|
return (get_sctlr() & CR_M) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
void invalidate_icache_all(void)
|
void invalidate_icache_all(void)
|
||||||
{
|
{
|
||||||
__asm_invalidate_icache_all();
|
__asm_invalidate_icache_all();
|
||||||
@@ -740,6 +745,11 @@ int icache_status(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mmu_status(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void invalidate_icache_all(void)
|
void invalidate_icache_all(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -338,6 +338,7 @@ extern void __readwrite_bug(const char *fn);
|
|||||||
|
|
||||||
/* Optimized copy functions to read from/write to IO sapce */
|
/* Optimized copy functions to read from/write to IO sapce */
|
||||||
#ifdef CONFIG_ARM64
|
#ifdef CONFIG_ARM64
|
||||||
|
#include <cpu_func.h>
|
||||||
/*
|
/*
|
||||||
* Copy data from IO memory space to "real" memory space.
|
* Copy data from IO memory space to "real" memory space.
|
||||||
*/
|
*/
|
||||||
@@ -351,11 +352,13 @@ void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
|
|||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count >= 8) {
|
if (mmu_status()) {
|
||||||
*(u64 *)to = __raw_readq(from);
|
while (count >= 8) {
|
||||||
from += 8;
|
*(u64 *)to = __raw_readq(from);
|
||||||
to += 8;
|
from += 8;
|
||||||
count -= 8;
|
to += 8;
|
||||||
|
count -= 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
@@ -379,11 +382,13 @@ void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
|
|||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count >= 8) {
|
if (mmu_status()) {
|
||||||
__raw_writeq(*(u64 *)from, to);
|
while (count >= 8) {
|
||||||
from += 8;
|
__raw_writeq(*(u64 *)from, to);
|
||||||
to += 8;
|
from += 8;
|
||||||
count -= 8;
|
to += 8;
|
||||||
|
count -= 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
|
@@ -59,6 +59,7 @@ int dcache_status(void);
|
|||||||
void dcache_enable(void);
|
void dcache_enable(void);
|
||||||
void dcache_disable(void);
|
void dcache_disable(void);
|
||||||
void mmu_disable(void);
|
void mmu_disable(void);
|
||||||
|
int mmu_status(void);
|
||||||
|
|
||||||
/* arch/$(ARCH)/lib/cache.c */
|
/* arch/$(ARCH)/lib/cache.c */
|
||||||
void enable_caches(void);
|
void enable_caches(void);
|
||||||
|
Reference in New Issue
Block a user