[Skiboot] [PATCH v4 4/8] SLW: Add opal_slw_set_reg support for power9

Vaidyanathan Srinivasan svaidy at linux.vnet.ibm.com
Fri Sep 15 18:31:05 AEST 2017


* Akshay Adiga <akshay.adiga at linux.vnet.ibm.com> [2017-09-15 13:04:32]:

> This OPAL call is made from Linux to OPAL to configure values in
> various SPRs after wakeup from a deep idle state.

The opal_slw_set_reg() OPAL call is used by Linux during init to setup
certain SPR values that should be loaded by microcode on wakeup from
a deep idle states where some SPR states are lost.

This helps to speed up wakeup by restoring key registers like HSPRG0,
LPCR and MSR.  On POWER9 platform Linux MSR need to be set using this
API since the micro-code running on host processor may have
a different MSR context.
 
> Signed-off-by: Akshay Adiga <akshay.adiga at linux.vnet.ibm.com>

Reviewed-by: Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>


> ---
>  hw/slw.c | 60 ++++++++++++++++++++++++++++++++++++++++--------------------
>  1 file changed, 40 insertions(+), 20 deletions(-)
> 
> diff --git a/hw/slw.c b/hw/slw.c
> index d8829a6..a1ed7ba 100644
> --- a/hw/slw.c
> +++ b/hw/slw.c
> @@ -30,6 +30,7 @@
>  #include <libfdt/libfdt.h>
>  #include <opal-api.h>
> 
> +#include <p9_stop_api.H>
>  #include <p8_pore_table_gen_api.H>
>  #include <sbe_xip_image.h>
> 
> @@ -1402,41 +1403,60 @@ int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val)
> 
>  	struct cpu_thread *c = find_cpu_by_pir(cpu_pir);
>  	struct proc_chip *chip;
> -	void *image;
>  	int rc;
> -	int i;
> -	int spr_is_supported = 0;
> 
>  	assert(c);
>  	chip = get_chip(c->chip_id);
>  	assert(chip);
> -	image = (void *) chip->slw_base;
> 
> -	/* Check of the SPR is supported by libpore */
> -	for ( i=0; i < SLW_SPR_REGS_SIZE ; i++)  {
> -		if (sprn == SLW_SPR_REGS[i].value)  {
> -			spr_is_supported = 1;
> -			break;
> +	if (proc_gen == proc_gen_p9) {
> +		if (!chip->homer_base) {
> +			log_simple_error(&e_info(OPAL_RC_SLW_REG),
> +					 "SLW: HOMER base not set %x\n",
> +					 chip->id);
> +			return OPAL_INTERNAL_ERROR;
>  		}
> -	}
> -	if (!spr_is_supported) {
> -		log_simple_error(&e_info(OPAL_RC_SLW_REG),
> +		rc = p9_stop_save_cpureg((void *)chip->homer_base,
> +					 sprn, val, cpu_pir);
> +
> +	} else if (proc_gen == proc_gen_p8) {
> +		int spr_is_supported = 0;
> +		void *image;
> +		int i;
> +
> +		/* Check of the SPR is supported by libpore */
> +		for (i = 0; i < SLW_SPR_REGS_SIZE ; i++)  {
> +			if (sprn == SLW_SPR_REGS[i].value)  {
> +				spr_is_supported = 1;
> +				break;
> +			}
> +		}
> +		if (!spr_is_supported) {
> +			log_simple_error(&e_info(OPAL_RC_SLW_REG),
>  			"SLW: Trying to set unsupported spr for CPU %x\n",
> -			c->pir);
> +				c->pir);
> +			return OPAL_UNSUPPORTED;
> +		}
> +		image = (void *)chip->slw_base;
> +		rc = p8_pore_gen_cpureg_fixed(image, P8_SLW_MODEBUILD_SRAM,
> +					      sprn, val,
> +					      cpu_get_core_index(c),
> +					      cpu_get_thread_index(c));
> +	} else {
> +		log_simple_error(&e_info(OPAL_RC_SLW_REG),
> +		"SLW: proc_gen not supported\n");
>  		return OPAL_UNSUPPORTED;
> -	}
> 
> -	rc = p8_pore_gen_cpureg_fixed(image, P8_SLW_MODEBUILD_SRAM, sprn,
> -						val, cpu_get_core_index(c),
> -						cpu_get_thread_index(c));
> +	}
> 
>  	if (rc) {
>  		log_simple_error(&e_info(OPAL_RC_SLW_REG),
> -			"SLW: Failed to set spr for CPU %x\n",
> -			c->pir);
> +			"SLW: Failed to set spr %llx for CPU %x, RC=0x%x\n",
> +			sprn, c->pir, rc);
>  		return OPAL_INTERNAL_ERROR;
>  	}
> -
> +	prlog(PR_DEBUG, "SLW: restore spr:0x%llx on c:0x%x with 0x%llx\n",
> +	      sprn, c->pir, val);
>  	return OPAL_SUCCESS;
> 
>  }
> -- 
> 2.5.5
> 



More information about the Skiboot mailing list