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 05/19] ppc/pnv: add XIVE support
Date: Tue, 5 Mar 2019 14:42:59 +1100	[thread overview]
Message-ID: <20190305034259.GG7877@umbus.fritz.box> (raw)
In-Reply-To: <22310d64-31f2-537a-1b04-1f38683697f1@kaod.org>

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

On Thu, Feb 21, 2019 at 09:32:44AM +0100, Cédric Le Goater wrote:
> On 2/21/19 4:13 AM, David Gibson wrote:
> > On Tue, Feb 19, 2019 at 08:31:25AM +0100, Cédric Le Goater wrote:
> >> On 2/12/19 6:40 AM, David Gibson wrote:
> >>> On Mon, Jan 28, 2019 at 10:46:11AM +0100, Cédric Le Goater wrote:
> > [snip]
> >>>>  #endif /* _PPC_PNV_H */
> >>>> diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
> >>>> index 9961ea3a92cd..8e57c064e661 100644
> >>>> --- a/include/hw/ppc/pnv_core.h
> >>>> +++ b/include/hw/ppc/pnv_core.h
> >>>> @@ -49,6 +49,7 @@ typedef struct PnvCoreClass {
> >>>>  
> >>>>  typedef struct PnvCPUState {
> >>>>      struct ICPState *icp;
> >>>> +    struct XiveTCTX *tctx;
> >>>
> >>> Unlike sPAPR, we really do always know in advance the interrupt
> >>> controller for a particular machine.  I think it makes sense to
> >>> further split the POWER8 and POWER9 cases here, so we only track one
> >>> for any given setup.
> >>
> >> So, you would define a : 
> >>
> >>   typedef struct Pnv9CPUState {
> >>       struct XiveTCTX *tctx;
> >>   } Pnv9CPUState;
> >>
> >> to be allocated when the core is realized ? and later the routine 
> >> pnv_chip_power9_intc_create() would assign the ->tctx pointer.
> > 
> > Sounds about right.
> > 
> > [snip]
> >>>> +    uint32_t      nr_ends;
> >>>> +    XiveENDSource end_source;
> >>>> +
> >>>> +    /* Interrupt controller registers */
> >>>> +    uint64_t      regs[0x300];
> >>>> +
> >>>> +    /* Can be configured by FW */
> >>>> +    uint32_t      tctx_chipid;
> >>>> +    uint32_t      chip_id;
> >>>
> >>> Can't you derive that since you have a pointer to the owning chip?
> >>
> >> Not always, there are register fields to purposely override this value.
> >> I can improve the current code a little I think.
> > 
> > Ok.
> > 
> > [snip]
> >>>> +/*
> >>>> + * Virtual structures table (VST)
> >>>> + */
> >>>> +typedef struct XiveVstInfo {
> >>>> +    uint32_t    type;
> >>>> +    const char *name;
> >>>> +    uint32_t    size;
> >>>> +    uint32_t    max_blocks;
> >>>> +} XiveVstInfo;
> >>>> +
> >>>> +static const XiveVstInfo vst_infos[] = {
> >>>> +    [VST_TSEL_IVT]  = { VST_TSEL_IVT,  "EAT",  sizeof(XiveEAS), 16 },
> >>>
> >>> I don't love explicitly storing the type/index in each record, as well
> >>> as it being implicit in the table slot.
> >>
> >> The 'vst_infos' table decribes the different table types and the 'type' 
> >> field is used to index the runtime table of VSDs. See
> >> pnv_xive_vst_addr()
> > 
> > Yes, I know what it's for but it's still redundant information.  You
> > could avoid it, for example, by passing around an index instead of a
> > pointer to a vst_infos[] slot - then you can look up both vst_infos
> > and the other table using that index.
> 
> :) This is exactly what the code was doing before and I thought passing 
> the pointer was cleaner ! No problem. This is minor. I will revert.
> 
> > [snip]
> >>>> +    case CQ_TM1_BAR: /* TM BAR. 4 pages. Map only once */
> >>>> +    case CQ_TM2_BAR: /* second TM BAR. for hotplug. Not modeled */
> >>>> +        xive->tm_shift = val & CQ_TM_BAR_64K ? 16 : 12;
> >>>> +        if (!(val & CQ_TM_BAR_VALID)) {
> >>>> +            xive->tm_base = 0;
> >>>> +            if (xive->regs[reg] & CQ_TM_BAR_VALID && xive->chip_id == 0) {
> >>>> +                memory_region_del_subregion(sysmem, &xive->tm_mmio);
> >>>> +            }
> >>>> +        } else {
> >>>> +            xive->tm_base = val & ~(CQ_TM_BAR_VALID | CQ_TM_BAR_64K);
> >>>> +            if (!(xive->regs[reg] & CQ_TM_BAR_VALID) && xive->chip_id == 0) {
> >>>> +                memory_region_add_subregion(sysmem, xive->tm_base,
> >>>> +                                            &xive->tm_mmio);
> >>>> +            }
> >>>> +        }
> >>>> +        break;
> >>>> +
> >>>> +    case CQ_PC_BARM:
> >>>> +        xive->regs[reg] = val;
> >>>
> >>> As discussed elsewhere, this seems to be a big mix of writing things
> >>> directly into regs[reg] and doing other things instead, and you really
> >>> want to go one way or the other.  I'd suggest dropping xive->regs[]
> >>> and instead putting the state you need persistent into its own
> >>> variables.
> >>
> >> I made a big effort to introduce helper routines to avoid storing values 
> >> that can be calculated under the PnvXive model, as you asked for it. 
> >> The assignment above is only necessary for the pnv_xive_pc_size() below
> >> and I don't know how handle this current case without duplicating the 
> >> switch statement, which I think is ugly.
> > 
> > I'm not sure quite what you mean about duplicating the case.
> >> The point here is that since you're only storing in a couple of the
> > switch cases, you can just have explicit data backing just those
> > values and write to those in the switch cases instead of having a
> > great big regs[] array of which only a few bits are used.
> 
> The model uses these registers :
> 
>     xive->regs[PC_GLOBAL_CONFIG >> 3]
>     xive->regs[CQ_VC_BARM >> 3]
>     xive->regs[CQ_PC_BARM >> 3]
>     xive->regs[CQ_TAR >> 3]
>     xive->regs[VC_GLOBAL_CONFIG >> 3]
>     xive->regs[VC_VSD_TABLE_ADDR >> 3]);
>     xive->regs[CQ_IC_BAR]
>     xive->regs[CQ_TM1_BAR]
>     xive->regs[CQ_VC_BAR]
>     xive->regs[PC_THREAD_EN_REG0 >> 3]
>     xive->regs[PC_THREAD_EN_REG1 >> 3]
>     xive->regs[(VC_EQC_CWATCH_DAT0 >> 3) + i];
>     xive->regs[(PC_VPC_CWATCH_DAT0 >> 3) + i]
>     xive->regs[VC_EQC_CONFIG];
>     xive->regs[VC_EQC_SCRUB_TRIG]
>     xive->regs[PC_AT_KILL];
>     xive->regs[VC_AT_MACRO_KILL]
>     xive->regs[(PC_TCTXT_INDIR0 >> 3) + i]
> 
> The regs array is useful for the different cache watch but apart 
> from that, yes, we could use independent fields. I will see how much 
> energy I have to put into this change. 
> 
> All the registers change in P10, may be this will be a better time
> to share a common PnvXive model and isolate the HW interface of each
> processor.

Changes on P10 does seem like a pretty good reason to decouple the
qemu internal state from the P9 register interface layout.

> >> So, I will keep the xive->regs[] and make the couple of fixes still needed.
> > 
> > [snip]
> >>>> +/*
> >>>> + * Virtualization Controller MMIO region containing the IPI and END ESB pages
> >>>> + */
> >>>> +static uint64_t pnv_xive_vc_read(void *opaque, hwaddr offset,
> >>>> +                                 unsigned size)
> >>>> +{
> >>>> +    PnvXive *xive = PNV_XIVE(opaque);
> >>>> +    uint64_t edt_index = offset >> pnv_xive_edt_shift(xive);
> >>>> +    uint64_t edt_type = 0;
> >>>> +    uint64_t edt_offset;
> >>>> +    MemTxResult result;
> >>>> +    AddressSpace *edt_as = NULL;
> >>>> +    uint64_t ret = -1;
> >>>> +
> >>>> +    if (edt_index < XIVE_TABLE_EDT_MAX) {
> >>>> +        edt_type = GETFIELD(CQ_TDR_EDT_TYPE, xive->edt[edt_index]);
> >>>> +    }
> >>>> +
> >>>> +    switch (edt_type) {
> >>>> +    case CQ_TDR_EDT_IPI:
> >>>> +        edt_as = &xive->ipi_as;
> >>>> +        break;
> >>>> +    case CQ_TDR_EDT_EQ:
> >>>> +        edt_as = &xive->end_as;
> >>>
> >>> I'm not entirely understanding the function of these AddressSpace objectz.
> >>
> >> The IPI and END ESB pages are exposed in the same VC region. But this VC 
> >> region is not splitted between the two types with a single offset. It 
> >> is segmented with the EDT tables which defines the type of each segment. 
> >>
> >> The purpose of these address spaces is to translate the load/stores in 
> >> the VC region in the equivalent IPI or END region exposing contigously 
> >> ESB pages of the same type: 'end_edt_mmio' and 'ipi_edt_mmio'. 
> >>
> >> The memory regions of the XiveENDSource and the XiveSource for the IPIs 
> >> are mapped in 'end_edt_mmio' and 'ipi_edt_mmio'.
> > 
> > Hmm.  Ok, I'm not immediately seeing why you can't map the various IPI
> > or END blocks directly into address_space memory rather than having
> > this extra internal layer of indirection.
> 
> I think I see what you mean.
> 
> You would get rid of the intermediate MR &xive->ipi_edt_mmio and map 
> directly &xsrc->esb_mmio into &xive->ipi_mmio
> 
> same for the ENDs, map directly &end_xsrc->esb_mmio in &xive->end_mmio
> 
> That might be overkill indeed. I will check.
> 
> >> (This is changing for P10, should be simpler)   
> > 
> > [snip]
> >>>> +/*
> >>>> + *  Maximum number of IRQs and ENDs supported by HW
> >>>> + */
> >>>> +#define PNV_XIVE_NR_IRQS (PNV9_XIVE_VC_SIZE / (1ull << XIVE_ESB_64K_2PAGE))
> >>>> +#define PNV_XIVE_NR_ENDS (PNV9_XIVE_VC_SIZE / (1ull << XIVE_ESB_64K_2PAGE))
> >>>> +
> >>>> +static void pnv_xive_realize(DeviceState *dev, Error **errp)
> >>>> +{
> >>>> +    PnvXive *xive = PNV_XIVE(dev);
> >>>> +    XiveSource *xsrc = &xive->source;
> >>>> +    XiveENDSource *end_xsrc = &xive->end_source;
> >>>> +    Error *local_err = NULL;
> >>>> +    Object *obj;
> >>>> +
> >>>> +    obj = object_property_get_link(OBJECT(dev), "chip", &local_err);
> >>>> +    if (!obj) {
> >>>> +        error_propagate(errp, local_err);
> >>>> +        error_prepend(errp, "required link 'chip' not found: ");
> >>>> +        return;
> >>>> +    }
> >>>> +
> >>>> +    /* The PnvChip id identifies the XIVE interrupt controller. */
> >>>> +    xive->chip = PNV_CHIP(obj);
> >>>> +
> >>>> +    /*
> >>>> +     * Xive Interrupt source and END source object with the maximum
> >>>> +     * allowed HW configuration. The ESB MMIO regions will be resized
> >>>> +     * dynamically when the controller is configured by the FW to
> >>>> +     * limit accesses to resources not provisioned.
> >>>> +     */
> >>>> +    object_property_set_int(OBJECT(xsrc), PNV_XIVE_NR_IRQS, "nr-irqs",
> >>>> +                            &error_fatal);
> >>>
> >>> You have a constant here, but your router object also includes a
> >>> nr_irqs field.  What's up with that?
> >>
> >> The XiveSource object of PnvXive is realized for the maximum size allowed
> >> by HW because we don't know how much IRQs the FW will provision for.
> >>
> >> The 'nr_irqs' is the number of IRQs configured by the FW (We changed the
> >> name to 'nr_ipis') See routine pnv_xive_vst_set_exclusive()
> > 
> > Ah, ok.
> > 
> 
> I will try to get that done for 4.0. 
> 
> PSI and LPC P9 models should be less complex to review.  
> 
> Thanks,
> 
> C.
> 

-- 
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: 833 bytes --]

  reply	other threads:[~2019-03-05  5:03 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-28  9:46 [Qemu-devel] [PATCH 00/19] ppc: support for the baremetal XIVE interrupt controller (POWER9) Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 01/19] ppc/xive: hardwire the Physical CAM line of the thread context Cédric Le Goater
2019-02-08  5:44   ` David Gibson
2019-02-08  7:28     ` Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 02/19] ppc: externalize ppc_get_vcpu_by_pir() Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 03/19] xive: extend the XiveRouter get_tctx() method with the page offset Cédric Le Goater
2019-02-12  4:34   ` David Gibson
2019-02-12  8:25     ` Cédric Le Goater
2019-02-12 20:31       ` Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 04/19] ppc/pnv: xive: export the TIMA memory accessors Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 05/19] ppc/pnv: add XIVE support Cédric Le Goater
2019-02-12  5:40   ` David Gibson
2019-02-19  7:31     ` Cédric Le Goater
2019-02-21  3:13       ` David Gibson
2019-02-21  8:32         ` Cédric Le Goater
2019-03-05  3:42           ` David Gibson [this message]
2019-01-28  9:46 ` [Qemu-devel] [PATCH 06/19] target/ppc: Remove some #if 0'ed code Cédric Le Goater
2019-02-12  5:41   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 07/19] target/ppc: Make special ORs match x86 pause and don't generate on mttcg Cédric Le Goater
2019-02-12  5:59   ` David Gibson
2019-02-13  0:03     ` Benjamin Herrenschmidt
2019-02-13  4:54       ` David Gibson
2019-02-13  8:07         ` Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 08/19] target/ppc: Fix nip on power management instructions Cédric Le Goater
2019-02-12  6:02   ` David Gibson
2019-02-13  0:04     ` Benjamin Herrenschmidt
2019-02-15 15:30       ` Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 09/19] target/ppc: Don't clobber MSR:EE on PM instructions Cédric Le Goater
2019-02-12  6:05   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 10/19] target/ppc: Fix support for "STOP light" states on POWER9 Cédric Le Goater
2019-02-13  5:05   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 11/19] target/ppc: Move "wakeup reset" code to a separate function Cédric Le Goater
2019-02-13  5:06   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 12/19] target/ppc: Disable ISA 2.06 PM instructions on POWER9 Cédric Le Goater
2019-02-13  5:07   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 13/19] target/ppc: Rename "in_pm_state" to "resume_as_sreset" Cédric Le Goater
2019-02-13  5:08   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 14/19] target/ppc: Add POWER9 exception model Cédric Le Goater
2019-02-13  5:10   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 15/19] target/ppc: Detect erroneous condition in interrupt delivery Cédric Le Goater
2019-02-13  5:11   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 16/19] target/ppc: Add Hypervisor Virtualization Interrupt on POWER9 Cédric Le Goater
2019-02-13  5:12   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 17/19] target/ppc: Add POWER9 external interrupt model Cédric Le Goater
2019-02-13  5:16   ` David Gibson
2019-02-15 15:43     ` Cédric Le Goater
2019-01-28  9:46 ` [Qemu-devel] [PATCH 18/19] ppc/xive: Make XIVE generate the proper interrupt types Cédric Le Goater
2019-02-13  5:17   ` David Gibson
2019-01-28  9:46 ` [Qemu-devel] [PATCH 19/19] target/ppc: Add support for LPCR:HEIC on POWER9 Cédric Le Goater
2019-02-13  5:18   ` 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=20190305034259.GG7877@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).