]> Pileus Git - ~andy/linux/blob - arch/powerpc/platforms/powernv/opal-flash.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[~andy/linux] / arch / powerpc / platforms / powernv / opal-flash.c
1 /*
2  * PowerNV OPAL Firmware Update Interface
3  *
4  * Copyright 2013 IBM Corp.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #define DEBUG
13
14 #include <linux/kernel.h>
15 #include <linux/reboot.h>
16 #include <linux/init.h>
17 #include <linux/kobject.h>
18 #include <linux/sysfs.h>
19 #include <linux/slab.h>
20 #include <linux/mm.h>
21 #include <linux/vmalloc.h>
22 #include <linux/pagemap.h>
23
24 #include <asm/opal.h>
25
26 /* FLASH status codes */
27 #define FLASH_NO_OP             -1099   /* No operation initiated by user */
28 #define FLASH_NO_AUTH           -9002   /* Not a service authority partition */
29
30 /* Validate image status values */
31 #define VALIDATE_IMG_READY      -1001   /* Image ready for validation */
32 #define VALIDATE_IMG_INCOMPLETE -1002   /* User copied < VALIDATE_BUF_SIZE */
33
34 /* Manage image status values */
35 #define MANAGE_ACTIVE_ERR       -9001   /* Cannot overwrite active img */
36
37 /* Flash image status values */
38 #define FLASH_IMG_READY         0       /* Img ready for flash on reboot */
39 #define FLASH_INVALID_IMG       -1003   /* Flash image shorter than expected */
40 #define FLASH_IMG_NULL_DATA     -1004   /* Bad data in sg list entry */
41 #define FLASH_IMG_BAD_LEN       -1005   /* Bad length in sg list entry */
42
43 /* Manage operation tokens */
44 #define FLASH_REJECT_TMP_SIDE   0       /* Reject temporary fw image */
45 #define FLASH_COMMIT_TMP_SIDE   1       /* Commit temporary fw image */
46
47 /* Update tokens */
48 #define FLASH_UPDATE_CANCEL     0       /* Cancel update request */
49 #define FLASH_UPDATE_INIT       1       /* Initiate update */
50
51 /* Validate image update result tokens */
52 #define VALIDATE_TMP_UPDATE     0     /* T side will be updated */
53 #define VALIDATE_FLASH_AUTH     1     /* Partition does not have authority */
54 #define VALIDATE_INVALID_IMG    2     /* Candidate image is not valid */
55 #define VALIDATE_CUR_UNKNOWN    3     /* Current fixpack level is unknown */
56 /*
57  * Current T side will be committed to P side before being replace with new
58  * image, and the new image is downlevel from current image
59  */
60 #define VALIDATE_TMP_COMMIT_DL  4
61 /*
62  * Current T side will be committed to P side before being replaced with new
63  * image
64  */
65 #define VALIDATE_TMP_COMMIT     5
66 /*
67  * T side will be updated with a downlevel image
68  */
69 #define VALIDATE_TMP_UPDATE_DL  6
70 /*
71  * The candidate image's release date is later than the system's firmware
72  * service entitlement date - service warranty period has expired
73  */
74 #define VALIDATE_OUT_OF_WRNTY   7
75
76 /* Validate buffer size */
77 #define VALIDATE_BUF_SIZE       4096
78
79 /* XXX: Assume candidate image size is <= 1GB */
80 #define MAX_IMAGE_SIZE  0x40000000
81
82 /* Flash sg list version */
83 #define SG_LIST_VERSION (1UL)
84
85 /* Image status */
86 enum {
87         IMAGE_INVALID,
88         IMAGE_LOADING,
89         IMAGE_READY,
90 };
91
92 /* Candidate image data */
93 struct image_data_t {
94         int             status;
95         void            *data;
96         uint32_t        size;
97 };
98
99 /* Candidate image header */
100 struct image_header_t {
101         uint16_t        magic;
102         uint16_t        version;
103         uint32_t        size;
104 };
105
106 struct validate_flash_t {
107         int             status;         /* Return status */
108         void            *buf;           /* Candidate image buffer */
109         uint32_t        buf_size;       /* Image size */
110         uint32_t        result;         /* Update results token */
111 };
112
113 struct manage_flash_t {
114         int status;             /* Return status */
115 };
116
117 struct update_flash_t {
118         int status;             /* Return status */
119 };
120
121 static struct image_header_t    image_header;
122 static struct image_data_t      image_data;
123 static struct validate_flash_t  validate_flash_data;
124 static struct manage_flash_t    manage_flash_data;
125 static struct update_flash_t    update_flash_data;
126
127 static DEFINE_MUTEX(image_data_mutex);
128
129 /*
130  * Validate candidate image
131  */
132 static inline void opal_flash_validate(void)
133 {
134         struct validate_flash_t *args_buf = &validate_flash_data;
135
136         args_buf->status = opal_validate_flash(__pa(args_buf->buf),
137                                                &(args_buf->buf_size),
138                                                &(args_buf->result));
139 }
140
141 /*
142  * Validate output format:
143  *     validate result token
144  *     current image version details
145  *     new image version details
146  */
147 static ssize_t validate_show(struct kobject *kobj,
148                              struct kobj_attribute *attr, char *buf)
149 {
150         struct validate_flash_t *args_buf = &validate_flash_data;
151         int len;
152
153         /* Candidate image is not validated */
154         if (args_buf->status < VALIDATE_TMP_UPDATE) {
155                 len = sprintf(buf, "%d\n", args_buf->status);
156                 goto out;
157         }
158
159         /* Result token */
160         len = sprintf(buf, "%d\n", args_buf->result);
161
162         /* Current and candidate image version details */
163         if ((args_buf->result != VALIDATE_TMP_UPDATE) &&
164             (args_buf->result < VALIDATE_CUR_UNKNOWN))
165                 goto out;
166
167         if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) {
168                 memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len);
169                 len = VALIDATE_BUF_SIZE;
170         } else {
171                 memcpy(buf + len, args_buf->buf, args_buf->buf_size);
172                 len += args_buf->buf_size;
173         }
174 out:
175         /* Set status to default */
176         args_buf->status = FLASH_NO_OP;
177         return len;
178 }
179
180 /*
181  * Validate candidate firmware image
182  *
183  * Note:
184  *   We are only interested in first 4K bytes of the
185  *   candidate image.
186  */
187 static ssize_t validate_store(struct kobject *kobj,
188                               struct kobj_attribute *attr,
189                               const char *buf, size_t count)
190 {
191         struct validate_flash_t *args_buf = &validate_flash_data;
192
193         if (buf[0] != '1')
194                 return -EINVAL;
195
196         mutex_lock(&image_data_mutex);
197
198         if (image_data.status != IMAGE_READY ||
199             image_data.size < VALIDATE_BUF_SIZE) {
200                 args_buf->result = VALIDATE_INVALID_IMG;
201                 args_buf->status = VALIDATE_IMG_INCOMPLETE;
202                 goto out;
203         }
204
205         /* Copy first 4k bytes of candidate image */
206         memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE);
207
208         args_buf->status = VALIDATE_IMG_READY;
209         args_buf->buf_size = VALIDATE_BUF_SIZE;
210
211         /* Validate candidate image */
212         opal_flash_validate();
213
214 out:
215         mutex_unlock(&image_data_mutex);
216         return count;
217 }
218
219 /*
220  * Manage flash routine
221  */
222 static inline void opal_flash_manage(uint8_t op)
223 {
224         struct manage_flash_t *const args_buf = &manage_flash_data;
225
226         args_buf->status = opal_manage_flash(op);
227 }
228
229 /*
230  * Show manage flash status
231  */
232 static ssize_t manage_show(struct kobject *kobj,
233                            struct kobj_attribute *attr, char *buf)
234 {
235         struct manage_flash_t *const args_buf = &manage_flash_data;
236         int rc;
237
238         rc = sprintf(buf, "%d\n", args_buf->status);
239         /* Set status to default*/
240         args_buf->status = FLASH_NO_OP;
241         return rc;
242 }
243
244 /*
245  * Manage operations:
246  *   0 - Reject
247  *   1 - Commit
248  */
249 static ssize_t manage_store(struct kobject *kobj,
250                             struct kobj_attribute *attr,
251                             const char *buf, size_t count)
252 {
253         uint8_t op;
254         switch (buf[0]) {
255         case '0':
256                 op = FLASH_REJECT_TMP_SIDE;
257                 break;
258         case '1':
259                 op = FLASH_COMMIT_TMP_SIDE;
260                 break;
261         default:
262                 return -EINVAL;
263         }
264
265         /* commit/reject temporary image */
266         opal_flash_manage(op);
267         return count;
268 }
269
270 /*
271  * Free sg list
272  */
273 static void free_sg_list(struct opal_sg_list *list)
274 {
275         struct opal_sg_list *sg1;
276         while (list) {
277                 sg1 = list->next;
278                 kfree(list);
279                 list = sg1;
280         }
281         list = NULL;
282 }
283
284 /*
285  * Build candidate image scatter gather list
286  *
287  * list format:
288  *   -----------------------------------
289  *  |  VER (8) | Entry length in bytes  |
290  *   -----------------------------------
291  *  |  Pointer to next entry            |
292  *   -----------------------------------
293  *  |  Address of memory area 1         |
294  *   -----------------------------------
295  *  |  Length of memory area 1          |
296  *   -----------------------------------
297  *  |   .........                       |
298  *   -----------------------------------
299  *  |   .........                       |
300  *   -----------------------------------
301  *  |  Address of memory area N         |
302  *   -----------------------------------
303  *  |  Length of memory area N          |
304  *   -----------------------------------
305  */
306 static struct opal_sg_list *image_data_to_sglist(void)
307 {
308         struct opal_sg_list *sg1, *list = NULL;
309         void *addr;
310         int size;
311
312         addr = image_data.data;
313         size = image_data.size;
314
315         sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
316         if (!sg1)
317                 return NULL;
318
319         list = sg1;
320         sg1->num_entries = 0;
321         while (size > 0) {
322                 /* Translate virtual address to physical address */
323                 sg1->entry[sg1->num_entries].data =
324                         (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
325
326                 if (size > PAGE_SIZE)
327                         sg1->entry[sg1->num_entries].length = PAGE_SIZE;
328                 else
329                         sg1->entry[sg1->num_entries].length = size;
330
331                 sg1->num_entries++;
332                 if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
333                         sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
334                         if (!sg1->next) {
335                                 pr_err("%s : Failed to allocate memory\n",
336                                        __func__);
337                                 goto nomem;
338                         }
339
340                         sg1 = sg1->next;
341                         sg1->num_entries = 0;
342                 }
343                 addr += PAGE_SIZE;
344                 size -= PAGE_SIZE;
345         }
346         return list;
347 nomem:
348         free_sg_list(list);
349         return NULL;
350 }
351
352 /*
353  * OPAL update flash
354  */
355 static int opal_flash_update(int op)
356 {
357         struct opal_sg_list *sg, *list, *next;
358         unsigned long addr;
359         int64_t rc = OPAL_PARAMETER;
360
361         if (op == FLASH_UPDATE_CANCEL) {
362                 pr_alert("FLASH: Image update cancelled\n");
363                 addr = '\0';
364                 goto flash;
365         }
366
367         list = image_data_to_sglist();
368         if (!list)
369                 goto invalid_img;
370
371         /* First entry address */
372         addr = __pa(list);
373
374         /* Translate sg list address to absolute */
375         for (sg = list; sg; sg = next) {
376                 next = sg->next;
377                 /* Don't translate NULL pointer for last entry */
378                 if (sg->next)
379                         sg->next = (struct opal_sg_list *)__pa(sg->next);
380                 else
381                         sg->next = NULL;
382
383                 /*
384                  * Convert num_entries to version/length format
385                  * to satisfy OPAL.
386                  */
387                 sg->num_entries = (SG_LIST_VERSION << 56) |
388                         (sg->num_entries * sizeof(struct opal_sg_entry) + 16);
389         }
390
391         pr_alert("FLASH: Image is %u bytes\n", image_data.size);
392         pr_alert("FLASH: Image update requested\n");
393         pr_alert("FLASH: Image will be updated during system reboot\n");
394         pr_alert("FLASH: This will take several minutes. Do not power off!\n");
395
396 flash:
397         rc = opal_update_flash(addr);
398
399 invalid_img:
400         return rc;
401 }
402
403 /*
404  * Show candidate image status
405  */
406 static ssize_t update_show(struct kobject *kobj,
407                            struct kobj_attribute *attr, char *buf)
408 {
409         struct update_flash_t *const args_buf = &update_flash_data;
410         return sprintf(buf, "%d\n", args_buf->status);
411 }
412
413 /*
414  * Set update image flag
415  *  1 - Flash new image
416  *  0 - Cancel flash request
417  */
418 static ssize_t update_store(struct kobject *kobj,
419                             struct kobj_attribute *attr,
420                             const char *buf, size_t count)
421 {
422         struct update_flash_t *const args_buf = &update_flash_data;
423         int rc = count;
424
425         mutex_lock(&image_data_mutex);
426
427         switch (buf[0]) {
428         case '0':
429                 if (args_buf->status == FLASH_IMG_READY)
430                         opal_flash_update(FLASH_UPDATE_CANCEL);
431                 args_buf->status = FLASH_NO_OP;
432                 break;
433         case '1':
434                 /* Image is loaded? */
435                 if (image_data.status == IMAGE_READY)
436                         args_buf->status =
437                                 opal_flash_update(FLASH_UPDATE_INIT);
438                 else
439                         args_buf->status = FLASH_INVALID_IMG;
440                 break;
441         default:
442                 rc = -EINVAL;
443         }
444
445         mutex_unlock(&image_data_mutex);
446         return rc;
447 }
448
449 /*
450  * Free image buffer
451  */
452 static void free_image_buf(void)
453 {
454         void *addr;
455         int size;
456
457         addr = image_data.data;
458         size = PAGE_ALIGN(image_data.size);
459         while (size > 0) {
460                 ClearPageReserved(vmalloc_to_page(addr));
461                 addr += PAGE_SIZE;
462                 size -= PAGE_SIZE;
463         }
464         vfree(image_data.data);
465         image_data.data = NULL;
466         image_data.status = IMAGE_INVALID;
467 }
468
469 /*
470  * Allocate image buffer.
471  */
472 static int alloc_image_buf(char *buffer, size_t count)
473 {
474         void *addr;
475         int size;
476
477         if (count < sizeof(struct image_header_t)) {
478                 pr_warn("FLASH: Invalid candidate image\n");
479                 return -EINVAL;
480         }
481
482         memcpy(&image_header, (void *)buffer, sizeof(struct image_header_t));
483         image_data.size = be32_to_cpu(image_header.size);
484         pr_debug("FLASH: Candidate image size = %u\n", image_data.size);
485
486         if (image_data.size > MAX_IMAGE_SIZE) {
487                 pr_warn("FLASH: Too large image\n");
488                 return -EINVAL;
489         }
490         if (image_data.size < VALIDATE_BUF_SIZE) {
491                 pr_warn("FLASH: Image is shorter than expected\n");
492                 return -EINVAL;
493         }
494
495         image_data.data = vzalloc(PAGE_ALIGN(image_data.size));
496         if (!image_data.data) {
497                 pr_err("%s : Failed to allocate memory\n", __func__);
498                 return -ENOMEM;
499         }
500
501         /* Pin memory */
502         addr = image_data.data;
503         size = PAGE_ALIGN(image_data.size);
504         while (size > 0) {
505                 SetPageReserved(vmalloc_to_page(addr));
506                 addr += PAGE_SIZE;
507                 size -= PAGE_SIZE;
508         }
509
510         image_data.status = IMAGE_LOADING;
511         return 0;
512 }
513
514 /*
515  * Copy candidate image
516  *
517  * Parse candidate image header to get total image size
518  * and pre-allocate required memory.
519  */
520 static ssize_t image_data_write(struct file *filp, struct kobject *kobj,
521                                 struct bin_attribute *bin_attr,
522                                 char *buffer, loff_t pos, size_t count)
523 {
524         int rc;
525
526         mutex_lock(&image_data_mutex);
527
528         /* New image ? */
529         if (pos == 0) {
530                 /* Free memory, if already allocated */
531                 if (image_data.data)
532                         free_image_buf();
533
534                 /* Cancel outstanding image update request */
535                 if (update_flash_data.status == FLASH_IMG_READY)
536                         opal_flash_update(FLASH_UPDATE_CANCEL);
537
538                 /* Allocate memory */
539                 rc = alloc_image_buf(buffer, count);
540                 if (rc)
541                         goto out;
542         }
543
544         if (image_data.status != IMAGE_LOADING) {
545                 rc = -ENOMEM;
546                 goto out;
547         }
548
549         if ((pos + count) > image_data.size) {
550                 rc = -EINVAL;
551                 goto out;
552         }
553
554         memcpy(image_data.data + pos, (void *)buffer, count);
555         rc = count;
556
557         /* Set image status */
558         if ((pos + count) == image_data.size) {
559                 pr_debug("FLASH: Candidate image loaded....\n");
560                 image_data.status = IMAGE_READY;
561         }
562
563 out:
564         mutex_unlock(&image_data_mutex);
565         return rc;
566 }
567
568 /*
569  * sysfs interface :
570  *  OPAL uses below sysfs files for code update.
571  *  We create these files under /sys/firmware/opal.
572  *
573  *   image              : Interface to load candidate firmware image
574  *   validate_flash     : Validate firmware image
575  *   manage_flash       : Commit/Reject firmware image
576  *   update_flash       : Flash new firmware image
577  *
578  */
579 static struct bin_attribute image_data_attr = {
580         .attr = {.name = "image", .mode = 0200},
581         .size = MAX_IMAGE_SIZE, /* Limit image size */
582         .write = image_data_write,
583 };
584
585 static struct kobj_attribute validate_attribute =
586         __ATTR(validate_flash, 0600, validate_show, validate_store);
587
588 static struct kobj_attribute manage_attribute =
589         __ATTR(manage_flash, 0600, manage_show, manage_store);
590
591 static struct kobj_attribute update_attribute =
592         __ATTR(update_flash, 0600, update_show, update_store);
593
594 static struct attribute *image_op_attrs[] = {
595         &validate_attribute.attr,
596         &manage_attribute.attr,
597         &update_attribute.attr,
598         NULL    /* need to NULL terminate the list of attributes */
599 };
600
601 static struct attribute_group image_op_attr_group = {
602         .attrs = image_op_attrs,
603 };
604
605 void __init opal_flash_init(void)
606 {
607         int ret;
608
609         /* Allocate validate image buffer */
610         validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
611         if (!validate_flash_data.buf) {
612                 pr_err("%s : Failed to allocate memory\n", __func__);
613                 return;
614         }
615
616         /* Make sure /sys/firmware/opal directory is created */
617         if (!opal_kobj) {
618                 pr_warn("FLASH: opal kobject is not available\n");
619                 goto nokobj;
620         }
621
622         /* Create the sysfs files */
623         ret = sysfs_create_group(opal_kobj, &image_op_attr_group);
624         if (ret) {
625                 pr_warn("FLASH: Failed to create sysfs files\n");
626                 goto nokobj;
627         }
628
629         ret = sysfs_create_bin_file(opal_kobj, &image_data_attr);
630         if (ret) {
631                 pr_warn("FLASH: Failed to create sysfs files\n");
632                 goto nosysfs_file;
633         }
634
635         /* Set default status */
636         validate_flash_data.status = FLASH_NO_OP;
637         manage_flash_data.status = FLASH_NO_OP;
638         update_flash_data.status = FLASH_NO_OP;
639         image_data.status = IMAGE_INVALID;
640         return;
641
642 nosysfs_file:
643         sysfs_remove_group(opal_kobj, &image_op_attr_group);
644
645 nokobj:
646         kfree(validate_flash_data.buf);
647         return;
648 }