LF-13910-8: drivers: firmware: imx: add support for i.MX8DXL/QXP/QM

add support for i.MX8DXL/QXP/QM

Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
Acked-by: Rahul Kumar Yadav <rahulkumar.yadav@nxp.com>
Acked-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Acked-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
Acked-by: Jason Liu <jason.hui.liu@nxp.com>
This commit is contained in:
Pankaj Gupta 2024-11-12 16:13:23 +05:30 committed by Jason Liu
parent 9e7d5cc9f6
commit 4faa6aeb8b
8 changed files with 616 additions and 17 deletions

View File

@ -49,6 +49,7 @@ config IMX_SEC_ENCLAVE
help
It is possible to use APIs exposed by the iMX Secure Enclave HW IP called:
- EdgeLock Enclave Firmware (for i.MX8ULP, i.MX93, i.MX95),
- SECO (for i.MX8DXL, i.MXQM, i.MXQXP),
like base, HSM, V2X & SHE using the SAB protocol via the shared Messaging
Unit. This driver exposes these interfaces via a set of file descriptors
allowing to configure shared memory, send and receive messages.

View File

@ -4,6 +4,7 @@ obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o seco
obj-${CONFIG_IMX_SCMI_MISC_CONTROL} += sm-misc.o
obj-$(CONFIG_IMX_SCMI_BBM_CONTROL) += sm-bbm.o
obj-$(CONFIG_IMX_ISPMU) += isp-mu.o
sec_enclave-objs = se_ctrl.o ele_common.o ele_base_msg.o ele_fw_api.o v2x_base_msg.o v2x_common.o
obj-${CONFIG_IMX_SCMI_MISC_DRV} += sm-misc.o
sec_enclave-objs = se_ctrl.o ele_common.o ele_base_msg.o ele_fw_api.o v2x_base_msg.o v2x_common.o seco_init.o
obj-${CONFIG_IMX_SEC_ENCLAVE} += sec_enclave.o
sec_enclave-${CONFIG_IMX_ELE_TRNG} += ele_trng.o

View File

@ -31,12 +31,15 @@
#include "ele_fw_api.h"
#include "ele_trng.h"
#include "se_ctrl.h"
#include "seco_init.h"
#include "v2x_base_msg.h"
#include "v2x_common.h"
#define MAX_SOC_INFO_DATA_SZ 256
#define MBOX_TX_NAME "tx"
#define MBOX_RX_NAME "rx"
#define MBOX_TXDB_NAME "txdb"
#define MBOX_RXDB_NAME "rxdb"
#define SE_RCV_MSG_DEFAULT_TIMEOUT 5000
#define SE_RCV_MSG_LONG_TIMEOUT 5000000
@ -167,11 +170,9 @@ static struct se_if_node_info_list imx95_info = {
.soc_id = SOC_ID_OF_IMX95,
.soc_register = false,
.se_fetch_soc_info = ele_fetch_soc_info,
.load_hsm_fw = {
.se_fw_img_nm = {
.prim_fw_nm_in_rfs = NULL,
.seco_fw_nm_in_rfs = NULL,
.is_fw_loaded = true,
.handle_susp_resm = false,
},
.info = {
{
@ -249,10 +250,150 @@ static struct se_if_node_info_list imx95_info = {
},
};
static struct se_if_node_info_list imx8dxl_info = {
.num_mu = 7,
.soc_id = SOC_ID_OF_IMX8DXL,
.soc_register = false,
.se_fetch_soc_info = seco_fetch_soc_info,
.se_fw_img_nm = {
.prim_fw_nm_in_rfs = NULL,
.seco_fw_nm_in_rfs = NULL,
},
.info = {
{
.se_if_id = 0,
.mu_buff_size = 0,
.if_defs = {
.se_if_type = SE_TYPE_ID_SHE,
.se_instance_id = 0,
.cmd_tag = 0x17,
.rsp_tag = 0xe1,
.success_tag = SECO_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_6,
.fw_api_ver = MESSAGING_VERSION_7,
},
.reserved_dma_ranges = false,
.start_rng = NULL,
.init_trng = NULL,
.se_if_early_init = imx_scu_init_fw,
.se_if_late_init = NULL,
},
{
.se_if_id = 1,
.mu_buff_size = 0,
.if_defs = {
.se_if_type = SE_TYPE_ID_HSM,
.se_instance_id = 0,
.cmd_tag = 0x17,
.rsp_tag = 0xe1,
.success_tag = SECO_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_6,
.fw_api_ver = MESSAGING_VERSION_7,
},
.reserved_dma_ranges = false,
.start_rng = NULL,
.init_trng = NULL,
.se_if_early_init = imx_scu_init_fw,
.se_if_late_init = NULL,
},
{
.se_if_id = 2,
.mu_buff_size = 0,
.if_defs = {
.se_if_type = SE_TYPE_ID_V2X_SV,
.se_instance_id = 0,
.cmd_tag = 0x18,
.rsp_tag = 0xe2,
.success_tag = SECO_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_2,
.fw_api_ver = MESSAGING_VERSION_7,
},
.reserved_dma_ranges = false,
.start_rng = NULL,
.init_trng = NULL,
.se_if_early_init = imx_scu_init_fw,
.se_if_late_init = NULL,
},
{
.se_if_id = 3,
.mu_buff_size = 0,
.if_defs = {
.se_if_type = SE_TYPE_ID_V2X_SV,
.se_instance_id = 1,
.cmd_tag = 0x19,
.rsp_tag = 0xe3,
.success_tag = SECO_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_2,
.fw_api_ver = MESSAGING_VERSION_7,
},
.reserved_dma_ranges = false,
.start_rng = NULL,
.init_trng = NULL,
.se_if_early_init = imx_scu_init_fw,
.se_if_late_init = NULL,
},
{
.se_if_id = 4,
.mu_buff_size = 16,
.if_defs = {
.se_if_type = SE_TYPE_ID_V2X_SHE,
.se_instance_id = 0,
.cmd_tag = 0x1a,
.rsp_tag = 0xe4,
.success_tag = SECO_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_2,
.fw_api_ver = MESSAGING_VERSION_7,
},
.reserved_dma_ranges = false,
.start_rng = NULL,
.init_trng = NULL,
.se_if_early_init = imx_scu_init_fw,
.se_if_late_init = NULL,
},
{
.se_if_id = 5,
.mu_buff_size = 0,
.if_defs = {
.se_if_type = SE_TYPE_ID_V2X_SG,
.se_instance_id = 0,
.cmd_tag = 0x1d,
.rsp_tag = 0xe7,
.success_tag = SECO_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_2,
.fw_api_ver = MESSAGING_VERSION_7,
},
.reserved_dma_ranges = false,
.start_rng = NULL,
.init_trng = NULL,
.se_if_early_init = imx_scu_init_fw,
.se_if_late_init = NULL,
},
{
.se_if_id = 6,
.mu_buff_size = 0,
.if_defs = {
.se_if_type = SE_TYPE_ID_V2X_SG,
.se_instance_id = 1,
.cmd_tag = 0x1e,
.rsp_tag = 0xe8,
.success_tag = SECO_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_2,
.fw_api_ver = MESSAGING_VERSION_7,
},
.reserved_dma_ranges = false,
.start_rng = NULL,
.init_trng = NULL,
.se_if_early_init = imx_scu_init_fw,
.se_if_late_init = NULL,
},
},
};
static const struct of_device_id se_match[] = {
{ .compatible = "fsl,imx8ulp-se", .data = (void *)&imx8ulp_info},
{ .compatible = "fsl,imx93-se", .data = (void *)&imx93_info},
{ .compatible = "fsl,imx95-se", .data = (void *)&imx95_info},
{ .compatible = "fsl,imx8dxl-se", .data = (void *)&imx8dxl_info},
{},
};
@ -398,6 +539,9 @@ void *imx_get_se_data_info(u32 soc_id, u32 idx)
info_list = &imx93_info; break;
case SOC_ID_OF_IMX95:
info_list = &imx95_info; break;
case SOC_ID_OF_IMX8DXL:
case SOC_ID_OF_IMX8QXP:
info_list = &imx8dxl_info; break;
default:
return NULL;
}
@ -445,12 +589,20 @@ static int se_soc_info(struct se_if_priv *priv)
dev_err(priv->dev, "Failed to fetch SoC Info.");
return err;
}
if (info_list->soc_id == SOC_ID_OF_IMX8DXL) {
struct seco_soc_info *soc_data = (void *)data;
s_info = (void *)data;
var_se_info.board_type = 0;
var_se_info.soc_id = info_list->soc_id;
var_se_info.soc_rev = s_info->d_info.soc_rev;
load_fw->imem.state = s_info->d_addn_info.imem_state;
var_se_info.board_type = soc_data->board_type;
var_se_info.soc_id = soc_data->soc_id;
var_se_info.soc_rev = soc_data->soc_rev;
} else {
s_info = (void *)data;
var_se_info.board_type = 0;
var_se_info.soc_id = info_list->soc_id;
var_se_info.soc_rev = s_info->d_info.soc_rev;
load_fw->imem.state = s_info->d_addn_info.imem_state;
}
} else {
dev_err(priv->dev, "Failed to fetch SoC revision.");
if (info_list->soc_register)
@ -706,6 +858,15 @@ static int init_se_shared_mem(struct se_if_device_ctx *dev_ctx)
if (!se_shared_mem_mgmt->non_secure_mem.ptr)
return -ENOMEM;
if (priv->flags & SCU_MEM_CFG) {
if (imx_scu_mem_access(dev_ctx)) {
dev_err(dev_ctx->priv->dev,
"%s: Failed to share access to shared memory\n",
dev_ctx->devname);
return -EPERM;
}
}
se_shared_mem_mgmt->non_secure_mem.size = MAX_DATA_SIZE_PER_USER;
se_shared_mem_mgmt->non_secure_mem.pos = 0;
@ -1056,6 +1217,13 @@ static int se_ioctl_get_mu_info(struct se_if_device_ctx *dev_ctx,
if_info.se_if_id = 0;
if_info.interrupt_idx = 0;
if_info.tz = 0;
if (get_se_soc_id(priv) == SOC_ID_OF_IMX8DXL ||
get_se_soc_id(priv) == SOC_ID_OF_IMX8QXP) {
if_info.se_if_id = info->se_if_id + 1;
if (priv->if_defs->se_if_type > SE_TYPE_ID_SHE)
if_info.se_if_id++;
}
if_info.did = info->se_if_did;
if_info.cmd_tag = priv->if_defs->cmd_tag;
if_info.rsp_tag = priv->if_defs->rsp_tag;
@ -1118,10 +1286,18 @@ static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx,
}
/* Select the shared memory to be used for this buffer. */
if (io.flags & SE_IO_BUF_FLAGS_USE_MU_BUF)
if (io.flags & SE_IO_BUF_FLAGS_USE_MU_BUF) {
shared_mem = &dev_ctx->priv->mu_mem;
else
shared_mem = &dev_ctx->se_shared_mem_mgmt.non_secure_mem;
} else {
if ((io.flags & SE_IO_BUF_FLAGS_USE_SEC_MEM) &&
(dev_ctx->priv->flags & SCU_MEM_CFG)) {
/* App requires to use secure memory for this buffer.*/
shared_mem = &dev_ctx->se_shared_mem_mgmt.secure_mem;
} else {
/* No specific requirement for this buffer. */
shared_mem = &dev_ctx->se_shared_mem_mgmt.non_secure_mem;
}
}
/* Check there is enough space in the shared memory. */
dev_dbg(dev_ctx->priv->dev,
@ -1144,6 +1320,14 @@ static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx,
shared_mem->pos += round_up(io.length, 8u);
io.ele_addr = (u64)shared_mem->dma_addr + pos;
if (dev_ctx->priv->flags & SCU_MEM_CFG) {
if ((io.flags & SE_IO_BUF_FLAGS_USE_SEC_MEM) &&
!(io.flags & SE_IO_BUF_FLAGS_USE_SHORT_ADDR)) {
/*Add base address to get full address.#TODO: Add API*/
io.ele_addr += SECURE_RAM_BASE_ADDRESS_SCU;
}
}
if (dev_ctx->priv->mu_mem.pos)
memset_io(shared_mem->ptr + pos, 0, io.length);
else
@ -1210,6 +1394,69 @@ exit:
return err;
}
/* Configure the shared memory according to user config */
static int se_ioctl_shared_mem_cfg_handler(struct file *fp,
struct se_if_device_ctx *dev_ctx,
unsigned long arg)
{
struct se_ioctl_shared_mem_cfg cfg;
int err = -EINVAL;
/* Check if not already configured. */
if (dev_ctx->se_shared_mem_mgmt.secure_mem.dma_addr != 0u) {
dev_err(dev_ctx->priv->dev, "Shared memory not configured\n");
return err;
}
err = (int)copy_from_user(&cfg, (u8 *)arg, sizeof(cfg));
if (err) {
dev_err(dev_ctx->priv->dev, "Fail copy memory config\n");
err = -EFAULT;
return err;
}
dev_dbg(dev_ctx->priv->dev, "cfg offset: %u(%d)\n", cfg.base_offset, cfg.size);
err = imx_scu_sec_mem_cfg(fp, cfg.base_offset, cfg.size);
if (err) {
dev_err(dev_ctx->priv->dev, "Failt to map memory\n");
err = -ENOMEM;
return err;
}
return err;
}
static int se_ioctl_signed_msg_handler(struct file *fp,
struct se_if_device_ctx *dev_ctx,
unsigned long arg)
{
struct se_ioctl_signed_message msg;
int err;
err = copy_from_user(&msg, (u8 *)arg, sizeof(msg));
if (err) {
dev_err(dev_ctx->priv->dev, "Failed to copy from user: %d\n", err);
return -EFAULT;
}
err = imx_scu_signed_msg(fp, msg.message, msg.msg_size, &msg.error_code);
if (err) {
dev_err(dev_ctx->priv->dev,
"Failed to send signed message: %d\n",
err);
return err;
}
err = copy_to_user((u8 *)arg, &msg, sizeof(msg));
if (err) {
dev_err(dev_ctx->priv->dev, "Failed to copy to user: %d\n", err);
return -EFAULT;
}
return err;
}
/*
* File operations for user-space
*/
@ -1438,6 +1685,18 @@ static long se_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
case SE_IOCTL_CMD_SEND_RCV_RSP:
err = se_ioctl_cmd_snd_rcv_rsp_handler(dev_ctx, arg);
break;
case SE_IOCTL_SHARED_BUF_CFG:
if (priv->flags & SCU_MEM_CFG)
err = se_ioctl_shared_mem_cfg_handler(fp, dev_ctx, arg);
else
err = -EPERM;
break;
case SE_IOCTL_SIGNED_MESSAGE:
if (priv->flags & SCU_SIGNED_MSG_CFG)
err = se_ioctl_signed_msg_handler(fp, dev_ctx, arg);
else
err = -EPERM;
break;
default:
err = -EINVAL;
dev_dbg(priv->dev,
@ -1608,13 +1867,18 @@ static int se_if_probe(struct platform_device *pdev)
priv->se_mb_cl.knows_txdone = true;
priv->se_mb_cl.rx_callback = se_if_rx_callback;
ret = se_if_request_channel(dev, &priv->tx_chan, &priv->se_mb_cl,
MBOX_TX_NAME);
ret = se_if_request_channel(dev, &priv->tx_chan,
&priv->se_mb_cl,
(info_list->soc_id == SOC_ID_OF_IMX8DXL) ?
MBOX_TXDB_NAME : MBOX_TX_NAME);
if (ret)
goto exit;
ret = se_if_request_channel(dev, &priv->rx_chan,
&priv->se_mb_cl, MBOX_RX_NAME);
ret = se_if_request_channel(dev,
&priv->rx_chan,
&priv->se_mb_cl,
(info_list->soc_id == SOC_ID_OF_IMX8DXL) ?
MBOX_RXDB_NAME : MBOX_RX_NAME);
if (ret)
goto exit;

View File

@ -131,11 +131,14 @@ struct se_if_priv {
struct mbox_client se_mb_cl;
struct mbox_chan *tx_chan, *rx_chan;
u32 flags;
struct se_shared_mem mu_mem;
struct gen_pool *mem_pool;
const struct se_if_defines *if_defs;
struct se_lg_fl_info lg_fl_info;
struct imx_sc_ipc *ipc_scu;
u8 part_owner;
struct se_if_device_ctx *priv_dev_ctx;
struct list_head dev_ctx_list;
u32 active_devctx_count;
@ -147,7 +150,7 @@ struct se_if_priv {
#define SE_DUMP_MU_RCV_BUFS 2
#define SE_DUMP_KDEBUG_BUFS 3
uint32_t get_se_soc_id(struct se_if_priv *priv);
u32 get_se_soc_id(struct se_if_priv *priv);
int se_dump_to_logfl(struct se_if_device_ctx *dev_ctx,
u8 caller_type, int buf_size,
const char *buf, ...);

View File

@ -0,0 +1,262 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2024 NXP
*
* File containing client-side RPC functions for the SECO service. These
* function are ported to clients that communicate to the SC.
*/
#include <linux/firmware/imx/ipc.h>
#include <linux/firmware/imx/se_api.h>
#include <linux/firmware/imx/svc/rm.h>
#include <linux/nvmem-consumer.h>
#include <linux/io.h>
#include <linux/sys_soc.h>
#include <uapi/linux/se_ioctl.h>
#include "seco_init.h"
static const struct soc_device_attribute soc_info_matches[] = {
{ .soc_id = "i.MX8DXL",
.revision = "1.1",
.data = &(struct seco_soc_info) {.soc_id = SOC_ID_OF_IMX8DXL, .soc_rev = SOC_REV_A1,}
},
{ .soc_id = "i.MX8DXL",
.revision = "1.2",
.data = &(struct seco_soc_info) {.soc_id = SOC_ID_OF_IMX8DXL, .soc_rev = SOC_REV_B0,}
},
{ .soc_id = "i.MX8QXP",
.revision = "1.1",
.data = &(struct seco_soc_info) {.soc_id = SOC_ID_OF_IMX8QXP, .soc_rev = SOC_REV_B0,}
},
{ .soc_id = "i.MX8QXP",
.revision = "1.2",
.data = &(struct seco_soc_info) {.soc_id = SOC_ID_OF_IMX8QXP, .soc_rev = SOC_REV_C0,}
},
{ .soc_id = "i.MX8QM",
.revision = "1.1",
.data = &(struct seco_soc_info) {.soc_id = SOC_ID_OF_IMX8QM, .soc_rev = SOC_REV_B0,}
},
{ .soc_id = "i.MX8QM",
.revision = "1.2",
.data = &(struct seco_soc_info) {.soc_id = SOC_ID_OF_IMX8QM, .soc_rev = SOC_REV_C0,}
},
{ }
};
static int read_fuse(struct se_if_priv *priv, u32 id, u32 *value, u8 mul)
{
struct nvmem_device *nvmem;
u32 size_to_read = mul * sizeof(u32);
struct device_node *np;
int ret = 0;
np = priv->dev->of_node;
if (!of_get_property(np, "nvmem", NULL))
return -EPERM;
nvmem = devm_nvmem_device_get(priv->dev, NULL);
if (IS_ERR(nvmem)) {
ret = PTR_ERR(nvmem);
if (ret != -EPROBE_DEFER)
dev_err(priv->dev, "Failed to retrieve nvmem node\n");
return ret;
}
ret = nvmem_device_read(nvmem, id, size_to_read, value);
if (ret < 0) {
dev_err(priv->dev, "Failed to read fuse %d: %d\n", id, ret);
return ret;
}
if (ret != size_to_read) {
dev_err(priv->dev, "Read only %d instead of %d\n", ret,
size_to_read);
return -ENOMEM;
}
dev_dbg(priv->dev, "FUSE value 0x%x 0x%x 0x%x 0x%x\n",
value[0], value[1],
value[2], value[3]);
devm_nvmem_device_put(priv->dev, nvmem);
return 0;
}
/* function to fetch SoC revision on the SECO platform */
int seco_fetch_soc_info(struct se_if_priv *priv, void *data)
{
struct seco_soc_info *soc_data = data;
const struct soc_device_attribute *imx_soc_match;
u32 fuse_val[4] = {0xFF};
int err = 0;
imx_soc_match = soc_device_match(soc_info_matches);
if (!imx_soc_match || !imx_soc_match->data) {
err = -EINVAL;
goto exit;
}
err = read_fuse(priv, 8, (u32 *)&fuse_val, 4);
if (err) {
dev_err(priv->dev, "Fail to read FIPS fuse\n");
return err;
}
if (fuse_val[2] & SECO_NON_FIPS)
soc_data->board_type = IMX8DXL_DL1;
else if (fuse_val[0] & V2X_NON_FIPS)
soc_data->board_type = IMX8DXL_DL3;
else if (!fuse_val[0] && !fuse_val[2])
soc_data->board_type = IMX8DXL_DL2;
soc_data->soc_id = ((const struct seco_soc_info *)imx_soc_match->data)->soc_id;
soc_data->soc_rev = ((const struct seco_soc_info *)imx_soc_match->data)->soc_rev;
exit:
return err;
}
int imx_scu_init_fw(struct se_if_priv *priv)
{
int ret;
if (!priv) {
ret = -EINVAL;
goto exit;
}
ret = imx_scu_get_handle(&priv->ipc_scu);
if (ret) {
dev_err(priv->dev, "Fail to retrieve IPC handle\n");
goto exit;
}
ret = imx_sc_rm_get_resource_owner(priv->ipc_scu, IMX_SC_R_SECO, &priv->part_owner);
if (ret) {
dev_err(priv->dev, "Fail get owner of SECO resource\n");
goto exit;
}
if (!ret) {
priv->flags |= SCU_MEM_CFG;
if (get_se_soc_id(priv) == SOC_ID_OF_IMX8DXL &&
(priv->if_defs->se_if_type == SE_TYPE_ID_SHE ||
priv->if_defs->se_if_type == SE_TYPE_ID_HSM))
priv->flags |= SCU_SIGNED_MSG_CFG;
}
exit:
return ret;
}
int imx_scu_sec_mem_cfg(struct file *fp, u32 offset, u32 size)
{
struct se_if_device_ctx *dev_ctx = fp->private_data;
u64 high_boundary;
int ret = 0;
high_boundary = offset;
if (high_boundary > SECURE_RAM_SIZE) {
dev_err(dev_ctx->priv->dev, "base offset is over secure memory\n");
return -ENOMEM;
}
high_boundary += size;
if (high_boundary > SECURE_RAM_SIZE) {
dev_err(dev_ctx->priv->dev, "total memory is over secure memory\n");
return -ENOMEM;
}
dev_ctx->se_shared_mem_mgmt.secure_mem.dma_addr = (dma_addr_t)offset;
dev_ctx->se_shared_mem_mgmt.secure_mem.size = size;
dev_ctx->se_shared_mem_mgmt.secure_mem.pos = 0;
dev_ctx->se_shared_mem_mgmt.secure_mem.ptr =
devm_ioremap(dev_ctx->priv->dev,
(phys_addr_t)(SECURE_RAM_BASE_ADDRESS +
(u64)dev_ctx->se_shared_mem_mgmt.secure_mem.dma_addr),
dev_ctx->se_shared_mem_mgmt.secure_mem.size);
if (!dev_ctx->se_shared_mem_mgmt.secure_mem.ptr) {
dev_err(dev_ctx->priv->dev, "Failed to map secure memory\n");
return -ENOMEM;
}
return ret;
}
int imx_scu_mem_access(struct se_if_device_ctx *dev_ctx)
{
struct se_if_priv *priv = dev_ctx->priv;
u8 mr;
u64 addr;
int ret;
addr = dev_ctx->se_shared_mem_mgmt.non_secure_mem.dma_addr;
ret = imx_sc_rm_find_memreg(priv->ipc_scu,
&mr,
addr,
addr + MAX_DATA_SIZE_PER_USER);
if (ret) {
dev_err(dev_ctx->priv->dev,
"%s: Fail find memreg\n", dev_ctx->devname);
return ret;
}
ret = imx_sc_rm_set_memreg_permissions(priv->ipc_scu, mr,
priv->part_owner,
IMX_SC_RM_PERM_FULL);
if (ret) {
dev_err(dev_ctx->priv->dev,
"%s: Fail set permission for resource\n",
dev_ctx->devname);
return ret;
}
return ret;
}
int imx_scu_signed_msg(struct file *fp,
u8 *msg,
u32 size,
u32 *error)
{
struct se_if_device_ctx *dev_ctx = fp->private_data;
struct se_if_priv *priv = dev_ctx->priv;
struct se_shared_mem *shared_mem = &dev_ctx->se_shared_mem_mgmt.non_secure_mem;
int err;
u64 addr;
u32 pos;
/* Check there is enough space in the shared memory. */
if (size >= shared_mem->size - shared_mem->pos) {
dev_err(dev_ctx->priv->dev,
"Not enough mem: %d left, %d required\n",
shared_mem->size - shared_mem->pos, size);
return -ENOMEM;
}
/* Allocate space in shared memory. 8 bytes aligned. */
pos = shared_mem->pos;
/* get physical address from the pos */
addr = (u64)shared_mem->dma_addr + pos;
/* copy signed message from user space to this allocated buffer */
err = copy_from_user(shared_mem->ptr + pos, msg, size);
if (err) {
dev_err(dev_ctx->priv->dev,
"Failed to signed message from user: %d\n",
err);
return -EFAULT;
}
*error = imx_sc_seco_sab_msg(priv->ipc_scu, addr);
err = *error;
if (err)
dev_err(dev_ctx->priv->dev, "Failt to send signed message\n");
return err;
}

View File

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2024 NXP
*/
#ifndef SECO_H
#define SECO_H
#include "se_ctrl.h"
#define SCU_MEM_CFG BIT(1)
#define SCU_SIGNED_MSG_CFG BIT(2)
#define SECO_SUCCESS_IND 0x00
#define SOC_REV_A1 0xA100
#define SOC_REV_B0 0xB000
#define SOC_REV_C0 0xC000
#define SECURE_RAM_BASE_ADDRESS (0x31800000ULL)
#define SECURE_RAM_BASE_ADDRESS_SCU (0x20800000u)
#define SECURE_RAM_SIZE (0x10000ULL)
#define V2X_NON_FIPS 0x00000c00
#define SECO_NON_FIPS 0x00000018
#define IMX8DXL_DL1 0x1
#define IMX8DXL_DL2 0x2
#define IMX8DXL_DL3 0x4
struct seco_soc_info {
u16 soc_id;
u16 soc_rev;
u16 board_type;
};
int seco_fetch_soc_info(struct se_if_priv *priv, void *data);
int imx_scu_init_fw(struct se_if_priv *priv);
int imx_scu_sec_mem_cfg(struct file *fp, u32 offset, u32 size);
int imx_scu_mem_access(struct se_if_device_ctx *dev_ctx);
int imx_scu_signed_msg(struct file *fp,
u8 *msg,
u32 size,
u32 *error);
#endif

View File

@ -9,7 +9,11 @@
#include <linux/types.h>
#define SOC_ID_OF_IMX8ULP 0x084D
#define SOC_ID_OF_IMX8DXL 0xE
#define SOC_ID_OF_IMX8QM 0x1
#define SOC_ID_OF_IMX8QXP 0x2
#define SOC_ID_OF_IMX93 0x9300
#define SOC_ID_OF_IMX95 0x9500
#define OTP_UNIQ_ID 0x01
#define OTFAD_CONFIG 0x2

View File

@ -61,6 +61,13 @@ struct se_ioctl_cmd_snd_rcv_rsp_info {
struct se_ioctl_get_soc_info {
__u16 soc_id;
__u16 soc_rev;
__u8 board_type;
};
struct se_ioctl_signed_message {
__u8 *message;
__u32 msg_size;
__u32 error_code;
};
/* IO Buffer Flags */
@ -68,6 +75,7 @@ struct se_ioctl_get_soc_info {
#define SE_IO_BUF_FLAGS_IS_INPUT (0x01u)
#define SE_IO_BUF_FLAGS_USE_SEC_MEM (0x02u)
#define SE_IO_BUF_FLAGS_USE_SHORT_ADDR (0x04u)
#define SE_IO_BUF_FLAGS_USE_MU_BUF (0x08u)
#define SE_IO_BUF_FLAGS_IS_IN_OUT (0x10u)
/* IOCTLS */
@ -80,6 +88,11 @@ struct se_ioctl_get_soc_info {
*/
#define SE_IOCTL_ENABLE_CMD_RCV _IO(SE_IOCTL, 0x01)
/*
* ioctl to get configure the SCU shared buffer.
*/
#define SE_IOCTL_SHARED_BUF_CFG _IOW(SE_IOCTL, 0x02, \
struct se_ioctl_shared_mem_cfg)
/*
* ioctl to get the buffer allocated from the memory, which is shared
* between kernel and FW.
@ -99,6 +112,13 @@ struct se_ioctl_get_soc_info {
*/
#define SE_IOCTL_GET_MU_INFO _IOR(SE_IOCTL, 0x04, \
struct se_ioctl_get_if_info)
/*
* ioctl to send signed message to SE.
*/
#define SE_IOCTL_SIGNED_MESSAGE _IOR(SE_IOCTL, 0x05, \
struct se_ioctl_signed_message)
/*
* ioctl to get SoC Info from user-space.
*/