diff options
author | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-09-09 15:39:40 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-09-09 15:39:40 -0700 |
commit | 64ec64876199ef94d7a8ac6eb64b68d7f9c84ee2 (patch) | |
tree | 75f604ec6c56aa1da7681429b7d8d1307a7fad6c | |
parent | 9beab4ff43f83bef9219f37955a27d9b415639b3 (diff) | |
download | riscv-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.h | 6 | ||||
-rw-r--r-- | riscv/insns/mfcr.h | 4 | ||||
-rw-r--r-- | riscv/insns/mfpcr.h | 6 | ||||
-rw-r--r-- | riscv/insns/mtcr.h | 8 | ||||
-rw-r--r-- | riscv/insns/mtpcr.h | 21 | ||||
-rw-r--r-- | riscv/processor.cc | 21 | ||||
-rw-r--r-- | riscv/processor.h | 3 |
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; |