target/loongarch: Add dynamic function access with CSR register

With CSR register, dynamic function access is used for CSR register
access in TCG mode, so that csr info can be used by other modules.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
This commit is contained in:
Bibo Mao 2025-01-13 11:28:18 +08:00
parent cf86770c7a
commit 90f73c2d7f
3 changed files with 51 additions and 3 deletions

View File

@ -76,7 +76,7 @@ enum {
#define CSR_OFF(NAME) \ #define CSR_OFF(NAME) \
CSR_OFF_FLAGS(NAME, 0) CSR_OFF_FLAGS(NAME, 0)
static const CSRInfo csr_info[] = { static CSRInfo csr_info[] = {
CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB),
CSR_OFF(PRMD), CSR_OFF(PRMD),
CSR_OFF_FLAGS(EUEN, CSRFL_EXITTB), CSR_OFF_FLAGS(EUEN, CSRFL_EXITTB),
@ -160,9 +160,9 @@ static bool check_plv(DisasContext *ctx)
return false; return false;
} }
static const CSRInfo *get_csr(unsigned csr_num) static CSRInfo *get_csr(unsigned csr_num)
{ {
const CSRInfo *csr; CSRInfo *csr;
if (csr_num >= ARRAY_SIZE(csr_info)) { if (csr_num >= ARRAY_SIZE(csr_info)) {
return NULL; return NULL;
@ -174,6 +174,37 @@ static const CSRInfo *get_csr(unsigned csr_num)
return csr; return csr;
} }
static bool set_csr_trans_func(unsigned int csr_num, GenCSRRead readfn,
GenCSRWrite writefn)
{
CSRInfo *csr;
csr = get_csr(csr_num);
if (!csr) {
return false;
}
csr->readfn = readfn;
csr->writefn = 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) static bool check_csr_flags(DisasContext *ctx, const CSRInfo *csr, bool write)
{ {
if ((csr->flags & CSRFL_READONLY) && write) { if ((csr->flags & CSRFL_READONLY) && write) {

View File

@ -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 */

View File

@ -16,6 +16,7 @@
#include "exec/log.h" #include "exec/log.h"
#include "qemu/qemu-print.h" #include "qemu/qemu-print.h"
#include "fpu/softfloat.h" #include "fpu/softfloat.h"
#include "tcg_loongarch.h"
#include "translate.h" #include "translate.h"
#include "internals.h" #include "internals.h"
#include "vec.h" #include "vec.h"
@ -358,4 +359,8 @@ void loongarch_translate_init(void)
offsetof(CPULoongArchState, lladdr), "lladdr"); offsetof(CPULoongArchState, lladdr), "lladdr");
cpu_llval = tcg_global_mem_new(tcg_env, cpu_llval = tcg_global_mem_new(tcg_env,
offsetof(CPULoongArchState, llval), "llval"); offsetof(CPULoongArchState, llval), "llval");
#ifndef CONFIG_USER_ONLY
loongarch_csr_translate_init();
#endif
} }