Re: [PATCH v4 1/6] target/ppc: Fix instruction loading endianness in alignment interrupt

2023-06-13 Thread Anushree Mathur


On 5/30/23 18:55, Nicholas Piggin wrote:

powerpc ifetch endianness depends on MSR[LE] so it has to byteswap
after cpu_ldl_code(). This corrects DSISR bits in alignment
interrupts when running in little endian mode.

Reviewed-by: Fabiano Rosas
Signed-off-by: Nicholas Piggin
---
  target/ppc/excp_helper.c | 22 +-
  1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index c13f2afa04..0274617b4a 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -133,6 +133,26 @@ static void dump_hcall(CPUPPCState *env)
env->nip);
  }
  
+#ifdef CONFIG_TCG

+/* Return true iff byteswap is needed in a scalar memop */
+static inline bool need_byteswap(CPUArchState *env)
+{
+/* SOFTMMU builds TARGET_BIG_ENDIAN. Need to swap when MSR[LE] is set */
+return !!(env->msr & ((target_ulong)1 << MSR_LE));
+}
+
+static uint32_t ppc_ldl_code(CPUArchState *env, abi_ptr addr)


This hunk fails to compile with configure --disable-tcg


FAILED: libqemu-ppc64-softmmu.fa.p/target_ppc_excp_helper.c.o
cc -m64 -mlittle-endian -Ilibqemu-ppc64-softmmu.fa.p -I. -I..
-Itarget/ppc -I../target/ppc -I../dtc/libfdt -Iqapi -Itrace -Iui
-Iui/shader -I/usr/include/pixman-1 -I/usr/include/glib-2.0
-I/usr/lib64/glib-2.0/include -I/usr/include/sysprof-4
-fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g
-fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -Wundef
-Wwrite-strings -Wmissing-prototypes -Wstrict-prototypes
-Wredundant-decls -Wold-style-declaration -Wold-style-definition
-Wtype-limits -Wformat-security -Wformat-y2k -Winit-self
-Wignored-qualifiers -Wempty-body -Wnested-externs -Wendif-labels
-Wexpansion-to-defined -Wimplicit-fallthrough=2
-Wmissing-format-attribute -Wno-missing-include-dirs
-Wno-shift-negative-value -Wno-psabi -isystem
/home/Shreya/qemu/linux-headers -isystem linux-headers -iquote . -iquote
/home/Shreya/qemu -iquote /home/Shreya/qemu/include -pthread
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-fno-strict-aliasing -fno-common -fwrapv -fPIE -isystem../linux-headers
-isystemlinux-headers -DNEED_CPU_H
'-DCONFIG_TARGET="ppc64-softmmu-config-target.h"'
'-DCONFIG_DEVICES="ppc64-softmmu-config-devices.h"' -MD -MQ
libqemu-ppc64-softmmu.fa.p/target_ppc_excp_helper.c.o -MF
libqemu-ppc64-softmmu.fa.p/target_ppc_excp_helper.c.o.d -o
libqemu-ppc64-softmmu.fa.p/target_ppc_excp_helper.c.o -c
../target/ppc/excp_helper.c
../target/ppc/excp_helper.c:143:49: error: unknown type name ‘abi_ptr’;
did you mean ‘si_ptr’?
    143 | static uint32_t ppc_ldl_code(CPUArchState *env, abi_ptr addr)
    | ^~~
    | si_ptr
../target/ppc/excp_helper.c: In function ‘powerpc_excp_books’:
../target/ppc/excp_helper.c:1416:16: error: implicit declaration of
function ‘ppc_ldl_code’ [-Werror=implicit-function-declaration]
   1416 | insn = ppc_ldl_code(env, env->nip);
    |    ^~~~
../target/ppc/excp_helper.c:1416:16: error: nested extern declaration of
‘ppc_ldl_code’ [-Werror=nested-externs]
cc1: all warnings being treated as errors



+{
+uint32_t insn = cpu_ldl_code(env, addr);
+
+if (need_byteswap(env)) {
+insn = bswap32(insn);
+}
+
+return insn;
+}
+#endif
+
  static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
  {
  const char *es;
@@ -3100,7 +3120,7 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr 
vaddr,
  
  /* Restore state and reload the insn we executed, for filling in DSISR.  */

  cpu_restore_state(cs, retaddr);
-insn = cpu_ldl_code(env, env->nip);
+insn = ppc_ldl_code(env, env->nip);
  
  switch (env->mmu_model) {

  case POWERPC_MMU_SOFT_4xx:

Re: [PATCH v2 22/23] target/arm: Convert load/store single structure to decodetree

2023-06-13 Thread Richard Henderson

On 6/11/23 18:00, Peter Maydell wrote:

Convert the ASIMD load/store single structure insns to decodetree.

Signed-off-by: Peter Maydell
Message-id:20230602155223.2040685-20-peter.mayd...@linaro.org
---
  target/arm/tcg/a64.decode  |  34 +
  target/arm/tcg/translate-a64.c | 219 +++--
  2 files changed, 136 insertions(+), 117 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 14/23] target/arm: Convert load/store-pair to decodetree

2023-06-13 Thread Richard Henderson

On 6/11/23 18:00, Peter Maydell wrote:

Convert the load/store register pair insns (LDP, STP,
LDNP, STNP, LDPSW, STGP) to decodetree.

Signed-off-by: Peter Maydell
Message-id:20230602155223.2040685-12-peter.mayd...@linaro.org
---
This was reviewed in v1, but the underlying code
changed enough in the atomic-ops work that I've dropped
the R-by tag.
---
  target/arm/tcg/a64.decode  |  61 +
  target/arm/tcg/translate-a64.c | 425 -
  2 files changed, 271 insertions(+), 215 deletions(-)


Reviewed-by: Richard Henderson 



+static bool trans_STP(DisasContext *s, arg_ldstpair *a)
+{
+uint64_t offset = a->imm << a->sz;
+TCGv_i64 clean_addr, dirty_addr, tcg_rt, tcg_rt2;
+MemOp mop = finalize_memop(s, a->sz);
+
+op_addr_ldstpair_pre(s, a, _addr, _addr, offset, true, mop);
+tcg_rt = cpu_reg(s, a->rt);
+tcg_rt2 = cpu_reg(s, a->rt2);
+/*
+ * We built mop above for the single logical access -- rebuild it
+ * now for the paired operation.
+ *
+ * With LSE2, non-sign-extending pairs are treated atomically if
+ * aligned, and if unaligned one of the pair will be completely
+ * within a 16-byte block and that element will be atomic.
+ * Otherwise each element is separately atomic.
+ * In all cases, issue one operation with the correct atomicity.
+ *
+ * This treats sign-extending loads like zero-extending loads,
+ * since that reuses the most code below.
+ */


Could lose the bit about loads within the store function.


r~



Re: [PATCH 1/4] pnv/chiptod: Add POWER9/10 chiptod model

2023-06-13 Thread Nicholas Piggin
On Tue Jun 6, 2023 at 12:57 AM AEST, Cédric Le Goater wrote:
> On 6/4/23 01:36, Nicholas Piggin wrote:

> > diff --git a/hw/ppc/pnv_chiptod.c b/hw/ppc/pnv_chiptod.c
> > new file mode 100644
> > index 00..04ef703e0f
> > --- /dev/null
> > +++ b/hw/ppc/pnv_chiptod.c
> > @@ -0,0 +1,488 @@
> > +/*
> > + * QEMU PowerPC PowerNV Emulation of some CHIPTOD behaviour
> > + *
> > + * Copyright (c) 2022-2023, IBM Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License, version 2, as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, see .
>
> You can simplify the header with
>
>   * SPDX-License-Identifier: GPL-2.0-or-later

Sure.

> > +
> > +static void chiptod_power9_send_remotes(PnvChipTOD *chiptod)
>
> Adding a class handler could be an alternative implementation.

Might be a good idea, I'll see how it looks.

> > +{
> > +PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
> > +int i;
> > +
> > +for (i = 0; i < pnv->num_chips; i++) {
>
> There are a few other models (XIVE, XIVE2) which loop on the chips,
> is it time to introduce a pnv_foreach_chip(fn, data) routine ?
>
>
> > +Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
> > +if (>chiptod != chiptod) {
> > +chip9->chiptod.tod_state = tod_running;
> > +}
> > +}
> > +}

[snip]

> > +case TOD_TX_TTYPE_CTRL_REG:
> > +if (val & PPC_BIT(35)) { /* SCOM addressing */
> > +uint32_t addr = val >> 32;
> > +uint32_t reg = addr & 0xfff;
> > +PnvCore *pc;
> > +
> > +if (reg != PC_TOD) {
> > +qemu_log_mask(LOG_GUEST_ERROR, "pnv_chiptod: SCOM 
> > addressing: "
> > +  "unimplemented slave register 0x%" PRIx32 
> > "\n",
> > +  reg);
> > +return;
> > +}
> > +
> > +/*
> > + * This may not deal with P10 big-core addressing at the 
> > moment.
> > + * The big-core code in skiboot syncs small cores, but it 
> > targets
> > + * the even PIR (first small-core) when syncing second 
> > small-core.
> > + */
> > +pc = pnv_get_vcpu_by_xscom_base(chiptod->chip, addr & ~0xfff);
>
> hmm, couldn't we map xscom subregions, one for each thread instead ?

I'm not sure what you mean. This scom-addressing uses the xscom
address of the core's PC unit (where its time facilities are) to
point nest chiptod transfers to cores.

>
> > +if (pc) {
> > +/*
> > + * If TCG implements SMT, TFMR is a per-core SPR and should
> > + * be updated such that it is reflected in all threads.
> > + * Same for TB if the chiptod model ever actually adjusted 
> > it.
> > + */
> > +chiptod->slave_cpu_target = pc->threads[0];
>
> ah ! SMT is implemented :) The xscom subregions would help to get the
> CPU pointer.

I think I may be mistaken at least in the "get_vcpu" part. I think
it should be get core, I don't know if chiptod is capable of addressing
threads individually.

I could test it with SMT patches and see what skiboot does.

> > +static int pnv_chiptod_dt_xscom(PnvXScomInterface *dev, void *fdt,
> > +int xscom_offset,
> > +const char compat[], size_t compat_size)
> > +{
> > +PnvChipTOD *chiptod = PNV_CHIPTOD(dev);
> > +g_autofree char *name = NULL;
> > +int offset;
> > +uint32_t lpc_pcba = PNV9_XSCOM_CHIPTOD_BASE;
>
> lpc ?

Shh don't tell anybody I mostly code via copy and paste :P

[snip]

> > +static void pnv_chiptod_realize(DeviceState *dev, Error **errp)
> > +{
> > +static bool got_primary = false;
> > +static bool got_secondary = false;
> > +
> > +PnvChipTOD *chiptod = PNV_CHIPTOD(dev);
> > +PnvChipTODClass *pctc = PNV_CHIPTOD_GET_CLASS(chiptod);
> > +
> > +if (!got_primary) {
> > +got_primary = true;
> > +chiptod->primary = true;
> > +chiptod->pss_mss_ctrl_reg |= PPC_BIT(1); /* TOD is master */
> > +} else if (!got_secondary) {
> > +got_secondary = true;
> > +chiptod->secondary = true;
> > +}
>
> It would be cleaner to introduce "primary" and "secondary" properties
> defined by the model realizing the PnvChipTOD objects.

Hum. There's a few hard-coded primaries on chip_id == 0 already
in the tree. I don't know how closely related they are, chiptod
can 

Re: [PATCH v2 04/23] target/arm: Consistently use finalize_memop_asimd() for ASIMD loads/stores

2023-06-13 Thread Richard Henderson

On 6/11/23 18:00, Peter Maydell wrote:

In the recent refactoring we missed a few places which should be
calling finalize_memop_asimd() for ASIMD loads and stores but
instead are just calling finalize_memop(); fix these.

For the disas_ldst_single_struct() and disas_ldst_multiple_struct()
cases, this is not a behaviour change because there the size
is never MO_128 and the two finalize functions do the same thing.

Signed-off-by: Peter Maydell
---
  target/arm/tcg/translate-a64.c | 10 ++
  1 file changed, 6 insertions(+), 4 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 03/23] target/arm: Pass memop to gen_mte_check1_mmuidx() in reg_imm9 decode

2023-06-13 Thread Richard Henderson

On 6/11/23 18:00, Peter Maydell wrote:

In disas_ldst_reg_imm9() we missed one place where a call to
a gen_mte_check* function should now be passed the memop we
have created rather than just being passed the size. Fix this.

Signed-off-by: Peter Maydell
---
  target/arm/tcg/translate-a64.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 8/9] meson: Replace CONFIG_SOFTMMU -> CONFIG_SYSTEM_ONLY

2023-06-13 Thread Richard Henderson

On 6/13/23 15:33, Philippe Mathieu-Daudé wrote:

Since we*might*  have user emulation with softmmu,
use the clearer 'CONFIG_SYSTEM_ONLY' key to check
for system emulation.

Signed-off-by: Philippe Mathieu-Daudé
---
  meson.build| 4 ++--
  accel/qtest/meson.build| 2 +-
  accel/stubs/meson.build| 2 +-
  accel/tcg/meson.build  | 6 +++---
  dump/meson.build   | 2 +-
  hw/i386/kvm/meson.build| 2 +-
  migration/meson.build  | 2 +-
  monitor/meson.build| 2 +-
  qapi/meson.build   | 2 +-
  semihosting/meson.build| 2 +-
  softmmu/meson.build| 4 ++--
  target/i386/tcg/sysemu/meson.build | 2 +-
  ui/meson.build | 4 ++--
  13 files changed, 18 insertions(+), 18 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 7/9] meson: Alias CONFIG_SOFTMMU -> CONFIG_SYSTEM_ONLY

2023-06-13 Thread Richard Henderson

On 6/13/23 15:33, Philippe Mathieu-Daudé wrote:

We use the CONFIG_USER_ONLY key to describe user emulation,
and the CONFIG_SOFTMMU key to describe system emulation. Alias
it as 'CONFIG_SYSTEM_ONLY' for parity with user emulation.

Signed-off-by: Philippe Mathieu-Daudé
---
  meson.build | 1 +
  1 file changed, 1 insertion(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v3 1/9] target/i386: Simplify i386_tr_init_disas_context()

2023-06-13 Thread Richard Henderson

On 6/13/23 15:33, Philippe Mathieu-Daudé wrote:

Since cpu_mmu_index() is well-defined for user-only,
we can remove the surrounding #ifdef'ry entirely.

Suggested-by: Richard Henderson
Signed-off-by: Philippe Mathieu-Daudé
---
  target/i386/tcg/translate.c | 3 ---
  1 file changed, 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 0/4] ppc/pnv: Add chiptod and core timebase state machine models

2023-06-13 Thread Nicholas Piggin
On Tue Jun 6, 2023 at 11:59 PM AEST, Cédric Le Goater wrote:
> On 6/4/23 01:36, Nicholas Piggin wrote:
> > This adds support for chiptod and core timebase state machine models in
> > the powernv POWER9 and POWER10 models.
> > 
> > This does not actually change the time or the value in TB registers
> > (because they are alrady synced in QEMU), but it does go through the
> > motions. It is enough to be able to run skiboot's chiptod initialisation
> > code that synchronises core timebases (after a patch to prevent skiboot
> > skipping chiptod for QEMU, posted to skiboot mailing list).
> > 
> > Sorry there was some delay since the last posting. There is a bit more
> > interest in this recently but feedback and comments from RFC was not
> > forgotten and is much appreciated.
> > 
> > https://lists.gnu.org/archive/html/qemu-ppc/2022-08/msg00324.html
> > 
> > I think I accounted for everything except moving register defines to the
> > .h file. I'm on the fence about that but if they are only used in the .c
> > file I think it's okay to keep them there for now. I cut out a lot of
> > unused ones so it's not so cluttered now.
> > 
> > Lots of other changes and fixes since that RFC. Notably:
> > - Register names changed to match the workbook names instead of skiboot.
> > - TFMR moved to timebase_helper.c from misc_helper.c
> > - More comprehensive model and error checking, particularly of TFMR.
> > - POWER10 with multi-chip support.
> > - chiptod and core timebase linked via specific state instead of TFMR.
>
>
> The chiptod units are not exposed to the OS, it is all handled at FW
> level AFAIK. Could the OPAL people provide some feedback on the low level
> models ?

Well, no takers so far. I guess I'm a OPAL people :)

I did some of the P10 chiptod addressing in skiboot, at least. This
patch does work with the skiboot chiptod driver at least.

I would eventually like to add in the ability to actually change the
TB with it, and inject errors and generate HMIs because that's an area
that seem to be a bit lacking (most of such testing seemed to be done
on real hardware using special time facility corruption injection).

But yes for now it is a bit difficult to verify it does much useful
aside from booting skiboot (+ patch to enable chiptod on QEMU I posted
recently).

Thanks,
Nick



Re: [PATCH v2 25/26] target/arm/tcg: Rename 'helper.h' -> 'tcg/helper.h.inc'

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

Since commit 139c1837db ("meson: rename included C source files
to .c.inc"), QEMU standard procedure for included C files is to
use *.c.inc.

Besides, since commit 6a0057aa22 ("docs/devel: make a statement
about includes") this is documented as the Coding Style:

   If you do use template header files they should be named with
   the ``.c.inc`` or ``.h.inc`` suffix to make it clear they are
   being included for expansion.

Therefore rename 'helper.h' as 'helper.h.inc'. Since this file
is TCG-specific, move it to the tcg/ directory.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/tcg/translate.h| 2 +-
  target/arm/{helper.h => tcg/helper.h.inc} | 0
  target/arm/debug_helper.c | 2 +-
  target/arm/helper.c   | 2 +-
  target/arm/tcg/crypto_helper.c| 2 +-
  target/arm/tcg/helper-a64.c   | 2 +-
  target/arm/tcg/hflags.c   | 2 +-
  target/arm/tcg/m_helper.c | 2 +-
  target/arm/tcg/op_helper.c| 2 +-
  target/arm/tcg/psci.c | 2 +-
  target/arm/tcg/tlb_helper.c   | 2 +-
  target/arm/tcg/translate.c| 2 +-
  target/arm/tcg/vec_helper.c   | 2 +-
  target/arm/vfp_helper.c   | 2 +-
  14 files changed, 13 insertions(+), 13 deletions(-)
  rename target/arm/{helper.h => tcg/helper.h.inc} (100%)


Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 24/26] target/arm/tcg: Inline 'exec/helper-proto.h'

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

+++ b/target/arm/tcg/vec_helper.c
@@ -19,12 +19,15 @@
  
  #include "qemu/osdep.h"

  #include "cpu.h"
-#include "exec/helper-proto.h"
  #include "tcg/tcg-gvec-desc.h"
  #include "fpu/softfloat.h"
  #include "qemu/int128.h"
  #include "vec_internal.h"
  
+#define HELPER_H "helper.h"

+#include "exec/helper-proto.h.inc"
+#undef  HELPER_H
+
  #define HELPER_H "tcg/helper-vfp.h.inc"
  #include "exec/helper-proto.h.inc"
  #undef  HELPER_H
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index cbd78cc810..51f8e92ff7 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -19,7 +19,6 @@
  
  #include "qemu/osdep.h"

  #include "cpu.h"
-#include "exec/helper-proto.h"
  #include "internals.h"
  #ifdef CONFIG_TCG
  #include "qemu/log.h"
@@ -32,6 +31,10 @@
  
  #ifdef CONFIG_TCG
  
+#define HELPER_H "helper.h"

+#include "exec/helper-proto.h.inc"
+#undef  HELPER_H
+
  #define HELPER_H "tcg/helper-vfp.h.inc"
  #include "exec/helper-proto.h.inc"
  #undef  HELPER_H


Are these really required, or are you simply replacing what you removed?

r~



Re: [PATCH v2 23/26] target/arm/tcg: Inline 'exec/helper-gen.h'

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

+++ b/target/arm/helper.c
@@ -26,6 +26,11 @@
  #include "qapi/error.h"
  #include "qemu/guest-random.h"
  #ifdef CONFIG_TCG
+
+#define HELPER_H "helper.h"
+#include "exec/helper-gen.h.inc"
+#undef  HELPER_H



Why is this here?  helper-gen is for tcg code generation, which should not be required at 
all in this file.  I can't see how the modification to translate.h affects this.



r~



Re: [PATCH v2 22/26] target/arm/tcg: Reduce 'helper-m.h.inc' inclusion

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

+++ b/target/arm/tcg/translate.c
@@ -37,6 +37,11 @@
  #include "exec/helper-gen.h.inc"
  #undef  HELPER_H
  
+#define HELPER_H "tcg/helper-m.h.inc"

+#include "exec/helper-proto.h.inc"
+#include "exec/helper-gen.h.inc"
+#undef  HELPER_H


You don't need helper-proto.h here do you?

Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v2 21/26] target/arm/tcg: Extract M-profile definitions to 'helper-m.h.inc'

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

helper.h is used by all units, but not all require the
M-profile definitions. Move them to a new header; the next
commit will remove it from the common helper.h.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/helper.h   | 17 ++---
  target/arm/tcg/helper-m.h.inc | 23 +++
  2 files changed, 25 insertions(+), 15 deletions(-)
  create mode 100644 target/arm/tcg/helper-m.h.inc


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 20/26] target/arm/tcg: Move v8m_stackcheck() from op_helper.c to m_helper.c

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

No need to have the v8m_stackcheck() helper in the generic
op_helper.c, move it with the rest of the M-profile helpers.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/tcg/m_helper.c  | 16 
  target/arm/tcg/op_helper.c | 16 
  2 files changed, 16 insertions(+), 16 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 19/26] target/arm/tcg: Reduce 'helper-a64.h.inc' inclusion

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

Instead of including helper-a64.h.inc via helper.h which
is included by all TCG files, restrict it to the few files
that require it.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/helper.h| 4 
  target/arm/tcg/helper-a64.c| 4 
  target/arm/tcg/mte_helper.c| 4 +++-
  target/arm/tcg/pauth_helper.c  | 4 +++-
  target/arm/tcg/sve_helper.c| 5 -
  target/arm/tcg/translate-a64.c | 6 ++
  target/arm/tcg/vec_helper.c| 4 
  7 files changed, 24 insertions(+), 7 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 18/26] target/arm/tcg: Reduce 'helper-sme.h.inc' inclusion

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

Instead of including helper-sme.h.inc via helper.h which
is included by all TCG files, restrict it to the few files
that require it.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/helper.h| 1 -
  target/arm/tcg/sme_helper.c| 5 -
  target/arm/tcg/translate-a64.c | 4 
  target/arm/tcg/translate-sme.c | 6 ++
  4 files changed, 14 insertions(+), 2 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 17/26] target/arm/tcg: Reduce 'helper-mve.h.inc' inclusion

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

Instead of including helper-mve.h.inc via helper.h which
is included by all TCG files, restrict it to the few files
that require it.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/helper.h| 2 --
  target/arm/tcg/mve_helper.c| 5 -
  target/arm/tcg/translate-mve.c | 6 ++
  target/arm/tcg/translate.c | 4 
  4 files changed, 14 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 16/26] target/arm/tcg: Reduce 'helper-sve.h.inc' inclusion

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

Instead of including helper-sve.h.inc via helper.h which
is included by all TCG files, restrict it to the few files
that require it.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/helper.h| 1 -
  target/arm/tcg/sve_helper.c| 4 
  target/arm/tcg/translate-sme.c | 4 
  target/arm/tcg/translate-sve.c | 5 +
  target/arm/tcg/vec_helper.c| 4 
  5 files changed, 17 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 14/26] target/arm/tcg: Reduce 'helper-neon.h.inc' inclusion

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

Instead of including helper-neon.h.inc via helper.h which
is included by all TCG files, restrict it to the few files
that require it.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/helper.h | 1 -
  target/arm/tcg/neon_helper.c| 5 -
  target/arm/tcg/translate-a64.c  | 4 
  target/arm/tcg/translate-neon.c | 6 ++
  target/arm/tcg/translate-sme.c  | 4 
  target/arm/tcg/translate.c  | 4 
  target/arm/tcg/vec_helper.c | 4 
  7 files changed, 26 insertions(+), 2 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 11/26] target/arm/tcg: Reduce 'helper-vfp.h.inc' inclusion

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

Instead of including helper-vfp.h.inc via helper.h which
is included by all TCG files, restrict it to the few files
that require it.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/arm/helper.h   | 1 -
  target/arm/tcg/mve_helper.c   | 4 
  target/arm/tcg/sve_helper.c   | 3 +++
  target/arm/tcg/translate-a64.c| 4 
  target/arm/tcg/translate-m-nocp.c | 5 +
  target/arm/tcg/translate-neon.c   | 4 
  target/arm/tcg/translate-vfp.c| 6 ++
  target/arm/tcg/vec_helper.c   | 4 
  target/arm/vfp_helper.c   | 4 
  9 files changed, 34 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 10/26] target/arm/tcg: Extract VFP definitions to 'helper-vfp.h.inc'

2023-06-13 Thread Richard Henderson

On 6/11/23 10:58, Philippe Mathieu-Daudé wrote:

helper.h is used by all units, but not all require the VFP
definitions. Move them to a new header; the next commit will
remove it from the common helper.h.

Signed-off-by: Philippe Mathieu-Daudé
---
TODO check recpe/rsqrte/rint* are VFP


Yep.

Reviewed-by: Richard Henderson 

r~




Support for ACK and PWR Leds in Raspberry Pi

2023-06-13 Thread Shivam
Hi, I want to add ACK and PWR leds support in the qemu raspi machine so
from the terminal of emulated raspi I should able to control these leds, I
coudn't able to understand the hardware level controlling of this leds , so
if any can help me to start on that then it would be great .

Thanks & Regards
Shivam Vijay


Re: [PULL 00/60] riscv-to-apply queue

2023-06-13 Thread Richard Henderson

On 6/14/23 03:19, Alistair Francis wrote:

The following changes since commit fdd0df5340a8ebc8de88078387ebc85c5af7b40f:

   Merge tag 'pull-ppc-20230610' ofhttps://gitlab.com/danielhb/qemu  into 
staging (2023-06-10 07:25:00 -0700)

are available in the Git repository at:

   https://github.com/alistair23/qemu.git  tags/pull-riscv-to-apply-20230614

for you to fetch changes up to 860029321d9ebdff47e89561de61e9441fead70a:

   hw/intc: If mmsiaddrcfgh.L == 1, smsiaddrcfg and smsiaddrcfgh are read-only. 
(2023-06-14 10:04:30 +1000)


Second RISC-V PR for 8.1

* Skip Vector set tail when vta is zero
* Move zc* out of the experimental properties
* Mask the implicitly enabled extensions in isa_string based on priv version
* Rework CPU extension validation and validate MISA changes
* Fixup PMP TLB cacheing errors
* Writing to pmpaddr and MML/MMWP correctly triggers TLB flushes
* Fixup PMP bypass checks
* Deny access if access is partially inside a PMP entry
* Correct OpenTitanState parent type/size
* Fix QEMU crash when NUMA nodes exceed available CPUs
* Fix pointer mask transformation for vector address
* Updates and improvements for Smstateen
* Support disas for Zcm* extensions
* Support disas for Z*inx extensions
* Remove unused decomp_rv32/64 value for vector instructions
* Enable PC-relative translation
* Assume M-mode FW in pflash0 only when "-bios none"
* Support using pflash via -blockdev option
* Add vector registers to log
* Clean up reference of Vector MTYPE
* Remove the check for extra Vector tail elements
* Smepmp: Return error when access permission not allowed in PMP
* Fixes for smsiaddrcfg and smsiaddrcfgh in AIA


Applied, thanks.  Please update https://wiki.qemu.org/ChangeLog/8.1 as 
appropriate.


r~




Re: [PULL 00/17] Misc patches for 2023-06-13

2023-06-13 Thread Richard Henderson

On 6/13/23 11:38, Philippe Mathieu-Daudé wrote:

Misc patches, some accumulated since too long.

The following changes since commit fdd0df5340a8ebc8de88078387ebc85c5af7b40f:

   Merge tag 'pull-ppc-20230610' ofhttps://gitlab.com/danielhb/qemu  into 
staging (2023-06-10 07:25:00 -0700)

are available in the Git repository at:

   https://github.com/philmd/qemu.git  tags/misc-20230613

for you to fetch changes up to b0182e537e5aba38031a5009cb16d5e924342458:

   exec/memory: Introduce RAM_NAMED_FILE flag (2023-06-13 11:28:58 +0200)


Misc patches queue

- user emulation: Preserve environment variable order
- macos/darwin/hvf: Fix build warnings, slighly optimize DCache flush
- target/i386: Minor cleanups, rename  template headers with '.inc' suffix
- target/hppa: Avoid building int_helper.o on user emulation
- hw: Add 'name' property to pca954x, export ISAParallelState, silent warnings
- hw/vfio: Trace number of bitmap dirty pages
- exec/memory: Introduce RAM_NAMED_FILE to distinct block without named backing 
store


Applied, thanks.  Please update https://wiki.qemu.org/ChangeLog/8.1 as 
appropriate.


r~




Re: [PATCH] Fix handling of AVR interrupts above 33.

2023-06-13 Thread Richard Henderson

On 6/13/23 21:34, Lucas Dietrich wrote:

This commit addresses a bug in the AVR interrupt handling code.
The modification involves replacing the usage of the ctz32 function
with ctz64 to ensure proper handling of interrupts above 33 in the AVR
target.

Previously, timers 3, 4, and 5 interrupts were not functioning correctly
because most of their interrupt vectors are numbered above 33.

Signed-off-by: Lucas Dietrich 


The change to target/avr/ looks right, but you shouldn't have all the 
subproject changes.


r~


---
  capstone  | 1 +
  dtc   | 1 +
  meson | 1 +
  roms/sgabios  | 1 +
  slirp | 1 +
  target/avr/helper.c   | 4 ++--
  tests/fp/berkeley-softfloat-3 | 1 +
  tests/fp/berkeley-testfloat-3 | 1 +
  ui/keycodemapdb   | 1 +
  9 files changed, 10 insertions(+), 2 deletions(-)
  create mode 16 capstone
  create mode 16 dtc
  create mode 16 meson
  create mode 16 roms/sgabios
  create mode 16 slirp
  create mode 16 tests/fp/berkeley-softfloat-3
  create mode 16 tests/fp/berkeley-testfloat-3
  create mode 16 ui/keycodemapdb





Re: [PULL v4 09/10] hw/arm: introduce xenpvh machine

2023-06-13 Thread Richard Henderson

On 6/12/23 02:10, Vikram Garhwal wrote:
Found the fix. QTest adds 'accel = qtest' and xen machines already have "accel = xen" 
option by default. Adding this xenpvh machine to skip fixed the issue, other xen machines 
are already in skip list. I am running the gitlab-ci locally to see if there are other fails/


Sounds right.

i checked your pipeline and can see there are other failure but unrelated to Xen. To make 
sure, are there any others failures related to my patches?


I don't think so.

Also, I am not an expert on gitlab ci flow. What i do to run gitlab-ci is this: Create a 
new gitlab pipeline with QEMU_CI = 2 and this runs around 120+ jobs. Is this enough or 
there any other variable setting needed?


That's correct.


r~




Re: [PATCH 09/10] target/ppc: Simplify syscall exception handlers

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> After previous changes the hypercall handling in 7xx and 74xx
> exception handlers can be folded into one if statement to simpilfy
> this code.
>
> Signed-off-by: BALATON Zoltan 
> ---
>  target/ppc/excp_helper.c | 26 ++
>  1 file changed, 10 insertions(+), 16 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 4f6a6dfb19..089417894e 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -738,26 +738,23 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
>  break;
>  case POWERPC_EXCP_SYSCALL:   /* System call exception
> */
>  {
> -int lev = env->error_code;
> +PowerPCCPU *cpu = env_archcpu(env);

I prefer to keep lev. Makes sense to combine the tests though
I suppose. Although with powernv it's not really clear that we
want to dump_syscall. dump_hcall is probably better (powernv
could support a non-PAPR hypervisor with different hcall
semantics, but also it could support an OS with different
syscall semantics too). I guess that could be changed back
when necessary though.

Thanks,
Nick

>  
> -if (lev == 1 && cpu->vhyp) {
> -dump_hcall(env);
> -} else {
> -dump_syscall(env);
> -}
>  /*
>   * The Virtual Open Firmware (VOF) relies on the 'sc 1'
>   * instruction to communicate with QEMU. The pegasos2 machine
>   * uses VOF and the 7xx CPUs, so although the 7xx don't have
>   * HV mode, we need to keep hypercall support.
>   */
> -if (lev == 1 && cpu->vhyp) {
> +if (unlikely(env->error_code == 1 && cpu->vhyp)) {
>  PPCVirtualHypervisorClass *vhc =
>  PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> +dump_hcall(env);
>  vhc->hypercall(cpu->vhyp, cpu);
>  return;
> +} else {
> +dump_syscall(env);
>  }
> -
>  break;
>  }
>  case POWERPC_EXCP_FPU:   /* Floating-point unavailable exception 
> */
> @@ -882,26 +879,23 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
>  break;
>  case POWERPC_EXCP_SYSCALL:   /* System call exception
> */
>  {
> -int lev = env->error_code;
> +PowerPCCPU *cpu = env_archcpu(env);
>  
> -if (lev == 1 && cpu->vhyp) {
> -dump_hcall(env);
> -} else {
> -dump_syscall(env);
> -}
>  /*
>   * The Virtual Open Firmware (VOF) relies on the 'sc 1'
>   * instruction to communicate with QEMU. The pegasos2 machine
>   * uses VOF and the 74xx CPUs, so although the 74xx don't have
>   * HV mode, we need to keep hypercall support.
>   */
> -if (lev == 1 && cpu->vhyp) {
> +if (unlikely(env->error_code == 1 && cpu->vhyp)) {
>  PPCVirtualHypervisorClass *vhc =
>  PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> +dump_hcall(env);
>  vhc->hypercall(cpu->vhyp, cpu);
>  return;
> +} else {
> +dump_syscall(env);
>  }
> -
>  break;
>  }
>  case POWERPC_EXCP_FPU:   /* Floating-point unavailable exception 
> */
> -- 
> 2.30.9




Re: [PATCH qemu v2 1/2] target/arm: Handle IC IVAU to improve compatibility with JITs

2023-06-13 Thread Richard Henderson

On 6/8/23 19:49, ~jhogberg wrote:

From: John Högberg

Unlike architectures with precise self-modifying code semantics
(e.g. x86) ARM processors do not maintain coherency for instruction
execution and memory, and require the explicit use of cache
management instructions as well as an instruction barrier to make
code updates visible (the latter on every core that is going to
execute said code).

While this is required to make JITs work on actual hardware, QEMU
has gotten away with not handling this since it does not emulate
caches, and unconditionally invalidates code whenever the softmmu
or the user-mode page protection logic detects that code has been
modified.

Unfortunately the latter does not work in the face of dual-mapped
code (a common W^X workaround), where one page is executable and
the other is writable: user-mode has no way to connect one with the
other as that is only known to the kernel and the emulated
application.

This commit works around the issue by invalidating code in
IC IVAU instructions.

Resolves:https://gitlab.com/qemu-project/qemu/-/issues/1034

Co-authored-by: Richard Henderson
Signed-off-by: John Högberg
---
  target/arm/helper.c | 47 ++---
  1 file changed, 44 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 08/10] target/ppc: Fix gen_sc to use correct nip

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> Most exceptions are raised with nip pointing to the faulting
> instruction but the sc instruction generating a syscall exception
> leaves nip pointing to next instruction. Fix gen_sc to not use
> gen_exception_err() which sets nip back but correctly set nip to
> pc_next so we don't have to patch this in the exception handlers.
>
> This changes the nip logged in dump_syscall and dump_hcall debug
> functions but now this matches how nip would be on a real CPU.
>
> Signed-off-by: BALATON Zoltan 
> ---
>  target/ppc/excp_helper.c | 39 ---
>  target/ppc/translate.c   |  8 +---
>  2 files changed, 5 insertions(+), 42 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 885e479301..4f6a6dfb19 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -493,12 +493,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  break;
>  case POWERPC_EXCP_SYSCALL:   /* System call exception
> */
>  dump_syscall(env);
> -
> -/*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> -env->nip += 4;
>  break;
>  case POWERPC_EXCP_FIT:   /* Fixed-interval timer interrupt   
> */
>  trace_ppc_excp_print("FIT");
> @@ -609,12 +603,6 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
>  break;
>  case POWERPC_EXCP_SYSCALL:   /* System call exception
> */
>  dump_syscall(env);
> -
> -/*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> -env->nip += 4;
>  break;
>  case POWERPC_EXCP_FPU:   /* Floating-point unavailable exception 
> */
>  case POWERPC_EXCP_DECR:  /* Decrementer exception
> */
> @@ -757,13 +745,6 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
>  } else {
>  dump_syscall(env);
>  }
> -
> -/*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> -env->nip += 4;
> -
>  /*
>   * The Virtual Open Firmware (VOF) relies on the 'sc 1'
>   * instruction to communicate with QEMU. The pegasos2 machine
> @@ -908,13 +889,6 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
>  } else {
>  dump_syscall(env);
>  }
> -
> -/*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> -env->nip += 4;
> -
>  /*
>   * The Virtual Open Firmware (VOF) relies on the 'sc 1'
>   * instruction to communicate with QEMU. The pegasos2 machine
> @@ -1073,12 +1047,6 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int 
> excp)
>  break;
>  case POWERPC_EXCP_SYSCALL:   /* System call exception
> */
>  dump_syscall(env);
> -
> -/*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> -env->nip += 4;
>  break;
>  case POWERPC_EXCP_FPU:   /* Floating-point unavailable exception 
> */
>  case POWERPC_EXCP_APU:   /* Auxiliary processor unavailable  
> */
> @@ -1320,13 +1288,6 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int 
> excp)
>  } else {
>  dump_syscall(env);
>  }
> -
> -/*
> - * We need to correct the NIP which in this case is supposed
> - * to point to the next instruction
> - */
> -env->nip += 4;
> -
>  /* "PAPR mode" built-in hypercall emulation */
>  if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
>  PPCVirtualHypervisorClass *vhc =
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index a32a9b8a5f..4260d3d66f 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -4419,10 +4419,12 @@ static void gen_hrfid(DisasContext *ctx)
>  #endif
>  static void gen_sc(DisasContext *ctx)
>  {
> -uint32_t lev;
> +uint32_t lev = (ctx->opcode >> 5) & 0x7F;
>  
> -lev = (ctx->opcode >> 5) & 0x7F;
> -gen_exception_err(ctx, POWERPC_SYSCALL, lev);
> +gen_update_nip(ctx, ctx->base.pc_next);
> +gen_helper_raise_exception_err(cpu_env, 
> tcg_constant_i32(POWERPC_SYSCALL),
> +   tcg_constant_i32(lev));
> +ctx->base.is_jmp = DISAS_NORETURN;

Generally for blame and bisect I don't like to mix cleanup with real
change, I guess this is pretty minor though.

Great cleanup though, sc is certainly defined to set SRR0 to the
instruction past the sc unlike other interrupts so 

Re: [PATCH 07/10] target/ppd: Remove unused define

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> Commit 7a3fe174b12d removed usage of POWERPC_SYSCALL_VECTORED, drop
> the unused define as well.
>
> Signed-off-by: BALATON Zoltan 

Reviewed-by: Nicholas Piggin 

> ---
>  target/ppc/translate.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index b591f2e496..a32a9b8a5f 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -4416,7 +4416,6 @@ static void gen_hrfid(DisasContext *ctx)
>  #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
>  #else
>  #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
> -#define POWERPC_SYSCALL_VECTORED POWERPC_EXCP_SYSCALL_VECTORED
>  #endif
>  static void gen_sc(DisasContext *ctx)
>  {
> -- 
> 2.30.9




Re: [PATCH 06/10] target/ppc: Readability improvements in exception handlers

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> Improve readability by shortening some long comments, removing
> comments that state the obvious and dropping some empty lines so they
> don't distract when reading the code.

Some changes are a matter of taste, but in the interest of having
somebody do some spring cleaning of this code I don't want to nitpick
it, so I won't :)

Acked-by: Nicholas Piggin 

>
> Signed-off-by: BALATON Zoltan 
> ---
>  target/ppc/cpu.h |   1 +
>  target/ppc/excp_helper.c | 180 +++
>  2 files changed, 33 insertions(+), 148 deletions(-)
>



Re: [PATCH] udmabuf: revert 'Add support for mapping hugepages (v4)'

2023-06-13 Thread Hugh Dickins
On Tue, 13 Jun 2023, David Hildenbrand wrote:
> On 13.06.23 10:26, Kasireddy, Vivek wrote:
> >> On 12.06.23 09:10, Kasireddy, Vivek wrote:
> >>> Sorry for the late reply; I just got back from vacation.
> >>> If it is unsafe to directly use the subpages of a hugetlb page, then
> >>> reverting
> >>> this patch seems like the only option for addressing this issue
> >>> immediately.
> >>> So, this patch is
> >>> Acked-by: Vivek Kasireddy 
> >>>
> >>> As far as the use-case is concerned, there are two main users of the
> >> udmabuf
> >>> driver: Qemu and CrosVM VMMs. However, it appears Qemu is the only
> >> one
> >>> that uses hugetlb pages (when hugetlb=on is set) as the backing store for
> >>> Guest (Linux, Android and Windows) system memory. The main goal is to
> >>> share the pages associated with the Guest allocated framebuffer (FB) with
> >>> the Host GPU driver and other components in a zero-copy way. To that
> >> end,
> >>> the guest GPU driver (virtio-gpu) allocates 4k size pages (associated with
> >>> the FB) and pins them before sharing the (guest) physical (or dma)
> >> addresses
> >>> (and lengths) with Qemu. Qemu then translates the addresses into file
> >>> offsets and shares these offsets with udmabuf.
> >>
> >> Is my understanding correct, that we can effectively long-term pin
> >> (worse than mlock) 64 MiB per UDMABUF_CREATE, allowing eventually !root
> > The 64 MiB limit is the theoretical upper bound that we have not seen hit in
> > practice. Typically, for a 1920x1080 resolution (commonly used in Guests),
> > the size of the FB is ~8 MB (1920x1080x4). And, most modern Graphics
> > compositors flip between two FBs.
> > 
> 
> Okay, but users with privileges to open that file can just create as many as
> they want? I think I'll have to play with it.
> 
> >> users
> >>
> >> ll /dev/udmabuf
> >> crw-rw 1 root kvm 10, 125 12. Jun 08:12 /dev/udmabuf
> >>
> >> to bypass there effective MEMLOCK limit, fragmenting physical memory and
> >> breaking swap?
> > Right, it does not look like the mlock limits are honored.
> > 
> 
> That should be added.

Agreed.

> 
> >>
> >> Regarding the udmabuf_vm_fault(), I assume we're mapping pages we
> >> obtained from the memfd ourselves into a special VMA (mmap() of the
> > mmap operation is really needed only if any component on the Host needs
> > CPU access to the buffer. But in most scenarios, we try to ensure direct GPU
> > access (h/w acceleration via gl) to these pages.
> > 
> >> udmabuf). I'm not sure how well shmem pages are prepared for getting
> >> mapped by someone else into an arbitrary VMA (page->index?).
> > Most drm/gpu drivers use shmem pages as the backing store for FBs and
> > other buffers and also provide mmap capability. What concerns do you see
> > with this approach?
> 
> Are these mmaping the pages the way udmabuf maps these pages (IOW, on-demand
> fault where we core-mm will adjust the mapcount etc)?
> 
> Skimming over at shmem_read_mapping_page() users, I assume most of them use a
> VM_PFNMAP mapping (or don't mmap them at all), where we won't be messing with
> the struct page at all.
> 
> (That might even allow you to mmap hugetlb sub-pages, because the struct page
> -- and mapcount -- will be ignored completely and not touched.)

You're well ahead of me: I didn't reach an understanding of whether or not
mapcount would get manipulated here - though if Junxiao's original patch
did fix the immediate hugetlb symptoms, presumably it is (and without much
point, since udmabuf holds on to that extra reference which pins each
page for the duration).

> 
> > 
> >>
> >> ... also, just imagine someone doing FALLOC_FL_PUNCH_HOLE / ftruncate()
> >> on the memfd. What's mapped into the memfd no longer corresponds to
> >> what's pinned / mapped into the VMA.
> > IIUC, making use of the DMA_BUF_IOCTL_SYNC ioctl would help with any
> > coherency issues:
> > https://www.kernel.org/doc/html/v6.2/driver-api/dma-buf.html#c.dma_buf_sync
> > 
> 
> Would it as of now? udmabuf_create() pulls the shmem pages out of the memfd,
> not sure how DMA_BUF_IOCTL_SYNC would help to update that whenever the pages
> inside the memfd would change (e.g., FALLOC_FL_PUNCH_HOLE + realloc).
> 
> But that's most probably simply "not supported".

Yes, the pages which udmabuf is holding would be the originals: they will
then be detached from the hole-punched file, and subsequent faults or writes
to that backing file (through shmem, rather than through udmabuf) can fill
in the holes with new, different pages.  So long as that's well understood,
then it's not necessarily a disaster.

I see udmabuf asks for SEAL_SHRINK (I guess to keep away from SIGBUS),
but refuses SEAL_WRITE - so hole-punching remains permitted.

> 
> >>
> >>
> >> Was linux-mm (and especially shmem maintainers, ccing Hugh) involved in
> >> the upstreaming of udmabuf?

Thanks for the Cc, David.  No, I wasn't involved at all; but I probably
would not have understood their needs much better then than now.

I don't 

Re: [PATCH v2 03/38] tests/multiarch: Add test-aes

2023-06-13 Thread Richard Henderson

On 6/12/23 16:46, Alex Bennée wrote:


Richard Henderson  writes:


Use a shared driver and backends for i386, aarch64, ppc64, riscv64.

Signed-off-by: Richard Henderson 
---
  tests/tcg/aarch64/test-aes.c|  58 
  tests/tcg/i386/test-aes.c   |  68 +
  tests/tcg/ppc64/test-aes.c  | 116 +++
  tests/tcg/riscv64/test-aes.c|  76 ++
  tests/tcg/multiarch/test-aes-main.c.inc | 183



I find it odd the file with the main function is the c.inc and the per
guest impl's are the plain .c files. Is it possible to have it the other
way around?


Not with the way tests/tcg is structured, no.


If we have a fallback library function for aes then we could
enable the test for all targets (a true multiarch test) with some having CPU 
specific
accelerations where available.


We don't have that either.


r~



Re: [PATCH 04/10] target/ppc: Use env_cpu for cpu_abort in excp_helper

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> Use the env_cpu function to get the CPUState for cpu_abort. These are
> only needed in case of fatal errors so this allows to avoid casting
> and storing CPUState in a local variable wnen not needed.

I don't entirely mind keeping cs around as a variable...

Thanks,
Nick

>
> Signed-off-by: BALATON Zoltan 
> ---
>  target/ppc/excp_helper.c | 118 +--
>  1 file changed, 63 insertions(+), 55 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index e4532f5088..51202f7028 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -422,7 +422,6 @@ static void powerpc_checkstop_state(CPUPPCState *env)
>  
>  static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  {
> -CPUState *cs = CPU(cpu);
>  CPUPPCState *env = >env;
>  target_ulong msr, new_msr, vector;
>  int srr0, srr1;

[snip]



Re: [PATCH 03/10] target/ppc: Move common check in exception handlers to a function

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> All powerpc exception handlers share some code when handling machine
> check exceptions. Move this to a common function.
>
> Signed-off-by: BALATON Zoltan 

Hah, I just did very similar to improve some checkstop code (but I can
rebase my patches on yours).

This is specifically to test checkstop due to machine check with
MSR[ME]=0 (other things can potentially case a checkstop). So
maybe rename it powerpc_mcheck_test_checkstop or something like
that?

Mechanically looks okay though, so other than the name,

Reviewed-by: Nicholas Piggin 


> ---
>  target/ppc/excp_helper.c | 112 ---
>  1 file changed, 23 insertions(+), 89 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 3783315fdb..e4532f5088 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -403,6 +403,23 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, 
> target_ulong vector,
>  env->reserve_addr = -1;
>  }
>  
> +static void powerpc_checkstop_state(CPUPPCState *env)
> +{
> +if (!FIELD_EX64(env->msr, MSR, ME)) {
> +CPUState *cs = env_cpu(env);
> +
> +/* Machine check exception is not enabled. Enter checkstop state. */
> +fprintf(stderr, "Machine check while not allowed. "
> +"Entering checkstop state\n");
> +if (qemu_log_separate()) {
> +qemu_log("Machine check while not allowed. "
> + "Entering checkstop state\n");
> +}
> +cs->halted = 1;
> +cpu_interrupt_exittb(cs);
> +}
> +}
> +
>  static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  {
>  CPUState *cs = CPU(cpu);
> @@ -445,21 +462,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  srr1 = SPR_40x_SRR3;
>  break;
>  case POWERPC_EXCP_MCHECK:/* Machine check exception  
> */
> -if (!FIELD_EX64(env->msr, MSR, ME)) {
> -/*
> - * Machine check exception is not enabled.  Enter
> - * checkstop state.
> - */
> -fprintf(stderr, "Machine check while not allowed. "
> -"Entering checkstop state\n");
> -if (qemu_log_separate()) {
> -qemu_log("Machine check while not allowed. "
> -"Entering checkstop state\n");
> -}
> -cs->halted = 1;
> -cpu_interrupt_exittb(cs);
> -}
> -
> +powerpc_checkstop_state(env);
>  /* machine check exceptions don't have ME set */
>  new_msr &= ~((target_ulong)1 << MSR_ME);
>  
> @@ -576,21 +579,7 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
>  case POWERPC_EXCP_CRITICAL:/* Critical input 
> */
>  break;
>  case POWERPC_EXCP_MCHECK:/* Machine check exception  
> */
> -if (!FIELD_EX64(env->msr, MSR, ME)) {
> -/*
> - * Machine check exception is not enabled.  Enter
> - * checkstop state.
> - */
> -fprintf(stderr, "Machine check while not allowed. "
> -"Entering checkstop state\n");
> -if (qemu_log_separate()) {
> -qemu_log("Machine check while not allowed. "
> -"Entering checkstop state\n");
> -}
> -cs->halted = 1;
> -cpu_interrupt_exittb(cs);
> -}
> -
> +powerpc_checkstop_state(env);
>  /* machine check exceptions don't have ME set */
>  new_msr &= ~((target_ulong)1 << MSR_ME);
>  
> @@ -749,21 +738,7 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
>  
>  switch (excp) {
>  case POWERPC_EXCP_MCHECK:/* Machine check exception  
> */
> -if (!FIELD_EX64(env->msr, MSR, ME)) {
> -/*
> - * Machine check exception is not enabled.  Enter
> - * checkstop state.
> - */
> -fprintf(stderr, "Machine check while not allowed. "
> -"Entering checkstop state\n");
> -if (qemu_log_separate()) {
> -qemu_log("Machine check while not allowed. "
> -"Entering checkstop state\n");
> -}
> -cs->halted = 1;
> -cpu_interrupt_exittb(cs);
> -}
> -
> +powerpc_checkstop_state(env);
>  /* machine check exceptions don't have ME set */
>  new_msr &= ~((target_ulong)1 << MSR_ME);
>  
> @@ -934,21 +909,7 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
>  
>  switch (excp) {
>  case POWERPC_EXCP_MCHECK:/* Machine check exception  
> */
> -if (!FIELD_EX64(env->msr, MSR, ME)) {
> -/*
> - * Machine check exception is not enabled.  Enter
> - * checkstop state.
> - */
> 

Re: [PATCH 02/10] target/ppc: Remove unneeded parameter from powerpc_reset_wakeup()

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> CPUState is rarely needed by this function (only for logging a fatal
> error) and it's easy to get from the env parameter so passing it
> separately is not necessary.
>
> Signed-off-by: BALATON Zoltan 

Caller does have env already, but I don't mind much either way.

Acked-by: Nicholas Piggin 

> ---
>  target/ppc/excp_helper.c | 9 -
>  1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 8298217e78..3783315fdb 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -166,8 +166,7 @@ static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int 
> excp)
>  }
>  
>  #if defined(TARGET_PPC64)
> -static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
> -target_ulong *msr)
> +static int powerpc_reset_wakeup(CPUPPCState *env, int excp, target_ulong 
> *msr)
>  {
>  /* We no longer are in a PM state */
>  env->resume_as_sreset = false;
> @@ -202,8 +201,8 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState 
> *env, int excp,
>  *msr |= SRR1_WAKEHVI;
>  break;
>  default:
> -cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
> -  excp);
> +cpu_abort(env_cpu(env),
> +  "Unsupported exception %d in Power Save mode\n", excp);
>  }
>  return POWERPC_EXCP_RESET;
>  }
> @@ -1353,7 +1352,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int 
> excp)
>   * P7/P8/P9
>   */
>  if (env->resume_as_sreset) {
> -excp = powerpc_reset_wakeup(cs, env, excp, );
> +excp = powerpc_reset_wakeup(env, excp, );
>  }
>  
>  /*
> -- 
> 2.30.9




[PATCH 0/2] target/riscv: Fix the xlen for data address when MPRV=1

2023-06-13 Thread Weiwei Li
Currently, we use the current env->xl as the xlen for address. However, the 
xlen for data address should be changed to the xlen related to MPP when MPRV=1.

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-addr-xl-upstream

Weiwei Li (2):
  target/riscv: Add additional xlen for address when MPRV=1
  target/riscv: update cur_pmbase/pmmask based on mode affected by MPRV

 target/riscv/cpu.h| 49 +--
 target/riscv/cpu_helper.c |  8 +--
 target/riscv/csr.c| 27 +++--
 target/riscv/translate.c  | 13 ++-
 4 files changed, 80 insertions(+), 17 deletions(-)

-- 
2.25.1




Re: [PATCH 01/10] target/ppc: Remove some superfluous parentheses

2023-06-13 Thread Nicholas Piggin
On Mon Jun 12, 2023 at 8:42 AM AEST, BALATON Zoltan wrote:
> Signed-off-by: BALATON Zoltan 

Acked-by: Nicholas Piggin 

> ---
>  target/ppc/excp_helper.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 12d8a7257b..8298217e78 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -1009,7 +1009,7 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
>  {
>  int lev = env->error_code;
>  
> -if ((lev == 1) && cpu->vhyp) {
> +if (lev == 1 && cpu->vhyp) {
>  dump_hcall(env);
>  } else {
>  dump_syscall(env);
> @@ -1027,7 +1027,7 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
>   * uses VOF and the 74xx CPUs, so although the 74xx don't have
>   * HV mode, we need to keep hypercall support.
>   */
> -if ((lev == 1) && cpu->vhyp) {
> +if (lev == 1 && cpu->vhyp) {
>  PPCVirtualHypervisorClass *vhc =
>  PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>  vhc->hypercall(cpu->vhyp, cpu);
> @@ -1481,7 +1481,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int 
> excp)
>  case POWERPC_EXCP_SYSCALL:   /* System call exception
> */
>  lev = env->error_code;
>  
> -if ((lev == 1) && cpu->vhyp) {
> +if (lev == 1 && cpu->vhyp) {
>  dump_hcall(env);
>  } else {
>  dump_syscall(env);
> @@ -1494,7 +1494,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int 
> excp)
>  env->nip += 4;
>  
>  /* "PAPR mode" built-in hypercall emulation */
> -if ((lev == 1) && books_vhyp_handles_hcall(cpu)) {
> +if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
>  PPCVirtualHypervisorClass *vhc =
>  PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>  vhc->hypercall(cpu->vhyp, cpu);
> -- 
> 2.30.9




[PATCH 1/2] target/riscv: Add additional xlen for address when MPRV=1

2023-06-13 Thread Weiwei Li
As specified in privilege spec:"When MPRV=1, load and store memory
addresses are treated as though the current XLEN were set to MPP’s
XLEN". So the xlen for address may be different from current xlen.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu.h| 49 +--
 target/riscv/cpu_helper.c |  1 +
 target/riscv/translate.c  | 13 ++-
 3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index e3e08d315f..cc20ee25a7 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -498,6 +498,7 @@ FIELD(TB_FLAGS, ITRIGGER, 22, 1)
 /* Virtual mode enabled */
 FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
 FIELD(TB_FLAGS, PRIV, 24, 2)
+FIELD(TB_FLAGS, AXL, 26, 2)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
@@ -514,13 +515,20 @@ static inline const RISCVCPUConfig 
*riscv_cpu_cfg(CPURISCVState *env)
 return _archcpu(env)->cfg;
 }
 
-#if defined(TARGET_RISCV32)
-#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
-#else
-static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
+#if !defined(CONFIG_USER_ONLY)
+static inline int cpu_address_mode(CPURISCVState *env)
+{
+int mode = env->priv;
+
+if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+mode = get_field(env->mstatus, MSTATUS_MPP);
+}
+return mode;
+}
+
+static inline RISCVMXL cpu_get_xl(CPURISCVState *env, target_ulong mode)
 {
 RISCVMXL xl = env->misa_mxl;
-#if !defined(CONFIG_USER_ONLY)
 /*
  * When emulating a 32-bit-only cpu, use RV32.
  * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
@@ -528,7 +536,7 @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
  * back to RV64 for lower privs.
  */
 if (xl != MXL_RV32) {
-switch (env->priv) {
+switch (mode) {
 case PRV_M:
 break;
 case PRV_U:
@@ -539,11 +547,38 @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState 
*env)
 break;
 }
 }
-#endif
 return xl;
 }
 #endif
 
+#if defined(TARGET_RISCV32)
+#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
+#else
+static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+return cpu_get_xl(env, env->priv);
+#else
+return env->misa_mxl;
+#endif
+}
+#endif
+
+#if defined(TARGET_RISCV32)
+#define cpu_address_xl(env)  ((void)(env), MXL_RV32)
+#else
+static inline RISCVMXL cpu_address_xl(CPURISCVState *env)
+{
+#ifdef CONFIG_USER_ONLY
+return env->xl;
+#else
+int mode = cpu_address_mode(env);
+
+return cpu_get_xl(env, mode);
+#endif
+}
+#endif
+
 static inline int riscv_cpu_xlen(CPURISCVState *env)
 {
 return 16 << env->xl;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 90cef9856d..f85113a3db 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -134,6 +134,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
 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));
 if (env->cur_pmmask != 0) {
 flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8a33da811e..4bf61766b6 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -64,6 +64,7 @@ typedef struct DisasContext {
 target_ulong priv_ver;
 RISCVMXL misa_mxl_max;
 RISCVMXL xl;
+RISCVMXL address_xl;
 uint32_t misa_ext;
 uint32_t opcode;
 RISCVExtStatus mstatus_fs;
@@ -152,6 +153,14 @@ MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
 #define get_xl(ctx)((ctx)->xl)
 #endif
 
+#ifdef TARGET_RISCV32
+#define get_address_xl(ctx)MXL_RV32
+#elif defined(CONFIG_USER_ONLY)
+#define get_address_xl(ctx)MXL_RV64
+#else
+#define get_address_xl(ctx)((ctx)->address_xl)
+#endif
+
 /* The word size for this machine mode. */
 static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
 {
@@ -598,12 +607,13 @@ static TCGv get_address(DisasContext *ctx, int rs1, int 
imm)
 tcg_gen_addi_tl(addr, src1, imm);
 if (ctx->pm_mask_enabled) {
 tcg_gen_andc_tl(addr, addr, pm_mask);
-} else if (get_xl(ctx) == MXL_RV32) {
+} else if (get_address_xl(ctx) == MXL_RV32) {
 tcg_gen_ext32u_tl(addr, addr);
 }
 if (ctx->pm_base_enabled) {
 tcg_gen_or_tl(addr, addr, pm_base);
 }
+
 return addr;
 }
 
@@ -1200,6 +1210,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
 ctx->misa_mxl_max = env->misa_mxl_max;
 ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
+ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
 ctx->cs = cs;
 

[PATCH 2/2] target/riscv: update cur_pmbase/pmmask based on mode affected by MPRV

2023-06-13 Thread Weiwei Li
Pointer mask is also affected by MPRV which means cur_pmbase/pmmask
should also take MPRV into consideration. As pointer mask for instruction
is not supported currently, so we can directly update cur_pmbase/pmmask
based on address related mode and xlen affected by MPRV now.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu_helper.c |  7 +--
 target/riscv/csr.c| 27 ---
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f85113a3db..2321f9132f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -148,13 +148,16 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, 
target_ulong *pc,
 void riscv_cpu_update_mask(CPURISCVState *env)
 {
 target_ulong mask = 0, base = 0;
+RISCVMXL xl = env->xl;
 /*
  * TODO: Current RVJ spec does not specify
  * how the extension interacts with XLEN.
  */
 #ifndef CONFIG_USER_ONLY
+int mode = cpu_address_mode(env);
+xl = cpu_get_xl(env, mode);
 if (riscv_has_ext(env, RVJ)) {
-switch (env->priv) {
+switch (mode) {
 case PRV_M:
 if (env->mmte & M_PM_ENABLE) {
 mask = env->mpmmask;
@@ -178,7 +181,7 @@ void riscv_cpu_update_mask(CPURISCVState *env)
 }
 }
 #endif
-if (env->xl == MXL_RV32) {
+if (xl == MXL_RV32) {
 env->cur_pmmask = mask & UINT32_MAX;
 env->cur_pmbase = base & UINT32_MAX;
 } else {
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 58499b5afc..63cc5d7e2d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1335,8 +1335,9 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
  */
 if (env->debugger) {
 env->xl = cpu_recompute_xl(env);
-riscv_cpu_update_mask(env);
 }
+
+riscv_cpu_update_mask(env);
 return RISCV_EXCP_NONE;
 }
 
@@ -3639,7 +3640,7 @@ static RISCVException write_mpmmask(CPURISCVState *env, 
int csrno,
 uint64_t mstatus;
 
 env->mpmmask = val;
-if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
 env->cur_pmmask = val;
 }
 env->mmte |= EXT_STATUS_DIRTY;
@@ -3667,8 +3668,11 @@ static RISCVException write_spmmask(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 env->spmmask = val;
-if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
 env->cur_pmmask = val;
+if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
+env->cur_pmmask &= UINT32_MAX;
+}
 }
 env->mmte |= EXT_STATUS_DIRTY;
 
@@ -3695,8 +3699,11 @@ static RISCVException write_upmmask(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 env->upmmask = val;
-if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
 env->cur_pmmask = val;
+if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
+env->cur_pmmask &= UINT32_MAX;
+}
 }
 env->mmte |= EXT_STATUS_DIRTY;
 
@@ -3719,7 +3726,7 @@ static RISCVException write_mpmbase(CPURISCVState *env, 
int csrno,
 uint64_t mstatus;
 
 env->mpmbase = val;
-if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
 env->cur_pmbase = val;
 }
 env->mmte |= EXT_STATUS_DIRTY;
@@ -3747,8 +3754,11 @@ static RISCVException write_spmbase(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 env->spmbase = val;
-if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
 env->cur_pmbase = val;
+if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
+env->cur_pmbase &= UINT32_MAX;
+}
 }
 env->mmte |= EXT_STATUS_DIRTY;
 
@@ -3775,8 +3785,11 @@ static RISCVException write_upmbase(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 env->upmbase = val;
-if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
 env->cur_pmbase = val;
+if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
+env->cur_pmbase &= UINT32_MAX;
+}
 }
 env->mmte |= EXT_STATUS_DIRTY;
 
-- 
2.25.1




RE: [PATCH v2 00/17] Support smp.clusters for x86

2023-06-13 Thread Ma, Yongwei
> On Mon, May 29, 2023 at 08:30:44PM +0800, Zhao Liu wrote:
> > Date: Mon, 29 May 2023 20:30:44 +0800
> > From: Zhao Liu 
> > Subject: [PATCH v2 00/17] Support smp.clusters for x86
> > X-Mailer: git-send-email 2.34.1
> >
> > From: Zhao Liu 
> >
> > Hi list,
> >
> > This is the our v2 patch series, rebased on the master branch at the
> > commit ac84b57b4d74 ("Merge tag 'for-upstream' of
> > https://gitlab.com/bonzini/qemu into staging").
> >
> > Comparing with v1 [1], v2 mainly reorganizes patches and does some
> > cleanup.
> >
> > This series add the cluster support for x86 PC machine, which allows
> > x86 can use smp.clusters to configure the modlue level CPU topology of
> > x86.
> >
> > And since the compatibility issue (see section: ## Why not share L2
> > cache in cluster directly), this series also introduce a new command
> > to adjust the topology of the x86 L2 cache.
> >
> > Welcome your comments!
> >
> >

[snip]

> 
> Could you please attach the test results?
> 

Tested module level APID 'test-x86-topo' cases and 'x-l2-cache-topo'
 based on CPUID on Intel platform.
Result looks good hence,

Tested-by: Yongwei Ma 

Best Regards,
Yongwei Ma



Re: [PATCH] hw/loongarch: Supplement cpu topology arguments

2023-06-13 Thread zhaotianrui



在 2023/6/13 下午8:55, Philippe Mathieu-Daudé 写道:

On 13/6/23 14:32, Tianrui Zhao wrote:

Supplement LoongArch cpu topology arguments, including support socket
and threads per core.

Base-on:
https://patchew.org/QEMU/20230613122613.2471743-1-zhaotian...@loongson.cn/ 



^ FYI this tag ...


Signed-off-by: Song Gao 
Signed-off-by: Tianrui Zhao 
---


... goes here after the '---' separator, because it is only helpful when
testing/merging the patch. Once it is committed, this become irrelevant.
(Everything after the '---' separator is normally stripped when applying
patches).


Thanks, I will move the 'Base-on' flag after the '---'.

Tianrui Zhao


  hw/loongarch/acpi-build.c | 4 
  hw/loongarch/virt.c   | 9 -
  2 files changed, 12 insertions(+), 1 deletion(-)


Reviewed-by: Philippe Mathieu-Daudé 





[PULL 32/60] target/riscv: Fix pointer mask transformation for vector address

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

actual_address = (requested_address & ~mpmmask) | mpmbase.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Message-Id: <20230524015933.17349-2-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 8e6c99e573..7505f9470a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -169,7 +169,7 @@ static inline uint32_t vext_get_total_elems(CPURISCVState 
*env, uint32_t desc,
 
 static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
 {
-return (addr & env->cur_pmmask) | env->cur_pmbase;
+return (addr & ~env->cur_pmmask) | env->cur_pmbase;
 }
 
 /*
-- 
2.40.1




[PULL 03/60] target/riscv/cpu.c: add riscv_cpu_validate_v()

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

The RVV verification will error out if fails and it's being done at the
end of riscv_cpu_validate_set_extensions(), after we've already set some
extensions that are dependent on RVV.  Let's put it in its own function
and do it earlier.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230517135714.211809-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 89 +-
 1 file changed, 48 insertions(+), 41 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 99ed9cb80e..1558a0b93f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -834,6 +834,46 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 }
 }
 
+static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
+ Error **errp)
+{
+int vext_version = VEXT_VERSION_1_00_0;
+
+if (!is_power_of_2(cfg->vlen)) {
+error_setg(errp, "Vector extension VLEN must be power of 2");
+return;
+}
+if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) {
+error_setg(errp,
+   "Vector extension implementation only supports VLEN "
+   "in the range [128, %d]", RV_VLEN_MAX);
+return;
+}
+if (!is_power_of_2(cfg->elen)) {
+error_setg(errp, "Vector extension ELEN must be power of 2");
+return;
+}
+if (cfg->elen > 64 || cfg->elen < 8) {
+error_setg(errp,
+   "Vector extension implementation only supports ELEN "
+   "in the range [8, 64]");
+return;
+}
+if (cfg->vext_spec) {
+if (!g_strcmp0(cfg->vext_spec, "v1.0")) {
+vext_version = VEXT_VERSION_1_00_0;
+} else {
+error_setg(errp, "Unsupported vector spec version '%s'",
+   cfg->vext_spec);
+return;
+}
+} else {
+qemu_log("vector version is not specified, "
+ "use the default value v1.0\n");
+}
+set_vext_version(env, vext_version);
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly.
@@ -841,6 +881,7 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
 CPURISCVState *env = >env;
+Error *local_err = NULL;
 
 /* Do some ISA extension error checking */
 if (riscv_has_ext(env, RVG) &&
@@ -909,8 +950,14 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-/* The V vector extension depends on the Zve64d extension */
 if (riscv_has_ext(env, RVV)) {
+riscv_cpu_validate_v(env, >cfg, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+
+/* The V vector extension depends on the Zve64d extension */
 cpu->cfg.ext_zve64d = true;
 }
 
@@ -1045,46 +1092,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zksed = true;
 cpu->cfg.ext_zksh = true;
 }
-
-if (riscv_has_ext(env, RVV)) {
-int vext_version = VEXT_VERSION_1_00_0;
-if (!is_power_of_2(cpu->cfg.vlen)) {
-error_setg(errp,
-   "Vector extension VLEN must be power of 2");
-return;
-}
-if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
-error_setg(errp,
-   "Vector extension implementation only supports VLEN "
-   "in the range [128, %d]", RV_VLEN_MAX);
-return;
-}
-if (!is_power_of_2(cpu->cfg.elen)) {
-error_setg(errp,
-   "Vector extension ELEN must be power of 2");
-return;
-}
-if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
-error_setg(errp,
-   "Vector extension implementation only supports ELEN "
-   "in the range [8, 64]");
-return;
-}
-if (cpu->cfg.vext_spec) {
-if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
-vext_version = VEXT_VERSION_1_00_0;
-} else {
-error_setg(errp,
-   "Unsupported vector spec version '%s'",
-   cpu->cfg.vext_spec);
-return;
-}
-} else {
-qemu_log("vector version is not specified, "
- "use the default value v1.0\n");
-}
-set_vext_version(env, vext_version);
-}
 }
 
 #ifndef CONFIG_USER_ONLY
-- 
2.40.1




[PULL 17/60] target/riscv: Change the return type of pmp_hart_has_privs() to bool

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

We no longer need the pmp_index for matched PMP entry now.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-5-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.h|  8 
 target/riscv/cpu_helper.c |  8 
 target/riscv/pmp.c| 32 +---
 3 files changed, 21 insertions(+), 27 deletions(-)

diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index 0a7e24750b..cf5c99f8e6 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -72,10 +72,10 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
 void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val);
 target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
-   target_ulong size, pmp_priv_t privs,
-   pmp_priv_t *allowed_privs,
-   target_ulong mode);
+bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+target_ulong size, pmp_priv_t privs,
+pmp_priv_t *allowed_privs,
+target_ulong mode);
 target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr);
 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
 void pmp_update_rule_nums(CPURISCVState *env);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 52d0b043df..35ddd0caac 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -697,16 +697,16 @@ static int get_physical_address_pmp(CPURISCVState *env, 
int *prot, hwaddr addr,
 int mode)
 {
 pmp_priv_t pmp_priv;
-int pmp_index = -1;
+bool pmp_has_privs;
 
 if (!riscv_cpu_cfg(env)->pmp) {
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TRANSLATE_SUCCESS;
 }
 
-pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
-   _priv, mode);
-if (pmp_index < 0) {
+pmp_has_privs = pmp_hart_has_privs(env, addr, size, 1 << access_type,
+   _priv, mode);
+if (!pmp_has_privs) {
 *prot = 0;
 return TRANSLATE_PMP_FAIL;
 }
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 3c90562d55..0684047b86 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -296,27 +296,23 @@ static bool pmp_hart_has_privs_default(CPURISCVState 
*env, target_ulong addr,
 
 /*
  * Check if the address has required RWX privs to complete desired operation
- * Return PMP rule index if a pmp rule match
- * Return MAX_RISCV_PMPS if default match
- * Return negtive value if no match
+ * Return true if a pmp rule match or default match
+ * Return false if no match
  */
-int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
-   target_ulong size, pmp_priv_t privs,
-   pmp_priv_t *allowed_privs, target_ulong mode)
+bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+target_ulong size, pmp_priv_t privs,
+pmp_priv_t *allowed_privs, target_ulong mode)
 {
 int i = 0;
-int ret = -1;
+bool ret = false;
 int pmp_size = 0;
 target_ulong s = 0;
 target_ulong e = 0;
 
 /* Short cut if no rules */
 if (0 == pmp_get_num_rules(env)) {
-if (pmp_hart_has_privs_default(env, addr, size, privs,
-   allowed_privs, mode)) {
-ret = MAX_RISCV_PMPS;
-}
-return ret;
+return pmp_hart_has_privs_default(env, addr, size, privs,
+  allowed_privs, mode);
 }
 
 if (size == 0) {
@@ -345,7 +341,7 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 if ((s + e) == 1) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "pmp violation - access is partially inside\n");
-ret = -1;
+ret = false;
 break;
 }
 
@@ -453,17 +449,15 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
  * defined with PMP must be used. We shouldn't fallback on
  * finding default privileges.
  */
-ret = i;
+ret = true;
 break;
 }
 }
 
 /* No rule matched */
-if (ret == -1) {
-if (pmp_hart_has_privs_default(env, addr, size, privs,
-   allowed_privs, mode)) {
-ret = MAX_RISCV_PMPS;
-}
+if (!ret) {
+ret = pmp_hart_has_privs_default(env, addr, size, privs,
+ allowed_privs, mode);
 }
 
 return ret;
-- 
2.40.1




[PULL 54/60] docs/system: riscv: Add pflash usage details

2023-06-13 Thread Alistair Francis
From: Sunil V L 

pflash devices can be used in virt machine for different
purposes like for ROM code or S-mode FW payload. Add a
section in the documentation on how to use pflash devices
for different purposes.

Signed-off-by: Sunil V L 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Message-Id: <20230601045910.18646-4-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 docs/system/riscv/virt.rst | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst
index 4b16e41d7f..b33f45e5b3 100644
--- a/docs/system/riscv/virt.rst
+++ b/docs/system/riscv/virt.rst
@@ -53,6 +53,37 @@ with the default OpenSBI firmware image as the -bios. It 
also supports
 the recommended RISC-V bootflow: U-Boot SPL (M-mode) loads OpenSBI fw_dynamic
 firmware and U-Boot proper (S-mode), using the standard -bios functionality.
 
+Using flash devices
+---
+
+By default, the first flash device (pflash0) is expected to contain
+S-mode firmware code. It can be configured as read-only, with the
+second flash device (pflash1) available to store configuration data.
+
+For example, booting edk2 looks like
+
+.. code-block:: bash
+
+  $ qemu-system-riscv64 \
+ -blockdev node-name=pflash0,driver=file,read-only=on,filename= 
\
+ -blockdev node-name=pflash1,driver=file,filename= \
+ -M virt,pflash0=pflash0,pflash1=pflash1 \
+ ... other args 
+
+For TCG guests only, it is also possible to boot M-mode firmware from
+the first flash device (pflash0) by additionally passing ``-bios
+none``, as in
+
+.. code-block:: bash
+
+  $ qemu-system-riscv64 \
+ -bios none \
+ -blockdev 
node-name=pflash0,driver=file,read-only=on,filename= \
+ -M virt,pflash0=pflash0 \
+ ... other args 
+
+Firmware images used for pflash must be exactly 32 MiB in size.
+
 Machine-specific options
 
 
-- 
2.40.1




[PULL 07/60] target/riscv: Mask the implicitly enabled extensions in isa_string based on priv version

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Using implicitly enabled extensions such as Zca/Zcf/Zcd instead of their
super extensions can simplify the extension related check. However, they
may have higher priv version than their super extensions. So we should mask
them in the isa_string based on priv version to make them invisible to user
if the specified priv version is lower than their minimal priv version.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Message-Id: <20230517135714.211809-6-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a0c4acfb47..81a785d525 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1758,7 +1758,8 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
**isa_str,
 int i;
 
 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
-if (isa_ext_is_enabled(cpu, _edata_arr[i])) {
+if (cpu->env.priv_ver >= isa_edata_arr[i].min_version &&
+isa_ext_is_enabled(cpu, _edata_arr[i])) {
 new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
 g_free(old);
 old = new;
-- 
2.40.1




[PULL 10/60] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl()

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

Let's remove more code that is open coded in riscv_cpu_realize() and put
it into a helper. Let's also add an error message instead of just
asserting out if env->misa_mxl_max != env->misa_mlx.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230517135714.211809-9-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 50 ++
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a0589abb16..89a1a25812 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -910,6 +910,33 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU 
*cpu)
 }
 }
 
+static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
+{
+RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
+CPUClass *cc = CPU_CLASS(mcc);
+CPURISCVState *env = >env;
+
+/* Validate that MISA_MXL is set properly. */
+switch (env->misa_mxl_max) {
+#ifdef TARGET_RISCV64
+case MXL_RV64:
+case MXL_RV128:
+cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
+break;
+#endif
+case MXL_RV32:
+cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
+break;
+default:
+g_assert_not_reached();
+}
+
+if (env->misa_mxl_max != env->misa_mxl) {
+error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
+return;
+}
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly.
@@ -1232,7 +1259,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 RISCVCPU *cpu = RISCV_CPU(dev);
 CPURISCVState *env = >env;
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
-CPUClass *cc = CPU_CLASS(mcc);
 Error *local_err = NULL;
 
 cpu_exec_realizefn(cs, _err);
@@ -1241,6 +1267,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+riscv_cpu_validate_misa_mxl(cpu, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+
 riscv_cpu_validate_priv_spec(cpu, _err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
@@ -1269,22 +1301,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 #endif /* CONFIG_USER_ONLY */
 
-/* Validate that MISA_MXL is set properly. */
-switch (env->misa_mxl_max) {
-#ifdef TARGET_RISCV64
-case MXL_RV64:
-case MXL_RV128:
-cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
-break;
-#endif
-case MXL_RV32:
-cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
-break;
-default:
-g_assert_not_reached();
-}
-assert(env->misa_mxl_max == env->misa_mxl);
-
 riscv_cpu_validate_set_extensions(cpu, _err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
-- 
2.40.1




[PULL 33/60] target/riscv: Update cur_pmmask/base when xl changes

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

write_mstatus() can only change current xl when in debug mode.
And we need update cur_pmmask/base in this case.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: LIU Zhiwei 
Message-Id: <20230524015933.17349-3-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index cf7da4f87f..ad73691878 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1324,8 +1324,15 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
 }
 env->mstatus = mstatus;
-env->xl = cpu_recompute_xl(env);
 
+/*
+ * Except in debug mode, UXL/SXL can only be modified by higher
+ * privilege mode. So xl will not be changed in normal mode.
+ */
+if (env->debugger) {
+env->xl = cpu_recompute_xl(env);
+riscv_cpu_update_mask(env);
+}
 return RISCV_EXCP_NONE;
 }
 
-- 
2.40.1




[PULL 23/60] target/riscv: Flush TLB only when pmpcfg/pmpaddr really changes

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

TLB needn't be flushed when pmpcfg/pmpaddr don't changes.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Reviewed-by: LIU Zhiwei 
Message-Id: <20230517091519.34439-11-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index e0acee7a15..3c12690565 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -26,7 +26,7 @@
 #include "trace.h"
 #include "exec/exec-all.h"
 
-static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
+static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
   uint8_t val);
 static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index);
 static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index);
@@ -83,7 +83,7 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, 
uint32_t pmp_index)
  * Accessor to set the cfg reg for a specific PMP/HART
  * Bounds checks and relevant lock bit.
  */
-static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
+static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
 {
 if (pmp_index < MAX_RISCV_PMPS) {
 bool locked = true;
@@ -119,14 +119,17 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t 
pmp_index, uint8_t val)
 
 if (locked) {
 qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
-} else {
+} else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) {
 env->pmp_state.pmp[pmp_index].cfg_reg = val;
 pmp_update_rule(env, pmp_index);
+return true;
 }
 } else {
 qemu_log_mask(LOG_GUEST_ERROR,
   "ignoring pmpcfg write - out of bounds\n");
 }
+
+return false;
 }
 
 static void pmp_decode_napot(target_ulong a, target_ulong *sa,
@@ -467,16 +470,19 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t 
reg_index,
 int i;
 uint8_t cfg_val;
 int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
+bool modified = false;
 
 trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
 
 for (i = 0; i < pmpcfg_nums; i++) {
 cfg_val = (val >> 8 * i)  & 0xff;
-pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
+modified |= pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
 }
 
 /* If PMP permission of any addr has been changed, flush TLB pages. */
-tlb_flush(env_cpu(env));
+if (modified) {
+tlb_flush(env_cpu(env));
+}
 }
 
 
@@ -526,12 +532,14 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t 
addr_index,
 }
 
 if (!pmp_is_locked(env, addr_index)) {
-env->pmp_state.pmp[addr_index].addr_reg = val;
-pmp_update_rule_addr(env, addr_index);
-if (is_next_cfg_tor) {
-pmp_update_rule_addr(env, addr_index + 1);
+if (env->pmp_state.pmp[addr_index].addr_reg != val) {
+env->pmp_state.pmp[addr_index].addr_reg = val;
+pmp_update_rule_addr(env, addr_index);
+if (is_next_cfg_tor) {
+pmp_update_rule_addr(env, addr_index + 1);
+}
+tlb_flush(env_cpu(env));
 }
-tlb_flush(env_cpu(env));
 } else {
 qemu_log_mask(LOG_GUEST_ERROR,
   "ignoring pmpaddr write - locked\n");
-- 
2.40.1




[PULL 50/60] target/riscv: Enable PC-relative translation

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Add a base pc_save for PC-relative translation(CF_PCREL).
Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
Use gen_pc_plus_diff to get the pc-relative address.
Enable CF_PCREL in System mode.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230526072124.298466-7-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c| 31 ++-
 target/riscv/translate.c  | 47 +++
 target/riscv/insn_trans/trans_rvi.c.inc   | 12 +-
 target/riscv/insn_trans/trans_rvzce.c.inc |  4 +-
 4 files changed, 74 insertions(+), 20 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 938c7bd87b..881bddf393 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -721,16 +721,18 @@ static vaddr riscv_cpu_get_pc(CPUState *cs)
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
   const TranslationBlock *tb)
 {
-RISCVCPU *cpu = RISCV_CPU(cs);
-CPURISCVState *env = >env;
-RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+if (!(tb_cflags(tb) & CF_PCREL)) {
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
 
-tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
 
-if (xl == MXL_RV32) {
-env->pc = (int32_t) tb->pc;
-} else {
-env->pc = tb->pc;
+if (xl == MXL_RV32) {
+env->pc = (int32_t) tb->pc;
+} else {
+env->pc = tb->pc;
+}
 }
 }
 
@@ -756,11 +758,18 @@ static void riscv_restore_state_to_opc(CPUState *cs,
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
 RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+target_ulong pc;
+
+if (tb_cflags(tb) & CF_PCREL) {
+pc = (env->pc & TARGET_PAGE_MASK) | data[0];
+} else {
+pc = data[0];
+}
 
 if (xl == MXL_RV32) {
-env->pc = (int32_t)data[0];
+env->pc = (int32_t)pc;
 } else {
-env->pc = data[0];
+env->pc = pc;
 }
 env->bins = data[1];
 }
@@ -1343,6 +1352,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 
 #ifndef CONFIG_USER_ONLY
+cs->tcg_cflags |= CF_PCREL;
+
 if (cpu->cfg.ext_sstc) {
 riscv_timer_init(cpu);
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7fb4cbe84c..bd2da9b079 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -62,6 +62,7 @@ typedef struct DisasContext {
 /* pc_succ_insn points to the instruction following base.pc_next */
 target_ulong pc_succ_insn;
 target_ulong cur_insn_len;
+target_ulong pc_save;
 target_ulong priv_ver;
 RISCVMXL misa_mxl_max;
 RISCVMXL xl;
@@ -230,15 +231,24 @@ static void gen_pc_plus_diff(TCGv target, DisasContext 
*ctx,
 {
 target_ulong dest = ctx->base.pc_next + diff;
 
-if (get_xl(ctx) == MXL_RV32) {
-dest = (int32_t)dest;
+assert(ctx->pc_save != -1);
+if (tb_cflags(ctx->base.tb) & CF_PCREL) {
+tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
+if (get_xl(ctx) == MXL_RV32) {
+tcg_gen_ext32s_tl(target, target);
+}
+} else {
+if (get_xl(ctx) == MXL_RV32) {
+dest = (int32_t)dest;
+}
+tcg_gen_movi_tl(target, dest);
 }
-tcg_gen_movi_tl(target, dest);
 }
 
 static void gen_update_pc(DisasContext *ctx, target_long diff)
 {
 gen_pc_plus_diff(cpu_pc, ctx, diff);
+ctx->pc_save = ctx->base.pc_next + diff;
 }
 
 static void generate_exception(DisasContext *ctx, int excp)
@@ -294,8 +304,21 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_long diff)
   * direct block chain benefits will be small.
   */
 if (translator_use_goto_tb(>base, dest) && !ctx->itrigger) {
-tcg_gen_goto_tb(n);
-gen_update_pc(ctx, diff);
+/*
+ * For pcrel, the pc must always be up-to-date on entry to
+ * the linked TB, so that it can use simple additions for all
+ * further adjustments.  For !pcrel, the linked TB is compiled
+ * to know its full virtual address, so we can delay the
+ * update to pc to the unlinked path.  A long chain of links
+ * can thus avoid many updates to the PC.
+ */
+if (tb_cflags(ctx->base.tb) & CF_PCREL) {
+gen_update_pc(ctx, diff);
+tcg_gen_goto_tb(n);
+} else {
+tcg_gen_goto_tb(n);
+gen_update_pc(ctx, diff);
+}
 tcg_gen_exit_tb(ctx->base.tb, n);
 } else {
 gen_update_pc(ctx, diff);
@@ -549,6 +572,8 @@ static void gen_set_fpr_d(DisasContext *ctx, int reg_num, 
TCGv_i64 t)
 
 static void gen_jal(DisasContext *ctx, int rd, 

[PULL 57/60] target/riscv/vector_helper.c: clean up reference of MTYPE

2023-06-13 Thread Alistair Francis
From: Xiao Wang 

There's no code using MTYPE, which was a concept used in older vector
implementation.

Signed-off-by: Xiao Wang 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Message-Id: <20230608053517.4102648-1-xiao.w.w...@intel.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7505f9470a..e8af64e626 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -388,7 +388,7 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 
 /*
  * masked unit-stride load and store operation will be a special case of
- * stride, stride = NF * sizeof (MTYPE)
+ * stride, stride = NF * sizeof (ETYPE)
  */
 
 #define GEN_VEXT_LD_US(NAME, ETYPE, LOAD_FN)\
@@ -660,10 +660,6 @@ GEN_VEXT_LDFF(vle64ff_v, int64_t, lde_d)
 #define DO_MAX(N, M)  ((N) >= (M) ? (N) : (M))
 #define DO_MIN(N, M)  ((N) >= (M) ? (M) : (N))
 
-/* Unsigned min/max */
-#define DO_MAXU(N, M) DO_MAX((UMTYPE)N, (UMTYPE)M)
-#define DO_MINU(N, M) DO_MIN((UMTYPE)N, (UMTYPE)M)
-
 /*
  * load and store whole register instructions
  */
-- 
2.40.1




[PULL 47/60] target/riscv: Change gen_goto_tb to work on displacements

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Reduce reliance on absolute value to prepare for PC-relative translation.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230526072124.298466-4-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c| 8 +---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ea63d20eef..33c666d74e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -283,8 +283,10 @@ static void exit_tb(DisasContext *ctx)
 tcg_gen_exit_tb(NULL, 0);
 }
 
-static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+static void gen_goto_tb(DisasContext *ctx, int n, target_long diff)
 {
+target_ulong dest = ctx->base.pc_next + diff;
+
  /*
   * Under itrigger, instruction executes one by one like singlestep,
   * direct block chain benefits will be small.
@@ -559,7 +561,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 }
 
 gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
-gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety 
*/
+gen_goto_tb(ctx, 0, imm); /* must use this for safety */
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
@@ -1231,7 +1233,7 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, 
CPUState *cpu)
 
 switch (ctx->base.is_jmp) {
 case DISAS_TOO_MANY:
-gen_goto_tb(ctx, 0, ctx->base.pc_next);
+gen_goto_tb(ctx, 0, 0);
 break;
 case DISAS_NORETURN:
 break;
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 009dc96dbd..321885f951 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -171,7 +171,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 } else {
 tcg_gen_brcond_tl(cond, src1, src2, l);
 }
-gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+gen_goto_tb(ctx, 1, ctx->cur_insn_len);
 
 gen_set_label(l); /* branch taken */
 
@@ -183,7 +183,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 gen_pc_plus_diff(target_pc, ctx, next_pc);
 gen_exception_inst_addr_mis(ctx, target_pc);
 } else {
-gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
+gen_goto_tb(ctx, 0, a->imm);
 }
 ctx->base.is_jmp = DISAS_NORETURN;
 
-- 
2.40.1




[PULL 53/60] riscv/virt: Support using pflash via -blockdev option

2023-06-13 Thread Alistair Francis
From: Sunil V L 

Currently, pflash devices can be configured only via -pflash
or -drive options. This is the legacy way and the
better way is to use -blockdev as in other architectures.
libvirt also has moved to use -blockdev method.

To support -blockdev option, pflash devices need to be
created in instance_init itself. So, update the code to
move the virt_flash_create() to instance_init. Also, use
standard interfaces to detect whether pflash0 is
configured or not.

Signed-off-by: Sunil V L 
Reported-by: Andrea Bolognani 
Tested-by: Andrea Bolognani 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Message-Id: <20230601045910.18646-3-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 17fdcef223..95708d890e 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1246,6 +1246,7 @@ static void virt_machine_done(Notifier *notifier, void 
*data)
 const char *firmware_name = riscv_default_firmware_name(>soc[0]);
 uint32_t fdt_load_addr;
 uint64_t kernel_entry = 0;
+BlockBackend *pflash_blk0;
 
 /*
  * Only direct boot kernel is currently supported for KVM VM,
@@ -1266,7 +1267,8 @@ static void virt_machine_done(Notifier *notifier, void 
*data)
 firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
  start_addr, NULL);
 
-if (drive_get(IF_PFLASH, 0, 0)) {
+pflash_blk0 = pflash_cfi01_get_blk(s->flash[0]);
+if (pflash_blk0) {
 if (machine->firmware && !strcmp(machine->firmware, "none") &&
 !kvm_enabled()) {
 /*
@@ -1499,8 +1501,6 @@ static void virt_machine_init(MachineState *machine)
 sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
 qdev_get_gpio_in(mmio_irqchip, RTC_IRQ));
 
-virt_flash_create(s);
-
 for (i = 0; i < ARRAY_SIZE(s->flash); i++) {
 /* Map legacy -drive if=pflash to machine properties */
 pflash_cfi01_legacy_drive(s->flash[i],
@@ -1527,6 +1527,8 @@ static void virt_machine_instance_init(Object *obj)
 {
 RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
 
+virt_flash_create(s);
+
 s->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
 s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
 s->acpi = ON_OFF_AUTO_AUTO;
-- 
2.40.1




[PULL 56/60] target/riscv: Fix initialized value for cur_pmmask

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

We initialize cur_pmmask as -1(UINT32_MAX/UINT64_MAX) and regard it
as if pointer mask is disabled in current implementation. However,
the addresses for vector load/store will be adjusted to zero in this
case and -1(UINT32_MAX/UINT64_MAX) is valid value for pmmask when
pointer mask is enabled.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: LIU Zhiwei 
Message-Id: <20230610094651.43786-1-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 523311b184..90cef9856d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -134,7 +134,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
 flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
 flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
-if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
+if (env->cur_pmmask != 0) {
 flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
 }
 if (env->cur_pmbase != 0) {
@@ -146,7 +146,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 
 void riscv_cpu_update_mask(CPURISCVState *env)
 {
-target_ulong mask = -1, base = 0;
+target_ulong mask = 0, base = 0;
 /*
  * TODO: Current RVJ spec does not specify
  * how the extension interacts with XLEN.
-- 
2.40.1




[PULL 27/60] hw/riscv/opentitan: Declare QOM types using DEFINE_TYPES() macro

2023-06-13 Thread Alistair Francis
From: Philippe Mathieu-Daudé 

When multiple QOM types are registered in the same file,
it is simpler to use the the DEFINE_TYPES() macro. Replace
the type_init() / type_register_static() combination. This
is in preparation of adding the OpenTitan machine type to
this array in a pair of commits.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20230520054510.68822-3-phi...@linaro.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/opentitan.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 2d21ee39c5..294955eeea 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -320,17 +320,14 @@ static void lowrisc_ibex_soc_class_init(ObjectClass *oc, 
void *data)
 dc->user_creatable = false;
 }
 
-static const TypeInfo lowrisc_ibex_soc_type_info = {
-.name = TYPE_RISCV_IBEX_SOC,
-.parent = TYPE_DEVICE,
-.instance_size = sizeof(LowRISCIbexSoCState),
-.instance_init = lowrisc_ibex_soc_init,
-.class_init = lowrisc_ibex_soc_class_init,
+static const TypeInfo open_titan_types[] = {
+{
+.name   = TYPE_RISCV_IBEX_SOC,
+.parent = TYPE_DEVICE,
+.instance_size  = sizeof(LowRISCIbexSoCState),
+.instance_init  = lowrisc_ibex_soc_init,
+.class_init = lowrisc_ibex_soc_class_init,
+}
 };
 
-static void lowrisc_ibex_soc_register_types(void)
-{
-type_register_static(_ibex_soc_type_info);
-}
-
-type_init(lowrisc_ibex_soc_register_types)
+DEFINE_TYPES(open_titan_types)
-- 
2.40.1




[PULL 45/60] target/riscv: Fix target address to update badaddr

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Compute the target address before storing it into badaddr
when mis-aligned exception is triggered.
Use a target_pc temp to store the target address to avoid
the confusing operation that udpate target address into
cpu_pc before misalign check, then update it into badaddr
and restore cpu_pc to current pc if exception is triggered.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230526072124.298466-2-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c  | 21 ++---
 target/riscv/insn_trans/trans_rvi.c.inc   | 23 ---
 target/riscv/insn_trans/trans_rvzce.c.inc |  4 ++--
 3 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 29f1fb3995..6fbdb50c5d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -224,21 +224,18 @@ static void decode_save_opc(DisasContext *ctx)
 ctx->insn_start = NULL;
 }
 
-static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
+ target_ulong dest)
 {
 if (get_xl(ctx) == MXL_RV32) {
 dest = (int32_t)dest;
 }
-tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_movi_tl(target, dest);
 }
 
-static void gen_set_pc(DisasContext *ctx, TCGv dest)
+static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
 {
-if (get_xl(ctx) == MXL_RV32) {
-tcg_gen_ext32s_tl(cpu_pc, dest);
-} else {
-tcg_gen_mov_tl(cpu_pc, dest);
-}
+gen_pc_plus_diff(cpu_pc, ctx, dest);
 }
 
 static void generate_exception(DisasContext *ctx, int excp)
@@ -259,9 +256,9 @@ static void gen_exception_illegal(DisasContext *ctx)
 }
 }
 
-static void gen_exception_inst_addr_mis(DisasContext *ctx)
+static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
 {
-tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
+tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
 generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
 }
 
@@ -553,7 +550,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 next_pc = ctx->base.pc_next + imm;
 if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
 if ((next_pc & 0x3) != 0) {
-gen_exception_inst_addr_mis(ctx);
+TCGv target_pc = tcg_temp_new();
+gen_pc_plus_diff(target_pc, ctx, next_pc);
+gen_exception_inst_addr_mis(ctx, target_pc);
 return;
 }
 }
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index d794247f40..009dc96dbd 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
 static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 {
 TCGLabel *misaligned = NULL;
+TCGv target_pc = tcg_temp_new();
 
-tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
-tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
+tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
+tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
+
+if (get_xl(ctx) == MXL_RV32) {
+tcg_gen_ext32s_tl(target_pc, target_pc);
+}
 
-gen_set_pc(ctx, cpu_pc);
 if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
 TCGv t0 = tcg_temp_new();
 
 misaligned = gen_new_label();
-tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+tcg_gen_andi_tl(t0, target_pc, 0x2);
 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
 }
 
 gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
+tcg_gen_mov_tl(cpu_pc, target_pc);
 lookup_and_goto_ptr(ctx);
 
 if (misaligned) {
 gen_set_label(misaligned);
-gen_exception_inst_addr_mis(ctx);
+gen_exception_inst_addr_mis(ctx, target_pc);
 }
 ctx->base.is_jmp = DISAS_NORETURN;
 
@@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 TCGLabel *l = gen_new_label();
 TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
 TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
+target_ulong next_pc;
 
 if (get_xl(ctx) == MXL_RV128) {
 TCGv src1h = get_gprh(ctx, a->rs1);
@@ -169,10 +175,13 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, 
TCGCond cond)
 
 gen_set_label(l); /* branch taken */
 
+next_pc = ctx->base.pc_next + a->imm;
 if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca &&
-((ctx->base.pc_next + a->imm) & 0x3)) {
+(next_pc & 0x3)) {
 /* misaligned */
-gen_exception_inst_addr_mis(ctx);
+TCGv target_pc = tcg_temp_new();
+gen_pc_plus_diff(target_pc, ctx, next_pc);
+gen_exception_inst_addr_mis(ctx, target_pc);
 } else {
 

[PULL 48/60] target/riscv: Change gen_set_pc_imm to gen_update_pc

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Reduce reliance on absolute values(by passing pc difference) to
prepare for PC-relative translation.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230526072124.298466-5-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c   | 10 +-
 target/riscv/insn_trans/trans_privileged.c.inc |  2 +-
 target/riscv/insn_trans/trans_rvi.c.inc|  6 +++---
 target/riscv/insn_trans/trans_rvv.c.inc|  4 ++--
 target/riscv/insn_trans/trans_rvzawrs.c.inc|  2 +-
 target/riscv/insn_trans/trans_xthead.c.inc |  2 +-
 6 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 33c666d74e..eda022d10b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -234,14 +234,14 @@ static void gen_pc_plus_diff(TCGv target, DisasContext 
*ctx,
 tcg_gen_movi_tl(target, dest);
 }
 
-static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+static void gen_update_pc(DisasContext *ctx, target_long diff)
 {
-gen_pc_plus_diff(cpu_pc, ctx, dest);
+gen_pc_plus_diff(cpu_pc, ctx, ctx->base.pc_next + diff);
 }
 
 static void generate_exception(DisasContext *ctx, int excp)
 {
-gen_set_pc_imm(ctx, ctx->base.pc_next);
+gen_update_pc(ctx, 0);
 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
 ctx->base.is_jmp = DISAS_NORETURN;
 }
@@ -293,10 +293,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_long diff)
   */
 if (translator_use_goto_tb(>base, dest) && !ctx->itrigger) {
 tcg_gen_goto_tb(n);
-gen_set_pc_imm(ctx, dest);
+gen_update_pc(ctx, diff);
 tcg_gen_exit_tb(ctx->base.tb, n);
 } else {
-gen_set_pc_imm(ctx, dest);
+gen_update_pc(ctx, diff);
 lookup_and_goto_ptr(ctx);
 }
 }
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
b/target/riscv/insn_trans/trans_privileged.c.inc
index 528baa1652..dc14d7fc7a 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -108,7 +108,7 @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
 {
 #ifndef CONFIG_USER_ONLY
 decode_save_opc(ctx);
-gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+gen_update_pc(ctx, ctx->cur_insn_len);
 gen_helper_wfi(cpu_env);
 return true;
 #else
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 321885f951..4837e133cc 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -777,7 +777,7 @@ static bool trans_pause(DisasContext *ctx, arg_pause *a)
  * PAUSE is a no-op in QEMU,
  * end the TB and return to main loop
  */
-gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+gen_update_pc(ctx, ctx->cur_insn_len);
 exit_tb(ctx);
 ctx->base.is_jmp = DISAS_NORETURN;
 
@@ -801,7 +801,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
  * FENCE_I is a no-op in QEMU,
  * however we need to end the translation block
  */
-gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+gen_update_pc(ctx, ctx->cur_insn_len);
 exit_tb(ctx);
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
@@ -812,7 +812,7 @@ static bool do_csr_post(DisasContext *ctx)
 /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
 decode_save_opc(ctx);
 /* We may have changed important cpu state -- exit to main loop. */
-gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+gen_update_pc(ctx, ctx->cur_insn_len);
 exit_tb(ctx);
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 6c07eebc52..c2f7527f53 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -169,7 +169,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, 
TCGv s2)
 gen_set_gpr(s, rd, dst);
 mark_vs_dirty(s);
 
-gen_set_pc_imm(s, s->pc_succ_insn);
+gen_update_pc(s, s->cur_insn_len);
 lookup_and_goto_ptr(s);
 s->base.is_jmp = DISAS_NORETURN;
 return true;
@@ -188,7 +188,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, 
TCGv s2)
 gen_helper_vsetvl(dst, cpu_env, s1, s2);
 gen_set_gpr(s, rd, dst);
 mark_vs_dirty(s);
-gen_set_pc_imm(s, s->pc_succ_insn);
+gen_update_pc(s, s->cur_insn_len);
 lookup_and_goto_ptr(s);
 s->base.is_jmp = DISAS_NORETURN;
 
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc 
b/target/riscv/insn_trans/trans_rvzawrs.c.inc
index 8254e7dfe2..32efbff4d5 100644
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
@@ -33,7 +33,7 @@ static bool trans_wrs(DisasContext *ctx)
 /* Clear the load reservation  (if any).  */
 

[PULL 41/60] disas/riscv.c: Support disas for Z*inx extensions

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Support disas for Z*inx instructions only when Zfinx extension is supported.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-Id: <20230523093539.203909-6-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index 6659f92179..c9a81af662 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -4598,16 +4598,24 @@ static void format_inst(char *buf, size_t buflen, 
size_t tab, rv_decode *dec)
 append(buf, rv_ireg_name_sym[dec->rs2], buflen);
 break;
 case '3':
-append(buf, rv_freg_name_sym[dec->rd], buflen);
+append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rd] :
+  rv_freg_name_sym[dec->rd],
+   buflen);
 break;
 case '4':
-append(buf, rv_freg_name_sym[dec->rs1], buflen);
+append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs1] :
+  rv_freg_name_sym[dec->rs1],
+   buflen);
 break;
 case '5':
-append(buf, rv_freg_name_sym[dec->rs2], buflen);
+append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs2] :
+  rv_freg_name_sym[dec->rs2],
+   buflen);
 break;
 case '6':
-append(buf, rv_freg_name_sym[dec->rs3], buflen);
+append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs3] :
+  rv_freg_name_sym[dec->rs3],
+   buflen);
 break;
 case '7':
 snprintf(tmp, sizeof(tmp), "%d", dec->rs1);
-- 
2.40.1




[PULL 55/60] util/log: Add vector registers to log

2023-06-13 Thread Alistair Francis
From: Ivan Klokov 

Added QEMU option 'vpu' to log vector extension registers such as gpr\fpu.

Signed-off-by: Ivan Klokov 
Reviewed-by: Alistair Francis 
Message-Id: <20230410124451.15929-2-ivan.klo...@syntacore.com>
Signed-off-by: Alistair Francis 
---
 include/hw/core/cpu.h | 2 ++
 include/qemu/log.h| 1 +
 accel/tcg/cpu-exec.c  | 3 +++
 util/log.c| 2 ++
 4 files changed, 8 insertions(+)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 383456d1b3..d84fbccaab 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -544,11 +544,13 @@ GuestPanicInformation *cpu_get_crash_info(CPUState *cpu);
  * @CPU_DUMP_CODE:
  * @CPU_DUMP_FPU: dump FPU register state, not just integer
  * @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state
+ * @CPU_DUMP_VPU: dump VPU registers
  */
 enum CPUDumpFlags {
 CPU_DUMP_CODE = 0x0001,
 CPU_DUMP_FPU  = 0x0002,
 CPU_DUMP_CCOP = 0x0004,
+CPU_DUMP_VPU  = 0x0008,
 };
 
 /**
diff --git a/include/qemu/log.h b/include/qemu/log.h
index c5643d8dd5..df59bfabcd 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -35,6 +35,7 @@ bool qemu_log_separate(void);
 /* LOG_STRACE is used for user-mode strace logging. */
 #define LOG_STRACE (1 << 19)
 #define LOG_PER_THREAD (1 << 20)
+#define CPU_LOG_TB_VPU (1 << 21)
 
 /* Lock/unlock output. */
 
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 42086525d7..ebc1db03d7 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -313,6 +313,9 @@ static void log_cpu_exec(target_ulong pc, CPUState *cpu,
 #if defined(TARGET_I386)
 flags |= CPU_DUMP_CCOP;
 #endif
+if (qemu_loglevel_mask(CPU_LOG_TB_VPU)) {
+flags |= CPU_DUMP_VPU;
+}
 cpu_dump_state(cpu, logfile, flags);
 qemu_log_unlock(logfile);
 }
diff --git a/util/log.c b/util/log.c
index 53b4f6c58e..def88a9402 100644
--- a/util/log.c
+++ b/util/log.c
@@ -495,6 +495,8 @@ const QEMULogItem qemu_log_items[] = {
   "log every user-mode syscall, its input, and its result" },
 { LOG_PER_THREAD, "tid",
   "open a separate log file per thread; filename must contain '%d'" },
+{ CPU_LOG_TB_VPU, "vpu",
+  "include VPU registers in the 'cpu' logging" },
 { 0, NULL, NULL },
 };
 
-- 
2.40.1




[PULL 43/60] disas/riscv.c: Fix lines with over 80 characters

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Fix lines with over 80 characters.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Message-Id: <20230523093539.203909-8-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 201 +++---
 1 file changed, 140 insertions(+), 61 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index 806c4b6f93..bc433c4120 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1110,8 +1110,10 @@ static const char rv_vreg_name_sym[32][4] = {
 /* pseudo-instruction constraints */
 
 static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
-static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, 
rvc_end };
-static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, 
rvc_imm_eq_zero, rvc_end };
+static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero,
+rvc_end };
+static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0,
+   rvc_imm_eq_zero, rvc_end };
 static const rvc_constraint rvcc_mv[] = { rvc_imm_eq_zero, rvc_end };
 static const rvc_constraint rvcc_not[] = { rvc_imm_eq_n1, rvc_end };
 static const rvc_constraint rvcc_neg[] = { rvc_rs1_eq_x0, rvc_end };
@@ -1141,18 +1143,28 @@ static const rvc_constraint rvcc_bleu[] = { rvc_end };
 static const rvc_constraint rvcc_bgt[] = { rvc_end };
 static const rvc_constraint rvcc_bgtu[] = { rvc_end };
 static const rvc_constraint rvcc_j[] = { rvc_rd_eq_x0, rvc_end };
-static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, 
rvc_end };
-static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, 
rvc_end };
-static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc00, rvc_end };
-static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, 
rvc_end };
-static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc02, rvc_end };
-static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc80, rvc_end };
-static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc81, rvc_end };
+static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra,
+   rvc_end };
+static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero,
+  rvc_end };
+static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00,
+   rvc_end };
+static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01,
+  rvc_end };
+static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0,
+ rvc_csr_eq_0xc02, rvc_end };
+static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0,
+rvc_csr_eq_0xc80, rvc_end };
+static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81,
+   rvc_end };
 static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0,
   rvc_csr_eq_0xc82, rvc_end };
-static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, 
rvc_end };
-static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, 
rvc_end };
-static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0x001, rvc_end };
+static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003,
+ rvc_end };
+static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002,
+rvc_end };
+static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001,
+   rvc_end };
 static const rvc_constraint rvcc_fscsr[] = { rvc_csr_eq_0x003, rvc_end };
 static const rvc_constraint rvcc_fsrm[] = { rvc_csr_eq_0x002, rvc_end };
 static const rvc_constraint rvcc_fsflags[] = { rvc_csr_eq_0x001, rvc_end };
@@ -1554,17 +1566,23 @@ const rv_opcode_data opcode_data[] = {
 { "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
 { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
   rv_op_addi, rv_op_addi, rvcd_imm_nz },
-{ "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, 
rv_op_fld, 0 },
-{ "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, 
rv_op_lw },
+{ "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld,
+  rv_op_fld, 0 },
+{ "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw,
+  rv_op_lw },
 { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
-{ 

[PULL 44/60] disas/riscv.c: Remove redundant parentheses

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Remove redundant parenthese and fix multi-line comments.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Message-Id: <20230523093539.203909-9-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 219 +-
 1 file changed, 110 insertions(+), 109 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index bc433c4120..5005364aba 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -2390,9 +2390,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 {
 rv_inst inst = dec->inst;
 rv_opcode op = rv_op_illegal;
-switch (((inst >> 0) & 0b11)) {
+switch ((inst >> 0) & 0b11) {
 case 0:
-switch (((inst >> 13) & 0b111)) {
+switch ((inst >> 13) & 0b111) {
 case 0: op = rv_op_c_addi4spn; break;
 case 1:
 if (isa == rv128) {
@@ -2445,9 +2445,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 }
 break;
 case 1:
-switch (((inst >> 13) & 0b111)) {
+switch ((inst >> 13) & 0b111) {
 case 0:
-switch (((inst >> 2) & 0b111)) {
+switch ((inst >> 2) & 0b111) {
 case 0: op = rv_op_c_nop; break;
 default: op = rv_op_c_addi; break;
 }
@@ -2461,13 +2461,13 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 break;
 case 2: op = rv_op_c_li; break;
 case 3:
-switch (((inst >> 7) & 0b1)) {
+switch ((inst >> 7) & 0b1) {
 case 2: op = rv_op_c_addi16sp; break;
 default: op = rv_op_c_lui; break;
 }
 break;
 case 4:
-switch (((inst >> 10) & 0b11)) {
+switch ((inst >> 10) & 0b11) {
 case 0:
 op = rv_op_c_srli;
 break;
@@ -2504,7 +2504,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 }
 break;
 case 2:
-switch (((inst >> 13) & 0b111)) {
+switch ((inst >> 13) & 0b111) {
 case 0:
 op = rv_op_c_slli;
 break;
@@ -2524,17 +2524,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 }
 break;
 case 4:
-switch (((inst >> 12) & 0b1)) {
+switch ((inst >> 12) & 0b1) {
 case 0:
-switch (((inst >> 2) & 0b1)) {
+switch ((inst >> 2) & 0b1) {
 case 0: op = rv_op_c_jr; break;
 default: op = rv_op_c_mv; break;
 }
 break;
 case 1:
-switch (((inst >> 2) & 0b1)) {
+switch ((inst >> 2) & 0b1) {
 case 0:
-switch (((inst >> 7) & 0b1)) {
+switch ((inst >> 7) & 0b1) {
 case 0: op = rv_op_c_ebreak; break;
 default: op = rv_op_c_jalr; break;
 }
@@ -2608,9 +2608,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 }
 break;
 case 3:
-switch (((inst >> 2) & 0b1)) {
+switch ((inst >> 2) & 0b1) {
 case 0:
-switch (((inst >> 12) & 0b111)) {
+switch ((inst >> 12) & 0b111) {
 case 0: op = rv_op_lb; break;
 case 1: op = rv_op_lh; break;
 case 2: op = rv_op_lw; break;
@@ -2622,17 +2622,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 }
 break;
 case 1:
-switch (((inst >> 12) & 0b111)) {
+switch ((inst >> 12) & 0b111) {
 case 0:
-switch (((inst >> 20) & 0b)) {
+switch ((inst >> 20) & 0b) {
 case 40: op = rv_op_vl1re8_v; break;
 case 552: op = rv_op_vl2re8_v; break;
 case 1576: op = rv_op_vl4re8_v; break;
 case 3624: op = rv_op_vl8re8_v; break;
 }
-switch (((inst >> 26) & 0b111)) {
+switch ((inst >> 26) & 0b111) {
 case 0:
-switch (((inst >> 20) & 0b1)) {
+switch ((inst >> 20) & 0b1) {
 case 0: op = rv_op_vle8_v; break;
 case 11: op = rv_op_vlm_v; break;
 case 16: op = rv_op_vle8ff_v; break;
@@ -2647,15 +2647,15 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 case 3: op = rv_op_fld; break;
 case 4: op = rv_op_flq; break;
 case 5:
-switch (((inst >> 20) & 0b)) {
+switch ((inst >> 20) & 0b) {
 case 40: op = rv_op_vl1re16_v; break;
 case 552: op = rv_op_vl2re16_v; 

[PULL 52/60] hw/riscv: virt: Assume M-mode FW in pflash0 only when "-bios none"

2023-06-13 Thread Alistair Francis
From: Sunil V L 

Currently, virt machine supports two pflash instances each with
32MB size. However, the first pflash is always assumed to
contain M-mode firmware and reset vector is set to this if
enabled. Hence, for S-mode payloads like EDK2, only one pflash
instance is available for use. This means both code and NV variables
of EDK2 will need to use the same pflash.

The OS distros keep the EDK2 FW code as readonly. When non-volatile
variables also need to share the same pflash, it is not possible
to keep it as readonly since variables need write access.

To resolve this issue, the code and NV variables need to be separated.
But in that case we need an extra flash. Hence, modify the convention
for non-KVM guests such that, pflash0 will contain the M-mode FW
only when "-bios none" option is used. Otherwise, pflash0 will contain
the S-mode payload FW. This enables both pflash instances available
for EDK2 use.

When KVM is enabled, pflash0 is always assumed to contain the
S-mode payload firmware only.

Example usage:
1) pflash0 containing M-mode FW
qemu-system-riscv64 -bios none -pflash  -machine virt
or
qemu-system-riscv64 -bios none \
-drive file=,if=pflash,format=raw,unit=0 -machine virt

2) pflash0 containing S-mode payload like EDK2
qemu-system-riscv64 -pflash  -pflash  -machine  virt
or
qemu-system-riscv64 -bios  \
-pflash  \
-pflash  \
-machine  virt
or
qemu-system-riscv64 -bios  \
-drive file=,if=pflash,format=raw,unit=0,readonly=on \
-drive file=,if=pflash,format=raw,unit=1 \
-machine virt

Signed-off-by: Sunil V L 
Reported-by: Heinrich Schuchardt 
Tested-by: Andrea Bolognani 
Reviewed-by: Alistair Francis 
Message-Id: <20230601045910.18646-2-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt.c | 53 -
 1 file changed, 21 insertions(+), 32 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 245c7b97b2..17fdcef223 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1245,7 +1245,7 @@ static void virt_machine_done(Notifier *notifier, void 
*data)
 target_ulong firmware_end_addr, kernel_start_addr;
 const char *firmware_name = riscv_default_firmware_name(>soc[0]);
 uint32_t fdt_load_addr;
-uint64_t kernel_entry;
+uint64_t kernel_entry = 0;
 
 /*
  * Only direct boot kernel is currently supported for KVM VM,
@@ -1266,42 +1266,31 @@ static void virt_machine_done(Notifier *notifier, void 
*data)
 firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
  start_addr, NULL);
 
-if (drive_get(IF_PFLASH, 0, 1)) {
-/*
- * S-mode FW like EDK2 will be kept in second plash (unit 1).
- * When both kernel, initrd and pflash options are provided in the
- * command line, the kernel and initrd will be copied to the fw_cfg
- * table and opensbi will jump to the flash address which is the
- * entry point of S-mode FW. It is the job of the S-mode FW to load
- * the kernel and initrd using fw_cfg table.
- *
- * If only pflash is given but not -kernel, then it is the job of
- * of the S-mode firmware to locate and load the kernel.
- * In either case, the next_addr for opensbi will be the flash address.
- */
-riscv_setup_firmware_boot(machine);
-kernel_entry = virt_memmap[VIRT_FLASH].base +
-   virt_memmap[VIRT_FLASH].size / 2;
-} else if (machine->kernel_filename) {
+if (drive_get(IF_PFLASH, 0, 0)) {
+if (machine->firmware && !strcmp(machine->firmware, "none") &&
+!kvm_enabled()) {
+/*
+ * Pflash was supplied but bios is none and not KVM guest,
+ * let's overwrite the address we jump to after reset to
+ * the base of the flash.
+ */
+start_addr = virt_memmap[VIRT_FLASH].base;
+} else {
+/*
+ * Pflash was supplied but either KVM guest or bios is not none.
+ * In this case, base of the flash would contain S-mode payload.
+ */
+riscv_setup_firmware_boot(machine);
+kernel_entry = virt_memmap[VIRT_FLASH].base;
+}
+}
+
+if (machine->kernel_filename && !kernel_entry) {
 kernel_start_addr = riscv_calc_kernel_start_addr(>soc[0],
  firmware_end_addr);
 
 kernel_entry = riscv_load_kernel(machine, >soc[0],
  kernel_start_addr, true, NULL);
-} else {
-   /*
-* If dynamic firmware is used, it doesn't know where is the next mode
-* if kernel argument is not set.
-*/
-kernel_entry = 0;
-}
-
-if (drive_get(IF_PFLASH, 0, 0)) {
-/*
- * Pflash was supplied, let's overwrite the address we jump to after
- * reset to the base of the flash.
-   

[PULL 22/60] target/riscv: Flush TLB when pmpaddr is updated

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

TLB should be flushed not only for pmpcfg csr changes, but also for
pmpaddr csr changes.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Reviewed-by: LIU Zhiwei 
Message-Id: <20230517091519.34439-10-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 48a3e44a77..e0acee7a15 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -531,6 +531,7 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t 
addr_index,
 if (is_next_cfg_tor) {
 pmp_update_rule_addr(env, addr_index + 1);
 }
+tlb_flush(env_cpu(env));
 } else {
 qemu_log_mask(LOG_GUEST_ERROR,
   "ignoring pmpaddr write - locked\n");
-- 
2.40.1




[PULL 58/60] target/riscv/vector_helper.c: Remove the check for extra tail elements

2023-06-13 Thread Alistair Francis
From: Xiao Wang 

Commit 752614cab8e6 ("target/riscv: rvv: Add tail agnostic for vector
load / store instructions") added an extra check for LMUL fragmentation,
intended for setting the "rest tail elements" in the last register for a
segment load insn.

Actually, the max_elements derived in vext_ld*() won't be a fraction of
vector register size, since the lmul encoded in desc is emul, which has
already been adjusted to 1 for LMUL fragmentation case by vext_get_emul()
in trans_rvv.c.inc, for ld_stride(), ld_us(), ld_index() and ldff().

Besides, vext_get_emul() has also taken EEW/SEW into consideration, so no
need to call vext_get_total_elems() which would base on the emul to derive
another emul, the second emul would be incorrect when esz differs from sew.

Thus this patch removes the check for extra tail elements.

Fixes: 752614cab8e6 ("target/riscv: rvv: Add tail agnostic for vector load / 
store instructions")

Signed-off-by: Xiao Wang 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Message-Id: <20230607091646.4049428-1-xiao.w.w...@intel.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 22 ++
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index e8af64e626..1e06e7447c 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -264,11 +264,10 @@ GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw)
 GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl)
 GEN_VEXT_ST_ELEM(ste_d, int64_t, H8, stq)
 
-static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl,
-   void *vd, uint32_t desc, uint32_t nf,
+static void vext_set_tail_elems_1s(target_ulong vl, void *vd,
+   uint32_t desc, uint32_t nf,
uint32_t esz, uint32_t max_elems)
 {
-uint32_t total_elems, vlenb, registers_used;
 uint32_t vta = vext_vta(desc);
 int k;
 
@@ -276,19 +275,10 @@ static void vext_set_tail_elems_1s(CPURISCVState *env, 
target_ulong vl,
 return;
 }
 
-total_elems = vext_get_total_elems(env, desc, esz);
-vlenb = riscv_cpu_cfg(env)->vlen >> 3;
-
 for (k = 0; k < nf; ++k) {
 vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
   (k * max_elems + max_elems) * esz);
 }
-
-if (nf * max_elems % total_elems != 0) {
-registers_used = ((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
-vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
-  registers_used * vlenb);
-}
 }
 
 /*
@@ -324,7 +314,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 }
 env->vstart = 0;
 
-vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
+vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
 #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)\
@@ -383,7 +373,7 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 }
 env->vstart = 0;
 
-vext_set_tail_elems_1s(env, evl, vd, desc, nf, esz, max_elems);
+vext_set_tail_elems_1s(evl, vd, desc, nf, esz, max_elems);
 }
 
 /*
@@ -504,7 +494,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 }
 env->vstart = 0;
 
-vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
+vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
 #define GEN_VEXT_LD_INDEX(NAME, ETYPE, INDEX_FN, LOAD_FN)  \
@@ -634,7 +624,7 @@ ProbeSuccess:
 }
 env->vstart = 0;
 
-vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
+vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
 #define GEN_VEXT_LDFF(NAME, ETYPE, LOAD_FN)   \
-- 
2.40.1




[PULL 29/60] hw/riscv/opentitan: Explicit machine type definition

2023-06-13 Thread Alistair Francis
From: Philippe Mathieu-Daudé 

Expand the DEFINE_MACHINE() macro, converting the class_init()
handler.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20230520054510.68822-5-phi...@linaro.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h |  3 ++-
 hw/riscv/opentitan.c | 10 +++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index fd70226ed8..806ff73528 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -24,6 +24,7 @@
 #include "hw/char/ibex_uart.h"
 #include "hw/timer/ibex_timer.h"
 #include "hw/ssi/ibex_spi_host.h"
+#include "hw/boards.h"
 #include "qom/object.h"
 
 #define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
@@ -53,7 +54,7 @@ struct LowRISCIbexSoCState {
 MemoryRegion flash_alias;
 };
 
-#define TYPE_OPENTITAN_MACHINE "opentitan"
+#define TYPE_OPENTITAN_MACHINE MACHINE_TYPE_NAME("opentitan")
 
 typedef struct OpenTitanState {
 /*< private >*/
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 7d7159ea30..9535308197 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -108,8 +108,10 @@ static void opentitan_machine_init(MachineState *machine)
 }
 }
 
-static void opentitan_machine_class_init(MachineClass *mc)
+static void opentitan_machine_class_init(ObjectClass *oc, void *data)
 {
+MachineClass *mc = MACHINE_CLASS(oc);
+
 mc->desc = "RISC-V Board compatible with OpenTitan";
 mc->init = opentitan_machine_init;
 mc->max_cpus = 1;
@@ -118,8 +120,6 @@ static void opentitan_machine_class_init(MachineClass *mc)
 mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size;
 }
 
-DEFINE_MACHINE(TYPE_OPENTITAN_MACHINE, opentitan_machine_class_init)
-
 static void lowrisc_ibex_soc_init(Object *obj)
 {
 LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
@@ -327,6 +327,10 @@ static const TypeInfo open_titan_types[] = {
 .instance_size  = sizeof(LowRISCIbexSoCState),
 .instance_init  = lowrisc_ibex_soc_init,
 .class_init = lowrisc_ibex_soc_class_init,
+}, {
+.name   = TYPE_OPENTITAN_MACHINE,
+.parent = TYPE_MACHINE,
+.class_init = opentitan_machine_class_init,
 }
 };
 
-- 
2.40.1




[PULL 42/60] disas/riscv.c: Remove unused decomp_rv32/64 value for vector instructions

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Currently decomp_rv32 and decomp_rv64 value in opcode_data for vector
instructions are the same op index as their own. And they have no
functional decomp_data. So they have no functional difference from just
leaving them as zero.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Message-Id: <20230523093539.203909-7-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 740 +-
 1 file changed, 370 insertions(+), 370 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index c9a81af662..806c4b6f93 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1732,376 +1732,376 @@ const rv_opcode_data opcode_data[] = {
 { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
 { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
-{ "vle8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle8_v, 
rv_op_vle8_v, 0 },
-{ "vle16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle16_v, 
rv_op_vle16_v, 0 },
-{ "vle32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle32_v, 
rv_op_vle32_v, 0 },
-{ "vle64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle64_v, 
rv_op_vle64_v, 0 },
-{ "vse8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse8_v, 
rv_op_vse8_v, 0 },
-{ "vse16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse16_v, 
rv_op_vse16_v, 0 },
-{ "vse32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse32_v, 
rv_op_vse32_v, 0 },
-{ "vse64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse64_v, 
rv_op_vse64_v, 0 },
-{ "vlm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vlm_v, 
rv_op_vlm_v, 0 },
-{ "vsm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vsm_v, 
rv_op_vsm_v, 0 },
-{ "vlse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse8_v, 
rv_op_vlse8_v, 0 },
-{ "vlse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 
rv_op_vlse16_v, rv_op_vlse16_v, 0 },
-{ "vlse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 
rv_op_vlse32_v, rv_op_vlse32_v, 0 },
-{ "vlse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 
rv_op_vlse64_v, rv_op_vlse64_v, 0 },
-{ "vsse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse8_v, 
rv_op_vsse8_v, 0 },
-{ "vsse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 
rv_op_vsse16_v, rv_op_vsse16_v, 0 },
-{ "vsse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 
rv_op_vsse32_v, rv_op_vsse32_v, 0 },
-{ "vsse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 
rv_op_vsse64_v, rv_op_vsse64_v, 0 },
-{ "vluxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vluxei8_v, rv_op_vluxei8_v, 0 },
-{ "vluxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vluxei16_v, rv_op_vluxei16_v, 0 },
-{ "vluxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vluxei32_v, rv_op_vluxei32_v, 0 },
-{ "vluxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vluxei64_v, rv_op_vluxei64_v, 0 },
-{ "vloxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vloxei8_v, rv_op_vloxei8_v, 0 },
-{ "vloxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vloxei16_v, rv_op_vloxei16_v, 0 },
-{ "vloxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vloxei32_v, rv_op_vloxei32_v, 0 },
-{ "vloxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vloxei64_v, rv_op_vloxei64_v, 0 },
-{ "vsuxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsuxei8_v, rv_op_vsuxei8_v, 0 },
-{ "vsuxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsuxei16_v, rv_op_vsuxei16_v, 0 },
-{ "vsuxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsuxei32_v, rv_op_vsuxei32_v, 0 },
-{ "vsuxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsuxei64_v, rv_op_vsuxei64_v, 0 },
-{ "vsoxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsoxei8_v, rv_op_vsoxei8_v, 0 },
-{ "vsoxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsoxei16_v, rv_op_vsoxei16_v, 0 },
-{ "vsoxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsoxei32_v, rv_op_vsoxei32_v, 0 },
-{ "vsoxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 
rv_op_vsoxei64_v, rv_op_vsoxei64_v, 0 },
-{ "vle8ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 
rv_op_vle8ff_v, rv_op_vle8ff_v, 0 },
-{ "vle16ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 
rv_op_vle16ff_v, rv_op_vle16ff_v, 0 },
-{ "vle32ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 
rv_op_vle32ff_v, rv_op_vle32ff_v, 0 },
-{ "vle64ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 
rv_op_vle64ff_v, rv_op_vle64ff_v, 0 },
-{ "vl1re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, 

[PULL 36/60] target/riscv: smstateen knobs

2023-06-13 Thread Alistair Francis
From: Mayuresh Chitale 

Add knobs to allow users to enable smstateen and also export it via the
ISA extension string.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li
Reviewed-by: Alistair Francis 
Message-Id: <20230518175058.2772506-4-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e67c78f860..d23b4c4d16 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -119,6 +119,7 @@ static const struct isa_ext_data 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(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
 ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
 ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
 ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
@@ -1601,8 +1602,8 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
 DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
 
+DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
 DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true),
-
 DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false),
 DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false),
 DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false),
-- 
2.40.1




[PULL 24/60] target/riscv: Separate pmp_update_rule() in pmpcfg_csr_write

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Use pmp_update_rule_addr() and pmp_update_rule_nums() separately to
update rule nums only once for each pmpcfg_csr_write. Then remove
pmp_update_rule() since it become unused.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-12-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 3c12690565..37e9985d6a 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -29,7 +29,6 @@
 static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
   uint8_t val);
 static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index);
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index);
 
 /*
  * Accessor method to extract address matching type 'a field' from cfg reg
@@ -121,7 +120,7 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t 
pmp_index, uint8_t val)
 qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
 } else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) {
 env->pmp_state.pmp[pmp_index].cfg_reg = val;
-pmp_update_rule(env, pmp_index);
+pmp_update_rule_addr(env, pmp_index);
 return true;
 }
 } else {
@@ -209,18 +208,6 @@ void pmp_update_rule_nums(CPURISCVState *env)
 }
 }
 
-/*
- * Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
- *   end address values.
- *   This function is called relatively infrequently whereas the check that
- *   an address is within a pmp rule is called often, so optimise that one
- */
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
-{
-pmp_update_rule_addr(env, pmp_index);
-pmp_update_rule_nums(env);
-}
-
 static int pmp_is_in_range(CPURISCVState *env, int pmp_index,
target_ulong addr)
 {
@@ -481,6 +468,7 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t 
reg_index,
 
 /* If PMP permission of any addr has been changed, flush TLB pages. */
 if (modified) {
+pmp_update_rule_nums(env);
 tlb_flush(env_cpu(env));
 }
 }
-- 
2.40.1




[PULL 46/60] target/riscv: Introduce cur_insn_len into DisasContext

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Use cur_insn_len to store the length of the current instruction to
prepare for PC-relative translation.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230526072124.298466-3-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6fbdb50c5d..ea63d20eef 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -61,6 +61,7 @@ typedef struct DisasContext {
 DisasContextBase base;
 /* pc_succ_insn points to the instruction following base.pc_next */
 target_ulong pc_succ_insn;
+target_ulong cur_insn_len;
 target_ulong priv_ver;
 RISCVMXL misa_mxl_max;
 RISCVMXL xl;
@@ -1116,8 +1117,9 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 };
 
 ctx->virt_inst_excp = false;
+ctx->cur_insn_len = insn_len(opcode);
 /* Check for compressed insn */
-if (insn_len(opcode) == 2) {
+if (ctx->cur_insn_len == 2) {
 ctx->opcode = opcode;
 ctx->pc_succ_insn = ctx->base.pc_next + 2;
 /*
-- 
2.40.1




[PULL 49/60] target/riscv: Use true diff for gen_pc_plus_diff

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Reduce reliance on absolute values by using true pc difference for
gen_pc_plus_diff() to prepare for PC-relative translation.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230526072124.298466-6-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c  | 13 ++---
 target/riscv/insn_trans/trans_rvi.c.inc   |  6 ++
 target/riscv/insn_trans/trans_rvzce.c.inc |  2 +-
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index eda022d10b..7fb4cbe84c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -226,8 +226,10 @@ static void decode_save_opc(DisasContext *ctx)
 }
 
 static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
- target_ulong dest)
+ target_long diff)
 {
+target_ulong dest = ctx->base.pc_next + diff;
+
 if (get_xl(ctx) == MXL_RV32) {
 dest = (int32_t)dest;
 }
@@ -236,7 +238,7 @@ static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
 
 static void gen_update_pc(DisasContext *ctx, target_long diff)
 {
-gen_pc_plus_diff(cpu_pc, ctx, ctx->base.pc_next + diff);
+gen_pc_plus_diff(cpu_pc, ctx, diff);
 }
 
 static void generate_exception(DisasContext *ctx, int excp)
@@ -547,14 +549,11 @@ static void gen_set_fpr_d(DisasContext *ctx, int reg_num, 
TCGv_i64 t)
 
 static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
 {
-target_ulong next_pc;
-
 /* check misaligned: */
-next_pc = ctx->base.pc_next + imm;
 if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
-if ((next_pc & 0x3) != 0) {
+if ((imm & 0x3) != 0) {
 TCGv target_pc = tcg_temp_new();
-gen_pc_plus_diff(target_pc, ctx, next_pc);
+gen_pc_plus_diff(target_pc, ctx, imm);
 gen_exception_inst_addr_mis(ctx, target_pc);
 return;
 }
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 4837e133cc..2d350cfbd7 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -158,7 +158,6 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 TCGLabel *l = gen_new_label();
 TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
 TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
-target_ulong next_pc;
 
 if (get_xl(ctx) == MXL_RV128) {
 TCGv src1h = get_gprh(ctx, a->rs1);
@@ -175,12 +174,11 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, 
TCGCond cond)
 
 gen_set_label(l); /* branch taken */
 
-next_pc = ctx->base.pc_next + a->imm;
 if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca &&
-(next_pc & 0x3)) {
+(a->imm & 0x3)) {
 /* misaligned */
 TCGv target_pc = tcg_temp_new();
-gen_pc_plus_diff(target_pc, ctx, next_pc);
+gen_pc_plus_diff(target_pc, ctx, a->imm);
 gen_exception_inst_addr_mis(ctx, target_pc);
 } else {
 gen_goto_tb(ctx, 0, a->imm);
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
index 5732d782f7..450b79dcbc 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -297,7 +297,7 @@ static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a)
  * Update pc to current for the non-unwinding exception
  * that might come from cpu_ld*_code() in the helper.
  */
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_update_pc(ctx, 0);
 gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->index));
 
 /* c.jt vs c.jalt depends on the index. */
-- 
2.40.1




[PULL 40/60] disas/riscv.c: Support disas for Zcm* extensions

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Support disas for Zcmt* instructions only when related extensions
are supported.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-Id: <20230523093539.203909-5-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index f2dd5fd531..6659f92179 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -2505,7 +2505,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 op = rv_op_c_sqsp;
 } else {
 op = rv_op_c_fsdsp;
-if (((inst >> 12) & 0b01)) {
+if (dec->cfg->ext_zcmp && ((inst >> 12) & 0b01)) {
 switch ((inst >> 8) & 0b0) {
 case 8:
 if (((inst >> 4) & 0b0) >= 4) {
@@ -2531,6 +2531,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 } else {
 switch ((inst >> 10) & 0b011) {
 case 0:
+if (!dec->cfg->ext_zcmt) {
+break;
+}
 if (((inst >> 2) & 0xFF) >= 32) {
 op = rv_op_cm_jalt;
 } else {
@@ -2538,6 +2541,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 }
 break;
 case 3:
+if (!dec->cfg->ext_zcmp) {
+break;
+}
 switch ((inst >> 5) & 0b011) {
 case 1: op = rv_op_cm_mvsa01; break;
 case 3: op = rv_op_cm_mva01s; break;
-- 
2.40.1




[PULL 59/60] target/riscv: Smepmp: Return error when access permission not allowed in PMP

2023-06-13 Thread Alistair Francis
From: Himanshu Chauhan 

On an address match, skip checking for default permissions and return error
based on access defined in PMP configuration.

v3 Changes:
o Removed explicit return of boolean value from comparision
  of priv/allowed_priv

v2 Changes:
o Removed goto to return in place when address matches
o Call pmp_hart_has_privs_default at the end of the loop

Fixes: 90b1fafce06 ("target/riscv: Smepmp: Skip applying default rules when 
address matches")
Signed-off-by: Himanshu Chauhan 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Message-Id: <20230605164548.715336-1-hchau...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 418738afd8..9d8db493e6 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -291,7 +291,6 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 pmp_priv_t *allowed_privs, target_ulong mode)
 {
 int i = 0;
-bool ret = false;
 int pmp_size = 0;
 target_ulong s = 0;
 target_ulong e = 0;
@@ -435,17 +434,12 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
  * defined with PMP must be used. We shouldn't fallback on
  * finding default privileges.
  */
-ret = true;
-break;
+return (privs & *allowed_privs) == privs;
 }
 }
 
 /* No rule matched */
-if (!ret) {
-ret = pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
-}
-
-return ret;
+return pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
 }
 
 /*
-- 
2.40.1




[PULL 28/60] hw/riscv/opentitan: Add TYPE_OPENTITAN_MACHINE definition

2023-06-13 Thread Alistair Francis
From: Philippe Mathieu-Daudé 

QOM type names are usually defined as TYPE_FOO.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20230520054510.68822-4-phi...@linaro.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h | 2 ++
 hw/riscv/opentitan.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index c40b05052a..fd70226ed8 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -53,6 +53,8 @@ struct LowRISCIbexSoCState {
 MemoryRegion flash_alias;
 };
 
+#define TYPE_OPENTITAN_MACHINE "opentitan"
+
 typedef struct OpenTitanState {
 /*< private >*/
 SysBusDevice parent_obj;
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 294955eeea..7d7159ea30 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -118,7 +118,7 @@ static void opentitan_machine_class_init(MachineClass *mc)
 mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size;
 }
 
-DEFINE_MACHINE("opentitan", opentitan_machine_class_init)
+DEFINE_MACHINE(TYPE_OPENTITAN_MACHINE, opentitan_machine_class_init)
 
 static void lowrisc_ibex_soc_init(Object *obj)
 {
-- 
2.40.1




[PULL 34/60] target/riscv: smstateen check for fcsr

2023-06-13 Thread Alistair Francis
From: Mayuresh Chitale 

Implement the s/h/mstateen.fcsr bit as defined in the smstateen spec
and check for it when accessing the fcsr register and its fields.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230518175058.2772506-2-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ad73691878..58499b5afc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -82,6 +82,10 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 !riscv_cpu_cfg(env)->ext_zfinx) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
+
+if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
+}
 #endif
 return RISCV_EXCP_NONE;
 }
@@ -2104,6 +2108,9 @@ static RISCVException write_mstateen0(CPURISCVState *env, 
int csrno,
   target_ulong new_val)
 {
 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+if (!riscv_has_ext(env, RVF)) {
+wr_mask |= SMSTATEEN0_FCSR;
+}
 
 return write_mstateen(env, csrno, wr_mask, new_val);
 }
@@ -2177,6 +2184,10 @@ static RISCVException write_hstateen0(CPURISCVState 
*env, int csrno,
 {
 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
+if (!riscv_has_ext(env, RVF)) {
+wr_mask |= SMSTATEEN0_FCSR;
+}
+
 return write_hstateen(env, csrno, wr_mask, new_val);
 }
 
@@ -2263,6 +2274,10 @@ static RISCVException write_sstateen0(CPURISCVState 
*env, int csrno,
 {
 uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
+if (!riscv_has_ext(env, RVF)) {
+wr_mask |= SMSTATEEN0_FCSR;
+}
+
 return write_sstateen(env, csrno, wr_mask, new_val);
 }
 
-- 
2.40.1




[PULL 21/60] target/riscv: Update the next rule addr in pmpaddr_csr_write()

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Currently only the rule addr of the same index of pmpaddr is updated
when pmpaddr CSR is modified. However, the rule addr of next PMP entry
may also be affected if its A field is PMP_AMATCH_TOR. So we should
also update it in this case.

Write to pmpaddr CSR will not affect the rule nums, So we needn't update
call pmp_update_rule_nums()  in pmpaddr_csr_write().

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-9-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 4d62dfc732..48a3e44a77 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -507,6 +507,7 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t 
addr_index,
target_ulong val)
 {
 trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
+bool is_next_cfg_tor = false;
 
 if (addr_index < MAX_RISCV_PMPS) {
 /*
@@ -515,9 +516,9 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t 
addr_index,
  */
 if (addr_index + 1 < MAX_RISCV_PMPS) {
 uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
+is_next_cfg_tor = PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg);
 
-if (pmp_cfg & PMP_LOCK &&
-PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) {
+if (pmp_cfg & PMP_LOCK && is_next_cfg_tor) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "ignoring pmpaddr write - pmpcfg + 1 locked\n");
 return;
@@ -526,7 +527,10 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t 
addr_index,
 
 if (!pmp_is_locked(env, addr_index)) {
 env->pmp_state.pmp[addr_index].addr_reg = val;
-pmp_update_rule(env, addr_index);
+pmp_update_rule_addr(env, addr_index);
+if (is_next_cfg_tor) {
+pmp_update_rule_addr(env, addr_index + 1);
+}
 } else {
 qemu_log_mask(LOG_GUEST_ERROR,
   "ignoring pmpaddr write - locked\n");
-- 
2.40.1




[PULL 60/60] hw/intc: If mmsiaddrcfgh.L == 1, smsiaddrcfg and smsiaddrcfgh are read-only.

2023-06-13 Thread Alistair Francis
From: Tommy Wu 

According to the `The RISC-V Advanced Interrupt Architecture`
document, if register `mmsiaddrcfgh` of the domain has bit L set
to one, then `smsiaddrcfg` and `smsiaddrcfgh` are locked as
read-only alongside `mmsiaddrcfg` and `mmsiaddrcfgh`.

Signed-off-by: Tommy Wu 
Reviewed-by: Frank Chang 
Acked-by: Alistair Francis 
Reviewed-by: Anup Patel 
Message-Id: <20230609055936.3925438-1-tommy...@sifive.com>
Signed-off-by: Alistair Francis 
---
 hw/intc/riscv_aplic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index afc5b54dbb..4bdc6a5d1a 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -688,13 +688,13 @@ static void riscv_aplic_write(void *opaque, hwaddr addr, 
uint64_t value,
  * domains).
  */
 if (aplic->num_children &&
-!(aplic->smsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
+!(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
 aplic->smsicfgaddr = value;
 }
 } else if (aplic->mmode && aplic->msimode &&
(addr == APLIC_SMSICFGADDRH)) {
 if (aplic->num_children &&
-!(aplic->smsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
+!(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
 aplic->smsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK;
 }
 } else if ((APLIC_SETIP_BASE <= addr) &&
-- 
2.40.1




[PULL 11/60] target/riscv/cpu.c: validate extensions before riscv_timer_init()

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

There is no need to init timers if we're not even sure that our
extensions are valid. Execute riscv_cpu_validate_set_extensions() before
riscv_timer_init().

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230517135714.211809-10-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 89a1a25812..9f2c8fa7c6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1294,13 +1294,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-
-#ifndef CONFIG_USER_ONLY
-if (cpu->cfg.ext_sstc) {
-riscv_timer_init(cpu);
-}
-#endif /* CONFIG_USER_ONLY */
-
 riscv_cpu_validate_set_extensions(cpu, _err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
@@ -1308,6 +1301,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 
 #ifndef CONFIG_USER_ONLY
+if (cpu->cfg.ext_sstc) {
+riscv_timer_init(cpu);
+}
+
 if (cpu->cfg.pmu_num) {
 if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
 cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-- 
2.40.1




[PULL 16/60] target/riscv: Make the short cut really work in pmp_hart_has_privs

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Return the result directly for short cut, since We needn't do the
following check on the PMP entries if there is no PMP rules.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-4-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 2bc924340a..3c90562d55 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -316,6 +316,7 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
allowed_privs, mode)) {
 ret = MAX_RISCV_PMPS;
 }
+return ret;
 }
 
 if (size == 0) {
-- 
2.40.1




[PULL 20/60] target/riscv: Flush TLB when MMWP or MML bits are changed

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

MMWP and MML bits may affect the allowed privs of PMP entries and the
default privs, both of which may change the allowed privs of exsited
TLB entries. So we need flush TLB when they are changed.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-8-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 2403039133..4d62dfc732 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -578,6 +578,9 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
 if (riscv_cpu_cfg(env)->epmp) {
 /* Sticky bits */
 val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
+if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) {
+tlb_flush(env_cpu(env));
+}
 } else {
 val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
 }
-- 
2.40.1




[PULL 30/60] hw/riscv/opentitan: Correct OpenTitanState parent type/size

2023-06-13 Thread Alistair Francis
From: Philippe Mathieu-Daudé 

OpenTitanState is the 'machine' (or 'board') state: it isn't
a SysBus device, but inherits from the MachineState type.
Correct the instance size.
Doing so we  avoid leaking an OpenTitanState pointer in
opentitan_machine_init().

Fixes: fe0fe4735e ("riscv: Initial commit of OpenTitan machine")
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20230520054510.68822-6-phi...@linaro.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h | 3 ++-
 hw/riscv/opentitan.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 806ff73528..609473d07b 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -55,10 +55,11 @@ struct LowRISCIbexSoCState {
 };
 
 #define TYPE_OPENTITAN_MACHINE MACHINE_TYPE_NAME("opentitan")
+OBJECT_DECLARE_SIMPLE_TYPE(OpenTitanState, OPENTITAN_MACHINE)
 
 typedef struct OpenTitanState {
 /*< private >*/
-SysBusDevice parent_obj;
+MachineState parent_obj;
 
 /*< public >*/
 LowRISCIbexSoCState soc;
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 9535308197..6a2fcc4ade 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -78,8 +78,8 @@ static const MemMapEntry ibex_memmap[] = {
 static void opentitan_machine_init(MachineState *machine)
 {
 MachineClass *mc = MACHINE_GET_CLASS(machine);
+OpenTitanState *s = OPENTITAN_MACHINE(machine);
 const MemMapEntry *memmap = ibex_memmap;
-OpenTitanState *s = g_new0(OpenTitanState, 1);
 MemoryRegion *sys_mem = get_system_memory();
 
 if (machine->ram_size != mc->default_ram_size) {
@@ -330,6 +330,7 @@ static const TypeInfo open_titan_types[] = {
 }, {
 .name   = TYPE_OPENTITAN_MACHINE,
 .parent = TYPE_MACHINE,
+.instance_size  = sizeof(OpenTitanState),
 .class_init = opentitan_machine_class_init,
 }
 };
-- 
2.40.1




[PULL 51/60] target/riscv: Remove pc_succ_insn from DisasContext

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

pc_succ_insn is no longer useful after the introduce of cur_insn_len
and all pc related value use diff value instead of absolute value.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230526072124.298466-8-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index bd2da9b079..8a33da811e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -59,8 +59,6 @@ typedef enum {
 
 typedef struct DisasContext {
 DisasContextBase base;
-/* pc_succ_insn points to the instruction following base.pc_next */
-target_ulong pc_succ_insn;
 target_ulong cur_insn_len;
 target_ulong pc_save;
 target_ulong priv_ver;
@@ -1149,7 +1147,6 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 /* Check for compressed insn */
 if (ctx->cur_insn_len == 2) {
 ctx->opcode = opcode;
-ctx->pc_succ_insn = ctx->base.pc_next + 2;
 /*
  * The Zca extension is added as way to refer to instructions in the C
  * extension that do not include the floating-point loads and stores
@@ -1164,7 +1161,6 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
  translator_lduw(env, >base,
  ctx->base.pc_next + 2));
 ctx->opcode = opcode32;
-ctx->pc_succ_insn = ctx->base.pc_next + 4;
 
 for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
 if (decoders[i].guard_func(ctx) &&
@@ -1185,7 +1181,6 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 uint32_t tb_flags = ctx->base.tb->flags;
 
 ctx->pc_save = ctx->base.pc_first;
-ctx->pc_succ_insn = ctx->base.pc_first;
 ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
 ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
 ctx->mstatus_fs = FIELD_EX32(tb_flags, TB_FLAGS, FS);
@@ -1238,7 +1233,7 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 
 ctx->ol = ctx->xl;
 decode_opc(env, ctx, opcode16);
-ctx->base.pc_next = ctx->pc_succ_insn;
+ctx->base.pc_next += ctx->cur_insn_len;
 
 /* Only the first insn within a TB is allowed to cross a page boundary. */
 if (ctx->base.is_jmp == DISAS_NEXT) {
-- 
2.40.1




[PULL 37/60] disas: Change type of disassemble_info.target_info to pointer

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Use pointer to pass more information of target to disasembler,
such as pass cpu.cfg related information in following commits.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-Id: <20230523093539.203909-2-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 include/disas/dis-asm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 2f6f91c2ee..2324f6b1a4 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -397,7 +397,7 @@ typedef struct disassemble_info {
   char * disassembler_options;
 
   /* Field intended to be used by targets in any way they deem suitable.  */
-  int64_t target_info;
+  void *target_info;
 
   /* Options for Capstone disassembly.  */
   int cap_arch;
-- 
2.40.1




[PULL 39/60] target/riscv: Pass RISCVCPUConfig as target_info to disassemble_info

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Pass RISCVCPUConfig as disassemble_info.target_info to support disas
of conflict instructions related to specific extensions.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-Id: <20230523093539.203909-4-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 disas/riscv.c  | 10 +++---
 target/riscv/cpu.c |  1 +
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index d597161d46..f2dd5fd531 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -19,7 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "disas/dis-asm.h"
-
+#include "target/riscv/cpu_cfg.h"
 
 /* types */
 
@@ -969,6 +969,7 @@ typedef enum {
 /* structures */
 
 typedef struct {
+RISCVCPUConfig *cfg;
 uint64_t  pc;
 uint64_t  inst;
 int32_t   imm;
@@ -4861,11 +4862,13 @@ static void decode_inst_decompress(rv_decode *dec, 
rv_isa isa)
 /* disassemble instruction */
 
 static void
-disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
+disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
+RISCVCPUConfig *cfg)
 {
 rv_decode dec = { 0 };
 dec.pc = pc;
 dec.inst = inst;
+dec.cfg = cfg;
 decode_inst_opcode(, isa);
 decode_inst_operands(, isa);
 decode_inst_decompress(, isa);
@@ -4920,7 +4923,8 @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info 
*info, rv_isa isa)
 break;
 }
 
-disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
+disasm_inst(buf, sizeof(buf), isa, memaddr, inst,
+(RISCVCPUConfig *)info->target_info);
 (*info->fprintf_func)(info->stream, "%s", buf);
 
 return len;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d23b4c4d16..938c7bd87b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -849,6 +849,7 @@ static void riscv_cpu_reset_hold(Object *obj)
 static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
 {
 RISCVCPU *cpu = RISCV_CPU(s);
+info->target_info = >cfg;
 
 switch (riscv_cpu_mxl(>env)) {
 case MXL_RV32:
-- 
2.40.1




[PULL 13/60] target/riscv: rework write_misa()

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

write_misa() must use as much common logic as possible. We want to open
code just the bits that are exclusive to the CSR write operation and TCG
internals.

Our validation is done with riscv_cpu_validate_set_extensions(), but we
need a small tweak first. When enabling RVG we're doing:

env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
env->misa_ext_mask = env->misa_ext;

This works fine for realize() time but this can potentially overwrite
env->misa_ext_mask if we reutilize the function for write_misa().

Instead of doing misa_ext_mask = misa_ext, sum up the RVG extensions in
misa_ext_mask as well. This won't change realize() time behavior
(misa_ext_mask will be == misa_ext) and will ensure that write_misa()
won't change misa_ext_mask by accident.

After that, rewrite write_misa() to work as follows:

- mask the write using misa_ext_mask to avoid enabling unsupported
  extensions;

- suppress RVC if the next insn isn't aligned;

- disable RVG if any of RVG dependencies are being disabled by the user;

- assign env->misa_ext and run riscv_cpu_validate_set_extensions(). On
  error, rollback env->misa_ext to its original value, logging a
  GUEST_ERROR to inform the user about the failed write;

- handle RVF and MSTATUS_FS and continue as usual.

Let's keep write_misa() as experimental for now until this logic gains
enough mileage.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Signed-off-by: Daniel Henrique Barboza 
Message-Id: <20230517135714.211809-12-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 +
 target/riscv/cpu.c |  4 ++--
 target/riscv/csr.c | 51 ++
 3 files changed, 27 insertions(+), 29 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 15423585d0..1f39edc687 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -548,6 +548,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 bool probe, uintptr_t retaddr);
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(void);
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
 
 #define cpu_list riscv_cpu_list
 #define cpu_mmu_index riscv_cpu_mmu_index
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 778801dffc..e67c78f860 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -981,7 +981,7 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, 
Error **errp)
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly.
  */
-static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
 CPURISCVState *env = >env;
 Error *local_err = NULL;
@@ -997,7 +997,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_ifencei = true;
 
 env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
-env->misa_ext_mask = env->misa_ext;
+env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD;
 }
 
 if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) {
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4451bd1263..cf7da4f87f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1387,39 +1387,18 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
 static RISCVException write_misa(CPURISCVState *env, int csrno,
  target_ulong val)
 {
+RISCVCPU *cpu = env_archcpu(env);
+uint32_t orig_misa_ext = env->misa_ext;
+Error *local_err = NULL;
+
 if (!riscv_cpu_cfg(env)->misa_w) {
 /* drop write to misa */
 return RISCV_EXCP_NONE;
 }
 
-/* 'I' or 'E' must be present */
-if (!(val & (RVI | RVE))) {
-/* It is not, drop write to misa */
-return RISCV_EXCP_NONE;
-}
-
-/* 'E' excludes all other extensions */
-if (val & RVE) {
-/*
- * when we support 'E' we can do "val = RVE;" however
- * for now we just drop writes if 'E' is present.
- */
-return RISCV_EXCP_NONE;
-}
-
-/*
- * misa.MXL writes are not supported by QEMU.
- * Drop writes to those bits.
- */
-
 /* Mask extensions that are not supported by this hart */
 val &= env->misa_ext_mask;
 
-/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
-if ((val & RVD) && !(val & RVF)) {
-val &= ~RVD;
-}
-
 /*
  * Suppress 'C' if next instruction is not aligned
  * TODO: this should check next_pc
@@ -1428,18 +1407,36 @@ static RISCVException write_misa(CPURISCVState *env, 
int csrno,
 val &= ~RVC;
 }
 
+/* Disable RVG if any of its dependencies are disabled */
+if (!(val & RVI && val & RVM && val & RVA &&
+  val & RVF && val & RVD)) {
+val &= ~RVG;
+}
+
 /* If nothing changed, do nothing. */
 if (val == env->misa_ext) {
  

[PULL 31/60] hw/riscv: qemu crash when NUMA nodes exceed available CPUs

2023-06-13 Thread Alistair Francis
From: Yin Wang 

Command "qemu-system-riscv64 -machine virt
-m 2G -smp 1 -numa node,mem=1G -numa node,mem=1G"
would trigger this problem.Backtrace with:
 #0  0x55b5b1a4 in riscv_numa_get_default_cpu_node_id  at 
../hw/riscv/numa.c:211
 #1  0x558ce510 in machine_numa_finish_cpu_init  at 
../hw/core/machine.c:1230
 #2  0x558ce9d3 in machine_run_board_init  at ../hw/core/machine.c:1346
 #3  0x55aaedc3 in qemu_init_board  at ../softmmu/vl.c:2513
 #4  0x55aaf064 in qmp_x_exit_preconfig  at ../softmmu/vl.c:2609
 #5  0x55ab1916 in qemu_init  at ../softmmu/vl.c:3617
 #6  0x5585463b in main  at ../softmmu/main.c:47
This commit fixes the issue by adding parameter checks.

Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Signed-off-by: Yin Wang 
Message-Id: <20230519023758.1759434-1-yin.w...@intel.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/numa.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
index 4720102561..e0414d5b1b 100644
--- a/hw/riscv/numa.c
+++ b/hw/riscv/numa.c
@@ -207,6 +207,12 @@ int64_t riscv_numa_get_default_cpu_node_id(const 
MachineState *ms, int idx)
 {
 int64_t nidx = 0;
 
+if (ms->numa_state->num_nodes > ms->smp.cpus) {
+error_report("Number of NUMA nodes (%d)"
+ " cannot exceed the number of available CPUs (%d).",
+ ms->numa_state->num_nodes, ms->smp.max_cpus);
+exit(EXIT_FAILURE);
+}
 if (ms->numa_state->num_nodes) {
 nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
 if (ms->numa_state->num_nodes <= nidx) {
-- 
2.40.1




[PULL 25/60] target/riscv: Deny access if access is partially inside the PMP entry

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Access will fail if access is partially inside the PMP entry.
However,only setting ret = false doesn't really mean pmp violation
since pmp_hart_has_privs_default() may return true at the end of
pmp_hart_has_privs().

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-13-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 37e9985d6a..418738afd8 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -327,8 +327,8 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 if ((s + e) == 1) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "pmp violation - access is partially inside\n");
-ret = false;
-break;
+*allowed_privs = 0;
+return false;
 }
 
 /* fully inside */
-- 
2.40.1




[PULL 38/60] target/riscv: Split RISCVCPUConfig declarations from cpu.h into cpu_cfg.h

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

Split RISCVCPUConfig declarations to prepare for passing it to disas.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20230523093539.203909-3-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 114 +-
 target/riscv/cpu_cfg.h | 136 +
 2 files changed, 137 insertions(+), 113 deletions(-)
 create mode 100644 target/riscv/cpu_cfg.h

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 1f39edc687..e3e08d315f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -27,6 +27,7 @@
 #include "qom/object.h"
 #include "qemu/int128.h"
 #include "cpu_bits.h"
+#include "cpu_cfg.h"
 #include "qapi/qapi-types-common.h"
 #include "cpu-qom.h"
 
@@ -370,119 +371,6 @@ struct CPUArchState {
 uint64_t kvm_timer_frequency;
 };
 
-/*
- * map is a 16-bit bitmap: the most significant set bit in map is the maximum
- * satp mode that is supported. It may be chosen by the user and must respect
- * what qemu implements (valid_1_10_32/64) and what the hw is capable of
- * (supported bitmap below).
- *
- * init is a 16-bit bitmap used to make sure the user selected a correct
- * configuration as per the specification.
- *
- * supported is a 16-bit bitmap used to reflect the hw capabilities.
- */
-typedef struct {
-uint16_t map, init, supported;
-} RISCVSATPMap;
-
-struct RISCVCPUConfig {
-bool ext_zba;
-bool ext_zbb;
-bool ext_zbc;
-bool ext_zbkb;
-bool ext_zbkc;
-bool ext_zbkx;
-bool ext_zbs;
-bool ext_zca;
-bool ext_zcb;
-bool ext_zcd;
-bool ext_zce;
-bool ext_zcf;
-bool ext_zcmp;
-bool ext_zcmt;
-bool ext_zk;
-bool ext_zkn;
-bool ext_zknd;
-bool ext_zkne;
-bool ext_zknh;
-bool ext_zkr;
-bool ext_zks;
-bool ext_zksed;
-bool ext_zksh;
-bool ext_zkt;
-bool ext_ifencei;
-bool ext_icsr;
-bool ext_icbom;
-bool ext_icboz;
-bool ext_zicond;
-bool ext_zihintpause;
-bool ext_smstateen;
-bool ext_sstc;
-bool ext_svadu;
-bool ext_svinval;
-bool ext_svnapot;
-bool ext_svpbmt;
-bool ext_zdinx;
-bool ext_zawrs;
-bool ext_zfh;
-bool ext_zfhmin;
-bool ext_zfinx;
-bool ext_zhinx;
-bool ext_zhinxmin;
-bool ext_zve32f;
-bool ext_zve64f;
-bool ext_zve64d;
-bool ext_zmmul;
-bool ext_zvfh;
-bool ext_zvfhmin;
-bool ext_smaia;
-bool ext_ssaia;
-bool ext_sscofpmf;
-bool rvv_ta_all_1s;
-bool rvv_ma_all_1s;
-
-uint32_t mvendorid;
-uint64_t marchid;
-uint64_t mimpid;
-
-/* Vendor-specific custom extensions */
-bool ext_xtheadba;
-bool ext_xtheadbb;
-bool ext_xtheadbs;
-bool ext_xtheadcmo;
-bool ext_xtheadcondmov;
-bool ext_xtheadfmemidx;
-bool ext_xtheadfmv;
-bool ext_xtheadmac;
-bool ext_xtheadmemidx;
-bool ext_xtheadmempair;
-bool ext_xtheadsync;
-bool ext_XVentanaCondOps;
-
-uint8_t pmu_num;
-char *priv_spec;
-char *user_spec;
-char *bext_spec;
-char *vext_spec;
-uint16_t vlen;
-uint16_t elen;
-uint16_t cbom_blocksize;
-uint16_t cboz_blocksize;
-bool mmu;
-bool pmp;
-bool epmp;
-bool debug;
-bool misa_w;
-
-bool short_isa_string;
-
-#ifndef CONFIG_USER_ONLY
-RISCVSATPMap satp_mode;
-#endif
-};
-
-typedef struct RISCVCPUConfig RISCVCPUConfig;
-
 /*
  * RISCVCPU:
  * @env: #CPURISCVState
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
new file mode 100644
index 00..c4a627d335
--- /dev/null
+++ b/target/riscv/cpu_cfg.h
@@ -0,0 +1,136 @@
+/*
+ * QEMU RISC-V CPU CFG
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2021-2023 PLCT Lab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef RISCV_CPU_CFG_H
+#define RISCV_CPU_CFG_H
+
+/*
+ * map is a 16-bit bitmap: the most significant set bit in map is the maximum
+ * satp mode that is supported. It may be chosen by the user and must respect
+ * what qemu implements (valid_1_10_32/64) and what the hw is capable of
+ * (supported bitmap below).
+ *
+ * init is a 16-bit bitmap used to make sure the user selected a correct
+ * configuration as per the specification.
+ *
+ * supported 

[PULL 35/60] target/riscv: Reuse tb->flags.FS

2023-06-13 Thread Alistair Francis
From: Mayuresh Chitale 

When misa.F is 0 tb->flags.FS field is unused and can be used to save
the current state of smstateen0.FCSR check which is needed by the
floating point translation routines.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Richard Henderson 
Reviewed-by: Weiwei Li 
Message-Id: <20230518175058.2772506-3-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c   | 6 ++
 target/riscv/insn_trans/trans_rvf.c.inc | 7 ---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 35ddd0caac..523311b184 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -120,6 +120,12 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
 }
 
+/* With Zfinx, floating point is enabled/disabled by Smstateen. */
+if (!riscv_has_ext(env, RVF)) {
+fs = (smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR) == RISCV_EXCP_NONE)
+ ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED;
+}
+
 if (cpu->cfg.debug && !icount_enabled()) {
 flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
 }
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index c47138575a..a0da7391c7 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -19,9 +19,10 @@
  */
 
 #define REQUIRE_FPU do {\
-if (ctx->mstatus_fs == EXT_STATUS_DISABLED) \
-if (!ctx->cfg_ptr->ext_zfinx) \
-return false; \
+if (ctx->mstatus_fs == EXT_STATUS_DISABLED) {   \
+ctx->virt_inst_excp = ctx->virt_enabled && ctx->cfg_ptr->ext_zfinx; \
+return false;   \
+}   \
 } while (0)
 
 #define REQUIRE_ZFINX_OR_F(ctx) do {\
-- 
2.40.1




[PULL 01/60] target/riscv/vector_helper.c: skip set tail when vta is zero

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

The function is a no-op if 'vta' is zero but we're still doing a lot of
stuff in this function regardless. vext_set_elems_1s() will ignore every
single time (since vta is zero) and we just wasted time.

Skip it altogether in this case. Aside from the code simplification
there's a noticeable emulation performance gain by doing it. For a
regular C binary that does a vectors operation like this:

===
 #define SZ 1000

int main ()
{
  int *a = malloc (SZ * sizeof (int));
  int *b = malloc (SZ * sizeof (int));
  int *c = malloc (SZ * sizeof (int));

  for (int i = 0; i < SZ; i++)
c[i] = a[i] + b[i];
  return c[SZ - 1];
}
===

Emulating it with qemu-riscv64 and RVV takes ~0.3 sec:

$ time ~/work/qemu/build/qemu-riscv64 \
-cpu rv64,debug=false,vext_spec=v1.0,v=true,vlen=128 ./foo.out

real0m0.303s
user0m0.281s
sys 0m0.023s

With this skip we take ~0.275 sec:

$ time ~/work/qemu/build/qemu-riscv64 \
-cpu rv64,debug=false,vext_spec=v1.0,v=true,vlen=128 ./foo.out

real0m0.274s
user0m0.252s
sys 0m0.019s

This performance gain adds up fast when executing heavy benchmarks like
SPEC.

Signed-off-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Reviewed-by: Palmer Dabbelt 
Reviewed-by: Weiwei Li 
Message-Id: <20230427205708.246679-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f4d0438988..8e6c99e573 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -268,12 +268,17 @@ static void vext_set_tail_elems_1s(CPURISCVState *env, 
target_ulong vl,
void *vd, uint32_t desc, uint32_t nf,
uint32_t esz, uint32_t max_elems)
 {
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
+uint32_t total_elems, vlenb, registers_used;
 uint32_t vta = vext_vta(desc);
-uint32_t registers_used;
 int k;
 
+if (vta == 0) {
+return;
+}
+
+total_elems = vext_get_total_elems(env, desc, esz);
+vlenb = riscv_cpu_cfg(env)->vlen >> 3;
+
 for (k = 0; k < nf; ++k) {
 vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
   (k * max_elems + max_elems) * esz);
-- 
2.40.1




[PULL 05/60] target/riscv/cpu.c: remove set_priv_version()

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

The setter is doing nothing special. Just set env->priv_ver directly.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230517135714.211809-4-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 29 -
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 13d725dc20..9fc9d1cc0f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -247,11 +247,6 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, 
uint32_t ext)
 env->misa_ext_mask = env->misa_ext = ext;
 }
 
-static void set_priv_version(CPURISCVState *env, int priv_ver)
-{
-env->priv_ver = priv_ver;
-}
-
 #ifndef CONFIG_USER_ONLY
 static uint8_t satp_mode_from_str(const char *satp_mode_str)
 {
@@ -350,7 +345,7 @@ static void riscv_any_cpu_init(Object *obj)
 VM_1_10_SV32 : VM_1_10_SV57);
 #endif
 
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 }
 
 #if defined(TARGET_RISCV64)
@@ -361,7 +356,7 @@ static void rv64_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV64, 0);
 riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -371,7 +366,7 @@ static void rv64_sifive_u_cpu_init(Object *obj)
 {
 CPURISCVState *env = _CPU(obj)->env;
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
 #endif
@@ -383,7 +378,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -396,7 +391,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU);
-set_priv_version(env, PRIV_VERSION_1_11_0);
+env->priv_ver = PRIV_VERSION_1_11_0;
 
 cpu->cfg.ext_zfh = true;
 cpu->cfg.mmu = true;
@@ -467,7 +462,7 @@ static void rv128_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV128, 0);
 riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -480,7 +475,7 @@ static void rv32_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV32, 0);
 riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
-set_priv_version(env, PRIV_VERSION_1_12_0);
+env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
@@ -490,7 +485,7 @@ static void rv32_sifive_u_cpu_init(Object *obj)
 {
 CPURISCVState *env = _CPU(obj)->env;
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
@@ -502,7 +497,7 @@ static void rv32_sifive_e_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -515,7 +510,7 @@ static void rv32_ibex_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
-set_priv_version(env, PRIV_VERSION_1_11_0);
+env->priv_ver = PRIV_VERSION_1_11_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -529,7 +524,7 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
-set_priv_version(env, PRIV_VERSION_1_10_0);
+env->priv_ver = PRIV_VERSION_1_10_0;
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -1211,7 +1206,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 
 if (priv_version >= PRIV_VERSION_1_10_0) {
-

[PULL 12/60] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

We have 4 config settings being done in riscv_cpu_init(): ext_ifencei,
ext_icsr, mmu and pmp. This is also the constructor of the "riscv-cpu"
device, which happens to be the parent device of every RISC-V cpu.

The result is that these 4 configs are being set every time, and every
other CPU should always account for them. CPUs such as sifive_e need to
disable settings that aren't enabled simply because the parent class
happens to be enabling it.

Moving all configurations from the parent class to each CPU will
centralize the config of each CPU into its own init(), which is clearer
than having to account to whatever happens to be set in the parent
device. These settings are also being set in register_cpu_props() when
no 'misa_ext' is set, so for these CPUs we don't need changes. Named
CPUs will receive all cfgs that the parent were setting into their
init().

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230517135714.211809-11-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 59 --
 1 file changed, 47 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9f2c8fa7c6..778801dffc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -332,7 +332,8 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
 
 static void riscv_any_cpu_init(Object *obj)
 {
-CPURISCVState *env = _CPU(obj)->env;
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = >env;
 #if defined(TARGET_RISCV32)
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
 #elif defined(TARGET_RISCV64)
@@ -346,6 +347,12 @@ static void riscv_any_cpu_init(Object *obj)
 #endif
 
 env->priv_ver = PRIV_VERSION_LATEST;
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.mmu = true;
+cpu->cfg.pmp = true;
 }
 
 #if defined(TARGET_RISCV64)
@@ -364,12 +371,19 @@ static void rv64_base_cpu_init(Object *obj)
 
 static void rv64_sifive_u_cpu_init(Object *obj)
 {
-CPURISCVState *env = _CPU(obj)->env;
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = >env;
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.mmu = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv64_sifive_e_cpu_init(Object *obj)
@@ -379,10 +393,14 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
 env->priv_ver = PRIV_VERSION_1_10_0;
-cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv64_thead_c906_cpu_init(Object *obj)
@@ -410,6 +428,9 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_SV39);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.pmp = true;
 }
 
 static void rv64_veyron_v1_cpu_init(Object *obj)
@@ -483,12 +504,19 @@ static void rv32_base_cpu_init(Object *obj)
 
 static void rv32_sifive_u_cpu_init(Object *obj)
 {
-CPURISCVState *env = _CPU(obj)->env;
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = >env;
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
 env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.mmu = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv32_sifive_e_cpu_init(Object *obj)
@@ -498,10 +526,14 @@ static void rv32_sifive_e_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
 env->priv_ver = PRIV_VERSION_1_10_0;
-cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
+
+/* inherited from parent obj via riscv_cpu_init() */
+cpu->cfg.ext_ifencei = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.pmp = true;
 }
 
 static void rv32_ibex_cpu_init(Object *obj)
@@ -511,11 +543,15 @@ static void rv32_ibex_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
 env->priv_ver = PRIV_VERSION_1_11_0;
-cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
 

[PULL 26/60] hw/riscv/opentitan: Rename machine_[class]_init() functions

2023-06-13 Thread Alistair Francis
From: Philippe Mathieu-Daudé 

Follow QOM style which declares FOO_init() as instance
initializer and FOO_class_init() as class initializer:
rename the OpenTitan machine class/instance init()
accordingly.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20230520054510.68822-2-phi...@linaro.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/opentitan.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index bc678766e7..2d21ee39c5 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -75,7 +75,7 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_FLASH_VIRTUAL] =  {  0x8000,  0x8 },
 };
 
-static void opentitan_board_init(MachineState *machine)
+static void opentitan_machine_init(MachineState *machine)
 {
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 const MemMapEntry *memmap = ibex_memmap;
@@ -108,17 +108,17 @@ static void opentitan_board_init(MachineState *machine)
 }
 }
 
-static void opentitan_machine_init(MachineClass *mc)
+static void opentitan_machine_class_init(MachineClass *mc)
 {
 mc->desc = "RISC-V Board compatible with OpenTitan";
-mc->init = opentitan_board_init;
+mc->init = opentitan_machine_init;
 mc->max_cpus = 1;
 mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
 mc->default_ram_id = "riscv.lowrisc.ibex.ram";
 mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size;
 }
 
-DEFINE_MACHINE("opentitan", opentitan_machine_init)
+DEFINE_MACHINE("opentitan", opentitan_machine_class_init)
 
 static void lowrisc_ibex_soc_init(Object *obj)
 {
-- 
2.40.1




[PULL 06/60] target/riscv: add PRIV_VERSION_LATEST

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

All these generic CPUs are using the latest priv available, at this
moment PRIV_VERSION_1_12_0:

- riscv_any_cpu_init()
- rv32_base_cpu_init()
- rv64_base_cpu_init()
- rv128_base_cpu_init()

Create a new PRIV_VERSION_LATEST enum and use it in those cases. I'll
make it easier to update everything at once when a new priv version is
available.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230517135714.211809-5-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 2 ++
 target/riscv/cpu.c | 8 
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de7e43126a..15423585d0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -61,6 +61,8 @@ enum {
 PRIV_VERSION_1_10_0 = 0,
 PRIV_VERSION_1_11_0,
 PRIV_VERSION_1_12_0,
+
+PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0,
 };
 
 #define VEXT_VERSION_1_00_0 0x0001
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9fc9d1cc0f..a0c4acfb47 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -345,7 +345,7 @@ static void riscv_any_cpu_init(Object *obj)
 VM_1_10_SV32 : VM_1_10_SV57);
 #endif
 
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 }
 
 #if defined(TARGET_RISCV64)
@@ -356,7 +356,7 @@ static void rv64_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV64, 0);
 riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -462,7 +462,7 @@ static void rv128_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV128, 0);
 riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -475,7 +475,7 @@ static void rv32_base_cpu_init(Object *obj)
 set_misa(env, MXL_RV32, 0);
 riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
-env->priv_ver = PRIV_VERSION_1_12_0;
+env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
-- 
2.40.1




[PULL 18/60] target/riscv: Make RLB/MML/MMWP bits writable only when Smepmp is enabled

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

RLB/MML/MMWP bits in mseccfg CSR are introduced by Smepmp extension.
So they can only be writable and set to 1s when cfg.epmp is true.
Then we also need't check on epmp in pmp_hart_has_privs_default().

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-6-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 50 --
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 0684047b86..9a6e04cda0 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -243,30 +243,28 @@ static bool pmp_hart_has_privs_default(CPURISCVState 
*env, target_ulong addr,
 {
 bool ret;
 
-if (riscv_cpu_cfg(env)->epmp) {
-if (MSECCFG_MMWP_ISSET(env)) {
-/*
- * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
- * so we default to deny all, even for M-mode.
- */
+if (MSECCFG_MMWP_ISSET(env)) {
+/*
+ * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
+ * so we default to deny all, even for M-mode.
+ */
+*allowed_privs = 0;
+return false;
+} else if (MSECCFG_MML_ISSET(env)) {
+/*
+ * The Machine Mode Lockdown (mseccfg.MML) bit is set
+ * so we can only execute code in M-mode with an applicable
+ * rule. Other modes are disabled.
+ */
+if (mode == PRV_M && !(privs & PMP_EXEC)) {
+ret = true;
+*allowed_privs = PMP_READ | PMP_WRITE;
+} else {
+ret = false;
 *allowed_privs = 0;
-return false;
-} else if (MSECCFG_MML_ISSET(env)) {
-/*
- * The Machine Mode Lockdown (mseccfg.MML) bit is set
- * so we can only execute code in M-mode with an applicable
- * rule. Other modes are disabled.
- */
-if (mode == PRV_M && !(privs & PMP_EXEC)) {
-ret = true;
-*allowed_privs = PMP_READ | PMP_WRITE;
-} else {
-ret = false;
-*allowed_privs = 0;
-}
-
-return ret;
 }
+
+return ret;
 }
 
 if (!riscv_cpu_cfg(env)->pmp || (mode == PRV_M)) {
@@ -580,8 +578,12 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong 
val)
 }
 }
 
-/* Sticky bits */
-val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
+if (riscv_cpu_cfg(env)->epmp) {
+/* Sticky bits */
+val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
+} else {
+val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
+}
 
 env->mseccfg = val;
 }
-- 
2.40.1




[PULL 09/60] target/riscv/cpu.c: add priv_spec validate/disable_exts helpers

2023-06-13 Thread Alistair Francis
From: Daniel Henrique Barboza 

We're doing env->priv_spec validation and assignment at the start of
riscv_cpu_realize(), which is fine, but then we're doing a force disable
on extensions that aren't compatible with the priv version.

This second step is being done too early. The disabled extensions might be
re-enabled again in riscv_cpu_validate_set_extensions() by accident. A
better place to put this code is at the end of
riscv_cpu_validate_set_extensions() after all the validations are
completed.

Add a new helper, riscv_cpu_disable_priv_spec_isa_exts(), to disable the
extesions after the validation is done. While we're at it, create a
riscv_cpu_validate_priv_spec() helper to host all env->priv_spec related
validation to unclog riscv_cpu_realize a bit.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230517135714.211809-8-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 91 --
 1 file changed, 56 insertions(+), 35 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 81a785d525..a0589abb16 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -864,6 +864,52 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
 env->vext_ver = vext_version;
 }
 
+static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
+{
+CPURISCVState *env = >env;
+int priv_version = -1;
+
+if (cpu->cfg.priv_spec) {
+if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
+priv_version = PRIV_VERSION_1_12_0;
+} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
+priv_version = PRIV_VERSION_1_11_0;
+} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
+priv_version = PRIV_VERSION_1_10_0;
+} else {
+error_setg(errp,
+   "Unsupported privilege spec version '%s'",
+   cpu->cfg.priv_spec);
+return;
+}
+
+env->priv_ver = priv_version;
+}
+}
+
+static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
+{
+CPURISCVState *env = >env;
+int i;
+
+/* Force disable extensions if priv spec version does not match */
+for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
+if (isa_ext_is_enabled(cpu, _edata_arr[i]) &&
+(env->priv_ver < isa_edata_arr[i].min_version)) {
+isa_ext_update_enabled(cpu, _edata_arr[i], false);
+#ifndef CONFIG_USER_ONLY
+warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
+" because privilege spec version does not match",
+isa_edata_arr[i].name, env->mhartid);
+#else
+warn_report("disabling %s extension because "
+"privilege spec version does not match",
+isa_edata_arr[i].name);
+#endif
+}
+}
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly.
@@ -1082,6 +1128,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zksed = true;
 cpu->cfg.ext_zksh = true;
 }
+
+/*
+ * Disable isa extensions based on priv spec after we
+ * validated and set everything we need.
+ */
+riscv_cpu_disable_priv_spec_isa_exts(cpu);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -1181,7 +1233,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 CPURISCVState *env = >env;
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
 CPUClass *cc = CPU_CLASS(mcc);
-int i, priv_version = -1;
 Error *local_err = NULL;
 
 cpu_exec_realizefn(cs, _err);
@@ -1190,23 +1241,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-if (cpu->cfg.priv_spec) {
-if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
-priv_version = PRIV_VERSION_1_12_0;
-} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
-priv_version = PRIV_VERSION_1_11_0;
-} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
-priv_version = PRIV_VERSION_1_10_0;
-} else {
-error_setg(errp,
-   "Unsupported privilege spec version '%s'",
-   cpu->cfg.priv_spec);
-return;
-}
-}
-
-if (priv_version >= PRIV_VERSION_1_10_0) {
-env->priv_ver = priv_version;
+riscv_cpu_validate_priv_spec(cpu, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
 }
 
 riscv_cpu_validate_misa_priv(env, _err);
@@ -1215,23 +1253,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-/* Force disable extensions if priv spec version does not match */
-for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
-if 

[PULL 19/60] target/riscv: Remove unused paramters in pmp_hart_has_privs_default()

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

The addr and size parameters in pmp_hart_has_privs_default() are unused.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-7-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 9a6e04cda0..2403039133 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -236,8 +236,7 @@ static int pmp_is_in_range(CPURISCVState *env, int 
pmp_index,
 /*
  * Check if the address has required RWX privs when no PMP entry is matched.
  */
-static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
-   target_ulong size, pmp_priv_t privs,
+static bool pmp_hart_has_privs_default(CPURISCVState *env, pmp_priv_t privs,
pmp_priv_t *allowed_privs,
target_ulong mode)
 {
@@ -309,8 +308,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 
 /* Short cut if no rules */
 if (0 == pmp_get_num_rules(env)) {
-return pmp_hart_has_privs_default(env, addr, size, privs,
-  allowed_privs, mode);
+return pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
 }
 
 if (size == 0) {
@@ -454,8 +452,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 
 /* No rule matched */
 if (!ret) {
-ret = pmp_hart_has_privs_default(env, addr, size, privs,
- allowed_privs, mode);
+ret = pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
 }
 
 return ret;
-- 
2.40.1




[PULL 14/60] target/riscv: Update pmp_get_tlb_size()

2023-06-13 Thread Alistair Francis
From: Weiwei Li 

PMP entries before (including) the matched PMP entry may only cover partial
of the TLB page, and this may split the page into regions with different
permissions. Such as for PMP0 (0x8008~0x800F, R) and PMP1 (0x8000~
0x8FFF, RWX), write access to 0x8000 will match PMP1. However we cannot
cache the translation result in the TLB since this will make the write access
to 0x8008 bypass the check of PMP0. So we should check all of them instead
of the matched PMP entry in pmp_get_tlb_size() and set the tlb_size to 1 in
this case.
Set tlb_size to TARGET_PAGE_SIZE if PMP is not support or there is no PMP rules.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20230517091519.34439-2-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.h|  3 +-
 target/riscv/cpu_helper.c |  7 ++--
 target/riscv/pmp.c| 69 ++-
 3 files changed, 57 insertions(+), 22 deletions(-)

diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index b296ea1fc6..0a7e24750b 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -76,8 +76,7 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
target_ulong size, pmp_priv_t privs,
pmp_priv_t *allowed_privs,
target_ulong mode);
-target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
-  target_ulong tlb_sa, target_ulong tlb_ea);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr);
 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
 void pmp_update_rule_nums(CPURISCVState *env);
 uint32_t pmp_get_num_rules(CPURISCVState *env);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 56381aaf26..065b433b88 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -715,11 +715,8 @@ static int get_physical_address_pmp(CPURISCVState *env, 
int *prot,
 }
 
 *prot = pmp_priv_to_page_prot(pmp_priv);
-if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
-target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
-target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
-
-*tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
+if (tlb_size != NULL) {
+*tlb_size = pmp_get_tlb_size(env, addr);
 }
 
 return TRANSLATE_SUCCESS;
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 1f5aca42e8..2bc924340a 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -601,28 +601,67 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
 }
 
 /*
- * Calculate the TLB size if the start address or the end address of
- * PMP entry is presented in the TLB page.
+ * Calculate the TLB size.
+ * It's possible that PMP regions only cover partial of the TLB page, and
+ * this may split the page into regions with different permissions.
+ * For example if PMP0 is (0x8008~0x800F, R) and PMP1 is (0x8000
+ * ~0x8FFF, RWX), then region 0x8008~0x800F has R permission, and
+ * the other regions in this page have RWX permissions.
+ * A write access to 0x8000 will match PMP1. However we cannot cache the
+ * translation result in the TLB since this will make the write access to
+ * 0x8008 bypass the check of PMP0.
+ * To avoid this we return a size of 1 (which means no caching) if the PMP
+ * region only covers partial of the TLB page.
  */
-target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
-  target_ulong tlb_sa, target_ulong tlb_ea)
+target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr)
 {
-target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
-target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
+target_ulong pmp_sa;
+target_ulong pmp_ea;
+target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
+target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
+int i;
 
-if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
+/*
+ * If PMP is not supported or there are no PMP rules, the TLB page will not
+ * be split into regions with different permissions by PMP so we set the
+ * size to TARGET_PAGE_SIZE.
+ */
+if (!riscv_cpu_cfg(env)->pmp || !pmp_get_num_rules(env)) {
 return TARGET_PAGE_SIZE;
-} else {
+}
+
+for (i = 0; i < MAX_RISCV_PMPS; i++) {
+if (pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg) == PMP_AMATCH_OFF) {
+continue;
+}
+
+pmp_sa = env->pmp_state.addr[i].sa;
+pmp_ea = env->pmp_state.addr[i].ea;
+
 /*
- * At this point we have a tlb_size that is the smallest possible size
- * That fits within a TARGET_PAGE_SIZE and the PMP region.
- *
- * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
- * This means the result isn't cached in the TLB 

  1   2   3   >