[Skiboot] [RFC PATCH 16/16] Add support to trigger memory preserving IPL on BMC system
Vasant Hegde
hegdevasant at linux.vnet.ibm.com
Tue Apr 3 22:04:47 AEST 2018
On FSP based system we call 'attn' instruction. FSP detects attention and
initiates memory preserving IPL. On BMC system we have to call SBE s0/s1
interrupt to initiate memory preserving IPL.
This patch adds support to call s0/s1 interrupt.
Flow:
- s1 interrupt on slave chip SBE
- s0 interrupt on master chip SBE
Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
---
hw/ipmi/ipmi-attn.c | 4 ++++
hw/sbe-p9.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
include/sbe-p9.h | 10 ++++++++++
3 files changed, 62 insertions(+)
diff --git a/hw/ipmi/ipmi-attn.c b/hw/ipmi/ipmi-attn.c
index 8ff872c62..15aeace56 100644
--- a/hw/ipmi/ipmi-attn.c
+++ b/hw/ipmi/ipmi-attn.c
@@ -19,6 +19,7 @@
#include <pel.h>
#include <platform.h>
#include <processor.h>
+#include <sbe-p9.h>
#include <skiboot.h>
#include <stack.h>
#include <timebase.h>
@@ -65,6 +66,9 @@ static void ipmi_log_terminate_event(const char *msg)
void __attribute__((noreturn)) ipmi_terminate(const char *msg)
{
+ /* On P9 BMC system this will trigger fadump */
+ p9_sbe_terminate();
+
/* Terminate called before initializing IPMI (early abort) */
if (!ipmi_present()) {
if (platform.cec_reboot)
diff --git a/hw/sbe-p9.c b/hw/sbe-p9.c
index e2566bf26..9c8253b28 100644
--- a/hw/sbe-p9.c
+++ b/hw/sbe-p9.c
@@ -828,3 +828,51 @@ void p9_sbe_init(void)
/* Initiate SBE timeout poller */
opal_add_poller(p9_sbe_timeout_poll, NULL);
}
+
+/* Terminate and initiate MPIPL */
+void p9_sbe_terminate(void)
+{
+ uint32_t chip_id;
+ uint32_t primary_chip = -1;
+ int rc;
+ struct dt_node *xn;
+
+ if (proc_gen < proc_gen_p9)
+ return;
+
+ dt_for_each_compatible(dt_root, xn, "ibm,xscom") {
+ chip_id = dt_get_chip_id(xn);
+
+ if (dt_has_node_property(xn, "primary", NULL)) {
+ primary_chip = chip_id;
+ continue;
+ }
+
+ rc = xscom_write(chip_id,
+ SBE_CONTROL_REG_RW, SBE_CONTROL_REG_S1);
+ /* Initiate normal reboot */
+ if (rc) {
+ prlog(PR_ERR, "Failed to write S1 interrupt [chip id = %x]\n",
+ chip_id);
+ return;
+ }
+ }
+
+ if (primary_chip == -1) {
+ prlog(PR_ERR, "Master chip ID not found.\n");
+ return;
+ }
+
+ /* Write S0 interrupt on master SBE */
+ rc = xscom_write(primary_chip,
+ SBE_CONTROL_REG_RW, SBE_CONTROL_REG_S0);
+ /* Initiate normal reboot */
+ if (rc) {
+ prlog(PR_ERR, "Failed to write S0 interrupt [chip id = %x]\n",
+ primary_chip);
+ return;
+ }
+
+ while (1)
+ time_wait_ms(100);
+}
diff --git a/include/sbe-p9.h b/include/sbe-p9.h
index b7ca8dba8..4df799cd5 100644
--- a/include/sbe-p9.h
+++ b/include/sbe-p9.h
@@ -103,6 +103,13 @@
#define SBE_HOST_TIMER_EXPIRY PPC_BIT(14)
#define SBE_HOST_RESPONSE_MASK (PPC_BITMASK(0, 4) | SBE_HOST_TIMER_EXPIRY)
+/* SBE Control Register */
+#define SBE_CONTROL_REG_RW 0x00050008
+
+/* SBE interrupt s0/s1 bits */
+#define SBE_CONTROL_REG_S0 PPC_BIT(14)
+#define SBE_CONTROL_REG_S1 PPC_BIT(15)
+
/* SBE Target Type */
#define SBE_TARGET_TYPE_PROC 0x00
#define SBE_TARGET_TYPE_EX 0x01
@@ -242,4 +249,7 @@ extern void p9_sbe_update_timer_expiry(uint64_t new_target);
/* Send skiboot relocated base address to SBE */
extern void p9_sbe_send_relocated_base(uint64_t val);
+/* Terminate and trigger MPIPL */
+extern void p9_sbe_terminate(void);
+
#endif /* __SBE_P9_H */
--
2.14.3
More information about the Skiboot
mailing list