Landin library reference discuss source

platform/riscv/hazard3

Importable on every target; it declares its items only where compiler.arch == rv32.

Hazard3's external interrupt controller, the RP2350's RISC-V cores': enable_irq and disable_irq write meiea, and force_irq and clear_forced_irq write meifa, which makes an IRQ pending as if its source had asserted it. The compiler's dispatch reads meinext and calls slot 16 + IRQ; enabling the IRQ, and mie's external line through platform/riscv, is the program's.

Items

When compiler.arch == rv32

public clear_forced_irq: (irq: u32) -> none

Stop forcing IRQ pending.

When compiler.arch == rv32

public disable_irq: (irq: u32) -> none

Disable external interrupt IRQ in meiea.

When compiler.arch == rv32

public enable_irq: (irq: u32) -> none

Enable external interrupt IRQ in meiea. The core takes it once it is pending and mie.MEIE, which platform/riscv's enable_lines(0x800) sets, and mstatus.MIE are set.

When compiler.arch == rv32

public force_irq: (irq: u32) -> none

Force IRQ pending through meifa, as if its source had asserted it, until clear_forced_irq.

Example program

This complete program is one of the compiler's runtime tests. View source.

The program, 16 lines
compiler/tests/fixtures/positive/library-platform-riscv-hazard3/main.ldn16 lines
--  Hazard3's interrupt controller (D687): an IRQ enabled in meiea and
--  forced pending through meifa, then the core's external line opened in
--  mie, which the compiler's meinext dispatch then serves at slot 16 + IRQ.
import platform/riscv
import platform/riscv/hazard3

public raise_irq: (irq: u32) -> none =
    hazard3.enable_irq(irq)
    hazard3.force_irq(irq)
    riscv.enable_lines(0x800)
end raise_irq

public lower_irq: (irq: u32) -> none =
    hazard3.clear_forced_irq(irq)
    hazard3.disable_irq(irq)
end lower_irq