From: Xiaojuan Yang <yangxiaojuan@loongson.cn>
To: qemu-devel@nongnu.org
Cc: mark.cave-ayland@ilande.co.uk, richard.henderson@linaro.org,
gaosong@loongson.cn
Subject: [PATCH v2 27/43] target/loongarch: Add TLB instruction support
Date: Mon, 25 Apr 2022 17:10:11 +0800 [thread overview]
Message-ID: <20220425091027.2877892-28-yangxiaojuan@loongson.cn> (raw)
In-Reply-To: <20220425091027.2877892-1-yangxiaojuan@loongson.cn>
This includes:
- TLBSRCH
- TLBRD
- TLBWR
- TLBFILL
- TLBCLR
- TLBFLUSH
- INVTLB
Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/disas.c | 18 +
target/loongarch/helper.h | 13 +
.../insn_trans/trans_privileged.c.inc | 102 +++++
target/loongarch/insns.decode | 11 +
target/loongarch/tlb_helper.c | 355 ++++++++++++++++++
5 files changed, 499 insertions(+)
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index fcc06abc6b..8e9a6443b7 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -297,6 +297,17 @@ static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a,
a->rd, a->rj, a->csr, csr_names[a->csr]);
}
+static void output_empty(DisasContext *ctx, arg_empty *a,
+ const char *mnemonic)
+{
+ output(ctx, mnemonic, "");
+}
+
+static void output_i_rr(DisasContext *ctx, arg_i_rr *a, const char *mnemonic)
+{
+ output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
+}
+
#define INSN(insn, type) \
static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
{ \
@@ -617,6 +628,13 @@ INSN(iocsrwr_b, rr)
INSN(iocsrwr_h, rr)
INSN(iocsrwr_w, rr)
INSN(iocsrwr_d, rr)
+INSN(tlbsrch, empty)
+INSN(tlbrd, empty)
+INSN(tlbwr, empty)
+INSN(tlbfill, empty)
+INSN(tlbclr, empty)
+INSN(tlbflush, empty)
+INSN(invtlb, i_rr)
#define output_fcmp(C, PREFIX, SUFFIX) \
{ \
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 4664a02dcf..b092ca75fe 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -108,3 +108,16 @@ DEF_HELPER_3(iocsrwr_b, void, env, tl, tl)
DEF_HELPER_3(iocsrwr_h, void, env, tl, tl)
DEF_HELPER_3(iocsrwr_w, void, env, tl, tl)
DEF_HELPER_3(iocsrwr_d, void, env, tl, tl)
+
+/* TLB helper */
+DEF_HELPER_1(tlbwr, void, env)
+DEF_HELPER_1(tlbfill, void, env)
+DEF_HELPER_1(tlbsrch, void, env)
+DEF_HELPER_1(tlbrd, void, env)
+DEF_HELPER_1(tlbclr, void, env)
+DEF_HELPER_1(tlbflush, void, env)
+DEF_HELPER_1(invtlb_all, void, env)
+DEF_HELPER_2(invtlb_all_g, void, env, i32)
+DEF_HELPER_2(invtlb_all_asid, void, env, tl)
+DEF_HELPER_3(invtlb_page_asid, void, env, tl, tl)
+DEF_HELPER_3(invtlb_page_asid_or_g, void, env, tl, tl)
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc
index 8a1c5b8511..0363d1fda4 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -291,3 +291,105 @@ TRANS(iocsrwr_b, gen_iocsrwr, gen_helper_iocsrwr_b)
TRANS(iocsrwr_h, gen_iocsrwr, gen_helper_iocsrwr_h)
TRANS(iocsrwr_w, gen_iocsrwr, gen_helper_iocsrwr_w)
TRANS(iocsrwr_d, gen_iocsrwr, gen_helper_iocsrwr_d)
+
+static void check_mmu_idx(DisasContext *ctx)
+{
+ if (ctx->mem_idx != MMU_DA_IDX) {
+ tcg_gen_exit_tb(NULL, 0);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ }
+}
+
+static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbsrch(cpu_env);
+ return true;
+}
+
+static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbrd(cpu_env);
+ return true;
+}
+
+static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbwr(cpu_env);
+ check_mmu_idx(ctx);
+ return true;
+}
+
+static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbfill(cpu_env);
+ check_mmu_idx(ctx);
+ return true;
+}
+
+static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbclr(cpu_env);
+ check_mmu_idx(ctx);
+ return true;
+}
+
+static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbflush(cpu_env);
+ check_mmu_idx(ctx);
+ return true;
+}
+
+static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)
+{
+ TCGv rj = gpr_src(ctx, a->rj, EXT_NONE);
+ TCGv rk = gpr_src(ctx, a->rk, EXT_NONE);
+
+ if (check_plv(ctx)) {
+ return false;
+ }
+
+ switch (a->imm) {
+ case 0:
+ case 1:
+ gen_helper_invtlb_all(cpu_env);
+ break;
+ case 2:
+ gen_helper_invtlb_all_g(cpu_env, tcg_constant_i32(1));
+ break;
+ case 3:
+ gen_helper_invtlb_all_g(cpu_env, tcg_constant_i32(0));
+ break;
+ case 4:
+ gen_helper_invtlb_all_asid(cpu_env, rj);
+ break;
+ case 5:
+ gen_helper_invtlb_page_asid(cpu_env, rj, rk);
+ break;
+ case 6:
+ gen_helper_invtlb_page_asid_or_g(cpu_env, rj, rk);
+ break;
+ default:
+ return false;
+ }
+ ctx->base.is_jmp = DISAS_STOP;
+ return true;
+}
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 2b436d3cd6..f8ed11d83e 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -47,6 +47,8 @@
&rr_offs rj rd offs
&r_csr rd csr
&rr_csr rd rj csr
+&empty
+&i_rr imm rj rk
#
# Formats
@@ -89,6 +91,8 @@
@rr_offs16 .... .. ................ rj:5 rd:5 &rr_offs offs=%offs16
@r_csr .... .... csr:14 ..... rd:5 &r_csr
@rr_csr .... .... csr:14 rj:5 rd:5 &rr_csr
+@empty .... ........ ..... ..... ..... ..... &empty
+@i_rr ...... ...... ..... rk:5 rj:5 imm:5 &i_rr
#
# Fixed point arithmetic operation instruction
@@ -459,3 +463,10 @@ iocsrwr_b 0000 01100100 10000 00100 ..... ..... @rr
iocsrwr_h 0000 01100100 10000 00101 ..... ..... @rr
iocsrwr_w 0000 01100100 10000 00110 ..... ..... @rr
iocsrwr_d 0000 01100100 10000 00111 ..... ..... @rr
+tlbsrch 0000 01100100 10000 01010 00000 00000 @empty
+tlbrd 0000 01100100 10000 01011 00000 00000 @empty
+tlbwr 0000 01100100 10000 01100 00000 00000 @empty
+tlbfill 0000 01100100 10000 01101 00000 00000 @empty
+tlbclr 0000 01100100 10000 01000 00000 00000 @empty
+tlbflush 0000 01100100 10000 01001 00000 00000 @empty
+invtlb 0000 01100100 10011 ..... ..... ..... @i_rr
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index fad8bc7746..4f84ef3e4b 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -7,9 +7,11 @@
*/
#include "qemu/osdep.h"
+#include "qemu/guest-random.h"
#include "cpu.h"
#include "internals.h"
+#include "exec/helper-proto.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "exec/log.h"
@@ -280,6 +282,359 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
}
}
+static void invalidate_tlb_entry(CPULoongArchState *env, int index)
+{
+ target_ulong addr, mask, pagesize;
+ uint8_t tlb_ps;
+ LoongArchTLB *tlb = &env->tlb[index];
+
+ int mmu_idx = cpu_mmu_index(env, false);
+ uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
+ uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
+ uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
+
+ 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);
+ }
+ pagesize = 1 << tlb_ps;
+ mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
+
+ 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,
+ mmu_idx, TARGET_LONG_BITS);
+ }
+}
+
+static void invalidate_tlb(CPULoongArchState *env, int index)
+{
+ LoongArchTLB *tlb;
+ uint16_t csr_asid, tlb_asid, tlb_g;
+
+ csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
+ tlb = &env->tlb[index];
+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ if (tlb_g == 0 && tlb_asid != csr_asid) {
+ return;
+ }
+ invalidate_tlb_entry(env, index);
+}
+
+static void fill_tlb_entry(CPULoongArchState *env, int index)
+{
+ LoongArchTLB *tlb = &env->tlb[index];
+ uint64_t lo0, lo1, csr_vppn;
+ uint16_t csr_asid;
+ uint8_t csr_ps;
+
+ if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
+ csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
+ csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
+ lo0 = env->CSR_TLBRELO0;
+ lo1 = env->CSR_TLBRELO1;
+ } else {
+ csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
+ csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
+ lo0 = env->CSR_TLBELO0;
+ lo1 = env->CSR_TLBELO1;
+ }
+
+ if (csr_ps == 0) {
+ qemu_log_mask(CPU_LOG_MMU, "page size is 0\n");
+ }
+
+ /* Only MTLB has the ps fields */
+ if (index >= LOONGARCH_STLB) {
+ 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);
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, csr_asid);
+
+ tlb->tlb_entry0 = lo0;
+ tlb->tlb_entry1 = lo1;
+}
+
+/* Return an random value between low and high */
+static uint32_t get_random_tlb(uint32_t low, uint32_t high)
+{
+ uint32_t val;
+
+ qemu_guest_getrandom_nofail(&val, sizeof(val));
+ return val % (high - low + 1) + low;
+}
+
+void helper_tlbsrch(CPULoongArchState *env)
+{
+ int index, match;
+
+ if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
+ match = loongarch_tlb_search(env, env->CSR_TLBREHI, &index);
+ } else {
+ match = loongarch_tlb_search(env, env->CSR_TLBEHI, &index);
+ }
+
+ if (match) {
+ env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX, index);
+ env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0);
+ return;
+ }
+
+ env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1);
+}
+
+void helper_tlbrd(CPULoongArchState *env)
+{
+ LoongArchTLB *tlb;
+ int index;
+ uint8_t tlb_ps, tlb_e;
+
+ 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_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
+
+ if (!tlb_e) {
+ /* Invalid TLB entry */
+ env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1);
+ env->CSR_ASID = FIELD_DP64(env->CSR_ASID, CSR_ASID, ASID, 0);
+ env->CSR_TLBEHI = 0;
+ env->CSR_TLBELO0 = 0;
+ env->CSR_TLBELO1 = 0;
+ env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, PS, 0);
+ } else {
+ /* Valid TLB entry */
+ env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0);
+ env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX,
+ PS, (tlb_ps & 0x3f));
+ env->CSR_TLBEHI = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN) <<
+ R_TLB_MISC_VPPN_SHIFT;
+ env->CSR_TLBELO0 = tlb->tlb_entry0;
+ env->CSR_TLBELO1 = tlb->tlb_entry1;
+ }
+}
+
+void helper_tlbwr(CPULoongArchState *env)
+{
+ int index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
+
+ invalidate_tlb(env, index);
+
+ if (FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, NE)) {
+ env->tlb[index].tlb_misc = FIELD_DP64(env->tlb[index].tlb_misc,
+ TLB_MISC, E, 0);
+ return;
+ }
+
+ fill_tlb_entry(env, index);
+}
+
+void helper_tlbfill(CPULoongArchState *env)
+{
+ uint64_t address, entryhi;
+ int index, set, stlb_idx;
+ uint16_t pagesize, stlb_ps;
+
+ if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
+ entryhi = env->CSR_TLBREHI;
+ pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
+ } else {
+ entryhi = env->CSR_TLBEHI;
+ pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
+ }
+
+ stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
+
+ if (pagesize == stlb_ps) {
+ /* Only write into STLB bits [47:13] */
+ address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
+
+ /* Choose one set ramdomly */
+ set = get_random_tlb(0, 7);
+
+ /* Index in one set */
+ stlb_idx = (address >> (stlb_ps + 1)) & 0xff; /* [0,255] */
+
+ index = set * 256 + stlb_idx;
+ } else {
+ /* Only write into MTLB */
+ index = get_random_tlb(LOONGARCH_STLB, LOONGARCH_TLB_MAX - 1);
+ }
+
+ invalidate_tlb(env, index);
+ fill_tlb_entry(env, index);
+}
+
+void helper_tlbclr(CPULoongArchState *env)
+{
+ LoongArchTLB *tlb;
+ int i, index;
+ uint16_t csr_asid, tlb_asid, tlb_g;
+
+ csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
+ index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
+
+ if (index < LOONGARCH_STLB) {
+ /* STLB. One line per operation */
+ for (i = 0; i < 8; i++) {
+ tlb = &env->tlb[i * 256 + (index % 256)];
+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ if (!tlb_g && tlb_asid == csr_asid) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
+ }
+ }
+ } else if (index < LOONGARCH_TLB_MAX) {
+ /* All MTLB entries */
+ for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; i++) {
+ tlb = &env->tlb[i];
+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ if (!tlb_g && tlb_asid == csr_asid) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
+ }
+ }
+ }
+
+ tlb_flush(env_cpu(env));
+}
+
+void helper_tlbflush(CPULoongArchState *env)
+{
+ int i, index;
+
+ index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
+
+ if (index < LOONGARCH_STLB) {
+ /* STLB. One line per operation */
+ for (i = 0; i < 8; i++) {
+ int s_idx = i * 256 + (index % 256);
+ env->tlb[s_idx].tlb_misc = FIELD_DP64(env->tlb[s_idx].tlb_misc,
+ TLB_MISC, E, 0);
+ }
+ } else if (index < LOONGARCH_TLB_MAX) {
+ /* All MTLB entries */
+ for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; i++) {
+ env->tlb[i].tlb_misc = FIELD_DP64(env->tlb[i].tlb_misc,
+ TLB_MISC, E, 0);
+ }
+ }
+
+ tlb_flush(env_cpu(env));
+}
+
+void helper_invtlb_all(CPULoongArchState *env)
+{
+ for (int i = 0; i < LOONGARCH_TLB_MAX; i++) {
+ env->tlb[i].tlb_misc = FIELD_DP64(env->tlb[i].tlb_misc,
+ TLB_MISC, E, 0);
+ }
+ tlb_flush(env_cpu(env));
+}
+
+void helper_invtlb_all_g(CPULoongArchState *env, uint32_t g)
+{
+ for (int i = 0; i < LOONGARCH_TLB_MAX; i++) {
+ LoongArchTLB *tlb = &env->tlb[i];
+ uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+
+ if (tlb_g == g) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
+ }
+ }
+ tlb_flush(env_cpu(env));
+}
+
+void helper_invtlb_all_asid(CPULoongArchState *env, target_ulong info)
+{
+ uint16_t asid = info & R_CSR_ASID_ASID_MASK;
+
+ for (int i = 0; i < LOONGARCH_TLB_MAX; i++) {
+ LoongArchTLB *tlb = &env->tlb[i];
+ uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+
+ if (!tlb_g && (tlb_asid == asid)) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
+ }
+ }
+ tlb_flush(env_cpu(env));
+}
+
+void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
+ target_ulong addr)
+{
+ uint16_t asid = info & 0x3ff;
+
+ for (int i = 0; i < LOONGARCH_TLB_MAX; i++) {
+ LoongArchTLB *tlb = &env->tlb[i];
+ uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+ uint64_t vpn, tlb_vppn;
+ uint8_t tlb_ps, compare_shift;
+
+ 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_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;
+
+ if (!tlb_g && (tlb_asid == asid) &&
+ (vpn == (tlb_vppn >> compare_shift))) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
+ }
+ }
+ tlb_flush(env_cpu(env));
+}
+
+void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
+ target_ulong info, target_ulong addr)
+{
+ uint16_t asid = info & 0x3ff;
+
+ for (int i = 0; i < LOONGARCH_TLB_MAX; i++) {
+ LoongArchTLB *tlb = &env->tlb[i];
+ uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+ uint64_t vpn, tlb_vppn;
+ uint8_t tlb_ps, compare_shift;
+
+ 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_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;
+
+ if ((tlb_g || (tlb_asid == asid)) &&
+ (vpn == (tlb_vppn >> compare_shift))) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
+ }
+ }
+ tlb_flush(env_cpu(env));
+}
+
bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr)
--
2.31.1
next prev parent reply other threads:[~2022-04-25 9:54 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-25 9:09 [PATCH v2 00/43] Add LoongArch softmmu support Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 01/43] target/loongarch: Add README Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 02/43] target/loongarch: Add core definition Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 03/43] target/loongarch: Add main translation routines Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 04/43] target/loongarch: Add fixed point arithmetic instruction translation Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 05/43] target/loongarch: Add fixed point shift " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 06/43] target/loongarch: Add fixed point bit " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 07/43] target/loongarch: Add fixed point load/store " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 08/43] target/loongarch: Add fixed point atomic " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 09/43] target/loongarch: Add fixed point extra " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 10/43] target/loongarch: Add floating point arithmetic " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 11/43] target/loongarch: Add floating point comparison " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 12/43] target/loongarch: Add floating point conversion " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 13/43] target/loongarch: Add floating point move " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 14/43] target/loongarch: Add floating point load/store " Xiaojuan Yang
2022-04-25 9:09 ` [PATCH v2 15/43] target/loongarch: Add branch " Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 16/43] target/loongarch: Add disassembler Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 17/43] target/loongarch: Add target build suport Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 18/43] target/loongarch: Add system emulation introduction Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 19/43] target/loongarch: Add CSRs definition Xiaojuan Yang
2022-04-25 22:36 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 20/43] target/loongarch: Add basic vmstate description of CPU Xiaojuan Yang
2022-04-25 22:46 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 21/43] target/loongarch: Implement qmp_query_cpu_definitions() Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 22/43] target/loongarch: Add MMU support for LoongArch CPU Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 23/43] target/loongarch: Add LoongArch interrupt and exception handle Xiaojuan Yang
2022-04-25 22:30 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 24/43] target/loongarch: Add constant timer support Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 25/43] target/loongarch: Add LoongArch CSR instruction Xiaojuan Yang
2022-04-25 22:55 ` Richard Henderson
2022-04-26 9:03 ` yangxiaojuan
2022-04-26 14:52 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 26/43] target/loongarch: Add LoongArch IOCSR instruction Xiaojuan Yang
2022-04-27 1:37 ` Richard Henderson
2022-04-25 9:10 ` Xiaojuan Yang [this message]
2022-04-25 9:10 ` [PATCH v2 28/43] target/loongarch: Add other core instructions support Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 29/43] target/loongarch: Add timer related " Xiaojuan Yang
2022-04-26 0:06 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 30/43] hw/loongarch: Add support loongson3 virt machine type Xiaojuan Yang
2022-04-27 1:43 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 31/43] hw/loongarch: Add LoongArch ipi interrupt support(IPI) Xiaojuan Yang
2022-04-27 1:49 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 32/43] hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC) Xiaojuan Yang
2022-04-28 8:15 ` Mark Cave-Ayland
2022-04-25 9:10 ` [PATCH v2 33/43] hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI) Xiaojuan Yang
2022-04-27 2:01 ` Richard Henderson
2022-04-28 7:40 ` Mark Cave-Ayland
2022-04-28 8:16 ` Mark Cave-Ayland
2022-04-25 9:10 ` [PATCH v2 34/43] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC) Xiaojuan Yang
2022-04-25 16:27 ` Mark Cave-Ayland
2022-04-27 10:02 ` yangxiaojuan
2022-04-27 2:07 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 35/43] hw/loongarch: Add irq hierarchy for the system Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 36/43] Enable common virtio pci support for LoongArch Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 37/43] hw/loongarch: Add some devices support for 3A5000 Xiaojuan Yang
2022-04-27 2:21 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 38/43] hw/loongarch: Add LoongArch ls7a rtc device support Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 39/43] hw/loongarch: Add LoongArch load elf function Xiaojuan Yang
2022-04-27 2:23 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 40/43] hw/loongarch: Add LoongArch ls7a acpi device support Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 41/43] target/loongarch: Add gdb support Xiaojuan Yang
2022-04-27 2:24 ` Richard Henderson
2022-04-25 9:10 ` [PATCH v2 42/43] tests/tcg/loongarch64: Add hello/memory test in loongarch64 system Xiaojuan Yang
2022-04-25 9:10 ` [PATCH v2 43/43] target/loongarch: 'make check-tcg' support Xiaojuan Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220425091027.2877892-28-yangxiaojuan@loongson.cn \
--to=yangxiaojuan@loongson.cn \
--cc=gaosong@loongson.cn \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.