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