SMC related changes for omaps for v5.6 merge window

A series of changes to use optee SMC calls if optee is initialized by
 the bootloader. Based on the discussions on LAKML in mailing list thread
 "arm_smccc_smc as generic smc interface?" we don't want to add more quirk
 handling to arm_smccc_smc() and want to handle it locally instead.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEkgNvrZJU/QSQYIcQG9Q+yVyrpXMFAl4grWMRHHRvbnlAYXRv
 bWlkZS5jb20ACgkQG9Q+yVyrpXMbBBAA3BlpJ2g8MUTIqn8tPQXF24JfWo8mkESW
 454c43lV7wWOv4QZZY8fWD6V4dupVFnCMCIEr91HHSVnNBAMdLl+t4rdZgkdVS0t
 QvA5xKbRX8U3B4ohI7qqsYSKgHUz+W/oqwxt8j8xnn93KELan07V8JV2OxBjXiGp
 msUc3qFwwKgLDiZcVHfAsRUYFYfZ0TtrVf2Dn/EsZNsa5KWM+Dx1nckTRpsXn9v4
 9PzG2peeKkFizE6nGLHFZj5n+rNjiVGzZ2NIlFkAkqm+BuBBaTaKcSbUzkB6Rf0a
 nWLlrvbAuwgLOHyYKZfx8vmv3hvT3Qvfz3LZYpVLlLZuA2eYpcJ0CLKAO85Lz1xg
 zaSqcJhkfLUxYYDngfGP2y3yl/BrhJj10MYT+daXCiSDS+uGZmON+7maXAB1rOTK
 zNJwY6YbjNu9KDLkvHwOPUeuQgATT4bZ2wPNrFAZisIDEjTzSKIqGrQj5h8IeOSx
 quD5YTk8Cc4E/QgSJUmqqgIkHlVNrc71hxIO7dZ+cZVviQS6PUfjAMGdkZ20UfFO
 mRBpmUp6ATTv9Q4TuQ3rnFlN0MfL+eSOtDdP5homNyyemseAVy3YxMrc68Wur3jP
 Mmcl5KZQweDy+NC4mQi/YqpHFOWMYra6o2cNsrcY73ZbVp/0bqDWw2klUWM0JyM5
 wjt8aly0yBQ=
 =XJDD
 -----END PGP SIGNATURE-----

Merge tag 'omap-for-v5.6/soc-smc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/soc

SMC related changes for omaps for v5.6 merge window

A series of changes to use optee SMC calls if optee is initialized by
the bootloader. Based on the discussions on LAKML in mailing list thread
"arm_smccc_smc as generic smc interface?" we don't want to add more quirk
handling to arm_smccc_smc() and want to handle it locally instead.

* tag 'omap-for-v5.6/soc-smc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP2+: sleep43xx: Call secure suspend/resume handlers
  ARM: OMAP2+: Use ARM SMC Calling Convention when OP-TEE is available
  ARM: OMAP2+: Introduce check for OP-TEE in omap_secure_init()
  ARM: OMAP2+: Add omap_secure_init callback hook for secure initialization

Link: https://lore.kernel.org/r/pull-1579200367-372444@atomide.com-2
Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson 2020-01-16 15:57:41 -08:00
commit 21473e16b1
6 changed files with 99 additions and 4 deletions

View File

@ -255,7 +255,7 @@ extern void gic_dist_disable(void);
extern void gic_dist_enable(void);
extern bool gic_dist_disabled(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 __iomem *omap4_get_sar_ram_base(void);
extern void omap4_mpuss_early_init(void);

View File

@ -51,6 +51,7 @@
#include "prm33xx.h"
#include "prm44xx.h"
#include "opp2xxx.h"
#include "omap-secure.h"
/*
* omap_clk_soc_init: points to a function that does the SoC-specific
@ -430,6 +431,7 @@ void __init omap2420_init_early(void)
omap_hwmod_init_postsetup();
omap_clk_soc_init = omap2420_dt_clk_init;
rate_table = omap2420_rate_table;
omap_secure_init();
}
void __init omap2420_init_late(void)
@ -454,6 +456,7 @@ void __init omap2430_init_early(void)
omap_hwmod_init_postsetup();
omap_clk_soc_init = omap2430_dt_clk_init;
rate_table = omap2430_rate_table;
omap_secure_init();
}
void __init omap2430_init_late(void)
@ -481,6 +484,7 @@ void __init omap3_init_early(void)
omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
omap_hwmod_init_postsetup();
omap_secure_init();
}
void __init omap3430_init_early(void)
@ -533,6 +537,7 @@ void __init ti814x_init_early(void)
dm814x_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = dm814x_dt_clk_init;
omap_secure_init();
}
void __init ti816x_init_early(void)
@ -549,6 +554,7 @@ void __init ti816x_init_early(void)
dm816x_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = dm816x_dt_clk_init;
omap_secure_init();
}
#endif
@ -566,6 +572,7 @@ void __init am33xx_init_early(void)
am33xx_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = am33xx_dt_clk_init;
omap_secure_init();
}
void __init am33xx_init_late(void)
@ -589,6 +596,7 @@ void __init am43xx_init_early(void)
omap_hwmod_init_postsetup();
omap_l2_cache_init();
omap_clk_soc_init = am43xx_dt_clk_init;
omap_secure_init();
}
void __init am43xx_init_late(void)
@ -617,6 +625,7 @@ void __init omap4430_init_early(void)
omap_hwmod_init_postsetup();
omap_l2_cache_init();
omap_clk_soc_init = omap4xxx_dt_clk_init;
omap_secure_init();
}
void __init omap4430_init_late(void)
@ -643,6 +652,7 @@ void __init omap5_init_early(void)
omap54xx_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = omap5xxx_dt_clk_init;
omap_secure_init();
}
void __init omap5_init_late(void)
@ -666,6 +676,7 @@ void __init dra7xx_init_early(void)
dra7xx_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = dra7xx_dt_clk_init;
omap_secure_init();
}
void __init dra7xx_init_late(void)

View File

@ -8,18 +8,42 @@
* Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
*/
#include <linux/arm-smccc.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/memblock.h>
#include <linux/of.h>
#include <asm/cacheflush.h>
#include <asm/memblock.h>
#include "common.h"
#include "omap-secure.h"
static phys_addr_t omap_secure_memblock_base;
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)
{
struct device_node *np;
/*
* We only check that the OP-TEE node is present and available. The
* OP-TEE kernel driver is not needed for the type of interaction made
* with OP-TEE here so the driver's status is not checked.
*/
np = of_find_node_by_path("/firmware/optee");
if (np && of_device_is_available(np))
optee_available = true;
of_node_put(np);
}
/**
* omap_sec_dispatcher: Routine to dispatch low power secure
* service routines
@ -53,6 +77,27 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
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 */
int __init omap_secure_ram_reserve_memblock(void)
{
@ -163,3 +208,8 @@ u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag)
NO_FLAG,
3, ptr, count, flag, 0);
}
void __init omap_secure_init(void)
{
omap_optee_init_check();
}

View File

@ -10,6 +10,8 @@
#ifndef OMAP_ARCH_OMAP_SECURE_H
#define OMAP_ARCH_OMAP_SECURE_H
#include <linux/types.h>
/* Monitor error code */
#define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE
#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF
@ -51,6 +53,9 @@
#define OMAP4_PPA_L2_POR_INDEX 0x23
#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
#define AM43xx_PPA_SVC_PM_SUSPEND 0x71
#define AM43xx_PPA_SVC_PM_RESUME 0x72
/* Secure RX-51 PPA (Primary Protected Application) APIs */
#define RX51_PPA_HWRNG 29
#define RX51_PPA_L2_INVAL 40
@ -60,6 +65,8 @@
extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
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_smc3(u32 id, u32 process, u32 flag, u32 pargs);
extern phys_addr_t omap_secure_ram_mempool_base(void);
@ -72,6 +79,9 @@ extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
extern bool optee_available;
void omap_secure_init(void);
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
void set_cntfreq(void);
#else

View File

@ -18,18 +18,18 @@
* the monitor API number. It uses few CPU registers
* internally and hence they need be backed up including
* 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_extension sec
ENTRY(omap_smc1)
ENTRY(_omap_smc1)
stmfd sp!, {r2-r12, lr}
mov r12, r0
mov r0, r1
dsb
smc #0
ldmfd sp!, {r2-r12, pc}
ENDPROC(omap_smc1)
ENDPROC(_omap_smc1)
/**
* u32 omap_smc2(u32 id, u32 falg, u32 pargs)

View File

@ -28,6 +28,7 @@
#include "prm33xx.h"
#include "soc.h"
#include "sram.h"
#include "omap-secure.h"
static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
static struct clockdomain *gfx_l4ls_clkdm;
@ -166,6 +167,16 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
{
int ret = 0;
/* Suspend secure side on HS devices */
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
if (optee_available)
omap_smccc_smc(AM43xx_PPA_SVC_PM_SUSPEND, 0);
else
omap_secure_dispatcher(AM43xx_PPA_SVC_PM_SUSPEND,
FLAG_START_CRITICAL,
0, 0, 0, 0, 0);
}
amx3_pre_suspend_common();
scu_power_mode(scu_base, SCU_PM_POWEROFF);
ret = cpu_suspend(args, fn);
@ -174,6 +185,19 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
if (!am43xx_check_off_mode_enable())
amx3_post_suspend_common();
/*
* Resume secure side on HS devices.
*
* Note that even on systems with OP-TEE available this resume call is
* issued to the ROM. This is because upon waking from suspend the ROM
* is restored as the secure monitor. On systems with OP-TEE ROM will
* restore OP-TEE during this call.
*/
if (omap_type() != OMAP2_DEVICE_TYPE_GP)
omap_secure_dispatcher(AM43xx_PPA_SVC_PM_RESUME,
FLAG_START_CRITICAL,
0, 0, 0, 0, 0);
return ret;
}