From: Ang Tien Sung <[email protected]>
Extending the fpga svc driver to support 6 new FPGA Crypto
Service(FCS) commands.
We are adding FCS SDOS data encryption and decryption,
random number generator, image validation request,
reading the data provision and certificate validation.
Signed-off-by: Ang Tien Sung <[email protected]>
---
changelog v2:
* Have corrected the missing /** due to accidental removal as
* reported by Reported-by: kernel test robot <[email protected]>.
* Re-run and compilation is passing.
drivers/firmware/stratix10-svc.c | 92 +++++++++++++-
include/linux/firmware/intel/stratix10-smc.h | 115 +++++++++++++++++-
.../firmware/intel/stratix10-svc-client.h | 41 ++++++-
3 files changed, 239 insertions(+), 9 deletions(-)
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index f6871aa66cbd..9fd41e00035a 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -99,8 +99,10 @@ struct stratix10_svc_data_mem {
/**
* struct stratix10_svc_data - service data structure
* @chan: service channel
- * @paddr: playload physical address
- * @size: playload size
+ * @paddr: physical address of to be processed payload
+ * @size: to be processed playload size
+ * @paddr_output: physical address of processed payload
+ * @size_output: processed payload size
* @command: service command requested by client
* @flag: configuration type (full or partial)
* @arg: args to be passed via registers and not physically mapped buffers
@@ -111,6 +113,8 @@ struct stratix10_svc_data {
struct stratix10_svc_chan *chan;
phys_addr_t paddr;
size_t size;
+ phys_addr_t paddr_output;
+ size_t size_output;
u32 command;
u32 flag;
u64 arg[3];
@@ -317,6 +321,8 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data,
case COMMAND_RECONFIG:
case COMMAND_RSU_UPDATE:
case COMMAND_RSU_NOTIFY:
+ case COMMAND_FCS_REQUEST_SERVICE:
+ case COMMAND_FCS_SEND_CERTIFICATE:
case COMMAND_POLL_SERVICE_STATUS:
cb_data->status = BIT(SVC_STATUS_OK);
break;
@@ -336,6 +342,15 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data,
cb_data->kaddr1 = &res.a1;
cb_data->kaddr2 = &res.a2;
break;
+ case COMMAND_FCS_RANDOM_NUMBER_GEN:
+ case COMMAND_FCS_DATA_ENCRYPTION:
+ case COMMAND_FCS_DATA_DECRYPTION:
+ case COMMAND_FCS_GET_PROVISION_DATA:
+ cb_data->status = BIT(SVC_STATUS_OK);
+ cb_data->kaddr1 = &res.a1;
+ cb_data->kaddr2 = svc_pa_to_va(res.a2);
+ cb_data->kaddr3 = &res.a3;
+ break;
default:
pr_warn("it shouldn't happen\n");
break;
@@ -362,7 +377,7 @@ static int svc_normal_to_secure_thread(void *data)
struct stratix10_svc_data *pdata;
struct stratix10_svc_cb_data *cbdata;
struct arm_smccc_res res;
- unsigned long a0, a1, a2;
+ unsigned long a0, a1, a2, a3, a4, a5;
int ret_fifo = 0;
pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
@@ -379,6 +394,9 @@ static int svc_normal_to_secure_thread(void *data)
a0 = INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK;
a1 = 0;
a2 = 0;
+ a3 = 0;
+ a4 = 0;
+ a5 = 0;
pr_debug("smc_hvc_shm_thread is running\n");
@@ -444,6 +462,45 @@ static int svc_normal_to_secure_thread(void *data)
a1 = 0;
a2 = 0;
break;
+
+ /* for FCS */
+ case COMMAND_FCS_DATA_ENCRYPTION:
+ a0 = INTEL_SIP_SMC_FCS_CRYPTION;
+ a1 = 1;
+ a2 = (unsigned long)pdata->paddr;
+ a3 = (unsigned long)pdata->size;
+ a4 = (unsigned long)pdata->paddr_output;
+ a5 = (unsigned long)pdata->size_output;
+ break;
+ case COMMAND_FCS_DATA_DECRYPTION:
+ a0 = INTEL_SIP_SMC_FCS_CRYPTION;
+ a1 = 0;
+ a2 = (unsigned long)pdata->paddr;
+ a3 = (unsigned long)pdata->size;
+ a4 = (unsigned long)pdata->paddr_output;
+ a5 = (unsigned long)pdata->size_output;
+ break;
+ case COMMAND_FCS_RANDOM_NUMBER_GEN:
+ a0 = INTEL_SIP_SMC_FCS_RANDOM_NUMBER;
+ a1 = (unsigned long)pdata->paddr;
+ a2 = (unsigned long)pdata->size;
+ break;
+ case COMMAND_FCS_REQUEST_SERVICE:
+ a0 = INTEL_SIP_SMC_FCS_SERVICE_REQUEST;
+ a1 = (unsigned long)pdata->paddr;
+ a2 = (unsigned long)pdata->size;
+ break;
+ case COMMAND_FCS_SEND_CERTIFICATE:
+ a0 = INTEL_SIP_SMC_FCS_SEND_CERTIFICATE;
+ a1 = (unsigned long)pdata->paddr;
+ a2 = (unsigned long)pdata->size;
+ break;
+ case COMMAND_FCS_GET_PROVISION_DATA:
+ a0 = INTEL_SIP_SMC_FCS_GET_PROVISION_DATA;
+ a1 = (unsigned long)pdata->paddr;
+ a2 = (unsigned long)pdata->size;
+ break;
+
/* for polling */
case COMMAND_POLL_SERVICE_STATUS:
a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
@@ -502,6 +559,22 @@ static int svc_normal_to_secure_thread(void *data)
break;
case INTEL_SIP_SMC_STATUS_REJECTED:
pr_debug("%s: STATUS_REJECTED\n", __func__);
+ /* for FCS */
+ switch (pdata->command) {
+ case COMMAND_FCS_REQUEST_SERVICE:
+ case COMMAND_FCS_SEND_CERTIFICATE:
+ case COMMAND_FCS_GET_PROVISION_DATA:
+ case COMMAND_FCS_DATA_ENCRYPTION:
+ case COMMAND_FCS_DATA_DECRYPTION:
+ case COMMAND_FCS_RANDOM_NUMBER_GEN:
+ cbdata->status = BIT(SVC_STATUS_INVALID_PARAM);
+ cbdata->kaddr1 = NULL;
+ cbdata->kaddr2 = NULL;
+ cbdata->kaddr3 = NULL;
+ pdata->chan->scl->receive_cb(pdata->chan->scl,
+ cbdata);
+ break;
+ }
break;
case INTEL_SIP_SMC_STATUS_ERROR:
case INTEL_SIP_SMC_RSU_ERROR:
@@ -875,15 +948,25 @@ int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg)
list_for_each_entry(p_mem, &svc_data_mem, node)
if (p_mem->vaddr == p_msg->payload) {
p_data->paddr = p_mem->paddr;
+ p_data->size = p_msg->payload_length;
break;
}
+ if (p_msg->payload_output) {
+ list_for_each_entry(p_mem, &svc_data_mem, node)
+ if (p_mem->vaddr == p_msg->payload_output) {
+ p_data->paddr_output =
+ p_mem->paddr;
+ p_data->size_output =
+ p_msg->payload_length_output;
+ break;
+ }
+ }
}
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__,
(unsigned int)p_data->paddr, p_data->command,
@@ -979,6 +1062,7 @@ void stratix10_svc_free_memory(struct stratix10_svc_chan *chan, void *kaddr)
break;
}
+ memset(kaddr, 0, size);
gen_pool_free(chan->ctrl->genpool, (unsigned long)kaddr, size);
pmem->vaddr = NULL;
list_del(&pmem->node);
diff --git a/include/linux/firmware/intel/stratix10-smc.h b/include/linux/firmware/intel/stratix10-smc.h
index 579efb14cfb4..eddaabbee1e3 100644
--- a/include/linux/firmware/intel/stratix10-smc.h
+++ b/include/linux/firmware/intel/stratix10-smc.h
@@ -403,7 +403,7 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
#define INTEL_SIP_SMC_RSU_MAX_RETRY \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY)
-/**
+ /**
* Request INTEL_SIP_SMC_SERVICE_COMPLETED
* Sync call to check if the secure world have completed service request
* or not.
@@ -424,4 +424,117 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
#define INTEL_SIP_SMC_SERVICE_COMPLETED \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_SERVICE_COMPLETED)
+/**
+ * SMC call protocol for FPGA Crypto Service (FCS)
+ * FUNCID starts from 90
+ */
+
+/**
+ * Request INTEL_SIP_SMC_FCS_RANDOM_NUMBER
+ *
+ * Sync call used to query the random number generated by the firmware
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_FCS_RANDOM_NUMBER
+ * a1 the physical address for firmware to write generated random data
+ * a2-a7 not used
+ *
+ * Return status:
+ * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FCS_ERROR or
+ * INTEL_SIP_SMC_FCS_REJECTED
+ * a1 the physical address of generated random number
+ * a2 the size
+ * a3 not used
+ */
+#define INTEL_SIP_SMC_FUNCID_FCS_RANDOM_NUMBER 90
+#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_RANDOM_NUMBER)
+
+/**
+ * Request INTEL_SIP_SMC_FCS_CRYPTION
+ * Async call for data encryption and HMAC signature generation, or for
+ * data decryption and HMAC verification.
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_FCS_CRYPTION
+ * a1 cryption mode (1 for encryption and 0 for decryption)
+ * a2 physical address which stores to be encrypted or decrypted data
+ * a3 input data size
+ * a4 physical address which will hold the encrypted or decrypted output data
+ * a5 output data size
+ * a6-a7 not used
+ *
+ * Return status:
+ * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_ERROR or
+ * INTEL_SIP_SMC_STATUS_REJECTED
+ * a1 mbox return code
+ * a2 physical address of output data which stores encrypted or decrypted data
+ * a3 output data size
+ */
+#define INTEL_SIP_SMC_FUNCID_FCS_CRYPTION 91
+#define INTEL_SIP_SMC_FCS_CRYPTION \
+ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_CRYPTION)
+
+/**
+ * Request INTEL_SIP_SMC_FCS_SERVICE_REQUEST
+ * Async call for authentication service of HPS software
+ *
+ * Sync call used by service driver at EL1 to query DCMF (Decision
+ * Configuration Management Firmware) version from FW
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_FCS_SERVICE_REQUEST
+ * a1 the physical address of data block
+ * a2 size of data block
+ * a3-a7 not used
+ *
+ * Return status:
+ * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_ERROR or
+ * INTEL_SIP_SMC_REJECTED
+ * a1-a3 not used
+ */
+#define INTEL_SIP_SMC_FUNCID_FCS_SERVICE_REQUEST 92
+#define INTEL_SIP_SMC_FCS_SERVICE_REQUEST \
+ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_SERVICE_REQUEST)
+
+/**
+ * Request INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE
+ * Sync call to send a signed certificate
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_FCS_SEND_CERTIFICATE
+ * a1 the physical address of CERTIFICATE block
+ * a2 size of data block
+ * a3-a7 not used
+ *
+ * Return status:
+ * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FCS_ERROR or
+ * INTEL_SIP_SMC_FCS_REJECTED
+ * a1-a3 not used
+ */
+#define INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE 93
+#define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE \
+ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE)
+
+/**
+ * Request INTEL_SIP_SMC_FCS_GET_PROVISION_DATA
+ * Sync call to dump all the fuses and key hashes
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_FCS_GET_PROVISION_DATA
+ * a1 the physical address for firmware to write structure of fuse and
+ * key hashes
+ * a2-a7 not used
+ *
+ * Return status:
+ * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FCS_ERROR or
+ * INTEL_SIP_SMC_FCS_REJECTED
+ * a1 physical address for the structure of fuse and key hashes
+ * a2 the size of structure
+ * a3 not used
+ *
+ */
+#define INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA 94
+#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA)
+
#endif
diff --git a/include/linux/firmware/intel/stratix10-svc-client.h b/include/linux/firmware/intel/stratix10-svc-client.h
index 82e8c9336cf4..1010f14d927b 100644
--- a/include/linux/firmware/intel/stratix10-svc-client.h
+++ b/include/linux/firmware/intel/stratix10-svc-client.h
@@ -49,8 +49,8 @@
#define SVC_STATUS_BUSY 4
#define SVC_STATUS_ERROR 5
#define SVC_STATUS_NO_SUPPORT 6
-
-/*
+#define SVC_STATUS_INVALID_PARAM 7
+/**
* Flag bit for COMMAND_RECONFIG
*
* COMMAND_RECONFIG_FLAG_PARTIAL:
@@ -66,6 +66,8 @@
#define SVC_RECONFIG_REQUEST_TIMEOUT_MS 300
#define SVC_RECONFIG_BUFFER_TIMEOUT_MS 720
#define SVC_RSU_REQUEST_TIMEOUT_MS 300
+#define SVC_FCS_REQUEST_TIMEOUT_MS 2000
+#define SVC_COMPLETED_TIMEOUT_MS 30000
struct stratix10_svc_chan;
@@ -105,21 +107,48 @@ struct stratix10_svc_chan;
* @COMMAND_RSU_DCMF_VERSION: query firmware for the DCMF version, return status
* is SVC_STATUS_OK or SVC_STATUS_ERROR
*
+ * @COMMAND_FCS_REQUEST_SERVICE: request validation of image from firmware,
+ * return status is SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM
+ *
+ * @COMMAND_FCS_SEND_CERTIFICATE: send a certificate, return status is
+ * SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
+ *
+ * @COMMAND_FCS_GET_PROVISION_DATA: read the provisioning data, return status is
+ * SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
+ *
+ * @COMMAND_FCS_DATA_ENCRYPTION: encrypt the data, return status is
+ * SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
+ *
+ * @COMMAND_FCS_DATA_DECRYPTION: decrypt the data, return status is
+ * SVC_STATUS_OK, SVC_STATUS_INVALID_PARAM, SVC_STATUS_ERROR
+ *
+ * @COMMAND_FCS_RANDOM_NUMBER_GEN: generate a random number, return status
+ * is SVC_STATUS_OK, SVC_STATUS_ERROR
+ *
* @COMMAND_POLL_SERVICE_STATUS: poll if the service request is complete,
* return statis is SVC_STATUS_OK, SVC_STATUS_ERROR or SVC_STATUS_BUSY
*/
enum stratix10_svc_command_code {
+ /* for FPGA */
COMMAND_NOOP = 0,
COMMAND_RECONFIG,
COMMAND_RECONFIG_DATA_SUBMIT,
COMMAND_RECONFIG_DATA_CLAIM,
COMMAND_RECONFIG_STATUS,
- COMMAND_RSU_STATUS,
+ /* for RSU */
+ COMMAND_RSU_STATUS = 10,
COMMAND_RSU_UPDATE,
COMMAND_RSU_NOTIFY,
COMMAND_RSU_RETRY,
COMMAND_RSU_MAX_RETRY,
COMMAND_RSU_DCMF_VERSION,
+ /* for FCS */
+ COMMAND_FCS_REQUEST_SERVICE = 20,
+ COMMAND_FCS_SEND_CERTIFICATE,
+ COMMAND_FCS_GET_PROVISION_DATA,
+ COMMAND_FCS_DATA_ENCRYPTION,
+ COMMAND_FCS_DATA_DECRYPTION,
+ COMMAND_FCS_RANDOM_NUMBER_GEN,
/* for general status poll */
COMMAND_POLL_SERVICE_STATUS = 40,
};
@@ -127,13 +156,17 @@ enum stratix10_svc_command_code {
/**
* struct stratix10_svc_client_msg - message sent by client to service
* @payload: starting address of data need be processed
- * @payload_length: data size in bytes
+ * @payload_length: to be processed data size in bytes
+ * @payload_output: starting address of processed data
+ * @payload_length_output: processed data size in bytes
* @command: service command
* @arg: args to be passed via registers and not physically mapped buffers
*/
struct stratix10_svc_client_msg {
void *payload;
size_t payload_length;
+ void *payload_output;
+ size_t payload_length_output;
enum stratix10_svc_command_code command;
u64 arg[3];
};
--
2.25.1
Hi,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linux/master]
[also build test WARNING on linus/master v5.17-rc8]
[cannot apply to next-20220310]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/tien-sung-ang-intel-com/firmware-stratix10-svc-Add-new-FCS-support/20220314-141232
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 2c271fe77d52a0555161926c232cd5bc07178b39
config: arm64-randconfig-r036-20220313 (https://download.01.org/0day-ci/archive/20220314/[email protected]/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 3e4950d7fa78ac83f33bbf1658e2f49a73719236)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm64 cross compiling tool for clang build
# apt-get install binutils-aarch64-linux-gnu
# https://github.com/0day-ci/linux/commit/e0831198268601b99d0bdf092fbe2eb8be3b6686
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review tien-sung-ang-intel-com/firmware-stratix10-svc-Add-new-FCS-support/20220314-141232
git checkout e0831198268601b99d0bdf092fbe2eb8be3b6686
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/firmware/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
>> drivers/firmware/stratix10-svc.c:380:32: warning: variable 'a4' set but not used [-Wunused-but-set-variable]
unsigned long a0, a1, a2, a3, a4, a5;
^
>> drivers/firmware/stratix10-svc.c:380:28: warning: variable 'a3' set but not used [-Wunused-but-set-variable]
unsigned long a0, a1, a2, a3, a4, a5;
^
>> drivers/firmware/stratix10-svc.c:380:36: warning: variable 'a5' set but not used [-Wunused-but-set-variable]
unsigned long a0, a1, a2, a3, a4, a5;
^
3 warnings generated.
vim +/a4 +380 drivers/firmware/stratix10-svc.c
362
363 /**
364 * svc_normal_to_secure_thread() - the function to run in the kthread
365 * @data: data pointer for kthread function
366 *
367 * Service layer driver creates stratix10_svc_smc_hvc_call kthread on CPU
368 * node 0, its function stratix10_svc_secure_call_thread is used to handle
369 * SMC or HVC calls between kernel driver and secure monitor software.
370 *
371 * Return: 0 for success or -ENOMEM on error.
372 */
373 static int svc_normal_to_secure_thread(void *data)
374 {
375 struct stratix10_svc_controller
376 *ctrl = (struct stratix10_svc_controller *)data;
377 struct stratix10_svc_data *pdata;
378 struct stratix10_svc_cb_data *cbdata;
379 struct arm_smccc_res res;
> 380 unsigned long a0, a1, a2, a3, a4, a5;
381 int ret_fifo = 0;
382
383 pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
384 if (!pdata)
385 return -ENOMEM;
386
387 cbdata = kmalloc(sizeof(*cbdata), GFP_KERNEL);
388 if (!cbdata) {
389 kfree(pdata);
390 return -ENOMEM;
391 }
392
393 /* default set, to remove build warning */
394 a0 = INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK;
395 a1 = 0;
396 a2 = 0;
397 a3 = 0;
398 a4 = 0;
399 a5 = 0;
400
401 pr_debug("smc_hvc_shm_thread is running\n");
402
403 while (!kthread_should_stop()) {
404 ret_fifo = kfifo_out_spinlocked(&ctrl->svc_fifo,
405 pdata, sizeof(*pdata),
406 &ctrl->svc_fifo_lock);
407
408 if (!ret_fifo)
409 continue;
410
411 pr_debug("get from FIFO pa=0x%016x, command=%u, size=%u\n",
412 (unsigned int)pdata->paddr, pdata->command,
413 (unsigned int)pdata->size);
414
415 switch (pdata->command) {
416 case COMMAND_RECONFIG_DATA_CLAIM:
417 svc_thread_cmd_data_claim(ctrl, pdata, cbdata);
418 continue;
419 case COMMAND_RECONFIG:
420 a0 = INTEL_SIP_SMC_FPGA_CONFIG_START;
421 pr_debug("conf_type=%u\n", (unsigned int)pdata->flag);
422 a1 = pdata->flag;
423 a2 = 0;
424 break;
425 case COMMAND_RECONFIG_DATA_SUBMIT:
426 a0 = INTEL_SIP_SMC_FPGA_CONFIG_WRITE;
427 a1 = (unsigned long)pdata->paddr;
428 a2 = (unsigned long)pdata->size;
429 break;
430 case COMMAND_RECONFIG_STATUS:
431 a0 = INTEL_SIP_SMC_FPGA_CONFIG_ISDONE;
432 a1 = 0;
433 a2 = 0;
434 break;
435 case COMMAND_RSU_STATUS:
436 a0 = INTEL_SIP_SMC_RSU_STATUS;
437 a1 = 0;
438 a2 = 0;
439 break;
440 case COMMAND_RSU_UPDATE:
441 a0 = INTEL_SIP_SMC_RSU_UPDATE;
442 a1 = pdata->arg[0];
443 a2 = 0;
444 break;
445 case COMMAND_RSU_NOTIFY:
446 a0 = INTEL_SIP_SMC_RSU_NOTIFY;
447 a1 = pdata->arg[0];
448 a2 = 0;
449 break;
450 case COMMAND_RSU_RETRY:
451 a0 = INTEL_SIP_SMC_RSU_RETRY_COUNTER;
452 a1 = 0;
453 a2 = 0;
454 break;
455 case COMMAND_RSU_MAX_RETRY:
456 a0 = INTEL_SIP_SMC_RSU_MAX_RETRY;
457 a1 = 0;
458 a2 = 0;
459 break;
460 case COMMAND_RSU_DCMF_VERSION:
461 a0 = INTEL_SIP_SMC_RSU_DCMF_VERSION;
462 a1 = 0;
463 a2 = 0;
464 break;
465
466 /* for FCS */
467 case COMMAND_FCS_DATA_ENCRYPTION:
468 a0 = INTEL_SIP_SMC_FCS_CRYPTION;
469 a1 = 1;
470 a2 = (unsigned long)pdata->paddr;
471 a3 = (unsigned long)pdata->size;
472 a4 = (unsigned long)pdata->paddr_output;
473 a5 = (unsigned long)pdata->size_output;
474 break;
475 case COMMAND_FCS_DATA_DECRYPTION:
476 a0 = INTEL_SIP_SMC_FCS_CRYPTION;
477 a1 = 0;
478 a2 = (unsigned long)pdata->paddr;
479 a3 = (unsigned long)pdata->size;
480 a4 = (unsigned long)pdata->paddr_output;
481 a5 = (unsigned long)pdata->size_output;
482 break;
483 case COMMAND_FCS_RANDOM_NUMBER_GEN:
484 a0 = INTEL_SIP_SMC_FCS_RANDOM_NUMBER;
485 a1 = (unsigned long)pdata->paddr;
486 a2 = (unsigned long)pdata->size;
487 break;
488 case COMMAND_FCS_REQUEST_SERVICE:
489 a0 = INTEL_SIP_SMC_FCS_SERVICE_REQUEST;
490 a1 = (unsigned long)pdata->paddr;
491 a2 = (unsigned long)pdata->size;
492 break;
493 case COMMAND_FCS_SEND_CERTIFICATE:
494 a0 = INTEL_SIP_SMC_FCS_SEND_CERTIFICATE;
495 a1 = (unsigned long)pdata->paddr;
496 a2 = (unsigned long)pdata->size;
497 break;
498 case COMMAND_FCS_GET_PROVISION_DATA:
499 a0 = INTEL_SIP_SMC_FCS_GET_PROVISION_DATA;
500 a1 = (unsigned long)pdata->paddr;
501 a2 = (unsigned long)pdata->size;
502 break;
503
504 /* for polling */
505 case COMMAND_POLL_SERVICE_STATUS:
506 a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
507 a1 = (unsigned long)pdata->paddr;
508 a2 = 0;
509 break;
510
511 default:
512 pr_warn("it shouldn't happen\n");
513 break;
514 }
515 pr_debug("%s: before SMC call -- a0=0x%016x a1=0x%016x",
516 __func__, (unsigned int)a0, (unsigned int)a1);
517 pr_debug(" a2=0x%016x\n", (unsigned int)a2);
518
519 ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, &res);
520
521 pr_debug("%s: after SMC call -- res.a0=0x%016x",
522 __func__, (unsigned int)res.a0);
523 pr_debug(" res.a1=0x%016x, res.a2=0x%016x",
524 (unsigned int)res.a1, (unsigned int)res.a2);
525 pr_debug(" res.a3=0x%016x\n", (unsigned int)res.a3);
526
527 if (pdata->command == COMMAND_RSU_STATUS) {
528 if (res.a0 == INTEL_SIP_SMC_RSU_ERROR)
529 cbdata->status = BIT(SVC_STATUS_ERROR);
530 else
531 cbdata->status = BIT(SVC_STATUS_OK);
532
533 cbdata->kaddr1 = &res;
534 cbdata->kaddr2 = NULL;
535 cbdata->kaddr3 = NULL;
536 pdata->chan->scl->receive_cb(pdata->chan->scl, cbdata);
537 continue;
538 }
539
540 switch (res.a0) {
541 case INTEL_SIP_SMC_STATUS_OK:
542 svc_thread_recv_status_ok(pdata, cbdata, res);
543 break;
544 case INTEL_SIP_SMC_STATUS_BUSY:
545 switch (pdata->command) {
546 case COMMAND_RECONFIG_DATA_SUBMIT:
547 svc_thread_cmd_data_claim(ctrl,
548 pdata, cbdata);
549 break;
550 case COMMAND_RECONFIG_STATUS:
551 case COMMAND_POLL_SERVICE_STATUS:
552 svc_thread_cmd_config_status(ctrl,
553 pdata, cbdata);
554 break;
555 default:
556 pr_warn("it shouldn't happen\n");
557 break;
558 }
559 break;
560 case INTEL_SIP_SMC_STATUS_REJECTED:
561 pr_debug("%s: STATUS_REJECTED\n", __func__);
562 /* for FCS */
563 switch (pdata->command) {
564 case COMMAND_FCS_REQUEST_SERVICE:
565 case COMMAND_FCS_SEND_CERTIFICATE:
566 case COMMAND_FCS_GET_PROVISION_DATA:
567 case COMMAND_FCS_DATA_ENCRYPTION:
568 case COMMAND_FCS_DATA_DECRYPTION:
569 case COMMAND_FCS_RANDOM_NUMBER_GEN:
570 cbdata->status = BIT(SVC_STATUS_INVALID_PARAM);
571 cbdata->kaddr1 = NULL;
572 cbdata->kaddr2 = NULL;
573 cbdata->kaddr3 = NULL;
574 pdata->chan->scl->receive_cb(pdata->chan->scl,
575 cbdata);
576 break;
577 }
578 break;
579 case INTEL_SIP_SMC_STATUS_ERROR:
580 case INTEL_SIP_SMC_RSU_ERROR:
581 pr_err("%s: STATUS_ERROR\n", __func__);
582 cbdata->status = BIT(SVC_STATUS_ERROR);
583 cbdata->kaddr1 = NULL;
584 cbdata->kaddr2 = NULL;
585 cbdata->kaddr3 = NULL;
586 pdata->chan->scl->receive_cb(pdata->chan->scl, cbdata);
587 break;
588 default:
589 pr_warn("Secure firmware doesn't support...\n");
590
591 /*
592 * be compatible with older version firmware which
593 * doesn't support RSU notify or retry
594 */
595 if ((pdata->command == COMMAND_RSU_RETRY) ||
596 (pdata->command == COMMAND_RSU_MAX_RETRY) ||
597 (pdata->command == COMMAND_RSU_NOTIFY)) {
598 cbdata->status =
599 BIT(SVC_STATUS_NO_SUPPORT);
600 cbdata->kaddr1 = NULL;
601 cbdata->kaddr2 = NULL;
602 cbdata->kaddr3 = NULL;
603 pdata->chan->scl->receive_cb(
604 pdata->chan->scl, cbdata);
605 }
606 break;
607
608 }
609 }
610
611 kfree(cbdata);
612 kfree(pdata);
613
614 return 0;
615 }
616
---
0-DAY CI Kernel Test Service
https://lists.01.org/hyperkitty/list/[email protected]