Max OS 0.3
Loading...
Searching...
No Matches
MaxOS::hardwarecommunication::LocalAPIC Class Reference

Handles the local APIC for the current core. More...

#include <apic.h>

Public Member Functions

 LocalAPIC ()
 Construct a new Local APIC object and map the APIC base address to the higher half if needed as well as enabling the APIC.
 
uint32_t read (uint32_t reg) const
 read a value from the apic register using the MSR or memory I/O depending on the local apic version
 
void write (uint32_t reg, uint32_t value) const
 write a value to the apic register using the MSR or memory I/O depending on the local apic version
 
uint32_t id () const
 Get the id of the local apic.
 
void send_eoi () const
 Acknowledge that the interrupt has been handled, allowing the PIC to process the next interrupt.
 
void send_init (uint8_t apic_id, bool assert) const
 send the init IPI to another apic
 
void send_startup (uint8_t apic_id, uint8_t vector) const
 send the start up IPI to another apic
 

Detailed Description

Handles the local APIC for the current core.

Definition at line 24 of file apic.h.

Constructor & Destructor Documentation

◆ LocalAPIC()

LocalAPIC::LocalAPIC ( )

Construct a new Local APIC object and map the APIC base address to the higher half if needed as well as enabling the APIC.

Definition at line 21 of file apic.cpp.

21 {
22
23 // Get the APIC base address
24 uint64_t msr_info = CPU::read_msr(0x1B);
25 m_apic_base = msr_info & 0xFFFFF000;
26
27 // Reserve the base address once
28 static bool bsp_setup = false;
29 if(!bsp_setup)
31
32 // Check if the APIC supports x2APIC
33 uint32_t ignored, xleaf, x2leaf;
34 CPU::cpuid(0x01, &ignored, &ignored, &x2leaf, &xleaf);
35
36 if (x2leaf & (1 << 21)) {
37
38 // Enable x2APIC
39 m_x2apic = true;
40 msr_info |= (1 << 10);
41 CPU::write_msr(0x1B, msr_info);
42 Logger::DEBUG() << "CPU supports x2APIC\n";
43
44 } else if (xleaf & (1 << 9)) {
45
46 m_x2apic = false;
47 Logger::DEBUG() << "CPU supports xAPIC\n";
48
49 // Map the APIC base address to the higher half
50 m_apic_base_high = (uint64_t) PhysicalMemoryManager::to_io_region(m_apic_base);
51 PhysicalMemoryManager::s_current_manager->map((physical_address_t*) m_apic_base, (virtual_address_t*) m_apic_base_high, PRESENT | WRITE);
52 Logger::DEBUG() << "APIC Base: phy=0x" << m_apic_base << ", virt=0x" << m_apic_base_high << "\n";
53 } else {
54 ASSERT(false, "CPU does not support xAPIC");
55 }
56
57 if (!(msr_info & (1 << 11))) {
58 Logger::WARNING() << "APIC is not enabled\n";
59 return;
60 }
61
62 // Enable the APIC
63 write(0xF0, (1 << 8) | 0x100);
64 bsp_setup = true;
65 Logger::DEBUG() << "APIC Enabled\n";
66}
static Logger DEBUG()
Gets active logger set to DEBUG level.
Definition logger.cpp:193
static Logger WARNING()
Gets active logger set to WARNING level.
Definition logger.cpp:205
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
void write(uint32_t reg, uint32_t value) const
write a value to the apic register using the MSR or memory I/O depending on the local apic version
Definition apic.cpp:91
static void * to_io_region(uintptr_t physical_address)
Converts a physical address to an IO region address if it is in the lower region using the higher hal...
Definition physical.cpp:915
void reserve(uint64_t address)
Reserves a physical address.
Definition physical.cpp:777
virtual_address_t * map(virtual_address_t *virtual_address, size_t flags)
Allocates a physical address to a virtual address.
Definition physical.cpp:538
static PhysicalMemoryManager * s_current_manager
The current physical memory manager in use.
Definition physical.h:185
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 uint64_t read_msr(uint32_t msr)
Reads the value of the specified MSR.
Definition cpu.cpp:372
static void write_msr(uint32_t msr, uint64_t value)
Writes the specified value to the specified MSR.
Definition cpu.cpp:388
#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, MaxOS::system::CPU::cpuid(), MaxOS::Logger::DEBUG(), MaxOS::memory::PhysicalMemoryManager::map(), MaxOS::memory::PRESENT, MaxOS::system::CPU::read_msr(), MaxOS::memory::PhysicalMemoryManager::reserve(), MaxOS::memory::PhysicalMemoryManager::s_current_manager, MaxOS::memory::PhysicalMemoryManager::to_io_region(), MaxOS::Logger::WARNING(), write(), MaxOS::memory::WRITE, and MaxOS::system::CPU::write_msr().

Member Function Documentation

◆ id()

uint32_t LocalAPIC::id ( ) const

Get the id of the local apic.

Returns
The id of the local apic

Definition at line 108 of file apic.cpp.

108 {
109
110 // Read the id
111 uint32_t id = read(0x20);
112
113 // Return the id
114 return m_x2apic ? id : (id >> 24);
115}
uint32_t id() const
Get the id of the local apic.
Definition apic.cpp:108
uint32_t read(uint32_t reg) const
read a value from the apic register using the MSR or memory I/O depending on the local apic version
Definition apic.cpp:76

References id(), and read().

Referenced by id().

◆ read()

uint32_t LocalAPIC::read ( uint32_t  reg) const

read a value from the apic register using the MSR or memory I/O depending on the local apic version

Parameters
regThe register to read
Returns
The value of the register

Definition at line 76 of file apic.cpp.

76 {
77
78 // If x2APIC is enabled I/O is done through the MSR
79 if (m_x2apic)
80 return (uint32_t) CPU::read_msr((reg >> 4) + 0x800);
81
82 return *(volatile uint32_t*) ((uintptr_t) m_apic_base_high + reg);
83}

References MaxOS::system::CPU::read_msr().

Referenced by id(), send_init(), and send_startup().

◆ send_eoi()

void LocalAPIC::send_eoi ( ) const

Acknowledge that the interrupt has been handled, allowing the PIC to process the next interrupt.

Definition at line 120 of file apic.cpp.

120 {
121
122 write(0xB0, 0);
123}

References write().

◆ send_init()

void LocalAPIC::send_init ( uint8_t  apic_id,
bool  assert 
) const

send the init IPI to another apic

Parameters
apic_idThe id of the apic to send to
assertIs this an assert code (drive / release the signal)

Definition at line 131 of file apic.cpp.

131 {
132
133 uint32_t icr_low = 0;
134
135 // Delivery mode = INIT (101b at bits 8-10)
136 icr_low |= (0b101 << 8);
137
138 // Level (bit 14): 1 = assert, 0 = de-assert
139 if (assert)
140 icr_low |= (1 << 14);
141
142 // Trigger mode: Level = 1
143 icr_low |= (1 << 15);
144
145 if (!m_x2apic) {
146
147 // Select target core
148 write(0x310, apic_id << 24);
149
150 // Send INIT (Delivery mode = INIT, Level = 1)
151 write(0x300, icr_low);
152
153 // Wait for delivery
154 while (read(0x300) & (1 << 12))
155 asm volatile("pause");
156
157 } else {
158
159 // x2APIC
160 CPU::write_msr(0x830, (uint64_t)apic_id << 32 | icr_low);
161 }
162}

References read(), write(), and MaxOS::system::CPU::write_msr().

◆ send_startup()

void LocalAPIC::send_startup ( uint8_t  apic_id,
uint8_t  vector 
) const

send the start up IPI to another apic

Parameters
apic_idThe apic to send it to
vectorWhere to start executing

Definition at line 170 of file apic.cpp.

170 {
171
172 if (!m_x2apic) {
173
174 // Select target core
175 write(0x310, apic_id << 24);
176
177 // Send SIPI (Delivery mode = STARTUP)
178 write(0x300, 0x4600 | vector);
179
180 // Wait for delivery
181 while (read(0x300) & (1 << 12))
182 asm volatile("pause");
183
184 } else {
185
186 // x2APIC
187 CPU::write_msr(0x831, (uint64_t)apic_id << 32 | 0x4600 | vector);
188 }
189
190
191}

References read(), write(), and MaxOS::system::CPU::write_msr().

◆ write()

void LocalAPIC::write ( uint32_t  reg,
uint32_t  value 
) const

write a value to the apic register using the MSR or memory I/O depending on the local apic version

Parameters
regThe register to write to
valueThe value to write

Definition at line 91 of file apic.cpp.

91 {
92
93 // If x2APIC is enabled I/O is done through the MSR
94 if (m_x2apic){
95 CPU::write_msr((reg >> 4) + 0x800, value);
96 return;
97 }
98
99 // Default to memory I/O
100 *(volatile uint32_t*) ((uintptr_t) m_apic_base_high + reg) = value;
101}

References MaxOS::system::CPU::write_msr().

Referenced by LocalAPIC(), send_eoi(), send_init(), send_startup(), and MaxOS::drivers::clock::Clock::setup_apic_clock().


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