Merge tag 'pull-riscv-to-apply-20230719-1' of https://github.com/alistair23/qemu into staging

Fourth RISC-V PR for 8.1

* Fix LMUL check to use VLEN
* Fix typo field in NUMA error_report
* check priv_ver before auto-enable zca/zcd/zcf
* Fix disas output of upper immediates
* tidy CPU firmware section

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmS3akMACgkQr3yVEwxT
# gBPQ/BAArrieEkrRco3tIQJFZqTLfII28M0cYdwN+gjMAkL6RlauCh5yKkc+gsGy
# bhhpr0AE+EzrjKfJgdyMQe2ZH08WEpoAfJHAmLTSm2ktgIlnDAjyJtVksZ3FSwfG
# MRK3v0CChyOav3EfDZzK9jcaXeaSSfjCIG8JW3enoZxf2TnpoXlsCIQdRTnMw7Um
# C73BWoOGOfixFehywHBnkkAPo/nkQPofELrRKNTlefAIsH1RcgYw+s3IgCIuYxJN
# zCjM1y6ye1aiaQhKcNJiLoiP4Eq2R6vUuL8RKWkXqTP3QBZUqKMPnRVgI+W0qRAj
# 9DS+l37zMdxytovQ4gmIqnENT8ty9bholOtWM8nI54subJBplQhkRednG3RBFYjH
# hqbsakcHfE1lyyNI7WoBpO8UMtnOad6eBNmMOM48VduSdNuBZN3ksoRVomnJTlCY
# nq1ZdteywHEZ3uBqk3k/4yzKH+jLj0McPz5FswxsMIGScVjd6H8rMYmM95r1He4k
# YTJ8GwnOTBs1tFxOz5DaM3BVfq5hrzB0SbpDHMOdQHNXnqkyfvSd/QWeXfnY09Ux
# kbNvSpzjn7wWRSP7s4KMcTmas4oGtPS2dheREB/gmoC1ubrfuhbzduDNXJt+omuC
# GDcn9cpouyE/Vp/358PuEe1gW9GFMH0CbYBJ66P0hI/76iPfwLY=
# =MOsI
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 19 Jul 2023 05:44:51 BST
# gpg:                using RSA key 6AE902B6A7CA877D6D659296AF7C95130C538013
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6AE9 02B6 A7CA 877D 6D65  9296 AF7C 9513 0C53 8013

* tag 'pull-riscv-to-apply-20230719-1' of https://github.com/alistair23/qemu:
  target/riscv: Fix LMUL check to use VLEN
  hw/riscv: Fix typo field in error_report
  target/riscv/cpu.c: check priv_ver before auto-enable zca/zcd/zcf
  riscv/disas: Fix disas output of upper immediates
  docs/system/target-riscv.rst: tidy CPU firmware section

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/disas/riscv.c b/disas/riscv.c
index cd7b6e8..3873a69 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1135,8 +1135,8 @@
 
 const rv_opcode_data rvi_opcode_data[] = {
     { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
-    { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
-    { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
+    { "lui", rv_codec_u, rv_fmt_rd_uimm, NULL, 0, 0, 0 },
+    { "auipc", rv_codec_u, rv_fmt_rd_uoffset, NULL, 0, 0, 0 },
     { "jal", rv_codec_uj, rv_fmt_rd_offset, rvcp_jal, 0, 0, 0 },
     { "jalr", rv_codec_i, rv_fmt_rd_rs1_offset, rvcp_jalr, 0, 0, 0 },
     { "beq", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_beq, 0, 0, 0 },
@@ -1382,7 +1382,7 @@
       rv_op_addi },
     { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
       rv_op_addi, rv_op_addi, rvcd_imm_nz },
-    { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
+    { "c.lui", rv_codec_ci_lui, rv_fmt_rd_uimm, NULL, rv_op_lui, rv_op_lui,
       rv_op_lui, rvcd_imm_nz },
     { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli,
       rv_op_srli, rv_op_srli, rvcd_imm_nz },
@@ -4694,6 +4694,19 @@
                 dec->pc + dec->imm);
             append(buf, tmp, buflen);
             break;
+        case 'U':
+            fmt++;
+            snprintf(tmp, sizeof(tmp), "%d", dec->imm >> 12);
+            append(buf, tmp, buflen);
+            if (*fmt == 'o') {
+                while (strlen(buf) < tab * 2) {
+                    append(buf, " ", buflen);
+                }
+                snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
+                    dec->pc + dec->imm);
+                append(buf, tmp, buflen);
+            }
+            break;
         case 'c': {
             const char *name = csr_name(dec->imm & 0xfff);
             if (name) {
diff --git a/disas/riscv.h b/disas/riscv.h
index 9cf901f..8abb578 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -227,7 +227,9 @@
 #define rv_fmt_pred_succ              "O\tp,s"
 #define rv_fmt_rs1_rs2                "O\t1,2"
 #define rv_fmt_rd_imm                 "O\t0,i"
+#define rv_fmt_rd_uimm                "O\t0,Ui"
 #define rv_fmt_rd_offset              "O\t0,o"
+#define rv_fmt_rd_uoffset             "O\t0,Uo"
 #define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
 #define rv_fmt_frd_rs1                "O\t3,1"
 #define rv_fmt_frd_rs1_rs2            "O\t3,1,2"
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
index 89a866e..ba195f1 100644
--- a/docs/system/target-riscv.rst
+++ b/docs/system/target-riscv.rst
@@ -76,11 +76,19 @@
 
 When using the ``sifive_u`` or ``virt`` machine there are three different
 firmware boot options:
-1. ``-bios default`` - This is the default behaviour if no -bios option
-is included. This option will load the default OpenSBI firmware automatically.
-The firmware is included with the QEMU release and no user interaction is
-required. All a user needs to do is specify the kernel they want to boot
-with the -kernel option
-2. ``-bios none`` - QEMU will not automatically load any firmware. It is up
-to the user to load all the images they need.
-3. ``-bios <file>`` - Tells QEMU to load the specified file as the firmware.
+
+* ``-bios default``
+
+This is the default behaviour if no ``-bios`` option is included. This option
+will load the default OpenSBI firmware automatically. The firmware is included
+with the QEMU release and no user interaction is required. All a user needs to
+do is specify the kernel they want to boot with the ``-kernel`` option
+
+* ``-bios none``
+
+QEMU will not automatically load any firmware. It is up to the user to load all
+the images they need.
+
+* ``-bios <file>``
+
+Tells QEMU to load the specified file as the firmware.
diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
index e0414d5..d319aef 100644
--- a/hw/riscv/numa.c
+++ b/hw/riscv/numa.c
@@ -209,8 +209,8 @@
 
     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);
+                     " cannot exceed the number of available CPUs (%u).",
+                     ms->numa_state->num_nodes, ms->smp.cpus);
         exit(EXIT_FAILURE);
     }
     if (ms->numa_state->num_nodes) {
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9339c02..6b93b04 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1225,7 +1225,8 @@
         }
     }
 
-    if (riscv_has_ext(env, RVC)) {
+    /* zca, zcd and zcf has a PRIV 1.12.0 restriction */
+    if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
         cpu->cfg.ext_zca = true;
         if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
             cpu->cfg.ext_zcf = true;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index cfacf2e..4d06754 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -43,9 +43,9 @@
                                             xlen - 1 - R_VTYPE_RESERVED_SHIFT);
 
     if (lmul & 4) {
-        /* Fractional LMUL. */
+        /* Fractional LMUL - check LMUL * VLEN >= SEW */
         if (lmul == 4 ||
-            cpu->cfg.elen >> (8 - lmul) < sew) {
+            cpu->cfg.vlen >> (8 - lmul) < sew) {
             vill = true;
         }
     }