[v4,18/18] mbox: Reset bmc mbox in MPIPL path

Message ID 20180703061727.8789-19-hegdevasant@linux.vnet.ibm.com
State New
Headers show
Series
  • MPIPL support
Related show

Commit Message

Vasant Hegde July 3, 2018, 6:17 a.m.
During boot SBE and early hostboot does not use MBOX protocol to get image
from PNOR. Instead it expects PNOR TOC and Hostboot Boot Loader to be
availabe at particular address in LPC bus. mbox daemon in BMC side takes care
of this during normal boot. Once boot is complete mbox daemon swiches to
normal mode.

During normal reboot, BMC side mbox daemon gets notification and takes care of
loading PNOR TOC and HBBL to LPC bus again.

In MPIPL path, OPAL call SBE S0/S1 interrupt to initiate MPIPL. BMC will not be
aware of this. But SBE expects PNOR TOC and HBBL to be available in LPC bus at
predefined address. Hence call MBOX Reset from OPAL in assert path.

Note that this is workaround to get mbox working for now. Long term solution is
to use a bit in the Host Status byte of the mbox protocol's memory layout to
indicate to mboxd that the host is preparing for reboot. We will implement once
BMC side implementation is complete.

CC: Andrew Jeffery <andrew@aj.id.au>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
---
Changes in 4:
  No changes from previous version.

-Vasant

 core/flash.c          |  9 +++++++++
 hw/sbe-p9.c           |  3 +++
 include/skiboot.h     |  1 +
 libflash/mbox-flash.c | 23 +++++++++++++++++++++++
 4 files changed, 36 insertions(+)

Patch

diff --git a/core/flash.c b/core/flash.c
index e3be57613..4a9014d87 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -23,6 +23,7 @@ 
 #include <device.h>
 #include <libflash/libflash.h>
 #include <libflash/libffs.h>
+#include <libflash/mbox-flash.h>
 #include <libflash/blocklevel.h>
 #include <libflash/ecc.h>
 #include <libstb/secureboot.h>
@@ -76,6 +77,14 @@  void flash_release(void)
 	unlock(&flash_lock);
 }
 
+void flash_unregister(void)
+{
+	struct blocklevel_device *bl = system_flash->bl;
+
+	if (dt_find_compatible_node(dt_root, NULL, "mbox"))
+		mbox_flash_exit(bl);
+}
+
 static int flash_nvram_info(uint32_t *total_size)
 {
 	int rc;
diff --git a/hw/sbe-p9.c b/hw/sbe-p9.c
index 6e2f8c52a..076005177 100644
--- a/hw/sbe-p9.c
+++ b/hw/sbe-p9.c
@@ -958,6 +958,9 @@  void __attribute__((noreturn)) p9_sbe_terminate(const char *msg)
 	u64 wait_tb;
 	struct dt_node *xn;
 
+	/* Unregister flash. It will request BMC MBOX reset */
+	flash_unregister();
+
 	dt_for_each_compatible(dt_root, xn, "ibm,xscom") {
 		chip_id = dt_get_chip_id(xn);
 
diff --git a/include/skiboot.h b/include/skiboot.h
index bba76c12c..262e618fb 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -218,6 +218,7 @@  extern int flash_start_preload_resource(enum resource_id id, uint32_t subid,
 extern int flash_resource_loaded(enum resource_id id, uint32_t idx);
 extern bool flash_reserve(void);
 extern void flash_release(void);
+extern void flash_unregister(void);
 #define FLASH_SUBPART_ALIGNMENT 0x1000
 #define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT
 extern int flash_subpart_info(void *part_header, uint32_t header_len,
diff --git a/libflash/mbox-flash.c b/libflash/mbox-flash.c
index 3239be964..559647e80 100644
--- a/libflash/mbox-flash.c
+++ b/libflash/mbox-flash.c
@@ -816,6 +816,27 @@  static int mbox_flash_read(struct blocklevel_device *bl, uint64_t pos,
 	return rc;
 }
 
+static int 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);
+
+	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 rc;
+	}
+	if (wait_for_bmc(mbox_flash, mbox_flash->timeout)) {
+		prlog(PR_ERR, "Error waiting for BMC\n");
+		return rc;
+	}
+
+	return OPAL_SUCCESS;
+}
+
 static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,
 		uint64_t *total_size, uint32_t *erase_granule)
 {
@@ -1165,6 +1186,8 @@  void mbox_flash_exit(struct blocklevel_device *bl)
 {
 	struct mbox_flash_data *mbox_flash;
 	if (bl) {
+		mbox_flash_reset(bl);
+
 		mbox_flash = container_of(bl, struct mbox_flash_data, bl);
 		free(mbox_flash);
 	}