aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/insns/eret.h6
-rw-r--r--riscv/mmu.cc26
-rw-r--r--riscv/mmu.h20
-rw-r--r--riscv/opcodes.h10
-rw-r--r--riscv/pcr.h68
-rw-r--r--riscv/processor.cc15
6 files changed, 81 insertions, 64 deletions
diff --git a/riscv/insns/eret.h b/riscv/insns/eret.h
index cd968bd..96d951c 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_pcr(PCR_SR, ((sr & SR_PS) ? sr : (sr & ~SR_S)) | SR_ET);
+set_pcr(PCR_SR, ((sr & ~(SR_PS | SR_EI)) |
+ ((sr & SR_PS) ? 0 : SR_S)) |
+ ((sr & SR_PEI) ? SR_EI : 0));
set_pc(epc);
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 8b63a43..01cbb97 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -40,9 +40,9 @@ reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
reg_t pte_perm = pte & PTE_PERM;
if (proc == NULL || (proc->sr & SR_S))
pte_perm = (pte_perm/(PTE_SX/PTE_UX)) & PTE_PERM;
- pte_perm |= pte & PTE_E;
+ pte_perm |= pte & PTE_V;
- reg_t perm = (fetch ? PTE_UX : store ? PTE_UW : PTE_UR) | PTE_E;
+ reg_t perm = (fetch ? PTE_UX : store ? PTE_UW : PTE_UR) | PTE_V;
if(unlikely((pte_perm & perm) != perm))
{
if (fetch)
@@ -53,7 +53,7 @@ reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
}
reg_t pgoff = addr & (PGSIZE-1);
- reg_t pgbase = pte >> PTE_PPN_SHIFT << PGSHIFT;
+ reg_t pgbase = pte >> PGSHIFT << PGSHIFT;
reg_t paddr = pgbase + pgoff;
if (unlikely(tracer.interested_in_range(pgbase, pgbase + PGSIZE, store, fetch)))
@@ -80,7 +80,7 @@ pte_t mmu_t::walk(reg_t addr)
else if (proc == NULL || !(proc->sr & SR_VM))
{
if(addr < memsz)
- pte = PTE_E | PTE_PERM | ((addr >> PGSHIFT) << PTE_PPN_SHIFT);
+ pte = PTE_V | PTE_PERM | ((addr >> PGSHIFT) << PGSHIFT);
}
else
{
@@ -97,23 +97,23 @@ pte_t mmu_t::walk(reg_t addr)
break;
ptd = *(pte_t*)(mem+pte_addr);
- if(ptd & PTE_E)
+
+ if (!(ptd & PTE_V)) // invalid mapping
+ break;
+ else if (ptd & PTE_T) // next level of page table
+ base = (ptd >> PGSHIFT) << PGSHIFT;
+ else // the actual PTE
{
// if this PTE is from a larger PT, fake a leaf
// PTE so the TLB will work right
reg_t vpn = addr >> PGSHIFT;
- ptd |= (vpn & ((1<<(ptshift))-1)) << PTE_PPN_SHIFT;
+ ptd |= (vpn & ((1<<(ptshift))-1)) << PGSHIFT;
- // fault if physical addr is invalid
- reg_t ppn = ptd >> PTE_PPN_SHIFT;
- if((ppn << PGSHIFT) + (addr & (PGSIZE-1)) < memsz)
+ // fault if physical addr is out of range
+ if (((ptd >> PGSHIFT) << PGSHIFT) < memsz)
pte = ptd;
break;
}
- else if(!(ptd & PTE_T))
- break;
-
- base = (ptd >> PTE_PPN_SHIFT) << PGSHIFT;
}
}
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 64b11d3..a754b60 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -13,28 +13,14 @@
// virtual memory configuration
typedef reg_t pte_t;
-const reg_t LEVELS = sizeof(pte_t) == sizeof(uint64_t) ? 3 : 2;
-const reg_t PGSHIFT = 13;
+const reg_t LEVELS = sizeof(pte_t) == 8 ? 3 : 2;
+const reg_t PTIDXBITS = 10;
+const reg_t PGSHIFT = PTIDXBITS + (sizeof(pte_t) == 8 ? 3 : 2);
const reg_t PGSIZE = 1 << PGSHIFT;
-const reg_t PTIDXBITS = PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2);
const reg_t VPN_BITS = PTIDXBITS * LEVELS;
const reg_t PPN_BITS = 8*sizeof(reg_t) - PGSHIFT;
const reg_t VA_BITS = VPN_BITS + PGSHIFT;
-// page table entry (PTE) fields
-#define PTE_T 0x001 // Entry is a page Table descriptor
-#define PTE_E 0x002 // Entry is a page table Entry
-#define PTE_R 0x004 // Referenced
-#define PTE_D 0x008 // Dirty
-#define PTE_UX 0x010 // User eXecute permission
-#define PTE_UW 0x020 // User Read permission
-#define PTE_UR 0x040 // User Write permission
-#define PTE_SX 0x080 // Supervisor eXecute permission
-#define PTE_SW 0x100 // Supervisor Read permission
-#define PTE_SR 0x200 // Supervisor Write permission
-#define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX)
-#define PTE_PPN_SHIFT 13 // LSB of physical page number in the PTE
-
// this class implements a processor's port into the virtual memory system.
// an MMU and instruction cache are maintained for simulator performance.
class mmu_t
diff --git a/riscv/opcodes.h b/riscv/opcodes.h
index e3fcf16..fd86d9d 100644
--- a/riscv/opcodes.h
+++ b/riscv/opcodes.h
@@ -13,7 +13,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, 0x3fffff)
+DECLARE_INSN(mfpcr, 0xf3, 0x3fffff)
DECLARE_INSN(fmax_d, 0x190d3, 0x1ffff)
DECLARE_INSN(bne, 0xe3, 0x3ff)
DECLARE_INSN(rdcycle, 0x277, 0x7ffffff)
@@ -21,7 +21,7 @@ DECLARE_INSN(fcvt_s_d, 0x11053, 0x3ff1ff)
DECLARE_INSN(bgeu, 0x3e3, 0x3ff)
DECLARE_INSN(fadd_d, 0xd3, 0x1f1ff)
DECLARE_INSN(sltiu, 0x193, 0x3ff)
-DECLARE_INSN(mtpcr, 0x1fb, 0x1ffff)
+DECLARE_INSN(mtpcr, 0x73, 0x1ffff)
DECLARE_INSN(break, 0xf7, 0xffffffff)
DECLARE_INSN(fcvt_s_w, 0xe053, 0x3ff1ff)
DECLARE_INSN(mul, 0x433, 0x1ffff)
@@ -47,7 +47,7 @@ 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(eret, 0x273, 0xffffffff)
DECLARE_INSN(blt, 0x263, 0x3ff)
DECLARE_INSN(mtfsr, 0x1f053, 0x3fffff)
DECLARE_INSN(sc_w, 0x1052b, 0x1ffff)
@@ -90,7 +90,7 @@ DECLARE_INSN(amomaxu_w, 0x1d2b, 0x1ffff)
DECLARE_INSN(fcvt_wu_s, 0xb053, 0x3ff1ff)
DECLARE_INSN(rdtime, 0x677, 0x7ffffff)
DECLARE_INSN(andi, 0x393, 0x3ff)
-DECLARE_INSN(clearpcr, 0x7b, 0x3ff)
+DECLARE_INSN(clearpcr, 0x1f3, 0x3ff)
DECLARE_INSN(fmv_x_s, 0x1c053, 0x3fffff)
DECLARE_INSN(fsgnjn_d, 0x60d3, 0x1ffff)
DECLARE_INSN(fnmadd_s, 0x4f, 0x1ff)
@@ -129,7 +129,7 @@ DECLARE_INSN(amomax_w, 0x152b, 0x1ffff)
DECLARE_INSN(fsgnj_d, 0x50d3, 0x1ffff)
DECLARE_INSN(mulhu, 0x5b3, 0x1ffff)
DECLARE_INSN(fence_v_g, 0x2af, 0x3ff)
-DECLARE_INSN(setpcr, 0xfb, 0x3ff)
+DECLARE_INSN(setpcr, 0x173, 0x3ff)
DECLARE_INSN(fcvt_lu_s, 0x9053, 0x3ff1ff)
DECLARE_INSN(fcvt_s_l, 0xc053, 0x3ff1ff)
DECLARE_INSN(auipc, 0x17, 0x7f)
diff --git a/riscv/pcr.h b/riscv/pcr.h
index 11bfc65..77cee01 100644
--- a/riscv/pcr.h
+++ b/riscv/pcr.h
@@ -3,18 +3,18 @@
#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_S 0x00000001
+#define SR_PS 0x00000002
+#define SR_EI 0x00000004
+#define SR_PEI 0x00000008
+#define SR_EF 0x00000010
+#define SR_U64 0x00000020
+#define SR_S64 0x00000040
+#define SR_VM 0x00000080
+#define SR_EV 0x00000100
#define SR_IM 0x00FF0000
#define SR_IP 0xFF000000
-#define SR_ZERO ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_U64|SR_S64|SR_VM|SR_IM|SR_IP)
+#define SR_ZERO ~(SR_S|SR_PS|SR_EI|SR_PEI|SR_EF|SR_U64|SR_S64|SR_VM|SR_EV|SR_IM|SR_IP)
#define SR_IM_SHIFT 16
#define SR_IP_SHIFT 24
@@ -22,16 +22,18 @@
#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_CAUSE 4
+#define PCR_PTBR 5
+#define PCR_ASID 6
+#define PCR_FATC 7
+#define PCR_COUNT 8
+#define PCR_COMPARE 9
+#define PCR_SEND_IPI 10
+#define PCR_CLR_IPI 11
+#define PCR_HARTID 12
+#define PCR_IMPL 13
+#define PCR_K0 14
+#define PCR_K1 15
#define PCR_VECBANK 18
#define PCR_VECCFG 19
#define PCR_RESET 29
@@ -65,8 +67,30 @@
#define CAUSE_VECTOR_FAULT_LOAD 30
#define CAUSE_VECTOR_FAULT_STORE 31
+// page table entry (PTE) fields
+#define PTE_V 0x001 // Entry is a page Table descriptor
+#define PTE_T 0x002 // Entry is a page Table, not a terminal node
+#define PTE_G 0x004 // Global
+#define PTE_UR 0x008 // User Write permission
+#define PTE_UW 0x010 // User Read permission
+#define PTE_UX 0x020 // User eXecute permission
+#define PTE_SR 0x040 // Supervisor Read permission
+#define PTE_SW 0x080 // Supervisor Write permission
+#define PTE_SX 0x100 // Supervisor eXecute permission
+#define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX)
+
#ifdef __riscv
+#ifdef __riscv64
+# define RISCV_PGLEVELS 3
+# define RISCV_PGSHIFT 13
+#else
+# define RISCV_PGLEVELS 2
+# define RISCV_PGSHIFT 12
+#endif
+#define RISCV_PGLEVEL_BITS 10
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
#define ASM_CR(r) _ASM_CR(r)
#define _ASM_CR(r) cr##r
@@ -88,6 +112,10 @@
asm volatile ("clearpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \
__tmp; })
+#define rdcycle() ({ unsigned long __tmp; \
+ asm volatile ("rdcycle %0" : "=r"(__tmp)); \
+ __tmp; })
+
#endif
#endif
diff --git a/riscv/processor.cc b/riscv/processor.cc
index e7c0872..4dff486 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -68,7 +68,7 @@ void processor_t::take_interrupt()
uint32_t interrupts = (sr & SR_IP) >> SR_IP_SHIFT;
interrupts &= (sr & SR_IM) >> SR_IM_SHIFT;
- if(interrupts && (sr & SR_ET))
+ if(interrupts && (sr & SR_EI))
for(int i = 0; ; i++, interrupts >>= 1)
if(interrupts & 1)
throw interrupt_t(i);
@@ -144,7 +144,9 @@ void processor_t::take_trap(reg_t t, bool noisy)
}
// switch to supervisor, set previous supervisor bit, disable traps
- set_pcr(PCR_SR, (((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
+ set_pcr(PCR_SR, (((sr & ~SR_EI) | SR_S) & ~SR_PS & ~SR_PEI) |
+ ((sr & SR_S) ? SR_PS : 0) |
+ ((sr & SR_EI) ? SR_PEI : 0));
cause = t;
epc = pc;
pc = evec;
@@ -177,9 +179,6 @@ void processor_t::set_pcr(int which, reg_t val)
#ifndef RISCV_ENABLE_FPU
sr &= ~SR_EF;
#endif
-#ifndef RISCV_ENABLE_RVC
- sr &= ~SR_EC;
-#endif
#ifndef RISCV_ENABLE_VEC
sr &= ~SR_EV;
#endif
@@ -245,7 +244,11 @@ reg_t processor_t::get_pcr(int which)
return cause;
case PCR_PTBR:
return mmu.get_ptbr();
- case PCR_COREID:
+ case PCR_ASID:
+ return 0;
+ case PCR_FATC:
+ mmu.flush_tlb();
+ case PCR_HARTID:
return id;
case PCR_IMPL:
return 1;