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. 5 import Base 6 import bend-osdev-word64@0.1.1.1/word64.bend as W 7 import bend-osdev-bytes@0.1.1.1/bytes.bend as B 8 9 def AcpiF.u8(o: B.Octets, i: Nat) -> U32: 10 Maybe.default(&2, U32, B.Octets.at(o, i), 0) 11 12 def AcpiF.u16(o: B.Octets, +i: Nat) -> U32: 13 Maybe.default(&2, U32, B.Octets.le16_at(o, i), 0) 14 15 def AcpiF.u32(o: B.Octets, +i: Nat) -> U32: 16 Maybe.default(&2, U32, B.Octets.le32_at(o, i), 0) 17 18 def 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 22 def 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) 26 def 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 30 def 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 34 def 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 38 def AcpiF.byte(v: U32) -> B.Octets: 39 B.Octets.of_list([v]) 40 41 def AcpiF.le16(v: U32) -> B.Octets: 42 B.Octets.le16(v) 43 44 def AcpiF.le32(v: U32) -> B.Octets: 45 B.Octets.le32(v) 46 47 def 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 51 def 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 55 def 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))))