On Mon, Nov 25, 2019 at 07:58:13AM +0100, Cédric Le Goater wrote:
> The TIMA region gives access to the thread interrupt context registers
> of a CPU. It is mapped at the same address on all chips and can be
> accessed by any CPU of the system. To identify the chip from which the
> access is being done, the PowerBUS uses a 'chip' field in the
> load/store messages. QEMU does not model these messages, instead, we
> extract the chip id from the CPU PIR and do a lookup at the machine
> level to fetch the targeted interrupt controller.
> 
> Introduce pnv_get_chip() and pnv_xive_tm_get_xive() helpers to clarify
> this process in pnv_xive_get_tctx(). The latter will be removed in the
> subsequent patches but the same principle will be kept.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>
> ---
>  include/hw/ppc/pnv.h |  3 +++
>  hw/intc/pnv_xive.c   | 40 +++++++++++++++++++++++-----------------
>  hw/ppc/pnv.c         | 14 ++++++++++++++
>  3 files changed, 40 insertions(+), 17 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index a58cfea3f2fd..3a7bc3c57e0d 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -103,6 +103,7 @@ typedef struct Pnv9Chip {
>   * A SMT8 fused core is a pair of SMT4 cores.
>   */
>  #define PNV9_PIR2FUSEDCORE(pir) (((pir) >> 3) & 0xf)
> +#define PNV9_PIR2CHIP(pir)      (((pir) >> 8) & 0x7f)
>  
>  typedef struct PnvChipClass {
>      /*< private >*/
> @@ -197,6 +198,8 @@ static inline bool pnv_is_power9(PnvMachineState *pnv)
>      return pnv_chip_is_power9(pnv->chips[0]);
>  }
>  
> +PnvChip *pnv_get_chip(uint32_t chip_id);
> +
>  #define PNV_FDT_ADDR          0x01000000
>  #define PNV_TIMEBASE_FREQ     512000000ULL
>  
> diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
> index 95e9de312cd9..db9d9c11a8f4 100644
> --- a/hw/intc/pnv_xive.c
> +++ b/hw/intc/pnv_xive.c
> @@ -439,31 +439,37 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, 
> uint8_t format,
>      return count;
>  }
>  
> +/*
> + * The TIMA MMIO space is shared among the chips and to identify the
> + * chip from which the access is being done, we extract the chip id
> + * from the PIR.
> + */
> +static PnvXive *pnv_xive_tm_get_xive(PowerPCCPU *cpu)
> +{
> +    int pir = ppc_cpu_pir(cpu);
> +    PnvChip *chip;
> +    PnvXive *xive;
> +
> +    chip = pnv_get_chip(PNV9_PIR2CHIP(pir));
> +    assert(chip);
> +    xive = &PNV9_CHIP(chip)->xive;
> +
> +    if (!pnv_xive_is_cpu_enabled(xive, cpu)) {
> +        xive_error(xive, "IC: CPU %x is not enabled", pir);
> +    }
> +    return xive;
> +}
> +
>  static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
> -    XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
> -    PnvXive *xive = NULL;
> -    CPUPPCState *env = &cpu->env;
> -    int pir = env->spr_cb[SPR_PIR].default_value;
> +    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
>  
> -    /*
> -     * Perform an extra check on the HW thread enablement.
> -     *
> -     * The TIMA is shared among the chips and to identify the chip
> -     * from which the access is being done, we extract the chip id
> -     * from the PIR.
> -     */
> -    xive = pnv_xive_get_ic((pir >> 8) & 0xf);
>      if (!xive) {
>          return NULL;
>      }
>  
> -    if (!(xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(pir & 0x3f))) {

I'm not seeing any code which will replace this check on the thread
enabled register.  Is that really what you intend?

> -        xive_error(PNV_XIVE(xrtr), "IC: CPU %x is not enabled", pir);
> -    }
> -
> -    return tctx;
> +    return XIVE_TCTX(pnv_cpu_state(cpu)->intc);
>  }
>  
>  /*
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 5b8b07f6aedc..fa656858b24a 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -1472,6 +1472,20 @@ static int pnv_match_nvt(XiveFabric *xfb, uint8_t 
> format,
>      return total_count;
>  }
>  
> +PnvChip *pnv_get_chip(uint32_t chip_id)
> +{
> +    PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
> +    int i;
> +
> +    for (i = 0; i < pnv->num_chips; i++) {
> +        PnvChip *chip = pnv->chips[i];
> +        if (chip->chip_id == chip_id) {
> +            return chip;
> +        }
> +    }
> +    return NULL;
> +}
> +
>  static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
>                                void *opaque, Error **errp)
>  {

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature

Reply via email to