@@ -283,11 +283,13 @@ struct CPUArchState {
target_ulong medeleg;
target_ulong stvec;
+ target_ulong stvt; /* clic-spec */
target_ulong sepc;
target_ulong scause;
target_ulong sintthresh; /* clic-spec */
target_ulong mtvec;
+ target_ulong mtvt; /* clic-spec */
target_ulong mepc;
target_ulong mcause;
target_ulong mtval; /* since: priv-1.10.0 */
@@ -153,6 +153,7 @@
#define CSR_MIE 0x304
#define CSR_MTVEC 0x305
#define CSR_MCOUNTEREN 0x306
+#define CSR_MTVT 0x307 /* clic-spec-draft */
/* 32-bit only */
#define CSR_MSTATUSH 0x310
@@ -192,6 +193,7 @@
#define CSR_SIE 0x104
#define CSR_STVEC 0x105
#define CSR_SCOUNTEREN 0x106
+#define CSR_STVT 0x107 /* clic-spec-draft */
/* Supervisor Configuration CSRs */
#define CSR_SENVCFG 0x10A
@@ -2170,9 +2170,23 @@ static RISCVException read_mtvec(CPURISCVState *env, int csrno,
static RISCVException write_mtvec(CPURISCVState *env, int csrno,
target_ulong val)
{
- /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
- if ((val & 3) < 2) {
+ /*
+ * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
+ * others reserved
+ */
+ target_ulong mode = get_field(val, XTVEC_MODE);
+ target_ulong fullmode = val & XTVEC_FULL_MODE;
+ if (mode <= XTVEC_CLINT_VECTORED) {
env->mtvec = val;
+ } else if (XTVEC_CLIC == fullmode && env->clic) {
+ /*
+ * CLIC mode hardwires xtvec bits 2-5 to zero.
+ * Layout:
+ * XLEN-1:6 base (WARL)
+ * 5:2 submode (WARL) - 0000 for CLIC
+ * 1:0 mode (WARL) - 11 for CLIC
+ */
+ env->mtvec = (val & XTVEC_NBASE) | XTVEC_CLIC;
} else {
qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
}
@@ -2271,6 +2285,18 @@ static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+static int read_mtvt(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->mtvt;
+ return RISCV_EXCP_NONE;
+}
+
+static int write_mtvt(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->mtvt = val & XTVEC_NBASE;
+ return RISCV_EXCP_NONE;
+}
+
/* Machine Trap Handling */
static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
Int128 *val)
@@ -3122,9 +3148,24 @@ static RISCVException read_stvec(CPURISCVState *env, int csrno,
static RISCVException write_stvec(CPURISCVState *env, int csrno,
target_ulong val)
{
- /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
- if ((val & 3) < 2) {
+ /*
+ * bits [1:0] encode mode; 0 = direct, 1 = vectored, 3 = CLIC,
+ * others reserved
+ */
+ target_ulong mode = val & XTVEC_MODE;
+ target_ulong fullmode = val & XTVEC_FULL_MODE;
+ if (mode <= XTVEC_CLINT_VECTORED) {
env->stvec = val;
+ } else if (XTVEC_CLIC == fullmode && env->clic) {
+ /*
+ * If only CLIC mode is supported, writes to bit 1 are also ignored and
+ * it is always set to one. CLIC mode hardwires xtvec bits 2-5 to zero.
+ * Layout:
+ * XLEN-1:6 base (WARL)
+ * 5:2 submode (WARL) - 0000 for CLIC
+ * 1:0 mode (WARL) - 11 for CLIC
+ */
+ env->stvec = (val & XTVEC_NBASE) | XTVEC_CLIC;
} else {
qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
}
@@ -3149,6 +3190,18 @@ static RISCVException write_scounteren(CPURISCVState *env, int csrno,
return RISCV_EXCP_NONE;
}
+static int read_stvt(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->stvt;
+ return RISCV_EXCP_NONE;
+}
+
+static int write_stvt(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->stvt = val & XTVEC_NBASE;
+ return RISCV_EXCP_NONE;
+}
+
/* Supervisor Trap Handling */
static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
Int128 *val)
@@ -5666,11 +5719,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
write_mhpmcounterh },
/* Machine Mode Core Level Interrupt Controller */
+ [CSR_MTVT] = { "mtvt", clic, read_mtvt, write_mtvt },
[CSR_MINTSTATUS] = { "mintstatus", clic, read_mintstatus },
[CSR_MINTTHRESH] = { "mintthresh", clic, read_mintthresh,
write_mintthresh },
/* Supervisor Mode Core Level Interrupt Controller */
+ [CSR_STVT] = { "stvt", clic, read_stvt, write_stvt },
[CSR_SINTSTATUS] = { "sintstatus", clic, read_sintstatus },
[CSR_SINTTHRESH] = { "sintthresh", clic, read_sintthresh,
write_sintthresh },