diff --git a/transport_mbox.c b/transport_mbox.c
new file mode 100644
index 0000000..c14ab27
--- /dev/null
+++ b/transport_mbox.c
@@ -0,0 +1,871 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2018 IBM Corp.
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/timerfd.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include "mbox.h"
+#include "common.h"
+#include "transport_mbox.h"
+#include "windows.h"
+#include "lpc.h"
+
+/*
+ * write_bmc_event_reg() - Write to the BMC controlled status register (reg 15)
+ * @context:	The mbox context pointer
+ *
+ * Return:	0 on success otherwise negative error code
+ */
+static int write_bmc_event_reg(struct mbox_context *context)
+{
+	int rc;
+
+	/* Seek mbox registers */
+	rc = lseek(context->fds[MBOX_FD].fd, MBOX_BMC_EVENT, SEEK_SET);
+	if (rc != MBOX_BMC_EVENT) {
+		MSG_ERR("Couldn't lseek mbox to byte %d: %s\n", MBOX_BMC_EVENT,
+				strerror(errno));
+		return -MBOX_R_SYSTEM_ERROR;
+	}
+
+	/* Write to mbox status register */
+	rc = write(context->fds[MBOX_FD].fd, &context->bmc_events, 1);
+	if (rc != 1) {
+		MSG_ERR("Couldn't write to BMC status reg: %s\n",
+				strerror(errno));
+		return -MBOX_R_SYSTEM_ERROR;
+	}
+
+	/* Reset to start */
+	rc = lseek(context->fds[MBOX_FD].fd, 0, SEEK_SET);
+	if (rc) {
+		MSG_ERR("Couldn't reset MBOX offset to zero: %s\n",
+				strerror(errno));
+		return -MBOX_R_SYSTEM_ERROR;
+	}
+
+	return 0;
+}
+
+/*
+ * set_bmc_events() - Set BMC events
+ * @context:	The mbox context pointer
+ * @bmc_event:	The bits to set
+ * @write_back:	Whether to write back to the register -> will interrupt host
+ *
+ * Return:	0 on success otherwise negative error code
+ */
+int set_bmc_events(struct mbox_context *context, uint8_t bmc_event,
+		   bool write_back)
+{
+	uint8_t mask = 0x00;
+
+	switch (context->version) {
+	case API_VERSION_1:
+		mask = BMC_EVENT_V1_MASK;
+		break;
+	default:
+		mask = BMC_EVENT_V2_MASK;
+		break;
+	}
+
+	context->bmc_events |= (bmc_event & mask);
+	MSG_DBG("BMC Events set to: 0x%.2x\n", context->bmc_events);
+
+	return write_back ? write_bmc_event_reg(context) : 0;
+}
+
+/*
+ * clr_bmc_events() - Clear BMC events
+ * @context:	The mbox context pointer
+ * @bmc_event:	The bits to clear
+ * @write_back:	Whether to write back to the register -> will interrupt host
+ *
+ * Return:	0 on success otherwise negative error code
+ */
+int clr_bmc_events(struct mbox_context *context, uint8_t bmc_event,
+		   bool write_back)
+{
+	context->bmc_events &= ~bmc_event;
+	MSG_DBG("BMC Events clear to: 0x%.2x\n", context->bmc_events);
+
+	return write_back ? write_bmc_event_reg(context) : 0;
+}
+
+/* Command Handlers */
+
+/*
+ * Command: RESET_STATE
+ * Reset the LPC mapping to point back at the flash, or memory in case we're
+ * using a virtual pnor.
+ */
+int mbox_handle_reset(struct mbox_context *context,
+			     union mbox_regs *req, struct mbox_msg *resp)
+{
+	/* Host requested it -> No BMC Event */
+	windows_reset_all(context, NO_BMC_EVENT);
+	return lpc_reset(context);
+}
+
+/*
+ * get_suggested_timeout() - get the suggested timeout value in seconds
+ * @context:	The mbox context pointer
+ *
+ * Return:	Suggested timeout in seconds
+ */
+static uint16_t get_suggested_timeout(struct mbox_context *context)
+{
+	struct window_context *window = windows_find_largest(context);
+	uint32_t max_size_mb = window ? (window->size >> 20) : 0;
+	uint16_t ret;
+
+	ret = align_up(max_size_mb * FLASH_ACCESS_MS_PER_MB, 1000) / 1000;
+
+	MSG_DBG("Suggested Timeout: %us, max window size: %uMB, for %dms/MB\n",
+		ret, max_size_mb, FLASH_ACCESS_MS_PER_MB);
+	return ret;
+}
+
+/*
+ * Command: GET_MBOX_INFO
+ * Get the API version, default window size and block size
+ * We also set the LPC mapping to point to the reserved memory region here so
+ * this command must be called before any window manipulation
+ *
+ * V1:
+ * ARGS[0]: API Version
+ *
+ * RESP[0]: API Version
+ * RESP[1:2]: Default read window size (number of blocks)
+ * RESP[3:4]: Default write window size (number of blocks)
+ * RESP[5]: Block size (as shift)
+ *
+ * V2:
+ * ARGS[0]: API Version
+ *
+ * RESP[0]: API Version
+ * RESP[1:2]: Default read window size (number of blocks)
+ * RESP[3:4]: Default write window size (number of blocks)
+ * RESP[5]: Block size (as shift)
+ */
+int mbox_handle_mbox_info(struct mbox_context *context,
+				 union mbox_regs *req, struct mbox_msg *resp)
+{
+	uint8_t mbox_api_version = req->msg.args[0];
+	uint8_t old_api_version = context->version;
+	int rc;
+
+	/* Check we support the version requested */
+	if (mbox_api_version < API_MIN_VERSION)
+		return -MBOX_R_PARAM_ERROR;
+
+	if (mbox_api_version > API_MAX_VERSION)
+		mbox_api_version = API_MAX_VERSION;
+
+	context->version = mbox_api_version;
+	MSG_INFO("Using Protocol Version: %d\n", context->version);
+
+	/*
+	 * The reset state is currently to have the LPC bus point directly to
+	 * flash, since we got a mbox_info command we know the host can talk
+	 * mbox so point the LPC bus mapping to the reserved memory region now
+	 * so the host can access what we put in it.
+	 */
+	rc = lpc_map_memory(context);
+	if (rc < 0) {
+		return rc;
+	}
+
+	switch (context->version) {
+	case API_VERSION_1:
+		context->block_size_shift = BLOCK_SIZE_SHIFT_V1;
+		break;
+	default:
+		context->block_size_shift = log_2(context->mtd_info.erasesize);
+		break;
+	}
+	MSG_INFO("Block Size: 0x%.8x (shift: %u)\n",
+		 1 << context->block_size_shift, context->block_size_shift);
+
+	/* Now we know the blocksize we can allocate the window dirty_bytemap */
+	if (mbox_api_version != old_api_version) {
+		windows_alloc_dirty_bytemap(context);
+	}
+	/* Reset if we were V1 since this required exact window mapping */
+	if (old_api_version == API_VERSION_1) {
+		/*
+		 * This will only set the BMC event if there was a current
+		 * window -> In which case we are better off notifying the
+		 * host.
+		 */
+		windows_reset_all(context, SET_BMC_EVENT);
+	}
+
+	resp->args[0] = mbox_api_version;
+	if (context->version == API_VERSION_1) {
+		put_u16(&resp->args[1], context->windows.default_size >>
+					context->block_size_shift);
+		put_u16(&resp->args[3], context->windows.default_size >>
+					context->block_size_shift);
+	}
+	if (context->version >= API_VERSION_2) {
+		resp->args[5] = context->block_size_shift;
+		put_u16(&resp->args[6], get_suggested_timeout(context));
+	}
+
+	return 0;
+}
+
+/*
+ * Command: GET_FLASH_INFO
+ * Get the flash size and erase granularity
+ *
+ * V1:
+ * RESP[0:3]: Flash Size (bytes)
+ * RESP[4:7]: Erase Size (bytes)
+ * V2:
+ * RESP[0:1]: Flash Size (number of blocks)
+ * RESP[2:3]: Erase Size (number of blocks)
+ */
+int mbox_handle_flash_info(struct mbox_context *context,
+				  union mbox_regs *req, struct mbox_msg *resp)
+{
+	switch (context->version) {
+	case API_VERSION_1:
+		/* Both Sizes in Bytes */
+		put_u32(&resp->args[0], context->flash_size);
+		put_u32(&resp->args[4], context->mtd_info.erasesize);
+		break;
+	case API_VERSION_2:
+		/* Both Sizes in Block Size */
+		put_u16(&resp->args[0],
+			context->flash_size >> context->block_size_shift);
+		put_u16(&resp->args[2],
+			context->mtd_info.erasesize >>
+					context->block_size_shift);
+		break;
+	default:
+		MSG_ERR("API Version Not Valid - Invalid System State\n");
+		return -MBOX_R_SYSTEM_ERROR;
+	}
+
+	return 0;
+}
+
+/*
+ * get_lpc_addr_shifted() - Get lpc address of the current window
+ * @context:		The mbox context pointer
+ *
+ * Return:	The lpc address to access that offset shifted by block size
+ */
+static inline uint16_t get_lpc_addr_shifted(struct mbox_context *context)
+{
+	uint32_t lpc_addr, mem_offset;
+
+	/* Offset of the current window in the reserved memory region */
+	mem_offset = context->current->mem - context->mem;
+	/* Total LPC Address */
+	lpc_addr = context->lpc_base + mem_offset;
+
+	MSG_DBG("LPC address of current window: 0x%.8x\n", lpc_addr);
+
+	return lpc_addr >> context->block_size_shift;
+}
+
+/*
+ * Command: CREATE_READ_WINDOW
+ * Opens a read window
+ * First checks if any current window with the requested data, if so we just
+ * point the host to that. Otherwise we read the request data in from flash and
+ * point the host there.
+ *
+ * V1:
+ * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
+ *
+ * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
+ *
+ * V2:
+ * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
+ * ARGS[2:3]: Requested window size (number of blocks)
+ *
+ * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
+ * RESP[2:3]: Actual window size that the host can access (number of blocks)
+ */
+int mbox_handle_read_window(struct mbox_context *context,
+				   union mbox_regs *req, struct mbox_msg *resp)
+{
+	uint32_t flash_offset;
+	int rc;
+
+	/* Close the current window if there is one */
+	if (context->current) {
+		/* There is an implicit flush if it was a write window */
+		if (context->current_is_write) {
+			rc = mbox_handle_flush_window(context, NULL, NULL);
+			if (rc < 0) {
+				MSG_ERR("Couldn't Flush Write Window\n");
+				return rc;
+			}
+		}
+		windows_close_current(context, NO_BMC_EVENT, FLAGS_NONE);
+	}
+
+	/* Offset the host has requested */
+	flash_offset = get_u16(&req->msg.args[0]) << context->block_size_shift;
+	MSG_INFO("Host requested flash @ 0x%.8x\n", flash_offset);
+	/* Check if we have an existing window */
+	context->current = windows_search(context, flash_offset,
+					  context->version == API_VERSION_1);
+
+	if (!context->current) { /* No existing window */
+		MSG_DBG("No existing window which maps that flash offset\n");
+		rc = windows_create_map(context, &context->current, flash_offset,
+				       context->version == API_VERSION_1);
+		if (rc < 0) { /* Unable to map offset */
+			MSG_ERR("Couldn't create window mapping for offset 0x%.8x\n"
+				, flash_offset);
+			return rc;
+		}
+	}
+
+	MSG_INFO("Window @ %p for size 0x%.8x maps flash offset 0x%.8x\n",
+		 context->current->mem, context->current->size,
+		 context->current->flash_offset);
+
+	put_u16(&resp->args[0], get_lpc_addr_shifted(context));
+	if (context->version >= API_VERSION_2) {
+		put_u16(&resp->args[2], context->current->size >>
+					context->block_size_shift);
+		put_u16(&resp->args[4], context->current->flash_offset >>
+					context->block_size_shift);
+	}
+
+	context->current_is_write = false;
+
+	return 0;
+}
+
+/*
+ * Command: CREATE_WRITE_WINDOW
+ * Opens a write window
+ * First checks if any current window with the requested data, if so we just
+ * point the host to that. Otherwise we read the request data in from flash and
+ * point the host there.
+ *
+ * V1:
+ * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
+ *
+ * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
+ *
+ * V2:
+ * ARGS[0:1]: Window Location as Offset into Flash (number of blocks)
+ * ARGS[2:3]: Requested window size (number of blocks)
+ *
+ * RESP[0:1]: LPC bus address for host to access this window (number of blocks)
+ * RESP[2:3]: Actual window size that was mapped/host can access (n.o. blocks)
+ */
+int mbox_handle_write_window(struct mbox_context *context,
+				    union mbox_regs *req, struct mbox_msg *resp)
+{
+	int rc;
+
+	/*
+	 * This is very similar to opening a read window (exactly the same
+	 * for now infact)
+	 */
+	rc = mbox_handle_read_window(context, req, resp);
+	if (rc < 0) {
+		return rc;
+	}
+
+	context->current_is_write = true;
+	return rc;
+}
+
+/*
+ * Commands: MARK_WRITE_DIRTY
+ * Marks a portion of the current (write) window dirty, informing the daemon
+ * that is has been written to and thus must be at some point written to the
+ * backing store
+ * These changes aren't written back to the backing store unless flush is then
+ * called or the window closed
+ *
+ * V1:
+ * ARGS[0:1]: Where within flash to start (number of blocks)
+ * ARGS[2:5]: Number to mark dirty (number of bytes)
+ *
+ * V2:
+ * ARGS[0:1]: Where within window to start (number of blocks)
+ * ARGS[2:3]: Number to mark dirty (number of blocks)
+ */
+int mbox_handle_dirty_window(struct mbox_context *context,
+				    union mbox_regs *req, struct mbox_msg *resp)
+{
+	uint32_t offset, size;
+	int rc;
+
+	if (!(context->current && context->current_is_write)) {
+		MSG_ERR("Tried to call mark dirty without open write window\n");
+		return context->version >= API_VERSION_2 ? -MBOX_R_WINDOW_ERROR
+							 : -MBOX_R_PARAM_ERROR;
+	}
+
+	offset = get_u16(&req->msg.args[0]);
+
+	if (context->version >= API_VERSION_2) {
+		size = get_u16(&req->msg.args[2]);
+	} else {
+		uint32_t off;
+		/* For V1 offset given relative to flash - we want the window */
+		off = offset - ((context->current->flash_offset) >>
+				context->block_size_shift);
+		if (off > offset) { /* Underflow - before current window */
+			MSG_ERR("Tried to mark dirty before start of window\n");
+			MSG_ERR("requested offset: 0x%x window start: 0x%x\n",
+				offset << context->block_size_shift,
+				context->current->flash_offset);
+			return -MBOX_R_PARAM_ERROR;
+		}
+		offset = off;
+		size = get_u32(&req->msg.args[2]);
+		/*
+		 * We only track dirty at the block level.
+		 * For protocol V1 we can get away with just marking the whole
+		 * block dirty.
+		 */
+		size = align_up(size, 1 << context->block_size_shift);
+		size >>= context->block_size_shift;
+	}
+
+	MSG_INFO("Dirty window @ 0x%.8x for 0x%.8x\n",
+		 offset << context->block_size_shift,
+		 size << context->block_size_shift);
+
+	rc = window_set_bytemap(context, context->current, offset, size,
+				  WINDOW_DIRTY);
+	if (rc < 0) {
+		return (rc == -EACCES) ? -MBOX_R_PARAM_ERROR
+				       : -MBOX_R_SYSTEM_ERROR;
+	}
+
+	return rc;
+}
+
+/*
+ * Commands: MARK_WRITE_ERASE
+ * Erases a portion of the current window
+ * These changes aren't written back to the backing store unless flush is then
+ * called or the window closed
+ *
+ * V1:
+ * Unimplemented
+ *
+ * V2:
+ * ARGS[0:1]: Where within window to start (number of blocks)
+ * ARGS[2:3]: Number to erase (number of blocks)
+ */
+int mbox_handle_erase_window(struct mbox_context *context,
+				    union mbox_regs *req, struct mbox_msg *resp)
+{
+	uint32_t offset, size;
+	int rc;
+
+	if (context->version < API_VERSION_2) {
+		MSG_ERR("Protocol Version invalid for Erase Command\n");
+		return -MBOX_R_PARAM_ERROR;
+	}
+
+	if (!(context->current && context->current_is_write)) {
+		MSG_ERR("Tried to call erase without open write window\n");
+		return -MBOX_R_WINDOW_ERROR;
+	}
+
+	offset = get_u16(&req->msg.args[0]);
+	size = get_u16(&req->msg.args[2]);
+
+	MSG_INFO("Erase window @ 0x%.8x for 0x%.8x\n",
+		 offset << context->block_size_shift,
+		 size << context->block_size_shift);
+
+	rc = window_set_bytemap(context, context->current, offset, size,
+				WINDOW_ERASED);
+	if (rc < 0) {
+		return (rc == -EACCES) ? -MBOX_R_PARAM_ERROR
+				       : -MBOX_R_SYSTEM_ERROR;
+	}
+
+	/* Write 0xFF to mem -> This ensures consistency between flash & ram */
+	memset(context->current->mem + (offset << context->block_size_shift),
+	       0xFF, size << context->block_size_shift);
+
+	return 0;
+}
+
+/*
+ * Command: WRITE_FLUSH
+ * Flushes any dirty or erased blocks in the current window back to the backing
+ * store
+ * NOTE: For V1 this behaves much the same as the dirty command in that it
+ * takes an offset and number of blocks to dirty, then also performs a flush as
+ * part of the same command. For V2 this will only flush blocks already marked
+ * dirty/erased with the appropriate commands and doesn't take any arguments
+ * directly.
+ *
+ * V1:
+ * ARGS[0:1]: Where within window to start (number of blocks)
+ * ARGS[2:5]: Number to mark dirty (number of bytes)
+ *
+ * V2:
+ * NONE
+ */
+int mbox_handle_flush_window(struct mbox_context *context,
+				    union mbox_regs *req, struct mbox_msg *resp)
+{
+	int rc, i, offset, count;
+	uint8_t prev;
+
+	if (!(context->current && context->current_is_write)) {
+		MSG_ERR("Tried to call flush without open write window\n");
+		return context->version >= API_VERSION_2 ? -MBOX_R_WINDOW_ERROR
+							 : -MBOX_R_PARAM_ERROR;
+	}
+
+	/*
+	 * For V1 the Flush command acts much the same as the dirty command
+	 * except with a flush as well. Only do this on an actual flush
+	 * command not when we call flush because we've implicitly closed a
+	 * window because we might not have the required args in req.
+	 */
+	if (context->version == API_VERSION_1 && req &&
+			req->msg.command == MBOX_C_WRITE_FLUSH) {
+		rc = mbox_handle_dirty_window(context, req, NULL);
+		if (rc < 0) {
+			return rc;
+		}
+	}
+
+	offset = 0;
+	count = 0;
+	prev = WINDOW_CLEAN;
+
+	MSG_INFO("Flush window @ %p for size 0x%.8x which maps flash @ 0x%.8x\n",
+		 context->current->mem, context->current->size,
+		 context->current->flash_offset);
+
+	/*
+	 * We look for streaks of the same type and keep a count, when the type
+	 * (dirty/erased) changes we perform the required action on the backing
+	 * store and update the current streak-type
+	 */
+	for (i = 0; i < (context->current->size >> context->block_size_shift);
+			i++) {
+		uint8_t cur = context->current->dirty_bmap[i];
+		if (cur != WINDOW_CLEAN) {
+			if (cur == prev) { /* Same as previous block, incrmnt */
+				count++;
+			} else if (prev == WINDOW_CLEAN) { /* Start of run */
+				offset = i;
+				count++;
+			} else { /* Change in streak type */
+				rc = window_flush(context, offset, count,
+						       prev);
+				if (rc < 0) {
+					return rc;
+				}
+				offset = i;
+				count = 1;
+			}
+		} else {
+			if (prev != WINDOW_CLEAN) { /* End of a streak */
+				rc = window_flush(context, offset, count,
+						       prev);
+				if (rc < 0) {
+					return rc;
+				}
+				offset = 0;
+				count = 0;
+			}
+		}
+		prev = cur;
+	}
+
+	if (prev != WINDOW_CLEAN) { /* Still the last streak to write */
+		rc = window_flush(context, offset, count, prev);
+		if (rc < 0) {
+			return rc;
+		}
+	}
+
+	/* Clear the dirty bytemap since we have written back all changes */
+	rc = window_set_bytemap(context, context->current, 0,
+				  context->current->size >>
+				  context->block_size_shift,
+				  WINDOW_CLEAN);
+	if (rc < 0) {
+		return (rc == -EACCES) ? -MBOX_R_PARAM_ERROR
+				       : -MBOX_R_SYSTEM_ERROR;
+	}
+
+	return rc;
+}
+
+/*
+ * Command: CLOSE_WINDOW
+ * Close the current window
+ * NOTE: There is an implicit flush
+ *
+ * V1:
+ * NONE
+ *
+ * V2:
+ * ARGS[0]: FLAGS
+ */
+int mbox_handle_close_window(struct mbox_context *context,
+				    union mbox_regs *req, struct mbox_msg *resp)
+{
+	uint8_t flags = 0;
+	int rc;
+
+	/* Close the current window if there is one */
+	if (context->current) {
+		/* There is an implicit flush if it was a write window */
+		if (context->current_is_write) {
+			rc = mbox_handle_flush_window(context, NULL, NULL);
+			if (rc < 0) {
+				MSG_ERR("Couldn't Flush Write Window\n");
+				return rc;
+			}
+		}
+
+		if (context->version >= API_VERSION_2) {
+			flags = req->msg.args[0];
+		}
+
+		/* Host asked for it -> Don't set the BMC Event */
+		windows_close_current(context, NO_BMC_EVENT, flags);
+	}
+
+	return 0;
+}
+
+/*
+ * Command: BMC_EVENT_ACK
+ * Sent by the host to acknowledge BMC events supplied in mailbox register 15
+ *
+ * ARGS[0]: Bitmap of bits to ack (by clearing)
+ */
+int mbox_handle_ack(struct mbox_context *context, union mbox_regs *req,
+			   struct mbox_msg *resp)
+{
+	uint8_t bmc_events = req->msg.args[0];
+
+	return clr_bmc_events(context, (bmc_events & BMC_EVENT_ACK_MASK),
+			      SET_BMC_EVENT);
+}
+
+/*
+ * check_req_valid() - Check if the given request is a valid mbox request
+ * @context:	The mbox context pointer
+ * @cmd:	The request registers
+ *
+ * Return:	0 if request is valid otherwise negative error code
+ */
+static int check_req_valid(struct mbox_context *context, union mbox_regs *req)
+{
+	uint8_t cmd = req->msg.command;
+	uint8_t seq = req->msg.seq;
+
+	if (cmd > NUM_MBOX_CMDS) {
+		MSG_ERR("Unknown mbox command: %d\n", cmd);
+		return -MBOX_R_PARAM_ERROR;
+	}
+
+	if (seq == context->prev_seq && cmd != MBOX_C_GET_MBOX_INFO) {
+		MSG_ERR("Invalid sequence number: %d, previous: %d\n", seq,
+			context->prev_seq);
+		return -MBOX_R_SEQ_ERROR;
+	}
+
+	if (context->state & STATE_SUSPENDED) {
+		if (cmd != MBOX_C_GET_MBOX_INFO && cmd != MBOX_C_ACK) {
+			MSG_ERR("Cannot use that cmd while suspended: %d\n",
+				cmd);
+			return context->version >= API_VERSION_2 ? -MBOX_R_BUSY
+						: -MBOX_R_PARAM_ERROR;
+		}
+	}
+
+	if (!(context->state & MAPS_MEM)) {
+		if (cmd != MBOX_C_RESET_STATE && cmd != MBOX_C_GET_MBOX_INFO
+					      && cmd != MBOX_C_ACK) {
+			MSG_ERR("Must call GET_MBOX_INFO before %d\n", cmd);
+			return -MBOX_R_PARAM_ERROR;
+		}
+	}
+
+	return 0;
+}
+
+static const mboxd_mbox_handler mbox_handlers[] = {
+	mbox_handle_reset,
+	mbox_handle_mbox_info,
+	mbox_handle_flash_info,
+	mbox_handle_read_window,
+	mbox_handle_close_window,
+	mbox_handle_write_window,
+	mbox_handle_dirty_window,
+	mbox_handle_flush_window,
+	mbox_handle_ack,
+	mbox_handle_erase_window
+};
+
+/*
+ * handle_mbox_req() - Handle an incoming mbox command request
+ * @context:	The mbox context pointer
+ * @req:	The mbox request message
+ *
+ * Return:	0 if handled successfully otherwise negative error code
+ */
+static int handle_mbox_req(struct mbox_context *context, union mbox_regs *req)
+{
+	struct mbox_msg resp = {
+		.command = req->msg.command,
+		.seq = req->msg.seq,
+		.args = { 0 },
+		.response = MBOX_R_SUCCESS
+	};
+	int rc = 0, len, i;
+
+	MSG_INFO("Received MBOX command: %u\n", req->msg.command);
+	rc = check_req_valid(context, req);
+	if (rc < 0) {
+		resp.response = -rc;
+	} else {
+		/* Commands start at 1 so we have to subtract 1 from the cmd */
+		mboxd_mbox_handler h = context->handlers[req->msg.command - 1];
+		rc = h(context, req, &resp);
+		if (rc < 0) {
+			MSG_ERR("Error handling mbox cmd: %d\n",
+				req->msg.command);
+			resp.response = -rc;
+		}
+	}
+
+	context->prev_seq = req->msg.seq;
+
+	MSG_DBG("Writing MBOX response:\n");
+	MSG_DBG("MBOX cmd: %u\n", resp.command);
+	MSG_DBG("MBOX seq: %u\n", resp.seq);
+	for (i = 0; i < MBOX_ARGS_BYTES; i++) {
+		MSG_DBG("MBOX arg[%d]: 0x%.2x\n", i, resp.args[i]);
+	}
+	MSG_INFO("Writing MBOX response: %u\n", resp.response);
+	len = write(context->fds[MBOX_FD].fd, &resp, sizeof(resp));
+	if (len < sizeof(resp)) {
+		MSG_ERR("Didn't write the full response\n");
+		rc = -errno;
+	}
+
+	return rc;
+}
+
+/*
+ * get_message() - Read an mbox request message from the mbox registers
+ * @context:	The mbox context pointer
+ * @msg:	Where to put the received message
+ *
+ * Return:	0 if read successfully otherwise negative error code
+ */
+static int get_message(struct mbox_context *context, union mbox_regs *msg)
+{
+	int rc, i;
+
+	rc = read(context->fds[MBOX_FD].fd, msg, sizeof(msg->raw));
+	if (rc < 0) {
+		MSG_ERR("Couldn't read: %s\n", strerror(errno));
+		return -errno;
+	} else if (rc < sizeof(msg->raw)) {
+		MSG_ERR("Short read: %d expecting %zu\n", rc, sizeof(msg->raw));
+		return -1;
+	}
+
+	MSG_DBG("Received MBOX request:\n");
+	MSG_DBG("MBOX cmd: %u\n", msg->msg.command);
+	MSG_DBG("MBOX seq: %u\n", msg->msg.seq);
+	for (i = 0; i < MBOX_ARGS_BYTES; i++) {
+		MSG_DBG("MBOX arg[%d]: 0x%.2x\n", i, msg->msg.args[i]);
+	}
+
+	return 0;
+}
+
+/*
+ * dispatch_mbox() - handle an mbox interrupt
+ * @context:	The mbox context pointer
+ *
+ * Return:	0 if handled successfully otherwise negative error code
+ */
+int dispatch_mbox(struct mbox_context *context)
+{
+	int rc = 0;
+	union mbox_regs req = { 0 };
+
+	assert(context);
+
+	rc = get_message(context, &req);
+	if (rc) {
+		return rc;
+	}
+
+	return handle_mbox_req(context, &req);
+}
+
+int __init_mbox_dev(struct mbox_context *context, const char *path)
+{
+	int fd;
+
+	context->handlers = mbox_handlers;
+
+	/* Open MBOX Device */
+	fd = open(path, O_RDWR | O_NONBLOCK);
+	if (fd < 0) {
+		MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n",
+			path, strerror(errno));
+		return -errno;
+	}
+	MSG_DBG("Opened mbox dev: %s\n", path);
+
+	context->fds[MBOX_FD].fd = fd;
+
+	return 0;
+}
+
+int init_mbox_dev(struct mbox_context *context)
+{
+	return __init_mbox_dev(context, MBOX_HOST_PATH);
+}
+
+void free_mbox_dev(struct mbox_context *context)
+{
+	close(context->fds[MBOX_FD].fd);
+}
