aml_host.bend
bend-osdev-acpi@0.1.1.0 · 139 lines · 21 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import Base
25import bend-osdev-word64@0.1.1.0/word64.bend as W
26import bend-osdev-bytes@0.1.1.0/bytes.bend as B
27import bend-osdev-acpi@0.1.1.0/error.bend as E
28
29type AmlAccess is Data:
30 AmlAccess{space: U32, address: W.W64, width: Nat}
31
32type AmlHostOp is Data:
33 AmlHRead{a: AmlAccess}
34 AmlHWrite{a: AmlAccess, v: W.W64}
35
36type AmlHostAns<-H: Data> is Data:
37 AmlHostAns{host: H, value: W.W64}
38
39def AmlPci.address(seg: U32, bus: U32, dev: U32, fun: U32, off: U32) -> W.W64:
40 W.W64.from_parts(U32.or(U32.shln(U32.and(seg, 255), 24n), U32.or(U32.shln(U32.and(bus, 255), 16n), U32.and(dev, 65535))), U32.or(U32.shln(U32.and(fun, 65535), 16n), U32.and(off, 65535)))
41
42
43
44type AmlMemHost is Data:
45 AmlMemHost{bytes: Map<&2, U32>, log: List<&2, AmlHostOp>}
46
47def AmlMemHost.new() -> AmlMemHost:
48 AmlMemHost{Map.new(&2, U32), Nil{}}
49
50def hst.key(+space: U32, +a: W.W64) -> String:
51 U32.show(space) ++ ":" ++ W.W64.show_hex(a)
52
53def hst.snd(r: Map<&2, U32> & U32) -> U32:
54 (m, v) = r
55 v
56
57def hst.byte(+m: Map<&2, U32>, +space: U32, +a: W.W64) -> U32:
58 hst.snd(Map.get(U32, 0, m, hst.key(space, a)))
59
60
61def hst.rd(n: Nat, +m: Map<&2, U32>, +space: U32, +a: W.W64, +sh: Nat, acc: W.W64) -> W.W64:
62 match n:
63 case 0n:
64 acc
65 case 1n+p:
66 hst.rd(p, m, space, W.W64.add(a, W.W64.one()), Nat.add(sh, 8n), W.W64.or(acc, W.W64.shl(W.W64.from_u32(hst.byte(m, space, a)), sh)))
67
68def hst.wr(n: Nat, m: Map<&2, U32>, +space: U32, +a: W.W64, +v: W.W64) -> Map<&2, U32>:
69 match n:
70 case 0n:
71 m
72 case 1n+p:
73 hst.wr(p, Map.set(&2, U32, m, hst.key(space, a), U32.and(W.W64.lo(v), 255)), space, W.W64.add(a, W.W64.one()), W.W64.shr(v, 8n))
74
75def hst.go(h: AmlMemHost, op: AmlHostOp) -> Result<&2, &2, E.AcpiError, AmlHostAns<AmlMemHost>>:
76 match h op:
77 case AmlMemHost{+m, log} AmlHRead{AmlAccess{+s, +a, +w}}:
78 Done{AmlHostAns{AmlMemHost{m, Con{AmlHRead{AmlAccess{s, a, w}}, log}}, hst.rd(Nat.div(w, 8n), m, s, a, 0n, W.W64.zero())}}
79 case AmlMemHost{m, log} AmlHWrite{AmlAccess{+s, +a, +w}, +v}:
80 Done{AmlHostAns{AmlMemHost{hst.wr(Nat.div(w, 8n), m, s, a, v), Con{AmlHWrite{AmlAccess{s, a, w}, v}, log}}, v}}
81
82
83
84def AmlMemHost.io(h: AmlMemHost, op: AmlHostOp) -> Result<&2, &2, E.AcpiError, AmlHostAns<AmlMemHost>>:
85 hst.go(h, op)
86
87def hst.load(xs: List<&2, U32>, m: Map<&2, U32>, +space: U32, +a: W.W64) -> Map<&2, U32>:
88 match xs:
89 case Nil{}:
90 m
91 case Con{x, t}:
92 hst.load(t, Map.set(&2, U32, m, hst.key(space, a), x), space, W.W64.add(a, W.W64.one()))
93
94
95def AmlMemHost.poke(h: AmlMemHost, +space: U32, +a: W.W64, o: B.Octets) -> AmlMemHost:
96 match h:
97 case AmlMemHost{m, log}:
98 AmlMemHost{hst.load(B.Octets.to_list(o), m, space, a), log}
99
100
101def AmlMemHost.peek(h: AmlMemHost, +space: U32, +a: W.W64) -> U32:
102 match h:
103 case AmlMemHost{+m, log}:
104 hst.byte(m, space, a)
105
106def hst.rev(xs: List<&2, AmlHostOp>, acc: List<&2, AmlHostOp>) -> List<&2, AmlHostOp>:
107 match xs:
108 case Nil{}:
109 acc
110 case Con{x, t}:
111 hst.rev(t, Con{x, acc})
112
113
114def AmlMemHost.log(h: AmlMemHost) -> List<&2, AmlHostOp>:
115 match h:
116 case AmlMemHost{m, log}:
117 hst.rev(log, Nil{})
118
119def AmlHostOp.show(op: AmlHostOp) -> String:
120 match op:
121 case AmlHRead{AmlAccess{s, a, w}}:
122 "read " ++ U32.show(s) ++ ":" ++ W.W64.show_hex(a) ++ "/" ++ Nat.show(w)
123 case AmlHWrite{AmlAccess{s, a, w}, v}:
124 "write " ++ U32.show(s) ++ ":" ++ W.W64.show_hex(a) ++ "/" ++ Nat.show(w) ++ " " ++ W.W64.show_hex(v)
125
126def hst.show(xs: List<&2, AmlHostOp>, first: Bool) -> String:
127 match xs:
128 case Nil{}:
129 ""
130 case Con{x, t}:
131 match first:
132 case True{}:
133 AmlHostOp.show(x) ++ hst.show(t, False{})
134 case False{}:
135 "; " ++ AmlHostOp.show(x) ++ hst.show(t, False{})
136
137
138def AmlMemHost.show_log(h: AmlMemHost) -> String:
139 hst.show(AmlMemHost.log(h), True{})