summaryrefslogtreecommitdiff
path: root/rvcontroller.lua
diff options
context:
space:
mode:
Diffstat (limited to 'rvcontroller.lua')
-rw-r--r--rvcontroller.lua176
1 files changed, 160 insertions, 16 deletions
diff --git a/rvcontroller.lua b/rvcontroller.lua
index 459116d..6a54c3c 100644
--- a/rvcontroller.lua
+++ b/rvcontroller.lua
@@ -428,6 +428,23 @@ local function readcsr(address)
bits[9] = mem.mpelp
bits[10] = mem.mdt
return implodebits(bits,32)
+ elseif address == 0x320 then --mcountinhibit
+ return implodebits(mem.mcountinhibit,32)
+ elseif address >= 0x327 and address <= 0x33f then --mhpmevent7-mhpmevent31
+ return 0
+ elseif address >= 0xb07 and address <= 0xb1f then --mhpmcounter7-mhpmcounter31
+ return 0
+ elseif address >= 0xb87 and address <= 0xb9f then --mhpmcounter7h-mhpmcounter31h
+ return 0
+ elseif address >= 0xb03 and address <= 0xb06 then --mhpmcounter3-mhpmcounter6
+ --Transform into hpmcounter3-hpmcounter6
+ address = address + 0x100
+ elseif address >= 0xb83 and address <= 0xb86 then --mhpmcounter3h-mhpmcounter6h
+ --Transform into hpmcounter3h-hpmcounter6h
+ address = address + 0x100
+ 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 == 0x747 then --mseccfg
local bits = {}
bits[10] = mem.mlpe
@@ -592,6 +609,26 @@ local function writecsr(address,data)
fault = 2
fval = readram(mem.registers.pc,4)
return
+ elseif address == 0x320 then --mcountinhibit
+ mem.mcountinhibit = explodebits(data,32)
+ mem.mcountinhibit[1] = nil
+ for i=7,31 do mem.mcountinhibit[i] = nil end
+ return
+ elseif address >= 0x323 and address <= 0x33f then --mhpmevent3-mhpmevent31
+ return
+ elseif address >= 0xb07 and address <= 0xb1f then --mhpmcounter7-mhpmcounter31
+ return
+ elseif address >= 0xb87 and address <= 0xb9f then --mhpmcounter7h-mhpmcounter31h
+ return
+ elseif address >= 0xb03 and address <= 0xb06 then --mhpmcounter3-mhpmcounter6
+ --Transform into hpmcounter3-hpmcounter6 (but allow the write)
+ address = address + 0x100
+ elseif address >= 0xb83 and address <= 0xb86 then --mhpmcounter3h-mhpmcounter6h
+ --Transform into hpmcounter3h-hpmcounter6h (but allow the write)
+ address = address + 0x100
+ 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
elseif address == 0xf11 or address == 0xf12 or address == 0xf13 or address == 0xf14 or address == 0xf15 then
--Read-only machine information register
fault = 2
@@ -662,12 +699,16 @@ end
local function trap(reason,val)
if reason >= 0x8000000 then
--Interrupt
- mem.csr[0xc03] = (mem.csr[0xc03]+1)%0x100000000 --hpmcounter3
- if mem.csr[0xc03] == 0 then mem.csr[0xc83] = (mem.csr[0xc83]+1)%0x100000000 end --hpmcounter3h
+ if not mem.mcountinhibit[3] then
+ mem.csr[0xc03] = (mem.csr[0xc03]+1)%0x100000000 --hpmcounter3
+ if mem.csr[0xc03] == 0 then mem.csr[0xc83] = (mem.csr[0xc83]+1)%0x100000000 end --hpmcounter3h
+ end
else
--Other
- mem.csr[0xc04] = (mem.csr[0xc04]+1)%0x100000000 --hpmcounter4
- if mem.csr[0xc04] == 0 then mem.csr[0xc84] = (mem.csr[0xc84]+1)%0x100000000 end --hpmcounter4h
+ if not mem.mcountinhibit[4] then
+ mem.csr[0xc04] = (mem.csr[0xc04]+1)%0x100000000 --hpmcounter4
+ if mem.csr[0xc04] == 0 then mem.csr[0xc84] = (mem.csr[0xc84]+1)%0x100000000 end --hpmcounter4h
+ end
end
local oldreason = reason
if mem.mdt then
@@ -3110,10 +3151,12 @@ end
local function run(limit)
--0xc00 = CYCLE
--0xc80 = CYCLEH
- 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)
- mem.csr[0xc00] = mem.csr[0xc00]%2^32
+ if not mem.mcountinhibit[0] 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)
+ mem.csr[0xc00] = mem.csr[0xc00]%2^32
+ end
end
--0xc01 = TIME
@@ -3166,10 +3209,12 @@ local function run(limit)
--0xc02 = INSTRET
--0xc82 = INSTRETH
- 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)
- mem.csr[0xc02] = mem.csr[0xc02]%2^32
+ if not mem.mcountinhibit[2] 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)
+ mem.csr[0xc02] = mem.csr[0xc02]%2^32
+ end
end
limit = limit - 1
until (not mem.running) or limit <= 0
@@ -3253,6 +3298,95 @@ local csraliases = {
hpmcounter4h = 0xc84,
hpmcounter5h = 0xc85,
hpmcounter6h = 0xc86,
+ mhpmcounter3 = 0xb03,
+ mhpmcounter4 = 0xb04,
+ mhpmcounter5 = 0xb05,
+ mhpmcounter6 = 0xb06,
+ mhpmcounter7 = 0xb07,
+ mhpmcounter8 = 0xb08,
+ mhpmcounter9 = 0xb09,
+ mhpmcounter10 = 0xb0a,
+ mhpmcounter11 = 0xb0b,
+ mhpmcounter12 = 0xb0c,
+ mhpmcounter13 = 0xb0d,
+ mhpmcounter14 = 0xb0e,
+ mhpmcounter15 = 0xb0f,
+ mhpmcounter16 = 0xb10,
+ mhpmcounter17 = 0xb11,
+ mhpmcounter18 = 0xb12,
+ mhpmcounter19 = 0xb13,
+ mhpmcounter20 = 0xb14,
+ mhpmcounter21 = 0xb15,
+ mhpmcounter22 = 0xb16,
+ mhpmcounter23 = 0xb17,
+ mhpmcounter24 = 0xb18,
+ mhpmcounter25 = 0xb19,
+ mhpmcounter26 = 0xb1a,
+ mhpmcounter27 = 0xb1b,
+ mhpmcounter28 = 0xb1c,
+ mhpmcounter29 = 0xb1d,
+ mhpmcounter30 = 0xb1e,
+ mhpmcounter31 = 0xb1f,
+ mhpmcounter3h = 0xb83,
+ mhpmcounter4h = 0xb84,
+ mhpmcounter5h = 0xb85,
+ mhpmcounter6h = 0xb86,
+ mhpmcounter7h = 0xb87,
+ mhpmcounter8h = 0xb88,
+ mhpmcounter9h = 0xb89,
+ mhpmcounter10h = 0xb8a,
+ mhpmcounter11h = 0xb8b,
+ mhpmcounter12h = 0xb8c,
+ mhpmcounter13h = 0xb8d,
+ mhpmcounter14h = 0xb8e,
+ mhpmcounter15h = 0xb8f,
+ mhpmcounter16h = 0xb90,
+ mhpmcounter17h = 0xb91,
+ mhpmcounter18h = 0xb92,
+ mhpmcounter19h = 0xb93,
+ mhpmcounter20h = 0xb94,
+ mhpmcounter21h = 0xb95,
+ mhpmcounter22h = 0xb96,
+ mhpmcounter23h = 0xb97,
+ mhpmcounter24h = 0xb98,
+ mhpmcounter25h = 0xb99,
+ mhpmcounter26h = 0xb9a,
+ mhpmcounter27h = 0xb9b,
+ mhpmcounter28h = 0xb9c,
+ mhpmcounter29h = 0xb9d,
+ mhpmcounter30h = 0xb9e,
+ mhpmcounter31h = 0xb9f,
+ mhpmevent3 = 0x323,
+ mhpmevent4 = 0x324,
+ mhpmevent5 = 0x325,
+ mhpmevent6 = 0x326,
+ mhpmevent7 = 0x327,
+ mhpmevent8 = 0x328,
+ mhpmevent9 = 0x329,
+ mhpmevent10 = 0x32a,
+ mhpmevent11 = 0x32b,
+ mhpmevent12 = 0x32c,
+ mhpmevent13 = 0x32d,
+ mhpmevent14 = 0x32e,
+ mhpmevent15 = 0x32f,
+ mhpmevent16 = 0x330,
+ mhpmevent17 = 0x331,
+ mhpmevent18 = 0x332,
+ mhpmevent19 = 0x333,
+ mhpmevent20 = 0x334,
+ mhpmevent21 = 0x335,
+ mhpmevent22 = 0x336,
+ mhpmevent23 = 0x337,
+ mhpmevent24 = 0x338,
+ mhpmevent25 = 0x339,
+ mhpmevent26 = 0x33a,
+ mhpmevent27 = 0x33b,
+ mhpmevent28 = 0x33c,
+ mhpmevent29 = 0x33d,
+ mhpmevent30 = 0x33e,
+ mhpmevent31 = 0x33f,
+ mcountinhibit = 0x320,
+ mconfigptr = 0xf15,
}
if event.type == "program" or event.iid == "reset" then
@@ -3274,10 +3408,15 @@ if event.type == "program" or event.iid == "reset" then
[0xf12] = 53, --marchid (53 is RVController's officially assigned value, see https://github.com/riscv/riscv-isa-manual/blob/main/marchid.md )
[0xf13] = 0x6f435652, --mimpid ("RVCo")
[0xf14] = 0, --mhartid
+ [0xf15] = 0, --mconfigptr
[0x300] = 0, --mstatus
[0x301] = 0x40801107, --misa (RV32IMACBX)
[0x304] = 0, --mie
[0x305] = 0, --mtvec
+ [0x323] = 1, --mhpmevent3
+ [0x324] = 2, --mhpmevent4
+ [0x325] = 3, --mhpmevent5
+ [0x326] = 4, --mhpmevent6
[0x340] = 0, --mscratch
[0x341] = 0, --mepc
[0x342] = 0, --mcause
@@ -3337,6 +3476,7 @@ if event.type == "program" or event.iid == "reset" then
mem.mlpe = false
mem.elp = false
mem.mpelp = false
+ mem.mcountinhibit = {}
elseif event.type == "on" or event.type == "off" then
local pname = string.lower(event.pin.name)
local pstate = pin[pname]
@@ -3585,8 +3725,10 @@ elseif event.channel == "monitorkb" then
digiline_send("monitordisp","Unknown command")
end
elseif event.channel == "stdin" then
- mem.csr[0xc06] = (mem.csr[0xc06]+1)%0x100000000 --hpmcounter6
- if mem.csr[0xc06] == 0 then mem.csr[0xc86] = (mem.csr[0xc86]+1)%0x100000000 end --hpmcounter6h
+ if not mem.mcountinhibit[6] then
+ mem.csr[0xc06] = (mem.csr[0xc06]+1)%0x100000000 --hpmcounter6
+ if mem.csr[0xc06] == 0 then mem.csr[0xc86] = (mem.csr[0xc86]+1)%0x100000000 end --hpmcounter6h
+ end
if mem.inputwaiting then
--Blocking read in progress
if mem.inputwaittype == "string" then
@@ -3664,8 +3806,10 @@ elseif event.channel == "load" then
end
end
elseif event.type == "digiline" then
- mem.csr[0xc05] = (mem.csr[0xc05]+1)%0x100000000 --hpmcounter5
- if mem.csr[0xc05] == 0 then mem.csr[0xc85] = (mem.csr[0xc85]+1)%0x100000000 end --hpmcounter5h
+ if not mem.mcountinhibit[5] then
+ mem.csr[0xc05] = (mem.csr[0xc05]+1)%0x100000000 --hpmcounter5
+ if mem.csr[0xc05] == 0 then mem.csr[0xc85] = (mem.csr[0xc85]+1)%0x100000000 end --hpmcounter5h
+ end
--Unrecognized digilines signals get forwarded on to the program
event.channel = string.sub(event.channel,1,256)
event.msg = string.sub(tostring(event.msg),1,256)