1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018-2019, Intel Corporation 4 */ 5 6 #include <linux/arm-smccc.h> 7 #include <linux/bitfield.h> 8 #include <linux/completion.h> 9 #include <linux/kobject.h> 10 #include <linux/module.h> 11 #include <linux/mutex.h> 12 #include <linux/of.h> 13 #include <linux/of_platform.h> 14 #include <linux/platform_device.h> 15 #include <linux/firmware/intel/stratix10-svc-client.h> 16 #include <linux/string.h> 17 #include <linux/sysfs.h> 18 19 #define RSU_STATE_MASK GENMASK_ULL(31, 0) 20 #define RSU_VERSION_MASK GENMASK_ULL(63, 32) 21 #define RSU_ERROR_LOCATION_MASK GENMASK_ULL(31, 0) 22 #define RSU_ERROR_DETAIL_MASK GENMASK_ULL(63, 32) 23 24 #define RSU_TIMEOUT (msecs_to_jiffies(SVC_RSU_REQUEST_TIMEOUT_MS)) 25 26 #define INVALID_RETRY_COUNTER 0xFFFFFFFF 27 28 typedef void (*rsu_callback)(struct stratix10_svc_client *client, 29 struct stratix10_svc_cb_data *data); 30 /** 31 * struct stratix10_rsu_priv - rsu data structure 32 * @chan: pointer to the allocated service channel 33 * @client: active service client 34 * @completion: state for callback completion 35 * @lock: a mutex to protect callback completion state 36 * @status.current_image: address of image currently running in flash 37 * @status.fail_image: address of failed image in flash 38 * @status.version: the version number of RSU firmware 39 * @status.state: the state of RSU system 40 * @status.error_details: error code 41 * @status.error_location: the error offset inside the image that failed 42 * @retry_counter: the current image's retry counter 43 */ 44 struct stratix10_rsu_priv { 45 struct stratix10_svc_chan *chan; 46 struct stratix10_svc_client client; 47 struct completion completion; 48 struct mutex lock; 49 struct { 50 unsigned long current_image; 51 unsigned long fail_image; 52 unsigned int version; 53 unsigned int state; 54 unsigned int error_details; 55 unsigned int error_location; 56 } status; 57 unsigned int retry_counter; 58 }; 59 60 /** 61 * rsu_status_callback() - Status callback from Intel Service Layer 62 * @client: pointer to service client 63 * @data: pointer to callback data structure 64 * 65 * Callback from Intel service layer for RSU status request. Status is 66 * only updated after a system reboot, so a get updated status call is 67 * made during driver probe. 68 */ 69 static void rsu_status_callback(struct stratix10_svc_client *client, 70 struct stratix10_svc_cb_data *data) 71 { 72 struct stratix10_rsu_priv *priv = client->priv; 73 struct arm_smccc_res *res = (struct arm_smccc_res *)data->kaddr1; 74 75 if (data->status == BIT(SVC_STATUS_RSU_OK)) { 76 priv->status.version = FIELD_GET(RSU_VERSION_MASK, 77 res->a2); 78 priv->status.state = FIELD_GET(RSU_STATE_MASK, res->a2); 79 priv->status.fail_image = res->a1; 80 priv->status.current_image = res->a0; 81 priv->status.error_location = 82 FIELD_GET(RSU_ERROR_LOCATION_MASK, res->a3); 83 priv->status.error_details = 84 FIELD_GET(RSU_ERROR_DETAIL_MASK, res->a3); 85 } else { 86 dev_err(client->dev, "COMMAND_RSU_STATUS returned 0x%lX\n", 87 res->a0); 88 priv->status.version = 0; 89 priv->status.state = 0; 90 priv->status.fail_image = 0; 91 priv->status.current_image = 0; 92 priv->status.error_location = 0; 93 priv->status.error_details = 0; 94 } 95 96 complete(&priv->completion); 97 } 98 99 /** 100 * rsu_command_callback() - Update callback from Intel Service Layer 101 * @client: pointer to client 102 * @data: pointer to callback data structure 103 * 104 * Callback from Intel service layer for RSU commands. 105 */ 106 static void rsu_command_callback(struct stratix10_svc_client *client, 107 struct stratix10_svc_cb_data *data) 108 { 109 struct stratix10_rsu_priv *priv = client->priv; 110 111 if (data->status == BIT(SVC_STATUS_RSU_NO_SUPPORT)) 112 dev_warn(client->dev, "Secure FW doesn't support notify\n"); 113 else if (data->status == BIT(SVC_STATUS_RSU_ERROR)) 114 dev_err(client->dev, "Failure, returned status is %lu\n", 115 BIT(data->status)); 116 117 complete(&priv->completion); 118 } 119 120 /** 121 * rsu_retry_callback() - Callback from Intel service layer for getting 122 * the current image's retry counter from firmware 123 * @client: pointer to client 124 * @data: pointer to callback data structure 125 * 126 * Callback from Intel service layer for retry counter, which is used by 127 * user to know how many times the images is still allowed to reload 128 * itself before giving up and starting RSU fail-over flow. 129 */ 130 static void rsu_retry_callback(struct stratix10_svc_client *client, 131 struct stratix10_svc_cb_data *data) 132 { 133 struct stratix10_rsu_priv *priv = client->priv; 134 unsigned int *counter = (unsigned int *)data->kaddr1; 135 136 if (data->status == BIT(SVC_STATUS_RSU_OK)) 137 priv->retry_counter = *counter; 138 else if (data->status == BIT(SVC_STATUS_RSU_NO_SUPPORT)) 139 dev_warn(client->dev, "Secure FW doesn't support retry\n"); 140 else 141 dev_err(client->dev, "Failed to get retry counter %lu\n", 142 BIT(data->status)); 143 144 complete(&priv->completion); 145 } 146 147 /** 148 * rsu_send_msg() - send a message to Intel service layer 149 * @priv: pointer to rsu private data 150 * @command: RSU status or update command 151 * @arg: the request argument, the bitstream address or notify status 152 * @callback: function pointer for the callback (status or update) 153 * 154 * Start an Intel service layer transaction to perform the SMC call that 155 * is necessary to get RSU boot log or set the address of bitstream to 156 * boot after reboot. 157 * 158 * Returns 0 on success or -ETIMEDOUT on error. 159 */ 160 static int rsu_send_msg(struct stratix10_rsu_priv *priv, 161 enum stratix10_svc_command_code command, 162 unsigned long arg, 163 rsu_callback callback) 164 { 165 struct stratix10_svc_client_msg msg; 166 int ret; 167 168 mutex_lock(&priv->lock); 169 reinit_completion(&priv->completion); 170 priv->client.receive_cb = callback; 171 172 msg.command = command; 173 if (arg) 174 msg.arg[0] = arg; 175 176 ret = stratix10_svc_send(priv->chan, &msg); 177 if (ret < 0) 178 goto status_done; 179 180 ret = wait_for_completion_interruptible_timeout(&priv->completion, 181 RSU_TIMEOUT); 182 if (!ret) { 183 dev_err(priv->client.dev, 184 "timeout waiting for SMC call\n"); 185 ret = -ETIMEDOUT; 186 goto status_done; 187 } else if (ret < 0) { 188 dev_err(priv->client.dev, 189 "error %d waiting for SMC call\n", ret); 190 goto status_done; 191 } else { 192 ret = 0; 193 } 194 195 status_done: 196 stratix10_svc_done(priv->chan); 197 mutex_unlock(&priv->lock); 198 return ret; 199 } 200 201 /* 202 * This driver exposes some optional features of the Intel Stratix 10 SoC FPGA. 203 * The sysfs interfaces exposed here are FPGA Remote System Update (RSU) 204 * related. They allow user space software to query the configuration system 205 * status and to request optional reboot behavior specific to Intel FPGAs. 206 */ 207 208 static ssize_t current_image_show(struct device *dev, 209 struct device_attribute *attr, char *buf) 210 { 211 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 212 213 if (!priv) 214 return -ENODEV; 215 216 return sprintf(buf, "0x%08lx\n", priv->status.current_image); 217 } 218 219 static ssize_t fail_image_show(struct device *dev, 220 struct device_attribute *attr, char *buf) 221 { 222 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 223 224 if (!priv) 225 return -ENODEV; 226 227 return sprintf(buf, "0x%08lx\n", priv->status.fail_image); 228 } 229 230 static ssize_t version_show(struct device *dev, struct device_attribute *attr, 231 char *buf) 232 { 233 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 234 235 if (!priv) 236 return -ENODEV; 237 238 return sprintf(buf, "0x%08x\n", priv->status.version); 239 } 240 241 static ssize_t state_show(struct device *dev, struct device_attribute *attr, 242 char *buf) 243 { 244 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 245 246 if (!priv) 247 return -ENODEV; 248 249 return sprintf(buf, "0x%08x\n", priv->status.state); 250 } 251 252 static ssize_t error_location_show(struct device *dev, 253 struct device_attribute *attr, char *buf) 254 { 255 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 256 257 if (!priv) 258 return -ENODEV; 259 260 return sprintf(buf, "0x%08x\n", priv->status.error_location); 261 } 262 263 static ssize_t error_details_show(struct device *dev, 264 struct device_attribute *attr, char *buf) 265 { 266 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 267 268 if (!priv) 269 return -ENODEV; 270 271 return sprintf(buf, "0x%08x\n", priv->status.error_details); 272 } 273 274 static ssize_t retry_counter_show(struct device *dev, 275 struct device_attribute *attr, char *buf) 276 { 277 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 278 279 if (!priv) 280 return -ENODEV; 281 282 return sprintf(buf, "0x%08x\n", priv->retry_counter); 283 } 284 285 static ssize_t reboot_image_store(struct device *dev, 286 struct device_attribute *attr, 287 const char *buf, size_t count) 288 { 289 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 290 unsigned long address; 291 int ret; 292 293 if (priv == 0) 294 return -ENODEV; 295 296 ret = kstrtoul(buf, 0, &address); 297 if (ret) 298 return ret; 299 300 ret = rsu_send_msg(priv, COMMAND_RSU_UPDATE, 301 address, rsu_command_callback); 302 if (ret) { 303 dev_err(dev, "Error, RSU update returned %i\n", ret); 304 return ret; 305 } 306 307 return count; 308 } 309 310 static ssize_t notify_store(struct device *dev, 311 struct device_attribute *attr, 312 const char *buf, size_t count) 313 { 314 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 315 unsigned long status; 316 int ret; 317 318 if (priv == 0) 319 return -ENODEV; 320 321 ret = kstrtoul(buf, 0, &status); 322 if (ret) 323 return ret; 324 325 ret = rsu_send_msg(priv, COMMAND_RSU_NOTIFY, 326 status, rsu_command_callback); 327 if (ret) { 328 dev_err(dev, "Error, RSU notify returned %i\n", ret); 329 return ret; 330 } 331 332 /* to get the updated state */ 333 ret = rsu_send_msg(priv, COMMAND_RSU_STATUS, 334 0, rsu_status_callback); 335 if (ret) { 336 dev_err(dev, "Error, getting RSU status %i\n", ret); 337 return ret; 338 } 339 340 ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback); 341 if (ret) { 342 dev_err(dev, "Error, getting RSU retry %i\n", ret); 343 return ret; 344 } 345 346 return count; 347 } 348 349 static DEVICE_ATTR_RO(current_image); 350 static DEVICE_ATTR_RO(fail_image); 351 static DEVICE_ATTR_RO(state); 352 static DEVICE_ATTR_RO(version); 353 static DEVICE_ATTR_RO(error_location); 354 static DEVICE_ATTR_RO(error_details); 355 static DEVICE_ATTR_RO(retry_counter); 356 static DEVICE_ATTR_WO(reboot_image); 357 static DEVICE_ATTR_WO(notify); 358 359 static struct attribute *rsu_attrs[] = { 360 &dev_attr_current_image.attr, 361 &dev_attr_fail_image.attr, 362 &dev_attr_state.attr, 363 &dev_attr_version.attr, 364 &dev_attr_error_location.attr, 365 &dev_attr_error_details.attr, 366 &dev_attr_retry_counter.attr, 367 &dev_attr_reboot_image.attr, 368 &dev_attr_notify.attr, 369 NULL 370 }; 371 372 ATTRIBUTE_GROUPS(rsu); 373 374 static int stratix10_rsu_probe(struct platform_device *pdev) 375 { 376 struct device *dev = &pdev->dev; 377 struct stratix10_rsu_priv *priv; 378 int ret; 379 380 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 381 if (!priv) 382 return -ENOMEM; 383 384 priv->client.dev = dev; 385 priv->client.receive_cb = NULL; 386 priv->client.priv = priv; 387 priv->status.current_image = 0; 388 priv->status.fail_image = 0; 389 priv->status.error_location = 0; 390 priv->status.error_details = 0; 391 priv->status.version = 0; 392 priv->status.state = 0; 393 priv->retry_counter = INVALID_RETRY_COUNTER; 394 395 mutex_init(&priv->lock); 396 priv->chan = stratix10_svc_request_channel_byname(&priv->client, 397 SVC_CLIENT_RSU); 398 if (IS_ERR(priv->chan)) { 399 dev_err(dev, "couldn't get service channel %s\n", 400 SVC_CLIENT_RSU); 401 return PTR_ERR(priv->chan); 402 } 403 404 init_completion(&priv->completion); 405 platform_set_drvdata(pdev, priv); 406 407 /* get the initial state from firmware */ 408 ret = rsu_send_msg(priv, COMMAND_RSU_STATUS, 409 0, rsu_status_callback); 410 if (ret) { 411 dev_err(dev, "Error, getting RSU status %i\n", ret); 412 stratix10_svc_free_channel(priv->chan); 413 } 414 415 ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback); 416 if (ret) { 417 dev_err(dev, "Error, getting RSU retry %i\n", ret); 418 stratix10_svc_free_channel(priv->chan); 419 } 420 421 return ret; 422 } 423 424 static int stratix10_rsu_remove(struct platform_device *pdev) 425 { 426 struct stratix10_rsu_priv *priv = platform_get_drvdata(pdev); 427 428 stratix10_svc_free_channel(priv->chan); 429 return 0; 430 } 431 432 static struct platform_driver stratix10_rsu_driver = { 433 .probe = stratix10_rsu_probe, 434 .remove = stratix10_rsu_remove, 435 .driver = { 436 .name = "stratix10-rsu", 437 .dev_groups = rsu_groups, 438 }, 439 }; 440 441 module_platform_driver(stratix10_rsu_driver); 442 443 MODULE_LICENSE("GPL v2"); 444 MODULE_DESCRIPTION("Intel Remote System Update Driver"); 445 MODULE_AUTHOR("Richard Gong <richard.gong@intel.com>"); 446