check.bend
bend-osdev-acpi@0.1.1.0 · 339 lines · 33 definitions
1import Base
2import bend-osdev-word64@0.1.1.0/word64.bend as W
3import bend-osdev-bytes@0.1.1.0/bytes.bend as B
4import bend-osdev-acpi@0.1.1.0/error.bend as E
5import bend-osdev-acpi@0.1.1.0/checksum.bend as C
6import bend-osdev-acpi@0.1.1.0/header.bend as H
7import bend-osdev-acpi@0.1.1.0/rsdp.bend as P
8import bend-osdev-acpi@0.1.1.0/rsdt.bend as S
9import bend-osdev-acpi@0.1.1.0/fadt.bend as F
10import bend-osdev-acpi@0.1.1.0/gas.bend as G
11import bend-osdev-acpi@0.1.1.0/madt.bend as M
12import bend-osdev-acpi@0.1.1.0/hpet.bend as Hp
13import bend-osdev-acpi@0.1.1.0/mcfg.bend as Mc
14import bend-osdev-acpi@0.1.1.0/slit.bend as Sl
15import bend-osdev-acpi@0.1.1.0/dsdt.bend as D
16import bend-osdev-acpi@0.1.1.0/registry.bend as R
17import bend-osdev-acpi@0.1.1.0/acpi.bend as A
18import bend-osdev-acpi@0.1.1.0/aml_pkglength.bend as K
19import bend-osdev-acpi@0.1.1.0/aml_name.bend as N
20import bend-osdev-acpi@0.1.1.0/aml_term.bend as T
21import bend-osdev-acpi@0.1.1.0/aml_value.bend as V
22import bend-osdev-acpi@0.1.1.0/aml_host.bend as Hs
23import bend-osdev-acpi@0.1.1.0/aml_interp.bend as I
24import bend-osdev-acpi@0.1.1.0/aml.bend as Am
25import bend-osdev-acpi@0.1.1.0/aml_resource.bend as Rs
26import bend-osdev-acpi@0.1.1.0/aml_device.bend as Dv
27import bend-osdev-acpi@0.1.1.0/example.bend as X
28
29def err(e: E.AcpiError) -> String:
30 match e:
31 case E.AcpiTooShort{n, g}:
32 "too short " ++ Nat.show(n) ++ " " ++ Nat.show(g)
33 case E.AcpiBadSignature{s}:
34 "bad signature " ++ B.Octets.to_string(s)
35 case E.AcpiBadLength{l}:
36 "bad length " ++ U32.show(l)
37 case E.AcpiBadChecksum{s}:
38 "bad checksum " ++ U32.show(s)
39 case E.AcpiRsdpBadChecksum{s}:
40 "bad RSDP checksum " ++ U32.show(s)
41 case E.AcpiNotMapped{a}:
42 "not mapped " ++ W.W64.show_hex(a)
43 case E.AcpiAmlUndefined{p}:
44 "undefined " ++ p
45 case E.AcpiAmlStepLimit{}:
46 "step limit"
47 case E.AcpiAmlBadOpcode{c}:
48 "bad opcode " ++ U32.show(c)
49 case E.AcpiAmlBadOperand{c}:
50 "bad operand " ++ U32.show(c)
51 case E.AcpiAmlBadType{s}:
52 "bad type " ++ s
53 case E.AcpiAmlDuplicate{p}:
54 "duplicate " ++ p
55 case E.AcpiAmlUnsupported{s}:
56 "unsupported " ++ s
57 case E.AcpiAmlTruncated{}:
58 "truncated"
59 case E.AcpiAmlRange{}:
60 "range"
61 case _:
62 "error"
63
64def loaded(l: A.AcpiLoaded<R.AcpiNoExt>) -> String:
65 match l:
66 case A.AcpiLoaded{a, Done{t}}:
67 W.W64.show_hex(a) ++ " " ++ R.AcpiTable.name(~R.AcpiNoExt, t)
68 case A.AcpiLoaded{a, Fail{e}}:
69 W.W64.show_hex(a) ++ " " ++ err(e)
70
71def loadeds(ls: List<&2, A.AcpiLoaded<R.AcpiNoExt>>) -> List<&2, String>:
72 match ls:
73 case Nil{}:
74 Nil{}
75 case Con{h, t}:
76 Con{loaded(h), loadeds(t)}
77
78def tables(r: Result<&2, &2, E.AcpiError, A.AcpiTableSet<R.AcpiNoExt>>) -> String:
79 match r:
80 case Done{A.AcpiTableSet{rp, root, ts, Some{Done{f}}}}:
81 String.join(loadeds(ts), ", ") ++ "; FACS ok"
82 case Done{A.AcpiTableSet{rp, root, ts, f}}:
83 String.join(loadeds(ts), ", ") ++ "; no FACS"
84 case Fail{e}:
85 err(e)
86
87def madt.e(e: M.AcpiMadtEntry) -> String:
88 match e:
89 case M.AcpiMadtLapic{u, a, f}:
90 "lapic " ++ U32.show(a)
91 case M.AcpiMadtIoApic{i, a, g}:
92 "ioapic " ++ U32.show(i) ++ " at " ++ U32.show(a)
93 case M.AcpiMadtIso{b, s, g, f}:
94 "irq " ++ U32.show(s) ++ "->" ++ U32.show(g) ++ "/" ++ U32.show(f)
95 case M.AcpiMadtLapicNmi{u, f, l}:
96 "nmi lint" ++ U32.show(l)
97 case M.AcpiMadtX2apic{x, f, u}:
98 "x2apic " ++ U32.show(x)
99 case _:
100 "other"
101
102def madt.es(es: List<&2, M.AcpiMadtEntry>) -> List<&2, String>:
103 match es:
104 case Nil{}:
105 Nil{}
106 case Con{h, t}:
107 Con{madt.e(h), madt.es(t)}
108
109def madt(r: Result<&2, &2, E.AcpiError, M.AcpiMadt>) -> String:
110 match r:
111 case Done{+m}:
112 W.W64.show_hex(M.AcpiMadt.lapic_address(m)) ++ ": " ++ String.join(madt.es(M.AcpiMadt.entries(m)), ", ")
113 case Fail{e}:
114 err(e)
115
116def fadt(r: Result<&2, &2, E.AcpiError, F.AcpiFadt>) -> String:
117 match r:
118 case Done{+f}:
119 "dsdt " ++ W.W64.show_hex(F.AcpiFadt.dsdt_address(f)) ++ " pm1a_evt " ++ G.AcpiGas.show(F.AcpiFadt.block(f, F.AcpiFadtPm1aEvt{})) ++ " pm1b_cnt " ++ G.AcpiGas.show(F.AcpiFadt.block(f, F.AcpiFadtPm1bCnt{})) ++ " reduced " ++ Bool.show(F.AcpiFadt.hw_reduced(f))
120 case Fail{e}:
121 err(e)
122
123def hpet(r: Result<&2, &2, E.AcpiError, Hp.AcpiHpet>) -> String:
124 match r:
125 case Done{+h}:
126 "vendor " ++ U32.show(Hp.AcpiHpet.vendor_id(h)) ++ " comparators " ++ U32.show(Hp.AcpiHpet.comparators(h)) ++ " 64-bit " ++ Bool.show(Hp.AcpiHpet.counter_64(h))
127 case Fail{e}:
128 err(e)
129
130def mw(m: Maybe<&2, W.W64>) -> String:
131 match m:
132 case Some{a}:
133 W.W64.show_hex(a)
134 case None{}:
135 "none"
136
137def mcfg(r: Result<&2, &2, E.AcpiError, Mc.AcpiMcfg>) -> String:
138 match r:
139 case Done{+m}:
140 mw(Mc.AcpiMcfg.ecam_address(m, 0, 0, 31, 0, 96)) ++ " " ++ mw(Mc.AcpiMcfg.ecam_address(m, 1, 0, 0, 0, 0))
141 case Fail{e}:
142 err(e)
143
144def mu(m: Maybe<&2, U32>) -> String:
145 match m:
146 case Some{a}:
147 U32.show(a)
148 case None{}:
149 "none"
150
151def slit(r: Result<&2, &2, E.AcpiError, Sl.AcpiSlit>) -> String:
152 match r:
153 case Done{+s}:
154 mu(Sl.AcpiSlit.distance(s, 0n, 1n)) ++ " " ++ mu(Sl.AcpiSlit.distance(s, 1n, 1n)) ++ " " ++ mu(Sl.AcpiSlit.distance(s, 2n, 0n))
155 case Fail{e}:
156 err(e)
157
158def sdt(r: Result<&2, &2, E.AcpiError, B.Octets>) -> String:
159 match r:
160 case Done{o}:
161 "ok " ++ Nat.show(B.Octets.len(o))
162 case Fail{e}:
163 err(e)
164
165def rsdp(r: Result<&2, &2, E.AcpiError, P.AcpiRsdp>) -> String:
166 match r:
167 case Done{+p}:
168 "revision " ++ U32.show(P.AcpiRsdp.revision(p)) ++ " xsdt " ++ W.W64.show_hex(P.AcpiRsdp.xsdt_address(p))
169 case Fail{e}:
170 err(e)
171
172def mn(m: Maybe<&2, Nat>) -> String:
173 match m:
174 case Some{n}:
175 Nat.show(n)
176 case None{}:
177 "none"
178
179
180def poke(+o: B.Octets, +i: Nat, +b: U32) -> B.Octets:
181 B.Octets.concat([B.Octets.take(i, o), B.Octets.of_list([b]), B.Octets.drop(1n+i, o)])
182
183
184
185def boot(r: Result<&2, &2, E.AcpiError, Am.AmlSystem<Hs.AmlMemHost>>) -> Am.AmlSystem<Hs.AmlMemHost>:
186 match r:
187 case Done{s}:
188 s
189 case Fail{e}:
190 Am.Aml.mem_system(True{})
191
192def sys() -> Am.AmlSystem<Hs.AmlMemHost>:
193 boot(Am.Aml.boot(~Hs.AmlMemHost, ~Hs.AmlMemHost.io, I.AmlOptions.default(), X.AcpiExample.host(), [X.AcpiExample.dsdt(), X.AcpiExample.ssdt()], 100000n))
194
195def val(r: Result<&2, &2, E.AcpiError, V.AmlValue>) -> String:
196 match r:
197 case Done{v}:
198 V.AmlValue.show(v)
199 case Fail{e}:
200 err(e)
201
202def ev(+s: Am.AmlSystem<Hs.AmlMemHost>, p: String, args: List<&2, V.AmlValue>, n: Nat) -> String:
203 +o = Am.Aml.eval_mem(s, p, args, n)
204 val(Am.AmlOutcome.result(Hs.AmlMemHost, o)) ++ " in " ++ Nat.show(Am.AmlOutcome.steps(Hs.AmlMemHost, o)) ++ " steps"
205
206def hid(m: Maybe<&2, Result<&2, &2, E.AcpiError, String>>) -> String:
207 match m:
208 case None{}:
209 "-"
210 case Some{Done{s}}:
211 s
212 case Some{Fail{e}}:
213 err(e)
214
215def sta(r: Result<&2, &2, E.AcpiError, W.W64>) -> String:
216 match r:
217 case Done{x}:
218 V.AmlValue.show_int(x)
219 case Fail{e}:
220 err(e)
221
222def devs(+s: Am.AmlSystem<Hs.AmlMemHost>, ps: List<&2, String>) -> List<&2, String>:
223 match ps:
224 case Nil{}:
225 Nil{}
226 case Con{+p, t}:
227 Con{p ++ " " ++ hid(Dv.AmlDevice.hid(~Hs.AmlMemHost, ~Hs.AmlMemHost.io, s, p, 1000n)) ++ " " ++ sta(Dv.AmlDevice.status(~Hs.AmlMemHost, ~Hs.AmlMemHost.io, s, p, 1000n)), devs(s, t)}
228
229def res.list(xs: List<&2, Rs.AmlResource>) -> List<&2, String>:
230 match xs:
231 case Nil{}:
232 Nil{}
233 case Con{h, t}:
234 Con{Rs.AmlResource.show(h), res.list(t)}
235
236def crs(r: Result<&2, &2, E.AcpiError, List<&2, Rs.AmlResource>>) -> String:
237 match r:
238 case Done{xs}:
239 String.join(res.list(xs), "; ")
240 case Fail{e}:
241 err(e)
242
243def prt.list(xs: List<&2, Dv.AmlPrtEntry>) -> List<&2, String>:
244 match xs:
245 case Nil{}:
246 Nil{}
247 case Con{Dv.AmlPrtEntry{a, p, s, i}, t}:
248 Con{V.AmlValue.show_int(a) ++ " pin " ++ U32.show(p) ++ " " ++ s ++ " " ++ U32.show(i), prt.list(t)}
249
250def prt(r: Result<&2, &2, E.AcpiError, List<&2, Dv.AmlPrtEntry>>) -> String:
251 match r:
252 case Done{xs}:
253 String.join(prt.list(xs), "; ")
254 case Fail{e}:
255 err(e)
256
257def notes(xs: List<&2, I.AmlNote>) -> List<&2, String>:
258 match xs:
259 case Nil{}:
260 Nil{}
261 case Con{I.AmlNote{p, v}, t}:
262 Con{"Notify(" ++ p ++ ", " ++ V.AmlValue.show_int(v) ++ ")", notes(t)}
263
264def note(+s: Am.AmlSystem<Hs.AmlMemHost>, p: String) -> String:
265 String.join(notes(Am.AmlOutcome.notes(Hs.AmlMemHost, Am.Aml.eval_mem(s, p, Nil{}, 1000n))), "; ")
266
267def log(+s: Am.AmlSystem<Hs.AmlMemHost>, p: String) -> String:
268 Hs.AmlMemHost.show_log(Am.AmlOutcome.host(Hs.AmlMemHost, Am.Aml.eval_mem(s, p, Nil{}, 1000n)))
269
270
271def narrow() -> String:
272 +s = Am.Aml.mem_system(False{})
273 +lo = Am.Aml.load_mem(s, T.AmlT.encode([T.AmlT.method("ONES", 0n, False{}, [T.AmlT.ret(T.AmlT.add(T.AmlT.ones(), T.AmlT.one(), T.AmlT.none()))]), T.AmlT.method("NOT_", 0n, False{}, [T.AmlT.ret(T.AmlT.not(T.AmlT.zero(), T.AmlT.none()))])]), 1000n)
274 +s2 = Am.AmlSystem.after(Hs.AmlMemHost, s, lo)
275 ev(s2, "\\ONES", Nil{}, 100n) ++ ", " ++ ev(s2, "\\NOT_", Nil{}, 100n)
276
277def main() -> IO(Unit):
278 +mem = X.AcpiExample.memory()
279 +s = sys()
280 +madt_o = M.AcpiMadt.build(X.AcpiExample.madt())
281 +rsdp_o = P.AcpiRsdp.build(X.AcpiExample.rsdp())
282 do IO<Unit>:
283 IO.print("rsdp at " ++ mn(P.AcpiRsdp.find(B.Octets.append(B.Octets.zeros(16n), rsdp_o))))
284 IO.print(rsdp(P.AcpiRsdp.parse(rsdp_o)))
285 IO.print(rsdp(P.AcpiRsdp.parse(poke(rsdp_o, 10n, 0))))
286 IO.print(tables(A.AcpiTables.load(~A.AcpiMemImage, ~A.AcpiMemImage.read, mem, X.AcpiExample.rsdp_address())))
287 IO.print(tables(A.AcpiTables.load_with(~A.AcpiMemImage, ~A.AcpiMemImage.read, ~R.AcpiNoExt, ~R.AcpiNoExt.parse, A.AcpiLoadOptions{False{}, R.AcpiRegistry.empty()}, mem, X.AcpiExample.rsdp_address())))
288 IO.print(madt(M.AcpiMadt.parse(madt_o)))
289 IO.print(sdt(H.AcpiSdt.check(madt_o)))
290 IO.print(sdt(H.AcpiSdt.check(poke(madt_o, 40n, 7))))
291 IO.print(sdt(H.AcpiSdt.check(B.Octets.take(30n, madt_o))))
292 IO.print(fadt(F.AcpiFadt.parse(F.AcpiFadt.build(X.AcpiExample.fadt()))))
293 IO.print(hpet(Hp.AcpiHpet.parse(Hp.AcpiHpet.build(X.AcpiExample.hpet()))))
294 IO.print(mcfg(Mc.AcpiMcfg.parse(Mc.AcpiMcfg.build(X.AcpiExample.mcfg()))))
295 IO.print(slit(Sl.AcpiSlit.parse(Sl.AcpiSlit.build(X.AcpiExample.slit()))))
296 IO.print(B.Octets.hex(K.AmlPkgLength.encode(63)) ++ " " ++ B.Octets.hex(K.AmlPkgLength.encode(64)) ++ " " ++ B.Octets.hex(K.AmlPkgLength.encode(4095)) ++ " " ++ B.Octets.hex(K.AmlPkgLength.encode(4096)) ++ " " ++ B.Octets.hex(K.AmlPkgLength.encode(268435455)))
297 IO.print(B.Octets.hex(N.AmlName.encode(N.AmlName.of_text("\\_SB.PCI0.LPCB"))) ++ " " ++ B.Octets.hex(N.AmlName.encode(N.AmlName.of_text("^^_STA"))))
298 IO.print(B.Octets.hex(T.AmlT.encode1(T.AmlT.name("_HID", T.AmlT.eisaid("PNP0A03")))) ++ " " ++ Dv.AmlEisaId.text(T.AmlT.eisaid_value("PNP0C0F")))
299 IO.print(String.join(devs(s, Dv.AmlDevice.list(Am.AmlSystem.ns(Hs.AmlMemHost, s))), ", "))
300 IO.print(crs(Dv.AmlDevice.crs(~Hs.AmlMemHost, ~Hs.AmlMemHost.io, s, "\\_SB_.PCI0", 1000n)))
301 IO.print(crs(Dv.AmlDevice.crs(~Hs.AmlMemHost, ~Hs.AmlMemHost.io, s, "\\_SB_.LNKA", 1000n)))
302 IO.print(log(s, "\\_SB_.LNKA._CRS"))
303 IO.print(prt(Dv.AmlDevice.prt(~Hs.AmlMemHost, ~Hs.AmlMemHost.io, s, "\\_SB_.PCI0", 1000n)))
304 IO.print(ev(s, "\\_TZ_.TZ00._TMP", Nil{}, 1000n))
305 IO.print(ev(s, "\\_SB_.SUM_", [V.AmlInt{W.W64.from_u32(100)}], 100000n))
306 IO.print(ev(s, "\\_SB_.OSYS", Nil{}, 1000n))
307 IO.print(note(s, "\\_SB_.PCI0.LPCB.EC0_._Q01"))
308 IO.print(ev(s, "\\_SB_.SPIN", Nil{}, 1000n))
309 IO.print(ev(s, "\\_SB_.NONE", Nil{}, 1000n))
310 IO.print(narrow())
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339