All of lore.kernel.org
 help / color / mirror / Atom feed
From: Xiaojuan Yang <yangxiaojuan@loongson.cn>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, thuth@redhat.com,
	chenhuacai@loongson.cn, mst@redhat.com, philmd@redhat.com,
	richard.henderson@linaro.org, laurent@vivier.eu,
	peterx@redhat.com, f4bug@amsat.org, yangxiaojuan@loongson.cn,
	alistair.francis@wdc.com, maobibo@loongson.cn,
	gaosong@loongson.cn, pbonzini@redhat.com,
	mark.cave-ayland@ilande.co.uk, bmeng.cn@gmail.com,
	alex.bennee@linaro.org, david@gibson.dropbear.id.au
Subject: [PATCH 09/31] target/loongarch: Add other core instructions support
Date: Tue, 19 Oct 2021 15:34:55 +0800	[thread overview]
Message-ID: <1634628917-10031-10-git-send-email-yangxiaojuan@loongson.cn> (raw)
In-Reply-To: <1634628917-10031-1-git-send-email-yangxiaojuan@loongson.cn>

This includes:
-CACOP
-LDDIR
-LDPTE
-ERTN
-DBCL
-IDLE

Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 target/loongarch/cpu.c                   |  1 +
 target/loongarch/cpu.h                   |  5 +-
 target/loongarch/helper.h                |  4 ++
 target/loongarch/insn_trans/trans_core.c | 57 ++++++++++++++++
 target/loongarch/insns.decode            | 15 +++++
 target/loongarch/op_helper.c             | 48 ++++++++++++++
 target/loongarch/tlb_helper.c            | 83 ++++++++++++++++++++++++
 7 files changed, 212 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index afd186abac..7fa3851251 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -45,6 +45,7 @@ static const char * const excp_names[EXCP_LAST + 1] = {
     [EXCP_TLBPE] = "TLB priviledged error",
     [EXCP_TLBNX] = "TLB execute-inhibit",
     [EXCP_TLBNR] = "TLB read-inhibit",
+    [EXCP_DBP] = "debug breakpoint",
 };
 
 const char *loongarch_exception_name(int32_t exception)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 567fc7620d..d39c618d6b 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -166,10 +166,13 @@ enum {
     EXCP_TLBPE,
     EXCP_TLBNX,
     EXCP_TLBNR,
+    EXCP_DBP,
 
-    EXCP_LAST = EXCP_TLBNR,
+    EXCP_LAST = EXCP_DBP,
 };
 
+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
+
 #define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
 #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
 #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 1bb1df91b3..8544771790 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -112,4 +112,8 @@ DEF_HELPER_1(tlbflush, void, env)
 DEF_HELPER_4(invtlb, void, env, tl, tl, tl)
 DEF_HELPER_2(iocsr_read, i64, env, tl)
 DEF_HELPER_4(iocsr_write, void, env, tl, tl, i32)
+DEF_HELPER_4(lddir, tl, env, tl, tl, i32)
+DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
+DEF_HELPER_1(ertn, void, env)
+DEF_HELPER_1(idle, void, env)
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/insn_trans/trans_core.c b/target/loongarch/insn_trans/trans_core.c
index f8a72436dd..7fa13e65b9 100644
--- a/target/loongarch/insn_trans/trans_core.c
+++ b/target/loongarch/insn_trans/trans_core.c
@@ -34,6 +34,12 @@ GEN_FALSE_TRANS(tlbfill)
 GEN_FALSE_TRANS(tlbclr)
 GEN_FALSE_TRANS(tlbflush)
 GEN_FALSE_TRANS(invtlb)
+GEN_FALSE_TRANS(cacop)
+GEN_FALSE_TRANS(ldpte)
+GEN_FALSE_TRANS(lddir)
+GEN_FALSE_TRANS(ertn)
+GEN_FALSE_TRANS(dbcl)
+GEN_FALSE_TRANS(idle)
 
 #else
 static bool trans_csrrd(DisasContext *ctx, unsigned rd, unsigned csr)
@@ -173,6 +179,11 @@ static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a)
     return true;
 }
 
+static bool trans_cacop(DisasContext *ctx, arg_cacop *a)
+{
+    return false;
+}
+
 static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a)
 {
     gen_helper_tlbsrch(cpu_env);
@@ -219,4 +230,50 @@ static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)
     return true;
 }
 
+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a)
+{
+    TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+    TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+    gen_helper_ldpte(cpu_env, src1, tcg_constant_tl(a->seq), mem_idx);
+    return true;
+}
+
+static bool trans_lddir(DisasContext *ctx, arg_lddir *a)
+{
+    TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+    TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
+    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+    gen_helper_lddir(dest, cpu_env, src, tcg_constant_tl(a->level), mem_idx);
+    return true;
+}
+
+static bool trans_ertn(DisasContext *ctx, arg_ertn *a)
+{
+    gen_helper_ertn(cpu_env);
+    ctx->base.is_jmp = DISAS_EXIT;
+    return true;
+}
+
+static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a)
+{
+    /*
+     * XXX: not clear which exception should be raised
+     *      when in debug mode...
+     */
+    generate_exception(ctx, EXCP_DBP);
+    return true;
+}
+
+static bool trans_idle(DisasContext *ctx, arg_idle *a)
+{
+    ctx->base.pc_next += 4;
+    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+    ctx->base.pc_next -= 4;
+    gen_helper_idle(cpu_env);
+    ctx->base.is_jmp = DISAS_NORETURN;
+    return true;
+}
+
 #endif
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index aa40ecfca7..2b18b27c88 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -42,9 +42,12 @@
 %offs16  10:s16
 %offs    0:s10 10:16
 %csr     10:14
+%cop     0:5
 %addr    10:5
 %info    5:5
 %invop   0:5
+%level   10:8
+%seq     10:8
 
 #
 # Argument sets
@@ -87,8 +90,11 @@
 &fmt_offs           offs
 &fmt_rjrdoffs16     rj rd offs16
 &fmt_rdrjcsr        rd rj csr
+&fmt_coprjsi12      cop rj si12
 &fmt_empty
 &fmt_invtlb         addr info invop
+&fmt_rdrjlevel      rd rj level
+&fmt_rjseq          rj seq
 
 #
 # Formats
@@ -131,8 +137,11 @@
 @fmt_offs            .... .. ..........................       &fmt_offs           %offs
 @fmt_rjrdoffs16      .... .. ................ ..... .....     &fmt_rjrdoffs16     %rj %rd %offs16
 @fmt_rdrjcsr         .... .... .............. ..... .....     &fmt_rdrjcsr        %rd %rj %csr
+@fmt_coprjsi12       .... ...... ............ ..... .....     &fmt_coprjsi12      %cop %rj %si12
 @fmt_empty           .... ........ ..... ..... ..... .....    &fmt_empty
 @fmt_invtlb          ...... ...... ..... ..... ..... .....    &fmt_invtlb         %addr %info %invop
+@fmt_rdrjlevel       .... ........ .. ........ ..... .....    &fmt_rdrjlevel      %rd %rj %level
+@fmt_rjseq           .... ........ .. ........ ..... .....    &fmt_rjseq          %rj %seq
 
 #
 # Fixed point arithmetic operation instruction
@@ -501,6 +510,7 @@ iocsrwr_b        0000 01100100 10000 00100 ..... .....    @fmt_rdrj
 iocsrwr_h        0000 01100100 10000 00101 ..... .....    @fmt_rdrj
 iocsrwr_w        0000 01100100 10000 00110 ..... .....    @fmt_rdrj
 iocsrwr_d        0000 01100100 10000 00111 ..... .....    @fmt_rdrj
+cacop            0000 011000 ............ ..... .....     @fmt_coprjsi12
 tlbsrch          0000 01100100 10000 01010 00000 00000    @fmt_empty
 tlbrd            0000 01100100 10000 01011 00000 00000    @fmt_empty
 tlbwr            0000 01100100 10000 01100 00000 00000    @fmt_empty
@@ -508,3 +518,8 @@ tlbfill          0000 01100100 10000 01101 00000 00000    @fmt_empty
 tlbclr           0000 01100100 10000 01000 00000 00000    @fmt_empty
 tlbflush         0000 01100100 10000 01001 00000 00000    @fmt_empty
 invtlb           0000 01100100 10011 ..... ..... .....    @fmt_invtlb
+lddir            0000 01100100 00 ........ ..... .....    @fmt_rdrjlevel
+ldpte            0000 01100100 01 ........ ..... 00000    @fmt_rjseq
+ertn             0000 01100100 10000 01110 00000 00000    @fmt_empty
+idle             0000 01100100 10001 ...............      @fmt_whint
+dbcl             0000 00000010 10101 ...............      @fmt_code
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
index c560a9be26..4547880c8f 100644
--- a/target/loongarch/op_helper.c
+++ b/target/loongarch/op_helper.c
@@ -83,3 +83,51 @@ target_ulong helper_cpucfg(CPULoongArchState *env, target_ulong rj)
 {
     return env->cpucfg[rj];
 }
+
+#ifndef CONFIG_USER_ONLY
+static inline void exception_return(CPULoongArchState *env)
+{
+    if (env->CSR_TLBRERA & 0x1) {
+        env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV,
+                                   FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV));
+        env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE,
+                                   FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE));
+        /* Clear Refill flag and set pc */
+        env->CSR_TLBRERA &= (~0x1);
+        env->pc = env->CSR_TLBRERA;
+        if (qemu_loglevel_mask(CPU_LOG_INT)) {
+            qemu_log("%s: TLBRERA 0x%lx\n", __func__, env->CSR_TLBRERA);
+        }
+    } else {
+        env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV,
+                                   FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PPLV));
+        env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE,
+                                   FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PIE));
+        /* set pc*/
+        env->pc = env->CSR_ERA;
+        if (qemu_loglevel_mask(CPU_LOG_INT)) {
+            qemu_log("%s: ERA 0x%lx\n", __func__, env->CSR_ERA);
+        }
+    }
+}
+
+void helper_ertn(CPULoongArchState *env)
+{
+    exception_return(env);
+    env->lladdr = 1;
+}
+
+void helper_idle(CPULoongArchState *env)
+{
+    CPUState *cs = env_cpu(env);
+
+    cs->halted = 1;
+    cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
+    /*
+     * Last instruction in the block, PC was updated before
+     * - no need to recover PC and icount
+     */
+    do_raise_exception(env, EXCP_HLT, 0);
+}
+
+#endif /* !CONFIG_USER_ONLY */
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index fd844d5a46..1eea4e1dc4 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -833,3 +833,86 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         do_raise_exception(env, cs->exception_index, retaddr);
     }
 }
+
+target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
+                          target_ulong level, uint32_t mem_idx)
+{
+    target_ulong badvaddr;
+    target_ulong index;
+    target_ulong vaddr;
+    int shift;
+    uint64_t dir1_base, dir1_width;
+    uint64_t dir3_base, dir3_width;
+
+    badvaddr = env->CSR_TLBRBADV;
+
+    /* 0:8B, 1:16B, 2:32B, 3:64B */
+    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
+    shift = (shift + 1) * 3;
+
+    switch (level) {
+    case 1:
+        dir1_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE);
+        dir1_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH);
+        index = (badvaddr >> dir1_base) & ((1 << dir1_width) - 1);
+        break;
+    case 3:
+        dir3_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE);
+        dir3_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH);
+        index = (badvaddr >> dir3_base) & ((1 << dir3_width) - 1);
+        break;
+    default:
+        do_raise_exception(env, EXCP_INE, GETPC());
+        return 0;
+    }
+
+    vaddr = base | index << shift;
+    return cpu_ldq_mmuidx_ra(env, vaddr, mem_idx, GETPC());
+}
+
+void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
+                  uint32_t mem_idx)
+{
+    target_ulong vaddr;
+    target_ulong tmp0;
+    target_ulong ptindex, ptoffset0, ptoffset1;
+    target_ulong pagesize;
+    target_ulong badv;
+    int shift;
+    bool huge = base & LOONGARCH_PAGE_HUGE;
+    uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE);
+    uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH);
+
+    if (huge) {
+        /* Huge Page. base is paddr */
+        tmp0 = base ^ LOONGARCH_PAGE_HUGE;
+        /* move Global bit */
+        tmp0 |= ((tmp0 & LOONGARCH_HUGE_GLOBAL)
+                 >> (LOONGARCH_HUGE_GLOBAL_SH - R_CSR_TLBELO0_G_SHIFT));
+        pagesize = ptbase + ptwidth - 1;
+        if (odd) {
+            tmp0 += (1 << pagesize);
+        }
+    } else {
+        /* 0:8B, 1:16B, 2:32B, 3:64B */
+        shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
+        shift = (shift + 1) * 3;
+        badv = env->CSR_TLBRBADV;
+
+        ptindex = (badv >> ptbase) & ((1 << ptwidth) - 1);
+        ptindex = ptindex & ~0x1;   /* clear bit 0 */
+        ptoffset0 = ptindex << shift;
+        ptoffset1 = (ptindex + 1) << shift;
+
+        vaddr = base | (odd ? ptoffset1 : ptoffset0);
+        tmp0 = cpu_ldq_mmuidx_ra(env, vaddr, mem_idx, GETPC());
+        pagesize = ptbase;
+    }
+    if (odd) {
+        env->CSR_TLBRELO1 = tmp0;
+    } else {
+        env->CSR_TLBRELO0 = tmp0;
+    }
+    env->CSR_TLBREHI = env->CSR_TLBREHI & (~0x3f);
+    env->CSR_TLBREHI = env->CSR_TLBREHI | pagesize;
+}
-- 
2.27.0



  parent reply	other threads:[~2021-10-19  7:43 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-19  7:34 [PATCH 00/31] Add Loongarch softmmu support Xiaojuan Yang
2021-10-19  7:34 ` [PATCH 02/31] target/loongarch: Add CSR registers definition Xiaojuan Yang
2021-10-19 19:10   ` Richard Henderson
2021-10-19  7:34 ` [PATCH 03/31] target/loongarch: Set default csr values Xiaojuan Yang
2021-10-19 19:18   ` Richard Henderson
2021-10-19  7:34 ` [PATCH 04/31] target/loongarch: Add basic vmstate description of CPU Xiaojuan Yang
2021-10-19 19:35   ` Richard Henderson
2021-10-19  7:34 ` [PATCH 05/31] target/loongarch: Implement qmp_query_cpu_definitions() Xiaojuan Yang
2021-10-19 20:25   ` Richard Henderson
2021-10-19  7:34 ` [PATCH 08/31] target/loongarch: Add tlb instruction support Xiaojuan Yang
2021-10-20  4:19   ` Richard Henderson
2021-10-29  7:01     ` yangxiaojuan
2021-10-29 17:48       ` Richard Henderson
2021-10-19  7:34 ` Xiaojuan Yang [this message]
2021-10-20  4:45   ` [PATCH 09/31] target/loongarch: Add other core instructions support Richard Henderson
2021-10-19  7:34 ` [PATCH 10/31] target/loongarch: Add loongarch interrupt and exception handle Xiaojuan Yang
2021-10-20  4:59   ` Richard Henderson
2021-10-19  7:34 ` [PATCH 11/31] target/loongarch: Add stabletimer support Xiaojuan Yang
2021-10-19  7:34 ` [PATCH 12/31] target/loongarch: Add timer related instructions support Xiaojuan Yang
2021-10-20  5:17   ` Richard Henderson
2021-10-19  7:34 ` [PATCH 13/31] hw/pci-host: Add ls7a1000 PCIe Host bridge support for Loongson Platform Xiaojuan Yang
2021-10-19  7:35 ` [PATCH 14/31] hw/loongarch: Add a virt loongarch 3A5000 board support Xiaojuan Yang
2021-10-19  7:35 ` [PATCH 15/31] hw/loongarch: Add loongarch cpu interrupt support(CPUINTC) Xiaojuan Yang
2021-10-19  7:35 ` [PATCH 16/31] hw/loongarch: Add loongarch ipi interrupt support(IPI) Xiaojuan Yang
2021-10-19  7:35 ` [PATCH 17/31] hw/intc: Add loongarch ls7a interrupt controller support(PCH-PIC) Xiaojuan Yang
2021-10-19  7:35 ` [PATCH 18/31] hw/intc: Add loongarch ls7a msi interrupt controller support(PCH-MSI) Xiaojuan Yang
2021-10-19  7:35 ` [PATCH 19/31] hw/intc: Add loongarch extioi interrupt controller(EIOINTC) Xiaojuan Yang
2021-10-19  7:35 ` [PATCH 20/31] hw/loongarch: Add irq hierarchy for the system Xiaojuan Yang
2021-10-19 14:52 ` [PATCH 00/31] Add Loongarch softmmu support WANG Xuerui
     [not found]   ` <7d933f8d.228e.17c9b556e98.Coremail.yangxiaojuan@loongson.cn>
2021-10-20  5:11     ` WANG Xuerui
     [not found] ` <1634628917-10031-24-git-send-email-yangxiaojuan@loongson.cn>
2021-10-19 16:19   ` [PATCH 23/31] hw/loongarch: Add default bios startup support Michael S. Tsirkin
     [not found] ` <1634628917-10031-2-git-send-email-yangxiaojuan@loongson.cn>
2021-10-19 18:56   ` [PATCH 01/31] target/loongarch: Upate the README for the softmmu Richard Henderson
2021-10-22  2:25     ` yangxiaojuan
     [not found] ` <1634628917-10031-7-git-send-email-yangxiaojuan@loongson.cn>
2021-10-19 21:11   ` [PATCH 06/31] target/loongarch: Add mmu support for Loongarch CPU Richard Henderson
     [not found] ` <1634628917-10031-8-git-send-email-yangxiaojuan@loongson.cn>
2021-10-20  1:36   ` [PATCH 07/31] target/loongarch: Add loongarch csr/iocsr instruction support Richard Henderson
2021-10-29  6:26     ` yangxiaojuan
2021-10-29 17:38       ` Richard Henderson

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=1634628917-10031-10-git-send-email-yangxiaojuan@loongson.cn \
    --to=yangxiaojuan@loongson.cn \
    --cc=alex.bennee@linaro.org \
    --cc=alistair.francis@wdc.com \
    --cc=bmeng.cn@gmail.com \
    --cc=chenhuacai@loongson.cn \
    --cc=david@gibson.dropbear.id.au \
    --cc=f4bug@amsat.org \
    --cc=gaosong@loongson.cn \
    --cc=laurent@vivier.eu \
    --cc=maobibo@loongson.cn \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=peterx@redhat.com \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=thuth@redhat.com \
    /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.