PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
ipi.h
Go to the documentation of this file.
1#pragma once
2
4#include <kernel/cpu/irq.h>
5#include <kernel/sync/lock.h>
7
8#include <stdbool.h>
9#include <stdint.h>
10#include <sys/list.h>
11
12typedef struct cpu cpu_t;
13
14/**
15 * @brief Inter-Processor Interrupts (IPIs)
16 * @defgroup kernel_cpu_ipi IPI
17 * @ingroup kernel_cpu
18 *
19 * Inter-Processor Interrupts are a way to remotely interrupt another CPU, this could be done with any interrupt vector,
20 * but for the sake of simplicity we reserve a single interrupt vector `VECTOR_IPI` for IPIs which, when received,
21 * will cause the CPU to check its IPI queue for any pending IPIs to execute.
22 *
23 * The actual remote interrupt invocation of the IPI is handled by a "IPI chip", usually the local APIC, which is
24 * implemented in a module.
25 *
26 * @{
27 */
28
29/**
30 * @brief Inter-Processor Interrupt (IPI) chip structure.
31 * @struct ipi_chip_t
32 *
33 * Represents a implemented hardware IPI controller, such as the local APIC.
34 */
35typedef struct ipi_chip
36{
37 const char* name;
38 /**
39 * @brief Should interrupt the given CPU with the given virtual IRQ.
40 *
41 * Should panic on failure.
42 *
43 * @param cpu The target CPU.
44 * @param virt The virtual IRQ to interrupt the CPU with.
45 */
46 void (*interrupt)(cpu_t* cpu, irq_virt_t virt);
47 void (*ack)(void);
48 void (*eoi)(void);
50
51/**
52 * @brief IPI function data structure.
53 * @struct ipi_func_data_t
54 *
55 * Data passed to an IPI function when invoked.
56 */
57typedef struct
58{
59 void* data;
61
62/**
63 * @brief IPI function type.
64 */
66
67/**
68 * @brief IPI structure.
69 * @struct ipi_t
70 *
71 * Represents a single IPI to be executed on a CPU.
72 */
73typedef struct ipi
74{
76 void* data;
77} ipi_t;
78
79/**
80 * @brief IPI queue size.
81 */
82#define IPI_QUEUE_SIZE 16
83
84/**
85 * @brief Per-CPU IPI context.
86 * @struct ipi_cpu_t
87 *
88 * Stores the IPIs received by the owner CPU.
89 */
90typedef struct ipi_cpu_ctx
91{
93 size_t readIndex;
94 size_t writeIndex;
96} ipi_cpu_t;
97
98/**
99 * @brief IPI flags.
100 * @enum ipi_flags_t
101 */
102typedef enum
103{
104 IPI_SINGLE = 0 << 0, ///< Send the IPI to the specified CPU.
105 IPI_BROADCAST = 1 << 0, ///< Send the IPI to all CPUs, specified CPU ignored.
106 IPI_OTHERS = 2 << 0, ///< Send the IPI to all CPUs except the specified CPU.
108
109/**
110 * @brief Initialize per-CPU IPI context.
111 *
112 * @param ctx The IPI context to initialize.
113 */
115
116/**
117 * @brief Handle pending IPIs on the current CPU.
118 *
119 * @param frame The interrupt frame.
120 */
122
123/**
124 * @brief Register an IPI chip.
125 *
126 * There can only be a single IPI chip registered at a time.
127 *
128 * @param chip The IPI chip to register.
129 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
130 * - `EINVAL`: Invalid parameters.
131 * - `EBUSY`: An IPI chip is already registered.
132 */
134
135/**
136 * @brief Unregister the IPI chip.
137 *
138 * If the given chip is not the registered chip, this is a no-op.
139 *
140 * @param chip The IPI chip to unregister, or `NULL` for no-op.
141 */
143
144/**
145 * @brief Get the number of registered IPI chips.
146 *
147 * Will always be `0` or `1`.
148 *
149 * @return The number of registered IPI chips.
150 */
152
153/**
154 * @brief Send an IPI to one or more CPUs.
155 *
156 * The CPU(s) is notified of the IPI by receiving a `VECTOR_IPI` interrupt.
157 *
158 * @param cpu The specified CPU, check `ipi_flags_t`.
159 * @param flags The flags for how to send the IPI.
160 * @param func The function to execute on target CPU(s).
161 * @param private The private data to pass to the function, will be found in `irq_func_data_t->data`.
162 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
163 * - `EINVAL`: Invalid parameters.
164 * - `ENODEV`: No IPI chip is registered.
165 * - `ENOSYS`: The registered IPI chip does not have a `notify` function.
166 * - `EBUSY`: The target CPU's IPI queue is full, some or all IPIs could not be sent.
167 * - Other errors returned by the IPI chip's `notify` function.
168 */
170
171/**
172 * @brief Wake up one or more CPUs.
173 *
174 * A wake-up IPI is an IPI with no function to execute, used to wake up a CPU that may be idle or sleeping and to prompt
175 * it to check for pending IPIs, notes, etc.
176 *
177 * @param cpu The specified CPU, check `ipi_flags_t`.
178 * @param flags The flags for how to send the IPI.
179 */
181
182/**
183 * @brief Invoke a IPI interrupt on the current CPU.
184 *
185 * Will use `IRQ_INVOKE(VECTOR_IPI)` to trigger the IPI interrupt, causing the CPU to enter an interrupt context and
186 * handle any pending IPIs, notes and potentially scheduling.
187 */
188void ipi_invoke(void);
189
190/** @} */
static fd_t data
Definition dwm.c:21
uint64_t ipi_send(cpu_t *cpu, ipi_flags_t flags, ipi_func_t func, void *data)
Send an IPI to one or more CPUs.
Definition ipi.c:140
#define IPI_QUEUE_SIZE
IPI queue size.
Definition ipi.h:82
ipi_flags_t
IPI flags.
Definition ipi.h:103
void ipi_handle_pending(interrupt_frame_t *frame)
Handle pending IPIs on the current CPU.
Definition ipi.c:26
void ipi_invoke(void)
Invoke a IPI interrupt on the current CPU.
Definition ipi.c:269
void ipi_wake_up(cpu_t *cpu, ipi_flags_t flags)
Wake up one or more CPUs.
Definition ipi.c:215
void ipi_cpu_init(ipi_cpu_t *ctx)
Initialize per-CPU IPI context.
void(* ipi_func_t)(ipi_func_data_t *data)
IPI function type.
Definition ipi.h:65
uint64_t ipi_chip_register(ipi_chip_t *chip)
Register an IPI chip.
Definition ipi.c:65
uint64_t ipi_chip_amount(void)
Get the number of registered IPI chips.
Definition ipi.c:104
void ipi_chip_unregister(ipi_chip_t *chip)
Unregister the IPI chip.
Definition ipi.c:86
@ IPI_OTHERS
Send the IPI to all CPUs except the specified CPU.
Definition ipi.h:106
@ IPI_SINGLE
Send the IPI to the specified CPU.
Definition ipi.h:104
@ IPI_BROADCAST
Send the IPI to all CPUs, specified CPU ignored.
Definition ipi.h:105
uint8_t irq_virt_t
Virtual IRQ numbers.
Definition irq.h:57
static const path_flag_t flags[]
Definition path.c:47
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
CPU structure.
Definition cpu.h:84
Trap Frame Structure.
Definition interrupt.h:195
Inter-Processor Interrupt (IPI) chip structure.
Definition ipi.h:36
const char * name
Definition ipi.h:37
Per-CPU IPI context.
Definition ipi.h:91
size_t readIndex
Definition ipi.h:93
size_t writeIndex
Definition ipi.h:94
lock_t lock
Definition ipi.h:95
IPI function data structure.
Definition ipi.h:58
void * data
Definition ipi.h:59
IPI structure.
Definition ipi.h:74
void * data
Definition ipi.h:76
ipi_func_t func
Definition ipi.h:75
A simple ticket lock implementation.
Definition lock.h:44