qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: "Cédric Le Goater" <clg@kaod.org>
Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH for-2.10 3/8] ppc/pnv: create the ICP and ICS objects under the machine
Date: Tue, 14 Mar 2017 16:45:19 +1100	[thread overview]
Message-ID: <20170314054519.GJ12564@umbus.fritz.box> (raw)
In-Reply-To: <1488970371-8865-4-git-send-email-clg@kaod.org>

[-- Attachment #1: Type: text/plain, Size: 7722 bytes --]

On Wed, Mar 08, 2017 at 11:52:46AM +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.
> 
> 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).
> 
> 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>
> ---
>  hw/ppc/pnv.c          | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/pnv.h  |  4 +++
>  include/hw/ppc/xics.h |  1 +
>  3 files changed, 94 insertions(+)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 09f0d22defb8..461d3535e99c 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -32,6 +32,8 @@
>  #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/pnv_xscom.h"
>  
> @@ -416,6 +418,23 @@ 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(ICPState, pnv->nr_servers);
> +    for (i = 0; i < pnv->nr_servers; i++) {
> +        ICPState *icp = &pnv->icps[i];
> +        object_initialize(icp, sizeof(*icp), TYPE_ICP);
> +        qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());

Your fixup for the PAPR case suggests this is not the right approach
to the device initialization.

> +        object_property_add_child(OBJECT(pnv), "icp[*]", OBJECT(icp),
> +                                  &error_fatal);

This isn't an urgent problem, but I dislike using the icp[*]
behaviour as a rule (it's fixed now, but it just to be you could
easily get O(n^3) behaviour using it).  In this case you already have
a handle on a specific id for the object.

As well as being a bit less expensive, using an explicit index means
that the exposed QOM address will definitely match an otherwise
meaningful id, rather than just lining up by accident if all the
orders remain the same.

> +        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)) {
> @@ -742,6 +761,48 @@ 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 void pnv_ics_eoi(XICSFabric *xi, int irq)
> +{
> +    PnvMachineState *pnv = POWERNV_MACHINE(xi);
> +    ICSState *ics;
> +
> +    QLIST_FOREACH(ics, &pnv->ics, list) {
> +        if (ics_valid_irq(ics, irq)) {

Unless something is badly wrong, this should only return true for
exactly one iteration through the loop.  Which makes this equivalent
to ics_get() followed by ics_eoi().

> +            ics_eoi(ics, irq);
> +        }
> +    }
> +}
> +
> +static ICPState *pnv_icp_get(XICSFabric *xi, int server)
> +{
> +    PnvMachineState *pnv = POWERNV_MACHINE(xi);
> +
> +    return (server < pnv->nr_servers) ? &pnv->icps[server] : NULL;
> +}
> +
>  static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name,
>                                void *opaque, Error **errp)
>  {
> @@ -783,9 +844,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(&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;
> @@ -796,6 +875,11 @@ 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_eoi = pnv_ics_eoi;
> +    xic->ics_resend = pnv_ics_resend;
> +    ispc->print_info = pnv_pic_print_info;
>  
>      powernv_machine_class_props_init(oc);
>  }
> @@ -806,6 +890,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..6a0b004cea93 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;
> +    ICPState     *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 00b003b2392d..c2032cac55f6 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -115,6 +115,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)

-- 
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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2017-03-14  5:55 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-08 10:52 [Qemu-devel] [PATCH for-2.10 0/8] ppc/pnv: interrupt controller (POWER8) Cédric Le Goater
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 1/8] ppc/xics: add a xics_get_cpu_index_by_pir() helper Cédric Le Goater
2017-03-14  5:38   ` David Gibson
2017-03-14  8:11     ` Cédric Le Goater
2017-03-14 17:00     ` Cédric Le Goater
2017-03-15  4:53       ` David Gibson
2017-03-15 10:04         ` Cédric Le Goater
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 2/8] ppc/xics: add an ics_eoi() handler to XICSFabric Cédric Le Goater
2017-03-14  5:40   ` David Gibson
2017-03-14  8:12     ` Cédric Le Goater
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 3/8] ppc/pnv: create the ICP and ICS objects under the machine Cédric Le Goater
2017-03-14  5:45   ` David Gibson [this message]
2017-03-14  9:47     ` Cédric Le Goater
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 4/8] ppc/pnv: add memory regions for the ICP registers Cédric Le Goater
2017-03-08 11:24   ` Philippe Mathieu-Daudé
2017-03-08 13:33     ` Cédric Le Goater
2017-03-14  5:49   ` David Gibson
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 5/8] ppc/pnv: map the ICP memory regions Cédric Le Goater
2017-03-14  5:52   ` David Gibson
2017-03-14 10:02     ` Cédric Le Goater
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 6/8] ppc/pnv: Add cut down PSI bridge model and hookup external interrupt Cédric Le Goater
2017-03-15  6:16   ` David Gibson
2017-03-15  9:38     ` Benjamin Herrenschmidt
2017-03-16 13:52     ` Cédric Le Goater
2017-03-17  2:00       ` David Gibson
2017-03-17  8:27         ` Cédric Le Goater
2017-03-21 13:36       ` Cédric Le Goater
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 7/8] ppc/pnv: Add OCC model stub with interrupt support Cédric Le Goater
2017-03-08 10:52 ` [Qemu-devel] [PATCH for-2.10 8/8] ppc/pnv: Add support for POWER8+ LPC Controller Cédric Le Goater

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=20170314054519.GJ12564@umbus.fritz.box \
    --to=david@gibson.dropbear.id.au \
    --cc=clg@kaod.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).