aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rwxr-xr-xarch/arm/mach-ux500/Makefile2
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c2
-rwxr-xr-xarch/arm/mach-ux500/include/mach/hardware.h9
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h7
-rwxr-xr-xarch/arm/mach-ux500/pm.c3
-rw-r--r--arch/arm/mach-ux500/tee_ux500.c66
6 files changed, 87 insertions, 2 deletions
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 3e3d7ad581c..cb341b1e75b 100755
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -35,3 +35,5 @@ obj-y += ste_conn_devices.o
else
obj-$(CONFIG_MFD_STE_CONN) += ste_conn_devices.o
endif
+
+obj-$(CONFIG_TEE_SUPPORT) += tee_ux500.o
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 992c0a1e90a..6fc5ada893d 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -29,9 +29,9 @@ static struct map_desc u8500_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
__IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
__IO_DEV_DESC(U8500_ASIC_ID_BASE, SZ_4K),
- __IO_DEV_DESC(U8500_ICN_BASE, SZ_8K),
{IO_ADDRESS(U8500_BACKUPRAM0_BASE),
__phys_to_pfn(U8500_BACKUPRAM0_BASE), SZ_8K, MT_BACKUP_RAM},
+ __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M),
};
static struct map_desc u8500_ed_io_desc[] __initdata = {
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index a0adb5402ce..ca10b97ebe6 100755
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -169,6 +169,15 @@
#define U8500_DSI_LINK_COUNT 0x3
#define U8500_DSI_LINK2_BASE (U8500_DSI_LINK1_BASE + U8500_DSI_LINK_SIZE)
#define U8500_DSI_LINK3_BASE (U8500_DSI_LINK2_BASE + U8500_DSI_LINK_SIZE)
+/* ACCCON secure base address */
+
+#define ACCCON_BASE_SEC (0xBFFF0000)
+/* ACCCON normal world base address */
+#define ACCCON_BASE (0xBFFF1000)
+/* ACCCON register for CPU reset jump address */
+#define ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020)
+/* ACCCON register for CPU reset */
+#define ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC)
#ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index dbc41f69811..2404563ec90 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -39,4 +39,11 @@ extern struct sys_timer u8500_timer;
.type = MT_DEVICE, \
}
+#define __MEM_DEV_DESC(x, sz) { \
+ .virtual = IO_ADDRESS(x), \
+ .pfn = __phys_to_pfn(x), \
+ .length = sz, \
+ .type = MT_MEMORY, \
+}
+
#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c
index 096cb675d79..7ac13b70233 100755
--- a/arch/arm/mach-ux500/pm.c
+++ b/arch/arm/mach-ux500/pm.c
@@ -7,6 +7,7 @@
*
*/
+#include <asm/io.h>
#include "pm.h"
#define U8500_EXT_BACKUPRAM_ADDR (0x80151FDC)
@@ -312,7 +313,7 @@ static struct ux500_interconnect_contxt icn_contxt;
*/
void ux500_save_icn_context(void)
{
- uint32_t base = IO_ADDRESS(U8500_ICN_BASE);
+ unsigned char *base = ioremap(U8500_ICN_BASE, 0);
icn_contxt.ux500_hibw1_esram_in_pri_regs[0] =
readb(base + NODE_HIBW1_ESRAM_IN_0_PRIORITY_REG);
diff --git a/arch/arm/mach-ux500/tee_ux500.c b/arch/arm/mach-ux500/tee_ux500.c
new file mode 100644
index 00000000000..e35466d7b78
--- /dev/null
+++ b/arch/arm/mach-ux500/tee_ux500.c
@@ -0,0 +1,66 @@
+/*
+ * TEE service to handle the calls to trusted applications.
+ *
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Joakim Bech <joakim.xx.bech@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/kernel.h>
+#include <linux/tee.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#define BOOT_CONVERSION_FUNC (U8500_BOOT_ROM_BASE + 0x18588)
+#define BOOT_BRIDGE_FUNC (U8500_BOOT_ROM_BASE + 0x18300)
+
+#define ISSWAPI_EXECUTE_TA 0x11000001
+#define SEC_ROM_FORCE_CLEAN_MASK 0x20
+
+static u32 call_sec_rom_bridge(u32 service_id, u32 cfg, ...)
+{
+ typedef u32 (*bridge_func)(u32, u32, va_list);
+ static bridge_func hw_sec_rom_pub_bridge;
+ va_list ap;
+ u32 ret;
+
+ hw_sec_rom_pub_bridge =
+ (bridge_func)((u32)IO_ADDRESS(BOOT_BRIDGE_FUNC));
+
+ va_start(ap, cfg);
+ ret = hw_sec_rom_pub_bridge(service_id, cfg, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+int call_sec_world(struct tee_session *ts)
+{
+ /*
+ * ts->ta and ts->uuid is set to NULL when opening the device,
+ * hence it should be safe to just do the call here.
+ */
+
+ if (ts->uuid == NULL) {
+ call_sec_rom_bridge(ISSWAPI_EXECUTE_TA,
+ SEC_ROM_FORCE_CLEAN_MASK,
+ virt_to_phys(&ts->id),
+ NULL,
+ virt_to_phys(ts->ta),
+ ts->cmd,
+ virt_to_phys((void *)(ts->idata)),
+ virt_to_phys((void *)(&ts->origin)));
+ } else {
+ call_sec_rom_bridge(ISSWAPI_EXECUTE_TA,
+ SEC_ROM_FORCE_CLEAN_MASK,
+ virt_to_phys(&ts->id),
+ virt_to_phys(ts->uuid),
+ virt_to_phys(ts->ta),
+ ts->cmd,
+ virt_to_phys((void *)(ts->idata)),
+ virt_to_phys((void *)(&ts->origin)));
+ }
+
+
+ return 0;
+}