[linux-yocto] [PATCH 10/14] FogBugz #554835-1: Add Stratix 10 SoC RSU Driver

Meng.Li at windriver.com Meng.Li at windriver.com
Wed May 16 02:14:44 PDT 2018


From: David Koltak <david.koltak at linux.intel.com>

commit 000af215119d8a7ccb469d49535a59a5dbb12ad7 from
https://github.com/altera-opensource/linux-socfpga.git

Add a kernel driver to expose interfaces required to
support the Remote System Update (RSU) feature of Stratix
10 SoC FPGAs.  The driver uses SysFS device attribute nodes.
The accesses are performed through the intel-service layer.

Signed-off-by: David Koltak <david.koltak at linux.intel.com>
Signed-off-by: Meng Li <Meng.Li at windriver.com>
---
 drivers/misc/Kconfig                 |  17 ++
 drivers/misc/Makefile                |   1 +
 drivers/misc/intel-rsu.c             | 377 +++++++++++++++++++++++++++++++++++
 drivers/misc/intel-service.c         |  51 ++++-
 drivers/misc/intel-smc.h             |  41 ++++
 include/linux/intel-service-client.h |  15 +-
 6 files changed, 498 insertions(+), 4 deletions(-)
 create mode 100644 drivers/misc/intel-rsu.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 5a48b8a..02f3359 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -151,6 +151,23 @@ config INTEL_SERVICE
 
 	  Say Y here if you want Intel service layer support.
 
+config INTEL_RSU
+	tristate "Intel Remote System Update"
+	depends on INTEL_SERVICE
+	help
+	  The Intel Remote System Update (RSU) driver exposes interfaces
+	  accessed through the Intel Service Layer to user space via SysFS
+	  device attribute nodes. The RSU interfaces report/control some of
+	  the optional RSU features of the Stratix 10 SoC FPGA.
+
+	  The RSU feature provides a way for customers to update the boot
+	  configuration of a Stratix 10 SoC device with significantly reduced
+	  risk of corrupting the bitstream storage and bricking the system.
+
+	  Enable RSU support if you are using an Intel SoC FPGA with the RSU
+	  feature enabled and you want Linux user space control.
+
+	  Say Y here if you want Intel RSU support.
 
 config SGI_IOC4
 	tristate "SGI IOC4 Base IO support"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 0cbc82f..837d9f0 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_AD525X_DPOT_I2C)	+= ad525x_dpot-i2c.o
 obj-$(CONFIG_AD525X_DPOT_SPI)	+= ad525x_dpot-spi.o
 obj-$(CONFIG_INTEL_MID_PTI)	+= pti.o
 obj-$(CONFIG_INTEL_SERVICE)     += intel-service.o
+obj-$(CONFIG_INTEL_RSU)		+= intel-rsu.o
 obj-$(CONFIG_ATMEL_SSC)		+= atmel-ssc.o
 obj-$(CONFIG_ATMEL_TCLIB)	+= atmel_tclib.o
 obj-$(CONFIG_DUMMY_IRQ)		+= dummy-irq.o
diff --git a/drivers/misc/intel-rsu.c b/drivers/misc/intel-rsu.c
new file mode 100644
index 0000000..4dc834b
--- /dev/null
+++ b/drivers/misc/intel-rsu.c
@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Intel Corporation
+ */
+
+/*
+ * 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.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/completion.h>
+#include <linux/intel-service-client.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+
+#define MAX_U64_STR_LEN 22
+
+/*
+ * Private data structure
+ */
+struct intel_rsu_priv {
+	struct intel_svc_chan *chan;
+	struct intel_svc_client client;
+	struct completion svc_completion;
+	struct {
+		unsigned long current_image;
+		unsigned long fail_image;
+		unsigned int version;
+		unsigned int state;
+		unsigned int error_details;
+		unsigned int error_location;
+	} status;
+};
+
+/*
+ * status_svc_callback() - Callback from intel-service layer that returns SMC
+ *                         response with RSU status data. Parses up data and
+ *                         update driver private data structure.
+ * client - returned context from intel-service layer
+ * data - SMC response data
+ */
+static void status_svc_callback(struct intel_svc_client *client,
+				struct intel_svc_c_data *data)
+{
+	struct intel_rsu_priv *priv = client->priv;
+	struct arm_smccc_res *res = (struct arm_smccc_res *)data->kaddr1;
+
+	if (data->status == BIT(SVC_STATUS_RSU_OK)) {
+		priv->status.version =
+		    (unsigned int)(res->a2 >> 32) & 0xFFFFFFFF;
+		priv->status.state = (unsigned int)res->a2 & 0xFFFFFFFF;
+		priv->status.fail_image = res->a1;
+		priv->status.current_image = res->a0;
+		priv->status.error_location =
+		    (unsigned int)res->a3 & 0xFFFFFFFF;
+		priv->status.error_details =
+		    (unsigned int)(res->a3 >> 32) & 0xFFFFFFFF;
+	} else {
+		dev_err(client->dev, "COMMAND_RSU_STATUS returned 0x%lX\n",
+			res->a0);
+		priv->status.version = 0;
+		priv->status.state = 0;
+		priv->status.fail_image = 0;
+		priv->status.current_image = 0;
+		priv->status.error_location = 0;
+		priv->status.error_details = 0;
+	}
+
+	complete(&priv->svc_completion);
+}
+
+/*
+ * get_status() - Start an intel-service layer transaction to perform the SMC
+ *                that is necessary to get RSU status information. Wait for
+ *                completion and timeout if needed.
+ * priv - driver private data
+ *
+ * Returns 0 on success
+ */
+static int get_status(struct intel_rsu_priv *priv)
+{
+	struct intel_svc_client_msg msg;
+	int ret;
+	unsigned long timeout;
+
+	reinit_completion(&priv->svc_completion);
+	priv->client.receive_cb = status_svc_callback;
+
+	msg.command = COMMAND_RSU_STATUS;
+	ret = intel_svc_send(priv->chan, &msg);
+	if (ret < 0)
+		return ret;
+
+	timeout = msecs_to_jiffies(SVC_RSU_REQUEST_TIMEOUT_MS);
+	ret =
+	    wait_for_completion_interruptible_timeout(&priv->svc_completion,
+						      timeout);
+	if (!ret) {
+		dev_err(priv->client.dev,
+			"timeout waiting for COMMAND_RSU_STATUS\n");
+		return -ETIMEDOUT;
+	}
+	if (ret < 0) {
+		dev_err(priv->client.dev,
+			"error (%d) waiting for COMMAND_RSU_STATUS\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* current_image_show() - DEVICE_ATTR callback to show current_image status */
+static ssize_t current_image_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct intel_rsu_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv)
+		return -ENODEV;
+
+	return sprintf(buf, "%ld", priv->status.current_image);
+}
+
+/* fail_image_show() - DEVICE_ATTR callback to show fail_image status */
+static ssize_t fail_image_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct intel_rsu_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv)
+		return -ENODEV;
+
+	return sprintf(buf, "%ld", priv->status.fail_image);
+}
+
+/* version_show() - DEVICE_ATTR callback to show version status */
+static ssize_t version_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct intel_rsu_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv)
+		return -ENODEV;
+
+	return sprintf(buf, "%d", priv->status.version);
+}
+
+/* state_show() - DEVICE_ATTR callback to show state status */
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	struct intel_rsu_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv)
+		return -ENODEV;
+
+	return sprintf(buf, "%d", priv->status.state);
+}
+
+/* error_location_show() - DEVICE_ATTR callback to show error_location status */
+static ssize_t error_location_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct intel_rsu_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv)
+		return -ENODEV;
+
+	return sprintf(buf, "%d", priv->status.error_location);
+}
+
+/* error_details_show() - DEVICE_ATTR callback to show error_details status */
+static ssize_t error_details_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct intel_rsu_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv)
+		return -ENODEV;
+
+	return sprintf(buf, "%d", priv->status.error_details);
+}
+
+/*
+ * update_svc_callback() - Callback from intel-service layer that returns SMC
+ *                         response from RSU update. Checks for success/fail.
+ * client - returned context from intel-service layer
+ * data - SMC repsonse data
+ */
+static void update_svc_callback(struct intel_svc_client *client,
+				struct intel_svc_c_data *data)
+{
+	struct intel_rsu_priv *priv = client->priv;
+
+	if (data->status != BIT(SVC_STATUS_RSU_OK))
+		dev_err(client->dev, "COMMAND_RSU_UPDATE returned %i\n",
+			data->status);
+
+	complete(&priv->svc_completion);
+}
+
+/*
+ * send_update() - Start an intel-service layer transaction to perform the SMC
+ *                 that is necessary to send an RSU update request. Wait for
+ *                 completion and timeout if needed.
+ * priv - driver private data
+ *
+ * Returns 0 on success
+ */
+static int send_update(struct intel_rsu_priv *priv,
+		       unsigned long address)
+{
+	struct intel_svc_client_msg msg;
+	int ret;
+	unsigned long timeout;
+
+	reinit_completion(&priv->svc_completion);
+	priv->client.receive_cb = update_svc_callback;
+
+	msg.command = COMMAND_RSU_UPDATE;
+	msg.arg[0] = address;
+
+	ret = intel_svc_send(priv->chan, &msg);
+	if (ret < 0)
+		return ret;
+
+	timeout = msecs_to_jiffies(SVC_RSU_REQUEST_TIMEOUT_MS);
+	ret = wait_for_completion_interruptible_timeout(&priv->svc_completion,
+							timeout);
+	if (!ret) {
+		dev_err(priv->client.dev,
+			"timeout waiting for COMMAND_RSU_UPDATE\n");
+		return -ETIMEDOUT;
+	}
+	if (ret < 0) {
+		dev_err(priv->client.dev,
+			"error (%d) waiting for COMMAND_RSU_UPDATE\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* reboot_image_store() - DEVICE_ATTR callback to store reboot_image request */
+static ssize_t reboot_image_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct intel_rsu_priv *priv = dev_get_drvdata(dev);
+	unsigned long address;
+	int ret;
+
+	if (priv == 0)
+		return -ENODEV;
+
+	/* Ensure the input buffer is null terminated and not too long */
+	if (strnlen(buf, MAX_U64_STR_LEN) == MAX_U64_STR_LEN)
+		return -EINVAL;
+
+	ret = kstrtoul(buf, 10, &address);
+	if (ret)
+		return ret;
+
+	send_update(priv, address);
+
+	return count;
+}
+
+/*
+ * Attribute structures
+ */
+
+static DEVICE_ATTR_RO(current_image);
+static DEVICE_ATTR_RO(fail_image);
+static DEVICE_ATTR_RO(state);
+static DEVICE_ATTR_RO(version);
+static DEVICE_ATTR_RO(error_location);
+static DEVICE_ATTR_RO(error_details);
+static DEVICE_ATTR_WO(reboot_image);
+
+static struct attribute *attrs[] = {
+	&dev_attr_current_image.attr,
+	&dev_attr_fail_image.attr,
+	&dev_attr_state.attr,
+	&dev_attr_version.attr,
+	&dev_attr_error_location.attr,
+	&dev_attr_error_details.attr,
+	&dev_attr_reboot_image.attr,
+	NULL
+};
+
+static struct attribute_group attr_group = {
+	.attrs = attrs
+};
+
+static int intel_rsu_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct device *dev = &pdev->dev;
+	struct intel_rsu_priv *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->client.dev = dev;
+	priv->client.receive_cb = update_svc_callback;
+	priv->client.priv = priv;
+
+	priv->status.current_image = 0;
+	priv->status.fail_image = 0;
+	priv->status.error_location = 0;
+	priv->status.error_details = 0;
+	priv->status.version = 0;
+	priv->status.state = 0;
+
+	priv->chan = request_svc_channel_byname(&priv->client, SVC_CLIENT_RSU);
+	if (IS_ERR(priv->chan)) {
+		dev_err(dev, "couldn't get service channel (%s)\n",
+			SVC_CLIENT_RSU);
+		return PTR_ERR(priv->chan);
+	}
+
+	init_completion(&priv->svc_completion);
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = get_status(priv);
+	if (ret) {
+		dev_err(dev, "Error getting RSU status (%i)\n", ret);
+		free_svc_channel(priv->chan);
+		return ret;
+	}
+
+	ret = sysfs_create_group(&dev->kobj, &attr_group);
+	if (ret)
+		free_svc_channel(priv->chan);
+
+	return ret;
+}
+
+static int intel_rsu_remove(struct platform_device *pdev)
+{
+	struct intel_rsu_priv *priv = platform_get_drvdata(pdev);
+
+	free_svc_channel(priv->chan);
+
+	return 0;
+}
+
+static const struct of_device_id intel_rsu_of_match[] = {
+	{.compatible = "intel,stratix10-rsu",},
+	{},
+};
+MODULE_DEVICE_TABLE(of, intel_rsu_of_match);
+
+static struct platform_driver intel_rsu_driver = {
+	.probe = intel_rsu_probe,
+	.remove = intel_rsu_remove,
+	.driver = {
+		   .name = "intel-rsu",
+		   .of_match_table = intel_rsu_of_match,
+		   },
+};
+
+module_platform_driver(intel_rsu_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Remote System Update SysFS Driver");
+MODULE_AUTHOR("David Koltak <david.koltak at linux.intel.com>");
diff --git a/drivers/misc/intel-service.c b/drivers/misc/intel-service.c
index 8aa2a24..3019936 100644
--- a/drivers/misc/intel-service.c
+++ b/drivers/misc/intel-service.c
@@ -49,7 +49,7 @@
 /* SVC_NUM_DATA_IN_FIFO - number of struct intel_svc_data in the FIFO */
 #define SVC_NUM_DATA_IN_FIFO			32
 /* SVC_NUM_CHANNEL - number of channel supported by service layer driver */
-#define SVC_NUM_CHANNEL				2
+#define SVC_NUM_CHANNEL				3
 /*
  * FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS - claim back the submitted buffer(s)
  * from the secure world for FPGA manager to reuse, or to free the buffer(s)
@@ -115,7 +115,7 @@ struct intel_svc_data_mem {
  * @paddr: playload physical address
  * @size: playload size
  * @command: service command requested by client
- *
+ * @arg[3]: args to be passed via registers and not physically mapped buffers
  * This struct is used in service FIFO for inter-process communication.
  */
 struct intel_svc_data {
@@ -123,6 +123,7 @@ struct intel_svc_data {
 	phys_addr_t paddr;
 	size_t size;
 	u32 command;
+	u64 arg[3];
 };
 
 /**
@@ -270,6 +271,9 @@ int intel_svc_send(struct intel_svc_chan *chan, void *msg)
 	}
 
 	p_data->command = p_msg->command;
+	p_data->arg[0] = p_msg->arg[0];
+	p_data->arg[1] = p_msg->arg[1];
+	p_data->arg[2] = p_msg->arg[2];
 	p_data->size = p_msg->payload_length;
 	p_data->chan = chan;
 	pr_debug("%s: put to FIFO pa=0x%016x, cmd=%x, size=%u\n", __func__,
@@ -566,6 +570,16 @@ static int svc_normal_to_secure_thread(void *data)
 			a1 = 0;
 			a2 = 0;
 			break;
+		case COMMAND_RSU_STATUS:
+			a0 = INTEL_SIP_SMC_RSU_STATUS;
+			a1 = 0;
+			a2 = 0;
+			break;
+		case COMMAND_RSU_UPDATE:
+			a0 = INTEL_SIP_SMC_RSU_UPDATE;
+			a1 = pdata->arg[0];
+			a2 = 0;
+			break;
 		default:
 			/* it shouldn't happen */
 			break;
@@ -582,6 +596,32 @@ static int svc_normal_to_secure_thread(void *data)
 			 (unsigned int)res.a1, (unsigned int)res.a2);
 		pr_debug(" res.a3=0x%016x\n", (unsigned int)res.a3);
 
+		if (pdata->command == COMMAND_RSU_STATUS) {
+			if (res.a0 == INTEL_SIP_SMC_RSU_ERROR)
+				cdata->status = 0;
+			else
+				cdata->status = BIT(SVC_STATUS_RSU_OK);
+
+			cdata->kaddr1 = &res;
+			cdata->kaddr2 = NULL;
+			cdata->kaddr3 = NULL;
+			pdata->chan->scl->receive_cb(pdata->chan->scl, cdata);
+			continue;
+		}
+
+		if (pdata->command == COMMAND_RSU_UPDATE) {
+			if (res.a0 == INTEL_SIP_SMC_STATUS_OK)
+				cdata->status = BIT(SVC_STATUS_RSU_OK);
+			else
+				cdata->status = 0;
+
+			cdata->kaddr1 = NULL;
+			cdata->kaddr2 = NULL;
+			cdata->kaddr3 = NULL;
+			pdata->chan->scl->receive_cb(pdata->chan->scl, cdata);
+			continue;
+		}
+
 		switch (res.a0) {
 		case INTEL_SIP_SMC_STATUS_OK:
 			svc_thread_recv_status_ok(pdata, cdata, res);
@@ -885,9 +925,14 @@ static int intel_svc_drv_probe(struct platform_device *pdev)
 
 	chans[1].scl = NULL;
 	chans[1].ctrl = controller;
-	chans[1].name = "dummy";
+	chans[1].name = "rsu";
 	spin_lock_init(&chans[1].lock);
 
+	chans[2].scl = NULL;
+	chans[2].ctrl = controller;
+	chans[2].name = "dummy";
+	spin_lock_init(&chans[2].lock);
+
 	wake_up_process(controller->task);
 
 	list_add_tail(&controller->node, &svc_ctrl);
diff --git a/drivers/misc/intel-smc.h b/drivers/misc/intel-smc.h
index d92dcd7..1612e5d 100644
--- a/drivers/misc/intel-smc.h
+++ b/drivers/misc/intel-smc.h
@@ -77,6 +77,7 @@
 #define INTEL_SIP_SMC_FPGA_CONFIG_STATUS_REJECTED       0x2
 #define INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR		0x4
 #define INTEL_SIP_SMC_REG_ERROR				0x5
+#define INTEL_SIP_SMC_RSU_ERROR				0x7
 
 /*
  * Request INTEL_SIP_SMC_FPGA_CONFIG_START
@@ -266,4 +267,44 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
 #define INTEL_SIP_SMC_REG_UPDATE \
 	INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_UPDATE)
 
+/*
+ * Request INTEL_SIP_SMC_RSU_STATUS
+ *
+ * Sync call used by service driver at EL1 to query the RSU status
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_STATUS
+ * a1-7 not used
+ *
+ * Return status
+ * a0: Current Image
+ * a1: Last Failing Image
+ * a2: Version | State
+ * a3: Error details | Error location
+ *
+ * Or
+ *
+ * a0: INTEL_SIP_SMC_RSU_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_STATUS 11
+#define INTEL_SIP_SMC_RSU_STATUS \
+	INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_STATUS)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_UPDATE
+ *
+ * Sync call used by service driver at EL1 to tell you next reboot is RSU_UPDATE
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_UPDATE
+ * a1 64bit physical address of the configuration data memory in flash
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_UPDATE 12
+#define INTEL_SIP_SMC_RSU_UPDATE \
+	INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_UPDATE)
+
 #endif
diff --git a/include/linux/intel-service-client.h b/include/linux/intel-service-client.h
index 8cef141..4a1c3e9 100644
--- a/include/linux/intel-service-client.h
+++ b/include/linux/intel-service-client.h
@@ -13,6 +13,7 @@
  */
 #define SVC_CLIENT_FPGA		"fpga"
 #define SVC_CLIENT_DUMMY	"dummy"
+#define SVC_CLIENT_RSU		"rsu"
 
 /*
  * Status of the sent command, in bit number
@@ -38,6 +39,7 @@
 #define SVC_STATUS_RECONFIG_COMPLETED		3
 #define SVC_STATUS_RECONFIG_BUSY		4
 #define SVC_STATUS_RECONFIG_ERROR		5
+#define SVC_STATUS_RSU_OK			6
 
 /*
  * Flag bit for COMMAND_RECONFIG
@@ -51,6 +53,9 @@
 #define SVC_RECONFIG_REQUEST_TIMEOUT_MS         100
 #define SVC_RECONFIG_BUFFER_TIMEOUT_MS          240
 
+/* Timeout settings for RSU driver */
+#define SVC_RSU_REQUEST_TIMEOUT_MS              300
+
 struct intel_svc_chan;
 
 /**
@@ -67,13 +72,19 @@ struct intel_svc_chan;
  * @COMMAND_RECONFIG_STATUS: check the status of the configuration, return
  * status is SVC_STATUS_RECONFIG_COMPLETED, or  SVC_STATUS_RECONFIG_BUSY, or
  * SVC_STATUS_RECONFIG_ERROR
+ * @COMMAND_RSU_STATUS: request remote system update boot log
+ * status is SVC_STATUS_RSU_ERROR or log data
+ * @COMMAND_RSU_UPDATE: set the offset of the bitstream to boot after reboot
+ * status is SVC_STATUS_RSU_OK or SVC_STATUS_RSU_ERROR
  */
 enum intel_svc_command_code {
 	COMMAND_NOOP = 0,
 	COMMAND_RECONFIG,
 	COMMAND_RECONFIG_DATA_SUBMIT,
 	COMMAND_RECONFIG_DATA_CLAIM,
-	COMMAND_RECONFIG_STATUS
+	COMMAND_RECONFIG_STATUS,
+	COMMAND_RSU_STATUS,
+	COMMAND_RSU_UPDATE
 };
 
 /**
@@ -81,11 +92,13 @@ enum intel_svc_command_code {
  * @command: service command
  * @payload: starting address of data need be processed
  * @payload_length: data size in bytes
+ * @arg: args to be passed via registers and not physically mapped buffers
  */
 struct intel_svc_client_msg {
 	void *payload;
 	size_t payload_length;
 	enum intel_svc_command_code command;
+	u64 arg[3];
 };
 
 /**
-- 
2.7.4



More information about the linux-yocto mailing list