CPU.
More...
CPU.
CPU structures and functions.
Events
Each CPU can generate events which can be handled by registering event handlers using cpu_handler_register().
As an example, the CPU_ONLINE event allows other subsystems to perform per-CPU initialization on each CPU no matter when they are initialized or even if IPIs are available yet.
This is what makes it possible for SMP to be in a module, at the cost of the system being perhaps slightly unintuitive and edge case heavy.
For more details see cpu_handler_register(), cpu_handler_unregister(), and cpu_handlers_check().
Per-CPU Data
- Todo:
- Implement per-CPU data. Use separate linker section?
|
| | GDT |
| | Global Descriptor Table.
|
| |
| | IDT |
| | Interrupt Descriptor Table.
|
| |
| | Interrupts |
| | Interrupt Handling.
|
| |
| | Port I/O |
| | I/O port operations and reservations.
|
| |
| | IPI |
| | Inter-Processor Interrupts (IPIs)
|
| |
| | IRQ |
| | Interrupt Requests (IRQs)
|
| |
| | SIMD |
| | SIMD context management.
|
| |
| | Stack Pointer |
| | Helpers for managing stacks.
|
| |
| | Syscall |
| | System Call Interface.
|
| |
| | TSS |
| | Task State Segment.
|
| |
◆ CPU_MAX [1/2]
Maximum number of CPUs supported.
Definition at line 51 of file cpu.h.
◆ CPU_ID_BOOTSTRAP [1/2]
| #define CPU_ID_BOOTSTRAP 0 |
ID of the bootstrap CPU.
Definition at line 56 of file cpu.h.
◆ CPU_ID_INVALID [1/2]
Invalid CPU ID.
Definition at line 61 of file cpu.h.
◆ CPU_STACK_CANARY
| #define CPU_STACK_CANARY 0x1234567890ABCDEFULL |
CPU stack canary value.
Placed at the bottom of CPU stacks, we then check in the interrupt handler if any of the stacks have overflowed by checking if its canary has been modified.
Definition at line 74 of file cpu.h.
◆ CPU_MAX_EVENT_HANDLERS
| #define CPU_MAX_EVENT_HANDLERS 32 |
Maximum number of CPU event handlers that can be registered.
We need to statically allocate the event handler array such that handlers can be registered before memory allocation has been initialized.
Definition at line 100 of file cpu.h.
◆ CPU_FOR_EACH
| #define CPU_FOR_EACH |
( |
|
cpu | ) |
|
Value:
cpu_t * _cpus[CPU_MAX]
Array of pointers to cpu_t structures for each CPU, indexed by CPU ID.
uint16_t _cpuAmount
The number of CPUs currently identified.
uint16_t cpuid_t
Type used to identify a CPU.
#define NULL
Pointer error value.
Macro to iterate over all CPUs.
The main reason for using this macro is to avoid changes the the internal implementation of how CPUs are stored affecting other parts of the code.
- Parameters
-
| cpu | Loop variable, a pointer to the current cpu_t. |
Definition at line 339 of file cpu.h.
◆ CPU_MAX [2/2]
Maximum number of CPUs supported.
Definition at line 14 of file cpu_id.h.
◆ CPU_ID_BOOTSTRAP [2/2]
| #define CPU_ID_BOOTSTRAP 0 |
ID of the bootstrap CPU.
Definition at line 19 of file cpu_id.h.
◆ CPU_ID_INVALID [2/2]
Invalid CPU ID.
Definition at line 24 of file cpu_id.h.
◆ cpuid_t [1/2]
Type used to identify a CPU.
Definition at line 66 of file cpu.h.
◆ cpu_func_t
CPU event function type.
Definition at line 105 of file cpu.h.
◆ cpuid_t [2/2]
Type used to identify a CPU.
Definition at line 29 of file cpu_id.h.
◆ cpu_event_type_t
CPU event types.
| Enumerator |
|---|
| CPU_ONLINE | |
| CPU_OFFLINE | |
Definition at line 80 of file cpu.h.
◆ cpu_init_early()
| void cpu_init_early |
( |
cpu_t * |
cpu | ) |
|
Only initialize the parts of the CPU structure needed for early boot.
The only reason we need this is to split the initialization of the bootstrap CPU to avoid circular dependencies during early boot and since we cant use memory allocation yet.
- Parameters
-
| cpu | The CPU structure to initialize. |
Definition at line 30 of file cpu.c.
◆ cpu_init()
| void cpu_init |
( |
cpu_t * |
cpu | ) |
|
Initializes the CPU represented by the cpu_t structure.
Must be called on the CPU that will be represented by the cpu structure, after setting the CPU ID MSR using cpu_init_early().
- Parameters
-
| cpu | The CPU structure to initialize. |
Definition at line 78 of file cpu.c.
◆ cpu_handler_register()
Registers a CPU event handler for all CPUs.
The registered handler will be immediately invoked with a CPU_ONLINE event on the current CPU, then invoked on all others when they call cpu_handlers_check() and on any new cpus when they are initialized.
- Parameters
-
| func | The event function to register a handler for. |
- Returns
- On success,
0. On failure, ERR and errno is set to:
EINVAL: Invalid parameters.
EBUSY: Too many event handlers registered.
EEXIST: A handler with the same function is already registered.
Definition at line 100 of file cpu.c.
◆ cpu_handler_unregister()
Unregisters a previously registered CPU event handler.
Will be a no-op if the handler was not registered.
- Parameters
-
| func | The event function of the handler to unregister, or NULL for no-op. |
Definition at line 150 of file cpu.c.
◆ cpu_handlers_check()
| void cpu_handlers_check |
( |
cpu_t * |
cpu | ) |
|
Checks if any handlers have been registered since the last check, and invokes them if so.
- Parameters
-
| cpu | The CPU to check, must be the current CPU. |
Definition at line 172 of file cpu.c.
◆ cpu_stacks_overflow_check()
| void cpu_stacks_overflow_check |
( |
cpu_t * |
cpu | ) |
|
Checks for CPU stack overflows.
Checks the canary values at the bottom of each CPU stack and if its been modified panics.
- Parameters
-
Definition at line 193 of file cpu.c.
◆ cpu_halt_others()
Halts all other CPUs.
- Returns
- On success,
0. On failure, ERR and errno is set.
Definition at line 225 of file cpu.c.
◆ cpu_amount()
Gets the number of identified CPUs.
Use this over _cpuAmount.
- Returns
- The number of identified CPUs.
Definition at line 234 of file cpu.h.
◆ cpu_get_by_id()
Gets a CPU structure by its ID.
- Parameters
-
| id | The ID of the CPU to get. |
- Returns
- A pointer to the CPU structure, or
NULL if no CPU with the given ID exists.
Definition at line 245 of file cpu.h.
◆ cpu_get()
| static cpu_t * cpu_get |
( |
void |
| ) |
|
|
inlinestatic |
Gets the current CPU structure.
Disables interrupts to prevent migration to another CPU.
Should be followed be a call to cpu_put() to re-enable interrupts.
- Returns
- A pointer to the current CPU structure.
Definition at line 263 of file cpu.h.
◆ cpu_put()
| static void cpu_put |
( |
void |
| ) |
|
|
inlinestatic |
Releases the current CPU structure.
Re-enables interrupts.
Definition at line 277 of file cpu.h.
◆ cpu_get_unsafe()
| static cpu_t * cpu_get_unsafe |
( |
void |
| ) |
|
|
inlinestatic |
Gets the current CPU structure without disabling interrupts.
- Warning
- This function does not disable interrupts, it should thus only be used when interrupts are already disabled.
- Returns
- A pointer to the current CPU structure.
Definition at line 289 of file cpu.h.
◆ cpu_get_id_unsafe()
| static cpuid_t cpu_get_id_unsafe |
( |
void |
| ) |
|
|
inlinestatic |
Gets the current CPU ID.
- Warning
- This function does not disable interrupts, it should thus only be used when interrupts are already disabled.
- Returns
- The current CPU ID.
Definition at line 306 of file cpu.h.
◆ cpu_get_next()
Gets the next CPU in the CPU array.
Wraps around to the first CPU if the current CPU is the last one.
- Parameters
-
- Returns
- A pointer to the next CPU.
Definition at line 321 of file cpu.h.
◆ _cpus
Array of pointers to cpu_t structures for each CPU, indexed by CPU ID.
We make this global since its accessed very frequently, so its a slight optimization.
Definition at line 23 of file cpu.c.
◆ _cpuAmount
The number of CPUs currently identified.
Use cpu_amount() over this variable.
Definition at line 24 of file cpu.c.