diff --git a/Architecture/i386/acpi.hpp b/Architecture/i386/acpi.hpp new file mode 100644 index 0000000..1a71f71 --- /dev/null +++ b/Architecture/i386/acpi.hpp @@ -0,0 +1,294 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifndef __FENNIX_KERNEL_ACPI_H__ +#define __FENNIX_KERNEL_ACPI_H__ + +#include + +#include +#include +#include +#include + +namespace ACPI +{ + class ACPI + { + public: + struct ACPIHeader + { + unsigned char Signature[4]; + uint32_t Length; + uint8_t Revision; + uint8_t Checksum; + uint8_t OEMID[6]; + uint8_t OEMTableID[8]; + uint32_t OEMRevision; + uint32_t CreatorID; + uint32_t CreatorRevision; + } __packed; + + struct GenericAddressStructure + { + uint8_t AddressSpace; + uint8_t BitWidth; + uint8_t BitOffset; + uint8_t AccessSize; + uint64_t Address; + } __packed; + + struct MCFGHeader + { + struct ACPIHeader Header; + uint64_t Reserved; + } __packed; + + struct HPETHeader + { + ACPIHeader Header; + uint8_t HardwareRevID; + uint8_t ComparatorCount : 5; + uint8_t CounterSize : 1; + uint8_t Reserved : 1; + uint8_t LegacyReplacement : 1; + uint16_t PCIVendorID; + struct GenericAddressStructure Address; + uint8_t HPETNumber; + uint16_t MinimumTick; + uint8_t PageProtection; + } __packed; + + struct FADTHeader + { + ACPIHeader Header; + uint32_t FirmwareCtrl; + uint32_t Dsdt; + uint8_t Reserved; + uint8_t PreferredPowerManagementProfile; + uint16_t SCI_Interrupt; + uint32_t SMI_CommandPort; + uint8_t AcpiEnable; + uint8_t AcpiDisable; + uint8_t S4BIOS_REQ; + uint8_t PSTATE_Control; + uint32_t PM1aEventBlock; + uint32_t PM1bEventBlock; + uint32_t PM1aControlBlock; + uint32_t PM1bControlBlock; + uint32_t PM2ControlBlock; + uint32_t PMTimerBlock; + uint32_t GPE0Block; + uint32_t GPE1Block; + uint8_t PM1EventLength; + uint8_t PM1ControlLength; + uint8_t PM2ControlLength; + uint8_t PMTimerLength; + uint8_t GPE0Length; + uint8_t GPE1Length; + uint8_t GPE1Base; + uint8_t CStateControl; + uint16_t WorstC2Latency; + uint16_t WorstC3Latency; + uint16_t FlushSize; + uint16_t FlushStride; + uint8_t DutyOffset; + uint8_t DutyWidth; + uint8_t DayAlarm; + uint8_t MonthAlarm; + uint8_t Century; + uint16_t BootArchitectureFlags; + uint8_t Reserved2; + uint32_t Flags; + struct GenericAddressStructure ResetReg; + uint8_t ResetValue; + uint8_t Reserved3[3]; + uint64_t X_FirmwareControl; + uint64_t X_Dsdt; + struct GenericAddressStructure X_PM1aEventBlock; + struct GenericAddressStructure X_PM1bEventBlock; + struct GenericAddressStructure X_PM1aControlBlock; + struct GenericAddressStructure X_PM1bControlBlock; + struct GenericAddressStructure X_PM2ControlBlock; + struct GenericAddressStructure X_PMTimerBlock; + struct GenericAddressStructure X_GPE0Block; + struct GenericAddressStructure X_GPE1Block; + } __packed; + + struct BGRTHeader + { + ACPIHeader Header; + uint16_t Version; + uint8_t Status; + uint8_t ImageType; + uint64_t ImageAddress; + uint32_t ImageOffsetX; + uint32_t ImageOffsetY; + }; + + struct SRATHeader + { + ACPIHeader Header; + uint32_t TableRevision; // Must be value 1 + uint64_t Reserved; // Reserved, must be zero + }; + + struct TPM2Header + { + ACPIHeader Header; + uint32_t Flags; + uint64_t ControlAddress; + uint32_t StartMethod; + }; + + struct TCPAHeader + { + ACPIHeader Header; + uint16_t Reserved; + uint32_t MaxLogLength; + uint64_t LogAddress; + }; + + struct WAETHeader + { + ACPIHeader Header; + uint32_t Flags; + }; + + struct HESTHeader + { + ACPIHeader Header; + uint32_t ErrorSourceCount; + }; + + struct MADTHeader + { + ACPIHeader Header; + uint32_t LocalControllerAddress; + uint32_t Flags; + char Entries[]; + } __packed; + + ACPIHeader *XSDT = nullptr; + MCFGHeader *MCFG = nullptr; + HPETHeader *HPET = nullptr; + FADTHeader *FADT = nullptr; + BGRTHeader *BGRT = nullptr; + SRATHeader *SRAT = nullptr; + TPM2Header *TPM2 = nullptr; + TCPAHeader *TCPA = nullptr; + WAETHeader *WAET = nullptr; + MADTHeader *MADT = nullptr; + HESTHeader *HEST = nullptr; + bool XSDTSupported = false; + + void *FindTable(ACPIHeader *ACPIHeader, char *Signature); + void SearchTables(ACPIHeader *Header); + ACPI(); + ~ACPI(); + }; + + class MADT + { + public: + struct APICHeader + { + uint8_t Type; + uint8_t Length; + } __packed; + + struct MADTIOApic + { + struct APICHeader Header; + uint8_t APICID; + uint8_t reserved; + uint32_t Address; + uint32_t GSIBase; + } __packed; + + struct MADTIso + { + struct APICHeader Header; + uint8_t BuSSource; + uint8_t IRQSource; + uint32_t GSI; + uint16_t Flags; + } __packed; + + struct MADTNmi + { + struct APICHeader Header; + uint8_t processor; + uint16_t flags; + uint8_t lint; + } __packed; + + struct LocalAPIC + { + struct APICHeader Header; + uint8_t ACPIProcessorId; + uint8_t APICId; + uint32_t Flags; + } __packed; + + struct LAPIC + { + uint8_t id; + uintptr_t PhysicalAddress; + void *VirtualAddress; + }; + + std::vector ioapic; + std::vector iso; + std::vector nmi; + std::vector lapic; + struct LAPIC *LAPICAddress; + uint16_t CPUCores; + + MADT(ACPI::MADTHeader *madt); + ~MADT(); + }; + + class DSDT : public Interrupts::Handler + { + private: + uint32_t SMI_CMD = 0; + uint8_t ACPI_ENABLE = 0; + uint8_t ACPI_DISABLE = 0; + uint32_t PM1a_CNT = 0; + uint32_t PM1b_CNT = 0; + uint16_t SLP_TYPa = 0; + uint16_t SLP_TYPb = 0; + uint16_t SLP_EN = 0; + uint16_t SCI_EN = 0; + uint8_t PM1_CNT_LEN = 0; + + ACPI *acpi; + void OnInterruptReceived(CPU::x64::TrapFrame *Frame); + + public: + bool ACPIShutdownSupported = false; + + void Reboot(); + void Shutdown(); + + DSDT(ACPI *acpi); + ~DSDT(); + }; +} + +#endif // !__FENNIX_KERNEL_ACPI_H__ diff --git a/Core/Time/HighPrecisionEventTimer.cpp b/Core/Time/HighPrecisionEventTimer.cpp index 6b0e576..e8699ae 100644 --- a/Core/Time/HighPrecisionEventTimer.cpp +++ b/Core/Time/HighPrecisionEventTimer.cpp @@ -24,6 +24,7 @@ #if defined(a64) #include "../../Architecture/amd64/acpi.hpp" #elif defined(a32) +#include "../../Architecture/i386/acpi.hpp" #elif defined(aa64) #endif diff --git a/Core/Time/Timer.cpp b/Core/Time/Timer.cpp index a0f5b54..837bd12 100644 --- a/Core/Time/Timer.cpp +++ b/Core/Time/Timer.cpp @@ -24,6 +24,7 @@ #if defined(a64) #include "../../Architecture/amd64/acpi.hpp" #elif defined(a32) +#include "../../Architecture/i386/acpi.hpp" #elif defined(aa64) #endif @@ -149,6 +150,7 @@ namespace Time void time::FindTimers(void *acpi) { +#if defined(a86) /* TODO: RTC check */ /* TODO: PIT check */ @@ -200,7 +202,7 @@ namespace Time } else KPrint("\eFF2200TSC is not invariant"); - +#endif } time::time()