gas.bend
bend-osdev-acpi@0.1.0.0 · 73 lines · 0 definitions
1# bend-osdev-acpi, gas.bend: the Generic Address Structure (ACPI 6.5,
2# section 5.2.3.2), 12 bytes:
3#
4# offset size field
5# 0 1 Address Space ID (0 system memory, 1 system I/O, 2 PCI
6# configuration space, 3 embedded controller, 4 SMBus,
7# 5 CMOS, 6 PCI BAR target, 7 IPMI, 8 GPIO, 9 generic
8# serial bus, 10 PCC, 11 PRM, 0x7F functional fixed hardware)
9# 1 1 Register Bit Width
10# 2 1 Register Bit Offset
11# 3 1 Access Size (0 undefined, 1 byte, 2 word, 3 dword, 4 qword)
12# 4 8 Address
13import Base
14import bend-osdev-word64@0.1.0.0/word64.bend as W
15import bend-osdev-bytes@0.1.0.0/bytes.bend as B
16import bend-osdev-acpi@0.1.0.0/fields.bend as F
17
18type AcpiGas is Data:
19 AcpiGas{space: U32, bit_width: U32, bit_offset: U32, access_size: U32, address: W.W64}
20
21def AcpiGas.space_memory() -> U32:
22 0
23
24def AcpiGas.space_io() -> U32:
25 1
26
27def AcpiGas.space_pci_config() -> U32:
28 2
29
30def AcpiGas.space_ec() -> U32:
31 3
32
33def AcpiGas.space_ffixedhw() -> U32:
34 127
35
36def AcpiGas.size() -> Nat:
37 12n
38
39# the structure at offset i of o
40def AcpiGas.at(+o: B.Octets, +i: Nat) -> AcpiGas:
41 AcpiGas{F.AcpiF.u8(o, i), F.AcpiF.u8(o, Nat.add(i, 1n)), F.AcpiF.u8(o, Nat.add(i, 2n)), F.AcpiF.u8(o, Nat.add(i, 3n)), F.AcpiF.u64(o, Nat.add(i, 4n))}
42
43def AcpiGas.encode(g: AcpiGas) -> B.Octets:
44 match g:
45 case AcpiGas{s, w, off, a, addr}:
46 B.Octets.append(B.Octets.of_list([s, w, off, a]), B.Octets.le64(addr))
47
48def AcpiGas.zero() -> AcpiGas:
49 AcpiGas{0, 0, 0, 0, W.W64.zero()}
50
51def AcpiGas.address(g: AcpiGas) -> W.W64:
52 match g:
53 case AcpiGas{s, w, off, a, addr}:
54 addr
55
56def AcpiGas.space(g: AcpiGas) -> U32:
57 match g:
58 case AcpiGas{s, w, off, a, addr}:
59 s
60
61# no register: the address is zero
62def AcpiGas.is_null(g: AcpiGas) -> Bool:
63 W.W64.is_zero(AcpiGas.address(g))
64
65# a system I/O register block at a 32-bit port address, n bytes long (how
66# the FADT's ACPI 1.0 block fields are read as Generic Addresses)
67def AcpiGas.io_block(port: U32, n: U32) -> AcpiGas:
68 AcpiGas{1, U32.and(255, U32.mul(n, 8)), 0, 0, W.W64.from_u32(port)}
69
70def AcpiGas.show(g: AcpiGas) -> String:
71 match g:
72 case AcpiGas{s, w, off, a, addr}:
73 "{" ++ U32.show(s) ++ " " ++ U32.show(w) ++ " " ++ U32.show(off) ++ " " ++ U32.show(a) ++ " " ++ W.W64.show_hex(addr) ++ "}"