// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2017-2018 IBM Corp. */

#define pr_fmt(fmt) "MBOX-FLASH: " fmt

#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <skiboot.h>
#include <inttypes.h>
#include <timebase.h>
#include <timer.h>
#include <libflash/libflash.h>
#include <libflash/mbox-flash.h>
#include <lpc.h>
#include <lpc-mbox.h>

#include <ccan/container_of/container_of.h>

#ifndef __SKIBOOT__
#ifndef __TEST__
#error "This libflash backend must be compiled with skiboot"
#endif
#endif

/* Same technique as BUILD_BUG_ON from linux */
#define CHECK_HANDLER_SIZE(handlers) ((void)sizeof(char[1 - 2*!!(ARRAY_SIZE(handlers) != (MBOX_COMMAND_COUNT + 1))]))

#define MBOX_DEFAULT_TIMEOUT 3 /* seconds */

#define MSG_CREATE(init_command) { .command = init_command }

struct mbox_flash_data;
typedef void (mbox_handler)(struct mbox_flash_data *, struct bmc_mbox_msg *);

struct lpc_window {
	uint32_t lpc_addr; /* Offset into LPC space */
	uint32_t cur_pos;  /* Current position of the window in the flash */
	uint32_t size;     /* Size of the window into the flash */
	bool open;
};

struct mbox_flash_data {
	int version;
	uint16_t timeout;
	uint32_t shift;
	struct lpc_window read;
	struct lpc_window write;
	struct blocklevel_device bl;
	uint32_t total_size;
	uint32_t erase_granule;
	int rc;
	bool reboot;
	bool pause;
	bool busy;
	bool ack;
	mbox_handler **handlers;
};

static mbox_handler mbox_flash_do_nop;
static mbox_handler mbox_flash_do_illegal;

/* Version 1, 2, 3 compatible */
static mbox_handler mbox_flash_do_get_mbox_info;

/* Version 2 and 3 compatible */
static mbox_handler mbox_flash_do_get_flash_info;
static mbox_handler mbox_flash_do_get_flash_info_v1;

/* Version 2 and 3 compatible */
static mbox_handler mbox_flash_do_create_read_window;
static mbox_handler mbox_flash_do_create_read_window_v1;

/* Version 2 and 3 compatible */
static mbox_handler mbox_flash_do_create_write_window;
static mbox_handler mbox_flash_do_create_write_window_v1;

/* Version 1, 2, 3 compatible */
static mbox_handler mbox_flash_do_close_window;

/* Plus one, commands start at 1 */
static mbox_handler *handlers_v3[] = {
	NULL,
	&mbox_flash_do_nop,
	&mbox_flash_do_get_mbox_info,
	&mbox_flash_do_get_flash_info,
	&mbox_flash_do_create_read_window,
	&mbox_flash_do_close_window,
	&mbox_flash_do_create_write_window,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop
};

/* Plus one, commands start at 1 */
static mbox_handler *handlers_v2[] = {
	NULL,
	&mbox_flash_do_nop,
	&mbox_flash_do_get_mbox_info,
	&mbox_flash_do_get_flash_info,
	&mbox_flash_do_create_read_window,
	&mbox_flash_do_close_window,
	&mbox_flash_do_create_write_window,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_illegal,
	&mbox_flash_do_illegal
};

/*
 * Plus one, commands start at 1.
 * V2 adds a command so there should never be a response for the last
 * command.
 * Ensure we print an error message with mbox_flash_do_illegal().
 */
static mbox_handler *handlers_v1[] = {
	NULL,
	&mbox_flash_do_nop,
	&mbox_flash_do_get_mbox_info,
	&mbox_flash_do_get_flash_info_v1,
	&mbox_flash_do_create_read_window_v1,
	&mbox_flash_do_close_window,
	&mbox_flash_do_create_write_window_v1,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_nop,
	&mbox_flash_do_illegal,
	&mbox_flash_do_illegal,
	&mbox_flash_do_illegal
};


static void mbox_flash_callback(struct bmc_mbox_msg *msg, void *priv);
static void mbox_flash_attn(uint8_t attn, void *priv);

static int protocol_init(struct mbox_flash_data *mbox_flash, uint8_t shift);

static int lpc_window_read(struct mbox_flash_data *mbox_flash, uint32_t pos,
			   void *buf, uint32_t len)
{
	uint32_t off = mbox_flash->read.lpc_addr + (pos - mbox_flash->read.cur_pos);

	prlog(PR_TRACE, "Reading at 0x%08x for 0x%08x offset: 0x%08x\n",
			pos, len, off);

	return lpc_fw_read(off, buf, len);
}

static int lpc_window_write(struct mbox_flash_data *mbox_flash, uint32_t pos,
			    const void *buf, uint32_t len)
{
	uint32_t off = mbox_flash->write.lpc_addr + (pos - mbox_flash->write.cur_pos);

	return lpc_fw_write(off, buf, len);
}

static uint64_t mbox_flash_mask(struct mbox_flash_data *mbox_flash)
{
	return (1ULL << mbox_flash->shift) - 1;
}

__unused static uint8_t msg_get_u8(struct bmc_mbox_msg *msg, int i)
{
	return msg->args[i];
}

static void msg_put_u8(struct bmc_mbox_msg *msg, int i, uint8_t val)
{
	msg->args[i] = val;
}

static uint16_t msg_get_u16(struct bmc_mbox_msg *msg, int i)
{
	return le16_to_cpu(*(__le16 *)(&msg->args[i]));
}

static void msg_put_u16(struct bmc_mbox_msg *msg, int i, uint16_t val)
{
	__le16 tmp = cpu_to_le16(val);
	memcpy(&msg->args[i], &tmp, sizeof(val));
}

static uint32_t msg_get_u32(struct bmc_mbox_msg *msg, int i)
{
	return le32_to_cpu(*(__le32 *)(&msg->args[i]));
}

static void msg_put_u32(struct bmc_mbox_msg *msg, int i, uint32_t val)
{
	__le32 tmp = cpu_to_le32(val);
	memcpy(&msg->args[i], &tmp, sizeof(val));
}

static uint32_t blocks_to_bytes(struct mbox_flash_data *mbox_flash, uint16_t blocks)
{
	return blocks << mbox_flash->shift;
}

static uint16_t bytes_to_blocks(struct mbox_flash_data *mbox_flash,
				uint32_t bytes)
{
	return bytes >> mbox_flash->shift;
}

/*
 * The BMC may send is an out of band message to say that it doesn't
 * own the flash anymore.
 * It guarantees we can still access our (open) windows but it does
 * not guarantee their contents until it clears the bit without
 * sending us a corresponding bit to say that the windows are bad
 * first.
 * Since this is all things that will happen in the future, we should
 * not perform any calls speculatively as its almost impossible to
 * rewind.
 */
static bool is_paused(struct mbox_flash_data *mbox_flash)
{
	return mbox_flash->pause;
}

/*
 * After a read or a write it is wise to check that the window we just
 * read/write to/from is still valid otherwise it is possible some of
 * the data didn't make it.
 * This check is an optimisation as we'll close all our windows on any
 * notification from the BMC that the windows are bad. See the above
 * comment about is_paused().
 * A foolproof (but much closer) method of validating reads/writes
 * would be to attempt to close the window, if that fails then we can
 * be sure that the read/write was no good.
 */
static bool is_valid(struct mbox_flash_data *mbox_flash, struct lpc_window *win)
{
	return !is_paused(mbox_flash) && win->open;
}

/*
 * Check if we've received a BMC reboot notification.
 * The strategy is to check on entry to mbox-flash and return a
 * failure accordingly. Races will be handled by the fact that the BMC
 * won't respond so timeouts will occur. As an added precaution
 * msg_send() checks right before sending a message (to make the race
 * as small as possible to avoid needless timeouts).
 */
static bool is_reboot(struct mbox_flash_data *mbox_flash)
{
	return mbox_flash->reboot;
}

static int msg_send(struct mbox_flash_data *mbox_flash, struct bmc_mbox_msg *msg,
		unsigned int timeout_sec)
{
	if (is_reboot(mbox_flash))
		return FLASH_ERR_AGAIN;
	mbox_flash->busy = true;
	mbox_flash->rc = 0;
	return bmc_mbox_enqueue(msg, timeout_sec);
}

static int wait_for_bmc(struct mbox_flash_data *mbox_flash, unsigned int timeout_sec)
{
	unsigned long last = 1, start = tb_to_secs(mftb());
	prlog(PR_TRACE, "Waiting for BMC\n");
	while (mbox_flash->busy && timeout_sec > last) {
		long now = tb_to_secs(mftb());
		if (now - start > last) {
			if (last < timeout_sec / 2)
				prlog(PR_TRACE, "Been waiting for the BMC for %lu secs\n", last);
			else
				prlog(PR_ERR, "BMC NOT RESPONDING %lu second wait\n", last);
			last++;
		}
		/*
		 * Both functions are important.
		 * Well time_wait_ms() relaxes the spin... so... its nice
		 */
		check_timers(false);
		if (mbox_flash->busy)
			time_wait_ms(MBOX_DEFAULT_POLL_MS);
		asm volatile ("" ::: "memory");
	}

	if (mbox_flash->busy) {
		prlog(PR_ERR, "Timeout waiting for BMC\n");
		mbox_flash->busy = false;
		return MBOX_R_TIMEOUT;
	}

	return mbox_flash->rc;
}

static int mbox_flash_ack(struct mbox_flash_data *mbox_flash, uint8_t reg)
{
	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_BMC_EVENT_ACK);
	int rc;

	msg_put_u8(&msg, 0, reg);

	/* Clear this first so msg_send() doesn't freak out */
	mbox_flash->reboot = false;

	/*
	 * Use a lower timeout - there is strong evidence to suggest the
	 * BMC won't respond, don't waste time spinning here just have the
	 * high levels retry when the BMC might be back
	 */
	rc = msg_send(mbox_flash, &msg, 3);

	/* Still need to deal with it, we've only acked it now. */
	mbox_flash->reboot = true;

	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
		return rc;
	}

	/*
	 * Use a lower timeout - there is strong evidence to suggest the
	 * BMC won't respond, don't waste time spinning here just have the
	 * high levels retry when the BMC might be back
	 */
	rc = wait_for_bmc(mbox_flash, 3);
	if (rc)
		prlog(PR_ERR, "Error waiting for BMC\n");

	return rc;
}

static int do_acks(struct mbox_flash_data *mbox_flash)
{
	int rc;

	if (!mbox_flash->ack)
		return 0; /* Nothing to do */

	rc = mbox_flash_ack(mbox_flash, bmc_mbox_get_attn_reg() & MBOX_ATTN_ACK_MASK);
	if (!rc)
		mbox_flash->ack = false;

	return rc;
}

static void mbox_flash_do_nop(struct mbox_flash_data *mbox_flash __unused,
		struct bmc_mbox_msg *msg __unused)
{
}

static void mbox_flash_do_illegal(struct mbox_flash_data *mbox_flash __unused,
		struct bmc_mbox_msg *msg __unused)
{
	prlog(PR_CRIT, "Got response to unknown message type\n");
}

/* Version 1, 2 and 3 compatible */
static void mbox_flash_do_get_mbox_info(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg)
{

	mbox_flash->version = msg_get_u8(msg, 0);
	switch (mbox_flash->version) {
		case 1:
			/* Not all version 1 daemons set argument 5 correctly */
			mbox_flash->shift = 12; /* Protocol hardcodes to 4K anyway */
			mbox_flash->read.size = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 1));
			mbox_flash->write.size = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 3));
			break;
		case 3:
		case 2:
			mbox_flash->shift = msg_get_u8(msg, 5);
			mbox_flash->timeout = msg_get_u16(msg, 6);
			if (mbox_flash->timeout == 0)
				mbox_flash->timeout = MBOX_DEFAULT_TIMEOUT;
			break;
	}
	/* Callers will handle the case where the version is not known
	 *
	 * Here we deliberately ignore the 'default' sizes.
	 * All windows opened will not provide a hint and we're
	 * happy to let the BMC figure everything out.
	 * Future optimisations may use the default size.
	 */
}

/* Version 2 and 3 compatible */
static void mbox_flash_do_get_flash_info(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg)
{
	mbox_flash->total_size = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 0));
	mbox_flash->erase_granule = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 2));
}

static void mbox_flash_do_get_flash_info_v1(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg)
{
	mbox_flash->total_size = msg_get_u32(msg, 0);
	mbox_flash->erase_granule = msg_get_u32(msg, 4);
}

/* Version 2 and 3 compatible */
static void mbox_flash_do_create_read_window(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg)
{
	mbox_flash->read.lpc_addr = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 0));
	mbox_flash->read.size = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 2));
	mbox_flash->read.cur_pos = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 4));
	mbox_flash->read.open = true;
	mbox_flash->write.open = false;
}

static void mbox_flash_do_create_read_window_v1(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg)
{
	mbox_flash->read.lpc_addr = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 0));
	mbox_flash->read.open = true;
	mbox_flash->write.open = false;
}

/* Version 2 and 3 compatible */
static void mbox_flash_do_create_write_window(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg)
{
	mbox_flash->write.lpc_addr = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 0));
	mbox_flash->write.size = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 2));
	mbox_flash->write.cur_pos = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 4));
	mbox_flash->write.open = true;
	mbox_flash->read.open = false;
}

static void mbox_flash_do_create_write_window_v1(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg)
{
	mbox_flash->write.lpc_addr = blocks_to_bytes(mbox_flash, msg_get_u16(msg, 0));
	mbox_flash->write.open = true;
	mbox_flash->read.open = false;
}

/* Version 1 and Version 2 compatible */
static void mbox_flash_do_close_window(struct mbox_flash_data *mbox_flash,
		struct bmc_mbox_msg *msg __unused)
{
	mbox_flash->read.open = false;
	mbox_flash->write.open = false;
}

static int handle_reboot(struct mbox_flash_data *mbox_flash)
{
	int rc;

	/*
	 * If the BMC ready bit isn't present then we're basically
	 * guaranteed to timeout trying to talk to it so just fail
	 * whatever is trying to happen.
	 * Importantly, we can't trust that the presence of the bit means
	 * the daemon is ok - don't assume it is going to respond at all
	 * from here onwards
	 */
	if (!(bmc_mbox_get_attn_reg() & MBOX_ATTN_BMC_DAEMON_READY))
		return FLASH_ERR_AGAIN;

	/* Clear this first so msg_send() doesn't freak out */
	mbox_flash->reboot = false;

	rc = do_acks(mbox_flash);
	if (rc) {
		if (rc == MBOX_R_TIMEOUT)
			rc = FLASH_ERR_AGAIN;
		mbox_flash->reboot = true;
		return rc;
	}

	rc = protocol_init(mbox_flash, 0);
	if (rc)
		mbox_flash->reboot = true;

	return rc;
}

static bool do_delayed_work(struct mbox_flash_data *mbox_flash)
{
	return is_paused(mbox_flash) || do_acks(mbox_flash) ||
		(is_reboot(mbox_flash) && handle_reboot(mbox_flash));
}

static int mbox_flash_mark_write(struct mbox_flash_data *mbox_flash,
				 uint64_t pos, uint64_t len, int type)
{
	struct bmc_mbox_msg msg = MSG_CREATE(type);
	int rc;

	if (mbox_flash->version == 1) {
		uint32_t start = ALIGN_DOWN(pos, 1 << mbox_flash->shift);
		msg_put_u16(&msg, 0, bytes_to_blocks(mbox_flash, pos));
		/*
		 * We need to make sure that we mark dirty until up to atleast
		 * pos + len.
		 */
		msg_put_u32(&msg, 2, pos + len - start);
	} else {
		uint64_t window_pos = pos - mbox_flash->write.cur_pos;
		uint16_t start = bytes_to_blocks(mbox_flash, window_pos);
		uint16_t end = bytes_to_blocks(mbox_flash,
					       ALIGN_UP(window_pos + len,
							1 << mbox_flash->shift));

		msg_put_u16(&msg, 0, start);
		msg_put_u16(&msg, 2, end - start); /* Total Length */
	}

	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
		return rc;
	}

	rc = wait_for_bmc(mbox_flash, mbox_flash->timeout);
	if (rc)
		prlog(PR_ERR, "Error waiting for BMC\n");

	return rc;
}

static int mbox_flash_dirty(struct mbox_flash_data *mbox_flash, uint64_t pos,
		uint64_t len)
{
	if (!mbox_flash->write.open) {
		prlog(PR_ERR, "Attempting to dirty without an open write window\n");
		return FLASH_ERR_DEVICE_GONE;
	}

	return mbox_flash_mark_write(mbox_flash, pos, len,
				     MBOX_C_MARK_WRITE_DIRTY);
}

static int mbox_flash_erase(struct mbox_flash_data *mbox_flash, uint64_t pos,
			    uint64_t len)
{
	if (!mbox_flash->write.open) {
		prlog(PR_ERR, "Attempting to erase without an open write window\n");
		return FLASH_ERR_DEVICE_GONE;
	}

	return mbox_flash_mark_write(mbox_flash, pos, len,
				     MBOX_C_MARK_WRITE_ERASED);
}

static int mbox_flash_flush(struct mbox_flash_data *mbox_flash)
{
	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_WRITE_FLUSH);
	int rc;

	if (!mbox_flash->write.open) {
		prlog(PR_ERR, "Attempting to flush without an open write window\n");
		return FLASH_ERR_DEVICE_GONE;
	}

	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
		return rc;
	}

	rc = wait_for_bmc(mbox_flash, mbox_flash->timeout);
	if (rc)
		prlog(PR_ERR, "Error waiting for BMC\n");

	return rc;
}

/* Is the current window able perform the complete operation */
static bool mbox_window_valid(struct lpc_window *win, uint64_t pos,
			      uint64_t len)
{
	if (!win->open)
		return false;
	if (pos < win->cur_pos) /* start */
		return false;
	if ((pos + len) > (win->cur_pos + win->size)) /* end */
		return false;
	return true;
}

static int mbox_window_move(struct mbox_flash_data *mbox_flash,
			    struct lpc_window *win, uint8_t command,
			    uint64_t pos, uint64_t len, uint64_t *size)
{
	struct bmc_mbox_msg msg = MSG_CREATE(command);
	int rc;

	/* Is the window currently open valid */
	if (mbox_window_valid(win, pos, len)) {
		*size = len;
		return 0;
	}

	/* V1 needs to remember where it has opened the window, note it
	 * here.
	 * If we're running V2 the response to the CREATE_*_WINDOW command
	 * will overwrite what we've noted here.
	 */
	win->cur_pos = pos & ~mbox_flash_mask(mbox_flash);

	msg_put_u16(&msg, 0, bytes_to_blocks(mbox_flash, pos));
	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
		return rc;
	}

	mbox_flash->read.open = false;
	mbox_flash->write.open = false;

	rc = wait_for_bmc(mbox_flash, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Error waiting for BMC\n");
		return rc;
	}

	*size = len;
	/* Is length past the end of the window? */
	if ((pos + len) > (win->cur_pos + win->size))
		/* Adjust size to meet current window */
		*size =  (win->cur_pos + win->size) - pos;

	/*
	 * It doesn't make sense for size to be zero if len isn't zero.
	 * If this condition happens we're most likely going to spin since
	 * the caller will likely decerement pos by zero then call this
	 * again.
	 * Debateable as to if this should return non zero. At least the
	 * bug will be obvious from the barf.
	 */
	if (len != 0 && *size == 0) {
		prlog(PR_ERR, "Failed read/write!\n");
		prlog(PR_ERR, "Please update your BMC firmware\n");
		prlog(PR_ERR, "Move window is indicating size zero!\n");
		prlog(PR_ERR, "pos: 0x%" PRIx64 ", len: 0x%" PRIx64 "\n", pos, len);
		prlog(PR_ERR, "win pos: 0x%08x win size: 0x%08x\n", win->cur_pos, win->size);
		/*
		 * In practice skiboot gets stuck and this eventually
		 * brings down the host. Just fail pass the error back
		 * up and hope someone makes a good decision
		 */
		return MBOX_R_SYSTEM_ERROR;
	}

	return rc;
}

static int mbox_flash_write(struct blocklevel_device *bl, uint64_t pos,
			    const void *buf, uint64_t len)
{
	struct mbox_flash_data *mbox_flash;
	uint64_t size;

	int rc = 0;

	/* LPC is only 32bit */
	if (pos > UINT_MAX || len > UINT_MAX)
		return FLASH_ERR_PARM_ERROR;

	mbox_flash = container_of(bl, struct mbox_flash_data, bl);

	if (do_delayed_work(mbox_flash))
		return FLASH_ERR_AGAIN;

	prlog(PR_TRACE, "Flash write at %#" PRIx64 " for %#" PRIx64 "\n", pos, len);
	while (len > 0) {
		/* Move window and get a new size to read */
		rc = mbox_window_move(mbox_flash, &mbox_flash->write,
				      MBOX_C_CREATE_WRITE_WINDOW, pos, len,
				      &size);
		if (rc)
			return rc;

 		/* Perform the read for this window */
		rc = lpc_window_write(mbox_flash, pos, buf, size);
		if (rc)
			return rc;

		rc = mbox_flash_dirty(mbox_flash, pos, size);
		if (rc)
			return rc;

		/*
		 * Must flush here as changing the window contents
		 * without flushing entitles the BMC to throw away the
		 * data. Unlike the read case there isn't a need to explicitly
		 * validate the window, the flush command will fail if the
		 * window was compromised.
		 */
		rc = mbox_flash_flush(mbox_flash);
		if (rc)
			return rc;

		len -= size;
		pos += size;
		buf += size;
	}
	return rc;
}

static int mbox_flash_read(struct blocklevel_device *bl, uint64_t pos,
			   void *buf, uint64_t len)
{
	struct mbox_flash_data *mbox_flash;
	uint64_t size;

	int rc = 0;

	/* LPC is only 32bit */
	if (pos > UINT_MAX || len > UINT_MAX)
		return FLASH_ERR_PARM_ERROR;

	mbox_flash = container_of(bl, struct mbox_flash_data, bl);

	if (do_delayed_work(mbox_flash))
		return FLASH_ERR_AGAIN;

	prlog(PR_TRACE, "Flash read at %#" PRIx64 " for %#" PRIx64 "\n", pos, len);
	while (len > 0) {
		/* Move window and get a new size to read */
		rc = mbox_window_move(mbox_flash, &mbox_flash->read,
				      MBOX_C_CREATE_READ_WINDOW, pos,
				      len, &size);
		if (rc)
			return rc;

 		/* Perform the read for this window */
		rc = lpc_window_read(mbox_flash, pos, buf, size);
		if (rc)
			return rc;

		len -= size;
		pos += size;
		buf += size;
		/*
		 * Ensure my window is still open, if it isn't we can't trust
		 * what we read
		 */
		if (!is_valid(mbox_flash, &mbox_flash->read))
			return FLASH_ERR_AGAIN;
	}
	return rc;
}

static bool mbox_flash_reset(struct blocklevel_device *bl)
{
	int rc;
	struct mbox_flash_data *mbox_flash;
	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_RESET_STATE);

	prlog(PR_NOTICE, "MBOX reset\n");
	mbox_flash = container_of(bl, struct mbox_flash_data, bl);

	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX RESET msg\n");
		return false;
	}
	if (wait_for_bmc(mbox_flash, mbox_flash->timeout)) {
		prlog(PR_ERR, "Error waiting for BMC\n");
		return false;
	}

	return true;
}

static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,
		uint64_t *total_size, uint32_t *erase_granule)
{
	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_GET_FLASH_INFO);
	struct mbox_flash_data *mbox_flash;
	int rc;

	mbox_flash = container_of(bl, struct mbox_flash_data, bl);

	if (do_delayed_work(mbox_flash))
		return FLASH_ERR_AGAIN;

	/*
	 * We want to avoid runtime mallocs in skiboot. The expected
	 * behavour to uses of libflash is that one can free() the memory
	 * returned.
	 * NULL will do for now.
	 */
	if (name)
		*name = NULL;

	mbox_flash->busy = true;
	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
		return rc;
	}

	if (wait_for_bmc(mbox_flash, mbox_flash->timeout)) {
		prlog(PR_ERR, "Error waiting for BMC\n");
		return rc;
	}

	mbox_flash->bl.erase_mask = mbox_flash->erase_granule - 1;

	if (total_size)
		*total_size = mbox_flash->total_size;
	if (erase_granule)
		*erase_granule = mbox_flash->erase_granule;

	return rc;
}

static int mbox_flash_erase_v2(struct blocklevel_device *bl, uint64_t pos,
			       uint64_t len)
{
	struct mbox_flash_data *mbox_flash;

	/* LPC is only 32bit */
	if (pos > UINT_MAX || len > UINT_MAX)
		return FLASH_ERR_PARM_ERROR;

	mbox_flash = container_of(bl, struct mbox_flash_data, bl);

	prlog(PR_TRACE, "Flash erase at 0x%08x for 0x%08x\n", (u32) pos, (u32) len);
	while (len > 0) {
		uint64_t size;
		int rc;

		/* Move window and get a new size to erase */
		rc = mbox_window_move(mbox_flash, &mbox_flash->write,
				      MBOX_C_CREATE_WRITE_WINDOW, pos, len, &size);
		if (rc)
			return rc;

		rc = mbox_flash_erase(mbox_flash, pos, size);
		if (rc)
			return rc;

		/*
		* Flush directly, don't mark that region dirty otherwise it
		* isn't clear if a write happened there or not
		*/

		rc = mbox_flash_flush(mbox_flash);
		if (rc)
			return rc;

		len -= size;
		pos += size;
	}

	return 0;
}

static int mbox_flash_erase_v1(struct blocklevel_device *bl __unused,
			       uint64_t pos __unused, uint64_t len __unused)
{
	/*
	* We can probably get away with doing nothing.
	* TODO: Rethink this, causes interesting behaviour in pflash.
	* Users do expect pflash -{e,E} to do something. This is because
	* on real flash this would have set that region to all 0xFF but
	* really the erase at the blocklevel interface was only designed
	* to be "please make this region writeable".
	* It may be wise (despite the large performance penalty) to
	* actually write all 0xFF here. I'll leave that as an exercise
	* for the future.
	*/

	return 0;
}

/* Called from interrupt handler, don't send any mbox messages */
static void mbox_flash_attn(uint8_t attn, void *priv)
{
	struct mbox_flash_data *mbox_flash = priv;

	if (attn & MBOX_ATTN_ACK_MASK)
		mbox_flash->ack = true;
	if (attn & MBOX_ATTN_BMC_REBOOT) {
		mbox_flash->reboot = true;
		mbox_flash->read.open = false;
		mbox_flash->write.open = false;
		attn &= ~MBOX_ATTN_BMC_REBOOT;
	}

	if (attn & MBOX_ATTN_BMC_WINDOW_RESET) {
		mbox_flash->read.open = false;
		mbox_flash->write.open = false;
		attn &= ~MBOX_ATTN_BMC_WINDOW_RESET;
	}

	if (attn & MBOX_ATTN_BMC_FLASH_LOST) {
		mbox_flash->pause = true;
		attn &= ~MBOX_ATTN_BMC_FLASH_LOST;
	} else {
		mbox_flash->pause = false;
	}
}

static void mbox_flash_callback(struct bmc_mbox_msg *msg, void *priv)
{
	struct mbox_flash_data *mbox_flash = priv;

	prlog(PR_TRACE, "BMC OK command %u\n", msg->command);

	if (msg->response != MBOX_R_SUCCESS) {
		prlog(PR_ERR, "Bad response code from BMC %d\n", msg->response);
		mbox_flash->rc = msg->response;
		goto out;
	}

	if (msg->command > MBOX_COMMAND_COUNT) {
		prlog(PR_ERR, "Got response to unknown command %02x\n", msg->command);
		mbox_flash->rc = -1;
		goto out;
	}

	if (!mbox_flash->handlers[msg->command]) {
		prlog(PR_ERR, "Couldn't find handler for message! command: %u, seq: %u\n",
				msg->command, msg->seq);
		mbox_flash->rc = MBOX_R_SYSTEM_ERROR;
		goto out;
	}

	mbox_flash->rc = 0;

	mbox_flash->handlers[msg->command](mbox_flash, msg);

out:
	mbox_flash->busy = false;
}

static int protocol_init(struct mbox_flash_data *mbox_flash, uint8_t shift)
{
	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_GET_MBOX_INFO);
	int rc;

	mbox_flash->read.open = false;
	mbox_flash->write.open = false;

	/* Assume V2+ */
	mbox_flash->bl.read = &mbox_flash_read;
	mbox_flash->bl.write = &mbox_flash_write;
	mbox_flash->bl.erase = &mbox_flash_erase_v2;
	mbox_flash->bl.get_info = &mbox_flash_get_info;

	/* Assume V3 */
	mbox_flash->handlers = handlers_v3;

	bmc_mbox_register_callback(&mbox_flash_callback, mbox_flash);
	bmc_mbox_register_attn(&mbox_flash_attn, mbox_flash);

	/*
	 * For V1 of the protocol this is fixed.
	 * V2+: The init code will update this
	 */
	mbox_flash->shift = 12;

	/*
	 * For V1 we'll use this value.
	 * V2+: The init code (may) update this
	 */
	mbox_flash->timeout = MBOX_DEFAULT_TIMEOUT;

	/*
	 * Always attempt init with highest version known.
	 * The GET_MBOX_INFO response will confirm that the other side can
	 * talk the highest version, we'll update this variable then if
	 * our highest version is not supported
	 */
	mbox_flash->version = 3;

negotiate_version:
	msg_put_u8(&msg, 0, mbox_flash->version);
	msg_put_u8(&msg, 1, shift);
	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
		return rc;
	}

	rc = wait_for_bmc(mbox_flash, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Error waiting for BMC\n");
		if (mbox_flash->version > 1) {
			mbox_flash->version--;
			prlog(PR_INFO, "Retrying MBOX negotiation with BMC"
			      " with MBOXv%d\n", mbox_flash->version);
			goto negotiate_version;
		}
		return rc;
	}

	prlog(PR_INFO, "Detected mbox protocol version %d\n", mbox_flash->version);
	switch (mbox_flash->version) {
		case 1:
			mbox_flash->bl.erase = &mbox_flash_erase_v1;
			mbox_flash->handlers = handlers_v1;
			break;
		case 2:
			mbox_flash->handlers = handlers_v2;
			break;
		case 3:
			/* Nothing to do we assumed it would be V3 */
			break;
		default:
			/*
			 * The BMC is can only lower the requested version not do
			 * anything else. FWIW there is no verion 0.
			 */
			prlog(PR_CRIT, "Bad version: %u\n", mbox_flash->version);
			rc = FLASH_ERR_PARM_ERROR;
	}

	return rc;
}

int mbox_flash_lock(struct blocklevel_device *bl, uint64_t pos, uint64_t len)
{
	struct mbox_flash_data *mbox_flash;
	struct bmc_mbox_msg msg = MSG_CREATE(MBOX_C_MARK_LOCKED);
	int rc;

	/* mbox-flash only talks 32bit for now */
	if (pos > UINT_MAX || len > UINT_MAX)
		return FLASH_ERR_PARM_ERROR;

	/*
	 * If the region isn't at least 4k aligned and in size then bail
	 * out, the protocol won't allow for smaller block sizes.
	 */
	if (pos & ((1 << 12) - 1) || len & ((1 << 12) - 1))
		return FLASH_ERR_PARM_ERROR;

	mbox_flash = container_of(bl, struct mbox_flash_data, bl);
	if ((pos & mbox_flash_mask(mbox_flash)) || (len & mbox_flash_mask(mbox_flash))) {
		uint8_t shift = 0;
		/*
		 * The current block size won't work for locking the requested
		 * region must reinit.
		 */
		while (!((1 << shift) & pos) && !((1 << shift) & len))
			shift++;

		prlog(PR_INFO, "Locking flash requires re-init from shift of %d to shift of %d\n",
				mbox_flash->shift, shift);

		rc = protocol_init(mbox_flash, shift);
		if (rc)
			return rc;

		/*
		 * The daemon didn't agree with the requested shift - the
		 * flash won't be able to be locked
		 */
		if (mbox_flash->shift > shift)
			return FLASH_ERR_PARM_ERROR;
	}

	msg_put_u16(&msg, 0, bytes_to_blocks(mbox_flash, pos));
	msg_put_u16(&msg, 2, bytes_to_blocks(mbox_flash, len));
	rc = msg_send(mbox_flash, &msg, mbox_flash->timeout);
	if (rc) {
		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
		return rc;
	}

	rc = wait_for_bmc(mbox_flash, mbox_flash->timeout);
	if (rc)
		prlog(PR_ERR, "Error waiting for BMC\n");

	return rc;
}

int mbox_flash_init(struct blocklevel_device **bl)
{
	struct mbox_flash_data *mbox_flash;
	int rc;

	CHECK_HANDLER_SIZE(handlers_v3);
	CHECK_HANDLER_SIZE(handlers_v2);
	CHECK_HANDLER_SIZE(handlers_v1);

	if (!bl)
		return FLASH_ERR_PARM_ERROR;

	/* XXX: We only support one blocklevel flash device over mbox. If we
	 * ever support more than one, move this out. The chances of that are
	 * slim though due to circumstances.
	 */
	mbox_init();

	*bl = NULL;

	mbox_flash = zalloc(sizeof(struct mbox_flash_data));
	if (!mbox_flash)
		return FLASH_ERR_MALLOC_FAILED;

	/* Assume V2+ */
	mbox_flash->bl.read = &mbox_flash_read;
	mbox_flash->bl.write = &mbox_flash_write;
	mbox_flash->bl.erase = &mbox_flash_erase_v2;
	mbox_flash->bl.get_info = &mbox_flash_get_info;
	mbox_flash->bl.exit = &mbox_flash_exit;

	if (bmc_mbox_get_attn_reg() & MBOX_ATTN_BMC_REBOOT)
		rc = handle_reboot(mbox_flash);
	else
		rc = protocol_init(mbox_flash, 0);
	if (rc) {
		free(mbox_flash);
		return rc;
	}

	mbox_flash->bl.keep_alive = 0;

	*bl = &(mbox_flash->bl);
	return 0;
}

bool mbox_flash_exit(struct blocklevel_device *bl)
{
	bool status = true;
	struct mbox_flash_data *mbox_flash;
	if (bl) {
		status = mbox_flash_reset(bl);
		mbox_flash = container_of(bl, struct mbox_flash_data, bl);
		free(mbox_flash);
	}

	return status;
}
