[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