From aaf96970cc4b324d8b767c871e682cd9b669eada Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 25 Mar 2013 20:06:10 -0700 Subject: [PATCH] expose pending interrupts in status register --- riscv/pcr.h | 5 ++++- riscv/processor.cc | 21 ++++++++++++++------- riscv/processor.h | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/riscv/pcr.h b/riscv/pcr.h index 7659a97..33939d8 100644 --- a/riscv/pcr.h +++ b/riscv/pcr.h @@ -11,8 +11,10 @@ #define SR_S64 0x00000080 #define SR_VM 0x00000100 #define SR_IM 0x00FF0000 -#define SR_ZERO ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_U64|SR_S64|SR_VM|SR_IM) +#define SR_IP 0xFF000000 +#define SR_ZERO ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_U64|SR_S64|SR_VM|SR_IM|SR_IP) #define SR_IM_SHIFT 16 +#define SR_IP_SHIFT 24 #define PCR_SR 0 #define PCR_EPC 1 @@ -35,6 +37,7 @@ #define PCR_FROMHOST 31 #define IRQ_IPI 5 +#define IRQ_HOST 6 #define IRQ_TIMER 7 #define CAUSE_MISALIGNED_FETCH 0 diff --git a/riscv/processor.cc b/riscv/processor.cc index 38f2965..b90bdd6 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -97,7 +97,7 @@ void processor_t::setvl(int vlapp) void processor_t::take_interrupt() { - uint32_t interrupts = interrupts_pending; + uint32_t interrupts = (sr & SR_IP) >> SR_IP_SHIFT; interrupts &= (sr & SR_IM) >> SR_IM_SHIFT; if(interrupts && (sr & SR_ET)) @@ -165,7 +165,7 @@ void processor_t::step(size_t n, bool noisy) uint32_t old_count = count; count += i; if(old_count < compare && uint64_t(old_count) + i >= compare) - interrupts_pending |= 1 << IRQ_TIMER; + set_interrupt(IRQ_TIMER, true); } void processor_t::take_trap(reg_t t, bool noisy) @@ -237,7 +237,7 @@ void processor_t::set_pcr(int which, reg_t val) count = val; break; case PCR_COMPARE: - interrupts_pending &= ~(1 << IRQ_TIMER); + set_interrupt(IRQ_TIMER, false); compare = val; break; case PCR_PTBR: @@ -247,10 +247,7 @@ void processor_t::set_pcr(int which, reg_t val) sim.send_ipi(val); break; case PCR_CLR_IPI: - if (val & 1) - interrupts_pending |= (1 << IRQ_IPI); - else - interrupts_pending &= ~(1 << IRQ_IPI); + set_interrupt(IRQ_IPI, val & 1); break; case PCR_K0: pcr_k0 = val; @@ -267,6 +264,7 @@ void processor_t::set_pcr(int which, reg_t val) tohost = val; break; case PCR_FROMHOST: + set_interrupt(IRQ_HOST, val != 0); fromhost = val; break; } @@ -309,3 +307,12 @@ reg_t processor_t::get_pcr(int which) } return -1; } + +void processor_t::set_interrupt(int which, bool on) +{ + uint32_t mask = (1 << (which + SR_IP_SHIFT)) & SR_IP; + if (on) + sr |= mask; + else + sr &= ~mask; +} diff --git a/riscv/processor.h b/riscv/processor.h index d086760..826fb96 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -25,6 +25,7 @@ public: void deliver_ipi(); // register an interprocessor interrupt bool running() { return run; } void set_pcr(int which, reg_t val); + void set_interrupt(int which, bool on); reg_t get_pcr(int which); mmu_t* get_mmu() { return &mmu; } @@ -49,7 +50,6 @@ private: reg_t cause; reg_t tohost; reg_t fromhost; - uint32_t interrupts_pending; uint32_t id; uint32_t sr; // only modify the status register using set_pcr() uint32_t fsr; -- 2.30.2