[Skiboot] [PATCH v7 17/22] fadump: Add support to trigger memory preserving IPL on BMC system
Michael Neuling
mikey at neuling.org
Thu May 9 14:04:01 AEST 2019
On Sat, 2019-04-13 at 14:45 +0530, Vasant Hegde wrote:
> 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
> interrupt to initiate memory preserving IPL.
>
> This patch adds support to call SBE S0 interrupt in assert path.
> Sequence :
> - S0 interrupt on slave chip SBE
> - S0 interrupt on master chip SBE
>
> Note that this is hooked to ipmi_terminate path. We have HDAT flag for MPIPL
> support. If MPIPL is not supported then we don't create 'ibm,opal/dump' node
> and we will fall back to existing termination flow.
>
> Note:
> - It uses xscom node to detect master and slave chip. So that we can
> trigger early MPIPL (even before initializing SBE driver).
> - At present we do not have a proper way to detect SBE is alive or not.
> So we wait for predefined time and then call normal reboot.
>
> Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
> ---
> hw/ipmi/ipmi-attn.c | 9 +++++++-
> hw/sbe-p9.c | 63
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/sbe-p9.h | 10 +++++++++
> 3 files changed, 81 insertions(+), 1 deletion(-)
>
> diff --git a/hw/ipmi/ipmi-attn.c b/hw/ipmi/ipmi-attn.c
> index c6c1c59b5..ae97e92ab 100644
> --- a/hw/ipmi/ipmi-attn.c
> +++ b/hw/ipmi/ipmi-attn.c
> @@ -1,4 +1,4 @@
> -/* Copyright 2015 IBM Corp.
> +/* Copyright 2015-2019 IBM Corp.
> *
> * Licensed under the Apache License, Version 2.0 (the "License");
> * you may not use this file except in compliance with the License.
> @@ -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,12 @@ static void ipmi_log_terminate_event(const char *msg)
>
> void __attribute__((noreturn)) ipmi_terminate(const char *msg)
> {
> + /*
> + * If fadump is supported then trigger SBE interrupt
> + * to initiate fadump
> + */
> + p9_sbe_terminate();
> +
I'm not sure we want to change every platform do this on all ipmi_terminate.
Why doesn't this use the OPAL reboot type like FSP systems?
> /* 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 ba7691f50..694375a5a 100644
> --- a/hw/sbe-p9.c
> +++ b/hw/sbe-p9.c
> @@ -948,3 +948,66 @@ 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;
> + u64 wait_tb;
> + struct dt_node *xn;
> +
> + if (proc_gen < proc_gen_p9)
> + return;
> +
> + /* Return if MPIPL is not supported */
> + if (!dt_find_by_path(opal_node, "dump"))
> + 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_S0);
> + /* Initiate normal reboot */
> + if (rc) {
> + prlog(PR_ERR, "Failed to write S0 interrupt [chip id =
> %x]\n",
> + chip_id);
> + return;
> + }
> + }
A comment as to what this above code is doing would be useful. Finding the
primary chip?
> +
> + if (primary_chip == -1) {
> + prlog(PR_ERR, "Master chip ID not found.\n");
Master or primary? Don't change language arbitrarily.
> + return;
> + }
> +
> + /* Write S0 interrupt on master SBE */
No comment needed above. It's clear what it's doing from the code.
> + rc = xscom_write(primary_chip,
> + SBE_CONTROL_REG_RW, SBE_CONTROL_REG_S0);
> + /* Initiate normal reboot */
this comment is useful, but should be up one line
> + if (rc) {
> + prlog(PR_ERR, "Failed to write S0 interrupt [chip id = %x]\n",
> + primary_chip);
> + return;
> + }
> +
> + /* XXX We do not have a way to detect SBE state. Hence wait for max
> + * time SBE takes to respond and then trigger normal reboot.
> + */
> + prlog(PR_NOTICE, "Initiated MPIPL, waiting for SBE to respond...\n");
> + wait_tb = mftb() + msecs_to_tb(SBE_CMD_TIMEOUT_MAX);
> + while (mftb() < wait_tb) {
> + cpu_relax();
> + }
> +
> + prlog(PR_ERR, "SBE did not respond within timeout period (%d secs).\n",
> + SBE_CMD_TIMEOUT_MAX / 1000);
> + prlog(PR_ERR, "Falling back to normal reboot\n");
> +}
> diff --git a/include/sbe-p9.h b/include/sbe-p9.h
> index ac1ec219b..9ea7d294f 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
> @@ -243,4 +250,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 reloc_base);
>
> +/* Terminate and trigger MPIPL */
> +extern void p9_sbe_terminate(void);
> +
> #endif /* __SBE_P9_H */
More information about the Skiboot
mailing list