1 // Copyright 2020 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /// The trait Aml can be implemented by the ACPI objects to translate itself
6 /// into the AML raw data. So that these AML raw data can be added into the
7 /// ACPI DSDT for guest.
8 pub trait Aml {
9 /// Translate an ACPI object into AML code and append to the vector
10 /// buffer.
11 /// * `bytes` - The vector used to append the AML code.
to_aml_bytes(&self, bytes: &mut Vec<u8>)12 fn to_aml_bytes(&self, bytes: &mut Vec<u8>);
13 }
14
15 // AML byte stream defines
16 const ZEROOP: u8 = 0x00;
17 const ONEOP: u8 = 0x01;
18 const NAMEOP: u8 = 0x08;
19 const BYTEPREFIX: u8 = 0x0a;
20 const WORDPREFIX: u8 = 0x0b;
21 const DWORDPREFIX: u8 = 0x0c;
22 const STRINGOP: u8 = 0x0d;
23 const QWORDPREFIX: u8 = 0x0e;
24 const SCOPEOP: u8 = 0x10;
25 const BUFFEROP: u8 = 0x11;
26 const PACKAGEOP: u8 = 0x12;
27 const VARPACKAGEOP: u8 = 0x13;
28 const METHODOP: u8 = 0x14;
29 const DUALNAMEPREFIX: u8 = 0x2e;
30 const MULTINAMEPREFIX: u8 = 0x2f;
31 const NAMECHARBASE: u8 = 0x40;
32
33 const EXTOPPREFIX: u8 = 0x5b;
34 const MUTEXOP: u8 = 0x01;
35 const CREATEFIELDOP: u8 = 0x13;
36 const ACQUIREOP: u8 = 0x23;
37 const RELEASEOP: u8 = 0x27;
38 const OPREGIONOP: u8 = 0x80;
39 const FIELDOP: u8 = 0x81;
40 const DEVICEOP: u8 = 0x82;
41 const POWERRESOURCEOP: u8 = 0x84;
42
43 const LOCAL0OP: u8 = 0x60;
44 const ARG0OP: u8 = 0x68;
45 const STOREOP: u8 = 0x70;
46 const ADDOP: u8 = 0x72;
47 const CONCATOP: u8 = 0x73;
48 const SUBTRACTOP: u8 = 0x74;
49 const MULTIPLYOP: u8 = 0x77;
50 const SHIFTLEFTOP: u8 = 0x79;
51 const SHIFTRIGHTOP: u8 = 0x7a;
52 const ANDOP: u8 = 0x7b;
53 const NANDOP: u8 = 0x7c;
54 const OROP: u8 = 0x7d;
55 const NOROP: u8 = 0x7e;
56 const XOROP: u8 = 0x7f;
57 const DEREFOFOP: u8 = 0x83;
58 const CONCATRESOP: u8 = 0x84;
59 const MODOP: u8 = 0x85;
60 const NOTIFYOP: u8 = 0x86;
61 const SIZEOFOP: u8 = 0x87;
62 const INDEXOP: u8 = 0x88;
63 const CREATEDWFIELDOP: u8 = 0x8a;
64 const OBJECTTYPEOP: u8 = 0x8e;
65 const CREATEQWFIELDOP: u8 = 0x8f;
66 const LNOTOP: u8 = 0x92;
67 const LEQUALOP: u8 = 0x93;
68 const LGREATEROP: u8 = 0x94;
69 const LLESSOP: u8 = 0x95;
70 const TOBUFFEROP: u8 = 0x96;
71 const TOINTEGEROP: u8 = 0x99;
72 const TOSTRINGOP: u8 = 0x9c;
73 const MIDOP: u8 = 0x9e;
74 const IFOP: u8 = 0xa0;
75 const ELSEOP: u8 = 0xa1;
76 const WHILEOP: u8 = 0xa2;
77 const RETURNOP: u8 = 0xa4;
78 const ONESOP: u8 = 0xff;
79
80 // AML resouce data fields
81 const IOPORTDESC: u8 = 0x47;
82 const ENDTAG: u8 = 0x79;
83 const MEMORY32FIXEDDESC: u8 = 0x86;
84 const DWORDADDRSPACEDESC: u8 = 0x87;
85 const WORDADDRSPACEDESC: u8 = 0x88;
86 const EXTIRQDESC: u8 = 0x89;
87 const QWORDADDRSPACEDESC: u8 = 0x8A;
88
89 /// Zero object in ASL.
90 pub const ZERO: Zero = Zero {};
91 pub struct Zero {}
92
93 impl Aml for Zero {
to_aml_bytes(&self, bytes: &mut Vec<u8>)94 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
95 bytes.push(ZEROOP);
96 }
97 }
98
99 /// One object in ASL.
100 pub const ONE: One = One {};
101 pub struct One {}
102
103 impl Aml for One {
to_aml_bytes(&self, bytes: &mut Vec<u8>)104 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
105 bytes.push(ONEOP);
106 }
107 }
108
109 /// Ones object represents all bits 1.
110 pub const ONES: Ones = Ones {};
111 pub struct Ones {}
112
113 impl Aml for Ones {
to_aml_bytes(&self, bytes: &mut Vec<u8>)114 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
115 bytes.push(ONESOP);
116 }
117 }
118
119 /// Represents Namestring to construct ACPI objects like
120 /// Name/Device/Method/Scope and so on...
121 pub struct Path {
122 root: bool,
123 name_parts: Vec<[u8; 4]>,
124 }
125
126 impl Aml for Path {
to_aml_bytes(&self, bytes: &mut Vec<u8>)127 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
128 if self.root {
129 bytes.push(b'\\');
130 }
131
132 match self.name_parts.len() {
133 0 => panic!("Name cannot be empty"),
134 1 => {}
135 2 => {
136 bytes.push(DUALNAMEPREFIX);
137 }
138 n => {
139 bytes.push(MULTINAMEPREFIX);
140 bytes.push(n as u8);
141 }
142 };
143
144 for part in &self.name_parts {
145 bytes.extend_from_slice(part);
146 }
147 }
148 }
149
150 impl Path {
151 /// Per ACPI Spec, the Namestring split by "." has 4 bytes long. So any name
152 /// not has 4 bytes will not be accepted.
new(name: &str) -> Self153 pub fn new(name: &str) -> Self {
154 let root = name.starts_with('\\');
155 let offset = root as usize;
156 let mut name_parts = Vec::new();
157 for part in name[offset..].split('.') {
158 assert_eq!(part.len(), 4);
159 let mut name_part = [0u8; 4];
160 name_part.copy_from_slice(part.as_bytes());
161 name_parts.push(name_part);
162 }
163
164 Path { root, name_parts }
165 }
166 }
167
168 impl From<&str> for Path {
from(s: &str) -> Self169 fn from(s: &str) -> Self {
170 Path::new(s)
171 }
172 }
173
174 pub type Byte = u8;
175
176 impl Aml for Byte {
to_aml_bytes(&self, bytes: &mut Vec<u8>)177 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
178 match *self {
179 0 => ZERO.to_aml_bytes(bytes),
180 1 => ONE.to_aml_bytes(bytes),
181 _ => {
182 bytes.push(BYTEPREFIX);
183 bytes.push(*self);
184 }
185 }
186 }
187 }
188
189 pub type Word = u16;
190
191 impl Aml for Word {
to_aml_bytes(&self, bytes: &mut Vec<u8>)192 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
193 if *self <= Byte::MAX.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
202 pub type DWord = u32;
203
204 impl Aml for DWord {
to_aml_bytes(&self, bytes: &mut Vec<u8>)205 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
206 if *self <= Word::MAX.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
215 pub type QWord = u64;
216
217 impl Aml for QWord {
to_aml_bytes(&self, bytes: &mut Vec<u8>)218 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
219 if *self <= DWord::MAX.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
228 /// Name object. bytes represents the raw AML data for it.
229 pub struct Name {
230 bytes: Vec<u8>,
231 }
232
233 impl Aml for Name {
to_aml_bytes(&self, bytes: &mut Vec<u8>)234 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
235 bytes.extend_from_slice(&self.bytes);
236 }
237 }
238
239 impl Name {
240 /// Create Name object:
241 ///
242 /// * `path` - The namestring.
243 /// * `inner` - AML objects contained in this namespace.
new(path: Path, inner: &dyn Aml) -> Self244 pub fn new(path: Path, inner: &dyn Aml) -> Self {
245 let mut bytes = vec![NAMEOP];
246 path.to_aml_bytes(&mut bytes);
247 inner.to_aml_bytes(&mut bytes);
248 Name { bytes }
249 }
250
251 /// Create Field name object
252 ///
253 /// * 'field_name' - name string
new_field_name(field_name: &str) -> Self254 pub fn new_field_name(field_name: &str) -> Self {
255 let bytes = field_name.as_bytes().to_vec();
256 Name { bytes }
257 }
258 }
259
260 /// Package object. 'children' represents the ACPI objects contained in this package.
261 pub struct Package {
262 children_bytes: Vec<u8>,
263 }
264
265 impl Aml for Package {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
273 impl Package {
274 /// Create Package object:
new(children: Vec<&dyn Aml>) -> Package275 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
286 /// Variable Package Term
287 pub struct VarPackageTerm<'a> {
288 data: &'a dyn Aml,
289 }
290
291 impl<'a> Aml for VarPackageTerm<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
303 impl<'a> VarPackageTerm<'a> {
304 /// Create Variable Package Term
new(data: &'a dyn Aml) -> Self305 pub fn new(data: &'a dyn Aml) -> Self {
306 VarPackageTerm { data }
307 }
308 }
309
310 /*
311
312 From the ACPI spec for PkgLength:
313
314 "The high 2 bits of the first byte reveal how many follow bytes are in the PkgLength. If the
315 PkgLength has only one byte, bit 0 through 5 are used to encode the package length (in other
316 words, values 0-63). If the package length value is more than 63, more than one byte must be
317 used for the encoding in which case bit 4 and 5 of the PkgLeadByte are reserved and must be zero.
318 If the multiple bytes encoding is used, bits 0-3 of the PkgLeadByte become the least significant 4
319 bits of the resulting package length value. The next ByteData will become the next least
320 significant 8 bits of the resulting value and so on, up to 3 ByteData bytes. Thus, the maximum
321 package length is 2**28."
322
323 */
324
325 /* Also used for NamedField but in that case the length is not included in itself */
insert_length(aml: &mut Vec<u8>, position: usize, len: usize, include_self: bool)326 fn insert_length(aml: &mut Vec<u8>, position: usize, len: usize, include_self: bool) {
327 /* PkgLength is inclusive and includes the length bytes */
328 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
insert_pkg_length(aml: &mut Vec<u8>, position: usize, len: usize)372 fn insert_pkg_length(aml: &mut Vec<u8>, position: usize, len: usize) {
373 insert_length(aml, position, len, true);
374 }
375
append_pkg_length(aml: &mut Vec<u8>, len: usize)376 fn append_pkg_length(aml: &mut Vec<u8>, len: usize) {
377 insert_length(aml, aml.len(), len, true);
378 }
379
380 // Append a NamedField length, which does not count the size of the encoded length itself.
append_named_field_length(aml: &mut Vec<u8>, len: usize)381 fn append_named_field_length(aml: &mut Vec<u8>, len: usize) {
382 insert_length(aml, aml.len(), len, false);
383 }
384
385 /// EISAName object. 'value' means the encoded u32 EisaIdString.
386 pub struct EISAName {
387 value: DWord,
388 }
389
390 impl EISAName {
391 /// Per ACPI Spec, the EisaIdString must be a String
392 /// object of the form UUUNNNN, where U is an uppercase letter
393 /// and N is a hexadecimal digit. No asterisks or other characters
394 /// are allowed in the string.
new(name: &str) -> Self395 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
413 impl Aml for EISAName {
to_aml_bytes(&self, bytes: &mut Vec<u8>)414 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
415 self.value.to_aml_bytes(bytes);
416 }
417 }
418
419 pub type Usize = usize;
420
421 impl Aml for Usize {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
append_aml_string(data: &mut Vec<u8>, v: &str)432 fn 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); /* NullChar */
436 }
437
438 /// implement Aml trait for 'str' so that 'str' can be directly append to the aml vector
439 pub type AmlStr = &'static str;
440
441 impl Aml for AmlStr {
to_aml_bytes(&self, bytes: &mut Vec<u8>)442 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
443 append_aml_string(bytes, self);
444 }
445 }
446
447 /// implement Aml trait for 'String'. So purpose with str.
448 pub type AmlString = String;
449
450 impl Aml for AmlString {
to_aml_bytes(&self, bytes: &mut Vec<u8>)451 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
452 append_aml_string(bytes, self);
453 }
454 }
455
456 /// ResouceTemplate object. 'children' represents the ACPI objects in it.
457 pub struct ResourceTemplate<'a> {
458 children: Vec<&'a dyn Aml>,
459 }
460
461 impl<'a> Aml for ResourceTemplate<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)462 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
463 aml.push(BUFFEROP);
464
465 let pos = aml.len();
466
467 // Add buffer data
468 for child in &self.children {
469 child.to_aml_bytes(aml);
470 }
471
472 // Mark with end and mark checksum as as always valid
473 aml.push(ENDTAG);
474 aml.push(0); /* zero checksum byte */
475
476 // Buffer length is an encoded integer including buffer data
477 // and EndTag and checksum byte
478 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 // PkgLength is everything else
484 let len = aml.len() - pos;
485 insert_pkg_length(aml, pos, len);
486 }
487 }
488
489 impl<'a> ResourceTemplate<'a> {
490 /// Create ResouceTemplate object
new(children: Vec<&'a dyn Aml>) -> Self491 pub fn new(children: Vec<&'a dyn Aml>) -> Self {
492 ResourceTemplate { children }
493 }
494 }
495
496 /// Memory32Fixed object with read_write accessing type, and the base address/length.
497 pub struct Memory32Fixed {
498 read_write: bool, /* true for read & write, false for read only */
499 base: u32,
500 length: u32,
501 }
502
503 impl Memory32Fixed {
504 /// Create Memory32Fixed object.
new(read_write: bool, base: u32, length: u32) -> Self505 pub fn new(read_write: bool, base: u32, length: u32) -> Self {
506 Memory32Fixed {
507 read_write,
508 base,
509 length,
510 }
511 }
512 }
513
514 impl Aml for Memory32Fixed {
to_aml_bytes(&self, bytes: &mut Vec<u8>)515 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
516 bytes.push(MEMORY32FIXEDDESC); /* 32bit Fixed Memory Range Descriptor */
517 bytes.extend_from_slice(&9u16.to_le_bytes());
518
519 // 9 bytes of payload
520 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)]
527 enum AddressSpaceType {
528 Memory,
529 IO,
530 BusNumber,
531 }
532
533 /// AddressSpaceCachable represent cache types for AddressSpace object
534 #[derive(Copy, Clone)]
535 pub enum AddressSpaceCachable {
536 NotCacheable,
537 Cacheable,
538 WriteCombining,
539 PreFetchable,
540 }
541
542 /// AddressSpace structure with type, resouce range and flags to
543 /// construct Memory/IO/BusNumber objects
544 pub struct AddressSpace<T> {
545 type_: AddressSpaceType,
546 min: T,
547 max: T,
548 type_flags: u8,
549 }
550
551 impl<T> AddressSpace<T> {
552 /// Create DWordMemory/QWordMemory object
new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self553 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 /// Create WordIO/DWordIO/QWordIO object
new_io(min: T, max: T) -> Self563 pub fn new_io(min: T, max: T) -> Self {
564 AddressSpace {
565 type_: AddressSpaceType::IO,
566 min,
567 max,
568 type_flags: 3, /* EntireRange */
569 }
570 }
571
572 /// Create WordBusNumber object
new_bus_number(min: T, max: T) -> Self573 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
push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize)582 fn push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize) {
583 bytes.push(descriptor); /* Word Address Space Descriptor */
584 bytes.extend_from_slice(&(length as u16).to_le_bytes());
585 bytes.push(self.type_ as u8); /* type */
586 let generic_flags = 1 << 2 /* Min Fixed */ | 1 << 3; /* Max Fixed */
587 bytes.push(generic_flags);
588 bytes.push(self.type_flags);
589 }
590 }
591
592 impl Aml for AddressSpace<u16> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)593 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
594 self.push_header(
595 bytes,
596 WORDADDRSPACEDESC, /* Word Address Space Descriptor */
597 3 + 5 * std::mem::size_of::<u16>(), /* 3 bytes of header + 5 u16 fields */
598 );
599
600 bytes.extend_from_slice(&0u16.to_le_bytes()); /* Granularity */
601 bytes.extend_from_slice(&self.min.to_le_bytes()); /* Min */
602 bytes.extend_from_slice(&self.max.to_le_bytes()); /* Max */
603 bytes.extend_from_slice(&0u16.to_le_bytes()); /* Translation */
604 let len = self.max - self.min + 1;
605 bytes.extend_from_slice(&len.to_le_bytes()); /* Length */
606 }
607 }
608
609 impl Aml for AddressSpace<u32> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)610 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
611 self.push_header(
612 bytes,
613 DWORDADDRSPACEDESC, /* DWord Address Space Descriptor */
614 3 + 5 * std::mem::size_of::<u32>(), /* 3 bytes of header + 5 u32 fields */
615 );
616
617 bytes.extend_from_slice(&0u32.to_le_bytes()); /* Granularity */
618 bytes.extend_from_slice(&self.min.to_le_bytes()); /* Min */
619 bytes.extend_from_slice(&self.max.to_le_bytes()); /* Max */
620 bytes.extend_from_slice(&0u32.to_le_bytes()); /* Translation */
621 let len = self.max - self.min + 1;
622 bytes.extend_from_slice(&len.to_le_bytes()); /* Length */
623 }
624 }
625
626 impl Aml for AddressSpace<u64> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)627 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
628 self.push_header(
629 bytes,
630 QWORDADDRSPACEDESC, /* QWord Address Space Descriptor */
631 3 + 5 * std::mem::size_of::<u64>(), /* 3 bytes of header + 5 u64 fields */
632 );
633
634 bytes.extend_from_slice(&0u64.to_le_bytes()); /* Granularity */
635 bytes.extend_from_slice(&self.min.to_le_bytes()); /* Min */
636 bytes.extend_from_slice(&self.max.to_le_bytes()); /* Max */
637 bytes.extend_from_slice(&0u64.to_le_bytes()); /* Translation */
638 let len = self.max - self.min + 1;
639 bytes.extend_from_slice(&len.to_le_bytes()); /* Length */
640 }
641 }
642
643 /// IO resouce object with the IO range, alignment and length
644 pub struct IO {
645 min: u16,
646 max: u16,
647 alignment: u8,
648 length: u8,
649 }
650
651 impl IO {
652 /// Create IO object
new(min: u16, max: u16, alignment: u8, length: u8) -> Self653 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
663 impl Aml for IO {
to_aml_bytes(&self, bytes: &mut Vec<u8>)664 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
665 bytes.push(IOPORTDESC); /* IO Port Descriptor */
666 bytes.push(1); /* IODecode16 */
667 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
674 /// Interrupt resouce object with the interrupt characters.
675 pub struct Interrupt {
676 consumer: bool,
677 edge_triggered: bool,
678 active_low: bool,
679 shared: bool,
680 number: u32,
681 }
682
683 impl Interrupt {
684 /// Create Interrupt object
new( consumer: bool, edge_triggered: bool, active_low: bool, shared: bool, number: u32, ) -> Self685 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
702 impl Aml for Interrupt {
to_aml_bytes(&self, bytes: &mut Vec<u8>)703 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
704 bytes.push(EXTIRQDESC); /* Extended IRQ Descriptor */
705 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); /* count */
712 bytes.extend_from_slice(&self.number.to_le_bytes());
713 }
714 }
715
716 /// Device object with its device name and children objects in it.
717 pub struct Device<'a> {
718 path: Path,
719 children: Vec<&'a dyn Aml>,
720 }
721
722 impl<'a> Aml for Device<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)723 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
724 aml.push(EXTOPPREFIX); /* ExtOpPrefix */
725 aml.push(DEVICEOP); /* DeviceOp */
726
727 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
738 impl<'a> Device<'a> {
739 /// Create Device object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self740 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
741 Device { path, children }
742 }
743 }
744
745 /// Scope object with its name and children objects in it.
746 pub struct Scope<'a> {
747 path: Path,
748 children: Vec<&'a dyn Aml>,
749 }
750
751 impl<'a> Aml for Scope<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
766 impl<'a> Scope<'a> {
767 /// Create Scope object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self768 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
769 Scope { path, children }
770 }
771
772 /// Create raw bytes representing a Scope from its children in raw bytes
raw(path: Path, mut children: Vec<u8>) -> Vec<u8>773 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
788 /// Method object with its name, children objects, arguments and serialized character.
789 pub struct Method<'a> {
790 path: Path,
791 children: Vec<&'a dyn Aml>,
792 args: u8,
793 serialized: bool,
794 }
795
796 impl<'a> Method<'a> {
797 /// Create Method object.
new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self798 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
808 impl<'a> Aml for Method<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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 /// FieldAccessType defines the field accessing types.
826 #[derive(Clone, Copy)]
827 pub enum FieldAccessType {
828 Any,
829 Byte,
830 Word,
831 DWord,
832 QWord,
833 Buffer,
834 }
835
836 /// FieldLockRule defines the rules whether to use the Global Lock.
837 #[derive(Clone, Copy)]
838 pub enum FieldLockRule {
839 NoLock = 0,
840 Lock = 1,
841 }
842
843 /// FieldUpdateRule defines the rules to update the field.
844 #[derive(Clone, Copy)]
845 pub enum FieldUpdateRule {
846 Preserve = 0,
847 WriteAsOnes = 1,
848 WriteAsZeroes = 2,
849 }
850
851 /// FieldEntry defines the field entry.
852 pub enum FieldEntry {
853 Named([u8; 4], usize),
854 Reserved(usize),
855 }
856
857 /// Field object with the region name, field entries, access type and update rules.
858 pub struct Field {
859 path: Path,
860
861 fields: Vec<FieldEntry>,
862 access_type: FieldAccessType,
863 lock_rule: FieldLockRule,
864 update_rule: FieldUpdateRule,
865 }
866
867 impl Field {
868 /// Create Field object
new( path: Path, access_type: FieldAccessType, lock_rule: FieldLockRule, update_rule: FieldUpdateRule, fields: Vec<FieldEntry>, ) -> Self869 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
886 impl Aml for Field {
to_aml_bytes(&self, aml: &mut Vec<u8>)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 /// The space type for OperationRegion object
917 #[derive(Clone, Copy)]
918 pub enum OpRegionSpace {
919 SystemMemory,
920 SystemIO,
921 PCIConfig,
922 EmbeddedControl,
923 SMBus,
924 SystemCMOS,
925 PciBarTarget,
926 IPMI,
927 GeneralPurposeIO,
928 GenericSerialBus,
929 }
930
931 /// OperationRegion object with region name, region space type, its offset and length.
932 pub struct OpRegion<'a> {
933 path: Path,
934 space: OpRegionSpace,
935 offset: &'a dyn Aml,
936 length: &'a dyn Aml,
937 }
938
939 impl<'a> OpRegion<'a> {
940 /// Create OperationRegion object.
new(path: Path, space: OpRegionSpace, offset: &'a dyn Aml, length: &'a dyn Aml) -> Self941 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
951 impl<'a> Aml for OpRegion<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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); /* RegionOffset */
959 self.length.to_aml_bytes(aml); /* RegionLen */
960 }
961 }
962
963 /// If object with the if condition(predicate) and the body presented by the if_children objects.
964 pub struct If<'a> {
965 predicate: &'a dyn Aml,
966 if_children: Vec<&'a dyn Aml>,
967 }
968
969 impl<'a> If<'a> {
970 /// Create If object.
new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self971 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
979 impl<'a> Aml for If<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
994 /// Else object
995 pub struct Else<'a> {
996 body: Vec<&'a dyn Aml>,
997 }
998
999 impl<'a> Else<'a> {
1000 /// Create Else object.
new(body: Vec<&'a dyn Aml>) -> Self1001 pub fn new(body: Vec<&'a dyn Aml>) -> Self {
1002 Else { body }
1003 }
1004 }
1005
1006 impl<'a> Aml for Else<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
1020 macro_rules! compare_op {
1021 ($name:ident, $opcode:expr, $invert:expr) => {
1022 /// Compare object with its right part and left part, which are both ACPI Object.
1023 pub struct $name<'a> {
1024 right: &'a dyn Aml,
1025 left: &'a dyn Aml,
1026 }
1027
1028 impl<'a> $name<'a> {
1029 /// Create the compare object method.
1030 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
1048 compare_op!(Equal, LEQUALOP, false);
1049 compare_op!(LessThan, LLESSOP, false);
1050 compare_op!(GreaterThan, LGREATEROP, false);
1051 compare_op!(NotEqual, LEQUALOP, true);
1052 compare_op!(GreaterEqual, LLESSOP, true);
1053 compare_op!(LessEqual, LGREATEROP, true);
1054
1055 /// Argx object.
1056 pub struct Arg(pub u8);
1057
1058 impl Aml for Arg {
1059 /// Per ACPI spec, there is maximum 7 Argx objects from
1060 /// Arg0 ~ Arg6. Any other Arg object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1061 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1062 assert!(self.0 <= 6);
1063 bytes.push(ARG0OP + self.0);
1064 }
1065 }
1066
1067 /// Localx object.
1068 pub struct Local(pub u8);
1069
1070 impl Aml for Local {
1071 /// Per ACPI spec, there is maximum 8 Localx objects from
1072 /// Local0 ~ Local7. Any other Local object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1073 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1074 assert!(self.0 <= 7);
1075 bytes.push(LOCAL0OP + self.0);
1076 }
1077 }
1078
1079 /// Store object with the ACPI object name which can be stored to and
1080 /// the ACPI object value which is to store.
1081 pub struct Store<'a> {
1082 name: &'a dyn Aml,
1083 value: &'a dyn Aml,
1084 }
1085
1086 impl<'a> Store<'a> {
1087 /// Create Store object.
new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self1088 pub fn new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1089 Store { name, value }
1090 }
1091 }
1092
1093 impl<'a> Aml for Store<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1101 /// Mutex object with a mutex name and a synchronization level.
1102 pub struct Mutex {
1103 path: Path,
1104 sync_level: u8,
1105 }
1106
1107 impl Mutex {
1108 /// Create Mutex object.
new(path: Path, sync_level: u8) -> Self1109 pub fn new(path: Path, sync_level: u8) -> Self {
1110 Self { path, sync_level }
1111 }
1112 }
1113
1114 impl Aml for Mutex {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1123 /// Acquire object with a Mutex object and timeout value.
1124 pub struct Acquire {
1125 mutex: Path,
1126 timeout: u16,
1127 }
1128
1129 impl Acquire {
1130 /// Create Acquire object.
new(mutex: Path, timeout: u16) -> Self1131 pub fn new(mutex: Path, timeout: u16) -> Self {
1132 Acquire { mutex, timeout }
1133 }
1134 }
1135
1136 impl Aml for Acquire {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1145 /// Release object with a Mutex object to release.
1146 pub struct Release {
1147 mutex: Path,
1148 }
1149
1150 impl Release {
1151 /// Create Release object.
new(mutex: Path) -> Self1152 pub fn new(mutex: Path) -> Self {
1153 Release { mutex }
1154 }
1155 }
1156
1157 impl Aml for Release {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1165 /// Notify object with an object which is to be notified with the value.
1166 pub struct Notify<'a> {
1167 object: &'a dyn Aml,
1168 value: &'a dyn Aml,
1169 }
1170
1171 impl<'a> Notify<'a> {
1172 /// Create Notify object.
new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self1173 pub fn new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1174 Notify { object, value }
1175 }
1176 }
1177
1178 impl<'a> Aml for Notify<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1186 /// While object with the while condition objects(predicate) and
1187 /// the while body objects(while_children).
1188 pub struct While<'a> {
1189 predicate: &'a dyn Aml,
1190 while_children: Vec<&'a dyn Aml>,
1191 }
1192
1193 impl<'a> While<'a> {
1194 /// Create While object.
new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self1195 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
1203 impl<'a> Aml for While<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
1218 macro_rules! object_op {
1219 ($name:ident, $opcode:expr) => {
1220 /// General operation on a object.
1221 pub struct $name<'a> {
1222 a: &'a dyn Aml,
1223 }
1224
1225 impl<'a> $name<'a> {
1226 /// Create the object method.
1227 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
1241 object_op!(ObjectType, OBJECTTYPEOP);
1242 object_op!(SizeOf, SIZEOFOP);
1243 object_op!(Return, RETURNOP);
1244 object_op!(DeRefOf, DEREFOFOP);
1245
1246 macro_rules! binary_op {
1247 ($name:ident, $opcode:expr) => {
1248 /// General operation object with the operator a/b and a target.
1249 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 /// Create the object.
1257 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); /* Op for the binary operator */
1265 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
1273 binary_op!(Add, ADDOP);
1274 binary_op!(Concat, CONCATOP);
1275 binary_op!(Subtract, SUBTRACTOP);
1276 binary_op!(Multiply, MULTIPLYOP);
1277 binary_op!(ShiftLeft, SHIFTLEFTOP);
1278 binary_op!(ShiftRight, SHIFTRIGHTOP);
1279 binary_op!(And, ANDOP);
1280 binary_op!(Nand, NANDOP);
1281 binary_op!(Or, OROP);
1282 binary_op!(Nor, NOROP);
1283 binary_op!(Xor, XOROP);
1284 binary_op!(ConcatRes, CONCATRESOP);
1285 binary_op!(Mod, MODOP);
1286 binary_op!(Index, INDEXOP);
1287 binary_op!(ToString, TOSTRINGOP);
1288 binary_op!(CreateDWordField, CREATEDWFIELDOP);
1289 binary_op!(CreateQWordField, CREATEQWFIELDOP);
1290
1291 macro_rules! convert_op {
1292 ($name:ident, $opcode:expr) => {
1293 /// General operation object with the operator a/b and a target.
1294 pub struct $name<'a> {
1295 a: &'a dyn Aml,
1296 target: &'a dyn Aml,
1297 }
1298
1299 impl<'a> $name<'a> {
1300 /// Create the object.
1301 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); /* Op for the binary operator */
1309 self.a.to_aml_bytes(bytes);
1310 self.target.to_aml_bytes(bytes);
1311 }
1312 }
1313 };
1314 }
1315
1316 convert_op!(ToBuffer, TOBUFFEROP);
1317 convert_op!(ToInteger, TOINTEGEROP);
1318
1319 /// Create Field Object.
1320 pub 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
1327 impl<'a> CreateField<'a> {
new( name_string: &'a dyn Aml, source: &'a dyn Aml, bit_index: &'a dyn Aml, bit_num: &'a dyn Aml, ) -> Self1328 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
1343 impl<'a> Aml for CreateField<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1354 /// Mid object with the source, index, length, and result objects.
1355 pub 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
1362 impl<'a> Mid<'a> {
new( source: &'a dyn Aml, index: &'a dyn Aml, length: &'a dyn Aml, result: &'a dyn Aml, ) -> Self1363 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
1378 impl<'a> Aml for Mid<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1388 /// MethodCall object with the method name and parameter objects.
1389 pub struct MethodCall<'a> {
1390 name: Path,
1391 args: Vec<&'a dyn Aml>,
1392 }
1393
1394 impl<'a> MethodCall<'a> {
1395 /// Create MethodCall object.
new(name: Path, args: Vec<&'a dyn Aml>) -> Self1396 pub fn new(name: Path, args: Vec<&'a dyn Aml>) -> Self {
1397 MethodCall { name, args }
1398 }
1399 }
1400
1401 impl<'a> Aml for MethodCall<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)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
1410 /// Buffer object with the TermArg in it.
1411 pub struct BufferTerm<'a> {
1412 data: &'a dyn Aml,
1413 }
1414
1415 impl<'a> BufferTerm<'a> {
1416 /// Create BufferTerm object.
new(data: &'a dyn Aml) -> Self1417 pub fn new(data: &'a dyn Aml) -> Self {
1418 BufferTerm { data }
1419 }
1420 }
1421
1422 impl<'a> Aml for BufferTerm<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
1434 /// Buffer object with the data in it.
1435 pub struct BufferData {
1436 data: Vec<u8>,
1437 }
1438
1439 impl BufferData {
1440 /// Create BufferData object.
new(data: Vec<u8>) -> Self1441 pub fn new(data: Vec<u8>) -> Self {
1442 BufferData { data }
1443 }
1444 }
1445
1446 impl Aml for BufferData {
to_aml_bytes(&self, aml: &mut Vec<u8>)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
1459 pub struct Uuid {
1460 name: BufferData,
1461 }
1462
hex2byte(v1: char, v2: char) -> u81463 fn 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
1472 impl Uuid {
1473 // Create Uuid object
1474 // eg. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
new(name: &str) -> Self1475 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 // dd - at offset 00
1486 data.push(hex2byte(name_vec[6], name_vec[7]));
1487 // cc - at offset 01
1488 data.push(hex2byte(name_vec[4], name_vec[5]));
1489 // bb - at offset 02
1490 data.push(hex2byte(name_vec[2], name_vec[3]));
1491 // aa - at offset 03
1492 data.push(hex2byte(name_vec[0], name_vec[1]));
1493
1494 // ff - at offset 04
1495 data.push(hex2byte(name_vec[11], name_vec[12]));
1496 // ee - at offset 05
1497 data.push(hex2byte(name_vec[9], name_vec[10]));
1498
1499 // hh - at offset 06
1500 data.push(hex2byte(name_vec[16], name_vec[17]));
1501 // gg - at offset 07
1502 data.push(hex2byte(name_vec[14], name_vec[15]));
1503
1504 // ii - at offset 08
1505 data.push(hex2byte(name_vec[19], name_vec[20]));
1506 // jj - at offset 09
1507 data.push(hex2byte(name_vec[21], name_vec[22]));
1508
1509 // kk - at offset 10
1510 data.push(hex2byte(name_vec[24], name_vec[25]));
1511 // ll - at offset 11
1512 data.push(hex2byte(name_vec[26], name_vec[27]));
1513 // mm - at offset 12
1514 data.push(hex2byte(name_vec[28], name_vec[29]));
1515 // nn - at offset 13
1516 data.push(hex2byte(name_vec[30], name_vec[31]));
1517 // oo - at offset 14
1518 data.push(hex2byte(name_vec[32], name_vec[33]));
1519 // pp - at offset 15
1520 data.push(hex2byte(name_vec[34], name_vec[35]));
1521
1522 Uuid {
1523 name: BufferData::new(data),
1524 }
1525 }
1526 }
1527
1528 impl Aml for Uuid {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1529 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1530 self.name.to_aml_bytes(bytes)
1531 }
1532 }
1533
1534 /// Power Resource object. 'children' represents Power Resource method.
1535 pub struct PowerResource<'a> {
1536 name: Path,
1537 level: u8,
1538 order: u16,
1539 children: Vec<&'a dyn Aml>,
1540 }
1541
1542 impl<'a> PowerResource<'a> {
1543 /// Create Power Resouce object
new(name: Path, level: u8, order: u16, children: Vec<&'a dyn Aml>) -> Self1544 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
1554 impl<'a> Aml for PowerResource<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)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 // Add name string
1562 self.name.to_aml_bytes(aml);
1563 // Add system level
1564 aml.push(self.level);
1565 // Add Resource Order
1566 let orders = self.order.to_le_bytes();
1567 aml.push(orders[0]);
1568 aml.push(orders[1]);
1569 // Add child data
1570 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)]
1581 mod tests {
1582 use super::*;
1583
1584 #[test]
test_device()1585 fn test_device() {
1586 /*
1587 Device (_SB.COM1)
1588 {
1589 Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */) // _HID: Hardware ID
1590 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1591 {
1592 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1593 {
1594 0x00000004,
1595 }
1596 IO (Decode16,
1597 0x03F8, // Range Minimum
1598 0x03F8, // Range Maximum
1599 0x00, // Alignment
1600 0x08, // Length
1601 )
1602 }
1603 }
1604 */
1605 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]
test_scope()1631 fn test_scope() {
1632 /*
1633 Scope (_SB.MBRD)
1634 {
1635 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1636 {
1637 Memory32Fixed (ReadWrite,
1638 0xE8000000, // Address Base
1639 0x10000000, // Address Length
1640 )
1641 })
1642 }
1643 */
1644
1645 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]
test_resource_template()1664 fn test_resource_template() {
1665 /*
1666 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1667 {
1668 Memory32Fixed (ReadWrite,
1669 0xE8000000, // Address Base
1670 0x10000000, // Address Length
1671 )
1672 })
1673 */
1674 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 /*
1688 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1689 {
1690 WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
1691 0x0000, // Granularity
1692 0x0000, // Range Minimum
1693 0x00FF, // Range Maximum
1694 0x0000, // Translation Offset
1695 0x0100, // Length
1696 ,, )
1697 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1698 0x0000, // Granularity
1699 0x0000, // Range Minimum
1700 0x0CF7, // Range Maximum
1701 0x0000, // Translation Offset
1702 0x0CF8, // Length
1703 ,, , TypeStatic, DenseTranslation)
1704 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1705 0x0000, // Granularity
1706 0x0D00, // Range Minimum
1707 0xFFFF, // Range Maximum
1708 0x0000, // Translation Offset
1709 0xF300, // Length
1710 ,, , TypeStatic, DenseTranslation)
1711 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1712 0x00000000, // Granularity
1713 0x000A0000, // Range Minimum
1714 0x000BFFFF, // Range Maximum
1715 0x00000000, // Translation Offset
1716 0x00020000, // Length
1717 ,, , AddressRangeMemory, TypeStatic)
1718 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
1719 0x00000000, // Granularity
1720 0xC0000000, // Range Minimum
1721 0xFEBFFFFF, // Range Maximum
1722 0x00000000, // Translation Offset
1723 0x3EC00000, // Length
1724 ,, , AddressRangeMemory, TypeStatic)
1725 QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1726 0x0000000000000000, // Granularity
1727 0x0000000800000000, // Range Minimum
1728 0x0000000FFFFFFFFF, // Range Maximum
1729 0x0000000000000000, // Translation Offset
1730 0x0000000800000000, // Length
1731 ,, , AddressRangeMemory, TypeStatic)
1732 })
1733 */
1734
1735 // WordBusNumber from above
1736 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 // WordIO blocks (x 2) from above
1750 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 // DWordMemory blocks (x 2) from above
1769 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 // QWordMemory from above
1799 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 /*
1821 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1822 {
1823 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1824 {
1825 0x00000004,
1826 }
1827 IO (Decode16,
1828 0x03F8, // Range Minimum
1829 0x03F8, // Range Maximum
1830 0x00, // Alignment
1831 0x08, // Length
1832 )
1833 })
1834
1835 */
1836 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]
test_pkg_length()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]
test_package()1876 fn test_package() {
1877 /*
1878 Name (_S5, Package (0x01) // _S5_: S5 System State
1879 {
1880 0x05
1881 })
1882 */
1883 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]
test_eisa_name()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]
test_name_path()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]
test_numbers()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 // u8
1936 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 // u16
1947 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 // u32
1961 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 // u64
1978 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 // usize
1998 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]
test_name()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, /* NameOp */
2029 0x2F, /* MultiNamePrefix */
2030 0x03, /* 3 name parts */
2031 0x5F, 0x53, 0x42, 0x5F, /* _SB_ */
2032 0x50, 0x43, 0x49, 0x30, /* PCI0 */
2033 0x5F, 0x55, 0x49, 0x44, /* _UID */
2034 0x0b, /* WordPrefix */
2035 0x34, 0x12
2036 ]
2037 );
2038 }
2039
2040 #[test]
test_string()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]
test_method()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]
test_field()2061 fn test_field() {
2062 /*
2063 Field (PRST, ByteAcc, NoLock, WriteAsZeros)
2064 {
2065 Offset (0x04),
2066 CPEN, 1,
2067 CINS, 1,
2068 CRMV, 1,
2069 CEJ0, 1,
2070 Offset (0x05),
2071 CCMD, 8
2072 }
2073
2074 */
2075
2076 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 /*
2102 Field (PRST, DWordAcc, Lock, Preserve)
2103 {
2104 CSEL, 32,
2105 Offset (0x08),
2106 CDAT, 32
2107 }
2108 */
2109
2110 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]
test_op_region()2132 fn test_op_region() {
2133 /*
2134 OperationRegion (PRST, SystemIO, 0x0CD8, 0x0C)
2135 */
2136 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]
test_arg_if()2152 fn test_arg_if() {
2153 /*
2154 Method(TEST, 1, NotSerialized) {
2155 If (Arg0 == Zero) {
2156 Return(One)
2157 }
2158 Return(Zero)
2159 }
2160 */
2161 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]
test_local_if()2181 fn test_local_if() {
2182 /*
2183 Method(TEST, 0, NotSerialized) {
2184 Local0 = One
2185 If (Local0 == Zero) {
2186 Return(One)
2187 }
2188 Return(Zero)
2189 }
2190 */
2191 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]
test_mutex()2212 fn test_mutex() {
2213 /*
2214 Device (_SB_.MHPC)
2215 {
2216 Name (_HID, EisaId("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
2217 Mutex (MLCK, 0x00)
2218 Method (TEST, 0, NotSerialized)
2219 {
2220 Acquire (MLCK, 0xFFFF)
2221 Local0 = One
2222 Release (MLCK)
2223 }
2224 }
2225 */
2226
2227 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]
test_notify()2258 fn test_notify() {
2259 /*
2260 Device (_SB.MHPC)
2261 {
2262 Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
2263 Method (TEST, 0, NotSerialized)
2264 {
2265 Notify (MHPC, One) // Device Check
2266 }
2267 }
2268 */
2269 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]
test_while()2293 fn test_while() {
2294 /*
2295 Device (_SB.MHPC)
2296 {
2297 Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
2298 Method (TEST, 0, NotSerialized)
2299 {
2300 Local0 = Zero
2301 While ((Local0 < 0x04))
2302 {
2303 Local0 += One
2304 }
2305 }
2306 }
2307 */
2308
2309 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]
test_method_call()2339 fn test_method_call() {
2340 /*
2341 Method (TST1, 1, NotSerialized)
2342 {
2343 TST2 (One, One)
2344 }
2345
2346 Method (TST2, 2, NotSerialized)
2347 {
2348 TST1 (One)
2349 }
2350 */
2351 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]
test_buffer()2375 fn test_buffer() {
2376 /*
2377 Name (_MAT, Buffer (0x08) // _MAT: Multiple APIC Table Entry
2378 {
2379 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 /* ........ */
2380 })
2381 */
2382 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 }
2396