Max OS 0.3
Loading...
Searching...
No Matches
cpu.h
Go to the documentation of this file.
1
9#ifndef MAXOS_SYSTEM_CPU_H
10#define MAXOS_SYSTEM_CPU_H
11
12#include <cpuid.h>
13#include <cstddef>
14#include <cstdint>
15#include <system/gdt.h>
18#include <memory/physical.h>
19
20// Forward declare
21
22namespace MaxOS::processes {
23 class Scheduler;
24}
25
26
27namespace MaxOS::system {
28
37 typedef struct PACKED CPUStatus {
38
39 uint64_t r15;
40 uint64_t r14;
41 uint64_t r13;
42 uint64_t r12;
43 uint64_t r11;
44 uint64_t r10;
45 uint64_t r9;
46 uint64_t r8;
47 uint64_t rdi;
48 uint64_t rsi;
49 uint64_t rbp;
50 uint64_t rdx;
51 uint64_t rcx;
52 uint64_t rbx;
53 uint64_t rax;
54
56 uint64_t error_code;
57
58 uint64_t rip;
59 uint64_t cs;
60 uint64_t rflags;
61 uint64_t rsp;
62 uint64_t ss;
63
64 } cpu_status_t;
65
73 typedef struct PACKED TaskStateSegment {
74
75 uint32_t reserved0;
76 uint64_t rsp0;
77 uint64_t rsp1;
78 uint64_t rsp2;
79 uint64_t reserved1;
80 uint64_t reserved2;
81 uint64_t ist1;
82 uint64_t ist2;
83 uint64_t ist3;
84 uint64_t ist4;
85 uint64_t ist5;
86 uint64_t ist6;
87 uint64_t ist7;
88 uint64_t reserved3;
89 uint16_t reserved4;
91
92 } tss_t;
93
100 enum class CPU_FEATURE_ECX : int32_t {
101 SSE3 = 1 << 0,
102 PCLMUL = 1 << 1,
103 DTES64 = 1 << 2,
104 MONITOR = 1 << 3,
105 DS_CPL = 1 << 4,
106 VMX = 1 << 5,
107 SMX = 1 << 6,
108 EST = 1 << 7,
109 TM2 = 1 << 8,
110 SSSE3 = 1 << 9,
111 CID = 1 << 10,
112 SDBG = 1 << 11,
113 FMA = 1 << 12,
114 CX16 = 1 << 13,
115 XTPR = 1 << 14,
116 PDCM = 1 << 15,
117 PCID = 1 << 17,
118 DCA = 1 << 18,
119 SSE4_1 = 1 << 19,
120 SSE4_2 = 1 << 20,
121 X2APIC = 1 << 21,
122 MOVBE = 1 << 22,
123 POPCNT = 1 << 23,
124 TSC = 1 << 24,
125 AES = 1 << 25,
126 XSAVE = 1 << 26,
127 OSXSAVE = 1 << 27,
128 AVX = 1 << 28,
129 F16C = 1 << 29,
130 RDRAND = 1 << 30,
131 HYPERVISOR = 1 << 31,
132 };
133
140 enum class CPU_FEATURE_EDX : int32_t {
141 FPU = 1 << 0,
142 VME = 1 << 1,
143 DE = 1 << 2,
144 PSE = 1 << 3,
145 TSC = 1 << 4,
146 MSR = 1 << 5,
147 PAE = 1 << 6,
148 MCE = 1 << 7,
149 CX8 = 1 << 8,
150 APIC = 1 << 9,
151 SEP = 1 << 11,
152 MTRR = 1 << 12,
153 PGE = 1 << 13,
154 MCA = 1 << 14,
155 CMOV = 1 << 15,
156 PAT = 1 << 16,
157 PSE36 = 1 << 17,
158 PSN = 1 << 18,
159 CLFLUSH = 1 << 19,
160 DS = 1 << 21,
161 ACPI = 1 << 22,
162 MMX = 1 << 23,
163 FXSR = 1 << 24,
164 SSE = 1 << 25,
165 SSE2 = 1 << 26,
166 SS = 1 << 27,
167 HTT = 1 << 28,
168 TM = 1 << 29,
169 IA64 = 1 << 30,
170 PBE = 1 << 31
171 };
172
180 typedef struct PACKED StackFrame {
181
183 uintptr_t rip;
184
185 } stack_frame_t;
186
194 typedef struct PACKED CoreBootInfo {
195
196 uint64_t stack;
197 uint64_t p4_table;
198 uint8_t id;
201
202 } core_boot_info_t;
203
205 constexpr size_t BOOT_STACK_SIZE = 16384;
206
207 class CPU;
208
213 class Core {
214
215 friend class CPU;
216
217 protected:
219
220 bool m_enabled = false;
221 bool m_can_enable = false;
222 bool m_bsp = false;
223
224 uint8_t m_apic_id;
225 uint64_t m_stack = 0;
226
227 void init_tss();
228 void init_sse();
229
230 public:
232 ~Core();
233
234 bool xsave_enabled = false;
235 bool avx_enabled = false;
236
237 void wake_up(CPU* cpu);
238 void init();
239
240 uint8_t id;
241 tss_t tss = { };
242 bool active = false;
243
247 };
248
253 class CPU {
254
255 public:
256
257 CPU(GlobalDescriptorTable* gdt, Multiboot* multiboot);
258 ~CPU();
259
262
263 static inline Core* panic_core = nullptr;
265
266 static cpu_status_t* prepare_for_panic(cpu_status_t* status = nullptr, const string& msg = "");
267 static void PANIC(const char* message, cpu_status_t* status = nullptr);
268 [[noreturn]] static void halt();
269
271 void find_cores() const;
272 void init_cores();
273 static Core* executing_core();
274
275 static bool check_nx();
276
277 static void get_status(cpu_status_t* status);
278 static void set_status(cpu_status_t* status);
279 static void print_registers(cpu_status_t* status);
280
281 static uint64_t read_msr(uint32_t msr);
282 static void write_msr(uint32_t msr, uint64_t value);
283
284 static void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
285 static bool check_cpu_feature(CPU_FEATURE_ECX feature);
286 static bool check_cpu_feature(CPU_FEATURE_EDX feature);
287
288 static void stack_trace(size_t);
289 };
290}
291
292
293#endif // MAXOS_SYSTEM_CPU_H
Defines an Advanced Configuration And Power Interface (ACPI class for handling ACPI table parsing and...
Defines classes and structures for handling the Advanced Programmable Interrupt Controller (APIC) in ...
struct PACKED MaxOS::hardwarecommunication::MADT_PROCESSOR_APIC madt_processor_apic_t
Alias for MADT_PROCESSOR_APIC struct.
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
Enables a resource to be used by only one instance at a time through locking and unlocking.
Definition spinlock.h:21
Handles ACPI table parsing and retrieval.
Definition acpi.h:99
Handles both the Local APIC (boot core) and IO APIC.
Definition apic.h:228
Handles the local APIC for the current core.
Definition apic.h:24
Schedules processes to run on the core via their threads.
Definition scheduler.h:85
Manages the CPU and its cores.
Definition cpu.h:253
static void print_registers(cpu_status_t *status)
Prints the CPU registers from the provided structure.
Definition cpu.cpp:338
static void PANIC(const char *message, cpu_status_t *status=nullptr)
Puts the CPU into a panic state and halts it. Dumps the stack trace and registers.
Definition cpu.cpp:439
hardwarecommunication::AdvancedConfigurationAndPowerInterface acpi
The ACPI interface for the CPU.
Definition cpu.h:260
static void halt()
Halts the CPU indefinitely.
Definition cpu.cpp:276
static void get_status(cpu_status_t *status)
Gets the current CPU status into the provided structure.
Definition cpu.cpp:287
void init_cores()
Wake up all the cores.
Definition cpu.cpp:551
static bool check_cpu_feature(CPU_FEATURE_ECX feature)
Checks if a CPU feature is supported (ECX Register)
Definition cpu.cpp:575
hardwarecommunication::AdvancedProgrammableInterruptController apic
The APIC interface for the CPU.
Definition cpu.h:261
static void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Executes the CPUID instruction with the specified leaf and returns the results in the provided pointe...
Definition cpu.cpp:403
static cpu_status_t * prepare_for_panic(cpu_status_t *status=nullptr, const string &msg="")
Ensure the CPU must panic and prepare for it if so.
Definition cpu.cpp:495
static void set_status(cpu_status_t *status)
Sets the CPU registers from the provided structure.
Definition cpu.cpp:312
void find_cores() const
Search the madt for cores and store them.
Definition cpu.cpp:527
static uint64_t read_msr(uint32_t msr)
Reads the value of the specified MSR.
Definition cpu.cpp:372
static common::Vector< Core * > cores
The list of CPU cores in the system (populated during initialization, includes the BSP and cores that...
Definition cpu.h:270
static Core * executing_core()
Gets the core that is currently executing.
Definition cpu.cpp:623
static void write_msr(uint32_t msr, uint64_t value)
Writes the specified value to the specified MSR.
Definition cpu.cpp:388
static Core * panic_core
The core that triggered the panic.
Definition cpu.h:263
static void stack_trace(size_t)
Prints a stack trace up to the specified level.
Definition cpu.cpp:414
static common::Spinlock panic_lock
Lock to prevent multiple panics at once.
Definition cpu.h:264
static bool check_nx()
Checks if the No Execute page flag is supported.
Definition cpu.cpp:605
Represents a CPU core in the system.
Definition cpu.h:213
void wake_up(CPU *cpu)
Wakes up the core by sending the appropriate IPIs. (see core_loader.s for startup code)
Definition cpu.cpp:59
void init_tss()
Initialises the task state segment for this core.
Definition cpu.cpp:110
uint64_t m_stack
The stack pointer for this core.
Definition cpu.h:225
bool m_bsp
Whether this core is the bootstrap processor.
Definition cpu.h:222
void init_sse()
Initialises the SSE instructions.
Definition cpu.cpp:167
GlobalDescriptorTable * gdt
The GDT for this core.
Definition cpu.h:245
void init()
Initialises the core by setting up the GDT, IDT, TSS, SSE and APIC.
Definition cpu.cpp:228
uint8_t id
The ID of this core.
Definition cpu.h:240
bool active
Whether this core is active.
Definition cpu.h:242
hardwarecommunication::LocalAPIC * local_apic
The local APIC for this core.
Definition cpu.h:244
processes::Scheduler * scheduler
The scheduler for this core.
Definition cpu.h:246
uint8_t m_apic_id
The ID of the apic for this core.
Definition cpu.h:224
bool xsave_enabled
Whether XSAVE is enabled.
Definition cpu.h:234
bool m_enabled
Whether the core is enabled.
Definition cpu.h:220
bool avx_enabled
Whether AVX is enabled.
Definition cpu.h:235
bool m_can_enable
Whether the core can be enabled.
Definition cpu.h:221
hardwarecommunication::madt_processor_apic_t * m_madt
The MADT entry for this core.
Definition cpu.h:218
tss_t tss
The Task State Segment for this core.
Definition cpu.h:241
Sets up the GDT in the CPU.
Definition gdt.h:53
Parses and provides access to Multiboot 2 information.
Definition multiboot.h:518
constexpr size_t BOOT_STACK_SIZE
The size of the stack allocated for booting a core (should align with the startup assembly code for t...
Definition cpu.h:205
struct PACKED MaxOS::system::CPUStatus cpu_status_t
Alias for CPUStatus struct.
CPU_FEATURE_ECX
CPU features indicated by the ECX register after calling CPUID with EAX = 1.
Definition cpu.h:100
CPU_FEATURE_EDX
CPU features indicated by the EDX register after calling CPUID with EAX = 1.
Definition cpu.h:140
struct PACKED MaxOS::system::TaskStateSegment tss_t
Alias for TaskStateSegment struct.
Defines a Global Descriptor Table (GDT) for setting up memory segments in protected mode.
Defines a PhysicalMemoryManager class for managing physical memory allocation and deallocation of pag...
Structure representing the CPU state during an interrupt.
Definition cpu.h:37
uint64_t error_code
The error code (if applicable)
Definition cpu.h:56
uint64_t r15
Register r15.
Definition cpu.h:39
uint64_t rdi
Register rdi (used for first argument)
Definition cpu.h:47
uint64_t r8
Register r8.
Definition cpu.h:46
uint64_t rip
Instruction pointer.
Definition cpu.h:58
uint64_t r10
Register r10.
Definition cpu.h:44
uint64_t rflags
Flags register.
Definition cpu.h:60
uint64_t rcx
Register rcx (used for fourth argument)
Definition cpu.h:51
uint64_t rdx
Register rdx (used for third argument)
Definition cpu.h:50
uint64_t r9
Register r9.
Definition cpu.h:45
uint64_t ss
Stack segment.
Definition cpu.h:62
uint64_t interrupt_number
The interrupt number.
Definition cpu.h:55
uint64_t rsi
Register rsi (used for second argument)
Definition cpu.h:48
uint64_t r14
Register r14.
Definition cpu.h:40
uint64_t rbp
Register rbp (base pointer)
Definition cpu.h:49
uint64_t r11
Register r11.
Definition cpu.h:43
uint64_t rsp
Stack pointer.
Definition cpu.h:61
uint64_t r13
Register r13.
Definition cpu.h:41
uint64_t rbx
Register rbx (base register)
Definition cpu.h:52
uint64_t rax
Register rax (accumulator)
Definition cpu.h:53
uint64_t cs
Code segment.
Definition cpu.h:59
uint64_t r12
Register r12.
Definition cpu.h:42
Information needed when booting a core.
Definition cpu.h:194
uint64_t stack
The stack pointer for the core.
Definition cpu.h:196
uint64_t p4_table
The physical address of the P4 page table.
Definition cpu.h:197
uint8_t id
The ID of the core.
Definition cpu.h:198
bool activated
Whether the core has been activated.
Definition cpu.h:199
void * gdt_64_base
The base of the 64-bit GDT.
Definition cpu.h:200
A snapshot of the a frame in the call stack.
Definition cpu.h:180
uintptr_t rip
The instruction pointer at this frame.
Definition cpu.h:183
StackFrame * next
Pointer to the next stack frame (up the call stack)
Definition cpu.h:182
Structure representing the Task State Segment (TSS)
Definition cpu.h:73
uint64_t reserved1
Unused, must be zero.
Definition cpu.h:79
uint64_t rsp2
Stack pointer for ring 2.
Definition cpu.h:78
uint64_t reserved2
Unused, must be zero.
Definition cpu.h:80
uint32_t reserved0
Unused, must be zero.
Definition cpu.h:75
uint16_t io_bitmap_offset
Offset to the I/O bitmap.
Definition cpu.h:90
uint64_t reserved3
Unused, must be zero.
Definition cpu.h:88
uint64_t ist5
Interrupt Stack Table entry 5.
Definition cpu.h:85
uint64_t ist6
Interrupt Stack Table entry 6.
Definition cpu.h:86
uint64_t ist1
Interrupt Stack Table entry 1.
Definition cpu.h:81
uint64_t ist4
Interrupt Stack Table entry 4.
Definition cpu.h:84
uint64_t rsp1
Stack pointer for ring 1.
Definition cpu.h:77
uint16_t reserved4
Unused, must be zero.
Definition cpu.h:89
uint64_t ist7
Interrupt Stack Table entry 7.
Definition cpu.h:87
uint64_t rsp0
Stack pointer for ring 0.
Definition cpu.h:76
uint64_t ist3
Interrupt Stack Table entry 3.
Definition cpu.h:83
uint64_t ist2
Interrupt Stack Table entry 2.
Definition cpu.h:82