QoL improvements

This commit is contained in:
Alex
2023-03-27 20:11:32 +03:00
parent 3eb6923374
commit 93afcd2210
59 changed files with 612 additions and 424 deletions

View File

@ -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))
;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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?
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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();
};

View File

@ -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();
};