Max OS 0.3
Loading...
Searching...
No Matches
MaxOS::system::Core Class Reference

Represents a CPU core in the system. More...

#include <cpu.h>

Public Member Functions

 Core (hardwarecommunication::madt_processor_apic_t *madt_item)
 Constructs a new Core object from the MADT entry.
 
void wake_up (CPU *cpu)
 Wakes up the core by sending the appropriate IPIs. (see core_loader.s for startup code)
 
void init ()
 Initialises the core by setting up the GDT, IDT, TSS, SSE and APIC.
 

Public Attributes

bool xsave_enabled = false
 Whether XSAVE is enabled.
 
bool avx_enabled = false
 Whether AVX is enabled.
 
uint8_t id
 The ID of this core.
 
tss_t tss = { }
 The Task State Segment for this core.
 
bool active = false
 Whether this core is active.
 
hardwarecommunication::LocalAPIC * local_apic = nullptr
 The local APIC for this core.
 
GlobalDescriptorTable * gdt = nullptr
 The GDT for this core.
 
processes::Scheduler * scheduler = nullptr
 The scheduler for this core.
 

Protected Member Functions

void init_tss ()
 Initialises the task state segment for this cor.
 
void init_sse ()
 Initialises the SSE instructions.
 

Protected Attributes

hardwarecommunication::madt_processor_apic_t * m_madt
 The MADT entry for this core.
 
bool m_enabled = false
 Whether the core is enabled.
 
bool m_can_enable = false
 Whether the core can be enabled.
 
bool m_bsp = false
 Whether this core is the bootstrap processor.
 
uint8_t m_apic_id
 The ID of the apic for this core.
 
uint64_t m_stack = 0
 The stack pointer for this core.
 

Friends

class CPU
 

Detailed Description

Represents a CPU core in the system.

Definition at line 216 of file cpu.h.

Constructor & Destructor Documentation

◆ Core()

Core::Core ( hardwarecommunication::madt_processor_apic_t *  madt_item)
explicit

Constructs a new Core object from the MADT entry.

Parameters
madt_itemThe MADT entry for this core

Definition at line 36 of file cpu.cpp.

37: m_madt(madt_item)
38{
39
40 id = m_madt->processor_id;
41 m_apic_id = m_madt->apic_id;
42
43 m_enabled = (m_madt->flags & 0x1) != 0;
44 m_can_enable = (m_madt->flags & 0x2) != 0;
45
46 m_stack = (uint64_t)MemoryManager::kmalloc(BOOT_STACK_SIZE);
47
48 Logger::DEBUG() << "Found CPU ID: " << id << " with APIC ID: " << m_apic_id << " (enabled = " << (string)m_enabled << ", can be enabled = " << (string)m_can_enable << ")\n";
49
50}
static LogRecord DEBUG()
Gets the active logger for debug logs.
Definition logger.cpp:204
static void * kmalloc(size_t size)
Allocates a block of memory in the KERNEL space.
uint64_t m_stack
The stack pointer for this core.
Definition cpu.h:228
uint8_t m_apic_id
The ID of the apic for this core.
Definition cpu.h:227
bool m_enabled
Whether the core is enabled.
Definition cpu.h:223
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

References MaxOS::system::BOOT_STACK_SIZE, MaxOS::Logger::DEBUG(), MaxOS::memory::MemoryManager::kmalloc(), m_apic_id, m_can_enable, m_enabled, m_madt, and m_stack.

Member Function Documentation

◆ init()

void Core::init ( )

Initialises the core by setting up the GDT, IDT, TSS, SSE and APIC.

Definition at line 227 of file cpu.cpp.

227 {
228
229 // Load the kernel IDT & GDT
232
233 // Setup this core's clock
234 local_apic = new LocalAPIC;
236
237 // Delegate large initiation
238 init_sse();
239 init_tss();
240
241 active = true;
242}
void setup_apic_clock(LocalAPIC *local_apic) const
Sets up the APIC clock to fire interrupts at the desired rate.
Definition clock.cpp:137
static Clock * active_clock()
Gets the currently active clock.
Definition clock.cpp:182
static void load_current()
Tell the processor to use the current InterruptManager.
Handles the local APIC for the current core.
Definition apic.h:34
void init_tss()
Initialises the task state segment for this cor.
Definition cpu.cpp:108
void init_sse()
Initialises the SSE instructions.
Definition cpu.cpp:166
GlobalDescriptorTable * gdt
The GDT for this core.
Definition cpu.h:248
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
Sets up the GDT in the CPU.
Definition gdt.h:53

References active, MaxOS::hardwarecommunication::Clock::active_clock(), gdt, init_sse(), init_tss(), MaxOS::hardwarecommunication::InterruptManager::load_current(), local_apic, and MaxOS::hardwarecommunication::Clock::setup_apic_clock().

◆ init_sse()

void Core::init_sse ( )
protected

Initialises the SSE instructions.

Definition at line 166 of file cpu.cpp.

166 {
167
168 // Get the CR0 register
169 uint64_t cr0;
170 asm volatile("mov %%cr0, %0" : "=r" (cr0));
171
172 // Get the CR4 register
173 uint64_t cr4;
174 asm volatile("mov %%cr4, %0" : "=r" (cr4));
175
176 // Check if FPU is supported
177 ASSERT(CPU::check_cpu_feature(CPU_FEATURE_EDX::FPU), "FPU not supported - needed for SSE");
178
179 // Clear the emulation flag, task switch flags and enable the monitor coprocessor, native exception bits
180 cr0 |= (1 << 1);
181 cr0 &= ~(1 << 2);
182 cr0 &= ~(1 << 3);
183 cr0 |= (1 << 5);
184 asm volatile("mov %0, %%cr0" : : "r" (cr0));
185
186 // Enable the FPU
187 asm volatile("fninit");
188
189 // Check if SSE is supported
190 ASSERT(CPU::check_cpu_feature(CPU_FEATURE_EDX::SSE), "SSE not supported");
191
192 // Enable FSAVE, FSTORE and SSE instructions
193 cr4 |= (1 << 9);
194 cr4 |= (1 << 10);
195 asm volatile("mov %0, %%cr4" : : "r" (cr4));
196
197 // Check if XSAVE is supported
198 xsave_enabled = CPU::check_cpu_feature(CPU_FEATURE_ECX::XSAVE) && CPU::check_cpu_feature(CPU_FEATURE_ECX::OSXSAVE);
199 Logger::DEBUG() << "XSAVE: " << (xsave_enabled ? "Supported" : "Not Supported") << "\n";
200 if (!xsave_enabled) return;
201
202 // Enable the XSAVE and XRESTORE instructions
203 cr4 |= (1 << 18);
204 asm volatile("mov %0, %%cr4" : : "r" (cr4));
205
206 // Set the SSE and x87 bits
207 uint64_t xcr0;
208 asm volatile("xgetbv" : "=a" (xcr0) : "c" (0));
209 xcr0 |= 0x7;
210 asm volatile("xsetbv" : : "c" (0), "a" (xcr0));
211
212 // Check if AVX is supported
213 avx_enabled = CPU::check_cpu_feature(CPU_FEATURE_ECX::AVX);
214 Logger::DEBUG() << "AVX: " << (avx_enabled ? "Supported" : "Not Supported") << "\n";
215 if (!avx_enabled) return;
216
217 // Enable the AVX instructions
218 cr4 |= (1 << 14);
219 asm volatile("mov %0, %%cr4" : : "r" (cr4));
220
221 Logger::DEBUG() << "SSE Enabled\n";
222}
static bool check_cpu_feature(CPU_FEATURE_ECX feature)
Checks if a CPU feature is supported (ECX Register)
Definition cpu.cpp:612
bool xsave_enabled
Whether XSAVE is enabled.
Definition cpu.h:237
bool avx_enabled
Whether AVX is enabled.
Definition cpu.h:238

References avx_enabled, MaxOS::system::CPU::check_cpu_feature(), MaxOS::Logger::DEBUG(), and xsave_enabled.

Referenced by init().

◆ init_tss()

void Core::init_tss ( )
protected

Initialises the task state segment for this cor.

Definition at line 108 of file cpu.cpp.

108 {
109
110 // The reserved have to be 0
111 tss.reserved0 = 0;
112 tss.reserved1 = 0;
113 tss.reserved2 = 0;
114 tss.reserved3 = 0;
115
116 // Kernel stack (scheduler will set the threads stack)
117 tss.rsp0 = (uint64_t)m_stack + BOOT_STACK_SIZE;
118 tss.rsp1 = 0;
119 tss.rsp2 = 0;
120
121 // Interrupt stacks can all be 0 (@todo implment)
122 tss.ist1 = 0;
123 tss.ist2 = 0;
124 tss.ist3 = 0;
125 tss.ist4 = 0;
126 tss.ist5 = 0;
127 tss.ist6 = 0;
128 tss.ist7 = 0;
129
130 // All ports denied by default
131 memset(&tss.io_bitmap, 0xFF, sizeof(tss.io_bitmap));
132 tss.io_bitmap[IO_BITMAP_SIZE] = 0xFF;
133 tss.io_bitmap_offset = offsetof(tss_t, io_bitmap);
134
135 // Split the base into 4 parts (16 bits, 8 bits, 8 bits, 32 bits)
136 auto base = (uint64_t) &tss;
137 uint16_t base_1 = base & 0xFFFF;
138 uint8_t base_2 = (base >> 16) & 0xFF;
139 uint8_t base_3 = (base >> 24) & 0xFF;
140 uint32_t base_4 = (base >> 32) & 0xFFFFFFFF;
141
142 auto limit_low = (uint16_t)(sizeof(tss) - 1);
143
144 // Flags: 1 - Type = 0x9, Descriptor Privilege Level = 0, Present = 1, 2 - Available = 0, Granularity = 0
145 uint8_t flags_1 = 0x89;
146 uint8_t flags_2 = 0;
147
148 // Create the TSS descriptors
149 uint64_t tss_descriptor_low = (uint64_t) base_3 << 56 | (uint64_t) flags_2 << 48 | (uint64_t) flags_1 << 40 | (uint64_t) base_2 << 32 | (uint64_t) base_1 << 16 | (uint64_t) limit_low;
150 uint64_t tss_descriptor_high = base_4;
151
152 // Store in the GDT
153 gdt -> table[5] = tss_descriptor_low;
154 gdt -> table[6] = tss_descriptor_high;
155 gdt -> load();
156
157 // Load the TSS
158 Logger::DEBUG() << "Loading TSS: 0x0" << tss_descriptor_low << " 0x0" << tss_descriptor_high << " at 0x" << (uint64_t) &tss << "\n";
159 asm volatile("ltr %%ax" : : "a" (0x28));
160
161}
tss_t tss
The Task State Segment for this core.
Definition cpu.h:244
constexpr size_t IO_BITMAP_SIZE
The size of the IO bitmap to track 65536 ports.
Definition cpu.h:67
struct PACKED MaxOS::system::TaskStateSegment tss_t
Alias for TaskStateSegment struct.

References MaxOS::system::BOOT_STACK_SIZE, MaxOS::Logger::DEBUG(), gdt, MaxOS::system::IO_BITMAP_SIZE, m_stack, and tss.

Referenced by init().

◆ wake_up()

void Core::wake_up ( CPU *  cpu)

Wakes up the core by sending the appropriate IPIs. (see core_loader.s for startup code)

Parameters
cpu
Todo:
Should handle core fails and not delay once we are in c++

Definition at line 60 of file cpu.cpp.

60 {
61
62 // Boot core is already setup
63 if(m_bsp){
64 Logger::DEBUG() << "BSP Already setup\n";
65 return;
66 }
67
68 Logger::DEBUG() << "Starting core: " << id << "\n";
69
70 // Core specific boot info
71 volatile auto info = (core_boot_info_t*)(core_boot_info);
72 info->activated = false;
73 info->id = id;
74 info->stack = m_stack + BOOT_STACK_SIZE;
75
76 // Send init IPI
77 cpu->apic.local_apic()->send_init(m_apic_id, true);
78
79 // Send de-assert IPI
80 cpu->apic.local_apic()->send_init(m_apic_id, false);
82
83 // Send tow SIPIs
84 for (int i = 0; i < 2; ++i) {
85
86 // Send the start up IPI
89
90 // Check if core started
91 if(info->activated){
92
93 // Wait for full init
94 while(!active)
95 asm("nop");
96
97 Logger::DEBUG() << "Core " << id << " started successfully \n";
98 return;
99 }
100 }
101
102 Logger::WARNING() << "Failed to start core: " << id << "\n";
103}
static LogRecord WARNING()
Gets the active logger for warnings.
Definition logger.cpp:213
void delay(uint32_t milliseconds) const
Delays the program for a specified number of milliseconds (rounded up to the nearest degree of accura...
Definition clock.cpp:102
void send_startup(uint8_t apic_id, uint8_t vector) const
Send the start up IPI to another apic.
Definition apic.cpp:190
void send_init(uint8_t apic_id, bool assert) const
send the init IPI to another apic
Definition apic.cpp:165
hardwarecommunication::AdvancedProgrammableInterruptController apic
The APIC interface for the CPU.
Definition cpu.h:264
bool m_bsp
Whether this core is the bootstrap processor.
Definition cpu.h:225
uint8_t id
The ID of this core.
Definition cpu.h:243
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::CoreBootInfo core_boot_info_t
Alias for CoreBootInfo struct.
uint8_t core_boot_info[]
The boot info structure for the core being started.
Definition kernel.cpp:31

References active, MaxOS::hardwarecommunication::Clock::active_clock(), MaxOS::system::CPU::apic, MaxOS::system::BOOT_STACK_SIZE, core_boot_info, MaxOS::Logger::DEBUG(), MaxOS::hardwarecommunication::Clock::delay(), id, MaxOS::hardwarecommunication::AdvancedProgrammableInterruptController::local_apic(), m_apic_id, m_bsp, m_stack, MaxOS::hardwarecommunication::LocalAPIC::send_init(), MaxOS::hardwarecommunication::LocalAPIC::send_startup(), and MaxOS::Logger::WARNING().

Friends And Related Symbol Documentation

◆ CPU

friend class CPU
friend

Definition at line 218 of file cpu.h.

Member Data Documentation

◆ active

bool MaxOS::system::Core::active = false

Whether this core is active.

Definition at line 245 of file cpu.h.

Referenced by init(), and wake_up().

◆ avx_enabled

bool MaxOS::system::Core::avx_enabled = false

Whether AVX is enabled.

Definition at line 238 of file cpu.h.

Referenced by init_sse().

◆ gdt

GlobalDescriptorTable* MaxOS::system::Core::gdt = nullptr

The GDT for this core.

Definition at line 248 of file cpu.h.

Referenced by init(), and init_tss().

◆ id

uint8_t MaxOS::system::Core::id

The ID of this core.

Definition at line 243 of file cpu.h.

Referenced by MaxOS::system::CPU::PANIC(), MaxOS::processes::GlobalScheduler::print_running_header(), and wake_up().

◆ local_apic

hardwarecommunication::LocalAPIC* MaxOS::system::Core::local_apic = nullptr

The local APIC for this core.

Definition at line 247 of file cpu.h.

Referenced by MaxOS::hardwarecommunication::InterruptManager::handle_interrupt_request(), init(), and MaxOS::system::CPU::prepare_for_panic().

◆ m_apic_id

uint8_t MaxOS::system::Core::m_apic_id
protected

The ID of the apic for this core.

Definition at line 227 of file cpu.h.

Referenced by Core(), and wake_up().

◆ m_bsp

bool MaxOS::system::Core::m_bsp = false
protected

Whether this core is the bootstrap processor.

Definition at line 225 of file cpu.h.

Referenced by wake_up().

◆ m_can_enable

bool MaxOS::system::Core::m_can_enable = false
protected

Whether the core can be enabled.

Definition at line 224 of file cpu.h.

Referenced by Core().

◆ m_enabled

bool MaxOS::system::Core::m_enabled = false
protected

Whether the core is enabled.

Definition at line 223 of file cpu.h.

Referenced by Core().

◆ m_madt

hardwarecommunication::madt_processor_apic_t* MaxOS::system::Core::m_madt
protected

The MADT entry for this core.

Definition at line 221 of file cpu.h.

Referenced by Core().

◆ m_stack

uint64_t MaxOS::system::Core::m_stack = 0
protected

The stack pointer for this core.

Definition at line 228 of file cpu.h.

Referenced by Core(), init_tss(), and wake_up().

◆ scheduler

processes::Scheduler* MaxOS::system::Core::scheduler = nullptr

◆ tss

tss_t MaxOS::system::Core::tss = { }

The Task State Segment for this core.

Definition at line 244 of file cpu.h.

244{ };

Referenced by init_tss().

◆ xsave_enabled

bool MaxOS::system::Core::xsave_enabled = false

Whether XSAVE is enabled.

Definition at line 237 of file cpu.h.

Referenced by init_sse().


The documentation for this class was generated from the following files: