From: Xiaojuan Yang <yangxiaojuan@loongson.cn>
To: qemu-devel@nongnu.org
Cc: philmd@redhat.com, mark.cave-ayland@ilande.co.uk,
richard.henderson@linaro.org, Song Gao <gaosong@loongson.cn>
Subject: [RFC PATCH v4 09/30] target/loongarch: Add TLB instruction support
Date: Sat, 8 Jan 2022 04:13:58 -0500 [thread overview]
Message-ID: <20220108091419.2027710-10-yangxiaojuan@loongson.cn> (raw)
In-Reply-To: <20220108091419.2027710-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>
---
target/loongarch/disas.c | 17 +
target/loongarch/helper.h | 12 +
target/loongarch/insn_trans/trans_core.c.inc | 112 ++++++
target/loongarch/insns.decode | 11 +
target/loongarch/tlb_helper.c | 364 +++++++++++++++++++
5 files changed, 516 insertions(+)
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index cbb264a318..483270f331 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -216,6 +216,16 @@ static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a,
output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->csr);
}
+static void output_empty(DisasContext *ctx, arg_empty *a,
+ const char *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) \
{ \
@@ -539,6 +549,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 1bcd082858..97af7ac8aa 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -100,4 +100,16 @@ DEF_HELPER_3(csr_wrq, i64, env, tl, i64)
DEF_HELPER_4(csr_xchgq, i64, env, tl, tl, i64)
DEF_HELPER_3(iocsr_read, i64, env, tl, i32)
DEF_HELPER_4(iocsr_write, void, env, tl, tl, i32)
+
+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)
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c.inc b/target/loongarch/insn_trans/trans_core.c.inc
index 592d2a339e..5a8e9e0643 100644
--- a/target/loongarch/insn_trans/trans_core.c.inc
+++ b/target/loongarch/insn_trans/trans_core.c.inc
@@ -28,6 +28,13 @@ GEN_FALSE_TRANS(iocsrwr_b)
GEN_FALSE_TRANS(iocsrwr_h)
GEN_FALSE_TRANS(iocsrwr_w)
GEN_FALSE_TRANS(iocsrwr_d)
+GEN_FALSE_TRANS(tlbsrch)
+GEN_FALSE_TRANS(tlbrd)
+GEN_FALSE_TRANS(tlbwr)
+GEN_FALSE_TRANS(tlbfill)
+GEN_FALSE_TRANS(tlbclr)
+GEN_FALSE_TRANS(tlbflush)
+GEN_FALSE_TRANS(invtlb)
#else
@@ -223,4 +230,109 @@ static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a)
gen_helper_iocsr_write(cpu_env, addr, val, tcg_constant_i32(8));
return true;
}
+
+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);
+
+ if (ctx->mem_idx != MMU_DA_IDX) {
+ tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ ctx->base.is_jmp = DISAS_EXIT;
+ }
+ return true;
+}
+
+static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbfill(cpu_env);
+
+ if (ctx->mem_idx != MMU_DA_IDX) {
+ tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ ctx->base.is_jmp = DISAS_EXIT;
+ }
+ return true;
+}
+
+static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbclr(cpu_env);
+ tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ ctx->base.is_jmp = DISAS_EXIT;
+ return true;
+}
+
+static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a)
+{
+ if (check_plv(ctx)) {
+ return false;
+ }
+ gen_helper_tlbflush(cpu_env);
+ tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ ctx->base.is_jmp = DISAS_EXIT;
+ 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;
+}
+
#endif
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 9a43f288c3..6f2a814195 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
@@ -462,3 +466,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 ff72ac4eaf..53dd70de17 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"
@@ -281,6 +283,368 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
}
}
+static void cpu_loongarch_tlb_flush(CPULoongArchState *env)
+{
+ /* Flush qemu's TLB and discard all shadowed entries. */
+ tlb_flush(env_cpu(env));
+}
+
+static void loongarch_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 loongarch_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;
+ }
+ loongarch_invalidate_tlb_entry(env, index);
+}
+
+static void loongarch_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 random value in [low, high] */
+static uint32_t cpu_loongarch_get_random_loongarch_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);
+
+ loongarch_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;
+ }
+
+ loongarch_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 bit [47:13] */
+ address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
+
+ /* Choose one set ramdomly */
+ set = cpu_loongarch_get_random_loongarch_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 = cpu_loongarch_get_random_loongarch_tlb(
+ LOONGARCH_STLB, LOONGARCH_TLB_MAX - 1);
+ }
+
+ loongarch_invalidate_tlb(env, index);
+ loongarch_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) {
+ /* MTLB. All 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);
+ }
+ }
+ }
+
+ cpu_loongarch_tlb_flush(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 index = i * 256 + (index % 256);
+ env->tlb[index].tlb_misc = FIELD_DP64(env->tlb[index].tlb_misc,
+ TLB_MISC, E, 0);
+ }
+ } else if (index < LOONGARCH_TLB_MAX) {
+ /* MTLB. All 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);
+ }
+ }
+
+ cpu_loongarch_tlb_flush(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);
+ }
+ cpu_loongarch_tlb_flush(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);
+ }
+ }
+ cpu_loongarch_tlb_flush(env);
+}
+
+void helper_invtlb_all_asid(CPULoongArchState *env, target_ulong info)
+{
+ 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);
+
+ if (!tlb_g && (tlb_asid == asid)) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
+ }
+ }
+ cpu_loongarch_tlb_flush(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);
+ }
+ }
+ cpu_loongarch_tlb_flush(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);
+ }
+ }
+ cpu_loongarch_tlb_flush(env);
+}
+
void loongarch_mmu_init(CPULoongArchState *env)
{
/* For 16KB, ps = 14, compare the bit [47:15] */
--
2.27.0
next prev parent reply other threads:[~2022-01-08 9:16 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-08 9:13 [RFC PATCH v4 00/30] Add LoongArch softmmu support Xiaojuan Yang
2022-01-08 9:13 ` [RFC PATCH v4 01/30] target/loongarch: Update README Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-15 12:42 ` Mark Cave-Ayland
2022-01-08 9:13 ` [RFC PATCH v4 02/30] target/loongarch: Add CSR registers definition Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-08 9:13 ` [RFC PATCH v4 03/30] target/loongarch: Add basic vmstate description of CPU Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-15 12:52 ` Mark Cave-Ayland
2022-01-27 10:01 ` yangxiaojuan
2022-01-08 9:13 ` [RFC PATCH v4 04/30] target/loongarch: Implement qmp_query_cpu_definitions() Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-08 9:13 ` [RFC PATCH v4 05/30] target/loongarch: Add constant timer support Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-15 13:02 ` Mark Cave-Ayland
2022-01-08 9:13 ` [RFC PATCH v4 06/30] target/loongarch: Add MMU support for LoongArch CPU Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-08 9:13 ` [RFC PATCH v4 07/30] target/loongarch: Add LoongArch CSR instruction Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-08 9:13 ` [RFC PATCH v4 08/30] target/loongarch: Add LoongArch IOCSR instruction Xiaojuan Yang
2022-01-09 9:25 ` WANG Xuerui
2022-01-08 9:13 ` Xiaojuan Yang [this message]
2022-01-09 9:26 ` [RFC PATCH v4 09/30] target/loongarch: Add TLB instruction support WANG Xuerui
2022-01-08 9:13 ` [RFC PATCH v4 10/30] target/loongarch: Add other core instructions support Xiaojuan Yang
2022-01-09 9:26 ` WANG Xuerui
2022-01-08 9:14 ` [RFC PATCH v4 11/30] target/loongarch: Add LoongArch interrupt and exception handle Xiaojuan Yang
2022-01-09 9:26 ` WANG Xuerui
2022-01-08 9:14 ` [RFC PATCH v4 12/30] target/loongarch: Add timer related instructions support Xiaojuan Yang
2022-01-09 9:26 ` WANG Xuerui
2022-01-08 9:14 ` [RFC PATCH v4 13/30] target/loongarch: Add gdb support Xiaojuan Yang
2022-01-09 9:26 ` WANG Xuerui
2022-01-08 9:14 ` [RFC PATCH v4 14/30] hw/pci-host: Add ls7a1000 PCIe Host bridge support for Loongson3 Platform Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 15/30] hw/loongarch: Add support loongson3-ls7a machine type Xiaojuan Yang
2022-01-15 13:35 ` Mark Cave-Ayland
2022-01-08 9:14 ` [RFC PATCH v4 16/30] hw/loongarch: Add LoongArch cpu interrupt support(CPUINTC) Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 17/30] hw/loongarch: Add LoongArch ipi interrupt support(IPI) Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 18/30] hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC) Xiaojuan Yang
2022-01-15 13:41 ` Mark Cave-Ayland
2022-01-08 9:14 ` [RFC PATCH v4 19/30] hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI) Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 20/30] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC) Xiaojuan Yang
2022-01-15 13:49 ` Mark Cave-Ayland
2022-01-08 9:14 ` [RFC PATCH v4 21/30] hw/loongarch: Add irq hierarchy for the system Xiaojuan Yang
2022-01-15 14:00 ` Mark Cave-Ayland
2022-01-08 9:14 ` [RFC PATCH v4 22/30] Enable common virtio pci support for LoongArch Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 23/30] hw/loongarch: Add some devices support for 3A5000 Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 24/30] hw/loongarch: Add LoongArch ls7a rtc device support Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 25/30] hw/loongarch: Add default bios startup support Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 26/30] hw/loongarch: Add -kernel and -initrd options support Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 27/30] hw/loongarch: Add LoongArch smbios support Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 28/30] hw/loongarch: Add LoongArch acpi support Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 29/30] hw/loongarch: Add fdt support Xiaojuan Yang
2022-01-08 9:14 ` [RFC PATCH v4 30/30] tests/tcg/loongarch64: Add hello/memory test in loongarch64 system Xiaojuan Yang
2022-01-09 9:26 ` [RFC PATCH v4 00/30] Add LoongArch softmmu support WANG Xuerui
2022-01-10 2:42 ` yangxiaojuan
2022-01-15 14:11 ` Mark Cave-Ayland
2022-01-17 1:49 ` yangxiaojuan
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=20220108091419.2027710-10-yangxiaojuan@loongson.cn \
--to=yangxiaojuan@loongson.cn \
--cc=gaosong@loongson.cn \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=philmd@redhat.com \
--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.