diff options
Diffstat (limited to 'rvcontroller.lua')
| -rw-r--r-- | rvcontroller.lua | 176 |
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) |
