This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:multiasm:paarm:chapter_5_7 [2025/12/04 11:37] – [Interrupts] eriks.klavins | en:multiasm:paarm:chapter_5_7 [2025/12/04 12:48] (current) – [Interrupts] eriks.klavins | ||
|---|---|---|---|
| Line 178: | Line 178: | ||
| There is no fixed number of interrupts available for the processor. The total number of available interrupts is defined by the Generic Interrupt Controller (GIC) implemented in the system. The Raspberry Pi 5 have a GIC-500 interrupt controller, and according to [[https:// | There is no fixed number of interrupts available for the processor. The total number of available interrupts is defined by the Generic Interrupt Controller (GIC) implemented in the system. The Raspberry Pi 5 have a GIC-500 interrupt controller, and according to [[https:// | ||
| * ID0..ID15 is used for Software Generated Interrupts (system calls) | * ID0..ID15 is used for Software Generated Interrupts (system calls) | ||
| - | * The next 16 IDs are used for Private Peripheral Interrupts for one single core | + | * The next 16 IDs are used for Private Peripheral Interrupts for a single core |
| + | * The rest of the IDs are for Shared Peripheral interrupts | ||
| + | Practically, | ||
| + | |||
| + | The interrupts can be disabled and enabled. For example:\\ | ||
| + | ''< | ||
| + | ''< | ||
| + | ''< | ||
| + | |||
| + | |||
| + | ** The Stack Pointer and Interrupt Handling ** | ||
| + | |||
| + | When an interrupt or exception occurs, the processor automatically saves the minimal state. It then switches to the stack pointer associated with the current exception level. The interrupt handler can safely use the stack at that level without overwriting user or kernel data. For example, when an IRQ occurs at EL1, the CPU switches from the user’s stack (SP_EL0) to the kernel’s stack (SP_EL1). This change is invisible to user code and helps isolate privilege levels. | ||
| + | Inside an interrupt handler, the code must save and restore any registers it modifies. A minimal handler might look like this:\\ | ||
| + | '' | ||
| + | ''< | ||
| + | ''< | ||
| + | ''< | ||
| + | ''< | ||
| + | |||
| + | Here, the stack pointer ensures the handler has a private area to store data safely, even if multiple interrupts occur. | ||
| + | |||
| + | < | ||
| + | < | ||
| + | < | ||
| + | irq_el1_handler: | ||
| + | @ Save registers | ||
| + | STP X0, X1, [SP, #-16]! | ||
| + | STP X2, X3, [SP, #-16]! | ||
| + | |||
| + | @ Acknowledge interrupt (example for GIC) | ||
| + | MRS X0, ICC_IAR1_EL1 | ||
| + | CMP X0, #1020 @ Spurious? | ||
| + | BEQ irq_done | ||
| + | |||
| + | @ Handle interrupt (custom code here) | ||
| + | BL handle_device_irq | ||
| + | |||
| + | @ Signal end of interrupt | ||
| + | MSR ICC_EOIR1_EL1, | ||
| + | |||
| + | irq_done: | ||
| + | @ Restore registers | ||
| + | LDP X2, X3, [SP], #16 | ||
| + | LDP X0, X1, [SP], #16 | ||
| + | ERET @ Return from exception | ||
| + | </ | ||
| + | </ | ||