PatchworkOS  da8a090
A non-POSIX operating system.
Loading...
Searching...
No Matches
interrupt.h
Go to the documentation of this file.
1#pragma once
2
3#include <kernel/cpu/idt.h>
4
5#include <stdbool.h>
6#include <stdint.h>
7
8/**
9 * @brief Interrupt Handling
10 * @defgroup kernel_cpu_interrupt Interrupts
11 * @ingroup kernel_cpu
12 *
13 * Interrupts are a way to allow the CPU or external devices to stop the currently executing code and instead to execute
14 * a handler function specified in the Interrupt Descriptor Table (IDT).
15 *
16 * ## Interrupt Frames
17 *
18 * An interrupt frame (`interrupt_frame_t`) is a structure that lets us access data pushed onto the stack by the CPU and
19 * in the assembly interrupt stubs when an interrupt occurs.
20 *
21 * First, when an interrupt occurs, the CPU automatically pushes some data onto the stack, such as the instruction
22 * pointer and code/data segments, this data is stored in the higher addresses of the `interrupt_frame_t` (since the
23 * stack grows downwards).
24 *
25 * After that, depending on the type of interrupt, the CPU might push an error code, if not the stub will push a `0` as
26 * a dummy, all stubs will also push the interrupt vector number onto the stack.
27 *
28 * Finally, the `vector_common` assembly function pushes all general-purpose registers onto the stack, completing the
29 * `interrupt_frame_t`.
30 *
31 * After the interrupt handler is done executing, the interrupt frame is popped off the stack allowing the CPU to
32 * restore its previous state or, if the interrupt handler modified the registers, it may return to a different state,
33 * for example, a different thread. This is how context switching is implemented.
34 *
35 * ## Interrupt Numbers
36 *
37 * Interrupts are identified by their vector number, which is an 8-bit value ranging from `0x00` to `0xFF`. Usually,
38 * each vector number would be associated with a specific handler function, but this is quite inconvenient for the OS as
39 * a whole, it's more practical to have one single `interrupt_handler()` function which can then more easily group and
40 * dispatch the interrupts as needed, it also lets us write interrupt handling code in C instead of assembly.
41 *
42 * This is done by, as mentioned above, having each vector's handler push its vector number onto the stack before
43 * jumping to the common `interrupt_handler()`, which can then read the vector number from the `interrupt_frame_t`.
44 *
45 * @{
46 */
47
48/**
49 * @brief Page Fault Error Codes.
50 * @enum page_fault_errors_t
51 *
52 * Will be stored in the error code of the interrupt frame on a page fault.
53 */
65
66/**
67 * @brief Interrupt Vectors.
68 * @enum interrupt_vector_t
69 *
70 * Lists all interrupt vectors, divided into exceptions, external interrupts and internal interrupts.
71 *
72 * ## Exceptions
73 *
74 * Exceptions are interrupts generated by the CPU itself in response to, usually, unexpected conditions such as a divide
75 * by zero. Sometimes exceptions can be intentional, such as the use of page faults for dynamic stack growth.
76 *
77 * ## External Interrupts
78 *
79 * External interrupts are reserved for the IRQ system.
80 *
81 * See @ref kernel_cpu_irq.
82 *
83 * ## Internal Interrupts
84 *
85 * Internal interrupts are, as the name suggests, used internally by the kernel for things such as timer interrupts and
86 * inter-processor interrupts (IPIs).
87 *
88 * See @ref kernel_cpu_ipi and @ref kernel_timer.
89 *
90 */
91typedef enum
92{
93 VECTOR_EXCEPTION_START = 0x0, ///< Inclusive start of exceptions.
119 VECTOR_EXCEPTION_END = 0x20, ///< Exclusive end of exceptions.
120
121 VECTOR_EXTERNAL_START = 0x20, ///< Inclusive start of external interrupts (handled by the IRQ system).
122 VECTOR_EXTERNAL_END = 0xF0, ///< Exclusive end of external interrupts.
123
125
126 VECTOR_INTERNAL_START = 0xF0, ///< Inclusive start of internal interrupts.
127 VECTOR_IPI = 0xFD, ///< See @ref kernel_cpu_ipi for more information.
128 VECTOR_TIMER = 0xFE, ///< See @ref kernel_timer for more information.
129 VECTOR_SPURIOUS = 0xFF, ///< Made available for any component to use as a sink for spurious interrupts.
130 VECTOR_INTERNAL_END = 0x100, ///< Exclusive end of internal interrupts.
131
134
135/**
136 * @brief Trap Frame Structure.
137 * @struct interrupt_frame_t
138 *
139 * Stores the CPU state at the time of a interrupt, usefull for context switching as we can modify the
140 * registers before returning from the interrupt.
141 */
169
170/**
171 * @brief Checks if a interrupt frame is from user space.
172 * @def INTERRUPT_FRAME_IN_USER_SPACE
173 *
174 * @param frame The interrupt frame to check.
175 * @return true if the interrupt frame is from user space, false otherwise.
176 */
177#define INTERRUPT_FRAME_IN_USER_SPACE(frame) ((frame)->ss == (GDT_SS_RING3) && (frame)->cs == (GDT_CS_RING3))
178
179/**
180 * @brief Per-CPU Interrupt Context.
181 * @struct interrupt_ctx_t
182 *
183 * Used to manage nested CLI (Clear Interrupt Flag) calls and track interrupt depth.
184 */
191
192/**
193 * @brief Pointers to functions to handle each vector.
194 */
195extern void* vectorTable[IDT_GATE_AMOUNT];
196
197/**
198 * @brief Initializes the interrupt context.
199 *
200 * @param ctx The interrupt context to initialize.
201 */
203
204/**
205 * @brief Disable interrupts and increment the disableDepth.
206 *
207 * Must have a matching `interrupt_enable()` call to re-enable interrupts when depth reaches zero.
208 */
209void interrupt_disable(void);
210
211/**
212 * @brief Decrement the CLI depth and enable interrupts if depth reaches zero and interrupts were previously enabled.
213 */
214void interrupt_enable(void);
215
216/**
217 * @brief Handles CPU interrupts.
218 *
219 * This will be called from `vector_common` in `vectors.s`.
220 *
221 * @param frame The interrupt frame containing the CPU state at the time of the exception.
222 */
224
225/** @} */
#define IDT_GATE_AMOUNT
Number of IDT gates.
Definition idt.h:20
void interrupt_ctx_init(interrupt_ctx_t *ctx)
Initializes the interrupt context.
Definition interrupt.c:16
void interrupt_handler(interrupt_frame_t *frame)
Handles CPU interrupts.
Definition interrupt.c:160
void * vectorTable[IDT_GATE_AMOUNT]
Pointers to functions to handle each vector.
void interrupt_disable(void)
Disable interrupts and increment the disableDepth.
Definition interrupt.c:23
void interrupt_enable(void)
Decrement the CLI depth and enable interrupts if depth reaches zero and interrupts were previously en...
Definition interrupt.c:35
page_fault_errors_t
Page Fault Error Codes.
Definition interrupt.h:55
interrupt_vector_t
Interrupt Vectors.
Definition interrupt.h:92
@ PAGE_FAULT_SOFTWARE_GUARD_EXT
Definition interrupt.h:63
@ PAGE_FAULT_WRITE
Definition interrupt.h:57
@ PAGE_FAULT_INSTRUCTION
Definition interrupt.h:60
@ PAGE_FAULT_USER
Definition interrupt.h:58
@ PAGE_FAULT_RESERVED
Definition interrupt.h:59
@ PAGE_FAULT_PRESENT
Definition interrupt.h:56
@ PAGE_FAULT_SHADOW_STACK
Definition interrupt.h:62
@ PAGE_FAULT_PROTECTION_KEY
Definition interrupt.h:61
@ VECTOR_VMM_COMMUNICATION_EXCEPTION
Definition interrupt.h:117
@ VECTOR_INTERNAL_START
Inclusive start of internal interrupts.
Definition interrupt.h:126
@ VECTOR_EXTERNAL_END
Exclusive end of external interrupts.
Definition interrupt.h:122
@ VECTOR_DEBUG
Definition interrupt.h:95
@ VECTOR_EXTERNAL_START
Inclusive start of external interrupts (handled by the IRQ system).
Definition interrupt.h:121
@ VECTOR_RESERVED
Definition interrupt.h:109
@ VECTOR_BOUND_RANGE_EXCEEDED
Definition interrupt.h:99
@ VECTOR_IPI
See IPI for more information.
Definition interrupt.h:127
@ VECTOR_HYPERVISOR_INJECTION_EXCEPTION
Definition interrupt.h:116
@ VECTOR_STACK_SEGMENT_FAULT
Definition interrupt.h:106
@ VECTOR_COPROCESSOR_SEGMENT_OVERRUN
Definition interrupt.h:103
@ VECTOR_VIRTUALIZATION_EXCEPTION
Definition interrupt.h:114
@ VECTOR_X87_FLOATING_POINT_EXCEPTION
Definition interrupt.h:110
@ VECTOR_PAGE_FAULT
Definition interrupt.h:108
@ VECTOR_SIMD_FLOATING_POINT_EXCEPTION
Definition interrupt.h:113
@ VECTOR_EXCEPTION_START
Inclusive start of exceptions.
Definition interrupt.h:93
@ VECTOR_INVALID_TSS
Definition interrupt.h:104
@ VECTOR_GENERAL_PROTECTION_FAULT
Definition interrupt.h:107
@ VECTOR_INTERNAL_END
Exclusive end of internal interrupts.
Definition interrupt.h:130
@ VECTOR_DOUBLE_FAULT
Definition interrupt.h:102
@ VECTOR_OVERFLOW
Definition interrupt.h:98
@ VECTOR_CONTROL_PROTECTION_EXCEPTION
Definition interrupt.h:115
@ VECTOR_NMI
Definition interrupt.h:96
@ VECTOR_SEGMENT_NOT_PRESENT
Definition interrupt.h:105
@ VECTOR_SECURITY_EXCEPTION
Definition interrupt.h:118
@ VECTOR_TIMER
See Timer subsystem for more information.
Definition interrupt.h:128
@ VECTOR_EXTERNAL_AMOUNT
Definition interrupt.h:124
@ VECTOR_DIVIDE_ERROR
Definition interrupt.h:94
@ VECTOR_SPURIOUS
Made available for any component to use as a sink for spurious interrupts.
Definition interrupt.h:129
@ VECTOR_TOTAL_AMOUNT
Definition interrupt.h:132
@ VECTOR_DEVICE_NOT_AVAILABLE
Definition interrupt.h:101
@ VECTOR_MACHINE_CHECK
Definition interrupt.h:112
@ VECTOR_INVALID_OPCODE
Definition interrupt.h:100
@ VECTOR_EXCEPTION_END
Exclusive end of exceptions.
Definition interrupt.h:119
@ VECTOR_ALIGNMENT_CHECK
Definition interrupt.h:111
@ VECTOR_BREAKPOINT
Definition interrupt.h:97
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
Per-CPU Interrupt Context.
Definition interrupt.h:186
uint32_t disableDepth
Definition interrupt.h:189
uint64_t oldRflags
Definition interrupt.h:188
Trap Frame Structure.
Definition interrupt.h:143
uint64_t errorCode
Definition interrupt.h:161