mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-11 15:29:18 +00:00
QoL improvements
This commit is contained in:
@ -124,8 +124,8 @@ namespace ACPI
|
||||
|
||||
if (FADT)
|
||||
{
|
||||
outb(FADT->SMI_CommandPort, FADT->AcpiEnable);
|
||||
while (!(inw(FADT->PM1aControlBlock) & 1))
|
||||
outb(s_cst(uint16_t, FADT->SMI_CommandPort), FADT->AcpiEnable);
|
||||
while (!(inw(s_cst(uint16_t, FADT->PM1aControlBlock)) & 1))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ SafeFunction NIF void init_limine()
|
||||
{
|
||||
struct limine_framebuffer *framebuffer = FrameBufferResponse->framebuffers[i];
|
||||
binfo.Framebuffer[i].BaseAddress = (void *)((uint64_t)framebuffer->address - 0xffff800000000000);
|
||||
binfo.Framebuffer[i].Width = framebuffer->width;
|
||||
binfo.Framebuffer[i].Height = framebuffer->height;
|
||||
binfo.Framebuffer[i].Pitch = framebuffer->pitch;
|
||||
binfo.Framebuffer[i].Width = (uint32_t)framebuffer->width;
|
||||
binfo.Framebuffer[i].Height = (uint32_t)framebuffer->height;
|
||||
binfo.Framebuffer[i].Pitch = (uint32_t)framebuffer->pitch;
|
||||
binfo.Framebuffer[i].BitsPerPixel = framebuffer->bpp;
|
||||
binfo.Framebuffer[i].MemoryModel = framebuffer->memory_model;
|
||||
binfo.Framebuffer[i].RedMaskSize = framebuffer->red_mask_size;
|
||||
@ -237,7 +237,7 @@ SafeFunction NIF void init_limine()
|
||||
|
||||
binfo.Kernel.PhysicalBase = (void *)KernelAddressResponse->physical_base;
|
||||
binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base;
|
||||
binfo.Kernel.FileBase = KernelFileResponse->kernel_file->address - 0xffff800000000000;
|
||||
binfo.Kernel.FileBase = (void *)((uint64_t)KernelFileResponse->kernel_file->address - 0xffff800000000000);
|
||||
strncpy(binfo.Kernel.CommandLine,
|
||||
KernelFileResponse->kernel_file->cmdline,
|
||||
strlen(KernelFileResponse->kernel_file->cmdline) + 1);
|
||||
|
@ -39,13 +39,13 @@ namespace ACPI
|
||||
uint16_t a = 0, b = 0;
|
||||
if (acpi->FADT->PM1aEventBlock)
|
||||
{
|
||||
a = inw(acpi->FADT->PM1aEventBlock);
|
||||
outw(acpi->FADT->PM1aEventBlock, a);
|
||||
a = inw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock));
|
||||
outw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock), a);
|
||||
}
|
||||
if (acpi->FADT->PM1bEventBlock)
|
||||
{
|
||||
b = inw(acpi->FADT->PM1bEventBlock);
|
||||
outw(acpi->FADT->PM1bEventBlock, b);
|
||||
b = inw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock));
|
||||
outw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock), b);
|
||||
}
|
||||
Event = a | b;
|
||||
}
|
||||
@ -99,12 +99,24 @@ namespace ACPI
|
||||
trace("Shutting down...");
|
||||
if (SCI_EN == 1)
|
||||
{
|
||||
outw(acpi->FADT->PM1aControlBlock, (inw(acpi->FADT->PM1aControlBlock) & 0xE3FF) | ((SLP_TYPa << 10) | ACPI_SLEEP));
|
||||
outw(s_cst(uint16_t, acpi->FADT->PM1aControlBlock),
|
||||
s_cst(uint16_t,
|
||||
(inw(s_cst(uint16_t,
|
||||
acpi->FADT->PM1aControlBlock)) &
|
||||
0xE3FF) |
|
||||
((SLP_TYPa << 10) | ACPI_SLEEP)));
|
||||
|
||||
if (acpi->FADT->PM1bControlBlock)
|
||||
outw(acpi->FADT->PM1bControlBlock, (inw(acpi->FADT->PM1bControlBlock) & 0xE3FF) | ((SLP_TYPb << 10) | ACPI_SLEEP));
|
||||
outw(PM1a_CNT, SLP_TYPa | SLP_EN);
|
||||
outw(s_cst(uint16_t, acpi->FADT->PM1bControlBlock),
|
||||
s_cst(uint16_t,
|
||||
(inw(
|
||||
s_cst(uint16_t, acpi->FADT->PM1bControlBlock)) &
|
||||
0xE3FF) |
|
||||
((SLP_TYPb << 10) | ACPI_SLEEP)));
|
||||
|
||||
outw(s_cst(uint16_t, PM1a_CNT), SLP_TYPa | SLP_EN);
|
||||
if (PM1b_CNT)
|
||||
outw(PM1b_CNT, SLP_TYPb | SLP_EN);
|
||||
outw(s_cst(uint16_t, PM1b_CNT), SLP_TYPb | SLP_EN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,12 +126,17 @@ namespace ACPI
|
||||
switch (acpi->FADT->ResetReg.AddressSpace)
|
||||
{
|
||||
case ACPI_GAS_MMIO:
|
||||
{
|
||||
*(uint8_t *)(acpi->FADT->ResetReg.Address) = acpi->FADT->ResetValue;
|
||||
break;
|
||||
}
|
||||
case ACPI_GAS_IO:
|
||||
outb(acpi->FADT->ResetReg.Address, acpi->FADT->ResetValue);
|
||||
{
|
||||
outb(s_cst(uint16_t, acpi->FADT->ResetReg.Address), acpi->FADT->ResetValue);
|
||||
break;
|
||||
}
|
||||
case ACPI_GAS_PCI:
|
||||
{
|
||||
fixme("ACPI_GAS_PCI not supported.");
|
||||
/*
|
||||
seg - 0
|
||||
@ -131,6 +148,12 @@ namespace ACPI
|
||||
*/
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
error("Unknown reset register address space: %d", acpi->FADT->ResetReg.AddressSpace);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DSDT::DSDT(ACPI *acpi) : Interrupts::Handler(acpi->FADT->SCI_Interrupt)
|
||||
@ -157,11 +180,11 @@ namespace ACPI
|
||||
S5Address += ((*S5Address & 0xC0) >> 6) + 2;
|
||||
if (*S5Address == 0x0A)
|
||||
S5Address++;
|
||||
SLP_TYPa = *(S5Address) << 10;
|
||||
SLP_TYPa = s_cst(uint16_t, *(S5Address) << 10);
|
||||
S5Address++;
|
||||
if (*S5Address == 0x0A)
|
||||
S5Address++;
|
||||
SLP_TYPb = *(S5Address) << 10;
|
||||
SLP_TYPb = s_cst(uint16_t, *(S5Address) << 10);
|
||||
SMI_CMD = acpi->FADT->SMI_CommandPort;
|
||||
ACPI_ENABLE = acpi->FADT->AcpiEnable;
|
||||
ACPI_DISABLE = acpi->FADT->AcpiDisable;
|
||||
@ -175,8 +198,8 @@ namespace ACPI
|
||||
|
||||
uint16_t value = ACPI_POWER_BUTTON | ACPI_SLEEP_BUTTON | ACPI_WAKE;
|
||||
{
|
||||
uint16_t a = acpi->FADT->PM1aEventBlock + (acpi->FADT->PM1EventLength / 2);
|
||||
uint16_t b = acpi->FADT->PM1bEventBlock + (acpi->FADT->PM1EventLength / 2);
|
||||
uint16_t a = s_cst(uint16_t, acpi->FADT->PM1aEventBlock + (acpi->FADT->PM1EventLength / 2));
|
||||
uint16_t b = s_cst(uint16_t, acpi->FADT->PM1bEventBlock + (acpi->FADT->PM1EventLength / 2));
|
||||
debug("SCI Event: %#llx [a:%#x b:%#x]", value, a, b);
|
||||
if (acpi->FADT->PM1aEventBlock)
|
||||
outw(a, value);
|
||||
@ -188,13 +211,13 @@ namespace ACPI
|
||||
uint16_t a = 0, b = 0;
|
||||
if (acpi->FADT->PM1aEventBlock)
|
||||
{
|
||||
a = inw(acpi->FADT->PM1aEventBlock);
|
||||
outw(acpi->FADT->PM1aEventBlock, a);
|
||||
a = inw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock));
|
||||
outw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock), a);
|
||||
}
|
||||
if (acpi->FADT->PM1bEventBlock)
|
||||
{
|
||||
b = inw(acpi->FADT->PM1bEventBlock);
|
||||
outw(acpi->FADT->PM1bEventBlock, b);
|
||||
b = inw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock));
|
||||
outw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock), b);
|
||||
}
|
||||
}
|
||||
((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, acpi->FADT->SCI_Interrupt, 1);
|
||||
|
@ -56,6 +56,11 @@ namespace ACPI
|
||||
KPrint("APIC found at \e8888FF%#lx\eCCCCCC", LAPICAddress);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
KPrint("Unknown MADT entry \e8888FF%#lx\eCCCCCC", *(ptr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
Memory::Virtual(KernelPageTable).Map((void *)LAPICAddress, (void *)LAPICAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD); // I should map more than one page?
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ namespace APIC
|
||||
if (x2APICSupported)
|
||||
{
|
||||
if (Register != APIC_ICRHI)
|
||||
return rdmsr((Register >> 4) + 0x800);
|
||||
return s_cst(uint32_t, rdmsr((Register >> 4) + 0x800));
|
||||
else
|
||||
return rdmsr(0x30 + 0x800);
|
||||
return s_cst(uint32_t, rdmsr(0x30 + 0x800));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -107,7 +107,7 @@ namespace APIC
|
||||
} while (icr.DeliveryStatus != Idle);
|
||||
}
|
||||
|
||||
void APIC::IPI(uint8_t CPU, InterruptCommandRegisterLow icr)
|
||||
void APIC::IPI(int CPU, InterruptCommandRegisterLow icr)
|
||||
{
|
||||
SmartCriticalSection(APICLock);
|
||||
if (x2APICSupported)
|
||||
@ -118,12 +118,12 @@ namespace APIC
|
||||
else
|
||||
{
|
||||
this->Write(APIC_ICRHI, (CPU << 24));
|
||||
this->Write(APIC_ICRLO, icr.raw);
|
||||
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
|
||||
this->WaitForIPI();
|
||||
}
|
||||
}
|
||||
|
||||
void APIC::SendInitIPI(uint8_t CPU)
|
||||
void APIC::SendInitIPI(int CPU)
|
||||
{
|
||||
SmartCriticalSection(APICLock);
|
||||
if (x2APICSupported)
|
||||
@ -137,12 +137,12 @@ namespace APIC
|
||||
icr.DeliveryMode = INIT;
|
||||
icr.Level = Assert;
|
||||
this->Write(APIC_ICRHI, (CPU << 24));
|
||||
this->Write(APIC_ICRLO, icr.raw);
|
||||
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
|
||||
this->WaitForIPI();
|
||||
}
|
||||
}
|
||||
|
||||
void APIC::SendStartupIPI(uint8_t CPU, uint64_t StartupAddress)
|
||||
void APIC::SendStartupIPI(int CPU, uint64_t StartupAddress)
|
||||
{
|
||||
SmartCriticalSection(APICLock);
|
||||
if (x2APICSupported)
|
||||
@ -153,11 +153,11 @@ namespace APIC
|
||||
else
|
||||
{
|
||||
InterruptCommandRegisterLow icr = {.raw = 0};
|
||||
icr.Vector = StartupAddress >> 12;
|
||||
icr.Vector = s_cst(uint8_t, StartupAddress >> 12);
|
||||
icr.DeliveryMode = Startup;
|
||||
icr.Level = Assert;
|
||||
this->Write(APIC_ICRHI, (CPU << 24));
|
||||
this->Write(APIC_ICRLO, icr.raw);
|
||||
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
|
||||
this->WaitForIPI();
|
||||
}
|
||||
}
|
||||
@ -168,14 +168,14 @@ namespace APIC
|
||||
return ((IOAPICVersion *)&TableAddress)->MaximumRedirectionEntry;
|
||||
}
|
||||
|
||||
void APIC::RawRedirectIRQ(uint8_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status)
|
||||
void APIC::RawRedirectIRQ(uint16_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)
|
||||
if (((ACPI::MADT *)PowerManager->GetMADT())->ioapic[i]->GSIBase + IOGetMaxRedirect(s_cst(uint32_t, i)) > GSI)
|
||||
{
|
||||
IOAPICTarget = i;
|
||||
break;
|
||||
@ -205,7 +205,7 @@ namespace APIC
|
||||
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)
|
||||
void APIC::RedirectIRQ(int CPU, uint16_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)
|
||||
@ -224,7 +224,7 @@ namespace APIC
|
||||
{
|
||||
SmartCriticalSection(APICLock);
|
||||
debug("Redirecting IRQs...");
|
||||
for (int i = 0; i < 16; i++)
|
||||
for (uint8_t i = 0; i < 16; i++)
|
||||
this->RedirectIRQ(CPU, i, 1);
|
||||
debug("Redirecting IRQs completed.");
|
||||
}
|
||||
@ -314,7 +314,7 @@ namespace APIC
|
||||
Spurious Spurious = {.raw = this->Read(APIC_SVR)};
|
||||
Spurious.Vector = IRQ223; // TODO: Should I map the IRQ to something?
|
||||
Spurious.Software = 1;
|
||||
this->Write(APIC_SVR, Spurious.raw);
|
||||
this->Write(APIC_SVR, s_cst(uint32_t, Spurious.raw));
|
||||
|
||||
static int once = 0;
|
||||
if (!once++)
|
||||
@ -337,14 +337,14 @@ namespace APIC
|
||||
{
|
||||
SmartCriticalSection(APICLock);
|
||||
LVTTimer timer = {.raw = 0};
|
||||
timer.Vector = Vector;
|
||||
timer.Vector = s_cst(uint8_t, Vector);
|
||||
timer.TimerMode = 0;
|
||||
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
|
||||
this->lapic->Write(APIC_TDCR, DivideBy128);
|
||||
else
|
||||
this->lapic->Write(APIC_TDCR, DivideBy16);
|
||||
this->lapic->Write(APIC_TICR, Ticks * Miliseconds);
|
||||
this->lapic->Write(APIC_TIMER, timer.raw);
|
||||
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks * Miliseconds));
|
||||
this->lapic->Write(APIC_TIMER, s_cst(uint32_t, timer.raw));
|
||||
}
|
||||
|
||||
Timer::Timer(APIC *apic) : Interrupts::Handler(0) /* IRQ0 */
|
||||
@ -372,8 +372,8 @@ namespace APIC
|
||||
|
||||
// Initialize APIC timer
|
||||
this->lapic->Write(APIC_TDCR, Divider);
|
||||
this->lapic->Write(APIC_TICR, Ticks);
|
||||
this->lapic->Write(APIC_TIMER, timer.raw);
|
||||
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks));
|
||||
this->lapic->Write(APIC_TIMER, s_cst(uint32_t, timer.raw));
|
||||
trace("%d APIC Timer %d ticks in.", GetCurrentCPU()->ID, Ticks);
|
||||
KPrint("APIC Timer: \e8888FF%ld\eCCCCCC ticks.", Ticks);
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ namespace GlobalDescriptorTable
|
||||
gdt[Core].Entries->TaskStateSegment.BaseLow = Base & 0xFFFF;
|
||||
gdt[Core].Entries->TaskStateSegment.BaseMiddle = (Base >> 16) & 0xFF;
|
||||
gdt[Core].Entries->TaskStateSegment.BaseHigh = (Base >> 24) & 0xFF;
|
||||
gdt[Core].Entries->TaskStateSegment.BaseUpper = (Base >> 32) & 0xFFFFFFFF;
|
||||
gdt[Core].Entries->TaskStateSegment.BaseUpper = s_cst(uint32_t, (Base >> 32) & 0xFFFFFFFF);
|
||||
gdt[Core].Entries->TaskStateSegment.Flags = {.A = 1, .RW = 0, .DC = 0, .E = 1, .S = 0, .DPL = 0, .P = 1};
|
||||
gdt[Core].Entries->TaskStateSegment.Granularity = (0 << 4) | ((Limit >> 16) & 0xF);
|
||||
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
#include "gdt.hpp"
|
||||
|
||||
/* conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘unsigned char:2’ may change value */
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
|
||||
extern "C" void MainInterruptHandler(void *Data);
|
||||
extern "C" void ExceptionHandler(void *Data);
|
||||
|
||||
@ -26,8 +29,8 @@ namespace InterruptDescriptorTable
|
||||
InterruptDescriptorTableFlags Ring,
|
||||
uint16_t SegmentSelector)
|
||||
{
|
||||
Entries[Index].BaseLow = (uint16_t)((uint64_t)Base & 0xFFFF);
|
||||
Entries[Index].BaseHigh = (uint64_t)((uint64_t)Base >> 16 /* & 0xFFFF */);
|
||||
Entries[Index].BaseLow = s_cst(uint16_t, ((uint64_t)Base & 0xFFFF));
|
||||
Entries[Index].BaseHigh = s_cst(uint64_t, ((uint64_t)Base >> 16 /* & 0xFFFF */));
|
||||
Entries[Index].SegmentSelector = SegmentSelector;
|
||||
Entries[Index].Flags = Attribute;
|
||||
Entries[Index].Reserved1 = 0;
|
||||
|
@ -50,7 +50,7 @@ SafeFunction CPUData *GetCurrentCPU()
|
||||
extern "C" void StartCPU()
|
||||
{
|
||||
CPU::Interrupts(CPU::Disable);
|
||||
uint64_t CoreID = (int)*reinterpret_cast<int *>(CORE);
|
||||
int CoreID = (int)*reinterpret_cast<int *>(CORE);
|
||||
CPU::InitializeFeatures(CoreID);
|
||||
// Initialize GDT and IDT
|
||||
Interrupts::Initialize(CoreID);
|
||||
@ -96,14 +96,14 @@ namespace SMP
|
||||
|
||||
memcpy((void *)TRAMPOLINE_START, &_trampoline_start, TrampolineLength);
|
||||
|
||||
POKE(volatile uint64_t, PAGE_TABLE) = (uint64_t)KernelPageTable;
|
||||
POKE(volatile uint64_t, STACK) = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
|
||||
POKE(volatile uint64_t, CORE) = i;
|
||||
VPOKE(uint64_t, PAGE_TABLE) = (uint64_t)KernelPageTable;
|
||||
VPOKE(uint64_t, STACK) = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
|
||||
VPOKE(int, CORE) = i;
|
||||
|
||||
asmv("sgdt [0x580]\n"
|
||||
"sidt [0x590]\n");
|
||||
|
||||
POKE(volatile uint64_t, START_ADDR) = (uintptr_t)&StartCPU;
|
||||
VPOKE(uint64_t, START_ADDR) = (uintptr_t)&StartCPU;
|
||||
|
||||
((APIC::APIC *)Interrupts::apic[0])->SendInitIPI(((ACPI::MADT *)madt)->lapic[i]->APICId);
|
||||
((APIC::APIC *)Interrupts::apic[0])->SendStartupIPI(((ACPI::MADT *)madt)->lapic[i]->APICId, TRAMPOLINE_START);
|
||||
|
@ -309,12 +309,12 @@ namespace APIC
|
||||
void EOI();
|
||||
void RedirectIRQs(int CPU = 0);
|
||||
void WaitForIPI();
|
||||
void IPI(uint8_t CPU, InterruptCommandRegisterLow icr);
|
||||
void SendInitIPI(uint8_t CPU);
|
||||
void SendStartupIPI(uint8_t CPU, uint64_t StartupAddress);
|
||||
void IPI(int CPU, InterruptCommandRegisterLow icr);
|
||||
void SendInitIPI(int CPU);
|
||||
void SendStartupIPI(int CPU, uint64_t StartupAddress);
|
||||
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);
|
||||
void RawRedirectIRQ(uint16_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status);
|
||||
void RedirectIRQ(int CPU, uint16_t IRQ, int Status);
|
||||
APIC(int Core);
|
||||
~APIC();
|
||||
};
|
||||
|
@ -314,7 +314,7 @@ namespace APIC
|
||||
void SendStartupIPI(uint8_t CPU, uint64_t StartupAddress);
|
||||
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);
|
||||
void RedirectIRQ(int CPU, uint16_t IRQ, int Status);
|
||||
APIC(int Core);
|
||||
~APIC();
|
||||
};
|
||||
|
Reference in New Issue
Block a user