From 4bce85dc09a5e496794be0656287d0c740b34128 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 3 Apr 2025 10:18:29 +0200 Subject: [PATCH] riscv: define CSR constants and use them where possible --- src/device/riscv/csr.go | 58 ++++++++++++++++++++++ src/runtime/interrupt/interrupt_esp32c3.go | 14 +++--- src/runtime/runtime_fe310.go | 12 ++--- src/runtime/runtime_k210.go | 12 ++--- 4 files changed, 77 insertions(+), 19 deletions(-) diff --git a/src/device/riscv/csr.go b/src/device/riscv/csr.go index 510a7b891..52e97a262 100644 --- a/src/device/riscv/csr.go +++ b/src/device/riscv/csr.go @@ -275,3 +275,61 @@ const ( DPC CSR = 0x7B1 // Debug PC. DSCRATCH CSR = 0x7B2 // Debug scratch register. ) + +// Bitfields for the CSR registers above. +const ( + // MSTATUS (common bits between RV32 and RV64) + MSTATUS_SIE = 1 << 1 + MSTATUS_MIE = 1 << 3 + MSTATUS_SPIE = 1 << 5 + MSTATUS_UBE = 1 << 6 + MSTATUS_MPIE = 1 << 7 + MSTATUS_SPP = 1 << 8 + MSTATUS_MPRV = 1 << 17 + MSTATUS_SUM = 1 << 18 + MSTATUS_MXR = 1 << 19 + MSTATUS_TVM = 1 << 20 + MSTATUS_TW = 1 << 21 + MSTATUS_TSR = 1 << 22 + + MIE_SSIE = 1 << 1 + MIE_MSIE = 1 << 3 + MIE_STIE = 1 << 5 + MIE_MTIE = 1 << 7 + MIE_SEIE = 1 << 9 + MIE_MEIE = 1 << 11 + + MIP_SSIP = 1 << 1 + MIP_MSIP = 1 << 3 + MIP_STIP = 1 << 5 + MIP_MTIP = 1 << 7 + MIP_SEIP = 1 << 9 + MIP_MEIP = 1 << 11 +) + +// Interrupt constants +const ( + // MCAUSE values with the topmost bit (interrupt bit) set. + SupervisorSoftwareInterrupt = 1 + MachineSoftwareInterrupt = 3 + SupervisorTimerInterrupt = 5 + MachineTimerInterrupt = 7 + SupervisorExternalInterrupt = 9 + MachineExternalInterrupt = 11 + + // MCAUSE values with the topmost bit (interrupt bit) clear. + InstructionAddressMisaligned = 0 + InstructionAccessFault = 1 + IllegalInstruction = 2 + Breakpoint = 3 + LoadAddressMisaligned = 4 + LoadAccessFault = 5 + StoreOrAMOAddressMisaligned = 6 + StoreOrAMOAccessFault = 7 + EnvironmentCallFromUMode = 8 + EnvironmentCallFromSMode = 9 + EnvironmentCallFromMMode = 11 + InstructionPageFault = 12 + LoadPageFault = 13 + StoreOrAMOPageFault = 15 +) diff --git a/src/runtime/interrupt/interrupt_esp32c3.go b/src/runtime/interrupt/interrupt_esp32c3.go index 4e3e3dccf..5725cd352 100644 --- a/src/runtime/interrupt/interrupt_esp32c3.go +++ b/src/runtime/interrupt/interrupt_esp32c3.go @@ -189,13 +189,13 @@ func handleInterrupt() { } // enable CPU interrupts - riscv.MSTATUS.SetBits(1 << 3) + riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE) // Call registered interrupt handler(s) callHandler(int(interruptNumber)) // disable CPU interrupts - riscv.MSTATUS.ClearBits(1 << 3) + riscv.MSTATUS.ClearBits(riscv.MSTATUS_MIE) // restore interrupt threshold to enable interrupt again reg.Set(thresholdSave) @@ -207,7 +207,7 @@ func handleInterrupt() { // do not enable CPU interrupts now // the 'MRET' in src/device/riscv/handleinterrupt.S will copies the state of MPIE back into MIE, and subsequently clears MPIE. - // riscv.MSTATUS.SetBits(0x8) + // riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE) } else { // Topmost bit is clear, so it is an exception of some sort. // We could implement support for unsupported instructions here (such as @@ -221,13 +221,13 @@ func handleException(mcause uintptr) { println("*** Exception: code:", uint32(mcause&0x1f)) println("*** Exception: mcause:", mcause) switch uint32(mcause & 0x1f) { - case 1: + case riscv.InstructionAccessFault: println("*** virtual address:", riscv.MTVAL.Get()) - case 2: + case riscv.IllegalInstruction: println("*** opcode:", riscv.MTVAL.Get()) - case 5: + case riscv.LoadAccessFault: println("*** read address:", riscv.MTVAL.Get()) - case 7: + case riscv.StoreOrAMOAccessFault: println("*** write address:", riscv.MTVAL.Get()) } for { diff --git a/src/runtime/runtime_fe310.go b/src/runtime/runtime_fe310.go index f65c39a4d..218962edb 100644 --- a/src/runtime/runtime_fe310.go +++ b/src/runtime/runtime_fe310.go @@ -38,10 +38,10 @@ func main() { // Reset the MIE register and enable external interrupts. // It must be reset here because it not zeroed at startup. - riscv.MIE.Set(1 << 11) // bit 11 is for machine external interrupts + riscv.MIE.Set(riscv.MIE_MEIE) // Enable global interrupts now that they've been set up. - riscv.MSTATUS.SetBits(1 << 3) // MIE + riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE) // MIE: machine external interrupts preinit() initPeripherals() @@ -59,13 +59,13 @@ func handleInterrupt() { if cause&(1<<31) != 0 { // Topmost bit is set, which means that it is an interrupt. switch code { - case 7: // Machine timer interrupt + case riscv.MachineTimerInterrupt: // Signal timeout. timerWakeup.Set(1) // Disable the timer, to avoid triggering the interrupt right after // this interrupt returns. - riscv.MIE.ClearBits(1 << 7) // MTIE bit - case 11: // Machine external interrupt + riscv.MIE.ClearBits(riscv.MIE_MTIE) + case riscv.MachineExternalInterrupt: // Claim this interrupt. id := sifive.PLIC.CLAIM.Get() // Call the interrupt handler, if any is registered for this ID. @@ -143,7 +143,7 @@ func sleepTicks(d timeUnit) { target := uint64(ticks() + d) sifive.CLINT.MTIMECMPH.Set(uint32(target >> 32)) sifive.CLINT.MTIMECMP.Set(uint32(target)) - riscv.MIE.SetBits(1 << 7) // MTIE + riscv.MIE.SetBits(riscv.MIE_MTIE) for { if timerWakeup.Get() != 0 { timerWakeup.Set(0) diff --git a/src/runtime/runtime_k210.go b/src/runtime/runtime_k210.go index 96cdd6340..8ee79b938 100644 --- a/src/runtime/runtime_k210.go +++ b/src/runtime/runtime_k210.go @@ -44,10 +44,10 @@ func main() { // Reset the MIE register and enable external interrupts. // It must be reset here because it not zeroed at startup. - riscv.MIE.Set(1 << 11) // bit 11 is for machine external interrupts + riscv.MIE.Set(riscv.MIE_MEIE) // MEIE is for machine external interrupts // Enable global interrupts now that they've been set up. - riscv.MSTATUS.SetBits(1 << 3) // MIE + riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE) preinit() initPeripherals() @@ -77,13 +77,13 @@ func handleInterrupt() { if cause&(1<<63) != 0 { // Topmost bit is set, which means that it is an interrupt. switch code { - case 7: // Machine timer interrupt + case riscv.MachineTimerInterrupt: // Signal timeout. timerWakeup.Set(1) // Disable the timer, to avoid triggering the interrupt right after // this interrupt returns. - riscv.MIE.ClearBits(1 << 7) // MTIE bit - case 11: // Machine external interrupt + riscv.MIE.ClearBits(riscv.MIE_MTIE) + case riscv.MachineExternalInterrupt: hartId := riscv.MHARTID.Get() // Claim this interrupt. @@ -149,7 +149,7 @@ func ticks() timeUnit { func sleepTicks(d timeUnit) { target := uint64(ticks() + d) kendryte.CLINT.MTIMECMP[0].Set(target) - riscv.MIE.SetBits(1 << 7) // MTIE + riscv.MIE.SetBits(riscv.MIE_MTIE) for { if timerWakeup.Get() != 0 { timerWakeup.Set(0)