* [PATCH 0/2 v2] Fix boot on Calxeda highbank
@ 2015-05-12 7:39 Sjoerd Simons
2015-05-12 7:39 ` [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock Sjoerd Simons
2015-05-12 7:39 ` [PATCH 2/2] ARM: l2c: highbank: Add dummy configure function Sjoerd Simons
0 siblings, 2 replies; 11+ messages in thread
From: Sjoerd Simons @ 2015-05-12 7:39 UTC (permalink / raw)
To: linux-arm-kernel
When upgrading our trusted Calxeda server to Debian Jessie recently the machine
wedged during booting the installer. Upon further investigation, this happens
due to the transition to the generic L2C infrastructure introduced in 3.16. The
generic l2x0 code unlocks the cache during setup, however the Caldexa SMC
interface doesn't seem to allow the kernel to enable enable non-secure access
to the lock registers.. Queue Imprecise aborts and a fairly unhappy machine.
First patch in this series adds detection to the l2x0 code to check if
unlocking is possible. Second patch adds a (empty) configure callback for the
highbank l2c, reflecting the fact that there seemingly isn't anything to
configured via an SMC on these maches.
Changes since v1:
- Auto-detect when unlocking the cache is unsafe rather then requiring a
explicit flag to be set in the machine-specific code
Sjoerd Simons (2):
ARM: cache-l2c: Detect whether it's safe to unlock
ARM: l2c: highbank: Add dummy configure function
arch/arm/mach-highbank/highbank.c | 8 ++++++++
arch/arm/mm/cache-l2x0.c | 20 ++++++++++++++++++++
2 files changed, 28 insertions(+)
--
2.1.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock
2015-05-12 7:39 [PATCH 0/2 v2] Fix boot on Calxeda highbank Sjoerd Simons
@ 2015-05-12 7:39 ` Sjoerd Simons
2015-05-15 11:34 ` Russell King - ARM Linux
2015-05-12 7:39 ` [PATCH 2/2] ARM: l2c: highbank: Add dummy configure function Sjoerd Simons
1 sibling, 1 reply; 11+ messages in thread
From: Sjoerd Simons @ 2015-05-12 7:39 UTC (permalink / raw)
To: linux-arm-kernel
The L2C cache should only be unlocked when the cache is setup to allow
that. In the common case the l2x0 driver sets up the cache for that to
be the case (e.g. setting L310_AUX_CTRL_NS_LOCKDOWN on L2C-310), making
unlock safe. However when a secure firmware is in use, it may not be
possible for the L2c to be configured that way making unlocking unsafe.
To handle that, for caches where special configuration is needed to allow
unlocking, check whether this has been setup before unlocking.
Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
---
arch/arm/mm/cache-l2x0.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index e309c8f..2563458 100644
--- 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 *);
+ bool (*can_unlock)(void __iomem *);
struct outer_cache_fns outer_cache;
};
@@ -100,6 +101,9 @@ static inline void l2c_unlock(void __iomem *base, unsigned num)
{
unsigned i;
+ if (l2x0_data->can_unlock && !l2x0_data->can_unlock(base))
+ return;
+
for (i = 0; i < num; i++) {
writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_D_BASE +
i * L2X0_LOCKDOWN_STRIDE);
@@ -403,12 +407,18 @@ static void l2c220_enable(void __iomem *base, u32 aux, unsigned num_lock)
l2c_enable(base, aux, num_lock);
}
+static bool l2c220_can_unlock(void __iomem *base)
+{
+ return readl_relaxed(base + L2X0_AUX_CTRL) & L220_AUX_CTRL_NS_LOCKDOWN;
+}
+
static const struct l2c_init_data l2c220_data = {
.type = "L2C-220",
.way_size_0 = SZ_8K,
.num_lock = 1,
.enable = l2c220_enable,
.save = l2c_save,
+ .can_unlock = l2c220_can_unlock,
.outer_cache = {
.inv_range = l2c220_inv_range,
.clean_range = l2c220_clean_range,
@@ -681,6 +691,11 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
}
}
+static bool l2c310_can_unlock(void __iomem *base)
+{
+ return readl_relaxed(base + L2X0_AUX_CTRL) & L310_AUX_CTRL_NS_LOCKDOWN;
+}
+
static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
struct outer_cache_fns *fns)
{
@@ -763,6 +778,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
.fixup = l2c310_fixup,
.save = l2c310_save,
.configure = l2c310_configure,
+ .can_unlock = l2c310_can_unlock,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -1084,6 +1100,7 @@ static const struct l2c_init_data of_l2c220_data __initconst = {
.of_parse = l2x0_of_parse,
.enable = l2c220_enable,
.save = l2c_save,
+ .can_unlock = l2c220_can_unlock,
.outer_cache = {
.inv_range = l2c220_inv_range,
.clean_range = l2c220_clean_range,
@@ -1211,6 +1228,7 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
.fixup = l2c310_fixup,
.save = l2c310_save,
.configure = l2c310_configure,
+ .can_unlock = l2c310_can_unlock,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -1240,6 +1258,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
.fixup = l2c310_fixup,
.save = l2c310_save,
.configure = l2c310_configure,
+ .can_unlock = l2c310_can_unlock,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -1585,6 +1604,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
.enable = l2c310_enable,
.save = l2c310_save,
.configure = l2c310_configure,
+ .can_unlock = l2c310_can_unlock,
.outer_cache = {
.inv_range = bcm_inv_range,
.clean_range = bcm_clean_range,
--
2.1.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/2] ARM: l2c: highbank: Add dummy configure function
2015-05-12 7:39 [PATCH 0/2 v2] Fix boot on Calxeda highbank Sjoerd Simons
2015-05-12 7:39 ` [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock Sjoerd Simons
@ 2015-05-12 7:39 ` Sjoerd Simons
1 sibling, 0 replies; 11+ messages in thread
From: Sjoerd Simons @ 2015-05-12 7:39 UTC (permalink / raw)
To: linux-arm-kernel
Add empty configure function for the highbank l2c to reflect that the
cache can't be confured through a SMC. This prevent a useless
WARN_ONCE during early boot.
Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
---
arch/arm/mach-highbank/highbank.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 231fba0..623eb5e8 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -60,12 +60,20 @@ static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
reg);
}
+static void highbank_l2c310_configure(const struct l2x0_regs *regs)
+{
+}
+
static void __init highbank_init_irq(void)
{
irqchip_init();
if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9"))
highbank_scu_map_io();
+
+ if (IS_ENABLED(CONFIG_CACHE_L2X0)) {
+ outer_cache.configure = highbank_l2c310_configure;
+ }
}
static void highbank_power_off(void)
--
2.1.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock
2015-05-12 7:39 ` [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock Sjoerd Simons
@ 2015-05-15 11:34 ` Russell King - ARM Linux
2015-05-27 13:00 ` Sjoerd Simons
0 siblings, 1 reply; 11+ messages in thread
From: Russell King - ARM Linux @ 2015-05-15 11:34 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, May 12, 2015 at 09:39:14AM +0200, Sjoerd Simons wrote:
> The L2C cache should only be unlocked when the cache is setup to allow
> that. In the common case the l2x0 driver sets up the cache for that to
> be the case (e.g. setting L310_AUX_CTRL_NS_LOCKDOWN on L2C-310), making
> unlock safe. However when a secure firmware is in use, it may not be
> possible for the L2c to be configured that way making unlocking unsafe.
>
> To handle that, for caches where special configuration is needed to allow
> unlocking, check whether this has been setup before unlocking.
I've come up with a different solution to this, which of course I prefer.
I'll post the patches later today, thanks.
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock
2015-05-15 11:34 ` Russell King - ARM Linux
@ 2015-05-27 13:00 ` Sjoerd Simons
2015-05-27 17:40 ` [PATCH 1/5] ARM: l2c: restore the behaviour documented above l2c_enable() Russell King
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Sjoerd Simons @ 2015-05-27 13:00 UTC (permalink / raw)
To: linux-arm-kernel
Hey Russell,
On Fri, 2015-05-15 at 12:34 +0100, Russell King - ARM Linux wrote:
> On Tue, May 12, 2015 at 09:39:14AM +0200, Sjoerd Simons wrote:
> > To handle that, for caches where special configuration is needed to allow
> > unlocking, check whether this has been setup before unlocking.
>
> I've come up with a different solution to this, which of course I prefer.
> I'll post the patches later today, thanks.
Did you get round to create/posting those patches? If not, i'm happy to
do a set with your suggested solution as well if you can point me in the
right direction :)
--
Sjoerd Simons <sjoerd.simons@collabora.co.uk>
Collabora Ltd.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/5] ARM: l2c: restore the behaviour documented above l2c_enable()
2015-05-27 13:00 ` Sjoerd Simons
@ 2015-05-27 17:40 ` Russell King
2015-05-27 17:40 ` [PATCH 2/5] ARM: l2c: write auxiliary control register first Russell King
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Russell King @ 2015-05-27 17:40 UTC (permalink / raw)
To: linux-arm-kernel
l2c_enable() is documented that it must not be called if the cache has
already been enabled. Unfortunately, commit 6b49241ac252 ("ARM: 8259/1:
l2c: Refactor the driver to use commit-like interface") changed this
without updating the comment, for very little reason. Revert this
change and restore the expected behaviour.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mm/cache-l2x0.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index e309c8f35af5..1471c0f29bd3 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -129,10 +129,6 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
{
unsigned long flags;
- /* Do not touch the controller if already enabled. */
- if (readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)
- return;
-
l2x0_saved_regs.aux_ctrl = aux;
l2c_configure(base);
@@ -163,7 +159,11 @@ static void l2c_save(void __iomem *base)
static void l2c_resume(void)
{
- l2c_enable(l2x0_base, l2x0_saved_regs.aux_ctrl, l2x0_data->num_lock);
+ void __iomem *base = l2x0_base;
+
+ /* Do not touch the controller if already enabled. */
+ if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
+ l2c_enable(base, l2x0_saved_regs.aux_ctrl, l2x0_data->num_lock);
}
/*
--
2.1.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/5] ARM: l2c: write auxiliary control register first
2015-05-27 13:00 ` Sjoerd Simons
2015-05-27 17:40 ` [PATCH 1/5] ARM: l2c: restore the behaviour documented above l2c_enable() Russell King
@ 2015-05-27 17:40 ` Russell King
2015-05-27 17:40 ` [PATCH 3/5] ARM: l2c: clean up l2c_configure() Russell King
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Russell King @ 2015-05-27 17:40 UTC (permalink / raw)
To: linux-arm-kernel
Before calling the controller specific configuration function, write
the auxiliary control register first, so that bits shared with other
registers (such as the prefetch control register) are not overwritten
by the later write to the auxctrl register.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mm/cache-l2x0.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 1471c0f29bd3..977eb9f4f77e 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -115,10 +115,10 @@ static void l2c_configure(void __iomem *base)
return;
}
+ l2c_write_sec(l2x0_saved_regs.aux_ctrl, base, L2X0_AUX_CTRL);
+
if (l2x0_data->configure)
l2x0_data->configure(base);
-
- l2c_write_sec(l2x0_saved_regs.aux_ctrl, base, L2X0_AUX_CTRL);
}
/*
--
2.1.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/5] ARM: l2c: clean up l2c_configure()
2015-05-27 13:00 ` Sjoerd Simons
2015-05-27 17:40 ` [PATCH 1/5] ARM: l2c: restore the behaviour documented above l2c_enable() Russell King
2015-05-27 17:40 ` [PATCH 2/5] ARM: l2c: write auxiliary control register first Russell King
@ 2015-05-27 17:40 ` Russell King
2015-05-27 17:40 ` [PATCH 4/5] ARM: l2c: only unlock caches if NS_LOCKDOWN bit is set Russell King
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Russell King @ 2015-05-27 17:40 UTC (permalink / raw)
To: linux-arm-kernel
l2c_configure() does not follow the pattern of other l2c_* functions.
Fix this so that it does to avoid future confusion.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mm/cache-l2x0.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 977eb9f4f77e..2864a7bcc24b 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -110,15 +110,7 @@ static inline void l2c_unlock(void __iomem *base, unsigned num)
static void l2c_configure(void __iomem *base)
{
- if (outer_cache.configure) {
- outer_cache.configure(&l2x0_saved_regs);
- return;
- }
-
l2c_write_sec(l2x0_saved_regs.aux_ctrl, base, L2X0_AUX_CTRL);
-
- if (l2x0_data->configure)
- l2x0_data->configure(base);
}
/*
@@ -130,7 +122,11 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
unsigned long flags;
l2x0_saved_regs.aux_ctrl = aux;
- l2c_configure(base);
+
+ if (outer_cache.configure)
+ outer_cache.configure(&l2x0_saved_regs);
+ else
+ l2x0_data->configure(base);
l2c_unlock(base, num_lock);
@@ -252,6 +248,7 @@ static const struct l2c_init_data l2c210_data __initconst = {
.num_lock = 1,
.enable = l2c_enable,
.save = l2c_save,
+ .configure = l2c_configure,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -409,6 +406,7 @@ static const struct l2c_init_data l2c220_data = {
.num_lock = 1,
.enable = l2c220_enable,
.save = l2c_save,
+ .configure = l2c_configure,
.outer_cache = {
.inv_range = l2c220_inv_range,
.clean_range = l2c220_clean_range,
@@ -569,6 +567,8 @@ static void l2c310_configure(void __iomem *base)
{
unsigned revision;
+ l2c_configure(base);
+
/* restore pl310 setup */
l2c_write_sec(l2x0_saved_regs.tag_latency, base,
L310_TAG_LATENCY_CTRL);
@@ -1066,6 +1066,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
.of_parse = l2x0_of_parse,
.enable = l2c_enable,
.save = l2c_save,
+ .configure = l2c_configure,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -1084,6 +1085,7 @@ static const struct l2c_init_data of_l2c220_data __initconst = {
.of_parse = l2x0_of_parse,
.enable = l2c220_enable,
.save = l2c_save,
+ .configure = l2c_configure,
.outer_cache = {
.inv_range = l2c220_inv_range,
.clean_range = l2c220_clean_range,
@@ -1416,6 +1418,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
.enable = l2c_enable,
.fixup = aurora_fixup,
.save = aurora_save,
+ .configure = l2c_configure,
.outer_cache = {
.inv_range = aurora_inv_range,
.clean_range = aurora_clean_range,
@@ -1435,6 +1438,7 @@ static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
.enable = aurora_enable_no_outer,
.fixup = aurora_fixup,
.save = aurora_save,
+ .configure = l2c_configure,
.outer_cache = {
.resume = l2c_resume,
},
@@ -1608,6 +1612,7 @@ static void __init tauros3_save(void __iomem *base)
static void tauros3_configure(void __iomem *base)
{
+ l2c_configure(base);
writel_relaxed(l2x0_saved_regs.aux2_ctrl,
base + TAUROS3_AUX2_CTRL);
writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
--
2.1.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/5] ARM: l2c: only unlock caches if NS_LOCKDOWN bit is set
2015-05-27 13:00 ` Sjoerd Simons
` (2 preceding siblings ...)
2015-05-27 17:40 ` [PATCH 3/5] ARM: l2c: clean up l2c_configure() Russell King
@ 2015-05-27 17:40 ` Russell King
2015-05-27 17:40 ` [PATCH 5/5] ARM: l2c: avoid passing auxiliary control register through enable method Russell King
2015-05-27 17:41 ` [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock Russell King - ARM Linux
5 siblings, 0 replies; 11+ messages in thread
From: Russell King @ 2015-05-27 17:40 UTC (permalink / raw)
To: linux-arm-kernel
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(-)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 2864a7bcc24b..95f33620353b 100644
--- 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 *base, u32 aux, unsigned num_lock)
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_data __initconst = {
.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 *base, u32 aux, unsigned num_lock)
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_data = {
.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_init_fns __initconst = {
.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_l2c210_data __initconst = {
.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_l2c220_data __initconst = {
.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_l2c310_data __initconst = {
.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_l2c310_coherent_data __initconst = {
.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_aurora_with_outer_data __initconst = {
.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_aurora_no_outer_data __initconst = {
.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_l2x0_data __initconst = {
.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_tauros3_data __initconst = {
.enable = l2c_enable,
.save = tauros3_save,
.configure = tauros3_configure,
+ .unlock = l2c_unlock,
/* Tauros3 broadcasts L1 cache operations to L2 */
.outer_cache = {
.resume = l2c_resume,
--
2.1.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/5] ARM: l2c: avoid passing auxiliary control register through enable method
2015-05-27 13:00 ` Sjoerd Simons
` (3 preceding siblings ...)
2015-05-27 17:40 ` [PATCH 4/5] ARM: l2c: only unlock caches if NS_LOCKDOWN bit is set Russell King
@ 2015-05-27 17:40 ` Russell King
2015-05-27 17:41 ` [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock Russell King - ARM Linux
5 siblings, 0 replies; 11+ messages in thread
From: Russell King @ 2015-05-27 17:40 UTC (permalink / raw)
To: linux-arm-kernel
Avoid passing the auxiliary control register value through the enable
method. In the resume path, we have to read the value stored in
l2x0_saved_regs.aux_ctrl, only to have it immediately written back by
l2c_enable(). We can avoid this if we have __l2c_init() save the value
directly to l2x0_saved_regs.aux_ctrl before calling the specific enable
method.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mm/cache-l2x0.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 95f33620353b..90599f60ff02 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -38,7 +38,7 @@ struct l2c_init_data {
unsigned way_size_0;
unsigned num_lock;
void (*of_parse)(const struct device_node *, u32 *, u32 *);
- void (*enable)(void __iomem *, u32, unsigned);
+ void (*enable)(void __iomem *, unsigned);
void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
void (*save)(void __iomem *);
void (*configure)(void __iomem *);
@@ -118,12 +118,10 @@ static void l2c_configure(void __iomem *base)
* Enable the L2 cache controller. This function must only be
* called when the cache controller is known to be disabled.
*/
-static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
+static void l2c_enable(void __iomem *base, unsigned num_lock)
{
unsigned long flags;
- l2x0_saved_regs.aux_ctrl = aux;
-
if (outer_cache.configure)
outer_cache.configure(&l2x0_saved_regs);
else
@@ -160,7 +158,7 @@ static void l2c_resume(void)
/* Do not touch the controller if already enabled. */
if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
- l2c_enable(base, l2x0_saved_regs.aux_ctrl, l2x0_data->num_lock);
+ l2c_enable(base, l2x0_data->num_lock);
}
/*
@@ -390,16 +388,16 @@ static void l2c220_sync(void)
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
}
-static void l2c220_enable(void __iomem *base, u32 aux, unsigned num_lock)
+static void l2c220_enable(void __iomem *base, unsigned num_lock)
{
/*
* Always enable non-secure access to the lockdown registers -
* we write to them as part of the L2C enable sequence so they
* need to be accessible.
*/
- aux |= L220_AUX_CTRL_NS_LOCKDOWN;
+ l2x0_saved_regs.aux_ctrl |= L220_AUX_CTRL_NS_LOCKDOWN;
- l2c_enable(base, aux, num_lock);
+ l2c_enable(base, num_lock);
}
static void l2c220_unlock(void __iomem *base, unsigned num_lock)
@@ -612,10 +610,11 @@ static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, v
return NOTIFY_OK;
}
-static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
+static void __init l2c310_enable(void __iomem *base, unsigned num_lock)
{
unsigned rev = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_RTL_MASK;
bool cortex_a9 = read_cpuid_part() == ARM_CPU_PART_CORTEX_A9;
+ u32 aux = l2x0_saved_regs.aux_ctrl;
if (rev >= L310_CACHE_ID_RTL_R2P0) {
if (cortex_a9) {
@@ -658,9 +657,9 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
* we write to them as part of the L2C enable sequence so they
* need to be accessible.
*/
- aux |= L310_AUX_CTRL_NS_LOCKDOWN;
+ l2x0_saved_regs.aux_ctrl = aux | L310_AUX_CTRL_NS_LOCKDOWN;
- l2c_enable(base, aux, num_lock);
+ l2c_enable(base, num_lock);
/* Read back resulting AUX_CTRL value as it could have been altered. */
aux = readl_relaxed(base + L2X0_AUX_CTRL);
@@ -872,8 +871,11 @@ static int __init __l2c_init(const struct l2c_init_data *data,
* Check if l2x0 controller is already enabled. If we are booting
* in non-secure mode accessing the below registers will fault.
*/
- if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
- data->enable(l2x0_base, aux, data->num_lock);
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ l2x0_saved_regs.aux_ctrl = aux;
+
+ data->enable(l2x0_base, data->num_lock);
+ }
outer_cache = fns;
@@ -1388,7 +1390,7 @@ static void aurora_save(void __iomem *base)
* For Aurora cache in no outer mode, enable via the CP15 coprocessor
* broadcasting of cache commands to L2.
*/
-static void __init aurora_enable_no_outer(void __iomem *base, u32 aux,
+static void __init aurora_enable_no_outer(void __iomem *base,
unsigned num_lock)
{
u32 u;
@@ -1399,7 +1401,7 @@ static void __init aurora_enable_no_outer(void __iomem *base, u32 aux,
isb();
- l2c_enable(base, aux, num_lock);
+ l2c_enable(base, num_lock);
}
static void __init aurora_fixup(void __iomem *base, u32 cache_id,
--
2.1.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock
2015-05-27 13:00 ` Sjoerd Simons
` (4 preceding siblings ...)
2015-05-27 17:40 ` [PATCH 5/5] ARM: l2c: avoid passing auxiliary control register through enable method Russell King
@ 2015-05-27 17:41 ` Russell King - ARM Linux
5 siblings, 0 replies; 11+ messages in thread
From: Russell King - ARM Linux @ 2015-05-27 17:41 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, May 27, 2015 at 03:00:13PM +0200, Sjoerd Simons wrote:
> Hey Russell,
>
> On Fri, 2015-05-15 at 12:34 +0100, Russell King - ARM Linux wrote:
> > On Tue, May 12, 2015 at 09:39:14AM +0200, Sjoerd Simons wrote:
> > > To handle that, for caches where special configuration is needed to allow
> > > unlocking, check whether this has been setup before unlocking.
> >
> > I've come up with a different solution to this, which of course I prefer.
> > I'll post the patches later today, thanks.
>
> Did you get round to create/posting those patches? If not, i'm happy to
> do a set with your suggested solution as well if you can point me in the
> right direction :)
Expect some to fall into your mailbox imminently. Sorry, once an email
gets buried, it gets forgotten about. :p
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-05-27 17:41 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-12 7:39 [PATCH 0/2 v2] Fix boot on Calxeda highbank Sjoerd Simons
2015-05-12 7:39 ` [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock Sjoerd Simons
2015-05-15 11:34 ` Russell King - ARM Linux
2015-05-27 13:00 ` Sjoerd Simons
2015-05-27 17:40 ` [PATCH 1/5] ARM: l2c: restore the behaviour documented above l2c_enable() Russell King
2015-05-27 17:40 ` [PATCH 2/5] ARM: l2c: write auxiliary control register first Russell King
2015-05-27 17:40 ` [PATCH 3/5] ARM: l2c: clean up l2c_configure() Russell King
2015-05-27 17:40 ` [PATCH 4/5] ARM: l2c: only unlock caches if NS_LOCKDOWN bit is set Russell King
2015-05-27 17:40 ` [PATCH 5/5] ARM: l2c: avoid passing auxiliary control register through enable method Russell King
2015-05-27 17:41 ` [PATCH 1/2] ARM: cache-l2c: Detect whether it's safe to unlock Russell King - ARM Linux
2015-05-12 7:39 ` [PATCH 2/2] ARM: l2c: highbank: Add dummy configure function Sjoerd Simons
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).