diff options
-rw-r--r-- | payloads/libpayload/arch/armv7/cache.c | 9 | ||||
-rw-r--r-- | payloads/libpayload/include/armv7/arch/cache.h | 16 | ||||
-rw-r--r-- | src/arch/armv7/cache.c | 18 | ||||
-rw-r--r-- | src/arch/armv7/include/arch/cache.h | 11 | ||||
-rw-r--r-- | src/arch/armv7/stages.c | 2 |
5 files changed, 55 insertions, 1 deletions
diff --git a/payloads/libpayload/arch/armv7/cache.c b/payloads/libpayload/arch/armv7/cache.c index efdf75ebbf..b4a937bf43 100644 --- a/payloads/libpayload/arch/armv7/cache.c +++ b/payloads/libpayload/arch/armv7/cache.c @@ -76,6 +76,7 @@ void icache_invalidate_all(void) } enum dcache_op { + OP_DCCSW, OP_DCCISW, OP_DCISW, OP_DCCIMVAC, @@ -142,6 +143,9 @@ static void dcache_op_set_way(enum dcache_op op) case OP_DCISW: dcisw(val); break; + case OP_DCCSW: + dccsw(val); + break; default: break; } @@ -175,6 +179,11 @@ static void dcache_foreach(enum dcache_op op) } } +void dcache_clean_all(void) +{ + dcache_foreach(OP_DCCSW); +} + void dcache_clean_invalidate_all(void) { dcache_foreach(OP_DCCISW); diff --git a/payloads/libpayload/include/armv7/arch/cache.h b/payloads/libpayload/include/armv7/arch/cache.h index 0414da37f2..0756f11813 100644 --- a/payloads/libpayload/include/armv7/arch/cache.h +++ b/payloads/libpayload/include/armv7/arch/cache.h @@ -110,6 +110,12 @@ static inline void tlbiall(void) asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0) : "memory"); } +/* invalidate unified TLB by MVA, all ASID */ +static inline void tlbimvaa(unsigned long mva) +{ + asm volatile ("mcr p15, 0, %0, c8, c7, 3" : : "r" (mva) : "memory"); +} + /* write data access control register (DACR) */ static inline void write_dacr(uint32_t val) { @@ -164,6 +170,12 @@ static inline void dccmvac(unsigned long mva) asm volatile ("mcr p15, 0, %0, c7, c10, 1" : : "r" (mva) : "memory"); } +/* data cache clean by set/way */ +static inline void dccsw(uint32_t val) +{ + asm volatile ("mcr p15, 0, %0, c7, c10, 2" : : "r" (val) : "memory"); +} + /* data cache invalidate by MVA to PoC */ static inline void dcimvac(unsigned long mva) { @@ -286,6 +298,8 @@ void dcache_clean_invalidate_by_mva(unsigned long addr, unsigned long len); /* dcache invalidate by modified virtual address to PoC */ void dcache_invalidate_by_mva(unsigned long addr, unsigned long len); +void dcache_clean_all(void); + /* dcache invalidate all (on current level given by CCSELR) */ void dcache_invalidate_all(void); @@ -317,6 +331,8 @@ enum dcache_policy { DCACHE_WRITETHROUGH, }; +/* disable the mmu for a range. Primarily useful to lock out address 0. */ +void mmu_disable_range(unsigned long start_mb, unsigned long size_mb); /* mmu range configuration (set dcache policy) */ void mmu_config_range(unsigned long start_mb, unsigned long size_mb, enum dcache_policy policy); diff --git a/src/arch/armv7/cache.c b/src/arch/armv7/cache.c index 4046451e34..b4a937bf43 100644 --- a/src/arch/armv7/cache.c +++ b/src/arch/armv7/cache.c @@ -76,10 +76,12 @@ void icache_invalidate_all(void) } enum dcache_op { + OP_DCCSW, OP_DCCISW, OP_DCISW, OP_DCCIMVAC, OP_DCCMVAC, + OP_DCIMVAC, }; /* @@ -141,6 +143,9 @@ static void dcache_op_set_way(enum dcache_op op) case OP_DCISW: dcisw(val); break; + case OP_DCCSW: + dccsw(val); + break; default: break; } @@ -174,6 +179,11 @@ static void dcache_foreach(enum dcache_op op) } } +void dcache_clean_all(void) +{ + dcache_foreach(OP_DCCSW); +} + void dcache_clean_invalidate_all(void) { dcache_foreach(OP_DCCISW); @@ -220,6 +230,9 @@ static void dcache_op_mva(unsigned long addr, case OP_DCCMVAC: dccmvac(line); break; + case OP_DCIMVAC: + dcimvac(line); + break; default: break; } @@ -238,6 +251,11 @@ void dcache_clean_invalidate_by_mva(unsigned long addr, unsigned long len) dcache_op_mva(addr, len, OP_DCCIMVAC); } +void dcache_invalidate_by_mva(unsigned long addr, unsigned long len) +{ + dcache_op_mva(addr, len, OP_DCIMVAC); +} + void dcache_mmu_disable(void) { uint32_t sctlr; diff --git a/src/arch/armv7/include/arch/cache.h b/src/arch/armv7/include/arch/cache.h index 8a14ff9388..0756f11813 100644 --- a/src/arch/armv7/include/arch/cache.h +++ b/src/arch/armv7/include/arch/cache.h @@ -170,6 +170,12 @@ static inline void dccmvac(unsigned long mva) asm volatile ("mcr p15, 0, %0, c7, c10, 1" : : "r" (mva) : "memory"); } +/* data cache clean by set/way */ +static inline void dccsw(uint32_t val) +{ + asm volatile ("mcr p15, 0, %0, c7, c10, 2" : : "r" (val) : "memory"); +} + /* data cache invalidate by MVA to PoC */ static inline void dcimvac(unsigned long mva) { @@ -289,6 +295,11 @@ void dcache_clean_by_mva(unsigned long addr, unsigned long len); /* dcache clean and invalidate by modified virtual address to PoC */ void dcache_clean_invalidate_by_mva(unsigned long addr, unsigned long len); +/* dcache invalidate by modified virtual address to PoC */ +void dcache_invalidate_by_mva(unsigned long addr, unsigned long len); + +void dcache_clean_all(void); + /* dcache invalidate all (on current level given by CCSELR) */ void dcache_invalidate_all(void); diff --git a/src/arch/armv7/stages.c b/src/arch/armv7/stages.c index 0d2072de50..38d1b1928a 100644 --- a/src/arch/armv7/stages.c +++ b/src/arch/armv7/stages.c @@ -52,7 +52,7 @@ void stage_exit(void *addr) /* make sure any code we installed is written to memory. Not all ARM have * unified caches. */ - dcache_clean_invalidate_all(); + dcache_clean_all(); /* Because most stages copy code to memory, it's a safe and hygienic thing * to flush the icache here. */ |