2014-04-21 21:53:21

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 00/10] ARM: bcm: SCM and L2 cache code cleanup

This series cleans up a number of things in the code that issues
secure monitor ("smc") requests for the bcm281xx and bcm21664 SoC
families. This code is currently used only for enabling the level-2
cache.

There are some bug fixes and other improvements. An assembly
language file containing a single function has been eliminated by
re-implementing the code using inline assembly. Some comments have
been expanded and clarified. Kernel configuration options allow
finer-grained control over how this code gets built. Finally, the
"kona.c" and "kona.h" files are renamed to reflect the fact that
only contain code related to level-2 cache support.

This series is based on v3.15-rc2, and depends on one patch posted
previously:
[PATCH v4] mach-bcm: clean up config and build targets
https://lkml.org/lkml/2014/4/15/303

It is available here:
http://git.linaro.org/landing-teams/working/broadcom/kernel.git
Branch review/bcm-smc-cleanup-v2

-Alex

History:
v2: - Followed two suggestions from Russell King. Rebased to v3.15-rc2

Alex Elder (10):
ARM: bcm: use memory accessors for ioremapped area
ARM: bcm: err, don't BUG() on SMC init failures
ARM: bcm: clean up SMC code
ARM: bcm: have bcm_kona_smc() return request result
ARM: bcm: don't special-case CPU 0 in bcm_kona_smc()
ARM: bcm: config option for l2 cache support
ARM: bcm: tidy up a few includes
ARM: bcm: use inline assembly for "smc" request
ARM: bcm: rewrite commentary for bcm_kona_do_smc()
ARM: bcm: rename "kona.h" and "kona.c"

arch/arm/mach-bcm/Kconfig | 12 ++-
arch/arm/mach-bcm/Makefile | 10 +-
arch/arm/mach-bcm/bcm_kona_smc.c | 136 +++++++++++++++++++-------
arch/arm/mach-bcm/bcm_kona_smc.h | 52 +---------
arch/arm/mach-bcm/bcm_kona_smc_asm.S | 41 --------
arch/arm/mach-bcm/board_bcm21664.c | 5 +-
arch/arm/mach-bcm/board_bcm281xx.c | 2 +-
arch/arm/mach-bcm/{kona.c => kona_l2_cache.c} | 16 +--
arch/arm/mach-bcm/{kona.h => kona_l2_cache.h} | 6 +-
9 files changed, 136 insertions(+), 144 deletions(-)
delete mode 100644 arch/arm/mach-bcm/bcm_kona_smc_asm.S
rename arch/arm/mach-bcm/{kona.c => kona_l2_cache.c} (80%)
rename arch/arm/mach-bcm/{kona.h => kona_l2_cache.h} (80%)

--
1.9.1


2014-04-21 21:53:39

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 06/10] ARM: bcm: config option for l2 cache support

Add a new config option ARCH_BCM_MOBILE_L2_CACHE that allows support
for level-2 cache to be enabled or disabled at build time for
BCM218XX and BCM21664 family SoCs.

Build support for SMC only if it's required (currently it's only
required for to support level 2 cache control).

If arch/arm/mach-bcm/kona.c gets compiled, ARCH_BCM_MOBILE_L2_CACHE
must have been selected, which implies CONFIG_CACHE_L2X0 is set.
There is therefore no need to check CONFIG_CACHE_L2X0 at the top
of kona_l2_cache_init(), so get rid of that check.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/Kconfig | 12 +++++++++++-
arch/arm/mach-bcm/Makefile | 5 ++++-
arch/arm/mach-bcm/kona.c | 3 ---
arch/arm/mach-bcm/kona.h | 5 +++++
4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 5f5740f..28f90a0 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -18,7 +18,6 @@ config ARCH_BCM_MOBILE
select ARM_GIC
select GPIO_BCM_KONA
select TICK_ONESHOT
- select CACHE_L2X0
select HAVE_ARM_ARCH_TIMER
select PINCTRL
help
@@ -43,6 +42,17 @@ config ARCH_BCM_21664
Enable support for the the BCM21664 family, which includes
BCM21663 and BCM21664 variants.

+config ARCH_BCM_MOBILE_L2_CACHE
+ bool "Broadcom mobile SoC level 2 cache support"
+ depends on (ARCH_BCM_281XX || ARCH_BCM_21664)
+ default y
+ select CACHE_L2X0
+ select ARCH_BCM_MOBILE_SMC
+
+config ARCH_BCM_MOBILE_SMC
+ bool
+ depends on ARCH_BCM_281XX || ARCH_BCM_21664
+
endmenu

endif
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 7fb9b04..5154981 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -17,7 +17,10 @@ obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o

# BCM281XX and BCM21664 L2 cache control
-obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_smc.o bcm_kona_smc_asm.o kona.o
+obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona.o
+
+# Support for secure monitor traps
+obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o bcm_kona_smc_asm.o
plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec)

diff --git a/arch/arm/mach-bcm/kona.c b/arch/arm/mach-bcm/kona.c
index ecdd713..60b5dd5 100644
--- a/arch/arm/mach-bcm/kona.c
+++ b/arch/arm/mach-bcm/kona.c
@@ -22,9 +22,6 @@ void __init kona_l2_cache_init(void)
unsigned int result;
int ret;

- if (!IS_ENABLED(CONFIG_CACHE_L2X0))
- return;
-
ret = bcm_kona_smc_init();
if (ret) {
pr_info("Secure API not available (%d). Skipping L2 init.\n",
diff --git a/arch/arm/mach-bcm/kona.h b/arch/arm/mach-bcm/kona.h
index 3a7a017..110185f 100644
--- a/arch/arm/mach-bcm/kona.h
+++ b/arch/arm/mach-bcm/kona.h
@@ -11,4 +11,9 @@
* GNU General Public License for more details.
*/

+#ifdef CONFIG_ARCH_BCM_MOBILE_L2_CACHE
+
void __init kona_l2_cache_init(void);
+#else
+#define kona_l2_cache_init() ((void)0)
+#endif
--
1.9.1

2014-04-21 21:53:27

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 02/10] ARM: bcm: err, don't BUG() on SMC init failures

Several conditions in bcm_kona_smc_init() are handled with BUG_ON().
That function is capable of returning an error, so do that instead.

Also, don't assume of_get_address() returns a valid pointer.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/bcm_kona_smc.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
index d881c72..ddc2f17 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.c
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -45,6 +45,7 @@ static const struct of_device_id bcm_kona_smc_ids[] __initconst = {
int __init bcm_kona_smc_init(void)
{
struct device_node *node;
+ const __be32 *prop_val;

/* Read buffer addr and size from the device tree node */
node = of_find_matching_node(NULL, bcm_kona_smc_ids);
@@ -52,12 +53,17 @@ int __init bcm_kona_smc_init(void)
return -ENODEV;

/* Don't care about size or flags of the DT node */
- bridge_data.buffer_addr =
- be32_to_cpu(*of_get_address(node, 0, NULL, NULL));
- BUG_ON(!bridge_data.buffer_addr);
+ prop_val = of_get_address(node, 0, NULL, NULL);
+ if (!prop_val)
+ return -EINVAL;
+
+ bridge_data.buffer_addr = be32_to_cpu(*prop_val);
+ if (!bridge_data.buffer_addr)
+ return -EINVAL;

bridge_data.bounce = of_iomap(node, 0);
- BUG_ON(!bridge_data.bounce);
+ if (!bridge_data.bounce)
+ return -ENOMEM;

bridge_data.initialized = 1;

--
1.9.1

2014-04-21 21:53:49

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 09/10] ARM: bcm: rewrite commentary for bcm_kona_do_smc()

The block of comments in bcm_kona_do_smc() are somewhat confusing.
This patch attempts to clarify what's going on.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/bcm_kona_smc.c | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
index cc81c86..a55a7ec 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.c
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -77,16 +77,34 @@ int __init bcm_kona_smc_init(void)
}

/*
- * Since interrupts are disabled in the open mode, we must keep
- * interrupts disabled in secure mode by setting R5=0x3. If interrupts
- * are enabled in open mode, we can set R5=0x0 to allow interrupts in
- * secure mode. If we did this, the secure monitor would return back
- * control to the open mode to handle the interrupt prior to completing
- * the secure service. If this happened, R12 would not be
- * SEC_EXIT_NORMAL and we would need to call SMC again after resetting
- * R5 (it gets clobbered by the secure monitor) and setting R4 to
- * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor
- * to finish up the previous uncompleted secure service.
+ * int bcm_kona_do_smc(u32 service_id, u32 buffer_addr)
+ *
+ * Only core 0 can run the secure monitor code. If an "smc" request
+ * is initiated on a different core it must be redirected to core 0
+ * for execution. We rely on the caller to handle this.
+ *
+ * Each "smc" request supplies a service id and the address of a
+ * buffer containing parameters related to the service to be
+ * performed. A flags value defines the behavior of the level 2
+ * cache and interrupt handling while the secure monitor executes.
+ *
+ * Parameters to the "smc" request are passed in r4-r6 as follows:
+ * r4 service id
+ * r5 flags (SEC_ROM_*)
+ * r6 physical address of buffer with other parameters
+ *
+ * Execution of an "smc" request produces two distinct results.
+ *
+ * First, the secure monitor call itself (regardless of the specific
+ * service request) can succeed, or can produce an error. When an
+ * "smc" request completes this value is found in r12; it should
+ * always be SEC_EXIT_NORMAL.
+ *
+ * In addition, the particular service performed produces a result.
+ * The values that should be expected depend on the service. We
+ * therefore return this value to the caller, so it can handle the
+ * request result appropriately. This result value is found in r0
+ * when the "smc" request completes.
*/
static int bcm_kona_do_smc(u32 service_id, u32 buffer_phys)
{
--
1.9.1

2014-04-21 21:53:51

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 08/10] ARM: bcm: use inline assembly for "smc" request

Move the code that implements the "smc" call into a C function that
uses inline assembly. This allows us to make that function private,
and enables us to get rid of "arch/arm/mach-bcm/bcm_kona_smc_asm.S".
Rename what had been the "buffer_addr" argument to be "buffer_phys"
so it's consistent with other usage in this file.

Since it's now easy to do, verify that r12 contains SEC_EXIT_NORMAL
upon completion of the SMC. There really isn't a good way to handle
the abnormal completion of a secure monitor request.

Since "bcm_kona_smc.h" is now only included from C files, eliminate
the #ifndef __ASSEMBLY__.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/Makefile | 7 +++---
arch/arm/mach-bcm/bcm_kona_smc.c | 46 +++++++++++++++++++++++++++++++++++-
arch/arm/mach-bcm/bcm_kona_smc.h | 6 -----
arch/arm/mach-bcm/bcm_kona_smc_asm.S | 41 --------------------------------
4 files changed, 49 insertions(+), 51 deletions(-)
delete mode 100644 arch/arm/mach-bcm/bcm_kona_smc_asm.S

diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 5154981..d5b60fe 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -20,9 +20,10 @@ obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o
obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona.o

# Support for secure monitor traps
-obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o bcm_kona_smc_asm.o
-plus_sec := $(call as-instr,.arch_extension sec,+sec)
-AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec)
+obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o
+ifeq ($(call as-instr,.arch_extension sec,as_has_sec),as_has_sec)
+CFLAGS_bcm_kona_smc.o += -Wa,-march=armv7-a+sec -DREQUIRES_SEC
+endif

# BCM2835
obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
index 6fdcf96..cc81c86 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.c
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -76,6 +76,50 @@ int __init bcm_kona_smc_init(void)
return 0;
}

+/*
+ * Since interrupts are disabled in the open mode, we must keep
+ * interrupts disabled in secure mode by setting R5=0x3. If interrupts
+ * are enabled in open mode, we can set R5=0x0 to allow interrupts in
+ * secure mode. If we did this, the secure monitor would return back
+ * control to the open mode to handle the interrupt prior to completing
+ * the secure service. If this happened, R12 would not be
+ * SEC_EXIT_NORMAL and we would need to call SMC again after resetting
+ * R5 (it gets clobbered by the secure monitor) and setting R4 to
+ * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor
+ * to finish up the previous uncompleted secure service.
+ */
+static int bcm_kona_do_smc(u32 service_id, u32 buffer_phys)
+{
+ register u32 ip asm("ip"); /* Also called r12 */
+ register u32 r0 asm("r0");
+ register u32 r4 asm("r4");
+ register u32 r5 asm("r5");
+ register u32 r6 asm("r6");
+
+ r4 = service_id;
+ r5 = 0x3; /* Keep IRQ and FIQ off in SM */
+ r6 = buffer_phys;
+
+ asm volatile (
+ /* Make sure we got the registers we want */
+ __asmeq("%0", "ip")
+ __asmeq("%1", "r0")
+ __asmeq("%2", "r4")
+ __asmeq("%3", "r5")
+ __asmeq("%4", "r6")
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ " smc #0\n"
+ : "=r" (ip), "=r" (r0)
+ : "r" (r4), "r" (r5), "r" (r6)
+ : "r1", "r2", "r3", "r7", "lr");
+
+ BUG_ON(ip != SEC_EXIT_NORMAL);
+
+ return r0;
+}
+
/* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */
static void __bcm_kona_smc(void *info)
{
@@ -95,7 +139,7 @@ static void __bcm_kona_smc(void *info)
flush_cache_all();

/* Trap into Secure Monitor and record the request result */
- data->result = bcm_kona_smc_asm(data->service_id, bcm_smc_buffer_phys);
+ data->result = bcm_kona_do_smc(data->service_id, bcm_smc_buffer_phys);
}

unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.h b/arch/arm/mach-bcm/bcm_kona_smc.h
index 629e64a..2e29ec6 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.h
+++ b/arch/arm/mach-bcm/bcm_kona_smc.h
@@ -21,7 +21,6 @@
#define SEC_ROM_RET_OK 0x00000001
#define SEC_EXIT_NORMAL 0x1

-#ifndef __ASSEMBLY__
extern int __init bcm_kona_smc_init(void);

extern unsigned bcm_kona_smc(unsigned service_id,
@@ -30,9 +29,4 @@ extern unsigned bcm_kona_smc(unsigned service_id,
unsigned arg2,
unsigned arg3);

-extern int bcm_kona_smc_asm(u32 service_id,
- u32 buffer_addr);
-
-#endif /* __ASSEMBLY__ */
-
#endif /* BCM_KONA_SMC_H */
diff --git a/arch/arm/mach-bcm/bcm_kona_smc_asm.S b/arch/arm/mach-bcm/bcm_kona_smc_asm.S
deleted file mode 100644
index a160848..0000000
--- a/arch/arm/mach-bcm/bcm_kona_smc_asm.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2013 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/linkage.h>
-#include "bcm_kona_smc.h"
-
-/*
- * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr)
- */
-
-ENTRY(bcm_kona_smc_asm)
- stmfd sp!, {r4-r12, lr}
- mov r4, r0 @ service_id
- mov r5, #3 @ Keep IRQ and FIQ off in SM
- /*
- * Since interrupts are disabled in the open mode, we must keep
- * interrupts disabled in secure mode by setting R5=0x3. If interrupts
- * are enabled in open mode, we can set R5=0x0 to allow interrupts in
- * secure mode. If we did this, the secure monitor would return back
- * control to the open mode to handle the interrupt prior to completing
- * the secure service. If this happened, R12 would not be
- * SEC_EXIT_NORMAL and we would need to call SMC again after resetting
- * R5 (it gets clobbered by the secure monitor) and setting R4 to
- * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor
- * to finish up the previous uncompleted secure service.
- */
- mov r6, r1 @ buffer_addr
- smc #0
- /* Check r12 for SEC_EXIT_NORMAL here if interrupts are enabled */
- ldmfd sp!, {r4-r12, pc}
-ENDPROC(bcm_kona_smc_asm)
--
1.9.1

2014-04-21 21:54:33

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 10/10] ARM: bcm: rename "kona.h" and "kona.c"

These source files contain only level-2 cache initialization code,
so rename them to make that fact more obvious.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/Makefile | 2 +-
arch/arm/mach-bcm/board_bcm21664.c | 2 +-
arch/arm/mach-bcm/board_bcm281xx.c | 2 +-
arch/arm/mach-bcm/{kona.c => kona_l2_cache.c} | 0
arch/arm/mach-bcm/{kona.h => kona_l2_cache.h} | 0
5 files changed, 3 insertions(+), 3 deletions(-)
rename arch/arm/mach-bcm/{kona.c => kona_l2_cache.c} (100%)
rename arch/arm/mach-bcm/{kona.h => kona_l2_cache.h} (100%)

diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index d5b60fe..7312921 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -17,7 +17,7 @@ obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o

# BCM281XX and BCM21664 L2 cache control
-obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona.o
+obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o

# Support for secure monitor traps
obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o
diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c
index 1091637..f0521cc 100644
--- a/arch/arm/mach-bcm/board_bcm21664.c
+++ b/arch/arm/mach-bcm/board_bcm21664.c
@@ -17,7 +17,7 @@

#include <asm/mach/arch.h>

-#include "kona.h"
+#include "kona_l2_cache.h"

#define RSTMGR_DT_STRING "brcm,bcm21664-resetmgr"

diff --git a/arch/arm/mach-bcm/board_bcm281xx.c b/arch/arm/mach-bcm/board_bcm281xx.c
index 6be54c1..1ac59fc 100644
--- a/arch/arm/mach-bcm/board_bcm281xx.c
+++ b/arch/arm/mach-bcm/board_bcm281xx.c
@@ -17,7 +17,7 @@

#include <asm/mach/arch.h>

-#include "kona.h"
+#include "kona_l2_cache.h"

#define SECWDOG_OFFSET 0x00000000
#define SECWDOG_RESERVED_MASK 0xe2000000
diff --git a/arch/arm/mach-bcm/kona.c b/arch/arm/mach-bcm/kona_l2_cache.c
similarity index 100%
rename from arch/arm/mach-bcm/kona.c
rename to arch/arm/mach-bcm/kona_l2_cache.c
diff --git a/arch/arm/mach-bcm/kona.h b/arch/arm/mach-bcm/kona_l2_cache.h
similarity index 100%
rename from arch/arm/mach-bcm/kona.h
rename to arch/arm/mach-bcm/kona_l2_cache.h
--
1.9.1

2014-04-21 21:55:05

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 07/10] ARM: bcm: tidy up a few includes

Clean up a few header file includes, eliminating a few that are not
really needed and putting in their place some that are.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/board_bcm21664.c | 3 +--
arch/arm/mach-bcm/kona.c | 5 +++--
arch/arm/mach-bcm/kona.h | 3 +--
3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c
index acc1573..1091637 100644
--- a/arch/arm/mach-bcm/board_bcm21664.c
+++ b/arch/arm/mach-bcm/board_bcm21664.c
@@ -11,13 +11,12 @@
* GNU General Public License for more details.
*/

-#include <linux/clocksource.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
+#include <linux/io.h>

#include <asm/mach/arch.h>

-#include "bcm_kona_smc.h"
#include "kona.h"

#define RSTMGR_DT_STRING "brcm,bcm21664-resetmgr"
diff --git a/arch/arm/mach-bcm/kona.c b/arch/arm/mach-bcm/kona.c
index 60b5dd5..b319703 100644
--- a/arch/arm/mach-bcm/kona.c
+++ b/arch/arm/mach-bcm/kona.c
@@ -11,11 +11,12 @@
* GNU General Public License for more details.
*/

-#include <linux/of_platform.h>
+
+#include <linux/init.h>
+#include <linux/printk.h>
#include <asm/hardware/cache-l2x0.h>

#include "bcm_kona_smc.h"
-#include "kona.h"

void __init kona_l2_cache_init(void)
{
diff --git a/arch/arm/mach-bcm/kona.h b/arch/arm/mach-bcm/kona.h
index 110185f..46f84a9 100644
--- a/arch/arm/mach-bcm/kona.h
+++ b/arch/arm/mach-bcm/kona.h
@@ -12,8 +12,7 @@
*/

#ifdef CONFIG_ARCH_BCM_MOBILE_L2_CACHE
-
-void __init kona_l2_cache_init(void);
+void kona_l2_cache_init(void);
#else
#define kona_l2_cache_init() ((void)0)
#endif
--
1.9.1

2014-04-21 21:53:34

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 04/10] ARM: bcm: have bcm_kona_smc() return request result

Currently it is assumed that SEC_ROM_RET_OK is the only valid "good"
result of a secure monitor request. However the values that can be
returned by a secure monitor request are dependent on which service
id was provided.

We therefore should handle the result in a request-dependent way.
The most natural way to do that is to have the initiator of the
request--where bcm_kona_smc() is called--handle the result in a way
appropriate to the request.

An "smc" operation must be performed only on core 0, while the
request can be initiated from any core. To pass back the request
result, we add a new field to the bcm_kona_smc_data structure, and
have bcm_kona_smc() return that value rather than 0.

There's only one caller right now. Move the existing check of the
result out of __bcm_kona_smc() and into the kona_l2_cache_init()
where the SSAPI_ENABLE_L2_CACHE request is initiated.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/bcm_kona_smc.c | 12 +++++-------
arch/arm/mach-bcm/kona.c | 8 +++++++-
2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
index 0d2bfe2..47cf360 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.c
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -30,6 +30,7 @@ struct bcm_kona_smc_data {
unsigned arg1;
unsigned arg2;
unsigned arg3;
+ unsigned result;
};

static const struct of_device_id bcm_kona_smc_ids[] __initconst = {
@@ -80,7 +81,6 @@ static void __bcm_kona_smc(void *info)
{
struct bcm_kona_smc_data *data = info;
u32 *args = bcm_smc_buffer;
- int rc;

BUG_ON(smp_processor_id() != 0);
BUG_ON(!args);
@@ -94,11 +94,8 @@ static void __bcm_kona_smc(void *info)
/* Flush caches for input data passed to Secure Monitor */
flush_cache_all();

- /* Trap into Secure Monitor */
- rc = bcm_kona_smc_asm(data->service_id, bcm_smc_buffer_phys);
-
- if (rc != SEC_ROM_RET_OK)
- pr_err("Secure Monitor call failed (0x%x)!\n", rc);
+ /* Trap into Secure Monitor and record the request result */
+ data->result = bcm_kona_smc_asm(data->service_id, bcm_smc_buffer_phys);
}

unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,
@@ -111,6 +108,7 @@ unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,
data.arg1 = arg1;
data.arg2 = arg2;
data.arg3 = arg3;
+ data.result = 0;

/*
* Due to a limitation of the secure monitor, we must use the SMP
@@ -123,5 +121,5 @@ unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,

put_cpu();

- return 0;
+ return data.result;
}
diff --git a/arch/arm/mach-bcm/kona.c b/arch/arm/mach-bcm/kona.c
index 768bc28..ecdd713 100644
--- a/arch/arm/mach-bcm/kona.c
+++ b/arch/arm/mach-bcm/kona.c
@@ -19,6 +19,7 @@

void __init kona_l2_cache_init(void)
{
+ unsigned int result;
int ret;

if (!IS_ENABLED(CONFIG_CACHE_L2X0))
@@ -31,7 +32,12 @@ void __init kona_l2_cache_init(void)
return;
}

- bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);
+ result = bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);
+ if (result != SEC_ROM_RET_OK) {
+ pr_err("Secure Monitor call failed (%u)! Skipping L2 init.\n",
+ result);
+ return;
+ }

/*
* The aux_val and aux_mask have no effect since L2 cache is already
--
1.9.1

2014-04-21 21:55:45

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 05/10] ARM: bcm: don't special-case CPU 0 in bcm_kona_smc()

There's logic in bcm_kona_smc() to ensure __bcm_kona_smc() gets
called on CPU 0; if already executing on CPU 0, that function is
called directly. The direct call is not protected from interrupts,
however, which is not safe.

Note that smp_call_function_single() is designed to handle the case
where the target cpu is the current one. It also gets a reference
to the CPU and disables IRQs across the call.

So we can simplify things and at the same time be protected against
interrupts by calling smp_call_function_single() unconditionally.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/bcm_kona_smc.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
index 47cf360..6fdcf96 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.c
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -114,12 +114,7 @@ unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1,
* Due to a limitation of the secure monitor, we must use the SMP
* infrastructure to forward all secure monitor calls to Core 0.
*/
- if (get_cpu() != 0)
- smp_call_function_single(0, __bcm_kona_smc, (void *)&data, 1);
- else
- __bcm_kona_smc(&data);
-
- put_cpu();
+ smp_call_function_single(0, __bcm_kona_smc, &data, 1);

return data.result;
}
--
1.9.1

2014-04-21 21:56:22

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 03/10] ARM: bcm: clean up SMC code

This patch just does some simple cleanup in "bcm_kona_smc.c":
- Get rid of the secure_bridge_data structure. Instead, just
define two globals that record the physical and virtual
addresses of the SMC arguments buffer. Use "buffer" instead
of "bounce" in their names. Drop of the erroneous __iomem
annotation for the physical address.
- Get rid of the initialized flag and just use a non-null buffer
address to indicate that.
- Get the size of the memory region when fetching the SMC
arguments buffer location from the device tree. Use it to
call ioremap() directly rather than requiring of_iomap() to
go look it up again.
- Do some additional validation on that memory region size.
- Flush caches unconditionally in __bcm_kona_smc(); nothing
supplies SSAPI_BRCM_START_VC_CORE as a service id.
- Drop a needless initialization of "rc" in __bcm_kona_smc().

It also deletes most of the content of "bcm_kona_smc.h" because it's
never actually used and is of questionable value anyway.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/bcm_kona_smc.c | 45 +++++++++++++++++++--------------------
arch/arm/mach-bcm/bcm_kona_smc.h | 46 ++--------------------------------------
2 files changed, 24 insertions(+), 67 deletions(-)

diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
index ddc2f17..0d2bfe2 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.c
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -21,11 +21,8 @@

#include "bcm_kona_smc.h"

-struct secure_bridge_data {
- void __iomem *bounce; /* virtual address */
- u32 __iomem buffer_addr; /* physical address */
- int initialized;
-} bridge_data;
+static u32 bcm_smc_buffer_phys; /* physical address */
+static void __iomem *bcm_smc_buffer; /* virtual address */

struct bcm_kona_smc_data {
unsigned service_id;
@@ -41,31 +38,37 @@ static const struct of_device_id bcm_kona_smc_ids[] __initconst = {
{},
};

-/* Map in the bounce area */
+/* Map in the args buffer area */
int __init bcm_kona_smc_init(void)
{
struct device_node *node;
const __be32 *prop_val;
+ u64 prop_size = 0;
+ unsigned long buffer_size;
+ u32 buffer_phys;

/* Read buffer addr and size from the device tree node */
node = of_find_matching_node(NULL, bcm_kona_smc_ids);
if (!node)
return -ENODEV;

- /* Don't care about size or flags of the DT node */
- prop_val = of_get_address(node, 0, NULL, NULL);
+ prop_val = of_get_address(node, 0, &prop_size, NULL);
if (!prop_val)
return -EINVAL;

- bridge_data.buffer_addr = be32_to_cpu(*prop_val);
- if (!bridge_data.buffer_addr)
+ /* We assume space for four 32-bit arguments */
+ if (prop_size < 4 * sizeof(u32) || prop_size > (u64)ULONG_MAX)
return -EINVAL;
+ buffer_size = (unsigned long)prop_size;

- bridge_data.bounce = of_iomap(node, 0);
- if (!bridge_data.bounce)
+ buffer_phys = be32_to_cpup(prop_val);
+ if (!buffer_phys)
+ return -EINVAL;
+
+ bcm_smc_buffer = ioremap(buffer_phys, buffer_size);
+ if (!bcm_smc_buffer)
return -ENOMEM;
-
- bridge_data.initialized = 1;
+ bcm_smc_buffer_phys = buffer_phys;

pr_info("Kona Secure API initialized\n");

@@ -76,14 +79,11 @@ int __init bcm_kona_smc_init(void)
static void __bcm_kona_smc(void *info)
{
struct bcm_kona_smc_data *data = info;
- u32 *args = bridge_data.bounce;
- int rc = 0;
+ u32 *args = bcm_smc_buffer;
+ int rc;

- /* Must run on CPU 0 */
BUG_ON(smp_processor_id() != 0);
-
- /* Check map in the bounce area */
- BUG_ON(!bridge_data.initialized);
+ BUG_ON(!args);

/* Copy the four 32 bit argument values into the bounce area */
writel_relaxed(data->arg0, args++);
@@ -92,11 +92,10 @@ static void __bcm_kona_smc(void *info)
writel(data->arg3, args);

/* Flush caches for input data passed to Secure Monitor */
- if (data->service_id != SSAPI_BRCM_START_VC_CORE)
- flush_cache_all();
+ flush_cache_all();

/* Trap into Secure Monitor */
- rc = bcm_kona_smc_asm(data->service_id, bridge_data.buffer_addr);
+ rc = bcm_kona_smc_asm(data->service_id, bcm_smc_buffer_phys);

if (rc != SEC_ROM_RET_OK)
pr_err("Secure Monitor call failed (0x%x)!\n", rc);
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.h b/arch/arm/mach-bcm/bcm_kona_smc.h
index d098a7e..629e64a 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.h
+++ b/arch/arm/mach-bcm/bcm_kona_smc.h
@@ -15,54 +15,12 @@
#define BCM_KONA_SMC_H

#include <linux/types.h>
-#define FLAGS (SEC_ROM_ICACHE_ENABLE_MASK | SEC_ROM_DCACHE_ENABLE_MASK | \
- SEC_ROM_IRQ_ENABLE_MASK | SEC_ROM_FIQ_ENABLE_MASK)

-/*!
- * Definitions for IRQ & FIQ Mask for ARM
- */
-
-#define FIQ_IRQ_MASK 0xC0
-#define FIQ_MASK 0x40
-#define IRQ_MASK 0x80
-
-/*!
- * Secure Mode FLAGs
- */
-
-/* When set, enables ICache within the secure mode */
-#define SEC_ROM_ICACHE_ENABLE_MASK 0x00000001
-
-/* When set, enables DCache within the secure mode */
-#define SEC_ROM_DCACHE_ENABLE_MASK 0x00000002
-
-/* When set, enables IRQ within the secure mode */
-#define SEC_ROM_IRQ_ENABLE_MASK 0x00000004
-
-/* When set, enables FIQ within the secure mode */
-#define SEC_ROM_FIQ_ENABLE_MASK 0x00000008
-
-/* When set, enables Unified L2 cache within the secure mode */
-#define SEC_ROM_UL2_CACHE_ENABLE_MASK 0x00000010
-
-/* Broadcom Secure Service API Service IDs */
-#define SSAPI_DORMANT_ENTRY_SERV 0x01000000
-#define SSAPI_PUBLIC_OTP_SERV 0x01000001
-#define SSAPI_ENABLE_L2_CACHE 0x01000002
-#define SSAPI_DISABLE_L2_CACHE 0x01000003
-#define SSAPI_WRITE_SCU_STATUS 0x01000004
-#define SSAPI_WRITE_PWR_GATE 0x01000005
-
-/* Broadcom Secure Service API Return Codes */
+/* Broadcom Secure Service API service IDs, return codes, and exit codes */
+#define SSAPI_ENABLE_L2_CACHE 0x01000002
#define SEC_ROM_RET_OK 0x00000001
-#define SEC_ROM_RET_FAIL 0x00000009
-
-#define SSAPI_RET_FROM_INT_SERV 0x4
#define SEC_EXIT_NORMAL 0x1

-#define SSAPI_ROW_AES 0x0E000006
-#define SSAPI_BRCM_START_VC_CORE 0x0E000008
-
#ifndef __ASSEMBLY__
extern int __init bcm_kona_smc_init(void);

--
1.9.1

2014-04-21 21:56:49

by Alex Elder

[permalink] [raw]
Subject: [PATCH v2 01/10] ARM: bcm: use memory accessors for ioremapped area

The pointer used to pass parameters to an "smc" call is produced
through a call to ioremap(). As such, we should be using functions
like writel() to access it.

Signed-off-by: Alex Elder <[email protected]>
Reviewed-by: Tim Kryger <[email protected]>
Reviewed-by: Markus Mayer <[email protected]>
Reviewed-by: Matt Porter <[email protected]>
---
arch/arm/mach-bcm/bcm_kona_smc.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
index 5e31e91..d881c72 100644
--- a/arch/arm/mach-bcm/bcm_kona_smc.c
+++ b/arch/arm/mach-bcm/bcm_kona_smc.c
@@ -79,11 +79,11 @@ static void __bcm_kona_smc(void *info)
/* Check map in the bounce area */
BUG_ON(!bridge_data.initialized);

- /* Copy one 32 bit word into the bounce area */
- args[0] = data->arg0;
- args[1] = data->arg1;
- args[2] = data->arg2;
- args[3] = data->arg3;
+ /* Copy the four 32 bit argument values into the bounce area */
+ writel_relaxed(data->arg0, args++);
+ writel_relaxed(data->arg1, args++);
+ writel_relaxed(data->arg2, args++);
+ writel(data->arg3, args);

/* Flush caches for input data passed to Secure Monitor */
if (data->service_id != SSAPI_BRCM_START_VC_CORE)
--
1.9.1

2014-04-25 13:51:47

by Matt Porter

[permalink] [raw]
Subject: Re: [PATCH v2 00/10] ARM: bcm: SCM and L2 cache code cleanup

On Mon, Apr 21, 2014 at 04:53:01PM -0500, Alex Elder wrote:
> This series cleans up a number of things in the code that issues
> secure monitor ("smc") requests for the bcm281xx and bcm21664 SoC
> families. This code is currently used only for enabling the level-2
> cache.
>
> There are some bug fixes and other improvements. An assembly
> language file containing a single function has been eliminated by
> re-implementing the code using inline assembly. Some comments have
> been expanded and clarified. Kernel configuration options allow
> finer-grained control over how this code gets built. Finally, the
> "kona.c" and "kona.h" files are renamed to reflect the fact that
> only contain code related to level-2 cache support.

Applied the series to mach-bcm for-3.16/cleanup

Thanks,
Matt

>
> This series is based on v3.15-rc2, and depends on one patch posted
> previously:
> [PATCH v4] mach-bcm: clean up config and build targets
> https://lkml.org/lkml/2014/4/15/303
>
> It is available here:
> http://git.linaro.org/landing-teams/working/broadcom/kernel.git
> Branch review/bcm-smc-cleanup-v2
>
> -Alex
>
> History:
> v2: - Followed two suggestions from Russell King. Rebased to v3.15-rc2
>
> Alex Elder (10):
> ARM: bcm: use memory accessors for ioremapped area
> ARM: bcm: err, don't BUG() on SMC init failures
> ARM: bcm: clean up SMC code
> ARM: bcm: have bcm_kona_smc() return request result
> ARM: bcm: don't special-case CPU 0 in bcm_kona_smc()
> ARM: bcm: config option for l2 cache support
> ARM: bcm: tidy up a few includes
> ARM: bcm: use inline assembly for "smc" request
> ARM: bcm: rewrite commentary for bcm_kona_do_smc()
> ARM: bcm: rename "kona.h" and "kona.c"
>
> arch/arm/mach-bcm/Kconfig | 12 ++-
> arch/arm/mach-bcm/Makefile | 10 +-
> arch/arm/mach-bcm/bcm_kona_smc.c | 136 +++++++++++++++++++-------
> arch/arm/mach-bcm/bcm_kona_smc.h | 52 +---------
> arch/arm/mach-bcm/bcm_kona_smc_asm.S | 41 --------
> arch/arm/mach-bcm/board_bcm21664.c | 5 +-
> arch/arm/mach-bcm/board_bcm281xx.c | 2 +-
> arch/arm/mach-bcm/{kona.c => kona_l2_cache.c} | 16 +--
> arch/arm/mach-bcm/{kona.h => kona_l2_cache.h} | 6 +-
> 9 files changed, 136 insertions(+), 144 deletions(-)
> delete mode 100644 arch/arm/mach-bcm/bcm_kona_smc_asm.S
> rename arch/arm/mach-bcm/{kona.c => kona_l2_cache.c} (80%)
> rename arch/arm/mach-bcm/{kona.h => kona_l2_cache.h} (80%)
>
> --
> 1.9.1
>