* [PULL 00/14] loongarch queue
@ 2025-08-29 2:54 Bibo Mao
2025-08-29 2:54 ` [PULL 01/14] target/loongarch: Move some function definition to kvm directory Bibo Mao
` (14 more replies)
0 siblings, 15 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:54 UTC (permalink / raw)
To: qemu-devel
The following changes since commit ca18b336e12c8433177a3cd639c5bf757952adaa:
Merge tag 'pull-lu-20250828' of https://gitlab.com/rth7680/qemu into staging (2025-08-28 09:24:36 +1000)
are available in the Git repository at:
https://github.com/bibo-mao/qemu.git tags/pull-loongarch-20250829
for you to fetch changes up to cc78259deb21940521a227619eb00a4b8e3e36c2:
target/loongarch: Use correct address when flush tlb (2025-08-29 10:05:02 +0800)
----------------------------------------------------------------
pull-loongarch-20250829 queue
----------------------------------------------------------------
Bibo Mao (14):
target/loongarch: Move some function definition to kvm directory
target/loongarch: Define function loongarch_cpu_post_init as static
target/loongarch: Set page size in TLB entry with STLB
target/loongarch: Add header file cpu-mmu.h
target/loongarch: Add enum type TLBRet definition
target/loongarch: Use vaddr in get_physical_address()
target/loongarch: Use MMUAccessType in loongarch_map_tlb_entry()
target/loongarch: Add common function loongarch_check_pte()
target/loongarch: Use loongarch_check_pte in loongarch_page_table_walker
target/loongarch: Use MMUConext in loongarch_map_tlb_entry()
target/loongarch: Use MMUContext in loongarch_get_addr_from_tlb
target/loongarch: Use MMUContext in loongarch_map_address()
target/loongarch: Use MMUContext in get_physical_address()
target/loongarch: Use correct address when flush tlb
hw/loongarch/virt.c | 1 +
target/loongarch/cpu-mmu.h | 40 ++++++++
target/loongarch/cpu.c | 181 ++++++++++++++++++-----------------
target/loongarch/cpu.h | 11 ---
target/loongarch/cpu_helper.c | 142 +++++++++++++++++----------
target/loongarch/internals.h | 20 ----
target/loongarch/kvm/kvm_loongarch.h | 4 +-
target/loongarch/tcg/csr_helper.c | 1 +
target/loongarch/tcg/tcg_loongarch.h | 7 +-
target/loongarch/tcg/tlb_helper.c | 144 ++++++++--------------------
10 files changed, 270 insertions(+), 281 deletions(-)
create mode 100644 target/loongarch/cpu-mmu.h
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PULL 01/14] target/loongarch: Move some function definition to kvm directory
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
@ 2025-08-29 2:54 ` Bibo Mao
2025-08-29 2:54 ` [PULL 02/14] target/loongarch: Define function loongarch_cpu_post_init as static Bibo Mao
` (13 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
Move function definition specified with kvm to the corresponding
directory. Also remove header file "cpu.h" including outside of
macro QEMU_KVM_LOONGARCH_H.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
hw/loongarch/virt.c | 1 +
target/loongarch/cpu.h | 9 ---------
target/loongarch/kvm/kvm_loongarch.h | 4 ++--
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index b15ada2078..31215b7785 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -46,6 +46,7 @@
#include "hw/block/flash.h"
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
+#include "kvm/kvm_loongarch.h"
static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 9538e8d61d..bbe6db33f1 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -496,13 +496,4 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value)
void loongarch_cpu_post_init(Object *obj);
-#ifdef CONFIG_KVM
-void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu);
-#else
-static inline void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
-{
-}
-#endif
-void kvm_loongarch_init_irq_routing(void);
-
#endif /* LOONGARCH_CPU_H */
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
index 1051a341ec..51475675d6 100644
--- a/target/loongarch/kvm/kvm_loongarch.h
+++ b/target/loongarch/kvm/kvm_loongarch.h
@@ -5,11 +5,11 @@
* Copyright (c) 2023 Loongson Technology Corporation Limited
*/
-#include "cpu.h"
-
#ifndef QEMU_KVM_LOONGARCH_H
#define QEMU_KVM_LOONGARCH_H
+void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu);
+void kvm_loongarch_init_irq_routing(void);
int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
void kvm_arch_reset_vcpu(CPUState *cs);
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 02/14] target/loongarch: Define function loongarch_cpu_post_init as static
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
2025-08-29 2:54 ` [PULL 01/14] target/loongarch: Move some function definition to kvm directory Bibo Mao
@ 2025-08-29 2:54 ` Bibo Mao
2025-08-29 2:54 ` [PULL 03/14] target/loongarch: Set page size in TLB entry with STLB Bibo Mao
` (12 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
Function loongarch_cpu_post_init() is implemented and used in the
same file target/loongarch/cpu.c, it can be defined as static function.
This patch moves implementation about function loongarch_cpu_post_init()
before it is referenced. And it is only code movement, no function
change.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu.c | 180 ++++++++++++++++++++---------------------
target/loongarch/cpu.h | 2 -
2 files changed, 90 insertions(+), 92 deletions(-)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index abad84c054..b96429ffb1 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -422,6 +422,96 @@ static void loongarch_la464_init_csr(Object *obj)
#endif
}
+static bool loongarch_get_lsx(Object *obj, Error **errp)
+{
+ return LOONGARCH_CPU(obj)->lsx != ON_OFF_AUTO_OFF;
+}
+
+static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+ uint32_t val;
+
+ cpu->lsx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+ if (cpu->lsx == ON_OFF_AUTO_OFF) {
+ cpu->lasx = ON_OFF_AUTO_OFF;
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
+ error_setg(errp, "Failed to disable LSX since LASX is enabled");
+ return;
+ }
+ }
+
+ if (kvm_enabled()) {
+ /* kvm feature detection in function kvm_arch_init_vcpu */
+ return;
+ }
+
+ /* LSX feature detection in TCG mode */
+ val = cpu->env.cpucfg[2];
+ if (cpu->lsx == ON_OFF_AUTO_ON) {
+ if (FIELD_EX32(val, CPUCFG2, LSX) == 0) {
+ error_setg(errp, "Failed to enable LSX in TCG mode");
+ return;
+ }
+ } else {
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, 0);
+ val = cpu->env.cpucfg[2];
+ }
+
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LSX, value);
+}
+
+static bool loongarch_get_lasx(Object *obj, Error **errp)
+{
+ return LOONGARCH_CPU(obj)->lasx != ON_OFF_AUTO_OFF;
+}
+
+static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+ uint32_t val;
+
+ cpu->lasx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+ if ((cpu->lsx == ON_OFF_AUTO_OFF) && (cpu->lasx == ON_OFF_AUTO_ON)) {
+ error_setg(errp, "Failed to enable LASX since lSX is disabled");
+ return;
+ }
+
+ if (kvm_enabled()) {
+ /* kvm feature detection in function kvm_arch_init_vcpu */
+ return;
+ }
+
+ /* LASX feature detection in TCG mode */
+ val = cpu->env.cpucfg[2];
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
+ if (FIELD_EX32(val, CPUCFG2, LASX) == 0) {
+ error_setg(errp, "Failed to enable LASX in TCG mode");
+ return;
+ }
+ }
+
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
+}
+
+static void loongarch_cpu_post_init(Object *obj)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+ cpu->lbt = ON_OFF_AUTO_OFF;
+ cpu->pmu = ON_OFF_AUTO_OFF;
+ cpu->lsx = ON_OFF_AUTO_AUTO;
+ cpu->lasx = ON_OFF_AUTO_AUTO;
+ object_property_add_bool(obj, "lsx", loongarch_get_lsx,
+ loongarch_set_lsx);
+ object_property_add_bool(obj, "lasx", loongarch_get_lasx,
+ loongarch_set_lasx);
+ /* lbt is enabled only in kvm mode, not supported in tcg mode */
+ if (kvm_enabled()) {
+ kvm_loongarch_cpu_post_init(cpu);
+ }
+}
+
static void loongarch_la464_initfn(Object *obj)
{
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
@@ -683,96 +773,6 @@ static void loongarch_cpu_unrealizefn(DeviceState *dev)
lacc->parent_unrealize(dev);
}
-static bool loongarch_get_lsx(Object *obj, Error **errp)
-{
- return LOONGARCH_CPU(obj)->lsx != ON_OFF_AUTO_OFF;
-}
-
-static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
-{
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
- uint32_t val;
-
- cpu->lsx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
- if (cpu->lsx == ON_OFF_AUTO_OFF) {
- cpu->lasx = ON_OFF_AUTO_OFF;
- if (cpu->lasx == ON_OFF_AUTO_ON) {
- error_setg(errp, "Failed to disable LSX since LASX is enabled");
- return;
- }
- }
-
- if (kvm_enabled()) {
- /* kvm feature detection in function kvm_arch_init_vcpu */
- return;
- }
-
- /* LSX feature detection in TCG mode */
- val = cpu->env.cpucfg[2];
- if (cpu->lsx == ON_OFF_AUTO_ON) {
- if (FIELD_EX32(val, CPUCFG2, LSX) == 0) {
- error_setg(errp, "Failed to enable LSX in TCG mode");
- return;
- }
- } else {
- cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, 0);
- val = cpu->env.cpucfg[2];
- }
-
- cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LSX, value);
-}
-
-static bool loongarch_get_lasx(Object *obj, Error **errp)
-{
- return LOONGARCH_CPU(obj)->lasx != ON_OFF_AUTO_OFF;
-}
-
-static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
-{
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
- uint32_t val;
-
- cpu->lasx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
- if ((cpu->lsx == ON_OFF_AUTO_OFF) && (cpu->lasx == ON_OFF_AUTO_ON)) {
- error_setg(errp, "Failed to enable LASX since lSX is disabled");
- return;
- }
-
- if (kvm_enabled()) {
- /* kvm feature detection in function kvm_arch_init_vcpu */
- return;
- }
-
- /* LASX feature detection in TCG mode */
- val = cpu->env.cpucfg[2];
- if (cpu->lasx == ON_OFF_AUTO_ON) {
- if (FIELD_EX32(val, CPUCFG2, LASX) == 0) {
- error_setg(errp, "Failed to enable LASX in TCG mode");
- return;
- }
- }
-
- cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
-}
-
-void loongarch_cpu_post_init(Object *obj)
-{
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
-
- cpu->lbt = ON_OFF_AUTO_OFF;
- cpu->pmu = ON_OFF_AUTO_OFF;
- cpu->lsx = ON_OFF_AUTO_AUTO;
- cpu->lasx = ON_OFF_AUTO_AUTO;
- object_property_add_bool(obj, "lsx", loongarch_get_lsx,
- loongarch_set_lsx);
- object_property_add_bool(obj, "lasx", loongarch_get_lasx,
- loongarch_set_lasx);
- /* lbt is enabled only in kvm mode, not supported in tcg mode */
- if (kvm_enabled()) {
- kvm_loongarch_cpu_post_init(cpu);
- }
-}
-
static void loongarch_cpu_init(Object *obj)
{
#ifndef CONFIG_USER_ONLY
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index bbe6db33f1..7731f6acdc 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -494,6 +494,4 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value)
#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
-void loongarch_cpu_post_init(Object *obj);
-
#endif /* LOONGARCH_CPU_H */
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 03/14] target/loongarch: Set page size in TLB entry with STLB
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
2025-08-29 2:54 ` [PULL 01/14] target/loongarch: Move some function definition to kvm directory Bibo Mao
2025-08-29 2:54 ` [PULL 02/14] target/loongarch: Define function loongarch_cpu_post_init as static Bibo Mao
@ 2025-08-29 2:54 ` Bibo Mao
2025-08-29 2:54 ` [PULL 04/14] target/loongarch: Add header file cpu-mmu.h Bibo Mao
` (11 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Song Gao
With VTLB different TLB entry may have different page size, and
page size is set in PS field of TLB entry. However with STLB, all
the TLB entries have the same page size, page size comes from register
CSR_STLBPS, PS field of TLB entry is not used.
Here PS field of TLB entry is used with all TLB entries, even with
STLB. It is convenient with TLB maintainance operation.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Song Gao <gaosong@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 41 ++++++++-----------------------
1 file changed, 10 insertions(+), 31 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 8872593ff0..3ea0e153b1 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -110,11 +110,8 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
if (!tlb_e) {
return;
}
- 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);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
@@ -173,11 +170,8 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
lo1 = env->CSR_TLBELO1;
}
- /* Only MTLB has the ps fields */
- if (index >= LOONGARCH_STLB) {
- tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
- }
-
+ /* Store page size in field PS */
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1);
csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
@@ -283,12 +277,7 @@ void helper_tlbrd(CPULoongArchState *env)
index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
tlb = &env->tlb[index];
-
- 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);
- }
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
if (!tlb_e) {
@@ -476,11 +465,8 @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -509,11 +495,8 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -673,11 +656,7 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
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);
- }
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
n = (address >> tlb_ps) & 0x1;/* Odd or even */
tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 04/14] target/loongarch: Add header file cpu-mmu.h
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (2 preceding siblings ...)
2025-08-29 2:54 ` [PULL 03/14] target/loongarch: Set page size in TLB entry with STLB Bibo Mao
@ 2025-08-29 2:54 ` Bibo Mao
2025-08-29 2:54 ` [PULL 05/14] target/loongarch: Add enum type TLBRet definition Bibo Mao
` (10 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
New header file cpu-mmu.h is added and move mmu relative function
declaration to this file.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu-mmu.h | 30 ++++++++++++++++++++++++++++++
target/loongarch/cpu.c | 1 +
target/loongarch/cpu_helper.c | 1 +
target/loongarch/internals.h | 20 --------------------
target/loongarch/tcg/csr_helper.c | 1 +
target/loongarch/tcg/tlb_helper.c | 1 +
6 files changed, 34 insertions(+), 20 deletions(-)
create mode 100644 target/loongarch/cpu-mmu.h
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
new file mode 100644
index 0000000000..4c5cbd7425
--- /dev/null
+++ b/target/loongarch/cpu-mmu.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch CPU parameters for QEMU.
+ *
+ * Copyright (c) 2025 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_MMU_H
+#define LOONGARCH_CPU_MMU_H
+
+enum {
+ TLBRET_MATCH = 0,
+ TLBRET_BADADDR = 1,
+ TLBRET_NOMATCH = 2,
+ TLBRET_INVALID = 3,
+ TLBRET_DIRTY = 4,
+ TLBRET_RI = 5,
+ TLBRET_XI = 6,
+ TLBRET_PE = 7,
+};
+
+bool check_ps(CPULoongArchState *ent, uint8_t ps);
+int get_physical_address(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx, int is_debug);
+void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
+ uint64_t *dir_width, target_ulong level);
+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+
+#endif /* LOONGARCH_CPU_MMU_H */
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index b96429ffb1..990985708e 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -17,6 +17,7 @@
#include "hw/qdev-properties.h"
#include "exec/translation-block.h"
#include "cpu.h"
+#include "cpu-mmu.h"
#include "internals.h"
#include "fpu/softfloat-helpers.h"
#include "csr.h"
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index b5f732f15b..418122f447 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -13,6 +13,7 @@
#include "exec/target_page.h"
#include "internals.h"
#include "cpu-csr.h"
+#include "cpu-mmu.h"
#include "tcg/tcg_loongarch.h"
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index a7384b0d31..e50d109767 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -32,19 +32,6 @@ void restore_fp_status(CPULoongArchState *env);
#endif
#ifndef CONFIG_USER_ONLY
-enum {
- TLBRET_MATCH = 0,
- TLBRET_BADADDR = 1,
- TLBRET_NOMATCH = 2,
- TLBRET_INVALID = 3,
- TLBRET_DIRTY = 4,
- TLBRET_RI = 5,
- TLBRET_XI = 6,
- TLBRET_PE = 7,
-};
-
-bool check_ps(CPULoongArchState *ent, uint8_t ps);
-
extern const VMStateDescription vmstate_loongarch_cpu;
void loongarch_cpu_set_irq(void *opaque, int irq, int level);
@@ -54,13 +41,6 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
uint64_t value);
-int get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx, int is_debug);
-void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
- uint64_t *dir_width, target_ulong level);
-hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-
#endif /* !CONFIG_USER_ONLY */
uint64_t read_fcc(CPULoongArchState *env);
diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c
index 28b1bb86bd..0d99e2c92b 100644
--- a/target/loongarch/tcg/csr_helper.c
+++ b/target/loongarch/tcg/csr_helper.c
@@ -16,6 +16,7 @@
#include "accel/tcg/cpu-ldst.h"
#include "hw/irq.h"
#include "cpu-csr.h"
+#include "cpu-mmu.h"
target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
{
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 3ea0e153b1..1f49619e7f 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -10,6 +10,7 @@
#include "qemu/guest-random.h"
#include "cpu.h"
+#include "cpu-mmu.h"
#include "internals.h"
#include "exec/helper-proto.h"
#include "exec/cputlb.h"
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 05/14] target/loongarch: Add enum type TLBRet definition
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (3 preceding siblings ...)
2025-08-29 2:54 ` [PULL 04/14] target/loongarch: Add header file cpu-mmu.h Bibo Mao
@ 2025-08-29 2:54 ` Bibo Mao
2025-08-29 2:54 ` [PULL 06/14] target/loongarch: Use vaddr in get_physical_address() Bibo Mao
` (9 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
There is mixed usage between enum variable TLBRET_xxx and int type,
here add enum type TLBRet definition and replace int type variable
with enum type TLBRet in some functions.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu-mmu.h | 27 ++++++++++++++-------------
target/loongarch/cpu_helper.c | 26 ++++++++++++++------------
target/loongarch/tcg/tcg_loongarch.h | 7 ++++---
target/loongarch/tcg/tlb_helper.c | 16 ++++++++--------
4 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
index 4c5cbd7425..cbe6f37773 100644
--- a/target/loongarch/cpu-mmu.h
+++ b/target/loongarch/cpu-mmu.h
@@ -8,21 +8,22 @@
#ifndef LOONGARCH_CPU_MMU_H
#define LOONGARCH_CPU_MMU_H
-enum {
- TLBRET_MATCH = 0,
- TLBRET_BADADDR = 1,
- TLBRET_NOMATCH = 2,
- TLBRET_INVALID = 3,
- TLBRET_DIRTY = 4,
- TLBRET_RI = 5,
- TLBRET_XI = 6,
- TLBRET_PE = 7,
-};
+typedef enum TLBRet {
+ TLBRET_MATCH,
+ TLBRET_BADADDR,
+ TLBRET_NOMATCH,
+ TLBRET_INVALID,
+ TLBRET_DIRTY,
+ TLBRET_RI,
+ TLBRET_XI,
+ TLBRET_PE,
+} TLBRet;
bool check_ps(CPULoongArchState *ent, uint8_t ps);
-int get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx, int is_debug);
+TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx,
+ int is_debug);
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
uint64_t *dir_width, target_ulong level);
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 418122f447..17a0735f5c 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -44,8 +44,9 @@ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
}
}
-static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address)
+static TLBRet loongarch_page_table_walker(CPULoongArchState *env,
+ hwaddr *physical,
+ int *prot, target_ulong address)
{
CPUState *cs = env_cpu(env);
target_ulong index, phys;
@@ -116,15 +117,15 @@ static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
/* mask other attribute bits */
*physical = base & TARGET_PAGE_MASK;
- return 0;
+ return TLBRET_MATCH;
}
-static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx,
- int is_debug)
+static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx,
+ int is_debug)
{
- int ret;
+ TLBRet ret;
if (tcg_enabled()) {
ret = loongarch_get_addr_from_tlb(env, physical, prot, address,
@@ -158,9 +159,10 @@ static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
}
}
-int get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx, int is_debug)
+TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx,
+ int is_debug)
{
int user_mode = mmu_idx == MMU_USER_IDX;
int kernel_mode = mmu_idx == MMU_KERNEL_IDX;
@@ -214,7 +216,7 @@ hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
int prot;
if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
- cpu_mmu_index(cs, false), 1) != 0) {
+ cpu_mmu_index(cs, false), 1) != TLBRET_MATCH) {
return -1;
}
return phys_addr;
diff --git a/target/loongarch/tcg/tcg_loongarch.h b/target/loongarch/tcg/tcg_loongarch.h
index fd4e116022..488700c3c3 100644
--- a/target/loongarch/tcg/tcg_loongarch.h
+++ b/target/loongarch/tcg/tcg_loongarch.h
@@ -7,6 +7,7 @@
#ifndef TARGET_LOONGARCH_TCG_LOONGARCH_H
#define TARGET_LOONGARCH_TCG_LOONGARCH_H
#include "cpu.h"
+#include "cpu-mmu.h"
void loongarch_csr_translate_init(void);
@@ -14,8 +15,8 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
-int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx);
+TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx);
#endif /* TARGET_LOONGARCH_TCG_LOONGARCH_H */
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 1f49619e7f..4a2a565985 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -30,7 +30,7 @@ bool check_ps(CPULoongArchState *env, uint8_t tlb_ps)
}
static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
- MMUAccessType access_type, int tlb_error)
+ MMUAccessType access_type, TLBRet tlb_error)
{
CPUState *cs = env_cpu(env);
@@ -517,7 +517,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
CPULoongArchState *env = cpu_env(cs);
hwaddr physical;
int prot;
- int ret;
+ TLBRet ret;
/* Data access */
ret = get_physical_address(env, &physical, &prot, address,
@@ -648,9 +648,9 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps);
}
-static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- int access_type, int index, int mmu_idx)
+static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ int access_type, int index, int mmu_idx)
{
LoongArchTLB *tlb = &env->tlb[index];
uint64_t plv = mmu_idx;
@@ -713,9 +713,9 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
return TLBRET_MATCH;
}
-int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx)
+TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx)
{
int index, match;
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 06/14] target/loongarch: Use vaddr in get_physical_address()
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (4 preceding siblings ...)
2025-08-29 2:54 ` [PULL 05/14] target/loongarch: Add enum type TLBRet definition Bibo Mao
@ 2025-08-29 2:54 ` Bibo Mao
2025-08-29 2:55 ` [PULL 07/14] target/loongarch: Use MMUAccessType in loongarch_map_tlb_entry() Bibo Mao
` (8 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
Replace target_ulong type with vaddr in function get_physical_address()
and the same with its calling functions.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu-mmu.h | 2 +-
target/loongarch/cpu_helper.c | 9 ++++-----
target/loongarch/tcg/tlb_helper.c | 11 ++++++-----
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
index cbe6f37773..dffc12820f 100644
--- a/target/loongarch/cpu-mmu.h
+++ b/target/loongarch/cpu-mmu.h
@@ -21,7 +21,7 @@ typedef enum TLBRet {
bool check_ps(CPULoongArchState *ent, uint8_t ps);
TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+ int *prot, vaddr address,
MMUAccessType access_type, int mmu_idx,
int is_debug);
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 17a0735f5c..0c037ef163 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -46,7 +46,7 @@ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
static TLBRet loongarch_page_table_walker(CPULoongArchState *env,
hwaddr *physical,
- int *prot, target_ulong address)
+ int *prot, vaddr address)
{
CPUState *cs = env_cpu(env);
target_ulong index, phys;
@@ -121,7 +121,7 @@ static TLBRet loongarch_page_table_walker(CPULoongArchState *env,
}
static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+ int *prot, vaddr address,
MMUAccessType access_type, int mmu_idx,
int is_debug)
{
@@ -147,8 +147,7 @@ static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
return TLBRET_NOMATCH;
}
-static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
- target_ulong dmw)
+static hwaddr dmw_va2pa(CPULoongArchState *env, vaddr va, target_ulong dmw)
{
if (is_la64(env)) {
return va & TARGET_VIRT_MASK;
@@ -160,7 +159,7 @@ static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
}
TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+ int *prot, vaddr address,
MMUAccessType access_type, int mmu_idx,
int is_debug)
{
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 4a2a565985..3d09f18020 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -29,7 +29,7 @@ bool check_ps(CPULoongArchState *env, uint8_t tlb_ps)
return BIT_ULL(tlb_ps) & (env->CSR_PRCFG2);
}
-static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
+static void raise_mmu_exception(CPULoongArchState *env, vaddr address,
MMUAccessType access_type, TLBRet tlb_error)
{
CPUState *cs = env_cpu(env);
@@ -198,7 +198,7 @@ static uint32_t get_random_tlb(uint32_t low, uint32_t high)
* field in tlb entry contains bit[47:13], so need adjust.
* virt_vpn = vaddr[47:13]
*/
-static bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
+static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr,
int *index)
{
LoongArchTLB *tlb;
@@ -649,8 +649,9 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
}
static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- int access_type, int index, int mmu_idx)
+ int *prot, vaddr address,
+ int access_type, int index,
+ int mmu_idx)
{
LoongArchTLB *tlb = &env->tlb[index];
uint64_t plv = mmu_idx;
@@ -714,7 +715,7 @@ static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
}
TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+ int *prot, vaddr address,
MMUAccessType access_type, int mmu_idx)
{
int index, match;
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 07/14] target/loongarch: Use MMUAccessType in loongarch_map_tlb_entry()
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (5 preceding siblings ...)
2025-08-29 2:54 ` [PULL 06/14] target/loongarch: Use vaddr in get_physical_address() Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-08-29 2:55 ` [PULL 08/14] target/loongarch: Add common function loongarch_check_pte() Bibo Mao
` (7 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
Enum type MMUAccessType is used in function loongarch_map_tlb_entry()
rather than int type, and keep consistent with its caller function.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/tcg/tlb_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 3d09f18020..915b1aadb5 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -650,7 +650,7 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
int *prot, vaddr address,
- int access_type, int index,
+ MMUAccessType access_type, int index,
int mmu_idx)
{
LoongArchTLB *tlb = &env->tlb[index];
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 08/14] target/loongarch: Add common function loongarch_check_pte()
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (6 preceding siblings ...)
2025-08-29 2:55 ` [PULL 07/14] target/loongarch: Use MMUAccessType in loongarch_map_tlb_entry() Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-08-29 2:55 ` [PULL 09/14] target/loongarch: Use loongarch_check_pte in loongarch_page_table_walker Bibo Mao
` (6 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
Common function loongarch_check_pte() is to check tlb entry, return
the physical address and access priviledge if found. Also it can be
used with page table entry, which is used in page table walker.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu-mmu.h | 10 +++++
target/loongarch/cpu_helper.c | 61 ++++++++++++++++++++++++++++
target/loongarch/tcg/tlb_helper.c | 66 ++++++-------------------------
3 files changed, 83 insertions(+), 54 deletions(-)
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
index dffc12820f..be3d11d3c1 100644
--- a/target/loongarch/cpu-mmu.h
+++ b/target/loongarch/cpu-mmu.h
@@ -19,7 +19,17 @@ typedef enum TLBRet {
TLBRET_PE,
} TLBRet;
+typedef struct MMUContext {
+ vaddr addr;
+ uint64_t pte;
+ hwaddr physical;
+ int ps; /* page size shift */
+ int prot;
+} MMUContext;
+
bool check_ps(CPULoongArchState *ent, uint8_t ps);
+TLBRet loongarch_check_pte(CPULoongArchState *env, MMUContext *context,
+ MMUAccessType access_type, int mmu_idx);
TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
int *prot, vaddr address,
MMUAccessType access_type, int mmu_idx,
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 0c037ef163..739cdab5aa 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -44,6 +44,67 @@ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
}
}
+TLBRet loongarch_check_pte(CPULoongArchState *env, MMUContext *context,
+ MMUAccessType access_type, int mmu_idx)
+{
+ uint64_t plv = mmu_idx;
+ uint64_t tlb_entry, tlb_ppn;
+ uint8_t tlb_ps, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
+
+ tlb_entry = context->pte;
+ tlb_ps = context->ps;
+ 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;
+ }
+
+ 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;
+ }
+
+ context->physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
+ (context->addr & MAKE_64BIT_MASK(0, tlb_ps));
+ context->prot = PAGE_READ;
+ if (tlb_d) {
+ context->prot |= PAGE_WRITE;
+ }
+ if (!tlb_nx) {
+ context->prot |= PAGE_EXEC;
+ }
+ return TLBRET_MATCH;
+}
+
static TLBRet loongarch_page_table_walker(CPULoongArchState *env,
hwaddr *physical,
int *prot, vaddr address)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 915b1aadb5..10322da62e 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -654,64 +654,22 @@ static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
int mmu_idx)
{
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;
+ uint8_t tlb_ps, n;
+ MMUContext context;
+ TLBRet ret;
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
n = (address >> tlb_ps) & 0x1;/* Odd or even */
+ context.pte = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
+ context.addr = address;
+ context.ps = tlb_ps;
+ ret = loongarch_check_pte(env, &context, access_type, mmu_idx);
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
- 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;
- }
-
- 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;
+ return ret;
}
TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 09/14] target/loongarch: Use loongarch_check_pte in loongarch_page_table_walker
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (7 preceding siblings ...)
2025-08-29 2:55 ` [PULL 08/14] target/loongarch: Add common function loongarch_check_pte() Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-08-29 2:55 ` [PULL 10/14] target/loongarch: Use MMUConext in loongarch_map_tlb_entry() Bibo Mao
` (5 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
Function loongarch_check_pte() can get physical address and access
priviledge, it works on both TLB entry and pte entry. It can be used
in function loongarch_page_table_walker() also.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu_helper.c | 42 +++++++++++++----------------------
1 file changed, 16 insertions(+), 26 deletions(-)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 739cdab5aa..cd61b33ef9 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -106,15 +106,17 @@ TLBRet loongarch_check_pte(CPULoongArchState *env, MMUContext *context,
}
static TLBRet loongarch_page_table_walker(CPULoongArchState *env,
- hwaddr *physical,
- int *prot, vaddr address)
+ MMUContext *context,
+ int access_type, int mmu_idx)
{
CPUState *cs = env_cpu(env);
target_ulong index, phys;
uint64_t dir_base, dir_width;
uint64_t base;
int level;
+ vaddr address;
+ address = context->addr;
if ((address >> 63) & 0x1) {
base = env->CSR_PGDH;
} else {
@@ -156,29 +158,9 @@ static TLBRet loongarch_page_table_walker(CPULoongArchState *env,
base = ldq_phys(cs->as, phys);
}
- /* TODO: check plv and other bits? */
-
- /* base is pte, in normal pte format */
- if (!FIELD_EX64(base, TLBENTRY, V)) {
- return TLBRET_NOMATCH;
- }
-
- if (!FIELD_EX64(base, TLBENTRY, D)) {
- *prot = PAGE_READ;
- } else {
- *prot = PAGE_READ | PAGE_WRITE;
- }
-
- /* get TARGET_PAGE_SIZE aligned physical address */
- base += (address & TARGET_PHYS_MASK) & ((1 << dir_base) - 1);
- /* mask RPLV, NX, NR bits */
- base = FIELD_DP64(base, TLBENTRY_64, RPLV, 0);
- base = FIELD_DP64(base, TLBENTRY_64, NX, 0);
- base = FIELD_DP64(base, TLBENTRY_64, NR, 0);
- /* mask other attribute bits */
- *physical = base & TARGET_PAGE_MASK;
-
- return TLBRET_MATCH;
+ context->ps = dir_base;
+ context->pte = base;
+ return loongarch_check_pte(env, context, access_type, mmu_idx);
}
static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
@@ -187,7 +169,9 @@ static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
int is_debug)
{
TLBRet ret;
+ MMUContext context;
+ context.addr = address;
if (tcg_enabled()) {
ret = loongarch_get_addr_from_tlb(env, physical, prot, address,
access_type, mmu_idx);
@@ -202,7 +186,13 @@ static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
* legal mapping, even if the mapping is not yet in TLB. return 0 if
* there is a valid map, else none zero.
*/
- return loongarch_page_table_walker(env, physical, prot, address);
+ ret = loongarch_page_table_walker(env, &context, access_type, mmu_idx);
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
+
+ return ret;
}
return TLBRET_NOMATCH;
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 10/14] target/loongarch: Use MMUConext in loongarch_map_tlb_entry()
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (8 preceding siblings ...)
2025-08-29 2:55 ` [PULL 09/14] target/loongarch: Use loongarch_check_pte in loongarch_page_table_walker Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-08-29 2:55 ` [PULL 11/14] target/loongarch: Use MMUContext in loongarch_get_addr_from_tlb Bibo Mao
` (4 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
With function loongarch_map_tlb_entry(), parameter MMUConext is added
and remove parameter physical, prot and address.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/tcg/tlb_helper.c | 33 +++++++++++++++----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 10322da62e..703ab9c8ca 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -648,28 +648,19 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps);
}
-static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
- int *prot, vaddr address,
+static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env,
+ MMUContext *context,
MMUAccessType access_type, int index,
int mmu_idx)
{
LoongArchTLB *tlb = &env->tlb[index];
uint8_t tlb_ps, n;
- MMUContext context;
- TLBRet ret;
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- n = (address >> tlb_ps) & 0x1;/* Odd or even */
- context.pte = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
- context.addr = address;
- context.ps = tlb_ps;
- ret = loongarch_check_pte(env, &context, access_type, mmu_idx);
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
-
- return ret;
+ n = (context->addr >> tlb_ps) & 0x1;/* Odd or even */
+ context->pte = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
+ context->ps = tlb_ps;
+ return loongarch_check_pte(env, context, access_type, mmu_idx);
}
TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
@@ -677,11 +668,19 @@ TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
MMUAccessType access_type, int mmu_idx)
{
int index, match;
+ MMUContext context;
+ TLBRet ret;
+ context.addr = address;
match = loongarch_tlb_search(env, address, &index);
if (match) {
- return loongarch_map_tlb_entry(env, physical, prot,
- address, access_type, index, mmu_idx);
+ ret = loongarch_map_tlb_entry(env, &context, access_type, index,
+ mmu_idx);
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
+ return ret;
}
return TLBRET_NOMATCH;
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 11/14] target/loongarch: Use MMUContext in loongarch_get_addr_from_tlb
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (9 preceding siblings ...)
2025-08-29 2:55 ` [PULL 10/14] target/loongarch: Use MMUConext in loongarch_map_tlb_entry() Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-08-29 2:55 ` [PULL 12/14] target/loongarch: Use MMUContext in loongarch_map_address() Bibo Mao
` (3 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
With function loongarch_get_addr_from_tlb(), parameter MMUContext
is added and remove parameter physical, prot and address.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu_helper.c | 7 +++++--
target/loongarch/tcg/tcg_loongarch.h | 4 ++--
target/loongarch/tcg/tlb_helper.c | 18 +++++-------------
3 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index cd61b33ef9..0cc01a0ca4 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -173,9 +173,12 @@ static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
context.addr = address;
if (tcg_enabled()) {
- ret = loongarch_get_addr_from_tlb(env, physical, prot, address,
- access_type, mmu_idx);
+ ret = loongarch_get_addr_from_tlb(env, &context, access_type, mmu_idx);
if (ret != TLBRET_NOMATCH) {
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
return ret;
}
}
diff --git a/target/loongarch/tcg/tcg_loongarch.h b/target/loongarch/tcg/tcg_loongarch.h
index 488700c3c3..47702893e3 100644
--- a/target/loongarch/tcg/tcg_loongarch.h
+++ b/target/loongarch/tcg/tcg_loongarch.h
@@ -15,8 +15,8 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
-TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env,
+ MMUContext *context,
MMUAccessType access_type, int mmu_idx);
#endif /* TARGET_LOONGARCH_TCG_LOONGARCH_H */
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 703ab9c8ca..64a4e82dec 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -663,24 +663,16 @@ static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env,
return loongarch_check_pte(env, context, access_type, mmu_idx);
}
-TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, vaddr address,
+TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env,
+ MMUContext *context,
MMUAccessType access_type, int mmu_idx)
{
int index, match;
- MMUContext context;
- TLBRet ret;
- context.addr = address;
- match = loongarch_tlb_search(env, address, &index);
+ match = loongarch_tlb_search(env, context->addr, &index);
if (match) {
- ret = loongarch_map_tlb_entry(env, &context, access_type, index,
- mmu_idx);
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
- return ret;
+ return loongarch_map_tlb_entry(env, context, access_type, index,
+ mmu_idx);
}
return TLBRET_NOMATCH;
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 12/14] target/loongarch: Use MMUContext in loongarch_map_address()
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (10 preceding siblings ...)
2025-08-29 2:55 ` [PULL 11/14] target/loongarch: Use MMUContext in loongarch_get_addr_from_tlb Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-08-29 2:55 ` [PULL 13/14] target/loongarch: Use MMUContext in get_physical_address() Bibo Mao
` (2 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
With function loongarch_map_address(), parameter MMUContext is added
and remove parameter address, prot and address.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu_helper.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 0cc01a0ca4..225382f70e 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -163,22 +163,16 @@ static TLBRet loongarch_page_table_walker(CPULoongArchState *env,
return loongarch_check_pte(env, context, access_type, mmu_idx);
}
-static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, vaddr address,
+static TLBRet loongarch_map_address(CPULoongArchState *env,
+ MMUContext *context,
MMUAccessType access_type, int mmu_idx,
int is_debug)
{
TLBRet ret;
- MMUContext context;
- context.addr = address;
if (tcg_enabled()) {
- ret = loongarch_get_addr_from_tlb(env, &context, access_type, mmu_idx);
+ ret = loongarch_get_addr_from_tlb(env, context, access_type, mmu_idx);
if (ret != TLBRET_NOMATCH) {
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
return ret;
}
}
@@ -189,13 +183,7 @@ static TLBRet loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
* legal mapping, even if the mapping is not yet in TLB. return 0 if
* there is a valid map, else none zero.
*/
- ret = loongarch_page_table_walker(env, &context, access_type, mmu_idx);
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
-
- return ret;
+ return loongarch_page_table_walker(env, context, access_type, mmu_idx);
}
return TLBRET_NOMATCH;
@@ -223,6 +211,8 @@ TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
int64_t addr_high;
uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
+ MMUContext context;
+ TLBRet ret;
/* Check PG and DA */
if (da & !pg) {
@@ -258,8 +248,14 @@ TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
}
/* Mapped address */
- return loongarch_map_address(env, physical, prot, address,
- access_type, mmu_idx, is_debug);
+ context.addr = address;
+ ret = loongarch_map_address(env, &context,
+ access_type, mmu_idx, is_debug);
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
+ return ret;
}
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 13/14] target/loongarch: Use MMUContext in get_physical_address()
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (11 preceding siblings ...)
2025-08-29 2:55 ` [PULL 12/14] target/loongarch: Use MMUContext in loongarch_map_address() Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-08-29 2:55 ` [PULL 14/14] target/loongarch: Use correct address when flush tlb Bibo Mao
2025-09-02 10:05 ` [PULL 00/14] loongarch queue Richard Henderson
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
With function get_physical_address(), parameter MMUContext is added
and remove parameter address, prot and address.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/cpu-mmu.h | 3 +--
target/loongarch/cpu_helper.c | 32 ++++++++++++-------------------
target/loongarch/tcg/tlb_helper.c | 8 +++++---
3 files changed, 18 insertions(+), 25 deletions(-)
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
index be3d11d3c1..0068d22efc 100644
--- a/target/loongarch/cpu-mmu.h
+++ b/target/loongarch/cpu-mmu.h
@@ -30,8 +30,7 @@ typedef struct MMUContext {
bool check_ps(CPULoongArchState *ent, uint8_t ps);
TLBRet loongarch_check_pte(CPULoongArchState *env, MMUContext *context,
MMUAccessType access_type, int mmu_idx);
-TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, vaddr address,
+TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context,
MMUAccessType access_type, int mmu_idx,
int is_debug);
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 225382f70e..4a9db3ea4c 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -200,8 +200,7 @@ static hwaddr dmw_va2pa(CPULoongArchState *env, vaddr va, target_ulong dmw)
}
}
-TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, vaddr address,
+TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context,
MMUAccessType access_type, int mmu_idx,
int is_debug)
{
@@ -211,13 +210,13 @@ TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
int64_t addr_high;
uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
- MMUContext context;
- TLBRet ret;
+ vaddr address;
/* Check PG and DA */
+ address = context->addr;
if (da & !pg) {
- *physical = address & TARGET_PHYS_MASK;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ context->physical = address & TARGET_PHYS_MASK;
+ context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TLBRET_MATCH;
}
@@ -235,8 +234,8 @@ TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG);
}
if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
- *physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ context->physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
+ context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TLBRET_MATCH;
}
}
@@ -248,25 +247,18 @@ TLBRet get_physical_address(CPULoongArchState *env, hwaddr *physical,
}
/* Mapped address */
- context.addr = address;
- ret = loongarch_map_address(env, &context,
- access_type, mmu_idx, is_debug);
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
- return ret;
+ return loongarch_map_address(env, context, access_type, mmu_idx, is_debug);
}
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
CPULoongArchState *env = cpu_env(cs);
- hwaddr phys_addr;
- int prot;
+ MMUContext context;
- if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
+ context.addr = addr;
+ if (get_physical_address(env, &context, MMU_DATA_LOAD,
cpu_mmu_index(cs, false), 1) != TLBRET_MATCH) {
return -1;
}
- return phys_addr;
+ return context.physical;
}
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 64a4e82dec..7d3f98633d 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -517,13 +517,15 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
CPULoongArchState *env = cpu_env(cs);
hwaddr physical;
int prot;
+ MMUContext context;
TLBRet ret;
/* Data access */
- ret = get_physical_address(env, &physical, &prot, address,
- access_type, mmu_idx, 0);
-
+ context.addr = address;
+ ret = get_physical_address(env, &context, access_type, mmu_idx, 0);
if (ret == TLBRET_MATCH) {
+ physical = context.physical;
+ prot = context.prot;
tlb_set_page(cs, address & TARGET_PAGE_MASK,
physical & TARGET_PAGE_MASK, prot,
mmu_idx, TARGET_PAGE_SIZE);
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PULL 14/14] target/loongarch: Use correct address when flush tlb
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (12 preceding siblings ...)
2025-08-29 2:55 ` [PULL 13/14] target/loongarch: Use MMUContext in get_physical_address() Bibo Mao
@ 2025-08-29 2:55 ` Bibo Mao
2025-09-02 10:05 ` [PULL 00/14] loongarch queue Richard Henderson
14 siblings, 0 replies; 18+ messages in thread
From: Bibo Mao @ 2025-08-29 2:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
With tlb_flush_range_by_mmuidx(), the virtual address is 64 bit.
However on LoongArch TLB emulation system, virtual address is
48 bit. It is necessary to signed-extend 48 bit address to 64 bit when
flush tlb, also fix address calculation issue with odd page.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/tcg/tlb_helper.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 7d3f98633d..9365860c8c 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -115,16 +115,16 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
+ addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask;
+ addr = sextract64(addr, 0, TARGET_VIRT_ADDR_SPACE_BITS);
if (tlb_v0) {
- addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask; /* even */
tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
if (tlb_v1) {
- addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & pagesize; /* odd */
- tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
+ tlb_flush_range_by_mmuidx(env_cpu(env), addr + pagesize, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
}
--
2.43.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PULL 00/14] loongarch queue
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
` (13 preceding siblings ...)
2025-08-29 2:55 ` [PULL 14/14] target/loongarch: Use correct address when flush tlb Bibo Mao
@ 2025-09-02 10:05 ` Richard Henderson
14 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2025-09-02 10:05 UTC (permalink / raw)
To: qemu-devel
On 8/29/25 12:54, Bibo Mao wrote:
> The following changes since commit ca18b336e12c8433177a3cd639c5bf757952adaa:
>
> Merge tag 'pull-lu-20250828' ofhttps://gitlab.com/rth7680/qemu into staging (2025-08-28 09:24:36 +1000)
>
> are available in the Git repository at:
>
> https://github.com/bibo-mao/qemu.git tags/pull-loongarch-20250829
>
> for you to fetch changes up to cc78259deb21940521a227619eb00a4b8e3e36c2:
>
> target/loongarch: Use correct address when flush tlb (2025-08-29 10:05:02 +0800)
>
> ----------------------------------------------------------------
> pull-loongarch-20250829 queue
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PULL 00/14] loongarch queue
@ 2025-10-23 12:06 Bibo Mao
2025-10-23 19:33 ` Richard Henderson
0 siblings, 1 reply; 18+ messages in thread
From: Bibo Mao @ 2025-10-23 12:06 UTC (permalink / raw)
To: qemu-devel
The following changes since commit c0e80879c876cbe4cbde43a92403329bcedf2ba0:
Merge tag 'pull-vfio-20251022' of https://github.com/legoater/qemu into staging (2025-10-22 08:01:21 -0500)
are available in the Git repository at:
https://github.com/bibo-mao/qemu.git tags/pull-loongarch-20251023
for you to fetch changes up to 79ff2eee9a377f654ed0c3533a0874a0e7d6226d:
target/loongarch: Add bit A/D checking in TLB entry with PTW supported (2025-10-23 19:43:48 +0800)
----------------------------------------------------------------
pull-loongarch-20251023 queue
----------------------------------------------------------------
Bibo Mao (14):
target/loongarch: Use auto method with PTW feature
target/loongarch: Add CSR_PWCH write helper function
target/loongarch: Add present and write bit with pte entry
target/loongarch: Add function sptw_prepare_tlb before adding tlb entry
target/loongarch: target/loongarch: Add common function get_tlb_random_index()
target/loongarch: Add MMUContext parameter in fill_tlb_entry()
target/loongarch: Add debug parameter with loongarch_page_table_walker()
target/loongarch: Reserve higher 48 bit PTE attribute with huge page
target/loongarch: Move last PTE lookup into page table walker loop
target/loongarch: Add field tlb_index to record TLB search info
target/loongarch: Add common interface update_tlb_index()
target/loongarch: Add basic hardware PTW support
target/loongarch: Update matched ptw bit A/D with PTW supported
target/loongarch: Add bit A/D checking in TLB entry with PTW supported
target/loongarch/cpu-csr.h | 4 +
target/loongarch/cpu-mmu.h | 62 ++++++++
target/loongarch/cpu.c | 26 ++++
target/loongarch/cpu.h | 2 +
target/loongarch/cpu_helper.c | 146 ++++++++++++++++---
target/loongarch/tcg/csr_helper.c | 15 ++
target/loongarch/tcg/helper.h | 1 +
.../tcg/insn_trans/trans_privileged.c.inc | 1 +
target/loongarch/tcg/tlb_helper.c | 157 ++++++++++++++++-----
9 files changed, 358 insertions(+), 56 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PULL 00/14] loongarch queue
2025-10-23 12:06 Bibo Mao
@ 2025-10-23 19:33 ` Richard Henderson
0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2025-10-23 19:33 UTC (permalink / raw)
To: qemu-devel
On 10/23/25 07:06, Bibo Mao wrote:
> The following changes since commit c0e80879c876cbe4cbde43a92403329bcedf2ba0:
>
> Merge tag 'pull-vfio-20251022' ofhttps://github.com/legoater/qemu into staging (2025-10-22 08:01:21 -0500)
>
> are available in the Git repository at:
>
> https://github.com/bibo-mao/qemu.git tags/pull-loongarch-20251023
>
> for you to fetch changes up to 79ff2eee9a377f654ed0c3533a0874a0e7d6226d:
>
> target/loongarch: Add bit A/D checking in TLB entry with PTW supported (2025-10-23 19:43:48 +0800)
>
> ----------------------------------------------------------------
> pull-loongarch-20251023 queue
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-10-23 19:33 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-29 2:54 [PULL 00/14] loongarch queue Bibo Mao
2025-08-29 2:54 ` [PULL 01/14] target/loongarch: Move some function definition to kvm directory Bibo Mao
2025-08-29 2:54 ` [PULL 02/14] target/loongarch: Define function loongarch_cpu_post_init as static Bibo Mao
2025-08-29 2:54 ` [PULL 03/14] target/loongarch: Set page size in TLB entry with STLB Bibo Mao
2025-08-29 2:54 ` [PULL 04/14] target/loongarch: Add header file cpu-mmu.h Bibo Mao
2025-08-29 2:54 ` [PULL 05/14] target/loongarch: Add enum type TLBRet definition Bibo Mao
2025-08-29 2:54 ` [PULL 06/14] target/loongarch: Use vaddr in get_physical_address() Bibo Mao
2025-08-29 2:55 ` [PULL 07/14] target/loongarch: Use MMUAccessType in loongarch_map_tlb_entry() Bibo Mao
2025-08-29 2:55 ` [PULL 08/14] target/loongarch: Add common function loongarch_check_pte() Bibo Mao
2025-08-29 2:55 ` [PULL 09/14] target/loongarch: Use loongarch_check_pte in loongarch_page_table_walker Bibo Mao
2025-08-29 2:55 ` [PULL 10/14] target/loongarch: Use MMUConext in loongarch_map_tlb_entry() Bibo Mao
2025-08-29 2:55 ` [PULL 11/14] target/loongarch: Use MMUContext in loongarch_get_addr_from_tlb Bibo Mao
2025-08-29 2:55 ` [PULL 12/14] target/loongarch: Use MMUContext in loongarch_map_address() Bibo Mao
2025-08-29 2:55 ` [PULL 13/14] target/loongarch: Use MMUContext in get_physical_address() Bibo Mao
2025-08-29 2:55 ` [PULL 14/14] target/loongarch: Use correct address when flush tlb Bibo Mao
2025-09-02 10:05 ` [PULL 00/14] loongarch queue Richard Henderson
-- strict thread matches above, loose matches on Subject: below --
2025-10-23 12:06 Bibo Mao
2025-10-23 19:33 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).