acpi_tables/
aml.rs

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