All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Cédric Le Goater" <clg@kaod.org>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 5/8] ppc/pnv: create the ICP and ICS objects under the machine
Date: Thu, 23 Mar 2017 09:25:49 +0100	[thread overview]
Message-ID: <1becb703-05d2-a5fd-25c1-ecd1037acd0c@kaod.org> (raw)
In-Reply-To: <20170323041612.GI19078@umbus.fritz.box>

On 03/23/2017 05:16 AM, David Gibson wrote:
> On Thu, Mar 16, 2017 at 03:35:09PM +0100, Cédric Le Goater wrote:
>> Like this is done for the sPAPR machine, we use a simple array under
>> the PowerNV machine to store the Interrupt Control Presenters (ICP)
>> objects, one for each vCPU. This array is indexed by 'cpu_index' of
>> the CPUState but the users will provide a core PIR number. The mapping
>> is done in the icp_get() handler of the machine and is transparent to
>> XICS.
> 
> I note that you don't actually seem to be setting the cpu's icp backlink.

Indeed. The PowerNV cpu's ICP backlink is assigned in patch : 

	[PATCH v2 7/8] ppc/pnv: link the CPUs to the machine XICSFabric

when the thread realize routine is called, like this is done for 
the sPAPR core. I did not use an object property link because it 
was adding complexity but I suppose it could be done that way if 
needed. 

Ideally, we could allocate the ICP object when the thread object 
is created but we would need to know which type to use, maybe 
through a new XICSFabric handler.

> 
>> We use a list to hold the different Interrupt Control Sources (ICS)
>> objects, as PowerNV needs to handle multiple sources: for PCI-E and
>> for the Processor Service Interface (PSI).
> 
> This is reasonable for now, but I wonder if we could use the fact we
> know the platform architecture to avoid having an explicit ics list.
> IIUC there's one ICS per chip (are there some extras as well?), so we
> could just iterate through the existing chip array, and check each
> one's ICS.

Each PHB object will bring two extra ICS objects (LSI and MSI) and 
there can be a few PHB per chip. But, yes, instead of using a list, 
we could also loop on the machine chips, checking PSI and the PHBs :

	pnv->chips[i]->psi.ics
	pnv->chips[i]->phb[j].lsi_ics
	pnv->chips[i]->phb[j].msis

using QLIST_FOREACH() makes the loop real simple though. Another 
solution would be to use :

	object_child_foreach_recursive(OBJECT(chip), ...);

but that would be slower.


>> Finally, to interface with the XICS layer which manipulates the ICP
>> and ICS objects, we extend the PowerNV machine with an XICSFabric
>> interface and its associated handlers.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>
>>  Changes since v1:
>>
>>  - handled pir-to-cpu_index mapping under icp_get 
>>  - removed ics_eio handler
>>  - changed ICP name indexing
>>  - removed sysbus parenting of the ICP object
>>
>>  hw/ppc/pnv.c          | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/pnv.h  |   4 ++
>>  include/hw/ppc/xics.h |   1 +
>>  3 files changed, 107 insertions(+)
>>
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index 3fa722af82e6..6ff01c3b84d5 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -33,7 +33,10 @@
>>  #include "exec/address-spaces.h"
>>  #include "qemu/cutils.h"
>>  #include "qapi/visitor.h"
>> +#include "monitor/monitor.h"
>> +#include "hw/intc/intc.h"
>>  
>> +#include "hw/ppc/xics.h"
>>  #include "hw/ppc/pnv_xscom.h"
>>  
>>  #include "hw/isa/isa.h"
>> @@ -417,6 +420,26 @@ static void ppc_powernv_init(MachineState *machine)
>>          machine->cpu_model = "POWER8";
>>      }
>>  
>> +    /* Create the Interrupt Control Presenters before the vCPUs */
>> +    pnv->nr_servers = pnv->num_chips * smp_cores * smp_threads;
>> +    pnv->icps = g_new0(PnvICPState, pnv->nr_servers);
>> +    for (i = 0; i < pnv->nr_servers; i++) {
>> +        PnvICPState *icp = &pnv->icps[i];
>> +        char name[32];
>> +
>> +        /* TODO: fix ICP object name to be in sync with the core name */
>> +        snprintf(name, sizeof(name), "icp[%d]", i);
>> +        object_initialize(icp, sizeof(*icp), TYPE_PNV_ICP);
>> +        object_property_add_child(OBJECT(pnv), name, OBJECT(icp),
>> +                                  &error_fatal);
>> +        object_property_add_const_link(OBJECT(icp), "xics", OBJECT(pnv),
>> +                                       &error_fatal);
>> +        object_property_set_bool(OBJECT(icp), true, "realized", &error_fatal);
>> +    }
>> +
>> +    /* and the list of Interrupt Control Sources */
>> +    QLIST_INIT(&pnv->ics);
>> +
>>      /* Create the processor chips */
>>      chip_typename = g_strdup_printf(TYPE_PNV_CHIP "-%s", machine->cpu_model);
>>      if (!object_class_by_name(chip_typename)) {
>> @@ -743,6 +766,58 @@ static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
>>      visit_type_uint32(v, name, &POWERNV_MACHINE(obj)->num_chips, errp);
>>  }
>>  
>> +static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
>> +{
>> +    PnvMachineState *pnv = POWERNV_MACHINE(xi);
>> +    ICSState *ics;
>> +
>> +    QLIST_FOREACH(ics, &pnv->ics, list) {
>> +        if (ics_valid_irq(ics, irq)) {
>> +            return ics;
>> +        }
>> +    }
>> +    return NULL;
>> +}
>> +
>> +static void pnv_ics_resend(XICSFabric *xi)
>> +{
>> +    PnvMachineState *pnv = POWERNV_MACHINE(xi);
>> +    ICSState *ics;
>> +
>> +    QLIST_FOREACH(ics, &pnv->ics, list) {
>> +        ics_resend(ics);
>> +    }
>> +}
>> +
>> +static PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
>> +{
>> +    CPUState *cs;
>> +
>> +    CPU_FOREACH(cs) {
>> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
>> +        CPUPPCState *env = &cpu->env;
>> +
>> +        if (env->spr_cb[SPR_PIR].default_value == pir) {
>> +            return cpu;
>> +        }
>> +    }
>> +
>> +    return NULL;
>> +}
>> +
>> +static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
>> +{
>> +    PnvMachineState *pnv = POWERNV_MACHINE(xi);
>> +    PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
>> +
>> +    if (!cpu) {
>> +        return NULL;
>> +    }
>> +
>> +    assert(cpu->parent_obj.cpu_index < pnv->nr_servers);
>> +    return ICP(&pnv->icps[cpu->parent_obj.cpu_index]);
>> +}
>> +
>>  static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name,
>>                                void *opaque, Error **errp)
>>  {
>> @@ -784,9 +859,27 @@ static void powernv_machine_class_props_init(ObjectClass *oc)
>>                                NULL);
>>  }
>>  
>> +static void pnv_pic_print_info(InterruptStatsProvider *obj,
>> +                               Monitor *mon)
>> +{
>> +    PnvMachineState *pnv = POWERNV_MACHINE(obj);
>> +    ICSState *ics;
>> +    int i;
>> +
>> +    for (i = 0; i < pnv->nr_servers; i++) {
>> +        icp_pic_print_info(ICP(&pnv->icps[i]), mon);
>> +    }
>> +
>> +    QLIST_FOREACH(ics, &pnv->ics, list) {
>> +        ics_pic_print_info(ics, mon);
>> +    }
>> +}
>> +
>>  static void powernv_machine_class_init(ObjectClass *oc, void *data)
>>  {
>>      MachineClass *mc = MACHINE_CLASS(oc);
>> +    XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
>> +    InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
>>  
>>      mc->desc = "IBM PowerNV (Non-Virtualized)";
>>      mc->init = ppc_powernv_init;
>> @@ -797,6 +890,10 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
>>      mc->no_parallel = 1;
>>      mc->default_boot_order = NULL;
>>      mc->default_ram_size = 1 * G_BYTE;
>> +    xic->icp_get = pnv_icp_get;
>> +    xic->ics_get = pnv_ics_get;
>> +    xic->ics_resend = pnv_ics_resend;
>> +    ispc->print_info = pnv_pic_print_info;
>>  
>>      powernv_machine_class_props_init(oc);
>>  }
>> @@ -807,6 +904,11 @@ static const TypeInfo powernv_machine_info = {
>>      .instance_size = sizeof(PnvMachineState),
>>      .instance_init = powernv_machine_initfn,
>>      .class_init    = powernv_machine_class_init,
>> +    .interfaces = (InterfaceInfo[]) {
>> +        { TYPE_XICS_FABRIC },
>> +        { TYPE_INTERRUPT_STATS_PROVIDER },
>> +        { },
>> +    },
>>  };
>>  
>>  static void powernv_machine_register_types(void)
>> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
>> index df98a72006e4..d6ef04771aff 100644
>> --- a/include/hw/ppc/pnv.h
>> +++ b/include/hw/ppc/pnv.h
>> @@ -22,6 +22,7 @@
>>  #include "hw/boards.h"
>>  #include "hw/sysbus.h"
>>  #include "hw/ppc/pnv_lpc.h"
>> +#include "hw/ppc/xics.h"
>>  
>>  #define TYPE_PNV_CHIP "powernv-chip"
>>  #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
>> @@ -114,6 +115,9 @@ typedef struct PnvMachineState {
>>      PnvChip      **chips;
>>  
>>      ISABus       *isa_bus;
>> +    PnvICPState  *icps;
>> +    uint32_t     nr_servers;
>> +    QLIST_HEAD(, ICSState) ics;
>>  } PnvMachineState;
>>  
>>  #define PNV_FDT_ADDR          0x01000000
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index cfcf7ecece69..4b100869003c 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -128,6 +128,7 @@ struct ICSState {
>>      qemu_irq *qirqs;
>>      ICSIRQState *irqs;
>>      XICSFabric *xics;
>> +    QLIST_ENTRY(ICSState) list;
>>  };
>>  
>>  static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
> 

  reply	other threads:[~2017-03-23  8:26 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-16 14:35 [Qemu-devel] [PATCH v2 0/8] ppc/pnv: interrupt controller (POWER8) Cédric Le Goater
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 1/8] ppc/xics: introduce an ICPState backlink under PowerPCCPU Cédric Le Goater
2017-03-22  6:33   ` David Gibson
2017-03-22 16:25     ` Cédric Le Goater
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 2/8] spapr: move the IRQ server number mapping under the machine Cédric Le Goater
2017-03-23  4:10   ` David Gibson
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 3/8] ppc/xics: add a realize() handler to ICPStateClass Cédric Le Goater
2017-03-23  4:10   ` David Gibson
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 4/8] ppc/pnv: add a PnvICPState object Cédric Le Goater
2017-03-23  4:12   ` David Gibson
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 5/8] ppc/pnv: create the ICP and ICS objects under the machine Cédric Le Goater
2017-03-23  4:16   ` David Gibson
2017-03-23  8:25     ` Cédric Le Goater [this message]
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 6/8] ppc/pnv: add a helper to calculate MMIO addresses registers Cédric Le Goater
2017-03-23  4:16   ` David Gibson
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 7/8] ppc/pnv: link the CPUs to the machine XICSFabric Cédric Le Goater
2017-03-23  4:18   ` David Gibson
2017-03-16 14:35 ` [Qemu-devel] [PATCH v2 8/8] ppc/pnv: add memory regions for the ICP registers Cédric Le Goater
2017-03-23  4:20   ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1becb703-05d2-a5fd-25c1-ecd1037acd0c@kaod.org \
    --to=clg@kaod.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.