summaryrefslogtreecommitdiff
path: root/rvcontroller.lua
diff options
context:
space:
mode:
authorcheapie <cheapiephp@gmail.com>2026-11-06 13:22:41 -0600
committercheapie <cheapiephp@gmail.com>2026-11-06 13:24:17 -0600
commitf1fe00423df3fda0ace4222d9d5e3d1976db3964 (patch)
tree0155ad01ad8a2ba1f18ae6cd59f3d0c912088580 /rvcontroller.lua
parentc3ca1afe6ba655b71db048b513801cd3d5acf406 (diff)
downloadrvcontroller-f1fe00423df3fda0ace4222d9d5e3d1976db3964.tar
rvcontroller-f1fe00423df3fda0ace4222d9d5e3d1976db3964.tar.gz
rvcontroller-f1fe00423df3fda0ace4222d9d5e3d1976db3964.tar.bz2
rvcontroller-f1fe00423df3fda0ace4222d9d5e3d1976db3964.tar.xz
rvcontroller-f1fe00423df3fda0ace4222d9d5e3d1976db3964.zip
Add Zihpm and Zicboz
Diffstat (limited to 'rvcontroller.lua')
-rw-r--r--rvcontroller.lua81
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)