fields.bend

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

1# bend-osdev-acpi, fields.bend (internal): little-endian field readers for
2# table parsers, over bytes whose length the parser has already checked. A
3# field past the end reads as zero; every parser checks a table's length
4# before reading the fields that length must hold.
5import Base
6import bend-osdev-word64@0.1.0.0/word64.bend as W
7import bend-osdev-bytes@0.1.0.0/bytes.bend as B
8
9def AcpiF.u8(o: B.Octets, i: Nat) -> U32:
10  Maybe.default(&2, U32, B.Octets.at(o, i), 0)
11
12def AcpiF.u16(o: B.Octets, +i: Nat) -> U32:
13  Maybe.default(&2, U32, B.Octets.le16_at(o, i), 0)
14
15def AcpiF.u32(o: B.Octets, +i: Nat) -> U32:
16  Maybe.default(&2, U32, B.Octets.le32_at(o, i), 0)
17
18def AcpiF.u64(o: B.Octets, +i: Nat) -> W.W64:
19  Maybe.default(&2, W.W64, B.Octets.le64_at(o, i), W.W64.zero())
20
21# the 3-byte little-endian field at offset i
22def AcpiF.u24(+o: B.Octets, +i: Nat) -> U32:
23  U32.or(AcpiF.u16(o, i), U32.shln(AcpiF.u8(o, Nat.add(i, 2n)), 16n))
24
25# n bytes at offset i (fewer if o ends first)
26def AcpiF.bytes(o: B.Octets, +i: Nat, n: Nat) -> B.Octets:
27  B.Octets.slice(i, n, o)
28
29# bit k of a word
30def AcpiF.bit(+v: U32, k: Nat) -> Bool:
31  U32.is_eq(U32.and(U32.shrn(v, k), 1), 1)
32
33# bits k .. k + n - 1 of a word
34def AcpiF.bits(+v: U32, k: Nat, n: Nat) -> U32:
35  U32.and(U32.shrn(v, k), U32.sub(U32.shln(1, n), 1))
36
37# one byte, as Octets
38def AcpiF.byte(v: U32) -> B.Octets:
39  B.Octets.of_list([v])
40
41def AcpiF.le16(v: U32) -> B.Octets:
42  B.Octets.le16(v)
43
44def AcpiF.le32(v: U32) -> B.Octets:
45  B.Octets.le32(v)
46
47def AcpiF.le64(v: W.W64) -> B.Octets:
48  B.Octets.le64(v)
49
50# the 3-byte little-endian encoding of the low 24 bits of v
51def AcpiF.le24(+v: U32) -> B.Octets:
52  B.Octets.of_list([v, U32.shrn(v, 8n), U32.shrn(v, 16n)])
53
54# o cut or padded with zeros to exactly n bytes
55def AcpiF.fit(+n: Nat, +o: B.Octets) -> B.Octets:
56  +h = B.Octets.take(n, o)
57  B.Octets.append(h, B.Octets.zeros(Nat.sub(n, B.Octets.len(h))))