registry.bend
bend-osdev-acpi@0.1.1.0 · 210 lines · 23 definitions
1
2
3
4
5
6
7
8import Base
9import bend-osdev-bytes@0.1.1.0/bytes.bend as B
10import bend-osdev-acpi@0.1.1.0/error.bend as E
11import bend-osdev-acpi@0.1.1.0/header.bend as H
12import bend-osdev-acpi@0.1.1.0/rsdt.bend as S
13import bend-osdev-acpi@0.1.1.0/madt.bend as M
14import bend-osdev-acpi@0.1.1.0/fadt.bend as F
15import bend-osdev-acpi@0.1.1.0/hpet.bend as P
16import bend-osdev-acpi@0.1.1.0/mcfg.bend as C
17import bend-osdev-acpi@0.1.1.0/srat.bend as R
18import bend-osdev-acpi@0.1.1.0/slit.bend as L
19import bend-osdev-acpi@0.1.1.0/bgrt.bend as G
20import bend-osdev-acpi@0.1.1.0/dsdt.bend as D
21
22
23type AcpiKind is Data:
24 AcpiKRsdt{}
25 AcpiKXsdt{}
26 AcpiKMadt{}
27 AcpiKFadt{}
28 AcpiKHpet{}
29 AcpiKMcfg{}
30 AcpiKSrat{}
31 AcpiKSlit{}
32 AcpiKBgrt{}
33
34 AcpiKAml{}
35
36 AcpiKRaw{}
37
38 AcpiKExt{tag: U32}
39
40type AcpiRegEntry is Data:
41 AcpiRegEntry{signature: B.Octets, kind: AcpiKind}
42
43type AcpiRegistry is Data:
44 AcpiRegistry{entries: List<&2, AcpiRegEntry>}
45
46def reg.e(s: String, k: AcpiKind) -> AcpiRegEntry:
47 AcpiRegEntry{B.Octets.of_string(s), k}
48
49
50def AcpiRegistry.default() -> AcpiRegistry:
51 AcpiRegistry{[reg.e("RSDT", AcpiKRsdt{}), reg.e("XSDT", AcpiKXsdt{}), reg.e("APIC", AcpiKMadt{}), reg.e("FACP", AcpiKFadt{}), reg.e("HPET", AcpiKHpet{}), reg.e("MCFG", AcpiKMcfg{}), reg.e("SRAT", AcpiKSrat{}), reg.e("SLIT", AcpiKSlit{}), reg.e("BGRT", AcpiKBgrt{}), reg.e("DSDT", AcpiKAml{}), reg.e("SSDT", AcpiKAml{})]}
52
53
54def AcpiRegistry.empty() -> AcpiRegistry:
55 AcpiRegistry{Nil{}}
56
57def reg.lookup.pick(hit: Bool, k: AcpiKind, rest: AcpiKind) -> AcpiKind:
58 match hit:
59 case True{}:
60 k
61 case False{}:
62 rest
63
64def reg.lookup(es: List<&2, AcpiRegEntry>, +sig: B.Octets) -> AcpiKind:
65 match es:
66 case Nil{}:
67 AcpiKRaw{}
68 case Con{AcpiRegEntry{s, k}, t}:
69 reg.lookup.pick(B.Octets.is_eq(s, sig), k, reg.lookup(t, sig))
70
71
72def AcpiRegistry.lookup(r: AcpiRegistry, +sig: B.Octets) -> AcpiKind:
73 match r:
74 case AcpiRegistry{es}:
75 reg.lookup(es, sig)
76
77def reg.keep(hit: Bool, e: AcpiRegEntry, rest: List<&2, AcpiRegEntry>) -> List<&2, AcpiRegEntry>:
78 match hit:
79 case True{}:
80 rest
81 case False{}:
82 Con{e, rest}
83
84def reg.drop(es: List<&2, AcpiRegEntry>, +sig: B.Octets) -> List<&2, AcpiRegEntry>:
85 match es:
86 case Nil{}:
87 Nil{}
88 case Con{AcpiRegEntry{+s, k}, t}:
89 reg.keep(B.Octets.is_eq(s, sig), AcpiRegEntry{s, k}, reg.drop(t, sig))
90
91
92def AcpiRegistry.set(r: AcpiRegistry, +sig: B.Octets, k: AcpiKind) -> AcpiRegistry:
93 match r:
94 case AcpiRegistry{es}:
95 AcpiRegistry{Con{AcpiRegEntry{sig, k}, reg.drop(es, sig)}}
96
97
98def AcpiRegistry.remove(r: AcpiRegistry, +sig: B.Octets) -> AcpiRegistry:
99 match r:
100 case AcpiRegistry{es}:
101 AcpiRegistry{reg.drop(es, sig)}
102
103
104
105type AcpiTable<-X: Data> is Data:
106 AcpiTRsdt{t: S.AcpiSdtList}
107 AcpiTXsdt{t: S.AcpiSdtList}
108 AcpiTMadt{t: M.AcpiMadt}
109 AcpiTFadt{t: F.AcpiFadt}
110 AcpiTHpet{t: P.AcpiHpet}
111 AcpiTMcfg{t: C.AcpiMcfg}
112 AcpiTSrat{t: R.AcpiSrat}
113 AcpiTSlit{t: L.AcpiSlit}
114 AcpiTBgrt{t: G.AcpiBgrt}
115 AcpiTAml{t: D.AcpiAml}
116 AcpiTRaw{t: H.AcpiSdt}
117 AcpiTExt{tag: U32, x: X}
118
119type AcpiNoExt is Data:
120 AcpiNoExt{}
121
122
123def AcpiNoExt.parse(tag: U32, t: H.AcpiSdt) -> Result<&2, &2, E.AcpiError, AcpiNoExt>:
124 Fail{E.AcpiBadSignature{H.AcpiHeader.signature(H.AcpiSdt.header(t))}}
125
126def reg.wrap(~X: Data, ~A: Data, ~f: A -> AcpiTable<X>, r: Result<&2, &2, E.AcpiError, A>) -> Result<&2, &2, E.AcpiError, AcpiTable<X>>:
127 match r:
128 case Fail{e}:
129 Fail{e}
130 case Done{a}:
131 Done{f(a)}
132
133def reg.ext(~X: Data, +tag: U32, r: Result<&2, &2, E.AcpiError, X>) -> Result<&2, &2, E.AcpiError, AcpiTable<X>>:
134 match r:
135 case Fail{e}:
136 Fail{e}
137 case Done{a}:
138 Done{AcpiTExt{tag, a}}
139
140def reg.dispatch(~X: Data, ~ext: U32 -> H.AcpiSdt -> Result<&2, &2, E.AcpiError, X>, k: AcpiKind, +t: H.AcpiSdt) -> Result<&2, &2, E.AcpiError, AcpiTable<X>>:
141 match k:
142 case AcpiKRsdt{}:
143 reg.wrap(~X, ~S.AcpiSdtList, ~(a => AcpiTRsdt{a}), S.AcpiRsdt.of_sdt(t))
144 case AcpiKXsdt{}:
145 reg.wrap(~X, ~S.AcpiSdtList, ~(a => AcpiTXsdt{a}), S.AcpiXsdt.of_sdt(t))
146 case AcpiKMadt{}:
147 reg.wrap(~X, ~M.AcpiMadt, ~(a => AcpiTMadt{a}), M.AcpiMadt.of_sdt(t))
148 case AcpiKFadt{}:
149 reg.wrap(~X, ~F.AcpiFadt, ~(a => AcpiTFadt{a}), F.AcpiFadt.of_sdt(t))
150 case AcpiKHpet{}:
151 reg.wrap(~X, ~P.AcpiHpet, ~(a => AcpiTHpet{a}), P.AcpiHpet.of_sdt(t))
152 case AcpiKMcfg{}:
153 reg.wrap(~X, ~C.AcpiMcfg, ~(a => AcpiTMcfg{a}), C.AcpiMcfg.of_sdt(t))
154 case AcpiKSrat{}:
155 reg.wrap(~X, ~R.AcpiSrat, ~(a => AcpiTSrat{a}), R.AcpiSrat.of_sdt(t))
156 case AcpiKSlit{}:
157 reg.wrap(~X, ~L.AcpiSlit, ~(a => AcpiTSlit{a}), L.AcpiSlit.of_sdt(t))
158 case AcpiKBgrt{}:
159 reg.wrap(~X, ~G.AcpiBgrt, ~(a => AcpiTBgrt{a}), G.AcpiBgrt.of_sdt(t))
160 case AcpiKAml{}:
161 reg.wrap(~X, ~D.AcpiAml, ~(a => AcpiTAml{a}), D.AcpiAml.of_sdt(t))
162 case AcpiKRaw{}:
163 Done{AcpiTRaw{t}}
164 case AcpiKExt{+tag}:
165 reg.ext(~X, tag, ext(tag, t))
166
167def reg.go(~X: Data, ~ext: U32 -> H.AcpiSdt -> Result<&2, &2, E.AcpiError, X>, +reg: AcpiRegistry, r: Result<&2, &2, E.AcpiError, H.AcpiSdt>) -> Result<&2, &2, E.AcpiError, AcpiTable<X>>:
168 match r:
169 case Fail{e}:
170 Fail{e}
171 case Done{+t}:
172 reg.dispatch(~X, ~ext, AcpiRegistry.lookup(reg, H.AcpiHeader.signature(H.AcpiSdt.header(t))), t)
173
174
175
176
177def AcpiTable.parse_with(~X: Data, ~ext: U32 -> H.AcpiSdt -> Result<&2, &2, E.AcpiError, X>, +reg: AcpiRegistry, +o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiTable<X>>:
178 reg.go(~X, ~ext, reg, H.AcpiSdt.parse(o))
179
180
181def AcpiTable.parse(+reg: AcpiRegistry, +o: B.Octets) -> Result<&2, &2, E.AcpiError, AcpiTable<AcpiNoExt>>:
182 AcpiTable.parse_with(~AcpiNoExt, ~AcpiNoExt.parse, reg, o)
183
184
185def AcpiTable.name(~X: Data, t: AcpiTable<X>) -> String:
186 match t:
187 case AcpiTRsdt{a}:
188 "RSDT"
189 case AcpiTXsdt{a}:
190 "XSDT"
191 case AcpiTMadt{a}:
192 "APIC"
193 case AcpiTFadt{a}:
194 "FACP"
195 case AcpiTHpet{a}:
196 "HPET"
197 case AcpiTMcfg{a}:
198 "MCFG"
199 case AcpiTSrat{a}:
200 "SRAT"
201 case AcpiTSlit{a}:
202 "SLIT"
203 case AcpiTBgrt{a}:
204 "BGRT"
205 case AcpiTAml{a}:
206 B.Octets.to_string(H.AcpiHeader.signature(D.AcpiAml.header(a)))
207 case AcpiTRaw{a}:
208 B.Octets.to_string(H.AcpiHeader.signature(H.AcpiSdt.header(a)))
209 case AcpiTExt{tag, x}:
210 "ext " ++ U32.show(tag)