/*
 * 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 <linux/delay.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

/* 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;

/* Initialize update_flash_data status to No Operation */
static struct update_flash_t	update_flash_data = {
	.status = FLASH_NO_OP,
};

static DEFINE_MUTEX(image_data_mutex);

/*
 * Validate candidate image
 */
static inline void opal_flash_validate(void)
{
	long ret;
	void *buf = validate_flash_data.buf;
	__be32 size = cpu_to_be32(validate_flash_data.buf_size);
	__be32 result;

	ret = opal_validate_flash(__pa(buf), &size, &result);

	validate_flash_data.status = ret;
	validate_flash_data.buf_size = be32_to_cpu(size);
	validate_flash_data.result = be32_to_cpu(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;
}

/*
 * OPAL update flash
 */
static int opal_flash_update(int op)
{
	struct opal_sg_list *list;
	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 = opal_vmalloc_to_sg_list(image_data.data, image_data.size);
	if (!list)
		goto invalid_img;

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

flash:
	rc = opal_update_flash(addr);

invalid_img:
	return rc;
}

/* Return CPUs to OPAL before starting FW update */
static void flash_return_cpu(void *info)
{
	int cpu = smp_processor_id();

	if (!cpu_online(cpu))
		return;

	/* Disable IRQ */
	hard_irq_disable();

	/* Return the CPU to OPAL */
	opal_return_cpu();
}

/* This gets called just before system reboots */
void opal_flash_term_callback(void)
{
	struct cpumask mask;

	if (update_flash_data.status != FLASH_IMG_READY)
		return;

	pr_alert("FLASH: Flashing new firmware\n");
	pr_alert("FLASH: Image is %u bytes\n", image_data.size);
	pr_alert("FLASH: Performing flash and reboot/shutdown\n");
	pr_alert("FLASH: This will take several minutes. Do not power off!\n");

	/* Small delay to help getting the above message out */
	msleep(500);

	/* Return secondary CPUs to firmware */
	cpumask_copy(&mask, cpu_online_mask);
	cpumask_clear_cpu(smp_processor_id(), &mask);
	if (!cpumask_empty(&mask))
		smp_call_function_many(&mask,
				       flash_return_cpu, NULL, false);
	/* Hard disable interrupts */
	hard_irq_disable();
}

/*
 * 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 const 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_update_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;
}
