Re: [PATCH 1/1] target/loongarch/kvm: Enable LSX/LASX extension

2024-01-21 Thread gaosong

在 2024/1/22 下午3:12, maobibo 写道:



On 2024/1/22 下午2:09, Song Gao wrote:

The kernel had already support LSX and LASX [1],
but QEMU is disable LSX/LASX for kvm. This patch adds
kvm_check_cpucfg to check CPUCFG2.

[1]: 
https://lore.kernel.org/all/cabgobfzhrf7e_7jk4uprmsyxty3eiuuywhc35jqncnl9s-z...@mail.gmail.com/


Signed-off-by: Song Gao 
---
  linux-headers/asm-loongarch/kvm.h |  1 +
  target/loongarch/kvm/kvm.c    | 35 ---
  2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/linux-headers/asm-loongarch/kvm.h 
b/linux-headers/asm-loongarch/kvm.h

index c6ad2ee610..923d0bd382 100644
--- a/linux-headers/asm-loongarch/kvm.h
+++ b/linux-headers/asm-loongarch/kvm.h
@@ -79,6 +79,7 @@ struct kvm_fpu {
  #define LOONGARCH_REG_64(TYPE, REG)    (TYPE | KVM_REG_SIZE_U64 | 
(REG << LOONGARCH_REG_SHIFT))
  #define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, 
REG)
  #define KVM_IOC_CPUCFG(REG) 
LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)

+#define KVM_LOONGARCH_VCPU_CPUCFG    0
    struct kvm_debug_exit_arch {
  };
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 84bcdf5f86..41b6947c7b 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -537,6 +537,28 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs)
  return ret;
  }
  +static int kvm_check_cpucfg(int id, CPUState *cs)
+{
+    int ret;
+    uint64_t val;
+    struct kvm_device_attr attr = {
+    .group = KVM_LOONGARCH_VCPU_CPUCFG,
+    .attr = id,
+    .addr = (uint64_t)&val,
+    };
+    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+    CPULoongArchState *env = &cpu->env;
+
+    ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
+
+    if (!ret) {
+    kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
+    env->cpucfg[id] &= val;

With feature bit represents supported or disabled, it is ok to use
logic of qemu feature bitmap and kvm supported feature bitmap.

However about feature version, there will be problem with "and logic".
Can we use minimal version here?


Yes, we can,  I will correct it on v2.

Thanks.
Song Gao

Regards
Bibo Mao

+    }
+
+    return ret;
+}
+
  static int kvm_loongarch_put_cpucfg(CPUState *cs)
  {
  int i, ret = 0;
@@ -545,14 +567,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
  uint64_t val;
    for (i = 0; i < 21; i++) {
+    if (i == 2) {
+    ret = kvm_check_cpucfg(i, cs);
+    if (ret) {
+    return ret;
+    }
+    }
  val = env->cpucfg[i];
-    /* LSX and LASX and LBT are not supported in kvm now */
-    if (i == 2) {
-    val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | 
BIT(R_CPUCFG2_LASX_SHIFT));

-    val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) |
- BIT(R_CPUCFG2_LBT_ARM_SHIFT) |
- BIT(R_CPUCFG2_LBT_MIPS_SHIFT));
-    }
  ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
  if (ret < 0) {
  trace_kvm_failed_put_cpucfg(strerror(errno));






RE: [RFC 4/7] virtio-iommu: Implement PCIIOMMUOps set_host_resv_regions

2024-01-21 Thread Duan, Zhenzhong
Hi Eric,

>-Original Message-
>From: Duan, Zhenzhong
>Subject: RE: [RFC 4/7] virtio-iommu: Implement PCIIOMMUOps
>set_host_resv_regions
>
>
>
>>-Original Message-
>>From: Eric Auger 
>>Subject: Re: [RFC 4/7] virtio-iommu: Implement PCIIOMMUOps
>>set_host_resv_regions
>>
>>Hi Zhenzhong,
>>On 1/18/24 08:43, Duan, Zhenzhong wrote:
>>> Hi Eric,
>>>
 -Original Message-
 From: Eric Auger 
 Subject: [RFC 4/7] virtio-iommu: Implement PCIIOMMUOps
 set_host_resv_regions

 Reuse the implementation of virtio_iommu_set_iova_ranges() which
 will be removed in subsequent patches.

 Signed-off-by: Eric Auger 
 ---
 hw/virtio/virtio-iommu.c | 134 +
>--
>>---
 -
 1 file changed, 101 insertions(+), 33 deletions(-)

 diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
 index 8a4bd933c6..716a3fcfbf 100644
 --- a/hw/virtio/virtio-iommu.c
 +++ b/hw/virtio/virtio-iommu.c
 @@ -461,8 +461,109 @@ static AddressSpace
 *virtio_iommu_find_add_as(PCIBus *bus, void *opaque,
 return &sdev->as;
 }

 +/**
 + * rebuild_resv_regions: rebuild resv regions with both the
 + * info of host resv ranges and property set resv ranges
 + */
 +static int rebuild_resv_regions(IOMMUDevice *sdev)
 +{
 +GList *l;
 +int i = 0;
 +
 +/* free the existing list and rebuild it from scratch */
 +g_list_free_full(sdev->resv_regions, g_free);
 +sdev->resv_regions = NULL;
 +
 +/* First add host reserved regions if any, all tagged as RESERVED */
 +for (l = sdev->host_resv_ranges; l; l = l->next) {
 +ReservedRegion *reg = g_new0(ReservedRegion, 1);
 +Range *r = (Range *)l->data;
 +
 +reg->type = VIRTIO_IOMMU_RESV_MEM_T_RESERVED;
 +range_set_bounds(®->range, range_lob(r), range_upb(r));
 +sdev->resv_regions = resv_region_list_insert(sdev->resv_regions,
>>reg);
 +trace_virtio_iommu_host_resv_regions(sdev-
> iommu_mr.parent_obj.name, i,
 + range_lob(®->range),
 + range_upb(®->range));
 +i++;
 +}
 +/*
 + * then add higher priority reserved regions set by the machine
 + * through properties
 + */
 +add_prop_resv_regions(sdev);
 +return 0;
 +}
 +
 +static int virtio_iommu_set_host_iova_ranges(PCIBus *bus, void
>>*opaque,
 + int devfn, GList 
 *iova_ranges,
 + Error **errp)
 +{
 +VirtIOIOMMU *s = opaque;
 +IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus);
 +IOMMUDevice *sdev;
 +GList *current_ranges;
 +GList *l, *tmp, *new_ranges = NULL;
 +int ret = -EINVAL;
 +
 +if (!sbus) {
 +error_report("%s no sbus", __func__);
 +}
>>> Do we plan to support multiple devices in same iommu group?
>>> as_by_busptr is hashed by bus which is an aliased bus of the device.
>>> So sbus may be NULL if device's bus is different from aliased bus.
>>If I understand you remark properly this means that
>>
>>virtio_iommu_set_host_iova_ranges should take as arg the aliased bus and
>>not the bus, right?
>>I think we shall support non singleton groups too.
>
>Not exactly. I think we should pass device's real BDF, not aliased BDF. Or else
>we setup reserved ranges of all devices in same group to aliased BDF.
>
>I'm just suspecting that the hash lookup with real BDF index will return NULL
>if
>multiple devices are in same group. If that’s true, then iova_ranges is never
>passed to guest.

I guess https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg04153.html
may help on the discussion here, it's a complementation to this series to make
multiple devices in same IOMMU group works. Comments welcome.

Thanks
Zhenzhong


Re: [PATCH v3] Handle wrap around in limit calculation

2024-01-21 Thread Peter Xu
On Mon, Jan 22, 2024 at 12:17:24AM +0100, Philippe Mathieu-Daudé wrote:
> > @@ -560,7 +569,7 @@ static const VMStateDescription 
> > vmstate_designware_pcie_viewport = {
> >   .fields = (const VMStateField[]) {
> >   VMSTATE_UINT64(base, DesignwarePCIEViewport),
> >   VMSTATE_UINT64(target, DesignwarePCIEViewport),
> > -VMSTATE_UINT32(limit, DesignwarePCIEViewport),
> > +VMSTATE_UINT64(limit, DesignwarePCIEViewport),
> 
> Unfortunately this breaks the migration stream. I'm not sure
> what is the best way to deal with it (Cc'ing migration
> maintainers).

My understanding is that we can have at least two ways to do this, one
relying on machine type properties, the other one can be VMSD versioning.
Frankly I don't have a solid mind either on which is the best approach.

I never had a talk with either Juan / Dave before on this, but my
understanding is that VMSD versioning is just less-flexible, because it
doesn't support backward migrations (only forward).  While machine-type
property based solution can support both (forward + backward).

I decided to draft a doc update for this, to put my thoughts here:

https://lore.kernel.org/qemu-devel/20240122070600.16681-1-pet...@redhat.com

It can be seen as a reference, or review comments also welcomed.

This device seems to be only supported by CONFIG_FSL_IMX7.  Maybe vmsd
versioning would be good enough here, then?  If so, instead of
VMSTATE_UINT64(), we may want a new VMSTATE_UINT32_V() with a boosted
version.

Thanks,

-- 
Peter Xu




Re: [PATCH 1/1] target/loongarch/kvm: Enable LSX/LASX extension

2024-01-21 Thread maobibo




On 2024/1/22 下午2:09, Song Gao wrote:

The kernel had already support LSX and LASX [1],
but QEMU is disable LSX/LASX for kvm. This patch adds
kvm_check_cpucfg to check CPUCFG2.

[1]: 
https://lore.kernel.org/all/cabgobfzhrf7e_7jk4uprmsyxty3eiuuywhc35jqncnl9s-z...@mail.gmail.com/

Signed-off-by: Song Gao 
---
  linux-headers/asm-loongarch/kvm.h |  1 +
  target/loongarch/kvm/kvm.c| 35 ---
  2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/linux-headers/asm-loongarch/kvm.h 
b/linux-headers/asm-loongarch/kvm.h
index c6ad2ee610..923d0bd382 100644
--- a/linux-headers/asm-loongarch/kvm.h
+++ b/linux-headers/asm-loongarch/kvm.h
@@ -79,6 +79,7 @@ struct kvm_fpu {
  #define LOONGARCH_REG_64(TYPE, REG)   (TYPE | KVM_REG_SIZE_U64 | (REG << 
LOONGARCH_REG_SHIFT))
  #define KVM_IOC_CSRID(REG)LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, 
REG)
  #define KVM_IOC_CPUCFG(REG)   
LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
+#define KVM_LOONGARCH_VCPU_CPUCFG  0
  
  struct kvm_debug_exit_arch {

  };
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 84bcdf5f86..41b6947c7b 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -537,6 +537,28 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs)
  return ret;
  }
  
+static int kvm_check_cpucfg(int id, CPUState *cs)

+{
+int ret;
+uint64_t val;
+struct kvm_device_attr attr = {
+.group = KVM_LOONGARCH_VCPU_CPUCFG,
+.attr = id,
+.addr = (uint64_t)&val,
+};
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
+
+if (!ret) {
+kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
+env->cpucfg[id] &= val;

With feature bit represents supported or disabled, it is ok to use
logic of qemu feature bitmap and kvm supported feature bitmap.

However about feature version, there will be problem with "and logic".
Can we use minimal version here?

Regards
Bibo Mao

+}
+
+return ret;
+}
+
  static int kvm_loongarch_put_cpucfg(CPUState *cs)
  {
  int i, ret = 0;
@@ -545,14 +567,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
  uint64_t val;
  
  for (i = 0; i < 21; i++) {

+   if (i == 2) {
+ret = kvm_check_cpucfg(i, cs);
+if (ret) {
+return ret;
+}
+   }
  val = env->cpucfg[i];
-/* LSX and LASX and LBT are not supported in kvm now */
-if (i == 2) {
-val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT));
-val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) |
- BIT(R_CPUCFG2_LBT_ARM_SHIFT) |
- BIT(R_CPUCFG2_LBT_MIPS_SHIFT));
-}
  ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
  if (ret < 0) {
  trace_kvm_failed_put_cpucfg(strerror(errno));






[PATCH] migration/docs: Explain two solutions for VMSD compatibility

2024-01-21 Thread peterx
From: Peter Xu 

The current article is not extremely easy to follow, and may contain too
much information for someone looking for solutions on VMSD compatibility
issues.  Meanwhile, VMSD versioning is not discussed.

I'm not yet sure whether we should just obsolete VMSD versioning; it's
still used quite a lot.  And I had a feeling that for simple use cases
where backward migration is not strongly required, device developers can
still consider using it.  So in this patch I decided to keep it (anyway, we
can't drop it in the near future because of massive existing users), and we
can still allow user to use it in contexts where forward-only migration
might be enough.

This doc patch does below changes:

  - Rename the page from "Backward compatibility" to "Migration
  compatibility", to avoid using "backward" as a word (because we'll want
  to identify "forward" / "backward" migrations in the new doc)

  - Add a TOC for this page for better indexing

  - A new section to explain what is forward/backward migration

  - A new small section for VMSD just to make things complete

  - Explain the two ways to make VMSD compatible with old qemu binaries

For this one, I added a small section on how to use VMSD versioning for
new fields just to start such documents.  Rename the old "How backwards
compatibility works" section to "machine type based (forward+backward
migration)" to be the 2nd solution (I called it machine type based
solution). When at it, I provided a summary and a TODO for the 2nd
solution.

  - A new section to explain which solution to choose

  - Moved the other two existing sections into "Extended readings", because
  they can be even further away to most device developers

Signed-off-by: Peter Xu 
---
 docs/devel/migration/compatibility.rst | 140 -
 1 file changed, 137 insertions(+), 3 deletions(-)

diff --git a/docs/devel/migration/compatibility.rst 
b/docs/devel/migration/compatibility.rst
index 5a5417ef06..ea9da201ef 100644
--- a/docs/devel/migration/compatibility.rst
+++ b/docs/devel/migration/compatibility.rst
@@ -1,8 +1,139 @@
-Backwards compatibility
 ===
+Migration compatibility
+===
+
+Migration is a hard topic sometimes.  One of the major reason is that it
+has a strict compatibility requirement - a migration (live or not) can
+happen between two different versions of QEMUs, so QEMU needs to make sure
+the migration can work across different versions of QEMU binaries.
+
+This document majorly discusses the compatibility requirement of forward /
+backward migrations that QEMU need to maintain, and what QEMU developers
+should do to achieve such compatibility requirements across different QEMU
+versions.
+
+.. contents::
+
+Types of migrations (forward / backward)
+
+
+Let's firstly define the terms **forward migration** and **backward
+migration**.
+
+.. note::
+
+To simplify the use case, we always discuss between two consecutive
+versions of QEMU major releases (between QEMU version *N* and QEMU
+version *N-1*).  But logically it applies to the case where the two
+QEMU binaries involved contains more than one major version difference.
+
+.. _forward_migration:
+
+**Forward migration**: can be seen as the use case where a VM cluster can
+upgrade its nodes to a newer version of QEMU (version *N*) from an older
+version of QEMU (version *N-1*).
+
+.. _backward_migration:
+
+**Backward migration**: can be seen as the use case where a VM cluster
+would like to migrate from a newer version of QEMU (version *N*) back to an
+even older version of QEMU (version *N-1*).
+
+A forward migration is more common, where system upgrades are needed.  In
+this case, the upgrade can be done seamlessly by live migrating the old VMs
+to the new VMs with the new binaries.
+
+A backward migration can be less common OTOH, because downgrade is less
+common than upgrade for whatever reasons.  However for a production level
+system setup, this should also be allowed, because a cluster can contain
+different versions of QEMU binary.  It should be always allowed to migrate
+between old and new hosts as long as the machine type is supported across
+all the relevant hosts / nodes.
+
+VMState description data structure (VMSD)
+=
+
+VMSD (or in the complete form, **VMStateDescription**) is the data
+structure that QEMU uses to describe data to be migrated for devices.
+Each device should provide its own VMSD structure to describe what it needs
+to be migrated when a VM live migration is requested.
+
+Device VMSD compatibility
+=
+
+Then if the VMSD structures need changing, how does the device maintain
+compatibilty?
 
-How backwards compatibility works
--
+Here we only discuss VMSD-based migrations.  If one device is not using
+VMSD to migrate its device data, it's considered part 

Re: [PATCH v4 2/6] target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v0.8

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 8:32 PM Alexey Baturo  wrote:
>
> From: Alexey Baturo 
>
> Signed-off-by: Alexey Baturo 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h  |  8 
>  target/riscv/cpu_bits.h |  3 +++
>  target/riscv/cpu_cfg.h  |  3 +++
>  target/riscv/csr.c  | 11 +++
>  target/riscv/machine.c  | 10 +++---
>  target/riscv/pmp.c  | 13 ++---
>  target/riscv/pmp.h  | 11 ++-
>  7 files changed, 48 insertions(+), 11 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index a43c8fba57..c9bed5c9fc 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -101,6 +101,14 @@ typedef enum {
>  EXT_STATUS_DIRTY,
>  } RISCVExtStatus;
>
> +/* Enum holds PMM field values for Zjpm v0.8 extension */
> +typedef enum {
> +PMM_FIELD_DISABLED = 0,
> +PMM_FIELD_RESERVED = 1,
> +PMM_FIELD_PMLEN7   = 2,
> +PMM_FIELD_PMLEN16  = 3,
> +} RISCVPmPmm;
> +
>  #define MMU_USER_IDX 3
>
>  #define MAX_RISCV_PMPS (16)
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 1c92458a01..7cf1049bf4 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -715,6 +715,7 @@ typedef enum RISCVException {
>  #define MENVCFG_CBIE   (3UL << 4)
>  #define MENVCFG_CBCFE  BIT(6)
>  #define MENVCFG_CBZE   BIT(7)
> +#define MENVCFG_PMM(3ULL << 32)
>  #define MENVCFG_ADUE   (1ULL << 61)
>  #define MENVCFG_PBMTE  (1ULL << 62)
>  #define MENVCFG_STCE   (1ULL << 63)
> @@ -728,11 +729,13 @@ typedef enum RISCVException {
>  #define SENVCFG_CBIE   MENVCFG_CBIE
>  #define SENVCFG_CBCFE  MENVCFG_CBCFE
>  #define SENVCFG_CBZE   MENVCFG_CBZE
> +#define SENVCFG_PMMMENVCFG_PMM
>
>  #define HENVCFG_FIOM   MENVCFG_FIOM
>  #define HENVCFG_CBIE   MENVCFG_CBIE
>  #define HENVCFG_CBCFE  MENVCFG_CBCFE
>  #define HENVCFG_CBZE   MENVCFG_CBZE
> +#define HENVCFG_PMMMENVCFG_PMM
>  #define HENVCFG_ADUE   MENVCFG_ADUE
>  #define HENVCFG_PBMTE  MENVCFG_PBMTE
>  #define HENVCFG_STCE   MENVCFG_STCE
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index f4605fb190..201f8af6ae 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -113,6 +113,9 @@ struct RISCVCPUConfig {
>  bool ext_ssaia;
>  bool ext_sscofpmf;
>  bool ext_smepmp;
> +bool ext_ssnpm;
> +bool ext_smnpm;
> +bool ext_smmpm;
>  bool rvv_ta_all_1s;
>  bool rvv_ma_all_1s;
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index ea4e1ac6ef..a67ba30494 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -527,6 +527,9 @@ static RISCVException have_mseccfg(CPURISCVState *env, 
> int csrno)
>  if (riscv_cpu_cfg(env)->ext_zkr) {
>  return RISCV_EXCP_NONE;
>  }
> +if (riscv_cpu_cfg(env)->ext_smmpm) {
> +return RISCV_EXCP_NONE;
> +}
>
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
> @@ -2030,6 +2033,10 @@ static RISCVException write_menvcfg(CPURISCVState 
> *env, int csrno,
>  (cfg->ext_sstc ? MENVCFG_STCE : 0) |
>  (cfg->ext_svadu ? MENVCFG_ADUE : 0);
>  }
> +/* Update PMM field only if the value is valid according to Zjpm v0.8 */
> +if (((val & MENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) {
> +mask |= MENVCFG_PMM;
> +}
>  env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
>
>  return RISCV_EXCP_NONE;
> @@ -2074,6 +2081,10 @@ static RISCVException write_senvcfg(CPURISCVState 
> *env, int csrno,
>  target_ulong val)
>  {
>  uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | 
> SENVCFG_CBZE;
> +/* Update PMM field only if the value is valid according to Zjpm v0.8 */
> +if (((val & SENVCFG_PMM) >> 32) != PMM_FIELD_RESERVED) {
> +mask |= SENVCFG_PMM;
> +}
>  RISCVException ret;
>
>  ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 71ee8bab19..0ad593ed5a 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -152,15 +152,19 @@ static const VMStateDescription vmstate_vector = {
>
>  static bool pointermasking_needed(void *opaque)
>  {
> -return false;
> +RISCVCPU *cpu = opaque;
> +return cpu->cfg.ext_ssnpm || cpu->cfg.ext_smnpm || cpu->cfg.ext_smmpm;
>  }
>
>  static const VMStateDescription vmstate_pointermasking = {
>  .name = "cpu/pointer_masking",
> -.version_id = 1,
> -.minimum_version_id = 1,
> +.version_id = 2,
> +.minimum_version_id = 2,
>  .needed = pointermasking_needed,
>  .fields = (VMStateField[

Re: [PATCH v4 4/6] target/riscv: Add pointer masking tb flags

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 8:31 PM Alexey Baturo  wrote:
>
> From: Alexey Baturo 
>
> Signed-off-by: Alexey Baturo 
>
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h| 3 +++
>  target/riscv/cpu_helper.c | 3 +++
>  target/riscv/translate.c  | 5 +
>  3 files changed, 11 insertions(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 1c8979c1c8..0284ea418f 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -545,6 +545,9 @@ FIELD(TB_FLAGS, ITRIGGER, 20, 1)
>  FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1)
>  FIELD(TB_FLAGS, PRIV, 22, 2)
>  FIELD(TB_FLAGS, AXL, 24, 2)
> +/* If pointer masking should be applied and address sign extended */
> +FIELD(TB_FLAGS, PM_PMM, 26, 2)
> +FIELD(TB_FLAGS, PM_SIGNEXTEND, 28, 1)
>
>  #ifdef TARGET_RISCV32
>  #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 9640e4c2c5..67bc51e510 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -68,6 +68,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
>  RISCVCPU *cpu = env_archcpu(env);
>  RISCVExtStatus fs, vs;
>  uint32_t flags = 0;
> +bool pm_signext = riscv_cpu_virt_mem_enabled(env);
>
>  *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
>  *cs_base = 0;
> @@ -135,6 +136,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
>  flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
>  flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
>  flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env));
> +flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env));
> +flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext);
>
>  *pflags = flags;
>  }
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 6b4b9a671c..2c89d749c0 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -103,6 +103,9 @@ typedef struct DisasContext {
>  bool vl_eq_vlmax;
>  CPUState *cs;
>  TCGv zero;
> +/* actual address width */
> +uint8_t addr_width;
> +bool addr_signed;
>  /* Use icount trigger for native debug */
>  bool itrigger;
>  /* FRM is known to contain a valid value. */
> @@ -1176,6 +1179,8 @@ static void 
> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>  ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
>  ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
>  ctx->cs = cs;
> +ctx->addr_width = 0;
> +ctx->addr_signed = false;
>  ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
>  ctx->zero = tcg_constant_tl(0);
>  ctx->virt_inst_excp = false;
> --
> 2.34.1
>
>



Re: [PATCH v4 5/6] target/riscv: Update address modify functions to take into account pointer masking

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 9:33 PM Alexey Baturo  wrote:
>
> From: Alexey Baturo 
>
> Signed-off-by: Alexey Baturo 
>
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/translate.c | 22 --
>  target/riscv/vector_helper.c | 13 +
>  2 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 2c89d749c0..457de381c7 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -579,8 +579,10 @@ static TCGv get_address(DisasContext *ctx, int rs1, int 
> imm)
>  TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
>
>  tcg_gen_addi_tl(addr, src1, imm);
> -if (get_address_xl(ctx) == MXL_RV32) {
> -tcg_gen_ext32u_tl(addr, addr);
> +if (ctx->addr_signed) {
> +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width);
> +} else {
> +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width);
>  }
>
>  return addr;
> @@ -593,8 +595,10 @@ static TCGv get_address_indexed(DisasContext *ctx, int 
> rs1, TCGv offs)
>  TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
>
>  tcg_gen_add_tl(addr, src1, offs);
> -if (get_xl(ctx) == MXL_RV32) {
> -tcg_gen_ext32u_tl(addr, addr);
> +if (ctx->addr_signed) {
> +tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_width);
> +} else {
> +tcg_gen_extract_tl(addr, addr, 0, ctx->addr_width);
>  }
>  return addr;
>  }
> @@ -1179,8 +1183,14 @@ static void 
> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>  ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
>  ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
>  ctx->cs = cs;
> -ctx->addr_width = 0;
> -ctx->addr_signed = false;
> +if (get_xl(ctx) == MXL_RV32) {
> +ctx->addr_width = 32;
> +ctx->addr_signed = false;
> +} else {
> +int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM);
> +ctx->addr_width = 64 - riscv_pm_get_pmlen(pm_pmm);
> +ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND);
> +}
>  ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
>  ctx->zero = tcg_constant_tl(0);
>  ctx->virt_inst_excp = false;
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 8e7a8e80a0..ff1178723c 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -94,6 +94,19 @@ static inline uint32_t vext_max_elems(uint32_t desc, 
> uint32_t log2_esz)
>
>  static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
>  {
> +RISCVPmPmm pmm = riscv_pm_get_pmm(env);
> +if (pmm == PMM_FIELD_DISABLED) {
> +return addr;
> +}
> +int pmlen = riscv_pm_get_pmlen(pmm);
> +bool signext = riscv_cpu_virt_mem_enabled(env);
> +addr = addr << pmlen;
> +/* sign/zero extend masked address by N-1 bit */
> +if (signext) {
> +addr = (target_long)addr >> pmlen;
> +} else {
> +addr = addr >> pmlen;
> +}
>  return addr;
>  }
>
> --
> 2.34.1
>
>



Re: [PATCH v4 6/6] target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 8:31 PM Alexey Baturo  wrote:
>
> From: Alexey Baturo 
>
> Signed-off-by: Alexey Baturo 
> ---
>  target/riscv/cpu.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index d8de1f1890..44ebd80aba 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -153,6 +153,9 @@ const RISCVIsaExtData isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
>  ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
>  ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
> +ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_12_0, ext_ssnpm),
> +ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_12_0, ext_smnpm),
> +ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_12_0, ext_smmpm),
>  ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
>  ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
>  ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs),
> @@ -1336,6 +1339,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
>
>  MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false),
>
> +/* Zjpm v0.8 extensions */
> +MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false),
> +MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false),
> +MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false),

As this isn't ratified yet can you add a "x-" in front the of the
names to indicate experimental

Alistair

> +
>  MULTI_EXT_CFG_BOOL("zca", ext_zca, false),
>  MULTI_EXT_CFG_BOOL("zcb", ext_zcb, false),
>  MULTI_EXT_CFG_BOOL("zcd", ext_zcd, false),
> --
> 2.34.1
>
>



Re: [PATCH v4 1/6] target/riscv: Remove obsolete pointer masking extension code.

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 8:30 PM Alexey Baturo  wrote:
>
> From: Alexey Baturo 
>
> Zjpm v0.8 is almost frozen and it's much simplier compared to the existing 
> one:
> The newer version doesn't allow to specify custom mask or base for masking.
> Instead it allows only certain options for masking top bits.
>
> Signed-off-by: Alexey Baturo 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c   |  13 +-
>  target/riscv/cpu.h   |  33 +---
>  target/riscv/cpu_bits.h  |  87 --
>  target/riscv/cpu_helper.c|  52 --
>  target/riscv/csr.c   | 326 ---
>  target/riscv/machine.c   |  14 +-
>  target/riscv/tcg/tcg-cpu.c   |   5 +-
>  target/riscv/translate.c |  27 +--
>  target/riscv/vector_helper.c |   2 +-
>  9 files changed, 14 insertions(+), 545 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 83c7c0cf07..d8de1f1890 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -40,7 +40,7 @@
>  /* RISC-V CPU definitions */
>  static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
>  const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV,
> -  RVC, RVS, RVU, RVH, RVJ, RVG, 0};
> +  RVC, RVS, RVU, RVH, RVG, 0};
>
>  /*
>   * From vector_helper.c
> @@ -710,13 +710,6 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
> int flags)
>  CSR_MSCRATCH,
>  CSR_SSCRATCH,
>  CSR_SATP,
> -CSR_MMTE,
> -CSR_UPMBASE,
> -CSR_UPMMASK,
> -CSR_SPMBASE,
> -CSR_SPMMASK,
> -CSR_MPMBASE,
> -CSR_MPMMASK,
>  };
>
>  for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
> @@ -891,8 +884,6 @@ static void riscv_cpu_reset_hold(Object *obj)
>  }
>  i++;
>  }
> -/* mmte is supposed to have pm.current hardwired to 1 */
> -env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
>
>  /*
>   * Clear mseccfg and unlock all the PMP entries upon reset.
> @@ -906,7 +897,6 @@ static void riscv_cpu_reset_hold(Object *obj)
>  pmp_unlock_entries(env);
>  #endif
>  env->xl = riscv_cpu_mxl(env);
> -riscv_cpu_update_mask(env);
>  cs->exception_index = RISCV_EXCP_NONE;
>  env->load_res = -1;
>  set_default_nan_mode(1, &env->fp_status);
> @@ -1251,7 +1241,6 @@ static const MISAExtInfo misa_ext_info_arr[] = {
>  MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
>  MISA_EXT_INFO(RVU, "u", "User-level instructions"),
>  MISA_EXT_INFO(RVH, "h", "Hypervisor"),
> -MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
>  MISA_EXT_INFO(RVV, "v", "Vector operations"),
>  MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
>  };
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index d74b361be6..a43c8fba57 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -67,7 +67,6 @@ typedef struct CPUArchState CPURISCVState;
>  #define RVS RV('S')
>  #define RVU RV('U')
>  #define RVH RV('H')
> -#define RVJ RV('J')
>  #define RVG RV('G')
>
>  extern const uint32_t misa_bits[];
> @@ -374,18 +373,7 @@ struct CPUArchState {
>  /* True if in debugger mode.  */
>  bool debugger;
>
> -/*
> - * CSRs for PointerMasking extension
> - */
> -target_ulong mmte;
> -target_ulong mpmmask;
> -target_ulong mpmbase;
> -target_ulong spmmask;
> -target_ulong spmbase;
> -target_ulong upmmask;
> -target_ulong upmbase;
> -
> -/* CSRs for execution environment configuration */
> +/* CSRs for execution enviornment configuration */
>  uint64_t menvcfg;
>  uint64_t mstateen[SMSTATEEN_MAX_COUNT];
>  uint64_t hstateen[SMSTATEEN_MAX_COUNT];
> @@ -393,8 +381,6 @@ struct CPUArchState {
>  target_ulong senvcfg;
>  uint64_t henvcfg;
>  #endif
> -target_ulong cur_pmmask;
> -target_ulong cur_pmbase;
>
>  /* Fields from here on are preserved across CPU reset. */
>  QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> @@ -543,17 +529,14 @@ FIELD(TB_FLAGS, VILL, 14, 1)
>  FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1)
>  /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
>  FIELD(TB_FLAGS, XL, 16, 2)
> -/* If PointerMasking should be applied */
> -FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1)
> -FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1)
> -FIELD(TB_FLAGS, VTA, 20, 1)
> -FIELD(TB_FLAGS, VMA, 21, 1)
> +FIELD(TB_FLAGS, VTA, 18, 1)
> +FIELD(TB_FLAGS, VMA, 19, 1)
>  /* Native debug itrigger */
> -FIELD(TB_FLAGS, ITRIGGER, 22, 1)
> +FIELD(TB_FLAGS, ITRIGGER, 20, 1)
>  /* Virtual mode enabled */
> -FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
> -FIELD(TB_FLAGS, PRIV, 24, 2)
> -FIELD(TB_FLAGS, AXL, 26, 2)
> +FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1)
> +FIELD(TB_FLAGS, PRIV, 22, 2)
> +FIELD(TB_FLAGS, AXL, 24, 2)
>
>  #ifdef TARGET_RISCV32
>  #define riscv_cpu_mxl(env)  ((vo

Re: [PATCH v4 0/6] Pointer Masking update for Zjpm v0.8

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 8:31 PM Alexey Baturo  wrote:
>
> From: Alexey Baturo 
>
> Hi,
>

Do you mind including a pointer to the exact spec (a Github link with
the SHA or tag is great) that you are targeting? We are having issues
with a different spec, so it will be helpful in future to know exactly
what the developer was targeting in the cover letter

Alistair

> Patch series updated after the suggested comments:
> - removed J-letter extension as it's unused
> - renamed and fixed function to detect if address should be sign-extended
> - zeroed unused context variables and moved computation logic to another patch
> - bumped pointer masking version_id and minimum_version_id by 1
>
> Thanks
>
> [v3]:
> There patches are updated after Richard's comments:
> - moved new tb flags to the end
> - used tcg_gen_(s)extract to get the final address
> - properly handle CONFIG_USER_ONLY
>
> Thanks
>
> [v2]:
> As per Richard's suggestion I made pmm field part of tb_flags.
> It allowed to get rid of global variable to store pmlen.
> Also it allowed to simplify all the machinery around it.
>
> Thanks
>
> [v1]:
> Hi all,
>
> It looks like Zjpm v0.8 is almost frozen and we don't expect it change 
> drastically anymore.
> Compared to the original implementation with explicit base and mask CSRs, we 
> now only have
> several fixed options for number of masked bits which are set using existing 
> CSRs.
> The changes have been tested with handwritten assembly tests and LLVM HWASAN
> test suite.
>
> Thanks
>
> Alexey Baturo (6):
>   target/riscv: Remove obsolete pointer masking extension code.
>   target/riscv: Add new CSR fields for S{sn,mn,m}pm extensions as part
> of Zjpm v0.8
>   target/riscv: Add helper functions to calculate current number of
> masked bits for pointer masking
>   target/riscv: Add pointer masking tb flags
>   target/riscv: Update address modify functions to take into account
> pointer masking
>   target/riscv: Enable updates for pointer masking variables and thus
> enable pointer masking extension
>
>  target/riscv/cpu.c   |  21 +--
>  target/riscv/cpu.h   |  46 +++--
>  target/riscv/cpu_bits.h  |  90 +-
>  target/riscv/cpu_cfg.h   |   3 +
>  target/riscv/cpu_helper.c|  96 +-
>  target/riscv/csr.c   | 337 ++-
>  target/riscv/machine.c   |  16 +-
>  target/riscv/pmp.c   |  13 +-
>  target/riscv/pmp.h   |  11 +-
>  target/riscv/tcg/tcg-cpu.c   |   5 +-
>  target/riscv/translate.c |  46 ++---
>  target/riscv/vector_helper.c |  14 +-
>  12 files changed, 153 insertions(+), 545 deletions(-)
>
> --
> 2.34.1
>
>



Re: Adding custom CSR to riscv-qemu

2024-01-21 Thread Alistair Francis
On Tue, Jan 2, 2024 at 7:22 PM Nati Rapaport  wrote:
>
> Hello,
>
> I’m going to add some custom CSRs (Control & Status Registers) to a new RiscV 
> core in qemu.
>
> Could you please help me understanding if there is any method to do it?

Have a look at decode_opc() in target/riscv/translate.c.

We probably want something similar where we can iterate over the
vendor enabled CSRs.

>
> Should I do it in /target/riscv/cpu_bits.h where all CSRs are defined  (and 
> other files, where all standard CSRs implementation reside?) and just put it 
> under a compilation flag for our new core only?

The vendor CSRs should be in their own file. The idea is to keep as
much as possible separated from the general RISC-V code.

>
> I don’t think so.. as I don’t see any similar example for that there.
>
> Should I add all the related code around these CSRs in dedicated source files 
> and let them built only for our core?

Pretty much, although it will be built by default. We don't want
custom binaries for vendors or anything like that

Alistair

>
> Please explain..
>
>
>
> Thank you in advance.
>
> Nati Rapaport
>
> Cadence Design Systems



[PATCH 2/3] hw/pci: Add two parameters to get_address_space

2024-01-21 Thread Zhenzhong Duan
This adds PCI device's real bus and devfn to API get_address_space(),
for vIOMMU which also wants real BDF, i.e., virtio-iommu.

Signed-off-by: Zhenzhong Duan 
---
 include/hw/pci/pci.h | 11 ---
 hw/alpha/typhoon.c   |  3 ++-
 hw/arm/smmu-common.c |  3 ++-
 hw/i386/amd_iommu.c  |  6 --
 hw/i386/intel_iommu.c|  6 --
 hw/pci-host/astro.c  |  3 ++-
 hw/pci-host/designware.c |  3 ++-
 hw/pci-host/dino.c   |  3 ++-
 hw/pci-host/pnv_phb3.c   |  3 ++-
 hw/pci-host/pnv_phb4.c   |  3 ++-
 hw/pci-host/ppce500.c|  3 ++-
 hw/pci-host/raven.c  |  3 ++-
 hw/pci-host/sabre.c  |  3 ++-
 hw/pci/pci.c |  3 ++-
 hw/ppc/ppc440_pcix.c |  3 ++-
 hw/ppc/spapr_pci.c   |  3 ++-
 hw/remote/iommu.c|  3 ++-
 hw/s390x/s390-pci-bus.c  |  3 ++-
 hw/virtio/virtio-iommu.c |  3 ++-
 19 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index fa6313aabc..2483d61a8c 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -378,13 +378,18 @@ typedef struct PCIIOMMUOps {
  *
  * Mandatory callback which returns a pointer to an #AddressSpace
  *
- * @bus: the #PCIBus being accessed.
+ * @bus: the aliased #PCIBus being accessed.
  *
  * @opaque: the data passed to pci_setup_iommu().
  *
- * @devfn: device and function number
+ * @devfn: aliased device and function number
+ *
+ * @real_bus: the #PCIBus being accessed.
+ *
+ * @real_devfn: device and function number
  */
-   AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int devfn);
+   AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int devfn,
+   PCIBus *real_bus, int real_devfn);
 } PCIIOMMUOps;
 
 AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index e8711ae16a..eda5a1c391 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -732,7 +732,8 @@ static IOMMUTLBEntry 
typhoon_translate_iommu(IOMMUMemoryRegion *iommu,
 return ret;
 }
 
-static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int 
devfn)
+static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int 
devfn,
+   PCIBus *real_bus, int real_devfn)
 {
 TyphoonState *s = opaque;
 return &s->pchip.iommu_as;
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index 9a8ac45431..c3a8f84c38 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -569,7 +569,8 @@ SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t 
bus_num)
 return NULL;
 }
 
-static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
+static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn,
+  PCIBus *real_bus, int real_devfn)
 {
 SMMUState *s = opaque;
 SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 4203144da9..0cc63fd050 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1390,7 +1390,8 @@ static const MemoryRegionOps amdvi_ir_ops = {
 }
 };
 
-static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
+static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn,
+  PCIBus *real_bus, int real_devfn)
 {
 char name[128];
 AMDVIState *s = opaque;
@@ -1578,7 +1579,8 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error 
**errp)
 }
 
 /* Pseudo address space under root PCI bus. */
-x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID);
+x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID,
+NULL, 0);
 
 /* set up MMIO */
 memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio",
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 1a07faddb4..9d8c8e1d03 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -4094,7 +4094,8 @@ static void vtd_reset(DeviceState *dev)
 vtd_address_space_refresh_all(s);
 }
 
-static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
+static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn,
+PCIBus *real_bus, int real_devfn)
 {
 IntelIOMMUState *s = opaque;
 VTDAddressSpace *vtd_as;
@@ -4233,7 +4234,8 @@ static void vtd_realize(DeviceState *dev, Error **errp)
 vtd_init(s);
 pci_setup_iommu(bus, &vtd_iommu_ops, dev);
 /* Pseudo address space under root PCI bus. */
-x86ms->ioapic_as = vtd_host_dma_iommu(bus, s, Q35_PSEUDO_DEVFN_IOAPIC);
+x86ms->ioapic_as = vtd_host_dma_iommu(bus, s, Q35_PSEUDO_DEVFN_IOAPIC,
+  NULL, 0);
 qemu_add_machine_init_done_notif

[PATCH 3/3] virtio-iommu: Support PCI device aliases

2024-01-21 Thread Zhenzhong Duan
Currently virtio-iommu doesn't work well if there are multiple devices
in same iommu group. In below example config, guest virtio-iommu driver
can successfully probe first device but fail on others. Only one device
under the bridge can work normally.

-device virtio-iommu \
-device pcie-pci-bridge,id=root0 \
-device vfio-pci,host=81:11.0,bus=root0 \
-device vfio-pci,host=6f:01.0,bus=root0 \

The reason is virtio-iommu stores AS(address space) in hash table with
aliased BDF and corelates endpoint which is indexed by device's real
BDF, i.e., virtio_iommu_mr() is passed a real BDF to lookup AS hash
table, we either get wrong AS or NULL.

Fix it by storing AS indexed by real BDF. This way also make iova_ranges
from vfio device stored in IOMMUDevice of real BDF successfully.

Signed-off-by: Zhenzhong Duan 
---
 hw/virtio/virtio-iommu.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index d99c1f0d64..6880d92a44 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -399,27 +399,27 @@ static AddressSpace *virtio_iommu_find_add_as(PCIBus 
*bus, void *opaque,
   int real_devfn)
 {
 VirtIOIOMMU *s = opaque;
-IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus);
+IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, real_bus);
 static uint32_t mr_index;
 IOMMUDevice *sdev;
 
 if (!sbus) {
 sbus = g_malloc0(sizeof(IOMMUPciBus) +
  sizeof(IOMMUDevice *) * PCI_DEVFN_MAX);
-sbus->bus = bus;
-g_hash_table_insert(s->as_by_busptr, bus, sbus);
+sbus->bus = real_bus;
+g_hash_table_insert(s->as_by_busptr, real_bus, sbus);
 }
 
-sdev = sbus->pbdev[devfn];
+sdev = sbus->pbdev[real_devfn];
 if (!sdev) {
 char *name = g_strdup_printf("%s-%d-%d",
  TYPE_VIRTIO_IOMMU_MEMORY_REGION,
- mr_index++, devfn);
-sdev = sbus->pbdev[devfn] = g_new0(IOMMUDevice, 1);
+ mr_index++, real_devfn);
+sdev = sbus->pbdev[real_devfn] = g_new0(IOMMUDevice, 1);
 
 sdev->viommu = s;
-sdev->bus = bus;
-sdev->devfn = devfn;
+sdev->bus = real_bus;
+sdev->devfn = real_devfn;
 
 trace_virtio_iommu_init_iommu_mr(name);
 
-- 
2.34.1




[PATCH 0/3] Two minor fixes on virtio-iommu

2024-01-21 Thread Zhenzhong Duan
PATCH1 fixes a potential issue with vfio devices when reboot to a
different OS which set bus number differently from previous OS.
I didn't reproduce the issue in reality, but it's still possible
in theory.

PATCH2 is a prerequisite of of PATCH3.

PATCH3 make virtio-iommu support PCI device aliases. If there are
more than one device in same IOMMU group, either due to topology,
isolation feature, etc. virtio-iommu can only make one which has
alias BDF works. This impacts both emulated and vfio devices.
I have reproduced the failure with an example config to have two
vfio devices under same pcie to pci bridge.
This patch also make a proper place in virtio-iommu to store
iova_ranges from vfio device when vfio device shares same IOMMU
group with other devices, either emulated or vfio devices.

Zhenzhong Duan (3):
  virtio_iommu: Clear IOMMUPciBus pointer cache when system reset
  hw/pci: Add two parameters to get_address_space
  virtio-iommu: Support PCI device aliases

 include/hw/pci/pci.h | 11 ---
 hw/alpha/typhoon.c   |  3 ++-
 hw/arm/smmu-common.c |  3 ++-
 hw/i386/amd_iommu.c  |  6 --
 hw/i386/intel_iommu.c|  6 --
 hw/pci-host/astro.c  |  3 ++-
 hw/pci-host/designware.c |  3 ++-
 hw/pci-host/dino.c   |  3 ++-
 hw/pci-host/pnv_phb3.c   |  3 ++-
 hw/pci-host/pnv_phb4.c   |  3 ++-
 hw/pci-host/ppce500.c|  3 ++-
 hw/pci-host/raven.c  |  3 ++-
 hw/pci-host/sabre.c  |  3 ++-
 hw/pci/pci.c |  3 ++-
 hw/ppc/ppc440_pcix.c |  3 ++-
 hw/ppc/spapr_pci.c   |  3 ++-
 hw/remote/iommu.c|  3 ++-
 hw/s390x/s390-pci-bus.c  |  3 ++-
 hw/virtio/virtio-iommu.c | 21 -
 19 files changed, 58 insertions(+), 31 deletions(-)

-- 
2.34.1




[PATCH 1/3] virtio_iommu: Clear IOMMUPciBus pointer cache when system reset

2024-01-21 Thread Zhenzhong Duan
IOMMUPciBus pointer cache is indexed by bus number, bus number
may not always be a fixed value, i.e., guest reboot to different
kernel which set bus number with different algorithm.

This could lead to endpoint binding to wrong iommu MR in
virtio_iommu_get_endpoint(), then vfio device setup wrong
mapping from other device.

Signed-off-by: Zhenzhong Duan 
---
 hw/virtio/virtio-iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 8a4bd933c6..bfce3237f3 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -1264,6 +1264,8 @@ static void virtio_iommu_system_reset(void *opaque)
 
 trace_virtio_iommu_system_reset();
 
+memset(s->iommu_pcibus_by_bus_num, 0, sizeof(s->iommu_pcibus_by_bus_num));
+
 /*
  * config.bypass is sticky across device reset, but should be restored on
  * system reset
-- 
2.34.1




[PULL 11/15] Hexagon (target/hexagon) Remove dead functions from hex_common.py

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

These functions are no longer used after making the generators
object oriented.

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20231210220712.491494-10-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/hex_common.py | 51 
 1 file changed, 51 deletions(-)

diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index ca5e9630c1..195620c7ec 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -33,9 +33,6 @@
 overrides = {}  # tags with helper overrides
 idef_parser_enabled = {}  # tags enabled for idef-parser
 
-def bad_register(regtype, regid):
-raise Exception(f"Bad register parse: regtype '{regtype}' regid '{regid}'")
-
 # We should do this as a hash for performance,
 # but to keep order let's keep it as a list.
 def uniquify(seq):
@@ -200,46 +197,6 @@ def get_tagimms():
 return dict(zip(tags, list(map(compute_tag_immediates, tags
 
 
-def is_pair(regid):
-return len(regid) == 2
-
-
-def is_single(regid):
-return len(regid) == 1
-
-
-def is_written(regid):
-return regid[0] in "dexy"
-
-
-def is_writeonly(regid):
-return regid[0] in "de"
-
-
-def is_read(regid):
-return regid[0] in "stuvwxy"
-
-
-def is_readwrite(regid):
-return regid[0] in "xy"
-
-
-def is_scalar_reg(regtype):
-return regtype in "RPC"
-
-
-def is_hvx_reg(regtype):
-return regtype in "VQ"
-
-
-def is_old_val(regtype, regid, tag):
-return regtype + regid + "V" in semdict[tag]
-
-
-def is_new_val(regtype, regid, tag):
-return regtype + regid + "N" in semdict[tag]
-
-
 def need_slot(tag):
 if (
 "A_CVI_SCATTER" not in attribdict[tag]
@@ -280,14 +237,6 @@ def skip_qemu_helper(tag):
 return tag in overrides.keys()
 
 
-def is_tmp_result(tag):
-return "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]
-
-
-def is_new_result(tag):
-return "A_CVI_NEW" in attribdict[tag]
-
-
 def is_idef_parser_enabled(tag):
 return tag in idef_parser_enabled
 
-- 
2.25.1



[PULL 10/15] Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

This is the only remaining use of the is_written function.  We will
remove it in the subsequent commit.

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20231210220712.491494-9-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/attribs_def.h.inc |  1 -
 target/hexagon/hex_common.py | 11 ---
 2 files changed, 12 deletions(-)

diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc
index 21d457fa4a..87942d46f4 100644
--- a/target/hexagon/attribs_def.h.inc
+++ b/target/hexagon/attribs_def.h.inc
@@ -117,7 +117,6 @@ DEF_ATTRIB(IMPLICIT_READS_P1, "Reads the P1 register", "", 
"")
 DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
 DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
 DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
-DEF_ATTRIB(WRITES_PRED_REG, "Writes a predicate register", "", "")
 DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
 DEF_ATTRIB(DEALLOCRET, "dealloc_return", "", "")
 DEF_ATTRIB(DEALLOCFRAME, "deallocframe", "", "")
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 4565dd1953..ca5e9630c1 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -94,10 +94,6 @@ def is_cond_call(tag):
 def calculate_attribs():
 add_qemu_macro_attrib("fREAD_PC", "A_IMPLICIT_READS_PC")
 add_qemu_macro_attrib("fTRAP", "A_IMPLICIT_READS_PC")
-add_qemu_macro_attrib("fWRITE_P0", "A_WRITES_PRED_REG")
-add_qemu_macro_attrib("fWRITE_P1", "A_WRITES_PRED_REG")
-add_qemu_macro_attrib("fWRITE_P2", "A_WRITES_PRED_REG")
-add_qemu_macro_attrib("fWRITE_P3", "A_WRITES_PRED_REG")
 add_qemu_macro_attrib("fSET_OVERFLOW", "A_IMPLICIT_WRITES_USR")
 add_qemu_macro_attrib("fSET_LPCFG", "A_IMPLICIT_WRITES_USR")
 add_qemu_macro_attrib("fLOAD", "A_SCALAR_LOAD")
@@ -122,13 +118,6 @@ def calculate_attribs():
 continue
 macro = macros[macname]
 attribdict[tag] |= set(macro.attribs)
-# Figure out which instructions write predicate registers
-tagregs = get_tagregs()
-for tag in tags:
-regs = tagregs[tag]
-for regtype, regid in regs:
-if regtype == "P" and is_written(regid):
-attribdict[tag].add("A_WRITES_PRED_REG")
 # Mark conditional jumps and calls
 # Not all instructions are properly marked with A_CONDEXEC
 for tag in tags:
-- 
2.25.1



[PULL 07/15] Hexagon (target/hexagon) Make generators object oriented - gen_idef_parser_funcs

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20231210220712.491494-6-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_idef_parser_funcs.py | 20 
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
index f4518e653f..550a48cb7b 100644
--- a/target/hexagon/gen_idef_parser_funcs.py
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -46,6 +46,7 @@ def main():
 hex_common.read_semantics_file(sys.argv[1])
 hex_common.read_attribs_file(sys.argv[2])
 hex_common.calculate_attribs()
+hex_common.init_registers()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
@@ -132,22 +133,9 @@ def main():
 
 arguments = []
 for regtype, regid in regs:
-prefix = "in " if hex_common.is_read(regid) else ""
-
-is_pair = hex_common.is_pair(regid)
-is_single_old = hex_common.is_single(regid) and 
hex_common.is_old_val(
-regtype, regid, tag
-)
-is_single_new = hex_common.is_single(regid) and 
hex_common.is_new_val(
-regtype, regid, tag
-)
-
-if is_pair or is_single_old:
-arguments.append(f"{prefix}{regtype}{regid}V")
-elif is_single_new:
-arguments.append(f"{prefix}{regtype}{regid}N")
-else:
-hex_common.bad_register(regtype, regid)
+reg = hex_common.get_register(tag, regtype, regid)
+prefix = "in " if reg.is_read() else ""
+arguments.append(f"{prefix}{reg.reg_tcg()}")
 
 for immlett, bits, immshift in imms:
 arguments.append(hex_common.imm_name(immlett))
-- 
2.25.1



[PULL 04/15] Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

The generators are generally a bunch of Python if-then-else
statements based on the regtype and regid.  Encapsulate regtype/regid
into a class hierarchy.  Clients lookup the register and invoke
methods.

This has several advantages for making the code easier to read,
understand, and maintain
- The class name makes it more clear what the operand does
- All the methods for a given type of operand are together
- Don't need hex_common.bad_register
  If a regtype/regid is missing, the lookup in hex_common.get_register
  will fail
- We can remove the functions in hex_common that use regtype/regid
  (e.g., is_read)

This patch creates the class hierarchy in hex_common and converts
gen_tcg_funcs.py.  The other scripts will be converted in subsequent
patches in this series.

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20231210220712.491494-3-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_tcg_funcs.py | 571 ++-
 target/hexagon/hex_common.py| 659 
 2 files changed, 683 insertions(+), 547 deletions(-)

diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 02d93bc5ce..3d8e3cb6a2 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -23,466 +23,13 @@
 import hex_common
 
 
-##
-## Helpers for gen_tcg_func
-##
-def gen_decl_ea_tcg(f, tag):
-f.write("TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
-
-
-def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
-regN = f"{regtype}{regid}N"
-if regtype == "R":
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-elif regtype == "C":
-f.write(f"const int {regN} = insn->regno[{regno}] + 
HEX_REG_SA0;\n")
-else:
-hex_common.bad_register(regtype, regid)
-f.write(f"TCGv_i64 {regtype}{regid}V = " f"get_result_gpr_pair(ctx, 
{regN});\n")
-
-
-def genptr_decl_writable(f, tag, regtype, regid, regno):
-regN = f"{regtype}{regid}N"
-if regtype == "R":
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
-elif regtype == "C":
-f.write(f"const int {regN} = insn->regno[{regno}] + 
HEX_REG_SA0;\n")
-f.write(f"TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
-elif regtype == "P":
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"TCGv {regtype}{regid}V = tcg_temp_new();\n")
-else:
-hex_common.bad_register(regtype, regid)
-
-
-def genptr_decl(f, tag, regtype, regid, regno):
-regN = f"{regtype}{regid}N"
-if regtype == "R":
-if regid in {"ss", "tt"}:
-f.write(f"TCGv_i64 {regtype}{regid}V = tcg_temp_new_i64();\n")
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-elif regid in {"dd", "ee", "xx", "yy"}:
-genptr_decl_pair_writable(f, tag, regtype, regid, regno)
-elif regid in {"s", "t", "u", "v"}:
-f.write(
-f"TCGv {regtype}{regid}V = " 
f"hex_gpr[insn->regno[{regno}]];\n"
-)
-elif regid in {"d", "e", "x", "y"}:
-genptr_decl_writable(f, tag, regtype, regid, regno)
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "P":
-if regid in {"s", "t", "u", "v"}:
-f.write(
-f"TCGv {regtype}{regid}V = " 
f"hex_pred[insn->regno[{regno}]];\n"
-)
-elif regid in {"d", "e", "x"}:
-genptr_decl_writable(f, tag, regtype, regid, regno)
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "C":
-if regid == "ss":
-f.write(f"TCGv_i64 {regtype}{regid}V = " 
f"tcg_temp_new_i64();\n")
-f.write(f"const int {regN} = insn->regno[{regno}] + " 
"HEX_REG_SA0;\n")
-elif regid == "dd":
-genptr_decl_pair_writable(f, tag, regtype, regid, regno)
-elif regid == "s":
-f.write(f"TCGv {regtype}{regid}V = tcg_temp_new();\n")
-f.write(
-f"const int {regtype}{regid}N = insn->regno[{regno}] + "
-"HEX_REG_SA0;\n"
-)
-elif regid == "d":
-genptr_decl_writable(f, tag, regtype, regid, regno)
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "M":
-if regid == "u":
-f.write(
-f"const int {regN} = insn->regno[{regno}] + HEX_REG_M0;\n"
-)
-f.write(
-f"TCGv {regtype}{regid}V = hex_gpr[{regN}];\n"
-)
-f.write(
-f"TCGv CS G_GNUC_UNUSED = "
-f"hex_gpr[{regN} - HEX_REG_M0 + HEX_REG_CS0];\n"
-)
-else:
-hex_common.bad_register(regtype, regid

[PULL 15/15] target/hexagon: reduce scope of def_regnum, remove dead assignment

2024-01-21 Thread Brian Cain
This is intended to address a coverity finding: CID 1527408.

Signed-off-by: Brian Cain 
Reviewed-by: Matheus Tavares Bernardino 
Message-Id: <20240114234453.4114587-1-bc...@quicinc.com>
---
 target/hexagon/mmvec/decode_ext_mmvec.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/target/hexagon/mmvec/decode_ext_mmvec.c 
b/target/hexagon/mmvec/decode_ext_mmvec.c
index 174eb3b78b..202d84c7c0 100644
--- a/target/hexagon/mmvec/decode_ext_mmvec.c
+++ b/target/hexagon/mmvec/decode_ext_mmvec.c
@@ -33,7 +33,6 @@ check_new_value(Packet *pkt)
 const char *dststr = NULL;
 uint16_t def_opcode;
 char letter;
-int def_regnum;
 
 for (i = 1; i < pkt->num_insns; i++) {
 uint16_t use_opcode = pkt->insn[i].opcode;
@@ -78,7 +77,6 @@ check_new_value(Packet *pkt)
 }
 }
 if ((dststr == NULL)  && GET_ATTRIB(def_opcode, A_CVI_GATHER)) {
-def_regnum = 0;
 pkt->insn[i].regno[use_regidx] = def_oreg;
 pkt->insn[i].new_value_producer_slot = pkt->insn[def_idx].slot;
 } else {
@@ -86,7 +84,7 @@ check_new_value(Packet *pkt)
 /* still not there, we have a bad packet */
 g_assert_not_reached();
 }
-def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
+int def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
 /* Now patch up the consumer with the register number */
 pkt->insn[i].regno[use_regidx] = def_regnum ^ def_oreg;
 /* special case for (Vx,Vy) */
-- 
2.25.1



[PULL 13/15] Hexagon (target/hexagon) Use QEMU decodetree (16-bit instructions)

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Section 10.3 of the Hexagon V73 Programmer's Reference Manual

A duplex is encoded as a 32-bit instruction with bits [15:14] set to 00.
The sub-instructions that comprise a duplex are encoded as 13-bit fields
in the duplex.

Create a decoder for each subinstruction class (a, l1, l2, s1, s2).

Extend gen_trans_funcs.py to handle all instructions rather than
filter by instruction class.

There is a g_assert_not_reached() in decode_insns() in decode.c to
verify we never try to use the old decoder on 16-bit instructions.

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240115221443.365287-3-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/README |  1 +
 target/hexagon/decode.c   | 85 +
 target/hexagon/gen_decodetree.py  | 12 -
 target/hexagon/gen_trans_funcs.py | 12 +
 target/hexagon/meson.build| 90 +++
 5 files changed, 188 insertions(+), 12 deletions(-)

diff --git a/target/hexagon/README b/target/hexagon/README
index 1b2a4d0eac..746ebec378 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -195,6 +195,7 @@ Step 1 is to run target/hexagon/gen_dectree_import.c to 
produce
 Step 2 is to import iset.py into target/hexagon/gen_decodetree.py to produce
 /target/hexagon/normal_decode_generated
 /target/hexagon/hvx_decode_generated
+/target/hexagon/subinsn_*_decode_generated
 Step 3 is to process the above files with QEMU's decodetree.py to produce
 /target/hexagon/decode_*_generated.c.inc
 Step 4 is to import iset.py into target/hexagon/gen_trans_funcs.py to produce
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index bddad1f75e..160b23a895 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -60,6 +60,7 @@ static int decode_mapped_reg_##NAME(DisasContext *ctx, int x) 
\
 }
 DECODE_MAPPED(R_16)
 DECODE_MAPPED(R_8)
+DECODE_MAPPED(R__8)
 
 /* Helper function for decodetree_trans_funcs_generated.c.inc */
 static int shift_left(DisasContext *ctx, int x, int n, int immno)
@@ -77,6 +78,13 @@ static int shift_left(DisasContext *ctx, int x, int n, int 
immno)
 #include "decode_normal_generated.c.inc"
 #include "decode_hvx_generated.c.inc"
 
+/* Include the generated decoder for 16 bit insn */
+#include "decode_subinsn_a_generated.c.inc"
+#include "decode_subinsn_l1_generated.c.inc"
+#include "decode_subinsn_l2_generated.c.inc"
+#include "decode_subinsn_s1_generated.c.inc"
+#include "decode_subinsn_s2_generated.c.inc"
+
 /* Include the generated helpers for the decoder */
 #include "decodetree_trans_funcs_generated.c.inc"
 
@@ -790,6 +798,63 @@ decode_insns_tablewalk(Insn *insn, const DectreeTable 
*table,
 }
 }
 
+/*
+ * Section 10.3 of the Hexagon V73 Programmer's Reference Manual
+ *
+ * A duplex is encoded as a 32-bit instruction with bits [15:14] set to 00.
+ * The sub-instructions that comprise a duplex are encoded as 13-bit fields
+ * in the duplex.
+ *
+ * Per table 10-4, the 4-bit duplex iclass is encoded in bits 31:29, 13
+ */
+static uint32_t get_duplex_iclass(uint32_t encoding)
+{
+uint32_t iclass = extract32(encoding, 13, 1);
+iclass = deposit32(iclass, 1, 3, extract32(encoding, 29, 3));
+return iclass;
+}
+
+/*
+ * Per table 10-5, the duplex ICLASS field values that specify the group of
+ * each sub-instruction in a duplex
+ *
+ * This table points to the decode instruction for each entry in the table
+ */
+typedef bool (*subinsn_decode_func)(DisasContext *ctx, uint16_t insn);
+typedef struct {
+subinsn_decode_func decode_slot0_subinsn;
+subinsn_decode_func decode_slot1_subinsn;
+} subinsn_decode_groups;
+
+static const subinsn_decode_groups decode_groups[16] = {
+[0x0] = { decode_subinsn_l1, decode_subinsn_l1 },
+[0x1] = { decode_subinsn_l2, decode_subinsn_l1 },
+[0x2] = { decode_subinsn_l2, decode_subinsn_l2 },
+[0x3] = { decode_subinsn_a,  decode_subinsn_a },
+[0x4] = { decode_subinsn_l1, decode_subinsn_a },
+[0x5] = { decode_subinsn_l2, decode_subinsn_a },
+[0x6] = { decode_subinsn_s1, decode_subinsn_a },
+[0x7] = { decode_subinsn_s2, decode_subinsn_a },
+[0x8] = { decode_subinsn_s1, decode_subinsn_l1 },
+[0x9] = { decode_subinsn_s1, decode_subinsn_l2 },
+[0xa] = { decode_subinsn_s1, decode_subinsn_s1 },
+[0xb] = { decode_subinsn_s2, decode_subinsn_s1 },
+[0xc] = { decode_subinsn_s2, decode_subinsn_l1 },
+[0xd] = { decode_subinsn_s2, decode_subinsn_l2 },
+[0xe] = { decode_subinsn_s2, decode_subinsn_s2 },
+[0xf] = { NULL,  NULL },  /* Reserved */
+};
+
+static uint16_t get_slot0_subinsn(uint32_t encoding)
+{
+return extract32(encoding, 0, 13);
+}
+
+static uint16_t get_slot1_subinsn(uint32_t encoding)
+{
+return extract32(encoding, 16, 13);
+}
+
 static unsigned int
 decode_insns(DisasContext *ctx, Insn *insn, uint32_t encoding)
 {
@@ -805,8 +870,28 @@ decode_insns(D

[PULL 01/15] tests/docker: Hexagon toolchain update

2024-01-21 Thread Brian Cain
This update includes support for privileged instructions.

Signed-off-by: Brian Cain 
Reviewed-by: Matheus Tavares Bernardino 
Tested-by: Matheus Tavares Bernardino 
Message-Id: <20240114232354.4109231-1-bc...@quicinc.com>
---
 tests/docker/dockerfiles/debian-hexagon-cross.docker | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker 
b/tests/docker/dockerfiles/debian-hexagon-cross.docker
index 7c38d7c9e4..60bd8faa20 100644
--- a/tests/docker/dockerfiles/debian-hexagon-cross.docker
+++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker
@@ -38,9 +38,9 @@ RUN apt-get update && \
 RUN /usr/bin/pip3 install tomli
 
 ENV TOOLCHAIN_INSTALL /opt
-ENV TOOLCHAIN_RELEASE 16.0.0
+ENV TOOLCHAIN_RELEASE 12.Dec.2023
 ENV TOOLCHAIN_BASENAME 
"clang+llvm-${TOOLCHAIN_RELEASE}-cross-hexagon-unknown-linux-musl"
-ENV TOOLCHAIN_URL 
https://codelinaro.jfrog.io/artifactory/codelinaro-toolchain-for-hexagon/v${TOOLCHAIN_RELEASE}/${TOOLCHAIN_BASENAME}.tar.xz
+ENV TOOLCHAIN_URL 
https://codelinaro.jfrog.io/artifactory/codelinaro-toolchain-for-hexagon/${TOOLCHAIN_RELEASE}/${TOOLCHAIN_BASENAME}.tar.xz
 ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
 
 RUN curl -#SL "$TOOLCHAIN_URL" | tar -xJC "$TOOLCHAIN_INSTALL"
-- 
2.25.1



[PULL 02/15] Hexagon (target/hexagon) Fix shadow variable when idef-parser is off

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Adding -Werror=shadow=compatible-local causes Hexagon not to build
when idef-parser is off.  The "label" variable in CHECK_NOSHUF_PRED
shadows a variable in the surrounding code.

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20231130183955.54314-1-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/macros.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 9a51b5709b..f99390e2a8 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -93,13 +93,13 @@
 
 #define CHECK_NOSHUF_PRED(GET_EA, SIZE, PRED) \
 do { \
-TCGLabel *label = gen_new_label(); \
-tcg_gen_brcondi_tl(TCG_COND_EQ, PRED, 0, label); \
+TCGLabel *noshuf_label = gen_new_label(); \
+tcg_gen_brcondi_tl(TCG_COND_EQ, PRED, 0, noshuf_label); \
 GET_EA; \
 if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
 probe_noshuf_load(EA, SIZE, ctx->mem_idx); \
 } \
-gen_set_label(label); \
+gen_set_label(noshuf_label); \
 if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
 process_store(ctx, 1); \
 } \
-- 
2.25.1



[PULL 12/15] Hexagon (target/hexagon) Use QEMU decodetree (32-bit instructions)

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

The Decodetree Specification can be found here
https://www.qemu.org/docs/master/devel/decodetree.html

Covers all 32-bit instructions, including HVX

We generate separate decoders for each instruction class.  The reason
will be more apparent in the next patch in this series.

We add 2 new scripts
gen_decodetree.pyGenerate the input to decodetree.py
gen_trans_funcs.py   Generate the trans_* functions used by the
 output of decodetree.py

Since the functions generated by decodetree.py take DisasContext * as an
argument, we add the argument to a couple of functions that didn't need
it previously.  We also set the insn field in DisasContext during decode
because it is used by the trans_* functions.

There is a g_assert_not_reached() in decode_insns() in decode.c to
verify we never try to use the old decoder on 32-bit instructions

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240115221443.365287-2-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/README |  13 +-
 target/hexagon/decode.c   |  54 -
 target/hexagon/decode.h   |   5 +-
 target/hexagon/gen_decodetree.py  | 190 ++
 target/hexagon/gen_trans_funcs.py | 132 +
 target/hexagon/meson.build|  55 +
 target/hexagon/translate.c|   4 +-
 7 files changed, 439 insertions(+), 14 deletions(-)
 create mode 100755 target/hexagon/gen_decodetree.py
 create mode 100755 target/hexagon/gen_trans_funcs.py

diff --git a/target/hexagon/README b/target/hexagon/README
index 69b2ffe9bb..1b2a4d0eac 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -189,11 +189,16 @@ the packet, and we mark the implicit writes.  After the 
analysis is performed,
 we initialize the result register for each of the predicated assignments.
 
 In addition to instruction semantics, we use a generator to create the decode
-tree.  This generation is also a two step process.  The first step is to run
-target/hexagon/gen_dectree_import.c to produce
+tree.  This generation is a four step process.
+Step 1 is to run target/hexagon/gen_dectree_import.c to produce
 /target/hexagon/iset.py
-This file is imported by target/hexagon/dectree.py to produce
-/target/hexagon/dectree_generated.h.inc
+Step 2 is to import iset.py into target/hexagon/gen_decodetree.py to produce
+/target/hexagon/normal_decode_generated
+/target/hexagon/hvx_decode_generated
+Step 3 is to process the above files with QEMU's decodetree.py to produce
+/target/hexagon/decode_*_generated.c.inc
+Step 4 is to import iset.py into target/hexagon/gen_trans_funcs.py to produce
+/target/hexagon/decodetree_trans_funcs_generated.c.inc
 
 *** Key Files ***
 
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 946c55cc71..bddad1f75e 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -52,6 +52,34 @@ DEF_REGMAP(R_8,   8,  0, 1, 2, 3, 4, 5, 6, 7)
 #define DECODE_MAPPED_REG(OPNUM, NAME) \
 insn->regno[OPNUM] = DECODE_REGISTER_##NAME[insn->regno[OPNUM]];
 
+/* Helper functions for decode_*_generated.c.inc */
+#define DECODE_MAPPED(NAME) \
+static int decode_mapped_reg_##NAME(DisasContext *ctx, int x) \
+{ \
+return DECODE_REGISTER_##NAME[x]; \
+}
+DECODE_MAPPED(R_16)
+DECODE_MAPPED(R_8)
+
+/* Helper function for decodetree_trans_funcs_generated.c.inc */
+static int shift_left(DisasContext *ctx, int x, int n, int immno)
+{
+int ret = x;
+Insn *insn = ctx->insn;
+if (!insn->extension_valid ||
+insn->which_extended != immno) {
+ret <<= n;
+}
+return ret;
+}
+
+/* Include the generated decoder for 32 bit insn */
+#include "decode_normal_generated.c.inc"
+#include "decode_hvx_generated.c.inc"
+
+/* Include the generated helpers for the decoder */
+#include "decodetree_trans_funcs_generated.c.inc"
+
 typedef struct {
 const struct DectreeTable *table_link;
 const struct DectreeTable *table_link_b;
@@ -550,7 +578,8 @@ apply_extender(Packet *pkt, int i, uint32_t extender)
 int immed_num;
 uint32_t base_immed;
 
-immed_num = opcode_which_immediate_is_extended(pkt->insn[i].opcode);
+immed_num = pkt->insn[i].which_extended;
+g_assert(immed_num == 
opcode_which_immediate_is_extended(pkt->insn[i].opcode));
 base_immed = pkt->insn[i].immed[immed_num];
 
 pkt->insn[i].immed[immed_num] = extender | fZXTN(6, 32, base_immed);
@@ -762,12 +791,19 @@ decode_insns_tablewalk(Insn *insn, const DectreeTable 
*table,
 }
 
 static unsigned int
-decode_insns(Insn *insn, uint32_t encoding)
+decode_insns(DisasContext *ctx, Insn *insn, uint32_t encoding)
 {
 const DectreeTable *table;
 if (parse_bits(encoding) != 0) {
+if (decode_normal(ctx, encoding) ||
+decode_hvx(ctx, encoding)) {
+insn->generate = opcode_genptr[insn->opcode];
+insn->iclass = iclass_bits(encodi

[PULL 06/15] Hexagon (target/hexagon) Make generators object oriented - gen_helper_funcs

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20231210220712.491494-5-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_helper_funcs.py | 370 +
 target/hexagon/hex_common.py   |  48 +++-
 2 files changed, 104 insertions(+), 314 deletions(-)

diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index ce21d3b688..9cc3d69c49 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -23,181 +23,14 @@
 import hex_common
 
 
-##
-## Helpers for gen_helper_function
-##
-def gen_decl_ea(f):
-f.write("uint32_t EA;\n")
-
-
-def gen_helper_return_type(f, regtype, regid, regno):
-if regno > 1:
-f.write(", ")
-f.write("int32_t")
-
-
-def gen_helper_return_type_pair(f, regtype, regid, regno):
-if regno > 1:
-f.write(", ")
-f.write("int64_t")
-
-
-def gen_helper_arg(f, regtype, regid, regno):
-if regno > 0:
-f.write(", ")
-f.write(f"int32_t {regtype}{regid}V")
-
-
-def gen_helper_arg_new(f, regtype, regid, regno):
-if regno >= 0:
-f.write(", ")
-f.write(f"int32_t {regtype}{regid}N")
-
-
-def gen_helper_arg_pair(f, regtype, regid, regno):
-if regno >= 0:
-f.write(", ")
-f.write(f"int64_t {regtype}{regid}V")
-
-
-def gen_helper_arg_ext(f, regtype, regid, regno):
-if regno > 0:
-f.write(", ")
-f.write(f"void *{regtype}{regid}V_void")
-
-
-def gen_helper_arg_ext_pair(f, regtype, regid, regno):
-if regno > 0:
-f.write(", ")
-f.write(f"void *{regtype}{regid}V_void")
-
-
-def gen_helper_arg_opn(f, regtype, regid, i, tag):
-if hex_common.is_pair(regid):
-if hex_common.is_hvx_reg(regtype):
-gen_helper_arg_ext_pair(f, regtype, regid, i)
-else:
-gen_helper_arg_pair(f, regtype, regid, i)
-elif hex_common.is_single(regid):
-if hex_common.is_old_val(regtype, regid, tag):
-if hex_common.is_hvx_reg(regtype):
-gen_helper_arg_ext(f, regtype, regid, i)
-else:
-gen_helper_arg(f, regtype, regid, i)
-elif hex_common.is_new_val(regtype, regid, tag):
-gen_helper_arg_new(f, regtype, regid, i)
-else:
-hex_common.bad_register(regtype, regid)
-else:
-hex_common.bad_register(regtype, regid)
-
-
-def gen_helper_arg_imm(f, immlett):
-f.write(f", int32_t {hex_common.imm_name(immlett)}")
-
-
-def gen_helper_dest_decl(f, regtype, regid, regno, subfield=""):
-f.write(f"int32_t {regtype}{regid}V{subfield} = 0;\n")
-
-
-def gen_helper_dest_decl_pair(f, regtype, regid, regno, subfield=""):
-f.write(f"int64_t {regtype}{regid}V{subfield} = 0;\n")
-
-
-def gen_helper_dest_decl_ext(f, regtype, regid):
-if regtype == "Q":
-f.write(
-f"/* {regtype}{regid}V is *(MMQReg *)" 
f"({regtype}{regid}V_void) */\n"
-)
-else:
-f.write(
-f"/* {regtype}{regid}V is *(MMVector *)"
-f"({regtype}{regid}V_void) */\n"
-)
-
-
-def gen_helper_dest_decl_ext_pair(f, regtype, regid, regno):
-f.write(
-f"/* {regtype}{regid}V is *(MMVectorPair *))"
-f"{regtype}{regid}V_void) */\n"
-)
-
-
-def gen_helper_dest_decl_opn(f, regtype, regid, i):
-if hex_common.is_pair(regid):
-if hex_common.is_hvx_reg(regtype):
-gen_helper_dest_decl_ext_pair(f, regtype, regid, i)
-else:
-gen_helper_dest_decl_pair(f, regtype, regid, i)
-elif hex_common.is_single(regid):
-if hex_common.is_hvx_reg(regtype):
-gen_helper_dest_decl_ext(f, regtype, regid)
-else:
-gen_helper_dest_decl(f, regtype, regid, i)
-else:
-hex_common.bad_register(regtype, regid)
-
-
-def gen_helper_src_var_ext(f, regtype, regid):
-if regtype == "Q":
-f.write(
-f"/* {regtype}{regid}V is *(MMQReg *)" 
f"({regtype}{regid}V_void) */\n"
-)
-else:
-f.write(
-f"/* {regtype}{regid}V is *(MMVector *)"
-f"({regtype}{regid}V_void) */\n"
-)
-
-
-def gen_helper_src_var_ext_pair(f, regtype, regid, regno):
-f.write(
-f"/* {regtype}{regid}V{regno} is *(MMVectorPair *)"
-f"({regtype}{regid}V{regno}_void) */\n"
-)
-
-
-def gen_helper_return(f, regtype, regid, regno):
-f.write(f"return {regtype}{regid}V;\n")
-
-
-def gen_helper_return_pair(f, regtype, regid, regno):
-f.write(f"return {regtype}{regid}V;\n")
-
-
-def gen_helper_dst_write_ext(f, regtype, regid):
-return
-
-
-def gen_helper_dst_write_ext_pair(f, regtype, regid):
-return
-
-
-def gen_helper_return_opn(f, regtype, regid, i):
-if hex_common.is_pair(regid):
-if hex_common.is_hvx_reg(regtype):
-gen_helper_dst_write_ext_pair(f, regtype, regid)
-else:
-gen_

[PULL 14/15] Hexagon (target/hexagon) Remove old dectree.py

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Now that we are using QEMU decodetree.py, remove the old decoder

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240115221443.365287-4-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/decode.c | 344 
 target/hexagon/dectree.py   | 403 
 target/hexagon/gen_dectree_import.c |  49 
 target/hexagon/meson.build  |  12 -
 target/hexagon/opcodes.c|  29 --
 target/hexagon/opcodes.h|   2 -
 6 files changed, 839 deletions(-)
 delete mode 100755 target/hexagon/dectree.py

diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 160b23a895..a40210ca1e 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -88,175 +88,6 @@ static int shift_left(DisasContext *ctx, int x, int n, int 
immno)
 /* Include the generated helpers for the decoder */
 #include "decodetree_trans_funcs_generated.c.inc"
 
-typedef struct {
-const struct DectreeTable *table_link;
-const struct DectreeTable *table_link_b;
-Opcode opcode;
-enum {
-DECTREE_ENTRY_INVALID,
-DECTREE_TABLE_LINK,
-DECTREE_SUBINSNS,
-DECTREE_EXTSPACE,
-DECTREE_TERMINAL
-} type;
-} DectreeEntry;
-
-typedef struct DectreeTable {
-unsigned int (*lookup_function)(int startbit, int width, uint32_t opcode);
-unsigned int size;
-unsigned int startbit;
-unsigned int width;
-const DectreeEntry table[];
-} DectreeTable;
-
-#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \
-static const DectreeTable dectree_table_##TAG;
-#define TABLE_LINK(TABLE) /* NOTHING */
-#define TERMINAL(TAG, ENC)/* NOTHING */
-#define SUBINSNS(TAG, CLASSA, CLASSB, ENC)/* NOTHING */
-#define EXTSPACE(TAG, ENC)/* NOTHING */
-#define INVALID() /* NOTHING */
-#define DECODE_END_TABLE(...) /* NOTHING */
-#define DECODE_MATCH_INFO(...)/* NOTHING */
-#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */
-#define DECODE_OPINFO(...)/* NOTHING */
-
-#include "dectree_generated.h.inc"
-
-#undef DECODE_OPINFO
-#undef DECODE_MATCH_INFO
-#undef DECODE_LEGACY_MATCH_INFO
-#undef DECODE_END_TABLE
-#undef INVALID
-#undef TERMINAL
-#undef SUBINSNS
-#undef EXTSPACE
-#undef TABLE_LINK
-#undef DECODE_NEW_TABLE
-#undef DECODE_SEPARATOR_BITS
-
-#define DECODE_SEPARATOR_BITS(START, WIDTH) NULL, START, WIDTH
-#define DECODE_NEW_TABLE_HELPER(TAG, SIZE, FN, START, WIDTH) \
-static const DectreeTable dectree_table_##TAG = { \
-.size = SIZE, \
-.lookup_function = FN, \
-.startbit = START, \
-.width = WIDTH, \
-.table = {
-#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT) \
-DECODE_NEW_TABLE_HELPER(TAG, SIZE, WHATNOT)
-
-#define TABLE_LINK(TABLE) \
-{ .type = DECTREE_TABLE_LINK, .table_link = &dectree_table_##TABLE },
-#define TERMINAL(TAG, ENC) \
-{ .type = DECTREE_TERMINAL, .opcode = TAG  },
-#define SUBINSNS(TAG, CLASSA, CLASSB, ENC) \
-{ \
-.type = DECTREE_SUBINSNS, \
-.table_link = &dectree_table_DECODE_SUBINSN_##CLASSA, \
-.table_link_b = &dectree_table_DECODE_SUBINSN_##CLASSB \
-},
-#define EXTSPACE(TAG, ENC) { .type = DECTREE_EXTSPACE },
-#define INVALID() { .type = DECTREE_ENTRY_INVALID, .opcode = XX_LAST_OPCODE },
-
-#define DECODE_END_TABLE(...) } };
-
-#define DECODE_MATCH_INFO(...)/* NOTHING */
-#define DECODE_LEGACY_MATCH_INFO(...) /* NOTHING */
-#define DECODE_OPINFO(...)/* NOTHING */
-
-#include "dectree_generated.h.inc"
-
-#undef DECODE_OPINFO
-#undef DECODE_MATCH_INFO
-#undef DECODE_LEGACY_MATCH_INFO
-#undef DECODE_END_TABLE
-#undef INVALID
-#undef TERMINAL
-#undef SUBINSNS
-#undef EXTSPACE
-#undef TABLE_LINK
-#undef DECODE_NEW_TABLE
-#undef DECODE_NEW_TABLE_HELPER
-#undef DECODE_SEPARATOR_BITS
-
-static const DectreeTable dectree_table_DECODE_EXT_EXT_noext = {
-.size = 1, .lookup_function = NULL, .startbit = 0, .width = 0,
-.table = {
-{ .type = DECTREE_ENTRY_INVALID, .opcode = XX_LAST_OPCODE },
-}
-};
-
-static const DectreeTable *ext_trees[XX_LAST_EXT_IDX];
-
-static void decode_ext_init(void)
-{
-int i;
-for (i = EXT_IDX_noext; i < EXT_IDX_noext_AFTER; i++) {
-ext_trees[i] = &dectree_table_DECODE_EXT_EXT_noext;
-}
-for (i = EXT_IDX_mmvec; i < EXT_IDX_mmvec_AFTER; i++) {
-ext_trees[i] = &dectree_table_DECODE_EXT_EXT_mmvec;
-}
-}
-
-typedef struct {
-uint32_t mask;
-uint32_t match;
-} DecodeITableEntry;
-
-#define DECODE_NEW_TABLE(TAG, SIZE, WHATNOT)  /* NOTHING */
-#define TABLE_LINK(TABLE) /* NOTHING */
-#define TERMINAL(TAG, ENC)/* NOTHING */
-#define SUBINSNS(TAG, CLASSA, CLASSB, ENC)/* NOTHING */
-#define EXTSPACE(TAG, ENC)/* NOTHING */
-

[PULL 03/15] Hexagon (target/hexagon) Clean up handling of modifier registers

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Currently, the register number (MuN) for modifier registers is the
modifier register number rather than the index into hex_gpr.  This
patch changes MuN to the hex_gpr index, which is consistent with
the handling of control registers.

Note that HELPER(fcircadd) needs the CS register corresponding to the
modifier register specified in the instruction.  We create a TCGv
variable "CS" to hold the value to pass to the helper.

Reviewed-by: Brian Cain 
Signed-off-by: Taylor Simpson 
Message-Id: <20231210220712.491494-2-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_tcg.h|  9 -
 target/hexagon/gen_tcg_funcs.py | 13 +
 target/hexagon/idef-parser/parser-helpers.c |  8 +++-
 target/hexagon/macros.h |  3 +--
 4 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index d992059fce..1c4391b415 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -68,15 +68,14 @@
 do { \
 TCGv tcgv_siV = tcg_constant_tl(siV); \
 tcg_gen_mov_tl(EA, RxV); \
-gen_helper_fcircadd(RxV, RxV, tcgv_siV, MuV, \
-hex_gpr[HEX_REG_CS0 + MuN]); \
+gen_helper_fcircadd(RxV, RxV, tcgv_siV, MuV, CS); \
 } while (0)
 #define GET_EA_pcr(SHIFT) \
 do { \
 TCGv ireg = tcg_temp_new(); \
 tcg_gen_mov_tl(EA, RxV); \
 gen_read_ireg(ireg, MuV, (SHIFT)); \
-gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
+gen_helper_fcircadd(RxV, RxV, ireg, MuV, CS); \
 } while (0)
 
 /* Instructions with multiple definitions */
@@ -113,7 +112,7 @@
 TCGv ireg = tcg_temp_new(); \
 tcg_gen_mov_tl(EA, RxV); \
 gen_read_ireg(ireg, MuV, SHIFT); \
-gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
+gen_helper_fcircadd(RxV, RxV, ireg, MuV, CS); \
 LOAD; \
 } while (0)
 
@@ -427,7 +426,7 @@
 TCGv BYTE G_GNUC_UNUSED = tcg_temp_new(); \
 tcg_gen_mov_tl(EA, RxV); \
 gen_read_ireg(ireg, MuV, SHIFT); \
-gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
+gen_helper_fcircadd(RxV, RxV, ireg, MuV, CS); \
 STORE; \
 } while (0)
 
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index f5246cee6d..02d93bc5ce 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -99,10 +99,15 @@ def genptr_decl(f, tag, regtype, regid, regno):
 hex_common.bad_register(regtype, regid)
 elif regtype == "M":
 if regid == "u":
-f.write(f"const int {regtype}{regid}N = " 
f"insn->regno[{regno}];\n")
 f.write(
-f"TCGv {regtype}{regid}V = hex_gpr[{regtype}{regid}N + "
-"HEX_REG_M0];\n"
+f"const int {regN} = insn->regno[{regno}] + HEX_REG_M0;\n"
+)
+f.write(
+f"TCGv {regtype}{regid}V = hex_gpr[{regN}];\n"
+)
+f.write(
+f"TCGv CS G_GNUC_UNUSED = "
+f"hex_gpr[{regN} - HEX_REG_M0 + HEX_REG_CS0];\n"
 )
 else:
 hex_common.bad_register(regtype, regid)
@@ -528,7 +533,7 @@ def gen_tcg_func(f, tag, regs, imms):
 ):
 declared.append(f"{regtype}{regid}V")
 if regtype == "M":
-declared.append(f"{regtype}{regid}N")
+declared.append("CS")
 elif hex_common.is_new_val(regtype, regid, tag):
 declared.append(f"{regtype}{regid}N")
 else:
diff --git a/target/hexagon/idef-parser/parser-helpers.c 
b/target/hexagon/idef-parser/parser-helpers.c
index 4af020933a..95f2b43076 100644
--- a/target/hexagon/idef-parser/parser-helpers.c
+++ b/target/hexagon/idef-parser/parser-helpers.c
@@ -1541,10 +1541,8 @@ void gen_circ_op(Context *c,
  HexValue *increment,
  HexValue *modifier)
 {
-HexValue cs = gen_tmp(c, locp, 32, UNSIGNED);
 HexValue increment_m = *increment;
 increment_m = rvalue_materialize(c, locp, &increment_m);
-OUT(c, locp, "gen_read_reg(", &cs, ", HEX_REG_CS0 + MuN);\n");
 OUT(c,
 locp,
 "gen_helper_fcircadd(",
@@ -1555,7 +1553,7 @@ void gen_circ_op(Context *c,
 &increment_m,
 ", ",
 modifier);
-OUT(c, locp, ", ", &cs, ");\n");
+OUT(c, locp, ", CS);\n");
 }
 
 HexValue gen_locnt_op(Context *c, YYLTYPE *locp, HexValue *src)
@@ -2080,9 +2078,9 @@ void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg)
 char reg_id[5];
 reg_compose(c, locp, &(arg->reg), reg_id);
 EMIT_SIG(c, ", %s %s", type, reg_id);
-/* MuV register requires also MuN to provide its index */
+/* MuV register requi

[PULL 05/15] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20231210220712.491494-4-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_helper_protos.py | 149 ++--
 target/hexagon/hex_common.py|   7 --
 2 files changed, 8 insertions(+), 148 deletions(-)

diff --git a/target/hexagon/gen_helper_protos.py 
b/target/hexagon/gen_helper_protos.py
index 131043795a..c82b0f54e4 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -22,39 +22,6 @@
 import string
 import hex_common
 
-##
-## Helpers for gen_helper_prototype
-##
-def_helper_types = {
-"N": "s32",
-"O": "s32",
-"P": "s32",
-"M": "s32",
-"C": "s32",
-"R": "s32",
-"V": "ptr",
-"Q": "ptr",
-}
-
-def_helper_types_pair = {
-"R": "s64",
-"C": "s64",
-"S": "s64",
-"G": "s64",
-"V": "ptr",
-"Q": "ptr",
-}
-
-
-def gen_def_helper_opn(f, tag, regtype, regid, i):
-if hex_common.is_pair(regid):
-f.write(f", {def_helper_types_pair[regtype]}")
-elif hex_common.is_single(regid):
-f.write(f", {def_helper_types[regtype]}")
-else:
-hex_common.bad_register(regtype, regid)
-
-
 ##
 ## Generate the DEF_HELPER prototype for an instruction
 ## For A2_add: Rd32=add(Rs32,Rt32)
@@ -65,116 +32,15 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 regs = tagregs[tag]
 imms = tagimms[tag]
 
-numresults = 0
-numscalarresults = 0
-numscalarreadwrite = 0
-for regtype, regid in regs:
-if hex_common.is_written(regid):
-numresults += 1
-if hex_common.is_scalar_reg(regtype):
-numscalarresults += 1
-if hex_common.is_readwrite(regid):
-if hex_common.is_scalar_reg(regtype):
-numscalarreadwrite += 1
+declared = []
+ret_type = hex_common.helper_ret_type(tag, regs).proto_arg
+declared.append(ret_type)
 
-if numscalarresults > 1:
-## The helper is bogus when there is more than one result
-f.write(f"DEF_HELPER_1({tag}, void, env)\n")
-else:
-## Figure out how many arguments the helper will take
-if numscalarresults == 0:
-def_helper_size = len(regs) + len(imms) + numscalarreadwrite + 1
-if hex_common.need_pkt_has_multi_cof(tag):
-def_helper_size += 1
-if hex_common.need_pkt_need_commit(tag):
-def_helper_size += 1
-if hex_common.need_part1(tag):
-def_helper_size += 1
-if hex_common.need_slot(tag):
-def_helper_size += 1
-if hex_common.need_PC(tag):
-def_helper_size += 1
-if hex_common.helper_needs_next_PC(tag):
-def_helper_size += 1
-if hex_common.need_condexec_reg(tag, regs):
-def_helper_size += 1
-f.write(f"DEF_HELPER_{def_helper_size}({tag}")
-## The return type is void
-f.write(", void")
-else:
-def_helper_size = len(regs) + len(imms) + numscalarreadwrite
-if hex_common.need_pkt_has_multi_cof(tag):
-def_helper_size += 1
-if hex_common.need_pkt_need_commit(tag):
-def_helper_size += 1
-if hex_common.need_part1(tag):
-def_helper_size += 1
-if hex_common.need_slot(tag):
-def_helper_size += 1
-if hex_common.need_PC(tag):
-def_helper_size += 1
-if hex_common.need_condexec_reg(tag, regs):
-def_helper_size += 1
-if hex_common.helper_needs_next_PC(tag):
-def_helper_size += 1
-f.write(f"DEF_HELPER_{def_helper_size}({tag}")
+for arg in hex_common.helper_args(tag, regs, imms):
+declared.append(arg.proto_arg)
 
-## Generate the qemu DEF_HELPER type for each result
-## Iterate over this list twice
-## - Emit the scalar result
-## - Emit the vector result
-i = 0
-for regtype, regid in regs:
-if hex_common.is_written(regid):
-if not hex_common.is_hvx_reg(regtype):
-gen_def_helper_opn(f, tag, regtype, regid, i)
-i += 1
-
-## Put the env between the outputs and inputs
-f.write(", env")
-i += 1
-
-# Second pass
-for regtype, regid in regs:
-if hex_common.is_written(regid):
-if hex_common.is_hvx_reg(regtype):
-gen_def_helper_opn(f, tag, regtype, regid, i)
-i += 1
-
-## For conditional instructions, we pass in the destination register
-if "A_CONDEXEC" in hex_common.attribdict[tag]:
-for regtype, regid in regs:
-if hex_common.is_writeonly(regid) and not 
hex_common.is_hvx_reg(
-r

[PULL 08/15] Hexagon (target/hexagon) Make generators object oriented - gen_op_regs

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

Reviewed-by: Brian Cain 
Signed-off-by: Taylor Simpson 
Message-Id: <20231210220712.491494-7-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_op_regs.py | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/gen_op_regs.py b/target/hexagon/gen_op_regs.py
index a8a7712129..7b7b33895a 100755
--- a/target/hexagon/gen_op_regs.py
+++ b/target/hexagon/gen_op_regs.py
@@ -70,6 +70,7 @@ def strip_reg_prefix(x):
 def main():
 hex_common.read_semantics_file(sys.argv[1])
 hex_common.read_attribs_file(sys.argv[2])
+hex_common.init_registers()
 tagregs = hex_common.get_tagregs(full=True)
 tagimms = hex_common.get_tagimms()
 
@@ -80,11 +81,12 @@ def main():
 wregs = []
 regids = ""
 for regtype, regid, _, numregs in regs:
-if hex_common.is_read(regid):
+reg = hex_common.get_register(tag, regtype, regid)
+if reg.is_read():
 if regid[0] not in regids:
 regids += regid[0]
 rregs.append(regtype + regid + numregs)
-if hex_common.is_written(regid):
+if reg.is_written():
 wregs.append(regtype + regid + numregs)
 if regid[0] not in regids:
 regids += regid[0]
-- 
2.25.1



[PULL 09/15] Hexagon (target/hexagon) Make generators object oriented - gen_analyze_funcs

2024-01-21 Thread Brian Cain
From: Taylor Simpson 

This patch conflicts with
https://lists.gnu.org/archive/html/qemu-devel/2023-11/msg00729.html
If that series goes in first, we'll rework this patch and vice versa.

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20231210220712.491494-8-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_analyze_funcs.py | 163 +---
 target/hexagon/hex_common.py| 151 ++
 2 files changed, 157 insertions(+), 157 deletions(-)

diff --git a/target/hexagon/gen_analyze_funcs.py 
b/target/hexagon/gen_analyze_funcs.py
index c3b521abef..a9af666cef 100755
--- a/target/hexagon/gen_analyze_funcs.py
+++ b/target/hexagon/gen_analyze_funcs.py
@@ -23,162 +23,6 @@
 import hex_common
 
 
-##
-## Helpers for gen_analyze_func
-##
-def is_predicated(tag):
-return "A_CONDEXEC" in hex_common.attribdict[tag]
-
-
-def analyze_opn_old(f, tag, regtype, regid, regno):
-regN = f"{regtype}{regid}N"
-predicated = "true" if is_predicated(tag) else "false"
-if regtype == "R":
-if regid in {"ss", "tt"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_reg_read_pair(ctx, {regN});\n")
-elif regid in {"dd", "ee", "xx", "yy"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_reg_write_pair(ctx, {regN}, 
{predicated});\n")
-elif regid in {"s", "t", "u", "v"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_reg_read(ctx, {regN});\n")
-elif regid in {"d", "e", "x", "y"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_reg_write(ctx, {regN}, {predicated});\n")
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "P":
-if regid in {"s", "t", "u", "v"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_pred_read(ctx, {regN});\n")
-elif regid in {"d", "e", "x"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_pred_write(ctx, {regN});\n")
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "C":
-if regid == "ss":
-f.write(
-f"const int {regN} = insn->regno[{regno}] "
-"+ HEX_REG_SA0;\n"
-)
-f.write(f"ctx_log_reg_read_pair(ctx, {regN});\n")
-elif regid == "dd":
-f.write(f"const int {regN} = insn->regno[{regno}] " "+ 
HEX_REG_SA0;\n")
-f.write(f"ctx_log_reg_write_pair(ctx, {regN}, 
{predicated});\n")
-elif regid == "s":
-f.write(
-f"const int {regN} = insn->regno[{regno}] "
-"+ HEX_REG_SA0;\n"
-)
-f.write(f"ctx_log_reg_read(ctx, {regN});\n")
-elif regid == "d":
-f.write(f"const int {regN} = insn->regno[{regno}] " "+ 
HEX_REG_SA0;\n")
-f.write(f"ctx_log_reg_write(ctx, {regN}, {predicated});\n")
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "M":
-if regid == "u":
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_reg_read(ctx, {regN});\n")
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "V":
-newv = "EXT_DFL"
-if hex_common.is_new_result(tag):
-newv = "EXT_NEW"
-elif hex_common.is_tmp_result(tag):
-newv = "EXT_TMP"
-if regid in {"dd", "xx"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(
-f"ctx_log_vreg_write_pair(ctx, {regN}, {newv}, " 
f"{predicated});\n"
-)
-elif regid in {"uu", "vv"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_vreg_read_pair(ctx, {regN});\n")
-elif regid in {"s", "u", "v", "w"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_vreg_read(ctx, {regN});\n")
-elif regid in {"d", "x", "y"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_vreg_write(ctx, {regN}, {newv}, " 
f"{predicated});\n")
-else:
-hex_common.bad_register(regtype, regid)
-elif regtype == "Q":
-if regid in {"d", "e", "x"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_qreg_write(ctx, {regN});\n")
-elif regid in {"s", "t", "u", "v"}:
-f.write(f"const int {regN} = insn->regno[{regno}];\n")
-f.write(f"ctx_log_qreg_read(ctx, {regN});\n")
-  

[PULL 00/15] target-hexagon queue, hexagon docker

2024-01-21 Thread Brian Cain
The following changes since commit 3f2a357b95845ea0bf7463eff6661e43b97d1afc:

  Merge tag 'hw-cpus-20240119' of https://github.com/philmd/qemu into staging 
(2024-01-19 11:39:38 +)

are available in the Git repository at:

  https://github.com/quic/qemu tags/pull-hex-20240121

for you to fetch changes up to bbe4209c8b4300d722f47791f9151e1a69cb0135:

  target/hexagon: reduce scope of def_regnum, remove dead assignment 
(2024-01-21 22:02:48 -0800)


Coverity fix, cross toolchain update, switch to decodetree


Brian Cain (2):
  tests/docker: Hexagon toolchain update
  target/hexagon: reduce scope of def_regnum, remove dead assignment

Taylor Simpson (13):
  Hexagon (target/hexagon) Fix shadow variable when idef-parser is off
  Hexagon (target/hexagon) Clean up handling of modifier registers
  Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs
  Hexagon (target/hexagon) Make generators object oriented - 
gen_helper_protos
  Hexagon (target/hexagon) Make generators object oriented - 
gen_helper_funcs
  Hexagon (target/hexagon) Make generators object oriented - 
gen_idef_parser_funcs
  Hexagon (target/hexagon) Make generators object oriented - gen_op_regs
  Hexagon (target/hexagon) Make generators object oriented - 
gen_analyze_funcs
  Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute
  Hexagon (target/hexagon) Remove dead functions from hex_common.py
  Hexagon (target/hexagon) Use QEMU decodetree (32-bit instructions)
  Hexagon (target/hexagon) Use QEMU decodetree (16-bit instructions)
  Hexagon (target/hexagon) Remove old dectree.py

 target/hexagon/README  |  14 +-
 target/hexagon/attribs_def.h.inc   |   1 -
 target/hexagon/decode.c| 439 +++---
 target/hexagon/decode.h|   5 +-
 target/hexagon/dectree.py  | 403 -
 target/hexagon/gen_analyze_funcs.py| 163 +---
 target/hexagon/gen_decodetree.py   | 198 +
 target/hexagon/gen_dectree_import.c|  49 --
 target/hexagon/gen_helper_funcs.py | 370 ++---
 target/hexagon/gen_helper_protos.py| 149 +---
 target/hexagon/gen_idef_parser_funcs.py|  20 +-
 target/hexagon/gen_op_regs.py  |   6 +-
 target/hexagon/gen_tcg.h   |   9 +-
 target/hexagon/gen_tcg_funcs.py| 566 +
 target/hexagon/gen_trans_funcs.py  | 124 +++
 target/hexagon/hex_common.py   | 921 +++--
 target/hexagon/idef-parser/parser-helpers.c|   8 +-
 target/hexagon/macros.h|   9 +-
 target/hexagon/meson.build | 147 +++-
 target/hexagon/mmvec/decode_ext_mmvec.c|   4 +-
 target/hexagon/opcodes.c   |  29 -
 target/hexagon/opcodes.h   |   2 -
 target/hexagon/translate.c |   4 +-
 .../docker/dockerfiles/debian-hexagon-cross.docker |   4 +-
 24 files changed, 1559 insertions(+), 2085 deletions(-)
 delete mode 100755 target/hexagon/dectree.py
 create mode 100755 target/hexagon/gen_decodetree.py
 create mode 100755 target/hexagon/gen_trans_funcs.py


[PATCH 1/1] target/loongarch/kvm: Enable LSX/LASX extension

2024-01-21 Thread Song Gao
The kernel had already support LSX and LASX [1],
but QEMU is disable LSX/LASX for kvm. This patch adds
kvm_check_cpucfg to check CPUCFG2.

[1]: 
https://lore.kernel.org/all/cabgobfzhrf7e_7jk4uprmsyxty3eiuuywhc35jqncnl9s-z...@mail.gmail.com/

Signed-off-by: Song Gao 
---
 linux-headers/asm-loongarch/kvm.h |  1 +
 target/loongarch/kvm/kvm.c| 35 ---
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/linux-headers/asm-loongarch/kvm.h 
b/linux-headers/asm-loongarch/kvm.h
index c6ad2ee610..923d0bd382 100644
--- a/linux-headers/asm-loongarch/kvm.h
+++ b/linux-headers/asm-loongarch/kvm.h
@@ -79,6 +79,7 @@ struct kvm_fpu {
 #define LOONGARCH_REG_64(TYPE, REG)(TYPE | KVM_REG_SIZE_U64 | (REG << 
LOONGARCH_REG_SHIFT))
 #define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, 
REG)
 #define KVM_IOC_CPUCFG(REG)
LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
+#define KVM_LOONGARCH_VCPU_CPUCFG  0
 
 struct kvm_debug_exit_arch {
 };
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 84bcdf5f86..41b6947c7b 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -537,6 +537,28 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs)
 return ret;
 }
 
+static int kvm_check_cpucfg(int id, CPUState *cs)
+{
+int ret;
+uint64_t val;
+struct kvm_device_attr attr = {
+.group = KVM_LOONGARCH_VCPU_CPUCFG,
+.attr = id,
+.addr = (uint64_t)&val,
+};
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
+
+if (!ret) {
+kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
+env->cpucfg[id] &= val;
+}
+
+return ret;
+}
+
 static int kvm_loongarch_put_cpucfg(CPUState *cs)
 {
 int i, ret = 0;
@@ -545,14 +567,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
 uint64_t val;
 
 for (i = 0; i < 21; i++) {
+   if (i == 2) {
+ret = kvm_check_cpucfg(i, cs);
+if (ret) {
+return ret;
+}
+   }
 val = env->cpucfg[i];
-/* LSX and LASX and LBT are not supported in kvm now */
-if (i == 2) {
-val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT));
-val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) |
- BIT(R_CPUCFG2_LBT_ARM_SHIFT) |
- BIT(R_CPUCFG2_LBT_MIPS_SHIFT));
-}
 ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
 if (ret < 0) {
 trace_kvm_failed_put_cpucfg(strerror(errno));
-- 
2.25.1




Re: [PATCH v4 0/4] Support RISC-V IOPMP

2024-01-21 Thread Alistair Francis
On Thu, Dec 21, 2023 at 4:38 PM Ethan Chen  wrote:
>
> On Mon, Dec 18, 2023 at 02:18:58PM +1000, Alistair Francis wrote:
> > On Wed, Nov 22, 2023 at 3:36 PM Ethan Chen via  
> > wrote:
> > >
> > > This series implements IOPMP specification v1.0.0-draft4 rapid-k model.
> > > The specification url:
> > > https://github.com/riscv-non-isa/iopmp-spec/blob/main/riscv_iopmp_specification.pdf
> > >
> > > When IOPMP is enabled, a DMA device ATCDMAC300 is added to RISC-V virt
> > > platform. This DMA device is connected to the IOPMP and has the 
> > > functionalities
> >
> > I don't think we want to add an Andes DMA device to the virt machine.
> >
> > I can't even find the spec for the ATCDMAC300, which isn't great
> >
> > Alistair
>
> Since the IOPMP does not take effect when there is no other device connects to
> IOPMP, I think it is necessary to have a DMA device for IOPMP demonstration.

That is true, but that device shouldn't be a vendor specific device
for the virt machine.

>
> Do you have any suggestions for supporting IOPMP on RISC-V virt machine?

A RVI device would be fine. Otherwise something that has become a
defacto standard by being commonly used (the SiFive PLIC for example).

I really don't think it should be some vendor IP, especially one that
doesn't have a public datasheet.

You could add an Andes machine that can use your vendor IP. Otherwise
we can look at adding IOPMP and not connecting it, but that is a pain.

What is the IOPMP spec group doing for testing?

Alistair



RE: [PATCH rfcv1 00/23] intel_iommu: Enable stage-1 translation

2024-01-21 Thread Duan, Zhenzhong


>-Original Message-
>From: Jason Wang 
>Subject: Re: [PATCH rfcv1 00/23] intel_iommu: Enable stage-1 translation
>
>On Mon, Jan 15, 2024 at 6:39 PM Zhenzhong Duan
> wrote:
>>
>> Hi,
>>
>> This series enables stage-1 translation support in intel iommu which
>> we called "modern" mode. In this mode, we don't do shadowing of
>> guest page table for passthrough device but pass stage-1 page table
>> to host side to construct a nested domain; we also support emulated
>> device by translating the stage-1 page table. There was some effort
>> to enable this feature in old days, see [1] for details.
>>
>> The key design is to utilize the dual-stage IOMMU translation
>> (also known as IOMMU nested translation) capability in host IOMMU.
>> As the below diagram shows, guest I/O page table pointer in GPA
>> (guest physical address) is passed to host and be used to perform
>> the stage-1 address translation. Along with it, modifications to
>> present mappings in the guest I/O page table should be followed
>> with an IOTLB invalidation.
>>
>> .-.  .---.
>> |   vIOMMU|  | Guest I/O page table  |
>> | |  '---'
>> ./
>> | PASID Entry |--- PASID cache flush --+
>> '-'|
>> | |V
>> | |   I/O page table pointer in GPA
>> '-'
>> Guest
>> --| Shadow |---|
>>   vv   v
>> Host
>> .-.  ..
>> |   pIOMMU|  |  FS for GIOVA->GPA |
>> | |  ''
>> ./  |
>> | PASID Entry | V (Nested xlate)
>> '\.--.
>> | |   | SS for GPA->HPA, unmanaged domain|
>> | |   '--'
>> '-'
>> Where:
>>  - FS = First stage page tables
>>  - SS = Second stage page tables
>> 
>>
>> There are some interactions between VFIO and vIOMMU.
>> * vIOMMU registers PCIIOMMUOps to PCI subsystem which VFIO can
>>   use to registers/unregisters IOMMUDevice object.
>> * VFIO registers an IOMMUFDDevice object at vfio device realize
>>   stage to vIOMMU, this is implemented as a prerequisite series[2].
>> * vIOMMU calls IOMMUFDDevice interface callback IOMMUFDDeviceOps
>>   to bind/unbind device to IOMMUFD backed domains, either nested
>>   domain or not.
>>
>> See below diagram:
>>
>> VFIO Device Intel IOMMU
>> .-. .---.
>> | | |   |
>> |   .-|PCIIOMMUOps  |.-.|
>> |   | IOMMUFD |(set_iommu_device)   || IOMMUFD ||
>> |   | Device  |>|| Device list ||
>> |   .-|(unset_iommu_device) |.-.|
>> | | |   |   |
>> | | |   V   |
>> |   .-| IOMMUFDDeviceOps|  .-.  |
>> |   | IOMMUFD |(attach_hwpt)|  | IOMMUFD |  |
>> |   | link|<|  | Device  |  |
>> |   .-|(detach_hwpt)|  .-.  |
>> | | |   |   |
>> | | |   ... |
>> .-. .---.
>>
>> Based on Yi's suggestion, we updated a new design of managing ioas and
>> hwpt, made it support multiple iommufd objects and the ERRATA_772415
>> case, meanwhile tried to be optimal to share ioas and hwpt whenever
>> possible.
>>
>> Stage-2 page table could be shared by different devices if there is
>> no conflict and devices link to same iommufd object, i.e. devices
>> under same host IOMMU can share same stage-2 page table. If there
>> is conflict, i.e. there is one device under non cache coherency
>> mode which is different from others, it requires a seperate
>> stage-2 page table in non-CC mode.
>>
>> SPR platform has ERRATA_772415 which requires no readonly mappings
>> in stage-2 page table. This series supports creating VTDIOASContainer
>> with no readonly mappings. I'm not clear if there is a rare case that
>> some IOMMUs on a multiple IOMMUs host have ERRATA_772415, this
>design
>> can survive even in that case.
>>
>> See below example diagram for a full view:
>>
>>   IntelIOMMUState
>>  |
>>  V
>> .--..--..---.
>> | 

Re: [PATCH] linux-user/riscv: Fix sizeof_reg typo in vdso unwind info

2024-01-21 Thread Alistair Francis
On Sat, Jan 13, 2024 at 8:04 AM Richard Henderson
 wrote:
>
> Reported-by: Vineet Gupta 
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  linux-user/riscv/vdso-32.so | Bin 2900 -> 2900 bytes
>  linux-user/riscv/vdso-64.so | Bin 3856 -> 3856 bytes
>  linux-user/riscv/vdso.S |   2 +-
>  3 files changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/linux-user/riscv/vdso-32.so b/linux-user/riscv/vdso-32.so
> index 
> 1ad1e5c8b1fe36b0fe4bcb6c06fab8219ecd..5829c1dc90f1c1aafde69f5b9f5bc9afb85251f7
>  100755
> GIT binary patch
> delta 112
> zcmV-$0FVFF7StB71OXHyD|k zhh2zViCc0VjaQCVk5!OVkyDaVlTnmVl~0yVmra;VnM;~Vn@OBVokyNVpGC7%
> S1ndF^OjB%HZ#A<;2M+}Mt1p-U
>
> delta 112
> zcmV-$0FVFF7StB71OXI7ek-E|Z8Fh9(G%V1AYqwmRqNri7y zhgOJGiBgJCi%yJ8jY^J4k4BJ0kwTI{lRlI@l{%I S1ndF^P;+@qVQaHR2M+{CwJgd2
>
> diff --git a/linux-user/riscv/vdso-64.so b/linux-user/riscv/vdso-64.so
> index 
> 83992bebe6d0182f24edfffc531015fd2f4e1cfb..de18e35537a493ba35307e93a2d33faaf489c0b3
>  100755
> GIT binary patch
> delta 118
> zcmV-+0Ez#Q9*`cepaB$miap5s7G5`$2#eqLH6 zhIof|h;)f^ig1f=jBJf+j%bf&kYtf!l3 YlidYEvmgdT0|snTdTn?%vuO#Z1^ZDlW&i*H
>
> delta 117
> zcmV-*0E+*R9*`cepaB$}OC4Olbn*vwtO;!U^UJ?5jVB4Sv;pe_K7av&e1mv|bcJw+
> zY=>xwWQkykT#HzYRE X-UULl9|lAN23SxxMKVLPX$hwVbapOM
>
> diff --git a/linux-user/riscv/vdso.S b/linux-user/riscv/vdso.S
> index a86d8fc488..4b4e34aeea 100644
> --- a/linux-user/riscv/vdso.S
> +++ b/linux-user/riscv/vdso.S
> @@ -101,7 +101,7 @@ endf __vdso_flush_icache
> .cfi_startproc simple
> .cfi_signal_frame
>
> -#define sizeof_reg (__riscv_xlen / 4)
> +#define sizeof_reg (__riscv_xlen / 8)
>  #define sizeof_freg8
>  #define B_GR   (offsetof_uc_mcontext - sizeof_rt_sigframe)
>  #define B_FR   (offsetof_uc_mcontext - sizeof_rt_sigframe + offsetof_freg0)
> --
> 2.34.1
>
>



Re: [PATCH v2 1/2] target/riscv: Add Zaamo and Zalrsc extensions

2024-01-21 Thread Alistair Francis
On Fri, Jan 19, 2024 at 9:22 PM Rob Bradford  wrote:
>
> These extensions represent the atomic operations from A (Zaamo) and the
> Load-Reserved/Store-Conditional operations from A (Zalrsc)
>
> Signed-off-by: Rob Bradford 
> Reviewed-by: Daniel Henrique Barboza 
> ---
>  target/riscv/cpu.c | 5 +
>  target/riscv/cpu_cfg.h | 2 ++
>  2 files changed, 7 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8d3ec74a1c..604baf53c8 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -103,7 +103,9 @@ const RISCVIsaExtData isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
>  ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
>  ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
> +ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
>  ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
> +ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
>  ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
>  ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
>  ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
> @@ -1491,6 +1493,9 @@ const RISCVCPUMultiExtConfig 
> riscv_cpu_experimental_exts[] = {
>  MULTI_EXT_CFG_BOOL("x-smaia", ext_smaia, false),
>  MULTI_EXT_CFG_BOOL("x-ssaia", ext_ssaia, false),
>
> +MULTI_EXT_CFG_BOOL("x-zaamo", ext_zaamo, false),
> +MULTI_EXT_CFG_BOOL("x-zalrsc", ext_zalrsc, false),

We should implement the extension before we expose it to userspace.
That helps maintain bisectability of the code

Alistair

> +
>  MULTI_EXT_CFG_BOOL("x-zvfh", ext_zvfh, false),
>  MULTI_EXT_CFG_BOOL("x-zvfhmin", ext_zvfhmin, false),
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index fea14c275f..cc4c30244c 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -78,7 +78,9 @@ struct RISCVCPUConfig {
>  bool ext_svnapot;
>  bool ext_svpbmt;
>  bool ext_zdinx;
> +bool ext_zaamo;
>  bool ext_zacas;
> +bool ext_zalrsc;
>  bool ext_zawrs;
>  bool ext_zfa;
>  bool ext_zfbfmin;
> --
> 2.43.0
>
>



Re: [PATCH 0/2] Export debug triggers as an extension

2024-01-21 Thread Alistair Francis
On Fri, Jan 12, 2024 at 11:34 PM Rob Bradford  wrote:
>
> On Fri, 2024-01-12 at 13:52 +1000, Alistair Francis wrote:
> > On Thu, Jan 11, 2024 at 5:20 AM Daniel Henrique Barboza
> >  wrote:
> > >
> > > Himanshu,
> > >
> > > We spoke offline but let's make everyone aware:
> > >
> > > - 'sdtrig' should be marked with 'x-' and be an experimental
> > > extension since
> > > the spec isn't yet frozen;
> > >
> > > - Alvin sent a patch to the ML adding the 'mcontext' CSR for
> > > 'sdtrig' some time
> > > ago:
> > >
> > > "[PATCH v2] target/riscv: Implement optional CSR mcontext of debug
> > > Sdtrig extension"
> > >
> > > It would be good to put his patch on top of this series to ease the
> > > review for everyone.
> > > The changes done in patch 2 would also be applicable to the
> > > mcontext CSR;
> > >
> > >
> > > - last but probably the most important: the existing 'debug' flag
> > > seems to be acting as
> > > the actual 'sdtrig' extension due to how the flag is gating trigger
> > > code, e.g.:
> > >
> > >if (cpu->cfg.debug) {
> > >  riscv_trigger_realize(&cpu->env);
> > >  }
> > >
> > > and
> > >
> > >  if (cpu->cfg.debug) {
> > >  riscv_trigger_reset_hold(env);
> > >  }
> > >
> > >
> > > If that's really the case, all the checks with cpu->cfg.debug will
> > > need to also include
> > > cpu->cfg.ext_sdtrig (one or the other). And now we'll have to make
> > > an option: do we leave
> > > the debug triggers (i.e. the 'debug' flag) as always enabled?
> >
> > From memory the "debug" property is for the original debug spec:
> > https://github.com/riscv/riscv-debug-spec/releases/tag/task_group_vote
> >
> > That was ratified and is an official extension. AFAIK this is what is
> > in physical hardware as well.
> >
> > The actual PDF says draft though, I'm not sure what's going on there.
> >
> > The debug spec doesn't have a Z* name, so it's just "debug", at least
> > AFAIK.
> >
> > "sdtrig" seems to be a new backwards-incompatible extension doing
> > basically the same thing. What a mess
> >
> > >
> > > If it's up to me I would make 'debug' as default 'false' and
> > > deprecate it. Users will need
> >
> > I don't think that's the right approach. It's a ratified extension
> > that we are supporting and is in hardware. I think we are stuck
> > supporting it
> >
> >
>
> I've done a bit of digging and I agree things are quite messy. Here are
> my discoveries:
>
> The debug option and the code for triggers was added in these commits:
>
> c9711bd778 target/riscv: cpu: Enable native debug feature
> 38b4e781a4 target/riscv: machine: Add debug state description
> b6092544fc target/riscv: csr: Hook debug CSR read/write
> 1acdb3b013 target/riscv: cpu: Add a config option for native debug
> 95799e36c1 target/riscv: Add initial support for the Sdtrig extension
>
> In March 2022 - since the commit refers to the Sdtrig extension name
> and from the date this was an implementation not of the ratified 0.13
> debug spec (which did not have Sdtrig as a separate extension) but
> rather a version of the in development 1.0 debug spec.

Yeah... We used the "stable" from master. That is our mistake there.

I'm pretty sure we targeted the 0.13. The "Sdtrig" was only added in
the v4 as the changelog says: "mention Sdtrig extension in the commit"

>
> It's not trivial to tell if it's closer to the ratified 0.13 version or
> the (hopefully soon to be frozen) 1.0 version.
>
> As the only part of the debug specification to be implemented is the
> triggers then effectively the debug option is x-sdtrig.
>
> I don't think there is any way for code running on the machine to
> identify what version of the debug is implemented - the appropriate
> register is only available for external debug. Once 1.0 is frozen then
> the presence of Sdtrig isa string would indicate 1.0 trigger support is
> available.
>
> According to JIRA - https://jira.riscv.org/browse/RVS-981 the debug
> specification should freeze this month.
>
> How about considering this as a solution:
>
> - Add a new x-sdtrig option that defaults to false
> - Deprecate debug option - but retain it with default on

We can't deprecate a ratified spec. The 0.13 just seems to call it
"debug" so that's what we are stuck with

> - Add warning if triggers are used and x-sdtrig is not enabled
> - Update the trigger implementation to match frozen spec

We will need to support two versions, as there are two ratified specs.

Alistair

>
> There is potentially a chance that some use cases will be broken but I
> don't think triggers are being widely use - the SBI support only just
> got merged:
> https://github.com/riscv-software-src/opensbi/commit/97f234f15c9657c6ec69fa6ed745be8107bf6ae2
>
> Hope this is helpful,
>
> Rob
>



Re: [PATCH v2 1/2] target/riscv: Convert sdtrig functionality from property to an extension

2024-01-21 Thread Alistair Francis
On Thu, Jan 18, 2024 at 12:25 AM Himanshu Chauhan
 wrote:
>
> The debug trigger (sdtrig) capability is controlled using the debug property.
> The sdtrig is an ISA extension and should be treated so. The sdtrig extension
> may or may not be implemented in a system. Therefore, it must raise an illegal
> instruction exception when it is disabled and its CSRs are accessed.
>
> This patch removes the "debug" property and replaces it with ext_sdtrig 
> extension.
> It also raises an illegal instruction exception when the extension is 
> disabled and
> its CSRs are accessed.
>
> Signed-off-by: Himanshu Chauhan 
> ---
>  target/riscv/cpu.c| 7 +++
>  target/riscv/cpu_cfg.h| 2 +-
>  target/riscv/cpu_helper.c | 2 +-
>  target/riscv/csr.c| 2 +-
>  target/riscv/machine.c| 2 +-
>  5 files changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index b07a76ef6b..c770a7e506 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -909,7 +909,7 @@ static void riscv_cpu_reset_hold(Object *obj)
>  set_default_nan_mode(1, &env->fp_status);
>
>  #ifndef CONFIG_USER_ONLY
> -if (cpu->cfg.debug) {
> +if (cpu->cfg.ext_sdtrig) {
>  riscv_trigger_reset_hold(env);
>  }
>
> @@ -1068,7 +1068,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>  riscv_cpu_register_gdb_regs_for_features(cs);
>
>  #ifndef CONFIG_USER_ONLY
> -if (cpu->cfg.debug) {
> +if (cpu->cfg.ext_sdtrig) {
>  riscv_trigger_realize(&cpu->env);
>  }
>  #endif
> @@ -1393,6 +1393,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
>
>  /* These are experimental so mark with 'x-' */
>  const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
> +MULTI_EXT_CFG_BOOL("x-sdtrig", ext_sdtrig, true),
>  MULTI_EXT_CFG_BOOL("x-smaia", ext_smaia, false),
>  MULTI_EXT_CFG_BOOL("x-ssaia", ext_ssaia, false),
>
> @@ -1480,8 +1481,6 @@ Property riscv_cpu_options[] = {
>  };
>
>  static Property riscv_cpu_properties[] = {
> -DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),

We can't do this. We have users of the debug spec already. It is a
ratified spec, we can't drop support for it either.

The debug working group has really backed us into a corner here. The
simplest approach is probably to just implement sdtrig (debug 1.0) and
the original debug (0.13) separately and support both. Then users can
enable which one they prefer

Alistair

> -
>  #ifndef CONFIG_USER_ONLY
>  DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
>  #endif
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index f4605fb190..341ebf726a 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -109,6 +109,7 @@ struct RISCVCPUConfig {
>  bool ext_zvfbfwma;
>  bool ext_zvfh;
>  bool ext_zvfhmin;
> +bool ext_sdtrig;
>  bool ext_smaia;
>  bool ext_ssaia;
>  bool ext_sscofpmf;
> @@ -145,7 +146,6 @@ struct RISCVCPUConfig {
>  uint16_t cboz_blocksize;
>  bool mmu;
>  bool pmp;
> -bool debug;
>  bool misa_w;
>
>  bool short_isa_string;
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index e7e23b34f4..3f7c2f1315 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -126,7 +126,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
>   ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED;
>  }
>
> -if (cpu->cfg.debug && !icount_enabled()) {
> +if (cpu->cfg.ext_sdtrig && !icount_enabled()) {
>  flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
>  }
>  #endif
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index c50a33397c..8dbb49aa88 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -543,7 +543,7 @@ static RISCVException have_mseccfg(CPURISCVState *env, 
> int csrno)
>
>  static RISCVException debug(CPURISCVState *env, int csrno)
>  {
> -if (riscv_cpu_cfg(env)->debug) {
> +if (riscv_cpu_cfg(env)->ext_sdtrig) {
>  return RISCV_EXCP_NONE;
>  }
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 72fe2374dc..8f9787a30f 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -231,7 +231,7 @@ static bool debug_needed(void *opaque)
>  {
>  RISCVCPU *cpu = opaque;
>
> -return cpu->cfg.debug;
> +return cpu->cfg.ext_sdtrig;
>  }
>
>  static int debug_post_load(void *opaque, int version_id)
> --
> 2.34.1
>
>



How can I know Page Table address on RAM?

2024-01-21 Thread Junho
Hello,

I'm a QEMU user with PowerPc target architecture.
I have some personal modifications related to tb jmp cache and chaining
logic to improve the performance of a specific guest code. To verify the
safety, I have to guarantee that the page table on RAM does not change
after initialization. Do you have any information related to this work?
Currently, what I need to find is the page table start address on the RAM
so that I can test with the range detected.

I look forward to your response.

Thank you
Junho


Re: [PATCH v2] target/riscv: Implement optional CSR mcontext of debug Sdtrig extension

2024-01-21 Thread Alistair Francis
On Tue, Dec 19, 2023 at 10:34 PM Alvin Chang via  wrote:
>
> The debug Sdtrig extension defines an CSR "mcontext". This commit
> implements its predicate and read/write operations into CSR table.
> Its value is reset as 0 when the trigger module is reset.
>
> Signed-off-by: Alvin Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Changes from v1: Remove dedicated cfg, always implement mcontext.
>
>  target/riscv/cpu.h  |  1 +
>  target/riscv/cpu_bits.h |  7 +++
>  target/riscv/csr.c  | 36 +++-
>  target/riscv/debug.c|  2 ++
>  4 files changed, 41 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index d74b361..e117641 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -345,6 +345,7 @@ struct CPUArchState {
>  target_ulong tdata1[RV_MAX_TRIGGERS];
>  target_ulong tdata2[RV_MAX_TRIGGERS];
>  target_ulong tdata3[RV_MAX_TRIGGERS];
> +target_ulong mcontext;
>  struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
>  struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
>  QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index ebd7917..3296648 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -361,6 +361,7 @@
>  #define CSR_TDATA2  0x7a2
>  #define CSR_TDATA3  0x7a3
>  #define CSR_TINFO   0x7a4
> +#define CSR_MCONTEXT0x7a8
>
>  /* Debug Mode Registers */
>  #define CSR_DCSR0x7b0
> @@ -905,4 +906,10 @@ typedef enum RISCVException {
>  /* JVT CSR bits */
>  #define JVT_MODE   0x3F
>  #define JVT_BASE   (~0x3F)
> +
> +/* Debug Sdtrig CSR masks */
> +#define MCONTEXT32 0x003F
> +#define MCONTEXT64 0x1FFFULL
> +#define MCONTEXT32_HCONTEXT0x007F
> +#define MCONTEXT64_HCONTEXT0x3FFFULL
>  #endif
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fde7ce1..ff1e128 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3900,6 +3900,31 @@ static RISCVException read_tinfo(CPURISCVState *env, 
> int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +static RISCVException read_mcontext(CPURISCVState *env, int csrno,
> +target_ulong *val)
> +{
> +*val = env->mcontext;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_mcontext(CPURISCVState *env, int csrno,
> + target_ulong val)
> +{
> +bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
> +int32_t mask;
> +
> +if (riscv_has_ext(env, RVH)) {
> +/* Spec suggest 7-bit for RV32 and 14-bit for RV64 w/ H extension */
> +mask = rv32 ? MCONTEXT32_HCONTEXT : MCONTEXT64_HCONTEXT;
> +} else {
> +/* Spec suggest 6-bit for RV32 and 13-bit for RV64 w/o H extension */
> +mask = rv32 ? MCONTEXT32 : MCONTEXT64;
> +}
> +
> +env->mcontext = val & mask;
> +return RISCV_EXCP_NONE;
> +}
> +
>  /*
>   * Functions to access Pointer Masking feature registers
>   * We have to check if current priv lvl could modify
> @@ -4794,11 +4819,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
>
>  /* Debug CSRs */
> -[CSR_TSELECT]   =  { "tselect", debug, read_tselect, write_tselect },
> -[CSR_TDATA1]=  { "tdata1",  debug, read_tdata,   write_tdata   },
> -[CSR_TDATA2]=  { "tdata2",  debug, read_tdata,   write_tdata   },
> -[CSR_TDATA3]=  { "tdata3",  debug, read_tdata,   write_tdata   },
> -[CSR_TINFO] =  { "tinfo",   debug, read_tinfo,   write_ignore  },
> +[CSR_TSELECT]   =  { "tselect",  debug, read_tselect,  write_tselect  },
> +[CSR_TDATA1]=  { "tdata1",   debug, read_tdata,write_tdata},
> +[CSR_TDATA2]=  { "tdata2",   debug, read_tdata,write_tdata},
> +[CSR_TDATA3]=  { "tdata3",   debug, read_tdata,write_tdata},
> +[CSR_TINFO] =  { "tinfo",debug, read_tinfo,write_ignore   },
> +[CSR_MCONTEXT]  =  { "mcontext", debug, read_mcontext, write_mcontext },
>
>  /* User Pointer Masking */
>  [CSR_UMTE]={ "umte",pointer_masking, read_umte,  write_umte 
> },
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index 4945d1a..e30d99c 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -940,4 +940,6 @@ void riscv_trigger_reset_hold(CPURISCVState *env)
>  env->cpu_watchpoint[i] = NULL;
>  timer_del(env->itrigger_timer[i]);
>  }
> +
> +env->mcontext = 0;
>  }
> --
> 2.34.1
>
>



Re: [PATCH v3 0/2] riscv: support new isa extension detection devicetree properties

2024-01-21 Thread Alistair Francis
On Wed, Jan 10, 2024 at 8:27 PM Conor Dooley  wrote:
>
> From: Conor Dooley 
>
> Making it a series to keep the standalone change to riscv_isa_string()
> that Drew reported separate.
>
> Changes in v3:
> - g_free() isa_extensions too
> - use misa_mxl_max rather than the compile target for the base isa
> - add a new patch changing riscv_isa_string() to do the same
> - drop a null check that cannot be null
> - rebased on top of Alistair's next branch

Do you mind rebasing on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next again?
There was a big re-org recently so lots of rebasing is required

Alistair

>
> Changes in v2:
> - use g_strdup() for multiletter extension string copying
> - wrap stuff in #ifndef to prevent breaking the user mode build
> - rename riscv_isa_set_props() -> riscv_isa_write_fdt()
>
> CC: Alistair Francis 
> CC: Bin Meng 
> CC: Palmer Dabbelt 
> CC: Weiwei Li 
> CC: Daniel Henrique Barboza 
> CC: Andrew Jones 
> CC: Liu Zhiwei 
> CC: qemu-ri...@nongnu.org
> CC: qemu-devel@nongnu.org
>
> Conor Dooley (2):
>   target/riscv: use misa_mxl_max to populate isa string rather than
> TARGET_LONG_BITS
>   target/riscv: support new isa extension detection devicetree
> properties
>
>  hw/riscv/sifive_u.c |  7 ++
>  hw/riscv/spike.c|  6 ++---
>  hw/riscv/virt.c |  6 ++---
>  target/riscv/cpu.c  | 57 -
>  target/riscv/cpu.h  |  1 +
>  5 files changed, 63 insertions(+), 14 deletions(-)
>
> --
> 2.39.2
>
>



Re: [PATCH v3 2/2] target/riscv: support new isa extension detection devicetree properties

2024-01-21 Thread Alistair Francis
On Wed, Jan 10, 2024 at 8:28 PM Conor Dooley  wrote:
>
> From: Conor Dooley 
>
> A few months ago I submitted a patch to various lists, deprecating
> "riscv,isa" with a lengthy commit message [0] that is now commit
> aeb71e42caae ("dt-bindings: riscv: deprecate riscv,isa") in the Linux
> kernel tree. Primarily, the goal was to replace "riscv,isa" with a new
> set of properties that allowed for strictly defining the meaning of
> various extensions, where "riscv,isa" was tied to whatever definitions
> inflicted upon us by the ISA manual, which have seen some variance over
> time.
>
> Two new properties were introduced: "riscv,isa-base" and
> "riscv,isa-extensions". The former is a simple string to communicate the
> base ISA implemented by a hart and the latter an array of strings used
> to communicate the set of ISA extensions supported, per the definitions
> of each substring in extensions.yaml [1]. A beneficial side effect was
> also the ability to define vendor extensions in a more "official" way,
> as the ISA manual and other RVI specifications only covered the format
> for vendor extensions in the ISA string, but not the meaning of vendor
> extensions, for obvious reasons.
>
> Add support for setting these two new properties in the devicetrees for
> the various devicetree platforms supported by QEMU for RISC-V. The Linux
> kernel already supports parsing ISA extensions from these new
> properties, and documenting them in the dt-binding is a requirement for
> new extension detection being added to the kernel.
>
> A side effect of the implementation is that the meaning for elements in
> "riscv,isa" and in "riscv,isa-extensions" are now tied together as they
> are constructed from the same source. The same applies to the ISA string
> provided in ACPI tables, but there does not appear to be any strict
> definitions of meanings in ACPI land either.
>
> Link: 
> https://lore.kernel.org/qemu-riscv/20230702-eats-scorebook-c951f170d29f@spud/ 
> [0]
> Link: 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/riscv/extensions.yaml
>  [1]
> Signed-off-by: Conor Dooley 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/sifive_u.c |  7 ++
>  hw/riscv/spike.c|  6 ++---
>  hw/riscv/virt.c |  6 ++---
>  target/riscv/cpu.c  | 53 +
>  target/riscv/cpu.h  |  1 +
>  5 files changed, 60 insertions(+), 13 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index ec76dce6c9..2f227f15bc 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -171,7 +171,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
> *memmap,
>  int cpu_phandle = phandle++;
>  nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
>  char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", 
> cpu);
> -char *isa;
>  qemu_fdt_add_subnode(fdt, nodename);
>  /* cpu 0 is the management hart that does not have mmu */
>  if (cpu != 0) {
> @@ -180,11 +179,10 @@ static void create_fdt(SiFiveUState *s, const 
> MemMapEntry *memmap,
>  } else {
>  qemu_fdt_setprop_string(fdt, nodename, "mmu-type", 
> "riscv,sv48");
>  }
> -isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
> +riscv_isa_write_fdt(&s->soc.u_cpus.harts[cpu - 1], fdt, 
> nodename);
>  } else {
> -isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
> +riscv_isa_write_fdt(&s->soc.e_cpus.harts[0], fdt, nodename);
>  }
> -qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
>  qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
>  qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
>  qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
> @@ -194,7 +192,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
> *memmap,
>  qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
>  qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
>  qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
> -g_free(isa);
>  g_free(intc);
>  g_free(nodename);
>  }
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index 81f7e53aed..64074395bc 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -59,7 +59,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>  MachineState *ms = MACHINE(s);
>  uint32_t *clint_cells;
>  uint32_t cpu_phandle, intc_phandle, phandle = 1;
> -char *name, *mem_name, *clint_name, *clust_name;
> +char *mem_name, *clint_name, *clust_name;
>  char *core_name, *cpu_name, *intc_name;
>  static const char * const clint_compat[2] = {
>  "sifive,clint0", "riscv,clint0"
> @@ -113,9 +113,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>  } else {
> 

Re: [PATCH v3 1/2] target/riscv: use misa_mxl_max to populate isa string rather than TARGET_LONG_BITS

2024-01-21 Thread Alistair Francis
On Wed, Jan 10, 2024 at 9:34 PM Conor Dooley  wrote:
>
> From: Conor Dooley 
>
> A cpu may not have the same xlen as the compile time target, and
> misa_mxl_max is the source of truth for what the hart supports.
>
> Reported-by: Andrew Jones 
> Link: 
> https://lore.kernel.org/qemu-riscv/20240108-efa3f83dcd3997dc0af458d7@orel/
> Signed-off-by: Conor Dooley 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Perhaps this misa_mxl_max -> width conversion should exist as a macro?
> There's now 3 individual conversions of this type - two I added and one
> in the gdb code.
> ---
>  target/riscv/cpu.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8cbfc7e781..5b5da970f2 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1860,7 +1860,9 @@ char *riscv_isa_string(RISCVCPU *cpu)
>  int i;
>  const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
>  char *isa_str = g_new(char, maxlen);
> -char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
> +int xlen = 16 << cpu->env.misa_mxl_max;
> +char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", xlen);
> +
>  for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
>  if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
>  *p++ = qemu_tolower(riscv_single_letter_exts[i]);
> --
> 2.39.2
>
>



Re: [PATCH v4 5/5] target/riscv: Implement privilege mode filtering for cycle/instret

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 10:29 AM Atish Patra  wrote:
>
> Privilege mode filtering can also be emulated for cycle/instret by
> tracking host_ticks/icount during each privilege mode switch. This
> patch implements that for both cycle/instret and mhpmcounters. The
> first one requires Smcntrpmf while the other one requires Sscofpmf
> to be enabled.
>
> The cycle/instret are still computed using host ticks when icount
> is not enabled. Otherwise, they are computed using raw icount which
> is more accurate in icount mode.
>
> Reviewed-by: Daniel Henrique Barboza 
> Signed-off-by: Atish Patra 
> ---
>  target/riscv/cpu.h| 11 +
>  target/riscv/cpu_helper.c |  9 +++-
>  target/riscv/csr.c| 95 ++-
>  target/riscv/pmu.c| 43 ++
>  target/riscv/pmu.h|  2 +
>  5 files changed, 136 insertions(+), 24 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 34617c4c4bab..40d10726155b 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -136,6 +136,15 @@ typedef struct PMUCTRState {
>  target_ulong irq_overflow_left;
>  } PMUCTRState;
>
> +typedef struct PMUFixedCtrState {
> +/* Track cycle and icount for each privilege mode */
> +uint64_t counter[4];
> +uint64_t counter_prev[4];

Are these two used?

Alistair

> +/* Track cycle and icount for each privilege mode when V = 1*/
> +uint64_t counter_virt[2];
> +uint64_t counter_virt_prev[2];
> +} PMUFixedCtrState;
> +
>  struct CPUArchState {
>  target_ulong gpr[32];
>  target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
> @@ -334,6 +343,8 @@ struct CPUArchState {
>  /* PMU event selector configured values for RV32 */
>  target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
>
> +PMUFixedCtrState pmu_fixed_ctrs[2];
> +
>  target_ulong sscratch;
>  target_ulong mscratch;
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index e7e23b34f455..3dddb1b433e8 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -715,8 +715,13 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
> newpriv)
>  {
>  g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
>
> -if (icount_enabled() && newpriv != env->priv) {
> -riscv_itrigger_update_priv(env);
> +if (newpriv != env->priv) {
> +if (icount_enabled()) {
> +riscv_itrigger_update_priv(env);
> +riscv_pmu_icount_update_priv(env, newpriv);
> +} else {
> +riscv_pmu_cycle_update_priv(env, newpriv);
> +}
>  }
>  /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>  env->priv = newpriv;
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 3bd4aa22374f..307d052021c5 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -782,32 +782,16 @@ static int write_vcsr(CPURISCVState *env, int csrno, 
> target_ulong val)
>  return RISCV_EXCP_NONE;
>  }
>
> +#if defined(CONFIG_USER_ONLY)
>  /* User Timers and Counters */
>  static target_ulong get_ticks(bool shift)
>  {
> -int64_t val;
> -target_ulong result;
> -
> -#if !defined(CONFIG_USER_ONLY)
> -if (icount_enabled()) {
> -val = icount_get();
> -} else {
> -val = cpu_get_host_ticks();
> -}
> -#else
> -val = cpu_get_host_ticks();
> -#endif
> -
> -if (shift) {
> -result = val >> 32;
> -} else {
> -result = val;
> -}
> +int64_t val = cpu_get_host_ticks();
> +target_ulong result = shift ? val >> 32 : val;
>
>  return result;
>  }
>
> -#if defined(CONFIG_USER_ONLY)
>  static RISCVException read_time(CPURISCVState *env, int csrno,
>  target_ulong *val)
>  {
> @@ -932,6 +916,70 @@ static int write_mhpmeventh(CPURISCVState *env, int 
> csrno, target_ulong val)
>  return RISCV_EXCP_NONE;
>  }
>
> +static target_ulong riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState *env,
> + int counter_idx,
> + bool upper_half)
> +{
> +uint64_t curr_val = 0;
> +target_ulong result = 0;
> +uint64_t *counter_arr = icount_enabled() ? 
> env->pmu_fixed_ctrs[1].counter :
> +env->pmu_fixed_ctrs[0].counter;
> +uint64_t *counter_arr_virt = icount_enabled() ?
> + env->pmu_fixed_ctrs[1].counter_virt :
> + env->pmu_fixed_ctrs[0].counter_virt;
> +uint64_t cfg_val = 0;
> +
> +if (counter_idx == 0) {
> +cfg_val = upper_half ? ((uint64_t)env->mcyclecfgh << 32) :
> +  env->mcyclecfg;
> +} else if (counter_idx == 2) {
> +cfg_val = upper_half ? ((uint64_t)env->minstretcfgh << 32) :
> +  env->minstretcfg;
> +} else {
> +cfg_val = upper_half ?
> +  (

Re: [PATCH v4 4/5] target/riscv: Add cycle & instret privilege mode filtering support

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 10:29 AM Atish Patra  wrote:
>
> From: Kaiwen Xue 
>
> QEMU only calculates dummy cycles and instructions, so there is no
> actual means to stop the icount in QEMU. Hence this patch merely adds
> the functionality of accessing the cfg registers, and cause no actual
> effects on the counting of cycle and instret counters.
>
> Signed-off-by: Atish Patra 
> Reviewed-by: Daniel Henrique Barboza 
> Signed-off-by: Kaiwen Xue 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 80 ++
>  1 file changed, 80 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 283468bbc652..3bd4aa22374f 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -233,6 +233,24 @@ static RISCVException sscofpmf_32(CPURISCVState *env, 
> int csrno)
>  return sscofpmf(env, csrno);
>  }
>
> +static RISCVException smcntrpmf(CPURISCVState *env, int csrno)
> +{
> +if (!riscv_cpu_cfg(env)->ext_smcntrpmf) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
> +
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException smcntrpmf_32(CPURISCVState *env, int csrno)
> +{
> +if (riscv_cpu_mxl(env) != MXL_RV32) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
> +
> +return smcntrpmf(env, csrno);
> +}
> +
>  static RISCVException any(CPURISCVState *env, int csrno)
>  {
>  return RISCV_EXCP_NONE;
> @@ -818,6 +836,54 @@ static int read_hpmcounterh(CPURISCVState *env, int 
> csrno, target_ulong *val)
>
>  #else /* CONFIG_USER_ONLY */
>
> +static int read_mcyclecfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +*val = env->mcyclecfg;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int write_mcyclecfg(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +env->mcyclecfg = val;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int read_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +*val = env->mcyclecfgh;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int write_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +env->mcyclecfgh = val;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int read_minstretcfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +*val = env->minstretcfg;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int write_minstretcfg(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +env->minstretcfg = val;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int read_minstretcfgh(CPURISCVState *env, int csrno, target_ulong 
> *val)
> +{
> +*val = env->minstretcfgh;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int write_minstretcfgh(CPURISCVState *env, int csrno, target_ulong 
> val)
> +{
> +env->minstretcfgh = val;
> +return RISCV_EXCP_NONE;
> +}
> +
>  static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
>  {
>  int evt_index = csrno - CSR_MCOUNTINHIBIT;
> @@ -4922,6 +4988,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>   write_mcountinhibit,
>   .min_priv_ver = PRIV_VERSION_1_11_0   },
>
> +[CSR_MCYCLECFG]  = { "mcyclecfg",   smcntrpmf, read_mcyclecfg,
> + write_mcyclecfg,
> + .min_priv_ver = PRIV_VERSION_1_12_0   },
> +[CSR_MINSTRETCFG]= { "minstretcfg", smcntrpmf, read_minstretcfg,
> + write_minstretcfg,
> + .min_priv_ver = PRIV_VERSION_1_12_0   },
> +
>  [CSR_MHPMEVENT3] = { "mhpmevent3", any,read_mhpmevent,
>   write_mhpmevent   },
>  [CSR_MHPMEVENT4] = { "mhpmevent4", any,read_mhpmevent,
> @@ -4981,6 +5054,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_MHPMEVENT31]= { "mhpmevent31",any,read_mhpmevent,
>   write_mhpmevent   },
>
> +[CSR_MCYCLECFGH] = { "mcyclecfgh",   smcntrpmf_32, read_mcyclecfgh,
> + write_mcyclecfgh,
> + .min_priv_ver = PRIV_VERSION_1_12_0},
> +[CSR_MINSTRETCFGH]   = { "minstretcfgh", smcntrpmf_32, read_minstretcfgh,
> + write_minstretcfgh,
> + .min_priv_ver = PRIV_VERSION_1_12_0},
> +
>  [CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf_32,  read_mhpmeventh,
>   write_mhpmeventh,
>   .min_priv_ver = PRIV_VERSION_1_12_0},
> --
> 2.34.1
>
>



Re: [PATCH v4 3/5] target/riscv: Add cycle & instret privilege mode filtering definitions

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 12:05 PM Atish Patra  wrote:
>
> From: Kaiwen Xue 
>
> This adds the definitions for ISA extension smcntrpmf.
>
> Signed-off-by: Kaiwen Xue 
> Reviewed-by: Daniel Henrique Barboza 
> Signed-off-by: Atish Patra 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h  |  6 ++
>  target/riscv/cpu_bits.h | 29 +
>  2 files changed, 35 insertions(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index d74b361be641..34617c4c4bab 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -319,6 +319,12 @@ struct CPUArchState {
>
>  target_ulong mcountinhibit;
>
> +/* PMU cycle & instret privilege mode filtering */
> +target_ulong mcyclecfg;
> +target_ulong mcyclecfgh;
> +target_ulong minstretcfg;
> +target_ulong minstretcfgh;
> +
>  /* PMU counter state */
>  PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index ebd7917d490a..0ee91e502e8f 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -401,6 +401,10 @@
>  /* Machine counter-inhibit register */
>  #define CSR_MCOUNTINHIBIT   0x320
>
> +/* Machine counter configuration registers */
> +#define CSR_MCYCLECFG   0x321
> +#define CSR_MINSTRETCFG 0x322
> +
>  #define CSR_MHPMEVENT3  0x323
>  #define CSR_MHPMEVENT4  0x324
>  #define CSR_MHPMEVENT5  0x325
> @@ -431,6 +435,9 @@
>  #define CSR_MHPMEVENT30 0x33e
>  #define CSR_MHPMEVENT31 0x33f
>
> +#define CSR_MCYCLECFGH  0x721
> +#define CSR_MINSTRETCFGH0x722
> +
>  #define CSR_MHPMEVENT3H 0x723
>  #define CSR_MHPMEVENT4H 0x724
>  #define CSR_MHPMEVENT5H 0x725
> @@ -885,6 +892,28 @@ typedef enum RISCVException {
>  /* PMU related bits */
>  #define MIE_LCOFIE (1 << IRQ_PMU_OVF)
>
> +#define MCYCLECFG_BIT_MINH BIT_ULL(62)
> +#define MCYCLECFGH_BIT_MINHBIT(30)
> +#define MCYCLECFG_BIT_SINH BIT_ULL(61)
> +#define MCYCLECFGH_BIT_SINHBIT(29)
> +#define MCYCLECFG_BIT_UINH BIT_ULL(60)
> +#define MCYCLECFGH_BIT_UINHBIT(28)
> +#define MCYCLECFG_BIT_VSINHBIT_ULL(59)
> +#define MCYCLECFGH_BIT_VSINH   BIT(27)
> +#define MCYCLECFG_BIT_VUINHBIT_ULL(58)
> +#define MCYCLECFGH_BIT_VUINH   BIT(26)
> +
> +#define MINSTRETCFG_BIT_MINH   BIT_ULL(62)
> +#define MINSTRETCFGH_BIT_MINH  BIT(30)
> +#define MINSTRETCFG_BIT_SINH   BIT_ULL(61)
> +#define MINSTRETCFGH_BIT_SINH  BIT(29)
> +#define MINSTRETCFG_BIT_UINH   BIT_ULL(60)
> +#define MINSTRETCFGH_BIT_UINH  BIT(28)
> +#define MINSTRETCFG_BIT_VSINH  BIT_ULL(59)
> +#define MINSTRETCFGH_BIT_VSINH BIT(27)
> +#define MINSTRETCFG_BIT_VUINH  BIT_ULL(58)
> +#define MINSTRETCFGH_BIT_VUINH BIT(26)
> +
>  #define MHPMEVENT_BIT_OF   BIT_ULL(63)
>  #define MHPMEVENTH_BIT_OF  BIT(31)
>  #define MHPMEVENT_BIT_MINH BIT_ULL(62)
> --
> 2.34.1
>
>



Re: [PATCH v4 2/5] target/riscv: Add cycle & instret privilege mode filtering properties

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 11:04 AM Atish Patra  wrote:
>
> From: Kaiwen Xue 
>
> This adds the properties for ISA extension smcntrpmf. Patches
> implementing it will follow.
>
> Signed-off-by: Atish Patra 
> Signed-off-by: Kaiwen Xue 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 2 ++
>  target/riscv/cpu_cfg.h | 1 +
>  2 files changed, 3 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 83c7c0cf07be..501ae560ec29 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -144,6 +144,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
>  ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
>  ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
> +ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
>  ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
>  ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
>  ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
> @@ -1296,6 +1297,7 @@ const char *riscv_get_misa_ext_description(uint32_t bit)
>  const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
>  /* Defaults for standard extensions */
>  MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
> +MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
>  MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
>  MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
>  MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index f4605fb190b9..00c34fdd3209 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -72,6 +72,7 @@ struct RISCVCPUConfig {
>  bool ext_zihpm;
>  bool ext_smstateen;
>  bool ext_sstc;
> +bool ext_smcntrpmf;
>  bool ext_svadu;
>  bool ext_svinval;
>  bool ext_svnapot;
> --
> 2.34.1
>
>



Re: [PATCH v2 1/4] smbios: add processor-family option

2024-01-21 Thread Alistair Francis
On Fri, Jan 5, 2024 at 3:44 PM Heinrich Schuchardt
 wrote:
>
> On 1/5/24 06:24, Alistair Francis wrote:
> > On Fri, Dec 29, 2023 at 10:48 PM Heinrich Schuchardt
> >  wrote:
> >>
> >> For RISC-V the SMBIOS standard requires specific values of the processor
> >> family value depending on the bitness of the CPU.
> >
> > Can you provide some details of where this is described? I can't seem to 
> > find it
> >
> > Alistair
>
> System Management BIOS (SMBIOS) Reference Specification 3.7.0 (DSP0134)
> https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.7.0.pdf
> 7.5.2 Processor Information — Processor Family
> Table 23 – Processor Information: Processor Family field
>
> 200h 512 RISC-V RV32
> 201h 513 RISC-V RV64
> 202h 514 RISC-V RV128
>
> While for other architectures values for different CPU generations have
> been defined the values for RISC-V only depend on the bitness.

Ah, I first read the commit message as saying this is RISC-V specific,
which I couldn't find in the spec.

I now realise you just mean it's important for RISC-V

Alistair

>
> Best regards
>
> Heinrich
>
> >
> >>
> >> Add a processor-family option for SMBIOS table 4.
> >>
> >> The value of processor-family may exceed 255 and therefore must be provided
> >> in the Processor Family 2 field. Set the Processor Family field to 0xFE
> >> which signals that the Processor Family 2 is used.
> >>
> >> Signed-off-by: Heinrich Schuchardt 
> >> ---
> >> v2:
> >>  new patch
> >> ---
> >>   hw/smbios/smbios.c | 13 +++--
> >>   qemu-options.hx|  4 ++--
> >>   2 files changed, 13 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> >> index 2a90601ac5..647bc6d603 100644
> >> --- a/hw/smbios/smbios.c
> >> +++ b/hw/smbios/smbios.c
> >> @@ -102,6 +102,7 @@ static struct {
> >>   #define DEFAULT_CPU_SPEED 2000
> >>
> >>   static struct {
> >> +uint16_t processor_family;
> >>   const char *sock_pfx, *manufacturer, *version, *serial, *asset, 
> >> *part;
> >>   uint64_t max_speed;
> >>   uint64_t current_speed;
> >> @@ -110,6 +111,7 @@ static struct {
> >>   .max_speed = DEFAULT_CPU_SPEED,
> >>   .current_speed = DEFAULT_CPU_SPEED,
> >>   .processor_id = 0,
> >> +.processor_family = 0x01, /* Other */
> >>   };
> >>
> >>   struct type8_instance {
> >> @@ -337,6 +339,10 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
> >>   .name = "part",
> >>   .type = QEMU_OPT_STRING,
> >>   .help = "part number",
> >> +}, {
> >> +.name = "processor-family",
> >> +.type = QEMU_OPT_NUMBER,
> >> +.help = "processor family",
> >>   }, {
> >>   .name = "processor-id",
> >>   .type = QEMU_OPT_NUMBER,
> >> @@ -726,7 +732,7 @@ static void smbios_build_type_4_table(MachineState 
> >> *ms, unsigned instance)
> >>   snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, 
> >> instance);
> >>   SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str);
> >>   t->processor_type = 0x03; /* CPU */
> >> -t->processor_family = 0x01; /* Other */
> >> +t->processor_family = 0xfe; /* use Processor Family 2 field */
> >>   SMBIOS_TABLE_SET_STR(4, processor_manufacturer_str, 
> >> type4.manufacturer);
> >>   if (type4.processor_id == 0) {
> >>   t->processor_id[0] = cpu_to_le32(smbios_cpuid_version);
> >> @@ -758,7 +764,7 @@ static void smbios_build_type_4_table(MachineState 
> >> *ms, unsigned instance)
> >>   t->thread_count = (threads_per_socket > 255) ? 0xFF : 
> >> threads_per_socket;
> >>
> >>   t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
> >> -t->processor_family2 = cpu_to_le16(0x01); /* Other */
> >> +t->processor_family2 = cpu_to_le16(type4.processor_family);
> >>
> >>   if (tbl_len == SMBIOS_TYPE_4_LEN_V30) {
> >>   t->core_count2 = t->core_enabled2 = 
> >> cpu_to_le16(cores_per_socket);
> >> @@ -1402,6 +1408,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> >>   return;
> >>   }
> >>   save_opt(&type4.sock_pfx, opts, "sock_pfx");
> >> +type4.processor_family = qemu_opt_get_number(opts,
> >> + 
> >> "processor-family",
> >> + 0x01 /* Other 
> >> */);
> >>   save_opt(&type4.manufacturer, opts, "manufacturer");
> >>   save_opt(&type4.version, opts, "version");
> >>   save_opt(&type4.serial, opts, "serial");
> >> diff --git a/qemu-options.hx b/qemu-options.hx
> >> index b66570ae00..7bdb414345 100644
> >> --- a/qemu-options.hx
> >> +++ b/qemu-options.hx
> >> @@ -2694,7 +2694,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
> >>   "specify SMBIOS type 3 fields\n"
> >>   "-smbios 
> >> type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str]\n"
> >>   "  
> >> [,

Re: [PATCH v2 1/4] smbios: add processor-family option

2024-01-21 Thread Alistair Francis
On Fri, Dec 29, 2023 at 10:48 PM Heinrich Schuchardt
 wrote:
>
> For RISC-V the SMBIOS standard requires specific values of the processor
> family value depending on the bitness of the CPU.
>
> Add a processor-family option for SMBIOS table 4.
>
> The value of processor-family may exceed 255 and therefore must be provided
> in the Processor Family 2 field. Set the Processor Family field to 0xFE
> which signals that the Processor Family 2 is used.
>
> Signed-off-by: Heinrich Schuchardt 

Reviewed-by: Alistair Francis 

Alistair

> ---
> v2:
> new patch
> ---
>  hw/smbios/smbios.c | 13 +++--
>  qemu-options.hx|  4 ++--
>  2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 2a90601ac5..647bc6d603 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -102,6 +102,7 @@ static struct {
>  #define DEFAULT_CPU_SPEED 2000
>
>  static struct {
> +uint16_t processor_family;
>  const char *sock_pfx, *manufacturer, *version, *serial, *asset, *part;
>  uint64_t max_speed;
>  uint64_t current_speed;
> @@ -110,6 +111,7 @@ static struct {
>  .max_speed = DEFAULT_CPU_SPEED,
>  .current_speed = DEFAULT_CPU_SPEED,
>  .processor_id = 0,
> +.processor_family = 0x01, /* Other */
>  };
>
>  struct type8_instance {
> @@ -337,6 +339,10 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
>  .name = "part",
>  .type = QEMU_OPT_STRING,
>  .help = "part number",
> +}, {
> +.name = "processor-family",
> +.type = QEMU_OPT_NUMBER,
> +.help = "processor family",
>  }, {
>  .name = "processor-id",
>  .type = QEMU_OPT_NUMBER,
> @@ -726,7 +732,7 @@ static void smbios_build_type_4_table(MachineState *ms, 
> unsigned instance)
>  snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance);
>  SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str);
>  t->processor_type = 0x03; /* CPU */
> -t->processor_family = 0x01; /* Other */
> +t->processor_family = 0xfe; /* use Processor Family 2 field */
>  SMBIOS_TABLE_SET_STR(4, processor_manufacturer_str, type4.manufacturer);
>  if (type4.processor_id == 0) {
>  t->processor_id[0] = cpu_to_le32(smbios_cpuid_version);
> @@ -758,7 +764,7 @@ static void smbios_build_type_4_table(MachineState *ms, 
> unsigned instance)
>  t->thread_count = (threads_per_socket > 255) ? 0xFF : threads_per_socket;
>
>  t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
> -t->processor_family2 = cpu_to_le16(0x01); /* Other */
> +t->processor_family2 = cpu_to_le16(type4.processor_family);
>
>  if (tbl_len == SMBIOS_TYPE_4_LEN_V30) {
>  t->core_count2 = t->core_enabled2 = cpu_to_le16(cores_per_socket);
> @@ -1402,6 +1408,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
>  return;
>  }
>  save_opt(&type4.sock_pfx, opts, "sock_pfx");
> +type4.processor_family = qemu_opt_get_number(opts,
> + "processor-family",
> + 0x01 /* Other */);
>  save_opt(&type4.manufacturer, opts, "manufacturer");
>  save_opt(&type4.version, opts, "version");
>  save_opt(&type4.serial, opts, "serial");
> diff --git a/qemu-options.hx b/qemu-options.hx
> index b66570ae00..7bdb414345 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2694,7 +2694,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
>  "specify SMBIOS type 3 fields\n"
>  "-smbios 
> type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str]\n"
>  "  
> [,asset=str][,part=str][,max-speed=%d][,current-speed=%d]\n"
> -"  [,processor-id=%d]\n"
> +"  [,processor-family=%d,processor-id=%d]\n"
>  "specify SMBIOS type 4 fields\n"
>  "-smbios 
> type=8[,external_reference=str][,internal_reference=str][,connector_type=%d][,port_type=%d]\n"
>  "specify SMBIOS type 8 fields\n"
> @@ -2722,7 +2722,7 @@ SRST
>  ``-smbios 
> type=3[,manufacturer=str][,version=str][,serial=str][,asset=str][,sku=str]``
>  Specify SMBIOS type 3 fields
>
> -``-smbios 
> type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str][,asset=str][,part=str][,processor-id=%d]``
> +``-smbios 
> type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str][,asset=str][,part=str][,processor-family=%d][,processor-id=%d]``
>  Specify SMBIOS type 4 fields
>
>  ``-smbios type=11[,value=str][,path=filename]``
> --
> 2.43.0
>
>



[PATCH] hw/ufs: Raise interrupt on UIC power mode change

2024-01-21 Thread Jeuk Kim
This patch allows the qemu ufs to raise an interrupt on
the DME_SET (PA_PWRMODE) command.

Signed-off-by: Jeuk Kim 
---
 hw/ufs/ufs.c| 15 ++-
 include/block/ufs.h | 65 +
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index eccdb852a0..e95f732a9f 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -301,6 +301,19 @@ static void ufs_process_uiccmd(UfsHc *u, uint32_t val)
  * are implemented.
  */
 switch (val) {
+case UFS_UIC_CMD_DME_SET:
+if (FIELD_EX32(u->reg.ucmdarg1, UCMDARG1, MIBattribute) ==
+UFS_UNIPRO_PA_PWRMODE) {
+u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, UPMCRS, UFS_PWR_LOCAL);
+u->reg.is = FIELD_DP32(u->reg.is, IS, UPMS, 1);
+}
+u->reg.ucmdarg2 = UFS_UIC_CMD_RESULT_SUCCESS;
+break;
+case UFS_UIC_CMD_DME_GET:
+case UFS_UIC_CMD_DME_PEER_GET:
+case UFS_UIC_CMD_DME_PEER_SET:
+u->reg.ucmdarg2 = UFS_UIC_CMD_RESULT_SUCCESS;
+break;
 case UFS_UIC_CMD_DME_LINK_STARTUP:
 u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, DP, 1);
 u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, UTRLRDY, 1);
@@ -434,7 +447,6 @@ static const MemoryRegionOps ufs_mmio_ops = {
 },
 };
 
-
 void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
uint8_t response, uint8_t scsi_status,
uint16_t data_segment_length)
@@ -1237,6 +1249,7 @@ static void ufs_init_hc(UfsHc *u)
 u->geometry_desc.supported_memory_types = cpu_to_be16(0x8001);
 
 memset(&u->attributes, 0, sizeof(u->attributes));
+u->attributes.current_power_mode = 0x11; /* Active Power Mode */
 u->attributes.max_data_in_size = 0x08;
 u->attributes.max_data_out_size = 0x08;
 u->attributes.ref_clk_freq = 0x01; /* 26 MHz */
diff --git a/include/block/ufs.h b/include/block/ufs.h
index d61598b8f3..fe2f2ce944 100644
--- a/include/block/ufs.h
+++ b/include/block/ufs.h
@@ -125,6 +125,8 @@ REG32(UTMRLCLR, offsetof(UfsReg, utmrlclr))
 REG32(UTMRLRSR, offsetof(UfsReg, utmrlrsr))
 REG32(UICCMD, offsetof(UfsReg, uiccmd))
 REG32(UCMDARG1, offsetof(UfsReg, ucmdarg1))
+FIELD(UCMDARG1, GenSelectorIndex, 0, 16)
+FIELD(UCMDARG1, MIBattribute, 16, 16)
 REG32(UCMDARG2, offsetof(UfsReg, ucmdarg2))
 REG32(UCMDARG3, offsetof(UfsReg, ucmdarg3))
 REG32(CCAP, offsetof(UfsReg, ccap))
@@ -1064,6 +1066,69 @@ typedef struct QEMU_PACKED UtpUpiuRsp {
 };
 } UtpUpiuRsp;
 
+/*
+ * PHY Adapter attributes
+ */
+#define UFS_UNIPRO_PA_PHY_TYPE 0x1500
+#define UFS_UNIPRO_PA_AVAILTXDATALANES 0x1520
+#define UFS_UNIPRO_PA_MAXTXSPEEDFAST 0x1521
+#define UFS_UNIPRO_PA_MAXTXSPEEDSLOW 0x1522
+#define UFS_UNIPRO_PA_MAXRXSPEEDFAST 0x1541
+#define UFS_UNIPRO_PA_MAXRXSPEEDSLOW 0x1542
+#define UFS_UNIPRO_PA_TXLINKSTARTUPHS 0x1544
+#define UFS_UNIPRO_PA_AVAILRXDATALANES 0x1540
+#define UFS_UNIPRO_PA_MINRXTRAILINGCLOCKS 0x1543
+#define UFS_UNIPRO_PA_LOCAL_TX_LCC_ENABLE 0x155E
+#define UFS_UNIPRO_PA_ACTIVETXDATALANES 0x1560
+#define UFS_UNIPRO_PA_CONNECTEDTXDATALANES 0x1561
+#define UFS_UNIPRO_PA_TXFORCECLOCK 0x1562
+#define UFS_UNIPRO_PA_TXPWRMODE 0x1563
+#define UFS_UNIPRO_PA_TXTRAILINGCLOCKS 0x1564
+#define UFS_UNIPRO_PA_TXSPEEDFAST 0x1565
+#define UFS_UNIPRO_PA_TXSPEEDSLOW 0x1566
+#define UFS_UNIPRO_PA_TXPWRSTATUS 0x1567
+#define UFS_UNIPRO_PA_TXGEAR 0x1568
+#define UFS_UNIPRO_PA_TXTERMINATION 0x1569
+#define UFS_UNIPRO_PA_HSSERIES 0x156A
+#define UFS_UNIPRO_PA_LEGACYDPHYESCDL 0x1570
+#define UFS_UNIPRO_PA_PWRMODE 0x1571
+#define UFS_UNIPRO_PA_ACTIVERXDATALANES 0x1580
+#define UFS_UNIPRO_PA_CONNECTEDRXDATALANES 0x1581
+#define UFS_UNIPRO_PA_RXPWRSTATUS 0x1582
+#define UFS_UNIPRO_PA_RXGEAR 0x1583
+#define UFS_UNIPRO_PA_RXTERMINATION 0x1584
+#define UFS_UNIPRO_PA_MAXRXPWMGEAR 0x1586
+#define UFS_UNIPRO_PA_MAXRXHSGEAR 0x1587
+#define UFS_UNIPRO_PA_PACPREQTIMEOUT 0x1590
+#define UFS_UNIPRO_PA_PACPREQEOBTIMEOUT 0x1591
+#define UFS_UNIPRO_PA_REMOTEVERINFO 0x15A0
+#define UFS_UNIPRO_PA_LOGICALLANEMAP 0x15A1
+#define UFS_UNIPRO_PA_SLEEPNOCONFIGTIME 0x15A2
+#define UFS_UNIPRO_PA_STALLNOCONFIGTIME 0x15A3
+#define UFS_UNIPRO_PA_SAVECONFIGTIME 0x15A4
+#define UFS_UNIPRO_PA_RXHSUNTERMCAP 0x15A5
+#define UFS_UNIPRO_PA_RXLSTERMCAP 0x15A6
+#define UFS_UNIPRO_PA_HIBERN8TIME 0x15A7
+#define UFS_UNIPRO_PA_LOCALVERINFO 0x15A9
+#define UFS_UNIPRO_PA_GRANULARITY 0x15AA
+#define UFS_UNIPRO_PA_TACTIVATE 0x15A8
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA0 0x15B0
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA1 0x15B1
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA2 0x15B2
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA3 0x15B3
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA4 0x15B4
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA5 0x15B5
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA6 0x15B6
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA7 0x15B7
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA8 0x15B8
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA9 0x15B9
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA10 0x15BA
+#d

Re: [PATCH 2/7] Add an internal clock multiplexer object

2024-01-21 Thread Alistair Francis
On Sat, Jan 13, 2024 at 8:31 PM Arnaud Minier
 wrote:
>
> Signed-off-by: Arnaud Minier 
> Signed-off-by: Inès Varhol 

Acked-by: Alistair Francis 

Alistair

> ---
>  hw/misc/stm32l4x5_rcc.c   | 154 ++
>  hw/misc/trace-events  |   5 +
>  include/hw/misc/stm32l4x5_rcc.h   | 119 +
>  include/hw/misc/stm32l4x5_rcc_internals.h |  29 
>  4 files changed, 307 insertions(+)
>
> diff --git a/hw/misc/stm32l4x5_rcc.c b/hw/misc/stm32l4x5_rcc.c
> index 5a6f475740..bcc69510b0 100644
> --- a/hw/misc/stm32l4x5_rcc.c
> +++ b/hw/misc/stm32l4x5_rcc.c
> @@ -35,6 +35,128 @@
>  #define LSE_FRQ 32768ULL
>  #define LSI_FRQ 32000ULL
>
> +static void clock_mux_update(RccClockMuxState *mux)
> +{
> +uint64_t src_freq, old_freq, freq;
> +
> +src_freq = clock_get_hz(mux->srcs[mux->src]);
> +old_freq = clock_get_hz(mux->out);
> +
> +if (!mux->enabled || !mux->divider) {
> +freq = 0;
> +} else {
> +freq = muldiv64(src_freq, mux->multiplier, mux->divider);
> +}
> +
> +/* No change, early return to avoid log spam and useless propagation */
> +if (old_freq == freq) {
> +return;
> +}
> +
> +clock_update_hz(mux->out, freq);
> +trace_stm32l4x5_rcc_mux_update(mux->id, mux->src, src_freq, freq);
> +}
> +
> +static void clock_mux_src_update(void *opaque, ClockEvent event)
> +{
> +RccClockMuxState **backref = opaque;
> +RccClockMuxState *s = *backref;
> +/*
> + * The backref value is equal to:
> + * s->backref + (sizeof(RccClockMuxState *) * update_src).
> + * By subtracting we can get back the index of the updated clock.
> + */
> +const uint32_t update_src = backref - s->backref;
> +/* Only update if the clock that was updated is the current source*/
> +if (update_src == s->src) {
> +clock_mux_update(s);
> +}
> +}
> +
> +static void clock_mux_init(Object *obj)
> +{
> +RccClockMuxState *s = RCC_CLOCK_MUX(obj);
> +size_t i;
> +
> +for (i = 0; i < RCC_NUM_CLOCK_MUX_SRC; i++) {
> +char *name = g_strdup_printf("srcs[%zu]", i);
> +s->backref[i] = s;
> +s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
> +clock_mux_src_update,
> +&s->backref[i],
> +ClockUpdate);
> +g_free(name);
> +}
> +
> +s->out = qdev_init_clock_out(DEVICE(s), "out");
> +}
> +
> +static void clock_mux_reset_hold(Object *obj)
> +{ }
> +
> +static const VMStateDescription clock_mux_vmstate = {
> +.name = TYPE_RCC_CLOCK_MUX,
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_ARRAY_CLOCK(srcs, RccClockMuxState,
> +RCC_NUM_CLOCK_MUX_SRC),
> +VMSTATE_BOOL(enabled, RccClockMuxState),
> +VMSTATE_UINT32(src, RccClockMuxState),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
> +static void clock_mux_class_init(ObjectClass *klass, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(klass);
> +ResettableClass *rc = RESETTABLE_CLASS(klass);
> +
> +rc->phases.hold = clock_mux_reset_hold;
> +dc->vmsd = &clock_mux_vmstate;
> +}
> +
> +static void clock_mux_set_enable(RccClockMuxState *mux, bool enabled)
> +{
> +if (mux->enabled == enabled) {
> +return;
> +}
> +
> +if (enabled) {
> +trace_stm32l4x5_rcc_mux_enable(mux->id);
> +} else {
> +trace_stm32l4x5_rcc_mux_disable(mux->id);
> +}
> +
> +mux->enabled = enabled;
> +clock_mux_update(mux);
> +}
> +
> +static void clock_mux_set_factor(RccClockMuxState *mux,
> + uint32_t multiplier, uint32_t divider)
> +{
> +if (mux->multiplier == multiplier && mux->divider == divider) {
> +return;
> +}
> +trace_stm32l4x5_rcc_mux_set_factor(mux->id,
> +mux->multiplier, multiplier, mux->divider, divider);
> +
> +mux->multiplier = multiplier;
> +mux->divider = divider;
> +clock_mux_update(mux);
> +}
> +
> +static void clock_mux_set_source(RccClockMuxState *mux, RccClockMuxSource 
> src)
> +{
> +if (mux->src == src) {
> +return;
> +}
> +
> +trace_stm32l4x5_rcc_mux_set_src(mux->id, mux->src, src);
> +mux->src = src;
> +clock_mux_update(mux);
> +}
> +
>  static void rcc_update_irq(Stm32l4x5RccState *s)
>  {
>  if (s->cifr & CIFR_IRQ_MASK) {
> @@ -326,6 +448,7 @@ static const ClockPortInitArray stm32l4x5_rcc_clocks = {
>  static void stm32l4x5_rcc_init(Object *obj)
>  {
>  Stm32l4x5RccState *s = STM32L4X5_RCC(obj);
> +size_t i;
>
>  sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
>
> @@ -335,6 +458,14 @@ static void stm32l4x5_rcc_init(Object *obj)
>
>  qdev_init_clocks(DEVICE(s), stm32l4x5_rcc_clocks);
>
> +for (i = 0; i < RCC_NUM_CLOCK_MUX; i++) {
> +
> +object_initialize_child(obj, "clock[*]",
> +   

Re: [PATCH 1/7] Implement STM32L4x5_RCC skeleton

2024-01-21 Thread Alistair Francis
On Sat, Jan 13, 2024 at 8:30 PM Arnaud Minier
 wrote:
>
> Signed-off-by: Arnaud Minier 
> Signed-off-by: Inès Varhol 
> ---
>  MAINTAINERS   |   5 +-
>  docs/system/arm/b-l475e-iot01a.rst|   2 +-
>  hw/arm/Kconfig|   1 +
>  hw/arm/stm32l4x5_soc.c|  12 +-
>  hw/misc/Kconfig   |   3 +
>  hw/misc/meson.build   |   1 +
>  hw/misc/stm32l4x5_rcc.c   | 429 ++
>  hw/misc/trace-events  |   4 +
>  include/hw/arm/stm32l4x5_soc.h|   2 +
>  include/hw/misc/stm32l4x5_rcc.h   |  80 
>  include/hw/misc/stm32l4x5_rcc_internals.h | 286 +++
>  11 files changed, 822 insertions(+), 3 deletions(-)
>  create mode 100644 hw/misc/stm32l4x5_rcc.c
>  create mode 100644 include/hw/misc/stm32l4x5_rcc.h
>  create mode 100644 include/hw/misc/stm32l4x5_rcc_internals.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b406fb20c0..c4085c32a7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1128,7 +1128,10 @@ M: Inès Varhol 
>  L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/stm32l4x5_soc.c
> -F: include/hw/arm/stm32l4x5_soc.h
> +F: hw/misc/stm32l4x5_exti.c
> +F: hw/misc/stm32l4x5_syscfg.c
> +F: hw/misc/stm32l4x5_rcc.c
> +F: include/hw/*/stm32l4x5_*.h
>
>  B-L475E-IOT01A IoT Node
>  M: Arnaud Minier 
> diff --git a/docs/system/arm/b-l475e-iot01a.rst 
> b/docs/system/arm/b-l475e-iot01a.rst
> index 1a021b306a..b857a56ca4 100644
> --- a/docs/system/arm/b-l475e-iot01a.rst
> +++ b/docs/system/arm/b-l475e-iot01a.rst
> @@ -17,13 +17,13 @@ Currently B-L475E-IOT01A machine's only supports the 
> following devices:
>  - Cortex-M4F based STM32L4x5 SoC
>  - STM32L4x5 EXTI (Extended interrupts and events controller)
>  - STM32L4x5 SYSCFG (System configuration controller)
> +- STM32L4x5 RCC (Reset and clock control)
>
>  Missing devices
>  """
>
>  The B-L475E-IOT01A does *not* support the following devices:
>
> -- Reset and clock control (RCC)
>  - Serial ports (UART)
>  - General-purpose I/Os (GPIO)
>  - Analog to Digital Converter (ADC)
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index bb4693bfbb..6bd7ba424f 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -461,6 +461,7 @@ config STM32L4X5_SOC
>  select OR_IRQ
>  select STM32L4X5_SYSCFG
>  select STM32L4X5_EXTI
> +select STM32L4X5_RCC
>
>  config XLNX_ZYNQMP_ARM
>  bool
> diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
> index 431f982caf..2538165af6 100644
> --- a/hw/arm/stm32l4x5_soc.c
> +++ b/hw/arm/stm32l4x5_soc.c
> @@ -75,6 +75,8 @@ static const int exti_irq[NUM_EXTI_IRQ] = {
>  1,  /* PVM4 wakeup */
>  78  /* LCD wakeup, Direct  */
>  };
> +#define RCC_BASE_ADDRESS 0x40021000
> +#define RCC_IRQ 5
>
>  static void stm32l4x5_soc_initfn(Object *obj)
>  {
> @@ -85,6 +87,7 @@ static void stm32l4x5_soc_initfn(Object *obj)
>
>  s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
>  s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);

New line here

> +object_initialize_child(obj, "rcc", &s->rcc, TYPE_STM32L4X5_RCC);
>  }
>
>  static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
> @@ -183,6 +186,14 @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, 
> Error **errp)
>qdev_get_gpio_in(DEVICE(&s->exti), i));
>  }
>
> +/* RCC device */
> +busdev = SYS_BUS_DEVICE(&s->rcc);
> +if (!sysbus_realize(busdev, errp)) {
> +return;
> +}
> +sysbus_mmio_map(busdev, 0, RCC_BASE_ADDRESS);
> +sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, RCC_IRQ));
> +
>  /* APB1 BUS */
>  create_unimplemented_device("TIM2",  0x4000, 0x400);
>  create_unimplemented_device("TIM3",  0x4400, 0x400);
> @@ -245,7 +256,6 @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, 
> Error **errp)
>  create_unimplemented_device("DMA1",  0x4002, 0x400);
>  create_unimplemented_device("DMA2",  0x40020400, 0x400);
>  /* RESERVED:0x40020800, 0x800 */
> -create_unimplemented_device("RCC",   0x40021000, 0x400);
>  /* RESERVED:0x40021400, 0xC00 */
>  create_unimplemented_device("FLASH", 0x40022000, 0x400);
>  /* RESERVED:0x40022400, 0xC00 */
> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> index 4fc6b29b43..727386fa4b 100644
> --- a/hw/misc/Kconfig
> +++ b/hw/misc/Kconfig
> @@ -93,6 +93,9 @@ config STM32L4X5_EXTI
>  config STM32L4X5_SYSCFG
>  bool
>
> +config STM32L4X5_RCC
> +bool
> +
>  config MIPS_ITU
>  bool
>
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index 2ca2ce4b62..1db9d31f80 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -112,6 +112,7 @@ system_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
> files('stm32f4xx_syscfg.

Re: [PATCH rfcv1 00/23] intel_iommu: Enable stage-1 translation

2024-01-21 Thread Jason Wang
On Mon, Jan 15, 2024 at 6:39 PM Zhenzhong Duan  wrote:
>
> Hi,
>
> This series enables stage-1 translation support in intel iommu which
> we called "modern" mode. In this mode, we don't do shadowing of
> guest page table for passthrough device but pass stage-1 page table
> to host side to construct a nested domain; we also support emulated
> device by translating the stage-1 page table. There was some effort
> to enable this feature in old days, see [1] for details.
>
> The key design is to utilize the dual-stage IOMMU translation
> (also known as IOMMU nested translation) capability in host IOMMU.
> As the below diagram shows, guest I/O page table pointer in GPA
> (guest physical address) is passed to host and be used to perform
> the stage-1 address translation. Along with it, modifications to
> present mappings in the guest I/O page table should be followed
> with an IOTLB invalidation.
>
> .-.  .---.
> |   vIOMMU|  | Guest I/O page table  |
> | |  '---'
> ./
> | PASID Entry |--- PASID cache flush --+
> '-'|
> | |V
> | |   I/O page table pointer in GPA
> '-'
> Guest
> --| Shadow |---|
>   vv   v
> Host
> .-.  ..
> |   pIOMMU|  |  FS for GIOVA->GPA |
> | |  ''
> ./  |
> | PASID Entry | V (Nested xlate)
> '\.--.
> | |   | SS for GPA->HPA, unmanaged domain|
> | |   '--'
> '-'
> Where:
>  - FS = First stage page tables
>  - SS = Second stage page tables
> 
>
> There are some interactions between VFIO and vIOMMU.
> * vIOMMU registers PCIIOMMUOps to PCI subsystem which VFIO can
>   use to registers/unregisters IOMMUDevice object.
> * VFIO registers an IOMMUFDDevice object at vfio device realize
>   stage to vIOMMU, this is implemented as a prerequisite series[2].
> * vIOMMU calls IOMMUFDDevice interface callback IOMMUFDDeviceOps
>   to bind/unbind device to IOMMUFD backed domains, either nested
>   domain or not.
>
> See below diagram:
>
> VFIO Device Intel IOMMU
> .-. .---.
> | | |   |
> |   .-|PCIIOMMUOps  |.-.|
> |   | IOMMUFD |(set_iommu_device)   || IOMMUFD ||
> |   | Device  |>|| Device list ||
> |   .-|(unset_iommu_device) |.-.|
> | | |   |   |
> | | |   V   |
> |   .-| IOMMUFDDeviceOps|  .-.  |
> |   | IOMMUFD |(attach_hwpt)|  | IOMMUFD |  |
> |   | link|<|  | Device  |  |
> |   .-|(detach_hwpt)|  .-.  |
> | | |   |   |
> | | |   ... |
> .-. .---.
>
> Based on Yi's suggestion, we updated a new design of managing ioas and
> hwpt, made it support multiple iommufd objects and the ERRATA_772415
> case, meanwhile tried to be optimal to share ioas and hwpt whenever
> possible.
>
> Stage-2 page table could be shared by different devices if there is
> no conflict and devices link to same iommufd object, i.e. devices
> under same host IOMMU can share same stage-2 page table. If there
> is conflict, i.e. there is one device under non cache coherency
> mode which is different from others, it requires a seperate
> stage-2 page table in non-CC mode.
>
> SPR platform has ERRATA_772415 which requires no readonly mappings
> in stage-2 page table. This series supports creating VTDIOASContainer
> with no readonly mappings. I'm not clear if there is a rare case that
> some IOMMUs on a multiple IOMMUs host have ERRATA_772415, this design
> can survive even in that case.
>
> See below example diagram for a full view:
>
>   IntelIOMMUState
>  |
>  V
> .--..--..---.
> | VTDIOASContainer |--->| VTDIOASContainer |--->| VTDIOASContainer  
> |-->...
> | (iommufd0,RW&RO) || (iommufd1,RW&RO) || (iommufd0,RW only)|
> .--..--..--

[PATCH v2] qemu-docs: Update options for graphical frontends

2024-01-21 Thread Yihuan Pan
The command line options `-ctrl-grab` and `-alt-grab` have been removed
in QEMU 7.1. Instead, use the `-display sdl,grab-mod=` option
to specify the grab modifiers.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2103
Signed-off-by: Yihuan Pan 
---
 docs/system/keys.rst.inc | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/docs/system/keys.rst.inc b/docs/system/keys.rst.inc
index bd9b8e5f6f..2e2c97aa23 100644
--- a/docs/system/keys.rst.inc
+++ b/docs/system/keys.rst.inc
@@ -1,8 +1,9 @@
-During the graphical emulation, you can use special key combinations to
-change modes. The default key mappings are shown below, but if you use
-``-alt-grab`` then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt)
-and if you use ``-ctrl-grab`` then the modifier is the right Ctrl key
-(instead of Ctrl-Alt):
+During the graphical emulation, you can use special key combinations from
+the following table to change modes. By default the modifier is Ctrl-Alt
+(used in the table below) which can be changed with ``-display`` suboption
+``mod=`` where appropriate. For example, ``-display sdl,
+grab-mod=lshift-lctrl-lalt`` changes the modifier key to Ctrl-Alt-Shift,
+while ``-display sdl,grab-mod=rctrl`` changes it to the right Ctrl key.
 
 Ctrl-Alt-f
Toggle full screen
-- 
2.43.0




Re: [PATCH] virtio-net: correctly copy vnet header when flushing TX

2024-01-21 Thread Jason Wang
On Sat, Jan 20, 2024 at 6:42 PM Michael Tokarev  wrote:
>
> 02.01.2024 06:29, Jason Wang :
> > When HASH_REPORT is negotiated, the guest_hdr_len might be larger than
> > the size of the mergeable rx buffer header. Using
> > virtio_net_hdr_mrg_rxbuf during the header swap might lead a stack
> > overflow in this case. Fixing this by using virtio_net_hdr_v1_hash
> > instead.
> >
> > Reported-by: Xiao Lei 
> > Cc: Yuri Benditovich 
> > Cc: qemu-sta...@nongnu.org
> > Cc: Mauro Matteo Cascella 
> > Fixes: CVE-2023-6693
> > Fixes: e22f0603fb2f ("virtio-net: reference implementation of hash report")
> > Signed-off-by: Jason Wang 
>
> Hi!  Can we get this to master before Jan-27 please, so it's included in 
> 8.2.1?

I think it will be.

Thanks

>
> Thanks!
>
> /mjt
>




Re: [PATCH] MAINTAINERS: Drop myself as VT-d maintainers

2024-01-21 Thread Jason Wang
On Thu, Jan 18, 2024 at 5:10 PM  wrote:
>
> From: Peter Xu 
>
> Due to my own limitation on bandwidth, I noticed that unfortunately I won't
> have time to review VT-d patches at least in the near future.  Meanwhile I
> expect a lot of possibilities could actually happen in this area in the
> near future.
>
> To reflect that reality, I decided to drop myself from the VT-d role.  It
> shouldn't affect much since we still have Jason around like usual, and
> Michael on top.  But I assume it'll always be good if anyone would like to
> fill this role up.
>
> I'll still work on QEMU.  So I suppose anyone can still copy me if one
> thinks essential.
>
> Cc: Michael S. Tsirkin 
> Cc: Jason Wang 
> Signed-off-by: Peter Xu 

Thanks a lot for the work for vtd.

Acked-by: Jason Wang 

Thanks




Re: [PATCH v2 0/2] riscv: add rv32i,rv32e and rv64e CPUs

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 3:40 AM Daniel Henrique Barboza
 wrote:
>
> Hi,
>
> This is the second version of a buried patch series:
>
> "[PATCH for-9.0 0/6] riscv: rv32i,rv32e,rv64i and rv64e CPUs"
>
> This version shrank to 2 patches since most of the prep work was already
> done by the RVA22 profile implementation, which is now queued in
> riscv-to-apply.next.
>
> The motivation is the same as in v1 - give users a cleaner way of using
> a customized CPU, from scratch, without the need to disable default
> extensions.
>
> Patches based on Alistair's riscv-to-apply.next.
>
> Changes from v1:
> - patches 1 to 4 from v1: dropped
> - patches 5 and 6 from v1: merged into patch 2
> - patch 1 (new):
>   - add a new common cpu_init() for all bare CPUs
> - v1 link: 
> https://lore.kernel.org/qemu-riscv/20231113213904.185320-1-dbarb...@ventanamicro.com/
>
>
> Daniel Henrique Barboza (2):
>   target/riscv/cpu.c: add riscv_bare_cpu_init()
>   target/riscv: add rv32i, rv32e and rv64e CPUs

Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next ?

Alistai

>
>  target/riscv/cpu-qom.h |  3 ++
>  target/riscv/cpu.c | 64 --
>  2 files changed, 52 insertions(+), 15 deletions(-)
>
> --
> 2.43.0
>
>



Re: [PATCH v3 00/13] target/riscv: add 'cpu->cfg.vlenb', remove 'cpu->cfg.vlen'

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:41 AM Daniel Henrique Barboza
 wrote:
>
> Hi,
>
> In this v3 the most significant change is with vext_get_vlmax() from
> cpu.h. The logic used in this function is also used in at least two
> other places, trans_vrgather_vi() and trans_vrgather_vx(), and we need
> to make changes in them to remove 'vlen' occurrences.
>
> Instead, we're adding an extra patch (11) to rework vext_get_vlmax()
> arguments to make the function usable in trans_vrgather_v*(). This
> rework includes some naming changes in local variables - we're using
> 'vsew' and 'vlmul' more often to be less ambiguous when reading code.
>
> Series based on Alistair's riscv-to-apply.next.
>
> Patches missing review: patches 10, 11, 12.
>
> Changes from v3:
> - patch 8:
>   - changed fractional LMUL comment to show the expansion
> - patches 9 and 10: switched places
> - patch 10 (former 9):
>   - use 'vlen' in vext_get_vlmax() to avoid a negative shift
> - patch 11 (new):
>   - change vext_get_vlmax() to use 'vlenb', 'vsew' and 'lmul'
> - patch 12 (former 11):
>   - use vext_get_vlmax() instead of calculating vlmax manually
> - v2 link: 
> https://lore.kernel.org/qemu-riscv/20240115222528.257342-1-dbarb...@ventanamicro.com/
>
>
> Daniel Henrique Barboza (13):
>   target/riscv: add 'vlenb' field in cpu->cfg
>   target/riscv/csr.c: use 'vlenb' instead of 'vlen'
>   target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'
>   target/riscv/insn_trans/trans_rvbf16.c.inc: use cpu->cfg.vlenb
>   target/riscv/insn_trans/trans_rvv.c.inc: use 'vlenb'
>   target/riscv/insn_trans/trans_rvvk.c.inc: use 'vlenb'
>   target/riscv/vector_helper.c: use 'vlenb'
>   target/riscv/vector_helper.c: use vlenb in HELPER(vsetvl)
>   target/riscv/insn_trans/trans_rvv.c.inc: use 'vlenb' in MAXSZ()
>   target/riscv/cpu.h: use 'vlenb' in vext_get_vlmax()
>   target/riscv: change vext_get_vlmax() arguments
>   trans_rvv.c.inc: use vext_get_vlmax() in trans_vrgather_v*()
>   target/riscv/cpu.c: remove cpu->cfg.vlen

Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next ?

Alistair

>
>  target/riscv/cpu.c |  12 +-
>  target/riscv/cpu.h |  14 +-
>  target/riscv/cpu_cfg.h |   2 +-
>  target/riscv/cpu_helper.c  |  11 +-
>  target/riscv/csr.c |   4 +-
>  target/riscv/gdbstub.c |   6 +-
>  target/riscv/insn_trans/trans_rvbf16.c.inc |  12 +-
>  target/riscv/insn_trans/trans_rvv.c.inc| 152 ++---
>  target/riscv/insn_trans/trans_rvvk.c.inc   |  16 +--
>  target/riscv/tcg/tcg-cpu.c |   4 +-
>  target/riscv/vector_helper.c   |  43 +++---
>  11 files changed, 148 insertions(+), 128 deletions(-)
>
> --
> 2.43.0
>
>



Re: [PATCH v2 2/2] target/riscv: add rv32i, rv32e and rv64e CPUs

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 2:19 AM Daniel Henrique Barboza
 wrote:
>
> A bare bones 32 bit RVI CPU, rv32i, will make users lives easier when a
> full customized 32 bit CPU is desired, and users won't need to disable
> defaults by hand as they would with the rv32 CPU. [1] has an example of
> a situation that would be avoided with rv32i.
>
> In fact, add bare bones CPUs for RVE as well. Trying to use RVE in QEMU
> requires one to disable every single default extension, including RVI,
> and then add the desirable extension set. Adding rv32e/rv64e makes it
> more pleasant to use embedded CPUs in QEMU.
>
> [1] 
> https://lore.kernel.org/qemu-riscv/258be47f-97be-4308-bed5-dc34ef7ff954@Spark/
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu-qom.h |  3 +++
>  target/riscv/cpu.c | 21 +
>  2 files changed, 24 insertions(+)
>
> diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
> index 9219c2fcc3..3670cfe6d9 100644
> --- a/target/riscv/cpu-qom.h
> +++ b/target/riscv/cpu-qom.h
> @@ -34,7 +34,10 @@
>  #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
>  #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
>  #define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
> +#define TYPE_RISCV_CPU_RV32IRISCV_CPU_TYPE_NAME("rv32i")
> +#define TYPE_RISCV_CPU_RV32ERISCV_CPU_TYPE_NAME("rv32e")
>  #define TYPE_RISCV_CPU_RV64IRISCV_CPU_TYPE_NAME("rv64i")
> +#define TYPE_RISCV_CPU_RV64ERISCV_CPU_TYPE_NAME("rv64e")
>  #define TYPE_RISCV_CPU_RVA22U64 RISCV_CPU_TYPE_NAME("rva22u64")
>  #define TYPE_RISCV_CPU_RVA22S64 RISCV_CPU_TYPE_NAME("rva22s64")
>  #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1202ec3e57..b9f10b773b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -576,6 +576,12 @@ static void rv64i_bare_cpu_init(Object *obj)
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
>  riscv_cpu_set_misa(env, MXL_RV64, RVI);
>  }
> +
> +static void rv64e_bare_cpu_init(Object *obj)
> +{
> +CPURISCVState *env = &RISCV_CPU(obj)->env;
> +riscv_cpu_set_misa(env, MXL_RV64, RVE);
> +}
>  #else
>  static void rv32_base_cpu_init(Object *obj)
>  {
> @@ -657,6 +663,18 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>  cpu->cfg.ext_zicsr = true;
>  cpu->cfg.pmp = true;
>  }
> +
> +static void rv32i_bare_cpu_init(Object *obj)
> +{
> +CPURISCVState *env = &RISCV_CPU(obj)->env;
> +riscv_cpu_set_misa(env, MXL_RV32, RVI);
> +}
> +
> +static void rv32e_bare_cpu_init(Object *obj)
> +{
> +CPURISCVState *env = &RISCV_CPU(obj)->env;
> +riscv_cpu_set_misa(env, MXL_RV32, RVE);
> +}
>  #endif
>
>  static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
> @@ -1948,6 +1966,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>  DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31,  rv32_sifive_e_cpu_init),
>  DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34,  
> rv32_imafcu_nommu_cpu_init),
>  DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34,  rv32_sifive_u_cpu_init),
> +DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV32I, rv32i_bare_cpu_init),
> +DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV32E, rv32e_bare_cpu_init),
>  #elif defined(TARGET_RISCV64)
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64,   rv64_base_cpu_init),
>  DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51,  rv64_sifive_e_cpu_init),
> @@ -1957,6 +1977,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>  DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,   rv64_veyron_v1_cpu_init),
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
>  DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
> +DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64E, rv64e_bare_cpu_init),
>  DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_profile_cpu_init),
>  DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64, rva22s64_profile_cpu_init),
>  #endif
> --
> 2.43.0
>
>



Re: [PATCH v2 1/2] target/riscv/cpu.c: add riscv_bare_cpu_init()

2024-01-21 Thread Alistair Francis
On Tue, Jan 9, 2024 at 3:32 AM Daniel Henrique Barboza
 wrote:
>
> Next patch will add more bare CPUs. Their cpu_init() functions would be
> glorified copy/pastes of rv64i_bare_cpu_init(), differing only by a
> riscv_cpu_set_misa() call.
>
> Add a new .instance_init for the TYPE_RISCV_BARE_CPU typ to avoid this
> code repetition. While we're at it, add a better explanation on why
> we're disabling the timing extensions for bare CPUs.
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 45 +
>  1 file changed, 29 insertions(+), 16 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index b32681f7f3..1202ec3e57 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -575,22 +575,6 @@ static void rv64i_bare_cpu_init(Object *obj)
>  {
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
>  riscv_cpu_set_misa(env, MXL_RV64, RVI);
> -
> -/* Remove the defaults from the parent class */
> -RISCV_CPU(obj)->cfg.ext_zicntr = false;
> -RISCV_CPU(obj)->cfg.ext_zihpm = false;
> -
> -/* Set to QEMU's first supported priv version */
> -env->priv_ver = PRIV_VERSION_1_10_0;
> -
> -/*
> - * Support all available satp_mode settings. The default
> - * value will be set to MBARE if the user doesn't set
> - * satp_mode manually (see set_satp_mode_default()).
> - */
> -#ifndef CONFIG_USER_ONLY
> -set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV64);
> -#endif
>  }
>  #else
>  static void rv32_base_cpu_init(Object *obj)
> @@ -1266,6 +1250,34 @@ static void riscv_cpu_init(Object *obj)
>  RISCV_CPU(obj)->cfg.ext_zihpm = true;
>  }
>
> +static void riscv_bare_cpu_init(Object *obj)
> +{
> +RISCVCPU *cpu = RISCV_CPU(obj);
> +
> +/*
> + * Bare CPUs do not inherit the timer and performance
> + * counters from the parent class (see riscv_cpu_init()
> + * for info on why the parent enables them).
> + *
> + * Users have to explicitly enable these counters for
> + * bare CPUs.
> + */
> +cpu->cfg.ext_zicntr = false;
> +cpu->cfg.ext_zihpm = false;
> +
> +/* Set to QEMU's first supported priv version */
> +cpu->env.priv_ver = PRIV_VERSION_1_10_0;
> +
> +/*
> + * Support all available satp_mode settings. The default
> + * value will be set to MBARE if the user doesn't set
> + * satp_mode manually (see set_satp_mode_default()).
> + */
> +#ifndef CONFIG_USER_ONLY
> +set_satp_mode_max_supported(cpu, VM_1_10_SV64);
> +#endif
> +}
> +
>  typedef struct misa_ext_info {
>  const char *name;
>  const char *description;
> @@ -1925,6 +1937,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>  {
>  .name = TYPE_RISCV_BARE_CPU,
>  .parent = TYPE_RISCV_CPU,
> +.instance_init = riscv_bare_cpu_init,
>  .abstract = true,
>  },
>  DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
> --
> 2.43.0
>
>



Re: [PATCH 1/3] hw/arm: Refactor struct arm_boot_info::get_dtb()

2024-01-21 Thread Alistair Francis
On Mon, Jan 15, 2024 at 2:36 PM Bin Meng  wrote:
>
> At present we expect struct arm_boot_info::get_dtb() to return the
> device tree pointer as well as the device tree size. However, this
> is not necessary as we can get the device tree size via the device
> tree header directly. Change get_dtb() signature to drop the *size
> argument, and get the size by ourselves.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  include/hw/arm/boot.h | 8 
>  hw/arm/boot.c | 3 ++-
>  hw/arm/sbsa-ref.c | 3 +--
>  hw/arm/virt.c | 4 +---
>  hw/arm/xlnx-versal-virt.c | 4 +---
>  5 files changed, 9 insertions(+), 13 deletions(-)
>
> diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
> index 80c492d742..37fd1b520e 100644
> --- a/include/hw/arm/boot.h
> +++ b/include/hw/arm/boot.h
> @@ -82,11 +82,11 @@ struct arm_boot_info {
>   const struct arm_boot_info *info);
>  /* if a board is able to create a dtb without a dtb file then it
>   * sets get_dtb. This will only be used if no dtb file is provided
> - * by the user. On success, sets *size to the length of the created
> - * dtb, and returns a pointer to it. (The caller must free this memory
> - * with g_free() when it has finished with it.) On failure, returns NULL.
> + * by the user. On success, returns a pointer to it. (The caller must
> + * free this memory with g_free() when it has finished with it.)
> + * On failure, returns NULL.
>   */
> -void *(*get_dtb)(const struct arm_boot_info *info, int *size);
> +void *(*get_dtb)(const struct arm_boot_info *info);
>  /* if a board needs to be able to modify a device tree provided by
>   * the user it should implement this hook.
>   */
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index 84ea6a807a..ff1173299f 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -538,11 +538,12 @@ int arm_load_dtb(hwaddr addr, const struct 
> arm_boot_info *binfo,
>  }
>  g_free(filename);
>  } else {
> -fdt = binfo->get_dtb(binfo, &size);
> +fdt = binfo->get_dtb(binfo);
>  if (!fdt) {
>  fprintf(stderr, "Board was unable to create a dtb blob\n");
>  goto fail;
>  }
> +size = fdt_totalsize(fdt);
>  }
>
>  if (addr_limit > addr && size > (addr_limit - addr)) {
> diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
> index 477dca0637..c5023871a7 100644
> --- a/hw/arm/sbsa-ref.c
> +++ b/hw/arm/sbsa-ref.c
> @@ -681,12 +681,11 @@ static void create_pcie(SBSAMachineState *sms)
>  create_smmu(sms, pci->bus);
>  }
>
> -static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
> +static void *sbsa_ref_dtb(const struct arm_boot_info *binfo)
>  {
>  const SBSAMachineState *board = container_of(binfo, SBSAMachineState,
>   bootinfo);
>
> -*fdt_size = board->fdt_size;
>  return board->fdt;
>  }
>
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 2793121cb4..1996fffa99 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -1577,14 +1577,12 @@ static void create_secure_ram(VirtMachineState *vms,
>  g_free(nodename);
>  }
>
> -static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
> +static void *machvirt_dtb(const struct arm_boot_info *binfo)
>  {
>  const VirtMachineState *board = container_of(binfo, VirtMachineState,
>   bootinfo);
>  MachineState *ms = MACHINE(board);
>
> -
> -*fdt_size = board->fdt_size;
>  return ms->fdt;
>  }
>
> diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> index 537118224f..1e043c813e 100644
> --- a/hw/arm/xlnx-versal-virt.c
> +++ b/hw/arm/xlnx-versal-virt.c
> @@ -551,12 +551,10 @@ static void versal_virt_modify_dtb(const struct 
> arm_boot_info *binfo,
>  fdt_add_memory_nodes(s, fdt, binfo->ram_size);
>  }
>
> -static void *versal_virt_get_dtb(const struct arm_boot_info *binfo,
> -  int *fdt_size)
> +static void *versal_virt_get_dtb(const struct arm_boot_info *binfo)
>  {
>  const VersalVirt *board = container_of(binfo, VersalVirt, binfo);
>
> -*fdt_size = board->fdt_size;
>  return board->fdt;
>  }
>
> --
> 2.34.1
>
>



Re: [PATCH v3 13/13] target/riscv/cpu.c: remove cpu->cfg.vlen

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:03 AM Daniel Henrique Barboza
 wrote:
>
> There is no need to keep both 'vlen' and 'vlenb'. All existing code
> that requires 'vlen' is retrieving it via 'vlenb << 3'.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 8 +++-
>  target/riscv/cpu_cfg.h | 1 -
>  target/riscv/tcg/tcg-cpu.c | 4 +++-
>  3 files changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index f4261d2ffc..7b3f69d3fb 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1313,7 +1313,6 @@ static void riscv_cpu_init(Object *obj)
>
>  /* Default values for non-bool cpu properties */
>  cpu->cfg.pmu_mask = MAKE_64BIT_MASK(3, 16);
> -cpu->cfg.vlen = 128;
>  cpu->cfg.vlenb = 128 >> 3;
>  cpu->cfg.elen = 64;
>  cpu->env.vext_ver = VEXT_VERSION_1_00_0;
> @@ -1802,22 +1801,21 @@ static void prop_vlen_set(Object *obj, Visitor *v, 
> const char *name,
>  return;
>  }
>
> -if (value != cpu->cfg.vlen && riscv_cpu_is_vendor(obj)) {
> +if (value != cpu->cfg.vlenb && riscv_cpu_is_vendor(obj)) {
>  cpu_set_prop_err(cpu, name, errp);
>  error_append_hint(errp, "Current '%s' val: %u\n",
> -  name, cpu->cfg.vlen);
> +  name, cpu->cfg.vlenb << 3);
>  return;
>  }
>
>  cpu_option_add_user_setting(name, value);
> -cpu->cfg.vlen = value;
>  cpu->cfg.vlenb = value >> 3;
>  }
>
>  static void prop_vlen_get(Object *obj, Visitor *v, const char *name,
>   void *opaque, Error **errp)
>  {
> -uint16_t value = RISCV_CPU(obj)->cfg.vlen;
> +uint16_t value = RISCV_CPU(obj)->cfg.vlenb << 3;
>
>  visit_type_uint16(v, name, &value, errp);
>  }
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index 50479dd72f..e241922f89 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -139,7 +139,6 @@ struct RISCVCPUConfig {
>  bool ext_XVentanaCondOps;
>
>  uint32_t pmu_mask;
> -uint16_t vlen;
>  uint16_t vlenb;
>  uint16_t elen;
>  uint16_t cbom_blocksize;
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index daff0b8f60..667421b0b7 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -298,7 +298,9 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, 
> Error **errp)
>  static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
>   Error **errp)
>  {
> -if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) {
> +uint32_t vlen = cfg->vlenb << 3;
> +
> +if (vlen > RV_VLEN_MAX || vlen < 128) {
>  error_setg(errp,
> "Vector extension implementation only supports VLEN "
> "in the range [128, %d]", RV_VLEN_MAX);
> --
> 2.43.0
>
>



Re: [PATCH v3 12/13] trans_rvv.c.inc: use vext_get_vlmax() in trans_vrgather_v*()

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:02 AM Daniel Henrique Barboza
 wrote:
>
> Use the helper instead of calculating vlmax by hand.
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index b4663b6e1f..9e101ab434 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -3535,8 +3535,7 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr 
> *a)
>  }
>
>  if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
> -int scale = s->lmul - (s->sew + 3);
> -int vlmax = s->cfg_ptr->vlen >> -scale;
> +int vlmax = vext_get_vlmax(s->cfg_ptr->vlenb, s->sew, s->lmul);
>  TCGv_i64 dest = tcg_temp_new_i64();
>
>  if (a->rs1 == 0) {
> @@ -3566,8 +3565,7 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr 
> *a)
>  }
>
>  if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
> -int scale = s->lmul - (s->sew + 3);
> -int vlmax = s->cfg_ptr->vlen >> -scale;
> +int vlmax = vext_get_vlmax(s->cfg_ptr->vlenb, s->sew, s->lmul);
>  if (a->rs1 >= vlmax) {
>  tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd),
>   MAXSZ(s), MAXSZ(s), 0);
> --
> 2.43.0
>
>



Re: [PATCH v3 11/13] target/riscv: change vext_get_vlmax() arguments

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:02 AM Daniel Henrique Barboza
 wrote:
>
> We'll re-use the logic froim vext_get_vlmax() in 2 other occurrences in
> the next patch, but first we need to make it independent of both 'cpu'
> and 'vtype'. To do that, add 'vlenb', 'vsew' and 'lmul' as parameters
> instead.
>
> Adapt the two existing callers. In cpu_get_tb_cpu_state(), rename 'sew'
> to 'vsew' to be less ambiguous about what we're encoding into *pflags.
>
> In HELPER(vsetvl) the following changes were made:
>
> - add a 'vsew' var to store vsew. Use it in the shift to get 'sew';
> - the existing 'lmul' var was renamed to 'vlmul';
> - add a new 'lmul' var to store 'lmul' encoded like DisasContext:lmul.
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h   |  7 +++
>  target/riscv/cpu_helper.c| 11 +++
>  target/riscv/vector_helper.c | 16 ++--
>  3 files changed, 20 insertions(+), 14 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3af61e0f94..9dcbc0649a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -688,11 +688,10 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
>   *   = 256 >> 7
>   *   = 2
>   */
> -static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
> +static inline uint32_t vext_get_vlmax(uint32_t vlenb, uint32_t vsew,
> +  int8_t lmul)
>  {
> -uint8_t vsew = FIELD_EX64(vtype, VTYPE, VSEW);
> -int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
> -uint32_t vlen = cpu->cfg.vlenb << 3;
> +uint32_t vlen = vlenb << 3;
>
>  /*
>   * We need to use 'vlen' instead of 'vlenb' to
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index c7cc7eb423..8da9104da4 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -81,13 +81,16 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
>   * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
>   * only when maxsz >= 8 bytes.
>   */
> -uint32_t vlmax = vext_get_vlmax(cpu, env->vtype);
> -uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
> -uint32_t maxsz = vlmax << sew;
> +
> +/* lmul encoded as in DisasContext::lmul */
> +int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3);
> +uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW);
> +uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
> +uint32_t maxsz = vlmax << vsew;
>  bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
> (maxsz >= 8);
>  flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
> -flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
> +flags = FIELD_DP32(flags, TB_FLAGS, SEW, vsew);
>  flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
> FIELD_EX64(env->vtype, VTYPE, VLMUL));
>  flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index b13be1541a..718a0c711a 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -35,16 +35,18 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
> target_ulong s1,
>  {
>  int vlmax, vl;
>  RISCVCPU *cpu = env_archcpu(env);
> -uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
> -uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
> +uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
> +uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
> +uint16_t sew = 8 << vsew;
>  uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
>  int xlen = riscv_cpu_xlen(env);
>  bool vill = (s2 >> (xlen - 1)) & 0x1;
>  target_ulong reserved = s2 &
>  MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
>  xlen - 1 - 
> R_VTYPE_RESERVED_SHIFT);
> +int8_t lmul;
>
> -if (lmul & 4) {
> +if (vlmul & 4) {
>  /*
>   * Fractional LMUL, check:
>   *
> @@ -53,8 +55,8 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
> target_ulong s1,
>   * (vlenb << 3) >> (8 - lmul) >= sew
>   * vlenb >> (8 - 3 - lmul) >= sew
>   */
> -if (lmul == 4 ||
> -cpu->cfg.vlenb >> (8 - 3 - lmul) < sew) {
> +if (vlmul == 4 ||
> +cpu->cfg.vlenb >> (8 - 3 - vlmul) < sew) {
>  vill = true;
>  }
>  }
> @@ -68,7 +70,9 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
> target_ulong s1,
>  return 0;
>  }
>
> -vlmax = vext_get_vlmax(cpu, s2);
> +/* lmul encoded as in DisasContext::lmul */
> +lmul = sextract32(FIELD_EX64(s2, VTYPE, VLMUL), 0, 3);
> +vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
>  if (s1 <= vlmax) {
>  vl = s1;
>  } els

Re: [PATCH v3 10/13] target/riscv/cpu.h: use 'vlenb' in vext_get_vlmax()

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:02 AM Daniel Henrique Barboza
 wrote:
>
> Rename the existing 'sew' variable to 'vsew' for extra clarity.
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 11df226a00..3af61e0f94 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -690,9 +690,16 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
>   */
>  static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
>  {
> -uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
> +uint8_t vsew = FIELD_EX64(vtype, VTYPE, VSEW);
>  int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
> -return cpu->cfg.vlen >> (sew + 3 - lmul);
> +uint32_t vlen = cpu->cfg.vlenb << 3;
> +
> +/*
> + * We need to use 'vlen' instead of 'vlenb' to
> + * preserve the '+ 3' in the formula. Otherwise
> + * we risk a negative shift if vsew < lmul.
> + */
> +return vlen >> (vsew + 3 - lmul);
>  }
>
>  void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
> --
> 2.43.0
>
>



Re: [PATCH v3 09/13] target/riscv/insn_trans/trans_rvv.c.inc: use 'vlenb' in MAXSZ()

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:02 AM Daniel Henrique Barboza
 wrote:
>
> Calculate the maximum vector size possible, 'max_sz', which is the size
> in bytes 'vlenb' multiplied by the max value of LMUL (LMUL = 8, when
> s->lmul = 3).
>
> 'max_sz' is then shifted right by 'scale', expressed as '3 - s->lmul',
> which is clearer than doing 'scale = lmul - 3' and then using '-scale'
> in the shift right.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index d743675262..b4663b6e1f 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -1160,12 +1160,12 @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, 1, true)
>  /*
>   * MAXSZ returns the maximum vector size can be operated in bytes,
>   * which is used in GVEC IR when vl_eq_vlmax flag is set to true
> - * to accerlate vector operation.
> + * to accelerate vector operation.
>   */
>  static inline uint32_t MAXSZ(DisasContext *s)
>  {
> -int scale = s->lmul - 3;
> -return s->cfg_ptr->vlen >> -scale;
> +int max_sz = s->cfg_ptr->vlenb * 8;
> +return max_sz >> (3 - s->lmul);
>  }
>
>  static bool opivv_check(DisasContext *s, arg_rmrr *a)
> --
> 2.43.0
>
>



Re: [PATCH v3 08/13] target/riscv/vector_helper.c: use vlenb in HELPER(vsetvl)

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:02 AM Daniel Henrique Barboza
 wrote:
>
> Use the new 'vlenb' CPU config to validate fractional LMUL. The original
> comparison is done with 'vlen' and 'sew', both in bits. Adjust the shift
> to use vlenb.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/vector_helper.c | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index cb944229b0..b13be1541a 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -45,9 +45,16 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
> target_ulong s1,
>  xlen - 1 - 
> R_VTYPE_RESERVED_SHIFT);
>
>  if (lmul & 4) {
> -/* Fractional LMUL - check LMUL * VLEN >= SEW */
> +/*
> + * Fractional LMUL, check:
> + *
> + * VLEN * LMUL >= SEW
> + * VLEN >> (8 - lmul) >= sew
> + * (vlenb << 3) >> (8 - lmul) >= sew
> + * vlenb >> (8 - 3 - lmul) >= sew
> + */
>  if (lmul == 4 ||
> -cpu->cfg.vlen >> (8 - lmul) < sew) {
> +cpu->cfg.vlenb >> (8 - 3 - lmul) < sew) {
>  vill = true;
>  }
>  }
> --
> 2.43.0
>
>



Re: [PATCH v3 07/13] target/riscv/vector_helper.c: use 'vlenb'

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 8:18 AM Daniel Henrique Barboza
 wrote:
>
> Use 'cpu->cfg.vlenb' instead of 'cpu->cfg.vlen >> 3'.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/vector_helper.c | 18 +-
>  1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index c1c3a4d1ea..cb944229b0 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -558,7 +558,7 @@ vext_ldst_whole(void *vd, target_ulong base, 
> CPURISCVState *env, uint32_t desc,
>  {
>  uint32_t i, k, off, pos;
>  uint32_t nf = vext_nf(desc);
> -uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
> +uint32_t vlenb = riscv_cpu_cfg(env)->vlenb;
>  uint32_t max_elems = vlenb >> log2_esz;
>
>  k = env->vstart / max_elems;
> @@ -929,7 +929,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
> *vs2,   \
>  { \
>  uint32_t vl = env->vl;\
>  uint32_t vm = vext_vm(desc);  \
> -uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
> +uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;\
>  uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
>  uint32_t i;   \
>\
> @@ -967,7 +967,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,
>   \
>  {   \
>  uint32_t vl = env->vl;  \
>  uint32_t vm = vext_vm(desc);\
> -uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
> +uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;  \
>  uint32_t vta_all_1s = vext_vta_all_1s(desc);\
>  uint32_t i; \
>  \
> @@ -1171,7 +1171,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
> *vs2,   \
>  { \
>  uint32_t vm = vext_vm(desc);  \
>  uint32_t vl = env->vl;\
> -uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
> +uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;\
>  uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
>  uint32_t vma = vext_vma(desc);\
>  uint32_t i;   \
> @@ -1236,7 +1236,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
> void *vs2,   \
>  {   \
>  uint32_t vm = vext_vm(desc);\
>  uint32_t vl = env->vl;  \
> -uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
> +uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;  \
>  uint32_t vta_all_1s = vext_vta_all_1s(desc);\
>  uint32_t vma = vext_vma(desc);  \
>  uint32_t i; \
> @@ -3971,7 +3971,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
> *vs2,   \
>  { \
>  uint32_t vm = vext_vm(desc);  \
>  uint32_t vl = env->vl;\
> -uint32_t total_elems = riscv_cpu_cfg(env)->vlen;  \
> +uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;\
>  uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
>  uint32_t vma = vext_vma(desc);\
>  uint32_t i;   \
> @@ -4011,7 +4011,7 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
> *vs2,   \
>  {   \
>  uint32_t vm = vext_vm(desc);\
>  uint32_t vl = env->vl;  \
> -uint32_t total_elems = riscv_cpu_cfg(env)->vlen;\
> +uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;  \
>  uint32_t vta_all_1s = vext_vta_all_1s(desc);\
>  uint32_t vma = vext_vma(desc);  \
>  uint32_t i; \
> @@ -4528,7 +4528,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,
>   \
>uint32_t desc)  \
>  {   

Re: [PATCH v3 06/13] target/riscv/insn_trans/trans_rvvk.c.inc: use 'vlenb'

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:01 AM Daniel Henrique Barboza
 wrote:
>
> Use s->cfg_ptr->vlenb instead of s->cfg_ptr->vlen / 8.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvvk.c.inc | 16 
>  1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
> b/target/riscv/insn_trans/trans_rvvk.c.inc
> index 3801c16829..a5cdd1b67f 100644
> --- a/target/riscv/insn_trans/trans_rvvk.c.inc
> +++ b/target/riscv/insn_trans/trans_rvvk.c.inc
> @@ -174,7 +174,7 @@ GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
>  data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
>  tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
> vreg_ofs(s, a->rs2), tcg_env,   \
> -   s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
> +   s->cfg_ptr->vlenb, s->cfg_ptr->vlenb,   \
> data, fns[s->sew]); \
>  mark_vs_dirty(s);  \
>  gen_set_label(over);   \
> @@ -267,7 +267,7 @@ GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, 
> vwsll_vx_check)
>  rd_v = tcg_temp_new_ptr();   
>  \
>  rs2_v = tcg_temp_new_ptr();  
>  \
>  desc = tcg_constant_i32( 
>  \
> -simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, 
> data)); \
> +simd_desc(s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, data));  
>  \
>  tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); 
>  \
>  tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2));   
>  \
>  gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc);   
>  \
> @@ -345,7 +345,7 @@ GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
>  rs2_v = tcg_temp_new_ptr();  
>  \
>  uimm_v = tcg_constant_i32(a->rs1);   
>  \
>  desc = tcg_constant_i32( 
>  \
> -simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, 
> data)); \
> +simd_desc(s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, data));  
>  \
>  tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd)); 
>  \
>  tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2));   
>  \
>  gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc);   
>  \
> @@ -413,7 +413,7 @@ GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, 
> ZVKNED_EGS)
>   
>  \
>  tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),  
>  \
> vreg_ofs(s, a->rs2), tcg_env, 
>  \
> -   s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8,   
>  \
> +   s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, 
>  \
> data, gen_helper_##NAME); 
>  \
>   
>  \
>  mark_vs_dirty(s);
>  \
> @@ -466,8 +466,8 @@ static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
>  data = FIELD_DP32(data, VDATA, VMA, s->vma);
>
>  tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
> -vreg_ofs(s, a->rs2), tcg_env, s->cfg_ptr->vlen / 8,
> -s->cfg_ptr->vlen / 8, data,
> +vreg_ofs(s, a->rs2), tcg_env, s->cfg_ptr->vlenb,
> +s->cfg_ptr->vlenb, data,
>  s->sew == MO_32 ?
>  gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
>
> @@ -500,8 +500,8 @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
>  data = FIELD_DP32(data, VDATA, VMA, s->vma);
>
>  tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
> -vreg_ofs(s, a->rs2), tcg_env, s->cfg_ptr->vlen / 8,
> -s->cfg_ptr->vlen / 8, data,
> +vreg_ofs(s, a->rs2), tcg_env, s->cfg_ptr->vlenb,
> +s->cfg_ptr->vlenb, data,
>  s->sew == MO_32 ?
>  gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
>
> --
> 2.43.0
>
>



Re: [PATCH v3 05/13] target/riscv/insn_trans/trans_rvv.c.inc: use 'vlenb'

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:00 AM Daniel Henrique Barboza
 wrote:
>
> Use s->cfg_ptr->vlenb instead of "s->cfg_ptr->vlen / 8"  and
> "s->cfg_ptr->vlen >> 3".
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 140 
>  1 file changed, 70 insertions(+), 70 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index 3871f0ea73..d743675262 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -217,7 +217,7 @@ static bool trans_vsetivli(DisasContext *s, arg_vsetivli 
> *a)
>  /* vector register offset from env */
>  static uint32_t vreg_ofs(DisasContext *s, int reg)
>  {
> -return offsetof(CPURISCVState, vreg) + reg * s->cfg_ptr->vlen / 8;
> +return offsetof(CPURISCVState, vreg) + reg * s->cfg_ptr->vlenb;
>  }
>
>  /* check functions */
> @@ -627,11 +627,11 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
> uint32_t data,
>   * As simd_desc supports at most 2048 bytes, and in this implementation,
>   * the max vector group length is 4096 bytes. So split it into two parts.
>   *
> - * The first part is vlen in bytes, encoded in maxsz of simd_desc.
> + * The first part is vlen in bytes (vlenb), encoded in maxsz of 
> simd_desc.
>   * The second part is lmul, encoded in data of simd_desc.
>   */
> -desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
> -  s->cfg_ptr->vlen / 8, data));
> +desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
> +  s->cfg_ptr->vlenb, data));
>
>  tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
>  tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
> @@ -791,8 +791,8 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, 
> uint32_t rs2,
>  mask = tcg_temp_new_ptr();
>  base = get_gpr(s, rs1, EXT_NONE);
>  stride = get_gpr(s, rs2, EXT_NONE);
> -desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
> -  s->cfg_ptr->vlen / 8, data));
> +desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
> +  s->cfg_ptr->vlenb, data));
>
>  tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
>  tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
> @@ -897,8 +897,8 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, 
> uint32_t vs2,
>  mask = tcg_temp_new_ptr();
>  index = tcg_temp_new_ptr();
>  base = get_gpr(s, rs1, EXT_NONE);
> -desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
> -  s->cfg_ptr->vlen / 8, data));
> +desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
> +  s->cfg_ptr->vlenb, data));
>
>  tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
>  tcg_gen_addi_ptr(index, tcg_env, vreg_ofs(s, vs2));
> @@ -1036,8 +1036,8 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, 
> uint32_t data,
>  dest = tcg_temp_new_ptr();
>  mask = tcg_temp_new_ptr();
>  base = get_gpr(s, rs1, EXT_NONE);
> -desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
> -  s->cfg_ptr->vlen / 8, data));
> +desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
> +  s->cfg_ptr->vlenb, data));
>
>  tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
>  tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
> @@ -1086,7 +1086,7 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, 
> uint32_t nf,
>   uint32_t width, gen_helper_ldst_whole *fn,
>   DisasContext *s, bool is_store)
>  {
> -uint32_t evl = (s->cfg_ptr->vlen / 8) * nf / width;
> +uint32_t evl = s->cfg_ptr->vlenb * nf / width;
>  TCGLabel *over = gen_new_label();
>  tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, evl, over);
>
> @@ -1096,8 +1096,8 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, 
> uint32_t nf,
>
>  uint32_t data = FIELD_DP32(0, VDATA, NF, nf);
>  dest = tcg_temp_new_ptr();
> -desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
> -  s->cfg_ptr->vlen / 8, data));
> +desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
> +  s->cfg_ptr->vlenb, data));
>
>  base = get_gpr(s, rs1, EXT_NONE);
>  tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
> @@ -1199,8 +1199,8 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
> *gvec_fn,
>  data = FIELD_DP32(data, VDATA, VMA, s->vma);
>  tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
> vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
> -   tcg_env, s->cfg_ptr->vlen / 8,
> - 

Re: [PATCH v3 04/13] target/riscv/insn_trans/trans_rvbf16.c.inc: use cpu->cfg.vlenb

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 8:17 AM Daniel Henrique Barboza
 wrote:
>
> Use ctx->cfg_ptr->vlenb instead of ctx->cfg_ptr->vlen / 8.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvbf16.c.inc | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc 
> b/target/riscv/insn_trans/trans_rvbf16.c.inc
> index 4e39c00884..8ee99df3f3 100644
> --- a/target/riscv/insn_trans/trans_rvbf16.c.inc
> +++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
> @@ -83,8 +83,8 @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, 
> arg_vfncvtbf16_f_f_w *a)
>  data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
>  tcg_gen_gvec_3_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
> vreg_ofs(ctx, a->rs2), tcg_env,
> -   ctx->cfg_ptr->vlen / 8,
> -   ctx->cfg_ptr->vlen / 8, data,
> +   ctx->cfg_ptr->vlenb,
> +   ctx->cfg_ptr->vlenb, data,
> gen_helper_vfncvtbf16_f_f_w);
>  mark_vs_dirty(ctx);
>  gen_set_label(over);
> @@ -112,8 +112,8 @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, 
> arg_vfwcvtbf16_f_f_v *a)
>  data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
>  tcg_gen_gvec_3_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
> vreg_ofs(ctx, a->rs2), tcg_env,
> -   ctx->cfg_ptr->vlen / 8,
> -   ctx->cfg_ptr->vlen / 8, data,
> +   ctx->cfg_ptr->vlenb,
> +   ctx->cfg_ptr->vlenb, data,
> gen_helper_vfwcvtbf16_f_f_v);
>  mark_vs_dirty(ctx);
>  gen_set_label(over);
> @@ -143,8 +143,8 @@ static bool trans_vfwmaccbf16_vv(DisasContext *ctx, 
> arg_vfwmaccbf16_vv *a)
>  tcg_gen_gvec_4_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
> vreg_ofs(ctx, a->rs1),
> vreg_ofs(ctx, a->rs2), tcg_env,
> -   ctx->cfg_ptr->vlen / 8,
> -   ctx->cfg_ptr->vlen / 8, data,
> +   ctx->cfg_ptr->vlenb,
> +   ctx->cfg_ptr->vlenb, data,
> gen_helper_vfwmaccbf16_vv);
>  mark_vs_dirty(ctx);
>  gen_set_label(over);
> --
> 2.43.0
>
>



Re: [PATCH v3 02/13] target/riscv/csr.c: use 'vlenb' instead of 'vlen'

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:00 AM Daniel Henrique Barboza
 wrote:
>
> As a bonus, we're being more idiomatic using cpu->cfg.vlenb when
> reading CSR_VLENB.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 674ea075a4..5c8d22452b 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -683,7 +683,7 @@ static RISCVException read_vl(CPURISCVState *env, int 
> csrno,
>
>  static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> -*val = riscv_cpu_cfg(env)->vlen >> 3;
> +*val = riscv_cpu_cfg(env)->vlenb;
>  return RISCV_EXCP_NONE;
>  }
>
> @@ -738,7 +738,7 @@ static RISCVException write_vstart(CPURISCVState *env, 
> int csrno,
>   * The vstart CSR is defined to have only enough writable bits
>   * to hold the largest element index, i.e. lg2(VLEN) bits.
>   */
> -env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlen));
> +env->vstart = val & ~(~0ULL << ctzl(riscv_cpu_cfg(env)->vlenb << 3));
>  return RISCV_EXCP_NONE;
>  }
>
> --
> 2.43.0
>
>



Re: [PATCH v3 03/13] target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:00 AM Daniel Henrique Barboza
 wrote:
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/gdbstub.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 58b3ace0fe..5ab0abda19 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -130,7 +130,7 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t 
> *mem_buf, int n)
>
>  static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
>  {
> -uint16_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
> +uint16_t vlenb = riscv_cpu_cfg(env)->vlenb;
>  if (n < 32) {
>  int i;
>  int cnt = 0;
> @@ -146,7 +146,7 @@ static int riscv_gdb_get_vector(CPURISCVState *env, 
> GByteArray *buf, int n)
>
>  static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
>  {
> -uint16_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
> +uint16_t vlenb = riscv_cpu_cfg(env)->vlenb;
>  if (n < 32) {
>  int i;
>  for (i = 0; i < vlenb; i += 8) {
> @@ -266,7 +266,7 @@ static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int 
> base_reg)
>  RISCVCPU *cpu = RISCV_CPU(cs);
>  GString *s = g_string_new(NULL);
>  g_autoptr(GString) ts = g_string_new("");
> -int reg_width = cpu->cfg.vlen;
> +int reg_width = cpu->cfg.vlenb << 3;
>  int num_regs = 0;
>  int i;
>
> --
> 2.43.0
>
>



Re: [PATCH v2 3/4] hw/cxl/mbox: replace sanitize_running() with cxl_dev_media_disabled()

2024-01-21 Thread Hyeonggon Yoo
On Tue, Jan 9, 2024 at 12:54 PM Jonathan Cameron
 wrote:
>
> On Fri, 22 Dec 2023 18:00:50 +0900
> Hyeonggon Yoo <42.hye...@gmail.com> wrote:
>
> > The spec states that reads/writes should have no effect and a part of
> > commands should be ignored when the media is disabled, not when the
> > sanitize command is running.qq
> >
> > Introduce cxl_dev_media_disabled() to check if the media is disabled and
> > replace sanitize_running() with it.
> >
> > Make sure that the media has been correctly disabled during sanitation
> > by adding an assert to __toggle_media(). Now, enabling when already
> > enabled or vice versa results in an assert() failure.
> >
> > Suggested-by: Davidlohr Bueso 
> > Signed-off-by: Hyeonggon Yoo <42.hye...@gmail.com>
>
> This applies to
>
> hw/cxl: Add get scan media capabilities cmd support.
>
> Should I just squash it with that patch in my tree?
> For now I'm holding it immediately on top of that, but I'm not keen to
> send messy code upstream unless there is a good reason to retain the
> history.

Oh, while the diff looks like the patch touches scan_media_running(), it's not.

The proper Fixes: tag will be:
Fixes: d77176724422 ("hw/cxl: Add support for device sanitation")

> If you are doing this sort of fix series in future, please call out
> what they fix explicitly.  Can't use fixes tags as the commit ids
> are unstable, but can mention the patch to make my life easier!

Okay, next time I will either add the Fixes tag or add a comment on
what it fixes.

By the way I guess your latest, public branch is still cxl-2023-11-02, right?
https://gitlab.com/jic23/qemu/-/tree/cxl-2023-11-02

I assume you adjusted my v2 series, but please let me know if you prefer
sending v3 against your latest tree.

Thanks,
Hyeonggon



Re: [PATCH v3 01/13] target/riscv: add 'vlenb' field in cpu->cfg

2024-01-21 Thread Alistair Francis
On Wed, Jan 17, 2024 at 7:00 AM Daniel Henrique Barboza
 wrote:
>
> Our usage of 'vlenb' is overwhelming superior than the use of 'vlen'.
> We're using 'vlenb' most of the time, having to do 'vlen >> 3' or
> 'vlen / 8' in every instance.
>
> In hindsight we would be better if the 'vlenb' property  was introduced
> instead of 'vlen'. That's not what happened, and now we can't easily get
> rid of it due to user scripts all around. What we can do, however, is to
> change our internal representation to use 'vlenb'.
>
> Add a 'vlenb' field in cpu->cfg. It'll be set via the existing 'vlen'
> property, i.e. setting 'vlen' will also set 'vlenb'.
>
> We'll replace all 'vlen >> 3' code to use 'vlenb' directly. Start with
> the single instance we have in target/riscv/cpu.c.
>
> Signed-off-by: Daniel Henrique Barboza 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 4 +++-
>  target/riscv/cpu_cfg.h | 1 +
>  2 files changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8d3ec74a1c..f4261d2ffc 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -847,7 +847,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
> int flags)
>   csr_ops[csrno].name, val);
>  }
>  }
> -uint16_t vlenb = cpu->cfg.vlen >> 3;
> +uint16_t vlenb = cpu->cfg.vlenb;
>
>  for (i = 0; i < 32; i++) {
>  qemu_fprintf(f, " %-8s ", riscv_rvv_regnames[i]);
> @@ -1314,6 +1314,7 @@ static void riscv_cpu_init(Object *obj)
>  /* Default values for non-bool cpu properties */
>  cpu->cfg.pmu_mask = MAKE_64BIT_MASK(3, 16);
>  cpu->cfg.vlen = 128;
> +cpu->cfg.vlenb = 128 >> 3;
>  cpu->cfg.elen = 64;
>  cpu->env.vext_ver = VEXT_VERSION_1_00_0;
>  }
> @@ -1810,6 +1811,7 @@ static void prop_vlen_set(Object *obj, Visitor *v, 
> const char *name,
>
>  cpu_option_add_user_setting(name, value);
>  cpu->cfg.vlen = value;
> +cpu->cfg.vlenb = value >> 3;
>  }
>
>  static void prop_vlen_get(Object *obj, Visitor *v, const char *name,
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index fea14c275f..50479dd72f 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -140,6 +140,7 @@ struct RISCVCPUConfig {
>
>  uint32_t pmu_mask;
>  uint16_t vlen;
> +uint16_t vlenb;
>  uint16_t elen;
>  uint16_t cbom_blocksize;
>  uint16_t cbop_blocksize;
> --
> 2.43.0
>
>



Re: [PATCH 0/5] buses: switch to 3-phase-reset

2024-01-21 Thread Peter Xu
Hi, Peter,

On Fri, Jan 19, 2024 at 04:35:07PM +, Peter Maydell wrote:
> I wrote this ages ago and recently picked it back up because of a
> recent PCI related reset ordering problem noted by Peter Xu.  I'm not
> sure if this patchset is necessary as a part of fixing that ordering
> problem (it might even be possible now to have the intel_iommu device
> use 3-phase reset and put the relevant parts of its reset into the
> 'exit' phase), but either way we really ought to do this cleanup
> to reduce the amount of legacy/transitional handling we have.

The VFIO issue I was working on may not directly benefit from this series
iiuc, as it's more of an special ordering on both (1) VFIO special case
reset path using qemu_register_reset(), and (2) VT-d device is not put at
the right place in the QOM hierachy [1].

Said that, thanks a lot for posting the patches; they all look reasonable
and good cleanups to the reset infrastructure, afaict.

[1] https://lore.kernel.org/r/ZapYii9nr5Tj9ClE@x1n

-- 
Peter Xu




Re: [PATCH] qdev: not add devices to bus in reverse order

2024-01-21 Thread Kai

On 1/18/24 20:07, Igor Mammedov wrote:

On Thu, 18 Jan 2024 14:48:50 +0800
Kai  wrote:


On 1/18/24 01:31, Peter Maydell wrote:

(cc'd the people listed for this file in MAINTAINERS)

On Tue, 9 Jan 2024 at 13:53, Kai Kang  wrote:

When this section of source codes were added via commit:

* 02e2da45c4 Add common BusState

it added devices to bus with LIST_INSERT_HEAD() which operated on the
single direction list. It didn't have something like LIST_INSERT_TAIL()
at that time and kept that way when turned to QTAILQ.

Then it causes the fist device in qemu command line inserted at the end
of the bus child link list. And when realize them, the first device will
be the last one to be realized.

Replace QTAILQ_INSERT_HEAD_RCU() with QTAILQ_INSERT_TAIL_RCU() to make
sure that devices are added to bus with the sequence in the command
line.

What are the problems being caused by the the list items being added
in reverse order? Your commit message doesn't say what specific
bug or problem it's trying to fix.

The problem I met was just as I asked for for help in the maillist on
Dec 18, 2023.

The indexes of serial isa devices changes with the commit dcdbfaafe90a
since qemu 6.2.0.
Before the commit, it creates devices literally with "1" & "2":

@@ -1252,8 +1222,6 @@ static void build_isa_devices_aml(Aml *table)
   aml_append(scope, build_fdc_device_aml(fdc));
   }
   aml_append(scope, build_lpt_device_aml());
-    build_com_device_aml(scope, 1);
-    build_com_device_aml(scope, 2);

After apply the commit, it uses the 'aml builder' way and the devices
are handled in reverse way.
Then the indexes are reversed. It affects guest os such as freebsd. When
run `pstat -t` on freebsd
with qemu, the sequence of the output is not right.

root@freebsd:~ # pstat -t
    LINE   INQ  CAN  LIN  LOW  OUTQ  USE  LOW   COL  SESS  PGID STATE
   ttyu2 0    0    0    0 0    0    0 0 0 0 IC
   ttyu3 0    0    0    0 0    0    0 0 0 0 IC
   ttyu1 0    0    0    0 0    0    0 0 0 0 IC
   ttyu0  1920    0    0  192  1984    0  199 0   664   668 ICOi

It is expected with ascend order which keeps the same behavior with
older version qemu.


Hi Peter & Igor,

Thanks for your reply.


this problem description should be in commit message.


Will do next time.



As for fixing it I'd wouldn't touch bus order as Peter already noted
it has high chances to break behavior elsewhere.

current state of COM naming:
1: QEMU 6.1  all machine types: COM1 { uid: 1, irq: 4}, COM2 { uid: 2, irq: 
3}
2: QEMU 6.2+ all machine types: COM1 { uid: 2, irq: 4}, COM1 { uid: 1, irq: 
3}
all of above in default case where user doesn't supply 'index' explicitly.

With 'index' provided explicitly old case #1 might break due to
hardcoded resource values in former build_com_device_aml().
#2 (current code) doesn't have issues with resource values
when explicit 'index' is used (which can be a possible workaround)


How to assign explicit 'index' in the command line? I don't figure it 
out the option for it.





So we essentially have changed enumeration for 6.1 and older
machine types in incompatible way with QEMU-6.2+ builds.
(and that in it's turn breaks exiting VM config when it
is started on QEMU-6.2+)

Kai,
Does above sum-up the issue you are encountering?


Yes, it does.

Thanks,
Kai




Regards,
Kai


In general this kind of patch is something I'm very cautious about,
because it seems very likely that various bits of the code where
order does matter will currently be expecting (and working around)
the reverse-order behaviour, because that's what has been done by
bus_add_child() for the last 20-plus years. (As one concrete example,
see the big comment at the top of create_virtio_devices() in
hw/arm/virt.c. There are probably others where we didn't comment
on the ordering but just assume it.)
  

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 43d863b0c5..5e2ff43715 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -89,7 +89,7 @@ static void bus_add_child(BusState *bus, DeviceState *child)
   kid->child = child;
   object_ref(OBJECT(kid->child));

-QTAILQ_INSERT_HEAD_RCU(&bus->children, kid, sibling);
+QTAILQ_INSERT_TAIL_RCU(&bus->children, kid, sibling);

   /* This transfers ownership of kid->child to the property.  */
   snprintf(name, sizeof(name), "child[%d]", kid->index);

thanks
-- PMM




--
Kai Kang
Wind River Linux




Re: [PATCH v3] Handle wrap around in limit calculation

2024-01-21 Thread Philippe Mathieu-Daudé

Hi Shlomo,

On 21/1/24 17:47, Shlomo Pongratz wrote:

From: Shlomo Pongratz 

 Hanlde wrap around when calculating the viewport size
 caused by the fact that perior to version 460A the limit variable
 was 32bit quantity and not 64 bits quantity.
 In the i.MX 6Dual/6Quad Applications Processor Reference Manual
 document on which the original code was based upon in the
 description of the iATU Region Upper Base Address Register it is
 written:
 Forms bits [63:32] of the start (and end) address of the address region to 
be
 translated.
 That is in this register is the upper of both base and the limit.
 In the current implementation this value was ignored for the limit
 which caused a wrap around of the size calculaiton.
 Using the documnet example:
 Base HI: 0x8000 Base LO: 0xd000 Limit LO: 0xd000
 The correct size is 0x8000d000 - 0x8000d000 + 1 =
0x01
 The wrong result is 0xd000 - 0x8000d000 + 1 = 
0x8001

 Signed-off-by: Shlomo Pongratz 

 

 Changes since v2:
  * Don't try to fix the calculation.
  * Change the limit variable from 32bit to 64 bit
  * Set the limit bits [63:32] same as the base according to
the specification on which the original code was base upon.

 Changes since v1:
  * Seperate subject and description
---
  hw/pci-host/designware.c | 19 ++-
  include/hw/pci-host/designware.h |  2 +-
  2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index dd9e389c07..43cba9432f 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -269,7 +269,7 @@ static void 
designware_pcie_update_viewport(DesignwarePCIERoot *root,
  {
  const uint64_t target = viewport->target;
  const uint64_t base   = viewport->base;
-const uint64_t size   = (uint64_t)viewport->limit - base + 1;
+const uint64_t size   = viewport->limit - base + 1;
  const bool enabled= viewport->cr[1] & DESIGNWARE_PCIE_ATU_ENABLE;
  
  MemoryRegion *current, *other;

@@ -351,6 +351,14 @@ static void designware_pcie_root_config_write(PCIDevice 
*d, uint32_t address,
  case DESIGNWARE_PCIE_ATU_UPPER_BASE:
  viewport->base &= 0xULL;
  viewport->base |= (uint64_t)val << 32;
+/* The documentatoin states that the value of this register
+ * "Forms bits [63:32] of the start (and end) address
+ * of the address region to be translated.
+ * Note that from version 406A there is a sperate
+ * register fot the upper end address
+ */
+viewport->limit &= 0xULL;
+viewport->limit |= (uint64_t)val << 32;


This code is easier to review using:

  viewport->limit = deposit64(viewport->limit, 32, 32, val);


  break;
  
  case DESIGNWARE_PCIE_ATU_LOWER_TARGET:

@@ -364,7 +372,8 @@ static void designware_pcie_root_config_write(PCIDevice *d, 
uint32_t address,
  break;
  
  case DESIGNWARE_PCIE_ATU_LIMIT:

-viewport->limit = val;
+viewport->limit &= 0xULL;
+viewport->limit |= val;


Here:

  viewport->limit = deposit64(viewport->limit, 0, 32, val);


  break;
  
  case DESIGNWARE_PCIE_ATU_CR1:

@@ -429,7 +438,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
  viewport->inbound = true;
  viewport->base= 0xULL;
  viewport->target  = 0xULL;
-viewport->limit   = UINT32_MAX;
+viewport->limit   = 0xULL;


Previous code is easier to review IMHO.


  viewport->cr[0]   = DESIGNWARE_PCIE_ATU_TYPE_MEM;
  
  source  = &host->pci.address_space_root;

@@ -453,7 +462,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
  viewport->inbound = false;
  viewport->base= 0xULL;
  viewport->target  = 0xULL;
-viewport->limit   = UINT32_MAX;
+viewport->limit   = 0xULL;


Ditto.


  viewport->cr[0]   = DESIGNWARE_PCIE_ATU_TYPE_MEM;
  
  destination = &host->pci.memory;

@@ -560,7 +569,7 @@ static const VMStateDescription 
vmstate_designware_pcie_viewport = {
  .fields = (const VMStateField[]) {
  VMSTATE_UINT64(base, DesignwarePCIEViewport),
  VMSTATE_UINT64(target, DesignwarePCIEViewport),
-VMSTATE_UINT32(limit, DesignwarePCIEViewport),
+VMSTATE_UINT64(limit, DesignwarePCIEViewport),


Unfortunately this breaks the migration stream. I'm not sure
what is the best way to deal with it (Cc'ing migration
maintainers).


  VMSTATE_UINT32_ARRAY(cr, DesignwarePCIEViewport, 2),
  VMSTATE_END_OF_LIST()
  }

Regards,

Phil.



Re: [PATCH] pc-bios/optionrom: Fix pvh.img ld build failure on fedora rawhide

2024-01-21 Thread Cole Robinson
On 1/3/24 10:44 AM, Gerd Hoffmann wrote:
> On Wed, Jan 03, 2024 at 12:44:39PM +, Daniel P. Berrangé wrote:
>> On Tue, Nov 28, 2023 at 09:36:47AM -0500, Cole Robinson wrote:
>>> binutils 2.39 shows some warnings when building pvh.img
>>>
>>> /usr/bin/ld: warning: pvh.o: missing .note.GNU-stack section implies 
>>> executable stack
>>> /usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a 
>>> future version of the linker
>>> /usr/bin/ld: warning: pvh.img has a LOAD segment with RWX permissions
>>>
>>> The latter of which is fatal on Fedora rawhide for some reason.
>>>
>>> Add linker options to suppress the errors
>>
>> This makes it silent, but I guess someone needs to confirm that this
>> option ROM code genuinely does NOT need to have executable stack,
>> otherwise the future change that is being warned about could impact
>> it ?
> 
> Skimming the code it does not look like it depends on a execute-able
> stack.  Beside that the option rom will be loaded as raw binary by
> seabios and run without paging.  There is nothing which could actually
> setup and enforce an NX stack ...
> 
> Acked-by: Gerd Hoffmann 
> 

I just realized this breaks the build on centos 9 with binutils
2.35.2-42.el9

make[1]: Leaving directory
'/builddir/build/BUILD/qemu-8.2.0/qemu_kvm_build/pc-bios/optionrom'
make[1]: Entering directory
'/builddir/build/BUILD/qemu-8.2.0/qemu_kvm_build/pc-bios/optionrom'
gcc -O2 -g -march=i486 -Wall -m32 -m16 -ffreestanding
-I/builddir/build/BUILD/qemu-8.2.0/include -fcf-protection=none -fno-pie
-no-pie -fno-stack-protector -Wno-array-bounds -nostdlib
-Wl,--build-id=none,-T,/builddir/build/BUILD/qemu-8.2.0/pc-bios/optionrom/flat.lds
-Wl,--no-warn-rwx-segments -Wl,--no-warn-execstack -s -o multiboot.img
multiboot.o
/usr/bin/ld: unrecognized option '--no-warn-rwx-segments'
/usr/bin/ld: use the --help option for usage information

This article has tips about how to fix these issues in the linker
scripts, so maybe that's the better approach:

https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments

Thanks,
Cole




[PATCH] tcg/arm: Fix SIGILL in tcg_out_qemu_st_direct

2024-01-21 Thread Joseph Burt
When tcg_out_qemu_st_{index,direct} were merged, the direct case for
MO_64 was omitted, causing qemu_st_i64 to be encoded as 0x due
to underflow when adding h.base and h.index.

Fixes: 1df6d611bdc2("tcg/arm: Introduce HostAddress")
Signed-off-by: Joseph Burt 
---
 tcg/arm/tcg-target.c.inc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index fc78566494..a9aa8aa91c 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1662,6 +1662,9 @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp 
opc, TCGReg datalo,
 } else {
 tcg_out_strd_r(s, h.cond, datalo, h.base, h.index);
 }
+} else if (h.index < 0) {
+tcg_out_st32_12(s, h.cond, datalo, h.base, 0);
+tcg_out_st32_12(s, h.cond, datahi, h.base, 4);
 } else if (h.index_scratch) {
 tcg_out_st32_rwb(s, h.cond, datalo, h.index, h.base);
 tcg_out_st32_12(s, h.cond, datahi, h.index, 4);
-- 
2.42.0




[PATCH v3] Handle wrap around in limit calculation

2024-01-21 Thread Shlomo Pongratz
From: Shlomo Pongratz 

Hanlde wrap around when calculating the viewport size
caused by the fact that perior to version 460A the limit variable
was 32bit quantity and not 64 bits quantity.
In the i.MX 6Dual/6Quad Applications Processor Reference Manual
document on which the original code was based upon in the
description of the iATU Region Upper Base Address Register it is
written:
Forms bits [63:32] of the start (and end) address of the address region to 
be
translated.
That is in this register is the upper of both base and the limit.
In the current implementation this value was ignored for the limit
which caused a wrap around of the size calculaiton.
Using the documnet example:
Base HI: 0x8000 Base LO: 0xd000 Limit LO: 0xd000
The correct size is 0x8000d000 - 0x8000d000 + 1 =
0x01
The wrong result is 0xd000 - 0x8000d000 + 1 = 0x8001

Signed-off-by: Shlomo Pongratz 



Changes since v2:
 * Don't try to fix the calculation.
 * Change the limit variable from 32bit to 64 bit
 * Set the limit bits [63:32] same as the base according to
   the specification on which the original code was base upon.

Changes since v1:
 * Seperate subject and description
---
 hw/pci-host/designware.c | 19 ++-
 include/hw/pci-host/designware.h |  2 +-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index dd9e389c07..43cba9432f 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -269,7 +269,7 @@ static void 
designware_pcie_update_viewport(DesignwarePCIERoot *root,
 {
 const uint64_t target = viewport->target;
 const uint64_t base   = viewport->base;
-const uint64_t size   = (uint64_t)viewport->limit - base + 1;
+const uint64_t size   = viewport->limit - base + 1;
 const bool enabled= viewport->cr[1] & DESIGNWARE_PCIE_ATU_ENABLE;
 
 MemoryRegion *current, *other;
@@ -351,6 +351,14 @@ static void designware_pcie_root_config_write(PCIDevice 
*d, uint32_t address,
 case DESIGNWARE_PCIE_ATU_UPPER_BASE:
 viewport->base &= 0xULL;
 viewport->base |= (uint64_t)val << 32;
+/* The documentatoin states that the value of this register
+ * "Forms bits [63:32] of the start (and end) address
+ * of the address region to be translated.
+ * Note that from version 406A there is a sperate
+ * register fot the upper end address
+ */
+viewport->limit &= 0xULL;
+viewport->limit |= (uint64_t)val << 32;
 break;
 
 case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
@@ -364,7 +372,8 @@ static void designware_pcie_root_config_write(PCIDevice *d, 
uint32_t address,
 break;
 
 case DESIGNWARE_PCIE_ATU_LIMIT:
-viewport->limit = val;
+viewport->limit &= 0xULL;
+viewport->limit |= val;
 break;
 
 case DESIGNWARE_PCIE_ATU_CR1:
@@ -429,7 +438,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
 viewport->inbound = true;
 viewport->base= 0xULL;
 viewport->target  = 0xULL;
-viewport->limit   = UINT32_MAX;
+viewport->limit   = 0xULL;
 viewport->cr[0]   = DESIGNWARE_PCIE_ATU_TYPE_MEM;
 
 source  = &host->pci.address_space_root;
@@ -453,7 +462,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
 viewport->inbound = false;
 viewport->base= 0xULL;
 viewport->target  = 0xULL;
-viewport->limit   = UINT32_MAX;
+viewport->limit   = 0xULL;
 viewport->cr[0]   = DESIGNWARE_PCIE_ATU_TYPE_MEM;
 
 destination = &host->pci.memory;
@@ -560,7 +569,7 @@ static const VMStateDescription 
vmstate_designware_pcie_viewport = {
 .fields = (const VMStateField[]) {
 VMSTATE_UINT64(base, DesignwarePCIEViewport),
 VMSTATE_UINT64(target, DesignwarePCIEViewport),
-VMSTATE_UINT32(limit, DesignwarePCIEViewport),
+VMSTATE_UINT64(limit, DesignwarePCIEViewport),
 VMSTATE_UINT32_ARRAY(cr, DesignwarePCIEViewport, 2),
 VMSTATE_END_OF_LIST()
 }
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
index 908f3d946b..51052683b7 100644
--- a/include/hw/pci-host/designware.h
+++ b/include/hw/pci-host/designware.h
@@ -41,7 +41,7 @@ typedef struct DesignwarePCIEViewport {
 
 uint64_t base;
 uint64_t target;
-uint32_t limit;
+uint64_t limit;
 uint32_t cr[2];
 
 bool inbound;
-- 
2.25.1




Re: [PATCH] hw/arm/musicpal: Convert to qemu_add_kbd_event_handler()

2024-01-21 Thread Jan Kiszka
On 19.01.24 12:24, Alex Bennée wrote:
> Peter Maydell  writes:
>
>> Convert the musicpal key input device to use
>> qemu_add_kbd_event_handler().  This lets us simplify it because we no
>> longer need to track whether we're in the middle of a PS/2 multibyte
>> key sequence.
>>
>> In the conversion we move the keyboard handler registration from init
>> to realize, because devices shouldn't disturb the state of the
>> simulation by doing things like registering input handlers until
>> they're realized, so that device objects can be introspected
>> safely.
>>
>> The behaviour where key-repeat is permitted for the arrow-keys only
>> is intentional (added in commit 7c6ce4baedfcd0c), so we retain it,
>> and add a comment to that effect.
>
> Well the key input all works as intended and looks good to me. I'm a
> little disappointed I couldn't get audio working on the musicpal machine
> but that is not a problem for this patch.
>
> Tested-by: Alex Bennée 
> Reviewed-by: Alex Bennée 
>

Looks good to me as well, all keys still work fine.

No idea what's the issue with sound, though. I think I haven't run the
whole stuff in a decade or so, had to search for all the pieces first of
all again. The webradio service original behind this stopped their
operations, at least for this device, but manually entered favorits
still work on the real device - I still have one, though that is
starting to get some issues as well.

Thanks,
Jan




Re: [PULL 17/22] plugins: add an API to read registers

2024-01-21 Thread Akihiko Odaki

On 2024/01/18 20:38, Alex Bennée wrote:

Akihiko Odaki  writes:


On 2024/01/16 19:48, Alex Bennée wrote:

We can only request a list of registers once the vCPU has been
initialised so the user needs to use either call the get function on
vCPU initialisation or during the translation phase.
We don't expose the reg number to the plugin instead hiding it
behind
an opaque handle. This allows for a bit of future proofing should the
internals need to be changed while also being hashed against the
CPUClass so we can handle different register sets per-vCPU in
hetrogenous situations.
Having an internal state within the plugins also allows us to expand
the interface in future (for example providing callbacks on register
change if the translator can track changes).
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1706
Cc: Akihiko Odaki 
Message-Id: <20240103173349.398526-39-alex.ben...@linaro.org>
Based-on: <20231025093128.33116-18-akihiko.od...@daynix.com>
Signed-off-by: Alex Bennée 
Reviewed-by: Pierrick Bouvier 
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 4daab6efd29..2c1930e7e45 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -11,6 +11,7 @@
   #ifndef QEMU_QEMU_PLUGIN_H
   #define QEMU_QEMU_PLUGIN_H
   +#include 
   #include 
   #include 
   #include 
@@ -227,8 +228,8 @@ struct qemu_plugin_insn;
* @QEMU_PLUGIN_CB_R_REGS: callback reads the CPU's regs
* @QEMU_PLUGIN_CB_RW_REGS: callback reads and writes the CPU's regs
*
- * Note: currently unused, plugins cannot read or change system
- * register state.
+ * Note: currently QEMU_PLUGIN_CB_RW_REGS is unused, plugins cannot change
+ * system register state.
*/
   enum qemu_plugin_cb_flags {
   QEMU_PLUGIN_CB_NO_REGS,
@@ -708,4 +709,50 @@ uint64_t qemu_plugin_end_code(void);
   QEMU_PLUGIN_API
   uint64_t qemu_plugin_entry_code(void);
   +/** struct qemu_plugin_register - Opaque handle for register
access */
+struct qemu_plugin_register;
+
+/**
+ * typedef qemu_plugin_reg_descriptor - register descriptions
+ *
+ * @handle: opaque handle for retrieving value with qemu_plugin_read_register
+ * @name: register name
+ * @feature: optional feature descriptor, can be NULL
+ */
+typedef struct {
+struct qemu_plugin_register *handle;
+const char *name;
+const char *feature;
+} qemu_plugin_reg_descriptor;
+
+/**
+ * qemu_plugin_get_registers() - return register list for vCPU
+ * @vcpu_index: vcpu to query
+ *
+ * Returns a GArray of qemu_plugin_reg_descriptor or NULL. Caller
+ * frees the array (but not the const strings).
+ *
+ * Should be used from a qemu_plugin_register_vcpu_init_cb() callback
+ * after the vCPU is initialised.
+ */
+GArray *qemu_plugin_get_registers(unsigned int vcpu_index);
+
+/**
+ * qemu_plugin_read_register() - read register
+ *
+ * @vcpu: vcpu index
+ * @handle: a @qemu_plugin_reg_handle handle
+ * @buf: A GByteArray for the data owned by the plugin
+ *
+ * This function is only available in a context that register read access is
+ * explicitly requested.
+ *
+ * Returns the size of the read register. The content of @buf is in target byte
+ * order. On failure returns -1
+ */
+int qemu_plugin_read_register(unsigned int vcpu,
+  struct qemu_plugin_register *handle,
+  GByteArray *buf);
+
+
   #endif /* QEMU_QEMU_PLUGIN_H */
diff --git a/plugins/api.c b/plugins/api.c
index ac39cdea0b3..8d5cca53295 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -8,6 +8,7 @@
*
*  qemu_plugin_tb
*  qemu_plugin_insn
+ *  qemu_plugin_register
*
* Which can then be passed back into the API to do additional things.
* As such all the public functions in here are exported in
@@ -35,10 +36,12 @@
*/
 #include "qemu/osdep.h"
+#include "qemu/main-loop.h"
   #include "qemu/plugin.h"
   #include "qemu/log.h"
   #include "tcg/tcg.h"
   #include "exec/exec-all.h"
+#include "exec/gdbstub.h"
   #include "exec/ram_addr.h"
   #include "disas/disas.h"
   #include "plugin.h"
@@ -435,3 +438,111 @@ uint64_t qemu_plugin_entry_code(void)
   #endif
   return entry;
   }
+
+/*
+ * Register handles
+ *
+ * The plugin infrastructure keeps hold of these internal data
+ * structures which are presented to plugins as opaque handles. They
+ * are global to the system and therefor additions to the hash table
+ * must be protected by the @reg_handle_lock.


The BQL should be used instead. This lock only serializes the plugin
access, but the whole gdbstub code needs to be serialized to ensure
the correct behaving of e.g., gdb_get_register_list().


Why does gdb_get_register_list need to take the BQL? It only works
through per-cpu structures. The reg_handle_lock only protects the hash
table itself.




+ *
+ * In order to future proof for up-coming heterogeneous work we want
+ * different entries for each CPU type while sharing them in the
+ * common case of multiple cores of the same type.


I don't think such an ef

Re: [PATCH v3 0/3] nubus: add nubus-virtio-mmio device

2024-01-21 Thread Mark Cave-Ayland

On 11/01/2024 10:29, Mark Cave-Ayland wrote:


This series introduces a new nubus-virtio-mmio device which can be plugged into
the q800 machine to enable a 68k Classic MacOS guest to access virtio devices
such as virtio-9p-device (host filesharing), virtio-gpu (extended framebuffer
support) and virtio-tablet-device (absolute positioning).

Once the nubus-virtio-mmio device has been plugged into the q800 machine, virtio
devices can be accessed by a Classic MacOS guest using the drivers from the
classicvirtio project at https://github.com/elliotnunn/classicvirtio.

The nubus-virtio-mmio device is purposefully designed to be similar to the
virtio-mmio interface used by the existing 68k virt machine, making use of a
similar memory layout and the goldfish PIC for simple interrupt management. The
main difference is that only a single goldfish PIC is used, however that still
allows up to 32 virtio devices to be connected using a single nubus card.

Patch 1 fixes an alignment bug in the existing nubus-device Declaration ROM code
whereby some ROM images could trigger an assert() in QEMU, patch 2 increases the
maximum Declaration ROM size (to aid development), whilst patch 3 adds the
nubus-virtio-mmio device itself.

Signed-off-by: Mark Cave-Ayland 

[Patches still needing review: 2, 3]

v3:
- Rebase onto master
- Update patch 1 alignment calculation to use intermediatery uint8_t rom_ptr
   variable, add Phil's R-B tag
- Add patch 2 to increase maximum Declaration ROM size to 1MB

v2:
- Rebase onto master
- Adjust comment in patch 1 as suggested by Phil


Mark Cave-Ayland (3):
   nubus-device: round Declaration ROM memory region address to
 qemu_target_page_size()
   nubus.h: increase maximum Declaration ROM size from 128k to 1Mb
   nubus: add nubus-virtio-mmio device

  hw/nubus/meson.build |   1 +
  hw/nubus/nubus-device.c  |  18 +++--
  hw/nubus/nubus-virtio-mmio.c | 102 +++
  include/hw/nubus/nubus-virtio-mmio.h |  36 ++
  include/hw/nubus/nubus.h |   2 +-
  5 files changed, 154 insertions(+), 5 deletions(-)
  create mode 100644 hw/nubus/nubus-virtio-mmio.c
  create mode 100644 include/hw/nubus/nubus-virtio-mmio.h


Ping?


ATB,

Mark.




Re: [PATCH 0/4] esp-pci: fixes for Linux and MS-DOS

2024-01-21 Thread Mark Cave-Ayland

On 20/01/2024 13:09, Michael Tokarev wrote:


12.01.2024 16:15, Mark Cave-Ayland:

This series contains fixes for the esp-pci device (am53c974 or dc390) for a
few issues spotted whilst testing the previous ESP series.

Patches 1-3 are fixes for issues found by Helge/Guenter whilst testing the
hppa C3700 machine with the amd53c974/dc390 devices under Linux, whilst patch
4 fixes an issue that was exposed by testing MS-DOS and Windows drivers.

With this series applied on top of the reworked ESP device, it is possible to
boot Linux under qemu-system-hppa without any errors and also boot and install
Win98SE from a DC390 PCI SCSI controller (no IDE!) using an MS-DOS boot floppy.

Signed-off-by: Mark Cave-Ayland 
Based-on: 20240112125420.514425-1-mark.cave-ayl...@ilande.co.uk


Mark Cave-Ayland (4):
   esp-pci.c: use correct address register for PCI DMA transfers
   esp-pci.c: generate PCI interrupt from separate ESP and PCI sources
   esp-pci.c: synchronise setting of DMA_STAT_DONE with ESP completion
 interrupt
   esp-pci.c: set DMA_STAT_BCMBLT when BLAST command issued


Is it worth to pick up for stable?  Especially the first one.
It's interesting this bug is here for a very long time.. :)


Good question! I did my comprehensive boot tests with this series on top of the core 
ESP series so I can't say that I've tested this series on its own. Then again other 
than the DMA_STAT_DONE patch which is a timing change, the rest of the patches are 
fixing specific edge cases which were already broken so I would be surprised if 
anything broke.



ATB,

Mark.




Re: [PATCH 0/5] buses: switch to 3-phase-reset

2024-01-21 Thread Michael S. Tsirkin
On Fri, Jan 19, 2024 at 04:35:07PM +, Peter Maydell wrote:
> This patchset switches the handful of bus types that implement a
> reset method over to using the 3-phase-reset APIs, and then removes
> the transitional infrastructure from the core bus class that was
> supporting the ability to have bus types that use old-style reset.
> 
> I wrote this ages ago and recently picked it back up because of a
> recent PCI related reset ordering problem noted by Peter Xu.  I'm not
> sure if this patchset is necessary as a part of fixing that ordering
> problem (it might even be possible now to have the intel_iommu device
> use 3-phase reset and put the relevant parts of its reset into the
> 'exit' phase), but either way we really ought to do this cleanup
> to reduce the amount of legacy/transitional handling we have.
> 
> In theory this patchset should be fine and shouldn't be changing
> behaviour.  On the other hand the reason I never sent it out when I
> originally wrote it was that I ran into a test failure in the
> BootLinuxConsole.test_sh4_r2d avocado test.  Rerunning all the
> avocado tests I don't see that failing now, so maybe I was just
> confused by a flaky test back then.
> 
> In any case, this could probably use a thorough soak testing with
> workloads that do resets of the PCI bus; I've only done 'make check'
> and 'make check-avocado' on it.  But I wanted to get it out onto the
> list anyway.
> 
> thanks
> -- PMM

>From a quick look, we need this cleanup

Acked-by: Michael S. Tsirkin 

I'll try some tests too, and report.

> Peter Maydell (5):
>   pci: Switch bus reset to 3-phase-reset
>   vmbus: Switch bus reset to 3-phase-reset
>   adb: Switch bus reset to 3-phase-reset
>   hw/s390x/css-bridge: switch virtual-css bus to 3-phase-reset
>   hw/core: Remove transitional infrastructure from BusClass
> 
>  include/hw/qdev-core.h |  2 --
>  hw/core/bus.c  | 67 --
>  hw/hyperv/vmbus.c  |  7 +++--
>  hw/input/adb.c |  7 +++--
>  hw/pci/pci.c   | 10 ---
>  hw/s390x/css-bridge.c  |  5 ++--
>  6 files changed, 17 insertions(+), 81 deletions(-)
> 
> -- 
> 2.34.1