diff options
| author | cheapie <cheapiephp@gmail.com> | 2026-06-26 09:55:56 -0500 |
|---|---|---|
| committer | cheapie <cheapiephp@gmail.com> | 2026-06-26 09:55:56 -0500 |
| commit | ca28b45e758e2f36be5a93c5ae0a5cdfe91d5db9 (patch) | |
| tree | 64993c1d5bd4bb6bd67b2f25daacf026f110c92d /rvcontroller.lua | |
| parent | 2e1e3c0468f4c8e46a8801c8fc5f74705ce20f20 (diff) | |
| download | rvcontroller-ca28b45e758e2f36be5a93c5ae0a5cdfe91d5db9.tar rvcontroller-ca28b45e758e2f36be5a93c5ae0a5cdfe91d5db9.tar.gz rvcontroller-ca28b45e758e2f36be5a93c5ae0a5cdfe91d5db9.tar.bz2 rvcontroller-ca28b45e758e2f36be5a93c5ae0a5cdfe91d5db9.tar.xz rvcontroller-ca28b45e758e2f36be5a93c5ae0a5cdfe91d5db9.zip | |
Add basic mesecons/digilines interrupt support
Diffstat (limited to 'rvcontroller.lua')
| -rw-r--r-- | rvcontroller.lua | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/rvcontroller.lua b/rvcontroller.lua index 8711a51..e6e86e5 100644 --- a/rvcontroller.lua +++ b/rvcontroller.lua @@ -207,6 +207,14 @@ Base + 10: mtimecmp (see RISC-V Machine Level ISA specification) Base + 18 - Base + 255: Reserved +Interrupts: + +Bits 7/16/17 of mie/mip are currently implemented. + +Bit 7: MTIP (machine timer interrupt), standard +Bit 16: MCIP (mesecons input interrupt), custom for RVController +Bit 17: DGIP (digilines receive interrupt), custom for RVController + ]] --Settings @@ -765,15 +773,17 @@ end local function checkinterrupts() local miebits = explodebits(mem.csr[0x304],32) - local mipbits = {} + local mipbits = explodebits(mem.csr[0x344],32) if mem.mtimecmphigh == mem.csr[0xc81] and (os.time() - mem.starttime) >= mem.mtimecmplow then mipbits[7] = true --mtip elseif mem.mtimecmphigh < mem.csr[0xc81] then mipbits[7] = true --mtip + else + mipbits[7] = false end mem.csr[0x344] = implodebits(mipbits,32) if not mem.mie then return end - local order = {11,3,7,9,1,5,13} + local order = {11,3,7,9,1,5,13,16,17} for _,i in ipairs(order) do if miebits[i] and mipbits[i] then return trap(0x80000000+i) @@ -1211,30 +1221,39 @@ local operations = { return trap(3,0) end, csrrw = function(rd,rs1,imm) - setreg(rd,readcsr(imm)) + local out = readcsr(imm) writecsr(imm,getreg(rs1)) + setreg(rd,out) return checkinterrupts() end, csrrs = function(rd,rs1,imm) - setreg(rd,readcsr(imm)) - if rs1 == 0 then return end + local out = readcsr(imm) + if rs1 == 0 then + setreg(rd,out) + return + end local csrbits = explodebits(readcsr(imm),32) local rs1bits = explodebits(getreg(rs1),32) for i=0,31 do csrbits[i] = csrbits[i] or rs1bits[i] end writecsr(imm,implodebits(csrbits,32)) + setreg(rd,out) return checkinterrupts() end, csrrc = function(rd,rs1,imm) - setreg(rd,readcsr(imm)) - if rs1 == 0 then return end + local out = readcsr(imm) + if rs1 == 0 then + setreg(rd,out) + return + end local csrbits = explodebits(readcsr(imm),32) local rs1bits = explodebits(getreg(rs1),32) for i=0,31 do csrbits[i] = csrbits[i] and not rs1bits[i] end writecsr(imm,implodebits(csrbits,32)) + setreg(rd,out) return checkinterrupts() end, csrrwi = function(rd,rs1,imm) @@ -3041,6 +3060,16 @@ elseif event.type == "on" or event.type == "off" then --MMIO is enabled writeram(readcsr(0x801)+1,0,1,true) --Invalidate any existing reservation set end + local mipbits = explodebits(mem.csr[0x344],32) + mipbits[16] = true + mem.csr[0x344] = implodebits(mipbits,32) + local miebits = explodebits(mem.csr[0x304],32) + if miebits[16] and mem.interruptwaiting then + mem.interruptwaiting = false + mem.running = true + digiline_send("monitordisp","CPU started") + interrupt(1/CLOCK_SPEED,"tick") + end end elseif event.channel == "reset" then mem.running = false @@ -3345,6 +3374,16 @@ elseif event.type == "digiline" then if mem.csr[0x800]%2 == 1 then interrupt(0,"tick") end + local mipbits = explodebits(mem.csr[0x344],32) + mipbits[17] = true + mem.csr[0x344] = implodebits(mipbits,32) + local miebits = explodebits(mem.csr[0x304],32) + if miebits[17] and mem.interruptwaiting then + mem.interruptwaiting = false + mem.running = true + digiline_send("monitordisp","CPU started") + interrupt(1/CLOCK_SPEED,"tick") + end elseif event.iid == "tick" and mem.running then run(INSTRUCTIONS_PER_CLOCK) if mem.csr[0x800]%2 == 1 then |
