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~; }