mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-08 21:13:39 +00:00
runtime/fe310: add support for PLIC interrupts
This commit adds support for software vectoring in the PLIC interrupt. The interrupt table is created by the compiler, which leads to very compact code while retaining the flexibility that the interrupt API provides.
This commit is contained in:
committed by
Ron Evans
parent
a9174d9184
commit
415c60551e
@@ -19,11 +19,6 @@ type Interrupt struct {
|
||||
// function: closures are not supported.
|
||||
func New(id int, handler func(Interrupt)) Interrupt
|
||||
|
||||
// Register is used to declare an interrupt. You should not normally call this
|
||||
// function: it is only for telling the compiler about the mapping between an
|
||||
// interrupt number and the interrupt handler name.
|
||||
func Register(id int, handlerName string) int
|
||||
|
||||
// handle is used internally, between IR generation and interrupt lowering. The
|
||||
// frontend will create runtime/interrupt.handle objects, cast them to an int,
|
||||
// and use that in an Interrupt object. That way the compiler will be able to
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// +build avr cortexm
|
||||
|
||||
package interrupt
|
||||
|
||||
// Register is used to declare an interrupt. You should not normally call this
|
||||
// function: it is only for telling the compiler about the mapping between an
|
||||
// interrupt number and the interrupt handler name.
|
||||
func Register(id int, handlerName string) int
|
||||
@@ -0,0 +1,18 @@
|
||||
// +build sifive
|
||||
|
||||
package interrupt
|
||||
|
||||
import "device/sifive"
|
||||
|
||||
// Enable enables this interrupt. Right after calling this function, the
|
||||
// interrupt may be invoked if it was already pending.
|
||||
func (irq Interrupt) Enable() {
|
||||
sifive.PLIC.ENABLE[irq.num/32].SetBits(1 << (uint(irq.num) % 32))
|
||||
}
|
||||
|
||||
// SetPriority sets the interrupt priority for this interrupt. A higher priority
|
||||
// number means a higher priority (unlike Cortex-M). Priority 0 effectively
|
||||
// disables the interrupt.
|
||||
func (irq Interrupt) SetPriority(priority uint8) {
|
||||
sifive.PLIC.PRIORITY[irq.num].Set(uint32(priority))
|
||||
}
|
||||
@@ -42,6 +42,10 @@ func main() {
|
||||
// of MTVEC won't be zero.
|
||||
riscv.MTVEC.Set(uintptr(unsafe.Pointer(&handleInterruptASM)))
|
||||
|
||||
// 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
|
||||
|
||||
// Enable global interrupts now that they've been set up.
|
||||
riscv.MSTATUS.SetBits(1 << 3) // MIE
|
||||
|
||||
@@ -68,6 +72,13 @@ func handleInterrupt() {
|
||||
// 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
|
||||
// Claim this interrupt.
|
||||
id := sifive.PLIC.CLAIM.Get()
|
||||
// Call the interrupt handler, if any is registered for this ID.
|
||||
callInterruptHandler(int(id))
|
||||
// Complete this interrupt.
|
||||
sifive.PLIC.CLAIM.Set(id)
|
||||
}
|
||||
} else {
|
||||
// Topmost bit is clear, so it is an exception of some sort.
|
||||
@@ -167,3 +178,7 @@ func handleException(code uint) {
|
||||
println()
|
||||
abort()
|
||||
}
|
||||
|
||||
// callInterruptHandler is a compiler-generated function that calls the
|
||||
// appropriate interrupt handler for the given interrupt ID.
|
||||
func callInterruptHandler(id int)
|
||||
|
||||
Reference in New Issue
Block a user