1
0
Fork 0

SSI-87: firmware: imx: Add APIs required for secvio

The Security Violation module requires SC API for the SECO, RM, MISC
and IRQ.

This patch does:
 - imx-scu-irq: Allow reuse of imx_scu_irq_get_status
 - seco:
    - Add imx_sc_seco_secvio_enable
    - Add imx_sc_seco_secvio_config
    - Add imx_sc_seco_secvio_dgo_config

Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
5.4-rM2-2.2.x-imx-squashed
Franck LENORMAND 2020-03-04 13:20:05 +01:00
parent ccf07c0822
commit 2ccb9a596a
6 changed files with 251 additions and 16 deletions

View File

@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2019 NXP
* Copyright 2019-2020 NXP
*
* Implementation of the SCU IRQ functions using MU.
*
*/
#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/firmware/imx/ipc.h>
#include <linux/firmware/imx/sci.h>
#include <linux/mailbox_client.h>
#include <linux/suspend.h>
@ -65,29 +65,18 @@ static int imx_scu_irq_notifier_call_chain(unsigned long status, u8 *group)
static void imx_scu_irq_work_handler(struct work_struct *work)
{
struct imx_sc_msg_irq_get_status msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
u32 irq_status;
int ret;
u8 i;
for (i = 0; i < IMX_SC_IRQ_NUM_GROUP; i++) {
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_IRQ;
hdr->func = IMX_SC_IRQ_FUNC_STATUS;
hdr->size = 2;
msg.data.req.resource = mu_resource_id;
msg.data.req.group = i;
ret = imx_scu_call_rpc(imx_sc_irq_ipc_handle, &msg, true);
ret = imx_scu_irq_get_status(i, &irq_status);
if (ret) {
pr_err("get irq group %d status failed, ret %d\n",
i, ret);
return;
}
irq_status = msg.data.resp.status;
if (!irq_status)
continue;
@ -96,6 +85,31 @@ static void imx_scu_irq_work_handler(struct work_struct *work)
}
}
int imx_scu_irq_get_status(u8 group, u32 *irq_status)
{
struct imx_sc_msg_irq_get_status msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
int ret;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_IRQ;
hdr->func = IMX_SC_IRQ_FUNC_STATUS;
hdr->size = 2;
msg.data.req.resource = mu_resource_id;
msg.data.req.group = group;
ret = imx_scu_call_rpc(imx_sc_irq_ipc_handle, &msg, true);
if (ret)
return ret;
if (irq_status)
*irq_status = msg.data.resp.status;
return 0;
}
EXPORT_SYMBOL(imx_scu_irq_get_status);
int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable)
{
struct imx_sc_msg_irq_enable msg;

View File

@ -60,3 +60,190 @@ int imx_sc_seco_sab_msg(struct imx_sc_ipc *ipc, u64 smsg_addr)
return ret;
}
EXPORT_SYMBOL(imx_sc_seco_sab_msg);
int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc)
{
struct imx_sc_rpc_msg msg;
struct imx_sc_rpc_msg *hdr = &msg;
int ret;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = (uint8_t)IMX_SC_RPC_SVC_SECO;
hdr->func = (uint8_t)IMX_SC_SECO_FUNC_SECVIO_ENABLE;
hdr->size = 1;
ret = imx_scu_call_rpc(ipc, &msg, true);
if (ret)
return ret;
return 0;
}
EXPORT_SYMBOL(imx_sc_seco_secvio_enable);
struct imx_sc_msg_req_seco_config {
struct imx_sc_rpc_msg hdr;
u32 data0;
u32 data1;
u32 data2;
u32 data3;
u32 data4;
u8 id;
u8 access;
u8 size;
} __packed __aligned(4);
struct imx_sc_msg_resp_seco_config {
struct imx_sc_rpc_msg hdr;
u32 data0;
u32 data1;
u32 data2;
u32 data3;
u32 data4;
} __packed;
int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data0, u32 *data1, u32 *data2, u32 *data3,
u32 *data4, u8 size)
{
struct imx_sc_msg_req_seco_config msg;
struct imx_sc_msg_resp_seco_config *resp;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
int ret;
if (!ipc)
return -EINVAL;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = (uint8_t)IMX_SC_RPC_SVC_SECO;
hdr->func = (uint8_t)IMX_SC_SECO_FUNC_SECVIO_CONFIG;
hdr->size = 7;
/* Check the pointers on data are valid and set it if doing a write */
switch (size) {
case 5:
if (data4) {
if (access)
msg.data4 = *data4;
} else {
return -EINVAL;
}
/* fallthrough */
case 4:
if (data3) {
if (access)
msg.data3 = *data3;
} else {
return -EINVAL;
}
/* fallthrough */
case 3:
if (data2) {
if (access)
msg.data2 = *data2;
} else {
return -EINVAL;
}
/* fallthrough */
case 2:
if (data1) {
if (access)
msg.data1 = *data1;
} else {
return -EINVAL;
}
/* fallthrough */
case 1:
if (data0) {
if (access)
msg.data0 = *data0;
} else {
return -EINVAL;
}
break;
default:
return -EINVAL;
}
msg.id = id;
msg.access = access;
msg.size = size;
ret = imx_scu_call_big_rpc(ipc, &msg, true);
if (ret)
return ret;
resp = (struct imx_sc_msg_resp_seco_config *)&msg;
/* Pointers already checked so we just copy the data if reading */
if (!access)
switch (size) {
case 5:
*data4 = resp->data4;
/* fallthrough */
case 4:
*data3 = resp->data3;
/* fallthrough */
case 3:
*data2 = resp->data2;
/* fallthrough */
case 2:
*data1 = resp->data1;
/* fallthrough */
case 1:
*data0 = resp->data0;
}
return 0;
}
EXPORT_SYMBOL(imx_sc_seco_secvio_config);
struct imx_sc_msg_req_seco_dgo_config {
struct imx_sc_rpc_msg hdr;
u32 data;
u8 id;
u8 access;
} __packed __aligned(4);
struct imx_sc_msg_resp_seco_dgo_config {
struct imx_sc_rpc_msg hdr;
u32 data;
} __packed;
int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data)
{
struct imx_sc_msg_req_seco_dgo_config msg;
struct imx_sc_msg_resp_seco_dgo_config *resp;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
int ret;
if (!ipc)
return -EINVAL;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = (uint8_t)IMX_SC_RPC_SVC_SECO;
hdr->func = (uint8_t)IMX_SC_SECO_FUNC_SECVIO_DGO_CONFIG;
hdr->size = 3;
if (access) {
if (data)
msg.data = *data;
else
return -EINVAL;
}
msg.access = access;
msg.id = id;
ret = imx_scu_call_rpc(ipc, &msg, true);
if (ret)
return ret;
resp = (struct imx_sc_msg_resp_seco_dgo_config *)&msg;
if (!access && data)
*data = resp->data;
return 0;
}
EXPORT_SYMBOL(imx_sc_seco_secvio_dgo_config);

View File

@ -28,7 +28,6 @@
#define IMX_SC_PAD_FUNC_GET_WAKEUP 9
#define IMX_SC_PAD_FUNC_SET_WAKEUP 4
#define IMX_SC_PAD_WAKEUP_OFF 0
#define IMX_SC_IRQ_GROUP_WAKE 3
#define IMX_SC_IRQ_PAD (1 << 1)
#endif

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017-2018 NXP
* Copyright 2017-2018,2020 NXP
*/
#ifndef __DT_BINDINGS_RSCRC_IMX_H
@ -51,6 +51,7 @@
#define IMX_SC_R_DC_1_BLIT2 38
#define IMX_SC_R_DC_1_BLIT_OUT 39
#define IMX_SC_R_DC_1_WARP 42
#define IMX_SC_R_SECVIO 44
#define IMX_SC_R_DC_1_VIDEO0 45
#define IMX_SC_R_DC_1_VIDEO1 46
#define IMX_SC_R_DC_1_FRAC0 47

View File

@ -17,8 +17,12 @@
#include <linux/firmware/imx/svc/rm.h>
#include <linux/firmware/imx/svc/seco.h>
#define IMX_SC_IRQ_GROUP_WAKE 3U /* Wakeup interrupts */
#define IMX_SC_IRQ_SECVIO BIT(6) /* Security violation */
int imx_scu_enable_general_irq_channel(struct device *dev);
int imx_scu_irq_register_notifier(struct notifier_block *nb);
int imx_scu_irq_unregister_notifier(struct notifier_block *nb);
int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable);
int imx_scu_irq_get_status(u8 group, u32 *irq_status);
#endif /* _SC_SCI_H */

View File

@ -23,12 +23,21 @@ enum imx_sc_seco_func {
IMX_SC_SECO_FUNC_UNKNOWN = 0,
IMX_SC_SECO_FUNC_BUILD_INFO = 16,
IMX_SC_SECO_FUNC_SAB_MSG = 23,
IMX_SC_SECO_FUNC_SECVIO_ENABLE = 25,
IMX_SC_SECO_FUNC_SECVIO_CONFIG = 26,
IMX_SC_SECO_FUNC_SECVIO_DGO_CONFIG = 27,
};
#if IS_ENABLED(CONFIG_IMX_SCU)
int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
uint32_t *commit);
int imx_sc_seco_sab_msg(struct imx_sc_ipc *ipc, u64 smsg_addr);
int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc);
int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data0, u32 *data1, u32 *data2, u32 *data3,
u32 *data4, u8 size);
int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data);
#else /* IS_ENABLED(CONFIG_IMX_SCU) */
static inline
int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
@ -42,6 +51,27 @@ int imx_sc_seco_sab_msg(struct imx_sc_ipc *ipc, u64 smsg_addr)
{
return -EOPNOTSUPP;
}
static inline
int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc)
{
return -EOPNOTSUPP;
}
static inline
int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data0, u32 *data1, u32 *data2, u32 *data3,
u32 *data4, u8 size)
{
return -EOPNOTSUPP;
}
static inline
int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data)
{
return -EOPNOTSUPP;
}
#endif /* IS_ENABLED(CONFIG_IMX_SCU) */
#endif /* _SC_SECO_API_H */