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::LocalAPIClocal_apic = nullptr
 The local APIC for this core.
 
GlobalDescriptorTablegdt = nullptr
 The GDT for this core.
 
processes::Schedulerscheduler = nullptr
 The scheduler for this core.
 

Protected Member Functions

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

Protected Attributes

hardwarecommunication::madt_processor_apic_tm_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 213 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 37 of file cpu.cpp.

39{
40
41 id = m_madt->processor_id;
42 m_apic_id = m_madt->apic_id;
43
44 m_enabled = (m_madt->flags & 0x1) != 0;
45 m_can_enable = (m_madt->flags & 0x2) != 0;
46
47 Logger::DEBUG() << "Found CPU ID: " << id << " with APIC ID: " << m_apic_id << " (enabled = " << (string)m_enabled << ", can be enabled = " << (string)m_can_enable << ")\n";
48
49}
static Logger DEBUG()
Gets active logger set to DEBUG level.
Definition logger.cpp:193
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
uint8_t m_apic_id
The ID of the apic for this core.
Definition cpu.h:224
bool m_enabled
Whether the core is enabled.
Definition cpu.h:220
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
class MaxOS::String string
Typedef for String.

References MaxOS::Logger::DEBUG(), m_apic_id, m_can_enable, m_enabled, and m_madt.

Member Function Documentation

◆ init()

void Core::init ( )

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

Definition at line 228 of file cpu.cpp.

228 {
229
230 // Load the kernel IDT & GDT
233
234 // Setup this core's clock
235 local_apic = new LocalAPIC;
236 Clock::active_clock()->setup_apic_clock(local_apic);
237
238 // Delegate large initiation
239 init_sse();
240 init_tss();
241
242 active = true;
243}
static Clock * active_clock()
Gets the currently active clock.
Definition clock.cpp:208
static void load_current()
Tell the processor to use the current InterruptManager.
Handles the local APIC for the current core.
Definition apic.h:24
void init_tss()
Initialises the task state segment for this core.
Definition cpu.cpp:110
void init_sse()
Initialises the SSE instructions.
Definition cpu.cpp:167
GlobalDescriptorTable * gdt
The GDT for this core.
Definition cpu.h:245
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
Sets up the GDT in the CPU.
Definition gdt.h:53

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

◆ init_sse()

void Core::init_sse ( )
protected

Initialises the SSE instructions.

Definition at line 167 of file cpu.cpp.

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

References ASSERT, 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 core.

Todo:
Implement IO bitmap when adding userspace drivers

Definition at line 110 of file cpu.cpp.

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

References MaxOS::system::BOOT_STACK_SIZE, MaxOS::Logger::DEBUG(), gdt, 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 59 of file cpu.cpp.

59 {
60
61 // Boot core is already setup
62 if(m_bsp){
63 Logger::DEBUG() << "BSP Already setup\n";
64 return;
65 }
66
67 Logger::DEBUG() << "Starting core: " << id << "\n";
68 m_stack = (uint64_t)MemoryManager::kmalloc(BOOT_STACK_SIZE);
69
70 // Core specific boot info
71 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);
81 Clock::active_clock()->delay(10);
82
83 // Send tow SIPIs
84 for (int i = 0; i < 2; ++i) {
85
86 // Send the start up IPI
87 cpu->apic.local_apic()->send_startup(m_apic_id, 0x8);
88 Clock::active_clock()->delay(200);
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 Logger WARNING()
Gets active logger set to WARNING level.
Definition logger.cpp:205
static void * kmalloc(size_t size)
Allocates a block of memory in the KERNEL space.
bool m_bsp
Whether this core is the bootstrap processor.
Definition cpu.h:222
uint8_t id
The ID of this core.
Definition cpu.h:240
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::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:43

References active, MaxOS::drivers::clock::Clock::active_clock(), MaxOS::system::BOOT_STACK_SIZE, core_boot_info, MaxOS::Logger::DEBUG(), id, MaxOS::memory::MemoryManager::kmalloc(), m_apic_id, m_bsp, m_stack, and MaxOS::Logger::WARNING().

Friends And Related Symbol Documentation

◆ CPU

friend class CPU
friend

Definition at line 215 of file cpu.h.

Member Data Documentation

◆ active

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

Whether this core is active.

Definition at line 242 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 235 of file cpu.h.

Referenced by init_sse().

◆ gdt

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

The GDT for this core.

Definition at line 245 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 240 of file cpu.h.

Referenced by 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 244 of file cpu.h.

Referenced by init().

◆ m_apic_id

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

The ID of the apic for this core.

Definition at line 224 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 222 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 221 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 220 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 218 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 225 of file cpu.h.

Referenced by init_tss(), and wake_up().

◆ scheduler

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

The scheduler for this core.

Definition at line 246 of file cpu.h.

Referenced by MaxOS::processes::GlobalScheduler::core_scheduler().

◆ tss

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

The Task State Segment for this core.

Definition at line 241 of file cpu.h.

241{ };

Referenced by init_tss().

◆ xsave_enabled

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

Whether XSAVE is enabled.

Definition at line 234 of file cpu.h.

Referenced by init_sse().


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