protocol: Add create_read_window

Change-Id: I82e9e69861163fb1ae35313fcfee37e03be69f65
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/mbox.h b/mbox.h
index 5fd074b..3676825 100644
--- a/mbox.h
+++ b/mbox.h
@@ -133,6 +133,7 @@
 };
 
 struct mbox_context;
+
 typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
 				  struct mbox_msg *);
 
diff --git a/protocol.c b/protocol.c
index 066c5b2..96c804f 100644
--- a/protocol.c
+++ b/protocol.c
@@ -63,6 +63,72 @@
 }
 
 /*
+ * 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;
+}
+
+int protocol_v1_create_read_window(struct mbox_context *context,
+				   struct protocol_create_window *io)
+{
+	int rc;
+	uint32_t offset = io->req.offset << context->block_size_shift;
+
+	/* 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 */
+	MSG_INFO("Host requested flash @ 0x%.8x\n", offset);
+	/* Check if we have an existing window */
+	context->current = windows_search(context, 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,
+				       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",
+				io->req.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);
+
+	io->resp.lpc_address = get_lpc_addr_shifted(context);
+
+	return 0;
+}
+
+/*
  * get_suggested_timeout() - get the suggested timeout value in seconds
  * @context:	The mbox context pointer
  *
@@ -126,16 +192,35 @@
 	return 0;
 }
 
+int protocol_v2_create_read_window(struct mbox_context *context,
+				   struct protocol_create_window *io)
+{
+	int rc;
+
+	rc = protocol_v1_create_read_window(context, io);
+	if (rc < 0)
+		return rc;
+
+	io->resp.size = context->current->size >> context->block_size_shift;
+	io->resp.offset = context->current->flash_offset >>
+					context->block_size_shift;
+
+	return 0;
+}
+
 static const struct protocol_ops protocol_ops_v1 = {
 	.reset = protocol_v1_reset,
 	.get_info = protocol_v1_get_info,
 	.get_flash_info = protocol_v1_get_flash_info,
+	.create_read_window = protocol_v1_create_read_window,
 };
 
 static const struct protocol_ops protocol_ops_v2 = {
 	.reset = protocol_v1_reset,
 	.get_info = protocol_v2_get_info,
 	.get_flash_info = protocol_v2_get_flash_info,
+	.create_read_window = protocol_v2_create_read_window,
+
 };
 
 static const struct protocol_ops *protocol_ops_map[] = {
diff --git a/protocol.h b/protocol.h
index 9503812..7608b0e 100644
--- a/protocol.h
+++ b/protocol.h
@@ -44,12 +44,27 @@
 	} resp;
 };
 
+struct protocol_create_window {
+	struct {
+		uint16_t offset;
+		uint16_t size;
+		uint8_t id;
+	} req;
+	struct {
+		uint16_t lpc_address;
+		uint16_t size;
+		uint16_t offset;
+	} resp;
+};
+
 struct protocol_ops {
 	int (*reset)(struct mbox_context *context);
 	int (*get_info)(struct mbox_context *context,
 			struct protocol_get_info *io);
 	int (*get_flash_info)(struct mbox_context *context,
 			      struct protocol_get_flash_info *io);
+	int (*create_read_window)(struct mbox_context *context,
+				  struct protocol_create_window *io);
 };
 
 int protocol_init(struct mbox_context *context);
@@ -63,11 +78,15 @@
 			 struct protocol_get_info *io);
 int protocol_v1_get_flash_info(struct mbox_context *context,
 			       struct protocol_get_flash_info *io);
+int protocol_v1_create_read_window(struct mbox_context *context,
+				   struct protocol_create_window *io);
 
 /* Protocol v2 */
 int protocol_v2_get_info(struct mbox_context *context,
 			 struct protocol_get_info *io);
 int protocol_v2_get_flash_info(struct mbox_context *context,
 			       struct protocol_get_flash_info *io);
+int protocol_v2_create_read_window(struct mbox_context *context,
+				   struct protocol_create_window *io);
 
 #endif /* PROTOCOL_H */
diff --git a/transport_mbox.c b/transport_mbox.c
index 873f952..a4e7efa 100644
--- a/transport_mbox.c
+++ b/transport_mbox.c
@@ -307,50 +307,20 @@
 int mbox_handle_read_window(struct mbox_context *context,
 				   union mbox_regs *req, struct mbox_msg *resp)
 {
-	uint32_t flash_offset;
+	struct protocol_create_window io;
 	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);
+	io.req.offset = get_u16(&req->msg.args[0]);
+
+	rc = context->protocol->create_read_window(context, &io);
+	if (rc < 0) {
+		return mbox_xlate_errno(context, rc);
 	}
 
-	/* 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));
+	put_u16(&resp->args[0], io.resp.lpc_address);
 	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);
+		put_u16(&resp->args[2], io.resp.size);
+		put_u16(&resp->args[4], io.resp.offset);
 	}
 
 	context->current_is_write = false;