diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-24 10:02:01 -0500 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-24 10:02:01 -0500 |
commit | 8f9cb50fe6bb15be72e1af4c7676969556d600da (patch) | |
tree | e683a9a219be6b2a5646720b34df395141c2c491 | |
parent | cf86770c7aa31ebd6e56f4eeb25c34107f92c51e (diff) | |
parent | 3215fe8528de45a1794f0314623cc10bd8e8e19f (diff) | |
download | qemu-8f9cb50fe6bb15be72e1af4c7676969556d600da.zip qemu-8f9cb50fe6bb15be72e1af4c7676969556d600da.tar.gz qemu-8f9cb50fe6bb15be72e1af4c7676969556d600da.tar.bz2 |
Merge tag 'pull-loongarch-20250124' of https://gitlab.com/bibo-mao/qemu into staging
loongarch queue
# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQQNhkKjomWfgLCz0aQfewwSUazn0QUCZ5M4AwAKCRAfewwSUazn
# 0aJAAP45/9qfbGSYiMCrBXpRFlyvtRN+GEXHEsERfk9Q1V+tQgEA/mMiUEcyc/xc
# Z1Z27cDoqUFRhPmxbd6/KyTGHzo2+As=
# =Zanw
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 24 Jan 2025 01:49:39 EST
# gpg: using EDDSA key 0D8642A3A2659F80B0B3D1A41F7B0C1251ACE7D1
# gpg: Good signature from "bibo mao <maobibo@loongson.cn>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 7044 3A00 19C0 E97A 31C7 13C4 8E86 8FB7 A176 9D4C
# Subkey fingerprint: 0D86 42A3 A265 9F80 B0B3 D1A4 1F7B 0C12 51AC E7D1
* tag 'pull-loongarch-20250124' of https://gitlab.com/bibo-mao/qemu:
target/loongarch: Dump all generic CSR registers
target/loongarch: Set unused flag with CSR registers
target/loongarch: Add common source file for CSR register
target/loongarch: Add common header file for CSR registers
target/loongarch: Add generic csr function type
target/loongarch: Remove static CSR function setting
target/loongarch: Add dynamic function access with CSR register
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | target/loongarch/cpu.c | 96 | ||||
-rw-r--r-- | target/loongarch/csr.c | 129 | ||||
-rw-r--r-- | target/loongarch/csr.h | 29 | ||||
-rw-r--r-- | target/loongarch/meson.build | 1 | ||||
-rw-r--r-- | target/loongarch/tcg/insn_trans/trans_privileged.c.inc | 161 | ||||
-rw-r--r-- | target/loongarch/tcg/tcg_loongarch.h | 12 | ||||
-rw-r--r-- | target/loongarch/tcg/translate.c | 5 |
7 files changed, 294 insertions, 139 deletions
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index d611a60..e91f4a5 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -19,7 +19,7 @@ #include "cpu.h" #include "internals.h" #include "fpu/softfloat-helpers.h" -#include "cpu-csr.h" +#include "csr.h" #ifndef CONFIG_USER_ONLY #include "system/reset.h" #endif @@ -375,6 +375,33 @@ static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch) return MMU_DA_IDX; } +static void loongarch_la464_init_csr(Object *obj) +{ +#ifndef CONFIG_USER_ONLY + static bool initialized; + LoongArchCPU *cpu = LOONGARCH_CPU(obj); + CPULoongArchState *env = &cpu->env; + int i, num; + + if (!initialized) { + initialized = true; + num = FIELD_EX64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM); + for (i = num; i < 16; i++) { + set_csr_flag(LOONGARCH_CSR_SAVE(i), CSRFL_UNUSED); + } + set_csr_flag(LOONGARCH_CSR_IMPCTL1, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_IMPCTL2, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_MERRCTL, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_MERRINFO1, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_MERRINFO2, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_MERRENTRY, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_MERRERA, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_MERRSAVE, CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_CTAG, CSRFL_UNUSED); + } +#endif +} + static void loongarch_la464_initfn(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); @@ -470,6 +497,7 @@ static void loongarch_la464_initfn(Object *obj) env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); + loongarch_la464_init_csr(obj); loongarch_cpu_post_init(obj); } @@ -765,6 +793,54 @@ static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model) return oc; } +static void loongarch_cpu_dump_csr(CPUState *cs, FILE *f) +{ +#ifndef CONFIG_USER_ONLY + CPULoongArchState *env = cpu_env(cs); + CSRInfo *csr_info; + int64_t *addr; + int i, j, len, col = 0; + + qemu_fprintf(f, "\n"); + + /* Dump all generic CSR register */ + for (i = 0; i < LOONGARCH_CSR_DBG; i++) { + csr_info = get_csr(i); + if (!csr_info || (csr_info->flags & CSRFL_UNUSED)) { + if (i == (col + 3)) { + qemu_fprintf(f, "\n"); + } + + continue; + } + + if ((i > (col + 3)) || (i == col)) { + col = i & ~3; + qemu_fprintf(f, " CSR%03d:", col); + } + + addr = (void *)env + csr_info->offset; + qemu_fprintf(f, " %s ", csr_info->name); + len = strlen(csr_info->name); + for (; len < 6; len++) { + qemu_fprintf(f, " "); + } + + qemu_fprintf(f, "%" PRIx64, *addr); + j = find_last_bit((void *)addr, BITS_PER_LONG) & (BITS_PER_LONG - 1); + len += j / 4 + 1; + for (; len < 22; len++) { + qemu_fprintf(f, " "); + } + + if (i == (col + 3)) { + qemu_fprintf(f, "\n"); + } + } + qemu_fprintf(f, "\n"); +#endif +} + static void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) { CPULoongArchState *env = cpu_env(cs); @@ -784,22 +860,8 @@ static void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) } } - qemu_fprintf(f, "CRMD=%016" PRIx64 "\n", env->CSR_CRMD); - qemu_fprintf(f, "PRMD=%016" PRIx64 "\n", env->CSR_PRMD); - qemu_fprintf(f, "EUEN=%016" PRIx64 "\n", env->CSR_EUEN); - qemu_fprintf(f, "ESTAT=%016" PRIx64 "\n", env->CSR_ESTAT); - qemu_fprintf(f, "ERA=%016" PRIx64 "\n", env->CSR_ERA); - qemu_fprintf(f, "BADV=%016" PRIx64 "\n", env->CSR_BADV); - qemu_fprintf(f, "BADI=%016" PRIx64 "\n", env->CSR_BADI); - qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY); - qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 "," - " PRCFG3=%016" PRIx64 "\n", - env->CSR_PRCFG1, env->CSR_PRCFG2, env->CSR_PRCFG3); - qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY); - qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV); - qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA); - qemu_fprintf(f, "TCFG=%016" PRIx64 "\n", env->CSR_TCFG); - qemu_fprintf(f, "TVAL=%016" PRIx64 "\n", env->CSR_TVAL); + /* csr */ + loongarch_cpu_dump_csr(cs, f); /* fpr */ if (flags & CPU_DUMP_FPU) { diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c new file mode 100644 index 0000000..7ea0a30 --- /dev/null +++ b/target/loongarch/csr.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2025 Loongson Technology Corporation Limited + */ +#include <stddef.h> +#include "qemu/osdep.h" +#include "cpu.h" +#include "csr.h" + +#define CSR_OFF_FUNCS(NAME, FL, RD, WR) \ + [LOONGARCH_CSR_##NAME] = { \ + .name = (stringify(NAME)), \ + .offset = offsetof(CPULoongArchState, CSR_##NAME), \ + .flags = FL, .readfn = RD, .writefn = WR \ + } + +#define CSR_OFF_ARRAY(NAME, N) \ + [LOONGARCH_CSR_##NAME(N)] = { \ + .name = (stringify(NAME##N)), \ + .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ + .flags = 0, .readfn = NULL, .writefn = NULL \ + } + +#define CSR_OFF_FLAGS(NAME, FL) CSR_OFF_FUNCS(NAME, FL, NULL, NULL) +#define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, 0) + +static CSRInfo csr_info[] = { + CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), + CSR_OFF(PRMD), + CSR_OFF_FLAGS(EUEN, CSRFL_EXITTB), + CSR_OFF_FLAGS(MISC, CSRFL_READONLY), + CSR_OFF(ECFG), + CSR_OFF_FLAGS(ESTAT, CSRFL_EXITTB), + CSR_OFF(ERA), + CSR_OFF(BADV), + CSR_OFF_FLAGS(BADI, CSRFL_READONLY), + CSR_OFF(EENTRY), + CSR_OFF(TLBIDX), + CSR_OFF(TLBEHI), + CSR_OFF(TLBELO0), + CSR_OFF(TLBELO1), + CSR_OFF_FLAGS(ASID, CSRFL_EXITTB), + CSR_OFF(PGDL), + CSR_OFF(PGDH), + CSR_OFF_FLAGS(PGD, CSRFL_READONLY), + CSR_OFF(PWCL), + CSR_OFF(PWCH), + CSR_OFF(STLBPS), + CSR_OFF(RVACFG), + CSR_OFF_FLAGS(CPUID, CSRFL_READONLY), + CSR_OFF_FLAGS(PRCFG1, CSRFL_READONLY), + CSR_OFF_FLAGS(PRCFG2, CSRFL_READONLY), + CSR_OFF_FLAGS(PRCFG3, CSRFL_READONLY), + CSR_OFF_ARRAY(SAVE, 0), + CSR_OFF_ARRAY(SAVE, 1), + CSR_OFF_ARRAY(SAVE, 2), + CSR_OFF_ARRAY(SAVE, 3), + CSR_OFF_ARRAY(SAVE, 4), + CSR_OFF_ARRAY(SAVE, 5), + CSR_OFF_ARRAY(SAVE, 6), + CSR_OFF_ARRAY(SAVE, 7), + CSR_OFF_ARRAY(SAVE, 8), + CSR_OFF_ARRAY(SAVE, 9), + CSR_OFF_ARRAY(SAVE, 10), + CSR_OFF_ARRAY(SAVE, 11), + CSR_OFF_ARRAY(SAVE, 12), + CSR_OFF_ARRAY(SAVE, 13), + CSR_OFF_ARRAY(SAVE, 14), + CSR_OFF_ARRAY(SAVE, 15), + CSR_OFF(TID), + CSR_OFF_FLAGS(TCFG, CSRFL_IO), + CSR_OFF_FLAGS(TVAL, CSRFL_READONLY | CSRFL_IO), + CSR_OFF(CNTC), + CSR_OFF_FLAGS(TICLR, CSRFL_IO), + CSR_OFF(LLBCTL), + CSR_OFF(IMPCTL1), + CSR_OFF(IMPCTL2), + CSR_OFF(TLBRENTRY), + CSR_OFF(TLBRBADV), + CSR_OFF(TLBRERA), + CSR_OFF(TLBRSAVE), + CSR_OFF(TLBRELO0), + CSR_OFF(TLBRELO1), + CSR_OFF(TLBREHI), + CSR_OFF(TLBRPRMD), + CSR_OFF(MERRCTL), + CSR_OFF(MERRINFO1), + CSR_OFF(MERRINFO2), + CSR_OFF(MERRENTRY), + CSR_OFF(MERRERA), + CSR_OFF(MERRSAVE), + CSR_OFF(CTAG), + CSR_OFF_ARRAY(DMW, 0), + CSR_OFF_ARRAY(DMW, 1), + CSR_OFF_ARRAY(DMW, 2), + CSR_OFF_ARRAY(DMW, 3), + CSR_OFF(DBG), + CSR_OFF(DERA), + CSR_OFF(DSAVE), +}; + +CSRInfo *get_csr(unsigned int csr_num) +{ + CSRInfo *csr; + + if (csr_num >= ARRAY_SIZE(csr_info)) { + return NULL; + } + + csr = &csr_info[csr_num]; + if (csr->offset == 0) { + return NULL; + } + + return csr; +} + +bool set_csr_flag(unsigned int csr_num, int flag) +{ + CSRInfo *csr; + + csr = get_csr(csr_num); + if (!csr) { + return false; + } + + csr->flags |= flag; + return true; +} diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h new file mode 100644 index 0000000..81a656b --- /dev/null +++ b/target/loongarch/csr.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2025 Loongson Technology Corporation Limited + */ + +#ifndef TARGET_LOONGARCH_CSR_H +#define TARGET_LOONGARCH_CSR_H + +#include "cpu-csr.h" + +typedef void (*GenCSRFunc)(void); +enum { + CSRFL_READONLY = (1 << 0), + CSRFL_EXITTB = (1 << 1), + CSRFL_IO = (1 << 2), + CSRFL_UNUSED = (1 << 3), +}; + +typedef struct { + const char *name; + int offset; + int flags; + GenCSRFunc readfn; + GenCSRFunc writefn; +} CSRInfo; + +CSRInfo *get_csr(unsigned int csr_num); +bool set_csr_flag(unsigned int csr_num, int flag); +#endif /* TARGET_LOONGARCH_CSR_H */ diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build index 7817318..20bd3e2 100644 --- a/target/loongarch/meson.build +++ b/target/loongarch/meson.build @@ -10,6 +10,7 @@ loongarch_system_ss = ss.source_set() loongarch_system_ss.add(files( 'arch_dump.c', 'cpu_helper.c', + 'csr.c', 'loongarch-qmp-cmds.c', 'machine.c', )) diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc index 30f9b83..3afa23a 100644 --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc @@ -5,7 +5,7 @@ * LoongArch translation routines for the privileged instructions. */ -#include "cpu-csr.h" +#include "csr.h" #ifdef CONFIG_USER_ONLY @@ -45,112 +45,6 @@ GEN_FALSE_TRANS(idle) typedef void (*GenCSRRead)(TCGv dest, TCGv_ptr env); typedef void (*GenCSRWrite)(TCGv dest, TCGv_ptr env, TCGv src); -typedef struct { - int offset; - int flags; - GenCSRRead readfn; - GenCSRWrite writefn; -} CSRInfo; - -enum { - CSRFL_READONLY = (1 << 0), - CSRFL_EXITTB = (1 << 1), - CSRFL_IO = (1 << 2), -}; - -#define CSR_OFF_FUNCS(NAME, FL, RD, WR) \ - [LOONGARCH_CSR_##NAME] = { \ - .offset = offsetof(CPULoongArchState, CSR_##NAME), \ - .flags = FL, .readfn = RD, .writefn = WR \ - } - -#define CSR_OFF_ARRAY(NAME, N) \ - [LOONGARCH_CSR_##NAME(N)] = { \ - .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ - .flags = 0, .readfn = NULL, .writefn = NULL \ - } - -#define CSR_OFF_FLAGS(NAME, FL) \ - CSR_OFF_FUNCS(NAME, FL, NULL, NULL) - -#define CSR_OFF(NAME) \ - CSR_OFF_FLAGS(NAME, 0) - -static const CSRInfo csr_info[] = { - CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), - CSR_OFF(PRMD), - CSR_OFF_FLAGS(EUEN, CSRFL_EXITTB), - CSR_OFF_FLAGS(MISC, CSRFL_READONLY), - CSR_OFF(ECFG), - CSR_OFF_FUNCS(ESTAT, CSRFL_EXITTB, NULL, gen_helper_csrwr_estat), - CSR_OFF(ERA), - CSR_OFF(BADV), - CSR_OFF_FLAGS(BADI, CSRFL_READONLY), - CSR_OFF(EENTRY), - CSR_OFF(TLBIDX), - CSR_OFF(TLBEHI), - CSR_OFF(TLBELO0), - CSR_OFF(TLBELO1), - CSR_OFF_FUNCS(ASID, CSRFL_EXITTB, NULL, gen_helper_csrwr_asid), - CSR_OFF(PGDL), - CSR_OFF(PGDH), - CSR_OFF_FUNCS(PGD, CSRFL_READONLY, gen_helper_csrrd_pgd, NULL), - CSR_OFF_FUNCS(PWCL, 0, NULL, gen_helper_csrwr_pwcl), - CSR_OFF(PWCH), - CSR_OFF(STLBPS), - CSR_OFF(RVACFG), - CSR_OFF_FUNCS(CPUID, CSRFL_READONLY, gen_helper_csrrd_cpuid, NULL), - CSR_OFF_FLAGS(PRCFG1, CSRFL_READONLY), - CSR_OFF_FLAGS(PRCFG2, CSRFL_READONLY), - CSR_OFF_FLAGS(PRCFG3, CSRFL_READONLY), - CSR_OFF_ARRAY(SAVE, 0), - CSR_OFF_ARRAY(SAVE, 1), - CSR_OFF_ARRAY(SAVE, 2), - CSR_OFF_ARRAY(SAVE, 3), - CSR_OFF_ARRAY(SAVE, 4), - CSR_OFF_ARRAY(SAVE, 5), - CSR_OFF_ARRAY(SAVE, 6), - CSR_OFF_ARRAY(SAVE, 7), - CSR_OFF_ARRAY(SAVE, 8), - CSR_OFF_ARRAY(SAVE, 9), - CSR_OFF_ARRAY(SAVE, 10), - CSR_OFF_ARRAY(SAVE, 11), - CSR_OFF_ARRAY(SAVE, 12), - CSR_OFF_ARRAY(SAVE, 13), - CSR_OFF_ARRAY(SAVE, 14), - CSR_OFF_ARRAY(SAVE, 15), - CSR_OFF(TID), - CSR_OFF_FUNCS(TCFG, CSRFL_IO, NULL, gen_helper_csrwr_tcfg), - CSR_OFF_FUNCS(TVAL, CSRFL_READONLY | CSRFL_IO, gen_helper_csrrd_tval, NULL), - CSR_OFF(CNTC), - CSR_OFF_FUNCS(TICLR, CSRFL_IO, NULL, gen_helper_csrwr_ticlr), - CSR_OFF(LLBCTL), - CSR_OFF(IMPCTL1), - CSR_OFF(IMPCTL2), - CSR_OFF(TLBRENTRY), - CSR_OFF(TLBRBADV), - CSR_OFF(TLBRERA), - CSR_OFF(TLBRSAVE), - CSR_OFF(TLBRELO0), - CSR_OFF(TLBRELO1), - CSR_OFF(TLBREHI), - CSR_OFF(TLBRPRMD), - CSR_OFF(MERRCTL), - CSR_OFF(MERRINFO1), - CSR_OFF(MERRINFO2), - CSR_OFF(MERRENTRY), - CSR_OFF(MERRERA), - CSR_OFF(MERRSAVE), - CSR_OFF(CTAG), - CSR_OFF_ARRAY(DMW, 0), - CSR_OFF_ARRAY(DMW, 1), - CSR_OFF_ARRAY(DMW, 2), - CSR_OFF_ARRAY(DMW, 3), - CSR_OFF(DBG), - CSR_OFF(DERA), - CSR_OFF(DSAVE), -}; - static bool check_plv(DisasContext *ctx) { if (ctx->plv == MMU_PLV_USER) { @@ -160,20 +54,37 @@ static bool check_plv(DisasContext *ctx) return false; } -static const CSRInfo *get_csr(unsigned csr_num) +static bool set_csr_trans_func(unsigned int csr_num, GenCSRRead readfn, + GenCSRWrite writefn) { - const CSRInfo *csr; + CSRInfo *csr; - if (csr_num >= ARRAY_SIZE(csr_info)) { - return NULL; - } - csr = &csr_info[csr_num]; - if (csr->offset == 0) { - return NULL; + csr = get_csr(csr_num); + if (!csr) { + return false; } - return csr; + + csr->readfn = (GenCSRFunc)readfn; + csr->writefn = (GenCSRFunc)writefn; + return true; } +#define SET_CSR_FUNC(NAME, read, write) \ + set_csr_trans_func(LOONGARCH_CSR_##NAME, read, write) + +void loongarch_csr_translate_init(void) +{ + SET_CSR_FUNC(ESTAT, NULL, gen_helper_csrwr_estat); + SET_CSR_FUNC(ASID, NULL, gen_helper_csrwr_asid); + SET_CSR_FUNC(PGD, gen_helper_csrrd_pgd, NULL); + SET_CSR_FUNC(PWCL, NULL, gen_helper_csrwr_pwcl); + SET_CSR_FUNC(CPUID, gen_helper_csrrd_cpuid, NULL); + SET_CSR_FUNC(TCFG, NULL, gen_helper_csrwr_tcfg); + SET_CSR_FUNC(TVAL, gen_helper_csrrd_tval, NULL); + SET_CSR_FUNC(TICLR, NULL, gen_helper_csrwr_ticlr); +} +#undef SET_CSR_FUNC + static bool check_csr_flags(DisasContext *ctx, const CSRInfo *csr, bool write) { if ((csr->flags & CSRFL_READONLY) && write) { @@ -191,6 +102,7 @@ static bool trans_csrrd(DisasContext *ctx, arg_csrrd *a) { TCGv dest; const CSRInfo *csr; + GenCSRRead readfn; if (check_plv(ctx)) { return false; @@ -202,8 +114,9 @@ static bool trans_csrrd(DisasContext *ctx, arg_csrrd *a) } else { check_csr_flags(ctx, csr, false); dest = gpr_dst(ctx, a->rd, EXT_NONE); - if (csr->readfn) { - csr->readfn(dest, tcg_env); + readfn = (GenCSRRead)csr->readfn; + if (readfn) { + readfn(dest, tcg_env); } else { tcg_gen_ld_tl(dest, tcg_env, csr->offset); } @@ -216,6 +129,7 @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a) { TCGv dest, src1; const CSRInfo *csr; + GenCSRWrite writefn; if (check_plv(ctx)) { return false; @@ -231,9 +145,10 @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a) return false; } src1 = gpr_src(ctx, a->rd, EXT_NONE); - if (csr->writefn) { + writefn = (GenCSRWrite)csr->writefn; + if (writefn) { dest = gpr_dst(ctx, a->rd, EXT_NONE); - csr->writefn(dest, tcg_env, src1); + writefn(dest, tcg_env, src1); } else { dest = tcg_temp_new(); tcg_gen_ld_tl(dest, tcg_env, csr->offset); @@ -247,6 +162,7 @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) { TCGv src1, mask, oldv, newv, temp; const CSRInfo *csr; + GenCSRWrite writefn; if (check_plv(ctx)) { return false; @@ -277,8 +193,9 @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) tcg_gen_andc_tl(temp, oldv, mask); tcg_gen_or_tl(newv, newv, temp); - if (csr->writefn) { - csr->writefn(oldv, tcg_env, newv); + writefn = (GenCSRWrite)csr->writefn; + if (writefn) { + writefn(oldv, tcg_env, newv); } else { tcg_gen_st_tl(newv, tcg_env, csr->offset); } diff --git a/target/loongarch/tcg/tcg_loongarch.h b/target/loongarch/tcg/tcg_loongarch.h new file mode 100644 index 0000000..da2539e --- /dev/null +++ b/target/loongarch/tcg/tcg_loongarch.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch TCG interface + * + * Copyright (c) 2025 Loongson Technology Corporation Limited + */ +#ifndef TARGET_LOONGARCH_TCG_LOONGARCH_H +#define TARGET_LOONGARCH_TCG_LOONGARCH_H + +void loongarch_csr_translate_init(void); + +#endif /* TARGET_LOONGARCH_TCG_LOONGARCH_H */ diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c index 68be999..3480f54 100644 --- a/target/loongarch/tcg/translate.c +++ b/target/loongarch/tcg/translate.c @@ -16,6 +16,7 @@ #include "exec/log.h" #include "qemu/qemu-print.h" #include "fpu/softfloat.h" +#include "tcg_loongarch.h" #include "translate.h" #include "internals.h" #include "vec.h" @@ -358,4 +359,8 @@ void loongarch_translate_init(void) offsetof(CPULoongArchState, lladdr), "lladdr"); cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPULoongArchState, llval), "llval"); + +#ifndef CONFIG_USER_ONLY + loongarch_csr_translate_init(); +#endif } |