LF-13910-3: firmware: imx: additional changes to the upstream driver.

additional changes to the upstream driver.
- construct se_name from se_type_id and instance id
- move soc_register to info_list
- move fetch soc info function pointer to info_list
- ele soc fetch generalization
- ele debug dump

Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
Acked-by: Rahul Kumar Yadav <rahulkumar.yadav@nxp.com>
Acked-by: Vabhav Sharma <vabhav.sharma@nxp.com>
Acked-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
Acked-by: Jason Liu <jason.hui.liu@nxp.com>
This commit is contained in:
Pankaj Gupta 2024-11-12 15:22:42 +05:30 committed by Jason Liu
parent 9dfd27b6b2
commit ad497d1c5b
6 changed files with 325 additions and 143 deletions

View File

@ -12,6 +12,8 @@
#include "ele_base_msg.h"
#include "ele_common.h"
#define FW_DBG_DUMP_FIXED_STR "\nELEX: "
int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
{
struct se_api_msg *tx_msg __free(kfree) = NULL;
@ -95,20 +97,14 @@ exit:
return ret;
}
int ele_fetch_soc_info(struct se_if_priv *priv, u16 *soc_rev, u64 *serial_num)
int ele_fetch_soc_info(struct se_if_priv *priv, void *data)
{
struct ele_dev_info s_info = {0};
int err;
err = ele_get_info(priv, &s_info);
err = ele_get_info(priv, data);
if (err < 0)
return err;
if (soc_rev)
*soc_rev = s_info.d_info.soc_rev;
if (serial_num)
*serial_num = GET_SERIAL_NUM_FROM_UID(s_info.d_info.uid, MAX_UID_SIZE >> 2);
return err;
}
@ -276,3 +272,135 @@ int ele_fw_authenticate(struct se_if_priv *priv, phys_addr_t addr)
exit:
return ret;
}
int ele_debug_dump(struct se_if_priv *priv)
{
struct se_api_msg *tx_msg __free(kfree) = NULL;
struct se_api_msg *rx_msg __free(kfree) = NULL;
bool keep_logging;
u8 dump_data[408];
u8 fmt_str[256];
int fmt_str_idx;
int rcv_dbg_wd_ct;
int msg_ex_cnt;
int ret = 0;
int w_ct;
if (!priv) {
ret = -EINVAL;
goto exit;
}
tx_msg = kzalloc(ELE_DEBUG_DUMP_REQ_SZ, GFP_KERNEL);
if (!tx_msg) {
ret = -ENOMEM;
goto exit;
}
rx_msg = kzalloc(ELE_DEBUG_DUMP_RSP_SZ, GFP_KERNEL);
if (!rx_msg) {
ret = -ENOMEM;
goto exit;
}
ret = se_fill_cmd_msg_hdr(priv,
&tx_msg->header,
ELE_DEBUG_DUMP_REQ,
ELE_DEBUG_DUMP_REQ_SZ,
true);
if (ret)
goto exit;
msg_ex_cnt = 0;
do {
w_ct = 0;
fmt_str_idx = 0;
memset(rx_msg, 0xCC, ELE_DEBUG_DUMP_RSP_SZ);
ret = ele_msg_send_rcv(priv->priv_dev_ctx,
tx_msg,
ELE_DEBUG_DUMP_REQ_SZ,
rx_msg,
ELE_DEBUG_DUMP_RSP_SZ);
if (ret < 0)
goto exit;
ret = se_val_rsp_hdr_n_status(priv,
rx_msg,
ELE_DEBUG_DUMP_REQ,
ELE_DEBUG_DUMP_RSP_SZ,
true);
if (!ret) {
rcv_dbg_wd_ct = rx_msg->header.size - ELE_NON_DUMP_BUFFER_SZ;
memcpy(fmt_str, FW_DBG_DUMP_FIXED_STR, strlen(FW_DBG_DUMP_FIXED_STR));
fmt_str_idx += strlen(FW_DBG_DUMP_FIXED_STR);
for (w_ct = 0; w_ct < rcv_dbg_wd_ct; w_ct++) {
fmt_str[fmt_str_idx] = '0';
fmt_str_idx++;
fmt_str[fmt_str_idx] = 'x';
fmt_str_idx++;
fmt_str[fmt_str_idx] = '%';
fmt_str_idx++;
fmt_str[fmt_str_idx] = '0';
fmt_str_idx++;
fmt_str[fmt_str_idx] = '8';
fmt_str_idx++;
fmt_str[fmt_str_idx] = 'x';
fmt_str_idx++;
fmt_str[fmt_str_idx] = ' ';
fmt_str_idx++;
if (w_ct % 2) {
memcpy(fmt_str + fmt_str_idx,
FW_DBG_DUMP_FIXED_STR,
strlen(FW_DBG_DUMP_FIXED_STR));
fmt_str_idx += strlen(FW_DBG_DUMP_FIXED_STR);
}
}
keep_logging = (rx_msg->header.size < (ELE_DEBUG_DUMP_RSP_SZ >> 2)) ?
false : true;
keep_logging = keep_logging ?
(msg_ex_cnt > ELE_MAX_DBG_DMP_PKT ? false : true) :
false;
/*
* Number of spaces = rcv_dbg_wd_ct
* DBG dump length in bytes = rcv_dbg_wd_ct * 4
*
* Since, one byte is represented as 2 character,
* DBG Dump string-length = rcv_dbg_wd_ct * 8
* Fixed string's string-length =
* strlen(FW_DBG_DUMP_FIXED_STR) * rcv_dbg_wd_ct
*
* Total dump_data length = Number of spaces +
* DBG Dump string' string-length +
* Fixed string's string-length
*
* Total dump_data length = rcv_dbg_wd_ct + (rcv_dbg_wd_ct * 8) +
* strlen(FW_DBG_DUMP_FIXED_STR) * rcv_dbg_wd_ct
*/
snprintf(dump_data,
((rcv_dbg_wd_ct * 9) +
(strlen(FW_DBG_DUMP_FIXED_STR) * rcv_dbg_wd_ct)),
fmt_str,
rx_msg->data[1], rx_msg->data[2],
rx_msg->data[3], rx_msg->data[4],
rx_msg->data[5], rx_msg->data[6],
rx_msg->data[7], rx_msg->data[8],
rx_msg->data[9], rx_msg->data[10],
rx_msg->data[11], rx_msg->data[12],
rx_msg->data[13], rx_msg->data[14],
rx_msg->data[15], rx_msg->data[16],
rx_msg->data[17], rx_msg->data[18],
rx_msg->data[19], rx_msg->data[20]);
dev_err(priv->dev, "%s", dump_data);
} else {
dev_err(priv->dev, "Dump_Debug_Buffer Error: %x.", ret);
break;
}
msg_ex_cnt++;
} while (keep_logging);
exit:
return ret;
}

View File

@ -62,8 +62,11 @@ struct ele_dev_info {
#define GET_SERIAL_NUM_FROM_UID(x, uid_word_sz) \
(((u64)(((u32 *)(x))[(uid_word_sz) - 1]) << 32) | ((u32 *)(x))[0])
#define ELE_MAX_DBG_DMP_PKT 30
#define ELE_NON_DUMP_BUFFER_SZ 3
#define ELE_DEBUG_DUMP_REQ 0x21
#define ELE_DEBUG_DUMP_RSP_SZ 0x17
#define ELE_DEBUG_DUMP_REQ_SZ 0x4
#define ELE_DEBUG_DUMP_RSP_SZ 0x5c
#define ELE_PING_REQ 0x01
#define ELE_PING_REQ_SZ 0x04
@ -85,10 +88,11 @@ struct ele_dev_info {
#define ELE_FW_AUTH_RSP_MSG_SZ 0x08
int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info);
int ele_fetch_soc_info(struct se_if_priv *priv, u16 *soc_rev, u64 *serial_num);
int ele_fetch_soc_info(struct se_if_priv *priv, void *data);
int ele_ping(struct se_if_priv *priv);
int ele_service_swap(struct se_if_priv *priv,
phys_addr_t addr,
u32 addr_size, u16 flag);
int ele_fw_authenticate(struct se_if_priv *priv, phys_addr_t addr);
int ele_debug_dump(struct se_if_priv *priv);
#endif

View File

@ -86,13 +86,12 @@ int ele_msg_send(struct se_if_device_ctx *dev_ctx,
* carried in the message.
*/
if (header->size << 2 != tx_msg_sz) {
err = -EINVAL;
dev_err(priv->dev,
"%s: User buf hdr: 0x%x, sz mismatced with input-sz (%d != %d).",
dev_ctx->devname,
*(u32 *)header,
header->size << 2, tx_msg_sz);
goto exit;
return -EINVAL;
}
err = mbox_send_message(priv->tx_chan, tx_msg);
@ -104,7 +103,6 @@ int ele_msg_send(struct se_if_device_ctx *dev_ctx,
}
err = tx_msg_sz;
exit:
return err;
}
@ -320,7 +318,7 @@ int se_save_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem)
imem->size = ret;
}
return ret;
return ret > 0 ? 0 : -1;
}
int se_restore_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem)
@ -336,8 +334,10 @@ int se_restore_imem_state(struct se_if_priv *priv, struct se_imem_buf *imem)
}
imem->state = s_info.d_addn_info.imem_state;
/* Get IMEM state, if 0xFE then import IMEM */
if (s_info.d_addn_info.imem_state == ELE_IMEM_STATE_BAD) {
/* Get IMEM state, if 0xFE and saved/exported IMEM buffer size is non-zero,
* then import IMEM
*/
if (s_info.d_addn_info.imem_state == ELE_IMEM_STATE_BAD && imem->size) {
/* IMPORT command will restore IMEM from the given
* address, here size is the actual size returned by ELE
* during the export operation

View File

@ -29,22 +29,24 @@
#include "ele_common.h"
#include "se_ctrl.h"
#define MAX_SOC_INFO_DATA_SZ 256
#define MBOX_TX_NAME "tx"
#define MBOX_RX_NAME "rx"
#define SE_TYPE_HSM "hsm"
#define SE_RCV_MSG_DEFAULT_TIMEOUT 5000
#define SE_RCV_MSG_LONG_TIMEOUT 5000000
u32 se_rcv_msg_timeout = SE_RCV_MSG_DEFAULT_TIMEOUT;
struct se_fw_load_info {
struct se_fw_img_name {
const u8 *prim_fw_nm_in_rfs;
const u8 *seco_fw_nm_in_rfs;
/* Mutex to prevent two parallel FW loading. */
struct mutex se_fw_load;
};
struct se_fw_load_info {
const struct se_fw_img_name *se_fw_img_nm;
bool is_fw_loaded;
bool handle_susp_resm;
bool imem_mgmt;
struct se_imem_buf imem;
};
@ -52,51 +54,63 @@ struct se_if_node_info {
u8 se_if_id;
u8 se_if_did;
struct se_if_defines if_defs;
u8 *se_name;
u8 *pool_name;
bool soc_register;
bool reserved_dma_ranges;
int (*se_fetch_soc_info)(struct se_if_priv *priv, u16 *soc_rev, u64 *serial_num);
};
/* contains fixed information */
struct se_if_node_info_list {
const u8 num_mu;
const u16 soc_id;
struct se_fw_load_info load_hsm_fw;
bool soc_register;
int (*se_fetch_soc_info)(struct se_if_priv *priv, void *data);
const struct se_fw_img_name se_fw_img_nm;
const struct se_if_node_info info[];
};
static u16 se_soc_rev;
struct se_var_info {
u8 board_type;
u16 soc_id;
u16 soc_rev;
struct se_fw_load_info load_fw;
};
static struct se_var_info var_se_info = {
.board_type = 0,
.soc_id = 0,
.soc_rev = 0,
.load_fw = {
.is_fw_loaded = true,
.imem_mgmt = false,
},
};
static struct se_if_node_info_list imx8ulp_info = {
.num_mu = 1,
.soc_id = SOC_ID_OF_IMX8ULP,
.load_hsm_fw = {
.soc_register = true,
.se_fetch_soc_info = ele_fetch_soc_info,
.se_fw_img_nm = {
.prim_fw_nm_in_rfs = IMX_ELE_FW_DIR
"mx8ulpa2-ahab-container.img",
.seco_fw_nm_in_rfs = IMX_ELE_FW_DIR
"mx8ulpa2ext-ahab-container.img",
.is_fw_loaded = false,
.handle_susp_resm = true,
.imem = {
.state = ELE_IMEM_STATE_OK,
},
},
.info = {
{
.se_if_id = 0,
.se_if_did = 7,
.if_defs = {
.se_if_type = SE_TYPE_ID_HSM,
.se_instance_id = 0,
.cmd_tag = 0x17,
.rsp_tag = 0xe1,
.success_tag = ELE_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_6,
.fw_api_ver = MESSAGING_VERSION_7,
},
.se_name = SE_TYPE_HSM "1",
.pool_name = "sram",
.soc_register = true,
.reserved_dma_ranges = true,
.se_fetch_soc_info = ele_fetch_soc_info,
},
},
};
@ -104,26 +118,26 @@ static struct se_if_node_info_list imx8ulp_info = {
static struct se_if_node_info_list imx93_info = {
.num_mu = 1,
.soc_id = SOC_ID_OF_IMX93,
.load_hsm_fw = {
.soc_register = false,
.se_fetch_soc_info = ele_fetch_soc_info,
.se_fw_img_nm = {
.prim_fw_nm_in_rfs = NULL,
.seco_fw_nm_in_rfs = NULL,
.is_fw_loaded = true,
.handle_susp_resm = false,
},
.info = {
{
.se_if_id = 2,
.se_if_did = 3,
.if_defs = {
.se_if_type = SE_TYPE_ID_HSM,
.se_instance_id = 0,
.cmd_tag = 0x17,
.rsp_tag = 0xe1,
.success_tag = ELE_SUCCESS_IND,
.base_api_ver = MESSAGING_VERSION_6,
.fw_api_ver = MESSAGING_VERSION_7,
},
.se_name = SE_TYPE_HSM "1",
.reserved_dma_ranges = true,
.soc_register = true,
},
},
};
@ -134,62 +148,101 @@ static const struct of_device_id se_match[] = {
{},
};
static const struct se_if_node_info
*get_se_if_node_info(const struct se_if_node_info_list *info_list,
const u32 idx)
char *get_se_if_name(u8 se_if_id)
{
return &info_list->info[idx];
switch (se_if_id) {
case SE_TYPE_ID_DBG: return SE_TYPE_STR_DBG;
case SE_TYPE_ID_HSM: return SE_TYPE_STR_HSM;
case SE_TYPE_ID_SHE: return SE_TYPE_STR_SHE;
case SE_TYPE_ID_V2X_DBG: return SE_TYPE_STR_V2X_DBG;
case SE_TYPE_ID_V2X_SHE: return SE_TYPE_STR_V2X_SHE;
case SE_TYPE_ID_V2X_SV: return SE_TYPE_STR_V2X_SV;
case SE_TYPE_ID_V2X_SG: return SE_TYPE_STR_V2X_SG;
}
return NULL;
}
/*
* get_se_soc_id() - to fetch the soc_id of the platform
*
* @priv : reference to the private data per SE MU interface.
*
* This function returns the SoC ID.
*
* Context: Other module, requiring to access the secure services based on SoC Id.
*
* Return: SoC Id of the device.
*/
uint32_t get_se_soc_id(struct se_if_priv *priv)
{
const struct se_if_node_info_list *info_list =
device_get_match_data(priv->dev);
if (var_se_info.soc_rev)
return var_se_info.soc_id;
else
return info_list->soc_id;
}
static struct se_fw_load_info *get_load_fw_instance(struct se_if_priv *priv)
{
return &var_se_info.load_fw;
}
static int se_soc_info(struct se_if_priv *priv)
{
const struct se_if_node_info *info;
struct se_if_node_info_list *info_list;
const struct se_if_node_info_list *info_list = device_get_match_data(priv->dev);
struct se_fw_load_info *load_fw = get_load_fw_instance(priv);
struct soc_device_attribute *attr;
struct ele_dev_info *s_info;
struct soc_device *sdev;
u64 serial_num;
u8 data[MAX_SOC_INFO_DATA_SZ];
int err = 0;
info = container_of(priv->if_defs, typeof(*info), if_defs);
info_list = container_of(info, typeof(*info_list), info[info->se_if_id]);
/* This function should be called once.
* Check if the se_soc_rev is zero to continue.
*/
if (se_soc_rev)
if (var_se_info.soc_rev)
return err;
if (info->se_fetch_soc_info) {
err = info->se_fetch_soc_info(priv, &se_soc_rev, &serial_num);
if (info_list->se_fetch_soc_info) {
err = info_list->se_fetch_soc_info(priv, &data);
if (err < 0) {
dev_err(priv->dev, "Failed to fetch SoC Info.");
return err;
}
s_info = (void *)data;
var_se_info.board_type = 0;
var_se_info.soc_id = info_list->soc_id;
var_se_info.soc_rev = s_info->d_info.soc_rev;
load_fw->imem.state = s_info->d_addn_info.imem_state;
} else {
dev_err(priv->dev, "Failed to fetch SoC revision.");
if (info->soc_register)
if (info_list->soc_register)
dev_err(priv->dev, "Failed to do SoC registration.");
err = -EINVAL;
return err;
}
if (!info->soc_register)
if (!info_list->soc_register)
return 0;
attr = devm_kzalloc(priv->dev, sizeof(*attr), GFP_KERNEL);
if (!attr)
return -ENOMEM;
if (FIELD_GET(DEV_GETINFO_MIN_VER_MASK, se_soc_rev))
if (FIELD_GET(DEV_GETINFO_MIN_VER_MASK, var_se_info.soc_rev))
attr->revision = devm_kasprintf(priv->dev, GFP_KERNEL, "%x.%x",
FIELD_GET(DEV_GETINFO_MIN_VER_MASK,
se_soc_rev),
var_se_info.soc_rev),
FIELD_GET(DEV_GETINFO_MAJ_VER_MASK,
se_soc_rev));
var_se_info.soc_rev));
else
attr->revision = devm_kasprintf(priv->dev, GFP_KERNEL, "%x",
FIELD_GET(DEV_GETINFO_MAJ_VER_MASK,
se_soc_rev));
var_se_info.soc_rev));
switch (info_list->soc_id) {
case SOC_ID_OF_IMX8ULP:
@ -210,7 +263,8 @@ static int se_soc_info(struct se_if_priv *priv)
attr->family = devm_kasprintf(priv->dev, GFP_KERNEL, "Freescale i.MX");
attr->serial_number = devm_kasprintf(priv->dev, GFP_KERNEL, "%016llX",
serial_num);
GET_SERIAL_NUM_FROM_UID(s_info->d_info.uid,
MAX_UID_SIZE >> 2));
sdev = soc_device_register(attr);
if (IS_ERR(sdev))
@ -219,24 +273,6 @@ static int se_soc_info(struct se_if_priv *priv)
return 0;
}
static struct se_fw_load_info *get_load_fw_instance(struct se_if_priv *priv)
{
const struct se_if_node_info *info = container_of(priv->if_defs,
typeof(*info),
if_defs);
struct se_if_node_info_list *info_list;
struct se_fw_load_info *load_fw = NULL;
info_list = container_of(info, typeof(*info_list), info[info->se_if_id]);
if (!memcmp(SE_TYPE_HSM, info->se_name, strlen(SE_TYPE_HSM)))
load_fw = &info_list->load_hsm_fw;
else
dev_err(priv->dev, "Invalid load fw configuration.");
return load_fw;
}
static int se_load_firmware(struct se_if_priv *priv)
{
struct se_fw_load_info *load_fw = get_load_fw_instance(priv);
@ -246,25 +282,13 @@ static int se_load_firmware(struct se_if_priv *priv)
u8 *se_fw_buf;
int ret;
guard(mutex)(&load_fw->se_fw_load);
if (load_fw->is_fw_loaded)
return 0;
se_img_file_to_load = load_fw->seco_fw_nm_in_rfs;
if (load_fw->prim_fw_nm_in_rfs) {
/* allocate buffer where SE store encrypted IMEM */
load_fw->imem.buf = dmam_alloc_coherent(priv->dev, ELE_IMEM_SIZE,
&load_fw->imem.phyaddr,
GFP_KERNEL);
if (!load_fw->imem.buf) {
dev_err(priv->dev,
"dmam-alloc-failed: To store encr-IMEM.\n");
ret = -ENOMEM;
goto exit;
}
if (load_fw->imem.state == ELE_IMEM_STATE_BAD)
se_img_file_to_load = load_fw->prim_fw_nm_in_rfs;
}
se_img_file_to_load = load_fw->se_fw_img_nm->seco_fw_nm_in_rfs;
if (load_fw->se_fw_img_nm->prim_fw_nm_in_rfs &&
load_fw->imem.state == ELE_IMEM_STATE_BAD)
se_img_file_to_load = load_fw->se_fw_img_nm->prim_fw_nm_in_rfs;
do {
ret = request_firmware(&fw, se_img_file_to_load, priv->dev);
@ -300,8 +324,8 @@ static int se_load_firmware(struct se_if_priv *priv)
fw = NULL;
if (!ret && load_fw->imem.state == ELE_IMEM_STATE_BAD &&
se_img_file_to_load == load_fw->prim_fw_nm_in_rfs)
se_img_file_to_load = load_fw->seco_fw_nm_in_rfs;
se_img_file_to_load == load_fw->se_fw_img_nm->prim_fw_nm_in_rfs)
se_img_file_to_load = load_fw->se_fw_img_nm->seco_fw_nm_in_rfs;
else
se_img_file_to_load = NULL;
@ -470,9 +494,6 @@ static int init_device_context(struct se_if_priv *priv, int ch_id,
struct se_if_device_ctx **new_dev_ctx,
const struct file_operations *se_if_fops)
{
const struct se_if_node_info *info = container_of(priv->if_defs,
typeof(*info),
if_defs);
struct se_if_device_ctx *dev_ctx;
int ret = 0;
@ -489,12 +510,13 @@ static int init_device_context(struct se_if_priv *priv, int ch_id,
dev_ctx->priv = priv;
if (ch_id)
dev_ctx->devname = kasprintf(GFP_KERNEL, "%s_ch%d",
info->se_name, ch_id);
dev_ctx->devname = kasprintf(GFP_KERNEL, "%s%d_ch%d",
get_se_if_name(priv->if_defs->se_if_type),
priv->if_defs->se_instance_id, ch_id);
else
dev_ctx->devname = devm_kasprintf(priv->dev,
GFP_KERNEL, "%s_ch%d",
info->se_name, ch_id);
dev_ctx->devname = devm_kasprintf(priv->dev, GFP_KERNEL, "%s%d_ch%d",
get_se_if_name(priv->if_defs->se_if_type),
priv->if_defs->se_instance_id, ch_id);
if (!dev_ctx->devname) {
ret = -ENOMEM;
if (ch_id)
@ -559,12 +581,7 @@ static int init_device_context(struct se_if_priv *priv, int ch_id,
static int se_ioctl_cmd_snd_rcv_rsp_handler(struct se_if_device_ctx *dev_ctx,
u64 arg)
{
const struct se_if_node_info *info = container_of(dev_ctx->priv->if_defs,
typeof(*info),
if_defs);
struct se_ioctl_cmd_snd_rcv_rsp_info cmd_snd_rcv_rsp_info = {0};
struct se_if_node_info_list *info_list = container_of(info, typeof(*info_list),
info[info->se_if_id]);
struct se_if_priv *priv = dev_ctx->priv;
struct se_api_msg *tx_msg __free(kfree) = NULL;
struct se_api_msg *rx_msg __free(kfree) = NULL;
@ -608,7 +625,7 @@ static int se_ioctl_cmd_snd_rcv_rsp_handler(struct se_if_device_ctx *dev_ctx,
}
if (tx_msg->header.ver == priv->if_defs->fw_api_ver &&
!info_list->load_hsm_fw.is_fw_loaded) {
!get_load_fw_instance(priv)->is_fw_loaded) {
err = se_load_firmware(priv);
if (err) {
dev_err(priv->dev, "Could not send the message as FW is not loaded.");
@ -679,7 +696,7 @@ static int se_ioctl_get_mu_info(struct se_if_device_ctx *dev_ctx,
info = container_of(priv->if_defs, typeof(*info), if_defs);
if_info.se_if_id = info->se_if_id;
if_info.se_if_id = 0;
if_info.interrupt_idx = 0;
if_info.tz = 0;
if_info.did = info->se_if_did;
@ -711,7 +728,8 @@ exit:
* Copy a buffer of data to/from the user and return the address to use in
* messages
*/
static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx, u64 arg)
static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx,
u64 arg)
{
struct se_shared_mem *shared_mem = NULL;
struct se_ioctl_setup_iobuf io = {0};
@ -746,6 +764,12 @@ static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx, u64 ar
shared_mem = &dev_ctx->se_shared_mem_mgmt.non_secure_mem;
/* Check there is enough space in the shared memory. */
dev_dbg(dev_ctx->priv->dev,
"%s: req_size = %d, max_size= %d, curr_pos = %d",
dev_ctx->devname,
round_up(io.length, 8u),
shared_mem->size, shared_mem->pos);
if (shared_mem->size < shared_mem->pos ||
round_up(io.length, 8u) > (shared_mem->size - shared_mem->pos)) {
dev_err(dev_ctx->priv->dev,
@ -802,16 +826,12 @@ exit:
static int se_ioctl_get_se_soc_info_handler(struct se_if_device_ctx *dev_ctx,
u64 arg)
{
const struct se_if_node_info_list *info_list;
struct se_ioctl_get_soc_info soc_info;
int err = -EINVAL;
info_list = device_get_match_data(dev_ctx->priv->dev);
if (!info_list)
goto exit;
soc_info.soc_id = info_list->soc_id;
soc_info.soc_rev = se_soc_rev;
soc_info.soc_id = var_se_info.soc_id;
soc_info.soc_rev = var_se_info.soc_rev;
soc_info.board_type = var_se_info.board_type;
err = (int)copy_to_user((u8 __user *)arg, (u8 *)(&soc_info), sizeof(soc_info));
if (err) {
@ -1167,7 +1187,7 @@ static int se_if_probe(struct platform_device *pdev)
return ret;
}
info = get_se_if_node_info(info_list, idx);
info = &info_list->info[idx];
if (!info) {
ret = -EINVAL;
goto exit;
@ -1238,24 +1258,39 @@ static int se_if_probe(struct platform_device *pdev)
goto exit;
}
ret = se_soc_info(priv);
if (ret) {
dev_err(dev,
"failed[%pe] to fetch SoC Info\n", ERR_PTR(ret));
goto exit;
if (info->if_defs.se_if_type == SE_TYPE_ID_HSM) {
ret = se_soc_info(priv);
if (ret) {
dev_err(dev,
"failed[%pe] to fetch SoC Info\n", ERR_PTR(ret));
goto exit;
}
}
load_fw = get_load_fw_instance(priv);
/* By default, there is no pending FW to be loaded.*/
if (load_fw->is_fw_loaded) {
mutex_init(&load_fw->se_fw_load);
ret = se_load_firmware(priv);
if (ret)
dev_warn(dev, "Failed to load firmware.");
ret = 0;
if (info_list->se_fw_img_nm.prim_fw_nm_in_rfs ||
info_list->se_fw_img_nm.seco_fw_nm_in_rfs) {
load_fw = get_load_fw_instance(priv);
load_fw->se_fw_img_nm = &info_list->se_fw_img_nm;
load_fw->is_fw_loaded = false;
if (info_list->se_fw_img_nm.prim_fw_nm_in_rfs) {
/* allocate buffer where SE store encrypted IMEM */
load_fw->imem.buf = dmam_alloc_coherent(priv->dev, ELE_IMEM_SIZE,
&load_fw->imem.phyaddr,
GFP_KERNEL);
if (!load_fw->imem.buf) {
dev_err(priv->dev,
"dmam-alloc-failed: To store encr-IMEM.\n");
ret = -ENOMEM;
goto exit;
}
load_fw->imem_mgmt = true;
}
}
dev_info(dev, "i.MX secure-enclave: %s interface to firmware, configured.\n",
info->se_name);
dev_info(dev, "i.MX secure-enclave: %s%d interface to firmware, configured.\n",
get_se_if_name(priv->if_defs->se_if_type),
priv->if_defs->se_instance_id);
return ret;
exit:
@ -1280,13 +1315,9 @@ static int se_suspend(struct device *dev)
se_rcv_msg_timeout = SE_RCV_MSG_DEFAULT_TIMEOUT;
load_fw = get_load_fw_instance(priv);
if (load_fw->handle_susp_resm) {
if (load_fw->imem_mgmt)
ret = se_save_imem_state(priv, &load_fw->imem);
if (ret < 0)
goto exit;
load_fw->imem.size = ret;
}
exit:
return ret;
}
@ -1297,7 +1328,7 @@ static int se_resume(struct device *dev)
load_fw = get_load_fw_instance(priv);
if (load_fw->handle_susp_resm)
if (load_fw->imem_mgmt)
se_restore_imem_state(priv, &load_fw->imem);
return 0;
@ -1309,7 +1340,7 @@ static const struct dev_pm_ops se_pm = {
static struct platform_driver se_driver = {
.driver = {
.name = "fsl-se-fw",
.name = "fsl-se",
.of_match_table = se_match,
.pm = &se_pm,
},

View File

@ -98,7 +98,8 @@ struct se_api_msg {
};
struct se_if_defines {
const void *info;
const u8 se_if_type;
const u8 se_instance_id;
u8 cmd_tag;
u8 rsp_tag;
u8 success_tag;
@ -132,4 +133,5 @@ struct se_if_priv {
u32 dev_ctx_mono_count;
};
char *get_se_if_name(u8 se_if_id);
#endif

View File

@ -8,6 +8,23 @@
#include <linux/types.h>
#define SE_TYPE_STR_DBG "dbg"
#define SE_TYPE_STR_HSM "hsm"
#define SE_TYPE_STR_SHE "she"
#define SE_TYPE_STR_V2X_SV "v2x_sv"
#define SE_TYPE_STR_V2X_SG "v2x_sg"
#define SE_TYPE_STR_V2X_SHE "v2x_she"
#define SE_TYPE_STR_V2X_DBG "v2x_dbg"
#define SE_TYPE_ID_UNKWN 0x0
#define SE_TYPE_ID_DBG 0x1
#define SE_TYPE_ID_HSM 0x2
#define SE_TYPE_ID_SHE 0x3
#define SE_TYPE_ID_V2X_DBG 0x4
#define SE_TYPE_ID_V2X_SHE 0x5
#define SE_TYPE_ID_V2X_SV 0x6
#define SE_TYPE_ID_V2X_SG 0x7
/* IOCTL definitions. */
struct se_ioctl_setup_iobuf {