1#![allow(missing_debug_implementations)]
8
9use std::marker::PhantomData;
10
11#[derive(Debug, Clone, thiserror::Error, displaydoc::Display)]
12pub enum AmlError {
13 NameEmpty,
15 InvalidPartLength,
17 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); }
78 n => {
79 bytes.push(0x2f); 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); 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); 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); 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); 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 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]; 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); 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
205fn create_pkg_length(data: &[u8], include_self: bool) -> Vec<u8> {
219 let mut result = Vec::new();
220
221 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); bytes.extend_from_slice(v.as_bytes());
314 bytes.push(0x0); }
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 for child in &self.children {
344 child.append_aml_bytes(&mut tmp)?;
345 }
346
347 tmp.push(0x79); tmp.push(0); 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 let pkg_length = create_pkg_length(&tmp, true);
361
362 bytes.push(0x11); 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, 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); bytes.extend_from_slice(&9u16.to_le_bytes());
395 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, })
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); bytes.extend_from_slice(&(TryInto::<u16>::try_into(length).unwrap()).to_le_bytes());
473 bytes.push(self.r#type as u8); let generic_flags = (1 << 2) | (1 << 3); 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, 3 + 5 * std::mem::size_of::<u16>(), );
487
488 bytes.extend_from_slice(&0u16.to_le_bytes()); bytes.extend_from_slice(&self.min.to_le_bytes()); bytes.extend_from_slice(&self.max.to_le_bytes()); bytes.extend_from_slice(&0u16.to_le_bytes()); let len = self.max - self.min + 1;
493 bytes.extend_from_slice(&len.to_le_bytes()); 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, 3 + 5 * std::mem::size_of::<u32>(), );
505
506 bytes.extend_from_slice(&0u32.to_le_bytes()); bytes.extend_from_slice(&self.min.to_le_bytes()); bytes.extend_from_slice(&self.max.to_le_bytes()); bytes.extend_from_slice(&0u32.to_le_bytes()); let len = self.max - self.min + 1;
511 bytes.extend_from_slice(&len.to_le_bytes()); 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, 3 + 5 * std::mem::size_of::<u64>(), );
523
524 bytes.extend_from_slice(&0u64.to_le_bytes()); bytes.extend_from_slice(&self.min.to_le_bytes()); bytes.extend_from_slice(&self.max.to_le_bytes()); bytes.extend_from_slice(&0u64.to_le_bytes()); let len = self.max - self.min + 1;
529 bytes.extend_from_slice(&len.to_le_bytes()); 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); bytes.push(1); 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); 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); 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); bytes.push(0x82); 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); 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); 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); 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); bytes.push(0x81); 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); bytes.push(0x80); self.path.append_aml_bytes(bytes)?;
832 bytes.push(self.space as u8);
833 self.offset.append_aml_bytes(bytes)?; self.length.append_aml_bytes(bytes)?; 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); 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); 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); 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); 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); 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); 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); bytes.push(0x01); 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); bytes.push(0x23); 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); bytes.push(0x27); 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); 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); 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); 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
1091binary_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); 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); 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); 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 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 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 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 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 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 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 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 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 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, 0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x55, 0x49, 0x44, 0x0b, 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 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 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 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 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 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 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 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 ¬ify_data[..]
1861 );
1862 }
1863
1864 #[test]
1865 fn test_while() {
1866 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 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 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 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}