ptos: drivers: Add ACPI driver groundwork
Signed-off-by: Chloe M <chloe@mensia.org>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Chloe M.
|
||||
* Provided under the BSD-3 clause.
|
||||
*
|
||||
* Description: ACPI init
|
||||
* Author: Chloe M.
|
||||
*/
|
||||
|
||||
#include <drivers/acpi/acpi.h>
|
||||
#include <drivers/acpi/tables.h>
|
||||
#include <ex/trace.h>
|
||||
#include <mm/vm.h>
|
||||
#include <ke/bpal.h>
|
||||
#include <ke/bugcheck.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DTRACE(Fmt, ...) \
|
||||
TRACE("[ ACPI ]: " Fmt, ##__VA_ARGS__)
|
||||
|
||||
static ACPI_RSDP *Rsdp;
|
||||
static ACPI_ROOT_SDT *RootSdt;
|
||||
static USIZE RootSdtEntries;
|
||||
|
||||
static VOID
|
||||
AcpiPrintVendor(VOID)
|
||||
{
|
||||
UCHAR Revision;
|
||||
|
||||
/*
|
||||
* On certain emulators this may become zero, just bump it up to
|
||||
* one because its behaviors are the same.
|
||||
*/
|
||||
Revision = Rsdp->Revision;
|
||||
if (Revision == 0) {
|
||||
++Revision;
|
||||
}
|
||||
|
||||
DTRACE("detected acpi %d.0 by %.6s\n", Revision, Rsdp->Oemid);
|
||||
}
|
||||
|
||||
static VOID
|
||||
RsdpVerify(VOID)
|
||||
{
|
||||
UCHAR Checksum = 0;
|
||||
USIZE Idx;
|
||||
|
||||
for (Idx = 0; Idx < Rsdp->Length; ++Idx) {
|
||||
Checksum += ((UCHAR *)Rsdp)[Idx];
|
||||
}
|
||||
|
||||
if ((Checksum & 0xFF) != 0) {
|
||||
KeBugCheck(
|
||||
BUGCHECK_BAD_CHECKSUM,
|
||||
"Got bad checksum %x for ACPI RSDP\n",
|
||||
Checksum
|
||||
);
|
||||
}
|
||||
|
||||
DTRACE("checksum ok\n");
|
||||
}
|
||||
|
||||
VOID *
|
||||
AcpiQuery(const CHAR *Signature)
|
||||
{
|
||||
BOOLEAN IsMatch;
|
||||
ACPI_HEADER *Header;
|
||||
UPTR Pma;
|
||||
USIZE Idx;
|
||||
|
||||
if (Signature == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (Idx = 0; Idx < RootSdtEntries; ++Idx) {
|
||||
Pma = (UPTR)RootSdt->Tables[Idx];
|
||||
Header = (ACPI_HEADER *)PMA_TO_VMA(Pma);
|
||||
IsMatch = !RtlMemCmp(
|
||||
Header->Signature,
|
||||
Signature,
|
||||
sizeof(Header->Signature)
|
||||
);
|
||||
|
||||
if (IsMatch) {
|
||||
return (VOID *)Header;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID
|
||||
AcpiInit(VOID)
|
||||
{
|
||||
BPAL_HANDLE BpalHandle;
|
||||
|
||||
KeBpalGetHandle(&BpalHandle);
|
||||
Rsdp = BpalHandle.RsdpBase;
|
||||
AcpiPrintVendor();
|
||||
RsdpVerify();
|
||||
|
||||
/* Select the correct root sdt */
|
||||
if (Rsdp->Revision < 2) {
|
||||
DTRACE("using rsdt as root sdt\n");
|
||||
RootSdt = PMA_TO_VMA((UPTR)Rsdp->RsdtAddr);
|
||||
RootSdtEntries = (RootSdt->Header.Length - sizeof(RootSdt->Header)) / 4;
|
||||
} else {
|
||||
DTRACE("using xsdt as root sdt\n");
|
||||
RootSdt = PMA_TO_VMA((UPTR)Rsdp->XsdtAddr);
|
||||
RootSdtEntries = (RootSdt->Header.Length - sizeof(RootSdt->Header)) / 8;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Chloe M.
|
||||
* Provided under the BSD-3 clause.
|
||||
*
|
||||
* Description: ACPI driver
|
||||
* Author: Chloe M.
|
||||
*/
|
||||
|
||||
#ifndef _ACPI_ACPI_H_
|
||||
#define _ACPI_ACPI_H_ 1
|
||||
|
||||
#include <ptdef.h>
|
||||
|
||||
/*
|
||||
* Initialize ACPI
|
||||
*/
|
||||
VOID AcpiInit(VOID);
|
||||
|
||||
/*
|
||||
* Query an ACPI structure
|
||||
*
|
||||
* @Signature: Signature to query for
|
||||
*
|
||||
* Returns the virtual structure base on success, otherwise
|
||||
* NULL on failure.
|
||||
*/
|
||||
VOID *AcpiQuery(const CHAR *Signature);
|
||||
|
||||
#endif /* !_ACPI_ACPI_H_ */
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Chloe M.
|
||||
* Provided under the BSD-3 clause.
|
||||
*
|
||||
* Description: ACPI definitions
|
||||
* Author: Chloe M.
|
||||
*/
|
||||
|
||||
#ifndef _ACPI_TABLES_H_
|
||||
#define _ACPI_TABLES_H_ 1
|
||||
|
||||
#include <ptdef.h>
|
||||
|
||||
/* MADT APIC header types */
|
||||
#define APIC_TYPE_LOCAL_APIC 0
|
||||
#define APIC_TYPE_IO_APIC 1
|
||||
#define APIC_TYPE_INTERRUPT_OVERRIDE 2
|
||||
|
||||
#define OEMID_SIZE 6
|
||||
|
||||
typedef struct PACKED {
|
||||
CHAR Signature[4];
|
||||
ULONG Length;
|
||||
UCHAR Revision;
|
||||
UCHAR Checksum;
|
||||
CHAR Oemid[OEMID_SIZE];
|
||||
CHAR OemTableId[8];
|
||||
ULONG OemRevision;
|
||||
ULONG CreatorId;
|
||||
ULONG CreatorRevision;
|
||||
} ACPI_HEADER;
|
||||
|
||||
typedef struct PACKED {
|
||||
UQUAD Signature;
|
||||
UCHAR Checksum;
|
||||
CHAR Oemid[OEMID_SIZE];
|
||||
UCHAR Revision;
|
||||
ULONG RsdtAddr;
|
||||
|
||||
/* Reserved if revision < 2 */
|
||||
ULONG Length;
|
||||
UQUAD XsdtAddr;
|
||||
UCHAR ExtChecksum;
|
||||
UCHAR Reserved[3];
|
||||
} ACPI_RSDP;
|
||||
|
||||
/*
|
||||
* XSDT or RSDT depending on the revision within the
|
||||
* header
|
||||
*/
|
||||
typedef struct PACKED {
|
||||
ACPI_HEADER Header;
|
||||
ULONG Tables[];
|
||||
} ACPI_ROOT_SDT;
|
||||
|
||||
typedef struct PACKED {
|
||||
ACPI_HEADER Header;
|
||||
ULONG LapicAddr;
|
||||
ULONG Flags;
|
||||
} ACPI_MADT;
|
||||
|
||||
typedef struct PACKED {
|
||||
UCHAR Type;
|
||||
UCHAR Length;
|
||||
} ACPI_APIC_HEADER;
|
||||
|
||||
typedef struct PACKED {
|
||||
ACPI_APIC_HEADER Header;
|
||||
UCHAR ProcessorId;
|
||||
UCHAR ApicId;
|
||||
ULONG Flags;
|
||||
} ACPI_LOCAL_APIC;
|
||||
|
||||
typedef struct PACKED {
|
||||
UCHAR AddressSpaceId;
|
||||
UCHAR RegisterBitWidth;
|
||||
UCHAR RegisterBitOffset;
|
||||
UCHAR Reserved;
|
||||
UQUAD Address;
|
||||
} ACPI_GAS;
|
||||
|
||||
/*
|
||||
* ACPI Address Space ID definitions for GAS
|
||||
*
|
||||
* See section 5.2.3.2 of the ACPI software programming
|
||||
* manual.
|
||||
*
|
||||
* XXX: 0x0B->0x7E is reserved as well as 0x80->0xBF
|
||||
* and 0xC0->0xFF is OEM defined. Values other than
|
||||
* the ones specified below are either garbage or
|
||||
* OEM specific values.
|
||||
*/
|
||||
#define ACPI_GAS_SYSMEM 0x00 /* System memory space */
|
||||
#define ACPI_GAS_SYSIO 0x01 /* System I/O space */
|
||||
#define ACPI_GAS_PCICONF 0x02 /* PCI configuration space */
|
||||
#define ACPI_GAS_EC 0x03 /* Embedded controller */
|
||||
#define ACPI_GAS_SMBUS 0x04 /* System management bus */
|
||||
#define ACPI_GAS_CMOS 0x05 /* System CMOS */
|
||||
#define ACPI_GAS_PCIBAR 0x06 /* PCI BAR target */
|
||||
#define ACPI_GAS_IPMI 0x07 /* IPMI (sensor monitoring) */
|
||||
#define ACPI_GAS_GPIO 0x08 /* General Purpose I/O */
|
||||
#define ACPI_GAS_GSBUS 0x09 /* GenericSerialBus */
|
||||
#define ACPI_GAS_PLATCOM 0x0A /* Platform Communications Channel */
|
||||
|
||||
/*
|
||||
* ACPI address size definitions for GAS
|
||||
*
|
||||
* See section 5.2.3.2 of the ACPI software programming
|
||||
* manual.
|
||||
*/
|
||||
#define ACPI_GAS_UNDEF 0 /* Undefined (legacy reasons) */
|
||||
#define ACPI_GAS_BYTE 1 /* Byte access */
|
||||
#define ACPI_GAS_WORD 2 /* Word access */
|
||||
#define ACPI_GAS_DWORD 3 /* Dword access */
|
||||
#define ACPI_GAS_QWORD 4 /* Qword access */
|
||||
|
||||
typedef struct PACKED {
|
||||
ACPI_HEADER Header;
|
||||
UCHAR HardwareRevId;
|
||||
UCHAR ComparatorCount : 5;
|
||||
UCHAR CounterSize : 1;
|
||||
UCHAR Reserved : 1;
|
||||
UCHAR LegacyReplacement : 1;
|
||||
USHORT PciVendorId;
|
||||
ACPI_GAS Gas;
|
||||
UCHAR HpetNumber;
|
||||
USHORT MinimumTick;
|
||||
UCHAR PageProtection;
|
||||
} ACPI_HPET;
|
||||
|
||||
#endif /* _ACPI_TABLES_H_ */
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <hal/serial.h>
|
||||
#include <hal/kpcr.h>
|
||||
#include <drivers/bootvid/fbio.h>
|
||||
#include <drivers/acpi/acpi.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Globals */
|
||||
@@ -89,6 +90,9 @@ KiKernelInit(VOID)
|
||||
/* Phase 2 init of bootstrap core */
|
||||
HalKpcrP2Init(&BootstrapCore);
|
||||
|
||||
/* Initialize ACPI */
|
||||
AcpiInit();
|
||||
|
||||
/* Initialize the root process */
|
||||
InitializeRootProcess();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user