aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2013-11-24 01:30:46 -0500
committerStephen Warren <swarren@nvidia.com>2013-12-13 14:50:30 -0500
commitd9a1beaa10e88cdba6fb532d540007c0e2a83686 (patch)
treec0b11d2128ada2f3de7819f3bc77243d87dcafc2 /arch/arm
parent6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae (diff)
ARM: add basic support for Trusted Foundations
Trusted Foundations is a TrustZone-based secure monitor for ARM that can be invoked using the same SMC-based API on supported platforms. This patch adds initial basic support for Trusted Foundations using the ARM firmware API. Current features are limited to the ability to boot secondary processors. Note: The API followed by Trusted Foundations does *not* follow the SMC calling conventions. It has nothing to do with PSCI neither and is only relevant to devices that use Trusted Foundations (like most Tegra-based retail devices). Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Tomasz Figa <t.figa@samsung.com> Reviewed-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/firmware/Kconfig28
-rw-r--r--arch/arm/firmware/Makefile1
-rw-r--r--arch/arm/firmware/trusted_foundations.c81
-rw-r--r--arch/arm/include/asm/trusted_foundations.h67
6 files changed, 180 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c1f1a7eee953..1b715ce03a64 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1053,6 +1053,8 @@ config ARM_TIMER_SP804
1053 select CLKSRC_MMIO 1053 select CLKSRC_MMIO
1054 select CLKSRC_OF if OF 1054 select CLKSRC_OF if OF
1055 1055
1056source "arch/arm/firmware/Kconfig"
1057
1056source arch/arm/mm/Kconfig 1058source arch/arm/mm/Kconfig
1057 1059
1058config ARM_NR_BANKS 1060config ARM_NR_BANKS
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c99b1086d83d..2cb05d4e4230 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -268,6 +268,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/
268core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ 268core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
269core-y += arch/arm/net/ 269core-y += arch/arm/net/
270core-y += arch/arm/crypto/ 270core-y += arch/arm/crypto/
271core-y += arch/arm/firmware/
271core-y += $(machdirs) $(platdirs) 272core-y += $(machdirs) $(platdirs)
272 273
273drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ 274drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
diff --git a/arch/arm/firmware/Kconfig b/arch/arm/firmware/Kconfig
new file mode 100644
index 000000000000..bb00ccf00d66
--- /dev/null
+++ b/arch/arm/firmware/Kconfig
@@ -0,0 +1,28 @@
1config ARCH_SUPPORTS_FIRMWARE
2 bool
3
4config ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
5 bool
6 select ARCH_SUPPORTS_FIRMWARE
7
8menu "Firmware options"
9 depends on ARCH_SUPPORTS_FIRMWARE
10
11config TRUSTED_FOUNDATIONS
12 bool "Trusted Foundations secure monitor support"
13 depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
14 help
15 Some devices (including most Tegra-based consumer devices on the
16 market) are booted with the Trusted Foundations secure monitor
17 active, requiring some core operations to be performed by the secure
18 monitor instead of the kernel.
19
20 This option allows the kernel to invoke the secure monitor whenever
21 required on devices using Trusted Foundations. See
22 arch/arm/include/asm/trusted_foundations.h or the
23 tl,trusted-foundations device tree binding documentation for details
24 on how to use it.
25
26 Say n if you don't know what this is about.
27
28endmenu
diff --git a/arch/arm/firmware/Makefile b/arch/arm/firmware/Makefile
new file mode 100644
index 000000000000..a71f16536b6c
--- /dev/null
+++ b/arch/arm/firmware/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
new file mode 100644
index 000000000000..ef1e3d8f4af0
--- /dev/null
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -0,0 +1,81 @@
1/*
2 * Trusted Foundations support for ARM CPUs
3 *
4 * Copyright (c) 2013, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/of.h>
20#include <asm/firmware.h>
21#include <asm/trusted_foundations.h>
22
23#define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
24
25static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2)
26{
27 asm volatile(
28 ".arch_extension sec\n\t"
29 "stmfd sp!, {r4 - r11, lr}\n\t"
30 __asmeq("%0", "r0")
31 __asmeq("%1", "r1")
32 __asmeq("%2", "r2")
33 "mov r3, #0\n\t"
34 "mov r4, #0\n\t"
35 "smc #0\n\t"
36 "ldmfd sp!, {r4 - r11, pc}"
37 :
38 : "r" (type), "r" (arg1), "r" (arg2)
39 : "memory");
40}
41
42static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
43{
44 tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, boot_addr, 0);
45
46 return 0;
47}
48
49static const struct firmware_ops trusted_foundations_ops = {
50 .set_cpu_boot_addr = tf_set_cpu_boot_addr,
51};
52
53void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
54{
55 /*
56 * we are not using version information for now since currently
57 * supported SMCs are compatible with all TF releases
58 */
59 register_firmware_ops(&trusted_foundations_ops);
60}
61
62void of_register_trusted_foundations(void)
63{
64 struct device_node *node;
65 struct trusted_foundations_platform_data pdata;
66 int err;
67
68 node = of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations");
69 if (!node)
70 return;
71
72 err = of_property_read_u32(node, "tlm,version-major",
73 &pdata.version_major);
74 if (err != 0)
75 panic("Trusted Foundation: missing version-major property\n");
76 err = of_property_read_u32(node, "tlm,version-minor",
77 &pdata.version_minor);
78 if (err != 0)
79 panic("Trusted Foundation: missing version-minor property\n");
80 register_trusted_foundations(&pdata);
81}
diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h
new file mode 100644
index 000000000000..3bd36e2c5f2e
--- /dev/null
+++ b/arch/arm/include/asm/trusted_foundations.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 2013, NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14
15/*
16 * Support for the Trusted Foundations secure monitor.
17 *
18 * Trusted Foundation comes active on some ARM consumer devices (most
19 * Tegra-based devices sold on the market are concerned). Such devices can only
20 * perform some basic operations, like setting the CPU reset vector, through
21 * SMC calls to the secure monitor. The calls are completely specific to
22 * Trusted Foundations, and do *not* follow the SMC calling convention or the
23 * PSCI standard.
24 */
25
26#ifndef __ASM_ARM_TRUSTED_FOUNDATIONS_H
27#define __ASM_ARM_TRUSTED_FOUNDATIONS_H
28
29#include <linux/kconfig.h>
30#include <linux/printk.h>
31#include <linux/bug.h>
32#include <linux/of.h>
33
34struct trusted_foundations_platform_data {
35 unsigned int version_major;
36 unsigned int version_minor;
37};
38
39#if IS_ENABLED(CONFIG_TRUSTED_FOUNDATIONS)
40
41void register_trusted_foundations(struct trusted_foundations_platform_data *pd);
42void of_register_trusted_foundations(void);
43
44#else /* CONFIG_TRUSTED_FOUNDATIONS */
45
46static inline void register_trusted_foundations(
47 struct trusted_foundations_platform_data *pd)
48{
49 /*
50 * If we try to register TF, this means the system needs it to continue.
51 * Its absence if thus a fatal error.
52 */
53 panic("No support for Trusted Foundations, stopping...\n");
54}
55
56static inline void of_register_trusted_foundations(void)
57{
58 /*
59 * If we find the target should enable TF but does not support it,
60 * fail as the system won't be able to do much anyway
61 */
62 if (of_find_compatible_node(NULL, NULL, "tl,trusted-foundations"))
63 register_trusted_foundations(NULL);
64}
65#endif /* CONFIG_TRUSTED_FOUNDATIONS */
66
67#endif