Commit 48840e16 authored by Andrew F. Davis's avatar Andrew F. Davis Committed by Tony Lindgren

ARM: OMAP2+: Use ARM SMC Calling Convention when OP-TEE is available

On High-Security(HS) OMAP2+ class devices a couple actions must be
performed from the ARM TrustZone during boot. These traditionally can be
performed by calling into the secure ROM code resident in this secure
world using legacy SMC calls. Optionally OP-TEE can replace this secure
world functionality by replacing the ROM after boot. ARM recommends a
standard calling convention is used for this interaction (SMC Calling
Convention). We check for the presence of OP-TEE and use this type of
call to perform the needed actions, falling back to the legacy OMAP ROM
call if OP-TEE is not available.
Signed-off-by: default avatarAndrew F. Davis <afd@ti.com>
Reviewed-by: default avatarLokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent dbebc8bf
...@@ -255,7 +255,7 @@ extern void gic_dist_disable(void); ...@@ -255,7 +255,7 @@ extern void gic_dist_disable(void);
extern void gic_dist_enable(void); extern void gic_dist_enable(void);
extern bool gic_dist_disabled(void); extern bool gic_dist_disabled(void);
extern void gic_timer_retrigger(void); extern void gic_timer_retrigger(void);
extern void omap_smc1(u32 fn, u32 arg); extern void _omap_smc1(u32 fn, u32 arg);
extern void omap4_sar_ram_init(void); extern void omap4_sar_ram_init(void);
extern void __iomem *omap4_get_sar_ram_base(void); extern void __iomem *omap4_get_sar_ram_base(void);
extern void omap4_mpuss_early_init(void); extern void omap4_mpuss_early_init(void);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
*/ */
#include <linux/arm-smccc.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -17,12 +18,17 @@ ...@@ -17,12 +18,17 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/memblock.h> #include <asm/memblock.h>
#include "common.h"
#include "omap-secure.h" #include "omap-secure.h"
static phys_addr_t omap_secure_memblock_base; static phys_addr_t omap_secure_memblock_base;
bool optee_available; bool optee_available;
#define OMAP_SIP_SMC_STD_CALL_VAL(func_num) \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_SIP, (func_num))
static void __init omap_optee_init_check(void) static void __init omap_optee_init_check(void)
{ {
struct device_node *np; struct device_node *np;
...@@ -71,6 +77,27 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, ...@@ -71,6 +77,27 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
return ret; return ret;
} }
void omap_smccc_smc(u32 fn, u32 arg)
{
struct arm_smccc_res res;
arm_smccc_smc(OMAP_SIP_SMC_STD_CALL_VAL(fn), arg,
0, 0, 0, 0, 0, 0, &res);
WARN(res.a0, "Secure function call 0x%08x failed\n", fn);
}
void omap_smc1(u32 fn, u32 arg)
{
/*
* If this platform has OP-TEE installed we use ARM SMC calls
* otherwise fall back to the OMAP ROM style calls.
*/
if (optee_available)
omap_smccc_smc(fn, arg);
else
_omap_smc1(fn, arg);
}
/* Allocate the memory to save secure ram */ /* Allocate the memory to save secure ram */
int __init omap_secure_ram_reserve_memblock(void) int __init omap_secure_ram_reserve_memblock(void)
{ {
......
...@@ -62,6 +62,8 @@ ...@@ -62,6 +62,8 @@
extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
u32 arg1, u32 arg2, u32 arg3, u32 arg4); u32 arg1, u32 arg2, u32 arg3, u32 arg4);
extern void omap_smccc_smc(u32 fn, u32 arg);
extern void omap_smc1(u32 fn, u32 arg);
extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs); extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
extern phys_addr_t omap_secure_ram_mempool_base(void); extern phys_addr_t omap_secure_ram_mempool_base(void);
......
...@@ -18,18 +18,18 @@ ...@@ -18,18 +18,18 @@
* the monitor API number. It uses few CPU registers * the monitor API number. It uses few CPU registers
* internally and hence they need be backed up including * internally and hence they need be backed up including
* link register "lr". * link register "lr".
* Function signature : void omap_smc1(u32 fn, u32 arg) * Function signature : void _omap_smc1(u32 fn, u32 arg)
*/ */
.arch armv7-a .arch armv7-a
.arch_extension sec .arch_extension sec
ENTRY(omap_smc1) ENTRY(_omap_smc1)
stmfd sp!, {r2-r12, lr} stmfd sp!, {r2-r12, lr}
mov r12, r0 mov r12, r0
mov r0, r1 mov r0, r1
dsb dsb
smc #0 smc #0
ldmfd sp!, {r2-r12, pc} ldmfd sp!, {r2-r12, pc}
ENDPROC(omap_smc1) ENDPROC(_omap_smc1)
/** /**
* u32 omap_smc2(u32 id, u32 falg, u32 pargs) * u32 omap_smc2(u32 id, u32 falg, u32 pargs)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment