mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Added APIC & SMP stub
This commit is contained in:
parent
f2f26c70a3
commit
ad9817a2db
@ -7,7 +7,7 @@ namespace ACPI
|
||||
{
|
||||
MADT::MADT(ACPI::MADTHeader *madt)
|
||||
{
|
||||
LAPICAddr = (LAPIC *)(uintptr_t)madt->LocalControllerAddress;
|
||||
LAPICAddress = (LAPIC *)(uintptr_t)madt->LocalControllerAddress;
|
||||
for (uint8_t *ptr = (uint8_t *)(madt->Entries);
|
||||
(uintptr_t)(ptr) < (uintptr_t)(madt) + madt->Header.Length;
|
||||
ptr += *(ptr + 1))
|
||||
@ -27,8 +27,8 @@ namespace ACPI
|
||||
case 1:
|
||||
{
|
||||
ioapic.push_back((MADTIOApic *)ptr);
|
||||
trace("I/O APIC %#llx (Address %#llx) found.", ioapic.back()->APICID, ioapic.back()->addr);
|
||||
Memory::Virtual().Map((void *)(uintptr_t)ioapic.back()->addr, (void *)(uintptr_t)ioapic.back()->addr, Memory::PTFlag::RW | Memory::PTFlag::PCD); // Make sure that the address is mapped.
|
||||
trace("I/O APIC %#llx (Address %#llx) found.", ioapic.back()->APICID, ioapic.back()->Address);
|
||||
Memory::Virtual().Map((void *)(uintptr_t)ioapic.back()->Address, (void *)(uintptr_t)ioapic.back()->Address, Memory::PTFlag::RW | Memory::PTFlag::PCD); // Make sure that the address is mapped.
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
@ -48,12 +48,12 @@ namespace ACPI
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
LAPICAddr = (LAPIC *)ptr;
|
||||
trace("APIC found at %#llx", LAPICAddr);
|
||||
LAPICAddress = (LAPIC *)ptr;
|
||||
trace("APIC found at %#llx", LAPICAddress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Memory::Virtual().Map((void *)LAPICAddr, (void *)LAPICAddr, Memory::PTFlag::RW | Memory::PTFlag::PCD); // I should map more than one page?
|
||||
Memory::Virtual().Map((void *)LAPICAddress, (void *)LAPICAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD); // I should map more than one page?
|
||||
}
|
||||
trace("Total CPU cores: %d", CPUCores);
|
||||
}
|
||||
|
@ -199,8 +199,8 @@ namespace ACPI
|
||||
struct APICHeader Header;
|
||||
uint8_t APICID;
|
||||
uint8_t reserved;
|
||||
uint32_t addr;
|
||||
uint32_t gsib;
|
||||
uint32_t Address;
|
||||
uint32_t GSIBase;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct MADTIso
|
||||
@ -239,7 +239,7 @@ namespace ACPI
|
||||
Vector<MADTIso *> iso;
|
||||
Vector<MADTNmi *> nmi;
|
||||
Vector<LocalAPIC *> lapic;
|
||||
struct LAPIC *LAPICAddr;
|
||||
struct LAPIC *LAPICAddress;
|
||||
uint8_t CPUCores;
|
||||
|
||||
MADT(ACPI::MADTHeader *madt);
|
||||
|
@ -0,0 +1,202 @@
|
||||
#include "apic.hpp"
|
||||
|
||||
#include <cpu.hpp>
|
||||
#include <smp.hpp>
|
||||
|
||||
#include "../../../kernel.h"
|
||||
#include "../acpi.hpp"
|
||||
|
||||
namespace APIC
|
||||
{
|
||||
enum IOAPICRegisters
|
||||
{
|
||||
GetIOAPICVersion = 0x1
|
||||
};
|
||||
|
||||
enum IOAPICFlags
|
||||
{
|
||||
ActiveHighLow = 2,
|
||||
EdgeLevel = 8
|
||||
};
|
||||
|
||||
struct IOAPICVersion
|
||||
{
|
||||
uint8_t Version;
|
||||
uint8_t Reserved;
|
||||
uint8_t MaximumRedirectionEntry;
|
||||
uint8_t Reserved2;
|
||||
};
|
||||
|
||||
// headache
|
||||
// https://www.amd.com/system/files/TechDocs/24593.pdf
|
||||
// https://www.naic.edu/~phil/software/intel/318148.pdf
|
||||
|
||||
uint32_t APIC::Read(uint32_t Register)
|
||||
{
|
||||
// Too repetitive
|
||||
if (Register != APIC_EOI &&
|
||||
Register != APIC_ID &&
|
||||
Register != APIC_TIMER &&
|
||||
Register != APIC_TDCR &&
|
||||
Register != APIC_TICR &&
|
||||
Register != APIC_TCCR)
|
||||
debug("APIC::Read(%#lx)", Register);
|
||||
if (x2APICSupported)
|
||||
{
|
||||
if (Register != APIC_ICRHI)
|
||||
return CPU::x64::rdmsr((Register >> 4) + 0x800);
|
||||
else
|
||||
return CPU::x64::rdmsr(0x30 + 0x800);
|
||||
}
|
||||
else
|
||||
return *((volatile uint32_t *)((uintptr_t)((ACPI::MADT *)PowerManager->GetMADT())->LAPICAddress + Register));
|
||||
}
|
||||
|
||||
void APIC::Write(uint32_t Register, uint32_t Value)
|
||||
{
|
||||
// Too repetitive
|
||||
if (Register != APIC_EOI &&
|
||||
Register != APIC_TIMER &&
|
||||
Register != APIC_TDCR &&
|
||||
Register != APIC_TICR &&
|
||||
Register != APIC_TCCR)
|
||||
debug("APIC::Write(%#lx, %#lx)", Register, Value);
|
||||
if (x2APICSupported)
|
||||
{
|
||||
if (Register != APIC_ICRHI)
|
||||
CPU::x64::wrmsr((Register >> 4) + 0x800, Value);
|
||||
else
|
||||
CPU::x64::wrmsr(CPU::x64::MSR_X2APIC_ICR, Value);
|
||||
}
|
||||
else
|
||||
*((volatile uint32_t *)(((uintptr_t)((ACPI::MADT *)PowerManager->GetMADT())->LAPICAddress) + Register)) = Value;
|
||||
}
|
||||
|
||||
void APIC::IOWrite(uint64_t Base, uint32_t Register, uint32_t Value)
|
||||
{
|
||||
debug("APIC::IOWrite(%#lx, %#lx, %#lx)", Base, Register, Value);
|
||||
*((volatile uint32_t *)(((uintptr_t)Base))) = Register;
|
||||
*((volatile uint32_t *)(((uintptr_t)Base + 16))) = Value;
|
||||
}
|
||||
|
||||
uint32_t APIC::IORead(uint64_t Base, uint32_t Register)
|
||||
{
|
||||
debug("APIC::IORead(%#lx, %#lx)", Base, Register);
|
||||
*((volatile uint32_t *)(((uintptr_t)Base))) = Register;
|
||||
return *((volatile uint32_t *)(((uintptr_t)Base + 16)));
|
||||
}
|
||||
|
||||
void APIC::EOI() { this->Write(APIC_EOI, 0); }
|
||||
|
||||
void APIC::RedirectIRQs(int CPU)
|
||||
{
|
||||
debug("Redirecting IRQs...");
|
||||
for (int i = 0; i < 16; i++)
|
||||
this->RedirectIRQ(CPU, i, 1);
|
||||
debug("Redirecting IRQs completed.");
|
||||
}
|
||||
|
||||
void APIC::IPI(uint8_t CPU, uint32_t InterruptNumber)
|
||||
{
|
||||
if (x2APICSupported)
|
||||
{
|
||||
CPU::x64::wrmsr(CPU::x64::MSR_X2APIC_ICR, ((uint64_t)CPU) << 32 | InterruptNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
InterruptNumber = (1 << 14) | InterruptNumber;
|
||||
this->Write(APIC_ICRHI, (CPU << 24));
|
||||
this->Write(APIC_ICRLO, InterruptNumber);
|
||||
}
|
||||
}
|
||||
|
||||
void APIC::OneShot(uint32_t Vector, uint64_t Miliseconds)
|
||||
{
|
||||
int apic_timer_ticks = 0;
|
||||
fixme("APIC::OneShot(%#lx, %#lx)", Vector, Miliseconds);
|
||||
this->Write(APIC_TDCR, 0x03);
|
||||
this->Write(APIC_TIMER, (APIC::APIC::APICRegisters::APIC_ONESHOT | Vector));
|
||||
this->Write(APIC_TICR, apic_timer_ticks * Miliseconds);
|
||||
}
|
||||
|
||||
uint32_t APIC::IOGetMaxRedirect(uint32_t APICID)
|
||||
{
|
||||
uint32_t TableAddress = (this->IORead((((ACPI::MADT *)PowerManager->GetMADT())->ioapic[APICID]->Address), GetIOAPICVersion));
|
||||
return ((IOAPICVersion *)&TableAddress)->MaximumRedirectionEntry;
|
||||
}
|
||||
|
||||
void APIC::RawRedirectIRQ(uint8_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status)
|
||||
{
|
||||
uint64_t Value = Vector;
|
||||
|
||||
int64_t IOAPICTarget = -1;
|
||||
for (uint64_t i = 0; ((ACPI::MADT *)PowerManager->GetMADT())->ioapic[i] != 0; i++)
|
||||
if (((ACPI::MADT *)PowerManager->GetMADT())->ioapic[i]->GSIBase <= GSI)
|
||||
if (((ACPI::MADT *)PowerManager->GetMADT())->ioapic[i]->GSIBase + IOGetMaxRedirect(i) > GSI)
|
||||
{
|
||||
IOAPICTarget = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IOAPICTarget == -1)
|
||||
{
|
||||
error("No ISO table found for I/O APIC");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Flags & ActiveHighLow)
|
||||
Value |= (1 << 13);
|
||||
|
||||
if (Flags & EdgeLevel)
|
||||
Value |= (1 << 15);
|
||||
|
||||
if (!Status)
|
||||
Value |= (1 << 16);
|
||||
|
||||
Value |= (((uintptr_t)GetCPU(CPU)->Data->LAPIC.APICId) << 56);
|
||||
uint32_t IORegister = (GSI - ((ACPI::MADT *)PowerManager->GetMADT())->ioapic[IOAPICTarget]->GSIBase) * 2 + 16;
|
||||
|
||||
this->IOWrite(((ACPI::MADT *)PowerManager->GetMADT())->ioapic[IOAPICTarget]->Address, IORegister, (uint32_t)Value);
|
||||
this->IOWrite(((ACPI::MADT *)PowerManager->GetMADT())->ioapic[IOAPICTarget]->Address, IORegister + 1, (uint32_t)(Value >> 32));
|
||||
}
|
||||
|
||||
void APIC::RedirectIRQ(int CPU, uint8_t IRQ, int Status)
|
||||
{
|
||||
for (uint64_t i = 0; i < ((ACPI::MADT *)PowerManager->GetMADT())->iso.size(); i++)
|
||||
if (((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->IRQSource == IRQ)
|
||||
{
|
||||
debug("[ISO %d] Mapping to source IRQ%#d GSI:%#lx on CPU %d",
|
||||
i, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->IRQSource, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->GSI, CPU);
|
||||
|
||||
this->RawRedirectIRQ(((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->IRQSource + 0x20, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->GSI, ((ACPI::MADT *)PowerManager->GetMADT())->iso[i]->Flags, CPU, Status);
|
||||
return;
|
||||
}
|
||||
debug("Mapping IRQ%d on CPU %d", IRQ, CPU);
|
||||
this->RawRedirectIRQ(IRQ + 0x20, IRQ, 0, CPU, Status);
|
||||
}
|
||||
|
||||
APIC::APIC()
|
||||
{
|
||||
uint32_t rcx;
|
||||
CPU::x64::cpuid(1, 0, 0, &rcx, 0);
|
||||
if (rcx & CPU::x64::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));
|
||||
}
|
||||
else
|
||||
{
|
||||
CPU::x64::wrmsr(CPU::x64::MSR_APIC_BASE, CPU::x64::rdmsr(CPU::x64::MSR_APIC_BASE) | (1 << 11));
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
APIC::~APIC()
|
||||
{
|
||||
}
|
||||
}
|
113
Architecture/amd64/cpu/SMPTrampoline.asm
Normal file
113
Architecture/amd64/cpu/SMPTrampoline.asm
Normal file
@ -0,0 +1,113 @@
|
||||
[bits 16]
|
||||
TRAMPOLINE_BASE equ 0x2000
|
||||
|
||||
extern StartCPU
|
||||
global _trampoline_start
|
||||
_trampoline_start:
|
||||
cli
|
||||
mov ax, 0x0
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
o32 lgdt [ProtectedMode_gdtr - _trampoline_start + TRAMPOLINE_BASE]
|
||||
mov eax, cr0
|
||||
or al, 0x1
|
||||
mov cr0, eax
|
||||
jmp 0x8:(Trampoline32 - _trampoline_start + TRAMPOLINE_BASE)
|
||||
|
||||
[bits 32]
|
||||
section .text
|
||||
Trampoline32:
|
||||
mov bx, 0x10
|
||||
mov ds, bx
|
||||
mov es, bx
|
||||
mov ss, bx
|
||||
mov eax, dword [0x500]
|
||||
mov cr3, eax
|
||||
mov eax, cr4
|
||||
or eax, 1 << 5 ; Set the PAE-bit, which is the 6th bit (bit 5).
|
||||
or eax, 1 << 7
|
||||
mov cr4, eax
|
||||
mov ecx, 0xc0000080
|
||||
rdmsr
|
||||
or eax,1 << 8 ; LME
|
||||
wrmsr
|
||||
mov eax, cr0
|
||||
or eax, 1 << 31
|
||||
mov cr0, eax
|
||||
lgdt [LongMode_gdtr - _trampoline_start + TRAMPOLINE_BASE]
|
||||
jmp 0x8:(Trampoline64 - _trampoline_start + TRAMPOLINE_BASE)
|
||||
|
||||
[bits 64]
|
||||
Trampoline64:
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
mov ax, 0x0
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
lgdt [0x580]
|
||||
lidt [0x590]
|
||||
mov rsp, [0x570]
|
||||
mov rbp, 0x0 ; Terminate stack traces here.
|
||||
; Reset RFLAGS.
|
||||
push 0x0
|
||||
popf
|
||||
mov rax, qword vcode64
|
||||
call vcode64
|
||||
|
||||
vcode64:
|
||||
push rbp
|
||||
; Set up SSE
|
||||
mov rax, cr0
|
||||
; btr eax, 2
|
||||
; bts eax, 1
|
||||
; mov cr0, rax
|
||||
mov rax, cr4
|
||||
bts eax, 9
|
||||
bts eax, 10
|
||||
mov cr4, rax
|
||||
mov rax, qword TrampolineExit
|
||||
call rax
|
||||
|
||||
align 16
|
||||
LongMode_gdtr:
|
||||
dw LongModeGDTEnd - LongModeGDTStart - 1
|
||||
dq LongModeGDTStart - _trampoline_start + TRAMPOLINE_BASE
|
||||
|
||||
align 16
|
||||
LongModeGDTStart:
|
||||
dq 0 ; NULL segment
|
||||
dq 0x00AF98000000FFFF ; Code segment
|
||||
dq 0x00CF92000000FFFF ; Data segment
|
||||
LongModeGDTEnd:
|
||||
|
||||
align 16
|
||||
ProtectedMode_gdtr:
|
||||
dw ProtectedModeGDTEnd - ProtectedModeGDTStart - 1
|
||||
dd ProtectedModeGDTStart - _trampoline_start + TRAMPOLINE_BASE
|
||||
|
||||
align 16
|
||||
ProtectedModeGDTStart:
|
||||
dq 0 ; NULL segment
|
||||
dq 0x00CF9A000000FFFF ; Code segment
|
||||
dq 0x00CF92000000FFFF ; Data segment
|
||||
ProtectedModeGDTEnd:
|
||||
|
||||
align 16
|
||||
ProtectedMode_idtr:
|
||||
dw 0
|
||||
dd 0
|
||||
dd 0
|
||||
align 16
|
||||
|
||||
global _trampoline_end
|
||||
_trampoline_end:
|
||||
|
||||
TrampolineExit:
|
||||
call StartCPU
|
||||
|
||||
times 512 - ($-$$) db 0
|
26
Architecture/amd64/cpu/SymmetricMultiprocessing.cpp
Normal file
26
Architecture/amd64/cpu/SymmetricMultiprocessing.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include <smp.hpp>
|
||||
|
||||
#include <cpu.hpp>
|
||||
|
||||
#include "../../../kernel.h"
|
||||
|
||||
extern "C" uint64_t _trampoline_start, _trampoline_end;
|
||||
|
||||
#define TRAMPOLINE_START 0x2000
|
||||
|
||||
enum SMPTrampolineAddress
|
||||
{
|
||||
PAGE_TABLE = 0x500,
|
||||
START_ADDR = 0x520,
|
||||
STACK = 0x570,
|
||||
GDT = 0x580,
|
||||
IDT = 0x590,
|
||||
};
|
||||
|
||||
volatile bool CPUEnabled = false;
|
||||
|
||||
extern "C" void StartCPU()
|
||||
{
|
||||
CPUEnabled = true;
|
||||
CPU::Stop();
|
||||
}
|
64
Architecture/amd64/cpu/apic.hpp
Normal file
64
Architecture/amd64/cpu/apic.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef __FENNIX_KERNEL_APIC_H__
|
||||
#define __FENNIX_KERNEL_APIC_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace APIC
|
||||
{
|
||||
class APIC
|
||||
{
|
||||
private:
|
||||
bool x2APICSupported = false;
|
||||
|
||||
public:
|
||||
enum APICRegisters
|
||||
{
|
||||
APIC_ONESHOT = (0 << 17), // LVT One-Shot Mode (for Timer)
|
||||
APIC_PERIODIC = (1 << 17), // LVT Periodic Mode (for Timer)
|
||||
APIC_TSC_DEADLINE = (2 << 17), // LVT Timer/sDeadline (for Timer)
|
||||
// source from: https://github.com/pdoane/osdev/blob/master/intr/local_apic.c
|
||||
APIC_ID = 0x20, // Local APIC ID
|
||||
APIC_VER = 0x30, // Local APIC Version
|
||||
APIC_TPR = 0x80, // Task Priority
|
||||
APIC_APR = 0x90, // Arbitration Priority
|
||||
APIC_PPR = 0xa0, // Processor Priority
|
||||
APIC_EOI = 0xb0, // EOI
|
||||
APIC_RRD = 0xc0, // Remote Read
|
||||
APIC_LDR = 0xd0, // Logical Destination
|
||||
APIC_DFR = 0xe0, // Destination Format
|
||||
APIC_SVR = 0xf0, // Spurious Interrupt Vector
|
||||
APIC_ISR = 0x100, // In-Service (8 registers)
|
||||
APIC_TMR = 0x180, // Trigger Mode (8 registers)
|
||||
APIC_IRR = 0x200, // Interrupt Request (8 registers)
|
||||
APIC_ESR = 0x280, // Error Status
|
||||
APIC_ICRLO = 0x300, // Interrupt Command
|
||||
APIC_ICRHI = 0x310, // Interrupt Command [63:32]
|
||||
APIC_TIMER = 0x320, // LVT Timer
|
||||
APIC_THERMAL = 0x330, // LVT Thermal Sensor
|
||||
APIC_PERF = 0x340, // LVT Performance Counter
|
||||
APIC_LINT0 = 0x350, // LVT LINT0
|
||||
APIC_LINT1 = 0x360, // LVT LINT1
|
||||
APIC_ERROR = 0x370, // LVT Error
|
||||
APIC_TICR = 0x380, // Initial Count (for Timer)
|
||||
APIC_TCCR = 0x390, // Current Count (for Timer)
|
||||
APIC_TDCR = 0x3e0, // Divide Configuration (for Timer)
|
||||
};
|
||||
|
||||
uint32_t Read(uint32_t Register);
|
||||
void Write(uint32_t Register, uint32_t Value);
|
||||
void IOWrite(uint64_t Base, uint32_t Register, uint32_t Value);
|
||||
uint32_t IORead(uint64_t Base, uint32_t Register);
|
||||
void EOI();
|
||||
void RedirectIRQs(int CPU = 0);
|
||||
void IPI(uint8_t CPU, uint32_t InterruptNumber);
|
||||
void OneShot(uint32_t Vector, uint64_t Miliseconds);
|
||||
bool APICSupported();
|
||||
uint32_t IOGetMaxRedirect(uint32_t APICID);
|
||||
void RawRedirectIRQ(uint8_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status);
|
||||
void RedirectIRQ(int CPU, uint8_t IRQ, int Status);
|
||||
APIC();
|
||||
~APIC();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_APIC_H__
|
@ -3,14 +3,24 @@
|
||||
#if defined(__amd64__)
|
||||
#include "../Architecture/amd64/cpu/gdt.hpp"
|
||||
#include "../Architecture/amd64/cpu/idt.hpp"
|
||||
#include "../Architecture/amd64/acpi.hpp"
|
||||
#include "../Architecture/amd64/cpu/apic.hpp"
|
||||
#elif defined(__i386__)
|
||||
#include "../Architecture/i686/cpu/gdt.hpp"
|
||||
#include "../Architecture/i686/cpu/idt.hpp"
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace Interrupts
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
APIC::APIC *apic = nullptr;
|
||||
#elif defined(__i386__)
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
@ -23,6 +33,16 @@ namespace Interrupts
|
||||
|
||||
void Enable()
|
||||
{
|
||||
|
||||
#if defined(__amd64__)
|
||||
if (((ACPI::MADT *)PowerManager->GetMADT())->LAPICAddress != nullptr)
|
||||
apic = new APIC::APIC;
|
||||
else
|
||||
{
|
||||
error("LAPIC not found");
|
||||
// PIC
|
||||
}
|
||||
#elif defined(__i386__)
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
11
Kernel.cpp
11
Kernel.cpp
@ -16,6 +16,8 @@ SymbolResolver::Symbols *KernelSymbolTable = nullptr;
|
||||
Power::Power *PowerManager = nullptr;
|
||||
PCI::PCI *PCIManager = nullptr;
|
||||
|
||||
Time BootClock;
|
||||
|
||||
// For the Display class. Printing on first buffer.
|
||||
extern "C" void putchar(char c) { Display->Print(c, 0); }
|
||||
|
||||
@ -46,6 +48,7 @@ EXTERNC void aarch64Entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t
|
||||
|
||||
EXTERNC void Entry(BootInfo *Info)
|
||||
{
|
||||
BootClock = ReadClock();
|
||||
trace("Hello, World!");
|
||||
InitializeMemoryManagement(Info);
|
||||
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
|
||||
@ -54,6 +57,9 @@ EXTERNC void Entry(BootInfo *Info)
|
||||
Display = new Video::Display(bInfo->Framebuffer[0]);
|
||||
printf_("\eFFFFFF%s - %s [\e058C19%s\eFFFFFF]\n", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT);
|
||||
/**************************************************************************************/
|
||||
KPrint("Time: \e8888FF%02d:%02d:%02d %02d/%02d/%02d UTC",
|
||||
BootClock.Hour, BootClock.Minute, BootClock.Second,
|
||||
BootClock.Day, BootClock.Month, BootClock.Year);
|
||||
KPrint("Initializing GDT and IDT");
|
||||
Interrupts::Initialize();
|
||||
KPrint("Loading kernel symbols");
|
||||
@ -64,13 +70,16 @@ EXTERNC void Entry(BootInfo *Info)
|
||||
PCIManager = new PCI::PCI;
|
||||
foreach (auto hdr in PCIManager->GetDevices())
|
||||
{
|
||||
KPrint("Found PCI device: %s / %s / %s / %s / %s",
|
||||
KPrint("Found PCI device: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s",
|
||||
PCI::Descriptors::GetVendorName(hdr->VendorID),
|
||||
PCI::Descriptors::GetDeviceName(hdr->VendorID, hdr->DeviceID),
|
||||
PCI::Descriptors::DeviceClasses[hdr->Class],
|
||||
PCI::Descriptors::GetSubclassName(hdr->Class, hdr->Subclass),
|
||||
PCI::Descriptors::GetProgIFName(hdr->Class, hdr->Subclass, hdr->ProgIF));
|
||||
}
|
||||
KPrint("Enabling interrupts");
|
||||
Interrupts::Enable();
|
||||
KPrint("\e058C19######## \eE85230END \e058C19########");
|
||||
while (1)
|
||||
CPU::Halt();
|
||||
}
|
||||
|
473
include/cpu.hpp
473
include/cpu.hpp
@ -132,6 +132,456 @@ namespace CPU
|
||||
|
||||
namespace x64
|
||||
{
|
||||
enum CPUIDFeatures
|
||||
{
|
||||
CPUID_FEAT_RCX_SSE3 = 1 << 0,
|
||||
CPUID_FEAT_RCX_PCLMULQDQ = 1 << 1,
|
||||
CPUID_FEAT_RCX_DTES64 = 1 << 2,
|
||||
CPUID_FEAT_RCX_MONITOR = 1 << 3,
|
||||
CPUID_FEAT_RCX_DS_CPL = 1 << 4,
|
||||
CPUID_FEAT_RCX_VMX = 1 << 5,
|
||||
CPUID_FEAT_RCX_SMX = 1 << 6,
|
||||
CPUID_FEAT_RCX_EST = 1 << 7,
|
||||
CPUID_FEAT_RCX_TM2 = 1 << 8,
|
||||
CPUID_FEAT_RCX_SSSE3 = 1 << 9,
|
||||
CPUID_FEAT_RCX_CID = 1 << 10,
|
||||
CPUID_FEAT_RCX_FMA = 1 << 12,
|
||||
CPUID_FEAT_RCX_CX16 = 1 << 13,
|
||||
CPUID_FEAT_RCX_ETPRD = 1 << 14,
|
||||
CPUID_FEAT_RCX_PDCM = 1 << 15,
|
||||
CPUID_FEAT_RCX_PCIDE = 1 << 17,
|
||||
CPUID_FEAT_RCX_DCA = 1 << 18,
|
||||
CPUID_FEAT_RCX_SSE4_1 = 1 << 19,
|
||||
CPUID_FEAT_RCX_SSE4_2 = 1 << 20,
|
||||
CPUID_FEAT_RCX_x2APIC = 1 << 21,
|
||||
CPUID_FEAT_RCX_MOVBE = 1 << 22,
|
||||
CPUID_FEAT_RCX_POPCNT = 1 << 23,
|
||||
CPUID_FEAT_RCX_AES = 1 << 25,
|
||||
CPUID_FEAT_RCX_XSAVE = 1 << 26,
|
||||
CPUID_FEAT_RCX_OSXSAVE = 1 << 27,
|
||||
CPUID_FEAT_RCX_AVX = 1 << 28,
|
||||
CPUID_FEAT_RCX_F16C = 1 << 29,
|
||||
CPUID_FEAT_RCX_RDRAND = 1 << 30,
|
||||
|
||||
CPUID_FEAT_RDX_FPU = 1 << 0,
|
||||
CPUID_FEAT_RDX_VME = 1 << 1,
|
||||
CPUID_FEAT_RDX_DE = 1 << 2,
|
||||
CPUID_FEAT_RDX_PSE = 1 << 3,
|
||||
CPUID_FEAT_RDX_TSC = 1 << 4,
|
||||
CPUID_FEAT_RDX_MSR = 1 << 5,
|
||||
CPUID_FEAT_RDX_PAE = 1 << 6,
|
||||
CPUID_FEAT_RDX_MCE = 1 << 7,
|
||||
CPUID_FEAT_RDX_CX8 = 1 << 8,
|
||||
CPUID_FEAT_RDX_APIC = 1 << 9,
|
||||
CPUID_FEAT_RDX_SEP = 1 << 11,
|
||||
CPUID_FEAT_RDX_MTRR = 1 << 12,
|
||||
CPUID_FEAT_RDX_PGE = 1 << 13,
|
||||
CPUID_FEAT_RDX_MCA = 1 << 14,
|
||||
CPUID_FEAT_RDX_CMOV = 1 << 15,
|
||||
CPUID_FEAT_RDX_PAT = 1 << 16,
|
||||
CPUID_FEAT_RDX_PSE36 = 1 << 17,
|
||||
CPUID_FEAT_RDX_PSN = 1 << 18,
|
||||
CPUID_FEAT_RDX_CLF = 1 << 19,
|
||||
CPUID_FEAT_RDX_DTES = 1 << 21,
|
||||
CPUID_FEAT_RDX_ACPI = 1 << 22,
|
||||
CPUID_FEAT_RDX_MMX = 1 << 23,
|
||||
CPUID_FEAT_RDX_FXSR = 1 << 24,
|
||||
CPUID_FEAT_RDX_SSE = 1 << 25,
|
||||
CPUID_FEAT_RDX_SSE2 = 1 << 26,
|
||||
CPUID_FEAT_RDX_SS = 1 << 27,
|
||||
CPUID_FEAT_RDX_HTT = 1 << 28,
|
||||
CPUID_FEAT_RDX_TM1 = 1 << 29,
|
||||
CPUID_FEAT_RDX_IA64 = 1 << 30,
|
||||
CPUID_FEAT_RDX_PBE = 1 << 31,
|
||||
|
||||
// ? Not sure how to get it.
|
||||
CPUID_FEAT_RDX_SMEP = 1 << 7,
|
||||
CPUID_FEAT_RDX_UMIP = 1 << 2,
|
||||
CPUID_FEAT_RDX_SYSCALL = 1 << 11,
|
||||
CPUID_FEAT_XD = 1 << 20,
|
||||
CPUID_FEAT_1GB_PAGE = 1 << 26,
|
||||
CPUID_FEAT_RDTSCP = 1 << 27,
|
||||
CPUID_FEAT_LONG_MODE = 1 << 29,
|
||||
CPUID_FEAT_RDX_SMAP = (1 << 20)
|
||||
};
|
||||
|
||||
enum MSRID
|
||||
{
|
||||
MSR_MONITOR_FILTER_SIZE = 0x6,
|
||||
MSR_TIME_STAMP_COUNTER = 0x10,
|
||||
MSR_PLATFORM_ID = 0x17,
|
||||
MSR_APIC_BASE = 0x1B,
|
||||
MSR_FEATURE_CONTROL = 0x3A,
|
||||
MSR_TSC_ADJUST = 0x3B,
|
||||
MSR_SPEC_CTRL = 0x48,
|
||||
MSR_PRED_CMD = 0x49,
|
||||
MSR_BIOS_UPDT_TRIG = 0x79,
|
||||
MSR_BIOS_SIGN_ID = 0x8B,
|
||||
MSR_SGXLEPUBKEYHASH0 = 0x8C,
|
||||
MSR_SGXLEPUBKEYHASH1 = 0x8D,
|
||||
MSR_SGXLEPUBKEYHASH2 = 0x8E,
|
||||
MSR_SGXLEPUBKEYHASH3 = 0x8F,
|
||||
MSR_SMM_MONITOR_CTL = 0x9B,
|
||||
MSR_SMBASE = 0x9E,
|
||||
MSR_PMC0 = 0xC1,
|
||||
MSR_PMC1 = 0xC2,
|
||||
MSR_PMC2 = 0xC3,
|
||||
MSR_PMC3 = 0xC4,
|
||||
MSR_PMC4 = 0xC5,
|
||||
MSR_PMC5 = 0xC6,
|
||||
MSR_PMC6 = 0xC7,
|
||||
MSR_PMC7 = 0xC8,
|
||||
MSR_UMWAIT_CONTROL = 0xE1,
|
||||
MSR_MPERF = 0xE7,
|
||||
MSR_APERF = 0xE8,
|
||||
MSR_MTRRCAP = 0xFE,
|
||||
MSR_ARCH_CAPABILITIES = 0x10A,
|
||||
MSR_FLUSH_CMD = 0x10B,
|
||||
MSR_SYSENTER_CS = 0x17A,
|
||||
MSR_SYSENTER_ESP = 0x175,
|
||||
MSR_SYSENTER_EIP = 0x176,
|
||||
MSR_MCG_CAP = 0x179,
|
||||
MSR_MCG_STATUS = 0x17A,
|
||||
MSR_MCG_CTL = 0x17B,
|
||||
MSR_PERFEVTSEL0 = 0x186,
|
||||
MSR_PERFEVTSEL1 = 0x187,
|
||||
MSR_PERFEVTSEL2 = 0x188,
|
||||
MSR_PERFEVTSEL3 = 0x189,
|
||||
MSR_PERF_STATUS = 0x198,
|
||||
MSR_PERF_CTL = 0x199,
|
||||
MSR_CLOCK_MODULATION = 0x19A,
|
||||
MSR_THERM_INTERRUPT = 0x19B,
|
||||
MSR_THERM_STATUS = 0x19C,
|
||||
MSR_MISC_ENABLE = 0x1A0,
|
||||
MSR_ENERGY_PERF_BIAS = 0x1B0,
|
||||
MSR_PACKAGE_THERM_STATUS = 0x1B1,
|
||||
MSR_PACKAGE_THERM_INTERRUPT = 0x1B2,
|
||||
MSR_DEBUGCTL = 0x1D9,
|
||||
MSR_SMRR_PHYSBASE = 0x1F2,
|
||||
MSR_SMRR_PHYSMASK = 0x1F3,
|
||||
MSR_PLATFORM_DCA_CAP = 0x1F8,
|
||||
MSR_CPU_DCA_CAP = 0x1F9,
|
||||
MSR_DCA_0_CAP = 0x1FA,
|
||||
MSR_MTRR_PHYSBASE0 = 0x200,
|
||||
MSR_MTRR_PHYSMASK0 = 0x201,
|
||||
MSR_MTRR_PHYSBASE1 = 0x202,
|
||||
MSR_MTRR_PHYSMASK1 = 0x203,
|
||||
MSR_MTRR_PHYSBASE2 = 0x204,
|
||||
MSR_MTRR_PHYSMASK2 = 0x205,
|
||||
MSR_MTRR_PHYSBASE3 = 0x206,
|
||||
MSR_MTRR_PHYSMASK3 = 0x207,
|
||||
MSR_MTRR_PHYSBASE4 = 0x208,
|
||||
MSR_MTRR_PHYSMASK4 = 0x209,
|
||||
MSR_MTRR_PHYSBASE5 = 0x20A,
|
||||
MSR_MTRR_PHYSMASK5 = 0x20B,
|
||||
MSR_MTRR_PHYSBASE6 = 0x20C,
|
||||
MSR_MTRR_PHYSMASK6 = 0x20D,
|
||||
MSR_MTRR_PHYSBASE7 = 0x20E,
|
||||
MSR_MTRR_PHYSMASK7 = 0x20F,
|
||||
MSR_MTRR_PHYSBASE8 = 0x210,
|
||||
MSR_MTRR_PHYSMASK8 = 0x211,
|
||||
MSR_MTRR_PHYSBASE9 = 0x212,
|
||||
MSR_MTRR_PHYSMASK9 = 0x213,
|
||||
MSR_MTRR_FIX64K_00000 = 0x250,
|
||||
MSR_MTRR_FIX16K_80000 = 0x258,
|
||||
MSR_MTRR_FIX16K_A0000 = 0x259,
|
||||
MSR_MTRR_FIX4K_C0000 = 0x268,
|
||||
MSR_MTRR_FIX4K_C8000 = 0x269,
|
||||
MSR_MTRR_FIX4K_D0000 = 0x26A,
|
||||
MSR_MTRR_FIX4K_D8000 = 0x26B,
|
||||
MSR_MTRR_FIX4K_E0000 = 0x26C,
|
||||
MSR_MTRR_FIX4K_E8000 = 0x26D,
|
||||
MSR_MTRR_FIX4K_F0000 = 0x26E,
|
||||
MSR_MTRR_FIX4K_F8000 = 0x26F,
|
||||
MSR_PAT = 0x277,
|
||||
MSR_MC0_CTL2 = 0x280,
|
||||
MSR_MC1_CTL2 = 0x281,
|
||||
MSR_MC2_CTL2 = 0x282,
|
||||
MSR_MC3_CTL2 = 0x283,
|
||||
MSR_MC4_CTL2 = 0x284,
|
||||
MSR_MC5_CTL2 = 0x285,
|
||||
MSR_MC6_CTL2 = 0x286,
|
||||
MSR_MC7_CTL2 = 0x287,
|
||||
MSR_MC8_CTL2 = 0x288,
|
||||
MSR_MC9_CTL2 = 0x289,
|
||||
MSR_MC10_CTL2 = 0x28A,
|
||||
MSR_MC11_CTL2 = 0x28B,
|
||||
MSR_MC12_CTL2 = 0x28C,
|
||||
MSR_MC13_CTL2 = 0x28D,
|
||||
MSR_MC14_CTL2 = 0x28E,
|
||||
MSR_MC15_CTL2 = 0x28F,
|
||||
MSR_MC16_CTL2 = 0x290,
|
||||
MSR_MC17_CTL2 = 0x291,
|
||||
MSR_MC18_CTL2 = 0x292,
|
||||
MSR_MC19_CTL2 = 0x293,
|
||||
MSR_MC20_CTL2 = 0x294,
|
||||
MSR_MC21_CTL2 = 0x295,
|
||||
MSR_MC22_CTL2 = 0x296,
|
||||
MSR_MC23_CTL2 = 0x297,
|
||||
MSR_MC24_CTL2 = 0x298,
|
||||
MSR_MC25_CTL2 = 0x299,
|
||||
MSR_MC26_CTL2 = 0x29A,
|
||||
MSR_MC27_CTL2 = 0x29B,
|
||||
MSR_MC28_CTL2 = 0x29C,
|
||||
MSR_MC29_CTL2 = 0x29D,
|
||||
MSR_MC30_CTL2 = 0x29E,
|
||||
MSR_MC31_CTL2 = 0x29F,
|
||||
MSR_MTRR_DEF_TYPE = 0x2FF,
|
||||
MSR_FIXED_CTR0 = 0x309,
|
||||
MSR_FIXED_CTR1 = 0x30A,
|
||||
MSR_FIXED_CTR2 = 0x30B,
|
||||
MSR_PERF_CAPABILITIES = 0x345,
|
||||
MSR_FIXED_CTR_CTRL = 0x38D,
|
||||
MSR_PERF_GLOBAL_STATUS = 0x38E,
|
||||
MSR_PERF_GLOBAL_CTRL = 0x38F,
|
||||
MSR_PERF_GLOBAL_STATUS_RESET = 0x390,
|
||||
MSR_PERF_GLOBAL_STATUS_SET = 0x391,
|
||||
MSR_PERF_GLOBAL_INUSE = 0x392,
|
||||
MSR_PEBS_ENABLE = 0x3F1,
|
||||
MSR_MC0_CTL = 0x400,
|
||||
MSR_MC0_STATUS = 0x401,
|
||||
MSR_MC0_ADDR = 0x402,
|
||||
MSR_MC0_MISC = 0x403,
|
||||
MSR_MC1_CTL = 0x404,
|
||||
MSR_MC1_STATUS = 0x405,
|
||||
MSR_MC1_ADDR = 0x406,
|
||||
MSR_MC1_MISC = 0x407,
|
||||
MSR_MC2_CTL = 0x408,
|
||||
MSR_MC2_STATUS = 0x409,
|
||||
MSR_MC2_ADDR = 0x40A,
|
||||
MSR_MC2_MISC = 0x40B,
|
||||
MSR_MC3_CTL = 0x40C,
|
||||
MSR_MC3_STATUS = 0x40D,
|
||||
MSR_MC3_ADDR = 0x40E,
|
||||
MSR_MC3_MISC = 0x40F,
|
||||
MSR_MC4_CTL = 0x410,
|
||||
MSR_MC4_STATUS = 0x411,
|
||||
MSR_MC4_ADDR = 0x412,
|
||||
MSR_MC4_MISC = 0x413,
|
||||
MSR_MC5_CTL = 0x414,
|
||||
MSR_MC5_STATUS = 0x415,
|
||||
MSR_MC5_ADDR = 0x416,
|
||||
MSR_MC5_MISC = 0x417,
|
||||
MSR_MC6_CTL = 0x418,
|
||||
MSR_MC6_STATUS = 0x419,
|
||||
MSR_MC6_ADDR = 0x41A,
|
||||
MSR_MC6_MISC = 0x41B,
|
||||
MSR_MC7_CTL = 0x41C,
|
||||
MSR_MC7_STATUS = 0x41D,
|
||||
MSR_MC7_ADDR = 0x41E,
|
||||
MSR_MC7_MISC = 0x41F,
|
||||
MSR_MC8_CTL = 0x420,
|
||||
MSR_MC8_STATUS = 0x421,
|
||||
MSR_MC8_ADDR = 0x422,
|
||||
MSR_MC8_MISC = 0x423,
|
||||
MSR_MC9_CTL = 0x424,
|
||||
MSR_MC9_STATUS = 0x425,
|
||||
MSR_MC9_ADDR = 0x426,
|
||||
MSR_MC9_MISC = 0x427,
|
||||
MSR_MC10_CTL = 0x428,
|
||||
MSR_MC10_STATUS = 0x429,
|
||||
MSR_MC10_ADDR = 0x42A,
|
||||
MSR_MC10_MISC = 0x42B,
|
||||
MSR_MC11_CTL = 0x42C,
|
||||
MSR_MC11_STATUS = 0x42D,
|
||||
MSR_MC11_ADDR = 0x42E,
|
||||
MSR_MC11_MISC = 0x42F,
|
||||
MSR_MC12_CTL = 0x430,
|
||||
MSR_MC12_STATUS = 0x431,
|
||||
MSR_MC12_ADDR = 0x432,
|
||||
MSR_MC12_MISC = 0x433,
|
||||
MSR_MC13_CTL = 0x434,
|
||||
MSR_MC13_STATUS = 0x435,
|
||||
MSR_MC13_ADDR = 0x436,
|
||||
MSR_MC13_MISC = 0x437,
|
||||
MSR_MC14_CTL = 0x438,
|
||||
MSR_MC14_STATUS = 0x439,
|
||||
MSR_MC14_ADDR = 0x43A,
|
||||
MSR_MC14_MISC = 0x43B,
|
||||
MSR_MC15_CTL = 0x43C,
|
||||
MSR_MC15_STATUS = 0x43D,
|
||||
MSR_MC15_ADDR = 0x43E,
|
||||
MSR_MC15_MISC = 0x43F,
|
||||
MSR_MC16_CTL = 0x440,
|
||||
MSR_MC16_STATUS = 0x441,
|
||||
MSR_MC16_ADDR = 0x442,
|
||||
MSR_MC16_MISC = 0x443,
|
||||
MSR_MC17_CTL = 0x444,
|
||||
MSR_MC17_STATUS = 0x445,
|
||||
MSR_MC17_ADDR = 0x446,
|
||||
MSR_MC17_MISC = 0x447,
|
||||
MSR_MC18_CTL = 0x448,
|
||||
MSR_MC18_STATUS = 0x449,
|
||||
MSR_MC18_ADDR = 0x44A,
|
||||
MSR_MC18_MISC = 0x44B,
|
||||
MSR_MC19_CTL = 0x44C,
|
||||
MSR_MC19_STATUS = 0x44D,
|
||||
MSR_MC19_ADDR = 0x44E,
|
||||
MSR_MC19_MISC = 0x44F,
|
||||
MSR_MC20_CTL = 0x450,
|
||||
MSR_MC20_STATUS = 0x451,
|
||||
MSR_MC20_ADDR = 0x452,
|
||||
MSR_MC20_MISC = 0x453,
|
||||
MSR_MC21_CTL = 0x454,
|
||||
MSR_MC21_STATUS = 0x455,
|
||||
MSR_MC21_ADDR = 0x456,
|
||||
MSR_MC21_MISC = 0x457,
|
||||
MSR_MC22_CTL = 0x458,
|
||||
MSR_MC22_STATUS = 0x459,
|
||||
MSR_MC22_ADDR = 0x45A,
|
||||
MSR_MC22_MISC = 0x45B,
|
||||
MSR_MC23_CTL = 0x45C,
|
||||
MSR_MC23_STATUS = 0x45D,
|
||||
MSR_MC23_ADDR = 0x45E,
|
||||
MSR_MC23_MISC = 0x45F,
|
||||
MSR_MC24_CTL = 0x460,
|
||||
MSR_MC24_STATUS = 0x461,
|
||||
MSR_MC24_ADDR = 0x462,
|
||||
MSR_MC24_MISC = 0x463,
|
||||
MSR_MC25_CTL = 0x464,
|
||||
MSR_MC25_STATUS = 0x465,
|
||||
MSR_MC25_ADDR = 0x466,
|
||||
MSR_MC25_MISC = 0x467,
|
||||
MSR_MC26_CTL = 0x468,
|
||||
MSR_MC26_STATUS = 0x469,
|
||||
MSR_MC26_ADDR = 0x46A,
|
||||
MSR_MC26_MISC = 0x46B,
|
||||
MSR_MC27_CTL = 0x46C,
|
||||
MSR_MC27_STATUS = 0x46D,
|
||||
MSR_MC27_ADDR = 0x46E,
|
||||
MSR_MC27_MISC = 0x46F,
|
||||
MSR_MC28_CTL = 0x470,
|
||||
MSR_MC28_STATUS = 0x471,
|
||||
MSR_MC28_ADDR = 0x472,
|
||||
MSR_MC28_MISC = 0x473,
|
||||
MSR_VMX_BASIC = 0x480,
|
||||
MSR_VMX_PINBASED_CTLS = 0x481,
|
||||
MSR_VMX_PROCBASED_CTLS = 0x482,
|
||||
MSR_VMX_EXIT_CTLS = 0x483,
|
||||
MSR_VMX_ENTRY_CTLS = 0x484,
|
||||
MSR_VMX_MISC = 0x485,
|
||||
MSR_VMX_CR0_FIXED0 = 0x486,
|
||||
MSR_VMX_CR0_FIXED1 = 0x487,
|
||||
MSR_VMX_CR4_FIXED0 = 0x488,
|
||||
MSR_VMX_CR4_FIXED1 = 0x489,
|
||||
MSR_VMX_VMCS_ENUM = 0x48A,
|
||||
MSR_VMX_PROCBASED_CTLS2 = 0x48B,
|
||||
MSR_VMX_EPT_VPID_CAP = 0x48C,
|
||||
MSR_VMX_TRUE_PINBASED_CTLS = 0x48D,
|
||||
MSR_VMX_TRUE_PROCBASED_CTLS = 0x48E,
|
||||
MSR_VMX_TRUE_EXIT_CTLS = 0x48F,
|
||||
MSR_VMX_TRUE_ENTRY_CTLS = 0x490,
|
||||
MSR_VMX_VMFUNC = 0x491,
|
||||
MSR_A_PMC0 = 0x4C1,
|
||||
MSR_A_PMC1 = 0x4C2,
|
||||
MSR_A_PMC2 = 0x4C3,
|
||||
MSR_A_PMC3 = 0x4C4,
|
||||
MSR_A_PMC4 = 0x4C5,
|
||||
MSR_A_PMC5 = 0x4C6,
|
||||
MSR_A_PMC6 = 0x4C7,
|
||||
MSR_A_PMC7 = 0x4C8,
|
||||
MSR_MCG_EXT_CTL = 0x4D0,
|
||||
MSR_SGX_SVN_STATUS = 0x500,
|
||||
MSR_RTIT_OUTPUT_BASE = 0x560,
|
||||
MSR_RTIT_OUTPUT_MASK_PTRS = 0x561,
|
||||
MSR_RTIT_CTL = 0x570,
|
||||
MSR_RTIT_STATUS = 0x571,
|
||||
MSR_RTIT_CR3_MATCH = 0x572,
|
||||
MSR_RTIT_ADDR0_A = 0x580,
|
||||
MSR_RTIT_ADDR0_B = 0x581,
|
||||
MSR_RTIT_ADDR1_A = 0x582,
|
||||
MSR_RTIT_ADDR1_B = 0x583,
|
||||
MSR_RTIT_ADDR2_A = 0x584,
|
||||
MSR_RTIT_ADDR2_B = 0x585,
|
||||
MSR_RTIT_ADDR3_A = 0x586,
|
||||
MSR_RTIT_ADDR3_B = 0x587,
|
||||
MSR_DS_AREA = 0x600,
|
||||
MSR_TSC_DEADLINE = 0x6E0,
|
||||
MSR_PM_ENABLE = 0x770,
|
||||
MSR_HWP_CAPABILITIES = 0x771,
|
||||
MSR_HWP_REQUEST_PKG = 0x772,
|
||||
MSR_HWP_INTERRUPT = 0x773,
|
||||
MSR_HWP_REQUEST = 0x774,
|
||||
MSR_HWP_STATUS = 0x777,
|
||||
MSR_X2APIC_APICID = 0x802,
|
||||
MSR_X2APIC_VERSION = 0x803,
|
||||
MSR_X2APIC_TPR = 0x808,
|
||||
MSR_X2APIC_PPR = 0x80A,
|
||||
MSR_X2APIC_EOI = 0x80B,
|
||||
MSR_X2APIC_LDR = 0x80D,
|
||||
MSR_X2APIC_SIVR = 0x80F,
|
||||
MSR_X2APIC_ISR0 = 0x810,
|
||||
MSR_X2APIC_ISR1 = 0x811,
|
||||
MSR_X2APIC_ISR2 = 0x812,
|
||||
MSR_X2APIC_ISR3 = 0x813,
|
||||
MSR_X2APIC_ISR4 = 0x814,
|
||||
MSR_X2APIC_ISR5 = 0x815,
|
||||
MSR_X2APIC_ISR6 = 0x816,
|
||||
MSR_X2APIC_ISR7 = 0x817,
|
||||
MSR_X2APIC_TMR0 = 0x818,
|
||||
MSR_X2APIC_TMR1 = 0x819,
|
||||
MSR_X2APIC_TMR2 = 0x81A,
|
||||
MSR_X2APIC_TMR3 = 0x81B,
|
||||
MSR_X2APIC_TMR4 = 0x81C,
|
||||
MSR_X2APIC_TMR5 = 0x81D,
|
||||
MSR_X2APIC_TMR6 = 0x81E,
|
||||
MSR_X2APIC_TMR7 = 0x81F,
|
||||
MSR_X2APIC_IRR0 = 0x820,
|
||||
MSR_X2APIC_IRR1 = 0x821,
|
||||
MSR_X2APIC_IRR2 = 0x822,
|
||||
MSR_X2APIC_IRR3 = 0x823,
|
||||
MSR_X2APIC_IRR4 = 0x824,
|
||||
MSR_X2APIC_IRR5 = 0x825,
|
||||
MSR_X2APIC_IRR6 = 0x826,
|
||||
MSR_X2APIC_IRR7 = 0x827,
|
||||
MSR_X2APIC_ESR = 0x828,
|
||||
MSR_X2APIC_LVT_CMCI = 0x82F,
|
||||
MSR_X2APIC_ICR = 0x830,
|
||||
MSR_X2APIC_LVT_TIMER = 0x832,
|
||||
MSR_X2APIC_LVT_THERMAL = 0x833,
|
||||
MSR_X2APIC_LVT_PMI = 0x834,
|
||||
MSR_X2APIC_LVT_LINT0 = 0x835,
|
||||
MSR_X2APIC_LVT_LINT1 = 0x836,
|
||||
MSR_X2APIC_LVT_ERROR = 0x837,
|
||||
MSR_X2APIC_INIT_COUNT = 0x838,
|
||||
MSR_X2APIC_CUR_COUNT = 0x839,
|
||||
MSR_X2APIC_DIV_CONF = 0x83E,
|
||||
MSR_X2APIC_SELF_IPI = 0x83F,
|
||||
MSR_DEBUG_INTERFACE = 0xC80,
|
||||
MSR_L3_QOS_CFG = 0xC81,
|
||||
MSR_L2_QOS_CFG = 0xC82,
|
||||
MSR_QM_EVTSEL = 0xC8D,
|
||||
MSR_QM_CTR = 0xC8E,
|
||||
MSR_PQR_ASSOC = 0xC8F,
|
||||
MSR_L3_MASK_0 = 0xC90,
|
||||
MSR_L2_MASK_0 = 0xD10,
|
||||
MSR_BNDCFGS = 0xD90,
|
||||
MSR_XSS = 0xDA0,
|
||||
MSR_PKG_HDC_CTL = 0xDB0,
|
||||
MSR_PM_CTL1 = 0xDB1,
|
||||
MSR_THREAD_STALL = 0xDB2,
|
||||
/** @brief Extended Feature Enable Register (0xc0000080) */
|
||||
MSR_EFER = 0xC0000080,
|
||||
/** @brief legacy SYSCALL (0xC0000081) */
|
||||
MSR_STAR = 0xC0000081,
|
||||
/** @brief 64bit SYSCALL (0xC0000082) */
|
||||
MSR_LSTAR = 0xC0000082,
|
||||
/** @brief compatibility mode SYSCALL (0xC0000083) */
|
||||
MSR_CSTAR = 0xC0000083,
|
||||
/** @brief EFLAGS mask for syscall (0xC0000084) */
|
||||
MSR_SYSCALL_MASK = 0xC0000084,
|
||||
/** @brief 64bit FS base (0xC0000100) */
|
||||
MSR_FS_BASE = 0xC0000100,
|
||||
/** @brief 64bit GS base (0xC0000101) */
|
||||
MSR_GS_BASE = 0xC0000101,
|
||||
/** @brief SwapGS GS shadow (0xC0000102) */
|
||||
MSR_SHADOW_GS_BASE = 0xC0000102,
|
||||
/** @brief Auxiliary TSC (0xC0000103) */
|
||||
MSR_TSC_AUX = 0xC0000103,
|
||||
MSR_CR_PAT = 0x00000277,
|
||||
MSR_CR_PAT_RESET = 0x0007040600070406ULL
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DivideByZero = 0x0,
|
||||
@ -548,6 +998,29 @@ namespace CPU
|
||||
asmv("cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(Function));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t rdmsr(uint32_t msr)
|
||||
{
|
||||
uint32_t Low, High;
|
||||
#if defined(__amd64__)
|
||||
asmv("rdmsr"
|
||||
: "=a"(Low), "=d"(High)
|
||||
: "c"(msr)
|
||||
: "memory");
|
||||
#endif
|
||||
return ((uint64_t)Low) | (((uint64_t)High) << 32);
|
||||
}
|
||||
|
||||
static inline void wrmsr(uint32_t msr, uint64_t Value)
|
||||
{
|
||||
uint32_t Low = Value, High = Value >> 32;
|
||||
#if defined(__amd64__)
|
||||
asmv("wrmsr"
|
||||
:
|
||||
: "c"(msr), "a"(Low), "d"(High)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
35
include/smp.hpp
Normal file
35
include/smp.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __FENNIX_KERNEL_SMP_H__
|
||||
#define __FENNIX_KERNEL_SMP_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define CPU_DATA_CHECKSUM 0xC0FFEE
|
||||
|
||||
struct CPUData
|
||||
{
|
||||
/**
|
||||
* @brief CPU ID.
|
||||
*/
|
||||
uint64_t ID;
|
||||
/**
|
||||
* @brief Local CPU error code.
|
||||
*/
|
||||
long ErrorCode;
|
||||
/**
|
||||
* @brief Is CPU online?
|
||||
*/
|
||||
bool IsActive;
|
||||
/**
|
||||
* @brief Architecture-specific CPU data.
|
||||
*/
|
||||
void *Data;
|
||||
/**
|
||||
* @brief Checksum. Used to verify the integrity of the data. Must be equal to CPU_DATA_CHECKSUM (0xC0FFEE).
|
||||
*/
|
||||
int Checksum;
|
||||
} __attribute__((packed));
|
||||
|
||||
CPUData *GetCurrentCPU();
|
||||
CPUData *GetCPU(uint64_t ID);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_SMP_H__
|
Loading…
x
Reference in New Issue
Block a user