Commit d9bf971323 for qemu.org

commit d9bf9713239945a5d4187593599de49da3351416
Merge: fc52456708 875caabdb1
Author: Stefan Hajnoczi <stefanha@redhat.com>
Date:   Thu Apr 24 13:44:39 2025 -0400

    Merge tag 'pull-loongarch-20250424' of https://github.com/gaosong715/qemu into staging

    pull-loongarch-20230424

    # -----BEGIN PGP SIGNATURE-----
    #
    # iLMEAAEKAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCaAmmRQAKCRBAov/yOSY+
    # 3yZoA/4udi9ZmLsaiPqfKCS+0eF8XScIT493lVD359lFTBTT7mshh9PPhTLzdtiC
    # 8fcfYi7jSjfC9gGTjPgnNCOzKIg3Gbdl61AFDgIwd8q/5HQAgonHAywTUtmqDaPK
    # bXZ/JkkJQby2dla6015XKQS/d/EXWHgYjrcb1JZIRoaLworZPw==
    # =zBCJ
    # -----END PGP SIGNATURE-----
    # gpg: Signature made Wed 23 Apr 2025 22:47:33 EDT
    # gpg:                using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF
    # gpg: Good signature from "Song Gao <m17746591750@163.com>" [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: B8FF 1DA0 D2FD CB2D A09C  6C2C 40A2 FFF2 3926 3EDF

    * tag 'pull-loongarch-20250424' of https://github.com/gaosong715/qemu:
      target/loongarch: Guard BCEQZ/BCNEZ instructions with FP feature
      target/loongarch: Add CRC feature flag and use it to gate CRC instructions
      linux-user/loongarch64: Decode BRK break codes for FPE signals
      target/loongarch: Move definition of TCG specified function to tcg directory
      target/loongarch: Add static definition with function loongarch_tlb_search()
      target/loongarch: Move function loongarch_tlb_search to directory tcg
      target/loongarch: Define function loongarch_get_addr_from_tlb() non-static
      target/loongarch: Set function loongarch_map_address() with common code
      target/loongarch: Add stub function loongarch_get_addr_from_tlb
      target/loongarch: Move function get_dir_base_width to common directory
      target/loongarch: Add function loongarch_get_addr_from_tlb
      target/loongarch: Move header file helper.h to directory tcg
      hw/intc/loongarch_pch_msi: Remove gpio input handler

    Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

diff --cc target/loongarch/cpu.c
index fe9462b3b7,588f5fd021..0e6c89eb1b
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@@ -29,9 -29,10 +29,10 @@@
  #include <linux/kvm.h>
  #endif
  #ifdef CONFIG_TCG
 -#include "exec/cpu_ldst.h"
 +#include "accel/tcg/cpu-ldst.h"
  #include "tcg/tcg.h"
  #endif
+ #include "tcg/tcg_loongarch.h"

  const char * const regnames[32] = {
      "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
diff --cc target/loongarch/cpu_helper.c
index bb343078bf,998857b8dc..e172b11ce1
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@@ -7,140 -7,38 +7,40 @@@
   */

  #include "qemu/osdep.h"
+ #include "system/tcg.h"
  #include "cpu.h"
 +#include "accel/tcg/cpu-mmu-index.h"
 +#include "exec/target_page.h"
  #include "internals.h"
  #include "cpu-csr.h"
+ #include "tcg/tcg_loongarch.h"

- #ifdef CONFIG_TCG
- static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
-                                    int *prot, target_ulong address,
-                                    int access_type, int index, int mmu_idx)
+ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
+                         uint64_t *dir_width, target_ulong level)
  {
-     LoongArchTLB *tlb = &env->tlb[index];
-     uint64_t plv = mmu_idx;
-     uint64_t tlb_entry, tlb_ppn;
-     uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
-
-     if (index >= LOONGARCH_STLB) {
-         tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
-     } else {
-         tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
-     }
-     n = (address >> tlb_ps) & 0x1;/* Odd or even */
-
-     tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
-     tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
-     tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
-     tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
-     if (is_la64(env)) {
-         tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
-         tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
-         tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
-         tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
-     } else {
-         tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
-         tlb_nx = 0;
-         tlb_nr = 0;
-         tlb_rplv = 0;
-     }
-
-     /* Remove sw bit between bit12 -- bit PS*/
-     tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) -1));
-
-     /* Check access rights */
-     if (!tlb_v) {
-         return TLBRET_INVALID;
-     }
-
-     if (access_type == MMU_INST_FETCH && tlb_nx) {
-         return TLBRET_XI;
+     switch (level) {
+     case 1:
+         *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE);
+         *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH);
+         break;
+     case 2:
+         *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE);
+         *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH);
+         break;
+     case 3:
+         *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE);
+         *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH);
+         break;
+     case 4:
+         *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE);
+         *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH);
+         break;
+     default:
+         /* level may be zero for ldpte */
+         *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE);
+         *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH);
+         break;
      }
-
-     if (access_type == MMU_DATA_LOAD && tlb_nr) {
-         return TLBRET_RI;
-     }
-
-     if (((tlb_rplv == 0) && (plv > tlb_plv)) ||
-         ((tlb_rplv == 1) && (plv != tlb_plv))) {
-         return TLBRET_PE;
-     }
-
-     if ((access_type == MMU_DATA_STORE) && !tlb_d) {
-         return TLBRET_DIRTY;
-     }
-
-     *physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
-                 (address & MAKE_64BIT_MASK(0, tlb_ps));
-     *prot = PAGE_READ;
-     if (tlb_d) {
-         *prot |= PAGE_WRITE;
-     }
-     if (!tlb_nx) {
-         *prot |= PAGE_EXEC;
-     }
-     return TLBRET_MATCH;
- }
-
- /*
-  * One tlb entry holds an adjacent odd/even pair, the vpn is the
-  * content of the virtual page number divided by 2. So the
-  * compare vpn is bit[47:15] for 16KiB page. while the vppn
-  * field in tlb entry contains bit[47:13], so need adjust.
-  * virt_vpn = vaddr[47:13]
-  */
- bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
-                           int *index)
- {
-     LoongArchTLB *tlb;
-     uint16_t csr_asid, tlb_asid, stlb_idx;
-     uint8_t tlb_e, tlb_ps, tlb_g, stlb_ps;
-     int i, compare_shift;
-     uint64_t vpn, tlb_vppn;
-
-     csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
-     stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
-     vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1);
-     stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */
-     compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
-
-     /* Search STLB */
-     for (i = 0; i < 8; ++i) {
-         tlb = &env->tlb[i * 256 + stlb_idx];
-         tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
-         if (tlb_e) {
-             tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
-             tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
-             tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
-
-             if ((tlb_g == 1 || tlb_asid == csr_asid) &&
-                 (vpn == (tlb_vppn >> compare_shift))) {
-                 *index = i * 256 + stlb_idx;
-                 return true;
-             }
-         }
-     }
-
-     /* Search MTLB */
-     for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; ++i) {
-         tlb = &env->tlb[i];
-         tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
-         if (tlb_e) {
-             tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
-             tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
-             tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
-             tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
-             compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
-             vpn = (vaddr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
-             if ((tlb_g == 1 || tlb_asid == csr_asid) &&
-                 (vpn == (tlb_vppn >> compare_shift))) {
-                 *index = i;
-                 return true;
-             }
-         }
-     }
-     return false;
  }

  static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
diff --cc target/loongarch/tcg/tlb_helper.c
index 9a76a2a205,2fdd10022b..af208d75ae
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@@ -15,10 -15,10 +15,11 @@@
  #include "exec/cputlb.h"
  #include "exec/exec-all.h"
  #include "exec/page-protection.h"
 -#include "exec/cpu_ldst.h"
 +#include "exec/target_page.h"
 +#include "accel/tcg/cpu-ldst.h"
  #include "exec/log.h"
  #include "cpu-csr.h"
+ #include "tcg/tcg_loongarch.h"

  bool check_ps(CPULoongArchState *env, uint8_t tlb_ps)
  {