diff --git a/mboxd_msg.c b/mboxd_msg.c
new file mode 100644
index 0000000..179af60
--- /dev/null
+++ b/mboxd_msg.c
@@ -0,0 +1,802 @@
+/*
+ * Mailbox Daemon MBOX Message Helpers
+ *
+ * Copyright 2016 IBM
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#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 "mboxd_msg.h"
+#include "mboxd_windows.h"
+#include "mboxd_lpc.h"
+
+static int mbox_handle_flush_window(struct mbox_context *context, union mbox_regs *req,
+			     struct mbox_msg *resp);
+
+typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
+				  struct mbox_msg *);
+
+/*
+ * 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);
+
+	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;
+
+	return write_back ? write_bmc_event_reg(context) : 0;
+}
+
+/* Command Handlers */
+
+/*
+ * Command: RESET_STATE
+ * Reset the LPC mapping to point back at the flash
+ */
+static int mbox_handle_reset(struct mbox_context *context,
+			     union mbox_regs *req, struct mbox_msg *resp)
+{
+	/* Host requested it -> No BMC Event */
+	reset_all_windows(context, NO_BMC_EVENT);
+	return point_to_flash(context);
+}
+
+/*
+ * 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)
+ */
+static 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 ||
+	    mbox_api_version > API_MAX_VERSION) {
+		return -MBOX_R_PARAM_ERROR;
+	}
+	context->version = mbox_api_version;
+	MSG_OUT("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 = point_to_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_OUT("Block Size Shift: %d\n", context->block_size_shift);
+
+	/* Now we know the blocksize we can allocate the window dirty_bytemap */
+	if (mbox_api_version != old_api_version) {
+		alloc_window_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.
+		 */
+		reset_all_windows(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;
+	}
+
+	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)
+ */
+static 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;
+		break;
+	}
+
+	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;
+
+	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)
+ */
+static 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;
+			}
+		}
+		close_current_window(context, NO_BMC_EVENT, FLAGS_NONE);
+	}
+
+	/* Offset the host has requested */
+	flash_offset = get_u16(&req->msg.args[0]) << context->block_size_shift;
+	MSG_OUT("Host Requested Flash @ 0x%.8x\n", flash_offset);
+	/* Check if we have an existing window */
+	context->current = search_windows(context, flash_offset,
+					  context->version == API_VERSION_1);
+
+	if (!context->current) { /* No existing window */
+		rc = create_map_window(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;
+		}
+	}
+
+	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)
+ */
+static 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)
+ */
+static int mbox_handle_dirty_window(struct mbox_context *context,
+				    union mbox_regs *req, struct mbox_msg *resp)
+{
+	uint32_t offset, size;
+
+	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;
+	}
+
+	return set_window_bytemap(context, context->current, offset, size,
+				  WINDOW_DIRTY);
+}
+
+/*
+ * 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)
+ */
+static 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]);
+
+	rc = set_window_bytemap(context, context->current, offset, size,
+				WINDOW_ERASED);
+	if (rc < 0) {
+		return rc;
+	}
+
+	/* 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
+ */
+static 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;
+
+	/*
+	 * 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 = write_from_window(context, offset, count,
+						       prev);
+				if (rc < 0) {
+					return rc;
+				}
+				offset = i;
+				count = 1;
+			}
+		} else {
+			if (prev != WINDOW_CLEAN) { /* End of a streak */
+				rc = write_from_window(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 = write_from_window(context, offset, count, prev);
+		if (rc < 0) {
+			return rc;
+		}
+	}
+
+	/* Clear the dirty bytemap since we have written back all changes */
+	return set_window_bytemap(context, context->current, 0,
+				  context->current->size >>
+				  context->block_size_shift,
+				  WINDOW_CLEAN);
+}
+
+/*
+ * Command: CLOSE_WINDOW
+ * Close the current window
+ * NOTE: There is an implicit flush
+ *
+ * V1:
+ * NONE
+ *
+ * V2:
+ * ARGS[0]: FLAGS
+ */
+static 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 */
+		close_current_window(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)
+ */
+static 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_cmd_valid() - Check if the given command is a valid mbox command code
+ * @context:	The mbox context pointer
+ * @cmd:	The command code
+ *
+ * Return:	0 if command is valid otherwise negative error code
+ */
+static int check_cmd_valid(struct mbox_context *context, int cmd)
+{
+	if (cmd <= 0 || cmd > NUM_MBOX_CMDS) {
+		MSG_ERR("UNKNOWN MBOX COMMAND: %d\n", cmd);
+		return -MBOX_R_PARAM_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 that cmd: %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;
+
+	MSG_OUT("Got data in with command %d\n", req->msg.command);
+	rc = check_cmd_valid(context, req->msg.command);
+	if (rc < 0) {
+		resp.response = -rc;
+	} else {
+		/* Commands start at 1 so we have to subtract 1 from the cmd */
+		rc = mbox_handlers[req->msg.command - 1](context, req, &resp);
+		if (rc < 0) {
+			MSG_ERR("Error handling mbox cmd: %d\n",
+				req->msg.command);
+			resp.response = -rc;
+		}
+	}
+
+	MSG_OUT("Writing response to MBOX regs: %d\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;
+
+	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;
+	}
+
+	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);
+
+	MSG_OUT("Dispatched to mbox\n");
+	rc = get_message(context, &req);
+	if (rc) {
+		return rc;
+	}
+
+	return handle_mbox_req(context, &req);
+}
+
+int init_mbox_dev(struct mbox_context *context)
+{
+	int fd;
+
+	/* Open MBOX Device */
+	fd = open(MBOX_HOST_PATH, O_RDWR | O_NONBLOCK);
+	if (fd < 0) {
+		MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n",
+			MBOX_HOST_PATH, strerror(errno));
+		return -errno;
+	}
+
+	context->fds[MBOX_FD].fd = fd;
+
+	return 0;
+}
+
+void free_mbox_dev(struct mbox_context *context)
+{
+	close(context->fds[MBOX_FD].fd);
+}
