aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-09-09 15:39:40 -0700
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-09-09 15:39:40 -0700
commit64ec64876199ef94d7a8ac6eb64b68d7f9c84ee2 (patch)
tree75f604ec6c56aa1da7681429b7d8d1307a7fad6c
parent9beab4ff43f83bef9219f37955a27d9b415639b3 (diff)
downloadriscv-isa-sim-64ec64876199ef94d7a8ac6eb64b68d7f9c84ee2.zip
riscv-isa-sim-64ec64876199ef94d7a8ac6eb64b68d7f9c84ee2.tar.gz
riscv-isa-sim-64ec64876199ef94d7a8ac6eb64b68d7f9c84ee2.tar.bz2
[pk, sim] added interrupt support to sim; added timer interrupt
-rw-r--r--riscv/decode.h6
-rw-r--r--riscv/insns/mfcr.h4
-rw-r--r--riscv/insns/mfpcr.h6
-rw-r--r--riscv/insns/mtcr.h8
-rw-r--r--riscv/insns/mtpcr.h21
-rw-r--r--riscv/processor.cc21
-rw-r--r--riscv/processor.h3
7 files changed, 52 insertions, 17 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index dffb9be..a5ea4bc 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -36,9 +36,11 @@ const int JUMP_ALIGN_BITS = 1;
#define SR_S 0x0000000000000008ULL
#define SR_EF 0x0000000000000010ULL
#define SR_UX 0x0000000000000020ULL
-#define SR_KX 0x0000000000000040ULL
+#define SR_SX 0x0000000000000040ULL
#define SR_IM 0x000000000000FF00ULL
-#define SR_ZERO ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_KX | SR_IM)
+#define SR_ZERO ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_SX | SR_IM)
+#define SR_IM_SHIFT 8
+#define TIMER_IRQ 7
#define FP_RD_NE 0
#define FP_RD_0 1
diff --git a/riscv/insns/mfcr.h b/riscv/insns/mfcr.h
index 7ce1d9e..088480c 100644
--- a/riscv/insns/mfcr.h
+++ b/riscv/insns/mfcr.h
@@ -2,6 +2,10 @@ reg_t val;
switch(insn.rtype.rb)
{
+ case 0:
+ val = fsr;
+ break;
+
case 1:
val = 32; // synci_step
break;
diff --git a/riscv/insns/mfpcr.h b/riscv/insns/mfpcr.h
index d9bfc22..d6fd424 100644
--- a/riscv/insns/mfpcr.h
+++ b/riscv/insns/mfpcr.h
@@ -16,6 +16,12 @@ switch(insn.rtype.rb)
case 3:
val = ebase;
break;
+ case 4:
+ val = count;
+ break;
+ case 5:
+ val = compare;
+ break;
case 8:
val = MEMSIZE >> 12;
diff --git a/riscv/insns/mtcr.h b/riscv/insns/mtcr.h
index 5f85a51..d7b2b17 100644
--- a/riscv/insns/mtcr.h
+++ b/riscv/insns/mtcr.h
@@ -1,8 +1,10 @@
-reg_t val = gprlen == 64 ? RA : sext32(RA);
-
switch(insn.rtype.rb)
{
+ case 0:
+ set_fsr(RA);
+ break;
+
case 29:
- tid = val;
+ tid = RA;
break;
}
diff --git a/riscv/insns/mtpcr.h b/riscv/insns/mtpcr.h
index cbb580b..d9b47f0 100644
--- a/riscv/insns/mtpcr.h
+++ b/riscv/insns/mtpcr.h
@@ -1,27 +1,32 @@
require_supervisor;
-reg_t val = gprlen == 64 ? RA : sext32(RA);
-
switch(insn.rtype.rb)
{
case 0:
- set_sr(val);
+ set_sr(RA);
break;
case 1:
- epc = val;
+ epc = RA;
break;
case 3:
- ebase = val & ~0xFFF;
+ ebase = RA & ~0xFFF;
+ break;
+ case 4:
+ count = RA;
+ break;
+ case 5:
+ interrupts_pending &= ~(1 << TIMER_IRQ);
+ compare = RA;
break;
case 16:
- sim->set_tohost(val);
+ sim->set_tohost(RA);
break;
case 24:
- pcr_k0 = val;
+ pcr_k0 = RA;
break;
case 25:
- pcr_k1 = val;
+ pcr_k1 = RA;
break;
}
diff --git a/riscv/processor.cc b/riscv/processor.cc
index fb32f96..e04f498 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -21,7 +21,10 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
tid = 0;
pcr_k0 = 0;
pcr_k1 = 0;
- set_sr(SR_S | (support_64bit ? SR_KX : 0));
+ count = 0;
+ compare = 0;
+ interrupts_pending = 0;
+ set_sr(SR_S | (support_64bit ? SR_SX : 0));
set_fsr(0);
memset(counters,0,sizeof(counters));
@@ -44,14 +47,15 @@ void processor_t::set_sr(uint32_t val)
{
sr = val & ~SR_ZERO;
if(!support_64bit)
- sr &= ~(SR_KX | SR_UX);
+ sr &= ~(SR_SX | SR_UX);
- gprlen = ((sr & SR_S) ? (sr & SR_KX) : (sr & SR_UX)) ? 64 : 32;
+ gprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
}
void processor_t::set_fsr(uint32_t val)
{
fsr = val & ~FSR_ZERO;
+ softfloat_roundingMode = (fsr & FSR_RD) >> FSR_RD_SHIFT;
}
void processor_t::step(size_t n, bool noisy)
@@ -61,6 +65,14 @@ void processor_t::step(size_t n, bool noisy)
{
for( ; i < n; i++)
{
+ uint32_t interrupts = interrupts_pending & ((sr & SR_IM) >> SR_IM_SHIFT);
+ if((sr & SR_ET) && interrupts)
+ {
+ for(int i = 0; interrupts; i++, interrupts >>= 1)
+ if(interrupts & 1)
+ throw trap_t(16+i);
+ }
+
insn_t insn = mmu.load_insn(pc);
reg_t npc = pc+sizeof(insn);
@@ -73,7 +85,8 @@ void processor_t::step(size_t n, bool noisy)
pc = npc;
R[0] = 0;
- counters[0]++;
+ if(count++ == compare)
+ interrupts_pending |= 1 << TIMER_IRQ;
}
return;
}
diff --git a/riscv/processor.h b/riscv/processor.h
index 26e49f3..8e9e6f0 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -31,6 +31,9 @@ private:
reg_t pcr_k1;
uint32_t id;
uint32_t sr;
+ uint32_t count;
+ uint32_t compare;
+ uint32_t interrupts_pending;
// unprivileged control registers
uint32_t tid;