You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.8 KiB
150 lines
4.8 KiB
10 years ago
|
From e946a8cbe4a47a7c2615ffb0d45712e72c7d0f3a Mon Sep 17 00:00:00 2001
|
||
|
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||
|
Date: Fri, 15 May 2015 11:51:51 +0100
|
||
|
Subject: [PATCH 73/74] ARM: l2c: only unlock caches if NS_LOCKDOWN bit is set
|
||
|
|
||
|
Some L2C caches have a bit which allows non-secure software to control
|
||
|
the cache lockdown. Some platforms are unable to set this bit. To
|
||
|
avoid receiving an abort while trying to unlock the cache lines, check
|
||
|
the state of this bit before unlocking. We do this by providing a new
|
||
|
method in the l2c_init_data to perform the unlocking.
|
||
|
|
||
|
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||
|
---
|
||
|
arch/arm/mm/cache-l2x0.c | 26 +++++++++++++++++++++++++-
|
||
|
1 file changed, 25 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/arch/arm/mm/cache-l2x0.c
|
||
|
+++ b/arch/arm/mm/cache-l2x0.c
|
||
|
@@ -42,6 +42,7 @@ struct l2c_init_data {
|
||
|
void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
|
||
|
void (*save)(void __iomem *);
|
||
|
void (*configure)(void __iomem *);
|
||
|
+ void (*unlock)(void __iomem *, unsigned);
|
||
|
struct outer_cache_fns outer_cache;
|
||
|
};
|
||
|
|
||
|
@@ -128,7 +129,7 @@ static void l2c_enable(void __iomem *bas
|
||
|
else
|
||
|
l2x0_data->configure(base);
|
||
|
|
||
|
- l2c_unlock(base, num_lock);
|
||
|
+ l2x0_data->unlock(base, num_lock);
|
||
|
|
||
|
local_irq_save(flags);
|
||
|
__l2c_op_way(base + L2X0_INV_WAY);
|
||
|
@@ -249,6 +250,7 @@ static const struct l2c_init_data l2c210
|
||
|
.enable = l2c_enable,
|
||
|
.save = l2c_save,
|
||
|
.configure = l2c_configure,
|
||
|
+ .unlock = l2c_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = l2c210_inv_range,
|
||
|
.clean_range = l2c210_clean_range,
|
||
|
@@ -400,6 +402,12 @@ static void l2c220_enable(void __iomem *
|
||
|
l2c_enable(base, aux, num_lock);
|
||
|
}
|
||
|
|
||
|
+static void l2c220_unlock(void __iomem *base, unsigned num_lock)
|
||
|
+{
|
||
|
+ if (readl_relaxed(base + L2X0_AUX_CTRL) & L220_AUX_CTRL_NS_LOCKDOWN)
|
||
|
+ l2c_unlock(base, num_lock);
|
||
|
+}
|
||
|
+
|
||
|
static const struct l2c_init_data l2c220_data = {
|
||
|
.type = "L2C-220",
|
||
|
.way_size_0 = SZ_8K,
|
||
|
@@ -407,6 +415,7 @@ static const struct l2c_init_data l2c220
|
||
|
.enable = l2c220_enable,
|
||
|
.save = l2c_save,
|
||
|
.configure = l2c_configure,
|
||
|
+ .unlock = l2c220_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = l2c220_inv_range,
|
||
|
.clean_range = l2c220_clean_range,
|
||
|
@@ -755,6 +764,12 @@ static void l2c310_resume(void)
|
||
|
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
|
||
|
}
|
||
|
|
||
|
+static void l2c310_unlock(void __iomem *base, unsigned num_lock)
|
||
|
+{
|
||
|
+ if (readl_relaxed(base + L2X0_AUX_CTRL) & L310_AUX_CTRL_NS_LOCKDOWN)
|
||
|
+ l2c_unlock(base, num_lock);
|
||
|
+}
|
||
|
+
|
||
|
static const struct l2c_init_data l2c310_init_fns __initconst = {
|
||
|
.type = "L2C-310",
|
||
|
.way_size_0 = SZ_8K,
|
||
|
@@ -763,6 +778,7 @@ static const struct l2c_init_data l2c310
|
||
|
.fixup = l2c310_fixup,
|
||
|
.save = l2c310_save,
|
||
|
.configure = l2c310_configure,
|
||
|
+ .unlock = l2c310_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = l2c210_inv_range,
|
||
|
.clean_range = l2c210_clean_range,
|
||
|
@@ -1067,6 +1083,7 @@ static const struct l2c_init_data of_l2c
|
||
|
.enable = l2c_enable,
|
||
|
.save = l2c_save,
|
||
|
.configure = l2c_configure,
|
||
|
+ .unlock = l2c_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = l2c210_inv_range,
|
||
|
.clean_range = l2c210_clean_range,
|
||
|
@@ -1086,6 +1103,7 @@ static const struct l2c_init_data of_l2c
|
||
|
.enable = l2c220_enable,
|
||
|
.save = l2c_save,
|
||
|
.configure = l2c_configure,
|
||
|
+ .unlock = l2c220_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = l2c220_inv_range,
|
||
|
.clean_range = l2c220_clean_range,
|
||
|
@@ -1213,6 +1231,7 @@ static const struct l2c_init_data of_l2c
|
||
|
.fixup = l2c310_fixup,
|
||
|
.save = l2c310_save,
|
||
|
.configure = l2c310_configure,
|
||
|
+ .unlock = l2c310_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = l2c210_inv_range,
|
||
|
.clean_range = l2c210_clean_range,
|
||
|
@@ -1242,6 +1261,7 @@ static const struct l2c_init_data of_l2c
|
||
|
.fixup = l2c310_fixup,
|
||
|
.save = l2c310_save,
|
||
|
.configure = l2c310_configure,
|
||
|
+ .unlock = l2c310_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = l2c210_inv_range,
|
||
|
.clean_range = l2c210_clean_range,
|
||
|
@@ -1419,6 +1439,7 @@ static const struct l2c_init_data of_aur
|
||
|
.fixup = aurora_fixup,
|
||
|
.save = aurora_save,
|
||
|
.configure = l2c_configure,
|
||
|
+ .unlock = l2c_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = aurora_inv_range,
|
||
|
.clean_range = aurora_clean_range,
|
||
|
@@ -1439,6 +1460,7 @@ static const struct l2c_init_data of_aur
|
||
|
.fixup = aurora_fixup,
|
||
|
.save = aurora_save,
|
||
|
.configure = l2c_configure,
|
||
|
+ .unlock = l2c_unlock,
|
||
|
.outer_cache = {
|
||
|
.resume = l2c_resume,
|
||
|
},
|
||
|
@@ -1589,6 +1611,7 @@ static const struct l2c_init_data of_bcm
|
||
|
.enable = l2c310_enable,
|
||
|
.save = l2c310_save,
|
||
|
.configure = l2c310_configure,
|
||
|
+ .unlock = l2c310_unlock,
|
||
|
.outer_cache = {
|
||
|
.inv_range = bcm_inv_range,
|
||
|
.clean_range = bcm_clean_range,
|
||
|
@@ -1626,6 +1649,7 @@ static const struct l2c_init_data of_tau
|
||
|
.enable = l2c_enable,
|
||
|
.save = tauros3_save,
|
||
|
.configure = tauros3_configure,
|
||
|
+ .unlock = l2c_unlock,
|
||
|
/* Tauros3 broadcasts L1 cache operations to L2 */
|
||
|
.outer_cache = {
|
||
|
.resume = l2c_resume,
|