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 <cstddef>
13#include <cstdint>
14#include <cpuid.h>
15
16#include <system/gdt.h>
19#include <memory/physical.h>
20
21// Forward declare
22
23namespace MaxOS::processes {
24 class Scheduler;
25}
26
27
28namespace MaxOS::system {
29
38 typedef struct PACKED CPUStatus {
39
40 uint64_t r15;
41 uint64_t r14;
42 uint64_t r13;
43 uint64_t r12;
44 uint64_t r11;
45 uint64_t r10;
46 uint64_t r9;
47 uint64_t r8;
48 uint64_t rdi;
49 uint64_t rsi;
50 uint64_t rbp;
51 uint64_t rdx;
52 uint64_t rcx;
53 uint64_t rbx;
54 uint64_t rax;
55
57 uint64_t error_code;
58
59 uint64_t rip;
60 uint64_t cs;
61 uint64_t rflags;
62 uint64_t rsp;
63 uint64_t ss;
64
65 } cpu_status_t;
66
67 constexpr size_t IO_BITMAP_SIZE = 8192;
68
76 typedef struct PACKED TaskStateSegment {
77
78 uint32_t reserved0;
79 uint64_t rsp0;
80 uint64_t rsp1;
81 uint64_t rsp2;
82 uint64_t reserved1;
83 uint64_t ist1;
84 uint64_t ist2;
85 uint64_t ist3;
86 uint64_t ist4;
87 uint64_t ist5;
88 uint64_t ist6;
89 uint64_t ist7;
90 uint64_t reserved2;
91 uint16_t reserved3;
93 uint8_t io_bitmap[IO_BITMAP_SIZE + 1];
94
95 } tss_t;
96
103 enum class CPU_FEATURE_ECX : int32_t {
104 SSE3 = 1 << 0,
105 PCLMUL = 1 << 1,
106 DTES64 = 1 << 2,
107 MONITOR = 1 << 3,
108 DS_CPL = 1 << 4,
109 VMX = 1 << 5,
110 SMX = 1 << 6,
111 EST = 1 << 7,
112 TM2 = 1 << 8,
113 SSSE3 = 1 << 9,
114 CID = 1 << 10,
115 SDBG = 1 << 11,
116 FMA = 1 << 12,
117 CX16 = 1 << 13,
118 XTPR = 1 << 14,
119 PDCM = 1 << 15,
120 PCID = 1 << 17,
121 DCA = 1 << 18,
122 SSE4_1 = 1 << 19,
123 SSE4_2 = 1 << 20,
124 X2APIC = 1 << 21,
125 MOVBE = 1 << 22,
126 POPCNT = 1 << 23,
127 TSC = 1 << 24,
128 AES = 1 << 25,
129 XSAVE = 1 << 26,
130 OSXSAVE = 1 << 27,
131 AVX = 1 << 28,
132 F16C = 1 << 29,
133 RDRAND = 1 << 30,
134 HYPERVISOR = 1 << 31,
135 };
136
143 enum class CPU_FEATURE_EDX : int32_t {
144 FPU = 1 << 0,
145 VME = 1 << 1,
146 DE = 1 << 2,
147 PSE = 1 << 3,
148 TSC = 1 << 4,
149 MSR = 1 << 5,
150 PAE = 1 << 6,
151 MCE = 1 << 7,
152 CX8 = 1 << 8,
153 APIC = 1 << 9,
154 SEP = 1 << 11,
155 MTRR = 1 << 12,
156 PGE = 1 << 13,
157 MCA = 1 << 14,
158 CMOV = 1 << 15,
159 PAT = 1 << 16,
160 PSE36 = 1 << 17,
161 PSN = 1 << 18,
162 CLFLUSH = 1 << 19,
163 DS = 1 << 21,
164 ACPI = 1 << 22,
165 MMX = 1 << 23,
166 FXSR = 1 << 24,
167 SSE = 1 << 25,
168 SSE2 = 1 << 26,
169 SS = 1 << 27,
170 HTT = 1 << 28,
171 TM = 1 << 29,
172 IA64 = 1 << 30,
173 PBE = 1 << 31
174 };
175
183 typedef struct PACKED StackFrame {
184
186 uintptr_t rip;
187
188 } stack_frame_t;
189
197 typedef struct PACKED CoreBootInfo {
198
199 uint64_t stack;
200 uint64_t p4_table;
201 uint8_t id;
204
205 } core_boot_info_t;
206
208 constexpr size_t BOOT_STACK_SIZE = 16384;
209
210 class CPU;
211
216 class Core {
217
218 friend class CPU;
219
220 protected:
222
223 bool m_enabled = false;
224 bool m_can_enable = false;
225 bool m_bsp = false;
226
227 uint8_t m_apic_id;
228 uint64_t m_stack = 0;
229
230 void init_tss();
231 void init_sse();
232
233 public:
235 ~Core();
236
237 bool xsave_enabled = false;
238 bool avx_enabled = false;
239
240 void wake_up(CPU* cpu);
241 void init();
242
243 uint8_t id;
244 tss_t tss = { };
245 bool active = false;
246
250 };
251
256 class CPU {
257
258 public:
259
260 CPU(GlobalDescriptorTable* gdt, Multiboot* multiboot);
261 ~CPU();
262
265
266 static inline Core* panic_core = nullptr;
267 static inline common::Spinlock panic_lock;
268
269 static cpu_status_t* prepare_for_panic(cpu_status_t* status = nullptr, const string& msg = "");
270 static void PANIC(const char* message, cpu_status_t* status = nullptr);
271 [[noreturn]] static void halt();
272
273 inline static common::Vector<Core*> cores;
274 void find_cores() const;
275 void init_cores();
276 static Core* executing_core();
277
278 static bool check_nx();
279
280 static void get_status(cpu_status_t* status);
281 static void set_status(cpu_status_t* status);
282 static void print_registers(cpu_status_t* status);
283
284 static uint64_t read_msr(uint32_t msr);
285 static void write_msr(uint32_t msr, uint64_t value);
286
287 static void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
288 static bool check_cpu_feature(CPU_FEATURE_ECX feature);
289 static bool check_cpu_feature(CPU_FEATURE_EDX feature);
290
291 static void stack_trace(size_t, cpu_status_t* status = nullptr);
292
293 static void enable_write_protect();
294 static void disable_write_protect();
295 };
296}
297
298
299#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.
Handles ACPI table parsing and retrieval.
Definition acpi.h:102
Handles both the Local APIC (boot core) and IO APIC.
Definition apic.h:240
Handles the local APIC for the current core.
Definition apic.h:34
Schedules processes to run on the core via their threads.
Definition scheduler.h:90
Manages the CPU and its cores.
Definition cpu.h:256
static void print_registers(cpu_status_t *status)
Prints the CPU registers from the provided structure.
Definition cpu.cpp:337
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:463
hardwarecommunication::AdvancedConfigurationAndPowerInterface acpi
The ACPI interface for the CPU.
Definition cpu.h:263
static void halt()
Halts the CPU indefinitely.
Definition cpu.cpp:275
static void get_status(cpu_status_t *status)
Gets the current CPU status into the provided structure.
Definition cpu.cpp:286
void init_cores()
Wake up all the cores.
Definition cpu.cpp:588
static bool check_cpu_feature(CPU_FEATURE_ECX feature)
Checks if a CPU feature is supported (ECX Register)
Definition cpu.cpp:612
hardwarecommunication::AdvancedProgrammableInterruptController apic
The APIC interface for the CPU.
Definition cpu.h:264
static void stack_trace(size_t, cpu_status_t *status=nullptr)
Prints a stack trace up to the specified level.
Definition cpu.cpp:414
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:402
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:521
static void set_status(cpu_status_t *status)
Sets the CPU registers from the provided structure.
Definition cpu.cpp:311
void find_cores() const
Search the madt for cores and store them.
Definition cpu.cpp:564
static uint64_t read_msr(uint32_t msr)
Reads the value of the specified MSR.
Definition cpu.cpp:371
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:273
static Core * executing_core()
Gets the core that is currently executing.
Definition cpu.cpp:660
static void write_msr(uint32_t msr, uint64_t value)
Writes the specified value to the specified MSR.
Definition cpu.cpp:387
static Core * panic_core
The core that triggered the panic.
Definition cpu.h:266
static common::Spinlock panic_lock
Lock to prevent multiple panics at once.
Definition cpu.h:267
static bool check_nx()
Checks if the No Execute page flag is supported.
Definition cpu.cpp:642
Represents a CPU core in the system.
Definition cpu.h:216
void wake_up(CPU *cpu)
Wakes up the core by sending the appropriate IPIs. (see core_loader.s for startup code)
Definition cpu.cpp:60
void init_tss()
Initialises the task state segment for this cor.
Definition cpu.cpp:108
uint64_t m_stack
The stack pointer for this core.
Definition cpu.h:228
bool m_bsp
Whether this core is the bootstrap processor.
Definition cpu.h:225
void init_sse()
Initialises the SSE instructions.
Definition cpu.cpp:166
GlobalDescriptorTable * gdt
The GDT for this core.
Definition cpu.h:248
void init()
Initialises the core by setting up the GDT, IDT, TSS, SSE and APIC.
Definition cpu.cpp:227
uint8_t id
The ID of this core.
Definition cpu.h:243
bool active
Whether this core is active.
Definition cpu.h:245
hardwarecommunication::LocalAPIC * local_apic
The local APIC for this core.
Definition cpu.h:247
processes::Scheduler * scheduler
The scheduler for this core.
Definition cpu.h:249
uint8_t m_apic_id
The ID of the apic for this core.
Definition cpu.h:227
bool xsave_enabled
Whether XSAVE is enabled.
Definition cpu.h:237
bool m_enabled
Whether the core is enabled.
Definition cpu.h:223
bool avx_enabled
Whether AVX is enabled.
Definition cpu.h:238
bool m_can_enable
Whether the core can be enabled.
Definition cpu.h:224
hardwarecommunication::madt_processor_apic_t * m_madt
The MADT entry for this core.
Definition cpu.h:221
tss_t tss
The Task State Segment for this core.
Definition cpu.h:244
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 IO_BITMAP_SIZE
The size of the IO bitmap to track 65536 ports.
Definition cpu.h:67
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:208
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:103
CPU_FEATURE_EDX
CPU features indicated by the EDX register after calling CPUID with EAX = 1.
Definition cpu.h:143
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:38
uint64_t error_code
The error code (if applicable)
Definition cpu.h:57
uint64_t r15
Register r15.
Definition cpu.h:40
uint64_t rdi
Register rdi (used for first argument)
Definition cpu.h:48
uint64_t r8
Register r8.
Definition cpu.h:47
uint64_t rip
Instruction pointer.
Definition cpu.h:59
uint64_t r10
Register r10.
Definition cpu.h:45
uint64_t rflags
Flags register.
Definition cpu.h:61
uint64_t rcx
Register rcx (used for fourth argument)
Definition cpu.h:52
uint64_t rdx
Register rdx (used for third argument)
Definition cpu.h:51
uint64_t r9
Register r9.
Definition cpu.h:46
uint64_t ss
Stack segment.
Definition cpu.h:63
uint64_t interrupt_number
The interrupt number.
Definition cpu.h:56
uint64_t rsi
Register rsi (used for second argument)
Definition cpu.h:49
uint64_t r14
Register r14.
Definition cpu.h:41
uint64_t rbp
Register rbp (base pointer)
Definition cpu.h:50
uint64_t r11
Register r11.
Definition cpu.h:44
uint64_t rsp
Stack pointer.
Definition cpu.h:62
uint64_t r13
Register r13.
Definition cpu.h:42
uint64_t rbx
Register rbx (base register)
Definition cpu.h:53
uint64_t rax
Register rax (accumulator)
Definition cpu.h:54
uint64_t cs
Code segment.
Definition cpu.h:60
uint64_t r12
Register r12.
Definition cpu.h:43
Information needed when booting a core.
Definition cpu.h:197
uint64_t stack
The stack pointer for the core.
Definition cpu.h:199
uint64_t p4_table
The physical address of the P4 page table.
Definition cpu.h:200
uint8_t id
The ID of the core.
Definition cpu.h:201
bool activated
Whether the core has been activated.
Definition cpu.h:202
void * gdt_64_base
The base of the 64-bit GDT.
Definition cpu.h:203
A snapshot of the a frame in the call stack.
Definition cpu.h:183
uintptr_t rip
The instruction pointer at this frame.
Definition cpu.h:186
StackFrame * next
Pointer to the next stack frame (up the call stack)
Definition cpu.h:185
Structure representing the Task State Segment (TSS)
Definition cpu.h:76
uint64_t reserved1
Unused, must be zero.
Definition cpu.h:82
uint64_t rsp2
Stack pointer for ring 2.
Definition cpu.h:81
uint64_t reserved2
Unused, must be zero.
Definition cpu.h:90
uint32_t reserved0
Unused, must be zero.
Definition cpu.h:78
uint16_t reserved3
Unused, must be zero.
Definition cpu.h:91
uint16_t io_bitmap_offset
Offset to the I/O bitmap.
Definition cpu.h:92
uint64_t ist5
Interrupt Stack Table entry 5.
Definition cpu.h:87
uint64_t ist6
Interrupt Stack Table entry 6.
Definition cpu.h:88
uint64_t ist1
Interrupt Stack Table entry 1.
Definition cpu.h:83
uint64_t ist4
Interrupt Stack Table entry 4.
Definition cpu.h:86
uint64_t rsp1
Stack pointer for ring 1.
Definition cpu.h:80
uint64_t ist7
Interrupt Stack Table entry 7.
Definition cpu.h:89
uint64_t rsp0
Stack pointer for ring 0.
Definition cpu.h:79
uint64_t ist3
Interrupt Stack Table entry 3.
Definition cpu.h:85
uint64_t ist2
Interrupt Stack Table entry 2.
Definition cpu.h:84