Browse Source

[pk, sim] added interrupt support to sim; added timer interrupt

cs250
Andrew Waterman 16 years ago
parent
commit
64ec648761
  1. 6
      riscv/decode.h
  2. 4
      riscv/insns/mfcr.h
  3. 6
      riscv/insns/mfpcr.h
  4. 8
      riscv/insns/mtcr.h
  5. 21
      riscv/insns/mtpcr.h
  6. 21
      riscv/processor.cc
  7. 3
      riscv/processor.h

6
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

4
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;

6
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;

8
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;
}

21
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;
}

21
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;
}

3
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;

Loading…
Cancel
Save