xref: /aosp_15_r20/external/crosvm/acpi_tables/src/aml.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2020 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 /// The trait Aml can be implemented by the ACPI objects to translate itself
6 /// into the AML raw data. So that these AML raw data can be added into the
7 /// ACPI DSDT for guest.
8 pub trait Aml {
9     /// Translate an ACPI object into AML code and append to the vector
10     /// buffer.
11     /// * `bytes` - The vector used to append the AML code.
to_aml_bytes(&self, bytes: &mut Vec<u8>)12     fn to_aml_bytes(&self, bytes: &mut Vec<u8>);
13 }
14 
15 // AML byte stream defines
16 const ZEROOP: u8 = 0x00;
17 const ONEOP: u8 = 0x01;
18 const NAMEOP: u8 = 0x08;
19 const BYTEPREFIX: u8 = 0x0a;
20 const WORDPREFIX: u8 = 0x0b;
21 const DWORDPREFIX: u8 = 0x0c;
22 const STRINGOP: u8 = 0x0d;
23 const QWORDPREFIX: u8 = 0x0e;
24 const SCOPEOP: u8 = 0x10;
25 const BUFFEROP: u8 = 0x11;
26 const PACKAGEOP: u8 = 0x12;
27 const VARPACKAGEOP: u8 = 0x13;
28 const METHODOP: u8 = 0x14;
29 const DUALNAMEPREFIX: u8 = 0x2e;
30 const MULTINAMEPREFIX: u8 = 0x2f;
31 const NAMECHARBASE: u8 = 0x40;
32 
33 const EXTOPPREFIX: u8 = 0x5b;
34 const MUTEXOP: u8 = 0x01;
35 const CREATEFIELDOP: u8 = 0x13;
36 const ACQUIREOP: u8 = 0x23;
37 const RELEASEOP: u8 = 0x27;
38 const OPREGIONOP: u8 = 0x80;
39 const FIELDOP: u8 = 0x81;
40 const DEVICEOP: u8 = 0x82;
41 const POWERRESOURCEOP: u8 = 0x84;
42 
43 const LOCAL0OP: u8 = 0x60;
44 const ARG0OP: u8 = 0x68;
45 const STOREOP: u8 = 0x70;
46 const ADDOP: u8 = 0x72;
47 const CONCATOP: u8 = 0x73;
48 const SUBTRACTOP: u8 = 0x74;
49 const MULTIPLYOP: u8 = 0x77;
50 const SHIFTLEFTOP: u8 = 0x79;
51 const SHIFTRIGHTOP: u8 = 0x7a;
52 const ANDOP: u8 = 0x7b;
53 const NANDOP: u8 = 0x7c;
54 const OROP: u8 = 0x7d;
55 const NOROP: u8 = 0x7e;
56 const XOROP: u8 = 0x7f;
57 const DEREFOFOP: u8 = 0x83;
58 const CONCATRESOP: u8 = 0x84;
59 const MODOP: u8 = 0x85;
60 const NOTIFYOP: u8 = 0x86;
61 const SIZEOFOP: u8 = 0x87;
62 const INDEXOP: u8 = 0x88;
63 const CREATEDWFIELDOP: u8 = 0x8a;
64 const OBJECTTYPEOP: u8 = 0x8e;
65 const CREATEQWFIELDOP: u8 = 0x8f;
66 const LNOTOP: u8 = 0x92;
67 const LEQUALOP: u8 = 0x93;
68 const LGREATEROP: u8 = 0x94;
69 const LLESSOP: u8 = 0x95;
70 const TOBUFFEROP: u8 = 0x96;
71 const TOINTEGEROP: u8 = 0x99;
72 const TOSTRINGOP: u8 = 0x9c;
73 const MIDOP: u8 = 0x9e;
74 const IFOP: u8 = 0xa0;
75 const ELSEOP: u8 = 0xa1;
76 const WHILEOP: u8 = 0xa2;
77 const RETURNOP: u8 = 0xa4;
78 const ONESOP: u8 = 0xff;
79 
80 // AML resouce data fields
81 const IOPORTDESC: u8 = 0x47;
82 const ENDTAG: u8 = 0x79;
83 const MEMORY32FIXEDDESC: u8 = 0x86;
84 const DWORDADDRSPACEDESC: u8 = 0x87;
85 const WORDADDRSPACEDESC: u8 = 0x88;
86 const EXTIRQDESC: u8 = 0x89;
87 const QWORDADDRSPACEDESC: u8 = 0x8A;
88 
89 /// Zero object in ASL.
90 pub const ZERO: Zero = Zero {};
91 pub struct Zero {}
92 
93 impl Aml for Zero {
to_aml_bytes(&self, bytes: &mut Vec<u8>)94     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
95         bytes.push(ZEROOP);
96     }
97 }
98 
99 /// One object in ASL.
100 pub const ONE: One = One {};
101 pub struct One {}
102 
103 impl Aml for One {
to_aml_bytes(&self, bytes: &mut Vec<u8>)104     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
105         bytes.push(ONEOP);
106     }
107 }
108 
109 /// Ones object represents all bits 1.
110 pub const ONES: Ones = Ones {};
111 pub struct Ones {}
112 
113 impl Aml for Ones {
to_aml_bytes(&self, bytes: &mut Vec<u8>)114     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
115         bytes.push(ONESOP);
116     }
117 }
118 
119 /// Represents Namestring to construct ACPI objects like
120 /// Name/Device/Method/Scope and so on...
121 pub struct Path {
122     root: bool,
123     name_parts: Vec<[u8; 4]>,
124 }
125 
126 impl Aml for Path {
to_aml_bytes(&self, bytes: &mut Vec<u8>)127     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
128         if self.root {
129             bytes.push(b'\\');
130         }
131 
132         match self.name_parts.len() {
133             0 => panic!("Name cannot be empty"),
134             1 => {}
135             2 => {
136                 bytes.push(DUALNAMEPREFIX);
137             }
138             n => {
139                 bytes.push(MULTINAMEPREFIX);
140                 bytes.push(n as u8);
141             }
142         };
143 
144         for part in &self.name_parts {
145             bytes.extend_from_slice(part);
146         }
147     }
148 }
149 
150 impl Path {
151     /// Per ACPI Spec, the Namestring split by "." has 4 bytes long. So any name
152     /// not has 4 bytes will not be accepted.
new(name: &str) -> Self153     pub fn new(name: &str) -> Self {
154         let root = name.starts_with('\\');
155         let offset = root as usize;
156         let mut name_parts = Vec::new();
157         for part in name[offset..].split('.') {
158             assert_eq!(part.len(), 4);
159             let mut name_part = [0u8; 4];
160             name_part.copy_from_slice(part.as_bytes());
161             name_parts.push(name_part);
162         }
163 
164         Path { root, name_parts }
165     }
166 }
167 
168 impl From<&str> for Path {
from(s: &str) -> Self169     fn from(s: &str) -> Self {
170         Path::new(s)
171     }
172 }
173 
174 pub type Byte = u8;
175 
176 impl Aml for Byte {
to_aml_bytes(&self, bytes: &mut Vec<u8>)177     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
178         match *self {
179             0 => ZERO.to_aml_bytes(bytes),
180             1 => ONE.to_aml_bytes(bytes),
181             _ => {
182                 bytes.push(BYTEPREFIX);
183                 bytes.push(*self);
184             }
185         }
186     }
187 }
188 
189 pub type Word = u16;
190 
191 impl Aml for Word {
to_aml_bytes(&self, bytes: &mut Vec<u8>)192     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
193         if *self <= Byte::MAX.into() {
194             (*self as Byte).to_aml_bytes(bytes);
195         } else {
196             bytes.push(WORDPREFIX);
197             bytes.extend_from_slice(&self.to_le_bytes());
198         }
199     }
200 }
201 
202 pub type DWord = u32;
203 
204 impl Aml for DWord {
to_aml_bytes(&self, bytes: &mut Vec<u8>)205     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
206         if *self <= Word::MAX.into() {
207             (*self as Word).to_aml_bytes(bytes);
208         } else {
209             bytes.push(DWORDPREFIX);
210             bytes.extend_from_slice(&self.to_le_bytes());
211         }
212     }
213 }
214 
215 pub type QWord = u64;
216 
217 impl Aml for QWord {
to_aml_bytes(&self, bytes: &mut Vec<u8>)218     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
219         if *self <= DWord::MAX.into() {
220             (*self as DWord).to_aml_bytes(bytes);
221         } else {
222             bytes.push(QWORDPREFIX);
223             bytes.extend_from_slice(&self.to_le_bytes());
224         }
225     }
226 }
227 
228 /// Name object. bytes represents the raw AML data for it.
229 pub struct Name {
230     bytes: Vec<u8>,
231 }
232 
233 impl Aml for Name {
to_aml_bytes(&self, bytes: &mut Vec<u8>)234     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
235         bytes.extend_from_slice(&self.bytes);
236     }
237 }
238 
239 impl Name {
240     /// Create Name object:
241     ///
242     /// * `path` - The namestring.
243     /// * `inner` - AML objects contained in this namespace.
new(path: Path, inner: &dyn Aml) -> Self244     pub fn new(path: Path, inner: &dyn Aml) -> Self {
245         let mut bytes = vec![NAMEOP];
246         path.to_aml_bytes(&mut bytes);
247         inner.to_aml_bytes(&mut bytes);
248         Name { bytes }
249     }
250 
251     /// Create Field name object
252     ///
253     /// * 'field_name' - name string
new_field_name(field_name: &str) -> Self254     pub fn new_field_name(field_name: &str) -> Self {
255         let bytes = field_name.as_bytes().to_vec();
256         Name { bytes }
257     }
258 }
259 
260 /// Package object. 'children' represents the ACPI objects contained in this package.
261 pub struct Package {
262     children_bytes: Vec<u8>,
263 }
264 
265 impl Aml for Package {
to_aml_bytes(&self, aml: &mut Vec<u8>)266     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
267         aml.push(PACKAGEOP);
268         append_pkg_length(aml, self.children_bytes.len());
269         aml.extend_from_slice(&self.children_bytes);
270     }
271 }
272 
273 impl Package {
274     /// Create Package object:
new(children: Vec<&dyn Aml>) -> Package275     pub fn new(children: Vec<&dyn Aml>) -> Package {
276         let mut bytes = vec![children.len() as u8];
277         for child in &children {
278             child.to_aml_bytes(&mut bytes);
279         }
280         Package {
281             children_bytes: bytes,
282         }
283     }
284 }
285 
286 /// Variable Package Term
287 pub struct VarPackageTerm<'a> {
288     data: &'a dyn Aml,
289 }
290 
291 impl<'a> Aml for VarPackageTerm<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)292     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
293         aml.push(VARPACKAGEOP);
294 
295         let start = aml.len();
296         self.data.to_aml_bytes(aml);
297         let data_len = aml.len() - start;
298 
299         insert_pkg_length(aml, start, data_len);
300     }
301 }
302 
303 impl<'a> VarPackageTerm<'a> {
304     /// Create Variable Package Term
new(data: &'a dyn Aml) -> Self305     pub fn new(data: &'a dyn Aml) -> Self {
306         VarPackageTerm { data }
307     }
308 }
309 
310 /*
311 
312 From the ACPI spec for PkgLength:
313 
314 "The high 2 bits of the first byte reveal how many follow bytes are in the PkgLength. If the
315 PkgLength has only one byte, bit 0 through 5 are used to encode the package length (in other
316 words, values 0-63). If the package length value is more than 63, more than one byte must be
317 used for the encoding in which case bit 4 and 5 of the PkgLeadByte are reserved and must be zero.
318 If the multiple bytes encoding is used, bits 0-3 of the PkgLeadByte become the least significant 4
319 bits of the resulting package length value. The next ByteData will become the next least
320 significant 8 bits of the resulting value and so on, up to 3 ByteData bytes. Thus, the maximum
321 package length is 2**28."
322 
323 */
324 
325 /* Also used for NamedField but in that case the length is not included in itself */
insert_length(aml: &mut Vec<u8>, position: usize, len: usize, include_self: bool)326 fn insert_length(aml: &mut Vec<u8>, position: usize, len: usize, include_self: bool) {
327     /* PkgLength is inclusive and includes the length bytes */
328     let length_length = if len < (2usize.pow(6) - 1) {
329         1
330     } else if len < (2usize.pow(12) - 2) {
331         2
332     } else if len < (2usize.pow(20) - 3) {
333         3
334     } else {
335         4
336     };
337 
338     let length = len + if include_self { length_length } else { 0 };
339 
340     match length_length {
341         1 => aml.insert(position, length as u8),
342         2 => {
343             aml.splice(
344                 position..position,
345                 [(1u8 << 6) | (length & 0xf) as u8, (length >> 4) as u8],
346             );
347         }
348         3 => {
349             aml.splice(
350                 position..position,
351                 [
352                     (2u8 << 6) | (length & 0xf) as u8,
353                     (length >> 4) as u8,
354                     (length >> 12) as u8,
355                 ],
356             );
357         }
358         _ => {
359             aml.splice(
360                 position..position,
361                 [
362                     (3u8 << 6) | (length & 0xf) as u8,
363                     (length >> 4) as u8,
364                     (length >> 12) as u8,
365                     (length >> 20) as u8,
366                 ],
367             );
368         }
369     }
370 }
371 
insert_pkg_length(aml: &mut Vec<u8>, position: usize, len: usize)372 fn insert_pkg_length(aml: &mut Vec<u8>, position: usize, len: usize) {
373     insert_length(aml, position, len, true);
374 }
375 
append_pkg_length(aml: &mut Vec<u8>, len: usize)376 fn append_pkg_length(aml: &mut Vec<u8>, len: usize) {
377     insert_length(aml, aml.len(), len, true);
378 }
379 
380 // Append a NamedField length, which does not count the size of the encoded length itself.
append_named_field_length(aml: &mut Vec<u8>, len: usize)381 fn append_named_field_length(aml: &mut Vec<u8>, len: usize) {
382     insert_length(aml, aml.len(), len, false);
383 }
384 
385 /// EISAName object. 'value' means the encoded u32 EisaIdString.
386 pub struct EISAName {
387     value: DWord,
388 }
389 
390 impl EISAName {
391     /// Per ACPI Spec, the EisaIdString must be a String
392     /// object of the form UUUNNNN, where U is an uppercase letter
393     /// and N is a hexadecimal digit. No asterisks or other characters
394     /// are allowed in the string.
new(name: &str) -> Self395     pub fn new(name: &str) -> Self {
396         assert_eq!(name.len(), 7);
397 
398         let data = name.as_bytes();
399 
400         let value: u32 = (u32::from(data[0].checked_sub(NAMECHARBASE).unwrap()) << 26
401             | u32::from(data[1].checked_sub(NAMECHARBASE).unwrap()) << 21
402             | u32::from(data[2].checked_sub(NAMECHARBASE).unwrap()) << 16
403             | name.chars().nth(3).unwrap().to_digit(16).unwrap() << 12
404             | name.chars().nth(4).unwrap().to_digit(16).unwrap() << 8
405             | name.chars().nth(5).unwrap().to_digit(16).unwrap() << 4
406             | name.chars().nth(6).unwrap().to_digit(16).unwrap())
407         .swap_bytes();
408 
409         EISAName { value }
410     }
411 }
412 
413 impl Aml for EISAName {
to_aml_bytes(&self, bytes: &mut Vec<u8>)414     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
415         self.value.to_aml_bytes(bytes);
416     }
417 }
418 
419 pub type Usize = usize;
420 
421 impl Aml for Usize {
to_aml_bytes(&self, bytes: &mut Vec<u8>)422     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
423         #[cfg(target_pointer_width = "16")]
424         (*self as u16).to_aml_bytes(bytes);
425         #[cfg(target_pointer_width = "32")]
426         (*self as u32).to_aml_bytes(bytes);
427         #[cfg(target_pointer_width = "64")]
428         (*self as u64).to_aml_bytes(bytes);
429     }
430 }
431 
append_aml_string(data: &mut Vec<u8>, v: &str)432 fn append_aml_string(data: &mut Vec<u8>, v: &str) {
433     data.push(STRINGOP);
434     data.extend_from_slice(v.as_bytes());
435     data.push(0x0); /* NullChar */
436 }
437 
438 /// implement Aml trait for 'str' so that 'str' can be directly append to the aml vector
439 pub type AmlStr = &'static str;
440 
441 impl Aml for AmlStr {
to_aml_bytes(&self, bytes: &mut Vec<u8>)442     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
443         append_aml_string(bytes, self);
444     }
445 }
446 
447 /// implement Aml trait for 'String'. So purpose with str.
448 pub type AmlString = String;
449 
450 impl Aml for AmlString {
to_aml_bytes(&self, bytes: &mut Vec<u8>)451     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
452         append_aml_string(bytes, self);
453     }
454 }
455 
456 /// ResouceTemplate object. 'children' represents the ACPI objects in it.
457 pub struct ResourceTemplate<'a> {
458     children: Vec<&'a dyn Aml>,
459 }
460 
461 impl<'a> Aml for ResourceTemplate<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)462     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
463         aml.push(BUFFEROP);
464 
465         let pos = aml.len();
466 
467         // Add buffer data
468         for child in &self.children {
469             child.to_aml_bytes(aml);
470         }
471 
472         // Mark with end and mark checksum as as always valid
473         aml.push(ENDTAG);
474         aml.push(0); /* zero checksum byte */
475 
476         // Buffer length is an encoded integer including buffer data
477         // and EndTag and checksum byte
478         let buffer_length = aml.len() - pos;
479         let mut buffer_length_bytes = Vec::new();
480         buffer_length.to_aml_bytes(&mut buffer_length_bytes);
481         aml.splice(pos..pos, buffer_length_bytes);
482 
483         // PkgLength is everything else
484         let len = aml.len() - pos;
485         insert_pkg_length(aml, pos, len);
486     }
487 }
488 
489 impl<'a> ResourceTemplate<'a> {
490     /// Create ResouceTemplate object
new(children: Vec<&'a dyn Aml>) -> Self491     pub fn new(children: Vec<&'a dyn Aml>) -> Self {
492         ResourceTemplate { children }
493     }
494 }
495 
496 /// Memory32Fixed object with read_write accessing type, and the base address/length.
497 pub struct Memory32Fixed {
498     read_write: bool, /* true for read & write, false for read only */
499     base: u32,
500     length: u32,
501 }
502 
503 impl Memory32Fixed {
504     /// Create Memory32Fixed object.
new(read_write: bool, base: u32, length: u32) -> Self505     pub fn new(read_write: bool, base: u32, length: u32) -> Self {
506         Memory32Fixed {
507             read_write,
508             base,
509             length,
510         }
511     }
512 }
513 
514 impl Aml for Memory32Fixed {
to_aml_bytes(&self, bytes: &mut Vec<u8>)515     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
516         bytes.push(MEMORY32FIXEDDESC); /* 32bit Fixed Memory Range Descriptor */
517         bytes.extend_from_slice(&9u16.to_le_bytes());
518 
519         // 9 bytes of payload
520         bytes.push(self.read_write as u8);
521         bytes.extend_from_slice(&self.base.to_le_bytes());
522         bytes.extend_from_slice(&self.length.to_le_bytes());
523     }
524 }
525 
526 #[derive(Copy, Clone)]
527 enum AddressSpaceType {
528     Memory,
529     IO,
530     BusNumber,
531 }
532 
533 /// AddressSpaceCachable represent cache types for AddressSpace object
534 #[derive(Copy, Clone)]
535 pub enum AddressSpaceCachable {
536     NotCacheable,
537     Cacheable,
538     WriteCombining,
539     PreFetchable,
540 }
541 
542 /// AddressSpace structure with type, resouce range and flags to
543 /// construct Memory/IO/BusNumber objects
544 pub struct AddressSpace<T> {
545     type_: AddressSpaceType,
546     min: T,
547     max: T,
548     type_flags: u8,
549 }
550 
551 impl<T> AddressSpace<T> {
552     /// Create DWordMemory/QWordMemory object
new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self553     pub fn new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self {
554         AddressSpace {
555             type_: AddressSpaceType::Memory,
556             min,
557             max,
558             type_flags: (cacheable as u8) << 1 | read_write as u8,
559         }
560     }
561 
562     /// Create WordIO/DWordIO/QWordIO object
new_io(min: T, max: T) -> Self563     pub fn new_io(min: T, max: T) -> Self {
564         AddressSpace {
565             type_: AddressSpaceType::IO,
566             min,
567             max,
568             type_flags: 3, /* EntireRange */
569         }
570     }
571 
572     /// Create WordBusNumber object
new_bus_number(min: T, max: T) -> Self573     pub fn new_bus_number(min: T, max: T) -> Self {
574         AddressSpace {
575             type_: AddressSpaceType::BusNumber,
576             min,
577             max,
578             type_flags: 0,
579         }
580     }
581 
push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize)582     fn push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize) {
583         bytes.push(descriptor); /* Word Address Space Descriptor */
584         bytes.extend_from_slice(&(length as u16).to_le_bytes());
585         bytes.push(self.type_ as u8); /* type */
586         let generic_flags = 1 << 2 /* Min Fixed */ | 1 << 3; /* Max Fixed */
587         bytes.push(generic_flags);
588         bytes.push(self.type_flags);
589     }
590 }
591 
592 impl Aml for AddressSpace<u16> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)593     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
594         self.push_header(
595             bytes,
596             WORDADDRSPACEDESC,                  /* Word Address Space Descriptor */
597             3 + 5 * std::mem::size_of::<u16>(), /* 3 bytes of header + 5 u16 fields */
598         );
599 
600         bytes.extend_from_slice(&0u16.to_le_bytes()); /* Granularity */
601         bytes.extend_from_slice(&self.min.to_le_bytes()); /* Min */
602         bytes.extend_from_slice(&self.max.to_le_bytes()); /* Max */
603         bytes.extend_from_slice(&0u16.to_le_bytes()); /* Translation */
604         let len = self.max - self.min + 1;
605         bytes.extend_from_slice(&len.to_le_bytes()); /* Length */
606     }
607 }
608 
609 impl Aml for AddressSpace<u32> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)610     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
611         self.push_header(
612             bytes,
613             DWORDADDRSPACEDESC, /* DWord Address Space Descriptor */
614             3 + 5 * std::mem::size_of::<u32>(), /* 3 bytes of header + 5 u32 fields */
615         );
616 
617         bytes.extend_from_slice(&0u32.to_le_bytes()); /* Granularity */
618         bytes.extend_from_slice(&self.min.to_le_bytes()); /* Min */
619         bytes.extend_from_slice(&self.max.to_le_bytes()); /* Max */
620         bytes.extend_from_slice(&0u32.to_le_bytes()); /* Translation */
621         let len = self.max - self.min + 1;
622         bytes.extend_from_slice(&len.to_le_bytes()); /* Length */
623     }
624 }
625 
626 impl Aml for AddressSpace<u64> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)627     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
628         self.push_header(
629             bytes,
630             QWORDADDRSPACEDESC, /* QWord Address Space Descriptor */
631             3 + 5 * std::mem::size_of::<u64>(), /* 3 bytes of header + 5 u64 fields */
632         );
633 
634         bytes.extend_from_slice(&0u64.to_le_bytes()); /* Granularity */
635         bytes.extend_from_slice(&self.min.to_le_bytes()); /* Min */
636         bytes.extend_from_slice(&self.max.to_le_bytes()); /* Max */
637         bytes.extend_from_slice(&0u64.to_le_bytes()); /* Translation */
638         let len = self.max - self.min + 1;
639         bytes.extend_from_slice(&len.to_le_bytes()); /* Length */
640     }
641 }
642 
643 /// IO resouce object with the IO range, alignment and length
644 pub struct IO {
645     min: u16,
646     max: u16,
647     alignment: u8,
648     length: u8,
649 }
650 
651 impl IO {
652     /// Create IO object
new(min: u16, max: u16, alignment: u8, length: u8) -> Self653     pub fn new(min: u16, max: u16, alignment: u8, length: u8) -> Self {
654         IO {
655             min,
656             max,
657             alignment,
658             length,
659         }
660     }
661 }
662 
663 impl Aml for IO {
to_aml_bytes(&self, bytes: &mut Vec<u8>)664     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
665         bytes.push(IOPORTDESC); /* IO Port Descriptor */
666         bytes.push(1); /* IODecode16 */
667         bytes.extend_from_slice(&self.min.to_le_bytes());
668         bytes.extend_from_slice(&self.max.to_le_bytes());
669         bytes.push(self.alignment);
670         bytes.push(self.length);
671     }
672 }
673 
674 /// Interrupt resouce object with the interrupt characters.
675 pub struct Interrupt {
676     consumer: bool,
677     edge_triggered: bool,
678     active_low: bool,
679     shared: bool,
680     number: u32,
681 }
682 
683 impl Interrupt {
684     /// Create Interrupt object
new( consumer: bool, edge_triggered: bool, active_low: bool, shared: bool, number: u32, ) -> Self685     pub fn new(
686         consumer: bool,
687         edge_triggered: bool,
688         active_low: bool,
689         shared: bool,
690         number: u32,
691     ) -> Self {
692         Interrupt {
693             consumer,
694             edge_triggered,
695             active_low,
696             shared,
697             number,
698         }
699     }
700 }
701 
702 impl Aml for Interrupt {
to_aml_bytes(&self, bytes: &mut Vec<u8>)703     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
704         bytes.push(EXTIRQDESC); /* Extended IRQ Descriptor */
705         bytes.extend_from_slice(&6u16.to_le_bytes());
706         let flags = (self.shared as u8) << 3
707             | (self.active_low as u8) << 2
708             | (self.edge_triggered as u8) << 1
709             | self.consumer as u8;
710         bytes.push(flags);
711         bytes.push(1u8); /* count */
712         bytes.extend_from_slice(&self.number.to_le_bytes());
713     }
714 }
715 
716 /// Device object with its device name and children objects in it.
717 pub struct Device<'a> {
718     path: Path,
719     children: Vec<&'a dyn Aml>,
720 }
721 
722 impl<'a> Aml for Device<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)723     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
724         aml.push(EXTOPPREFIX); /* ExtOpPrefix */
725         aml.push(DEVICEOP); /* DeviceOp */
726 
727         let start = aml.len();
728         self.path.to_aml_bytes(aml);
729         for child in &self.children {
730             child.to_aml_bytes(aml);
731         }
732         let len = aml.len() - start;
733 
734         insert_pkg_length(aml, start, len);
735     }
736 }
737 
738 impl<'a> Device<'a> {
739     /// Create Device object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self740     pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
741         Device { path, children }
742     }
743 }
744 
745 /// Scope object with its name and children objects in it.
746 pub struct Scope<'a> {
747     path: Path,
748     children: Vec<&'a dyn Aml>,
749 }
750 
751 impl<'a> Aml for Scope<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)752     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
753         aml.push(SCOPEOP);
754 
755         let start = aml.len();
756         self.path.to_aml_bytes(aml);
757         for child in &self.children {
758             child.to_aml_bytes(aml);
759         }
760         let len = aml.len() - start;
761 
762         insert_pkg_length(aml, start, len);
763     }
764 }
765 
766 impl<'a> Scope<'a> {
767     /// Create Scope object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self768     pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
769         Scope { path, children }
770     }
771 
772     /// Create raw bytes representing a Scope from its children in raw bytes
raw(path: Path, mut children: Vec<u8>) -> Vec<u8>773     pub fn raw(path: Path, mut children: Vec<u8>) -> Vec<u8> {
774         let mut bytes = Vec::new();
775         bytes.push(SCOPEOP);
776 
777         let start = bytes.len();
778         path.to_aml_bytes(&mut bytes);
779         bytes.append(&mut children);
780         let len = bytes.len() - start;
781 
782         insert_pkg_length(&mut bytes, start, len);
783 
784         bytes
785     }
786 }
787 
788 /// Method object with its name, children objects, arguments and serialized character.
789 pub struct Method<'a> {
790     path: Path,
791     children: Vec<&'a dyn Aml>,
792     args: u8,
793     serialized: bool,
794 }
795 
796 impl<'a> Method<'a> {
797     /// Create Method object.
new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self798     pub fn new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self {
799         Method {
800             path,
801             children,
802             args,
803             serialized,
804         }
805     }
806 }
807 
808 impl<'a> Aml for Method<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)809     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
810         aml.push(METHODOP);
811 
812         let start = aml.len();
813         self.path.to_aml_bytes(aml);
814         let flags: u8 = (self.args & 0x7) | (self.serialized as u8) << 3;
815         aml.push(flags);
816         for child in &self.children {
817             child.to_aml_bytes(aml);
818         }
819         let len = aml.len() - start;
820 
821         insert_pkg_length(aml, start, len);
822     }
823 }
824 
825 /// FieldAccessType defines the field accessing types.
826 #[derive(Clone, Copy)]
827 pub enum FieldAccessType {
828     Any,
829     Byte,
830     Word,
831     DWord,
832     QWord,
833     Buffer,
834 }
835 
836 /// FieldLockRule defines the rules whether to use the Global Lock.
837 #[derive(Clone, Copy)]
838 pub enum FieldLockRule {
839     NoLock = 0,
840     Lock = 1,
841 }
842 
843 /// FieldUpdateRule defines the rules to update the field.
844 #[derive(Clone, Copy)]
845 pub enum FieldUpdateRule {
846     Preserve = 0,
847     WriteAsOnes = 1,
848     WriteAsZeroes = 2,
849 }
850 
851 /// FieldEntry defines the field entry.
852 pub enum FieldEntry {
853     Named([u8; 4], usize),
854     Reserved(usize),
855 }
856 
857 /// Field object with the region name, field entries, access type and update rules.
858 pub struct Field {
859     path: Path,
860 
861     fields: Vec<FieldEntry>,
862     access_type: FieldAccessType,
863     lock_rule: FieldLockRule,
864     update_rule: FieldUpdateRule,
865 }
866 
867 impl Field {
868     /// Create Field object
new( path: Path, access_type: FieldAccessType, lock_rule: FieldLockRule, update_rule: FieldUpdateRule, fields: Vec<FieldEntry>, ) -> Self869     pub fn new(
870         path: Path,
871         access_type: FieldAccessType,
872         lock_rule: FieldLockRule,
873         update_rule: FieldUpdateRule,
874         fields: Vec<FieldEntry>,
875     ) -> Self {
876         Field {
877             path,
878             access_type,
879             lock_rule,
880             update_rule,
881             fields,
882         }
883     }
884 }
885 
886 impl Aml for Field {
to_aml_bytes(&self, aml: &mut Vec<u8>)887     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
888         aml.push(EXTOPPREFIX);
889         aml.push(FIELDOP);
890 
891         let start = aml.len();
892         self.path.to_aml_bytes(aml);
893 
894         let flags: u8 =
895             self.access_type as u8 | (self.lock_rule as u8) << 4 | (self.update_rule as u8) << 5;
896         aml.push(flags);
897 
898         for field in self.fields.iter() {
899             match field {
900                 FieldEntry::Named(name, length) => {
901                     aml.extend_from_slice(name);
902                     append_named_field_length(aml, *length);
903                 }
904                 FieldEntry::Reserved(length) => {
905                     aml.push(0x0);
906                     append_named_field_length(aml, *length);
907                 }
908             }
909         }
910 
911         let len = aml.len() - start;
912         insert_pkg_length(aml, start, len);
913     }
914 }
915 
916 /// The space type for OperationRegion object
917 #[derive(Clone, Copy)]
918 pub enum OpRegionSpace {
919     SystemMemory,
920     SystemIO,
921     PCIConfig,
922     EmbeddedControl,
923     SMBus,
924     SystemCMOS,
925     PciBarTarget,
926     IPMI,
927     GeneralPurposeIO,
928     GenericSerialBus,
929 }
930 
931 /// OperationRegion object with region name, region space type, its offset and length.
932 pub struct OpRegion<'a> {
933     path: Path,
934     space: OpRegionSpace,
935     offset: &'a dyn Aml,
936     length: &'a dyn Aml,
937 }
938 
939 impl<'a> OpRegion<'a> {
940     /// Create OperationRegion object.
new(path: Path, space: OpRegionSpace, offset: &'a dyn Aml, length: &'a dyn Aml) -> Self941     pub fn new(path: Path, space: OpRegionSpace, offset: &'a dyn Aml, length: &'a dyn Aml) -> Self {
942         OpRegion {
943             path,
944             space,
945             offset,
946             length,
947         }
948     }
949 }
950 
951 impl<'a> Aml for OpRegion<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)952     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
953         aml.push(EXTOPPREFIX);
954         aml.push(OPREGIONOP);
955 
956         self.path.to_aml_bytes(aml);
957         aml.push(self.space as u8);
958         self.offset.to_aml_bytes(aml); /* RegionOffset */
959         self.length.to_aml_bytes(aml); /* RegionLen */
960     }
961 }
962 
963 /// If object with the if condition(predicate) and the body presented by the if_children objects.
964 pub struct If<'a> {
965     predicate: &'a dyn Aml,
966     if_children: Vec<&'a dyn Aml>,
967 }
968 
969 impl<'a> If<'a> {
970     /// Create If object.
new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self971     pub fn new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self {
972         If {
973             predicate,
974             if_children,
975         }
976     }
977 }
978 
979 impl<'a> Aml for If<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)980     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
981         aml.push(IFOP);
982 
983         let start = aml.len();
984         self.predicate.to_aml_bytes(aml);
985         for child in self.if_children.iter() {
986             child.to_aml_bytes(aml);
987         }
988         let len = aml.len() - start;
989 
990         insert_pkg_length(aml, start, len);
991     }
992 }
993 
994 /// Else object
995 pub struct Else<'a> {
996     body: Vec<&'a dyn Aml>,
997 }
998 
999 impl<'a> Else<'a> {
1000     /// Create Else object.
new(body: Vec<&'a dyn Aml>) -> Self1001     pub fn new(body: Vec<&'a dyn Aml>) -> Self {
1002         Else { body }
1003     }
1004 }
1005 
1006 impl<'a> Aml for Else<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1007     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1008         aml.push(ELSEOP);
1009 
1010         let start = aml.len();
1011         for child in self.body.iter() {
1012             child.to_aml_bytes(aml);
1013         }
1014         let len = aml.len() - start;
1015 
1016         insert_pkg_length(aml, start, len);
1017     }
1018 }
1019 
1020 macro_rules! compare_op {
1021     ($name:ident, $opcode:expr, $invert:expr) => {
1022         /// Compare object with its right part and left part, which are both ACPI Object.
1023         pub struct $name<'a> {
1024             right: &'a dyn Aml,
1025             left: &'a dyn Aml,
1026         }
1027 
1028         impl<'a> $name<'a> {
1029             /// Create the compare object method.
1030             pub fn new(left: &'a dyn Aml, right: &'a dyn Aml) -> Self {
1031                 $name { left, right }
1032             }
1033         }
1034 
1035         impl<'a> Aml for $name<'a> {
1036             fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1037                 if $invert {
1038                     bytes.push(LNOTOP);
1039                 }
1040                 bytes.push($opcode);
1041                 self.left.to_aml_bytes(bytes);
1042                 self.right.to_aml_bytes(bytes);
1043             }
1044         }
1045     };
1046 }
1047 
1048 compare_op!(Equal, LEQUALOP, false);
1049 compare_op!(LessThan, LLESSOP, false);
1050 compare_op!(GreaterThan, LGREATEROP, false);
1051 compare_op!(NotEqual, LEQUALOP, true);
1052 compare_op!(GreaterEqual, LLESSOP, true);
1053 compare_op!(LessEqual, LGREATEROP, true);
1054 
1055 /// Argx object.
1056 pub struct Arg(pub u8);
1057 
1058 impl Aml for Arg {
1059     /// Per ACPI spec, there is maximum 7 Argx objects from
1060     /// Arg0 ~ Arg6. Any other Arg object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1061     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1062         assert!(self.0 <= 6);
1063         bytes.push(ARG0OP + self.0);
1064     }
1065 }
1066 
1067 /// Localx object.
1068 pub struct Local(pub u8);
1069 
1070 impl Aml for Local {
1071     /// Per ACPI spec, there is maximum 8 Localx objects from
1072     /// Local0 ~ Local7. Any other Local object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1073     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1074         assert!(self.0 <= 7);
1075         bytes.push(LOCAL0OP + self.0);
1076     }
1077 }
1078 
1079 /// Store object with the ACPI object name which can be stored to and
1080 /// the ACPI object value which is to store.
1081 pub struct Store<'a> {
1082     name: &'a dyn Aml,
1083     value: &'a dyn Aml,
1084 }
1085 
1086 impl<'a> Store<'a> {
1087     /// Create Store object.
new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self1088     pub fn new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1089         Store { name, value }
1090     }
1091 }
1092 
1093 impl<'a> Aml for Store<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1094     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1095         bytes.push(STOREOP);
1096         self.value.to_aml_bytes(bytes);
1097         self.name.to_aml_bytes(bytes);
1098     }
1099 }
1100 
1101 /// Mutex object with a mutex name and a synchronization level.
1102 pub struct Mutex {
1103     path: Path,
1104     sync_level: u8,
1105 }
1106 
1107 impl Mutex {
1108     /// Create Mutex object.
new(path: Path, sync_level: u8) -> Self1109     pub fn new(path: Path, sync_level: u8) -> Self {
1110         Self { path, sync_level }
1111     }
1112 }
1113 
1114 impl Aml for Mutex {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1115     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1116         bytes.push(EXTOPPREFIX);
1117         bytes.push(MUTEXOP);
1118         self.path.to_aml_bytes(bytes);
1119         bytes.push(self.sync_level);
1120     }
1121 }
1122 
1123 /// Acquire object with a Mutex object and timeout value.
1124 pub struct Acquire {
1125     mutex: Path,
1126     timeout: u16,
1127 }
1128 
1129 impl Acquire {
1130     /// Create Acquire object.
new(mutex: Path, timeout: u16) -> Self1131     pub fn new(mutex: Path, timeout: u16) -> Self {
1132         Acquire { mutex, timeout }
1133     }
1134 }
1135 
1136 impl Aml for Acquire {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1137     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1138         bytes.push(EXTOPPREFIX);
1139         bytes.push(ACQUIREOP);
1140         self.mutex.to_aml_bytes(bytes);
1141         bytes.extend_from_slice(&self.timeout.to_le_bytes());
1142     }
1143 }
1144 
1145 /// Release object with a Mutex object to release.
1146 pub struct Release {
1147     mutex: Path,
1148 }
1149 
1150 impl Release {
1151     /// Create Release object.
new(mutex: Path) -> Self1152     pub fn new(mutex: Path) -> Self {
1153         Release { mutex }
1154     }
1155 }
1156 
1157 impl Aml for Release {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1158     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1159         bytes.push(EXTOPPREFIX);
1160         bytes.push(RELEASEOP);
1161         self.mutex.to_aml_bytes(bytes);
1162     }
1163 }
1164 
1165 /// Notify object with an object which is to be notified with the value.
1166 pub struct Notify<'a> {
1167     object: &'a dyn Aml,
1168     value: &'a dyn Aml,
1169 }
1170 
1171 impl<'a> Notify<'a> {
1172     /// Create Notify object.
new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self1173     pub fn new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1174         Notify { object, value }
1175     }
1176 }
1177 
1178 impl<'a> Aml for Notify<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1179     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1180         bytes.push(NOTIFYOP);
1181         self.object.to_aml_bytes(bytes);
1182         self.value.to_aml_bytes(bytes);
1183     }
1184 }
1185 
1186 /// While object with the while condition objects(predicate) and
1187 /// the while body objects(while_children).
1188 pub struct While<'a> {
1189     predicate: &'a dyn Aml,
1190     while_children: Vec<&'a dyn Aml>,
1191 }
1192 
1193 impl<'a> While<'a> {
1194     /// Create While object.
new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self1195     pub fn new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self {
1196         While {
1197             predicate,
1198             while_children,
1199         }
1200     }
1201 }
1202 
1203 impl<'a> Aml for While<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1204     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1205         aml.push(WHILEOP);
1206 
1207         let start = aml.len();
1208         self.predicate.to_aml_bytes(aml);
1209         for child in self.while_children.iter() {
1210             child.to_aml_bytes(aml);
1211         }
1212         let len = aml.len() - start;
1213 
1214         insert_pkg_length(aml, start, len);
1215     }
1216 }
1217 
1218 macro_rules! object_op {
1219     ($name:ident, $opcode:expr) => {
1220         /// General operation on a object.
1221         pub struct $name<'a> {
1222             a: &'a dyn Aml,
1223         }
1224 
1225         impl<'a> $name<'a> {
1226             /// Create the object method.
1227             pub fn new(a: &'a dyn Aml) -> Self {
1228                 $name { a }
1229             }
1230         }
1231 
1232         impl<'a> Aml for $name<'a> {
1233             fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1234                 bytes.push($opcode);
1235                 self.a.to_aml_bytes(bytes);
1236             }
1237         }
1238     };
1239 }
1240 
1241 object_op!(ObjectType, OBJECTTYPEOP);
1242 object_op!(SizeOf, SIZEOFOP);
1243 object_op!(Return, RETURNOP);
1244 object_op!(DeRefOf, DEREFOFOP);
1245 
1246 macro_rules! binary_op {
1247     ($name:ident, $opcode:expr) => {
1248         /// General operation object with the operator a/b and a target.
1249         pub struct $name<'a> {
1250             a: &'a dyn Aml,
1251             b: &'a dyn Aml,
1252             target: &'a dyn Aml,
1253         }
1254 
1255         impl<'a> $name<'a> {
1256             /// Create the object.
1257             pub fn new(target: &'a dyn Aml, a: &'a dyn Aml, b: &'a dyn Aml) -> Self {
1258                 $name { target, a, b }
1259             }
1260         }
1261 
1262         impl<'a> Aml for $name<'a> {
1263             fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1264                 bytes.push($opcode); /* Op for the binary operator */
1265                 self.a.to_aml_bytes(bytes);
1266                 self.b.to_aml_bytes(bytes);
1267                 self.target.to_aml_bytes(bytes);
1268             }
1269         }
1270     };
1271 }
1272 
1273 binary_op!(Add, ADDOP);
1274 binary_op!(Concat, CONCATOP);
1275 binary_op!(Subtract, SUBTRACTOP);
1276 binary_op!(Multiply, MULTIPLYOP);
1277 binary_op!(ShiftLeft, SHIFTLEFTOP);
1278 binary_op!(ShiftRight, SHIFTRIGHTOP);
1279 binary_op!(And, ANDOP);
1280 binary_op!(Nand, NANDOP);
1281 binary_op!(Or, OROP);
1282 binary_op!(Nor, NOROP);
1283 binary_op!(Xor, XOROP);
1284 binary_op!(ConcatRes, CONCATRESOP);
1285 binary_op!(Mod, MODOP);
1286 binary_op!(Index, INDEXOP);
1287 binary_op!(ToString, TOSTRINGOP);
1288 binary_op!(CreateDWordField, CREATEDWFIELDOP);
1289 binary_op!(CreateQWordField, CREATEQWFIELDOP);
1290 
1291 macro_rules! convert_op {
1292     ($name:ident, $opcode:expr) => {
1293         /// General operation object with the operator a/b and a target.
1294         pub struct $name<'a> {
1295             a: &'a dyn Aml,
1296             target: &'a dyn Aml,
1297         }
1298 
1299         impl<'a> $name<'a> {
1300             /// Create the object.
1301             pub fn new(target: &'a dyn Aml, a: &'a dyn Aml) -> Self {
1302                 $name { target, a }
1303             }
1304         }
1305 
1306         impl<'a> Aml for $name<'a> {
1307             fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1308                 bytes.push($opcode); /* Op for the binary operator */
1309                 self.a.to_aml_bytes(bytes);
1310                 self.target.to_aml_bytes(bytes);
1311             }
1312         }
1313     };
1314 }
1315 
1316 convert_op!(ToBuffer, TOBUFFEROP);
1317 convert_op!(ToInteger, TOINTEGEROP);
1318 
1319 /// Create Field Object.
1320 pub struct CreateField<'a> {
1321     name_string: &'a dyn Aml,
1322     source: &'a dyn Aml,
1323     bit_index: &'a dyn Aml,
1324     bit_num: &'a dyn Aml,
1325 }
1326 
1327 impl<'a> CreateField<'a> {
new( name_string: &'a dyn Aml, source: &'a dyn Aml, bit_index: &'a dyn Aml, bit_num: &'a dyn Aml, ) -> Self1328     pub fn new(
1329         name_string: &'a dyn Aml,
1330         source: &'a dyn Aml,
1331         bit_index: &'a dyn Aml,
1332         bit_num: &'a dyn Aml,
1333     ) -> Self {
1334         CreateField {
1335             name_string,
1336             source,
1337             bit_index,
1338             bit_num,
1339         }
1340     }
1341 }
1342 
1343 impl<'a> Aml for CreateField<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1344     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1345         bytes.push(EXTOPPREFIX);
1346         bytes.push(CREATEFIELDOP);
1347         self.source.to_aml_bytes(bytes);
1348         self.bit_index.to_aml_bytes(bytes);
1349         self.bit_num.to_aml_bytes(bytes);
1350         self.name_string.to_aml_bytes(bytes);
1351     }
1352 }
1353 
1354 /// Mid object with the source, index, length, and result objects.
1355 pub struct Mid<'a> {
1356     source: &'a dyn Aml,
1357     index: &'a dyn Aml,
1358     length: &'a dyn Aml,
1359     result: &'a dyn Aml,
1360 }
1361 
1362 impl<'a> Mid<'a> {
new( source: &'a dyn Aml, index: &'a dyn Aml, length: &'a dyn Aml, result: &'a dyn Aml, ) -> Self1363     pub fn new(
1364         source: &'a dyn Aml,
1365         index: &'a dyn Aml,
1366         length: &'a dyn Aml,
1367         result: &'a dyn Aml,
1368     ) -> Self {
1369         Mid {
1370             source,
1371             index,
1372             length,
1373             result,
1374         }
1375     }
1376 }
1377 
1378 impl<'a> Aml for Mid<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1379     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1380         bytes.push(MIDOP);
1381         self.source.to_aml_bytes(bytes);
1382         self.index.to_aml_bytes(bytes);
1383         self.length.to_aml_bytes(bytes);
1384         self.result.to_aml_bytes(bytes);
1385     }
1386 }
1387 
1388 /// MethodCall object with the method name and parameter objects.
1389 pub struct MethodCall<'a> {
1390     name: Path,
1391     args: Vec<&'a dyn Aml>,
1392 }
1393 
1394 impl<'a> MethodCall<'a> {
1395     /// Create MethodCall object.
new(name: Path, args: Vec<&'a dyn Aml>) -> Self1396     pub fn new(name: Path, args: Vec<&'a dyn Aml>) -> Self {
1397         MethodCall { name, args }
1398     }
1399 }
1400 
1401 impl<'a> Aml for MethodCall<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1402     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1403         self.name.to_aml_bytes(bytes);
1404         for arg in self.args.iter() {
1405             arg.to_aml_bytes(bytes);
1406         }
1407     }
1408 }
1409 
1410 /// Buffer object with the TermArg in it.
1411 pub struct BufferTerm<'a> {
1412     data: &'a dyn Aml,
1413 }
1414 
1415 impl<'a> BufferTerm<'a> {
1416     /// Create BufferTerm object.
new(data: &'a dyn Aml) -> Self1417     pub fn new(data: &'a dyn Aml) -> Self {
1418         BufferTerm { data }
1419     }
1420 }
1421 
1422 impl<'a> Aml for BufferTerm<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1423     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1424         aml.push(BUFFEROP);
1425 
1426         let start = aml.len();
1427         self.data.to_aml_bytes(aml);
1428         let len = aml.len() - start;
1429 
1430         insert_pkg_length(aml, start, len);
1431     }
1432 }
1433 
1434 /// Buffer object with the data in it.
1435 pub struct BufferData {
1436     data: Vec<u8>,
1437 }
1438 
1439 impl BufferData {
1440     /// Create BufferData object.
new(data: Vec<u8>) -> Self1441     pub fn new(data: Vec<u8>) -> Self {
1442         BufferData { data }
1443     }
1444 }
1445 
1446 impl Aml for BufferData {
to_aml_bytes(&self, aml: &mut Vec<u8>)1447     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1448         aml.push(BUFFEROP);
1449 
1450         let start = aml.len();
1451         self.data.len().to_aml_bytes(aml);
1452         aml.extend_from_slice(&self.data);
1453         let len = aml.len() - start;
1454 
1455         insert_pkg_length(aml, start, len);
1456     }
1457 }
1458 
1459 pub struct Uuid {
1460     name: BufferData,
1461 }
1462 
hex2byte(v1: char, v2: char) -> u81463 fn hex2byte(v1: char, v2: char) -> u8 {
1464     let hi = v1.to_digit(16).unwrap() as u8;
1465     assert!(hi <= 15);
1466     let lo = v2.to_digit(16).unwrap() as u8;
1467     assert!(lo <= 15);
1468 
1469     (hi << 4) | lo
1470 }
1471 
1472 impl Uuid {
1473     // Create Uuid object
1474     // eg. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
new(name: &str) -> Self1475     pub fn new(name: &str) -> Self {
1476         let name_vec: Vec<char> = name.chars().collect();
1477         let mut data = Vec::new();
1478 
1479         assert_eq!(name_vec.len(), 36);
1480         assert_eq!(name_vec[8], '-');
1481         assert_eq!(name_vec[13], '-');
1482         assert_eq!(name_vec[18], '-');
1483         assert_eq!(name_vec[23], '-');
1484 
1485         // dd - at offset 00
1486         data.push(hex2byte(name_vec[6], name_vec[7]));
1487         // cc - at offset 01
1488         data.push(hex2byte(name_vec[4], name_vec[5]));
1489         // bb - at offset 02
1490         data.push(hex2byte(name_vec[2], name_vec[3]));
1491         // aa - at offset 03
1492         data.push(hex2byte(name_vec[0], name_vec[1]));
1493 
1494         // ff - at offset 04
1495         data.push(hex2byte(name_vec[11], name_vec[12]));
1496         // ee - at offset 05
1497         data.push(hex2byte(name_vec[9], name_vec[10]));
1498 
1499         // hh - at offset 06
1500         data.push(hex2byte(name_vec[16], name_vec[17]));
1501         // gg - at offset 07
1502         data.push(hex2byte(name_vec[14], name_vec[15]));
1503 
1504         // ii - at offset 08
1505         data.push(hex2byte(name_vec[19], name_vec[20]));
1506         // jj - at offset 09
1507         data.push(hex2byte(name_vec[21], name_vec[22]));
1508 
1509         // kk - at offset 10
1510         data.push(hex2byte(name_vec[24], name_vec[25]));
1511         // ll - at offset 11
1512         data.push(hex2byte(name_vec[26], name_vec[27]));
1513         // mm - at offset 12
1514         data.push(hex2byte(name_vec[28], name_vec[29]));
1515         // nn - at offset 13
1516         data.push(hex2byte(name_vec[30], name_vec[31]));
1517         // oo - at offset 14
1518         data.push(hex2byte(name_vec[32], name_vec[33]));
1519         // pp - at offset 15
1520         data.push(hex2byte(name_vec[34], name_vec[35]));
1521 
1522         Uuid {
1523             name: BufferData::new(data),
1524         }
1525     }
1526 }
1527 
1528 impl Aml for Uuid {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1529     fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1530         self.name.to_aml_bytes(bytes)
1531     }
1532 }
1533 
1534 /// Power Resource object. 'children' represents Power Resource method.
1535 pub struct PowerResource<'a> {
1536     name: Path,
1537     level: u8,
1538     order: u16,
1539     children: Vec<&'a dyn Aml>,
1540 }
1541 
1542 impl<'a> PowerResource<'a> {
1543     /// Create Power Resouce object
new(name: Path, level: u8, order: u16, children: Vec<&'a dyn Aml>) -> Self1544     pub fn new(name: Path, level: u8, order: u16, children: Vec<&'a dyn Aml>) -> Self {
1545         PowerResource {
1546             name,
1547             level,
1548             order,
1549             children,
1550         }
1551     }
1552 }
1553 
1554 impl<'a> Aml for PowerResource<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1555     fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1556         aml.push(EXTOPPREFIX);
1557         aml.push(POWERRESOURCEOP);
1558 
1559         let start = aml.len();
1560 
1561         // Add name string
1562         self.name.to_aml_bytes(aml);
1563         // Add system level
1564         aml.push(self.level);
1565         // Add Resource Order
1566         let orders = self.order.to_le_bytes();
1567         aml.push(orders[0]);
1568         aml.push(orders[1]);
1569         // Add child data
1570         for child in &self.children {
1571             child.to_aml_bytes(aml);
1572         }
1573 
1574         let len = aml.len() - start;
1575 
1576         insert_pkg_length(aml, start, len);
1577     }
1578 }
1579 
1580 #[cfg(test)]
1581 mod tests {
1582     use super::*;
1583 
1584     #[test]
test_device()1585     fn test_device() {
1586         /*
1587         Device (_SB.COM1)
1588         {
1589             Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */) // _HID: Hardware ID
1590             Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
1591             {
1592                 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1593                 {
1594                     0x00000004,
1595                 }
1596                 IO (Decode16,
1597                     0x03F8,             // Range Minimum
1598                     0x03F8,             // Range Maximum
1599                     0x00,               // Alignment
1600                     0x08,               // Length
1601                     )
1602             }
1603         }
1604             */
1605         let com1_device = [
1606             0x5B, 0x82, 0x30, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31, 0x08, 0x5F,
1607             0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01, 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11,
1608             0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01, 0x04, 0x00, 0x00, 0x00, 0x47, 0x01,
1609             0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1610         ];
1611         let mut aml = Vec::new();
1612 
1613         Device::new(
1614             "_SB_.COM1".into(),
1615             vec![
1616                 &Name::new("_HID".into(), &EISAName::new("PNP0501")),
1617                 &Name::new(
1618                     "_CRS".into(),
1619                     &ResourceTemplate::new(vec![
1620                         &Interrupt::new(true, true, false, false, 4),
1621                         &IO::new(0x3f8, 0x3f8, 0, 0x8),
1622                     ]),
1623                 ),
1624             ],
1625         )
1626         .to_aml_bytes(&mut aml);
1627         assert_eq!(aml, &com1_device[..]);
1628     }
1629 
1630     #[test]
test_scope()1631     fn test_scope() {
1632         /*
1633         Scope (_SB.MBRD)
1634         {
1635             Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
1636             {
1637                 Memory32Fixed (ReadWrite,
1638                     0xE8000000,         // Address Base
1639                     0x10000000,         // Address Length
1640                     )
1641             })
1642         }
1643         */
1644 
1645         let mbrd_scope = [
1646             0x10, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x42, 0x52, 0x44, 0x08, 0x5F, 0x43,
1647             0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE8,
1648             0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1649         ];
1650         let mut aml = Vec::new();
1651 
1652         Scope::new(
1653             "_SB_.MBRD".into(),
1654             vec![&Name::new(
1655                 "_CRS".into(),
1656                 &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1657             )],
1658         )
1659         .to_aml_bytes(&mut aml);
1660         assert_eq!(aml, &mbrd_scope[..]);
1661     }
1662 
1663     #[test]
test_resource_template()1664     fn test_resource_template() {
1665         /*
1666         Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
1667         {
1668             Memory32Fixed (ReadWrite,
1669                 0xE8000000,         // Address Base
1670                 0x10000000,         // Address Length
1671                 )
1672         })
1673         */
1674         let crs_memory_32_fixed = [
1675             0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00,
1676             0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1677         ];
1678         let mut aml = Vec::new();
1679 
1680         Name::new(
1681             "_CRS".into(),
1682             &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1683         )
1684         .to_aml_bytes(&mut aml);
1685         assert_eq!(aml, crs_memory_32_fixed);
1686 
1687         /*
1688             Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
1689             {
1690                 WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
1691                     0x0000,             // Granularity
1692                     0x0000,             // Range Minimum
1693                     0x00FF,             // Range Maximum
1694                     0x0000,             // Translation Offset
1695                     0x0100,             // Length
1696                     ,, )
1697                 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1698                     0x0000,             // Granularity
1699                     0x0000,             // Range Minimum
1700                     0x0CF7,             // Range Maximum
1701                     0x0000,             // Translation Offset
1702                     0x0CF8,             // Length
1703                     ,, , TypeStatic, DenseTranslation)
1704                 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1705                     0x0000,             // Granularity
1706                     0x0D00,             // Range Minimum
1707                     0xFFFF,             // Range Maximum
1708                     0x0000,             // Translation Offset
1709                     0xF300,             // Length
1710                     ,, , TypeStatic, DenseTranslation)
1711                 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1712                     0x00000000,         // Granularity
1713                     0x000A0000,         // Range Minimum
1714                     0x000BFFFF,         // Range Maximum
1715                     0x00000000,         // Translation Offset
1716                     0x00020000,         // Length
1717                     ,, , AddressRangeMemory, TypeStatic)
1718                 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
1719                     0x00000000,         // Granularity
1720                     0xC0000000,         // Range Minimum
1721                     0xFEBFFFFF,         // Range Maximum
1722                     0x00000000,         // Translation Offset
1723                     0x3EC00000,         // Length
1724                     ,, , AddressRangeMemory, TypeStatic)
1725                 QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1726                     0x0000000000000000, // Granularity
1727                     0x0000000800000000, // Range Minimum
1728                     0x0000000FFFFFFFFF, // Range Maximum
1729                     0x0000000000000000, // Translation Offset
1730                     0x0000000800000000, // Length
1731                     ,, , AddressRangeMemory, TypeStatic)
1732             })
1733         */
1734 
1735         // WordBusNumber from above
1736         let crs_word_bus_number = [
1737             0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x15, 0x0A, 0x12, 0x88, 0x0D, 0x00, 0x02, 0x0C,
1738             0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x79, 0x00,
1739         ];
1740         aml.clear();
1741 
1742         Name::new(
1743             "_CRS".into(),
1744             &ResourceTemplate::new(vec![&AddressSpace::new_bus_number(0x0u16, 0xffu16)]),
1745         )
1746         .to_aml_bytes(&mut aml);
1747         assert_eq!(aml, &crs_word_bus_number);
1748 
1749         // WordIO blocks (x 2) from above
1750         let crs_word_io = [
1751             0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x25, 0x0A, 0x22, 0x88, 0x0D, 0x00, 0x01, 0x0C,
1752             0x03, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0C, 0x00, 0x00, 0xF8, 0x0C, 0x88, 0x0D, 0x00,
1753             0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF3, 0x79,
1754             0x00,
1755         ];
1756         aml.clear();
1757 
1758         Name::new(
1759             "_CRS".into(),
1760             &ResourceTemplate::new(vec![
1761                 &AddressSpace::new_io(0x0u16, 0xcf7u16),
1762                 &AddressSpace::new_io(0xd00u16, 0xffffu16),
1763             ]),
1764         )
1765         .to_aml_bytes(&mut aml);
1766         assert_eq!(aml, &crs_word_io[..]);
1767 
1768         // DWordMemory blocks (x 2) from above
1769         let crs_dword_memory = [
1770             0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x39, 0x0A, 0x36, 0x87, 0x17, 0x00, 0x00, 0x0C,
1771             0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xFF, 0xFF, 0x0B, 0x00, 0x00,
1772             0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x87, 0x17, 0x00, 0x00, 0x0C, 0x01, 0x00,
1773             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xBF, 0xFE, 0x00, 0x00, 0x00,
1774             0x00, 0x00, 0x00, 0xC0, 0x3E, 0x79, 0x00,
1775         ];
1776         aml.clear();
1777 
1778         Name::new(
1779             "_CRS".into(),
1780             &ResourceTemplate::new(vec![
1781                 &AddressSpace::new_memory(
1782                     AddressSpaceCachable::Cacheable,
1783                     true,
1784                     0xa_0000u32,
1785                     0xb_ffffu32,
1786                 ),
1787                 &AddressSpace::new_memory(
1788                     AddressSpaceCachable::NotCacheable,
1789                     true,
1790                     0xc000_0000u32,
1791                     0xfebf_ffffu32,
1792                 ),
1793             ]),
1794         )
1795         .to_aml_bytes(&mut aml);
1796         assert_eq!(aml, &crs_dword_memory[..]);
1797 
1798         // QWordMemory from above
1799         let crs_qword_memory = [
1800             0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x33, 0x0A, 0x30, 0x8A, 0x2B, 0x00, 0x00, 0x0C,
1801             0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1802             0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x79,
1804             0x00,
1805         ];
1806         aml.clear();
1807         Name::new(
1808             "_CRS".into(),
1809             &ResourceTemplate::new(vec![&AddressSpace::new_memory(
1810                 AddressSpaceCachable::Cacheable,
1811                 true,
1812                 0x8_0000_0000u64,
1813                 0xf_ffff_ffffu64,
1814             )]),
1815         )
1816         .to_aml_bytes(&mut aml);
1817 
1818         assert_eq!(aml, &crs_qword_memory[..]);
1819 
1820         /*
1821             Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
1822             {
1823                 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1824                 {
1825                     0x00000004,
1826                 }
1827                 IO (Decode16,
1828                     0x03F8,             // Range Minimum
1829                     0x03F8,             // Range Maximum
1830                     0x00,               // Alignment
1831                     0x08,               // Length
1832                     )
1833             })
1834 
1835         */
1836         let interrupt_io_data = [
1837             0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01,
1838             0x04, 0x00, 0x00, 0x00, 0x47, 0x01, 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1839         ];
1840         aml.clear();
1841         Name::new(
1842             "_CRS".into(),
1843             &ResourceTemplate::new(vec![
1844                 &Interrupt::new(true, true, false, false, 4),
1845                 &IO::new(0x3f8, 0x3f8, 0, 0x8),
1846             ]),
1847         )
1848         .to_aml_bytes(&mut aml);
1849 
1850         assert_eq!(aml, &interrupt_io_data[..]);
1851     }
1852 
1853     #[test]
test_pkg_length()1854     fn test_pkg_length() {
1855         let mut pkg_len_62 = Vec::new();
1856         insert_pkg_length(&mut pkg_len_62, 0, 62);
1857         assert_eq!(pkg_len_62, [63]);
1858 
1859         let mut pkg_len_64 = Vec::new();
1860         insert_pkg_length(&mut pkg_len_64, 0, 64);
1861         assert_eq!(pkg_len_64, [1 << 6 | (66 & 0xf), 66 >> 4]);
1862 
1863         let mut pkg_len_4096 = Vec::new();
1864         insert_pkg_length(&mut pkg_len_4096, 0, 4096);
1865         assert_eq!(
1866             pkg_len_4096,
1867             [
1868                 2 << 6 | (4099 & 0xf) as u8,
1869                 (4099 >> 4) as u8,
1870                 (4099 >> 12) as u8
1871             ]
1872         );
1873     }
1874 
1875     #[test]
test_package()1876     fn test_package() {
1877         /*
1878         Name (_S5, Package (0x01)  // _S5_: S5 System State
1879         {
1880             0x05
1881         })
1882         */
1883         let s5_sleep_data = [0x08, 0x5F, 0x53, 0x35, 0x5F, 0x12, 0x04, 0x01, 0x0A, 0x05];
1884         let mut aml = Vec::new();
1885 
1886         Name::new("_S5_".into(), &Package::new(vec![&5u8])).to_aml_bytes(&mut aml);
1887 
1888         assert_eq!(s5_sleep_data.to_vec(), aml);
1889     }
1890 
1891     #[test]
test_eisa_name()1892     fn test_eisa_name() {
1893         let mut aml = Vec::new();
1894         Name::new("_HID".into(), &EISAName::new("PNP0501")).to_aml_bytes(&mut aml);
1895         assert_eq!(
1896             aml,
1897             [0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01],
1898         )
1899     }
1900     #[test]
test_name_path()1901     fn test_name_path() {
1902         let mut aml = Vec::new();
1903         (&"_SB_".into() as &Path).to_aml_bytes(&mut aml);
1904         assert_eq!(aml, [0x5Fu8, 0x53, 0x42, 0x5F]);
1905         aml.clear();
1906         (&"\\_SB_".into() as &Path).to_aml_bytes(&mut aml);
1907         assert_eq!(aml, [0x5C, 0x5F, 0x53, 0x42, 0x5F]);
1908         aml.clear();
1909         (&"_SB_.COM1".into() as &Path).to_aml_bytes(&mut aml);
1910         assert_eq!(aml, [0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31]);
1911         aml.clear();
1912         (&"_SB_.PCI0._HID".into() as &Path).to_aml_bytes(&mut aml);
1913         assert_eq!(
1914             aml,
1915             [0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x48, 0x49, 0x44]
1916         );
1917     }
1918 
1919     #[test]
test_numbers()1920     fn test_numbers() {
1921         let mut aml = Vec::new();
1922         128u8.to_aml_bytes(&mut aml);
1923         assert_eq!(aml, [0x0a, 0x80]);
1924         aml.clear();
1925         1024u16.to_aml_bytes(&mut aml);
1926         assert_eq!(aml, [0x0b, 0x0, 0x04]);
1927         aml.clear();
1928         (16u32 << 20).to_aml_bytes(&mut aml);
1929         assert_eq!(aml, [0x0c, 0x00, 0x00, 0x0, 0x01]);
1930         aml.clear();
1931         0xdeca_fbad_deca_fbadu64.to_aml_bytes(&mut aml);
1932         assert_eq!(aml, [0x0e, 0xad, 0xfb, 0xca, 0xde, 0xad, 0xfb, 0xca, 0xde]);
1933         aml.clear();
1934 
1935         // u8
1936         0x00_u8.to_aml_bytes(&mut aml);
1937         assert_eq!(aml, [0x00]);
1938         aml.clear();
1939         0x01_u8.to_aml_bytes(&mut aml);
1940         assert_eq!(aml, [0x01]);
1941         aml.clear();
1942         0x86_u8.to_aml_bytes(&mut aml);
1943         assert_eq!(aml, [0x0a, 0x86]);
1944         aml.clear();
1945 
1946         // u16
1947         0x00_u16.to_aml_bytes(&mut aml);
1948         assert_eq!(aml, [0x00]);
1949         aml.clear();
1950         0x01_u16.to_aml_bytes(&mut aml);
1951         assert_eq!(aml, [0x01]);
1952         aml.clear();
1953         0x86_u16.to_aml_bytes(&mut aml);
1954         assert_eq!(aml, [0x0a, 0x86]);
1955         aml.clear();
1956         0xF00D_u16.to_aml_bytes(&mut aml);
1957         assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
1958         aml.clear();
1959 
1960         // u32
1961         0x00_u32.to_aml_bytes(&mut aml);
1962         assert_eq!(aml, [0x00]);
1963         aml.clear();
1964         0x01_u32.to_aml_bytes(&mut aml);
1965         assert_eq!(aml, [0x01]);
1966         aml.clear();
1967         0x86_u32.to_aml_bytes(&mut aml);
1968         assert_eq!(aml, [0x0a, 0x86]);
1969         aml.clear();
1970         0xF00D_u32.to_aml_bytes(&mut aml);
1971         assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
1972         aml.clear();
1973         0xDECAF_u32.to_aml_bytes(&mut aml);
1974         assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
1975         aml.clear();
1976 
1977         // u64
1978         0x00_u64.to_aml_bytes(&mut aml);
1979         assert_eq!(aml, [0x00]);
1980         aml.clear();
1981         0x01_u64.to_aml_bytes(&mut aml);
1982         assert_eq!(aml, [0x01]);
1983         aml.clear();
1984         0x86_u64.to_aml_bytes(&mut aml);
1985         assert_eq!(aml, [0x0a, 0x86]);
1986         aml.clear();
1987         0xF00D_u64.to_aml_bytes(&mut aml);
1988         assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
1989         aml.clear();
1990         0xDECAF_u64.to_aml_bytes(&mut aml);
1991         assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
1992         aml.clear();
1993         0xDECAFC0FFEE_u64.to_aml_bytes(&mut aml);
1994         assert_eq!(aml, [0x0e, 0xee, 0xff, 0xc0, 0xaf, 0xec, 0x0d, 0x00, 0x00]);
1995         aml.clear();
1996 
1997         // usize
1998         0x00_usize.to_aml_bytes(&mut aml);
1999         assert_eq!(aml, [0x00]);
2000         aml.clear();
2001         0x01_usize.to_aml_bytes(&mut aml);
2002         assert_eq!(aml, [0x01]);
2003         aml.clear();
2004         0x86_usize.to_aml_bytes(&mut aml);
2005         assert_eq!(aml, [0x0a, 0x86]);
2006         aml.clear();
2007         0xF00D_usize.to_aml_bytes(&mut aml);
2008         assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
2009         aml.clear();
2010         0xDECAF_usize.to_aml_bytes(&mut aml);
2011         assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
2012         aml.clear();
2013         #[cfg(target_pointer_width = "64")]
2014         {
2015             0xDECAFC0FFEE_usize.to_aml_bytes(&mut aml);
2016             assert_eq!(aml, [0x0e, 0xee, 0xff, 0xc0, 0xaf, 0xec, 0x0d, 0x00, 0x00]);
2017             aml.clear();
2018         }
2019     }
2020 
2021     #[test]
test_name()2022     fn test_name() {
2023         let mut aml = Vec::new();
2024         Name::new("_SB_.PCI0._UID".into(), &0x1234u16).to_aml_bytes(&mut aml);
2025         assert_eq!(
2026             aml,
2027             [
2028                 0x08, /* NameOp */
2029                 0x2F, /* MultiNamePrefix */
2030                 0x03, /* 3 name parts */
2031                 0x5F, 0x53, 0x42, 0x5F, /* _SB_ */
2032                 0x50, 0x43, 0x49, 0x30, /* PCI0 */
2033                 0x5F, 0x55, 0x49, 0x44, /* _UID */
2034                 0x0b, /* WordPrefix */
2035                 0x34, 0x12
2036             ]
2037         );
2038     }
2039 
2040     #[test]
test_string()2041     fn test_string() {
2042         let mut aml = Vec::new();
2043         (&"ACPI" as &dyn Aml).to_aml_bytes(&mut aml);
2044         assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
2045         aml.clear();
2046         "ACPI".to_owned().to_aml_bytes(&mut aml);
2047         assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
2048     }
2049 
2050     #[test]
test_method()2051     fn test_method() {
2052         let mut aml = Vec::new();
2053         Method::new("_STA".into(), 0, false, vec![&Return::new(&0xfu8)]).to_aml_bytes(&mut aml);
2054         assert_eq!(
2055             aml,
2056             [0x14, 0x09, 0x5F, 0x53, 0x54, 0x41, 0x00, 0xA4, 0x0A, 0x0F]
2057         );
2058     }
2059 
2060     #[test]
test_field()2061     fn test_field() {
2062         /*
2063             Field (PRST, ByteAcc, NoLock, WriteAsZeros)
2064             {
2065                 Offset (0x04),
2066                 CPEN,   1,
2067                 CINS,   1,
2068                 CRMV,   1,
2069                 CEJ0,   1,
2070                 Offset (0x05),
2071                 CCMD,   8
2072             }
2073 
2074         */
2075 
2076         let field_data = [
2077             0x5Bu8, 0x81, 0x23, 0x50, 0x52, 0x53, 0x54, 0x41, 0x00, 0x20, 0x43, 0x50, 0x45, 0x4E,
2078             0x01, 0x43, 0x49, 0x4E, 0x53, 0x01, 0x43, 0x52, 0x4D, 0x56, 0x01, 0x43, 0x45, 0x4A,
2079             0x30, 0x01, 0x00, 0x04, 0x43, 0x43, 0x4D, 0x44, 0x08,
2080         ];
2081         let mut aml = Vec::new();
2082 
2083         Field::new(
2084             "PRST".into(),
2085             FieldAccessType::Byte,
2086             FieldLockRule::NoLock,
2087             FieldUpdateRule::WriteAsZeroes,
2088             vec![
2089                 FieldEntry::Reserved(32),
2090                 FieldEntry::Named(*b"CPEN", 1),
2091                 FieldEntry::Named(*b"CINS", 1),
2092                 FieldEntry::Named(*b"CRMV", 1),
2093                 FieldEntry::Named(*b"CEJ0", 1),
2094                 FieldEntry::Reserved(4),
2095                 FieldEntry::Named(*b"CCMD", 8),
2096             ],
2097         )
2098         .to_aml_bytes(&mut aml);
2099         assert_eq!(aml, &field_data[..]);
2100 
2101         /*
2102             Field (PRST, DWordAcc, Lock, Preserve)
2103             {
2104                 CSEL,   32,
2105                 Offset (0x08),
2106                 CDAT,   32
2107             }
2108         */
2109 
2110         let field_data = [
2111             0x5Bu8, 0x81, 0x12, 0x50, 0x52, 0x53, 0x54, 0x13, 0x43, 0x53, 0x45, 0x4C, 0x20, 0x00,
2112             0x20, 0x43, 0x44, 0x41, 0x54, 0x20,
2113         ];
2114         aml.clear();
2115 
2116         Field::new(
2117             "PRST".into(),
2118             FieldAccessType::DWord,
2119             FieldLockRule::Lock,
2120             FieldUpdateRule::Preserve,
2121             vec![
2122                 FieldEntry::Named(*b"CSEL", 32),
2123                 FieldEntry::Reserved(32),
2124                 FieldEntry::Named(*b"CDAT", 32),
2125             ],
2126         )
2127         .to_aml_bytes(&mut aml);
2128         assert_eq!(aml, &field_data[..]);
2129     }
2130 
2131     #[test]
test_op_region()2132     fn test_op_region() {
2133         /*
2134             OperationRegion (PRST, SystemIO, 0x0CD8, 0x0C)
2135         */
2136         let op_region_data = [
2137             0x5Bu8, 0x80, 0x50, 0x52, 0x53, 0x54, 0x01, 0x0B, 0xD8, 0x0C, 0x0A, 0x0C,
2138         ];
2139         let mut aml = Vec::new();
2140 
2141         OpRegion::new(
2142             "PRST".into(),
2143             OpRegionSpace::SystemIO,
2144             &0xcd8_usize,
2145             &0xc_usize,
2146         )
2147         .to_aml_bytes(&mut aml);
2148         assert_eq!(aml, &op_region_data[..]);
2149     }
2150 
2151     #[test]
test_arg_if()2152     fn test_arg_if() {
2153         /*
2154             Method(TEST, 1, NotSerialized) {
2155                 If (Arg0 == Zero) {
2156                         Return(One)
2157                 }
2158                 Return(Zero)
2159             }
2160         */
2161         let arg_if_data = [
2162             0x14, 0x0F, 0x54, 0x45, 0x53, 0x54, 0x01, 0xA0, 0x06, 0x93, 0x68, 0x00, 0xA4, 0x01,
2163             0xA4, 0x00,
2164         ];
2165         let mut aml = Vec::new();
2166 
2167         Method::new(
2168             "TEST".into(),
2169             1,
2170             false,
2171             vec![
2172                 &If::new(&Equal::new(&Arg(0), &ZERO), vec![&Return::new(&ONE)]),
2173                 &Return::new(&ZERO),
2174             ],
2175         )
2176         .to_aml_bytes(&mut aml);
2177         assert_eq!(aml, &arg_if_data);
2178     }
2179 
2180     #[test]
test_local_if()2181     fn test_local_if() {
2182         /*
2183             Method(TEST, 0, NotSerialized) {
2184                 Local0 = One
2185                 If (Local0 == Zero) {
2186                         Return(One)
2187                 }
2188                 Return(Zero)
2189             }
2190         */
2191         let local_if_data = [
2192             0x14, 0x12, 0x54, 0x45, 0x53, 0x54, 0x00, 0x70, 0x01, 0x60, 0xA0, 0x06, 0x93, 0x60,
2193             0x00, 0xA4, 0x01, 0xA4, 0x00,
2194         ];
2195         let mut aml = Vec::new();
2196 
2197         Method::new(
2198             "TEST".into(),
2199             0,
2200             false,
2201             vec![
2202                 &Store::new(&Local(0), &ONE),
2203                 &If::new(&Equal::new(&Local(0), &ZERO), vec![&Return::new(&ONE)]),
2204                 &Return::new(&ZERO),
2205             ],
2206         )
2207         .to_aml_bytes(&mut aml);
2208         assert_eq!(aml, &local_if_data);
2209     }
2210 
2211     #[test]
test_mutex()2212     fn test_mutex() {
2213         /*
2214         Device (_SB_.MHPC)
2215         {
2216                 Name (_HID, EisaId("PNP0A06") /* Generic Container Device */)  // _HID: Hardware ID
2217                 Mutex (MLCK, 0x00)
2218                 Method (TEST, 0, NotSerialized)
2219                 {
2220                     Acquire (MLCK, 0xFFFF)
2221                     Local0 = One
2222                     Release (MLCK)
2223                 }
2224         }
2225         */
2226 
2227         let mutex_data = [
2228             0x5B, 0x82, 0x33, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2229             0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x5B, 0x01, 0x4D, 0x4C, 0x43, 0x4B,
2230             0x00, 0x14, 0x17, 0x54, 0x45, 0x53, 0x54, 0x00, 0x5B, 0x23, 0x4D, 0x4C, 0x43, 0x4B,
2231             0xFF, 0xFF, 0x70, 0x01, 0x60, 0x5B, 0x27, 0x4D, 0x4C, 0x43, 0x4B,
2232         ];
2233         let mut aml = Vec::new();
2234 
2235         let mutex = Mutex::new("MLCK".into(), 0);
2236         Device::new(
2237             "_SB_.MHPC".into(),
2238             vec![
2239                 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2240                 &mutex,
2241                 &Method::new(
2242                     "TEST".into(),
2243                     0,
2244                     false,
2245                     vec![
2246                         &Acquire::new("MLCK".into(), 0xffff),
2247                         &Store::new(&Local(0), &ONE),
2248                         &Release::new("MLCK".into()),
2249                     ],
2250                 ),
2251             ],
2252         )
2253         .to_aml_bytes(&mut aml);
2254         assert_eq!(aml, &mutex_data[..]);
2255     }
2256 
2257     #[test]
test_notify()2258     fn test_notify() {
2259         /*
2260         Device (_SB.MHPC)
2261         {
2262             Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */)  // _HID: Hardware ID
2263             Method (TEST, 0, NotSerialized)
2264             {
2265                 Notify (MHPC, One) // Device Check
2266             }
2267         }
2268         */
2269         let notify_data = [
2270             0x5B, 0x82, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2271             0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x0C, 0x54, 0x45, 0x53, 0x54,
2272             0x00, 0x86, 0x4D, 0x48, 0x50, 0x43, 0x01,
2273         ];
2274         let mut aml = Vec::new();
2275 
2276         Device::new(
2277             "_SB_.MHPC".into(),
2278             vec![
2279                 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2280                 &Method::new(
2281                     "TEST".into(),
2282                     0,
2283                     false,
2284                     vec![&Notify::new(&Path::new("MHPC"), &ONE)],
2285                 ),
2286             ],
2287         )
2288         .to_aml_bytes(&mut aml);
2289         assert_eq!(aml, &notify_data[..]);
2290     }
2291 
2292     #[test]
test_while()2293     fn test_while() {
2294         /*
2295         Device (_SB.MHPC)
2296         {
2297             Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */)  // _HID: Hardware ID
2298             Method (TEST, 0, NotSerialized)
2299             {
2300                 Local0 = Zero
2301                 While ((Local0 < 0x04))
2302                 {
2303                     Local0 += One
2304                 }
2305             }
2306         }
2307         */
2308 
2309         let while_data = [
2310             0x5B, 0x82, 0x28, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2311             0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x13, 0x54, 0x45, 0x53, 0x54,
2312             0x00, 0x70, 0x00, 0x60, 0xA2, 0x09, 0x95, 0x60, 0x0A, 0x04, 0x72, 0x60, 0x01, 0x60,
2313         ];
2314         let mut aml = Vec::new();
2315 
2316         Device::new(
2317             "_SB_.MHPC".into(),
2318             vec![
2319                 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2320                 &Method::new(
2321                     "TEST".into(),
2322                     0,
2323                     false,
2324                     vec![
2325                         &Store::new(&Local(0), &ZERO),
2326                         &While::new(
2327                             &LessThan::new(&Local(0), &4usize),
2328                             vec![&Add::new(&Local(0), &Local(0), &ONE)],
2329                         ),
2330                     ],
2331                 ),
2332             ],
2333         )
2334         .to_aml_bytes(&mut aml);
2335         assert_eq!(aml, &while_data[..])
2336     }
2337 
2338     #[test]
test_method_call()2339     fn test_method_call() {
2340         /*
2341             Method (TST1, 1, NotSerialized)
2342             {
2343                 TST2 (One, One)
2344             }
2345 
2346             Method (TST2, 2, NotSerialized)
2347             {
2348                 TST1 (One)
2349             }
2350         */
2351         let test_data = [
2352             0x14, 0x0C, 0x54, 0x53, 0x54, 0x31, 0x01, 0x54, 0x53, 0x54, 0x32, 0x01, 0x01, 0x14,
2353             0x0B, 0x54, 0x53, 0x54, 0x32, 0x02, 0x54, 0x53, 0x54, 0x31, 0x01,
2354         ];
2355 
2356         let mut methods = Vec::new();
2357         Method::new(
2358             "TST1".into(),
2359             1,
2360             false,
2361             vec![&MethodCall::new("TST2".into(), vec![&ONE, &ONE])],
2362         )
2363         .to_aml_bytes(&mut methods);
2364         Method::new(
2365             "TST2".into(),
2366             2,
2367             false,
2368             vec![&MethodCall::new("TST1".into(), vec![&ONE])],
2369         )
2370         .to_aml_bytes(&mut methods);
2371         assert_eq!(&methods[..], &test_data[..])
2372     }
2373 
2374     #[test]
test_buffer()2375     fn test_buffer() {
2376         /*
2377         Name (_MAT, Buffer (0x08)  // _MAT: Multiple APIC Table Entry
2378         {
2379             0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00   /* ........ */
2380         })
2381         */
2382         let buffer_data = [
2383             0x08, 0x5F, 0x4D, 0x41, 0x54, 0x11, 0x0B, 0x0A, 0x08, 0x00, 0x08, 0x00, 0x00, 0x01,
2384             0x00, 0x00, 0x00,
2385         ];
2386         let mut aml = Vec::new();
2387 
2388         Name::new(
2389             "_MAT".into(),
2390             &BufferData::new(vec![0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00]),
2391         )
2392         .to_aml_bytes(&mut aml);
2393         assert_eq!(aml, &buffer_data[..])
2394     }
2395 }
2396