[Skiboot] [PATCH v4 3/8] capp/phb: Introduce 'struct capp' to hold capp related info in 'struct phb'
Andrew Donnellan
andrew.donnellan at au1.ibm.com
Mon Jan 14 18:27:06 AEDT 2019
On 13/1/19 4:37 pm, Vaibhav Jain wrote:
> Previously struct proc_chip member 'capp_phb3_attached_mask' was used
> for Power-8 to keep track of PHB attached to the single CAPP on the
> chip. CAPP on that chip supported a flexible PHB assignment
> scheme. However since then new chips only support a static assignment
> i.e a CAPP can only be attached to a specific PEC.
>
> Hence instead of using 'proc_chip.capp_phb4_attached_mask' to manage
> CAPP <-> PEC assignments which needs a global lock (capi_lock) to be
> updated, we introduce a new struct named 'capp' a pointer to which
> resides inside struct 'phb4'. Since updates to struct 'phb4' already
> happen in context of phb_lock; this eliminates the
> need to use mutex 'capi_lock' while updating
> 'capp_phb4_attached_mask'.
>
> This struct is also used to hold CAPP specific variables such as
> pointer to the 'struct phb' to which the CAPP is attached,
> 'capp_xscom_offset' which is the xscom offset to be added to CAPP
> registers in case there are more than 1 on the chip, 'capp_index'
> which is the index of the CAPP on the chip, and attached_pe' which is
> the process endpoint index to which CAPP is attached. Finally member
> 'chip_id' holds the chip-id thats used for performing xscom
> read/writes.
>
> Also new helpers named capp_xscom_read()/write() are introduced to
> make access to CAPP xscom registers easier.
>
> Signed-off-by: Vaibhav Jain <vaibhav at linux.ibm.com>
Reviewed-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
> ---
> Change-log
>
> v4:
> * Fixed a potential leak of struct capp on capp ucode load failure
> [Fred]
> * capp_xscom_read()/write() now return OPAL_PARAMETER instead of
> OPAL_UNSUPPORTED in case of an capp == NULL.
>
> v3:
> * Moved the 'struct capp *' from struct 'phb' to struct 'phb4' [Christophe]
> * Introduced 'chip_id' as a member of struct 'capp'.
> * Introduced helpers capp_xscom_read()/write().
> ---
> hw/capp.c | 12 +++++++++++
> hw/phb4.c | 54 +++++++++++++++++++++++++++++++++++++++++++-------
> include/capp.h | 12 +++++++++++
> include/chip.h | 1 -
> include/phb4.h | 3 +++
> 5 files changed, 74 insertions(+), 8 deletions(-)
>
> diff --git a/hw/capp.c b/hw/capp.c
> index eeaa4ac4..78ab0580 100644
> --- a/hw/capp.c
> +++ b/hw/capp.c
> @@ -240,3 +240,15 @@ int64_t capp_get_info(int chip_id, struct phb *phb, struct capp_info *info)
>
> return OPAL_PARAMETER;
> }
> +
> +int64_t capp_xscom_read(struct capp *capp, int64_t off, uint64_t *val)
> +{
> + return capp == NULL ? OPAL_PARAMETER :
> + xscom_read(capp->chip_id, off + capp->capp_xscom_offset, val);
> +}
> +
> +int64_t capp_xscom_write(struct capp *capp, int64_t off, uint64_t val)
> +{
> + return capp == NULL ? OPAL_PARAMETER :
> + xscom_write(capp->chip_id, off + capp->capp_xscom_offset, val);
> +}
> diff --git a/hw/phb4.c b/hw/phb4.c
> index c0797647..a0431d4f 100644
> --- a/hw/phb4.c
> +++ b/hw/phb4.c
> @@ -3880,13 +3880,13 @@ static int64_t phb4_get_capp_info(int chip_id, struct phb *phb,
> struct capp_info *info)
> {
> struct phb4 *p = phb_to_phb4(phb);
> - struct proc_chip *chip = get_chip(p->chip_id);
> uint32_t offset;
>
> if (chip_id != p->chip_id)
> return OPAL_PARAMETER;
>
> - if (!((1 << p->index) & chip->capp_phb4_attached_mask))
> + /* Check is CAPP is attached to the PHB */
> + if (p->capp == NULL || p->capp->phb != phb)
> return OPAL_PARAMETER;
>
> offset = PHB4_CAPP_REG_OFFSET(p);
> @@ -4397,23 +4397,63 @@ static int64_t enable_capi_mode(struct phb4 *p, uint64_t pe_number,
> return OPAL_SUCCESS;
> }
>
> +
> +static int64_t phb4_init_capp(struct phb4 *p)
> +{
> + struct capp *capp;
> + int rc;
> +
> + if (p->index != CAPP0_PHB_INDEX &&
> + p->index != CAPP1_PHB_INDEX)
> + return OPAL_UNSUPPORTED;
> +
> + capp = zalloc(sizeof(struct capp));
> + if (capp == NULL)
> + return OPAL_NO_MEM;
> +
> + if (p->index == CAPP0_PHB_INDEX) {
> + capp->capp_index = 0;
> + capp->capp_xscom_offset = 0;
> +
> + } else if (p->index == CAPP1_PHB_INDEX) {
> + capp->capp_index = 1;
> + capp->capp_xscom_offset = CAPP1_REG_OFFSET;
> + }
> +
> + capp->attached_pe = phb4_get_reserved_pe_number(&p->phb);
> + capp->chip_id = p->chip_id;
> +
> + /* Load capp microcode into the capp unit */
> + rc = load_capp_ucode(p);
> +
> + if (rc == OPAL_SUCCESS)
> + p->capp = capp;
> + else
> + free(capp);
> +
> + return rc;
> +}
> +
> static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode,
> uint64_t pe_number)
> {
> struct phb4 *p = phb_to_phb4(phb);
> struct proc_chip *chip = get_chip(p->chip_id);
> + struct capp *capp = p->capp;
> uint64_t reg, ret;
> uint32_t offset;
>
> + if (capp == NULL)
> + return OPAL_UNSUPPORTED;
>
> if (!capp_ucode_loaded(chip, p->index)) {
> PHBERR(p, "CAPP: ucode not loaded\n");
> return OPAL_RESOURCE;
> }
>
> - lock(&capi_lock);
> - chip->capp_phb4_attached_mask |= 1 << p->index;
> - unlock(&capi_lock);
> + /* mark the capp attached to the phb */
> + capp->phb = phb;
> + capp->attached_pe = pe_number;
>
> offset = PHB4_CAPP_REG_OFFSET(p);
> xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL + offset, ®);
> @@ -5595,8 +5635,8 @@ static void phb4_create(struct dt_node *np)
> /* Get the HW up and running */
> phb4_init_hw(p);
>
> - /* Load capp microcode into capp unit */
> - load_capp_ucode(p);
> + /* init capp that might get attached to the phb */
> + phb4_init_capp(p);
>
> /* Compute XIVE source flags depending on PHB revision */
> irq_flags = 0;
> diff --git a/include/capp.h b/include/capp.h
> index 6ec3f7fe..cc70e443 100644
> --- a/include/capp.h
> +++ b/include/capp.h
> @@ -79,6 +79,14 @@ struct capp_ops {
> int64_t (*get_capp_info)(int, struct phb *, struct capp_info *);
> };
>
> +struct capp {
> + struct phb *phb;
> + unsigned int capp_index;
> + uint64_t capp_xscom_offset;
> + uint64_t attached_pe;
> + uint64_t chip_id;
> +};
> +
> struct proc_chip;
> extern struct lock capi_lock;
> extern struct capp_ops capi_ops;
> @@ -96,4 +104,8 @@ extern int64_t capp_load_ucode(unsigned int chip_id, uint32_t opal_id,
> extern int64_t capp_get_info(int chip_id, struct phb *phb,
> struct capp_info *info);
>
> +
> +/* Helpers to read/write capp registers */
> +extern int64_t capp_xscom_read(struct capp *capp, int64_t off, uint64_t *val);
> +extern int64_t capp_xscom_write(struct capp *capp, int64_t off, uint64_t val);
> #endif /* __CAPP_H */
> diff --git a/include/chip.h b/include/chip.h
> index 2fb8126d..c759d0a0 100644
> --- a/include/chip.h
> +++ b/include/chip.h
> @@ -197,7 +197,6 @@ struct proc_chip {
>
> /* Must hold capi_lock to change */
> uint8_t capp_phb3_attached_mask;
> - uint8_t capp_phb4_attached_mask;
> uint8_t capp_ucode_loaded;
>
> /* Used by hw/centaur.c */
> diff --git a/include/phb4.h b/include/phb4.h
> index 43819d57..60c1735d 100644
> --- a/include/phb4.h
> +++ b/include/phb4.h
> @@ -232,6 +232,9 @@ struct phb4 {
> /* Current NPU2 relaxed ordering state */
> bool ro_state;
>
> + /* Any capp instance attached to the PHB4 */
> + struct capp *capp;
> +
> struct phb phb;
> };
>
>
--
Andrew Donnellan OzLabs, ADL Canberra
andrew.donnellan at au1.ibm.com IBM Australia Limited
More information about the Skiboot
mailing list