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