mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-11 07:19:20 +00:00
Update kernel
This commit is contained in:
132
core/dsdt.cpp
132
core/dsdt.cpp
@ -54,11 +54,7 @@ namespace ACPI
|
||||
#define ACPI_GAS_IO 1
|
||||
#define ACPI_GAS_PCI 2
|
||||
|
||||
#if defined(a64)
|
||||
void DSDT::OnInterruptReceived(CPU::x64::TrapFrame *)
|
||||
#elif defined(a32)
|
||||
void DSDT::OnInterruptReceived(CPU::x32::TrapFrame *)
|
||||
#endif
|
||||
void DSDT::OnInterruptReceived(CPU::TrapFrame *)
|
||||
{
|
||||
debug("SCI Handle Triggered");
|
||||
uint16_t Event = 0;
|
||||
@ -77,7 +73,27 @@ namespace ACPI
|
||||
Event = a | b;
|
||||
}
|
||||
|
||||
debug("SCI Event: %#lx", Event);
|
||||
#ifdef DEBUG
|
||||
char dbgEvStr[128];
|
||||
dbgEvStr[0] = '\0';
|
||||
if (Event & ACPI_BUSMASTER)
|
||||
strcat(dbgEvStr, "BUSMASTER ");
|
||||
if (Event & ACPI_GLOBAL)
|
||||
strcat(dbgEvStr, "GLOBAL ");
|
||||
if (Event & ACPI_POWER_BUTTON)
|
||||
strcat(dbgEvStr, "POWER_BUTTON ");
|
||||
if (Event & ACPI_SLEEP_BUTTON)
|
||||
strcat(dbgEvStr, "SLEEP_BUTTON ");
|
||||
if (Event & ACPI_RTC_ALARM)
|
||||
strcat(dbgEvStr, "RTC_ALARM ");
|
||||
if (Event & ACPI_PCIE_WAKE)
|
||||
strcat(dbgEvStr, "PCIE_WAKE ");
|
||||
if (Event & ACPI_WAKE)
|
||||
strcat(dbgEvStr, "WAKE ");
|
||||
if (Event & ACPI_TIMER)
|
||||
strcat(dbgEvStr, "ACPI_TIMER ");
|
||||
KPrint("SCI Event: %s", dbgEvStr);
|
||||
#endif
|
||||
if (Event & ACPI_BUSMASTER)
|
||||
{
|
||||
fixme("ACPI Busmaster");
|
||||
@ -88,12 +104,13 @@ namespace ACPI
|
||||
}
|
||||
else if (Event & ACPI_POWER_BUTTON)
|
||||
{
|
||||
if (TaskManager && !TaskManager->IsPanic())
|
||||
Tasking::PCB *pcb = thisProcess;
|
||||
if (pcb && !pcb->GetContext()->IsPanic())
|
||||
{
|
||||
TaskManager->CreateThread(TaskManager->CreateProcess(nullptr,
|
||||
"Shutdown",
|
||||
Tasking::TaskExecutionMode::Kernel),
|
||||
Tasking::IP(KST_Shutdown));
|
||||
Tasking::Task *ctx = pcb->GetContext();
|
||||
ctx->CreateThread(ctx->GetKernelProcess(),
|
||||
Tasking::IP(KST_Shutdown))
|
||||
->Rename("Shutdown");
|
||||
}
|
||||
else
|
||||
KernelShutdownThread(false);
|
||||
@ -120,35 +137,56 @@ namespace ACPI
|
||||
}
|
||||
else
|
||||
{
|
||||
error("ACPI unknown event %#lx on CPU %d", Event, GetCurrentCPU()->ID);
|
||||
CPU::Stop();
|
||||
error("ACPI unknown event %#lx on CPU %d",
|
||||
Event, GetCurrentCPU()->ID);
|
||||
KPrint("ACPI unknown event %#lx on CPU %d",
|
||||
Event, GetCurrentCPU()->ID);
|
||||
}
|
||||
}
|
||||
|
||||
void DSDT::Shutdown()
|
||||
{
|
||||
trace("Shutting down...");
|
||||
if (SCI_EN == 1)
|
||||
if (SCI_EN != 1)
|
||||
{
|
||||
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(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(s_cst(uint16_t, PM1b_CNT), SLP_TYPb | SLP_EN);
|
||||
error("ACPI Shutdown not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inw(s_cst(uint16_t, PM1a_CNT) & SCI_EN) == 0)
|
||||
{
|
||||
KPrint("ACPI was disabled, enabling...");
|
||||
if (SMI_CMD == 0 || ACPI_ENABLE == 0)
|
||||
{
|
||||
error("ACPI Shutdown not supported");
|
||||
KPrint("ACPI Shutdown not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
outb(s_cst(uint16_t, SMI_CMD), ACPI_ENABLE);
|
||||
|
||||
uint16_t Timeout = 3000;
|
||||
while ((inw(s_cst(uint16_t, PM1a_CNT)) & SCI_EN) == 0 && Timeout-- > 0)
|
||||
;
|
||||
|
||||
if (Timeout == 0)
|
||||
{
|
||||
error("ACPI Shutdown not supported");
|
||||
KPrint("ACPI Shutdown not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PM1b_CNT)
|
||||
{
|
||||
Timeout = 3000;
|
||||
while ((inw(s_cst(uint16_t, PM1b_CNT)) & SCI_EN) == 0 && Timeout-- > 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
outw(s_cst(uint16_t, PM1a_CNT), SLP_TYPa | SLP_EN);
|
||||
if (PM1b_CNT)
|
||||
outw(s_cst(uint16_t, PM1b_CNT), SLP_TYPb | SLP_EN);
|
||||
}
|
||||
|
||||
void DSDT::Reboot()
|
||||
@ -187,21 +225,24 @@ namespace ACPI
|
||||
}
|
||||
}
|
||||
|
||||
DSDT::DSDT(ACPI *acpi) : Interrupts::Handler(acpi->FADT->SCI_Interrupt)
|
||||
DSDT::DSDT(ACPI *acpi) : Interrupts::Handler(acpi->FADT->SCI_Interrupt, true)
|
||||
{
|
||||
/* TODO: AML Interpreter */
|
||||
|
||||
this->acpi = acpi;
|
||||
uint64_t Address = ((IsCanonical(acpi->FADT->X_Dsdt) && acpi->XSDTSupported) ? acpi->FADT->X_Dsdt : acpi->FADT->Dsdt);
|
||||
uint8_t *S5Address = (uint8_t *)(Address) + 36;
|
||||
ACPI::ACPI::ACPIHeader *Header = (ACPI::ACPI::ACPIHeader *)Address;
|
||||
if (!Memory::Virtual().Check(Header))
|
||||
Memory::Virtual vmm;
|
||||
if (!vmm.Check(Header))
|
||||
{
|
||||
warn("DSDT is not mapped");
|
||||
debug("DSDT: %#lx", Address);
|
||||
Memory::Virtual().Map(Header, Header, Memory::RW);
|
||||
vmm.Map(Header, Header, Memory::RW);
|
||||
}
|
||||
|
||||
size_t Length = Header->Length;
|
||||
Memory::Virtual().Map(Header, Header, Length, Memory::RW);
|
||||
vmm.Map(Header, Header, Length, Memory::RW);
|
||||
|
||||
while (Length-- > 0)
|
||||
{
|
||||
@ -212,20 +253,27 @@ namespace ACPI
|
||||
|
||||
if (Length <= 0)
|
||||
{
|
||||
warn("_S5 not present in ACPI");
|
||||
warn("_S5_ not present in ACPI");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*(S5Address - 1) == 0x08 || (*(S5Address - 2) == 0x08 && *(S5Address - 1) == '\\')) && *(S5Address + 4) == 0x12)
|
||||
if ((*(S5Address - 1) == 0x08 ||
|
||||
(*(S5Address - 2) == 0x08 &&
|
||||
*(S5Address - 1) == '\\')) &&
|
||||
*(S5Address + 4) == 0x12)
|
||||
{
|
||||
S5Address += 5;
|
||||
S5Address += ((*S5Address & 0xC0) >> 6) + 2;
|
||||
|
||||
if (*S5Address == 0x0A)
|
||||
S5Address++;
|
||||
|
||||
SLP_TYPa = s_cst(uint16_t, *(S5Address) << 10);
|
||||
S5Address++;
|
||||
|
||||
if (*S5Address == 0x0A)
|
||||
S5Address++;
|
||||
|
||||
SLP_TYPb = s_cst(uint16_t, *(S5Address) << 10);
|
||||
SMI_CMD = acpi->FADT->SMI_CommandPort;
|
||||
ACPI_ENABLE = acpi->FADT->AcpiEnable;
|
||||
@ -235,11 +283,13 @@ namespace ACPI
|
||||
PM1_CNT_LEN = acpi->FADT->PM1ControlLength;
|
||||
SLP_EN = 1 << 13;
|
||||
SCI_EN = 1;
|
||||
trace("ACPI Shutdown is supported");
|
||||
KPrint("ACPI Shutdown is supported");
|
||||
ACPIShutdownSupported = true;
|
||||
|
||||
{
|
||||
uint16_t value = ACPI_POWER_BUTTON | ACPI_SLEEP_BUTTON | ACPI_WAKE;
|
||||
const uint16_t value = /*ACPI_TIMER |*/ ACPI_BUSMASTER | ACPI_GLOBAL |
|
||||
ACPI_POWER_BUTTON | ACPI_SLEEP_BUTTON | ACPI_RTC_ALARM |
|
||||
ACPI_PCIE_WAKE | ACPI_WAKE;
|
||||
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: %#x [a:%#x b:%#x]", value, a, b);
|
||||
@ -266,7 +316,7 @@ namespace ACPI
|
||||
((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, uint8_t(acpi->FADT->SCI_Interrupt), 1);
|
||||
return;
|
||||
}
|
||||
warn("Failed to parse _S5 in ACPI");
|
||||
warn("Failed to parse _S5_ in ACPI");
|
||||
SCI_EN = 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user