You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qemu/target/loongarch/csr.c

130 lines
3.3 KiB
C

/* 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;
}