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