1pub trait Aml {
9 fn to_aml_bytes(&self, bytes: &mut Vec<u8>);
13}
14
15const ZEROOP: u8 = 0x00;
17const ONEOP: u8 = 0x01;
18const NAMEOP: u8 = 0x08;
19const BYTEPREFIX: u8 = 0x0a;
20const WORDPREFIX: u8 = 0x0b;
21const DWORDPREFIX: u8 = 0x0c;
22const STRINGOP: u8 = 0x0d;
23const QWORDPREFIX: u8 = 0x0e;
24const SCOPEOP: u8 = 0x10;
25const BUFFEROP: u8 = 0x11;
26const PACKAGEOP: u8 = 0x12;
27const VARPACKAGEOP: u8 = 0x13;
28const METHODOP: u8 = 0x14;
29const DUALNAMEPREFIX: u8 = 0x2e;
30const MULTINAMEPREFIX: u8 = 0x2f;
31const NAMECHARBASE: u8 = 0x40;
32
33const EXTOPPREFIX: u8 = 0x5b;
34const MUTEXOP: u8 = 0x01;
35const CREATEFIELDOP: u8 = 0x13;
36const ACQUIREOP: u8 = 0x23;
37const RELEASEOP: u8 = 0x27;
38const OPREGIONOP: u8 = 0x80;
39const FIELDOP: u8 = 0x81;
40const DEVICEOP: u8 = 0x82;
41const POWERRESOURCEOP: u8 = 0x84;
42
43const LOCAL0OP: u8 = 0x60;
44const ARG0OP: u8 = 0x68;
45const STOREOP: u8 = 0x70;
46const ADDOP: u8 = 0x72;
47const CONCATOP: u8 = 0x73;
48const SUBTRACTOP: u8 = 0x74;
49const MULTIPLYOP: u8 = 0x77;
50const SHIFTLEFTOP: u8 = 0x79;
51const SHIFTRIGHTOP: u8 = 0x7a;
52const ANDOP: u8 = 0x7b;
53const NANDOP: u8 = 0x7c;
54const OROP: u8 = 0x7d;
55const NOROP: u8 = 0x7e;
56const XOROP: u8 = 0x7f;
57const DEREFOFOP: u8 = 0x83;
58const CONCATRESOP: u8 = 0x84;
59const MODOP: u8 = 0x85;
60const NOTIFYOP: u8 = 0x86;
61const SIZEOFOP: u8 = 0x87;
62const INDEXOP: u8 = 0x88;
63const CREATEDWFIELDOP: u8 = 0x8a;
64const OBJECTTYPEOP: u8 = 0x8e;
65const CREATEQWFIELDOP: u8 = 0x8f;
66const LNOTOP: u8 = 0x92;
67const LEQUALOP: u8 = 0x93;
68const LGREATEROP: u8 = 0x94;
69const LLESSOP: u8 = 0x95;
70const TOBUFFEROP: u8 = 0x96;
71const TOINTEGEROP: u8 = 0x99;
72const TOSTRINGOP: u8 = 0x9c;
73const MIDOP: u8 = 0x9e;
74const IFOP: u8 = 0xa0;
75const ELSEOP: u8 = 0xa1;
76const WHILEOP: u8 = 0xa2;
77const RETURNOP: u8 = 0xa4;
78const ONESOP: u8 = 0xff;
79
80const IOPORTDESC: u8 = 0x47;
82const ENDTAG: u8 = 0x79;
83const MEMORY32FIXEDDESC: u8 = 0x86;
84const DWORDADDRSPACEDESC: u8 = 0x87;
85const WORDADDRSPACEDESC: u8 = 0x88;
86const EXTIRQDESC: u8 = 0x89;
87const QWORDADDRSPACEDESC: u8 = 0x8A;
88
89pub const ZERO: Zero = Zero {};
91pub struct Zero {}
92
93impl Aml for Zero {
94 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
95 bytes.push(ZEROOP);
96 }
97}
98
99pub const ONE: One = One {};
101pub struct One {}
102
103impl Aml for One {
104 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
105 bytes.push(ONEOP);
106 }
107}
108
109pub const ONES: Ones = Ones {};
111pub struct Ones {}
112
113impl Aml for Ones {
114 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
115 bytes.push(ONESOP);
116 }
117}
118
119pub struct Path {
122 root: bool,
123 name_parts: Vec<[u8; 4]>,
124}
125
126impl Aml for Path {
127 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
128 if self.root {
129 bytes.push(b'\\');
130 }
131
132 match self.name_parts.len() {
133 0 => panic!("Name cannot be empty"),
134 1 => {}
135 2 => {
136 bytes.push(DUALNAMEPREFIX);
137 }
138 n => {
139 bytes.push(MULTINAMEPREFIX);
140 bytes.push(n as u8);
141 }
142 };
143
144 for part in &self.name_parts {
145 bytes.extend_from_slice(part);
146 }
147 }
148}
149
150impl Path {
151 pub fn new(name: &str) -> Self {
154 let root = name.starts_with('\\');
155 let offset = root as usize;
156 let mut name_parts = Vec::new();
157 for part in name[offset..].split('.') {
158 assert_eq!(part.len(), 4);
159 let mut name_part = [0u8; 4];
160 name_part.copy_from_slice(part.as_bytes());
161 name_parts.push(name_part);
162 }
163
164 Path { root, name_parts }
165 }
166}
167
168impl From<&str> for Path {
169 fn from(s: &str) -> Self {
170 Path::new(s)
171 }
172}
173
174pub type Byte = u8;
175
176impl Aml for Byte {
177 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
178 match *self {
179 0 => ZERO.to_aml_bytes(bytes),
180 1 => ONE.to_aml_bytes(bytes),
181 _ => {
182 bytes.push(BYTEPREFIX);
183 bytes.push(*self);
184 }
185 }
186 }
187}
188
189pub type Word = u16;
190
191impl Aml for Word {
192 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
193 if *self <= Byte::MAX.into() {
194 (*self as Byte).to_aml_bytes(bytes);
195 } else {
196 bytes.push(WORDPREFIX);
197 bytes.extend_from_slice(&self.to_le_bytes());
198 }
199 }
200}
201
202pub type DWord = u32;
203
204impl Aml for DWord {
205 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
206 if *self <= Word::MAX.into() {
207 (*self as Word).to_aml_bytes(bytes);
208 } else {
209 bytes.push(DWORDPREFIX);
210 bytes.extend_from_slice(&self.to_le_bytes());
211 }
212 }
213}
214
215pub type QWord = u64;
216
217impl Aml for QWord {
218 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
219 if *self <= DWord::MAX.into() {
220 (*self as DWord).to_aml_bytes(bytes);
221 } else {
222 bytes.push(QWORDPREFIX);
223 bytes.extend_from_slice(&self.to_le_bytes());
224 }
225 }
226}
227
228pub struct Name {
230 bytes: Vec<u8>,
231}
232
233impl Aml for Name {
234 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
235 bytes.extend_from_slice(&self.bytes);
236 }
237}
238
239impl Name {
240 pub fn new(path: Path, inner: &dyn Aml) -> Self {
245 let mut bytes = vec![NAMEOP];
246 path.to_aml_bytes(&mut bytes);
247 inner.to_aml_bytes(&mut bytes);
248 Name { bytes }
249 }
250
251 pub fn new_field_name(field_name: &str) -> Self {
255 let bytes = field_name.as_bytes().to_vec();
256 Name { bytes }
257 }
258}
259
260pub struct Package {
262 children_bytes: Vec<u8>,
263}
264
265impl Aml for Package {
266 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
267 aml.push(PACKAGEOP);
268 append_pkg_length(aml, self.children_bytes.len());
269 aml.extend_from_slice(&self.children_bytes);
270 }
271}
272
273impl Package {
274 pub fn new(children: Vec<&dyn Aml>) -> Package {
276 let mut bytes = vec![children.len() as u8];
277 for child in &children {
278 child.to_aml_bytes(&mut bytes);
279 }
280 Package {
281 children_bytes: bytes,
282 }
283 }
284}
285
286pub struct VarPackageTerm<'a> {
288 data: &'a dyn Aml,
289}
290
291impl Aml for VarPackageTerm<'_> {
292 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
293 aml.push(VARPACKAGEOP);
294
295 let start = aml.len();
296 self.data.to_aml_bytes(aml);
297 let data_len = aml.len() - start;
298
299 insert_pkg_length(aml, start, data_len);
300 }
301}
302
303impl<'a> VarPackageTerm<'a> {
304 pub fn new(data: &'a dyn Aml) -> Self {
306 VarPackageTerm { data }
307 }
308}
309
310fn insert_length(aml: &mut Vec<u8>, position: usize, len: usize, include_self: bool) {
327 let length_length = if len < (2usize.pow(6) - 1) {
329 1
330 } else if len < (2usize.pow(12) - 2) {
331 2
332 } else if len < (2usize.pow(20) - 3) {
333 3
334 } else {
335 4
336 };
337
338 let length = len + if include_self { length_length } else { 0 };
339
340 match length_length {
341 1 => aml.insert(position, length as u8),
342 2 => {
343 aml.splice(
344 position..position,
345 [(1u8 << 6) | (length & 0xf) as u8, (length >> 4) as u8],
346 );
347 }
348 3 => {
349 aml.splice(
350 position..position,
351 [
352 (2u8 << 6) | (length & 0xf) as u8,
353 (length >> 4) as u8,
354 (length >> 12) as u8,
355 ],
356 );
357 }
358 _ => {
359 aml.splice(
360 position..position,
361 [
362 (3u8 << 6) | (length & 0xf) as u8,
363 (length >> 4) as u8,
364 (length >> 12) as u8,
365 (length >> 20) as u8,
366 ],
367 );
368 }
369 }
370}
371
372fn insert_pkg_length(aml: &mut Vec<u8>, position: usize, len: usize) {
373 insert_length(aml, position, len, true);
374}
375
376fn append_pkg_length(aml: &mut Vec<u8>, len: usize) {
377 insert_length(aml, aml.len(), len, true);
378}
379
380fn append_named_field_length(aml: &mut Vec<u8>, len: usize) {
382 insert_length(aml, aml.len(), len, false);
383}
384
385pub struct EISAName {
387 value: DWord,
388}
389
390impl EISAName {
391 pub fn new(name: &str) -> Self {
396 assert_eq!(name.len(), 7);
397
398 let data = name.as_bytes();
399
400 let value: u32 = (u32::from(data[0].checked_sub(NAMECHARBASE).unwrap()) << 26
401 | u32::from(data[1].checked_sub(NAMECHARBASE).unwrap()) << 21
402 | u32::from(data[2].checked_sub(NAMECHARBASE).unwrap()) << 16
403 | name.chars().nth(3).unwrap().to_digit(16).unwrap() << 12
404 | name.chars().nth(4).unwrap().to_digit(16).unwrap() << 8
405 | name.chars().nth(5).unwrap().to_digit(16).unwrap() << 4
406 | name.chars().nth(6).unwrap().to_digit(16).unwrap())
407 .swap_bytes();
408
409 EISAName { value }
410 }
411}
412
413impl Aml for EISAName {
414 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
415 self.value.to_aml_bytes(bytes);
416 }
417}
418
419pub type Usize = usize;
420
421impl Aml for Usize {
422 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
423 #[cfg(target_pointer_width = "16")]
424 (*self as u16).to_aml_bytes(bytes);
425 #[cfg(target_pointer_width = "32")]
426 (*self as u32).to_aml_bytes(bytes);
427 #[cfg(target_pointer_width = "64")]
428 (*self as u64).to_aml_bytes(bytes);
429 }
430}
431
432fn append_aml_string(data: &mut Vec<u8>, v: &str) {
433 data.push(STRINGOP);
434 data.extend_from_slice(v.as_bytes());
435 data.push(0x0); }
437
438pub type AmlStr = &'static str;
440
441impl Aml for AmlStr {
442 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
443 append_aml_string(bytes, self);
444 }
445}
446
447pub type AmlString = String;
449
450impl Aml for AmlString {
451 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
452 append_aml_string(bytes, self);
453 }
454}
455
456pub struct ResourceTemplate<'a> {
458 children: Vec<&'a dyn Aml>,
459}
460
461impl Aml for ResourceTemplate<'_> {
462 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
463 aml.push(BUFFEROP);
464
465 let pos = aml.len();
466
467 for child in &self.children {
469 child.to_aml_bytes(aml);
470 }
471
472 aml.push(ENDTAG);
474 aml.push(0); let buffer_length = aml.len() - pos;
479 let mut buffer_length_bytes = Vec::new();
480 buffer_length.to_aml_bytes(&mut buffer_length_bytes);
481 aml.splice(pos..pos, buffer_length_bytes);
482
483 let len = aml.len() - pos;
485 insert_pkg_length(aml, pos, len);
486 }
487}
488
489impl<'a> ResourceTemplate<'a> {
490 pub fn new(children: Vec<&'a dyn Aml>) -> Self {
492 ResourceTemplate { children }
493 }
494}
495
496pub struct Memory32Fixed {
498 read_write: bool, base: u32,
500 length: u32,
501}
502
503impl Memory32Fixed {
504 pub fn new(read_write: bool, base: u32, length: u32) -> Self {
506 Memory32Fixed {
507 read_write,
508 base,
509 length,
510 }
511 }
512}
513
514impl Aml for Memory32Fixed {
515 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
516 bytes.push(MEMORY32FIXEDDESC); bytes.extend_from_slice(&9u16.to_le_bytes());
518
519 bytes.push(self.read_write as u8);
521 bytes.extend_from_slice(&self.base.to_le_bytes());
522 bytes.extend_from_slice(&self.length.to_le_bytes());
523 }
524}
525
526#[derive(Copy, Clone)]
527enum AddressSpaceType {
528 Memory,
529 IO,
530 BusNumber,
531}
532
533#[derive(Copy, Clone)]
535pub enum AddressSpaceCachable {
536 NotCacheable,
537 Cacheable,
538 WriteCombining,
539 PreFetchable,
540}
541
542pub struct AddressSpace<T> {
545 type_: AddressSpaceType,
546 min: T,
547 max: T,
548 type_flags: u8,
549}
550
551impl<T> AddressSpace<T> {
552 pub fn new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self {
554 AddressSpace {
555 type_: AddressSpaceType::Memory,
556 min,
557 max,
558 type_flags: (cacheable as u8) << 1 | read_write as u8,
559 }
560 }
561
562 pub fn new_io(min: T, max: T) -> Self {
564 AddressSpace {
565 type_: AddressSpaceType::IO,
566 min,
567 max,
568 type_flags: 3, }
570 }
571
572 pub fn new_bus_number(min: T, max: T) -> Self {
574 AddressSpace {
575 type_: AddressSpaceType::BusNumber,
576 min,
577 max,
578 type_flags: 0,
579 }
580 }
581
582 fn push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize) {
583 bytes.push(descriptor); bytes.extend_from_slice(&(length as u16).to_le_bytes());
585 bytes.push(self.type_ as u8); let generic_flags = 1 << 2 | 1 << 3; bytes.push(generic_flags);
588 bytes.push(self.type_flags);
589 }
590}
591
592impl Aml for AddressSpace<u16> {
593 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
594 self.push_header(
595 bytes,
596 WORDADDRSPACEDESC, 3 + 5 * std::mem::size_of::<u16>(), );
599
600 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;
605 bytes.extend_from_slice(&len.to_le_bytes()); }
607}
608
609impl Aml for AddressSpace<u32> {
610 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
611 self.push_header(
612 bytes,
613 DWORDADDRSPACEDESC, 3 + 5 * std::mem::size_of::<u32>(), );
616
617 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;
622 bytes.extend_from_slice(&len.to_le_bytes()); }
624}
625
626impl Aml for AddressSpace<u64> {
627 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
628 self.push_header(
629 bytes,
630 QWORDADDRSPACEDESC, 3 + 5 * std::mem::size_of::<u64>(), );
633
634 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;
639 bytes.extend_from_slice(&len.to_le_bytes()); }
641}
642
643pub struct IO {
645 min: u16,
646 max: u16,
647 alignment: u8,
648 length: u8,
649}
650
651impl IO {
652 pub fn new(min: u16, max: u16, alignment: u8, length: u8) -> Self {
654 IO {
655 min,
656 max,
657 alignment,
658 length,
659 }
660 }
661}
662
663impl Aml for IO {
664 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
665 bytes.push(IOPORTDESC); bytes.push(1); bytes.extend_from_slice(&self.min.to_le_bytes());
668 bytes.extend_from_slice(&self.max.to_le_bytes());
669 bytes.push(self.alignment);
670 bytes.push(self.length);
671 }
672}
673
674pub struct Interrupt {
676 consumer: bool,
677 edge_triggered: bool,
678 active_low: bool,
679 shared: bool,
680 number: u32,
681}
682
683impl Interrupt {
684 pub fn new(
686 consumer: bool,
687 edge_triggered: bool,
688 active_low: bool,
689 shared: bool,
690 number: u32,
691 ) -> Self {
692 Interrupt {
693 consumer,
694 edge_triggered,
695 active_low,
696 shared,
697 number,
698 }
699 }
700}
701
702impl Aml for Interrupt {
703 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
704 bytes.push(EXTIRQDESC); bytes.extend_from_slice(&6u16.to_le_bytes());
706 let flags = (self.shared as u8) << 3
707 | (self.active_low as u8) << 2
708 | (self.edge_triggered as u8) << 1
709 | self.consumer as u8;
710 bytes.push(flags);
711 bytes.push(1u8); bytes.extend_from_slice(&self.number.to_le_bytes());
713 }
714}
715
716pub struct Device<'a> {
718 path: Path,
719 children: Vec<&'a dyn Aml>,
720}
721
722impl Aml for Device<'_> {
723 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
724 aml.push(EXTOPPREFIX); aml.push(DEVICEOP); let start = aml.len();
728 self.path.to_aml_bytes(aml);
729 for child in &self.children {
730 child.to_aml_bytes(aml);
731 }
732 let len = aml.len() - start;
733
734 insert_pkg_length(aml, start, len);
735 }
736}
737
738impl<'a> Device<'a> {
739 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
741 Device { path, children }
742 }
743}
744
745pub struct Scope<'a> {
747 path: Path,
748 children: Vec<&'a dyn Aml>,
749}
750
751impl Aml for Scope<'_> {
752 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
753 aml.push(SCOPEOP);
754
755 let start = aml.len();
756 self.path.to_aml_bytes(aml);
757 for child in &self.children {
758 child.to_aml_bytes(aml);
759 }
760 let len = aml.len() - start;
761
762 insert_pkg_length(aml, start, len);
763 }
764}
765
766impl<'a> Scope<'a> {
767 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
769 Scope { path, children }
770 }
771
772 pub fn raw(path: Path, mut children: Vec<u8>) -> Vec<u8> {
774 let mut bytes = Vec::new();
775 bytes.push(SCOPEOP);
776
777 let start = bytes.len();
778 path.to_aml_bytes(&mut bytes);
779 bytes.append(&mut children);
780 let len = bytes.len() - start;
781
782 insert_pkg_length(&mut bytes, start, len);
783
784 bytes
785 }
786}
787
788pub struct Method<'a> {
790 path: Path,
791 children: Vec<&'a dyn Aml>,
792 args: u8,
793 serialized: bool,
794}
795
796impl<'a> Method<'a> {
797 pub fn new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self {
799 Method {
800 path,
801 children,
802 args,
803 serialized,
804 }
805 }
806}
807
808impl Aml for Method<'_> {
809 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
810 aml.push(METHODOP);
811
812 let start = aml.len();
813 self.path.to_aml_bytes(aml);
814 let flags: u8 = (self.args & 0x7) | (self.serialized as u8) << 3;
815 aml.push(flags);
816 for child in &self.children {
817 child.to_aml_bytes(aml);
818 }
819 let len = aml.len() - start;
820
821 insert_pkg_length(aml, start, len);
822 }
823}
824
825#[derive(Clone, Copy)]
827pub enum FieldAccessType {
828 Any,
829 Byte,
830 Word,
831 DWord,
832 QWord,
833 Buffer,
834}
835
836#[derive(Clone, Copy)]
838pub enum FieldLockRule {
839 NoLock = 0,
840 Lock = 1,
841}
842
843#[derive(Clone, Copy)]
845pub enum FieldUpdateRule {
846 Preserve = 0,
847 WriteAsOnes = 1,
848 WriteAsZeroes = 2,
849}
850
851pub enum FieldEntry {
853 Named([u8; 4], usize),
854 Reserved(usize),
855}
856
857pub struct Field {
859 path: Path,
860
861 fields: Vec<FieldEntry>,
862 access_type: FieldAccessType,
863 lock_rule: FieldLockRule,
864 update_rule: FieldUpdateRule,
865}
866
867impl Field {
868 pub fn new(
870 path: Path,
871 access_type: FieldAccessType,
872 lock_rule: FieldLockRule,
873 update_rule: FieldUpdateRule,
874 fields: Vec<FieldEntry>,
875 ) -> Self {
876 Field {
877 path,
878 access_type,
879 lock_rule,
880 update_rule,
881 fields,
882 }
883 }
884}
885
886impl Aml for Field {
887 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
888 aml.push(EXTOPPREFIX);
889 aml.push(FIELDOP);
890
891 let start = aml.len();
892 self.path.to_aml_bytes(aml);
893
894 let flags: u8 =
895 self.access_type as u8 | (self.lock_rule as u8) << 4 | (self.update_rule as u8) << 5;
896 aml.push(flags);
897
898 for field in self.fields.iter() {
899 match field {
900 FieldEntry::Named(name, length) => {
901 aml.extend_from_slice(name);
902 append_named_field_length(aml, *length);
903 }
904 FieldEntry::Reserved(length) => {
905 aml.push(0x0);
906 append_named_field_length(aml, *length);
907 }
908 }
909 }
910
911 let len = aml.len() - start;
912 insert_pkg_length(aml, start, len);
913 }
914}
915
916#[derive(Clone, Copy)]
918pub enum OpRegionSpace {
919 SystemMemory,
920 SystemIO,
921 PCIConfig,
922 EmbeddedControl,
923 SMBus,
924 SystemCMOS,
925 PciBarTarget,
926 IPMI,
927 GeneralPurposeIO,
928 GenericSerialBus,
929}
930
931pub struct OpRegion<'a> {
933 path: Path,
934 space: OpRegionSpace,
935 offset: &'a dyn Aml,
936 length: &'a dyn Aml,
937}
938
939impl<'a> OpRegion<'a> {
940 pub fn new(path: Path, space: OpRegionSpace, offset: &'a dyn Aml, length: &'a dyn Aml) -> Self {
942 OpRegion {
943 path,
944 space,
945 offset,
946 length,
947 }
948 }
949}
950
951impl Aml for OpRegion<'_> {
952 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
953 aml.push(EXTOPPREFIX);
954 aml.push(OPREGIONOP);
955
956 self.path.to_aml_bytes(aml);
957 aml.push(self.space as u8);
958 self.offset.to_aml_bytes(aml); self.length.to_aml_bytes(aml); }
961}
962
963pub struct If<'a> {
965 predicate: &'a dyn Aml,
966 if_children: Vec<&'a dyn Aml>,
967}
968
969impl<'a> If<'a> {
970 pub fn new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self {
972 If {
973 predicate,
974 if_children,
975 }
976 }
977}
978
979impl Aml for If<'_> {
980 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
981 aml.push(IFOP);
982
983 let start = aml.len();
984 self.predicate.to_aml_bytes(aml);
985 for child in self.if_children.iter() {
986 child.to_aml_bytes(aml);
987 }
988 let len = aml.len() - start;
989
990 insert_pkg_length(aml, start, len);
991 }
992}
993
994pub struct Else<'a> {
996 body: Vec<&'a dyn Aml>,
997}
998
999impl<'a> Else<'a> {
1000 pub fn new(body: Vec<&'a dyn Aml>) -> Self {
1002 Else { body }
1003 }
1004}
1005
1006impl Aml for Else<'_> {
1007 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1008 aml.push(ELSEOP);
1009
1010 let start = aml.len();
1011 for child in self.body.iter() {
1012 child.to_aml_bytes(aml);
1013 }
1014 let len = aml.len() - start;
1015
1016 insert_pkg_length(aml, start, len);
1017 }
1018}
1019
1020macro_rules! compare_op {
1021 ($name:ident, $opcode:expr, $invert:expr) => {
1022 pub struct $name<'a> {
1024 right: &'a dyn Aml,
1025 left: &'a dyn Aml,
1026 }
1027
1028 impl<'a> $name<'a> {
1029 pub fn new(left: &'a dyn Aml, right: &'a dyn Aml) -> Self {
1031 $name { left, right }
1032 }
1033 }
1034
1035 impl<'a> Aml for $name<'a> {
1036 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1037 if $invert {
1038 bytes.push(LNOTOP);
1039 }
1040 bytes.push($opcode);
1041 self.left.to_aml_bytes(bytes);
1042 self.right.to_aml_bytes(bytes);
1043 }
1044 }
1045 };
1046}
1047
1048compare_op!(Equal, LEQUALOP, false);
1049compare_op!(LessThan, LLESSOP, false);
1050compare_op!(GreaterThan, LGREATEROP, false);
1051compare_op!(NotEqual, LEQUALOP, true);
1052compare_op!(GreaterEqual, LLESSOP, true);
1053compare_op!(LessEqual, LGREATEROP, true);
1054
1055pub struct Arg(pub u8);
1057
1058impl Aml for Arg {
1059 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1062 assert!(self.0 <= 6);
1063 bytes.push(ARG0OP + self.0);
1064 }
1065}
1066
1067pub struct Local(pub u8);
1069
1070impl Aml for Local {
1071 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1074 assert!(self.0 <= 7);
1075 bytes.push(LOCAL0OP + self.0);
1076 }
1077}
1078
1079pub struct Store<'a> {
1082 name: &'a dyn Aml,
1083 value: &'a dyn Aml,
1084}
1085
1086impl<'a> Store<'a> {
1087 pub fn new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1089 Store { name, value }
1090 }
1091}
1092
1093impl Aml for Store<'_> {
1094 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1095 bytes.push(STOREOP);
1096 self.value.to_aml_bytes(bytes);
1097 self.name.to_aml_bytes(bytes);
1098 }
1099}
1100
1101pub struct Mutex {
1103 path: Path,
1104 sync_level: u8,
1105}
1106
1107impl Mutex {
1108 pub fn new(path: Path, sync_level: u8) -> Self {
1110 Self { path, sync_level }
1111 }
1112}
1113
1114impl Aml for Mutex {
1115 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1116 bytes.push(EXTOPPREFIX);
1117 bytes.push(MUTEXOP);
1118 self.path.to_aml_bytes(bytes);
1119 bytes.push(self.sync_level);
1120 }
1121}
1122
1123pub struct Acquire {
1125 mutex: Path,
1126 timeout: u16,
1127}
1128
1129impl Acquire {
1130 pub fn new(mutex: Path, timeout: u16) -> Self {
1132 Acquire { mutex, timeout }
1133 }
1134}
1135
1136impl Aml for Acquire {
1137 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1138 bytes.push(EXTOPPREFIX);
1139 bytes.push(ACQUIREOP);
1140 self.mutex.to_aml_bytes(bytes);
1141 bytes.extend_from_slice(&self.timeout.to_le_bytes());
1142 }
1143}
1144
1145pub struct Release {
1147 mutex: Path,
1148}
1149
1150impl Release {
1151 pub fn new(mutex: Path) -> Self {
1153 Release { mutex }
1154 }
1155}
1156
1157impl Aml for Release {
1158 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1159 bytes.push(EXTOPPREFIX);
1160 bytes.push(RELEASEOP);
1161 self.mutex.to_aml_bytes(bytes);
1162 }
1163}
1164
1165pub struct Notify<'a> {
1167 object: &'a dyn Aml,
1168 value: &'a dyn Aml,
1169}
1170
1171impl<'a> Notify<'a> {
1172 pub fn new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1174 Notify { object, value }
1175 }
1176}
1177
1178impl Aml for Notify<'_> {
1179 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1180 bytes.push(NOTIFYOP);
1181 self.object.to_aml_bytes(bytes);
1182 self.value.to_aml_bytes(bytes);
1183 }
1184}
1185
1186pub struct While<'a> {
1189 predicate: &'a dyn Aml,
1190 while_children: Vec<&'a dyn Aml>,
1191}
1192
1193impl<'a> While<'a> {
1194 pub fn new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self {
1196 While {
1197 predicate,
1198 while_children,
1199 }
1200 }
1201}
1202
1203impl Aml for While<'_> {
1204 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1205 aml.push(WHILEOP);
1206
1207 let start = aml.len();
1208 self.predicate.to_aml_bytes(aml);
1209 for child in self.while_children.iter() {
1210 child.to_aml_bytes(aml);
1211 }
1212 let len = aml.len() - start;
1213
1214 insert_pkg_length(aml, start, len);
1215 }
1216}
1217
1218macro_rules! object_op {
1219 ($name:ident, $opcode:expr) => {
1220 pub struct $name<'a> {
1222 a: &'a dyn Aml,
1223 }
1224
1225 impl<'a> $name<'a> {
1226 pub fn new(a: &'a dyn Aml) -> Self {
1228 $name { a }
1229 }
1230 }
1231
1232 impl<'a> Aml for $name<'a> {
1233 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1234 bytes.push($opcode);
1235 self.a.to_aml_bytes(bytes);
1236 }
1237 }
1238 };
1239}
1240
1241object_op!(ObjectType, OBJECTTYPEOP);
1242object_op!(SizeOf, SIZEOFOP);
1243object_op!(Return, RETURNOP);
1244object_op!(DeRefOf, DEREFOFOP);
1245
1246macro_rules! binary_op {
1247 ($name:ident, $opcode:expr) => {
1248 pub struct $name<'a> {
1250 a: &'a dyn Aml,
1251 b: &'a dyn Aml,
1252 target: &'a dyn Aml,
1253 }
1254
1255 impl<'a> $name<'a> {
1256 pub fn new(target: &'a dyn Aml, a: &'a dyn Aml, b: &'a dyn Aml) -> Self {
1258 $name { target, a, b }
1259 }
1260 }
1261
1262 impl<'a> Aml for $name<'a> {
1263 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1264 bytes.push($opcode); self.a.to_aml_bytes(bytes);
1266 self.b.to_aml_bytes(bytes);
1267 self.target.to_aml_bytes(bytes);
1268 }
1269 }
1270 };
1271}
1272
1273binary_op!(Add, ADDOP);
1274binary_op!(Concat, CONCATOP);
1275binary_op!(Subtract, SUBTRACTOP);
1276binary_op!(Multiply, MULTIPLYOP);
1277binary_op!(ShiftLeft, SHIFTLEFTOP);
1278binary_op!(ShiftRight, SHIFTRIGHTOP);
1279binary_op!(And, ANDOP);
1280binary_op!(Nand, NANDOP);
1281binary_op!(Or, OROP);
1282binary_op!(Nor, NOROP);
1283binary_op!(Xor, XOROP);
1284binary_op!(ConcatRes, CONCATRESOP);
1285binary_op!(Mod, MODOP);
1286binary_op!(Index, INDEXOP);
1287binary_op!(ToString, TOSTRINGOP);
1288binary_op!(CreateDWordField, CREATEDWFIELDOP);
1289binary_op!(CreateQWordField, CREATEQWFIELDOP);
1290
1291macro_rules! convert_op {
1292 ($name:ident, $opcode:expr) => {
1293 pub struct $name<'a> {
1295 a: &'a dyn Aml,
1296 target: &'a dyn Aml,
1297 }
1298
1299 impl<'a> $name<'a> {
1300 pub fn new(target: &'a dyn Aml, a: &'a dyn Aml) -> Self {
1302 $name { target, a }
1303 }
1304 }
1305
1306 impl<'a> Aml for $name<'a> {
1307 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1308 bytes.push($opcode); self.a.to_aml_bytes(bytes);
1310 self.target.to_aml_bytes(bytes);
1311 }
1312 }
1313 };
1314}
1315
1316convert_op!(ToBuffer, TOBUFFEROP);
1317convert_op!(ToInteger, TOINTEGEROP);
1318
1319pub struct CreateField<'a> {
1321 name_string: &'a dyn Aml,
1322 source: &'a dyn Aml,
1323 bit_index: &'a dyn Aml,
1324 bit_num: &'a dyn Aml,
1325}
1326
1327impl<'a> CreateField<'a> {
1328 pub fn new(
1329 name_string: &'a dyn Aml,
1330 source: &'a dyn Aml,
1331 bit_index: &'a dyn Aml,
1332 bit_num: &'a dyn Aml,
1333 ) -> Self {
1334 CreateField {
1335 name_string,
1336 source,
1337 bit_index,
1338 bit_num,
1339 }
1340 }
1341}
1342
1343impl Aml for CreateField<'_> {
1344 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1345 bytes.push(EXTOPPREFIX);
1346 bytes.push(CREATEFIELDOP);
1347 self.source.to_aml_bytes(bytes);
1348 self.bit_index.to_aml_bytes(bytes);
1349 self.bit_num.to_aml_bytes(bytes);
1350 self.name_string.to_aml_bytes(bytes);
1351 }
1352}
1353
1354pub struct Mid<'a> {
1356 source: &'a dyn Aml,
1357 index: &'a dyn Aml,
1358 length: &'a dyn Aml,
1359 result: &'a dyn Aml,
1360}
1361
1362impl<'a> Mid<'a> {
1363 pub fn new(
1364 source: &'a dyn Aml,
1365 index: &'a dyn Aml,
1366 length: &'a dyn Aml,
1367 result: &'a dyn Aml,
1368 ) -> Self {
1369 Mid {
1370 source,
1371 index,
1372 length,
1373 result,
1374 }
1375 }
1376}
1377
1378impl Aml for Mid<'_> {
1379 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1380 bytes.push(MIDOP);
1381 self.source.to_aml_bytes(bytes);
1382 self.index.to_aml_bytes(bytes);
1383 self.length.to_aml_bytes(bytes);
1384 self.result.to_aml_bytes(bytes);
1385 }
1386}
1387
1388pub struct MethodCall<'a> {
1390 name: Path,
1391 args: Vec<&'a dyn Aml>,
1392}
1393
1394impl<'a> MethodCall<'a> {
1395 pub fn new(name: Path, args: Vec<&'a dyn Aml>) -> Self {
1397 MethodCall { name, args }
1398 }
1399}
1400
1401impl Aml for MethodCall<'_> {
1402 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1403 self.name.to_aml_bytes(bytes);
1404 for arg in self.args.iter() {
1405 arg.to_aml_bytes(bytes);
1406 }
1407 }
1408}
1409
1410pub struct BufferTerm<'a> {
1412 data: &'a dyn Aml,
1413}
1414
1415impl<'a> BufferTerm<'a> {
1416 pub fn new(data: &'a dyn Aml) -> Self {
1418 BufferTerm { data }
1419 }
1420}
1421
1422impl Aml for BufferTerm<'_> {
1423 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1424 aml.push(BUFFEROP);
1425
1426 let start = aml.len();
1427 self.data.to_aml_bytes(aml);
1428 let len = aml.len() - start;
1429
1430 insert_pkg_length(aml, start, len);
1431 }
1432}
1433
1434pub struct BufferData {
1436 data: Vec<u8>,
1437}
1438
1439impl BufferData {
1440 pub fn new(data: Vec<u8>) -> Self {
1442 BufferData { data }
1443 }
1444}
1445
1446impl Aml for BufferData {
1447 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1448 aml.push(BUFFEROP);
1449
1450 let start = aml.len();
1451 self.data.len().to_aml_bytes(aml);
1452 aml.extend_from_slice(&self.data);
1453 let len = aml.len() - start;
1454
1455 insert_pkg_length(aml, start, len);
1456 }
1457}
1458
1459pub struct Uuid {
1460 name: BufferData,
1461}
1462
1463fn hex2byte(v1: char, v2: char) -> u8 {
1464 let hi = v1.to_digit(16).unwrap() as u8;
1465 assert!(hi <= 15);
1466 let lo = v2.to_digit(16).unwrap() as u8;
1467 assert!(lo <= 15);
1468
1469 (hi << 4) | lo
1470}
1471
1472impl Uuid {
1473 pub fn new(name: &str) -> Self {
1476 let name_vec: Vec<char> = name.chars().collect();
1477 let mut data = Vec::new();
1478
1479 assert_eq!(name_vec.len(), 36);
1480 assert_eq!(name_vec[8], '-');
1481 assert_eq!(name_vec[13], '-');
1482 assert_eq!(name_vec[18], '-');
1483 assert_eq!(name_vec[23], '-');
1484
1485 data.push(hex2byte(name_vec[6], name_vec[7]));
1487 data.push(hex2byte(name_vec[4], name_vec[5]));
1489 data.push(hex2byte(name_vec[2], name_vec[3]));
1491 data.push(hex2byte(name_vec[0], name_vec[1]));
1493
1494 data.push(hex2byte(name_vec[11], name_vec[12]));
1496 data.push(hex2byte(name_vec[9], name_vec[10]));
1498
1499 data.push(hex2byte(name_vec[16], name_vec[17]));
1501 data.push(hex2byte(name_vec[14], name_vec[15]));
1503
1504 data.push(hex2byte(name_vec[19], name_vec[20]));
1506 data.push(hex2byte(name_vec[21], name_vec[22]));
1508
1509 data.push(hex2byte(name_vec[24], name_vec[25]));
1511 data.push(hex2byte(name_vec[26], name_vec[27]));
1513 data.push(hex2byte(name_vec[28], name_vec[29]));
1515 data.push(hex2byte(name_vec[30], name_vec[31]));
1517 data.push(hex2byte(name_vec[32], name_vec[33]));
1519 data.push(hex2byte(name_vec[34], name_vec[35]));
1521
1522 Uuid {
1523 name: BufferData::new(data),
1524 }
1525 }
1526}
1527
1528impl Aml for Uuid {
1529 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1530 self.name.to_aml_bytes(bytes)
1531 }
1532}
1533
1534pub struct PowerResource<'a> {
1536 name: Path,
1537 level: u8,
1538 order: u16,
1539 children: Vec<&'a dyn Aml>,
1540}
1541
1542impl<'a> PowerResource<'a> {
1543 pub fn new(name: Path, level: u8, order: u16, children: Vec<&'a dyn Aml>) -> Self {
1545 PowerResource {
1546 name,
1547 level,
1548 order,
1549 children,
1550 }
1551 }
1552}
1553
1554impl Aml for PowerResource<'_> {
1555 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1556 aml.push(EXTOPPREFIX);
1557 aml.push(POWERRESOURCEOP);
1558
1559 let start = aml.len();
1560
1561 self.name.to_aml_bytes(aml);
1563 aml.push(self.level);
1565 let orders = self.order.to_le_bytes();
1567 aml.push(orders[0]);
1568 aml.push(orders[1]);
1569 for child in &self.children {
1571 child.to_aml_bytes(aml);
1572 }
1573
1574 let len = aml.len() - start;
1575
1576 insert_pkg_length(aml, start, len);
1577 }
1578}
1579
1580#[cfg(test)]
1581mod tests {
1582 use super::*;
1583
1584 #[test]
1585 fn test_device() {
1586 let com1_device = [
1606 0x5B, 0x82, 0x30, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31, 0x08, 0x5F,
1607 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01, 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11,
1608 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01, 0x04, 0x00, 0x00, 0x00, 0x47, 0x01,
1609 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1610 ];
1611 let mut aml = Vec::new();
1612
1613 Device::new(
1614 "_SB_.COM1".into(),
1615 vec![
1616 &Name::new("_HID".into(), &EISAName::new("PNP0501")),
1617 &Name::new(
1618 "_CRS".into(),
1619 &ResourceTemplate::new(vec![
1620 &Interrupt::new(true, true, false, false, 4),
1621 &IO::new(0x3f8, 0x3f8, 0, 0x8),
1622 ]),
1623 ),
1624 ],
1625 )
1626 .to_aml_bytes(&mut aml);
1627 assert_eq!(aml, &com1_device[..]);
1628 }
1629
1630 #[test]
1631 fn test_scope() {
1632 let mbrd_scope = [
1646 0x10, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x42, 0x52, 0x44, 0x08, 0x5F, 0x43,
1647 0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE8,
1648 0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1649 ];
1650 let mut aml = Vec::new();
1651
1652 Scope::new(
1653 "_SB_.MBRD".into(),
1654 vec![&Name::new(
1655 "_CRS".into(),
1656 &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1657 )],
1658 )
1659 .to_aml_bytes(&mut aml);
1660 assert_eq!(aml, &mbrd_scope[..]);
1661 }
1662
1663 #[test]
1664 fn test_resource_template() {
1665 let crs_memory_32_fixed = [
1675 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00,
1676 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1677 ];
1678 let mut aml = Vec::new();
1679
1680 Name::new(
1681 "_CRS".into(),
1682 &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1683 )
1684 .to_aml_bytes(&mut aml);
1685 assert_eq!(aml, crs_memory_32_fixed);
1686
1687 let crs_word_bus_number = [
1737 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x15, 0x0A, 0x12, 0x88, 0x0D, 0x00, 0x02, 0x0C,
1738 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x79, 0x00,
1739 ];
1740 aml.clear();
1741
1742 Name::new(
1743 "_CRS".into(),
1744 &ResourceTemplate::new(vec![&AddressSpace::new_bus_number(0x0u16, 0xffu16)]),
1745 )
1746 .to_aml_bytes(&mut aml);
1747 assert_eq!(aml, &crs_word_bus_number);
1748
1749 let crs_word_io = [
1751 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x25, 0x0A, 0x22, 0x88, 0x0D, 0x00, 0x01, 0x0C,
1752 0x03, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0C, 0x00, 0x00, 0xF8, 0x0C, 0x88, 0x0D, 0x00,
1753 0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF3, 0x79,
1754 0x00,
1755 ];
1756 aml.clear();
1757
1758 Name::new(
1759 "_CRS".into(),
1760 &ResourceTemplate::new(vec![
1761 &AddressSpace::new_io(0x0u16, 0xcf7u16),
1762 &AddressSpace::new_io(0xd00u16, 0xffffu16),
1763 ]),
1764 )
1765 .to_aml_bytes(&mut aml);
1766 assert_eq!(aml, &crs_word_io[..]);
1767
1768 let crs_dword_memory = [
1770 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x39, 0x0A, 0x36, 0x87, 0x17, 0x00, 0x00, 0x0C,
1771 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xFF, 0xFF, 0x0B, 0x00, 0x00,
1772 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x87, 0x17, 0x00, 0x00, 0x0C, 0x01, 0x00,
1773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xBF, 0xFE, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0xC0, 0x3E, 0x79, 0x00,
1775 ];
1776 aml.clear();
1777
1778 Name::new(
1779 "_CRS".into(),
1780 &ResourceTemplate::new(vec![
1781 &AddressSpace::new_memory(
1782 AddressSpaceCachable::Cacheable,
1783 true,
1784 0xa_0000u32,
1785 0xb_ffffu32,
1786 ),
1787 &AddressSpace::new_memory(
1788 AddressSpaceCachable::NotCacheable,
1789 true,
1790 0xc000_0000u32,
1791 0xfebf_ffffu32,
1792 ),
1793 ]),
1794 )
1795 .to_aml_bytes(&mut aml);
1796 assert_eq!(aml, &crs_dword_memory[..]);
1797
1798 let crs_qword_memory = [
1800 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x33, 0x0A, 0x30, 0x8A, 0x2B, 0x00, 0x00, 0x0C,
1801 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1802 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x79,
1804 0x00,
1805 ];
1806 aml.clear();
1807 Name::new(
1808 "_CRS".into(),
1809 &ResourceTemplate::new(vec![&AddressSpace::new_memory(
1810 AddressSpaceCachable::Cacheable,
1811 true,
1812 0x8_0000_0000u64,
1813 0xf_ffff_ffffu64,
1814 )]),
1815 )
1816 .to_aml_bytes(&mut aml);
1817
1818 assert_eq!(aml, &crs_qword_memory[..]);
1819
1820 let interrupt_io_data = [
1837 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01,
1838 0x04, 0x00, 0x00, 0x00, 0x47, 0x01, 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1839 ];
1840 aml.clear();
1841 Name::new(
1842 "_CRS".into(),
1843 &ResourceTemplate::new(vec![
1844 &Interrupt::new(true, true, false, false, 4),
1845 &IO::new(0x3f8, 0x3f8, 0, 0x8),
1846 ]),
1847 )
1848 .to_aml_bytes(&mut aml);
1849
1850 assert_eq!(aml, &interrupt_io_data[..]);
1851 }
1852
1853 #[test]
1854 fn test_pkg_length() {
1855 let mut pkg_len_62 = Vec::new();
1856 insert_pkg_length(&mut pkg_len_62, 0, 62);
1857 assert_eq!(pkg_len_62, [63]);
1858
1859 let mut pkg_len_64 = Vec::new();
1860 insert_pkg_length(&mut pkg_len_64, 0, 64);
1861 assert_eq!(pkg_len_64, [1 << 6 | (66 & 0xf), 66 >> 4]);
1862
1863 let mut pkg_len_4096 = Vec::new();
1864 insert_pkg_length(&mut pkg_len_4096, 0, 4096);
1865 assert_eq!(
1866 pkg_len_4096,
1867 [
1868 2 << 6 | (4099 & 0xf) as u8,
1869 (4099 >> 4) as u8,
1870 (4099 >> 12) as u8
1871 ]
1872 );
1873 }
1874
1875 #[test]
1876 fn test_package() {
1877 let s5_sleep_data = [0x08, 0x5F, 0x53, 0x35, 0x5F, 0x12, 0x04, 0x01, 0x0A, 0x05];
1884 let mut aml = Vec::new();
1885
1886 Name::new("_S5_".into(), &Package::new(vec![&5u8])).to_aml_bytes(&mut aml);
1887
1888 assert_eq!(s5_sleep_data.to_vec(), aml);
1889 }
1890
1891 #[test]
1892 fn test_eisa_name() {
1893 let mut aml = Vec::new();
1894 Name::new("_HID".into(), &EISAName::new("PNP0501")).to_aml_bytes(&mut aml);
1895 assert_eq!(
1896 aml,
1897 [0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01],
1898 )
1899 }
1900 #[test]
1901 fn test_name_path() {
1902 let mut aml = Vec::new();
1903 (&"_SB_".into() as &Path).to_aml_bytes(&mut aml);
1904 assert_eq!(aml, [0x5Fu8, 0x53, 0x42, 0x5F]);
1905 aml.clear();
1906 (&"\\_SB_".into() as &Path).to_aml_bytes(&mut aml);
1907 assert_eq!(aml, [0x5C, 0x5F, 0x53, 0x42, 0x5F]);
1908 aml.clear();
1909 (&"_SB_.COM1".into() as &Path).to_aml_bytes(&mut aml);
1910 assert_eq!(aml, [0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31]);
1911 aml.clear();
1912 (&"_SB_.PCI0._HID".into() as &Path).to_aml_bytes(&mut aml);
1913 assert_eq!(
1914 aml,
1915 [0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x48, 0x49, 0x44]
1916 );
1917 }
1918
1919 #[test]
1920 fn test_numbers() {
1921 let mut aml = Vec::new();
1922 128u8.to_aml_bytes(&mut aml);
1923 assert_eq!(aml, [0x0a, 0x80]);
1924 aml.clear();
1925 1024u16.to_aml_bytes(&mut aml);
1926 assert_eq!(aml, [0x0b, 0x0, 0x04]);
1927 aml.clear();
1928 (16u32 << 20).to_aml_bytes(&mut aml);
1929 assert_eq!(aml, [0x0c, 0x00, 0x00, 0x0, 0x01]);
1930 aml.clear();
1931 0xdeca_fbad_deca_fbadu64.to_aml_bytes(&mut aml);
1932 assert_eq!(aml, [0x0e, 0xad, 0xfb, 0xca, 0xde, 0xad, 0xfb, 0xca, 0xde]);
1933 aml.clear();
1934
1935 0x00_u8.to_aml_bytes(&mut aml);
1937 assert_eq!(aml, [0x00]);
1938 aml.clear();
1939 0x01_u8.to_aml_bytes(&mut aml);
1940 assert_eq!(aml, [0x01]);
1941 aml.clear();
1942 0x86_u8.to_aml_bytes(&mut aml);
1943 assert_eq!(aml, [0x0a, 0x86]);
1944 aml.clear();
1945
1946 0x00_u16.to_aml_bytes(&mut aml);
1948 assert_eq!(aml, [0x00]);
1949 aml.clear();
1950 0x01_u16.to_aml_bytes(&mut aml);
1951 assert_eq!(aml, [0x01]);
1952 aml.clear();
1953 0x86_u16.to_aml_bytes(&mut aml);
1954 assert_eq!(aml, [0x0a, 0x86]);
1955 aml.clear();
1956 0xF00D_u16.to_aml_bytes(&mut aml);
1957 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
1958 aml.clear();
1959
1960 0x00_u32.to_aml_bytes(&mut aml);
1962 assert_eq!(aml, [0x00]);
1963 aml.clear();
1964 0x01_u32.to_aml_bytes(&mut aml);
1965 assert_eq!(aml, [0x01]);
1966 aml.clear();
1967 0x86_u32.to_aml_bytes(&mut aml);
1968 assert_eq!(aml, [0x0a, 0x86]);
1969 aml.clear();
1970 0xF00D_u32.to_aml_bytes(&mut aml);
1971 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
1972 aml.clear();
1973 0xDECAF_u32.to_aml_bytes(&mut aml);
1974 assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
1975 aml.clear();
1976
1977 0x00_u64.to_aml_bytes(&mut aml);
1979 assert_eq!(aml, [0x00]);
1980 aml.clear();
1981 0x01_u64.to_aml_bytes(&mut aml);
1982 assert_eq!(aml, [0x01]);
1983 aml.clear();
1984 0x86_u64.to_aml_bytes(&mut aml);
1985 assert_eq!(aml, [0x0a, 0x86]);
1986 aml.clear();
1987 0xF00D_u64.to_aml_bytes(&mut aml);
1988 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
1989 aml.clear();
1990 0xDECAF_u64.to_aml_bytes(&mut aml);
1991 assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
1992 aml.clear();
1993 0xDECAFC0FFEE_u64.to_aml_bytes(&mut aml);
1994 assert_eq!(aml, [0x0e, 0xee, 0xff, 0xc0, 0xaf, 0xec, 0x0d, 0x00, 0x00]);
1995 aml.clear();
1996
1997 0x00_usize.to_aml_bytes(&mut aml);
1999 assert_eq!(aml, [0x00]);
2000 aml.clear();
2001 0x01_usize.to_aml_bytes(&mut aml);
2002 assert_eq!(aml, [0x01]);
2003 aml.clear();
2004 0x86_usize.to_aml_bytes(&mut aml);
2005 assert_eq!(aml, [0x0a, 0x86]);
2006 aml.clear();
2007 0xF00D_usize.to_aml_bytes(&mut aml);
2008 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
2009 aml.clear();
2010 0xDECAF_usize.to_aml_bytes(&mut aml);
2011 assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
2012 aml.clear();
2013 #[cfg(target_pointer_width = "64")]
2014 {
2015 0xDECAFC0FFEE_usize.to_aml_bytes(&mut aml);
2016 assert_eq!(aml, [0x0e, 0xee, 0xff, 0xc0, 0xaf, 0xec, 0x0d, 0x00, 0x00]);
2017 aml.clear();
2018 }
2019 }
2020
2021 #[test]
2022 fn test_name() {
2023 let mut aml = Vec::new();
2024 Name::new("_SB_.PCI0._UID".into(), &0x1234u16).to_aml_bytes(&mut aml);
2025 assert_eq!(
2026 aml,
2027 [
2028 0x08, 0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x55, 0x49, 0x44, 0x0b, 0x34, 0x12
2036 ]
2037 );
2038 }
2039
2040 #[test]
2041 fn test_string() {
2042 let mut aml = Vec::new();
2043 (&"ACPI" as &dyn Aml).to_aml_bytes(&mut aml);
2044 assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
2045 aml.clear();
2046 "ACPI".to_owned().to_aml_bytes(&mut aml);
2047 assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
2048 }
2049
2050 #[test]
2051 fn test_method() {
2052 let mut aml = Vec::new();
2053 Method::new("_STA".into(), 0, false, vec![&Return::new(&0xfu8)]).to_aml_bytes(&mut aml);
2054 assert_eq!(
2055 aml,
2056 [0x14, 0x09, 0x5F, 0x53, 0x54, 0x41, 0x00, 0xA4, 0x0A, 0x0F]
2057 );
2058 }
2059
2060 #[test]
2061 fn test_field() {
2062 let field_data = [
2077 0x5Bu8, 0x81, 0x23, 0x50, 0x52, 0x53, 0x54, 0x41, 0x00, 0x20, 0x43, 0x50, 0x45, 0x4E,
2078 0x01, 0x43, 0x49, 0x4E, 0x53, 0x01, 0x43, 0x52, 0x4D, 0x56, 0x01, 0x43, 0x45, 0x4A,
2079 0x30, 0x01, 0x00, 0x04, 0x43, 0x43, 0x4D, 0x44, 0x08,
2080 ];
2081 let mut aml = Vec::new();
2082
2083 Field::new(
2084 "PRST".into(),
2085 FieldAccessType::Byte,
2086 FieldLockRule::NoLock,
2087 FieldUpdateRule::WriteAsZeroes,
2088 vec![
2089 FieldEntry::Reserved(32),
2090 FieldEntry::Named(*b"CPEN", 1),
2091 FieldEntry::Named(*b"CINS", 1),
2092 FieldEntry::Named(*b"CRMV", 1),
2093 FieldEntry::Named(*b"CEJ0", 1),
2094 FieldEntry::Reserved(4),
2095 FieldEntry::Named(*b"CCMD", 8),
2096 ],
2097 )
2098 .to_aml_bytes(&mut aml);
2099 assert_eq!(aml, &field_data[..]);
2100
2101 let field_data = [
2111 0x5Bu8, 0x81, 0x12, 0x50, 0x52, 0x53, 0x54, 0x13, 0x43, 0x53, 0x45, 0x4C, 0x20, 0x00,
2112 0x20, 0x43, 0x44, 0x41, 0x54, 0x20,
2113 ];
2114 aml.clear();
2115
2116 Field::new(
2117 "PRST".into(),
2118 FieldAccessType::DWord,
2119 FieldLockRule::Lock,
2120 FieldUpdateRule::Preserve,
2121 vec![
2122 FieldEntry::Named(*b"CSEL", 32),
2123 FieldEntry::Reserved(32),
2124 FieldEntry::Named(*b"CDAT", 32),
2125 ],
2126 )
2127 .to_aml_bytes(&mut aml);
2128 assert_eq!(aml, &field_data[..]);
2129 }
2130
2131 #[test]
2132 fn test_op_region() {
2133 let op_region_data = [
2137 0x5Bu8, 0x80, 0x50, 0x52, 0x53, 0x54, 0x01, 0x0B, 0xD8, 0x0C, 0x0A, 0x0C,
2138 ];
2139 let mut aml = Vec::new();
2140
2141 OpRegion::new(
2142 "PRST".into(),
2143 OpRegionSpace::SystemIO,
2144 &0xcd8_usize,
2145 &0xc_usize,
2146 )
2147 .to_aml_bytes(&mut aml);
2148 assert_eq!(aml, &op_region_data[..]);
2149 }
2150
2151 #[test]
2152 fn test_arg_if() {
2153 let arg_if_data = [
2162 0x14, 0x0F, 0x54, 0x45, 0x53, 0x54, 0x01, 0xA0, 0x06, 0x93, 0x68, 0x00, 0xA4, 0x01,
2163 0xA4, 0x00,
2164 ];
2165 let mut aml = Vec::new();
2166
2167 Method::new(
2168 "TEST".into(),
2169 1,
2170 false,
2171 vec![
2172 &If::new(&Equal::new(&Arg(0), &ZERO), vec![&Return::new(&ONE)]),
2173 &Return::new(&ZERO),
2174 ],
2175 )
2176 .to_aml_bytes(&mut aml);
2177 assert_eq!(aml, &arg_if_data);
2178 }
2179
2180 #[test]
2181 fn test_local_if() {
2182 let local_if_data = [
2192 0x14, 0x12, 0x54, 0x45, 0x53, 0x54, 0x00, 0x70, 0x01, 0x60, 0xA0, 0x06, 0x93, 0x60,
2193 0x00, 0xA4, 0x01, 0xA4, 0x00,
2194 ];
2195 let mut aml = Vec::new();
2196
2197 Method::new(
2198 "TEST".into(),
2199 0,
2200 false,
2201 vec![
2202 &Store::new(&Local(0), &ONE),
2203 &If::new(&Equal::new(&Local(0), &ZERO), vec![&Return::new(&ONE)]),
2204 &Return::new(&ZERO),
2205 ],
2206 )
2207 .to_aml_bytes(&mut aml);
2208 assert_eq!(aml, &local_if_data);
2209 }
2210
2211 #[test]
2212 fn test_mutex() {
2213 let mutex_data = [
2228 0x5B, 0x82, 0x33, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2229 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x5B, 0x01, 0x4D, 0x4C, 0x43, 0x4B,
2230 0x00, 0x14, 0x17, 0x54, 0x45, 0x53, 0x54, 0x00, 0x5B, 0x23, 0x4D, 0x4C, 0x43, 0x4B,
2231 0xFF, 0xFF, 0x70, 0x01, 0x60, 0x5B, 0x27, 0x4D, 0x4C, 0x43, 0x4B,
2232 ];
2233 let mut aml = Vec::new();
2234
2235 let mutex = Mutex::new("MLCK".into(), 0);
2236 Device::new(
2237 "_SB_.MHPC".into(),
2238 vec![
2239 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2240 &mutex,
2241 &Method::new(
2242 "TEST".into(),
2243 0,
2244 false,
2245 vec![
2246 &Acquire::new("MLCK".into(), 0xffff),
2247 &Store::new(&Local(0), &ONE),
2248 &Release::new("MLCK".into()),
2249 ],
2250 ),
2251 ],
2252 )
2253 .to_aml_bytes(&mut aml);
2254 assert_eq!(aml, &mutex_data[..]);
2255 }
2256
2257 #[test]
2258 fn test_notify() {
2259 let notify_data = [
2270 0x5B, 0x82, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2271 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x0C, 0x54, 0x45, 0x53, 0x54,
2272 0x00, 0x86, 0x4D, 0x48, 0x50, 0x43, 0x01,
2273 ];
2274 let mut aml = Vec::new();
2275
2276 Device::new(
2277 "_SB_.MHPC".into(),
2278 vec![
2279 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2280 &Method::new(
2281 "TEST".into(),
2282 0,
2283 false,
2284 vec![&Notify::new(&Path::new("MHPC"), &ONE)],
2285 ),
2286 ],
2287 )
2288 .to_aml_bytes(&mut aml);
2289 assert_eq!(aml, ¬ify_data[..]);
2290 }
2291
2292 #[test]
2293 fn test_while() {
2294 let while_data = [
2310 0x5B, 0x82, 0x28, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2311 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x13, 0x54, 0x45, 0x53, 0x54,
2312 0x00, 0x70, 0x00, 0x60, 0xA2, 0x09, 0x95, 0x60, 0x0A, 0x04, 0x72, 0x60, 0x01, 0x60,
2313 ];
2314 let mut aml = Vec::new();
2315
2316 Device::new(
2317 "_SB_.MHPC".into(),
2318 vec![
2319 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2320 &Method::new(
2321 "TEST".into(),
2322 0,
2323 false,
2324 vec![
2325 &Store::new(&Local(0), &ZERO),
2326 &While::new(
2327 &LessThan::new(&Local(0), &4usize),
2328 vec![&Add::new(&Local(0), &Local(0), &ONE)],
2329 ),
2330 ],
2331 ),
2332 ],
2333 )
2334 .to_aml_bytes(&mut aml);
2335 assert_eq!(aml, &while_data[..])
2336 }
2337
2338 #[test]
2339 fn test_method_call() {
2340 let test_data = [
2352 0x14, 0x0C, 0x54, 0x53, 0x54, 0x31, 0x01, 0x54, 0x53, 0x54, 0x32, 0x01, 0x01, 0x14,
2353 0x0B, 0x54, 0x53, 0x54, 0x32, 0x02, 0x54, 0x53, 0x54, 0x31, 0x01,
2354 ];
2355
2356 let mut methods = Vec::new();
2357 Method::new(
2358 "TST1".into(),
2359 1,
2360 false,
2361 vec![&MethodCall::new("TST2".into(), vec![&ONE, &ONE])],
2362 )
2363 .to_aml_bytes(&mut methods);
2364 Method::new(
2365 "TST2".into(),
2366 2,
2367 false,
2368 vec![&MethodCall::new("TST1".into(), vec![&ONE])],
2369 )
2370 .to_aml_bytes(&mut methods);
2371 assert_eq!(&methods[..], &test_data[..])
2372 }
2373
2374 #[test]
2375 fn test_buffer() {
2376 let buffer_data = [
2383 0x08, 0x5F, 0x4D, 0x41, 0x54, 0x11, 0x0B, 0x0A, 0x08, 0x00, 0x08, 0x00, 0x00, 0x01,
2384 0x00, 0x00, 0x00,
2385 ];
2386 let mut aml = Vec::new();
2387
2388 Name::new(
2389 "_MAT".into(),
2390 &BufferData::new(vec![0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00]),
2391 )
2392 .to_aml_bytes(&mut aml);
2393 assert_eq!(aml, &buffer_data[..])
2394 }
2395}