typedefvoid (*rsu_callback)(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data); /** * struct stratix10_rsu_priv - rsu data structure * @chan: pointer to the allocated service channel * @client: active service client * @completion: state for callback completion * @lock: a mutex to protect callback completion state * @status.current_image: address of image currently running in flash * @status.fail_image: address of failed image in flash * @status.version: the interface version number of RSU firmware * @status.state: the state of RSU system * @status.error_details: error code * @status.error_location: the error offset inside the image that failed * @dcmf_version.dcmf0: Quartus dcmf0 version * @dcmf_version.dcmf1: Quartus dcmf1 version * @dcmf_version.dcmf2: Quartus dcmf2 version * @dcmf_version.dcmf3: Quartus dcmf3 version * @dcmf_status.dcmf0: dcmf0 status * @dcmf_status.dcmf1: dcmf1 status * @dcmf_status.dcmf2: dcmf2 status * @dcmf_status.dcmf3: dcmf3 status * @retry_counter: the current image's retry counter * @max_retry: the preset max retry value * @spt0_address: address of spt0 * @spt1_address: address of spt1 * @get_spt_response_buf: response from sdm for get_spt command
*/ struct stratix10_rsu_priv { struct stratix10_svc_chan *chan; struct stratix10_svc_client client; struct completion completion; struct mutex lock; struct { unsignedlong current_image; unsignedlong fail_image; unsignedint version; unsignedint state; unsignedint error_details; unsignedint error_location;
} status;
/** * rsu_status_callback() - Status callback from Intel Service Layer * @client: pointer to service client * @data: pointer to callback data structure * * Callback from Intel service layer for RSU status request. Status is * only updated after a system reboot, so a get updated status call is * made during driver probe.
*/ staticvoid rsu_status_callback(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data)
{ struct stratix10_rsu_priv *priv = client->priv; struct arm_smccc_res *res = (struct arm_smccc_res *)data->kaddr1;
/** * rsu_command_callback() - Update callback from Intel Service Layer * @client: pointer to client * @data: pointer to callback data structure * * Callback from Intel service layer for RSU commands.
*/ staticvoid rsu_command_callback(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data)
{ struct stratix10_rsu_priv *priv = client->priv;
if (data->status == BIT(SVC_STATUS_NO_SUPPORT))
dev_warn(client->dev, "Secure FW doesn't support notify\n"); elseif (data->status == BIT(SVC_STATUS_ERROR))
dev_err(client->dev, "Failure, returned status is %lu\n",
BIT(data->status));
complete(&priv->completion);
}
/** * rsu_retry_callback() - Callback from Intel service layer for getting * the current image's retry counter from the firmware * @client: pointer to client * @data: pointer to callback data structure * * Callback from Intel service layer for retry counter, which is used by * user to know how many times the images is still allowed to reload * itself before giving up and starting RSU fail-over flow.
*/ staticvoid rsu_retry_callback(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data)
{ struct stratix10_rsu_priv *priv = client->priv; unsignedint *counter = (unsignedint *)data->kaddr1;
if (data->status == BIT(SVC_STATUS_OK))
priv->retry_counter = *counter; elseif (data->status == BIT(SVC_STATUS_NO_SUPPORT))
dev_warn(client->dev, "Secure FW doesn't support retry\n"); else
dev_err(client->dev, "Failed to get retry counter %lu\n",
BIT(data->status));
complete(&priv->completion);
}
/** * rsu_max_retry_callback() - Callback from Intel service layer for getting * the max retry value from the firmware * @client: pointer to client * @data: pointer to callback data structure * * Callback from Intel service layer for max retry.
*/ staticvoid rsu_max_retry_callback(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data)
{ struct stratix10_rsu_priv *priv = client->priv; unsignedint *max_retry = (unsignedint *)data->kaddr1;
if (data->status == BIT(SVC_STATUS_OK))
priv->max_retry = *max_retry; elseif (data->status == BIT(SVC_STATUS_NO_SUPPORT))
dev_warn(client->dev, "Secure FW doesn't support max retry\n"); else
dev_err(client->dev, "Failed to get max retry %lu\n",
BIT(data->status));
complete(&priv->completion);
}
/** * rsu_dcmf_version_callback() - Callback from Intel service layer for getting * the DCMF version * @client: pointer to client * @data: pointer to callback data structure * * Callback from Intel service layer for DCMF version number
*/ staticvoid rsu_dcmf_version_callback(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data)
{ struct stratix10_rsu_priv *priv = client->priv; unsignedlonglong *value1 = (unsignedlonglong *)data->kaddr1; unsignedlonglong *value2 = (unsignedlonglong *)data->kaddr2;
if (data->status == BIT(SVC_STATUS_OK)) {
priv->dcmf_version.dcmf0 = FIELD_GET(RSU_DCMF0_MASK, *value1);
priv->dcmf_version.dcmf1 = FIELD_GET(RSU_DCMF1_MASK, *value1);
priv->dcmf_version.dcmf2 = FIELD_GET(RSU_DCMF2_MASK, *value2);
priv->dcmf_version.dcmf3 = FIELD_GET(RSU_DCMF3_MASK, *value2);
} else
dev_err(client->dev, "failed to get DCMF version\n");
complete(&priv->completion);
}
/** * rsu_dcmf_status_callback() - Callback from Intel service layer for getting * the DCMF status * @client: pointer to client * @data: pointer to callback data structure * * Callback from Intel service layer for DCMF status
*/ staticvoid rsu_dcmf_status_callback(struct stratix10_svc_client *client, struct stratix10_svc_cb_data *data)
{ struct stratix10_rsu_priv *priv = client->priv; unsignedlonglong *value = (unsignedlonglong *)data->kaddr1;
if (data->status == BIT(SVC_STATUS_OK)) {
priv->dcmf_status.dcmf0 = FIELD_GET(RSU_DCMF0_STATUS_MASK,
*value);
priv->dcmf_status.dcmf1 = FIELD_GET(RSU_DCMF1_STATUS_MASK,
*value);
priv->dcmf_status.dcmf2 = FIELD_GET(RSU_DCMF2_STATUS_MASK,
*value);
priv->dcmf_status.dcmf3 = FIELD_GET(RSU_DCMF3_STATUS_MASK,
*value);
} else
dev_err(client->dev, "failed to get DCMF status\n");
/** * rsu_send_msg() - send a message to Intel service layer * @priv: pointer to rsu private data * @command: RSU status or update command * @arg: the request argument, the bitstream address or notify status * @callback: function pointer for the callback (status or update) * * Start an Intel service layer transaction to perform the SMC call that * is necessary to get RSU boot log or set the address of bitstream to * boot after reboot. * * Returns 0 on success or -ETIMEDOUT on error.
*/ staticint rsu_send_msg(struct stratix10_rsu_priv *priv, enum stratix10_svc_command_code command, unsignedlong arg,
rsu_callback callback)
{ struct stratix10_svc_client_msg msg; int ret;
/* * This driver exposes some optional features of the Intel Stratix 10 SoC FPGA. * The sysfs interfaces exposed here are FPGA Remote System Update (RSU) * related. They allow user space software to query the configuration system * status and to request optional reboot behavior specific to Intel FPGAs.
*/
ret = kstrtoul(buf, 0, &status); if (ret) return ret;
ret = rsu_send_msg(priv, COMMAND_RSU_NOTIFY,
status, rsu_command_callback); if (ret) {
dev_err(dev, "Error, RSU notify returned %i\n", ret); return ret;
}
/* to get the updated state */
ret = rsu_send_msg(priv, COMMAND_RSU_STATUS,
0, rsu_status_callback); if (ret) {
dev_err(dev, "Error, getting RSU status %i\n", ret); return ret;
}
ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback); if (ret) {
dev_err(dev, "Error, getting RSU retry %i\n", ret); return ret;
}
/* get the initial state from firmware */
ret = rsu_send_msg(priv, COMMAND_RSU_STATUS,
0, rsu_status_callback); if (ret) {
dev_err(dev, "Error, getting RSU status %i\n", ret);
stratix10_svc_free_channel(priv->chan);
}
/* get DCMF version from firmware */
ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_VERSION,
0, rsu_dcmf_version_callback); if (ret) {
dev_err(dev, "Error, getting DCMF version %i\n", ret);
stratix10_svc_free_channel(priv->chan);
}
ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_STATUS,
0, rsu_dcmf_status_callback); if (ret) {
dev_err(dev, "Error, getting DCMF status %i\n", ret);
stratix10_svc_free_channel(priv->chan);
}
ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback); if (ret) {
dev_err(dev, "Error, getting RSU retry %i\n", ret);
stratix10_svc_free_channel(priv->chan);
}
ret = rsu_send_msg(priv, COMMAND_RSU_MAX_RETRY, 0,
rsu_max_retry_callback); if (ret) {
dev_err(dev, "Error, getting RSU max retry %i\n", ret);
stratix10_svc_free_channel(priv->chan);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.