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

#define pr_fmt(fmt) "HIOMAP: " fmt

#include <hiomap.h>
#include <inttypes.h>
#include <ipmi.h>
#include <lpc.h>
#include <mem_region-malloc.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>

#include <ccan/container_of/container_of.h>

#include "errors.h"
#include "ipmi-hiomap.h"

#define CMD_OP_HIOMAP_EVENT	0x0f

struct ipmi_hiomap_result {
	struct ipmi_hiomap *ctx;
	int16_t cc;
};

#define RESULT_INIT(_name, _ctx) struct ipmi_hiomap_result _name = { _ctx, -1 }

static inline uint32_t blocks_to_bytes(struct ipmi_hiomap *ctx, uint16_t blocks)
{
	return blocks << ctx->block_size_shift;
}

static inline uint16_t bytes_to_blocks(struct ipmi_hiomap *ctx, uint32_t bytes)
{
	return bytes >> ctx->block_size_shift;
}

static inline uint16_t bytes_to_blocks_align_up(struct ipmi_hiomap *ctx,
						uint32_t pos, uint32_t len)
{
	uint32_t block_size = 1 << ctx->block_size_shift;
	uint32_t delta = pos & (block_size - 1);
	uint32_t aligned = ALIGN_UP((len + delta), block_size);
	uint32_t blocks = aligned >> ctx->block_size_shift;
	/* Our protocol can handle block count < sizeof(u16) */
	uint32_t mask = ((1 << 16) - 1);

	assert(!(blocks & ~mask));

	return blocks & mask;
}

/* Call under ctx->lock */
static int hiomap_protocol_ready(struct ipmi_hiomap *ctx)
{
	if (!(ctx->bmc_state & HIOMAP_E_DAEMON_READY))
		return FLASH_ERR_DEVICE_GONE;
	if (ctx->bmc_state & HIOMAP_E_FLASH_LOST)
		return FLASH_ERR_AGAIN;

	return 0;
}

static int hiomap_queue_msg_sync(struct ipmi_hiomap *ctx, struct ipmi_msg *msg)
{
	int rc;

	/*
	 * There's an unavoidable TOCTOU race here with the BMC sending an
	 * event saying it's no-longer available right after we test but before
	 * we call into the IPMI stack to send the message.
	 * hiomap_queue_msg_sync() exists to capture the race in a single
	 * location.
	 */
	lock(&ctx->lock);
	rc = hiomap_protocol_ready(ctx);
	unlock(&ctx->lock);
	if (rc) {
		ipmi_free_msg(msg);
		return rc;
	}

	ipmi_queue_msg_sync(msg);

	return 0;
}

/* Call under ctx->lock */
static int hiomap_window_valid(struct ipmi_hiomap *ctx, uint64_t pos,
			        uint64_t len)
{
	if (ctx->bmc_state & HIOMAP_E_FLASH_LOST)
		return FLASH_ERR_AGAIN;
	if (ctx->bmc_state & HIOMAP_E_PROTOCOL_RESET)
		return FLASH_ERR_AGAIN;
	if (ctx->bmc_state & HIOMAP_E_WINDOW_RESET)
		return FLASH_ERR_AGAIN;
	if (ctx->window_state == closed_window)
		return FLASH_ERR_PARM_ERROR;
	if (pos < ctx->current.cur_pos)
		return FLASH_ERR_PARM_ERROR;
	if ((pos + len) > (ctx->current.cur_pos + ctx->current.size))
		return FLASH_ERR_PARM_ERROR;

	return 0;
}

static void ipmi_hiomap_cmd_cb(struct ipmi_msg *msg)
{
	struct ipmi_hiomap_result *res = msg->user_data;
	struct ipmi_hiomap *ctx = res->ctx;

	res->cc = msg->cc;
	if (msg->cc != IPMI_CC_NO_ERROR) {
		ipmi_free_msg(msg);
		return;
	}

	/* We at least need the command and sequence */
	if (msg->resp_size < 2) {
		prerror("Illegal response size: %u\n", msg->resp_size);
		res->cc = IPMI_ERR_UNSPECIFIED;
		ipmi_free_msg(msg);
		return;
	}

	if (msg->data[1] != ctx->seq) {
		prerror("Unmatched sequence number: wanted %u got %u\n",
			ctx->seq, msg->data[1]);
		res->cc = IPMI_ERR_UNSPECIFIED;
		ipmi_free_msg(msg);
		return;
	}

	switch (msg->data[0]) {
	case HIOMAP_C_GET_INFO:
	{
		struct hiomap_v2_info *parms;

		if (msg->resp_size != 6) {
			prerror("%u: Unexpected response size: %u\n", msg->data[0],
				msg->resp_size);
			res->cc = IPMI_ERR_UNSPECIFIED;
			break;
		}

		ctx->version = msg->data[2];
		if (ctx->version < 2) {
			prerror("Failed to negotiate protocol v2 or higher: %d\n",
				ctx->version);
			res->cc = IPMI_ERR_UNSPECIFIED;
			break;
		}

		parms = (struct hiomap_v2_info *)&msg->data[3];
		ctx->block_size_shift = parms->block_size_shift;
		ctx->timeout = le16_to_cpu(parms->timeout);
		break;
	}
	case HIOMAP_C_GET_FLASH_INFO:
	{
		struct hiomap_v2_flash_info *parms;

		if (msg->resp_size != 6) {
			prerror("%u: Unexpected response size: %u\n", msg->data[0],
				msg->resp_size);
			res->cc = IPMI_ERR_UNSPECIFIED;
			break;
		}

		parms = (struct hiomap_v2_flash_info *)&msg->data[2];
		ctx->total_size =
			blocks_to_bytes(ctx, le16_to_cpu(parms->total_size));
		ctx->erase_granule =
			blocks_to_bytes(ctx, le16_to_cpu(parms->erase_granule));
		break;
	}
	case HIOMAP_C_CREATE_READ_WINDOW:
	case HIOMAP_C_CREATE_WRITE_WINDOW:
	{
		struct hiomap_v2_create_window *parms;

		if (msg->resp_size != 8) {
			prerror("%u: Unexpected response size: %u\n", msg->data[0],
				msg->resp_size);
			res->cc = IPMI_ERR_UNSPECIFIED;
			break;
		}

		parms = (struct hiomap_v2_create_window *)&msg->data[2];

		ctx->current.lpc_addr =
			blocks_to_bytes(ctx, le16_to_cpu(parms->lpc_addr));
		ctx->current.size =
			blocks_to_bytes(ctx, le16_to_cpu(parms->size));
		ctx->current.cur_pos =
			blocks_to_bytes(ctx, le16_to_cpu(parms->offset));

		lock(&ctx->lock);
		if (msg->data[0] == HIOMAP_C_CREATE_READ_WINDOW)
			ctx->window_state = read_window;
		else
			ctx->window_state = write_window;
		unlock(&ctx->lock);

		break;
	}
	case HIOMAP_C_MARK_DIRTY:
	case HIOMAP_C_FLUSH:
	case HIOMAP_C_ACK:
	case HIOMAP_C_ERASE:
	case HIOMAP_C_RESET:
		if (msg->resp_size != 2) {
			prerror("%u: Unexpected response size: %u\n", msg->data[0],
				msg->resp_size);
			res->cc = IPMI_ERR_UNSPECIFIED;
			break;
		}
		break;
	default:
		prlog(PR_WARNING, "Unimplemented command handler: %u\n",
		      msg->data[0]);
		break;
	};
	ipmi_free_msg(msg);
}

static void hiomap_init(struct ipmi_hiomap *ctx)
{
	/*
	 * Speculatively mark the daemon as available so we attempt to perform
	 * the handshake without immediately bailing out.
	 */
	lock(&ctx->lock);
	ctx->bmc_state = HIOMAP_E_DAEMON_READY;
	unlock(&ctx->lock);
}

static int hiomap_get_info(struct ipmi_hiomap *ctx)
{
	RESULT_INIT(res, ctx);
	unsigned char req[3];
	struct ipmi_msg *msg;
	int rc;

	/* Negotiate protocol version 2 */
	req[0] = HIOMAP_C_GET_INFO;
	req[1] = ++ctx->seq;
	req[2] = HIOMAP_V2;

	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 6);

	rc = hiomap_queue_msg_sync(ctx, msg);
	if (rc)
		return rc;

	if (res.cc != IPMI_CC_NO_ERROR) {
		prerror("%s failed: %d\n", __func__, res.cc);
		return FLASH_ERR_PARM_ERROR; /* XXX: Find something better? */
	}

	return 0;
}

static int hiomap_get_flash_info(struct ipmi_hiomap *ctx)
{
	RESULT_INIT(res, ctx);
	unsigned char req[2];
	struct ipmi_msg *msg;
	int rc;

	req[0] = HIOMAP_C_GET_FLASH_INFO;
	req[1] = ++ctx->seq;
	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2 + 2 + 2);

	rc = hiomap_queue_msg_sync(ctx, msg);
	if (rc)
		return rc;

	if (res.cc != IPMI_CC_NO_ERROR) {
		prerror("%s failed: %d\n", __func__, res.cc);
		return FLASH_ERR_PARM_ERROR; /* XXX: Find something better? */
	}

	return 0;
}

static int hiomap_window_move(struct ipmi_hiomap *ctx, uint8_t command,
			      uint64_t pos, uint64_t len, uint64_t *size)
{
	enum lpc_window_state want_state;
	struct hiomap_v2_range *range;
	RESULT_INIT(res, ctx);
	unsigned char req[6];
	struct ipmi_msg *msg;
	bool valid_state;
	bool is_read;
	int rc;

	is_read = (command == HIOMAP_C_CREATE_READ_WINDOW);
	want_state = is_read ? read_window : write_window;

	lock(&ctx->lock);

	valid_state = want_state == ctx->window_state;
	rc = hiomap_window_valid(ctx, pos, len);
	if (valid_state && !rc) {
		unlock(&ctx->lock);
		*size = len;
		return 0;
	}

	ctx->window_state = closed_window;

	unlock(&ctx->lock);

	req[0] = command;
	req[1] = ++ctx->seq;

	range = (struct hiomap_v2_range *)&req[2];
	range->offset = cpu_to_le16(bytes_to_blocks(ctx, pos));
	range->size = cpu_to_le16(bytes_to_blocks_align_up(ctx, pos, len));

	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req),
			 2 + 2 + 2 + 2);

	rc = hiomap_queue_msg_sync(ctx, msg);
	if (rc)
		return rc;

	if (res.cc != IPMI_CC_NO_ERROR) {
		prlog(PR_INFO, "%s failed: %d\n", __func__, res.cc);
		return FLASH_ERR_PARM_ERROR; /* XXX: Find something better? */
	}

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

	if (len != 0 && *size == 0) {
		unlock(&ctx->lock);
		prerror("Invalid window properties: len: %"PRIu64", size: %"PRIu64"\n",
			len, *size);
		return FLASH_ERR_PARM_ERROR;
	}

	prlog(PR_DEBUG, "Opened %s window from 0x%x for %u bytes at 0x%x\n",
	      (command == HIOMAP_C_CREATE_READ_WINDOW) ? "read" : "write",
	      ctx->current.cur_pos, ctx->current.size, ctx->current.lpc_addr);

	unlock(&ctx->lock);

	return 0;
}

static int hiomap_mark_dirty(struct ipmi_hiomap *ctx, uint64_t offset,
			      uint64_t size)
{
	struct hiomap_v2_range *range;
	enum lpc_window_state state;
	RESULT_INIT(res, ctx);
	unsigned char req[6];
	struct ipmi_msg *msg;
	uint32_t pos;
	int rc;

	lock(&ctx->lock);
	state = ctx->window_state;
	unlock(&ctx->lock);

	if (state != write_window)
		return FLASH_ERR_PARM_ERROR;

	req[0] = HIOMAP_C_MARK_DIRTY;
	req[1] = ++ctx->seq;

	pos = offset - ctx->current.cur_pos;
	range = (struct hiomap_v2_range *)&req[2];
	range->offset = cpu_to_le16(bytes_to_blocks(ctx, pos));
	range->size = cpu_to_le16(bytes_to_blocks_align_up(ctx, pos, size));

	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2);

	rc = hiomap_queue_msg_sync(ctx, msg);
	if (rc)
		return rc;

	if (res.cc != IPMI_CC_NO_ERROR) {
		prerror("%s failed: %d\n", __func__, res.cc);
		return FLASH_ERR_PARM_ERROR;
	}

	prlog(PR_DEBUG, "Marked flash dirty at 0x%" PRIx64 " for %" PRIu64 "\n",
	      offset, size);

	return 0;
}

static int hiomap_flush(struct ipmi_hiomap *ctx)
{
	enum lpc_window_state state;
	RESULT_INIT(res, ctx);
	unsigned char req[2];
	struct ipmi_msg *msg;
	int rc;

	lock(&ctx->lock);
	state = ctx->window_state;
	unlock(&ctx->lock);

	if (state != write_window)
		return FLASH_ERR_PARM_ERROR;

	req[0] = HIOMAP_C_FLUSH;
	req[1] = ++ctx->seq;

	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2);

	rc = hiomap_queue_msg_sync(ctx, msg);
	if (rc)
		return rc;

	if (res.cc != IPMI_CC_NO_ERROR) {
		prerror("%s failed: %d\n", __func__, res.cc);
		return FLASH_ERR_PARM_ERROR;
	}

	prlog(PR_DEBUG, "Flushed writes\n");

	return 0;
}

static int hiomap_ack(struct ipmi_hiomap *ctx, uint8_t ack)
{
	RESULT_INIT(res, ctx);
	unsigned char req[3];
	struct ipmi_msg *msg;
	int rc;

	req[0] = HIOMAP_C_ACK;
	req[1] = ++ctx->seq;
	req[2] = ack;

	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2);

	rc = hiomap_queue_msg_sync(ctx, msg);
	if (rc)
		return rc;

	if (res.cc != IPMI_CC_NO_ERROR) {
		prlog(PR_DEBUG, "%s failed: %d\n", __func__, res.cc);
		return FLASH_ERR_PARM_ERROR;
	}

	prlog(PR_DEBUG, "Acked events: 0x%x\n", ack);

	return 0;
}

static int hiomap_erase(struct ipmi_hiomap *ctx, uint64_t offset,
			 uint64_t size)
{
	struct hiomap_v2_range *range;
	enum lpc_window_state state;
	RESULT_INIT(res, ctx);
	unsigned char req[6];
	struct ipmi_msg *msg;
	uint32_t pos;
	int rc;

	lock(&ctx->lock);
	state = ctx->window_state;
	unlock(&ctx->lock);

	if (state != write_window)
		return FLASH_ERR_PARM_ERROR;

	req[0] = HIOMAP_C_ERASE;
	req[1] = ++ctx->seq;

	pos = offset - ctx->current.cur_pos;
	range = (struct hiomap_v2_range *)&req[2];
	range->offset = cpu_to_le16(bytes_to_blocks(ctx, pos));
	range->size = cpu_to_le16(bytes_to_blocks_align_up(ctx, pos, size));

	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2);
	rc = hiomap_queue_msg_sync(ctx, msg);
	if (rc)
		return rc;

	if (res.cc != IPMI_CC_NO_ERROR) {
		prerror("%s failed: %d\n", __func__, res.cc);
		return FLASH_ERR_PARM_ERROR;
	}

	prlog(PR_DEBUG, "Erased flash at 0x%" PRIx64 " for %" PRIu64 "\n",
	      offset, size);

	return 0;
}

static bool hiomap_reset(struct ipmi_hiomap *ctx)
{
	RESULT_INIT(res, ctx);
	unsigned char req[2];
	struct ipmi_msg *msg;

	prlog(PR_NOTICE, "Reset\n");

	req[0] = HIOMAP_C_RESET;
	req[1] = ++ctx->seq;
	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
		         bmc_platform->sw->ipmi_oem_hiomap_cmd,
			 ipmi_hiomap_cmd_cb, &res, req, sizeof(req), 2);
	ipmi_queue_msg_sync(msg);

	if (res.cc != IPMI_CC_NO_ERROR) {
		prlog(PR_ERR, "%s failed: %d\n", __func__, res.cc);
		return false;
	}

	return true;
}

static void hiomap_event(uint8_t events, void *context)
{
	struct ipmi_hiomap *ctx = context;

	prlog(PR_DEBUG, "Received events: 0x%x\n", events);

	lock(&ctx->lock);
	ctx->bmc_state = events | (ctx->bmc_state & HIOMAP_E_ACK_MASK);
	unlock(&ctx->lock);
}

static int lpc_window_read(struct ipmi_hiomap *ctx, uint32_t pos,
			   void *buf, uint32_t len)
{
	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
	int rc;

	if ((ctx->current.lpc_addr + ctx->current.size) < (off + len))
		return FLASH_ERR_PARM_ERROR;

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

	while(len) {
		uint32_t chunk;
		uint32_t dat;

		/* XXX: make this read until it's aligned */
		if (len > 3 && !(off & 3)) {
			rc = lpc_read(OPAL_LPC_FW, off, &dat, 4);
			if (!rc) {
				/*
				 * lpc_read swaps to CPU endian but it's not
				 * really a 32-bit value, so convert back.
				 */
				*(__be32 *)buf = cpu_to_be32(dat);
			}
			chunk = 4;
		} else {
			rc = lpc_read(OPAL_LPC_FW, off, &dat, 1);
			if (!rc)
				*(uint8_t *)buf = dat;
			chunk = 1;
		}
		if (rc) {
			prlog(PR_ERR, "lpc_read failure %d to FW 0x%08x\n", rc, off);
			return rc;
		}
		len -= chunk;
		off += chunk;
		buf += chunk;
	}

	return 0;
}

static int lpc_window_write(struct ipmi_hiomap *ctx, uint32_t pos,
			    const void *buf, uint32_t len)
{
	uint32_t off = ctx->current.lpc_addr + (pos - ctx->current.cur_pos);
	enum lpc_window_state state;
	int rc;

	lock(&ctx->lock);
	state = ctx->window_state;
	unlock(&ctx->lock);

	if (state != write_window)
		return FLASH_ERR_PARM_ERROR;

	if ((ctx->current.lpc_addr + ctx->current.size) < (off + len))
		return FLASH_ERR_PARM_ERROR;

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

	while(len) {
		uint32_t chunk;

		if (len > 3 && !(off & 3)) {
			/* endian swap: see lpc_window_write */
			uint32_t dat = be32_to_cpu(*(__be32 *)buf);

			rc = lpc_write(OPAL_LPC_FW, off, dat, 4);
			chunk = 4;
		} else {
			uint8_t dat = *(uint8_t *)buf;

			rc = lpc_write(OPAL_LPC_FW, off, dat, 1);
			chunk = 1;
		}
		if (rc) {
			prlog(PR_ERR, "lpc_write failure %d to FW 0x%08x\n", rc, off);
			return rc;
		}
		len -= chunk;
		off += chunk;
		buf += chunk;
	}

	return 0;
}

/* Best-effort asynchronous event handling by blocklevel callbacks */
static int ipmi_hiomap_handle_events(struct ipmi_hiomap *ctx)
{
	uint8_t status;
	int rc;

	lock(&ctx->lock);

	status = ctx->bmc_state;

	/*
	 * Immediately clear the ackable events to make sure we don't race to
	 * clear them after dropping the lock, as we may lose protocol or
	 * window state if a race materialises. In the event of a failure where
	 * we haven't completed the recovery, the state we mask out below gets
	 * OR'ed back in to avoid losing it.
	 */
	ctx->bmc_state &= ~HIOMAP_E_ACK_MASK;

	/*
	 * We won't be attempting to restore window state -
	 * ipmi_hiomap_handle_events() is followed by hiomap_window_move() in
	 * all cases. Attempting restoration after HIOMAP_E_PROTOCOL_RESET or
	 * HIOMAP_E_WINDOW_RESET can be wasteful if we immediately shift the
	 * window elsewhere, and if it does not need to be shifted with respect
	 * to the subsequent request then hiomap_window_move() will handle
	 * re-opening it from the closed state.
	 *
	 * Therefore it is enough to mark the window as closed to consider it
	 * recovered.
	 */
	if (status & (HIOMAP_E_PROTOCOL_RESET | HIOMAP_E_WINDOW_RESET))
		ctx->window_state = closed_window;

	unlock(&ctx->lock);

	/*
	 * If there's anything to acknowledge, do so in the one request to
	 * minimise overhead. By sending the ACK prior to performing the
	 * protocol recovery we ensure that even with coalesced resets we still
	 * end up in the recovered state and not unknowingly stuck in a reset
	 * state. We may receive reset events after the ACK but prior to the
	 * recovery procedures being run, but this just means that we will
	 * needlessly perform recovery on the following invocation of
	 * ipmi_hiomap_handle_events(). If the reset event is a
	 * HIOMAP_E_WINDOW_RESET it is enough that the window is already marked
	 * as closed above - future accesses will force it to be re-opened and
	 * the BMC's cache must be valid if opening the window is successful.
	 */
	if (status & HIOMAP_E_ACK_MASK) {
		/* ACK is unversioned, can send it if the daemon is ready */
		rc = hiomap_ack(ctx, status & HIOMAP_E_ACK_MASK);
		if (rc) {
			prlog(PR_DEBUG, "Failed to ack events: 0x%x\n",
			      status & HIOMAP_E_ACK_MASK);
			goto restore;
		}
	}

	if (status & HIOMAP_E_PROTOCOL_RESET) {
		prlog(PR_INFO, "Protocol was reset\n");

		rc = hiomap_get_info(ctx);
		if (rc) {
			prerror("Failure to renegotiate after protocol reset\n");
			goto restore;
		}

		rc = hiomap_get_flash_info(ctx);
		if (rc) {
			prerror("Failure to fetch flash info after protocol reset\n");
			goto restore;
		}

		prlog(PR_INFO, "Restored state after protocol reset\n");
	}

	/*
	 * As there's no change to the protocol on HIOMAP_E_WINDOW_RESET we
	 * simply need to open a window to recover, which as mentioned above is
	 * handled by hiomap_window_move() after our cleanup here.
	 */

	return 0;

restore:
	/*
	 * Conservatively restore the events to the un-acked state to avoid
	 * losing events due to races. It might cause us to restore state more
	 * than necessary, but never less than necessary.
	 */
	lock(&ctx->lock);
	ctx->bmc_state |= (status & HIOMAP_E_ACK_MASK);
	unlock(&ctx->lock);

	return rc;
}

static int ipmi_hiomap_read(struct blocklevel_device *bl, uint64_t pos,
			    void *buf, uint64_t len)
{
	struct ipmi_hiomap *ctx;
	uint64_t size;
	int rc = 0;

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

	ctx = container_of(bl, struct ipmi_hiomap, bl);

	rc = ipmi_hiomap_handle_events(ctx);
	if (rc)
		return rc;

	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 = hiomap_window_move(ctx, HIOMAP_C_CREATE_READ_WINDOW, pos,
				        len, &size);
		if (rc)
			return rc;

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

		/* Check we can trust what we read */
		lock(&ctx->lock);
		rc = hiomap_window_valid(ctx, pos, size);
		unlock(&ctx->lock);
		if (rc)
			return rc;

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

}

static int ipmi_hiomap_write(struct blocklevel_device *bl, uint64_t pos,
			     const void *buf, uint64_t len)
{
	struct ipmi_hiomap *ctx;
	uint64_t size;
	int rc = 0;

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

	ctx = container_of(bl, struct ipmi_hiomap, bl);

	rc = ipmi_hiomap_handle_events(ctx);
	if (rc)
		return rc;

	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 = hiomap_window_move(ctx, HIOMAP_C_CREATE_WRITE_WINDOW, pos,
				        len, &size);
		if (rc)
			return rc;

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

		/*
		 * Unlike ipmi_hiomap_read() we don't explicitly test if the
		 * window is still valid after completing the LPC accesses as
		 * the following hiomap_mark_dirty() will implicitly check for
		 * us. In the case of a read operation there's no requirement
		 * that a command that validates window state follows, so the
		 * read implementation explicitly performs a check.
		 */

		rc = hiomap_mark_dirty(ctx, pos, size);
		if (rc)
			return rc;

		/*
		 * The BMC *should* flush if the window is implicitly closed,
		 * but do an explicit flush here to be sure.
		 *
		 * XXX: Removing this could improve performance
		 */
		rc = hiomap_flush(ctx);
		if (rc)
			return rc;

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

static int ipmi_hiomap_erase(struct blocklevel_device *bl, uint64_t pos,
			     uint64_t len)
{
	struct ipmi_hiomap *ctx;
	int rc;

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

	ctx = container_of(bl, struct ipmi_hiomap, bl);

	rc = ipmi_hiomap_handle_events(ctx);
	if (rc)
		return rc;

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

		/* Move window and get a new size to erase */
		rc = hiomap_window_move(ctx, HIOMAP_C_CREATE_WRITE_WINDOW, pos,
				        len, &size);
		if (rc)
			return rc;

		rc = hiomap_erase(ctx, 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 = hiomap_flush(ctx);
		if (rc)
			return rc;

		len -= size;
		pos += size;
	}

	return 0;
}

static int ipmi_hiomap_get_flash_info(struct blocklevel_device *bl,
				      const char **name, uint64_t *total_size,
				      uint32_t *erase_granule)
{
	struct ipmi_hiomap *ctx;
	int rc;

	ctx = container_of(bl, struct ipmi_hiomap, bl);

	rc = ipmi_hiomap_handle_events(ctx);
	if (rc)
		return rc;

	rc = hiomap_get_flash_info(ctx);
	if (rc)
		return rc;

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

	if (name)
		*name = NULL;
	if (total_size)
		*total_size = ctx->total_size;
	if (erase_granule)
		*erase_granule = ctx->erase_granule;

	return 0;
}

int ipmi_hiomap_init(struct blocklevel_device **bl)
{
	struct ipmi_hiomap *ctx;
	int rc;

	if (!bmc_platform->sw->ipmi_oem_hiomap_cmd)
		/* FIXME: Find a better error code */
		return FLASH_ERR_DEVICE_GONE;

	if (!bl)
		return FLASH_ERR_PARM_ERROR;

	*bl = NULL;

	ctx = zalloc(sizeof(struct ipmi_hiomap));
	if (!ctx)
		return FLASH_ERR_MALLOC_FAILED;

	init_lock(&ctx->lock);

	ctx->bl.read = &ipmi_hiomap_read;
	ctx->bl.write = &ipmi_hiomap_write;
	ctx->bl.erase = &ipmi_hiomap_erase;
	ctx->bl.get_info = &ipmi_hiomap_get_flash_info;
	ctx->bl.exit = &ipmi_hiomap_exit;

	hiomap_init(ctx);

	/* Ack all pending ack-able events to avoid spurious failures */
	rc = hiomap_ack(ctx, HIOMAP_E_ACK_MASK);
	if (rc) {
		prlog(PR_DEBUG, "Failed to ack events: 0x%x\n",
		      HIOMAP_E_ACK_MASK);
		goto err;
	}

	rc = ipmi_sel_register(CMD_OP_HIOMAP_EVENT, hiomap_event, ctx);
	if (rc < 0)
		goto err;

	/* Negotiate protocol behaviour */
	rc = hiomap_get_info(ctx);
	if (rc) {
		prerror("Failed to get hiomap parameters: %d\n", rc);
		goto err;
	}

	/* Grab the flash parameters */
	rc = hiomap_get_flash_info(ctx);
	if (rc) {
		prerror("Failed to get flash parameters: %d\n", rc);
		goto err;
	}

	prlog(PR_NOTICE, "Negotiated hiomap protocol v%u\n", ctx->version);
	prlog(PR_NOTICE, "Block size is %uKiB\n",
	      1 << (ctx->block_size_shift - 10));
	prlog(PR_NOTICE, "BMC suggested flash timeout of %us\n", ctx->timeout);
	prlog(PR_NOTICE, "Flash size is %uMiB\n", ctx->total_size >> 20);
	prlog(PR_NOTICE, "Erase granule size is %uKiB\n",
	      ctx->erase_granule >> 10);

	ctx->bl.keep_alive = 0;

	*bl = &(ctx->bl);

	return 0;

err:
	free(ctx);

	return rc;
}

bool ipmi_hiomap_exit(struct blocklevel_device *bl)
{
	bool status = true;

	struct ipmi_hiomap *ctx;
	if (bl) {
		ctx = container_of(bl, struct ipmi_hiomap, bl);
		status = hiomap_reset(ctx);
		free(ctx);
	}

	return status;
}
