[Skiboot] [PATCH v2 4/5] xscom: Add indirect form 1 scoms

Cédric Le Goater clg at kaod.org
Fri Mar 24 01:31:20 AEDT 2017


On 03/23/2017 07:15 AM, Michael Neuling wrote:
> Add code to perform indirect form 1 scoms.
> 
> POWER8 does form 0 only. POWER9 adds form 1. The form is determined
> from the address only. Hardware only allows writes for form 1.
> 
> Only hostboot uses these scoms during IPL, so they are unused by
> skiboot currently.
> 
> Signed-off-by: Michael Neuling <mikey at neuling.org>

I checked the indirect form1 specs. It looks good.
  
Reviewed-by: Cédric Le Goater <clg at kaod.org>

C.

> ---
>  hw/xscom.c      | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
>  include/xscom.h |  1 +
>  2 files changed, 48 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/xscom.c b/hw/xscom.c
> index b0bc260087..9fb7da6d3d 100644
> --- a/hw/xscom.c
> +++ b/hw/xscom.c
> @@ -317,7 +317,8 @@ static int __xscom_write(uint32_t gcid, uint32_t pcb_addr, uint64_t val)
>  /*
>   * Indirect XSCOM access functions
>   */
> -static int xscom_indirect_read(uint32_t gcid, uint64_t pcb_addr, uint64_t *val)
> +static int xscom_indirect_read_form0(uint32_t gcid, uint64_t pcb_addr,
> +				     uint64_t *val)
>  {
>  	uint32_t addr;
>  	uint64_t data;
> @@ -360,7 +361,23 @@ static int xscom_indirect_read(uint32_t gcid, uint64_t pcb_addr, uint64_t *val)
>  	return rc;
>  }
>  
> -static int xscom_indirect_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val)
> +static int xscom_indirect_form(uint64_t pcb_addr)
> +{
> +	return (pcb_addr >> 60) & 1;
> +}
> +
> +static int xscom_indirect_read(uint32_t gcid, uint64_t pcb_addr, uint64_t *val)
> +{
> +	uint64_t form = xscom_indirect_form(pcb_addr);
> +
> +	if ((proc_gen == proc_gen_p9) && (form == 1))
> +		return OPAL_UNSUPPORTED;
> +
> +	return xscom_indirect_read_form0(gcid, pcb_addr, val);
> +}
> +
> +static int xscom_indirect_write_form0(uint32_t gcid, uint64_t pcb_addr,
> +				      uint64_t val)
>  {
>  	uint32_t addr;
>  	uint64_t data;
> @@ -402,6 +419,34 @@ static int xscom_indirect_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val)
>  	return rc;
>  }
>  
> +static int xscom_indirect_write_form1(uint32_t gcid, uint64_t pcb_addr,
> +				      uint64_t val)
> +{
> +	uint32_t addr;
> +	uint64_t data;
> +
> +	if (proc_gen < proc_gen_p9)
> +		return OPAL_UNSUPPORTED;
> +	if (val & ~(XSCOM_DATA_IND_FORM1_DATA))
> +		return OPAL_PARAMETER;
> +
> +	/* Mangle address and data for form1 */
> +	addr = (pcb_addr & 0x000ffffffff);
> +	data = (pcb_addr & 0xfff00000000) << 20;
> +	data |= val;
> +	return __xscom_write(gcid, addr, data);
> +}
> +
> +static int xscom_indirect_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val)
> +{
> +	uint64_t form = xscom_indirect_form(pcb_addr);
> +
> +	if ((proc_gen == proc_gen_p9) && (form == 1))
> +		return xscom_indirect_write_form1(gcid, pcb_addr, val);
> +
> +	return xscom_indirect_write_form0(gcid, pcb_addr, val);
> +}
> +
>  static uint32_t xscom_decode_chiplet(uint32_t partid, uint64_t *pcb_addr)
>  {
>  	uint32_t gcid = (partid & 0x0fffffff) >> 4;
> diff --git a/include/xscom.h b/include/xscom.h
> index bad9140cf7..871d210d18 100644
> --- a/include/xscom.h
> +++ b/include/xscom.h
> @@ -192,6 +192,7 @@
>  #define XSCOM_DATA_IND_COMPLETE		PPC_BIT(32)
>  #define XSCOM_DATA_IND_ERR		PPC_BITMASK(33,35)
>  #define XSCOM_DATA_IND_DATA		PPC_BITMASK(48,63)
> +#define XSCOM_DATA_IND_FORM1_DATA	PPC_BITMASK(12,63)
>  
>  /* HB folks say: try 10 time for now */
>  #define XSCOM_IND_MAX_RETRIES		10
> 



More information about the Skiboot mailing list