diff options
Diffstat (limited to 'rvcontroller.lua')
| -rw-r--r-- | rvcontroller.lua | 81 |
1 files changed, 69 insertions, 12 deletions
diff --git a/rvcontroller.lua b/rvcontroller.lua index 6f97a32..9d9a337 100644 --- a/rvcontroller.lua +++ b/rvcontroller.lua @@ -469,7 +469,7 @@ local function readcsr(address) false, --Zfa false, --Zfh false, --Zfhmin - false, --Zicboz + true, --Zicboz true, --Zicond false, --Zihintntl true, --Zihintpause @@ -514,9 +514,9 @@ local function readcsr(address) true, --Zifencei mem.isa.m, --Zmmul false, --Zibi - false, --supm(?) + false, --supm(S-mode?) true, --Zicntr - false, --Zihpm + true, --Zihpm false, --Zfbfmin false, --Zvfbfmin false, --Zvfbfwma @@ -576,6 +576,11 @@ local function writecsr(address,data) fault = 2 fval = readram(mem.registers.pc,4) return + elseif (address >= 0xc03 and address <= 0xc1f) or (address >= 0xc83 and address < 0xc9f) then + --One of the read-only CSRs from Zihpm + fault = 2 + fval = readram(mem.registers.pc,4) + return elseif address == 0xf11 or address == 0xf12 or address == 0xf13 or address == 0xf14 or address == 0xf15 then --Read-only machine information register fault = 2 @@ -644,6 +649,15 @@ local function writecsr(address,data) 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 + 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 + end local oldreason = reason if mem.mdt then writecsr(0x34b,reason) --mtval2 @@ -1973,6 +1987,15 @@ local operations = { interrupt(1,"checkinterrupt") return false,true end, + cbozero = function(rs1) + local address = getreg(rs1) + address = address - (address%0x100) + if address >= RAM_SIZE then + return trap(7,getreg(rs1)) + end + local segment = address/0x100 + mem.ram[segment] = string.rep(string.char(0),256) + end, } local function runinst(instruction) @@ -2438,11 +2461,22 @@ local function runinst(instruction) end end elseif opcode == 0x0f then - --Memory is always consistent on this implementation, - --so all fences can just turn into NOPs + local immbits = {[0] = bits[20],bits[21],bits[22],bits[23],bits[24],bits[25],bits[26],bits[27],bits[28],bits[29],bits[30],bits[31]} + local imm = implodebits(immbits,12) + local f3 = implodebits({[0] = bits[12],bits[13],bits[14]},3) + local rd = implodebits({[0] = bits[7],bits[8],bits[9],bits[10],bits[11]},5) + local rs1 = implodebits({[0] = bits[15],bits[16],bits[17],bits[18],bits[19]},5) if instruction == 0x0100000f then --pause return false,true + elseif f3 == 0 or f3 == 1 then + --fence, fence.tso, or fence.i + --Memory is always consistent on this implementation, + --so all fences can just turn into NOPs + return false,false + elseif f3 == 2 and rd == 0 and imm == 4 then + --cbo.zero + return operations.cbozero(rs1) end elseif opcode == 0x0b and mem.isa.x then --Custom0 instruction (currently all R-type) @@ -2828,7 +2862,10 @@ local function run(limit) first = false local instruction = readram(mem.registers.pc,4,true) if mem.elp and mem.mlpe then - if instruction%2^12 == 0x017 and mem.registers.pc%4 == 0 and (math.floor(instruction/2^12) == math.floor(getreg(7)/2^12) or math.floor(instruction/2^12) == 0) then + if instruction%2^12 == 0x017 + and mem.registers.pc%4 == 0 + and (math.floor(instruction/2^12) == math.floor(getreg(7)/2^12) + or math.floor(instruction/2^12) == 0) then mem.elp = false else trap(18,2) @@ -2935,6 +2972,14 @@ local csraliases = { minstreth = 0xb82, mseccfg = 0x747, ["h3.misa"] = 0xbf1, + hpmcounter3 = 0xc03, + hpmcounter4 = 0xc04, + hpmcounter5 = 0xc05, + hpmcounter6 = 0xc06, + hpmcounter3h = 0xc83, + hpmcounter4h = 0xc84, + hpmcounter5h = 0xc85, + hpmcounter6h = 0xc86, } if event.type == "program" or event.iid == "reset" then @@ -2969,12 +3014,20 @@ if event.type == "program" or event.iid == "reset" then [0x800] = 0, --Clock Controls [0x801] = 0, --MMIO Base Address [0xbf1] = 0, --h3.misa - [0xc00] = 0, --CYCLE - [0xc01] = 0, --TIME - [0xc02] = 0, --INSTRET - [0xc80] = 0, --CYCLEH - [0xc81] = 0, --TIMEH - [0xc82] = 0, --INSTRETH + [0xc00] = 0, --cycle + [0xc01] = 0, --time + [0xc02] = 0, --instret + [0xc03] = 0, --hpmcounter3 + [0xc04] = 0, --hpmcounter4 + [0xc05] = 0, --hpmcounter5 + [0xc06] = 0, --hpmcounter6 + [0xc80] = 0, --cycleh + [0xc81] = 0, --timeh + [0xc82] = 0, --instreth + [0xc83] = 0, --hpmcounter3h + [0xc84] = 0, --hpmcounter4h + [0xc85] = 0, --hpmcounter5h + [0xc86] = 0, --hpmcounter6h } for i=1,6 do mem.stdout[i] = "" end local mdisp = event.type == "program" and "\nReset: Cold" or "\nReset: Warm" @@ -3259,6 +3312,8 @@ 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 mem.inputwaiting then --Blocking read in progress if mem.inputwaittype == "string" then @@ -3336,6 +3391,8 @@ 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 --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) |
