[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits
Hi, On 09/10/16 15:20, Vijay Kilari wrote: > On Wed, Sep 28, 2016 at 11:54 PM, Andre Przywara <andre.przywara@xxxxxxx> > wrote: >> Create a new file to hold the emulation code for the ITS widget. >> For now we emulate the memory mapped ITS registers and provide a stub >> to introduce the ITS command handling framework (but without actually >> emulating any commands at this time). >> >> Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> >> --- >> xen/arch/arm/Makefile | 1 + >> xen/arch/arm/vgic-its.c | 378 >> ++++++++++++++++++++++++++++++++++++++ >> xen/arch/arm/vgic-v3.c | 9 - >> xen/include/asm-arm/gic_v3_defs.h | 19 ++ >> 4 files changed, 398 insertions(+), 9 deletions(-) >> create mode 100644 xen/arch/arm/vgic-its.c >> >> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile >> index c2c4daa..cb0201f 100644 >> --- a/xen/arch/arm/Makefile >> +++ b/xen/arch/arm/Makefile >> @@ -44,6 +44,7 @@ obj-y += traps.o >> obj-y += vgic.o >> obj-y += vgic-v2.o >> obj-$(CONFIG_ARM_64) += vgic-v3.o >> +obj-$(CONFIG_HAS_ITS) += vgic-its.o >> obj-y += vm_event.o >> obj-y += vtimer.o >> obj-y += vpsci.o >> diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c >> new file mode 100644 >> index 0000000..875b992 >> --- /dev/null >> +++ b/xen/arch/arm/vgic-its.c >> @@ -0,0 +1,378 @@ >> +/* >> + * xen/arch/arm/vgic-its.c >> + * >> + * ARM Interrupt Translation Service (ITS) emulation >> + * >> + * Andre Przywara <andre.przywara@xxxxxxx> >> + * Copyright (c) 2016 ARM Ltd. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * 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/config.h> >> +#include <xen/domain_page.h> >> +#include <xen/lib.h> >> +#include <xen/init.h> >> +#include <xen/softirq.h> >> +#include <xen/irq.h> >> +#include <xen/sched.h> >> +#include <xen/sizes.h> >> +#include <asm/current.h> >> +#include <asm/mmio.h> >> +#include <asm/gic_v3_defs.h> >> +#include <asm/gic-its.h> >> +#include <asm/vgic.h> >> +#include <asm/vgic-emul.h> >> + >> +/* Data structure to describe a virtual ITS */ >> +struct virt_its { >> + struct domain *d; >> + struct host_its *hw_its; >> + spinlock_t vcmd_lock; /* protects the virtual command buffer */ >> + uint64_t cbaser; >> + uint64_t *cmdbuf; >> + int cwriter; >> + int creadr; >> + spinlock_t its_lock; /* protects the collection and device >> tables */ >> + uint64_t baser0, baser1; >> + uint16_t *coll_table; >> + int max_collections; >> + uint64_t *dev_table; >> + int max_devices; >> + bool enabled; >> +}; >> + >> +/* An Interrupt Translation Table Entry: this is indexed by a >> + * DeviceID/EventID pair and is located in guest memory. >> + */ >> +struct vits_itte >> +{ >> + uint64_t hlpi:24; >> + uint64_t vlpi:24; >> + uint64_t collection:16; >> +}; >> + >> +/************************************** >> + * Functions that handle ITS commands * >> + **************************************/ >> + >> +static uint64_t its_cmd_mask_field(uint64_t *its_cmd, >> + int word, int shift, int size) >> +{ >> + return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT(size) - 1); >> +} >> + >> +#define its_cmd_get_command(cmd) its_cmd_mask_field(cmd, 0, 0, 8) >> +#define its_cmd_get_deviceid(cmd) its_cmd_mask_field(cmd, 0, 32, 32) >> +#define its_cmd_get_size(cmd) its_cmd_mask_field(cmd, 1, 0, 5) >> +#define its_cmd_get_id(cmd) its_cmd_mask_field(cmd, 1, 0, 32) >> +#define its_cmd_get_physical_id(cmd) its_cmd_mask_field(cmd, 1, 32, 32) >> +#define its_cmd_get_collection(cmd) its_cmd_mask_field(cmd, 2, 0, 16) >> +#define its_cmd_get_target_addr(cmd) its_cmd_mask_field(cmd, 2, 16, 32) >> +#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1) >> + >> +#define ITS_CMD_BUFFER_SIZE(baser) ((((baser) & 0xff) + 1) << 12) >> + >> +static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, >> + uint32_t writer) >> +{ >> + uint64_t *cmdptr; >> + >> + if ( !its->cmdbuf ) >> + return -1; >> + >> + if ( writer >= ITS_CMD_BUFFER_SIZE(its->cbaser) ) >> + return -1; >> + >> + spin_lock(&its->vcmd_lock); >> + >> + while ( its->creadr != writer ) >> + { >> + cmdptr = its->cmdbuf + (its->creadr / sizeof(*its->cmdbuf)); >> + switch (its_cmd_get_command(cmdptr)) >> + { >> + case GITS_CMD_SYNC: >> + /* We handle ITS commands synchronously, so we ignore SYNC. */ >> + break; >> + default: >> + gdprintk(XENLOG_G_WARNING, "ITS: unhandled ITS command %ld\n", >> + its_cmd_get_command(cmdptr)); >> + break; >> + } >> + >> + its->creadr += ITS_CMD_SIZE; >> + if ( its->creadr == ITS_CMD_BUFFER_SIZE(its->cbaser) ) >> + its->creadr = 0; >> + } >> + its->cwriter = writer; >> + >> + spin_unlock(&its->vcmd_lock); >> + >> + return 0; >> +} >> + >> +/***************************** >> + * ITS registers read access * >> + *****************************/ >> + >> +/* The physical address is encoded slightly differently depending on >> + * the used page size: the highest four bits are stored in the lowest >> + * four bits of the field for 64K pages. >> + */ >> +static paddr_t get_baser_phys_addr(uint64_t reg) >> +{ >> + if ( reg & BIT(9) ) >> + return (reg & GENMASK(47, 16)) | ((reg & GENMASK(15, 12)) << 36); >> + else >> + return reg & GENMASK(47, 12); >> +} >> + >> +static int vgic_v3_its_mmio_read(struct vcpu *v, mmio_info_t *info, >> + register_t *r, void *priv) >> +{ >> + struct virt_its *its = priv; >> + >> + switch ( info->gpa & 0xffff ) >> + { >> + case VREG32(GITS_CTLR): >> + if ( info->dabt.size != DABT_WORD ) goto bad_width; >> + *r = vgic_reg32_extract(its->enabled | BIT(31), info); >> + break; >> + case VREG32(GITS_IIDR): >> + if ( info->dabt.size != DABT_WORD ) goto bad_width; >> + *r = vgic_reg32_extract(GITS_IIDR_VALUE, info); >> + break; >> + case VREG64(GITS_TYPER): >> + if ( info->dabt.size < DABT_WORD ) goto bad_width; >> + *r = vgic_reg64_extract(0x1eff1, info); > > Here you are limiting DevID bits to 15, which is not enough Right, I wasn't aware of those segments Cavium uses. I will try to find out other vendor's requirements for maximum device IDs and will adjust this number. And it seems to be one of the places where I missed to change the hacked up numbers into nice #defines ;-) Cheers, Andre. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |