summaryrefslogtreecommitdiff
path: root/lib/acpi.c3l/acpi.c3
diff options
context:
space:
mode:
Diffstat (limited to 'lib/acpi.c3l/acpi.c3')
-rw-r--r--lib/acpi.c3l/acpi.c3170
1 files changed, 170 insertions, 0 deletions
diff --git a/lib/acpi.c3l/acpi.c3 b/lib/acpi.c3l/acpi.c3
new file mode 100644
index 0000000..26021dc
--- /dev/null
+++ b/lib/acpi.c3l/acpi.c3
@@ -0,0 +1,170 @@
+module acpi;
+
+import c3os::util;
+
+extern fn int memcmp(void*, void*, usz);
+
+alias Oemid = char[6];
+
+excuse INVALID_DESCRIPTION_HEADER;
+
+enum DescriptionHeaderSignature
+{
+ AEST,
+ AGDI,
+ APIC,
+ APMT,
+ ASPT,
+ BDAT,
+ BERT,
+ BGRT,
+ BOOT,
+ CCEL,
+ CEDT,
+ CPEP,
+ CSRT,
+ DBGP,
+ DBG2,
+ DMAR,
+ DRTM,
+ DSDT,
+ DTPR,
+ ECDT,
+ EINJ,
+ ERST,
+ ETDT,
+ FACP,
+ FACS,
+ FPDT,
+ GTDT,
+ HEST,
+ HPET,
+ IBFT,
+ IERS,
+ IORT,
+ IOVT,
+ IRDT,
+ IVRS,
+ KEYP,
+ LPIT,
+ MCFG,
+ MCHI,
+ MHSP,
+ MISC,
+ MPAM,
+ MPST,
+ MSCT,
+ MSDM,
+ NBFT,
+ NFIT,
+ NHLT,
+ PCCT,
+ PHAT,
+ PMTT,
+ PPTT,
+ PRMT,
+ PSDT,
+ RASF,
+ RAS2,
+ RGRT,
+ RHCT,
+ RIMT,
+ RQSC,
+ RSDT,
+ SBST,
+ SDEI,
+ SDEV,
+ SLIC,
+ SLIT,
+ SPCR,
+ SPMI,
+ SRAT,
+ SSDT,
+ STAO,
+ SVKL,
+ SWFT,
+ TCPA,
+ TPM2,
+ UEFI,
+ WAET,
+ WDAT,
+ WDDT,
+ WDRT,
+ WPBT,
+ WSMT,
+ XENV,
+ XSDT,
+}
+
+$assert(DescriptionHeader::size == 36);
+$assert(RootSystemDescriptionPointer::size == 35);
+struct RootSystemDescriptionPointer @packed
+{
+ char[8] signature;
+ char checksum;
+ Oemid oemid;
+ char revision;
+ uint rsdtAddress;
+ uint length;
+ ExtendedSystemDescriptionTable* xsdtAddress;
+ char[3] _res;
+}
+
+fn bool RootSystemDescriptionPointer.is_valid(&self)
+{
+ if (memcmp(&self.signature, "RSD PTR ", 8) != 0) return false;
+ if (self.revision != 2) return false;
+ char sum = 0;
+ for (int i = 0; i < 20; i++) sum += ((char*)self)[i];
+ if (sum != 0) return false;
+ for (int i = 0; i < RootSystemDescriptionPointer::size; i++) sum += ((char*)self)[i];
+ return (sum == 0);
+}
+
+$assert(ExtendedSystemDescriptionTable::size == 36);
+struct ExtendedSystemDescriptionTable @packed
+{
+ inline DescriptionHeader header;
+ ulong[*] descriptionHeaders;
+}
+
+fn bool ExtendedSystemDescriptionTable.is_valid(&self)
+{
+ if (memcmp(&self.signature, "XSDT", 4) != 0) return false;
+ if (self.revision != 1) return false;
+ char sum = 0;
+ for (uint i = 0; i < self.length; i++) sum += ((char*)self)[i];
+ if (sum != 0) return false;
+ return true;
+}
+
+struct DescriptionHeader @packed
+{
+ char[4] signature;
+ uint length;
+ char revision;
+ char checksum;
+ Oemid oemid;
+ char[8] oemTableId;
+ uint oemRevision;
+ uint creatorId;
+ uint creatorRevision;
+}
+
+fn bool DescriptionHeader.is_valid(&self)
+{
+ if (catch excuse = self.sig()) return false;
+ char sum = 0;
+ for (uint i = 0; i < self.length; i++) sum += ((char*)self)[i];
+ if (sum != 0) return false;
+ return true;
+}
+
+fn DescriptionHeaderSignature? DescriptionHeader.sig(&self)
+{
+ foreach (i, name : DescriptionHeaderSignature::names)
+ {
+ if (memcmp(name, &self.signature, 4) == 0) return (DescriptionHeaderSignature)i;
+ }
+ return INVALID_DESCRIPTION_HEADER~;
+}