summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/_start_here.txt1
-rw-r--r--doc/csr.txt4
-rw-r--r--rvcontroller.lua24
3 files changed, 27 insertions, 2 deletions
diff --git a/doc/_start_here.txt b/doc/_start_here.txt
index b2693d1..b9dc6d0 100644
--- a/doc/_start_here.txt
+++ b/doc/_start_here.txt
@@ -88,6 +88,7 @@ RVController is intended to be compliant with the following specifications:
* Xh3bextm: Hazard3 bit extract multiple, Version 1.0
- Note: Defined in the Hazard3 reference manual, available at https://github.com/Wren6991/Hazard3/releases/download/v1.1/hazard3.pdf
* Machine-Level ISA, Version 1.13
+* "Smcntrpmf" Cycle and Instret Privilege Mode Filtering, Version 1.0
* "Smdbltrp" Double Trap Extension, Version 1.0
For full specification text, visit https://docs.riscv.org/reference/home/index.html
diff --git a/doc/csr.txt b/doc/csr.txt
index 866f2e3..2e88f67 100644
--- a/doc/csr.txt
+++ b/doc/csr.txt
@@ -10,6 +10,8 @@ The following standard CSRs are available:
* 0x305: mtvec
* 0x310: mstatush
* 0x320: mcountinhibit
+* 0x321: mcyclecfg
+* 0x322: minstretcfg
* 0x323 - 0x33f: mhpmevent3 - mhpmevent31
* 0x340: mscratch
* 0x341: mepc
@@ -17,6 +19,8 @@ The following standard CSRs are available:
* 0x343: mtval
* 0x344: mip
* 0x34b: mtval2
+* 0x721: mcyclecfgh
+* 0x722: minstretcfgh
* 0x747: mseccfg
* 0xb00: mcycle
* 0xb02: minstret
diff --git a/rvcontroller.lua b/rvcontroller.lua
index 6a54c3c..c4e27d6 100644
--- a/rvcontroller.lua
+++ b/rvcontroller.lua
@@ -445,6 +445,12 @@ local function readcsr(address)
elseif address == 0xb00 or address == 0xb02 or address == 0xb80 or address == 0xb82 then --mcycle(h)/minstret(h)
--Transform into cycle(h)/instret(h)
address = address + 0x100
+ elseif address == 0x321 or address == 0x322 then --mcyclecfg/minstretcfg
+ return 0
+ elseif address == 0x721 then --mcyclecfgh
+ return mem.cycleminh and 0x40000000 or 0
+ elseif address == 0x722 then --minstretcfgh
+ return mem.instretminh and 0x40000000 or 0
elseif address == 0x747 then --mseccfg
local bits = {}
bits[10] = mem.mlpe
@@ -626,6 +632,14 @@ local function writecsr(address,data)
elseif address >= 0xb83 and address <= 0xb86 then --mhpmcounter3h-mhpmcounter6h
--Transform into hpmcounter3h-hpmcounter6h (but allow the write)
address = address + 0x100
+ elseif address == 0x321 or address == 0x322 then --mcyclecfg/minstretcfg
+ return
+ elseif address == 0x721 then --mcyclecfgh
+ mem.cycleminh = explodebits(data,32)[30]
+ return
+ elseif address == 0x722 then --minstretcfgh
+ mem.instretminh = explodebits(data,32)[30]
+ return
elseif address == 0xb00 or address == 0xb02 or address == 0xb80 or address == 0xb82 then --mcycle(h)/minstret(h)
--Transform into cycle(h)/instret(h) (but allow the write)
address = address + 0x100
@@ -3151,7 +3165,7 @@ end
local function run(limit)
--0xc00 = CYCLE
--0xc80 = CYCLEH
- if not mem.mcountinhibit[0] then
+ if not (mem.mcountinhibit[0] or mem.cycleminh) then
mem.csr[0xc00] = mem.csr[0xc00] + 1
if mem.csr[0xc00] >= 2^32 then
mem.csr[0xc80] = mem.csr[0xc80] + math.floor(mem.csr[0xc00]/2^32)
@@ -3209,7 +3223,7 @@ local function run(limit)
--0xc02 = INSTRET
--0xc82 = INSTRETH
- if not mem.mcountinhibit[2] then
+ if not (mem.mcountinhibit[2] or mem.instretminh) then
mem.csr[0xc02] = mem.csr[0xc02] + 1
if mem.csr[0xc02] >= 2^32 then
mem.csr[0xc82] = mem.csr[0xc82] + math.floor(mem.csr[0xc02]/2^32)
@@ -3387,6 +3401,10 @@ local csraliases = {
mhpmevent31 = 0x33f,
mcountinhibit = 0x320,
mconfigptr = 0xf15,
+ mcyclecfg = 0x321,
+ minstretcfg = 0x322,
+ mcyclecfgh = 0x721,
+ minstretcfgh = 0x722,
}
if event.type == "program" or event.iid == "reset" then
@@ -3477,6 +3495,8 @@ if event.type == "program" or event.iid == "reset" then
mem.elp = false
mem.mpelp = false
mem.mcountinhibit = {}
+ mem.cycleminh = false
+ mem.instretminh = false
elseif event.type == "on" or event.type == "off" then
local pname = string.lower(event.pin.name)
local pstate = pin[pname]