[1/2] Fix scom addresses for power9 core checkstop hmi handling.

Message ID 20170713065918.GA22546@in.ibm.com
State New
Headers show

Commit Message

Mahesh J Salgaonkar July 13, 2017, 6:59 a.m.
On 2017-07-12 12:32:29 Wed, Andrew Donnellan wrote:
> On 03/07/17 15:08, Mahesh J Salgaonkar wrote:
> > From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> > 
> > Scom addresses for CORE FIR (Fault Isolation Register) and Malfunction
> > Alert Register has changed for Power9. Fixup those while handling core
> > checkstop for Power9.
> > 
> > Without this change HMI handler fails to check for correct reason for
> > core checkstop on Power9.
> > 
> > Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> 
> Comments below
> 
> > ---
> >  core/hmi.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
> >  1 file changed, 56 insertions(+), 5 deletions(-)
> > 
> > diff --git a/core/hmi.c b/core/hmi.c
> > index 84f2c2d..8e1ebbd 100644
> > --- a/core/hmi.c
> > +++ b/core/hmi.c
> > @@ -154,7 +154,13 @@
> >  		((((1UL) << (t_count)) - 1) << ((s_id) * (t_count)))
> > 
> >  /* xscom addresses for core FIR (Fault Isolation Register) */
> > -#define CORE_FIR		0x10013100
> > +#define P8_CORE_FIR		0x10013100
> > +#define P9_CORE_FIR		0x20010A40
> > +
> > +/* xscom addresses for pMisc Receive Malfunction Alert Register */
> > +#define P8_MALFUNC_ALERT	0x02020011
> > +#define P9_MALFUNC_ALERT	0x00090022
> > +
> >  #define NX_STATUS_REG		0x02013040 /* NX status register */
> >  #define NX_DMA_ENGINE_FIR	0x02013100 /* DMA & Engine FIR Data Register */
> >  #define NX_PBI_FIR		0x02013080 /* PowerBus Interface FIR Register */
> > @@ -215,6 +221,23 @@ static const struct nx_xstop_bit_info nx_pbi_xstop_bits[] = {
> >  };
> > 
> >  static struct lock hmi_lock = LOCK_UNLOCKED;
> > +static uint32_t malf_alert_scom;
> > +
> > +static int setup_scom_addresses(void)
> > +{
> > +	switch (proc_gen) {
> > +	case proc_gen_p8:
> > +		malf_alert_scom = P8_MALFUNC_ALERT;
> > +		return 1;
> > +	case proc_gen_p9:
> > +		malf_alert_scom = P9_MALFUNC_ALERT;
> > +		return 1;
> > +	default:
> > +		prerror("HMI: %s: Unknown CPU type\n", __func__);
> > +		break;
> > +	}
> > +	return 0;
> > +}
> > 
> >  static int queue_hmi_event(struct OpalHMIEvent *hmi_evt, int recover)
> >  {
> > @@ -244,6 +267,25 @@ static int queue_hmi_event(struct OpalHMIEvent *hmi_evt, int recover)
> >  				num_params, (uint64_t *)hmi_evt);
> >  }
> > 
> > +static int read_core_fir(uint32_t chip_id, uint32_t core_id, uint64_t *core_fir)
> > +{
> > +	int rc;
> > +
> > +	switch (proc_gen) {
> > +	case proc_gen_p8:
> > +		rc = xscom_read(chip_id,
> > +			XSCOM_ADDR_P8_EX(core_id, P8_CORE_FIR), core_fir);
> > +		break;
> > +	case proc_gen_p9:
> > +		rc = xscom_read(chip_id,
> > +			XSCOM_ADDR_P9_EC(core_id, P9_CORE_FIR), core_fir);
> > +		break;
> > +	default:
> > +		rc = OPAL_HARDWARE;
> > +	}
> > +	return rc;
> > +}
> > +
> >  static bool decode_core_fir(struct cpu_thread *cpu,
> >  				struct OpalHMIEvent *hmi_evt)
> >  {
> > @@ -260,8 +302,7 @@ static bool decode_core_fir(struct cpu_thread *cpu,
> >  	core_id = pir_to_core_id(cpu->pir);
> > 
> >  	/* Get CORE FIR register value. */
> > -	ret = xscom_read(cpu->chip_id, XSCOM_ADDR_P8_EX(core_id, CORE_FIR),
> > -			 &core_fir);
> > +	ret = read_core_fir(cpu->chip_id, core_id, &core_fir);
> > 
> >  	if (ret == OPAL_HARDWARE) {
> >  		prerror("HMI: XSCOM error reading CORE FIR\n");
> > @@ -529,14 +570,24 @@ static void decode_malfunction(struct OpalHMIEvent *hmi_evt)
> >  	uint64_t malf_alert;
> >  	bool event_generated = false;
> > 
> > -	xscom_read(this_cpu()->chip_id, 0x2020011, &malf_alert);
> > +	if (!setup_scom_addresses()) {
> 
> Any way we can move the call so this only gets called once at startup?

Yes we can. How about we move this call xscom_init() ?
Let me know what you think about patch below ?

---
opal/hmi: Setup xscom addresses at startup.

From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Move call to setup_xscom_addresses to xscom_init(). Also change the
function name to hmi_setup_xscom_addrs().

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
 core/hmi.c      |   16 ++++++++++------
 hw/xscom.c      |    3 +++
 include/xscom.h |    3 +++
 3 files changed, 16 insertions(+), 6 deletions(-)

Patch

diff --git a/core/hmi.c b/core/hmi.c
index 8b229eb..0b281f8 100644
--- a/core/hmi.c
+++ b/core/hmi.c
@@ -225,31 +225,35 @@  static const struct nx_xstop_bit_info nx_pbi_xstop_bits[] = {
 };
 
 static struct lock hmi_lock = LOCK_UNLOCKED;
+static bool xscom_addrs_valid;
 static uint32_t malf_alert_scom;
 static uint32_t nx_status_reg;
 static uint32_t nx_dma_engine_fir;
 static uint32_t nx_pbi_fir;
 
-static int setup_scom_addresses(void)
+void hmi_setup_xscom_addrs(void)
 {
+	xscom_addrs_valid = true;
+
 	switch (proc_gen) {
 	case proc_gen_p8:
 		malf_alert_scom = P8_MALFUNC_ALERT;
 		nx_status_reg = P8_NX_STATUS_REG;
 		nx_dma_engine_fir = P8_NX_DMA_ENGINE_FIR;
 		nx_pbi_fir = P8_NX_PBI_FIR;
-		return 1;
+		return;
 	case proc_gen_p9:
 		malf_alert_scom = P9_MALFUNC_ALERT;
 		nx_status_reg = P9_NX_STATUS_REG;
 		nx_dma_engine_fir = P9_NX_DMA_ENGINE_FIR;
 		nx_pbi_fir = P9_NX_PBI_FIR;
-		return 1;
+		return;
 	default:
+		xscom_addrs_valid = false;
 		prerror("HMI: %s: Unknown CPU type\n", __func__);
 		break;
 	}
-	return 0;
+	return;
 }
 
 static int queue_hmi_event(struct OpalHMIEvent *hmi_evt, int recover)
@@ -583,8 +587,8 @@  static void decode_malfunction(struct OpalHMIEvent *hmi_evt)
 	uint64_t malf_alert;
 	bool event_generated = false;
 
-	if (!setup_scom_addresses()) {
-		prerror("HMI: Failed to setup scom addresses\n");
+	if (!xscom_addrs_valid) {
+		prerror("HMI: xscom addresses invalid\n");
 		/* Send an unknown HMI event. */
 		hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_UNKNOWN;
 		hmi_evt->u.xstop_error.xstop_reason = 0;
diff --git a/hw/xscom.c b/hw/xscom.c
index a739b3c..6a1201b 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -756,6 +756,9 @@  void xscom_init(void)
 		      xstop_xscom.addr, xstop_xscom.fir_bit);
 	} else
 		prlog(PR_DEBUG, "XSTOP: ibm,sw-checkstop-fir prop not found\n");
+
+	/* Setup HMI xscom addresses. */
+	hmi_setup_xscom_addrs();
 }
 
 void xscom_used_by_console(void)
diff --git a/include/xscom.h b/include/xscom.h
index 743a47b..dc5bcac 100644
--- a/include/xscom.h
+++ b/include/xscom.h
@@ -248,4 +248,7 @@  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);
 
+/* HMI xscom setup function */
+extern void hmi_setup_xscom_addrs(void);
+
 #endif /* __XSCOM_H */