Makes cpu_helper.c agnostic to compile-time target specifics, allowing
it to be compiled twice (once for user- and once for system mode).
target_[u]long is widened to [u]int64_t and runtime target_long_bits()
is used in place of the equivalent macro.  Most changes are straight
forward and no behavioural change is intended.

Note: the following change might be a bit unclear at first glance

  #define PTE_PPN_MASK 0x3FFFFFFFFFFC00ULL

  - target_ulong pte;
  + uint64_t pte;

  - ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT;
  + ppn = (pte & PTE_PPN_MASK) >> PTE_PPN_SHIFT;

but retains expected behaviour as pte is written a uint32_t for
MXL_RV32, meaning the top bits of PTE_PPN_MASK or chopped of in the &,
rather than truncated.

Note: This commit will print all addresses as 64-bit values, even for a
32-bit target. If breaking this interface is not an option we can
instead opt for more runtime branching, as done by Joel Stanley
in commit 409c7d8682a.

Reviewed-by: Pierrick Bouvier <[email protected]>
Signed-off-by: Anton Johansson <[email protected]>
---
 target/riscv/tcg/cpu_helper.c | 79 ++++++++++++++++++++++---------------------
 target/riscv/tcg/meson.build  |  3 +-
 2 files changed, 43 insertions(+), 39 deletions(-)

diff --git a/target/riscv/tcg/cpu_helper.c b/target/riscv/tcg/cpu_helper.c
index 07d9222652..ee433a88fe 100644
--- a/target/riscv/tcg/cpu_helper.c
+++ b/target/riscv/tcg/cpu_helper.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
+#include "qemu/target-info.h"
 #include "cpu.h"
 #include "internals.h"
 #include "pmu.h"
@@ -28,7 +29,6 @@
 #include "exec/target_page.h"
 #include "system/memory.h"
 #include "instmap.h"
-#include "tcg/tcg-op.h"
 #include "accel/tcg/cpu-loop.h"
 #include "accel/tcg/cpu-ops.h"
 #include "trace.h"
@@ -1017,7 +1017,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     bool use_background = false;
     hwaddr ppn;
     int napot_bits = 0;
-    target_ulong napot_mask;
+    uint64_t napot_mask;
     bool is_sstack_idx = ((mmu_idx & MMU_IDX_SS_WRITE) == MMU_IDX_SS_WRITE);
     bool sstack_page = false;
 
@@ -1101,7 +1101,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     int sxlen_bytes = sxlen / 8;
 
     if (first_stage == true) {
-        target_ulong mask, masked_msbs;
+        uint64_t mask, masked_msbs;
 
         if (sxlen > (va_bits - 1)) {
             mask = (1L << (sxlen - (va_bits - 1))) - 1;
@@ -1131,7 +1131,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     }
 
     int ptshift;
-    target_ulong pte;
+    uint64_t pte;
     hwaddr pte_addr;
     const hwaddr base_root = base;
     const bool be = mo_endian_env(env) == MO_BE;
@@ -1141,7 +1141,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     ptshift = (levels - 1) * ptidxbits;
     base = base_root;
     for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
-        target_ulong idx;
+        uint64_t idx;
         if (i == 0) {
             idx = (addr >> (PGSHIFT + ptshift)) &
                            ((1 << (ptidxbits + widened)) - 1);
@@ -1214,7 +1214,8 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
         } else {
             if (pte & PTE_RESERVED(svrsw60t59b)) {
                 qemu_log_mask(LOG_GUEST_ERROR, "%s: reserved bits set in PTE: "
-                              "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx 
"\n",
+                              "addr: 0x%" HWADDR_PRIx
+                              " pte: 0x%016" PRIx64 "\n",
                               __func__, pte_addr, pte);
                 return TRANSLATE_FAIL;
             }
@@ -1223,7 +1224,8 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
                 /* Reserved without Svpbmt. */
                 qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits set in PTE, "
                               "and Svpbmt extension is disabled: "
-                              "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx 
"\n",
+                              "addr: 0x%" HWADDR_PRIx
+                              " pte: 0x%016" PRIx64 "\n",
                               __func__, pte_addr, pte);
                 return TRANSLATE_FAIL;
             }
@@ -1242,7 +1244,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
             if ((pte & PTE_PBMT) == PTE_PBMT) {
                 qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are "
                         "reserved but are set in PTE: "
-                        "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
+                        "addr: 0x%" HWADDR_PRIx " pte: 0x%016" PRIx64 "\n",
                         __func__, pte_addr, pte);
                 return TRANSLATE_FAIL;
             }
@@ -1251,12 +1253,13 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
                 /* Reserved without Svnapot extension */
                 qemu_log_mask(LOG_GUEST_ERROR, "%s: N bit set in PTE, "
                               "and Svnapot extension is disabled: "
-                              "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx 
"\n",
+                              "addr: 0x%" HWADDR_PRIx
+                              " pte: 0x%016" PRIx64 "\n",
                               __func__, pte_addr, pte);
                 return TRANSLATE_FAIL;
             }
 
-            ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT;
+            ppn = (pte & PTE_PPN_MASK) >> PTE_PPN_SHIFT;
         }
 
         if (!(pte & PTE_V)) {
@@ -1271,7 +1274,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
         if (pte & (PTE_D | PTE_A | PTE_U | PTE_ATTR)) {
             /* D, A, and U bits are reserved in non-leaf/inner PTEs */
             qemu_log_mask(LOG_GUEST_ERROR, "%s: D, A, or U bits set in 
non-leaf PTE: "
-                          "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx 
"\n",
+                          "addr: 0x%" HWADDR_PRIx " pte: 0x%016" PRIx64 "\n",
                           __func__, pte_addr, pte);
             return TRANSLATE_FAIL;
         }
@@ -1286,7 +1289,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     if (ppn & ((1ULL << ptshift) - 1)) {
         /* Misaligned PPN */
         qemu_log_mask(LOG_GUEST_ERROR, "%s: PPN bits in PTE is misaligned: "
-                      "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
+                      "addr: 0x%" HWADDR_PRIx " pte: 0x%016" PRIx64 "\n",
                       __func__, pte_addr, pte);
         return TRANSLATE_FAIL;
     }
@@ -1294,7 +1297,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
         /* Reserved without Svpbmt. */
         qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits set in PTE, "
                       "and Svpbmt extension is disabled: "
-                      "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
+                      "addr: 0x%" HWADDR_PRIx " pte: 0x%016" PRIx64 "\n",
                       __func__, pte_addr, pte);
         return TRANSLATE_FAIL;
     }
@@ -1311,12 +1314,12 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     if ((pte & PTE_PBMT) == PTE_PBMT) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are "
                       "reserved but are set in leaf PTE: "
-                      "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
+                      "addr: 0x%" HWADDR_PRIx " pte: 0x%016" PRIx64 "\n",
                       __func__, pte_addr, pte);
         return TRANSLATE_FAIL;
     }
 
-    target_ulong rwx = pte & (PTE_R | PTE_W | PTE_X);
+    uint64_t rwx = pte & (PTE_R | PTE_W | PTE_X);
     /* Check for reserved combinations of RWX flags. */
     switch (rwx) {
     case PTE_W | PTE_X:
@@ -1403,7 +1406,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
         return sstack_page ? TRANSLATE_PMP_FAIL : TRANSLATE_FAIL;
     }
 
-    target_ulong updated_pte = pte;
+    uint64_t updated_pte = pte;
 
     /*
      * If ADUE is enabled, set accessed and dirty bits.
@@ -1471,7 +1474,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     }
 
     /* For superpage mappings, make a fake leaf PTE for the TLB's benefit. */
-    target_ulong vpn = addr >> PGSHIFT;
+    uint64_t vpn = addr >> PGSHIFT;
 
     if (riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
         napot_bits = ctzl(ppn) + 1;
@@ -1482,7 +1485,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
 
     napot_mask = (1 << napot_bits) - 1;
     *physical = (((ppn & ~napot_mask) | (vpn & napot_mask) |
-                  (vpn & (((target_ulong)1 << ptshift) - 1))
+                  (vpn & ((1ULL << ptshift) - 1))
                  ) << PGSHIFT) | (addr & ~TARGET_PAGE_MASK);
 
     /*
@@ -1498,7 +1501,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     return TRANSLATE_SUCCESS;
 }
 
-static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
+static void raise_mmu_exception(CPURISCVState *env, vaddr address,
                                 MMUAccessType access_type,
                                 bool pmp_pma_violation,
                                 bool first_stage, bool two_stage,
@@ -1795,12 +1798,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, 
int size,
     return true;
 }
 
-static target_ulong riscv_transformed_insn(CPURISCVState *env,
-                                           target_ulong insn,
-                                           target_ulong taddr)
+static uint64_t riscv_transformed_insn(CPURISCVState *env,
+                                           uint64_t insn,
+                                           uint64_t taddr)
 {
-    target_ulong xinsn = 0;
-    target_ulong access_rs1 = 0, access_imm = 0, access_size = 0;
+    uint64_t xinsn = 0;
+    uint64_t access_rs1 = 0, access_imm = 0, access_size = 0;
 
     /*
      * Only Quadrant 0 and Quadrant 2 of RVC instruction space need to
@@ -1956,7 +1959,7 @@ static target_ulong riscv_transformed_insn(CPURISCVState 
*env,
          * Clear Bit1 of transformed instruction to indicate that
          * original insruction was a 16bit instruction
          */
-        xinsn &= ~((target_ulong)0x2);
+        xinsn &= ~((uint64_t)0x2);
     } else {
         /* Transform 32bit (or wider) instructions */
         switch (MASK_OP_MAJOR(insn)) {
@@ -2000,7 +2003,7 @@ static target_ulong riscv_transformed_insn(CPURISCVState 
*env,
     return xinsn;
 }
 
-static target_ulong promote_load_fault(target_ulong orig_cause)
+static uint64_t promote_load_fault(uint64_t orig_cause)
 {
     switch (orig_cause) {
     case RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT:
@@ -2020,7 +2023,7 @@ static target_ulong promote_load_fault(target_ulong 
orig_cause)
     return orig_cause;
 }
 
-static void riscv_do_nmi(CPURISCVState *env, target_ulong cause, bool virt)
+static void riscv_do_nmi(CPURISCVState *env, uint64_t cause, bool virt)
 {
     env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, false);
     env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPV, virt);
@@ -2059,7 +2062,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
      * so we mask off the MSB and separate into trap type and cause.
      */
     bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG);
-    target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK;
+    uint64_t cause = cs->exception_index & RISCV_EXCP_INT_MASK;
     uint64_t deleg = async ? env->mideleg : env->medeleg;
     bool s_injected = env->mvip & (1ULL << cause) & env->mvien &&
         !(env->mip & (1ULL << cause));
@@ -2070,17 +2073,17 @@ void riscv_cpu_do_interrupt(CPUState *cs)
     const bool prev_virt = env->virt_enabled;
     const privilege_mode_t prev_priv = env->priv;
     uint64_t last_pc = env->pc;
-    target_ulong tval = 0;
-    target_ulong tinst = 0;
-    target_ulong htval = 0;
-    target_ulong mtval2 = 0;
-    target_ulong src;
+    uint64_t tval = 0;
+    uint64_t tinst = 0;
+    uint64_t htval = 0;
+    uint64_t mtval2 = 0;
+    uint64_t src;
     int sxlen = 0;
     int mxlen = 16 << riscv_cpu_mxl(env);
     bool nnmi_excep = false;
 
     if (cpu->cfg.ext_smrnmi && env->rnmip && async) {
-        riscv_do_nmi(env, cause | ((target_ulong)1U << (mxlen - 1)),
+        riscv_do_nmi(env, cause | (1ULL << (mxlen - 1)),
                      env->virt_enabled);
         return;
     }
@@ -2173,8 +2176,8 @@ void riscv_cpu_do_interrupt(CPUState *cs)
                      riscv_cpu_get_trap_name(cause, async));
 
     qemu_log_mask(CPU_LOG_INT,
-                  "%s: hart:%"PRIu64", async:%d, cause:"TARGET_FMT_lx", "
-                  "epc:0x%"PRIx64", tval:0x"TARGET_FMT_lx", desc=%s\n",
+                  "%s: hart:%"PRIu64", async:%d, cause:%016"PRIx64", "
+                  "epc:0x%016"PRIx64", tval:0x%016"PRIx64", desc=%s\n",
                   __func__, env->mhartid, async, cause, env->pc,
                   tval, riscv_cpu_get_trap_name(cause, async));
 
@@ -2253,7 +2256,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         }
         env->mstatus = s;
         sxlen = 16 << riscv_cpu_sxl(env);
-        env->scause = cause | ((target_ulong)async << (sxlen - 1));
+        env->scause = cause | ((uint64_t)async << (sxlen - 1));
         env->sepc = env->pc;
         env->stval = tval;
         env->htval = htval;
@@ -2325,7 +2328,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
             s = set_field(s, MSTATUS_MDT, 1);
         }
         env->mstatus = s;
-        env->mcause = cause | ((target_ulong)async << (mxlen - 1));
+        env->mcause = cause | ((uint64_t)async << (mxlen - 1));
         if (smode_double_trap) {
             env->mtval2 = env->mcause;
             env->mcause = RISCV_EXCP_DOUBLE_TRAP;
diff --git a/target/riscv/tcg/meson.build b/target/riscv/tcg/meson.build
index 8f95c8f400..cc50f3764c 100644
--- a/target/riscv/tcg/meson.build
+++ b/target/riscv/tcg/meson.build
@@ -4,7 +4,6 @@ endif
 
 riscv_ss.add(files(
   'bitmanip_helper.c',
- 'cpu_helper.c',
   'crypto_helper.c',
   'fpu_helper.c',
   'm128_helper.c',
@@ -24,11 +23,13 @@ riscv_system_ss.add(files(
 
 
 riscv_user_ss.add(files(
+  'cpu_helper.c',
   'csr.c',
 ))
 
 
 riscv_common_system_ss.add(files(
+  'cpu_helper.c',
   'csr.c',
   'mips_csr.c',
   'pmu.c',

-- 
2.52.0


Reply via email to