PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
lapic.h
Go to the documentation of this file.
1#pragma once
2
3#include <kernel/cpu/cpu.h>
4#include <kernel/cpu/irq.h>
5#include <kernel/cpu/percpu.h>
6
7#include <stdint.h>
8
9/**
10 * @brief Local Advanced Programmable Interrupt Controller.
11 * @defgroup kernel_drivers_apic_lapic Local APIC
12 * @ingroup kernel_drivers_apic
13 *
14 * ## Local APICs
15 *
16 * Each CPU has its own local APIC, which, when used with the IO APICs, allows for more advanced
17 * interrupt handling in comparison to the traditional PIC, such as routing interrupts to specific CPUs, interrupt
18 * prioritization, and more. Most of its features are not used in PatchworkOS yet.
19 *
20 * Additionally, the local APICs provide Inter-Processor Interrupts (IPIs) which allow a CPU to interrupt another CPU by
21 * using its local APIC.
22 *
23 * @note Its a common mistake to assume that the local APIC IDs are contiguous, or that they are the same as the CPU
24 * IDs, but this is not the case. The local APIC IDs are assigned by the firmware and can be any value.
25 *
26 * @see [ACPI Specification Version 6.6](https://uefi.org/sites/default/files/resources/ACPI_Spec_6.6.pdf)
27 *
28 * @{
29 */
30
31/**
32 * @brief Local APIC ID type.
33 */
35
36/**
37 * @brief Local APIC MSR Flags.
38 * @enum lapic_msr_flags_t
39 */
40typedef enum
41{
43 LAPIC_MSR_BSP = 0x100
45
46/**
47 * @brief Local APIC Registers.
48 * @enum lapic_register_t
49 */
79
80/**
81 * @brief The offset at which the lapic id is stored in the LAPIC_REG_ID register.
82 */
83#define LAPIC_REG_ID_OFFSET 24
84
85/**
86 * @brief Local APIC Flags.
87 * @enum lapic_flags_t
88 */
89typedef enum
90{
92 LAPIC_LVT_MASKED = (1 << 16)
94
95/**
96 * @brief Local APIC ICR Delivery Modes.
97 * @enum lapic_icr_delivery_mode_t
98 */
99typedef enum
100{
101 LAPIC_ICR_FIXED = (0 << 8),
103 LAPIC_ICR_SMI = (2 << 8),
104 LAPIC_ICR_NMI = (4 << 8),
105 LAPIC_ICR_INIT = (5 << 8),
106 LAPIC_ICR_STARTUP = (6 << 8)
108
109/**
110 * @brief Local APIC ICR Flags.
111 * @enum lapic_icr_flags_t
112 */
113typedef enum
114{
117
118/**
119 * @brief Local APIC Structure.
120 * @struct lapic_t
121 *
122 * Represents each CPU's local APIC and local data.
123 */
124typedef struct
125{
126 uint64_t ticksPerMs; ///< Initialized to 0, set on first use of the APIC timer on the CPU.
128} lapic_t;
129
130/**
131 * @brief The per-CPU local APIC structure.
132 */
134
135/**
136 * @brief Initialize the local APIC for a CPU.
137 *
138 * @param cpu The current CPU.
139 */
140void lapic_init(cpu_t* cpu);
141
142/**
143 * @brief Read from a local apic register.
144 *
145 * @param reg The register to read from.
146 * @return The value read from the register.
147 */
149
150/**
151 * @brief Write to a local apic register.
152 *
153 * @param reg The register to write to.
154 * @param value The value to write.
155 */
156void lapic_write(uint32_t reg, uint32_t value);
157
158/**
159 * @brief Send an INIT IPI to the specified local APIC.
160 *
161 * Sending an INIT IPI will cause the target CPU to enter the INIT state, preparing it for startup.
162 *
163 * @param id The ID of the local APIC to send the INIT IPI to.
164 */
166
167/**
168 * @brief Send a Startup IPI (SIPI) to the specified local APIC.
169 *
170 * Sending a SIPI will cause the target CPU to start executing code at the specified entry point address.
171 *
172 * @param id The ID of the local APIC to send the SIPI to.
173 * @param entryPoint The entry point address for the SIPI, must be page-aligned.
174 */
175void lapic_send_sipi(lapic_id_t id, void* entryPoint);
176
177/**
178 * @brief Global initialization for the local APICs.
179 *
180 * @return On success, `0`. On failure, `ERR` and `errno` is set.
181 */
183
184/** @} */
#define PERCPU
Attribute specifying that the variable is an offset into the GS segment register.
Definition percpu.h:75
lapic_flags_t
Local APIC Flags.
Definition lapic.h:90
void lapic_init(cpu_t *cpu)
Initialize the local APIC for a CPU.
lapic_msr_flags_t
Local APIC MSR Flags.
Definition lapic.h:41
void lapic_send_init(lapic_id_t id)
Send an INIT IPI to the specified local APIC.
Definition lapic.c:66
void lapic_send_sipi(lapic_id_t id, void *entryPoint)
Send a Startup IPI (SIPI) to the specified local APIC.
Definition lapic.c:72
lapic_icr_flags_t
Local APIC ICR Flags.
Definition lapic.h:114
uint32_t lapic_read(uint32_t reg)
Read from a local apic register.
Definition lapic.c:37
uint64_t lapic_global_init(void)
Global initialization for the local APICs.
Definition lapic.c:80
lapic_t PERCPU _pcpu_lapic
The per-CPU local APIC structure.
uint8_t lapic_id_t
Local APIC ID type.
Definition lapic.h:34
lapic_register_t
Local APIC Registers.
Definition lapic.h:51
lapic_icr_delivery_mode_t
Local APIC ICR Delivery Modes.
Definition lapic.h:100
void lapic_write(uint32_t reg, uint32_t value)
Write to a local apic register.
Definition lapic.c:42
@ LAPIC_LVT_MASKED
Definition lapic.h:92
@ LAPIC_SPURIOUS_ENABLE
Definition lapic.h:91
@ LAPIC_MSR_BSP
Definition lapic.h:43
@ LAPIC_MSR_ENABLE
Definition lapic.h:42
@ LAPIC_ICR_CLEAR_INIT_LEVEL
Definition lapic.h:115
@ LAPIC_REG_TASK_PRIORITY
Definition lapic.h:54
@ LAPIC_REG_TIMER_CURRENT_COUNT
Definition lapic.h:76
@ LAPIC_REG_TIMER_INITIAL_COUNT
Definition lapic.h:75
@ LAPIC_REG_LVT_CMCI
Definition lapic.h:66
@ LAPIC_REG_REMOTE_READ
Definition lapic.h:58
@ LAPIC_REG_LOGICAL_DEST
Definition lapic.h:59
@ LAPIC_REG_LVT_PERFCTR
Definition lapic.h:71
@ LAPIC_REG_ERROR_STATUS
Definition lapic.h:65
@ LAPIC_REG_TIMER_DIVIDER
Definition lapic.h:77
@ LAPIC_REG_LVT_THERMAL
Definition lapic.h:70
@ LAPIC_REG_LVT_LINT0
Definition lapic.h:72
@ LAPIC_REG_IRR_BASE
Definition lapic.h:64
@ LAPIC_REG_VERSION
Definition lapic.h:53
@ LAPIC_REG_PROCESSOR_PRIORITY
Definition lapic.h:56
@ LAPIC_REG_ID
Definition lapic.h:52
@ LAPIC_REG_LVT_ERROR
Definition lapic.h:74
@ LAPIC_REG_ISR_BASE
Definition lapic.h:62
@ LAPIC_REG_ICR1
Definition lapic.h:68
@ LAPIC_REG_TMR_BASE
Definition lapic.h:63
@ LAPIC_REG_EOI
Definition lapic.h:57
@ LAPIC_REG_DEST_FORMAT
Definition lapic.h:60
@ LAPIC_REG_ARBITRATION_PRIORITY
Definition lapic.h:55
@ LAPIC_REG_LVT_LINT1
Definition lapic.h:73
@ LAPIC_REG_SPURIOUS
Definition lapic.h:61
@ LAPIC_REG_ICR0
Definition lapic.h:67
@ LAPIC_REG_LVT_TIMER
Definition lapic.h:69
@ LAPIC_ICR_SMI
Definition lapic.h:103
@ LAPIC_ICR_STARTUP
Definition lapic.h:106
@ LAPIC_ICR_LOWEST_PRIORITY
Definition lapic.h:102
@ LAPIC_ICR_FIXED
Definition lapic.h:101
@ LAPIC_ICR_NMI
Definition lapic.h:104
@ LAPIC_ICR_INIT
Definition lapic.h:105
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
CPU structure.
Definition cpu.h:84
Local APIC Structure.
Definition lapic.h:125
uint64_t ticksPerMs
Initialized to 0, set on first use of the APIC timer on the CPU.
Definition lapic.h:126
lapic_id_t lapicId
Definition lapic.h:127