qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v6 13/20] ppc/pnv: Clarify how the TIMA is accessed on a mult


From: Cédric Le Goater
Subject: Re: [PATCH v6 13/20] ppc/pnv: Clarify how the TIMA is accessed on a multichip system
Date: Wed, 27 Nov 2019 07:57:31 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.1

On 27/11/2019 06:23, David Gibson wrote:
> 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 <address@hidden>
>> ---
>>  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?

it is calling pnv_xive_tm_get_xive() which calls pnv_xive_is_cpu_enabled()
which does the same check in better.

C. 


> 
>> -        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)
>>  {
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]