arm: introduce invalidate_dcache_va_range

Take care of handling non-cacheline aligned addresses and sizes.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Stefano Stabellini authored and Jan Beulich committed 2014-10-23 12:04:19 +02:00
1 parent 71d64afe3e
commit 09146ae71b
3 files changed
+38

No files matched your search

+3
View File
@@ -19,6 +19,9 @@ static inline void write_pte(lpae_t *p, lpae_t pte)
: : "r" (pte.bits), "r" (p) : "memory");
}
/* Inline ASM to invalidate dcache on register R (may be an inline asm operand) */
#define __invalidate_dcache_one(R) STORE_CP32(R, DCIMVAC)
/* Inline ASM to flush dcache on register R (may be an inline asm operand) */
#define __clean_dcache_one(R) STORE_CP32(R, DCCMVAC)
+3
View File
@@ -14,6 +14,9 @@ static inline void write_pte(lpae_t *p, lpae_t pte)
: : "r" (pte.bits), "r" (p) : "memory");
}
/* Inline ASM to invalidate dcache on register R (may be an inline asm operand) */
#define __invalidate_dcache_one(R) "dc ivac, %" #R ";"
/* Inline ASM to flush dcache on register R (may be an inline asm operand) */
#define __clean_dcache_one(R) "dc cvac, %" #R ";"
+32
View File
@@ -268,6 +268,38 @@ extern size_t cacheline_bytes;
/* Functions for flushing medium-sized areas.
* if 'range' is large enough we might want to use model-specific
* full-cache flushes. */
static inline int invalidate_dcache_va_range(const void *p, unsigned long size)
{
size_t off;
const void *end = p + size;
dsb(sy); /* So the CPU issues all writes to the range */
off = (unsigned long)p % cacheline_bytes;
if ( off )
{
p -= off;
asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (p));
p += cacheline_bytes;
size -= cacheline_bytes - off;
}
off = (unsigned long)end % cacheline_bytes;
if ( off )
{
end -= off;
size -= off;
asm volatile (__clean_and_invalidate_dcache_one(0) : : "r" (end));
}
for ( ; p < end; p += cacheline_bytes )
asm volatile (__invalidate_dcache_one(0) : : "r" (p));
dsb(sy); /* So we know the flushes happen before continuing */
return 0;
}
static inline int clean_dcache_va_range(const void *p, unsigned long size)
{
const void *end;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.