Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: add remote status update client support

Extend Intel Stratix10 service layer to support the second service layer
client, Remote Status Update (RSU).

RSU is used to provide our customers with protection against loading bad
bitstreams onto their devices when those devices are booting from flash.

Signed-off-by: Richard Gong <richard.gong@intel.com>
Signed-off-by: Alan Tull <atull@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Richard Gong and committed by
Greg Kroah-Hartman
6b50d882 0d5c06aa

+98 -4
+33 -2
drivers/firmware/stratix10-svc.c
··· 34 34 * timeout is set to 30 seconds (30 * 1000) at Intel Stratix10 SoC. 35 35 */ 36 36 #define SVC_NUM_DATA_IN_FIFO 32 37 - #define SVC_NUM_CHANNEL 1 37 + #define SVC_NUM_CHANNEL 2 38 38 #define FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS 200 39 39 #define FPGA_CONFIG_STATUS_TIMEOUT_SEC 30 40 40 ··· 271 271 * @cb_data: pointer to callback data structure to service client 272 272 * @res: result from SMC or HVC call 273 273 * 274 - * Send back the correspond status to the service client (FPGA manager etc). 274 + * Send back the correspond status to the service clients. 275 275 */ 276 276 static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data, 277 277 struct stratix10_svc_cb_data *cb_data, ··· 294 294 break; 295 295 case COMMAND_RECONFIG_STATUS: 296 296 cb_data->status = BIT(SVC_STATUS_RECONFIG_COMPLETED); 297 + break; 298 + case COMMAND_RSU_UPDATE: 299 + cb_data->status = BIT(SVC_STATUS_RSU_OK); 297 300 break; 298 301 default: 299 302 pr_warn("it shouldn't happen\n"); ··· 376 373 a1 = 0; 377 374 a2 = 0; 378 375 break; 376 + case COMMAND_RSU_STATUS: 377 + a0 = INTEL_SIP_SMC_RSU_STATUS; 378 + a1 = 0; 379 + a2 = 0; 380 + break; 381 + case COMMAND_RSU_UPDATE: 382 + a0 = INTEL_SIP_SMC_RSU_UPDATE; 383 + a1 = pdata->arg[0]; 384 + a2 = 0; 385 + break; 379 386 default: 380 387 pr_warn("it shouldn't happen\n"); 381 388 break; ··· 401 388 pr_debug(" res.a1=0x%016x, res.a2=0x%016x", 402 389 (unsigned int)res.a1, (unsigned int)res.a2); 403 390 pr_debug(" res.a3=0x%016x\n", (unsigned int)res.a3); 391 + 392 + if (pdata->command == COMMAND_RSU_STATUS) { 393 + if (res.a0 == INTEL_SIP_SMC_RSU_ERROR) 394 + cbdata->status = BIT(SVC_STATUS_RSU_ERROR); 395 + else 396 + cbdata->status = BIT(SVC_STATUS_RSU_OK); 397 + 398 + cbdata->kaddr1 = &res; 399 + cbdata->kaddr2 = NULL; 400 + cbdata->kaddr3 = NULL; 401 + pdata->chan->scl->receive_cb(pdata->chan->scl, cbdata); 402 + continue; 403 + } 404 404 405 405 switch (res.a0) { 406 406 case INTEL_SIP_SMC_STATUS_OK: ··· 966 940 chans[0].ctrl = controller; 967 941 chans[0].name = SVC_CLIENT_FPGA; 968 942 spin_lock_init(&chans[0].lock); 943 + 944 + chans[1].scl = NULL; 945 + chans[1].ctrl = controller; 946 + chans[1].name = SVC_CLIENT_RSU; 947 + spin_lock_init(&chans[1].lock); 969 948 970 949 list_add_tail(&controller->node, &svc_ctrl); 971 950 platform_set_drvdata(pdev, controller);
+47
include/linux/firmware/intel/stratix10-smc.h
··· 67 67 * 68 68 * INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR: 69 69 * There is error during the FPGA configuration process. 70 + * 71 + * INTEL_SIP_SMC_REG_ERROR: 72 + * There is error during a read or write operation of the protected registers. 73 + * 74 + * INTEL_SIP_SMC_RSU_ERROR: 75 + * There is error during a remote status update. 70 76 */ 71 77 #define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF 72 78 #define INTEL_SIP_SMC_STATUS_OK 0x0 ··· 80 74 #define INTEL_SIP_SMC_FPGA_CONFIG_STATUS_REJECTED 0x2 81 75 #define INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR 0x4 82 76 #define INTEL_SIP_SMC_REG_ERROR 0x5 77 + #define INTEL_SIP_SMC_RSU_ERROR 0x7 83 78 84 79 /** 85 80 * Request INTEL_SIP_SMC_FPGA_CONFIG_START ··· 269 262 #define INTEL_SIP_SMC_REG_UPDATE \ 270 263 INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_UPDATE) 271 264 265 + /* 266 + * Request INTEL_SIP_SMC_RSU_STATUS 267 + * 268 + * Request remote status update boot log, call is synchronous. 269 + * 270 + * Call register usage: 271 + * a0 INTEL_SIP_SMC_RSU_STATUS 272 + * a1-7 not used 273 + * 274 + * Return status 275 + * a0: Current Image 276 + * a1: Last Failing Image 277 + * a2: Version | State 278 + * a3: Error details | Error location 279 + * 280 + * Or 281 + * 282 + * a0: INTEL_SIP_SMC_RSU_ERROR 283 + */ 284 + #define INTEL_SIP_SMC_FUNCID_RSU_STATUS 11 285 + #define INTEL_SIP_SMC_RSU_STATUS \ 286 + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_STATUS) 287 + 288 + /* 289 + * Request INTEL_SIP_SMC_RSU_UPDATE 290 + * 291 + * Request to set the offset of the bitstream to boot after reboot, call 292 + * is synchronous. 293 + * 294 + * Call register usage: 295 + * a0 INTEL_SIP_SMC_RSU_UPDATE 296 + * a1 64bit physical address of the configuration data memory in flash 297 + * a2-7 not used 298 + * 299 + * Return status 300 + * a0 INTEL_SIP_SMC_STATUS_OK 301 + */ 302 + #define INTEL_SIP_SMC_FUNCID_RSU_UPDATE 12 303 + #define INTEL_SIP_SMC_RSU_UPDATE \ 304 + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_UPDATE) 272 305 #endif
+18 -2
include/linux/firmware/intel/stratix10-svc-client.h
··· 10 10 * Service layer driver supports client names 11 11 * 12 12 * fpga: for FPGA configuration 13 + * rsu: for remote status update 13 14 */ 14 15 #define SVC_CLIENT_FPGA "fpga" 16 + #define SVC_CLIENT_RSU "rsu" 15 17 16 18 /** 17 19 * Status of the sent command, in bit number ··· 38 36 * 39 37 * SVC_COMMAND_STATUS_RECONFIG_ERROR: 40 38 * Error encountered during FPGA configuration. 39 + * 40 + * SVC_STATUS_RSU_OK: 41 + * Secure firmware accepts the request of remote status update (RSU). 41 42 */ 42 43 #define SVC_STATUS_RECONFIG_REQUEST_OK 0 43 44 #define SVC_STATUS_RECONFIG_BUFFER_SUBMITTED 1 ··· 48 43 #define SVC_STATUS_RECONFIG_COMPLETED 3 49 44 #define SVC_STATUS_RECONFIG_BUSY 4 50 45 #define SVC_STATUS_RECONFIG_ERROR 5 51 - 46 + #define SVC_STATUS_RSU_OK 6 47 + #define SVC_STATUS_RSU_ERROR 7 52 48 /** 53 49 * Flag bit for COMMAND_RECONFIG 54 50 * ··· 62 56 /** 63 57 * Timeout settings for service clients: 64 58 * timeout value used in Stratix10 FPGA manager driver. 59 + * timeout value used in RSU driver 65 60 */ 66 61 #define SVC_RECONFIG_REQUEST_TIMEOUT_MS 100 67 62 #define SVC_RECONFIG_BUFFER_TIMEOUT_MS 240 63 + #define SVC_RSU_REQUEST_TIMEOUT_MS 300 68 64 69 65 struct stratix10_svc_chan; 70 66 ··· 89 81 * @COMMAND_RECONFIG_STATUS: check the status of the configuration, return 90 82 * status is SVC_STATUS_RECONFIG_COMPLETED, or SVC_STATUS_RECONFIG_BUSY, or 91 83 * SVC_STATUS_RECONFIG_ERROR 84 + * 85 + * @COMMAND_RSU_STATUS: request remote system update boot log, return status 86 + * is log data or SVC_STATUS_RSU_ERROR 87 + * 88 + * @COMMAND_RSU_UPDATE: set the offset of the bitstream to boot after reboot, 89 + * return status is SVC_STATUS_RSU_OK or SVC_STATUS_RSU_ERROR 92 90 */ 93 91 enum stratix10_svc_command_code { 94 92 COMMAND_NOOP = 0, 95 93 COMMAND_RECONFIG, 96 94 COMMAND_RECONFIG_DATA_SUBMIT, 97 95 COMMAND_RECONFIG_DATA_CLAIM, 98 - COMMAND_RECONFIG_STATUS 96 + COMMAND_RECONFIG_STATUS, 97 + COMMAND_RSU_STATUS, 98 + COMMAND_RSU_UPDATE 99 99 }; 100 100 101 101 /**