[Skiboot] [PATCH v4 1/2] opal-api: Add OPAL call to handle abnormal reboots.
Samuel Mendoza-Jonas
sam.mj at au1.ibm.com
Thu Jul 30 11:08:18 AEST 2015
On 30/07/15 03:58, Mahesh J Salgaonkar wrote:
> From: Vipin K Parashar <vipin at linux.vnet.ibm.com>
>
> This patch adds a new OPAL call OPAL_CEC_REBOOT2 which will
> be used to handle abnormal reboot/termination by kernel host.
>
> This call will allow host kernel to pass reboot type and additional
> debug data which needs to be captured/saved somewhere (for later
> analysis) before going down.
>
> Currently it will support two reboot types (0). normal reboot, that
> will behave similar to that of opal_cec_reboot() call, and
> (1). platform error reboot, that will trigger a system checkstop
> using xscom address and FIR bit information obtained via device-tree
> property 'ibm,sw-checkstop-fir'.
>
> For unsupported reboot type, this call will do nothing and return
> with OPAL_UNSUPPORTED.
I was going to ask whether this was the kind of behaviour we want but
I think I answered in my own head - I suppose it would be up to the
caller to check for OPAL_UNSUPPORTED and then presumably try to call
the original OPAL_CEC_REBOOT call?
A very minor comment below about log_add_section() but otherwise
Reviewed-by: Samuel Mendoza-Jonas <sam.mj at au1.ibm.com>
>
> In future, we can overload this call to support additional reboot types.
>
> Signed-off-by: Vipin K Parashar <vipin at linux.vnet.ibm.com>
> Signed-off-by: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>
> ---
> core/platform.c | 39 +++++++++++++++++++++++++++++++++++++++
> hw/xscom.c | 32 ++++++++++++++++++++++++++++++++
> include/errorlog.h | 3 +++
> include/opal-api.h | 9 ++++++++-
> include/xscom.h | 1 +
> 5 files changed, 83 insertions(+), 1 deletion(-)
>
> diff --git a/core/platform.c b/core/platform.c
> index dec7e96..12c4ec2 100644
> --- a/core/platform.c
> +++ b/core/platform.c
> @@ -21,9 +21,15 @@
> #include <timebase.h>
> #include <cpu.h>
> #include <chip.h>
> +#include <xscom.h>
> +#include <errorlog.h>
>
> struct platform platform;
>
> +DEFINE_LOG_ENTRY(OPAL_RC_ABNORMAL_REBOOT, OPAL_PLATFORM_ERR_EVT, OPAL_CEC,
> + OPAL_CEC_HARDWARE, OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT,
> + OPAL_ABNORMAL_POWER_OFF);
> +
> /*
> * Various wrappers for platform functions
> */
> @@ -53,6 +59,39 @@ static int64_t opal_cec_reboot(void)
> }
> opal_call(OPAL_CEC_REBOOT, opal_cec_reboot, 0);
>
> +static int64_t opal_cec_reboot2(uint32_t reboot_type, char *diag)
> +{
> + struct errorlog *buf;
> +
> + switch (reboot_type) {
> + case OPAL_REBOOT_NORMAL:
> + return opal_cec_reboot();
> + case OPAL_REBOOT_PLATFORM_ERROR:
> + prlog(PR_EMERG,
> + "OPAL: Reboot requested due to Platform error.");
> + buf = opal_elog_create(&e_info(OPAL_RC_ABNORMAL_REBOOT), 0);
> + if (buf) {
> + log_append_msg(buf,
> + "OPAL: Reboot requested due to Platform error.");
> + if (diag) {
> + /* Add user section "DESC" */
> + log_add_section(buf, 0x44455350);
log_add_section() will use "DESC" for the tag if it's given just a 0,
which means you don't need to carry around the magic 0x44455350 - just
depends how explicit you want to be about how you're tagging it.
> + log_append_data(buf, diag, strlen(diag));
> + log_commit(buf);
> + }
> + } else {
> + prerror("OPAL: failed to log an error\n");
> + }
> + return xscom_trigger_xstop();
> + default:
> + printf("OPAL: Unsupported reboot request %d\n", reboot_type);
> + return OPAL_UNSUPPORTED;
> + break;
> + }
> + return OPAL_SUCCESS;
> +}
> +opal_call(OPAL_CEC_REBOOT2, opal_cec_reboot2, 2);
> +
> static void generic_platform_init(void)
> {
> force_dummy_console();
> diff --git a/hw/xscom.c b/hw/xscom.c
> index ef3ff0f..ba9130a 100644
> --- a/hw/xscom.c
> +++ b/hw/xscom.c
> @@ -53,6 +53,12 @@ DEFINE_LOG_ENTRY(OPAL_RC_XSCOM_RESET, OPAL_PLATFORM_ERR_EVT, OPAL_XSCOM,
> OPAL_CEC_HARDWARE, OPAL_PREDICTIVE_ERR_GENERAL,
> OPAL_NA);
>
> +/* xscom details to trigger xstop */
> +static struct {
> + uint64_t addr;
> + uint64_t fir_bit;
> +} xstop_xscom;
> +
> /*
> * Locking notes:
> *
> @@ -483,9 +489,25 @@ static void xscom_init_chip_info(struct proc_chip *chip)
> chip->ec_level |= (val >> 8) & 0xf;
> }
>
> +/*
> +* This function triggers xstop by writing to XSCOM.
> +* Machine would enter xstop state post completion of this.
> +*/
> +int64_t xscom_trigger_xstop(void)
> +{
> + int rc = OPAL_UNSUPPORTED;
> +
> + if (xstop_xscom.addr)
> + rc = xscom_writeme(xstop_xscom.addr,
> + PPC_BIT(xstop_xscom.fir_bit));
> +
> + return rc;
> +}
> +
> void xscom_init(void)
> {
> struct dt_node *xn;
> + const struct dt_property *p;
>
> dt_for_each_compatible(dt_root, xn, "ibm,xscom") {
> uint32_t gcid = dt_get_chip_id(xn);
> @@ -521,6 +543,16 @@ void xscom_init(void)
> chip->ec_level >> 4,
> chip->ec_level & 0xf);
> }
> +
> + /* Collect details to trigger xstop via XSCOM write */
> + p = dt_find_property(dt_root, "ibm,sw-checkstop-fir");
> + if (p) {
> + xstop_xscom.addr = dt_property_get_cell(p, 0);
> + xstop_xscom.fir_bit = dt_property_get_cell(p, 1);
> + prlog(PR_INFO, "XSTOP: XSCOM addr = 0x%llx, FIR bit = %lld\n",
> + xstop_xscom.addr, xstop_xscom.fir_bit);
> + } else
> + prlog(PR_INFO, "XSTOP: ibm,sw-checkstop-fir prop not found\n");
> }
>
> void xscom_used_by_console(void)
> diff --git a/include/errorlog.h b/include/errorlog.h
> index b908fd4..1499587 100644
> --- a/include/errorlog.h
> +++ b/include/errorlog.h
> @@ -322,6 +322,9 @@ enum opal_reasoncode {
> /* IPMI */
> OPAL_RC_IPMI_REQ = OPAL_IP | 0x10,
> OPAL_RC_IPMI_RESP = OPAL_IP | 0x11,
> +
> +/* Platform error */
> + OPAL_RC_ABNORMAL_REBOOT = OPAL_CE | 0x10,
> };
>
> #define DEFINE_LOG_ENTRY(reason, type, id, subsys, \
> diff --git a/include/opal-api.h b/include/opal-api.h
> index bfad589..e22370f 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -161,7 +161,8 @@
> #define OPAL_PRD_MSG 113
> #define OPAL_LEDS_GET_INDICATOR 114
> #define OPAL_LEDS_SET_INDICATOR 115
> -#define OPAL_LAST 115
> +#define OPAL_CEC_REBOOT2 116
> +#define OPAL_LAST 116
>
> /* Device tree flags */
>
> @@ -972,6 +973,12 @@ struct opal_i2c_request {
> __be64 buffer_ra; /* Buffer real address */
> };
>
> +/* Argument to OPAL_CEC_REBOOT2() */
> +enum {
> + OPAL_REBOOT_NORMAL = 0,
> + OPAL_REBOOT_PLATFORM_ERROR,
> +};
> +
> #endif /* __ASSEMBLY__ */
>
> #endif /* __OPAL_API_H */
> diff --git a/include/xscom.h b/include/xscom.h
> index a841261..09db99b 100644
> --- a/include/xscom.h
> +++ b/include/xscom.h
> @@ -179,5 +179,6 @@ extern void xscom_used_by_console(void);
> extern bool xscom_ok(void);
>
> extern int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id);
> +extern int64_t xscom_trigger_xstop(void);
>
> #endif /* __XSCOM_H */
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
>
--
-----------
LTC Ozlabs
IBM
More information about the Skiboot
mailing list