Re: [PATCH v1 1/8] hw/intc: GICv3 ITS initial framework
Shashi Mallela writes: > Added register definitions relevant to ITS,implemented overall > ITS device framework with stubs for ITS control and translater > regions read/write,extended ITS common to handle mmio init between > existing kvm device and newer qemu device. > > Signed-off-by: Shashi Mallela > --- > hw/intc/arm_gicv3_its.c| 323 > hw/intc/arm_gicv3_its_common.c | 17 +- > hw/intc/arm_gicv3_its_kvm.c| 2 +- > hw/intc/gicv3_internal.h | 173 ++- > hw/intc/meson.build| 1 + > include/hw/intc/arm_gicv3_its_common.h | 12 +- > 6 files changed, 520 insertions(+), 8 deletions(-) > > diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c > new file mode 100644 > index 00..34e49b4d63 > --- /dev/null > +++ b/hw/intc/arm_gicv3_its.c > @@ -0,0 +1,323 @@ > +/* > + * ITS emulation for a GICv3-based system > + * > + * Copyright Linaro.org 2021 > + * > + * Authors: > + * Shashi Mallela > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or (at > your > + * option) any later version. See the COPYING file in the top-level > directory. > + * > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/log.h" > +#include "hw/qdev-properties.h" > +#include "hw/intc/arm_gicv3_its_common.h" > +#include "gicv3_internal.h" > +#include "qom/object.h" > + > +typedef struct GICv3ITSClass GICv3ITSClass; > +/* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */ > +DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass, > + ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS) > + > +struct GICv3ITSClass { > +GICv3ITSCommonClass parent_class; > +void (*parent_reset)(DeviceState *dev); > +}; > + > +static MemTxResult its_trans_writew(GICv3ITSState *s, hwaddr offset, > + uint64_t value, MemTxAttrs attrs) > +{ > +MemTxResult result = MEMTX_OK; > + > +return result; > +} > + > +static MemTxResult its_trans_writel(GICv3ITSState *s, hwaddr offset, > + uint64_t value, MemTxAttrs attrs) > +{ > +MemTxResult result = MEMTX_OK; > + > +return result; > +} > + > +static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset, > + uint64_t data, unsigned size, MemTxAttrs > attrs) > +{ > +GICv3ITSState *s = (GICv3ITSState *)opaque; > +MemTxResult result; > + > +switch (size) { > +case 2: > +result = its_trans_writew(s, offset, data, attrs); > +break; > +case 4: > +result = its_trans_writel(s, offset, data, attrs); > +break; > +default: > +result = MEMTX_ERROR; > +break; > +} > + > +if (result == MEMTX_ERROR) { > +qemu_log_mask(LOG_GUEST_ERROR, > + "%s: invalid guest write at offset " TARGET_FMT_plx > + "size %u\n", __func__, offset, size); > +/* > + * The spec requires that reserved registers are RAZ/WI; > + * so use MEMTX_ERROR returns from leaf functions as a way to > + * trigger the guest-error logging but don't return it to > + * the caller, or we'll cause a spurious guest data abort. > + */ > +result = MEMTX_OK; > +} > +return result; > +} > + > +static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset, > + uint64_t *data, unsigned size, MemTxAttrs > attrs) > +{ > +qemu_log_mask(LOG_GUEST_ERROR, > +"%s: Invalid read from transaction register area at offset " > +TARGET_FMT_plx "\n", __func__, offset); > +return MEMTX_ERROR; > +} > + > +static MemTxResult its_writeb(GICv3ITSState *s, hwaddr offset, > + uint64_t value, MemTxAttrs attrs) > +{ > +qemu_log_mask(LOG_GUEST_ERROR, > +"%s: unsupported byte write to register at offset " > +TARGET_FMT_plx "\n", __func__, offset); > +return MEMTX_ERROR; unsupported should be LOG_UNIMP which makes it easier to see where QEMU is missing something vs the guest doing something nuts. > +} > + > +static MemTxResult its_readb(GICv3ITSState *s, hwaddr offset, > + uint64_t *data, MemTxAttrs attrs) > +{ > +qemu_log_mask(LOG_GUEST_ERROR, > +"%s: unsupported byte read from register at offset " > +TARGET_FMT_plx "\n", __func__, offset); > +return MEMTX_ERROR; > +} > + > +static MemTxResult its_writew(GICv3ITSState *s, hwaddr offset, > + uint64_t value, MemTxAttrs attrs) > +{ > +qemu_log_mask(LOG_GUEST_ERROR, > +"%s: unsupported word write to register at offset " > +TARGET_FMT_plx "\n", __func__, offset); > +return MEMTX_ERROR; > +} > + > +static MemTxResult its_readw(GICv3ITSState *s, hwaddr offset, > + uint64_t *data, MemTxAttrs attrs) > +{ > +
Re: [PATCH v1 1/8] hw/intc: GICv3 ITS initial framework
Shashi Mallela writes: > Added register definitions relevant to ITS,implemented overall > ITS device framework with stubs for ITS control and translater > regions read/write,extended ITS common to handle mmio init between > existing kvm device and newer qemu device. > > Signed-off-by: Shashi Mallela > --- > > typedef struct GICv3ITSState GICv3ITSState; > Also could we kernel-doc this function and explain when and why tops would be NULL. > -void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops); > +void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops, > + const MemoryRegionOps *tops); > > #define TYPE_ARM_GICV3_ITS_COMMON "arm-gicv3-its-common" > typedef struct GICv3ITSCommonClass GICv3ITSCommonClass; -- Alex Bennée
[PATCH v1 1/8] hw/intc: GICv3 ITS initial framework
Added register definitions relevant to ITS,implemented overall ITS device framework with stubs for ITS control and translater regions read/write,extended ITS common to handle mmio init between existing kvm device and newer qemu device. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_its.c| 323 hw/intc/arm_gicv3_its_common.c | 17 +- hw/intc/arm_gicv3_its_kvm.c| 2 +- hw/intc/gicv3_internal.h | 173 ++- hw/intc/meson.build| 1 + include/hw/intc/arm_gicv3_its_common.h | 12 +- 6 files changed, 520 insertions(+), 8 deletions(-) diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c new file mode 100644 index 00..34e49b4d63 --- /dev/null +++ b/hw/intc/arm_gicv3_its.c @@ -0,0 +1,323 @@ +/* + * ITS emulation for a GICv3-based system + * + * Copyright Linaro.org 2021 + * + * Authors: + * Shashi Mallela + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at your + * option) any later version. See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/qdev-properties.h" +#include "hw/intc/arm_gicv3_its_common.h" +#include "gicv3_internal.h" +#include "qom/object.h" + +typedef struct GICv3ITSClass GICv3ITSClass; +/* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */ +DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass, + ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS) + +struct GICv3ITSClass { +GICv3ITSCommonClass parent_class; +void (*parent_reset)(DeviceState *dev); +}; + +static MemTxResult its_trans_writew(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ +MemTxResult result = MEMTX_OK; + +return result; +} + +static MemTxResult its_trans_writel(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ +MemTxResult result = MEMTX_OK; + +return result; +} + +static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset, + uint64_t data, unsigned size, MemTxAttrs attrs) +{ +GICv3ITSState *s = (GICv3ITSState *)opaque; +MemTxResult result; + +switch (size) { +case 2: +result = its_trans_writew(s, offset, data, attrs); +break; +case 4: +result = its_trans_writel(s, offset, data, attrs); +break; +default: +result = MEMTX_ERROR; +break; +} + +if (result == MEMTX_ERROR) { +qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest write at offset " TARGET_FMT_plx + "size %u\n", __func__, offset, size); +/* + * The spec requires that reserved registers are RAZ/WI; + * so use MEMTX_ERROR returns from leaf functions as a way to + * trigger the guest-error logging but don't return it to + * the caller, or we'll cause a spurious guest data abort. + */ +result = MEMTX_OK; +} +return result; +} + +static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset, + uint64_t *data, unsigned size, MemTxAttrs attrs) +{ +qemu_log_mask(LOG_GUEST_ERROR, +"%s: Invalid read from transaction register area at offset " +TARGET_FMT_plx "\n", __func__, offset); +return MEMTX_ERROR; +} + +static MemTxResult its_writeb(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ +qemu_log_mask(LOG_GUEST_ERROR, +"%s: unsupported byte write to register at offset " +TARGET_FMT_plx "\n", __func__, offset); +return MEMTX_ERROR; +} + +static MemTxResult its_readb(GICv3ITSState *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ +qemu_log_mask(LOG_GUEST_ERROR, +"%s: unsupported byte read from register at offset " +TARGET_FMT_plx "\n", __func__, offset); +return MEMTX_ERROR; +} + +static MemTxResult its_writew(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ +qemu_log_mask(LOG_GUEST_ERROR, +"%s: unsupported word write to register at offset " +TARGET_FMT_plx "\n", __func__, offset); +return MEMTX_ERROR; +} + +static MemTxResult its_readw(GICv3ITSState *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ +qemu_log_mask(LOG_GUEST_ERROR, +"%s: unsupported word read from register at offset " +TARGET_FMT_plx "\n", __func__, offset); +return MEMTX_ERROR; +} + +static MemTxResult its_writel(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ +MemTxResult result = MEMTX_OK; + +return result; +} + +static MemTxResult its_readl(GICv3ITSState *s, hwaddr offset, +