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

Manages the CPU and its cores. More...

#include <cpu.h>

Public Member Functions

 CPU (GlobalDescriptorTable *gdt, Multiboot *multiboot)
 Constructor for the CPU class.
 
void find_cores () const
 Search the madt for cores and store them.
 
void init_cores ()
 Wake up all the cores.
 

Static Public Member Functions

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.
 
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.
 
static void halt ()
 Halts the CPU indefinitely.
 
static Core * executing_core ()
 Gets the core that is currently executing.
 
static bool check_nx ()
 Checks if the No Execute page flag is supported.
 
static void get_status (cpu_status_t *status)
 Gets the current CPU status into the provided structure.
 
static void set_status (cpu_status_t *status)
 Sets the CPU registers from the provided structure.
 
static void print_registers (cpu_status_t *status)
 Prints the CPU registers from the provided structure.
 
static uint64_t read_msr (uint32_t msr)
 Reads the value of the specified MSR.
 
static void write_msr (uint32_t msr, uint64_t value)
 Writes the specified value to the specified MSR.
 
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 pointers.
 
static bool check_cpu_feature (CPU_FEATURE_ECX feature)
 Checks if a CPU feature is supported (ECX Register)
 
static bool check_cpu_feature (CPU_FEATURE_EDX feature)
 Checks if a CPU feature is supported (EDX Register)
 
static void stack_trace (size_t, cpu_status_t *status=nullptr)
 Prints a stack trace up to the specified level.
 
static void enable_write_protect ()
 
static void disable_write_protect ()
 

Public Attributes

hardwarecommunication::AdvancedConfigurationAndPowerInterface acpi
 The ACPI interface for the CPU.
 
hardwarecommunication::AdvancedProgrammableInterruptController apic
 The APIC interface for the CPU.
 

Static Public Attributes

static Core * panic_core = nullptr
 The core that triggered the panic.
 
static common::Spinlock panic_lock
 Lock to prevent multiple panics at once.
 
static common::Vector< Core * > cores
 The list of CPU cores in the system (populated during initialization, includes the BSP and cores that failed to start)
 

Detailed Description

Manages the CPU and its cores.

Definition at line 256 of file cpu.h.

Constructor & Destructor Documentation

◆ CPU()

CPU::CPU ( GlobalDescriptorTable *  gdt,
Multiboot *  multiboot 
)

Constructor for the CPU class.

Parameters
gdtThe global descriptor table
multibootThe multiboot information struct

Definition at line 251 of file cpu.cpp.

252: acpi(multiboot),
253 apic(&acpi)
254{
255
256 Logger::INFO() << "Setting up CPU \n";
257 find_cores();
258
259 // Manually set up the BSP
260 auto bsp = cores[0];
261 bsp -> m_bsp = true;
262 bsp -> active = true;
263 bsp -> gdt = gdt;
264 bsp -> local_apic = apic.local_apic();
265 bsp -> init_tss();
266 bsp -> init_sse();
267
268}
static LogRecord INFO()
Gets the active logger for info logs.
Definition logger.cpp:195
hardwarecommunication::AdvancedConfigurationAndPowerInterface acpi
The ACPI interface for the CPU.
Definition cpu.h:263
hardwarecommunication::AdvancedProgrammableInterruptController apic
The APIC interface for the CPU.
Definition cpu.h:264
void find_cores() const
Search the madt for cores and store them.
Definition cpu.cpp:564
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

References apic, cores, find_cores(), MaxOS::Logger::INFO(), and MaxOS::hardwarecommunication::AdvancedProgrammableInterruptController::local_apic().

Member Function Documentation

◆ check_cpu_feature() [1/2]

bool CPU::check_cpu_feature ( CPU_FEATURE_ECX  feature)
static

Checks if a CPU feature is supported (ECX Register)

Parameters
featureThe feature to check
Returns
If the feature is supported

Definition at line 612 of file cpu.cpp.

612 {
613
614 // Get the CPUID
615 uint32_t eax, ebx, ecx, edx;
616 cpuid(0x1, &eax, &ebx, &ecx, &edx);
617
618 // Check the feature
619 return ecx & (uint32_t) feature;
620}
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

References cpuid().

Referenced by MaxOS::system::Core::init_sse().

◆ check_cpu_feature() [2/2]

bool CPU::check_cpu_feature ( CPU_FEATURE_EDX  feature)
static

Checks if a CPU feature is supported (EDX Register)

Parameters
featureThe feature to check
Returns
True if the feature is supported

Definition at line 628 of file cpu.cpp.

628 {
629
630 // Get the CPUID
631 uint32_t eax, ebx, ecx, edx;
632 cpuid(0x1, &eax, &ebx, &ecx, &edx);
633
634 // Check the feature
635 return edx & (uint32_t) feature;
636}

References cpuid().

◆ check_nx()

bool CPU::check_nx ( )
static

Checks if the No Execute page flag is supported.

Returns
True if the NX flag is supported

Definition at line 642 of file cpu.cpp.

642 {
643
644 // Get the EFER MSR
645 uint64_t efer = read_msr(0xC0000080);
646
647 // Check if the NX flag is supported (bit 11)
648 bool supported = efer & (1 << 11);
649 Logger::DEBUG() << "NX: " << (supported ? "Supported" : "Not Supported") << "\n";
650
651 // Return if the NX flag is supported
652 return supported;
653}
static LogRecord DEBUG()
Gets the active logger for debug logs.
Definition logger.cpp:204
static uint64_t read_msr(uint32_t msr)
Reads the value of the specified MSR.
Definition cpu.cpp:371

References MaxOS::Logger::DEBUG(), and read_msr().

Referenced by MaxOS::memory::PhysicalMemoryManager::PhysicalMemoryManager().

◆ cpuid()

void CPU::cpuid ( uint32_t  leaf,
uint32_t *  eax,
uint32_t *  ebx,
uint32_t *  ecx,
uint32_t *  edx 
)
static

Executes the CPUID instruction with the specified leaf and returns the results in the provided pointers.

Parameters
leafThe CPUID leaf to query
eaxThe pointer to store the EAX result
ebxThe pointer to store the EBX result
ecxThe pointer to store the ECX result
edxThe pointer to store the EDX result

Definition at line 402 of file cpu.cpp.

402 {
403
404 // Call the cpuid instruction
405 __get_cpuid(leaf, eax, ebx, ecx, edx);
406}

Referenced by check_cpu_feature(), check_cpu_feature(), executing_core(), and MaxOS::hardwarecommunication::LocalAPIC::LocalAPIC().

◆ disable_write_protect()

void CPU::disable_write_protect ( )
static

Definition at line 445 of file cpu.cpp.

445 {
446
447 // Read the current state
448 uint64_t cr0;
449 asm volatile("mov %%cr0, %0" : "=r"(cr0));
450
451 // Update to have WP bit disabled
452 cr0 &= ~(1ULL << 16);
453 asm volatile("mov %0, %%cr0" : : "r"(cr0));
454
455}

◆ enable_write_protect()

void CPU::enable_write_protect ( )
static

Definition at line 433 of file cpu.cpp.

433 {
434
435 // Read the current state
436 uint64_t cr0;
437 asm volatile("mov %%cr0, %0" : "=r"(cr0));
438
439 // Update to have WP bit enabled
440 cr0 |= (1ULL << 16);
441 asm volatile("mov %0, %%cr0" : : "r"(cr0));
442
443}

◆ executing_core()

Core * CPU::executing_core ( )
static

Gets the core that is currently executing.

Returns
The currently executing core

Definition at line 660 of file cpu.cpp.

660 {
661
662 // No cores?
663 if(cores.empty())
664 return nullptr;
665
666 // Get the id of this core
667 uint32_t eax, ebx, ecx, edx;
668 CPU::cpuid(1, &eax, &ebx, &ecx, &edx);
669 uint32_t core_id = (ebx >> 24) & 0xFF;
670
671 return cores[core_id];
672}

References cores, and cpuid().

Referenced by core_main(), MaxOS::processes::GlobalScheduler::core_scheduler(), MaxOS::hardwarecommunication::GeneralProtectionHandler::get_message(), MaxOS::hardwarecommunication::InterruptManager::handle_interrupt_request(), MaxOS::processes::Thread::load_port_bitmap(), prepare_for_panic(), MaxOS::processes::GlobalScheduler::print_running_header(), MaxOS::processes::Thread::restore_sse_state(), MaxOS::processes::Thread::save_sse_state(), and MaxOS::processes::Thread::Thread().

◆ find_cores()

void CPU::find_cores ( ) const

Search the madt for cores and store them.

Todo:
Support for x2apic

Definition at line 564 of file cpu.cpp.

564 {
565
566 // Now that memory is set up the vector can be used
567 cores.reserve(1);
568
569 // Search and setup each core
570 int index = 0;
571 while (true){
572
573 // Try to find a processor
574 MADTEntry* processor_madt = apic.io_apic()->get_madt_item(MADT_TYPE::PROCESSOR_APIC, index);
575 if(!processor_madt)
576 break;
577
578 // Create a cpu
579 auto* processor_apic = (madt_processor_apic_t*) ((uint64_t) processor_madt + sizeof(MADTEntry));
580 cores.push_back(new Core(processor_apic));
581 index++;
582 }
583}
struct PACKED MaxOS::hardwarecommunication::MADT_PROCESSOR_APIC madt_processor_apic_t
Alias for MADT_PROCESSOR_APIC struct.
MADTEntry * get_madt_item(MADT_TYPE type, uint8_t index)
Get an item in the MADT.
Definition apic.cpp:308
Represents a CPU core in the system.
Definition cpu.h:216
An item in the MADT table.
Definition apic.h:80

References apic, cores, MaxOS::hardwarecommunication::IOAPIC::get_madt_item(), and MaxOS::hardwarecommunication::AdvancedProgrammableInterruptController::io_apic().

Referenced by CPU().

◆ get_status()

void CPU::get_status ( cpu_status_t *  status)
static

Gets the current CPU status into the provided structure.

Parameters
statusThe structure to fill with the CPU status

Definition at line 286 of file cpu.cpp.

286 {
287
288 // Get the registers
289 asm volatile("mov %%r15, %0" : "=r" (status->r15));
290 asm volatile("mov %%r14, %0" : "=r" (status->r14));
291 asm volatile("mov %%r13, %0" : "=r" (status->r13));
292 asm volatile("mov %%r12, %0" : "=r" (status->r12));
293 asm volatile("mov %%r11, %0" : "=r" (status->r11));
294 asm volatile("mov %%r10, %0" : "=r" (status->r10));
295 asm volatile("mov %%r9, %0" : "=r" (status->r9));
296 asm volatile("mov %%r8, %0" : "=r" (status->r8));
297 asm volatile("mov %%rdi, %0" : "=r" (status->rdi));
298 asm volatile("mov %%rsi, %0" : "=r" (status->rsi));
299 asm volatile("mov %%rbp, %0" : "=r" (status->rbp));
300 asm volatile("mov %%rdx, %0" : "=r" (status->rdx));
301 asm volatile("mov %%rcx, %0" : "=r" (status->rcx));
302 asm volatile("mov %%rbx, %0" : "=r" (status->rbx));
303 asm volatile("mov %%rax, %0" : "=r" (status->rax));
304}

Referenced by PANIC().

◆ halt()

void CPU::halt ( )
static

Halts the CPU indefinitely.

Definition at line 275 of file cpu.cpp.

275 {
276
277 while (true)
278 asm volatile("hlt");
279}

Referenced by core_main(), MaxOS::hardwarecommunication::CPUStopHandler::handle_interrupt(), and PANIC().

◆ init_cores()

void CPU::init_cores ( )

Wake up all the cores.

Definition at line 588 of file cpu.cpp.

588 {
589
590 Logger::INFO() << "Waking up cores: \n";
591
592 // Make sure core_start is accessible
593 ASSERT((void*)&core_start == (void*)0x8000, "Core start not at expected address");
595
596 // Set up the boot info
597 auto info = (core_boot_info_t*)(core_boot_info);
598 info->p4_table = (uint64_t)PhysicalMemoryManager::to_lower_region((uintptr_t)p4_table);
599
600 // Start each core
601 for(const auto& core : cores)
602 core->wake_up(this);
603}
static void * to_lower_region(uintptr_t virtual_address)
Converts a virtual address to a lower region address if it is in the higher region using the higher h...
Definition physical.cpp:898
static PhysicalMemoryManager * s_current_manager
The current physical memory manager in use.
Definition physical.h:183
void identity_map(physical_address_t *physical_address, size_t flags)
Maps a physical address to its virtual address counter-part.
Definition physical.cpp:579
void core_start()
The entry point for the core startup assembly code.
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
volatile PAGE_ALIGNED unsigned char p4_table[]
The PML4 table setup in loader.s.
void physical_address_t
A type representing a physical address (used for readability)
Definition physical.h:31

References core_boot_info, core_start(), cores, MaxOS::memory::PhysicalMemoryManager::identity_map(), MaxOS::Logger::INFO(), p4_table, MaxOS::memory::PRESENT, MaxOS::memory::PhysicalMemoryManager::s_current_manager, MaxOS::memory::PhysicalMemoryManager::to_lower_region(), and MaxOS::memory::WRITE.

Referenced by kernel_main().

◆ PANIC()

void CPU::PANIC ( const char *  message,
cpu_status_t *  status = nullptr 
)
static

Puts the CPU into a panic state and halts it. Dumps the stack trace and registers.

Parameters
messageThe panic message
statusThe CPU status at the time of the panic (if available, otherwise will be fetched)

Definition at line 463 of file cpu.cpp.

463 {
464
465 // Ensure ready to panic - At this point it is not an issue if it is possible can avoid the panic as it is most
466 // likely called by a place that cant switch to the avoidable state
468 panic_lock.lock();
469
470 // Get the current process
472
473 // Print using the backend
474 Logger::Out() << "\n";
475 Logger::ERROR() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n";
476 Logger::ERROR() << "Kernel Panic: " << message;
477 Logger::ERROR() << "On Core: " << (panic_core ? panic_core->id : 0) << "\n";
478
479 // Info about the running process
480 Logger::ERROR() << "Process: " << (process ? process->name.c_str() : "Kernel") << "\n";
481 if (process)
482 Logger::ERROR() << "After running for " << process->total_ticks() << " ticks (system uptime: " << GlobalScheduler::core_scheduler()->ticks() << " ticks)\n";
483
484 // Stack trace
485 Logger::ERROR() << "----------------------------\n";
486 Logger::ERROR() << "Stack Trace:\n";
487 stack_trace(20, status);
488
489 // Register dump
490 Logger::ERROR() << "----------------------------\n";
491 Logger::ERROR() << "Register Dump:\n";
492
493 // Log the regs
494 cpu_status_t new_status{};
495 if (!status) {
496 get_status(&new_status);
497 status = &new_status;
498 }
499 print_registers(status);
500
501 // Print some text to the user
502 Logger::ERROR() << "----------------------------\n";
503 Logger::ERROR() << "There has been a fatal error in MaxOS and the system has been halted.\n";
504 Logger::ERROR() << "Please check the logs for more info.\n"; // TODO: save to a file
505 Logger::ERROR() << "Please restart the system.\n";
506
507 // Print the logo
508 Logger::ERROR() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n";
509
510 // Halt
511 halt();
512}
static LogRecord ERROR()
Gets the active logger for error logs.
Definition logger.cpp:222
static LogRecord Out()
Gets the active logger.
Definition logger.cpp:176
static Scheduler * core_scheduler()
Gets the scheduler for the currently executing core.
static Process * current_process()
Gets the process on the currently executing core.
A process that can be scheduled by the Scheduler, wraps & manages threads as well as its own address ...
Definition process.h:94
uint64_t total_ticks()
Gets the total ticks of the threads in the process (not this does not include any past killed threads...
Definition process.cpp:439
string name
The name of the process.
Definition process.h:118
uint64_t ticks() const
Gets how long the system has been running for.
static void print_registers(cpu_status_t *status)
Prints the CPU registers from the provided structure.
Definition cpu.cpp:337
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
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 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 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
uint8_t id
The ID of this core.
Definition cpu.h:243
struct PACKED MaxOS::system::CPUStatus cpu_status_t
Alias for CPUStatus struct.

References MaxOS::processes::GlobalScheduler::core_scheduler(), MaxOS::processes::GlobalScheduler::current_process(), MaxOS::Logger::ERROR(), get_status(), halt(), MaxOS::system::Core::id, MaxOS::processes::Process::name, MaxOS::Logger::Out(), panic_core, panic_lock, prepare_for_panic(), print_registers(), stack_trace(), MaxOS::processes::Scheduler::ticks(), and MaxOS::processes::Process::total_ticks().

Referenced by MaxOS::Logger::assert(), and MaxOS::hardwarecommunication::ExceptionHandler::handle_interrupt().

◆ prepare_for_panic()

cpu_status_t * CPU::prepare_for_panic ( cpu_status_t *  status = nullptr,
const string &  msg = "" 
)
static

Ensure the CPU must panic and prepare for it if so.

Parameters
statusThe status of the CPU (if available)
msgThe message to print to diagnose the cause of the panic (prints when close program)
Returns
A CPU status to avoid having to panic or a nullptr if the CPU must panic

Definition at line 521 of file cpu.cpp.

521 {
522 panic_lock.lock();
523
524 // If it may have occurred in a process, switch to the avoidable state
526
527 // Get the current process
529
530 // If the faulting address is in lower half just kill the process and move on
531 if (status && !memory::PhysicalMemoryManager::in_higher_region(status->rip)) {
532 Logger::Out() << "\n";
533 Logger::ERROR() << msg;
534 Logger::ERROR() << "CPU Panicked (i " << (int)status->interrupt_number << ") in process " << process->name.c_str() << " at 0x" << status->rip << " - killing process\n";
535 panic_lock.unlock();
537 }
538
539 // Otherwise occurred whilst the kernel was doing something for the process, thus a fault in the kernel fault
540 // and is unrecoverable
541 }
542
543 // Kill the others to make sure everything else stops
545 executing_core()->local_apic->send_interrupt(0, 0x81, EXCLUDE_SELF);
547 }
548
549 // Prepare for printing debug messages
551 Logger::active_logger() -> enable_all_log_writers();
552
553 // Unresumable state
554 panic_lock.unlock();
556 return nullptr;
557}
static Logger * active_logger()
Gets the active logger (to be used to modify the logger)
Definition logger.cpp:240
static void print_logo(bool is_panic=false)
Prints the logo to the center of the screen.
void send_interrupt(uint8_t apic_id, uint8_t vector, size_t flags) const
Send an interrupt to a specific core.
Definition apic.cpp:213
static bool in_higher_region(uintptr_t virtual_address)
Checks if a virtual address is in the higher region.
Definition physical.cpp:960
static GlobalScheduler * system_scheduler()
Gets the system scheduler.
Definition scheduler.cpp:55
static void deactivate()
Deactivates each core's scheduler.
static bool is_active()
Checks if the global scheduler is active.
static system::cpu_status_t * force_remove_process(Process *process)
Removes a process from the scheduler and deletes all threads, begins running the next process.
static Core * executing_core()
Gets the core that is currently executing.
Definition cpu.cpp:660
hardwarecommunication::LocalAPIC * local_apic
The local APIC for this core.
Definition cpu.h:247

References MaxOS::Logger::active_logger(), MaxOS::processes::GlobalScheduler::current_process(), MaxOS::processes::GlobalScheduler::deactivate(), MaxOS::Logger::ERROR(), executing_core(), MaxOS::processes::GlobalScheduler::force_remove_process(), MaxOS::memory::PhysicalMemoryManager::in_higher_region(), MaxOS::processes::GlobalScheduler::is_active(), MaxOS::system::Core::local_apic, MaxOS::processes::Process::name, MaxOS::Logger::Out(), panic_core, panic_lock, MaxOS::console::FramebufferConsole::print_logo(), MaxOS::hardwarecommunication::LocalAPIC::send_interrupt(), and MaxOS::processes::GlobalScheduler::system_scheduler().

Referenced by MaxOS::hardwarecommunication::ExceptionHandler::handle_interrupt(), and PANIC().

◆ print_registers()

void CPU::print_registers ( cpu_status_t *  status)
static

Prints the CPU registers from the provided structure.

Parameters
statusThe structure containing the CPU status

Definition at line 337 of file cpu.cpp.

337 {
338
339 // Print the registers
340 Logger::ERROR() << "R15: \t0x" << status->r15 << "\n";
341 Logger::ERROR() << "R14: \t0x" << status->r14 << "\n";
342 Logger::ERROR() << "R13: \t0x" << status->r13 << "\n";
343 Logger::ERROR() << "R12: \t0x" << status->r12 << "\n";
344 Logger::ERROR() << "R11: \t0x" << status->r11 << "\n";
345 Logger::ERROR() << "R10: \t0x" << status->r10 << "\n";
346 Logger::ERROR() << "R9: \t0x" << status->r9 << "\n";
347 Logger::ERROR() << "R8: \t0x" << status->r8 << "\n";
348 Logger::ERROR() << "RDI: \t0x" << status->rdi << "\n";
349 Logger::ERROR() << "RSI: \t0x" << status->rsi << "\n";
350 Logger::ERROR() << "RBP: \t0x" << status->rbp << "\n";
351 Logger::ERROR() << "RDX: \t0x" << status->rdx << "\n";
352 Logger::ERROR() << "RCX: \t0x" << status->rcx << "\n";
353 Logger::ERROR() << "RBX: \t0x" << status->rbx << "\n";
354 Logger::ERROR() << "RAX: \t0x" << status->rax << "\n";
355 Logger::ERROR() << "INT: \t0x" << status->interrupt_number << "\n";
356 Logger::ERROR() << "ERRCD: \t0x" << status->error_code << "\n";
357 Logger::ERROR() << "RIP: \t0x" << status->rip << "\n";
358 Logger::ERROR() << "CS: \t0x" << status->cs << "\n";
359 Logger::ERROR() << "RFlGS: \t0x" << status->rflags << "\n";
360 Logger::ERROR() << "RSP: \t0x" << status->rsp << "\n";
361 Logger::ERROR() << "SS: \t0x" << status->ss << "\n";
362
363}

References MaxOS::Logger::ERROR().

Referenced by PANIC().

◆ read_msr()

uint64_t CPU::read_msr ( uint32_t  msr)
static

Reads the value of the specified MSR.

Parameters
msrThe MSR to read
Returns
The value of the MSR

Definition at line 371 of file cpu.cpp.

371 {
372
373 // Read the MSR
374 uint32_t low, high;
375 asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
376
377 // Return the value
378 return (uint64_t) low | ((uint64_t) high << 32);
379}

Referenced by check_nx(), MaxOS::hardwarecommunication::LocalAPIC::LocalAPIC(), and MaxOS::hardwarecommunication::LocalAPIC::read().

◆ set_status()

void CPU::set_status ( cpu_status_t *  status)
static

Sets the CPU registers from the provided structure.

Parameters
statusThe structure containing the CPU status

Definition at line 311 of file cpu.cpp.

311 {
312
313 // Set the registers
314 asm volatile("mov %0, %%r15" : : "r" (status->r15));
315 asm volatile("mov %0, %%r14" : : "r" (status->r14));
316 asm volatile("mov %0, %%r13" : : "r" (status->r13));
317 asm volatile("mov %0, %%r12" : : "r" (status->r12));
318 asm volatile("mov %0, %%r11" : : "r" (status->r11));
319 asm volatile("mov %0, %%r10" : : "r" (status->r10));
320 asm volatile("mov %0, %%r9" : : "r" (status->r9));
321 asm volatile("mov %0, %%r8" : : "r" (status->r8));
322 asm volatile("mov %0, %%rdi" : : "r" (status->rdi));
323 asm volatile("mov %0, %%rsi" : : "r" (status->rsi));
324 asm volatile("mov %0, %%rbp" : : "r" (status->rbp));
325 asm volatile("mov %0, %%rdx" : : "r" (status->rdx));
326 asm volatile("mov %0, %%rcx" : : "r" (status->rcx));
327 asm volatile("mov %0, %%rbx" : : "r" (status->rbx));
328 asm volatile("mov %0, %%rax" : : "r" (status->rax));
329
330}

◆ stack_trace()

void CPU::stack_trace ( size_t  level,
cpu_status_t *  status = nullptr 
)
static

Prints a stack trace up to the specified level.

Parameters
levelThe number of stack frames to print
statusThe execution state to trace (optional, null will be interpreted as use the current state)

Definition at line 414 of file cpu.cpp.

414 {
415
416 auto* frame = status ? (stack_frame_t*)status->rbp : (stack_frame_t*) __builtin_frame_address(0);
417
418 // Loop through the frames logging
419 for (size_t current_level = 0; current_level < level; current_level++) {
420
421 // Print the frame
422 auto function = resolve_symbol(frame->rip);
423 Logger::ERROR() << "(" << current_level << "): " << (function ? function : "Unknown()") << " at 0x" << frame->rip << "\n";
424
425 // Next frame
426 frame = frame->next;
427 if (frame == nullptr)
428 break;
429
430 }
431}
struct PACKED MaxOS::system::StackFrame stack_frame_t
Alias for StackFrame struct.
const char * resolve_symbol(uintptr_t rip, uintptr_t link_base, uintptr_t load_base)
resolve an instruction pointer (rip) to a symbol name and optional offset.
Definition symbols.cpp:23

References MaxOS::Logger::ERROR(), and MaxOS::common::resolve_symbol().

Referenced by PANIC().

◆ write_msr()

void CPU::write_msr ( uint32_t  msr,
uint64_t  value 
)
static

Writes the specified value to the specified MSR.

Parameters
msrThe MSR to write to
valueThe value to write

Definition at line 387 of file cpu.cpp.

387 {
388
389 // Write the MSR
390 asm volatile("wrmsr" : : "a" ((uint32_t) value), "d" ((uint32_t) (value >> 32)), "c" (msr));
391}

Referenced by MaxOS::hardwarecommunication::LocalAPIC::LocalAPIC(), MaxOS::hardwarecommunication::LocalAPIC::send_icr(), and MaxOS::hardwarecommunication::LocalAPIC::write().

Member Data Documentation

◆ acpi

The ACPI interface for the CPU.

Definition at line 263 of file cpu.h.

◆ apic

The APIC interface for the CPU.

Definition at line 264 of file cpu.h.

Referenced by CPU(), find_cores(), kernel_main(), and MaxOS::system::Core::wake_up().

◆ cores

◆ panic_core

Core* MaxOS::system::CPU::panic_core = nullptr
inlinestatic

The core that triggered the panic.

Definition at line 266 of file cpu.h.

Referenced by PANIC(), and prepare_for_panic().

◆ panic_lock

common::Spinlock MaxOS::system::CPU::panic_lock
inlinestatic

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