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