/*
 * PowerNV OPAL Firmware Update Interface
 *
 * Copyright 2013 IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#define DEBUG

#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>

#include <asm/opal.h>

/* FLASH status codes */
#define FLASH_NO_OP		-1099	/* No operation initiated by user */
#define FLASH_NO_AUTH		-9002	/* Not a service authority partition */

/* Validate image status values */
#define VALIDATE_IMG_READY	-1001	/* Image ready for validation */
#define VALIDATE_IMG_INCOMPLETE	-1002	/* User copied < VALIDATE_BUF_SIZE */

/* Manage image status values */
#define MANAGE_ACTIVE_ERR	-9001	/* Cannot overwrite active img */

/* Flash image status values */
#define FLASH_IMG_READY		0	/* Img ready for flash on reboot */
#define FLASH_INVALID_IMG	-1003	/* Flash image shorter than expected */
#define FLASH_IMG_NULL_DATA	-1004	/* Bad data in sg list entry */
#define FLASH_IMG_BAD_LEN	-1005	/* Bad length in sg list entry */

/* Manage operation tokens */
#define FLASH_REJECT_TMP_SIDE	0	/* Reject temporary fw image */
#define FLASH_COMMIT_TMP_SIDE	1	/* Commit temporary fw image */

/* Update tokens */
#define FLASH_UPDATE_CANCEL	0	/* Cancel update request */
#define FLASH_UPDATE_INIT	1	/* Initiate update */

/* Validate image update result tokens */
#define VALIDATE_TMP_UPDATE	0     /* T side will be updated */
#define VALIDATE_FLASH_AUTH	1     /* Partition does not have authority */
#define VALIDATE_INVALID_IMG	2     /* Candidate image is not valid */
#define VALIDATE_CUR_UNKNOWN	3     /* Current fixpack level is unknown */
/*
 * Current T side will be committed to P side before being replace with new
 * image, and the new image is downlevel from current image
 */
#define VALIDATE_TMP_COMMIT_DL	4
/*
 * Current T side will be committed to P side before being replaced with new
 * image
 */
#define VALIDATE_TMP_COMMIT	5
/*
 * T side will be updated with a downlevel image
 */
#define VALIDATE_TMP_UPDATE_DL	6
/*
 * The candidate image's release date is later than the system's firmware
 * service entitlement date - service warranty period has expired
 */
#define VALIDATE_OUT_OF_WRNTY	7

/* Validate buffer size */
#define VALIDATE_BUF_SIZE	4096

/* XXX: Assume candidate image size is <= 1GB */
#define MAX_IMAGE_SIZE	0x40000000

/* Flash sg list version */
#define SG_LIST_VERSION (1UL)

/* Image status */
enum {
	IMAGE_INVALID,
	IMAGE_LOADING,
	IMAGE_READY,
};

/* Candidate image data */
struct image_data_t {
	int		status;
	void		*data;
	uint32_t	size;
};

/* Candidate image header */
struct image_header_t {
	uint16_t	magic;
	uint16_t	version;
	uint32_t	size;
};

struct validate_flash_t {
	int		status;		/* Return status */
	void		*buf;		/* Candidate image buffer */
	uint32_t	buf_size;	/* Image size */
	uint32_t	result;		/* Update results token */
};

struct manage_flash_t {
	int status;		/* Return status */
};

struct update_flash_t {
	int status;		/* Return status */
};

static struct image_header_t	image_header;
static struct image_data_t	image_data;
static struct validate_flash_t	validate_flash_data;
static struct manage_flash_t	manage_flash_data;
static struct update_flash_t	update_flash_data;

static DEFINE_MUTEX(image_data_mutex);

/*
 * Validate candidate image
 */
static inline void opal_flash_validate(void)
{
	struct validate_flash_t *args_buf = &validate_flash_data;

	args_buf->status = opal_validate_flash(__pa(args_buf->buf),
					       &(args_buf->buf_size),
					       &(args_buf->result));
}

/*
 * Validate output format:
 *     validate result token
 *     current image version details
 *     new image version details
 */
static ssize_t validate_show(struct kobject *kobj,
			     struct kobj_attribute *attr, char *buf)
{
	struct validate_flash_t *args_buf = &validate_flash_data;
	int len;

	/* Candidate image is not validated */
	if (args_buf->status < VALIDATE_TMP_UPDATE) {
		len = sprintf(buf, "%d\n", args_buf->status);
		goto out;
	}

	/* Result token */
	len = sprintf(buf, "%d\n", args_buf->result);

	/* Current and candidate image version details */
	if ((args_buf->result != VALIDATE_TMP_UPDATE) &&
	    (args_buf->result < VALIDATE_CUR_UNKNOWN))
		goto out;

	if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) {
		memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len);
		len = VALIDATE_BUF_SIZE;
	} else {
		memcpy(buf + len, args_buf->buf, args_buf->buf_size);
		len += args_buf->buf_size;
	}
out:
	/* Set status to default */
	args_buf->status = FLASH_NO_OP;
	return len;
}

/*
 * Validate candidate firmware image
 *
 * Note:
 *   We are only interested in first 4K bytes of the
 *   candidate image.
 */
static ssize_t validate_store(struct kobject *kobj,
			      struct kobj_attribute *attr,
			      const char *buf, size_t count)
{
	struct validate_flash_t *args_buf = &validate_flash_data;

	if (buf[0] != '1')
		return -EINVAL;

	mutex_lock(&image_data_mutex);

	if (image_data.status != IMAGE_READY ||
	    image_data.size < VALIDATE_BUF_SIZE) {
		args_buf->result = VALIDATE_INVALID_IMG;
		args_buf->status = VALIDATE_IMG_INCOMPLETE;
		goto out;
	}

	/* Copy first 4k bytes of candidate image */
	memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE);

	args_buf->status = VALIDATE_IMG_READY;
	args_buf->buf_size = VALIDATE_BUF_SIZE;

	/* Validate candidate image */
	opal_flash_validate();

out:
	mutex_unlock(&image_data_mutex);
	return count;
}

/*
 * Manage flash routine
 */
static inline void opal_flash_manage(uint8_t op)
{
	struct manage_flash_t *const args_buf = &manage_flash_data;

	args_buf->status = opal_manage_flash(op);
}

/*
 * Show manage flash status
 */
static ssize_t manage_show(struct kobject *kobj,
			   struct kobj_attribute *attr, char *buf)
{
	struct manage_flash_t *const args_buf = &manage_flash_data;
	int rc;

	rc = sprintf(buf, "%d\n", args_buf->status);
	/* Set status to default*/
	args_buf->status = FLASH_NO_OP;
	return rc;
}

/*
 * Manage operations:
 *   0 - Reject
 *   1 - Commit
 */
static ssize_t manage_store(struct kobject *kobj,
			    struct kobj_attribute *attr,
			    const char *buf, size_t count)
{
	uint8_t op;
	switch (buf[0]) {
	case '0':
		op = FLASH_REJECT_TMP_SIDE;
		break;
	case '1':
		op = FLASH_COMMIT_TMP_SIDE;
		break;
	default:
		return -EINVAL;
	}

	/* commit/reject temporary image */
	opal_flash_manage(op);
	return count;
}

/*
 * Free sg list
 */
static void free_sg_list(struct opal_sg_list *list)
{
	struct opal_sg_list *sg1;
	while (list) {
		sg1 = list->next;
		kfree(list);
		list = sg1;
	}
	list = NULL;
}

/*
 * Build candidate image scatter gather list
 *
 * list format:
 *   -----------------------------------
 *  |  VER (8) | Entry length in bytes  |
 *   -----------------------------------
 *  |  Pointer to next entry            |
 *   -----------------------------------
 *  |  Address of memory area 1         |
 *   -----------------------------------
 *  |  Length of memory area 1          |
 *   -----------------------------------
 *  |   .........                       |
 *   -----------------------------------
 *  |   .........                       |
 *   -----------------------------------
 *  |  Address of memory area N         |
 *   -----------------------------------
 *  |  Length of memory area N          |
 *   -----------------------------------
 */
static struct opal_sg_list *image_data_to_sglist(void)
{
	struct opal_sg_list *sg1, *list = NULL;
	void *addr;
	int size;

	addr = image_data.data;
	size = image_data.size;

	sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
	if (!sg1)
		return NULL;

	list = sg1;
	sg1->num_entries = 0;
	while (size > 0) {
		/* Translate virtual address to physical address */
		sg1->entry[sg1->num_entries].data =
			(void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);

		if (size > PAGE_SIZE)
			sg1->entry[sg1->num_entries].length = PAGE_SIZE;
		else
			sg1->entry[sg1->num_entries].length = size;

		sg1->num_entries++;
		if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
			sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
			if (!sg1->next) {
				pr_err("%s : Failed to allocate memory\n",
				       __func__);
				goto nomem;
			}

			sg1 = sg1->next;
			sg1->num_entries = 0;
		}
		addr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	return list;
nomem:
	free_sg_list(list);
	return NULL;
}

/*
 * OPAL update flash
 */
static int opal_flash_update(int op)
{
	struct opal_sg_list *sg, *list, *next;
	unsigned long addr;
	int64_t rc = OPAL_PARAMETER;

	if (op == FLASH_UPDATE_CANCEL) {
		pr_alert("FLASH: Image update cancelled\n");
		addr = '\0';
		goto flash;
	}

	list = image_data_to_sglist();
	if (!list)
		goto invalid_img;

	/* First entry address */
	addr = __pa(list);

	/* Translate sg list address to absolute */
	for (sg = list; sg; sg = next) {
		next = sg->next;
		/* Don't translate NULL pointer for last entry */
		if (sg->next)
			sg->next = (struct opal_sg_list *)__pa(sg->next);
		else
			sg->next = NULL;

		/*
		 * Convert num_entries to version/length format
		 * to satisfy OPAL.
		 */
		sg->num_entries = (SG_LIST_VERSION << 56) |
			(sg->num_entries * sizeof(struct opal_sg_entry) + 16);
	}

	pr_alert("FLASH: Image is %u bytes\n", image_data.size);
	pr_alert("FLASH: Image update requested\n");
	pr_alert("FLASH: Image will be updated during system reboot\n");
	pr_alert("FLASH: This will take several minutes. Do not power off!\n");

flash:
	rc = opal_update_flash(addr);

invalid_img:
	return rc;
}

/*
 * Show candidate image status
 */
static ssize_t update_show(struct kobject *kobj,
			   struct kobj_attribute *attr, char *buf)
{
	struct update_flash_t *const args_buf = &update_flash_data;
	return sprintf(buf, "%d\n", args_buf->status);
}

/*
 * Set update image flag
 *  1 - Flash new image
 *  0 - Cancel flash request
 */
static ssize_t update_store(struct kobject *kobj,
			    struct kobj_attribute *attr,
			    const char *buf, size_t count)
{
	struct update_flash_t *const args_buf = &update_flash_data;
	int rc = count;

	mutex_lock(&image_data_mutex);

	switch (buf[0]) {
	case '0':
		if (args_buf->status == FLASH_IMG_READY)
			opal_flash_update(FLASH_UPDATE_CANCEL);
		args_buf->status = FLASH_NO_OP;
		break;
	case '1':
		/* Image is loaded? */
		if (image_data.status == IMAGE_READY)
			args_buf->status =
				opal_flash_update(FLASH_UPDATE_INIT);
		else
			args_buf->status = FLASH_INVALID_IMG;
		break;
	default:
		rc = -EINVAL;
	}

	mutex_unlock(&image_data_mutex);
	return rc;
}

/*
 * Free image buffer
 */
static void free_image_buf(void)
{
	void *addr;
	int size;

	addr = image_data.data;
	size = PAGE_ALIGN(image_data.size);
	while (size > 0) {
		ClearPageReserved(vmalloc_to_page(addr));
		addr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	vfree(image_data.data);
	image_data.data = NULL;
	image_data.status = IMAGE_INVALID;
}

/*
 * Allocate image buffer.
 */
static int alloc_image_buf(char *buffer, size_t count)
{
	void *addr;
	int size;

	if (count < sizeof(struct image_header_t)) {
		pr_warn("FLASH: Invalid candidate image\n");
		return -EINVAL;
	}

	memcpy(&image_header, (void *)buffer, sizeof(struct image_header_t));
	image_data.size = be32_to_cpu(image_header.size);
	pr_debug("FLASH: Candidate image size = %u\n", image_data.size);

	if (image_data.size > MAX_IMAGE_SIZE) {
		pr_warn("FLASH: Too large image\n");
		return -EINVAL;
	}
	if (image_data.size < VALIDATE_BUF_SIZE) {
		pr_warn("FLASH: Image is shorter than expected\n");
		return -EINVAL;
	}

	image_data.data = vzalloc(PAGE_ALIGN(image_data.size));
	if (!image_data.data) {
		pr_err("%s : Failed to allocate memory\n", __func__);
		return -ENOMEM;
	}

	/* Pin memory */
	addr = image_data.data;
	size = PAGE_ALIGN(image_data.size);
	while (size > 0) {
		SetPageReserved(vmalloc_to_page(addr));
		addr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}

	image_data.status = IMAGE_LOADING;
	return 0;
}

/*
 * Copy candidate image
 *
 * Parse candidate image header to get total image size
 * and pre-allocate required memory.
 */
static ssize_t image_data_write(struct file *filp, struct kobject *kobj,
				struct bin_attribute *bin_attr,
				char *buffer, loff_t pos, size_t count)
{
	int rc;

	mutex_lock(&image_data_mutex);

	/* New image ? */
	if (pos == 0) {
		/* Free memory, if already allocated */
		if (image_data.data)
			free_image_buf();

		/* Cancel outstanding image update request */
		if (update_flash_data.status == FLASH_IMG_READY)
			opal_flash_update(FLASH_UPDATE_CANCEL);

		/* Allocate memory */
		rc = alloc_image_buf(buffer, count);
		if (rc)
			goto out;
	}

	if (image_data.status != IMAGE_LOADING) {
		rc = -ENOMEM;
		goto out;
	}

	if ((pos + count) > image_data.size) {
		rc = -EINVAL;
		goto out;
	}

	memcpy(image_data.data + pos, (void *)buffer, count);
	rc = count;

	/* Set image status */
	if ((pos + count) == image_data.size) {
		pr_debug("FLASH: Candidate image loaded....\n");
		image_data.status = IMAGE_READY;
	}

out:
	mutex_unlock(&image_data_mutex);
	return rc;
}

/*
 * sysfs interface :
 *  OPAL uses below sysfs files for code update.
 *  We create these files under /sys/firmware/opal.
 *
 *   image		: Interface to load candidate firmware image
 *   validate_flash	: Validate firmware image
 *   manage_flash	: Commit/Reject firmware image
 *   update_flash	: Flash new firmware image
 *
 */
static struct bin_attribute image_data_attr = {
	.attr = {.name = "image", .mode = 0200},
	.size = MAX_IMAGE_SIZE,	/* Limit image size */
	.write = image_data_write,
};

static struct kobj_attribute validate_attribute =
	__ATTR(validate_flash, 0600, validate_show, validate_store);

static struct kobj_attribute manage_attribute =
	__ATTR(manage_flash, 0600, manage_show, manage_store);

static struct kobj_attribute update_attribute =
	__ATTR(update_flash, 0600, update_show, update_store);

static struct attribute *image_op_attrs[] = {
	&validate_attribute.attr,
	&manage_attribute.attr,
	&update_attribute.attr,
	NULL	/* need to NULL terminate the list of attributes */
};

static struct attribute_group image_op_attr_group = {
	.attrs = image_op_attrs,
};

void __init opal_flash_init(void)
{
	int ret;

	/* Allocate validate image buffer */
	validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
	if (!validate_flash_data.buf) {
		pr_err("%s : Failed to allocate memory\n", __func__);
		return;
	}

	/* Make sure /sys/firmware/opal directory is created */
	if (!opal_kobj) {
		pr_warn("FLASH: opal kobject is not available\n");
		goto nokobj;
	}

	/* Create the sysfs files */
	ret = sysfs_create_group(opal_kobj, &image_op_attr_group);
	if (ret) {
		pr_warn("FLASH: Failed to create sysfs files\n");
		goto nokobj;
	}

	ret = sysfs_create_bin_file(opal_kobj, &image_data_attr);
	if (ret) {
		pr_warn("FLASH: Failed to create sysfs files\n");
		goto nosysfs_file;
	}

	/* Set default status */
	validate_flash_data.status = FLASH_NO_OP;
	manage_flash_data.status = FLASH_NO_OP;
	update_flash_data.status = FLASH_NO_OP;
	image_data.status = IMAGE_INVALID;
	return;

nosysfs_file:
	sysfs_remove_group(opal_kobj, &image_op_attr_group);

nokobj:
	kfree(validate_flash_data.buf);
	return;
}
