aml_ns.bend
bend-osdev-acpi@0.1.1.0 · 247 lines · 29 definitions
1
2
3
4
5
6
7
8
9import Base
10import bend-osdev-word64@0.1.1.0/word64.bend as W
11import bend-osdev-bytes@0.1.1.0/bytes.bend as B
12import bend-osdev-acpi@0.1.1.0/error.bend as E
13import bend-osdev-acpi@0.1.1.0/aml_name.bend as N
14import bend-osdev-acpi@0.1.1.0/aml_value.bend as V
15
16type AmlObject is Data:
17
18 AmlOData{v: V.AmlValue}
19
20 AmlOMethod{nargs: Nat, flags: U32, body: B.Octets}
21
22
23 AmlOScope{kind: U32}
24
25
26 AmlORegion{space: U32, offset: W.W64, length: W.W64, parent: String}
27
28
29 AmlOField{region: String, bit_off: Nat, bits: Nat, flags: U32}
30
31 AmlOIndexField{index: String, data: String, bit_off: Nat, bits: Nat, flags: U32}
32
33
34 AmlOBufField{buf: V.AmlLoc, bit_off: Nat, bits: Nat}
35 AmlOMutex{sync: U32}
36 AmlOEvent{}
37 AmlOAlias{target: String}
38
39 AmlOBuiltin{id: U32}
40
41 AmlOExternal{kind: U32}
42
43type AmlNs is Data:
44 AmlNs{objs: Map<&2, AmlObject>}
45
46def AmlObject.type(o: AmlObject) -> U32:
47 match o:
48 case AmlOData{v}:
49 V.AmlValue.type(v)
50 case AmlOMethod{n, f, b}:
51 8
52 case AmlOScope{k}:
53 k
54 case AmlORegion{s, off, l, p}:
55 10
56 case AmlOField{r, o2, n, f}:
57 5
58 case AmlOIndexField{i, d, o2, n, f}:
59 5
60 case AmlOBufField{b, o2, n}:
61 14
62 case AmlOMutex{s}:
63 9
64 case AmlOEvent{}:
65 7
66 case AmlOAlias{t}:
67 0
68 case AmlOBuiltin{i}:
69 8
70 case AmlOExternal{k}:
71 k
72
73
74
75def AmlPath.root() -> String:
76 "\\"
77
78def AmlPath.is_root(+p: String) -> Bool:
79 String.eq(p, "\\")
80
81def ns.child.pick(root: Bool, scope: String, seg: String) -> String:
82 match root:
83 case True{}:
84 "\\" ++ seg
85 case False{}:
86 scope ++ "." ++ seg
87
88def ns.parent.pick(top: Bool, +p: String) -> String:
89 match top:
90 case True{}:
91 "\\"
92 case False{}:
93 String.take(p, Nat.sub(String.length(p), 5n))
94
95
96
97
98
99
100def AmlPath.child(+scope: String, seg: String) -> String:
101 ns.child.pick(AmlPath.is_root(scope), scope, seg)
102
103def AmlPath.parent(+p: String) -> String:
104 ns.parent.pick(Nat.is_le(String.length(p), 5n), p)
105
106def AmlPath.last(+p: String) -> String:
107 String.drop(p, Nat.sub(String.length(p), 4n))
108
109def ns.ups(n: Nat, +p: String) -> String:
110 match n:
111 case 0n:
112 p
113 case 1n+k:
114 ns.ups(k, AmlPath.parent(p))
115
116def ns.segs(ss: List<&2, B.Octets>, +p: String) -> String:
117 match ss:
118 case Nil{}:
119 p
120 case Con{s, t}:
121 ns.segs(t, AmlPath.child(p, B.Octets.to_string(s)))
122
123def ns.of_name.pick(root: Bool, u: Nat, +scope: String, ss: List<&2, B.Octets>) -> String:
124 match root:
125 case True{}:
126 ns.segs(ss, "\\")
127 case False{}:
128 ns.segs(ss, ns.ups(u, scope))
129
130
131
132
133
134
135def AmlPath.of_name(+scope: String, n: N.AmlName) -> String:
136 match n:
137 case N.AmlName{r, u, ss}:
138 ns.of_name.pick(r, u, scope, ss)
139
140def AmlNs.empty() -> AmlNs:
141 AmlNs{Map.new(&2, AmlObject)}
142
143def ns.snd.bool(r: Map<&2, AmlObject> & Bool) -> Bool:
144 (m, b) = r
145 b
146
147
148def ns.snd.obj(r: Map<&2, AmlObject> & AmlObject) -> AmlObject:
149 (m, o) = r
150 o
151
152
153def ns.got(has: Bool, +m: Map<&2, AmlObject>, +p: String) -> Maybe<&2, AmlObject>:
154 match has:
155 case True{}:
156 Some{ns.snd.obj(Map.get(AmlObject, AmlOEvent{}, m, p))}
157 case False{}:
158 None{}
159
160
161
162def AmlNs.has(ns: AmlNs, +p: String) -> Bool:
163 match ns:
164 case AmlNs{m}:
165 ns.snd.bool(Map.has(&2, AmlObject, m, p))
166
167
168def AmlNs.get(ns: AmlNs, +p: String) -> Maybe<&2, AmlObject>:
169 match ns:
170 case AmlNs{+m}:
171 ns.got(ns.snd.bool(Map.has(&2, AmlObject, m, p)), m, p)
172
173def AmlNs.set(ns: AmlNs, p: String, o: AmlObject) -> AmlNs:
174 match ns:
175 case AmlNs{m}:
176 AmlNs{Map.set(&2, AmlObject, m, p, o)}
177
178def AmlNs.remove(ns: AmlNs, p: String) -> AmlNs:
179 match ns:
180 case AmlNs{m}:
181 AmlNs{Map.del(&2, AmlObject, m, p)}
182
183
184def AmlNs.paths(ns: AmlNs) -> List<&2, String>:
185 match ns:
186 case AmlNs{m}:
187 List.sort(~String, ~String.is_le, Map.keys(&2, AmlObject, m))
188
189
190
191def ns.search.go(n: Nat, hit: Bool, top: Bool, +ns: AmlNs, +scope: String, +seg: String) -> Maybe<&2, String>:
192 match n:
193 case 0n:
194 None{}
195 case 1n+k:
196 match hit:
197 case True{}:
198 Some{AmlPath.child(scope, seg)}
199 case False{}:
200 match top:
201 case True{}:
202 None{}
203 case False{}:
204 +up = AmlPath.parent(scope)
205 ns.search.go(k, AmlNs.has(ns, AmlPath.child(up, seg)), AmlPath.is_root(up), ns, up, seg)
206
207def ns.single(ss: List<&2, B.Octets>) -> String:
208 match ss:
209 case Con{s, t}:
210 B.Octets.to_string(s)
211 case Nil{}:
212 ""
213
214
215def ns.exists(hit: Bool, p: String) -> Maybe<&2, String>:
216 match hit:
217 case True{}:
218 Some{p}
219 case False{}:
220 None{}
221
222
223
224
225
226def ns.resolve.pick(single: Bool, +ns: AmlNs, +scope: String, +n: N.AmlName) -> Maybe<&2, String>:
227 match single:
228 case True{}:
229 +seg = ns.single(N.AmlName.segs(n))
230 ns.search.go(String.length(scope), AmlNs.has(ns, AmlPath.child(scope, seg)), AmlPath.is_root(scope), ns, scope, seg)
231 case False{}:
232 +p = AmlPath.of_name(scope, n)
233 ns.exists(AmlNs.has(ns, p), p)
234
235
236
237
238def AmlNs.resolve(+ns: AmlNs, +scope: String, +n: N.AmlName) -> Maybe<&2, String>:
239 match n:
240 case N.AmlName{r, u, +ss}:
241 ns.resolve.pick(Bool.and(Bool.not(r), Bool.and(Nat.is_eq(u, 0n), Nat.is_eq(List.length(&2, B.Octets, ss), 1n))), ns, scope, N.AmlName{r, u, ss})
242
243def AmlNs.initial(os: String, rev: U32) -> AmlNs:
244 +a = AmlNs.set(AmlNs.empty(), "\\", AmlOScope{0})
245 +b = AmlNs.set(AmlNs.set(AmlNs.set(a, "\\_GPE", AmlOScope{0}), "\\_PR_", AmlOScope{0}), "\\_SB_", AmlOScope{6})
246 +c = AmlNs.set(AmlNs.set(b, "\\_SI_", AmlOScope{0}), "\\_TZ_", AmlOScope{0})
247 AmlNs.set(AmlNs.set(AmlNs.set(c, "\\_OS_", AmlOData{V.AmlStr{B.Octets.of_string(os)}}), "\\_REV", AmlOData{V.AmlInt{W.W64.from_u32(rev)}}), "\\_OSI", AmlOBuiltin{1})