mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2026-01-27 12:35:36 +01:00
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:
parent
ab72b4936f
commit
bdeff7cd56
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue
Block a user