gas.bend

bend-osdev-acpi@0.1.2.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.1.1/word64.bend as W
15import bend-osdev-bytes@0.1.1.1/bytes.bend as B
16import bend-osdev-acpi@0.1.2.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) ++ "}"