Added APIC_BASE structure

This commit is contained in:
Alex 2022-10-23 03:10:43 +03:00
parent fd154bc547
commit eb65bd1896
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
3 changed files with 55 additions and 19 deletions

View File

@ -9,6 +9,8 @@
#include "../../../kernel.h" #include "../../../kernel.h"
#include "../acpi.hpp" #include "../acpi.hpp"
using namespace CPU::x64;
namespace APIC namespace APIC
{ {
enum IOAPICRegisters enum IOAPICRegisters
@ -40,9 +42,9 @@ namespace APIC
if (x2APICSupported) if (x2APICSupported)
{ {
if (Register != APIC_ICRHI) if (Register != APIC_ICRHI)
return CPU::x64::rdmsr((Register >> 4) + 0x800); return rdmsr((Register >> 4) + 0x800);
else else
return CPU::x64::rdmsr(0x30 + 0x800); return rdmsr(0x30 + 0x800);
} }
else else
{ {
@ -63,9 +65,9 @@ namespace APIC
if (x2APICSupported) if (x2APICSupported)
{ {
if (Register != APIC_ICRHI) if (Register != APIC_ICRHI)
CPU::x64::wrmsr((Register >> 4) + 0x800, Value); wrmsr((Register >> 4) + 0x800, Value);
else else
CPU::x64::wrmsr(CPU::x64::MSR_X2APIC_ICR, Value); wrmsr(MSR_X2APIC_ICR, Value);
} }
else else
{ {
@ -110,7 +112,7 @@ namespace APIC
{ {
if (x2APICSupported) if (x2APICSupported)
{ {
CPU::x64::wrmsr(CPU::x64::MSR_X2APIC_ICR, ((uint64_t)CPU) << 32 | InterruptNumber); wrmsr(MSR_X2APIC_ICR, ((uint64_t)CPU) << 32 | InterruptNumber);
} }
else else
{ {
@ -179,20 +181,25 @@ namespace APIC
APIC::APIC(int Core) APIC::APIC(int Core)
{ {
APIC_BASE BaseStruct = {.raw = rdmsr(MSR_APIC_BASE)};
void *APICBaseAddress = (void *)(uint64_t)(BaseStruct.ApicBaseLo << 12u | BaseStruct.ApicBaseHi << 32u);
trace("APIC Address: %#lx", APICBaseAddress);
uint32_t rcx; uint32_t rcx;
CPU::x64::cpuid(1, 0, 0, &rcx, 0); cpuid(1, 0, 0, &rcx, 0);
if (rcx & CPU::x64::CPUID_FEAT_RCX_x2APIC) if (rcx & CPUID_FEAT_RCX_x2APIC)
{ {
// this->x2APICSupported = true; // this->x2APICSupported = true;
warn("x2APIC not supported yet."); warn("x2APIC not supported yet.");
// CPU::x64::wrmsr(CPU::x64::MSR_APIC_BASE, (CPU::x64::rdmsr(CPU::x64::MSR_APIC_BASE) | (1 << 11)) & ~(1 << 10)); // wrmsr(MSR_APIC_BASE, (rdmsr(MSR_APIC_BASE) | (1 << 11)) & ~(1 << 10));
CPU::x64::wrmsr(CPU::x64::MSR_APIC_BASE, CPU::x64::rdmsr(CPU::x64::MSR_APIC_BASE) | (1 << 11)); BaseStruct.EN = 1;
wrmsr(MSR_APIC_BASE, BaseStruct.raw);
} }
else else
{ {
CPU::x64::wrmsr(CPU::x64::MSR_APIC_BASE, CPU::x64::rdmsr(CPU::x64::MSR_APIC_BASE) | (1 << 11)); BaseStruct.EN = 1;
wrmsr(MSR_APIC_BASE, BaseStruct.raw);
} }
trace("APIC Address: %#lx", CPU::x64::rdmsr(CPU::x64::MSR_APIC_BASE));
this->Write(APIC_TPR, 0x0); this->Write(APIC_TPR, 0x0);
this->Write(APIC_SVR, this->Read(APIC_SVR) | 0x100); // 0x1FF or 0x100 ? on https://wiki.osdev.org/APIC is 0x100 this->Write(APIC_SVR, this->Read(APIC_SVR) | 0x100); // 0x1FF or 0x100 ? on https://wiki.osdev.org/APIC is 0x100
@ -216,9 +223,9 @@ namespace APIC
if (madt->nmi[i]->flags & 8) if (madt->nmi[i]->flags & 8)
nmi |= 1 << 15; nmi |= 1 << 15;
if (madt->nmi[i]->lint == 0) if (madt->nmi[i]->lint == 0)
this->Write(0x350, nmi); this->Write(APIC_LINT0, nmi);
else if (madt->nmi[i]->lint == 1) else if (madt->nmi[i]->lint == 1)
this->Write(0x360, nmi); this->Write(APIC_LINT1, nmi);
} }
} }
@ -226,9 +233,9 @@ namespace APIC
{ {
} }
void Timer::OnInterruptReceived(CPU::x64::TrapFrame *Frame) void Timer::OnInterruptReceived(TrapFrame *Frame)
{ {
// fixme("APIC IRQ0 INTERRUPT RECEIVED ON CPU %d", CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE)); // fixme("APIC IRQ0 INTERRUPT RECEIVED ON CPU %d", rdmsr(MSR_FS_BASE));
// UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write('\n'); // UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write('\n');
// UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write('H'); // UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write('H');
// UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write('\n'); // UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write('\n');
@ -244,7 +251,7 @@ namespace APIC
this->lapic->Write(APIC_TICR, (TicksIn10ms / 10) * Miliseconds); this->lapic->Write(APIC_TICR, (TicksIn10ms / 10) * Miliseconds);
} }
Timer::Timer(APIC *apic) : Interrupts::Handler(CPU::x64::IRQ0) Timer::Timer(APIC *apic) : Interrupts::Handler(IRQ0)
{ {
trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID); trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID);
this->lapic = apic; this->lapic = apic;
@ -283,7 +290,7 @@ namespace APIC
TicksIn10ms = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR); TicksIn10ms = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR);
LVTTimer timer = {0, 0, 0, 0, 0, 0, 0}; LVTTimer timer = {0, 0, 0, 0, 0, 0, 0};
timer.Vector = CPU::x64::IRQ0; timer.Vector = IRQ0;
timer.Mask = 0; timer.Mask = 0;
timer.TimerMode = 1; timer.TimerMode = 1;

View File

@ -38,7 +38,7 @@ namespace APIC
APIC_TDCR = 0x3E0, // Divide Configuration (for Timer) APIC_TDCR = 0x3E0, // Divide Configuration (for Timer)
}; };
union LVTTimer typedef union
{ {
struct struct
{ {
@ -73,7 +73,7 @@ namespace APIC
uint64_t Reserved2 : 14; uint64_t Reserved2 : 14;
}; };
uint64_t raw; uint64_t raw;
}; } __attribute__((packed)) LVTTimer;
class APIC class APIC
{ {

View File

@ -994,6 +994,35 @@ namespace CPU
IRQ223 = 0xff, IRQ223 = 0xff,
} Interrupts; } Interrupts;
/**
* @brief MSR_APIC_BASE structure
* @see MSR_APIC_BASE
*/
typedef union
{
struct
{
/** @brief Reserved */
uint32_t Reserved0 : 8;
/**
* @brief BSP Flag
* @details If the BSP flag is set to 1, the processor is the bootstrap processor.
*/
uint32_t BSP : 1;
/** @brief Reserved */
uint32_t Reserved1 : 1;
/** @brief Enable x2APIC mode */
uint32_t EXTD : 1;
/** @brief APIC Global Enable */
uint32_t EN : 1;
/** @brief APIC Base Low Address */
uint32_t ApicBaseLo : 20;
/** @brief APIC Base High Address */
uint32_t ApicBaseHi : 32;
};
uint64_t raw;
} __attribute__((packed)) APIC_BASE;
typedef union typedef union
{ {
struct struct