[Skiboot] [PATCH V2 5/6] hmi: Recover CAPP unit on Naples after malfunction alert

Michael Neuling mikey at neuling.org
Tue Mar 8 15:49:29 AEDT 2016


On Mon, 2016-02-22 at 14:17 +0100, Philippe Bergheaud wrote:

> Naples has two capp units. Probe both units to identify the card in
> error. Use the xscom register offset to operate on the right unit.
> 
> Signed-off-by: Philippe Bergheaud <felix at linux.vnet.ibm.com>
> ---
> V2: after Mickey's review

I don't know who this "Mickey" guy is.. but he sounds pretty cool

More comments below...

Mikey

>   - Identify and recover the broken card (not both)
>   - Add reg_offset to register adresses in do_capp_recovery_scoms
> 
>  core/hmi.c | 35 +++++++++++++++++++++++------------
>  hw/phb3.c  | 16 +++++++++++-----
>  2 files changed, 34 insertions(+), 17 deletions(-)
> 
> diff --git a/core/hmi.c b/core/hmi.c
> index d2cca90..5ad0ebb 100644
> --- a/core/hmi.c
> +++ b/core/hmi.c
> @@ -242,14 +242,19 @@ static int queue_hmi_event(struct OpalHMIEvent
> *hmi_evt, int recover)
>  				hmi_data[3]);
>  }
>  
> -static int is_capp_recoverable(int chip_id)
> +static int is_capp_recoverable(int chip_id, int capp)
>  {
>  	uint64_t reg;
> -	xscom_read(chip_id, CAPP_ERR_STATUS_CTRL, &reg);
> +	uint32_t reg_offset = capp ? CAPP1_REG_OFFSET : 0x0;
> +
> +	xscom_read(chip_id, CAPP_ERR_STATUS_CTRL + reg_offset,
> &reg);
>  	return (reg & PPC_BIT(0)) != 0;
>  }
>  
> -static int handle_capp_recoverable(int chip_id)
> +#define CAPP_PHB3_ATTACHED(chip, phb_index) \
> +	(chip->capp_phb3_attached_mask & (1 << phb_index))

Macros need parenthesis around input parameters!  ie.

#define CAPP_PHB3_ATTACHED(chip, phb_index) \
	((chip)->capp_phb3_attached_mask & (1 << (phb_index)))


> +
> +static int handle_capp_recoverable(int chip_id, int capp)
>  {
>  	struct dt_node *np;
>  	u64 phb_id;
> @@ -257,14 +262,16 @@ static int handle_capp_recoverable(int chip_id)
>  	struct phb *phb;
>  	u32 phb_index;
>  	struct proc_chip *chip = get_chip(chip_id);
> -	u8 mask = chip->capp_phb3_attached_mask;
> +	int dual_capp = (chip->type == PROC_CHIP_P8_NAPLES);
>  
>  	dt_for_each_compatible(dt_root, np, "ibm,power8-pciex") {
>  		dt_chip_id = dt_prop_get_u32(np, "ibm,chip-id");
>  		phb_index = dt_prop_get_u32(np, "ibm,phb-index");
>  		phb_id = dt_prop_get_u64(np, "ibm,opal-phbid");
>  
> -		if ((mask & (1 << phb_index)) && (chip_id ==
dt_chip_id)) {
> +		if ((chip_id == dt_chip_id) &&
> +		    CAPP_PHB3_ATTACHED(chip, phb_index) &&
> +		    (!dual_capp || phb_index == capp)) {

What is this trying to do?  It might need a comment.

>  			phb = pci_get_phb(phb_id);
>  			phb->ops->lock(phb);
>  			phb->ops->set_capp_recovery(phb);
> @@ -277,17 +284,21 @@ static int handle_capp_recoverable(int chip_id)
>  
>  static int decode_one_malfunction(int flat_chip_id, struct
> OpalHMIEvent *hmi_evt)
>  {
> +	int capp;
> +	struct proc_chip *chip = get_chip(flat_chip_id);
> +	int dual_capp = (chip->type == PROC_CHIP_P8_NAPLES);
> +
>  	hmi_evt->severity = OpalHMI_SEV_FATAL;
>  	hmi_evt->type = OpalHMI_ERROR_MALFUNC_ALERT;
>  
> -	if (is_capp_recoverable(flat_chip_id)) {
> -		if (handle_capp_recoverable(flat_chip_id) == 0)
> -			return 0;
> +	for (capp = 0; capp < (dual_capp ? 2 : 1); capp++)

Can we store the the number of capp units chip rather that doing this?

> +		if (is_capp_recoverable(flat_chip_id, capp))
> +			if (handle_capp_recoverable(flat_chip_id,
capp)) {
> +				hmi_evt->severity =
OpalHMI_SEV_NO_ERROR;
> +				hmi_evt->type =
OpalHMI_ERROR_CAPP_RECOVERY;
> +				return 1;
> +			}
>  
> -		hmi_evt->severity = OpalHMI_SEV_NO_ERROR;
> -		hmi_evt->type = OpalHMI_ERROR_CAPP_RECOVERY;
> -		return 1;
> -	}
>  	/* TODO check other FIRs */
>  	return 0;
>  }
> diff --git a/hw/phb3.c b/hw/phb3.c
> index 76fa1cc..4965701 100644
> --- a/hw/phb3.c
> +++ b/hw/phb3.c
> @@ -2445,16 +2445,22 @@ static int64_t capp_load_ucode(struct phb3
> *p)
>  static void do_capp_recovery_scoms(struct phb3 *p)
>  {
>  	uint64_t reg;
> +	uint32_t reg_offset;
> +
>  	PHBDBG(p, "Doing CAPP recovery scoms\n");
>  
> -	xscom_write(p->chip_id, SNOOP_CAPI_CONFIG, 0); /* disable
> snoops */
> +	reg_offset = CAPP_REG_OFFSET(p->rev, p->index);
> +	/* disable snoops */
> +	xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + reg_offset, 0);
>  	capp_load_ucode(p);
> -	xscom_write(p->chip_id, CAPP_ERR_RPT_CLR, 0); /* clear err
> rpt reg*/
> -	xscom_write(p->chip_id, CAPP_FIR, 0); /* clear capp fir */
> +	/* clear err rpt reg*/
> +	xscom_write(p->chip_id, CAPP_ERR_RPT_CLR + reg_offset, 0);
> +	/* clear capp fir */
> +	xscom_write(p->chip_id, CAPP_FIR + reg_offset, 0);
>  
> -	xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL, &reg);
> +	xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL + reg_offset,
> &reg);
>  	reg &= ~(PPC_BIT(0) | PPC_BIT(1));
> -	xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL, reg);
> +	xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL + reg_offset,
> reg);
>  }
>  
>  /*


More information about the Skiboot mailing list