acpi/aml/
ops.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Utilities for encoding procedural operations into ACPI
5//! Machine Language (AML).
6
7/// An AML operation.
8pub trait OperationObject {
9    fn append_to_vec(&self, byte_stream: &mut Vec<u8>);
10
11    fn to_bytes(&self) -> Vec<u8> {
12        let mut byte_stream = Vec::new();
13        self.append_to_vec(&mut byte_stream);
14        byte_stream
15    }
16}
17
18/// A bitwise AND AML operation.
19pub struct AndOp {
20    pub operand1: Vec<u8>,
21    pub operand2: Vec<u8>,
22    pub target_name: Vec<u8>,
23}
24
25impl OperationObject for AndOp {
26    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
27        byte_stream.push(0x7b);
28        byte_stream.extend_from_slice(&self.operand1);
29        byte_stream.extend_from_slice(&self.operand2);
30        byte_stream.extend_from_slice(&self.target_name);
31    }
32}
33
34/// A bitwise OR AML operation.
35pub struct OrOp {
36    pub operand1: Vec<u8>,
37    pub operand2: Vec<u8>,
38    pub target_name: Vec<u8>,
39}
40
41impl OperationObject for OrOp {
42    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
43        byte_stream.push(0x7d);
44        byte_stream.extend_from_slice(&self.operand1);
45        byte_stream.extend_from_slice(&self.operand2);
46        byte_stream.extend_from_slice(&self.target_name);
47    }
48}
49
50/// An AML operation to return from a procedure.
51pub struct ReturnOp {
52    pub result: Vec<u8>,
53}
54
55impl OperationObject for ReturnOp {
56    fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
57        byte_stream.push(0xa4);
58        byte_stream.extend_from_slice(&self.result);
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65    use crate::aml::encode_integer;
66    use crate::aml::test_helpers::verify_expected_bytes;
67
68    #[test]
69    fn verify_and_operation() {
70        let op = AndOp {
71            operand1: vec![b'S', b'T', b'A', b'_'],
72            operand2: encode_integer(13),
73            target_name: vec![b'S', b'T', b'A', b'_'],
74        };
75        let bytes = op.to_bytes();
76        verify_expected_bytes(
77            &bytes,
78            &[
79                0x7b, b'S', b'T', b'A', b'_', 0x0a, 0x0d, b'S', b'T', b'A', b'_',
80            ],
81        );
82    }
83
84    #[test]
85    fn verify_or_operation() {
86        let op = OrOp {
87            operand1: vec![b'S', b'T', b'A', b'_'],
88            operand2: encode_integer(13),
89            target_name: vec![b'S', b'T', b'A', b'_'],
90        };
91        let bytes = op.to_bytes();
92        verify_expected_bytes(
93            &bytes,
94            &[
95                0x7d, b'S', b'T', b'A', b'_', 0x0a, 0x0d, b'S', b'T', b'A', b'_',
96            ],
97        );
98    }
99
100    #[test]
101    fn verify_return_operation() {
102        let op = ReturnOp {
103            result: vec![b'S', b'T', b'A', b'_'],
104        };
105        let bytes = op.to_bytes();
106        verify_expected_bytes(&bytes, &[0xa4, b'S', b'T', b'A', b'_']);
107    }
108}