SMC: secmon: uniform SMC call interface.

PD#160539: check secmon dev in dts and uniform SMC call interface.

 1. SMC call interface is provided by ARCH.
    arm_smccc_smc(...)
 2. check secmon device is registed or not.

Change-Id: I5bd58747db5b167ab8ad59be083f31e7b6395bbf
Signed-off-by: Yan Wang <yan.wang@amlogic.com>
Signed-off-by: jiamin ma <jiamin.ma@amlogic.com>
This commit is contained in:
Yan Wang
2018-01-29 16:16:11 +08:00
committed by Yixun Lan
parent 27ceb5fe97
commit 43ea2d9687
10 changed files with 117 additions and 304 deletions

View File

@@ -28,6 +28,7 @@
#include <linux/of.h>
#include <linux/slab.h>
#include "audio_data.h"
#include <linux/arm-smccc.h>
#ifdef CONFIG_MESON_TRUSTZONE
#include <mach/meson-secure.h>
@@ -66,11 +67,7 @@ int meson_efuse_fn_smc_query_audioinfo(struct efuse_hal_api_arg *arg)
int ret;
unsigned int cmd, offset, size;
unsigned long *retcnt;
register unsigned x0 asm("x0");
register unsigned x1 asm("x1");
register unsigned x2 asm("x2");
register unsigned x3 asm("x3");
struct arm_smccc_res res;
if (!arg)
return -1;
@@ -86,24 +83,11 @@ int meson_efuse_fn_smc_query_audioinfo(struct efuse_hal_api_arg *arg)
memcpy((void *)sharemem_input, (const void *)arg->buffer, size);
asm __volatile__("" : : : "memory");
x0 = cmd;
x1 = offset;
x2 = size;
x3 = 0;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
__asmeq("%2", "x1")
__asmeq("%3", "x2")
__asmeq("%4", "x3")
"smc #0\n"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2), "r"(x3));
} while (0);
ret = x0;
*retcnt = x0;
arm_smccc_smc(cmd, offset, size, 0, 0, 0, 0, 0, &res);
ret = res.a0;
*retcnt = res.a0;
MYPRT("[%s %d]ret/%d\n", __func__, __LINE__, ret);
if (ret == 0) {

View File

@@ -29,13 +29,11 @@
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/amlogic/iomap.h>
#ifndef CONFIG_ARM64
#include <asm/opcodes-sec.h>
#endif
#include <linux/amlogic/secmon.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/amlogic/cpu_version.h>
#include <linux/arm-smccc.h>
static unsigned char cpuinfo_chip_id[16] = { 0 };
@@ -44,20 +42,14 @@ static noinline int fn_smc(u64 function_id,
u64 arg1,
u64 arg2)
{
register long x0 asm("x0") = function_id;
register long x1 asm("x1") = arg0;
register long x2 asm("x2") = arg1;
register long x3 asm("x3") = arg2;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (x0)
: "r" (x1), "r" (x2), "r" (x3));
struct arm_smccc_res res;
return x0;
arm_smccc_smc((unsigned long)function_id,
(unsigned long)arg0,
(unsigned long)arg1,
(unsigned long)arg2,
0, 0, 0, 0, &res);
return res.a0;
}
static int cpuinfo_probe(struct platform_device *pdev)

View File

@@ -20,9 +20,9 @@
/* #include <asm/compiler.h> */
#include <linux/amlogic/iomap.h>
#include "securekey.h"
#include <linux/arm-smccc.h>
#ifdef CONFIG_ARM64
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
int aml_is_secure_set(void)
{
@@ -36,12 +36,11 @@ int aml_is_secure_set(void)
long get_sharemem_info(unsigned long function_id)
{
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r" (function_id));
struct arm_smccc_res res;
return function_id;
arm_smccc_smc((unsigned long)function_id, 0, 0, 0, 0, 0, 0, 0, &res);
return res.a0;
}
unsigned long aml_sec_boot_check(unsigned long nType,
@@ -49,38 +48,20 @@ unsigned long aml_sec_boot_check(unsigned long nType,
unsigned long nLength,
unsigned long nOption)
{
uint64_t ret = 1;
register uint64_t x0 asm("x0");
register uint64_t x1 asm("x1");
register uint64_t x2 asm("x2");
register uint64_t x3 asm("x3");
register uint64_t x4 asm("x4");
struct arm_smccc_res res;
asm __volatile__("" : : : "memory");
x0 = AML_DATA_PROCESS;
x1 = nType;
x2 = pBuffer;
x3 = nLength;
x4 = nOption;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
__asmeq("%2", "x1")
__asmeq("%3", "x2")
__asmeq("%4", "x3")
__asmeq("%5", "x4")
"smc #0\n"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4));
arm_smccc_smc((unsigned long)AML_DATA_PROCESS,
(unsigned long)nType,
(unsigned long)pBuffer,
(unsigned long)nLength,
(unsigned long)nOption,
0, 0, 0, &res);
} while (0);
ret = x0;
return ret;
return res.a0;
}
#endif

View File

@@ -25,24 +25,19 @@
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/amlogic/iomap.h>
#ifndef CONFIG_ARM64
#include <asm/opcodes-sec.h>
#endif
#include "efuse.h"
#ifdef CONFIG_ARM64
#include <linux/amlogic/efuse.h>
#endif
#include <linux/amlogic/secmon.h>
#include <linux/arm-smccc.h>
static long meson_efuse_fn_smc(struct efuse_hal_api_arg *arg)
{
long ret;
unsigned int cmd, offset, size;
unsigned long *retcnt = (unsigned long *)(arg->retcnt);
register unsigned int x0 asm("x0");
register unsigned int x1 asm("x1");
register unsigned int x2 asm("x2");
struct arm_smccc_res res;
if (!sharemem_input_base || !sharemem_output_base)
return -1;
@@ -60,19 +55,9 @@ static long meson_efuse_fn_smc(struct efuse_hal_api_arg *arg)
asm __volatile__("" : : : "memory");
x0 = cmd;
x1 = offset;
x2 = size;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
__asmeq("%2", "x1")
__asmeq("%3", "x2")
"smc #0\n"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2));
ret = x0;
*retcnt = x0;
arm_smccc_smc(cmd, offset, size, 0, 0, 0, 0, 0, &res);
ret = res.a0;
*retcnt = res.a0;
if ((arg->cmd == EFUSE_HAL_API_READ) && (ret != 0))
memcpy((void *)arg->buffer,
@@ -102,24 +87,14 @@ ssize_t meson_trustzone_efuse_get_max(struct efuse_hal_api_arg *arg)
{
ssize_t ret;
unsigned int cmd;
register uint64_t x0 asm("x0");
struct arm_smccc_res res;
if (arg->cmd == EFUSE_HAL_API_USER_MAX) {
cmd = efuse_get_max_cmd;
asm __volatile__("" : : : "memory");
x0 = cmd;
do {
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x0")
"smc #0\n"
: "=r"(x0)
: "r"(x0));
} while (0);
ret = x0;
arm_smccc_smc(cmd, 0, 0, 0, 0, 0, 0, 0, &res);
ret = res.a0;
if (!ret)
return -1;

View File

@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#include <linux/arm-smccc.h>
/* Local include */
#include "hdmi_rx_drv.h"
@@ -50,7 +51,6 @@
#define GCP_GLOBAVMUTE_EN 1 /* ag506 must clear this bit */
#define EDID_CLK_DIV 9 /* sys clk/(9+1) = 20M */
#define HDCP_KEY_WR_TRIES (5)
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
/*------------------------variable define------------------------------*/
static DEFINE_SPINLOCK(reg_rw_lock);
@@ -485,17 +485,10 @@ unsigned int rx_hdcp22_rd_top(uint32_t addr)
*/
void sec_top_write(unsigned int *addr, unsigned int value)
{
register long x0 asm("x0") = 0x8200001e;
register long x1 asm("x1") = (unsigned long)addr;
register long x2 asm("x2") = value;
struct arm_smccc_res res;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
"smc #0\n"
: : "r"(x0), "r"(x1), "r"(x2)
);
arm_smccc_smc(0x8200001e, (unsigned long)(uintptr_t)addr,
value, 0, 0, 0, 0, 0, &res);
}
/*
@@ -503,16 +496,12 @@ void sec_top_write(unsigned int *addr, unsigned int value)
*/
unsigned int sec_top_read(unsigned int *addr)
{
register long x0 asm("x0") = 0x8200001d;
register long x1 asm("x1") = (unsigned long)addr;
struct arm_smccc_res res;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
"smc #0\n"
: "+r"(x0) : "r"(x1)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x8200001d, (unsigned long)(uintptr_t)addr,
0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
/*
@@ -520,17 +509,10 @@ unsigned int sec_top_read(unsigned int *addr)
*/
void rx_sec_reg_write(unsigned int *addr, unsigned int value)
{
register long x0 asm("x0") = 0x8200002f;
register long x1 asm("x1") = (unsigned long)addr;
register long x2 asm("x2") = value;
struct arm_smccc_res res;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
"smc #0\n"
: : "r"(x0), "r"(x1), "r"(x2)
);
arm_smccc_smc(0x8200002f, (unsigned long)(uintptr_t)addr,
value, 0, 0, 0, 0, 0, &res);
}
/*
@@ -538,16 +520,12 @@ void rx_sec_reg_write(unsigned int *addr, unsigned int value)
*/
unsigned int rx_sec_reg_read(unsigned int *addr)
{
register long x0 asm("x0") = 0x8200001f;
register long x1 asm("x1") = (unsigned long)addr;
struct arm_smccc_res res;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
"smc #0\n"
: "+r"(x0) : "r"(x1)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x8200001f, (unsigned long)(uintptr_t)addr,
0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
/*
@@ -555,14 +533,11 @@ unsigned int rx_sec_reg_read(unsigned int *addr)
*/
unsigned int rx_sec_set_duk(void)
{
register long x0 asm("x0") = 0x8200002e;
struct arm_smccc_res res;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r"(x0)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x8200002e, 0, 0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
/*

View File

@@ -46,6 +46,7 @@
#include "common.h"
#include "hdcpVerify.h"
#include "hw_clk.h"
#include <linux/arm-smccc.h>
static void mode420_half_horizontal_para(void);
static void hdmi_phy_suspend(void);
@@ -169,98 +170,45 @@ EXPORT_SYMBOL(hdmitx_ddc_hw_op);
int hdmitx_hdcp_opr(unsigned int val)
{
struct arm_smccc_res res;
if (val == 1) { /* HDCP14_ENABLE */
register long x0 asm("x0") = 0x82000010;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: : "r"(x0)
);
arm_smccc_smc(0x82000010, 0, 0, 0, 0, 0, 0, 0, &res);
}
if (val == 2) { /* HDCP14_RESULT */
register long x0 asm("x0") = 0x82000011;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r"(x0)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x82000011, 0, 0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
if (val == 0) { /* HDCP14_INIT */
register long x0 asm("x0") = 0x82000012;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: : "r"(x0)
);
arm_smccc_smc(0x82000012, 0, 0, 0, 0, 0, 0, 0, &res);
}
if (val == 3) { /* HDCP14_EN_ENCRYPT */
register long x0 asm("x0") = 0x82000013;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: : "r"(x0)
);
arm_smccc_smc(0x82000013, 0, 0, 0, 0, 0, 0, 0, &res);
}
if (val == 4) { /* HDCP14_OFF */
register long x0 asm("x0") = 0x82000014;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: : "r"(x0)
);
arm_smccc_smc(0x82000014, 0, 0, 0, 0, 0, 0, 0, &res);
}
if (val == 5) { /* HDCP_MUX_22 */
register long x0 asm("x0") = 0x82000015;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: : "r"(x0)
);
arm_smccc_smc(0x82000015, 0, 0, 0, 0, 0, 0, 0, &res);
}
if (val == 6) { /* HDCP_MUX_14 */
register long x0 asm("x0") = 0x82000016;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: : "r"(x0)
);
arm_smccc_smc(0x82000016, 0, 0, 0, 0, 0, 0, 0, &res);
}
if (val == 7) { /* HDCP22_RESULT */
register long x0 asm("x0") = 0x82000017;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r"(x0)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x82000017, 0, 0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
if (val == 0xa) { /* HDCP14_KEY_LSTORE */
register long x0 asm("x0") = 0x8200001a;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r"(x0)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x8200001a, 0, 0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
if (val == 0xb) { /* HDCP22_KEY_LSTORE */
register long x0 asm("x0") = 0x8200001b;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r"(x0)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x8200001b, 0, 0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
if (val == 0xc) { /* HDCP22_KEY_SET_DUK */
register long x0 asm("x0") = 0x8200001c;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r"(x0)
);
return (unsigned int)(x0&0xffffffff);
arm_smccc_smc(0x8200001c, 0, 0, 0, 0, 0, 0, 0, &res);
return (unsigned int)((res.a0)&0xffffffff);
}
return -1;
}

View File

@@ -31,6 +31,7 @@
#include <linux/cdev.h>
#include <linux/io.h>
#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h>
#include <linux/arm-smccc.h>
#include "common.h"
#include "hdmi_tx_reg.h"
#include "reg_ops.h"
@@ -316,23 +317,16 @@ void hd_set_reg_bits(unsigned int addr, unsigned int value,
}
EXPORT_SYMBOL(hd_set_reg_bits);
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
unsigned int hdmitx_rd_reg_normal(unsigned int addr)
{
unsigned long offset = (addr & DWC_OFFSET_MASK) >> 24;
unsigned int data;
struct arm_smccc_res res;
register long x0 asm("x0") = 0x82000018;
register long x1 asm("x1") = (unsigned long)addr;
arm_smccc_smc(0x82000018, (unsigned long)addr, 0, 0, 0, 0, 0, 0, &res);
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
"smc #0\n"
: "+r"(x0) : "r"(x1)
);
data = (unsigned int)(x0&0xffffffff);
data = (unsigned int)((res.a0)&0xffffffff);
pr_debug(REG "%s rd[0x%x] 0x%x\n", offset ? "DWC" : "TOP",
addr, data);
@@ -388,18 +382,12 @@ EXPORT_SYMBOL(hdmitx_rd_reg);
void hdmitx_wr_reg_normal(unsigned int addr, unsigned int data)
{
unsigned long offset = (addr & DWC_OFFSET_MASK) >> 24;
struct arm_smccc_res res;
register long x0 asm("x0") = 0x82000019;
register long x1 asm("x1") = (unsigned long)addr;
register long x2 asm("x2") = data;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
"smc #0\n"
: : "r"(x0), "r"(x1), "r"(x2)
);
arm_smccc_smc(0x82000019,
(unsigned long)addr,
data,
0, 0, 0, 0, 0, &res);
pr_debug("%s wr[0x%x] 0x%x\n", offset ? "DWC" : "TOP",
addr, data);

View File

@@ -32,6 +32,7 @@
#include <linux/amlogic/reboot.h>
#include <asm/compiler.h>
#include <linux/kdebug.h>
#include <linux/arm-smccc.h>
static u32 psci_function_id_restart;
static u32 psci_function_id_poweroff;
@@ -70,20 +71,14 @@ static u32 parse_reason(const char *cmd)
static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
register long x0 asm("x0") = function_id;
register long x1 asm("x1") = arg0;
register long x2 asm("x2") = arg1;
register long x3 asm("x3") = arg2;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (x0)
: "r" (x1), "r" (x2), "r" (x3));
struct arm_smccc_res res;
return function_id;
arm_smccc_smc((unsigned long)function_id,
(unsigned long)arg0,
(unsigned long)arg1,
(unsigned long)arg2,
0, 0, 0, 0, &res);
return res.a0;
}
void meson_smc_restart(u64 function_id, u64 reboot_reason)
{

View File

@@ -26,9 +26,7 @@
#include <linux/platform_device.h>
#include <linux/dma-contiguous.h>
#include <asm/compiler.h>
#ifndef CONFIG_ARM64
#include <asm/opcodes-sec.h>
#endif
#include <linux/arm-smccc.h>
#undef pr_fmt
#define pr_fmt(fmt) "secmon: " fmt
@@ -43,36 +41,17 @@ static long phy_out_base;
#endif
#define OUT_SIZE 0x1000
static DEFINE_MUTEX(sharemem_mutex);
#ifdef CONFIG_ARM64
#define DEV_REGISTED 1
#define DEV_UNREGISTED 0
static int secmon_dev_registed = DEV_UNREGISTED;
static long get_sharemem_info(unsigned int function_id)
{
long ret;
struct arm_smccc_res res;
asm volatile(
"mov x0, %[function_id] \n"
"smc #0 \n"
"mov %[ret], x0 \n"
: [ret] "=r" (ret)
: [function_id] "r" (function_id)
: "memory", "cc", "x0"
);
arm_smccc_smc(function_id, 0, 0, 0, 0, 0, 0, 0, &res);
return ret;
return res.a0;
}
#else
static long get_sharemem_info(unsigned int function_id)
{
register long r0 asm("r0") = function_id;
asm volatile(
__asmeq("%0", "r0")
__asmeq("%1", "r0")
__SMC(0)
: "=r" (r0)
: "r"(r0));
return r0;
}
#endif
#define RESERVE_MEM_SIZE 0x300000
static int secmon_probe(struct platform_device *pdev)
@@ -118,6 +97,7 @@ static int secmon_probe(struct platform_device *pdev)
pr_info("secmon share mem out buffer remap fail!\n");
return -ENOMEM;
}
secmon_dev_registed = DEV_REGISTED;
pr_info("share in base: 0x%lx, share out base: 0x%lx\n",
(long)sharemem_in_base, (long)sharemem_out_base);
pr_info("phy_in_base: 0x%lx, phy_out_base: 0x%lx\n",
@@ -142,9 +122,14 @@ static struct platform_driver secmon_platform_driver = {
int __init meson_secmon_init(void)
{
return platform_driver_register(&secmon_platform_driver);
int ret;
ret = platform_driver_register(&secmon_platform_driver);
WARN((secmon_dev_registed != DEV_REGISTED),
"ERROR: secmon device must be enable!!!\n");
return ret;
}
module_init(meson_secmon_init);
subsys_initcall(meson_secmon_init);
void sharemem_mutex_lock(void)
{

View File

@@ -26,13 +26,11 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/amlogic/unifykey/security_key.h>
#include <linux/arm-smccc.h>
#undef pr_fmt
#define pr_fmt(fmt) "unifykey: " fmt
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
static void __iomem *storage_in_base;
static void __iomem *storage_out_base;
static void __iomem *storage_block_base;
@@ -61,30 +59,22 @@ static int storage_init_status;
static uint64_t storage_smc_ops(uint64_t func)
{
register unsigned long x0 asm("x0") = func;
asm volatile(
__asmeq("%0", "x0")
"smc #0\n"
: "+r" (x0));
struct arm_smccc_res res;
return x0;
arm_smccc_smc((unsigned long)func, 0, 0, 0, 0, 0, 0, 0, &res);
return res.a0;
}
static uint64_t storage_smc_ops2(uint64_t func, uint64_t arg1)
{
register unsigned long x0 asm("x0") = func;
register unsigned long x1 asm("x1") = arg1;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
"smc #0\n"
: "+r" (x0)
: "r"(x1));
struct arm_smccc_res res;
return x0;
arm_smccc_smc((unsigned long)func,
(unsigned long)arg1,
0, 0, 0, 0, 0, 0, &res);
return res.a0;
}
static inline int32_t smc_to_linux_errno(uint64_t errno)
{
int32_t ret = (int32_t)(errno & 0xffffffff);