1use super::helpers::*;
7use super::objects::*;
8use super::ops::*;
9
10pub struct Method {
12 pub name: [u8; 4],
13 pub sync_level: u8,
14 pub is_serialized: bool,
15 pub arg_count: u8,
16 operations: Vec<u8>,
17}
18
19impl Method {
20 pub fn new(name: &[u8; 4]) -> Self {
22 let local_name: [u8; 4] = [name[0], name[1], name[2], name[3]];
23 Self {
24 name: local_name,
25 sync_level: 0,
26 is_serialized: false,
27 arg_count: 0,
28 operations: vec![],
29 }
30 }
31
32 pub fn set_arg_count(&mut self, arg_count: u8) {
34 self.arg_count = arg_count;
35 }
36
37 pub fn add_operation(&mut self, op: &impl OperationObject) {
39 op.append_to_vec(&mut self.operations);
40 }
41}
42
43impl AmlObject for Method {
44 fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
45 byte_stream.push(0x14);
46 byte_stream.extend_from_slice(&encode_package_len(5 + self.operations.len()));
47 byte_stream.extend_from_slice(&self.name);
48 byte_stream.push(
49 self.sync_level << 4 | if self.is_serialized { 1 << 3 } else { 0 } | self.arg_count,
50 );
51 byte_stream.extend_from_slice(&self.operations);
52 }
53}
54
55pub struct Device {
57 name: Vec<u8>,
58 objects: Vec<u8>,
59}
60
61impl Device {
62 pub fn new(name: &[u8]) -> Self {
64 Self {
65 name: encode_name(name),
66 objects: vec![],
67 }
68 }
69
70 pub fn add_object(&mut self, obj: &impl AmlObject) {
72 obj.append_to_vec(&mut self.objects);
73 }
74}
75
76impl AmlObject for Device {
77 fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
80 byte_stream.push(0x5b);
81 byte_stream.push(0x82);
82 let length = self.name.len() + self.objects.len();
83 byte_stream.extend_from_slice(&encode_package_len(length));
84 byte_stream.extend_from_slice(&self.name);
85 byte_stream.extend_from_slice(&self.objects);
86 }
87}
88
89pub struct EisaId(pub [u8; 7]);
91
92impl AmlObject for EisaId {
93 fn append_to_vec(&self, byte_stream: &mut Vec<u8>) {
94 let mut id: [u8; 4] = [0; 4];
95 id[0] = (self.0[0] - b'@') << 2 | (self.0[1] - b'@') >> 3;
96 id[1] = (self.0[1] & 7) << 5 | (self.0[2] - b'@');
97 id[2] = char_to_hex(self.0[3]) << 4 | char_to_hex(self.0[4]);
98 id[3] = char_to_hex(self.0[5]) << 4 | char_to_hex(self.0[6]);
99 byte_stream.append(&mut encode_integer(u32::from_le_bytes(id) as u64));
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106 use crate::aml::test_helpers::verify_expected_bytes;
107
108 #[test]
109 fn verify_eisaid() {
110 let eisa_id = EisaId(*b"PNP0003");
111 let bytes = eisa_id.to_bytes();
112 verify_expected_bytes(&bytes, &[0xc, 0x41, 0xd0, 0, 0x3]);
113 }
114
115 #[test]
116 fn verify_method() {
117 let op = AndOp {
118 operand1: vec![b'S', b'T', b'A', b'_'],
119 operand2: encode_integer(13),
120 target_name: vec![b'S', b'T', b'A', b'_'],
121 };
122 let mut method = Method::new(b"_DIS");
123 method.add_operation(&op);
124 let bytes = method.to_bytes();
125 verify_expected_bytes(
126 &bytes,
127 &[
128 0x14, 0x11, 0x5F, 0x44, 0x49, 0x53, 0x00, 0x7b, b'S', b'T', b'A', b'_', 0x0a, 0x0d,
129 b'S', b'T', b'A', b'_',
130 ],
131 );
132 }
133
134 #[test]
135 fn verify_device_object() {
136 let package = Package(vec![0]);
137 let nobj = NamedObject::new(b"FOO", &package);
138 let mut device = Device::new(b"DEV");
139 device.add_object(&nobj);
140 let bytes = device.to_bytes();
141 verify_expected_bytes(
142 &bytes,
143 &[
144 0x5b, 0x82, 14, b'D', b'E', b'V', b'_', 8, b'F', b'O', b'O', b'_', 0x12, 3, 1, 0,
145 ],
146 );
147 }
148}