aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-02-26 01:29:42 -1000
committerRichard Henderson <richard.henderson@linaro.org>2022-03-03 09:49:17 -1000
commit8d8d73b55144e0d8d3c15a83a8fd8f3de78c460d (patch)
tree2a253c516c6b2a7a0398c22add3595fe7a677100
parent304c05df7c3e383133a70e20d7b5121d75ae4190 (diff)
target/nios2: Special case ipending in rdctl and wrctl
It was never correct to be able to write to ipending. Until the rest of the irq code is tidied, the read of ipending will generate an "unnecessary" mask. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--target/nios2/translate.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 52965ba17e..a5f8d20729 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -452,6 +452,17 @@ static void rdctl(DisasContext *dc, uint32_t code, uint32_t flags)
}
switch (instr.imm5 + CR_BASE) {
+ case CR_IPENDING:
+ /*
+ * The value of the ipending register is synthetic.
+ * In hw, this is the AND of a set of hardware irq lines
+ * with the ienable register. In qemu, we re-use the space
+ * of CR_IPENDING to store the set of irq lines, and so we
+ * must perform the AND here, and anywhere else we need the
+ * guest value of ipending.
+ */
+ tcg_gen_and_tl(cpu_R[instr.c], cpu_R[CR_IPENDING], cpu_R[CR_IENABLE]);
+ break;
default:
tcg_gen_mov_tl(cpu_R[instr.c], cpu_R[instr.imm5 + CR_BASE]);
break;
@@ -477,6 +488,9 @@ static void wrctl(DisasContext *dc, uint32_t code, uint32_t flags)
case CR_TLBMISC:
gen_helper_mmu_write_tlbmisc(cpu_env, v);
break;
+ case CR_IPENDING:
+ /* ipending is read only, writes ignored. */
+ break;
default:
tcg_gen_mov_tl(cpu_R[instr.imm5 + CR_BASE], v);
break;