From eb65bd189647d1fa5cd792cf5ee6385a35d3760d Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 23 Oct 2022 03:10:43 +0300 Subject: [PATCH] Added APIC_BASE structure --- ...dvancedProgrammableInterruptController.cpp | 41 +++++++++++-------- Architecture/amd64/cpu/apic.hpp | 4 +- include/cpu.hpp | 29 +++++++++++++ 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp index e9466c08..bb5a8db9 100644 --- a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp +++ b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp @@ -9,6 +9,8 @@ #include "../../../kernel.h" #include "../acpi.hpp" +using namespace CPU::x64; + namespace APIC { enum IOAPICRegisters @@ -40,9 +42,9 @@ namespace APIC if (x2APICSupported) { if (Register != APIC_ICRHI) - return CPU::x64::rdmsr((Register >> 4) + 0x800); + return rdmsr((Register >> 4) + 0x800); else - return CPU::x64::rdmsr(0x30 + 0x800); + return rdmsr(0x30 + 0x800); } else { @@ -63,9 +65,9 @@ namespace APIC if (x2APICSupported) { if (Register != APIC_ICRHI) - CPU::x64::wrmsr((Register >> 4) + 0x800, Value); + wrmsr((Register >> 4) + 0x800, Value); else - CPU::x64::wrmsr(CPU::x64::MSR_X2APIC_ICR, Value); + wrmsr(MSR_X2APIC_ICR, Value); } else { @@ -110,7 +112,7 @@ namespace APIC { 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 { @@ -179,20 +181,25 @@ namespace APIC 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; - CPU::x64::cpuid(1, 0, 0, &rcx, 0); - if (rcx & CPU::x64::CPUID_FEAT_RCX_x2APIC) + cpuid(1, 0, 0, &rcx, 0); + if (rcx & CPUID_FEAT_RCX_x2APIC) { // this->x2APICSupported = true; 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)); - CPU::x64::wrmsr(CPU::x64::MSR_APIC_BASE, CPU::x64::rdmsr(CPU::x64::MSR_APIC_BASE) | (1 << 11)); + // wrmsr(MSR_APIC_BASE, (rdmsr(MSR_APIC_BASE) | (1 << 11)) & ~(1 << 10)); + BaseStruct.EN = 1; + wrmsr(MSR_APIC_BASE, BaseStruct.raw); } 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_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) nmi |= 1 << 15; if (madt->nmi[i]->lint == 0) - this->Write(0x350, nmi); + this->Write(APIC_LINT0, nmi); 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('H'); // UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write('\n'); @@ -244,7 +251,7 @@ namespace APIC 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); this->lapic = apic; @@ -283,7 +290,7 @@ namespace APIC TicksIn10ms = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR); LVTTimer timer = {0, 0, 0, 0, 0, 0, 0}; - timer.Vector = CPU::x64::IRQ0; + timer.Vector = IRQ0; timer.Mask = 0; timer.TimerMode = 1; diff --git a/Architecture/amd64/cpu/apic.hpp b/Architecture/amd64/cpu/apic.hpp index aac2bed5..ef6fa35f 100644 --- a/Architecture/amd64/cpu/apic.hpp +++ b/Architecture/amd64/cpu/apic.hpp @@ -38,7 +38,7 @@ namespace APIC APIC_TDCR = 0x3E0, // Divide Configuration (for Timer) }; - union LVTTimer + typedef union { struct { @@ -73,7 +73,7 @@ namespace APIC uint64_t Reserved2 : 14; }; uint64_t raw; - }; + } __attribute__((packed)) LVTTimer; class APIC { diff --git a/include/cpu.hpp b/include/cpu.hpp index 23af6506..3c2e1711 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -994,6 +994,35 @@ namespace CPU IRQ223 = 0xff, } 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 { struct