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
parent
ccf07c0822
commit
2ccb9a596a
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue