Message ID | 20180321163235.12529-18-andre.przywara@linaro.org |
---|---|
State | New |
Headers | show |
Series | New VGIC(-v2) implementation | expand |
On Wed, 21 Mar 2018, Andre Przywara wrote: > Create vgic-mmio-v2.c to describe GICv2 emulation specific handlers > using the initializer macros provided by the VGIC MMIO framework. > Provide a function to register the GICv2 distributor registers to > the Xen MMIO framework. > The actual handler functions are still stubs in this patch. > > This is based on Linux commit fb848db39661, written by Andre Przywara. > > Signed-off-by: Andre Przywara <andre.przywara@linaro.org> > Reviewed-by: Julien Grall <julien.grall@arm.com> Acked-by: Stefano Stabellini <sstabellini@kernel.org> > --- > xen/arch/arm/vgic/vgic-mmio-v2.c | 83 ++++++++++++++++++++++++++++++++++++++++ > xen/arch/arm/vgic/vgic-mmio.c | 25 ++++++++++++ > xen/arch/arm/vgic/vgic-mmio.h | 2 + > xen/arch/arm/vgic/vgic.h | 2 + > 4 files changed, 112 insertions(+) > create mode 100644 xen/arch/arm/vgic/vgic-mmio-v2.c > > diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c b/xen/arch/arm/vgic/vgic-mmio-v2.c > new file mode 100644 > index 0000000000..6f10cf16ca > --- /dev/null > +++ b/xen/arch/arm/vgic/vgic-mmio-v2.c > @@ -0,0 +1,83 @@ > +/* > + * VGICv2 MMIO handling functions > + * Imported from Linux ("new" KVM VGIC) and heavily adapted to Xen. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <xen/bitops.h> > +#include <xen/sched.h> > +#include <xen/sizes.h> > +#include <asm/new_vgic.h> > + > +#include "vgic.h" > +#include "vgic-mmio.h" > + > +static const struct vgic_register_region vgic_v2_dist_registers[] = { > + REGISTER_DESC_WITH_LENGTH(GICD_CTLR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 12, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_IGROUPR, > + vgic_mmio_read_rao, vgic_mmio_write_wi, 1, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ISENABLER, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICENABLER, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ISPENDR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICPENDR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ISACTIVER, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICACTIVER, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_IPRIORITYR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 8, > + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ITARGETSR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 8, > + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), > + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICFGR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 2, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_LENGTH(GICD_SGIR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 4, > + VGIC_ACCESS_32bit), > + REGISTER_DESC_WITH_LENGTH(GICD_CPENDSGIR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 16, > + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), > + REGISTER_DESC_WITH_LENGTH(GICD_SPENDSGIR, > + vgic_mmio_read_raz, vgic_mmio_write_wi, 16, > + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), > +}; > + > +unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev) > +{ > + dev->regions = vgic_v2_dist_registers; > + dev->nr_regions = ARRAY_SIZE(vgic_v2_dist_registers); > + > + return SZ_4K; > +} > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/arch/arm/vgic/vgic-mmio.c b/xen/arch/arm/vgic/vgic-mmio.c > index 866023a84d..a03e8d88b9 100644 > --- a/xen/arch/arm/vgic/vgic-mmio.c > +++ b/xen/arch/arm/vgic/vgic-mmio.c > @@ -170,6 +170,31 @@ struct mmio_handler_ops vgic_io_ops = { > .write = dispatch_mmio_write, > }; > > +int vgic_register_dist_iodev(struct domain *d, gfn_t dist_base_fn, > + enum vgic_type type) > +{ > + struct vgic_io_device *io_device = &d->arch.vgic.dist_iodev; > + unsigned int len; > + > + switch ( type ) > + { > + case VGIC_V2: > + len = vgic_v2_init_dist_iodev(io_device); > + break; > + default: > + BUG(); > + } > + > + io_device->base_fn = dist_base_fn; > + io_device->iodev_type = IODEV_DIST; > + io_device->redist_vcpu = NULL; > + > + register_mmio_handler(d, &vgic_io_ops, gfn_to_gaddr(dist_base_fn), len, > + io_device); > + > + return 0; > +} > + > /* > * Local variables: > * mode: C > diff --git a/xen/arch/arm/vgic/vgic-mmio.h b/xen/arch/arm/vgic/vgic-mmio.h > index bf062a27ca..c280668694 100644 > --- a/xen/arch/arm/vgic/vgic-mmio.h > +++ b/xen/arch/arm/vgic/vgic-mmio.h > @@ -86,4 +86,6 @@ unsigned long vgic_mmio_read_rao(struct vcpu *vcpu, > void vgic_mmio_write_wi(struct vcpu *vcpu, paddr_t addr, > unsigned int len, unsigned long val); > > +unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev); > + > #endif > diff --git a/xen/arch/arm/vgic/vgic.h b/xen/arch/arm/vgic/vgic.h > index 41cc0c5b54..7f221fd195 100644 > --- a/xen/arch/arm/vgic/vgic.h > +++ b/xen/arch/arm/vgic/vgic.h > @@ -49,6 +49,8 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq) > void vgic_v2_fold_lr_state(struct vcpu *vcpu); > void vgic_v2_populate_lr(struct vcpu *vcpu, struct vgic_irq *irq, int lr); > void vgic_v2_set_underflow(struct vcpu *vcpu); > +int vgic_register_dist_iodev(struct domain *d, gfn_t dist_base_fn, > + enum vgic_type); > > #endif > > -- > 2.14.1 >
diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c b/xen/arch/arm/vgic/vgic-mmio-v2.c new file mode 100644 index 0000000000..6f10cf16ca --- /dev/null +++ b/xen/arch/arm/vgic/vgic-mmio-v2.c @@ -0,0 +1,83 @@ +/* + * VGICv2 MMIO handling functions + * Imported from Linux ("new" KVM VGIC) and heavily adapted to Xen. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <xen/bitops.h> +#include <xen/sched.h> +#include <xen/sizes.h> +#include <asm/new_vgic.h> + +#include "vgic.h" +#include "vgic-mmio.h" + +static const struct vgic_register_region vgic_v2_dist_registers[] = { + REGISTER_DESC_WITH_LENGTH(GICD_CTLR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 12, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_IGROUPR, + vgic_mmio_read_rao, vgic_mmio_write_wi, 1, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ISENABLER, + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICENABLER, + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ISPENDR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICPENDR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ISACTIVER, + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICACTIVER, + vgic_mmio_read_raz, vgic_mmio_write_wi, 1, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_IPRIORITYR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 8, + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ITARGETSR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 8, + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), + REGISTER_DESC_WITH_BITS_PER_IRQ(GICD_ICFGR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 2, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_LENGTH(GICD_SGIR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 4, + VGIC_ACCESS_32bit), + REGISTER_DESC_WITH_LENGTH(GICD_CPENDSGIR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 16, + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), + REGISTER_DESC_WITH_LENGTH(GICD_SPENDSGIR, + vgic_mmio_read_raz, vgic_mmio_write_wi, 16, + VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), +}; + +unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev) +{ + dev->regions = vgic_v2_dist_registers; + dev->nr_regions = ARRAY_SIZE(vgic_v2_dist_registers); + + return SZ_4K; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/vgic/vgic-mmio.c b/xen/arch/arm/vgic/vgic-mmio.c index 866023a84d..a03e8d88b9 100644 --- a/xen/arch/arm/vgic/vgic-mmio.c +++ b/xen/arch/arm/vgic/vgic-mmio.c @@ -170,6 +170,31 @@ struct mmio_handler_ops vgic_io_ops = { .write = dispatch_mmio_write, }; +int vgic_register_dist_iodev(struct domain *d, gfn_t dist_base_fn, + enum vgic_type type) +{ + struct vgic_io_device *io_device = &d->arch.vgic.dist_iodev; + unsigned int len; + + switch ( type ) + { + case VGIC_V2: + len = vgic_v2_init_dist_iodev(io_device); + break; + default: + BUG(); + } + + io_device->base_fn = dist_base_fn; + io_device->iodev_type = IODEV_DIST; + io_device->redist_vcpu = NULL; + + register_mmio_handler(d, &vgic_io_ops, gfn_to_gaddr(dist_base_fn), len, + io_device); + + return 0; +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/vgic/vgic-mmio.h b/xen/arch/arm/vgic/vgic-mmio.h index bf062a27ca..c280668694 100644 --- a/xen/arch/arm/vgic/vgic-mmio.h +++ b/xen/arch/arm/vgic/vgic-mmio.h @@ -86,4 +86,6 @@ unsigned long vgic_mmio_read_rao(struct vcpu *vcpu, void vgic_mmio_write_wi(struct vcpu *vcpu, paddr_t addr, unsigned int len, unsigned long val); +unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev); + #endif diff --git a/xen/arch/arm/vgic/vgic.h b/xen/arch/arm/vgic/vgic.h index 41cc0c5b54..7f221fd195 100644 --- a/xen/arch/arm/vgic/vgic.h +++ b/xen/arch/arm/vgic/vgic.h @@ -49,6 +49,8 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq) void vgic_v2_fold_lr_state(struct vcpu *vcpu); void vgic_v2_populate_lr(struct vcpu *vcpu, struct vgic_irq *irq, int lr); void vgic_v2_set_underflow(struct vcpu *vcpu); +int vgic_register_dist_iodev(struct domain *d, gfn_t dist_base_fn, + enum vgic_type); #endif