1 # bend-osdev-acpi, facs.bend: the Firmware ACPI Control Structure, "FACS" 2 # (ACPI 6.5, section 5.2.10). It has no standard header and no 3 # checksum; the FADT points to it. 64 bytes: 4 # 5 # offset size field 6 # 0 4 Signature "FACS" 7 # 4 4 Length (64 or more) 8 # 8 4 Hardware Signature 9 # 12 4 Firmware Waking Vector (32-bit) 10 # 16 4 Global Lock 11 # 20 4 Flags (bit 0 S4BIOS_F, bit 1 64BIT_WAKE_SUPPORTED_F) 12 # 24 8 X Firmware Waking Vector (64-bit) 13 # 32 1 Version (2 from ACPI 4.0) 14 # 33 3 Reserved 15 # 36 4 OSPM Flags (bit 0 64BIT_WAKE_F) 16 # 40 24 Reserved 17 import Base 18 import bend-osdev-word64@0.1.0.0/word64.bend as W 19 import bend-osdev-bytes@0.1.0.0/bytes.bend as B 20 import ./error.bend as E 21 import ./fields.bend as F 22 23 type AcpiFacs is Data: 24 AcpiFacs{length: U32, hardware_signature: U32, waking_vector: U32, global_lock: U32, flags: U32, x_waking_vector: W.W64, version: U32, ospm_flags: U32} 25 26 def facs.p3(ok: Bool, +l: U32, +o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiFacs>: 27 match ok: 28 case False{}: 29 Fail{E.AcpiBadLength{l}} 30 case True{}: 31 Done{AcpiFacs{l, F.AcpiF.u32(o, 8n), F.AcpiF.u32(o, 12n), F.AcpiF.u32(o, 16n), F.AcpiF.u32(o, 20n), F.AcpiF.u64(o, 24n), F.AcpiF.u8(o, 32n), F.AcpiF.u32(o, 36n)}} 32 33 def facs.p2(ok: Bool, +o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiFacs>: 34 match ok: 35 case False{}: 36 Fail{E.AcpiBadSignature{B.Octets.take(4n, o)}} 37 case True{}: 38 +l = F.AcpiF.u32(o, 4n) 39 facs.p3(Nat.is_le(64n, U32.to_nat(l)), l, o) 40 41 def facs.p1(ok: Bool, +o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiFacs>: 42 match ok: 43 case False{}: 44 Fail{E.AcpiTooShort{64n, B.Octets.len(o)}} 45 case True{}: 46 facs.p2(B.Octets.is_eq(B.Octets.take(4n, o), B.Octets.of_string("FACS")), o) 47 48 # the FACS at the front of o: at least 64 bytes, the signature, a length 49 # of at least 64 50 def AcpiFacs.parse(+o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiFacs>: 51 facs.p1(Nat.is_le(64n, B.Octets.len(o)), o) 52 53 def AcpiFacs.build(f: AcpiFacs) -> B.Octets: 54 match f: 55 case AcpiFacs{l, hs, wv, gl, fl, xw, v, of}: 56 B.Octets.concat([B.Octets.of_string("FACS"), B.Octets.le32(64), B.Octets.le32(hs), B.Octets.le32(wv), B.Octets.le32(gl), B.Octets.le32(fl), B.Octets.le64(xw), B.Octets.of_list([v]), B.Octets.zeros(3n), B.Octets.le32(of), B.Octets.zeros(24n)])