4 The Interrupt Heirarchy
5 -----------------------
7 Freedom Metal conceptualizes interrupts as a heirarchy of interrupt controllers.
8 This heirarchy is established by the interrupt heirarchy of the target platform
9 itself. Presently, the interrupt heirarchy for a given platform is best documented
10 by the target's DeviceTree representation, which can be found in
11 ``bsp/<target-name>/design.dts``.
13 In Freedom Metal, the heirarchy is a tree. The nodes of the tree consist of
14 ``struct metal_interrupt``:
16 .. doxygenstruct:: metal_interrupt
19 And the vertices of the tree consist of interrupt ``id``.
21 .. digraph:: int_heirarchy_graph
24 cpu_int [label="CPU Interrupt Controller", shape=box];
25 timer_int [label="Timer Interrupt Controller", shape=box];
26 soft_int [label="Software Interrupt Controller", shape=box];
28 cpu -> cpu_int [label="ID = 0"];
29 cpu_int -> timer_int [label="ID = timer_id"];
30 cpu_int -> soft_int [label="ID = software_id"];
32 The CPU Interrupt Controller
33 ----------------------------
35 The CPU interrupt controller is the top of the interrupt heirarchy. It must be
36 initialized before any other interrupt controllers are initialized. In example:
40 struct metal_cpu *cpu0 = metal_get_cpu(0);
42 /* Unable to get CPU handle */
44 struct metal_interrupt *cpu_int = metal_cpu_interrupt_controller(cpu0);
46 /* Unable to get CPU interrupt handle */
48 metal_interrupt_init(cpu_int);
50 The CPU interrupt must be enabled for the CPU to receive any interrupts, and any
51 enabled interrupts can be masked by disabling the CPU interrupt.
57 /* Enable the CPU interrupt */
58 rc = metal_interrupt_enable(cpu_int, 0);
60 /* Failed to enable the CPU interrupt */
63 /* Disable the CPU interrupt */
64 rc = metal_interrupt_disable(cpu_int, 0);
66 /* Failed to disable the CPU interrupt */
72 Interrupt handlers must conform to the following function signature:
74 .. doxygentypedef:: metal_interrupt_handler_t
77 Therefore, an interrupt handler might look like:
81 void my_interrupt_handler(int id, void *priv_data) {
82 /* Contents of handler */
85 Registering an Interrupt Handler
86 --------------------------------
88 Interrupt handlers are registered with the interrupt controller for the interrupt
89 they are servicing. For example, if we want to register a CPU timer interrupt:
93 struct metal_interrupt *timer_int = metal_cpu_timer_interrupt_controller(cpu0);
95 /* Failed to get timer interrupt controller */
97 metal_interrupt_init(timer_int);
99 int timer_id = metal_cpu_timer_get_interrupt_id(cpu0);
101 int rc = metal_interrupt_register_handler(timer_int, timer_id, my_interrupt_handler, cpu0);
103 /* Failed to register interrupt handler */
106 Additional Documentation
107 ------------------------
109 Additional documentation for the interrupt handler API can be found in
110 :doc:`the CPU API reference </apiref/cpu>` and
111 :doc:`the Interrupt API reference </apiref/interrupt>`.