aml_device.bend
bend-osdev-acpi@0.1.1.0 · 177 lines · 23 definitions
1
2
3
4
5
6import Base
7import bend-osdev-word64@0.1.1.0/word64.bend as W
8import bend-osdev-bytes@0.1.1.0/bytes.bend as B
9import bend-osdev-acpi@0.1.1.0/error.bend as E
10import bend-osdev-acpi@0.1.1.0/aml_value.bend as V
11import bend-osdev-acpi@0.1.1.0/aml_ns.bend as S
12import bend-osdev-acpi@0.1.1.0/aml_host.bend as Hs
13import bend-osdev-acpi@0.1.1.0/aml_interp.bend as I
14import bend-osdev-acpi@0.1.1.0/aml.bend as A
15import bend-osdev-acpi@0.1.1.0/aml_resource.bend as R
16
17
18
19
20def dv.hex.pick(lt: Bool, +d: U32) -> U32:
21 match lt:
22 case True{}:
23 U32.add(48, d)
24 case False{}:
25 U32.add(55, d)
26
27def dv.hex(+d: U32) -> U32:
28 dv.hex.pick(U32.is_lt(d, 10), d)
29
30def AmlEisaId.text(+v: U32) -> String:
31 +id = U32.or(U32.or(U32.shln(U32.and(v, 255), 24n), U32.shln(U32.and(U32.shrn(v, 8n), 255), 16n)), U32.or(U32.shln(U32.and(U32.shrn(v, 16n), 255), 8n), U32.and(U32.shrn(v, 24n), 255)))
32 B.to_string([U32.add(64, U32.and(U32.shrn(id, 26n), 31)), U32.add(64, U32.and(U32.shrn(id, 21n), 31)), U32.add(64, U32.and(U32.shrn(id, 16n), 31)), dv.hex(U32.and(U32.shrn(id, 12n), 15)), dv.hex(U32.and(U32.shrn(id, 8n), 15)), dv.hex(U32.and(U32.shrn(id, 4n), 15)), dv.hex(U32.and(id, 15))])
33
34
35
36def dv.get.pick(~H: Data, ~io: H -> Hs.AmlHostOp -> Result<&2, &2, E.AcpiError, Hs.AmlHostAns<H>>, has: Bool, +s: A.AmlSystem<H>, +p: String, +n: Nat) -> Maybe<&2, Result<&2, &2, E.AcpiError, V.AmlValue>>:
37 match has:
38 case True{}:
39 Some{A.AmlOutcome.result(H, A.Aml.eval(~H, ~io, s, p, Nil{}, n))}
40 case False{}:
41 None{}
42
43
44
45def AmlDevice.get(~H: Data, ~io: H -> Hs.AmlHostOp -> Result<&2, &2, E.AcpiError, Hs.AmlHostAns<H>>, +s: A.AmlSystem<H>, +dev: String, +seg: String, +n: Nat) -> Maybe<&2, Result<&2, &2, E.AcpiError, V.AmlValue>>:
46 +p = S.AmlPath.child(dev, seg)
47 dv.get.pick(~H, ~io, S.AmlNs.has(A.AmlSystem.ns(H, s), p), s, p, n)
48
49def dv.sta(m: Maybe<&2, Result<&2, &2, E.AcpiError, V.AmlValue>>) -> Result<&2, &2, E.AcpiError, W.W64>:
50 match m:
51 case None{}:
52 Done{W.W64.from_u32(15)}
53 case Some{Fail{e}}:
54 Fail{e}
55 case Some{Done{v}}:
56 V.AmlValue.to_int(True{}, v)
57
58
59
60def AmlDevice.status(~H: Data, ~io: H -> Hs.AmlHostOp -> Result<&2, &2, E.AcpiError, Hs.AmlHostAns<H>>, +s: A.AmlSystem<H>, +dev: String, +n: Nat) -> Result<&2, &2, E.AcpiError, W.W64>:
61 dv.sta(AmlDevice.get(~H, ~io, s, dev, "_STA", n))
62
63def dv.id(v: V.AmlValue) -> Result<&2, &2, E.AcpiError, String>:
64 match v:
65 case V.AmlInt{x}:
66 Done{AmlEisaId.text(W.W64.lo(x))}
67 case V.AmlStr{t}:
68 Done{B.Octets.to_string(t)}
69 case _:
70 Fail{E.AcpiAmlBadType{"_HID is not an integer or a string"}}
71
72def dv.hid(m: Maybe<&2, Result<&2, &2, E.AcpiError, V.AmlValue>>) -> Maybe<&2, Result<&2, &2, E.AcpiError, String>>:
73 match m:
74 case None{}:
75 None{}
76 case Some{Fail{e}}:
77 Some{Fail{e}}
78 case Some{Done{v}}:
79 Some{dv.id(v)}
80
81
82def AmlDevice.hid(~H: Data, ~io: H -> Hs.AmlHostOp -> Result<&2, &2, E.AcpiError, Hs.AmlHostAns<H>>, +s: A.AmlSystem<H>, +dev: String, +n: Nat) -> Maybe<&2, Result<&2, &2, E.AcpiError, String>>:
83 dv.hid(AmlDevice.get(~H, ~io, s, dev, "_HID", n))
84
85def dv.crs(m: Maybe<&2, Result<&2, &2, E.AcpiError, V.AmlValue>>) -> Result<&2, &2, E.AcpiError, List<&2, R.AmlResource>>:
86 match m:
87 case None{}:
88 Done{Nil{}}
89 case Some{Fail{e}}:
90 Fail{e}
91 case Some{Done{V.AmlBuf{b}}}:
92 R.AmlResource.parse(b)
93 case Some{Done{v}}:
94 Fail{E.AcpiAmlBadType{"_CRS is not a buffer"}}
95
96
97def AmlDevice.crs(~H: Data, ~io: H -> Hs.AmlHostOp -> Result<&2, &2, E.AcpiError, Hs.AmlHostAns<H>>, +s: A.AmlSystem<H>, +dev: String, +n: Nat) -> Result<&2, &2, E.AcpiError, List<&2, R.AmlResource>>:
98 dv.crs(AmlDevice.get(~H, ~io, s, dev, "_CRS", n))
99
100
101
102
103
104type AmlPrtEntry is Data:
105 AmlPrtEntry{address: W.W64, pin: U32, source: String, index: U32}
106
107def dv.prt.src(v: V.AmlValue) -> String:
108 match v:
109 case V.AmlRef{V.AmlLName{p}}:
110 p
111 case V.AmlStr{t}:
112 B.Octets.to_string(t)
113 case _:
114 ""
115
116def dv.prt.one(v: V.AmlValue) -> Result<&2, &2, E.AcpiError, AmlPrtEntry>:
117 match v:
118 case V.AmlPkg{[V.AmlInt{a}, V.AmlInt{p}, src, V.AmlInt{i}]}:
119 Done{AmlPrtEntry{a, W.W64.lo(p), dv.prt.src(src), W.W64.lo(i)}}
120 case _:
121 Fail{E.AcpiAmlBadType{"a _PRT entry is not a package of four"}}
122
123def dv.prt.cons(r: Result<&2, &2, E.AcpiError, AmlPrtEntry>, rs: Result<&2, &2, E.AcpiError, List<&2, AmlPrtEntry>>) -> Result<&2, &2, E.AcpiError, List<&2, AmlPrtEntry>>:
124 match r rs:
125 case Done{e} Done{es}:
126 Done{Con{e, es}}
127 case Fail{e} _:
128 Fail{e}
129 case Done{e} Fail{x}:
130 Fail{x}
131
132def dv.prt.all(xs: List<&2, V.AmlValue>) -> Result<&2, &2, E.AcpiError, List<&2, AmlPrtEntry>>:
133 match xs:
134 case Nil{}:
135 Done{Nil{}}
136 case Con{x, t}:
137 dv.prt.cons(dv.prt.one(x), dv.prt.all(t))
138
139def dv.prt(m: Maybe<&2, Result<&2, &2, E.AcpiError, V.AmlValue>>) -> Result<&2, &2, E.AcpiError, List<&2, AmlPrtEntry>>:
140 match m:
141 case None{}:
142 Done{Nil{}}
143 case Some{Fail{e}}:
144 Fail{e}
145 case Some{Done{V.AmlPkg{xs}}}:
146 dv.prt.all(xs)
147 case Some{Done{v}}:
148 Fail{E.AcpiAmlBadType{"_PRT is not a package"}}
149
150
151def AmlDevice.prt(~H: Data, ~io: H -> Hs.AmlHostOp -> Result<&2, &2, E.AcpiError, Hs.AmlHostAns<H>>, +s: A.AmlSystem<H>, +dev: String, +n: Nat) -> Result<&2, &2, E.AcpiError, List<&2, AmlPrtEntry>>:
152 dv.prt(AmlDevice.get(~H, ~io, s, dev, "_PRT", n))
153
154def dv.kind(o: Maybe<&2, S.AmlObject>) -> U32:
155 match o:
156 case Some{x}:
157 S.AmlObject.type(x)
158 case None{}:
159 0
160
161def dv.devs.pick(dev: Bool, p: String, rest: List<&2, String>) -> List<&2, String>:
162 match dev:
163 case True{}:
164 Con{p, rest}
165 case False{}:
166 rest
167
168def dv.devs(ps: List<&2, String>, +ns: S.AmlNs) -> List<&2, String>:
169 match ps:
170 case Nil{}:
171 Nil{}
172 case Con{+p, t}:
173 dv.devs.pick(U32.is_eq(dv.kind(S.AmlNs.get(ns, p)), 6), p, dv.devs(t, ns))
174
175
176def AmlDevice.list(+ns: S.AmlNs) -> List<&2, String>:
177 dv.devs(S.AmlNs.paths(ns), ns)