On Tue, Apr 24, 2018 at 10:19:58AM +0200, Cédric Le Goater wrote: > On 04/24/2018 08:58 AM, David Gibson wrote: > > On Thu, Apr 19, 2018 at 02:43:01PM +0200, Cédric Le Goater wrote: > >> Bare-metal systems (PowerNV) have multiples interrupt sources. The > >> XIVE interrupt controller has an internal source for IPIs and generic > >> IPIs, the PSIHB has one and also the PHBs. But, for simplicity on the > >> sPAPR machine, we use a unique XiveSource object for all IPIs and > >> virtual device interrupts of the VM. > >> > >> The ESB MMIO region used to control the sources is mapped at the > >> address of chip 0 of a real system and only the provisioned IRQ > >> numbers are covered. > > > > Is that MMIO address PAPR specified, or arbitrary? > > There are no specified value for the ESB address. It's queried by > the guest using the H_INT_GET_SOURCE_INFO hcall. For KVM, I have > introduced a ioctl to configure the KVM device.
Ok. > > Same for the TIMA, but in this case, the address is exposed to the > guest in the device tree. > > > > >> Signed-off-by: Cédric Le Goater <c...@kaod.org> > >> --- > >> hw/intc/spapr_xive.c | 34 ++++++++++++++++++++++++++++++++++ > >> include/hw/ppc/spapr_xive.h | 3 +++ > >> include/hw/ppc/xive.h | 6 ++++++ > >> 3 files changed, 43 insertions(+) > >> > >> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c > >> index 020444e2665a..90cde8a4082d 100644 > >> --- a/hw/intc/spapr_xive.c > >> +++ b/hw/intc/spapr_xive.c > >> @@ -14,12 +14,15 @@ > >> #include "sysemu/cpus.h" > >> #include "monitor/monitor.h" > >> #include "hw/ppc/spapr_xive.h" > >> +#include "hw/ppc/xive.h" > >> #include "hw/ppc/xive_regs.h" > >> > >> void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) > >> { > >> int i; > >> > >> + xive_source_pic_print_info(&xive->source, mon); > >> + > >> monitor_printf(mon, "IVE Table\n"); > >> for (i = 0; i < xive->nr_irqs; i++) { > >> XiveIVE *ive = &xive->ivt[i]; > >> @@ -40,6 +43,9 @@ static void spapr_xive_reset(DeviceState *dev) > >> sPAPRXive *xive = SPAPR_XIVE(dev); > >> int i; > >> > >> + /* Xive Source reset is done through SysBus, it should put all > >> + * IRQs to OFF (!P|Q) */ > >> + > >> /* Mask all valid IVEs in the IRQ number space. */ > >> for (i = 0; i < xive->nr_irqs; i++) { > >> XiveIVE *ive = &xive->ivt[i]; > >> @@ -51,18 +57,42 @@ static void spapr_xive_reset(DeviceState *dev) > >> > >> static void spapr_xive_init(Object *obj) > >> { > >> + sPAPRXive *xive = SPAPR_XIVE(obj); > >> > >> + object_initialize(&xive->source, sizeof(xive->source), > >> TYPE_XIVE_SOURCE); > >> + object_property_add_child(obj, "source", OBJECT(&xive->source), NULL); > >> } > >> > >> static void spapr_xive_realize(DeviceState *dev, Error **errp) > >> { > >> sPAPRXive *xive = SPAPR_XIVE(dev); > >> + XiveSource *xsrc = &xive->source; > >> + Error *local_err = NULL; > >> > >> if (!xive->nr_irqs) { > >> error_setg(errp, "Number of interrupt needs to be greater 0"); > >> return; > >> } > >> > >> + /* The XIVE interrupt controller has an internal source for IPIs > >> + * and generic IPIs, the PSIHB has one and also the PHBs. For > >> + * simplicity, we use a unique XIVE source object for *all* > >> + * interrupts on sPAPR. The ESBs pages are mapped at the address > >> + * of chip 0 of a real system. > >> + */ > >> + object_property_set_int(OBJECT(xsrc), XIVE_VC_BASE, "bar", > >> + &error_fatal); > >> + object_property_set_int(OBJECT(xsrc), xive->nr_irqs, "nr-irqs", > >> + &error_fatal); > >> + object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(xive), > >> + &error_fatal); > >> + object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err); > >> + if (local_err) { > >> + error_propagate(errp, local_err); > >> + return; > >> + } > >> + qdev_set_parent_bus(DEVICE(xsrc), sysbus_get_default()); > >> + > >> /* Allocate the Interrupt Virtualization Table */ > >> xive->ivt = g_new0(XiveIVE, xive->nr_irqs); > >> } > >> @@ -137,23 +167,27 @@ type_init(spapr_xive_register_types) > >> bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi) > >> { > >> XiveIVE *ive = spapr_xive_get_ive(XIVE_FABRIC(xive), lisn); > >> + XiveSource *xsrc = &xive->source; > >> > >> if (!ive) { > >> return false; > >> } > >> > >> ive->w |= IVE_VALID; > >> + xive_source_irq_set(xsrc, lisn - xsrc->offset, lsi); > >> return true; > >> } > >> > >> bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn) > >> { > >> XiveIVE *ive = spapr_xive_get_ive(XIVE_FABRIC(xive), lisn); > >> + XiveSource *xsrc = &xive->source; > >> > >> if (!ive) { > >> return false; > >> } > >> > >> ive->w &= ~IVE_VALID; > >> + xive_source_irq_set(xsrc, lisn - xsrc->offset, false); > >> return true; > >> } > >> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h > >> index 1d966b5d3a96..4538c622b60a 100644 > >> --- a/include/hw/ppc/spapr_xive.h > >> +++ b/include/hw/ppc/spapr_xive.h > >> @@ -19,6 +19,9 @@ > >> typedef struct sPAPRXive { > >> SysBusDevice parent; > >> > >> + /* Internal interrupt source for IPIs and virtual devices */ > >> + XiveSource source; > >> + > >> /* Routing table */ > >> XiveIVE *ivt; > >> uint32_t nr_irqs; > >> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h > >> index 5b145816acdc..57295715a4a5 100644 > >> --- a/include/hw/ppc/xive.h > >> +++ b/include/hw/ppc/xive.h > >> @@ -16,6 +16,12 @@ > >> typedef struct XiveFabric XiveFabric; > >> > >> /* > >> + * XIVE MMIO regions > >> + */ > >> + > >> +#define XIVE_VC_BASE 0x0006010000000000ull > >> + > >> +/* > >> * XIVE Interrupt Source > >> */ > >> > > > -- 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
signature.asc
Description: PGP signature