Re: [Qemu-devel] [PATCH 05/19] ppc/pnv: add XIVE support

2019-03-04 Thread David Gibson
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_ttype;
>  +const char *name;
>  +uint32_tsize;
>  +uint32_tmax_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, >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,
>  +>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]
> 

Re: [Qemu-devel] [PATCH 05/19] ppc/pnv: add XIVE support

2019-02-21 Thread Cédric Le Goater
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_ttype;
 +const char *name;
 +uint32_tsize;
 +uint32_tmax_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, >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,
 +>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]

Re: [Qemu-devel] [PATCH 05/19] ppc/pnv: add XIVE support

2019-02-20 Thread David Gibson
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_ttype;
> >> +const char *name;
> >> +uint32_tsize;
> >> +uint32_tmax_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.

[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, >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,
> >> +>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.

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

Re: [Qemu-devel] [PATCH 05/19] ppc/pnv: add XIVE support

2019-02-18 Thread Cédric Le Goater
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:
>> This is simple model of the POWER9 XIVE interrupt controller for the
>> PowerNV machine. XIVE for baremetal is a complex controller and the
>> model only addresses the needs of the skiboot firmware.
>>
>> The PowerNV model reuses the common XIVE framework developed for sPAPR
>> and the fundamentals aspects are quite the same. The difference are
>> outlined below.
>>
>> The controller initial BAR configuration is performed using the XSCOM
>> bus from there, MMIO are used for further configuration.
>>
>> The MMIO regions exposed are :
>>
>>  - Interrupt controller registers
>>  - ESB pages for IPIs and ENDs
>>  - Presenter MMIO (Not used)
>>  - Thread Interrupt Management Area MMIO, direct and indirect
>>
>> The virtualization controller MMIO region containing the IPI ESB pages
>> and END ESB pages is sub-divided into "sets" which map portions of the
>> VC region to the different ESB pages. These are modeled with custom
>> address spaces and the XiveSource and XiveENDSource objects are sized
>> to the maximum allowed by HW. The memory regions are resized at
>> run-time using the configuration of EDT set translation table provided
>> by the firmware.
>>
>> The XIVE virtualization structure tables (EAT, ENDT, NVTT) are now in
>> the machine RAM and not in the hypervisor anymore. The firmware
>> (skiboot) configures these tables using Virtual Structure Descriptor
>> defining the characteristics of each table : SBE, EAS, END and
>> NVT. These are later used to access the virtual interrupt entries. The
>> internal cache of these tables in the interrupt controller is updated
>> and invalidated using a set of registers.
>>
>> Still to address to complete the model but not fully required is the
>> support for block grouping. Escalation support will be necessary for
>> KVM guests.
>>
>> Signed-off-by: Cédric Le Goater 
>> ---
>>  hw/intc/pnv_xive_regs.h|  315 +++
>>  include/hw/ppc/pnv.h   |   21 +
>>  include/hw/ppc/pnv_core.h  |1 +
>>  include/hw/ppc/pnv_xive.h  |   95 ++
>>  include/hw/ppc/pnv_xscom.h |3 +
>>  include/hw/ppc/xive.h  |1 +
>>  hw/intc/pnv_xive.c | 1698 
>>  hw/intc/xive.c |   59 +-
>>  hw/ppc/pnv.c   |   68 +-
>>  hw/intc/Makefile.objs  |2 +-
>>  10 files changed, 2253 insertions(+), 10 deletions(-)
>>  create mode 100644 hw/intc/pnv_xive_regs.h
>>  create mode 100644 include/hw/ppc/pnv_xive.h
>>  create mode 100644 hw/intc/pnv_xive.c
>>
>> diff --git a/hw/intc/pnv_xive_regs.h b/hw/intc/pnv_xive_regs.h
>> new file mode 100644
>> index ..96ac27701cee
>> --- /dev/null
>> +++ b/hw/intc/pnv_xive_regs.h
>> @@ -0,0 +1,315 @@
>> +/*
>> + * QEMU PowerPC XIVE interrupt controller model
>> + *
>> + * Copyright (c) 2017-2018, IBM Corporation.
>> + *
>> + * This code is licensed under the GPL version 2 or later. See the
>> + * COPYING file in the top-level directory.
>> + */
>> +
>> +#ifndef PPC_PNV_XIVE_REGS_H
>> +#define PPC_PNV_XIVE_REGS_H
>> +
>> +/* IC register offsets 0x0 - 0x400 */
>> +#define CQ_SWI_CMD_HIST 0x020
>> +#define CQ_SWI_CMD_POLL 0x028
>> +#define CQ_SWI_CMD_BCAST0x030
>> +#define CQ_SWI_CMD_ASSIGN   0x038
>> +#define CQ_SWI_CMD_BLK_UPD  0x040
>> +#define CQ_SWI_RSP  0x048
>> +#define X_CQ_CFG_PB_GEN 0x0a
>> +#define CQ_CFG_PB_GEN   0x050
>> +#define   CQ_INT_ADDR_OPT   PPC_BITMASK(14, 15)
>> +#define X_CQ_IC_BAR 0x10
>> +#define X_CQ_MSGSND 0x0b
>> +#define CQ_MSGSND   0x058
>> +#define CQ_CNPM_SEL 0x078
>> +#define CQ_IC_BAR   0x080
>> +#define   CQ_IC_BAR_VALID   PPC_BIT(0)
>> +#define   CQ_IC_BAR_64K PPC_BIT(1)
>> +#define X_CQ_TM1_BAR0x12
>> +#define CQ_TM1_BAR  0x90
>> +#define X_CQ_TM2_BAR0x014
>> +#define CQ_TM2_BAR  0x0a0
>> +#define   CQ_TM_BAR_VALID   PPC_BIT(0)
>> +#define   CQ_TM_BAR_64K PPC_BIT(1)
>> +#define X_CQ_PC_BAR 0x16
>> +#define CQ_PC_BAR   0x0b0
>> +#define  CQ_PC_BAR_VALIDPPC_BIT(0)
>> +#define X_CQ_PC_BARM0x17
>> +#define CQ_PC_BARM  0x0b8
>> +#define  CQ_PC_BARM_MASKPPC_BITMASK(26, 38)
>> +#define X_CQ_VC_BAR 0x18
>> +#define CQ_VC_BAR   0x0c0
>> +#define  CQ_VC_BAR_VALIDPPC_BIT(0)
>> +#define X_CQ_VC_BARM0x19
>> +#define CQ_VC_BARM  0x0c8
>> +#define  CQ_VC_BARM_MASKPPC_BITMASK(21, 37)
>> +#define X_CQ_TAR0x1e
>> +#define CQ_TAR  0x0f0
>> +#define  CQ_TAR_TBL_AUTOINC PPC_BIT(0)
>> +#define  CQ_TAR_TSELPPC_BITMASK(12, 15)
>> +#define  CQ_TAR_TSEL_BLKPPC_BIT(12)
>> +#define  CQ_TAR_TSEL_MIGPPC_BIT(13)
>> +#define  CQ_TAR_TSEL_VDTPPC_BIT(14)
>> 

Re: [Qemu-devel] [PATCH 05/19] ppc/pnv: add XIVE support

2019-02-11 Thread David Gibson
On Mon, Jan 28, 2019 at 10:46:11AM +0100, Cédric Le Goater wrote:
> This is simple model of the POWER9 XIVE interrupt controller for the
> PowerNV machine. XIVE for baremetal is a complex controller and the
> model only addresses the needs of the skiboot firmware.
> 
> The PowerNV model reuses the common XIVE framework developed for sPAPR
> and the fundamentals aspects are quite the same. The difference are
> outlined below.
> 
> The controller initial BAR configuration is performed using the XSCOM
> bus from there, MMIO are used for further configuration.
> 
> The MMIO regions exposed are :
> 
>  - Interrupt controller registers
>  - ESB pages for IPIs and ENDs
>  - Presenter MMIO (Not used)
>  - Thread Interrupt Management Area MMIO, direct and indirect
> 
> The virtualization controller MMIO region containing the IPI ESB pages
> and END ESB pages is sub-divided into "sets" which map portions of the
> VC region to the different ESB pages. These are modeled with custom
> address spaces and the XiveSource and XiveENDSource objects are sized
> to the maximum allowed by HW. The memory regions are resized at
> run-time using the configuration of EDT set translation table provided
> by the firmware.
>
> The XIVE virtualization structure tables (EAT, ENDT, NVTT) are now in
> the machine RAM and not in the hypervisor anymore. The firmware
> (skiboot) configures these tables using Virtual Structure Descriptor
> defining the characteristics of each table : SBE, EAS, END and
> NVT. These are later used to access the virtual interrupt entries. The
> internal cache of these tables in the interrupt controller is updated
> and invalidated using a set of registers.
> 
> Still to address to complete the model but not fully required is the
> support for block grouping. Escalation support will be necessary for
> KVM guests.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/intc/pnv_xive_regs.h|  315 +++
>  include/hw/ppc/pnv.h   |   21 +
>  include/hw/ppc/pnv_core.h  |1 +
>  include/hw/ppc/pnv_xive.h  |   95 ++
>  include/hw/ppc/pnv_xscom.h |3 +
>  include/hw/ppc/xive.h  |1 +
>  hw/intc/pnv_xive.c | 1698 
>  hw/intc/xive.c |   59 +-
>  hw/ppc/pnv.c   |   68 +-
>  hw/intc/Makefile.objs  |2 +-
>  10 files changed, 2253 insertions(+), 10 deletions(-)
>  create mode 100644 hw/intc/pnv_xive_regs.h
>  create mode 100644 include/hw/ppc/pnv_xive.h
>  create mode 100644 hw/intc/pnv_xive.c
> 
> diff --git a/hw/intc/pnv_xive_regs.h b/hw/intc/pnv_xive_regs.h
> new file mode 100644
> index ..96ac27701cee
> --- /dev/null
> +++ b/hw/intc/pnv_xive_regs.h
> @@ -0,0 +1,315 @@
> +/*
> + * QEMU PowerPC XIVE interrupt controller model
> + *
> + * Copyright (c) 2017-2018, IBM Corporation.
> + *
> + * This code is licensed under the GPL version 2 or later. See the
> + * COPYING file in the top-level directory.
> + */
> +
> +#ifndef PPC_PNV_XIVE_REGS_H
> +#define PPC_PNV_XIVE_REGS_H
> +
> +/* IC register offsets 0x0 - 0x400 */
> +#define CQ_SWI_CMD_HIST 0x020
> +#define CQ_SWI_CMD_POLL 0x028
> +#define CQ_SWI_CMD_BCAST0x030
> +#define CQ_SWI_CMD_ASSIGN   0x038
> +#define CQ_SWI_CMD_BLK_UPD  0x040
> +#define CQ_SWI_RSP  0x048
> +#define X_CQ_CFG_PB_GEN 0x0a
> +#define CQ_CFG_PB_GEN   0x050
> +#define   CQ_INT_ADDR_OPT   PPC_BITMASK(14, 15)
> +#define X_CQ_IC_BAR 0x10
> +#define X_CQ_MSGSND 0x0b
> +#define CQ_MSGSND   0x058
> +#define CQ_CNPM_SEL 0x078
> +#define CQ_IC_BAR   0x080
> +#define   CQ_IC_BAR_VALID   PPC_BIT(0)
> +#define   CQ_IC_BAR_64K PPC_BIT(1)
> +#define X_CQ_TM1_BAR0x12
> +#define CQ_TM1_BAR  0x90
> +#define X_CQ_TM2_BAR0x014
> +#define CQ_TM2_BAR  0x0a0
> +#define   CQ_TM_BAR_VALID   PPC_BIT(0)
> +#define   CQ_TM_BAR_64K PPC_BIT(1)
> +#define X_CQ_PC_BAR 0x16
> +#define CQ_PC_BAR   0x0b0
> +#define  CQ_PC_BAR_VALIDPPC_BIT(0)
> +#define X_CQ_PC_BARM0x17
> +#define CQ_PC_BARM  0x0b8
> +#define  CQ_PC_BARM_MASKPPC_BITMASK(26, 38)
> +#define X_CQ_VC_BAR 0x18
> +#define CQ_VC_BAR   0x0c0
> +#define  CQ_VC_BAR_VALIDPPC_BIT(0)
> +#define X_CQ_VC_BARM0x19
> +#define CQ_VC_BARM  0x0c8
> +#define  CQ_VC_BARM_MASKPPC_BITMASK(21, 37)
> +#define X_CQ_TAR0x1e
> +#define CQ_TAR  0x0f0
> +#define  CQ_TAR_TBL_AUTOINC PPC_BIT(0)
> +#define  CQ_TAR_TSELPPC_BITMASK(12, 15)
> +#define  CQ_TAR_TSEL_BLKPPC_BIT(12)
> +#define  CQ_TAR_TSEL_MIGPPC_BIT(13)
> +#define  CQ_TAR_TSEL_VDTPPC_BIT(14)
> +#define  CQ_TAR_TSEL_EDTPPC_BIT(15)
> +#define  CQ_TAR_TSEL_INDEX  PPC_BITMASK(26, 31)
> +#define X_CQ_TDR0x1f
> +#define 

[Qemu-devel] [PATCH 05/19] ppc/pnv: add XIVE support

2019-01-28 Thread Cédric Le Goater
This is simple model of the POWER9 XIVE interrupt controller for the
PowerNV machine. XIVE for baremetal is a complex controller and the
model only addresses the needs of the skiboot firmware.

The PowerNV model reuses the common XIVE framework developed for sPAPR
and the fundamentals aspects are quite the same. The difference are
outlined below.

The controller initial BAR configuration is performed using the XSCOM
bus from there, MMIO are used for further configuration.

The MMIO regions exposed are :

 - Interrupt controller registers
 - ESB pages for IPIs and ENDs
 - Presenter MMIO (Not used)
 - Thread Interrupt Management Area MMIO, direct and indirect

The virtualization controller MMIO region containing the IPI ESB pages
and END ESB pages is sub-divided into "sets" which map portions of the
VC region to the different ESB pages. These are modeled with custom
address spaces and the XiveSource and XiveENDSource objects are sized
to the maximum allowed by HW. The memory regions are resized at
run-time using the configuration of EDT set translation table provided
by the firmware.
   
The XIVE virtualization structure tables (EAT, ENDT, NVTT) are now in
the machine RAM and not in the hypervisor anymore. The firmware
(skiboot) configures these tables using Virtual Structure Descriptor
defining the characteristics of each table : SBE, EAS, END and
NVT. These are later used to access the virtual interrupt entries. The
internal cache of these tables in the interrupt controller is updated
and invalidated using a set of registers.

Still to address to complete the model but not fully required is the
support for block grouping. Escalation support will be necessary for
KVM guests.

Signed-off-by: Cédric Le Goater 
---
 hw/intc/pnv_xive_regs.h|  315 +++
 include/hw/ppc/pnv.h   |   21 +
 include/hw/ppc/pnv_core.h  |1 +
 include/hw/ppc/pnv_xive.h  |   95 ++
 include/hw/ppc/pnv_xscom.h |3 +
 include/hw/ppc/xive.h  |1 +
 hw/intc/pnv_xive.c | 1698 
 hw/intc/xive.c |   59 +-
 hw/ppc/pnv.c   |   68 +-
 hw/intc/Makefile.objs  |2 +-
 10 files changed, 2253 insertions(+), 10 deletions(-)
 create mode 100644 hw/intc/pnv_xive_regs.h
 create mode 100644 include/hw/ppc/pnv_xive.h
 create mode 100644 hw/intc/pnv_xive.c

diff --git a/hw/intc/pnv_xive_regs.h b/hw/intc/pnv_xive_regs.h
new file mode 100644
index ..96ac27701cee
--- /dev/null
+++ b/hw/intc/pnv_xive_regs.h
@@ -0,0 +1,315 @@
+/*
+ * QEMU PowerPC XIVE interrupt controller model
+ *
+ * Copyright (c) 2017-2018, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_PNV_XIVE_REGS_H
+#define PPC_PNV_XIVE_REGS_H
+
+/* IC register offsets 0x0 - 0x400 */
+#define CQ_SWI_CMD_HIST 0x020
+#define CQ_SWI_CMD_POLL 0x028
+#define CQ_SWI_CMD_BCAST0x030
+#define CQ_SWI_CMD_ASSIGN   0x038
+#define CQ_SWI_CMD_BLK_UPD  0x040
+#define CQ_SWI_RSP  0x048
+#define X_CQ_CFG_PB_GEN 0x0a
+#define CQ_CFG_PB_GEN   0x050
+#define   CQ_INT_ADDR_OPT   PPC_BITMASK(14, 15)
+#define X_CQ_IC_BAR 0x10
+#define X_CQ_MSGSND 0x0b
+#define CQ_MSGSND   0x058
+#define CQ_CNPM_SEL 0x078
+#define CQ_IC_BAR   0x080
+#define   CQ_IC_BAR_VALID   PPC_BIT(0)
+#define   CQ_IC_BAR_64K PPC_BIT(1)
+#define X_CQ_TM1_BAR0x12
+#define CQ_TM1_BAR  0x90
+#define X_CQ_TM2_BAR0x014
+#define CQ_TM2_BAR  0x0a0
+#define   CQ_TM_BAR_VALID   PPC_BIT(0)
+#define   CQ_TM_BAR_64K PPC_BIT(1)
+#define X_CQ_PC_BAR 0x16
+#define CQ_PC_BAR   0x0b0
+#define  CQ_PC_BAR_VALIDPPC_BIT(0)
+#define X_CQ_PC_BARM0x17
+#define CQ_PC_BARM  0x0b8
+#define  CQ_PC_BARM_MASKPPC_BITMASK(26, 38)
+#define X_CQ_VC_BAR 0x18
+#define CQ_VC_BAR   0x0c0
+#define  CQ_VC_BAR_VALIDPPC_BIT(0)
+#define X_CQ_VC_BARM0x19
+#define CQ_VC_BARM  0x0c8
+#define  CQ_VC_BARM_MASKPPC_BITMASK(21, 37)
+#define X_CQ_TAR0x1e
+#define CQ_TAR  0x0f0
+#define  CQ_TAR_TBL_AUTOINC PPC_BIT(0)
+#define  CQ_TAR_TSELPPC_BITMASK(12, 15)
+#define  CQ_TAR_TSEL_BLKPPC_BIT(12)
+#define  CQ_TAR_TSEL_MIGPPC_BIT(13)
+#define  CQ_TAR_TSEL_VDTPPC_BIT(14)
+#define  CQ_TAR_TSEL_EDTPPC_BIT(15)
+#define  CQ_TAR_TSEL_INDEX  PPC_BITMASK(26, 31)
+#define X_CQ_TDR0x1f
+#define CQ_TDR  0x0f8
+#define  CQ_TDR_VDT_VALID   PPC_BIT(0)
+#define  CQ_TDR_VDT_BLK PPC_BITMASK(11, 15)
+#define  CQ_TDR_VDT_INDEX   PPC_BITMASK(28, 31)
+#define  CQ_TDR_EDT_TYPEPPC_BITMASK(0, 1)
+#define  CQ_TDR_EDT_INVALID 0
+#define  CQ_TDR_EDT_IPI 1
+#define