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