mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 02:57:46 +00:00
riscv: define CSR constants and use them where possible
This commit is contained in:
committed by
Ron Evans
parent
8a73502f11
commit
4bce85dc09
@@ -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
|
||||
)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user