github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/arm/irq.go (about)

     1  // ARM processor support
     2  // https://github.com/usbarmory/tamago
     3  //
     4  // Copyright (c) WithSecure Corporation
     5  // https://foundry.withsecure.com
     6  //
     7  // Use of this source code is governed by the license
     8  // that can be found in the LICENSE file.
     9  
    10  package arm
    11  
    12  import (
    13  	"math"
    14  	"runtime"
    15  	"time"
    16  )
    17  
    18  // IRQ handling goroutine, set with RegisterInterruptHandler()
    19  var (
    20  	irqHandlerG uint32
    21  	irqHandlerP uint32
    22  )
    23  
    24  // defined in irq.s
    25  func irq_enable(spsr bool)
    26  func irq_disable(spsr bool)
    27  func fiq_enable(spsr bool)
    28  func fiq_disable(spsr bool)
    29  
    30  // EnableInterrupts unmasks IRQ interrupts in the current or saved program
    31  // status.
    32  func (cpu *CPU) EnableInterrupts(saved bool) {
    33  	irq_enable(saved)
    34  }
    35  
    36  // DisableInterrupts masks IRQ interrupts in the current or saved program
    37  // status.
    38  func (cpu *CPU) DisableInterrupts(saved bool) {
    39  	irq_disable(saved)
    40  }
    41  
    42  // EnableFastInterrupts unmasks FIQ interrupts in the current or saved program
    43  // status.
    44  func (cpu *CPU) EnableFastInterrupts(saved bool) {
    45  	fiq_enable(saved)
    46  }
    47  
    48  // DisableFastInterrupts masks FIQ interrupts in the current or saved program
    49  // status.
    50  func (cpu *CPU) DisableFastInterrupts(saved bool) {
    51  	fiq_disable(saved)
    52  }
    53  
    54  // RegisterInterruptHandler sets the calling goroutine as IRQ handler, the
    55  // goroutine must then use WaitInterrupt() to receive an IRQ and service it.
    56  func RegisterInterruptHandler() {
    57  	irqHandlerG, irqHandlerP = runtime.GetG()
    58  }
    59  
    60  // WaitInterrupt() puts the calling goroutine in wait state, its execution is
    61  // resumed when an IRQ exception is received.
    62  func WaitInterrupt() {
    63  	// To avoid losing interrupts, re-enabling must happen only after we
    64  	// are sleeping.
    65  	go irq_enable(false)
    66  
    67  	// Sleep indefinitely until woken up by runtime.WakeG
    68  	// (see irqHandler in exception.s).
    69  	time.Sleep(math.MaxInt64)
    70  }