rsdt.bend
bend-osdev-acpi@0.1.1.0 · 106 lines · 16 definitions
1
2
3
4
5import Base
6import bend-osdev-word64@0.1.1.0/word64.bend as W
7import bend-osdev-bytes@0.1.1.0/bytes.bend as B
8import bend-osdev-acpi@0.1.1.0/error.bend as E
9import bend-osdev-acpi@0.1.1.0/header.bend as H
10import bend-osdev-acpi@0.1.1.0/fields.bend as F
11
12type AcpiSdtList is Data:
13 AcpiSdtList{header: H.AcpiHeader, entries: List<&2, W.W64>}
14
15def AcpiSdtList.entries(t: AcpiSdtList) -> List<&2, W.W64>:
16 match t:
17 case AcpiSdtList{h, es}:
18 es
19
20def AcpiSdtList.header(t: AcpiSdtList) -> H.AcpiHeader:
21 match t:
22 case AcpiSdtList{h, es}:
23 h
24
25def sl.rev(xs: List<&2, W.W64>, acc: List<&2, W.W64>) -> List<&2, W.W64>:
26 match xs:
27 case Nil{}:
28 acc
29 case Con{h, t}:
30 sl.rev(t, Con{h, acc})
31
32
33def sl.read(n: Nat, wide: Bool, +o: B.Octets, acc: List<&2, W.W64>) -> List<&2, W.W64>:
34 match n:
35 case 0n:
36 sl.rev(acc, Nil{})
37 case 1n+p:
38 match wide:
39 case True{}:
40 sl.read(p, True{}, B.Octets.drop(8n, o), Con{F.AcpiF.u64(o, 0n), acc})
41 case False{}:
42 sl.read(p, False{}, B.Octets.drop(4n, o), Con{W.W64.from_u32(F.AcpiF.u32(o, 0n)), acc})
43
44def sl.width(wide: Bool) -> Nat:
45 match wide:
46 case True{}:
47 8n
48 case False{}:
49 4n
50
51def sl.body(ok: Bool, +wide: Bool, +h: H.AcpiHeader, +body: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiSdtList>:
52 match ok:
53 case False{}:
54 Fail{E.AcpiBadSize{B.Octets.len(body)}}
55 case True{}:
56 Done{AcpiSdtList{h, sl.read(Nat.div(B.Octets.len(body), sl.width(wide)), wide, body, Nil{})}}
57
58
59
60def sl.of_sdt(+wide: Bool, t: H.AcpiSdt) -> Result<&2, &2, E.AcpiError, AcpiSdtList>:
61 match t:
62 case H.AcpiSdt{h, +body}:
63 sl.body(Nat.is_eq(Nat.mod(B.Octets.len(body), sl.width(wide)), 0n), wide, h, body)
64
65def AcpiRsdt.of_sdt(t: H.AcpiSdt) -> Result<&2, &2, E.AcpiError, AcpiSdtList>:
66 sl.of_sdt(False{}, t)
67
68def AcpiXsdt.of_sdt(t: H.AcpiSdt) -> Result<&2, &2, E.AcpiError, AcpiSdtList>:
69 sl.of_sdt(True{}, t)
70
71def sl.parse(+wide: Bool, r: Result<&2, &2, E.AcpiError, H.AcpiSdt>) -> Result<&2, &2, E.AcpiError, AcpiSdtList>:
72 match r:
73 case Fail{e}:
74 Fail{e}
75 case Done{t}:
76 sl.of_sdt(wide, t)
77
78def AcpiRsdt.parse(+o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiSdtList>:
79 sl.parse(False{}, H.AcpiSdt.parse_sig(B.Octets.of_string("RSDT"), o))
80
81def AcpiXsdt.parse(+o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiSdtList>:
82 sl.parse(True{}, H.AcpiSdt.parse_sig(B.Octets.of_string("XSDT"), o))
83
84def sl.enc(xs: List<&2, W.W64>, wide: Bool) -> List<&2, B.Octets>:
85 match xs:
86 case Nil{}:
87 Nil{}
88 case Con{h, t}:
89 match wide:
90 case True{}:
91 Con{B.Octets.le64(h), sl.enc(t, True{})}
92 case False{}:
93 Con{B.Octets.le32(W.W64.lo(h)), sl.enc(t, False{})}
94
95
96
97
98def AcpiRsdt.build(h: H.AcpiHeader, xs: List<&2, W.W64>) -> B.Octets:
99 match h:
100 case H.AcpiHeader{s, l, r, c, o, t, orv, ci, cr}:
101 H.AcpiSdt.build(H.AcpiHeader{B.Octets.of_string("RSDT"), l, r, c, o, t, orv, ci, cr}, B.Octets.concat(sl.enc(xs, False{})))
102
103def AcpiXsdt.build(h: H.AcpiHeader, xs: List<&2, W.W64>) -> B.Octets:
104 match h:
105 case H.AcpiHeader{s, l, r, c, o, t, orv, ci, cr}:
106 H.AcpiSdt.build(H.AcpiHeader{B.Octets.of_string("XSDT"), l, r, c, o, t, orv, ci, cr}, B.Octets.concat(sl.enc(xs, True{})))