riscv: define CSR constants and use them where possible

This commit is contained in:
Ayke van Laethem
2025-04-03 10:18:29 +02:00
committed by Ron Evans
parent 8a73502f11
commit 4bce85dc09
4 changed files with 77 additions and 19 deletions
+58
View File
@@ -275,3 +275,61 @@ const (
DPC CSR = 0x7B1 // Debug PC. DPC CSR = 0x7B1 // Debug PC.
DSCRATCH CSR = 0x7B2 // Debug scratch register. 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
)
+7 -7
View File
@@ -189,13 +189,13 @@ func handleInterrupt() {
} }
// enable CPU interrupts // enable CPU interrupts
riscv.MSTATUS.SetBits(1 << 3) riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE)
// Call registered interrupt handler(s) // Call registered interrupt handler(s)
callHandler(int(interruptNumber)) callHandler(int(interruptNumber))
// disable CPU interrupts // disable CPU interrupts
riscv.MSTATUS.ClearBits(1 << 3) riscv.MSTATUS.ClearBits(riscv.MSTATUS_MIE)
// restore interrupt threshold to enable interrupt again // restore interrupt threshold to enable interrupt again
reg.Set(thresholdSave) reg.Set(thresholdSave)
@@ -207,7 +207,7 @@ func handleInterrupt() {
// do not enable CPU interrupts now // 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. // 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 { } else {
// Topmost bit is clear, so it is an exception of some sort. // Topmost bit is clear, so it is an exception of some sort.
// We could implement support for unsupported instructions here (such as // 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: code:", uint32(mcause&0x1f))
println("*** Exception: mcause:", mcause) println("*** Exception: mcause:", mcause)
switch uint32(mcause & 0x1f) { switch uint32(mcause & 0x1f) {
case 1: case riscv.InstructionAccessFault:
println("*** virtual address:", riscv.MTVAL.Get()) println("*** virtual address:", riscv.MTVAL.Get())
case 2: case riscv.IllegalInstruction:
println("*** opcode:", riscv.MTVAL.Get()) println("*** opcode:", riscv.MTVAL.Get())
case 5: case riscv.LoadAccessFault:
println("*** read address:", riscv.MTVAL.Get()) println("*** read address:", riscv.MTVAL.Get())
case 7: case riscv.StoreOrAMOAccessFault:
println("*** write address:", riscv.MTVAL.Get()) println("*** write address:", riscv.MTVAL.Get())
} }
for { for {
+6 -6
View File
@@ -38,10 +38,10 @@ func main() {
// Reset the MIE register and enable external interrupts. // Reset the MIE register and enable external interrupts.
// It must be reset here because it not zeroed at startup. // 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. // 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() preinit()
initPeripherals() initPeripherals()
@@ -59,13 +59,13 @@ func handleInterrupt() {
if cause&(1<<31) != 0 { if cause&(1<<31) != 0 {
// Topmost bit is set, which means that it is an interrupt. // Topmost bit is set, which means that it is an interrupt.
switch code { switch code {
case 7: // Machine timer interrupt case riscv.MachineTimerInterrupt:
// Signal timeout. // Signal timeout.
timerWakeup.Set(1) timerWakeup.Set(1)
// Disable the timer, to avoid triggering the interrupt right after // Disable the timer, to avoid triggering the interrupt right after
// this interrupt returns. // this interrupt returns.
riscv.MIE.ClearBits(1 << 7) // MTIE bit riscv.MIE.ClearBits(riscv.MIE_MTIE)
case 11: // Machine external interrupt case riscv.MachineExternalInterrupt:
// Claim this interrupt. // Claim this interrupt.
id := sifive.PLIC.CLAIM.Get() id := sifive.PLIC.CLAIM.Get()
// Call the interrupt handler, if any is registered for this ID. // Call the interrupt handler, if any is registered for this ID.
@@ -143,7 +143,7 @@ func sleepTicks(d timeUnit) {
target := uint64(ticks() + d) target := uint64(ticks() + d)
sifive.CLINT.MTIMECMPH.Set(uint32(target >> 32)) sifive.CLINT.MTIMECMPH.Set(uint32(target >> 32))
sifive.CLINT.MTIMECMP.Set(uint32(target)) sifive.CLINT.MTIMECMP.Set(uint32(target))
riscv.MIE.SetBits(1 << 7) // MTIE riscv.MIE.SetBits(riscv.MIE_MTIE)
for { for {
if timerWakeup.Get() != 0 { if timerWakeup.Get() != 0 {
timerWakeup.Set(0) timerWakeup.Set(0)
+6 -6
View File
@@ -44,10 +44,10 @@ func main() {
// Reset the MIE register and enable external interrupts. // Reset the MIE register and enable external interrupts.
// It must be reset here because it not zeroed at startup. // 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. // Enable global interrupts now that they've been set up.
riscv.MSTATUS.SetBits(1 << 3) // MIE riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE)
preinit() preinit()
initPeripherals() initPeripherals()
@@ -77,13 +77,13 @@ func handleInterrupt() {
if cause&(1<<63) != 0 { if cause&(1<<63) != 0 {
// Topmost bit is set, which means that it is an interrupt. // Topmost bit is set, which means that it is an interrupt.
switch code { switch code {
case 7: // Machine timer interrupt case riscv.MachineTimerInterrupt:
// Signal timeout. // Signal timeout.
timerWakeup.Set(1) timerWakeup.Set(1)
// Disable the timer, to avoid triggering the interrupt right after // Disable the timer, to avoid triggering the interrupt right after
// this interrupt returns. // this interrupt returns.
riscv.MIE.ClearBits(1 << 7) // MTIE bit riscv.MIE.ClearBits(riscv.MIE_MTIE)
case 11: // Machine external interrupt case riscv.MachineExternalInterrupt:
hartId := riscv.MHARTID.Get() hartId := riscv.MHARTID.Get()
// Claim this interrupt. // Claim this interrupt.
@@ -149,7 +149,7 @@ func ticks() timeUnit {
func sleepTicks(d timeUnit) { func sleepTicks(d timeUnit) {
target := uint64(ticks() + d) target := uint64(ticks() + d)
kendryte.CLINT.MTIMECMP[0].Set(target) kendryte.CLINT.MTIMECMP[0].Set(target)
riscv.MIE.SetBits(1 << 7) // MTIE riscv.MIE.SetBits(riscv.MIE_MTIE)
for { for {
if timerWakeup.Get() != 0 { if timerWakeup.Get() != 0 {
timerWakeup.Set(0) timerWakeup.Set(0)