PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
interrupt.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef __ASSEMBLER__
4#include <kernel/cpu/idt.h>
5
6#include <stdbool.h>
7#include <stdint.h>
8
9typedef struct cpu cpu_t;
10#endif
11
12/**
13 * @brief Interrupt Handling
14 * @defgroup kernel_cpu_interrupt Interrupts
15 * @ingroup kernel_cpu
16 *
17 * Interrupts are a way to allow the CPU or external devices to stop the currently executing code and instead to execute
18 * a handler function specified in the Interrupt Descriptor Table (IDT).
19 *
20 * ## Interrupt Frames
21 *
22 * An interrupt frame (`interrupt_frame_t`) is a structure that lets us access data pushed onto the stack by the CPU and
23 * in the assembly interrupt stubs when an interrupt occurs.
24 *
25 * First, when an interrupt occurs, the CPU automatically pushes some data onto the stack, such as the instruction
26 * pointer and code/data segments, this data is stored in the higher addresses of the `interrupt_frame_t` (since the
27 * stack grows downwards).
28 *
29 * After that, depending on the type of interrupt, the CPU might push an error code, if not the stub will push a `0` as
30 * a dummy, all stubs will also push the interrupt vector number onto the stack.
31 *
32 * Finally, the `vector_common` assembly function pushes all general-purpose registers onto the stack, completing the
33 * `interrupt_frame_t`.
34 *
35 * After the interrupt handler is done executing, the interrupt frame is popped off the stack allowing the CPU to
36 * restore its previous state or, if the interrupt handler modified the registers, it may return to a different state,
37 * for example, a different thread. This is how context switching is implemented.
38 *
39 * ## Interrupt Numbers
40 *
41 * Interrupts are identified by their vector number, which is an 8-bit value ranging from `0x00` to `0xFF`. Usually,
42 * each vector number would be associated with a specific handler function, but this is quite inconvenient for the OS as
43 * a whole, it's more practical to have one single `interrupt_handler()` function which can then more easily group and
44 * dispatch the interrupts as needed, it also lets us write interrupt handling code in C instead of assembly.
45 *
46 * This is done by, as mentioned above, having each vector's handler push its vector number onto the stack before
47 * jumping to the common `interrupt_handler()`, which can then read the vector number from the `interrupt_frame_t`.
48 *
49 * @{
50 */
51
52/**
53 * @brief Macro to be used in ASM to define the size of an interrupt frame.
54 */
55#define INTERRUPT_FRAME_SIZE (8 * 22)
56
57/**
58 * @brief Macro to be used in ASM to push general-purpose registers onto the stack.
59 */
60#define INTERRUPT_FRAME_REGS_PUSH \
61 pushq % rax; \
62 pushq % rbx; \
63 pushq % rcx; \
64 pushq % rdx; \
65 pushq % rsi; \
66 pushq % rdi; \
67 pushq % rbp; \
68 pushq % r8; \
69 pushq % r9; \
70 pushq % r10; \
71 pushq % r11; \
72 pushq % r12; \
73 pushq % r13; \
74 pushq % r14; \
75 pushq % r15;
76
77/**
78 * @brief Macro to be used in ASM to pop general-purpose registers from the stack.
79 */
80#define INTERRUPT_FRAME_REGS_POP \
81 popq % r15; \
82 popq % r14; \
83 popq % r13; \
84 popq % r12; \
85 popq % r11; \
86 popq % r10; \
87 popq % r9; \
88 popq % r8; \
89 popq % rbp; \
90 popq % rdi; \
91 popq % rsi; \
92 popq % rdx; \
93 popq % rcx; \
94 popq % rbx; \
95 popq % rax;
96
97#ifndef __ASSEMBLER__
98
99/**
100 * @brief Page Fault Error Codes.
101 * @enum page_fault_errors_t
102 *
103 * Will be stored in the error code of the interrupt frame on a page fault.
104 */
116
117/**
118 * @brief Interrupt Vectors.
119 * @enum interrupt_vector_t
120 *
121 * Lists all interrupt vectors, divided into exceptions, external interrupts and internal interrupts.
122 *
123 * ## Exceptions
124 *
125 * Exceptions are interrupts generated by the CPU itself in response to, usually, unexpected conditions such as a divide
126 * by zero. Sometimes exceptions can be intentional, such as the use of page faults for dynamic stack growth.
127 *
128 * ## External Interrupts
129 *
130 * External interrupts are reserved for the IRQ system.
131 *
132 * See @ref kernel_cpu_irq.
133 *
134 * ## Internal Interrupts
135 *
136 * Internal interrupts are, as the name suggests, used internally by the kernel for things such as timer interrupts and
137 * inter-processor interrupts (IPIs).
138 *
139 * See @ref kernel_cpu_ipi and @ref kernel_timer.
140 *
141 */
142typedef enum
143{
144 VECTOR_EXCEPTION_START = 0x0, ///< Inclusive start of exceptions.
170 VECTOR_EXCEPTION_END = 0x20, ///< Exclusive end of exceptions.
171
172 VECTOR_EXTERNAL_START = 0x20, ///< Inclusive start of external interrupts (handled by the IRQ system).
173 VECTOR_EXTERNAL_END = 0xF0, ///< Exclusive end of external interrupts.
174
176
177 VECTOR_INTERNAL_START = 0xF0, ///< Inclusive start of internal interrupts.
178 VECTOR_FAKE = 0xFC, ///< Used to implement `interrupt_fake()`.
179 VECTOR_IPI = 0xFD, ///< See @ref kernel_cpu_ipi for more information.
180 VECTOR_TIMER = 0xFE, ///< See @ref kernel_timer for more information.
181 VECTOR_SPURIOUS = 0xFF, ///< Made available for any component to use as a sink for spurious interrupts.
182 VECTOR_INTERNAL_END = 0x100, ///< Exclusive end of internal interrupts.
183
186
187/**
188 * @brief Trap Frame Structure.
189 * @struct interrupt_frame_t
190 *
191 * Stores the CPU state at the time of a interrupt, usefull for context switching as we can modify the
192 * registers before returning from the interrupt.
193 */
221
222/**
223 * @brief Checks if a interrupt frame is from user space.
224 * @def INTERRUPT_FRAME_IN_USER_SPACE
225 *
226 * @param frame The interrupt frame to check.
227 * @return true if the interrupt frame is from user space, false otherwise.
228 */
229#define INTERRUPT_FRAME_IN_USER_SPACE(frame) ((frame)->ss == (GDT_SS_RING3) && (frame)->cs == (GDT_CS_RING3))
230
231/**
232 * @brief Pointers to functions to handle each vector.
233 */
234extern void* vectorTable[IDT_GATE_AMOUNT];
235
236/**
237 * @brief Handles CPU interrupts.
238 *
239 * This will be called from `vector_common` in `vectors.S`.
240 *
241 * @param frame The interrupt frame containing the CPU state at the time of the exception.
242 */
244
245/**
246 * @brief Enter a fake interrupt context as if an interrupt had occurred at the given frame.
247 *
248 * Provides a way to schedule and handle notes outside of a real interrupt context.
249 *
250 * @warning Must only be called when interrupts are disabled.
251 *
252 * @param frame The interrupt frame representing the state at the time of the fake interrupt.
253 * @return Will not return, instead will load and jump to the given interrupt frame, unless the thread gets scheduled or
254 * the frame is modified.
255 */
257
258#endif
259
260/** @} */
#define _NORETURN
Definition config.h:28
#define IDT_GATE_AMOUNT
Number of IDT gates.
Definition idt.h:20
void interrupt_handler(interrupt_frame_t *frame)
Handles CPU interrupts.
Definition interrupt.c:184
_NORETURN void interrupt_fake(interrupt_frame_t *frame)
Enter a fake interrupt context as if an interrupt had occurred at the given frame.
void * vectorTable[IDT_GATE_AMOUNT]
Pointers to functions to handle each vector.
page_fault_errors_t
Page Fault Error Codes.
Definition interrupt.h:106
interrupt_vector_t
Interrupt Vectors.
Definition interrupt.h:143
@ PAGE_FAULT_SOFTWARE_GUARD_EXT
Definition interrupt.h:114
@ PAGE_FAULT_WRITE
Definition interrupt.h:108
@ PAGE_FAULT_INSTRUCTION
Definition interrupt.h:111
@ PAGE_FAULT_USER
Definition interrupt.h:109
@ PAGE_FAULT_RESERVED
Definition interrupt.h:110
@ PAGE_FAULT_PRESENT
Definition interrupt.h:107
@ PAGE_FAULT_SHADOW_STACK
Definition interrupt.h:113
@ PAGE_FAULT_PROTECTION_KEY
Definition interrupt.h:112
@ VECTOR_VMM_COMMUNICATION_EXCEPTION
Definition interrupt.h:168
@ VECTOR_INTERNAL_START
Inclusive start of internal interrupts.
Definition interrupt.h:177
@ VECTOR_EXTERNAL_END
Exclusive end of external interrupts.
Definition interrupt.h:173
@ VECTOR_DEBUG
Definition interrupt.h:146
@ VECTOR_EXTERNAL_START
Inclusive start of external interrupts (handled by the IRQ system).
Definition interrupt.h:172
@ VECTOR_RESERVED
Definition interrupt.h:160
@ VECTOR_BOUND_RANGE_EXCEEDED
Definition interrupt.h:150
@ VECTOR_IPI
See IPI for more information.
Definition interrupt.h:179
@ VECTOR_HYPERVISOR_INJECTION_EXCEPTION
Definition interrupt.h:167
@ VECTOR_STACK_SEGMENT_FAULT
Definition interrupt.h:157
@ VECTOR_COPROCESSOR_SEGMENT_OVERRUN
Definition interrupt.h:154
@ VECTOR_VIRTUALIZATION_EXCEPTION
Definition interrupt.h:165
@ VECTOR_X87_FLOATING_POINT_EXCEPTION
Definition interrupt.h:161
@ VECTOR_PAGE_FAULT
Definition interrupt.h:159
@ VECTOR_SIMD_FLOATING_POINT_EXCEPTION
Definition interrupt.h:164
@ VECTOR_EXCEPTION_START
Inclusive start of exceptions.
Definition interrupt.h:144
@ VECTOR_INVALID_TSS
Definition interrupt.h:155
@ VECTOR_GENERAL_PROTECTION_FAULT
Definition interrupt.h:158
@ VECTOR_INTERNAL_END
Exclusive end of internal interrupts.
Definition interrupt.h:182
@ VECTOR_DOUBLE_FAULT
Definition interrupt.h:153
@ VECTOR_OVERFLOW
Definition interrupt.h:149
@ VECTOR_FAKE
Used to implement interrupt_fake().
Definition interrupt.h:178
@ VECTOR_CONTROL_PROTECTION_EXCEPTION
Definition interrupt.h:166
@ VECTOR_NMI
Definition interrupt.h:147
@ VECTOR_SEGMENT_NOT_PRESENT
Definition interrupt.h:156
@ VECTOR_SECURITY_EXCEPTION
Definition interrupt.h:169
@ VECTOR_TIMER
See Timer subsystem for more information.
Definition interrupt.h:180
@ VECTOR_EXTERNAL_AMOUNT
Definition interrupt.h:175
@ VECTOR_DIVIDE_ERROR
Definition interrupt.h:145
@ VECTOR_SPURIOUS
Made available for any component to use as a sink for spurious interrupts.
Definition interrupt.h:181
@ VECTOR_TOTAL_AMOUNT
Definition interrupt.h:184
@ VECTOR_DEVICE_NOT_AVAILABLE
Definition interrupt.h:152
@ VECTOR_MACHINE_CHECK
Definition interrupt.h:163
@ VECTOR_INVALID_OPCODE
Definition interrupt.h:151
@ VECTOR_EXCEPTION_END
Exclusive end of exceptions.
Definition interrupt.h:170
@ VECTOR_ALIGNMENT_CHECK
Definition interrupt.h:162
@ VECTOR_BREAKPOINT
Definition interrupt.h:148
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
CPU structure.
Definition cpu.h:84
Trap Frame Structure.
Definition interrupt.h:195
uint64_t errorCode
Definition interrupt.h:213