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

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

Checks

Context Check Description
snowpatch_ozlabs/make_check success Test make_check on branch master
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied

Commit Message

Vasant Hegde Aug. 16, 2018, 8:57 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 calls SBE S0 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>
---
 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 8f00d85e4..30b0c5e7f 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 184898cd6..4ae5f81ad 100644
--- a/hw/sbe-p9.c
+++ b/hw/sbe-p9.c
@@ -961,6 +961,9 @@  void __attribute__((noreturn)) p9_sbe_terminate(const char *msg)
 	if (!dt_find_by_path(opal_node, "dump"))
 		goto out_reboot;
 
+	/* 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);
 	}