Re: [PATCH v1 1/8] hw/intc: GICv3 ITS initial framework

2021-03-25 Thread Alex Bennée


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

2021-03-25 Thread Alex Bennée


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

2021-03-22 Thread Shashi Mallela
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,
+