aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2012-03-24 12:54:03 -0700
committerAndrew Waterman <waterman@eecs.berkeley.edu>2012-03-24 12:54:03 -0700
commit01db50f070d576e433d2b93ad061a0d8239e7b0c (patch)
treecf9d70747c76b92512ed2d2213ab2091ba9462db
parentd8a587dedc38d6c1ec7e1f1348da5a4daf0b7f1e (diff)
downloadspike-01db50f070d576e433d2b93ad061a0d8239e7b0c.zip
spike-01db50f070d576e433d2b93ad061a0d8239e7b0c.tar.gz
spike-01db50f070d576e433d2b93ad061a0d8239e7b0c.tar.bz2
new supervisor mode
-rw-r--r--riscv/decode.h16
-rw-r--r--riscv/disasm.cc12
-rw-r--r--riscv/htif.cc8
-rw-r--r--riscv/insns/clearpcr.h4
-rw-r--r--riscv/insns/di.h4
-rw-r--r--riscv/insns/ei.h4
-rw-r--r--riscv/insns/eret.h2
-rw-r--r--riscv/insns/mfpcr.h55
-rw-r--r--riscv/insns/mtpcr.h49
-rw-r--r--riscv/insns/setpcr.h4
-rw-r--r--riscv/mmu.cc2
-rw-r--r--riscv/opcodes.h33
-rw-r--r--riscv/pcr.h90
-rw-r--r--riscv/processor.cc148
-rw-r--r--riscv/processor.h9
-rw-r--r--riscv/sim.cc5
-rw-r--r--riscv/sim.h1
-rw-r--r--riscv/trap.h9
18 files changed, 257 insertions, 198 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index d7e91f2..3256f1b 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -3,6 +3,7 @@
#define __STDC_LIMIT_MACROS
#include <stdint.h>
+#include "pcr.h"
typedef int int128_t __attribute__((mode(TI)));
typedef unsigned int uint128_t __attribute__((mode(TI)));
@@ -31,21 +32,6 @@ const int BIGIMM_BITS = 20;
const int BRANCH_ALIGN_BITS = 1;
const int JUMP_ALIGN_BITS = 1;
-#define SR_ET 0x0000000000000001ULL
-#define SR_EF 0x0000000000000002ULL
-#define SR_EV 0x0000000000000004ULL
-#define SR_EC 0x0000000000000008ULL
-#define SR_PS 0x0000000000000010ULL
-#define SR_S 0x0000000000000020ULL
-#define SR_UX 0x0000000000000040ULL
-#define SR_SX 0x0000000000000080ULL
-#define SR_IM 0x000000000000FF00ULL
-#define SR_VM 0x0000000000010000ULL
-#define SR_ZERO ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_UX|SR_SX|SR_IM|SR_VM)
-#define SR_IM_SHIFT 8
-#define IPI_IRQ 5
-#define TIMER_IRQ 7
-
#define FP_RD_NE 0
#define FP_RD_0 1
#define FP_RD_DN 2
diff --git a/riscv/disasm.cc b/riscv/disasm.cc
index 3de9741..07c7bcc 100644
--- a/riscv/disasm.cc
+++ b/riscv/disasm.cc
@@ -219,7 +219,7 @@ class pcr_reg_t : public arg_t
virtual std::string to_string(insn_t insn) const
{
std::stringstream s;
- s << "pcr" << insn.rtype.rs2;
+ s << "pcr" << insn.rtype.rs1;
return s.str();
}
};
@@ -565,19 +565,19 @@ disassembler::disassembler()
DEFINE_DTYPE(rdtime);
DEFINE_DTYPE(rdinstret);
- add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr, xrs1_reg, pcr_reg));
+ add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr | mask_rd, xrs2_reg, pcr_reg));
+ add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr, xrd_reg, xrs2_reg, pcr_reg));
add_insn(new disasm_insn_t("mfpcr", match_mfpcr, mask_mfpcr, xrd_reg, pcr_reg));
- DEFINE_NOARG(cflush)
+ add_insn(new disasm_insn_t("setpcr", match_setpcr, mask_setpcr, xrd_reg, pcr_reg, imm));
+ add_insn(new disasm_insn_t("clearpcr", match_clearpcr, mask_clearpcr, xrd_reg, pcr_reg, imm));
DEFINE_NOARG(eret)
- DEFINE_DTYPE(ei)
- DEFINE_DTYPE(di)
+ DEFINE_NOARG(cflush)
DEFINE_RS1(vxcptsave);
DEFINE_RS1(vxcptrestore);
DEFINE_NOARG(vxcptkill);
DEFINE_RS1(vxcptevac);
- DEFINE_NOARG(vxcptwait);
DEFINE_NOARG(vxcpthold);
DEFINE_RS1_RS2(venqcmd);
DEFINE_RS1_RS2(venqimm1);
diff --git a/riscv/htif.cc b/riscv/htif.cc
index 9aa9a7c..8a9cd30 100644
--- a/riscv/htif.cc
+++ b/riscv/htif.cc
@@ -135,18 +135,18 @@ int htif_t::wait_for_packet()
sim->mmu->store_uint64((p.addr+i)*HTIF_DATA_ALIGN, p.data[i]);
break;
case APP_CMD_READ_CONTROL_REG:
- assert(p.addr == 16);
+ assert(p.addr == PCR_TOHOST);
assert(p.data_size == 1);
ackpacket.data_size = 1;
memcpy(ackpacket.data, &sim->tohost, sizeof(reg_t));
break;
case APP_CMD_WRITE_CONTROL_REG:
- assert(p.addr == 17 || p.addr == 15);
+ assert(p.addr == PCR_FROMHOST || p.addr == PCR_RESET);
assert(p.data_size == 1);
sim->tohost = 0;
- if (p.addr == 17)
+ if (p.addr == PCR_FROMHOST)
memcpy(&sim->fromhost, p.data, sizeof(reg_t));
- else if (p.addr == 15)
+ else if (p.addr == PCR_RESET)
{
bool next_reset = p.data[0] & 1;
if (!reset && next_reset)
diff --git a/riscv/insns/clearpcr.h b/riscv/insns/clearpcr.h
new file mode 100644
index 0000000..7acf221
--- /dev/null
+++ b/riscv/insns/clearpcr.h
@@ -0,0 +1,4 @@
+require_supervisor;
+reg_t temp = get_pcr(insn.rtype.rs1);
+set_pcr(insn.rtype.rs1, temp & ~SIMM);
+RD = temp;
diff --git a/riscv/insns/di.h b/riscv/insns/di.h
deleted file mode 100644
index 31280d5..0000000
--- a/riscv/insns/di.h
+++ /dev/null
@@ -1,4 +0,0 @@
-require_supervisor;
-uint32_t temp = sr;
-set_sr(sr & ~SR_ET);
-RD = temp;
diff --git a/riscv/insns/ei.h b/riscv/insns/ei.h
deleted file mode 100644
index 8306aeb..0000000
--- a/riscv/insns/ei.h
+++ /dev/null
@@ -1,4 +0,0 @@
-require_supervisor;
-uint32_t temp = sr;
-set_sr(sr | SR_ET);
-RD = temp;
diff --git a/riscv/insns/eret.h b/riscv/insns/eret.h
index 46d5bed..cd968bd 100644
--- a/riscv/insns/eret.h
+++ b/riscv/insns/eret.h
@@ -1,5 +1,5 @@
require_supervisor;
if(sr & SR_ET)
throw trap_illegal_instruction;
-set_sr(((sr & SR_PS) ? sr : (sr & ~SR_S)) | SR_ET);
+set_pcr(PCR_SR, ((sr & SR_PS) ? sr : (sr & ~SR_S)) | SR_ET);
set_pc(epc);
diff --git a/riscv/insns/mfpcr.h b/riscv/insns/mfpcr.h
index c686669..f7aea9f 100644
--- a/riscv/insns/mfpcr.h
+++ b/riscv/insns/mfpcr.h
@@ -1,55 +1,2 @@
require_supervisor;
-
-reg_t val;
-
-switch(insn.rtype.rs2)
-{
- case 0:
- val = sr;
- break;
- case 1:
- val = epc;
- break;
- case 2:
- val = badvaddr;
- break;
- case 3:
- val = evec;
- break;
- case 4:
- val = count;
- break;
- case 5:
- val = compare;
- break;
- case 6:
- val = cause;
- break;
- case 7:
- val = mmu.get_ptbr();
- break;
-
- case 10:
- val = id;
- break;
-
- case 12:
- val = pcr_k0;
- break;
- case 13:
- val = pcr_k1;
- break;
-
- case 17:
- val = sim.get_fromhost();
- break;
-
- case 18:
- val = vecbanks;
- break;
-
- default:
- val = -1;
-}
-
-RD = sext_xprlen(val);
+RD = get_pcr(insn.rtype.rs1);
diff --git a/riscv/insns/mtpcr.h b/riscv/insns/mtpcr.h
index f06fcf3..5cd0134 100644
--- a/riscv/insns/mtpcr.h
+++ b/riscv/insns/mtpcr.h
@@ -1,47 +1,4 @@
require_supervisor;
-
-switch(insn.rtype.rs2)
-{
- case 0:
- set_sr(RS1);
- break;
- case 1:
- epc = RS1;
- break;
- case 3:
- evec = RS1;
- break;
- case 4:
- count = RS1;
- break;
- case 5:
- interrupts_pending &= ~(1 << TIMER_IRQ);
- compare = RS1;
- break;
- case 7:
- mmu.set_ptbr(RS1);
- break;
-
- case 8:
- sim.send_ipi(RS1);
- break;
- case 9:
- interrupts_pending &= ~(1 << IPI_IRQ);
- break;
-
- case 12:
- pcr_k0 = RS1;
- break;
- case 13:
- pcr_k1 = RS1;
- break;
-
- case 16:
- sim.set_tohost(RS1);
- break;
-
- case 18:
- vecbanks = RS1 & 0xff;
- vecbanks_count = __builtin_popcountll(vecbanks);
- break;
-}
+reg_t val = get_pcr(insn.rtype.rs1);
+set_pcr(insn.rtype.rs1, RS2);
+RD = val;
diff --git a/riscv/insns/setpcr.h b/riscv/insns/setpcr.h
new file mode 100644
index 0000000..d645626
--- /dev/null
+++ b/riscv/insns/setpcr.h
@@ -0,0 +1,4 @@
+require_supervisor;
+reg_t temp = get_pcr(insn.rtype.rs1);
+set_pcr(insn.rtype.rs1, temp | SIMM);
+RD = temp;
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 55273f3..c8eec16 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -63,7 +63,7 @@ pte_t mmu_t::walk(reg_t addr)
// the address must be a canonical sign-extended VA_BITS-bit number
int shift = 8*sizeof(reg_t) - VA_BITS;
- if (((sreg_t)addr << shift >> shift) != addr)
+ if (((sreg_t)addr << shift >> shift) != (sreg_t)addr)
;
else if(!vm_enabled)
{
diff --git a/riscv/opcodes.h b/riscv/opcodes.h
index feeca92..52af654 100644
--- a/riscv/opcodes.h
+++ b/riscv/opcodes.h
@@ -23,7 +23,7 @@ DECLARE_INSN(fcvt_d_w, 0xe0d3, 0x3ff1ff)
DECLARE_INSN(lw, 0x103, 0x3ff)
DECLARE_INSN(add, 0x33, 0x1ffff)
DECLARE_INSN(fcvt_d_s, 0x100d3, 0x3ff1ff)
-DECLARE_INSN(mfpcr, 0x17b, 0x7c1ffff)
+DECLARE_INSN(mfpcr, 0x17b, 0x3fffff)
DECLARE_INSN(c_fsd, 0x18, 0x1f)
DECLARE_INSN(fmax_d, 0x190d3, 0x1ffff)
DECLARE_INSN(bne, 0xe3, 0x3ff)
@@ -33,10 +33,10 @@ DECLARE_INSN(vlh, 0x8b, 0x3fffff)
DECLARE_INSN(bgeu, 0x3e3, 0x3ff)
DECLARE_INSN(vflstd, 0x158b, 0x1ffff)
DECLARE_INSN(c_li, 0x0, 0x1f)
-DECLARE_INSN(di, 0xfb, 0x7ffffff)
+DECLARE_INSN(fadd_d, 0xd3, 0x1f1ff)
DECLARE_INSN(sltiu, 0x193, 0x3ff)
-DECLARE_INSN(mtpcr, 0x1fb, 0xf801ffff)
-DECLARE_INSN(vxcptwait, 0x180fb, 0xffffffff)
+DECLARE_INSN(mtpcr, 0x1fb, 0x1ffff)
+DECLARE_INSN(vlb, 0xb, 0x3fffff)
DECLARE_INSN(stop, 0x177, 0xffffffff)
DECLARE_INSN(vld, 0x18b, 0x3fffff)
DECLARE_INSN(c_slli, 0x19, 0x1c1f)
@@ -46,7 +46,7 @@ DECLARE_INSN(fcvt_s_w, 0xe053, 0x3ff1ff)
DECLARE_INSN(vflstw, 0x150b, 0x1ffff)
DECLARE_INSN(mul, 0x433, 0x1ffff)
DECLARE_INSN(c_lw, 0xa, 0x1f)
-DECLARE_INSN(vxcptevac, 0x1807b, 0xf83fffff)
+DECLARE_INSN(vxcptevac, 0x237b, 0xf83fffff)
DECLARE_INSN(vlw, 0x10b, 0x3fffff)
DECLARE_INSN(vssegstw, 0x90f, 0xfff)
DECLARE_INSN(amominu_d, 0x19ab, 0x1ffff)
@@ -70,7 +70,6 @@ DECLARE_INSN(mftx_s, 0x1c053, 0x3fffff)
DECLARE_INSN(vssegsth, 0x88f, 0xfff)
DECLARE_INSN(vvcfgivl, 0xf3, 0x3ff)
DECLARE_INSN(j, 0x67, 0x7f)
-DECLARE_INSN(ei, 0x7b, 0x7ffffff)
DECLARE_INSN(fence, 0x12f, 0x3ff)
DECLARE_INSN(vsw, 0x10f, 0x3fffff)
DECLARE_INSN(fnmsub_s, 0x4b, 0x1ff)
@@ -86,7 +85,6 @@ DECLARE_INSN(vsetvl, 0x2f3, 0x3fffff)
DECLARE_INSN(fle_d, 0x170d3, 0x1ffff)
DECLARE_INSN(fence_i, 0xaf, 0x3ff)
DECLARE_INSN(vlsegbu, 0x220b, 0x1ffff)
-DECLARE_INSN(vlsegstb, 0x80b, 0xfff)
DECLARE_INSN(fnmsub_d, 0xcb, 0x1ff)
DECLARE_INSN(addw, 0x3b, 0x1ffff)
DECLARE_INSN(sll, 0xb3, 0x1ffff)
@@ -127,13 +125,14 @@ DECLARE_INSN(c_add3, 0x1c, 0x31f)
DECLARE_INSN(sraiw, 0x1029b, 0x3f83ff)
DECLARE_INSN(vssegd, 0x218f, 0x1ffff)
DECLARE_INSN(srl, 0x2b3, 0x1ffff)
-DECLARE_INSN(venqcmd, 0x181fb, 0xf801ffff)
+DECLARE_INSN(venqcmd, 0x2b7b, 0xf801ffff)
DECLARE_INSN(vfmts, 0x1973, 0x1ffff)
-DECLARE_INSN(venqimm1, 0x1827b, 0xf801ffff)
+DECLARE_INSN(venqimm1, 0x2f7b, 0xf801ffff)
DECLARE_INSN(fsgnjx_s, 0x7053, 0x1ffff)
DECLARE_INSN(vfmsv, 0x973, 0x3fffff)
-DECLARE_INSN(venqimm2, 0x182fb, 0xf801ffff)
+DECLARE_INSN(venqimm2, 0x337b, 0xf801ffff)
DECLARE_INSN(fcvt_d_wu, 0xf0d3, 0x3ff1ff)
+DECLARE_INSN(vxcptrestore, 0x77b, 0xf83fffff)
DECLARE_INSN(vmts, 0x1873, 0x1ffff)
DECLARE_INSN(or, 0x333, 0x1ffff)
DECLARE_INSN(rdinstret, 0xa77, 0x7ffffff)
@@ -156,7 +155,8 @@ DECLARE_INSN(vlstd, 0x118b, 0x1ffff)
DECLARE_INSN(c_ld0, 0x8012, 0x801f)
DECLARE_INSN(rdtime, 0x677, 0x7ffffff)
DECLARE_INSN(andi, 0x393, 0x3ff)
-DECLARE_INSN(venqcnt, 0x1837b, 0xf801ffff)
+DECLARE_INSN(clearpcr, 0x7b, 0x3ff)
+DECLARE_INSN(venqcnt, 0x377b, 0xf801ffff)
DECLARE_INSN(fsgnjn_d, 0x60d3, 0x1ffff)
DECLARE_INSN(fnmadd_s, 0x4f, 0x1ff)
DECLARE_INSN(jal, 0x6f, 0x7f)
@@ -216,8 +216,8 @@ DECLARE_INSN(vfmvv, 0x173, 0x3fffff)
DECLARE_INSN(vlstwu, 0x130b, 0x1ffff)
DECLARE_INSN(c_sub3, 0x11c, 0x31f)
DECLARE_INSN(vsh, 0x8f, 0x3fffff)
-DECLARE_INSN(vlb, 0xb, 0x3fffff)
-DECLARE_INSN(vxcptsave, 0x1007b, 0xf83fffff)
+DECLARE_INSN(vlsegstb, 0x80b, 0xfff)
+DECLARE_INSN(vxcptsave, 0x37b, 0xf83fffff)
DECLARE_INSN(vlsegstd, 0x98b, 0xfff)
DECLARE_INSN(vflsegd, 0x258b, 0x1ffff)
DECLARE_INSN(vflsegw, 0x250b, 0x1ffff)
@@ -229,10 +229,9 @@ DECLARE_INSN(mulhu, 0x5b3, 0x1ffff)
DECLARE_INSN(fence_v_g, 0x2af, 0x3ff)
DECLARE_INSN(vmsv, 0x873, 0x3fffff)
DECLARE_INSN(vmst, 0x1073, 0x1ffff)
-DECLARE_INSN(fadd_d, 0xd3, 0x1f1ff)
-DECLARE_INSN(vxcptrestore, 0x100fb, 0xf83fffff)
+DECLARE_INSN(setpcr, 0xfb, 0x3ff)
DECLARE_INSN(rdnpc, 0x26b, 0x7ffffff)
-DECLARE_INSN(vxcpthold, 0x1817b, 0xffffffff)
+DECLARE_INSN(vxcpthold, 0x277b, 0xffffffff)
DECLARE_INSN(fcvt_s_l, 0xc053, 0x3ff1ff)
DECLARE_INSN(vflsegstd, 0xd8b, 0xfff)
DECLARE_INSN(c_add, 0x1a, 0x801f)
@@ -243,7 +242,7 @@ DECLARE_INSN(fmadd_s, 0x43, 0x1ff)
DECLARE_INSN(fcvt_w_s, 0xa053, 0x3ff1ff)
DECLARE_INSN(vssegh, 0x208f, 0x1ffff)
DECLARE_INSN(fsqrt_s, 0x4053, 0x3ff1ff)
-DECLARE_INSN(vxcptkill, 0x1017b, 0xffffffff)
+DECLARE_INSN(vxcptkill, 0xb7b, 0xffffffff)
DECLARE_INSN(c_srai, 0x1019, 0x1c1f)
DECLARE_INSN(amomin_w, 0x112b, 0x1ffff)
DECLARE_INSN(fsgnjn_s, 0x6053, 0x1ffff)
diff --git a/riscv/pcr.h b/riscv/pcr.h
new file mode 100644
index 0000000..7659a97
--- /dev/null
+++ b/riscv/pcr.h
@@ -0,0 +1,90 @@
+#ifndef _RISCV_PCR_H
+#define _RISCV_PCR_H
+
+#define SR_ET 0x00000001
+#define SR_EF 0x00000002
+#define SR_EV 0x00000004
+#define SR_EC 0x00000008
+#define SR_PS 0x00000010
+#define SR_S 0x00000020
+#define SR_U64 0x00000040
+#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_IM_SHIFT 16
+
+#define PCR_SR 0
+#define PCR_EPC 1
+#define PCR_BADVADDR 2
+#define PCR_EVEC 3
+#define PCR_COUNT 4
+#define PCR_COMPARE 5
+#define PCR_CAUSE 6
+#define PCR_PTBR 7
+#define PCR_SEND_IPI 8
+#define PCR_CLR_IPI 9
+#define PCR_COREID 10
+#define PCR_IMPL 11
+#define PCR_K0 12
+#define PCR_K1 13
+#define PCR_VECBANK 18
+#define PCR_VECCFG 19
+#define PCR_RESET 29
+#define PCR_TOHOST 30
+#define PCR_FROMHOST 31
+
+#define IRQ_IPI 5
+#define IRQ_TIMER 7
+
+#define CAUSE_MISALIGNED_FETCH 0
+#define CAUSE_FAULT_FETCH 1
+#define CAUSE_ILLEGAL_INSTRUCTION 2
+#define CAUSE_PRIVILEGED_INSTRUCTION 3
+#define CAUSE_FP_DISABLED 4
+#define CAUSE_SYSCALL 6
+#define CAUSE_BREAKPOINT 7
+#define CAUSE_MISALIGNED_LOAD 8
+#define CAUSE_MISALIGNED_STORE 9
+#define CAUSE_FAULT_LOAD 10
+#define CAUSE_FAULT_STORE 11
+#define CAUSE_VECTOR_DISABLED 12
+#define CAUSE_VECTOR_BANK 13
+
+#define CAUSE_VECTOR_MISALIGNED_FETCH 24
+#define CAUSE_VECTOR_FAULT_FETCH 25
+#define CAUSE_VECTOR_ILLEGAL_INSTRUCTION 26
+#define CAUSE_VECTOR_ILLEGAL_COMMAND 27
+#define CAUSE_VECTOR_MISALIGNED_LOAD 28
+#define CAUSE_VECTOR_MISALIGNED_STORE 29
+#define CAUSE_VECTOR_FAULT_LOAD 30
+#define CAUSE_VECTOR_FAULT_STORE 31
+
+#ifdef __riscv
+
+#define ASM_CR(r) _ASM_CR(r)
+#define _ASM_CR(r) cr##r
+
+#ifndef __ASSEMBLER__
+
+#define mtpcr(reg,val) ({ long __tmp = (long)(val), __tmp2; \
+ asm volatile ("mtpcr %0,%1,cr%2" : "=r"(__tmp2) : "r"(__tmp),"i"(reg)); \
+ __tmp2; })
+
+#define mfpcr(reg) ({ long __tmp; \
+ asm volatile ("mfpcr %0,cr%1" : "=r"(__tmp) : "i"(reg)); \
+ __tmp; })
+
+#define setpcr(reg,val) ({ long __tmp; \
+ asm volatile ("setpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \
+ __tmp; })
+
+#define clearpcr(reg,val) ({ long __tmp; \
+ asm volatile ("clearpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \
+ __tmp; })
+
+#endif
+
+#endif
+
+#endif
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 9785799..322bf32 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -23,7 +23,7 @@ processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id,
: sim(*_sim), mmu(*_mmu), id(_id)
{
reset();
- set_sr(sr | SR_EF | SR_EV);
+ set_pcr(PCR_SR, sr | SR_EF | SR_EV);
utidx = _utidx;
// microthreads don't possess their own microthreads
@@ -43,7 +43,7 @@ void processor_t::reset()
// is in supervisor mode, and in 64-bit mode, if supported, with traps
// and virtual memory disabled. we accomplish this by setting EVEC to
// 0x2000 and *enabling* traps, then sending the core an IPI.
- set_sr(SR_S | SR_SX | SR_ET | SR_IM);
+ set_pcr(PCR_SR, SR_S | SR_S64 | SR_ET | SR_IM);
evec = 0x2000;
// the following state is undefined upon boot-up,
@@ -73,32 +73,6 @@ void processor_t::reset()
nfpr_use = 32;
}
-void processor_t::set_sr(uint32_t val)
-{
- sr = val & ~SR_ZERO; // clear SR bits that read as zero
-
-#ifndef RISCV_ENABLE_64BIT
- sr &= ~(SR_SX | SR_UX); // SX=UX=0 for RV32 implementations
-#endif
-#ifndef RISCV_ENABLE_FPU
- sr &= ~SR_EF;
-#endif
-#ifndef RISCV_ENABLE_RVC
- sr &= ~SR_EC;
-#endif
-#ifndef RISCV_ENABLE_VEC
- sr &= ~SR_EV;
-#endif
-
- // update MMU state and flush TLB
- mmu.set_vm_enabled(sr & SR_VM);
- mmu.set_supervisor(sr & SR_S);
- mmu.flush_tlb();
-
- // set the fixed-point register length
- xprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
-}
-
void processor_t::set_fsr(uint32_t val)
{
fsr = val & ~FSR_ZERO; // clear FSR bits that read as zero
@@ -127,7 +101,7 @@ void processor_t::take_interrupt()
if(interrupts && (sr & SR_ET))
for(int i = 0; ; i++, interrupts >>= 1)
if(interrupts & 1)
- throw (trap_t)(trap_irq0 + i);
+ throw interrupt_t(i);
}
void processor_t::step(size_t n, bool noisy)
@@ -178,6 +152,11 @@ void processor_t::step(size_t n, bool noisy)
i++;
take_trap(t,noisy);
}
+ catch(interrupt_t t)
+ {
+ i++;
+ take_trap((1ULL << (8*sizeof(reg_t)-1)) + t.i, noisy);
+ }
catch(vt_command_t cmd)
{
// this microthread has finished
@@ -198,17 +177,17 @@ 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 << TIMER_IRQ;
+ interrupts_pending |= 1 << IRQ_TIMER;
}
-void processor_t::take_trap(trap_t t, bool noisy)
+void processor_t::take_trap(reg_t t, bool noisy)
{
if(noisy)
printf("core %3d: trap %s, pc 0x%016llx\n",
- id, trap_name(t), (unsigned long long)pc);
+ id, trap_name(trap_t(t)), (unsigned long long)pc);
// switch to supervisor, set previous supervisor bit, disable traps
- set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
+ set_pcr(PCR_SR, (((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
cause = t;
epc = pc;
pc = evec;
@@ -217,7 +196,7 @@ void processor_t::take_trap(trap_t t, bool noisy)
void processor_t::deliver_ipi()
{
- interrupts_pending |= 1 << IPI_IRQ;
+ interrupts_pending |= 1 << IRQ_IPI;
run = true;
}
@@ -228,3 +207,104 @@ void processor_t::disasm(insn_t insn, reg_t pc)
printf("core %3d: 0x%016llx (0x%08x) %s\n", id, (unsigned long long)pc,
insn.bits, disasm.disassemble(insn).c_str());
}
+
+void processor_t::set_pcr(int which, reg_t val)
+{
+ switch (which)
+ {
+ case PCR_SR:
+ sr = val & ~SR_ZERO; // clear SR bits that read as zero
+#ifndef RISCV_ENABLE_64BIT
+ sr &= ~(SR_S64 | SR_U64);
+#endif
+#ifndef RISCV_ENABLE_FPU
+ sr &= ~SR_EF;
+#endif
+#ifndef RISCV_ENABLE_RVC
+ sr &= ~SR_EC;
+#endif
+#ifndef RISCV_ENABLE_VEC
+ sr &= ~SR_EV;
+#endif
+ // update MMU state and flush TLB
+ mmu.set_vm_enabled(sr & SR_VM);
+ mmu.set_supervisor(sr & SR_S);
+ mmu.flush_tlb();
+ // set the fixed-point register length
+ xprlen = ((sr & SR_S) ? (sr & SR_S64) : (sr & SR_U64)) ? 64 : 32;
+ break;
+ case PCR_EPC:
+ epc = val;
+ break;
+ case PCR_EVEC:
+ evec = val;
+ break;
+ case PCR_COUNT:
+ count = val;
+ break;
+ case PCR_COMPARE:
+ interrupts_pending &= ~(1 << IRQ_TIMER);
+ compare = val;
+ break;
+ case PCR_PTBR:
+ mmu.set_ptbr(val);
+ break;
+ case PCR_SEND_IPI:
+ sim.send_ipi(val);
+ break;
+ case PCR_CLR_IPI:
+ interrupts_pending &= ~(1 << IRQ_IPI);
+ break;
+ case PCR_K0:
+ pcr_k0 = val;
+ break;
+ case PCR_K1:
+ pcr_k1 = val;
+ break;
+ case PCR_VECBANK:
+ vecbanks = val & 0xff;
+ vecbanks_count = __builtin_popcountll(vecbanks);
+ break;
+ case PCR_TOHOST:
+ sim.set_tohost(val);
+ break;
+ }
+}
+
+reg_t processor_t::get_pcr(int which)
+{
+ switch (which)
+ {
+ case PCR_SR:
+ return sr;
+ case PCR_EPC:
+ return epc;
+ case PCR_BADVADDR:
+ return badvaddr;
+ case PCR_EVEC:
+ return evec;
+ case PCR_COUNT:
+ return count;
+ case PCR_COMPARE:
+ return compare;
+ case PCR_CAUSE:
+ return cause;
+ case PCR_PTBR:
+ return mmu.get_ptbr();
+ case PCR_COREID:
+ return id;
+ case PCR_IMPL:
+ return 1;
+ case PCR_K0:
+ return pcr_k0;
+ case PCR_K1:
+ return pcr_k1;
+ case PCR_VECBANK:
+ return vecbanks;
+ case PCR_TOHOST:
+ return sim.get_tohost();
+ case PCR_FROMHOST:
+ return sim.get_fromhost();
+ }
+ return -1;
+}
diff --git a/riscv/processor.h b/riscv/processor.h
index 09fac00..db26f7e 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -41,10 +41,10 @@ private:
reg_t evec;
reg_t pcr_k0;
reg_t pcr_k1;
- uint32_t cause;
+ reg_t cause;
uint32_t interrupts_pending;
uint32_t id;
- uint32_t sr; // only modify the status register using set_sr()
+ uint32_t sr; // only modify the status register using set_pcr()
uint32_t fsr;
uint32_t count;
uint32_t compare;
@@ -58,9 +58,10 @@ private:
// functions
void reset(); // resets architected state; halts processor if it was running
void take_interrupt(); // take a trap if any interrupts are pending
- void set_sr(uint32_t val); // set the status register
+ void set_pcr(int which, reg_t val);
+ reg_t get_pcr(int which);
void set_fsr(uint32_t val); // set the floating-point status register
- void take_trap(trap_t t, bool noisy); // take an exception
+ void take_trap(reg_t t, bool noisy); // take an exception
void disasm(insn_t insn, reg_t pc); // disassemble and print an instruction
// vector stuff
diff --git a/riscv/sim.cc b/riscv/sim.cc
index fb533a8..0d0b555 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -63,6 +63,11 @@ void sim_t::set_tohost(reg_t val)
htif->wait_for_tohost_write();
}
+reg_t sim_t::get_tohost()
+{
+ return tohost;
+}
+
reg_t sim_t::get_fromhost()
{
htif->wait_for_fromhost_write();
diff --git a/riscv/sim.h b/riscv/sim.h
index c4058d3..0d384c4 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -20,6 +20,7 @@ public:
// communicate with the host machine
void set_tohost(reg_t val);
+ reg_t get_tohost();
reg_t get_fromhost();
// deliver an IPI to a specific processor
diff --git a/riscv/trap.h b/riscv/trap.h
index 8e43c2c..d09da3f 100644
--- a/riscv/trap.h
+++ b/riscv/trap.h
@@ -18,14 +18,6 @@
DECLARE_TRAP(vector_bank), \
DECLARE_TRAP(vector_illegal_instruction), \
DECLARE_TRAP(reserved1), \
- DECLARE_TRAP(irq0), \
- DECLARE_TRAP(irq1), \
- DECLARE_TRAP(irq2), \
- DECLARE_TRAP(irq3), \
- DECLARE_TRAP(irq4), \
- DECLARE_TRAP(irq5), \
- DECLARE_TRAP(irq6), \
- DECLARE_TRAP(irq7), \
#define DECLARE_TRAP(x) trap_##x
enum trap_t
@@ -35,6 +27,7 @@ enum trap_t
};
#undef DECLARE_TRAP
+struct interrupt_t { interrupt_t(int which) : i(which) {} int i; };
struct halt_t {}; // thrown to stop the processor from running
extern "C" const char* trap_name(trap_t t);