PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/powerpc/platforms/powernv/opal-flash.c

https://github.com/tiwai/sound
C | 566 lines | 357 code | 91 blank | 118 comment | 42 complexity | e2aab7d58eee230540deef32b76f7589 MD5 | raw file
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * PowerNV OPAL Firmware Update Interface
  4. *
  5. * Copyright 2013 IBM Corp.
  6. */
  7. #define DEBUG
  8. #include <linux/kernel.h>
  9. #include <linux/reboot.h>
  10. #include <linux/init.h>
  11. #include <linux/kobject.h>
  12. #include <linux/sysfs.h>
  13. #include <linux/slab.h>
  14. #include <linux/mm.h>
  15. #include <linux/vmalloc.h>
  16. #include <linux/pagemap.h>
  17. #include <linux/delay.h>
  18. #include <asm/opal.h>
  19. /* FLASH status codes */
  20. #define FLASH_NO_OP -1099 /* No operation initiated by user */
  21. #define FLASH_NO_AUTH -9002 /* Not a service authority partition */
  22. /* Validate image status values */
  23. #define VALIDATE_IMG_READY -1001 /* Image ready for validation */
  24. #define VALIDATE_IMG_INCOMPLETE -1002 /* User copied < VALIDATE_BUF_SIZE */
  25. /* Manage image status values */
  26. #define MANAGE_ACTIVE_ERR -9001 /* Cannot overwrite active img */
  27. /* Flash image status values */
  28. #define FLASH_IMG_READY 0 /* Img ready for flash on reboot */
  29. #define FLASH_INVALID_IMG -1003 /* Flash image shorter than expected */
  30. #define FLASH_IMG_NULL_DATA -1004 /* Bad data in sg list entry */
  31. #define FLASH_IMG_BAD_LEN -1005 /* Bad length in sg list entry */
  32. /* Manage operation tokens */
  33. #define FLASH_REJECT_TMP_SIDE 0 /* Reject temporary fw image */
  34. #define FLASH_COMMIT_TMP_SIDE 1 /* Commit temporary fw image */
  35. /* Update tokens */
  36. #define FLASH_UPDATE_CANCEL 0 /* Cancel update request */
  37. #define FLASH_UPDATE_INIT 1 /* Initiate update */
  38. /* Validate image update result tokens */
  39. #define VALIDATE_TMP_UPDATE 0 /* T side will be updated */
  40. #define VALIDATE_FLASH_AUTH 1 /* Partition does not have authority */
  41. #define VALIDATE_INVALID_IMG 2 /* Candidate image is not valid */
  42. #define VALIDATE_CUR_UNKNOWN 3 /* Current fixpack level is unknown */
  43. /*
  44. * Current T side will be committed to P side before being replace with new
  45. * image, and the new image is downlevel from current image
  46. */
  47. #define VALIDATE_TMP_COMMIT_DL 4
  48. /*
  49. * Current T side will be committed to P side before being replaced with new
  50. * image
  51. */
  52. #define VALIDATE_TMP_COMMIT 5
  53. /*
  54. * T side will be updated with a downlevel image
  55. */
  56. #define VALIDATE_TMP_UPDATE_DL 6
  57. /*
  58. * The candidate image's release date is later than the system's firmware
  59. * service entitlement date - service warranty period has expired
  60. */
  61. #define VALIDATE_OUT_OF_WRNTY 7
  62. /* Validate buffer size */
  63. #define VALIDATE_BUF_SIZE 4096
  64. /* XXX: Assume candidate image size is <= 1GB */
  65. #define MAX_IMAGE_SIZE 0x40000000
  66. /* Image status */
  67. enum {
  68. IMAGE_INVALID,
  69. IMAGE_LOADING,
  70. IMAGE_READY,
  71. };
  72. /* Candidate image data */
  73. struct image_data_t {
  74. int status;
  75. void *data;
  76. uint32_t size;
  77. };
  78. /* Candidate image header */
  79. struct image_header_t {
  80. uint16_t magic;
  81. uint16_t version;
  82. uint32_t size;
  83. };
  84. struct validate_flash_t {
  85. int status; /* Return status */
  86. void *buf; /* Candidate image buffer */
  87. uint32_t buf_size; /* Image size */
  88. uint32_t result; /* Update results token */
  89. };
  90. struct manage_flash_t {
  91. int status; /* Return status */
  92. };
  93. struct update_flash_t {
  94. int status; /* Return status */
  95. };
  96. static struct image_header_t image_header;
  97. static struct image_data_t image_data;
  98. static struct validate_flash_t validate_flash_data;
  99. static struct manage_flash_t manage_flash_data;
  100. /* Initialize update_flash_data status to No Operation */
  101. static struct update_flash_t update_flash_data = {
  102. .status = FLASH_NO_OP,
  103. };
  104. static DEFINE_MUTEX(image_data_mutex);
  105. /*
  106. * Validate candidate image
  107. */
  108. static inline void opal_flash_validate(void)
  109. {
  110. long ret;
  111. void *buf = validate_flash_data.buf;
  112. __be32 size = cpu_to_be32(validate_flash_data.buf_size);
  113. __be32 result;
  114. ret = opal_validate_flash(__pa(buf), &size, &result);
  115. validate_flash_data.status = ret;
  116. validate_flash_data.buf_size = be32_to_cpu(size);
  117. validate_flash_data.result = be32_to_cpu(result);
  118. }
  119. /*
  120. * Validate output format:
  121. * validate result token
  122. * current image version details
  123. * new image version details
  124. */
  125. static ssize_t validate_show(struct kobject *kobj,
  126. struct kobj_attribute *attr, char *buf)
  127. {
  128. struct validate_flash_t *args_buf = &validate_flash_data;
  129. int len;
  130. /* Candidate image is not validated */
  131. if (args_buf->status < VALIDATE_TMP_UPDATE) {
  132. len = sprintf(buf, "%d\n", args_buf->status);
  133. goto out;
  134. }
  135. /* Result token */
  136. len = sprintf(buf, "%d\n", args_buf->result);
  137. /* Current and candidate image version details */
  138. if ((args_buf->result != VALIDATE_TMP_UPDATE) &&
  139. (args_buf->result < VALIDATE_CUR_UNKNOWN))
  140. goto out;
  141. if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) {
  142. memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len);
  143. len = VALIDATE_BUF_SIZE;
  144. } else {
  145. memcpy(buf + len, args_buf->buf, args_buf->buf_size);
  146. len += args_buf->buf_size;
  147. }
  148. out:
  149. /* Set status to default */
  150. args_buf->status = FLASH_NO_OP;
  151. return len;
  152. }
  153. /*
  154. * Validate candidate firmware image
  155. *
  156. * Note:
  157. * We are only interested in first 4K bytes of the
  158. * candidate image.
  159. */
  160. static ssize_t validate_store(struct kobject *kobj,
  161. struct kobj_attribute *attr,
  162. const char *buf, size_t count)
  163. {
  164. struct validate_flash_t *args_buf = &validate_flash_data;
  165. if (buf[0] != '1')
  166. return -EINVAL;
  167. mutex_lock(&image_data_mutex);
  168. if (image_data.status != IMAGE_READY ||
  169. image_data.size < VALIDATE_BUF_SIZE) {
  170. args_buf->result = VALIDATE_INVALID_IMG;
  171. args_buf->status = VALIDATE_IMG_INCOMPLETE;
  172. goto out;
  173. }
  174. /* Copy first 4k bytes of candidate image */
  175. memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE);
  176. args_buf->status = VALIDATE_IMG_READY;
  177. args_buf->buf_size = VALIDATE_BUF_SIZE;
  178. /* Validate candidate image */
  179. opal_flash_validate();
  180. out:
  181. mutex_unlock(&image_data_mutex);
  182. return count;
  183. }
  184. /*
  185. * Manage flash routine
  186. */
  187. static inline void opal_flash_manage(uint8_t op)
  188. {
  189. struct manage_flash_t *const args_buf = &manage_flash_data;
  190. args_buf->status = opal_manage_flash(op);
  191. }
  192. /*
  193. * Show manage flash status
  194. */
  195. static ssize_t manage_show(struct kobject *kobj,
  196. struct kobj_attribute *attr, char *buf)
  197. {
  198. struct manage_flash_t *const args_buf = &manage_flash_data;
  199. int rc;
  200. rc = sprintf(buf, "%d\n", args_buf->status);
  201. /* Set status to default*/
  202. args_buf->status = FLASH_NO_OP;
  203. return rc;
  204. }
  205. /*
  206. * Manage operations:
  207. * 0 - Reject
  208. * 1 - Commit
  209. */
  210. static ssize_t manage_store(struct kobject *kobj,
  211. struct kobj_attribute *attr,
  212. const char *buf, size_t count)
  213. {
  214. uint8_t op;
  215. switch (buf[0]) {
  216. case '0':
  217. op = FLASH_REJECT_TMP_SIDE;
  218. break;
  219. case '1':
  220. op = FLASH_COMMIT_TMP_SIDE;
  221. break;
  222. default:
  223. return -EINVAL;
  224. }
  225. /* commit/reject temporary image */
  226. opal_flash_manage(op);
  227. return count;
  228. }
  229. /*
  230. * OPAL update flash
  231. */
  232. static int opal_flash_update(int op)
  233. {
  234. struct opal_sg_list *list;
  235. unsigned long addr;
  236. int64_t rc = OPAL_PARAMETER;
  237. if (op == FLASH_UPDATE_CANCEL) {
  238. pr_alert("FLASH: Image update cancelled\n");
  239. addr = '\0';
  240. goto flash;
  241. }
  242. list = opal_vmalloc_to_sg_list(image_data.data, image_data.size);
  243. if (!list)
  244. goto invalid_img;
  245. /* First entry address */
  246. addr = __pa(list);
  247. flash:
  248. rc = opal_update_flash(addr);
  249. invalid_img:
  250. return rc;
  251. }
  252. /* This gets called just before system reboots */
  253. void opal_flash_update_print_message(void)
  254. {
  255. if (update_flash_data.status != FLASH_IMG_READY)
  256. return;
  257. pr_alert("FLASH: Flashing new firmware\n");
  258. pr_alert("FLASH: Image is %u bytes\n", image_data.size);
  259. pr_alert("FLASH: Performing flash and reboot/shutdown\n");
  260. pr_alert("FLASH: This will take several minutes. Do not power off!\n");
  261. /* Small delay to help getting the above message out */
  262. msleep(500);
  263. }
  264. /*
  265. * Show candidate image status
  266. */
  267. static ssize_t update_show(struct kobject *kobj,
  268. struct kobj_attribute *attr, char *buf)
  269. {
  270. struct update_flash_t *const args_buf = &update_flash_data;
  271. return sprintf(buf, "%d\n", args_buf->status);
  272. }
  273. /*
  274. * Set update image flag
  275. * 1 - Flash new image
  276. * 0 - Cancel flash request
  277. */
  278. static ssize_t update_store(struct kobject *kobj,
  279. struct kobj_attribute *attr,
  280. const char *buf, size_t count)
  281. {
  282. struct update_flash_t *const args_buf = &update_flash_data;
  283. int rc = count;
  284. mutex_lock(&image_data_mutex);
  285. switch (buf[0]) {
  286. case '0':
  287. if (args_buf->status == FLASH_IMG_READY)
  288. opal_flash_update(FLASH_UPDATE_CANCEL);
  289. args_buf->status = FLASH_NO_OP;
  290. break;
  291. case '1':
  292. /* Image is loaded? */
  293. if (image_data.status == IMAGE_READY)
  294. args_buf->status =
  295. opal_flash_update(FLASH_UPDATE_INIT);
  296. else
  297. args_buf->status = FLASH_INVALID_IMG;
  298. break;
  299. default:
  300. rc = -EINVAL;
  301. }
  302. mutex_unlock(&image_data_mutex);
  303. return rc;
  304. }
  305. /*
  306. * Free image buffer
  307. */
  308. static void free_image_buf(void)
  309. {
  310. void *addr;
  311. int size;
  312. addr = image_data.data;
  313. size = PAGE_ALIGN(image_data.size);
  314. while (size > 0) {
  315. ClearPageReserved(vmalloc_to_page(addr));
  316. addr += PAGE_SIZE;
  317. size -= PAGE_SIZE;
  318. }
  319. vfree(image_data.data);
  320. image_data.data = NULL;
  321. image_data.status = IMAGE_INVALID;
  322. }
  323. /*
  324. * Allocate image buffer.
  325. */
  326. static int alloc_image_buf(char *buffer, size_t count)
  327. {
  328. void *addr;
  329. int size;
  330. if (count < sizeof(image_header)) {
  331. pr_warn("FLASH: Invalid candidate image\n");
  332. return -EINVAL;
  333. }
  334. memcpy(&image_header, (void *)buffer, sizeof(image_header));
  335. image_data.size = be32_to_cpu(image_header.size);
  336. pr_debug("FLASH: Candidate image size = %u\n", image_data.size);
  337. if (image_data.size > MAX_IMAGE_SIZE) {
  338. pr_warn("FLASH: Too large image\n");
  339. return -EINVAL;
  340. }
  341. if (image_data.size < VALIDATE_BUF_SIZE) {
  342. pr_warn("FLASH: Image is shorter than expected\n");
  343. return -EINVAL;
  344. }
  345. image_data.data = vzalloc(PAGE_ALIGN(image_data.size));
  346. if (!image_data.data) {
  347. pr_err("%s : Failed to allocate memory\n", __func__);
  348. return -ENOMEM;
  349. }
  350. /* Pin memory */
  351. addr = image_data.data;
  352. size = PAGE_ALIGN(image_data.size);
  353. while (size > 0) {
  354. SetPageReserved(vmalloc_to_page(addr));
  355. addr += PAGE_SIZE;
  356. size -= PAGE_SIZE;
  357. }
  358. image_data.status = IMAGE_LOADING;
  359. return 0;
  360. }
  361. /*
  362. * Copy candidate image
  363. *
  364. * Parse candidate image header to get total image size
  365. * and pre-allocate required memory.
  366. */
  367. static ssize_t image_data_write(struct file *filp, struct kobject *kobj,
  368. struct bin_attribute *bin_attr,
  369. char *buffer, loff_t pos, size_t count)
  370. {
  371. int rc;
  372. mutex_lock(&image_data_mutex);
  373. /* New image ? */
  374. if (pos == 0) {
  375. /* Free memory, if already allocated */
  376. if (image_data.data)
  377. free_image_buf();
  378. /* Cancel outstanding image update request */
  379. if (update_flash_data.status == FLASH_IMG_READY)
  380. opal_flash_update(FLASH_UPDATE_CANCEL);
  381. /* Allocate memory */
  382. rc = alloc_image_buf(buffer, count);
  383. if (rc)
  384. goto out;
  385. }
  386. if (image_data.status != IMAGE_LOADING) {
  387. rc = -ENOMEM;
  388. goto out;
  389. }
  390. if ((pos + count) > image_data.size) {
  391. rc = -EINVAL;
  392. goto out;
  393. }
  394. memcpy(image_data.data + pos, (void *)buffer, count);
  395. rc = count;
  396. /* Set image status */
  397. if ((pos + count) == image_data.size) {
  398. pr_debug("FLASH: Candidate image loaded....\n");
  399. image_data.status = IMAGE_READY;
  400. }
  401. out:
  402. mutex_unlock(&image_data_mutex);
  403. return rc;
  404. }
  405. /*
  406. * sysfs interface :
  407. * OPAL uses below sysfs files for code update.
  408. * We create these files under /sys/firmware/opal.
  409. *
  410. * image : Interface to load candidate firmware image
  411. * validate_flash : Validate firmware image
  412. * manage_flash : Commit/Reject firmware image
  413. * update_flash : Flash new firmware image
  414. *
  415. */
  416. static const struct bin_attribute image_data_attr = {
  417. .attr = {.name = "image", .mode = 0200},
  418. .size = MAX_IMAGE_SIZE, /* Limit image size */
  419. .write = image_data_write,
  420. };
  421. static struct kobj_attribute validate_attribute =
  422. __ATTR(validate_flash, 0600, validate_show, validate_store);
  423. static struct kobj_attribute manage_attribute =
  424. __ATTR(manage_flash, 0600, manage_show, manage_store);
  425. static struct kobj_attribute update_attribute =
  426. __ATTR(update_flash, 0600, update_show, update_store);
  427. static struct attribute *image_op_attrs[] = {
  428. &validate_attribute.attr,
  429. &manage_attribute.attr,
  430. &update_attribute.attr,
  431. NULL /* need to NULL terminate the list of attributes */
  432. };
  433. static const struct attribute_group image_op_attr_group = {
  434. .attrs = image_op_attrs,
  435. };
  436. void __init opal_flash_update_init(void)
  437. {
  438. int ret;
  439. /* Firmware update is not supported by firmware */
  440. if (!opal_check_token(OPAL_FLASH_VALIDATE))
  441. return;
  442. /* Allocate validate image buffer */
  443. validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
  444. if (!validate_flash_data.buf) {
  445. pr_err("%s : Failed to allocate memory\n", __func__);
  446. return;
  447. }
  448. /* Make sure /sys/firmware/opal directory is created */
  449. if (!opal_kobj) {
  450. pr_warn("FLASH: opal kobject is not available\n");
  451. goto nokobj;
  452. }
  453. /* Create the sysfs files */
  454. ret = sysfs_create_group(opal_kobj, &image_op_attr_group);
  455. if (ret) {
  456. pr_warn("FLASH: Failed to create sysfs files\n");
  457. goto nokobj;
  458. }
  459. ret = sysfs_create_bin_file(opal_kobj, &image_data_attr);
  460. if (ret) {
  461. pr_warn("FLASH: Failed to create sysfs files\n");
  462. goto nosysfs_file;
  463. }
  464. /* Set default status */
  465. validate_flash_data.status = FLASH_NO_OP;
  466. manage_flash_data.status = FLASH_NO_OP;
  467. update_flash_data.status = FLASH_NO_OP;
  468. image_data.status = IMAGE_INVALID;
  469. return;
  470. nosysfs_file:
  471. sysfs_remove_group(opal_kobj, &image_op_attr_group);
  472. nokobj:
  473. kfree(validate_flash_data.buf);
  474. return;
  475. }