CS 452/652 Winter 2024 - Lecture 8
Interrupts
Feb 1, 2024 prev next
BCM - Broadcom BCM2711 data sheet
GIC - ARM Generic Interrupt Controller
Interrupts
- Motivation
- avoid busy waiting for devices
- instead, device signals to get attention
- Interrupts start with signals asserted by devices
- each device defines the signals it can generate
- example: system timer
- four signals, corresponding to 4 System Timer Compare registers (C0-C3)
- when CLO matches value in Cx, signal is asserted
- example of what ARM refers to as a Shared Peripheral Interrupt (SPI)
- generated by a device, routed to some processor
- also Private Peripheral Interrupts (PPI) and Software Generated Interrupts (SGIs)
- PPI specific to a single processor (not used here)
- SGI generated by software running on some core - can be used to signal other cores
- Interrupts result in an asynchronous exception at a processor
- mapped to one of two signals (FIQ and IRQ) at each processor core
- Reminder: exception vector
- groups identify execution state when exception occurred:
- Current EL with SPO/SPx, Lower EL using 64/32 bit mode
- within each group, entries for different types of exceptions
- synchronous exception (e.g. syscall, memory protectionm, illegal instruction)
- IRQ - asynchronous
- FIQ - asynchronous (not used)
- SError - async memory-related exceptions (e.g, parity error, cache write-back error)
- If IRQ signal is asserted
- CPU transfers control to exception handler after execution of current instruction
- Handler/Kernel
- saves current application context
- figures out the reason for the interrupt
- handle the interrupt
- includes device control and interrupt acknowledgement (more later)
- choose next task to run
- restore chosen task context, return from exception (
eret
)
- Masking
- Interrupts can be masked at processor
- IRQ/FIQ still get asserted, but processor ignores them
- DAIF bits in pstate
- I is mask for IRQ, F is mask for FIQ
- When exception occurs, interrupts get masked automatically
- kernel unmasks by ensuring I and F bits are cleared in
SPSR_EL1
prior to context switch
- possible to unmask within the kernel, but we don't do this!
- Interrupt handling also presents overheads
- direct: pipeline flush, handler execution
- indirect: cache disturbance
- high-rate of interrupts? use hybrid approach (Interrupt Mitigation):
- poll device and deliver event
- only enable interrupt, if poll (or several polls) unsuccessful
- disable interrupt after it is triggered
- real-world example: Linux NAPI
- similar strategy useful for CS 452 microkernel
Interrupt Controller
System at Boot Time
- GIC distribution and signalling enabled (GICD_CTLR, GICC_CTLR)
- all interrupts disabled at GIC
- interrupt routing ?
- interrupts masked in EL1 (via boot.S)
System Timer Interrupts
- Initialization
- Timer has 4 interrupt signals, corresponding to C0-C3
- C0 and C2 reserved by VC, so use on C1 and C3
- BCM Chap 6 says system timer interrupts are first 4 VC (video core) interrupts
- Interrupt IDs for video core start at 96, so
- C1 interrupt has InterruptID 97
- C3 interrupt has InterruptID 99
- route the interrupt to IRQ on CPU 0
- use
GICD_ITARGETSRn
- each register defines targets for 4 interrupts
- make sure IRQ handler is set up in your kernel's exception vector
- enable the interrupt
- use
GICD_ISENABLERn
- 4-byte registers, with 1 bit per InterruptID
- write values into system timer C1/C3 to trigger interrupt assertion at correct time
- enable IRQ handling in CPU via pstate
- Handling the Interrupt
- save application context
- read
GICC_IAR
- returns interruptID (should be 97/99)!
- sets interrupt state to Active in GIC
- do work
- update value of system timer C1/C3 (why?)
- write InterruptID to
GICC_EOIR
- marks interrupt as not active in GIC
- choose next task, restore next task context, return from exception