hpet.bend
bend-osdev-acpi@0.1.2.0 · 75 lines · 0 definitions
1# bend-osdev-acpi, hpet.bend: the HPET Description Table, "HPET" (IA-PC HPET
2# (High Precision Event Timers) Specification, revision 1.0a, Intel, 2004,
3# section 3.2.4; its signature is reserved by ACPI 6.5, section 5.2.6),
4# 56 bytes:
5#
6# offset size field
7# 36 4 Event Timer Block ID: bits 0-7 hardware revision, 8-12
8# number of comparators in the first block minus one, 13
9# COUNT_SIZE_CAP (64-bit counter), 15 legacy replacement
10# IRQ routing capable, 16-31 PCI vendor ID
11# 40 12 Base Address (a Generic Address Structure, gas.bend)
12# 52 1 HPET Number
13# 53 2 Main Counter Minimum Clock Tick in Periodic Mode
14# 55 1 Page Protection and OEM Attribute
15import Base
16import bend-osdev-word64@0.1.1.1/word64.bend as W
17import bend-osdev-bytes@0.1.1.1/bytes.bend as B
18import bend-osdev-acpi@0.1.2.0/error.bend as E
19import bend-osdev-acpi@0.1.2.0/header.bend as H
20import bend-osdev-acpi@0.1.2.0/fields.bend as F
21import bend-osdev-acpi@0.1.2.0/gas.bend as G
22
23type AcpiHpet is Data:
24 AcpiHpet{header: H.AcpiHeader, block_id: U32, base: G.AcpiGas, number: U32, min_tick: U32, page_protection: U32}
25
26def hpet.read(ok: Bool, +h: H.AcpiHeader, +o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiHpet>:
27 match ok:
28 case False{}:
29 Fail{E.AcpiTooShort{56n, B.Octets.len(o)}}
30 case True{}:
31 Done{AcpiHpet{h, F.AcpiF.u32(o, 36n), G.AcpiGas.at(o, 40n), F.AcpiF.u8(o, 52n), F.AcpiF.u16(o, 53n), F.AcpiF.u8(o, 55n)}}
32
33def AcpiHpet.of_sdt(t: H.AcpiSdt) -> Result<&2, &2, E.AcpiError, AcpiHpet>:
34 match t:
35 case H.AcpiSdt{+h, body}:
36 +o = B.Octets.append(H.AcpiHeader.encode(h), body)
37 hpet.read(Nat.is_le(56n, B.Octets.len(o)), h, o)
38
39def hpet.parse(r: Result<&2, &2, E.AcpiError, H.AcpiSdt>) -> Result<&2, &2, E.AcpiError, AcpiHpet>:
40 match r:
41 case Fail{e}:
42 Fail{e}
43 case Done{t}:
44 AcpiHpet.of_sdt(t)
45
46def AcpiHpet.parse(+o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiHpet>:
47 hpet.parse(H.AcpiSdt.parse_sig(B.Octets.of_string("HPET"), o))
48
49def AcpiHpet.block_id(t: AcpiHpet) -> U32:
50 match t:
51 case AcpiHpet{h, id, g, n, m, p}:
52 id
53
54def AcpiHpet.base(t: AcpiHpet) -> G.AcpiGas:
55 match t:
56 case AcpiHpet{h, id, g, n, m, p}:
57 g
58
59# the fields of the Event Timer Block ID
60def AcpiHpet.vendor_id(t: AcpiHpet) -> U32:
61 F.AcpiF.bits(AcpiHpet.block_id(t), 16n, 16n)
62
63def AcpiHpet.comparators(t: AcpiHpet) -> U32:
64 U32.add(F.AcpiF.bits(AcpiHpet.block_id(t), 8n, 5n), 1)
65
66def AcpiHpet.counter_64(t: AcpiHpet) -> Bool:
67 F.AcpiF.bit(AcpiHpet.block_id(t), 13n)
68
69def AcpiHpet.legacy_capable(t: AcpiHpet) -> Bool:
70 F.AcpiF.bit(AcpiHpet.block_id(t), 15n)
71
72def AcpiHpet.build(t: AcpiHpet) -> B.Octets:
73 match t:
74 case AcpiHpet{H.AcpiHeader{s, l, r, c, o, tid, orv, ci, cr}, id, g, n, m, p}:
75 H.AcpiSdt.build(H.AcpiHeader{B.Octets.of_string("HPET"), l, r, c, o, tid, orv, ci, cr}, B.Octets.concat([B.Octets.le32(id), G.AcpiGas.encode(g), B.Octets.of_list([n]), B.Octets.le16(m), B.Octets.of_list([p])]))