diff options
Diffstat (limited to 'arch')
-rwxr-xr-x | arch/arm/mach-ux500/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpu-db8500.c | 2 | ||||
-rwxr-xr-x | arch/arm/mach-ux500/include/mach/hardware.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/setup.h | 7 | ||||
-rwxr-xr-x | arch/arm/mach-ux500/pm.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-ux500/tee_ux500.c | 66 |
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; +} |