45 panic(
NULL,
"Failed to init exception stack for cpu %u\n", cpu->
id);
54 panic(
NULL,
"Failed to init double fault stack for cpu %u\n", cpu->
id);
63 panic(
NULL,
"Failed to init NMI stack for cpu %u\n", cpu->
id);
72 panic(
NULL,
"Failed to init interrupt stack for cpu %u\n", cpu->
id);
125 eventHandler->
func = func;
133 eventHandler->
func(self, &event);
162 if (eventHandler->
func == func)
174 bool expected =
true;
187 eventHandler->
func(cpu, &event);
197 panic(
NULL,
"CPU%u exception stack overflow detected", cpu->
id);
201 panic(
NULL,
"CPU%u double fault stack overflow detected", cpu->
id);
205 panic(
NULL,
"CPU%u NMI stack overflow detected", cpu->
id);
209 panic(
NULL,
"CPU%u interrupt stack overflow detected", cpu->
id);
219 asm volatile(
"cli; hlt");
222 __builtin_unreachable();
static void cpu_halt_ipi_handler(ipi_func_data_t *data)
static uint64_t eventHandlerCount
static lock_t eventHandlerLock
static cpu_handler_t eventHandlers[CPU_MAX_EVENT_HANDLERS]
void gdt_cpu_tss_load(tss_t *tss)
Load a TSS into the GDT and load it using the ltr instruction on the current CPU.
void gdt_cpu_load(void)
Load the GDT on the current CPU.
void idt_cpu_load(void)
Load the IDT on the current CPU.
void interrupt_ctx_init(interrupt_ctx_t *ctx)
Initializes the interrupt context.
void ipi_cpu_ctx_init(ipi_cpu_ctx_t *ctx)
Initialize per-CPU IPI context.
uint64_t ipi_send(cpu_t *cpu, ipi_flags_t flags, ipi_func_t func, void *private)
Send an IPI to one or more CPUs.
@ IPI_OTHERS
Send the IPI to all CPUs except the specified CPU.
void stack_pointer_deinit_buffer(stack_pointer_t *stack)
Deinitializes a stack pointer structure that was initialized using stack_pointer_init_buffer().
uint64_t stack_pointer_init_buffer(stack_pointer_t *stack, void *buffer, uint64_t pages)
Initializes a stack pointer structure using a provided buffer, does not allocate or map any memory.
void syscalls_cpu_init(void)
Initialize syscalls on the current CPU.
void tss_ist_load(tss_t *tss, tss_ist_t ist, stack_pointer_t *stack)
Load a stack into an IST entry.
#define TSS_IST_NMI
The IST index to use for non-maskable interrupts.
void tss_init(tss_t *tss)
Initialize a TSS structure.
#define TSS_IST_INTERRUPT
The IST index to use for other interrupts.
#define TSS_IST_EXCEPTION
The IST index to use for exceptions.
#define TSS_IST_DOUBLE_FAULT
The IST index to use for double faults.
uint64_t cpu_halt_others(void)
Halts all other CPUs.
void cpu_stacks_overflow_check(cpu_t *cpu)
Checks for CPU stack overflows.
uint64_t cpu_handler_register(cpu_func_t func)
Registers a CPU event handler for all CPUs.
static cpu_t * cpu_get_unsafe(void)
Gets the current CPU structure without disabling interrupts.
void(* cpu_func_t)(cpu_t *cpu, const cpu_event_t *event)
CPU event function type.
void cpu_init(cpu_t *cpu)
Initializes the CPU represented by the cpu_t structure.
#define CPU_MAX
Maximum number of CPUs supported.
cpu_t * _cpus[CPU_MAX]
Array of pointers to cpu_t structures for each CPU, indexed by CPU ID.
#define CPU_STACK_CANARY
CPU stack canary value.
void cpu_handlers_check(cpu_t *cpu)
Checks if any handlers have been registered since the last check, and invokes them if so.
#define CPU_FOR_EACH(cpu)
Macro to iterate over all CPUs.
void cpu_init_early(cpu_t *cpu)
Only initialize the parts of the CPU structure needed for early boot.
#define CPU_MAX_EVENT_HANDLERS
Maximum number of CPU event handlers that can be registered.
void cpu_handler_unregister(cpu_func_t func)
Unregisters a previously registered CPU event handler.
uint16_t _cpuAmount
The number of CPUs currently identified.
uint16_t cpuid_t
Type used to identify a CPU.
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
void vmm_cpu_ctx_init(vmm_cpu_ctx_t *ctx)
Initializes a per-CPU VMM context and performs per-CPU VMM initialization.
void wait_init(wait_t *wait)
Initialize an instance of the waiting subsystem.
void sched_init(sched_t *sched)
Initialize the scheduler for a CPU.
#define LOCK_CREATE()
Create a lock initializer.
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
void timer_cpu_ctx_init(timer_cpu_ctx_t *ctx)
Initialize per-CPU timer context.
#define CONFIG_INTERRUPT_STACK_PAGES
Interrupt stack configuration.
#define EEXIST
File exists.
#define EINVAL
Invalid argument.
#define EBUSY
Device or resource busy.
#define errno
Error number variable.
void bitmap_clear_range(bitmap_t *map, uint64_t low, uint64_t high)
Clear a range of bits in the bitmap.
bool bitmap_is_set(bitmap_t *map, uint64_t idx)
Check if a bit is set in the bitmap.
void bitmap_set(bitmap_t *map, uint64_t index)
Set a bit in the bitmap.
#define BITMAP_DEFINE_INIT(name, bits)
Initialize a bitmap defined with BITMAP_DEFINE.
#define NULL
Pointer error value.
#define ERR
Integer error value.
static void msr_write(uint32_t msr, uint64_t value)
#define atomic_store(object, desired)
#define atomic_compare_exchange_strong(object, expected, desired)
_PUBLIC void * memmove(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
interrupt_ctx_t interrupt
atomic_bool needHandlersCheck
stack_pointer_t exceptionStack
stack_pointer_t interruptStack
stack_pointer_t doubleFaultStack
IPI function data structure.
A simple ticket lock implementation.
uintptr_t bottom
The bottom of the stack, this address is inclusive.