PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
cpu.c
Go to the documentation of this file.
1#include <errno.h>
2#include <kernel/cpu/cpu.h>
3
4#include <kernel/cpu/gdt.h>
5#include <kernel/cpu/idt.h>
7#include <kernel/cpu/ipi.h>
8#include <kernel/cpu/simd.h>
10#include <kernel/cpu/tss.h>
11#include <kernel/drivers/perf.h>
12#include <kernel/log/log.h>
13#include <kernel/log/panic.h>
14#include <kernel/mem/vmm.h>
15#include <kernel/sched/sched.h>
16#include <kernel/sync/lock.h>
17#include <kernel/sync/rwlock.h>
18#include <kernel/utils/map.h>
19
20#include <stdatomic.h>
21#include <stdint.h>
22#include <sys/list.h>
23
26
27void cpu_init(cpu_t* cpu)
28{
29 cpu_id_t id = _cpuAmount++;
30 _cpus[id] = cpu;
32
33 cpu->self = cpu;
34 cpu->id = id;
35 cpu->syscallRsp = 0;
36 cpu->userRsp = 0;
37 cpu->inInterrupt = false;
38
41 tss_init(&cpu->tss);
42 gdt_cpu_tss_load(&cpu->tss);
43
44 percpu_init(cpu);
45
46 if (stack_pointer_init_buffer(&cpu->exceptionStack, cpu->exceptionStackBuffer, CONFIG_INTERRUPT_STACK_PAGES) == ERR)
47 {
48 panic(NULL, "Failed to init exception stack for cpu %u\n", cpu->id);
49 }
52
53 if (stack_pointer_init_buffer(&cpu->doubleFaultStack, cpu->doubleFaultStackBuffer, CONFIG_INTERRUPT_STACK_PAGES) ==
54 ERR)
55 {
57 panic(NULL, "Failed to init double fault stack for cpu %u\n", cpu->id);
58 }
61
62 if (stack_pointer_init_buffer(&cpu->nmiStack, cpu->nmiStackBuffer, CONFIG_INTERRUPT_STACK_PAGES) == ERR)
63 {
66 panic(NULL, "Failed to init NMI stack for cpu %u\n", cpu->id);
67 }
69 tss_ist_load(&cpu->tss, TSS_IST_NMI, &cpu->nmiStack);
70
71 if (stack_pointer_init_buffer(&cpu->interruptStack, cpu->interruptStackBuffer, CONFIG_INTERRUPT_STACK_PAGES) == ERR)
72 {
75 panic(NULL, "Failed to init interrupt stack for cpu %u\n", cpu->id);
76 }
79
80 memset(cpu->percpu, 0, CONFIG_PERCPU_SIZE);
81}
82
84{
85 if (*(uint64_t*)SELF->exceptionStack.bottom != CPU_STACK_CANARY)
86 {
87 panic(NULL, "CPU%u exception stack overflow detected", SELF->id);
88 }
89 if (*(uint64_t*)SELF->doubleFaultStack.bottom != CPU_STACK_CANARY)
90 {
91 panic(NULL, "CPU%u double fault stack overflow detected", SELF->id);
92 }
93 if (*(uint64_t*)SELF->nmiStack.bottom != CPU_STACK_CANARY)
94 {
95 panic(NULL, "CPU%u NMI stack overflow detected", SELF->id);
96 }
97 if (*(uint64_t*)SELF->interruptStack.bottom != CPU_STACK_CANARY)
98 {
99 panic(NULL, "CPU%u interrupt stack overflow detected", SELF->id);
100 }
101}
102
104{
105 UNUSED(data);
106
107 while (true)
108 {
109 ASM("cli; hlt");
110 }
111
112 __builtin_unreachable();
113}
114
116{
118 {
119 return ERR;
120 }
121 return 0;
122}
123
125{
126 return SELF->interruptStack.top;
127}
static void cpu_halt_ipi_handler(ipi_func_data_t *data)
Definition cpu.c:103
static fd_t data
Definition dwm.c:21
static char * id
Definition dwm.c:20
#define CONFIG_PERCPU_SIZE
Per-CPU data size configuration.
Definition config.h:173
#define CONFIG_INTERRUPT_STACK_PAGES
Interrupt stack configuration.
Definition config.h:21
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.
Definition gdt.c:64
void gdt_cpu_load(void)
Load the GDT on the current CPU.
Definition gdt.c:56
void idt_cpu_load(void)
Load the IDT on the current CPU.
Definition idt.c:53
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
@ IPI_OTHERS
Send the IPI to all CPUs except the specified CPU.
Definition ipi.h:106
void percpu_init(cpu_t *cpu)
Initialize the percpu system.
Definition percpu.c:33
#define SELF
Macro to access data in the current cpu.
Definition percpu.h:85
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 tss_ist_load(tss_t *tss, tss_ist_t ist, stack_pointer_t *stack)
Load a stack into an IST entry.
Definition tss.c:21
#define TSS_IST_NMI
The IST index to use for non-maskable interrupts.
Definition tss.h:50
void tss_init(tss_t *tss)
Initialize a TSS structure.
Definition tss.c:5
#define TSS_IST_INTERRUPT
The IST index to use for other interrupts.
Definition tss.h:55
#define TSS_IST_EXCEPTION
The IST index to use for exceptions.
Definition tss.h:40
#define TSS_IST_DOUBLE_FAULT
The IST index to use for double faults.
Definition tss.h:45
uint64_t cpu_halt_others(void)
Halts all other CPUs.
Definition cpu.c:115
void cpu_stacks_overflow_check(void)
Checks the current CPU for stack overflows.
Definition cpu.c:83
uintptr_t cpu_interrupt_stack_top(void)
Gets the top of the interrupt stack for the current CPU.
Definition cpu.c:124
uint16_t cpu_id_t
Type used to identify a CPU.
Definition cpu.h:65
void cpu_init(cpu_t *cpu)
Initializes a CPU structure.
Definition cpu.c:27
#define CPU_MAX
Maximum number of CPUs supported.
Definition cpu.h:50
cpu_t * _cpus[CPU_MAX]
Array of pointers to cpu_t structures for each CPU, indexed by CPU ID.
Definition cpu.c:24
#define CPU_STACK_CANARY
CPU stack canary value.
Definition cpu.h:73
uint16_t _cpuAmount
The number of CPUs currently identified.
Definition cpu.c:25
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:292
#define ASM(...)
Inline assembly macro.
Definition defs.h:160
#define UNUSED(x)
Mark a variable as unused.
Definition defs.h:96
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
#define MSR_TSC_AUX
Definition regs.h:14
static void msr_write(uint32_t msr, uint64_t value)
Definition regs.h:73
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
__UINT16_TYPE__ uint16_t
Definition stdint.h:13
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4
CPU structure.
Definition cpu.h:84
cpu_id_t id
Definition cpu.h:86
stack_pointer_t exceptionStack
Definition cpu.h:93
tss_t tss
Definition cpu.h:92
uint64_t userRsp
Definition cpu.h:88
stack_pointer_t interruptStack
Definition cpu.h:96
uint64_t syscallRsp
Definition cpu.h:87
stack_pointer_t nmiStack
Definition cpu.h:95
stack_pointer_t doubleFaultStack
Definition cpu.h:94
volatile bool inInterrupt
Definition cpu.h:89
cpu_t * self
Definition cpu.h:85
IPI function data structure.
Definition ipi.h:58
uintptr_t bottom
The bottom of the stack, this address is inclusive.