facs.bend

bend-osdev-acpi@0.1.0.0 · 56 lines · 0 definitions

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
17import Base
18import bend-osdev-word64@0.1.0.0/word64.bend as W
19import bend-osdev-bytes@0.1.0.0/bytes.bend as B
20import bend-osdev-acpi@0.1.0.0/error.bend as E
21import bend-osdev-acpi@0.1.0.0/fields.bend as F
22
23type 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
26def 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
33def 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
41def 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
50def AcpiFacs.parse(+o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiFacs>:
51  facs.p1(Nat.is_le(64n, B.Octets.len(o)), o)
52
53def 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)])