aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/arch/armv7/cache.c9
-rw-r--r--payloads/libpayload/include/armv7/arch/cache.h16
-rw-r--r--src/arch/armv7/cache.c18
-rw-r--r--src/arch/armv7/include/arch/cache.h11
-rw-r--r--src/arch/armv7/stages.c2
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.
*/