risc-v supervisor mode updates
authorAndrew Waterman <waterman@eecs.berkeley.edu>
Fri, 11 May 2012 04:28:54 +0000 (21:28 -0700)
committerAndrew Waterman <waterman@eecs.berkeley.edu>
Fri, 11 May 2012 04:36:24 +0000 (21:36 -0700)
kern/arch/riscv/arch.h
kern/arch/riscv/boot.S
kern/arch/riscv/console.c
kern/arch/riscv/cpuinfo.c
kern/arch/riscv/fpu.c [new file with mode: 0644]
kern/arch/riscv/opcodes.h [new file with mode: 0644]
kern/arch/riscv/pcr.h
kern/arch/riscv/process.c
kern/arch/riscv/ros/trapframe.h
kern/arch/riscv/time.c
kern/arch/riscv/trap.c

index 746e696..b709d39 100644 (file)
@@ -65,13 +65,13 @@ read_tsc_serialized(void)
 static __inline void
 enable_irq(void)
 {
-  asm volatile("ei");
+  setpcr(PCR_SR, SR_ET);
 }
 
 static __inline void
 disable_irq(void)
 {
-  asm volatile("di");
+  clearpcr(PCR_SR, SR_ET);
 }
 
 static __inline int
index ee987f9..bedec2b 100644 (file)
@@ -16,7 +16,7 @@
 // entry point
 ///////////////////////////////////////////////////////////////////
 
-#define PCR0 (SR_S | SR_ET | SR_SX | (1 << (IPI_IRQ + SR_IM_SHIFT)))
+#define PCR0 (SR_S | SR_ET | SR_S64 | (1 << (IRQ_IPI + SR_IM_SHIFT)))
 .text
 
 .global _start
index f3fa4ba..b3fadcc 100644 (file)
@@ -5,10 +5,7 @@
 long
 fesvr_syscall(long n, long a0, long a1, long a2, long a3)
 {
-  static volatile uint64_t magic_mem[8];
-
-  static spinlock_t lock = SPINLOCK_INITIALIZER;
-  spin_lock_irqsave(&lock);
+  volatile uint64_t magic_mem[8];
 
   magic_mem[0] = n;
   magic_mem[1] = a0;
@@ -16,15 +13,12 @@ fesvr_syscall(long n, long a0, long a1, long a2, long a3)
   magic_mem[3] = a2;
   magic_mem[4] = a3;
 
-  asm volatile ("cflush; fence");
-
+  mb();
   mtpcr(PCR_TOHOST, PADDR(magic_mem));
   while(mfpcr(PCR_FROMHOST) == 0);
+  mb();
 
-  long ret = magic_mem[0];
-
-  spin_unlock_irqsave(&lock);
-  return ret;
+  return magic_mem[0];
 }
 
 void
index 066c05b..83f3641 100644 (file)
@@ -15,7 +15,13 @@ static_asserts_can_go_here()
 void
 print_cpuinfo(void)
 {
-       cprintf("CPU Info: Not Just Any Other RISC-V Core (TM)\n");
+       int id = mfpcr(PCR_IMPL);
+       const char* name = "(unknown implementation)";
+       if (id == 1)
+         name = "ISA Simulator";
+       else if (id == 2)
+         name = "Rocket64";
+       cprintf("CPU Info: RISC-V %s\n", name);
 }
 
 void show_mapping(uintptr_t start, size_t size)
diff --git a/kern/arch/riscv/fpu.c b/kern/arch/riscv/fpu.c
new file mode 100644 (file)
index 0000000..505e79f
--- /dev/null
@@ -0,0 +1,81 @@
+#include <arch/trap.h>
+#include <smp.h>
+#include <umem.h>
+
+int emulate_fpu(struct trapframe* state, ancillary_state_t* silly)
+{
+       int insn;
+       if (!memcpy_from_user(current, &insn, (void*)state->epc, 4))
+       {
+               state->cause = CAUSE_FAULT_FETCH;
+               handle_trap(state);
+       }
+
+       #define DECLARE_INSN(name, match, mask) bool is_##name = (insn & match) == mask;
+       #include <arch/opcodes.h>
+       #undef DECLARE_INSN
+
+       int rd  = (insn >> 27) & 0x1f;
+       int rs1 = (insn >> 22) & 0x1f;
+       int rs2 = (insn >> 17) & 0x1f;
+       int rs3 = (insn >> 12) & 0x1f;
+
+       int imm = (insn << 10) >> 20;
+       int bimm = ((insn >> 10) & 0x7f) | ((insn & 0xf8000000) >> 20);
+
+       void* load_address = (void*)(state->gpr[rs1] + imm);
+       void* store_address = (void*)(state->gpr[rs1] + bimm);
+
+       if (is_mffsr)
+       {
+               state->gpr[rd] = silly->fsr;
+       }
+       else if (is_mtfsr)
+       {
+               silly->fsr = state->gpr[rs1];
+       }
+       else if (is_fld)
+       {
+               uint64_t dest;
+               if (!memcpy_from_user(current, &dest, load_address, sizeof(dest)))
+               {
+                       state->cause = CAUSE_FAULT_LOAD;
+                       state->badvaddr = (long)load_address;
+                       handle_trap(state);
+               }
+               silly->fpr[rd] = dest;
+       }
+       else if (is_flw)
+       {
+               uint32_t dest;
+               if (!memcpy_from_user(current, &dest, load_address, sizeof(dest)))
+               {
+                       state->cause = CAUSE_FAULT_LOAD;
+                       state->badvaddr = (long)load_address;
+                       handle_trap(state);
+               }
+               silly->fpr[rd] = dest;
+       }
+       else if (is_fsd)
+       {
+               if (!memcpy_to_user(current, store_address, &silly->fpr[rs2], sizeof(uint64_t)))
+               {
+                       state->cause = CAUSE_FAULT_STORE;
+                       state->badvaddr = (long)store_address;
+                       handle_trap(state);
+               }
+       }
+       else if (is_flw)
+       {
+               if (!memcpy_to_user(current, store_address, &silly->fpr[rs2], sizeof(uint32_t)))
+               {
+                       state->cause = CAUSE_FAULT_STORE;
+                       state->badvaddr = (long)store_address;
+                       handle_trap(state);
+               }
+       }
+       else
+         return 1;
+       
+       return 0;
+}
diff --git a/kern/arch/riscv/opcodes.h b/kern/arch/riscv/opcodes.h
new file mode 100644 (file)
index 0000000..519a75f
--- /dev/null
@@ -0,0 +1,272 @@
+DECLARE_INSN(movn, 0x6f7, 0x1ffff)
+DECLARE_INSN(vfsstw, 0x150f, 0x1ffff)
+DECLARE_INSN(remuw, 0x7bb, 0x1ffff)
+DECLARE_INSN(fmin_d, 0x180d3, 0x1ffff)
+DECLARE_INSN(vlsthu, 0x128b, 0x1ffff)
+DECLARE_INSN(c_swsp, 0x8, 0x1f)
+DECLARE_INSN(bltu, 0x363, 0x3ff)
+DECLARE_INSN(vlsegstwu, 0xb0b, 0xfff)
+DECLARE_INSN(movz, 0x2f7, 0x1ffff)
+DECLARE_INSN(fcvt_lu_s, 0x9053, 0x3ff1ff)
+DECLARE_INSN(fence_l_cv, 0x32f, 0x3ff)
+DECLARE_INSN(fmin_s, 0x18053, 0x1ffff)
+DECLARE_INSN(c_lw0, 0x12, 0x801f)
+DECLARE_INSN(slliw, 0x9b, 0x3f83ff)
+DECLARE_INSN(lb, 0x3, 0x3ff)
+DECLARE_INSN(vlwu, 0x30b, 0x3fffff)
+DECLARE_INSN(fcvt_d_l, 0xc0d3, 0x3ff1ff)
+DECLARE_INSN(lh, 0x83, 0x3ff)
+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(fence_g_v, 0x2af, 0x3ff)
+DECLARE_INSN(mfpcr, 0x17b, 0x7c1ffff)
+DECLARE_INSN(c_fsd, 0x18, 0x1f)
+DECLARE_INSN(fmax_d, 0x190d3, 0x1ffff)
+DECLARE_INSN(bne, 0xe3, 0x3ff)
+DECLARE_INSN(rdcycle, 0x277, 0x7ffffff)
+DECLARE_INSN(fcvt_s_d, 0x11053, 0x3ff1ff)
+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(sltiu, 0x193, 0x3ff)
+DECLARE_INSN(mtpcr, 0x1fb, 0xf801ffff)
+DECLARE_INSN(vlb, 0xb, 0x3fffff)
+DECLARE_INSN(stop, 0x177, 0xffffffff)
+DECLARE_INSN(vld, 0x18b, 0x3fffff)
+DECLARE_INSN(c_slli, 0x19, 0x1c1f)
+DECLARE_INSN(break, 0xf7, 0xffffffff)
+DECLARE_INSN(cflush, 0x2fb, 0xffffffff)
+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(vlw, 0x10b, 0x3fffff)
+DECLARE_INSN(vssegstw, 0x90f, 0xfff)
+DECLARE_INSN(amominu_d, 0x19ab, 0x1ffff)
+DECLARE_INSN(c_sdsp, 0x6, 0x1f)
+DECLARE_INSN(utidx, 0x1f7, 0x7ffffff)
+DECLARE_INSN(srli, 0x293, 0x3f03ff)
+DECLARE_INSN(c_srli, 0x819, 0x1c1f)
+DECLARE_INSN(c_ldsp, 0x4, 0x1f)
+DECLARE_INSN(c_flw, 0x14, 0x1f)
+DECLARE_INSN(c_srai32, 0x1419, 0x1c1f)
+DECLARE_INSN(amominu_w, 0x192b, 0x1ffff)
+DECLARE_INSN(divuw, 0x6bb, 0x1ffff)
+DECLARE_INSN(mulw, 0x43b, 0x1ffff)
+DECLARE_INSN(vssegstd, 0x98f, 0xfff)
+DECLARE_INSN(srlw, 0x2bb, 0x1ffff)
+DECLARE_INSN(vssegstb, 0x80f, 0xfff)
+DECLARE_INSN(mftx_d, 0x1c0d3, 0x3fffff)
+DECLARE_INSN(div, 0x633, 0x1ffff)
+DECLARE_INSN(c_ld, 0x9, 0x1f)
+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)
+DECLARE_INSN(vfssegstd, 0xd8f, 0xfff)
+DECLARE_INSN(fcvt_l_s, 0x8053, 0x3ff1ff)
+DECLARE_INSN(fle_s, 0x17053, 0x1ffff)
+DECLARE_INSN(vsb, 0xf, 0x3fffff)
+DECLARE_INSN(mffsr, 0x1d053, 0x7ffffff)
+DECLARE_INSN(fdiv_s, 0x3053, 0x1f1ff)
+DECLARE_INSN(vlstbu, 0x120b, 0x1ffff)
+DECLARE_INSN(vsetvl, 0x2f3, 0x3fffff)
+DECLARE_INSN(fle_d, 0x170d3, 0x1ffff)
+DECLARE_INSN(fence_i, 0xaf, 0x3ff)
+DECLARE_INSN(vlsegbu, 0x220b, 0x1ffff)
+DECLARE_INSN(fnmsub_d, 0xcb, 0x1ff)
+DECLARE_INSN(addw, 0x3b, 0x1ffff)
+DECLARE_INSN(sll, 0xb3, 0x1ffff)
+DECLARE_INSN(xor, 0x233, 0x1ffff)
+DECLARE_INSN(sub, 0x10033, 0x1ffff)
+DECLARE_INSN(eret, 0x27b, 0xffffffff)
+DECLARE_INSN(blt, 0x263, 0x3ff)
+DECLARE_INSN(vsstw, 0x110f, 0x1ffff)
+DECLARE_INSN(mtfsr, 0x1f053, 0x3fffff)
+DECLARE_INSN(vssth, 0x108f, 0x1ffff)
+DECLARE_INSN(rem, 0x733, 0x1ffff)
+DECLARE_INSN(srliw, 0x29b, 0x3f83ff)
+DECLARE_INSN(lui, 0x37, 0x7f)
+DECLARE_INSN(vsstb, 0x100f, 0x1ffff)
+DECLARE_INSN(fcvt_s_lu, 0xd053, 0x3ff1ff)
+DECLARE_INSN(vsstd, 0x118f, 0x1ffff)
+DECLARE_INSN(addi, 0x13, 0x3ff)
+DECLARE_INSN(vfmst, 0x1173, 0x1ffff)
+DECLARE_INSN(mulh, 0x4b3, 0x1ffff)
+DECLARE_INSN(fmul_s, 0x2053, 0x1f1ff)
+DECLARE_INSN(vlsegsthu, 0xa8b, 0xfff)
+DECLARE_INSN(srai, 0x10293, 0x3f03ff)
+DECLARE_INSN(amoand_d, 0x9ab, 0x1ffff)
+DECLARE_INSN(flt_d, 0x160d3, 0x1ffff)
+DECLARE_INSN(sraw, 0x102bb, 0x1ffff)
+DECLARE_INSN(fmul_d, 0x20d3, 0x1f1ff)
+DECLARE_INSN(ld, 0x183, 0x3ff)
+DECLARE_INSN(ori, 0x313, 0x3ff)
+DECLARE_INSN(flt_s, 0x16053, 0x1ffff)
+DECLARE_INSN(addiw, 0x1b, 0x3ff)
+DECLARE_INSN(amoand_w, 0x92b, 0x1ffff)
+DECLARE_INSN(feq_s, 0x15053, 0x1ffff)
+DECLARE_INSN(fsgnjx_d, 0x70d3, 0x1ffff)
+DECLARE_INSN(sra, 0x102b3, 0x1ffff)
+DECLARE_INSN(c_lwsp, 0x5, 0x1f)
+DECLARE_INSN(bge, 0x2e3, 0x3ff)
+DECLARE_INSN(c_add3, 0x1c, 0x31f)
+DECLARE_INSN(sraiw, 0x1029b, 0x3f83ff)
+DECLARE_INSN(vssegd, 0x218f, 0x1ffff)
+DECLARE_INSN(srl, 0x2b3, 0x1ffff)
+DECLARE_INSN(vfmts, 0x1973, 0x1ffff)
+DECLARE_INSN(fsgnjx_s, 0x7053, 0x1ffff)
+DECLARE_INSN(vfmsv, 0x973, 0x3fffff)
+DECLARE_INSN(feq_d, 0x150d3, 0x1ffff)
+DECLARE_INSN(fcvt_d_wu, 0xf0d3, 0x3ff1ff)
+DECLARE_INSN(vmts, 0x1873, 0x1ffff)
+DECLARE_INSN(or, 0x333, 0x1ffff)
+DECLARE_INSN(rdinstret, 0xa77, 0x7ffffff)
+DECLARE_INSN(fcvt_wu_d, 0xb0d3, 0x3ff1ff)
+DECLARE_INSN(subw, 0x1003b, 0x1ffff)
+DECLARE_INSN(jalr_c, 0x6b, 0x3ff)
+DECLARE_INSN(fmax_s, 0x19053, 0x1ffff)
+DECLARE_INSN(amomaxu_d, 0x1dab, 0x1ffff)
+DECLARE_INSN(c_slliw, 0x1819, 0x1c1f)
+DECLARE_INSN(jalr_j, 0x16b, 0x3ff)
+DECLARE_INSN(c_fld, 0x15, 0x1f)
+DECLARE_INSN(vlstw, 0x110b, 0x1ffff)
+DECLARE_INSN(vlsth, 0x108b, 0x1ffff)
+DECLARE_INSN(xori, 0x213, 0x3ff)
+DECLARE_INSN(jalr_r, 0xeb, 0x3ff)
+DECLARE_INSN(amomaxu_w, 0x1d2b, 0x1ffff)
+DECLARE_INSN(fcvt_wu_s, 0xb053, 0x3ff1ff)
+DECLARE_INSN(vlstb, 0x100b, 0x1ffff)
+DECLARE_INSN(vlstd, 0x118b, 0x1ffff)
+DECLARE_INSN(c_ld0, 0x8012, 0x801f)
+DECLARE_INSN(rdtime, 0x677, 0x7ffffff)
+DECLARE_INSN(andi, 0x393, 0x3ff)
+DECLARE_INSN(c_srli32, 0xc19, 0x1c1f)
+DECLARE_INSN(fsgnjn_d, 0x60d3, 0x1ffff)
+DECLARE_INSN(fnmadd_s, 0x4f, 0x1ff)
+DECLARE_INSN(jal, 0x6f, 0x7f)
+DECLARE_INSN(lwu, 0x303, 0x3ff)
+DECLARE_INSN(vlsegstbu, 0xa0b, 0xfff)
+DECLARE_INSN(c_beq, 0x10, 0x1f)
+DECLARE_INSN(vlhu, 0x28b, 0x3fffff)
+DECLARE_INSN(vfsstd, 0x158f, 0x1ffff)
+DECLARE_INSN(c_bne, 0x11, 0x1f)
+DECLARE_INSN(fnmadd_d, 0xcf, 0x1ff)
+DECLARE_INSN(fence_g_cv, 0x3af, 0x3ff)
+DECLARE_INSN(amoadd_d, 0x1ab, 0x1ffff)
+DECLARE_INSN(c_sw, 0xd, 0x1f)
+DECLARE_INSN(amomax_w, 0x152b, 0x1ffff)
+DECLARE_INSN(c_move, 0x2, 0x801f)
+DECLARE_INSN(fmovn, 0xef7, 0x1ffff)
+DECLARE_INSN(c_fsw, 0x16, 0x1f)
+DECLARE_INSN(c_j, 0x8002, 0x801f)
+DECLARE_INSN(mulhsu, 0x533, 0x1ffff)
+DECLARE_INSN(c_sd, 0xc, 0x1f)
+DECLARE_INSN(amoadd_w, 0x12b, 0x1ffff)
+DECLARE_INSN(fcvt_d_lu, 0xd0d3, 0x3ff1ff)
+DECLARE_INSN(amomax_d, 0x15ab, 0x1ffff)
+DECLARE_INSN(fcvt_w_d, 0xa0d3, 0x3ff1ff)
+DECLARE_INSN(fmovz, 0xaf7, 0x1ffff)
+DECLARE_INSN(c_or3, 0x21c, 0x31f)
+DECLARE_INSN(vmvv, 0x73, 0x3fffff)
+DECLARE_INSN(vfssegstw, 0xd0f, 0xfff)
+DECLARE_INSN(slt, 0x133, 0x1ffff)
+DECLARE_INSN(mxtf_d, 0x1e0d3, 0x3fffff)
+DECLARE_INSN(sllw, 0xbb, 0x1ffff)
+DECLARE_INSN(amoor_d, 0xdab, 0x1ffff)
+DECLARE_INSN(slti, 0x113, 0x3ff)
+DECLARE_INSN(remu, 0x7b3, 0x1ffff)
+DECLARE_INSN(flw, 0x107, 0x3ff)
+DECLARE_INSN(remw, 0x73b, 0x1ffff)
+DECLARE_INSN(sltu, 0x1b3, 0x1ffff)
+DECLARE_INSN(slli, 0x93, 0x3f03ff)
+DECLARE_INSN(c_and3, 0x31c, 0x31f)
+DECLARE_INSN(vssegw, 0x210f, 0x1ffff)
+DECLARE_INSN(amoor_w, 0xd2b, 0x1ffff)
+DECLARE_INSN(vsd, 0x18f, 0x3fffff)
+DECLARE_INSN(beq, 0x63, 0x3ff)
+DECLARE_INSN(fld, 0x187, 0x3ff)
+DECLARE_INSN(mxtf_s, 0x1e053, 0x3fffff)
+DECLARE_INSN(fsub_s, 0x1053, 0x1f1ff)
+DECLARE_INSN(and, 0x3b3, 0x1ffff)
+DECLARE_INSN(vtcfgivl, 0x1f3, 0x3ff)
+DECLARE_INSN(lbu, 0x203, 0x3ff)
+DECLARE_INSN(vf, 0x3f3, 0xf80003ff)
+DECLARE_INSN(vlsegstw, 0x90b, 0xfff)
+DECLARE_INSN(syscall, 0x77, 0xffffffff)
+DECLARE_INSN(fsgnj_s, 0x5053, 0x1ffff)
+DECLARE_INSN(c_addi, 0x1, 0x1f)
+DECLARE_INSN(vfmvv, 0x173, 0x3fffff)
+DECLARE_INSN(vlstwu, 0x130b, 0x1ffff)
+DECLARE_INSN(c_sub3, 0x11c, 0x31f)
+DECLARE_INSN(vsh, 0x8f, 0x3fffff)
+DECLARE_INSN(vlsegstb, 0x80b, 0xfff)
+DECLARE_INSN(vlsegstd, 0x98b, 0xfff)
+DECLARE_INSN(vflsegd, 0x258b, 0x1ffff)
+DECLARE_INSN(vflsegw, 0x250b, 0x1ffff)
+DECLARE_INSN(vlsegsth, 0x88b, 0xfff)
+DECLARE_INSN(fsgnj_d, 0x50d3, 0x1ffff)
+DECLARE_INSN(vflsegstw, 0xd0b, 0xfff)
+DECLARE_INSN(c_sub, 0x801a, 0x801f)
+DECLARE_INSN(mulhu, 0x5b3, 0x1ffff)
+DECLARE_INSN(fcvt_l_d, 0x80d3, 0x3ff1ff)
+DECLARE_INSN(vmsv, 0x873, 0x3fffff)
+DECLARE_INSN(vmst, 0x1073, 0x1ffff)
+DECLARE_INSN(fadd_d, 0xd3, 0x1f1ff)
+DECLARE_INSN(fcvt_s_wu, 0xf053, 0x3ff1ff)
+DECLARE_INSN(rdnpc, 0x26b, 0x7ffffff)
+DECLARE_INSN(fcvt_s_l, 0xc053, 0x3ff1ff)
+DECLARE_INSN(vflsegstd, 0xd8b, 0xfff)
+DECLARE_INSN(c_add, 0x1a, 0x801f)
+DECLARE_INSN(fcvt_lu_d, 0x90d3, 0x3ff1ff)
+DECLARE_INSN(vfld, 0x58b, 0x3fffff)
+DECLARE_INSN(fsub_d, 0x10d3, 0x1f1ff)
+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(c_srai, 0x1019, 0x1c1f)
+DECLARE_INSN(amomin_w, 0x112b, 0x1ffff)
+DECLARE_INSN(fsgnjn_s, 0x6053, 0x1ffff)
+DECLARE_INSN(c_slli32, 0x419, 0x1c1f)
+DECLARE_INSN(vlsegwu, 0x230b, 0x1ffff)
+DECLARE_INSN(vfsw, 0x50f, 0x3fffff)
+DECLARE_INSN(amoswap_d, 0x5ab, 0x1ffff)
+DECLARE_INSN(fence_l_v, 0x22f, 0x3ff)
+DECLARE_INSN(fsqrt_d, 0x40d3, 0x3ff1ff)
+DECLARE_INSN(vflw, 0x50b, 0x3fffff)
+DECLARE_INSN(fdiv_d, 0x30d3, 0x1f1ff)
+DECLARE_INSN(fmadd_d, 0xc3, 0x1ff)
+DECLARE_INSN(divw, 0x63b, 0x1ffff)
+DECLARE_INSN(amomin_d, 0x11ab, 0x1ffff)
+DECLARE_INSN(divu, 0x6b3, 0x1ffff)
+DECLARE_INSN(amoswap_w, 0x52b, 0x1ffff)
+DECLARE_INSN(vfsd, 0x58f, 0x3fffff)
+DECLARE_INSN(fadd_s, 0x53, 0x1f1ff)
+DECLARE_INSN(vlsegb, 0x200b, 0x1ffff)
+DECLARE_INSN(fsd, 0x1a7, 0x3ff)
+DECLARE_INSN(vlsegd, 0x218b, 0x1ffff)
+DECLARE_INSN(vlsegh, 0x208b, 0x1ffff)
+DECLARE_INSN(sw, 0x123, 0x3ff)
+DECLARE_INSN(fmsub_s, 0x47, 0x1ff)
+DECLARE_INSN(vfssegw, 0x250f, 0x1ffff)
+DECLARE_INSN(c_addiw, 0x1d, 0x1f)
+DECLARE_INSN(lhu, 0x283, 0x3ff)
+DECLARE_INSN(sh, 0xa3, 0x3ff)
+DECLARE_INSN(vlsegw, 0x210b, 0x1ffff)
+DECLARE_INSN(fsw, 0x127, 0x3ff)
+DECLARE_INSN(vlbu, 0x20b, 0x3fffff)
+DECLARE_INSN(sb, 0x23, 0x3ff)
+DECLARE_INSN(fmsub_d, 0xc7, 0x1ff)
+DECLARE_INSN(vlseghu, 0x228b, 0x1ffff)
+DECLARE_INSN(vssegb, 0x200f, 0x1ffff)
+DECLARE_INSN(vfssegd, 0x258f, 0x1ffff)
+DECLARE_INSN(sd, 0x1a3, 0x3ff)
index f2ebaab..7659a97 100644 (file)
@@ -1,18 +1,18 @@
-#ifndef _RISCV_COP0_H
-#define _RISCV_COP0_H
+#ifndef _RISCV_PCR_H
+#define _RISCV_PCR_H
 
-#define SR_ET    0x0000000000000001
-#define SR_EF    0x0000000000000002
-#define SR_EV    0x0000000000000004
-#define SR_EC    0x0000000000000008
-#define SR_PS    0x0000000000000010
-#define SR_S     0x0000000000000020
-#define SR_UX    0x0000000000000040
-#define SR_SX    0x0000000000000080
-#define SR_IM    0x000000000000FF00
-#define SR_VM    0x0000000000010000
-
-#define SR_IM_SHIFT 8
+#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_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_TOHOST   16
-#define PCR_FROMHOST 17
-#define PCR_CONSOLE  18
+#define PCR_VECBANK  18
+#define PCR_VECCFG   19
+#define PCR_RESET    29
+#define PCR_TOHOST   30
+#define PCR_FROMHOST 31
 
-#define IPI_IRQ   5
-#define TIMER_IRQ 7
+#define IRQ_IPI   5
+#define IRQ_TIMER 7
 
 #define CAUSE_MISALIGNED_FETCH 0
 #define CAUSE_FAULT_FETCH 1
 #define CAUSE_FAULT_LOAD 10
 #define CAUSE_FAULT_STORE 11
 #define CAUSE_VECTOR_DISABLED 12
-#define CAUSE_IRQ0 16
-#define CAUSE_IRQ1 17
-#define CAUSE_IRQ2 18
-#define CAUSE_IRQ3 19
-#define CAUSE_IRQ4 20
-#define CAUSE_IRQ5 21
-#define CAUSE_IRQ6 22
-#define CAUSE_IRQ7 23
-#define NUM_CAUSES 24
+#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); \
-          asm volatile ("mtpcr %0,cr%1"::"r"(__tmp),"i"(reg)); })
+#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 irq_disable() asm volatile("di")
-#define irq_enable() asm volatile("ei")
+#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
 
index dc834dc..a80667e 100644 (file)
@@ -14,7 +14,7 @@ void proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
        memset(tf, 0, sizeof(*tf));
 
        tf->gpr[30] = stack_top-64;
-       tf->sr = SR_S | (mfpcr(PCR_SR) & SR_IM) | SR_SX | SR_UX | SR_VM;
+       tf->sr = SR_S | (mfpcr(PCR_SR) & SR_IM) | SR_S64 | SR_U64 | SR_VM;
 
        tf->epc = entryp;
 
@@ -25,7 +25,7 @@ void proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
 
 void proc_secure_trapframe(struct trapframe *tf)
 {
-       tf->sr = SR_S | (mfpcr(PCR_SR) & SR_IM) | SR_SX | SR_UX | SR_VM;
+       tf->sr = SR_S | (mfpcr(PCR_SR) & SR_IM) | SR_S64 | SR_U64 | SR_VM;
 }
 
 /* Called when we are currently running an address space on our core and want to
index b41b7c3..8e99ef2 100644 (file)
@@ -10,7 +10,7 @@ typedef struct trapframe
   uintptr_t sr;
   uintptr_t epc;
   uintptr_t badvaddr;
-  uintptr_t cause;
+  long cause;
   uintptr_t insn;
 } trapframe_t;
 
index 637643c..bc5bde2 100644 (file)
@@ -30,13 +30,13 @@ set_core_timer(uint32_t usec, bool periodic)
 
          mtpcr(PCR_COUNT, 0);
          mtpcr(PCR_COMPARE, clocks);
-         mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (TIMER_IRQ+SR_IM_SHIFT)));
+         mtpcr(PCR_SR, mfpcr(PCR_SR) | (1 << (IRQ_TIMER+SR_IM_SHIFT)));
 
          enable_irqsave(&irq_state);
        }
        else
        {
-         mtpcr(PCR_SR, mfpcr(PCR_SR) & ~(1 << (TIMER_IRQ+SR_IM_SHIFT)));
+         mtpcr(PCR_SR, mfpcr(PCR_SR) & ~(1 << (IRQ_TIMER+SR_IM_SHIFT)));
        }
 }
 
index d93bde0..8533664 100644 (file)
@@ -389,7 +389,7 @@ handle_breakpoint(trapframe_t* state)
 void
 handle_trap(trapframe_t* tf)
 {
-       static void (*const trap_handlers[NUM_CAUSES])(trapframe_t*) = {
+       static void (*const trap_handlers[])(trapframe_t*) = {
          [CAUSE_MISALIGNED_FETCH] = handle_misaligned_fetch,
          [CAUSE_FAULT_FETCH] = handle_fault_fetch,
          [CAUSE_ILLEGAL_INSTRUCTION] = handle_illegal_instruction,
@@ -401,12 +401,26 @@ handle_trap(trapframe_t* tf)
          [CAUSE_MISALIGNED_STORE] = handle_misaligned_store,
          [CAUSE_FAULT_LOAD] = handle_fault_load,
          [CAUSE_FAULT_STORE] = handle_fault_store,
-         [CAUSE_IRQ0 + IPI_IRQ] = handle_ipi,
-         [CAUSE_IRQ0 + TIMER_IRQ] = handle_timer_interrupt,
+       };
+
+       static void (*const irq_handlers[])(trapframe_t*) = {
+         [IRQ_TIMER] = handle_timer_interrupt,
+         [IRQ_IPI] = handle_ipi,
        };
        
-       assert(tf->cause < NUM_CAUSES && trap_handlers[tf->cause]);
-       trap_handlers[tf->cause](tf);
+       if (tf->cause < 0)
+       {
+               uint8_t irq = tf->cause;
+               assert(irq < sizeof(irq_handlers)/sizeof(irq_handlers[0]) &&
+                      irq_handlers[irq]);
+               irq_handlers[irq](tf);
+       }
+       else
+       {
+               assert(tf->cause < sizeof(trap_handlers)/sizeof(trap_handlers[0]) &&
+                      trap_handlers[tf->cause]);
+               trap_handlers[tf->cause](tf);
+       }
        
        /* Return to the current process, which should be runnable.  If we're the
         * kernel, we should just return naturally.  Note that current and tf need