LF-13910: remove base driver for secure-enclave

remove base driver for secure-enclave

Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
Acked-by: Jason Liu <jason.hui.liu@nxp.com>
This commit is contained in:
Pankaj Gupta 2025-04-21 21:48:56 +05:30 committed by Jason Liu
parent ab72b4936f
commit bdeff7cd56
19 changed files with 1 additions and 5505 deletions

View File

@ -29,38 +29,6 @@ config IMX_SCU_PD
help
The System Controller Firmware (SCFW) based power domain driver.
config IMX_SECO_MU
tristate "i.MX Security Controller (SECO) support"
depends on IMX_MBOX
default y if IMX_SCU
help
It is possible to use APIs exposed by the SECO like HSM and 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.
config IMX_SEC_ENCLAVE
tristate "i.MX Embedded Secure Enclave - EdgeLock Enclave Firmware driver."
depends on IMX_MBOX && ARCH_MXC && ARM64
default m if ARCH_MXC
help
It is possible to use APIs exposed by the iMX Secure Enclave HW IP called:
- EdgeLock Enclave Firmware (for i.MX8ULP, i.MX93),
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.
config IMX_ELE_TRNG
tristate "i.MX ELE True Random Number Generator"
default y
select CRYPTO_RNG
select HW_RANDOM
help
This driver provides kernel-side support for the Random Number generation,
through NXP hardware IP for secure-enclave called EdgeLock Enclave.
config IMX_ISPMU
tristate "IMX ISP MU Protocol driver"
depends on IMX_MBOX

View File

@ -2,9 +2,5 @@
obj-$(CONFIG_IMX_DSP) += imx-dsp.o
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o seco.o
obj-${CONFIG_IMX_SCMI_MISC_CONTROL} += sm-misc.o
obj-${CONFIG_IMX_SECO_MU} += seco_mu.o
sec_enclave-objs = se_fw.o ele_common.o ele_base_msg.o ele_fw_api.o v2x_base_msg.o
obj-${CONFIG_IMX_SEC_ENCLAVE} += sec_enclave.o
sec_enclave-${CONFIG_IMX_ELE_TRNG} += ele_trng.o
obj-$(CONFIG_IMX_SCMI_BBM_CONTROL) += sm-bbm.o
obj-$(CONFIG_IMX_ISPMU) += isp-mu.o

View File

@ -1,602 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2021-2024 NXP
*/
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/firmware/imx/ele_base_msg.h>
#include <linux/firmware/imx/ele_mu_ioctl.h>
#include "ele_common.h"
int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_GET_INFO_REQ,
ELE_GET_INFO_REQ_MSG_SZ,
true);
if (ret)
goto exit;
priv->tx_msg->data[0] = upper_32_bits(addr);
priv->tx_msg->data[1] = lower_32_bits(addr);
priv->tx_msg->data[2] = data_size;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_GET_INFO_REQ,
ELE_GET_INFO_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_GET_INFO_REQ, status);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
int ele_get_v2x_fw_state(struct device *dev, uint32_t *state)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
struct mu_hdr *hdr;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
hdr = (struct mu_hdr *)&priv->tx_msg->header;
ret = plat_fill_cmd_msg_hdr(priv,
hdr,
ELE_GET_STATE, ELE_GET_STATE_REQ_SZ,
true);
if (ret) {
pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
goto exit;
}
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_GET_STATE,
ELE_GET_STATE_RSP_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_GET_STATE, status);
ret = -1;
} else {
*state = 0xFF & priv->rx_msg->data[1];
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
int ele_write_fuse(struct device *dev, uint16_t fuse_id, u32 value, bool lock)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
unsigned int status, ind;
int ret;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_WRITE_FUSE, ELE_WRITE_FUSE_REQ_MSG_SZ,
true);
if (ret) {
pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
goto exit;
}
priv->tx_msg->data[0] = (32 << 16) | (fuse_id << 5);
if (lock)
priv->tx_msg->data[0] |= BIT(31);
priv->tx_msg->data[1] = value;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_WRITE_FUSE,
ELE_WRITE_FUSE_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
ind = RES_IND(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Status=0x%x, Indicator=0x%x",
ELE_WRITE_FUSE, status, ind);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ele_write_fuse);
int ele_ping(struct device *dev)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_PING_REQ, ELE_PING_REQ_SZ,
true);
if (ret) {
pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
goto exit;
}
ret = imx_ele_msg_send_rcv(priv);
if (ret)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_PING_REQ,
ELE_PING_RSP_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_PING_REQ, status);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
/*
* ele_get_trng_state() - prepare and send the command to read
* crypto lib and TRNG state
* TRNG state
* 0x1 TRNG is in program mode
* 0x2 TRNG is still generating entropy
* 0x3 TRNG entropy is valid and ready to be read
* 0x4 TRNG encounter an error while generating entropy
*
* CSAL state
* 0x0 Crypto Lib random context initialization is not done yet
* 0x1 Crypto Lib random context initialization is on-going
* 0x2 Crypto Lib random context initialization succeed
* 0x3 Crypto Lib random context initialization failed
*
* returns: csal and trng state.
*
*/
int ele_get_trng_state(struct device *dev)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_GET_TRNG_STATE_REQ,
ELE_GET_TRNG_STATE_REQ_MSG_SZ,
true);
if (ret) {
pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
goto exit;
}
ret = imx_ele_msg_send_rcv(priv);
if (ret)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_GET_TRNG_STATE_REQ,
ELE_GET_TRNG_STATE_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_GET_TRNG_STATE_REQ, status);
ret = -1;
} else
ret = (priv->rx_msg->data[1] & CSAL_TRNG_STATE_MASK);
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
/*
* ele_start_rng() - prepare and send the command to start
* initialization of the ELE RNG context
*
* returns: 0 on success.
*/
int ele_start_rng(struct device *dev)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_START_RNG_REQ,
ELE_START_RNG_REQ_MSG_SZ,
true);
if (ret)
goto exit;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_START_RNG_REQ,
ELE_START_RNG_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_START_RNG_REQ, status);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
int ele_service_swap(struct device *dev,
phys_addr_t addr,
u32 addr_size, u16 flag)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_SERVICE_SWAP_REQ,
ELE_SERVICE_SWAP_REQ_MSG_SZ,
true);
if (ret)
goto exit;
priv->tx_msg->data[0] = flag;
priv->tx_msg->data[1] = addr_size;
priv->tx_msg->data[2] = ELE_NONE_VAL;
priv->tx_msg->data[3] = lower_32_bits(addr);
priv->tx_msg->data[4] = plat_add_msg_crc((uint32_t *)&priv->tx_msg[0],
ELE_SERVICE_SWAP_REQ_MSG_SZ);
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_SERVICE_SWAP_REQ,
ELE_SERVICE_SWAP_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_SERVICE_SWAP_REQ, status);
ret = -1;
} else {
if (flag == ELE_IMEM_EXPORT)
ret = priv->rx_msg->data[1];
else
ret = 0;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
int ele_fw_authenticate(struct device *dev, phys_addr_t addr)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
unsigned int status;
int ret;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_FW_AUTH_REQ,
ELE_FW_AUTH_REQ_SZ,
true);
if (ret)
goto exit;
priv->tx_msg->data[0] = addr;
priv->tx_msg->data[1] = 0x0;
priv->tx_msg->data[2] = addr;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_FW_AUTH_REQ,
ELE_FW_AUTH_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_FW_AUTH_REQ, status);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
static int read_otp_uniq_id(struct ele_mu_priv *priv, u32 *value)
{
int ret;
unsigned int status;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_READ_FUSE_REQ,
ELE_READ_FUSE_OTP_UNQ_ID_RSP_MSG_SZ,
true);
if (ret)
return ret;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(priv->dev, "Command Id[%d], Response Failure = 0x%x",
ELE_READ_FUSE_REQ, status);
ret = -1;
} else {
value[0] = priv->rx_msg->data[1];
value[1] = priv->rx_msg->data[2];
value[2] = priv->rx_msg->data[3];
value[3] = priv->rx_msg->data[4];
ret = 0;
}
return ret;
}
static int read_fuse_word(struct ele_mu_priv *priv, u32 *value)
{
int ret;
unsigned int status;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_READ_FUSE_REQ,
ELE_READ_FUSE_RSP_MSG_SZ,
true);
if (ret)
return ret;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(priv->dev, "Command Id[%d], Response Failure = 0x%x",
ELE_READ_FUSE_REQ, status);
ret = -1;
} else {
value[0] = priv->rx_msg->data[1];
ret = 0;
}
return ret;
}
/**
* read_common_fuse() - Brief description of function.
* @struct device *dev: Device to send the request to read fuses.
* @uint16_t fuse_id: Fuse identifier to read.
* @u32 *value: unsigned integer array to store the fused-values.
*
* Secure-enclave like EdgeLock Enclave, manages the fuse. This API
* requests FW to read the common fuses. FW sends the read value as
* response.
*
* Context: This function takes two mutex locks: one on the command
* and second on the message unit.
* such that multiple commands cannot be sent.
* for the device Describes whether the function can sleep, what locks it takes,
* releases, or expects to be held. It can extend over multiple
* lines.
* Return: Describe the return value of function_name.
*
* The return value description can also have multiple paragraphs, and should
* be placed at the end of the comment block.
*/
int read_common_fuse(struct device *dev,
uint16_t fuse_id, u32 *value)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_READ_FUSE_REQ,
ELE_READ_FUSE_REQ_MSG_SZ,
true);
if (ret) {
pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
goto exit;
}
priv->tx_msg->data[0] = fuse_id;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
switch (fuse_id) {
case OTP_UNIQ_ID:
ret = read_otp_uniq_id(priv, value);
break;
default:
ret = read_fuse_word(priv, value);
break;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
EXPORT_SYMBOL_GPL(read_common_fuse);
int ele_voltage_change_req(struct device *dev, bool start)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
uint8_t cmd = start ? ELE_VOLT_CHANGE_START_REQ : ELE_VOLT_CHANGE_FINISH_REQ;
if (start)
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
cmd,
ELE_VOLT_CHANGE_REQ_MSG_SZ,
true);
if (ret) {
pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
goto exit;
}
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
cmd,
ELE_VOLT_CHANGE_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_VOLT_CHANGE_START_REQ, status);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
if (!start || ret)
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
EXPORT_SYMBOL_GPL(ele_voltage_change_req);

View File

@ -1,291 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2023 NXP
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware/imx/ele_base_msg.h>
#include "ele_common.h"
#include "se_fw.h"
int imx_se_alloc_tx_rx_buf(struct ele_mu_priv *priv)
{
int ret = 0;
priv->tx_msg = devm_kzalloc(priv->dev,
sizeof(*priv->tx_msg),
GFP_KERNEL);
if (!priv->tx_msg) {
ret = -ENOMEM;
dev_err(priv->dev, "Fail allocate mem for tx_msg.\n");
return ret;
}
priv->rx_msg = devm_kzalloc(priv->dev,
sizeof(*priv->rx_msg),
GFP_KERNEL);
if (!priv->rx_msg) {
ret = -ENOMEM;
dev_err(priv->dev, "Fail allocate mem for rx_msg.\n");
return ret;
}
return ret;
}
void imx_se_free_tx_rx_buf(struct ele_mu_priv *priv)
{
if (priv->tx_msg)
devm_kfree(priv->dev, priv->tx_msg);
if (priv->rx_msg)
devm_kfree(priv->dev, priv->rx_msg);
}
uint32_t plat_add_msg_crc(uint32_t *msg, uint32_t msg_len)
{
uint32_t i;
uint32_t crc = 0;
uint32_t nb_words = msg_len / (uint32_t)sizeof(uint32_t);
for (i = 0; i < nb_words - 1; i++)
crc ^= *(msg + i);
return crc;
}
int imx_ele_msg_send_rcv(struct ele_mu_priv *priv)
{
unsigned int wait;
int err;
mutex_lock(&priv->mu_lock);
err = mbox_send_message(priv->tx_chan, priv->tx_msg);
if (err < 0) {
pr_err("Error: mbox_send_message failure.\n");
mutex_unlock(&priv->mu_lock);
return err;
}
err = 0;
mutex_unlock(&priv->mu_lock);
wait = msecs_to_jiffies(1000);
if (!wait_for_completion_timeout(&priv->done, wait)) {
pr_err("Error: wait_for_completion timed out.\n");
err = -ETIMEDOUT;
}
return err;
}
/* Fill a command message header with a given command ID and length in bytes. */
int plat_fill_cmd_msg_hdr(struct ele_mu_priv *priv,
struct mu_hdr *hdr,
uint8_t cmd,
uint32_t len,
bool is_base_api)
{
hdr->tag = priv->cmd_tag;
hdr->ver = (is_base_api) ? priv->base_api_ver : priv->fw_api_ver;
hdr->command = cmd;
hdr->size = len >> 2;
return 0;
}
int validate_rsp_hdr(struct ele_mu_priv *priv, unsigned int header,
uint8_t msg_id, uint8_t sz, bool is_base_api)
{
unsigned int tag, command, size, ver;
int ret = -EINVAL;
tag = MSG_TAG(header);
command = MSG_COMMAND(header);
size = MSG_SIZE(header);
ver = MSG_VER(header);
do {
if (tag != priv->rsp_tag) {
dev_err(priv->dev,
"MSG[0x%x] Hdr: Resp tag mismatch. (0x%x != 0x%x)",
msg_id, tag, priv->rsp_tag);
break;
}
if (command != msg_id) {
dev_err(priv->dev,
"MSG Header: Cmd id mismatch. (0x%x != 0x%x)",
command, msg_id);
break;
}
if (size != (sz >> 2)) {
dev_err(priv->dev,
"MSG[0x%x] Hdr: Cmd size mismatch. (0x%x != 0x%x)",
msg_id, size, (sz >> 2));
break;
}
if (is_base_api && (ver != priv->base_api_ver)) {
dev_err(priv->dev,
"MSG[0x%x] Hdr: Base API Vers mismatch. (0x%x != 0x%x)",
msg_id, ver, priv->base_api_ver);
break;
} else if (!is_base_api && ver != priv->fw_api_ver) {
dev_err(priv->dev,
"MSG[0x%x] Hdr: FW API Vers mismatch. (0x%x != 0x%x)",
msg_id, ver, priv->fw_api_ver);
break;
}
ret = 0;
} while (false);
return ret;
}
int ele_do_start_rng(struct device *dev)
{
int ret;
int count = ELE_GET_TRNG_STATE_RETRY_COUNT;
ret = ele_get_trng_state(dev);
if (ret < 0) {
dev_err(dev, "Failed to get trng state\n");
return ret;
} else if (ret != ELE_TRNG_STATE_OK) {
/* call start rng */
ret = ele_start_rng(dev);
if (ret) {
dev_err(dev, "Failed to start rng\n");
return ret;
}
/* poll get trng state API, ELE_GET_TRNG_STATE_RETRY_COUNT times
* or while trng state != 0x203
*/
do {
msleep(10);
ret = ele_get_trng_state(dev);
if (ret < 0) {
dev_err(dev, "Failed to get trng state\n");
return ret;
}
count--;
} while ((ret != ELE_TRNG_STATE_OK) && count);
if (ret != ELE_TRNG_STATE_OK)
return -EIO;
}
return 0;
}
#ifdef CONFIG_PM_SLEEP
int save_imem(struct device *dev)
{
int ret;
struct ele_mu_priv *priv = dev_get_drvdata(dev);
/* EXPORT command will save encrypted IMEM to given address,
* so later in resume, IMEM can be restored from the given
* address.
*
* Size must be at least 64 kB.
*/
ret = ele_service_swap(dev,
priv->imem.phyaddr,
ELE_IMEM_SIZE,
ELE_IMEM_EXPORT);
if (ret < 0)
dev_err(dev, "Failed to export IMEM\n");
else
dev_info(dev,
"Exported %d bytes of encrypted IMEM\n",
ret);
return ret;
}
int restore_imem(struct device *dev,
uint8_t *pool_name)
{
int ret;
u32 imem_state;
u32 *get_info_buf = NULL;
phys_addr_t get_info_phyaddr = 0;
struct ele_mu_priv *priv = dev_get_drvdata(dev);
get_info_phyaddr
= pool_name ? get_phy_buf_mem_pool(dev,
pool_name,
&get_info_buf,
DEVICE_GET_INFO_SZ)
: 0x0;
if (!get_info_buf) {
dev_err(dev, "Unable to alloc sram from sram pool\n");
return -ENOMEM;
}
ret = ele_do_start_rng(dev);
if (ret)
goto exit;
/* get info from ELE */
ret = ele_get_info(dev, get_info_phyaddr, ELE_GET_INFO_READ_SZ);
if (ret) {
dev_err(dev, "Failed to get info from ELE.\n");
goto exit;
}
/* Get IMEM state, if 0xFE then import IMEM */
imem_state = (get_info_buf[ELE_IMEM_STATE_WORD]
& ELE_IMEM_STATE_MASK) >> 16;
if (imem_state == ELE_IMEM_STATE_BAD) {
/* IMPORT command will restore IMEM from the given
* address, here size is the actual size returned by ELE
* during the export operation
*/
ret = ele_service_swap(dev,
priv->imem.phyaddr,
priv->imem.size,
ELE_IMEM_IMPORT);
if (ret) {
dev_err(dev, "Failed to import IMEM\n");
goto exit;
}
} else
goto exit;
/* After importing IMEM, check if IMEM state is equal to 0xCA
* to ensure IMEM is fully loaded and
* ELE functionality can be used.
*/
ret = ele_get_info(dev, get_info_phyaddr, ELE_GET_INFO_READ_SZ);
if (ret) {
dev_err(dev, "Failed to get info from ELE.\n");
goto exit;
}
imem_state = (get_info_buf[ELE_IMEM_STATE_WORD]
& ELE_IMEM_STATE_MASK) >> 16;
if (imem_state == ELE_IMEM_STATE_OK)
dev_info(dev, "Successfully restored IMEM\n");
else
dev_err(dev, "Failed to restore IMEM\n");
exit:
if (pool_name && get_info_buf)
free_phybuf_mem_pool(dev, pool_name,
get_info_buf, DEVICE_GET_INFO_SZ);
return ret;
}
#endif

View File

@ -1,40 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2023 NXP
*/
#ifndef __ELE_COMMON_H__
#define __ELE_COMMON_H__
#include "se_fw.h"
uint32_t plat_add_msg_crc(uint32_t *msg, uint32_t msg_len);
int imx_ele_msg_send_rcv(struct ele_mu_priv *priv);
void imx_se_free_tx_rx_buf(struct ele_mu_priv *priv);
int imx_se_alloc_tx_rx_buf(struct ele_mu_priv *priv);
int validate_rsp_hdr(struct ele_mu_priv *priv, unsigned int header,
uint8_t msg_id, uint8_t sz, bool is_base_api);
int plat_fill_cmd_msg_hdr(struct ele_mu_priv *priv,
struct mu_hdr *hdr,
uint8_t cmd,
uint32_t len,
bool is_base_api);
#ifdef CONFIG_IMX_ELE_TRNG
int ele_trng_init(struct device *dev);
#else
static inline int ele_trng_init(struct device *dev)
{
return 0;
}
#endif
int ele_do_start_rng(struct device *dev);
#ifdef CONFIG_PM_SLEEP
int save_imem(struct device *dev);
int restore_imem(struct device *dev,
uint8_t *pool_name);
#endif
#endif /*__ELE_COMMON_H__ */

View File

@ -1,142 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2023-2024 NXP
*/
#include <linux/dma-mapping.h>
#include "ele_common.h"
#include "ele_fw_api.h"
struct ele_rng_msg {
u32 header; /* u8 Tag; u8 Command; u8 Size; u8 Ver; */
u16 rsv;
u16 flags;
u32 data[2];
};
int ele_init_fw(struct device *dev)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
unsigned int status;
int ret;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
ELE_INIT_FW_REQ, ELE_INIT_FW_REQ_SZ,
false);
if (ret)
goto exit;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_INIT_FW_REQ,
ELE_INIT_FW_RSP_SZ,
false);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_INIT_FW_REQ, status);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}
/*
* ele_get_random() - prepare and send the command to proceed
* with a random number generation operation
*
* returns: size of the rondom number generated
*/
int ele_get_random(struct device *dev,
void *data, size_t len)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
struct ele_rng_msg *tx_msg;
unsigned int status;
dma_addr_t dst_dma;
u8 *buf;
int ret;
/* As per RBG3(RS) construction mentioned in NIST SP800-90C,
* CTR_DRBG generates 128(full entropy) bits after reseeding
* the CTR_DRBG with 256 bits of entropy. so splitting the
* user rng request in multiple of 128 bits & enforce reseed
* for every iteration.
*/
len = ELE_RNG_MAX_SIZE;
buf = dmam_alloc_coherent(priv->dev, len, &dst_dma, GFP_KERNEL);
if (!buf) {
dev_err(priv->dev, "Failed to map destination buffer memory\n");
return -ENOMEM;
}
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret) {
ret = -ENOMEM;
goto exit;
}
tx_msg = (struct ele_rng_msg *)priv->tx_msg;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&tx_msg->header,
ELE_GET_RANDOM_REQ, ELE_GET_RANDOM_REQ_SZ,
false);
if (ret)
goto exit;
/* bit 1(blocking reseed): wait for trng entropy,
* then reseed rng context.
*/
if (get_se_soc_id(dev) != SOC_ID_OF_IMX95)
tx_msg->flags = BIT(1);
tx_msg->data[0] = dst_dma;
tx_msg->data[1] = len;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
ELE_GET_RANDOM_REQ,
ELE_GET_RANDOM_RSP_SZ,
false);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
ELE_GET_RANDOM_REQ, status);
ret = -1;
} else {
memcpy(data, buf, len);
ret = len;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
dmam_free_coherent(priv->dev, len, buf, dst_dma);
return ret;
}

View File

@ -1,26 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2023 NXP
*/
#ifndef ELE_FW_API_H
#define ELE_FW_API_H
#include <linux/hw_random.h>
#define MESSAGING_VERSION_7 0x7
#define ELE_INIT_FW_REQ 0x17
#define ELE_INIT_FW_REQ_SZ 0x04
#define ELE_INIT_FW_RSP_SZ 0x08
#define ELE_GET_RANDOM_REQ 0xCD
#define ELE_GET_RANDOM_REQ_SZ 0x10
#define ELE_GET_RANDOM_RSP_SZ 0x08
#define ELE_RNG_MAX_SIZE 16
int ele_init_fw(struct device *dev);
int ele_get_random(struct device *dev, void *data, size_t len);
int ele_get_hwrng(struct hwrng *rng, void *data, size_t len, bool wait);
#endif /* ELE_FW_API_H */

View File

@ -1,47 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* ELE Random Number Generator Driver NXP's Platforms
*
* Copyright 2023 NXP
*/
#include "ele_common.h"
#include "ele_fw_api.h"
struct ele_trng {
struct hwrng rng;
struct device *dev;
};
int ele_trng_init(struct device *dev)
{
struct ele_trng *trng;
int ret;
trng = devm_kzalloc(dev, sizeof(*trng), GFP_KERNEL);
if (!trng)
return -ENOMEM;
trng->dev = dev;
trng->rng.name = "ele-trng";
trng->rng.read = ele_get_hwrng;
trng->rng.priv = (unsigned long)trng;
trng->rng.quality = 1024;
dev_dbg(dev, "registering ele-trng\n");
ret = devm_hwrng_register(dev, &trng->rng);
if (ret)
return ret;
dev_info(dev, "Successfully registered ele-trng\n");
return 0;
}
int ele_get_hwrng(struct hwrng *rng,
void *data, size_t len, bool wait)
{
struct ele_trng *trng = (struct ele_trng *)rng->priv;
return ele_get_random(trng->dev, data, len);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,172 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2021-2024 NXP
*/
#ifndef SE_MU_H
#define SE_MU_H
#include <linux/miscdevice.h>
#include <linux/semaphore.h>
#include <linux/mailbox_client.h>
#define MAX_MESSAGE_SIZE 31
#define MAX_RECV_SIZE MAX_MESSAGE_SIZE
#define MAX_RECV_SIZE_BYTES (MAX_RECV_SIZE << 2)
#define MAX_MESSAGE_SIZE_BYTES (MAX_MESSAGE_SIZE << 2)
#define ELE_MSG_DATA_NUM 10
#define MSG_TAG(x) (((x) & 0xff000000) >> 24)
#define MSG_COMMAND(x) (((x) & 0x00ff0000) >> 16)
#define MSG_SIZE(x) (((x) & 0x0000ff00) >> 8)
#define MSG_VER(x) ((x) & 0x000000ff)
#define RES_STATUS(x) ((x) & 0x000000ff)
#define RES_IND(x) (((x) & 0x0000ff00) >> 8)
#define MAX_DATA_SIZE_PER_USER (65 * 1024)
#define S4_DEFAULT_MUAP_INDEX (2)
#define S4_MUAP_DEFAULT_MAX_USERS (4)
#define MESSAGING_VERSION_6 0x6
#define MESSAGING_VERSION_7 0x7
#define DEFAULT_MESSAGING_TAG_COMMAND (0x17u)
#define DEFAULT_MESSAGING_TAG_RESPONSE (0xe1u)
#define ELE_MU_IO_FLAGS_USE_SEC_MEM (0x02u)
#define ELE_MU_IO_FLAGS_USE_SHORT_ADDR (0x04u)
#define SOC_ID_OF_IMX95 0x9500
struct ele_imem_buf {
u8 *buf;
phys_addr_t phyaddr;
u32 size;
u32 state;
};
struct ele_buf_desc {
u8 *shared_buf_ptr;
u8 *usr_buf_ptr;
u32 size;
struct list_head link;
};
/* Status of a char device */
enum mu_device_status_t {
MU_FREE,
MU_OPENED
};
struct ele_shared_mem {
dma_addr_t dma_addr;
u32 size;
u32 pos;
u8 *ptr;
};
/* Private struct for each char device instance. */
struct ele_mu_device_ctx {
struct device *dev;
struct ele_mu_priv *priv;
struct miscdevice miscdev;
enum mu_device_status_t status;
wait_queue_head_t wq;
struct semaphore fops_lock;
bool signal_recvd;
u32 pending_hdr;
struct list_head pending_in;
struct list_head pending_out;
struct ele_shared_mem secure_mem;
struct ele_shared_mem non_secure_mem;
u32 mu_buff_offset;
u32 temp_cmd[MAX_MESSAGE_SIZE];
u32 temp_resp[MAX_RECV_SIZE];
u32 temp_resp_size;
struct notifier_block ele_notify;
};
/* Header of the messages exchange with the EdgeLock Enclave */
struct mu_hdr {
u8 ver;
u8 size;
u8 command;
u8 tag;
} __packed;
#define ELE_MU_HDR_SZ 4
#define TAG_OFFSET (ELE_MU_HDR_SZ - 1)
#define CMD_OFFSET (ELE_MU_HDR_SZ - 2)
#define SZ_OFFSET (ELE_MU_HDR_SZ - 3)
#define VER_OFFSET (ELE_MU_HDR_SZ - 4)
struct ele_api_msg {
u32 header; /* u8 Tag; u8 Command; u8 Size; u8 Ver; */
u32 data[ELE_MSG_DATA_NUM];
};
struct perf_time_frame {
struct timespec64 t_start;
struct timespec64 t_end;
};
struct ele_mu_priv {
struct list_head priv_data;
struct ele_mu_device_ctx *cmd_receiver_dev;
struct ele_mu_device_ctx *waiting_rsp_dev;
/*
* prevent parallel access to the MU registers
* e.g. a user trying to send a command while the other one is
* sending a response.
*/
struct mutex mu_lock;
/*
* prevent a command to be sent on the MU while another one is still
* processing. (response to a command is allowed)
*/
struct mutex mu_cmd_lock;
struct device *dev;
u8 ele_mu_did;
u8 pdev_name[20];
u32 ele_mu_id;
u8 cmd_tag;
u8 rsp_tag;
u8 success_tag;
u8 base_api_ver;
u8 fw_api_ver;
uint16_t abort_err_code;
u32 fw_fail;
const void *info;
struct mbox_client ele_mb_cl;
struct mbox_chan *tx_chan, *rx_chan;
struct ele_api_msg *tx_msg, *rx_msg;
struct completion done;
spinlock_t lock;
/*
* Flag to retain the state of initialization done at
* the time of ele-mu probe.
*/
uint32_t flags;
u8 max_dev_ctx;
struct ele_mu_device_ctx **ctxs;
struct ele_imem_buf imem;
struct perf_time_frame time_frame;
struct imx_sc_ipc *ipc_scu;
u8 part_owner;
u8 *se_img_file_to_load;
};
uint32_t get_se_soc_id(struct device *dev);
phys_addr_t get_phy_buf_mem_pool(struct device *dev,
char *mem_pool_name,
u32 **buf,
uint32_t size);
void free_phybuf_mem_pool(struct device *dev,
char *mem_pool_name,
u32 *buf,
uint32_t size);
#endif

View File

@ -8,7 +8,6 @@
#include <linux/firmware/imx/sci.h>
#include <linux/io.h>
#include "se_fw.h"
struct imx_sc_msg_seco_get_build_id {
struct imx_sc_rpc_msg hdr;
@ -250,145 +249,4 @@ int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
}
EXPORT_SYMBOL(imx_sc_seco_secvio_dgo_config);
int imx_scu_init_fw(struct device *dev)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
ret = imx_scu_get_handle(&priv->ipc_scu);
if (ret) {
dev_err(dev, "Fail to retrieve IPC handle\n");
return ret;
}
ret = imx_sc_rm_get_resource_owner(priv->ipc_scu, IMX_SC_R_SECO, &priv->part_owner);
if (ret) {
dev_err(dev, "Fail get owner of SECO resource\n");
return ret;
}
return ret;
}
EXPORT_SYMBOL(imx_scu_init_fw);
int imx_scu_sec_mem_cfg(struct file *fp, uint32_t offset, uint32_t size)
{
struct ele_mu_device_ctx *dev_ctx
= container_of(fp->private_data,
struct ele_mu_device_ctx,
miscdev);
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->secure_mem.dma_addr = (dma_addr_t)offset;
dev_ctx->secure_mem.size = size;
dev_ctx->secure_mem.pos = 0;
dev_ctx->secure_mem.ptr = devm_ioremap(dev_ctx->dev,
(phys_addr_t)(SECURE_RAM_BASE_ADDRESS +
(u64)dev_ctx->secure_mem.dma_addr),
dev_ctx->secure_mem.size);
if (!dev_ctx->secure_mem.ptr) {
dev_err(dev_ctx->priv->dev, "Failed to map secure memory\n");
return -ENOMEM;
}
return ret;
}
EXPORT_SYMBOL(imx_scu_sec_mem_cfg);
int imx_scu_mem_access(struct file *fp)
{
struct ele_mu_device_ctx *dev_ctx
= container_of(fp->private_data,
struct ele_mu_device_ctx,
miscdev);
struct ele_mu_priv *priv = dev_ctx->priv;
u8 mr;
u64 addr;
int ret;
addr = dev_ctx->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->miscdev.name);
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->miscdev.name);
return ret;
}
return ret;
}
EXPORT_SYMBOL(imx_scu_mem_access);
int imx_scu_signed_msg(struct file *fp,
uint8_t *msg,
uint32_t size,
uint32_t *error)
{
struct ele_mu_device_ctx *dev_ctx
= container_of(fp->private_data,
struct ele_mu_device_ctx,
miscdev);
struct ele_mu_priv *priv = dev_ctx->priv;
struct ele_shared_mem *shared_mem = &dev_ctx->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;
}
EXPORT_SYMBOL(imx_scu_signed_msg);

File diff suppressed because it is too large Load Diff

View File

@ -1,70 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2021-2023 NXP
*/
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/firmware/imx/v2x_base_msg.h>
#include "ele_common.h"
/*
* v2x_start_rng() - prepare and send the command to start
* initialization of the ELE RNG context
*
* returns: 0 on success.
*/
int v2x_start_rng(struct device *dev)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
int ret;
unsigned int status;
mutex_lock(&priv->mu_cmd_lock);
ret = imx_se_alloc_tx_rx_buf(priv);
if (ret)
goto exit;
ret = plat_fill_cmd_msg_hdr(priv,
(struct mu_hdr *)&priv->tx_msg->header,
V2X_START_RNG_REQ,
V2X_START_RNG_REQ_MSG_SZ,
true);
if (ret)
goto exit;
ret = imx_ele_msg_send_rcv(priv);
if (ret < 0)
goto exit;
ret = validate_rsp_hdr(priv,
priv->rx_msg->header,
V2X_START_RNG_REQ,
V2X_START_RNG_RSP_MSG_SZ,
true);
if (ret)
goto exit;
status = RES_STATUS(priv->rx_msg->data[0]);
if (status != priv->success_tag) {
/* Initialization in progress for:
* P-TRNG at bit 0
* S-TRNG at bit 1
* Any of the bit is set, it in progress.
*/
if (priv->rx_msg->data[1] & 0x3)
goto exit;
dev_err(dev, "Command Id[%d], Response Failure = 0x%x",
V2X_START_RNG_REQ, status);
ret = -1;
}
exit:
imx_se_free_tx_rx_buf(priv);
mutex_unlock(&priv->mu_cmd_lock);
return ret;
}

View File

@ -1,102 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2021-2024 NXP
*
* Header file for the ELE Base API(s).
*/
#ifndef ELE_BASE_MSG_H
#define ELE_BASE_MSG_H
#include <linux/types.h>
#define WORD_SZ 4
#define ELE_NONE_VAL 0x0
#define ELE_SUCCESS_IND 0xD6
#define ELE_GET_INFO_REQ 0xDA
#define ELE_GET_INFO_REQ_MSG_SZ 0x10
#define ELE_GET_INFO_RSP_MSG_SZ 0x08
#define ELE_GET_INFO_BUFF_SZ 0x100
#define ELE_GET_INFO_READ_SZ 0xA0
#define DEVICE_GET_INFO_SZ 0x100
#define GET_INFO_SOC_INFO_WORD_OFFSET 1
#define GET_INFO_UUID_WORD_OFFSET 3
#define GET_INFO_SL_NUM_MSB_WORD_OFF \
(GET_INFO_UUID_WORD_OFFSET + 3)
#define GET_INFO_SL_NUM_LSB_WORD_OFF \
(GET_INFO_UUID_WORD_OFFSET + 0)
#define ELE_PING_REQ 0x01
#define ELE_PING_REQ_SZ 0x04
#define ELE_PING_RSP_SZ 0x08
#define ELE_START_RNG_REQ 0xA3
#define ELE_START_RNG_REQ_MSG_SZ 0x04
#define ELE_START_RNG_RSP_MSG_SZ 0x08
#define ELE_GET_TRNG_STATE_REQ 0xA4
#define ELE_GET_TRNG_STATE_REQ_MSG_SZ 0x04
#define ELE_GET_TRNG_STATE_RSP_MSG_SZ 0x0C
#define ELE_TRNG_STATE_OK 0x203
#define ELE_GET_TRNG_STATE_RETRY_COUNT 0x5
#define CSAL_TRNG_STATE_MASK 0x0000ffff
#define ELE_SERVICE_SWAP_REQ 0xDF
#define ELE_SERVICE_SWAP_REQ_MSG_SZ 0x18
#define ELE_SERVICE_SWAP_RSP_MSG_SZ 0x0C
#define ELE_IMEM_SIZE 0x10000
#define ELE_IMEM_STATE_OK 0xCA
#define ELE_IMEM_STATE_BAD 0xFE
#define ELE_IMEM_STATE_WORD 0x27
#define ELE_IMEM_STATE_MASK 0x00ff0000
#define ELE_IMEM_EXPORT 0x1
#define ELE_IMEM_IMPORT 0x2
#define ELE_FW_AUTH_REQ 0x02
#define ELE_FW_AUTH_REQ_SZ 0x10
#define ELE_FW_AUTH_RSP_MSG_SZ 0x08
#define ELE_READ_FUSE_REQ 0x97
#define ELE_READ_FUSE_REQ_MSG_SZ 0x08
#define ELE_READ_FUSE_RSP_MSG_SZ 0x0C
#define ELE_READ_FUSE_OTP_UNQ_ID_RSP_MSG_SZ \
0x1C
#define OTP_UNIQ_ID 0x01
#define OTFAD_CONFIG 0x2
#define ELE_GET_STATE 0xB2
#define ELE_GET_STATE_REQ_SZ 0x04
#define ELE_GET_STATE_RSP_SZ 0x10
#define ELE_WRITE_FUSE 0xD6
#define ELE_WRITE_FUSE_REQ_MSG_SZ 12
#define ELE_WRITE_FUSE_RSP_MSG_SZ 12
#define V2X_FW_STATE_UNKNOWN 0x00
#define V2X_FW_STATE_RUNNING 0x15
#define ELE_VOLT_CHANGE_START_REQ 0x12
#define ELE_VOLT_CHANGE_FINISH_REQ 0x13
#define ELE_VOLT_CHANGE_REQ_MSG_SZ 0x4
#define ELE_VOLT_CHANGE_RSP_MSG_SZ 0x8
int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size);
int ele_ping(struct device *dev);
int ele_start_rng(struct device *dev);
int ele_get_trng_state(struct device *dev);
int ele_service_swap(struct device *dev,
phys_addr_t addr,
u32 addr_size, u16 flag);
int ele_get_v2x_fw_state(struct device *dev, uint32_t *state);
int ele_write_fuse(struct device *dev, uint16_t fuse_index, u32 value, bool block);
int ele_voltage_change_req(struct device *dev, bool start);
int read_common_fuse(struct device *dev,
uint16_t fuse_id, u32 *value);
int ele_fw_authenticate(struct device *dev, phys_addr_t addr);
#endif

View File

@ -1,112 +0,0 @@
/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause*/
/*
* Copyright 2019-2024 NXP
*/
#ifndef ELE_MU_IOCTL_H
#define ELE_MU_IOCTL_H
/* IOCTL definitions. */
struct ele_mu_ioctl_setup_iobuf {
u8 *user_buf;
u32 length;
u32 flags;
u64 ele_addr;
};
struct ele_mu_ioctl_shared_mem_cfg {
u32 base_offset;
u32 size;
};
struct ele_mu_ioctl_get_mu_info {
u8 ele_mu_id;
u8 interrupt_idx;
u8 tz;
u8 did;
u8 cmd_tag;
u8 rsp_tag;
u8 success_tag;
u8 base_api_ver;
u8 fw_api_ver;
};
struct ele_mu_ioctl_signed_message {
u8 *message;
u32 msg_size;
u32 error_code;
};
struct ele_mu_ioctl_get_soc_info {
u16 soc_id;
u16 soc_rev;
u8 board_type;
};
struct ele_time_frame {
struct timespec64 t_start;
struct timespec64 t_end;
};
/* IO Buffer Flags */
#define ELE_MU_IO_FLAGS_IS_OUTPUT (0x00u)
#define ELE_MU_IO_FLAGS_IS_INPUT (0x01u)
#define ELE_MU_IO_FLAGS_USE_SEC_MEM (0x02u)
#define ELE_MU_IO_FLAGS_USE_SHORT_ADDR (0x04u)
#define ELE_MU_IO_DATA_BUF_SHE_V2X (0x08u)
#define ELE_MU_IO_FLAGS_IS_IN_OUT (0x10u)
/* IOCTLS */
#define ELE_MU_IOCTL 0x0A /* like MISC_MAJOR. */
/*
* ioctl to designated the current fd as logical-reciever.
* This is ioctl is send when the nvm-daemon, a slave to the
* firmware is started by the user.
*/
#define ELE_MU_IOCTL_ENABLE_CMD_RCV _IO(ELE_MU_IOCTL, 0x01)
/*
* ioctl to get configure the SCU shared buffer.
*/
#define ELE_MU_IOCTL_SHARED_BUF_CFG _IOW(ELE_MU_IOCTL, 0x02, \
struct ele_mu_ioctl_shared_mem_cfg)
/*
* ioctl to get the buffer allocated from the memory, which is shared
* between kernel and FW.
* Post allocation, the kernel tagged the allocated memory with:
* Output
* Input
* Input-Output
* Short address
* Secure-memory
*/
#define ELE_MU_IOCTL_SETUP_IOBUF _IOWR(ELE_MU_IOCTL, 0x03, \
struct ele_mu_ioctl_setup_iobuf)
/*
* ioctl to get the mu information, that is used to exchange message
* with FW, from user-spaced.
*/
#define ELE_MU_IOCTL_GET_MU_INFO _IOR(ELE_MU_IOCTL, 0x04, \
struct ele_mu_ioctl_get_mu_info)
/*
* ioctl to send signed message to SE.
*/
#define ELE_MU_IOCTL_SIGNED_MESSAGE _IOR(ELE_MU_IOCTL, 0x05, \
struct ele_mu_ioctl_signed_message)
/*
* ioctl to get SoC Info from user-space.
*/
#define ELE_MU_IOCTL_GET_SOC_INFO _IOR(ELE_MU_IOCTL, 0x06, \
struct ele_mu_ioctl_get_soc_info)
/*
* ioctl to capture the timestamp at the request to FW and response from FW
* for a crypto operation
*/
#define ELE_MU_IOCTL_GET_TIMER _IOR(ELE_MU_IOCTL, 0x08, struct ele_time_frame)
#endif

View File

@ -1,10 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2023 NXP
*/
#ifndef SE_FW_INC_H
#define SE_FW_INC_H
struct device *get_se_dev(const uint8_t *pdev_name);
#endif /* SE_FW_INC_H */

View File

@ -1,63 +0,0 @@
/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause*/
/*
* Copyright 2019-2020, 2023 NXP
*/
#ifndef SECO_MU_IOCTL_H
#define SECO_MU_IOCTL_H
/* IOCTL definitions. */
struct seco_mu_ioctl_setup_iobuf {
u8 *user_buf;
u32 length;
u32 flags;
u64 seco_addr;
};
struct seco_mu_ioctl_shared_mem_cfg {
u32 base_offset;
u32 size;
};
struct seco_mu_ioctl_get_mu_info {
u8 seco_mu_idx;
u8 interrupt_idx;
u8 tz;
u8 did;
u8 cmd_tag;
u8 rsp_tag;
u8 success_tag;
u8 base_api_ver;
u8 fw_api_ver;
};
struct seco_mu_ioctl_signed_message {
u8 *message;
u32 msg_size;
u32 error_code;
};
struct seco_mu_ioctl_get_soc_info {
u16 soc_id;
u16 soc_rev;
};
#define SECO_MU_IO_FLAGS_IS_INPUT (0x01u)
#define SECO_MU_IO_FLAGS_USE_SEC_MEM (0x02u)
#define SECO_MU_IO_FLAGS_USE_SHORT_ADDR (0x04u)
#define SECO_MU_IO_FLAGS_SHE_V2X (0x08u)
#define SECO_MU_IOCTL 0x0A /* like MISC_MAJOR. */
#define SECO_MU_IOCTL_ENABLE_CMD_RCV _IO(SECO_MU_IOCTL, 0x01)
#define SECO_MU_IOCTL_SHARED_BUF_CFG _IOW(SECO_MU_IOCTL, 0x02, \
struct seco_mu_ioctl_shared_mem_cfg)
#define SECO_MU_IOCTL_SETUP_IOBUF _IOWR(SECO_MU_IOCTL, 0x03, \
struct seco_mu_ioctl_setup_iobuf)
#define SECO_MU_IOCTL_GET_MU_INFO _IOR(SECO_MU_IOCTL, 0x04, \
struct seco_mu_ioctl_get_mu_info)
#define SECO_MU_IOCTL_SIGNED_MESSAGE _IOWR(SECO_MU_IOCTL, 0x05, \
struct seco_mu_ioctl_signed_message)
#define SECO_MU_IOCTL_GET_SOC_INFO _IOR(SECO_MU_IOCTL, 0x06, \
struct seco_mu_ioctl_get_soc_info)
#endif

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2020 NXP
* Copyright 2020, 2024 NXP
*
* Header file containing the public API for the System Controller (SC)
* Security Controller (SECO) function.
@ -42,10 +42,6 @@ int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data4, u8 size);
int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
u32 *data);
int imx_scu_init_fw(struct device *dev);
int imx_scu_sec_mem_cfg(struct file *fp, uint32_t offset, uint32_t size);
int imx_scu_mem_access(struct file *fp);
int imx_scu_signed_msg(struct file *fp, uint8_t *msg, uint32_t size, uint32_t *error);
#else /* IS_ENABLED(CONFIG_IMX_SCU) */
static inline
int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
@ -81,29 +77,6 @@ int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
return -EOPNOTSUPP;
}
static inline
int imx_scu_init_fw(struct device *dev)
{
return -EOPNOTSUPP;
}
static inline
int imx_scu_sec_mem_cfg(struct file *fp, uint32_t offset, uint32_t size)
{
return -EOPNOTSUPP;
}
static inline
int imx_scu_signed_msg(struct file *fp, uint8_t *msg, uint32_t size, uint32_t *error)
{
return -EOPNOTSUPP;
}
static inline
int imx_scu_mem_access(struct file *fp)//device *dev)
{
return -EOPNOTSUPP;
}
#endif /* IS_ENABLED(CONFIG_IMX_SCU) */
#endif /* _SC_SECO_API_H */

View File

@ -1,20 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2021-2023 NXP
*
* Header file for the ELE Base API(s).
*/
#ifndef V2X_BASE_MSG_H
#define V2X_BASE_MSG_H
#include <linux/types.h>
#define WORD_SZ 4
#define V2X_START_RNG_REQ 0x0E
#define V2X_START_RNG_REQ_MSG_SZ 0x04
#define V2X_START_RNG_RSP_MSG_SZ 0x0C
int v2x_start_rng(struct device *dev);
#endif