aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2013-03-25 20:06:10 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2013-03-25 20:06:10 -0700
commitaaf96970cc4b324d8b767c871e682cd9b669eada (patch)
treeb2ace5fe2d693eb94af35d25b067bde514579f5e /riscv
parent7abd96d407906b47436d354a5b8b7a23923eb58e (diff)
downloadriscv-isa-sim-aaf96970cc4b324d8b767c871e682cd9b669eada.zip
riscv-isa-sim-aaf96970cc4b324d8b767c871e682cd9b669eada.tar.gz
riscv-isa-sim-aaf96970cc4b324d8b767c871e682cd9b669eada.tar.bz2
expose pending interrupts in status register
Diffstat (limited to 'riscv')
-rw-r--r--riscv/pcr.h5
-rw-r--r--riscv/processor.cc21
-rw-r--r--riscv/processor.h2
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;