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