acpi/dsdt/
objects.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::helpers::*;
5
6pub trait DsdtObject {
7    fn append_to_vec(&self, byte_stream: &mut Vec<u8>);
8
9    fn to_bytes(&self) -> Vec<u8> {
10        let mut byte_stream = Vec::new();
11        self.append_to_vec(&mut byte_stream);
12        byte_stream
13    }
14}
15
16pub struct NamedObject {
17    name: Vec<u8>,
18    object: Vec<u8>,
19}
20
21impl NamedObject {
22    pub fn new(name: &[u8], object: &impl DsdtObject) -> Self {
23        let encoded_name = encode_name(name);
24        assert!(!encoded_name.is_empty());
25        NamedObject {
26            name: encoded_name,
27            object: object.to_bytes(),
28        }
29    }
30}
31
32impl DsdtObject for NamedObject {
33    // A named object consists of the identifier (0x8) followed by the 4-byte name
34    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
35        byte_stream.push(8);
36        byte_stream.extend_from_slice(&self.name);
37        byte_stream.extend_from_slice(&self.object);
38    }
39}
40
41pub struct GenericObject<T: AsRef<[u8]>>(pub T);
42
43impl<T> DsdtObject for GenericObject<T>
44where
45    T: AsRef<[u8]>,
46{
47    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
48        let buffer = self.0.as_ref();
49        byte_stream.extend_from_slice(buffer);
50    }
51}
52
53pub struct NamedInteger {
54    data: NamedObject,
55}
56
57impl NamedInteger {
58    pub fn new(name: &[u8], value: u64) -> Self {
59        Self {
60            data: NamedObject::new(name, &GenericObject(encode_integer(value))),
61        }
62    }
63}
64
65impl DsdtObject for NamedInteger {
66    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
67        self.data.append_to_vec(byte_stream);
68    }
69}
70
71pub struct NamedString {
72    data: NamedObject,
73}
74
75impl NamedString {
76    pub fn new(name: &[u8], value: &[u8]) -> Self {
77        Self {
78            data: NamedObject::new(name, &GenericObject(encode_string(value))),
79        }
80    }
81}
82
83impl DsdtObject for NamedString {
84    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
85        self.data.append_to_vec(byte_stream);
86    }
87}
88
89pub struct StructuredPackage<T: AsRef<[u8]>> {
90    pub elem_count: u8,
91    pub elem_data: T,
92}
93
94impl<T> DsdtObject for StructuredPackage<T>
95where
96    T: AsRef<[u8]>,
97{
98    // A package consists of the identifier (0x12), followed by the length (including itself),
99    // the number of elements (depends on what package contents represent) and the content.
100    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
101        let buffer = self.elem_data.as_ref();
102        byte_stream.push(0x12);
103        byte_stream.extend_from_slice(&encode_package_len(buffer.len() + 1));
104        byte_stream.push(self.elem_count);
105        byte_stream.extend_from_slice(buffer);
106    }
107}
108
109pub struct Package<T: AsRef<[u8]>>(pub T);
110
111impl<T> DsdtObject for Package<T>
112where
113    T: AsRef<[u8]>,
114{
115    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
116        let buffer = self.0.as_ref();
117        StructuredPackage {
118            elem_count: buffer.len() as u8,
119            elem_data: buffer,
120        }
121        .append_to_vec(byte_stream);
122    }
123}
124
125pub struct Buffer<T: AsRef<[u8]>>(pub T);
126
127impl<T> DsdtObject for Buffer<T>
128where
129    T: AsRef<[u8]>,
130{
131    // A buffer consists of the identifier (0x11), followed by the length (including itself), followed by the size of
132    // the buffer in bytes and then the content.
133    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
134        let buffer = self.0.as_ref();
135        let encoded_len = encode_integer(buffer.len().try_into().unwrap());
136        byte_stream.push(0x11);
137        byte_stream.extend_from_slice(&encode_package_len(buffer.len() + encoded_len.len()));
138        byte_stream.extend_from_slice(&encoded_len);
139        byte_stream.extend_from_slice(buffer);
140    }
141}
142
143#[cfg(test)]
144mod tests {
145    use super::*;
146    use crate::dsdt::tests::verify_expected_bytes;
147
148    #[test]
149    fn verify_package() {
150        let package = Package(vec![1, 2, 3, 4]);
151        let bytes = package.to_bytes();
152        verify_expected_bytes(&bytes, &[0x12, 6, 4, 1, 2, 3, 4]);
153    }
154
155    #[test]
156    fn verify_large_package() {
157        let package = Package(vec![0; 0xff]);
158        let bytes = package.to_bytes();
159        assert_eq!(bytes.len(), 0xff + 4);
160        verify_expected_bytes(&bytes[..5], &[0x12, (1 << 6) | 2, 0x10, 0xff, 0]);
161        assert_eq!(bytes[0xff + 3], 0);
162    }
163
164    #[test]
165    fn verify_named_object() {
166        let package = Package(vec![0]);
167        let nobj = NamedObject::new(b"FOO", &package);
168        let bytes = nobj.to_bytes();
169        verify_expected_bytes(&bytes, &[8, b'F', b'O', b'O', b'_', 0x12, 3, 1, 0]);
170    }
171
172    #[test]
173    fn verify_named_integers() {
174        let nobj = NamedInteger::new(b"FOO", 0);
175        let bytes = nobj.to_bytes();
176        verify_expected_bytes(&bytes, &[8, b'F', b'O', b'O', b'_', 0]);
177
178        let nobj = NamedInteger::new(b"FOO", 1);
179        let bytes = nobj.to_bytes();
180        verify_expected_bytes(&bytes, &[8, b'F', b'O', b'O', b'_', 1]);
181
182        let nobj = NamedInteger::new(b"FOO", 2);
183        let bytes = nobj.to_bytes();
184        verify_expected_bytes(&bytes, &[8, b'F', b'O', b'O', b'_', 0xa, 2]);
185
186        let nobj = NamedInteger::new(b"FOO", 0x100);
187        let bytes = nobj.to_bytes();
188        verify_expected_bytes(&bytes, &[8, b'F', b'O', b'O', b'_', 0xb, 0x00, 0x01]);
189
190        let nobj = NamedInteger::new(b"FOO", 0x10000);
191        let bytes = nobj.to_bytes();
192        verify_expected_bytes(
193            &bytes,
194            &[8, b'F', b'O', b'O', b'_', 0xc, 0x00, 0x00, 0x01, 0x00],
195        );
196
197        let nobj = NamedInteger::new(b"FOO", 0x100000000);
198        let bytes = nobj.to_bytes();
199        verify_expected_bytes(
200            &bytes,
201            &[
202                8, b'F', b'O', b'O', b'_', 0xe, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
203            ],
204        );
205    }
206
207    #[test]
208    fn verify_named_string() {
209        let nobj = NamedString::new(b"FOO", b"hello");
210        let bytes = nobj.to_bytes();
211        verify_expected_bytes(
212            &bytes,
213            &[
214                8, b'F', b'O', b'O', b'_', 0xd, b'h', b'e', b'l', b'l', b'o', 0,
215            ],
216        );
217    }
218}