mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Added APIC_BASE structure
This commit is contained in:
parent
fd154bc547
commit
eb65bd1896
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user