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.append(&mut vec![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.append(&mut vec![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.append(&mut vec![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.clone().iter_mut() {
145 bytes.append(&mut part.to_vec());
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_value().into() {
194 (*self as Byte).to_aml_bytes(bytes);
195 } else {
196 bytes.push(WORDPREFIX);
197 bytes.append(&mut self.to_le_bytes().to_vec());
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_value().into() {
207 (*self as Word).to_aml_bytes(bytes);
208 } else {
209 bytes.push(DWORDPREFIX);
210 bytes.append(&mut self.to_le_bytes().to_vec());
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_value().into() {
220 (*self as DWord).to_aml_bytes(bytes);
221 } else {
222 bytes.push(QWORDPREFIX);
223 bytes.append(&mut self.to_le_bytes().to_vec());
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.append(&mut self.bytes.clone());
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 mut bytes: Vec<u8> = Vec::new();
256 bytes.extend_from_slice(field_name.as_bytes());
257 Name { bytes }
258 }
259 }
260
261 /// Package object. 'children' represents the ACPI objects contained in this package.
262 pub struct Package {
263 children_bytes: Vec<u8>,
264 }
265
266 impl Aml for Package {
to_aml_bytes(&self, aml: &mut Vec<u8>)267 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
268 let pkg_length = create_pkg_length(&self.children_bytes, true);
269 aml.append(
270 &mut [
271 &[PACKAGEOP],
272 pkg_length.as_slice(),
273 self.children_bytes.as_slice(),
274 ]
275 .concat(),
276 );
277 }
278 }
279
280 impl Package {
281 /// Create Package object:
new(children: Vec<&dyn Aml>) -> Package282 pub fn new(children: Vec<&dyn Aml>) -> Package {
283 let mut bytes = vec![children.len() as u8];
284 for child in &children {
285 child.to_aml_bytes(&mut bytes);
286 }
287 Package {
288 children_bytes: bytes,
289 }
290 }
291 }
292
293 /// Variable Package Term
294 pub struct VarPackageTerm<'a> {
295 data: &'a dyn Aml,
296 }
297
298 impl<'a> Aml for VarPackageTerm<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)299 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
300 let mut bytes = Vec::new();
301 self.data.to_aml_bytes(&mut bytes);
302
303 let mut pkg_length = create_pkg_length(&bytes, true);
304 pkg_length.reverse();
305 for byte in pkg_length {
306 bytes.insert(0, byte);
307 }
308
309 bytes.insert(0, VARPACKAGEOP);
310
311 aml.append(&mut bytes)
312 }
313 }
314
315 impl<'a> VarPackageTerm<'a> {
316 /// Create Variable Package Term
new(data: &'a dyn Aml) -> Self317 pub fn new(data: &'a dyn Aml) -> Self {
318 VarPackageTerm { data }
319 }
320 }
321
322 /*
323
324 From the ACPI spec for PkgLength:
325
326 "The high 2 bits of the first byte reveal how many follow bytes are in the PkgLength. If the
327 PkgLength has only one byte, bit 0 through 5 are used to encode the package length (in other
328 words, values 0-63). If the package length value is more than 63, more than one byte must be
329 used for the encoding in which case bit 4 and 5 of the PkgLeadByte are reserved and must be zero.
330 If the multiple bytes encoding is used, bits 0-3 of the PkgLeadByte become the least significant 4
331 bits of the resulting package length value. The next ByteData will become the next least
332 significant 8 bits of the resulting value and so on, up to 3 ByteData bytes. Thus, the maximum
333 package length is 2**28."
334
335 */
336
337 /* Also used for NamedField but in that case the length is not included in itself */
create_pkg_length(data: &[u8], include_self: bool) -> Vec<u8>338 fn create_pkg_length(data: &[u8], include_self: bool) -> Vec<u8> {
339 let mut result = Vec::new();
340
341 /* PkgLength is inclusive and includes the length bytes */
342 let length_length = if data.len() < (2usize.pow(6) - 1) {
343 1
344 } else if data.len() < (2usize.pow(12) - 2) {
345 2
346 } else if data.len() < (2usize.pow(20) - 3) {
347 3
348 } else {
349 4
350 };
351
352 let length = data.len() + if include_self { length_length } else { 0 };
353
354 match length_length {
355 1 => result.push(length as u8),
356 2 => {
357 result.push((1u8 << 6) | (length & 0xf) as u8);
358 result.push((length >> 4) as u8)
359 }
360 3 => {
361 result.push((2u8 << 6) | (length & 0xf) as u8);
362 result.push((length >> 4) as u8);
363 result.push((length >> 12) as u8);
364 }
365 _ => {
366 result.push((3u8 << 6) | (length & 0xf) as u8);
367 result.push((length >> 4) as u8);
368 result.push((length >> 12) as u8);
369 result.push((length >> 20) as u8);
370 }
371 }
372
373 result
374 }
375
376 /// EISAName object. 'value' means the encoded u32 EisaIdString.
377 pub struct EISAName {
378 value: DWord,
379 }
380
381 impl EISAName {
382 /// Per ACPI Spec, the EisaIdString must be a String
383 /// object of the form UUUNNNN, where U is an uppercase letter
384 /// and N is a hexadecimal digit. No asterisks or other characters
385 /// are allowed in the string.
new(name: &str) -> Self386 pub fn new(name: &str) -> Self {
387 assert_eq!(name.len(), 7);
388
389 let data = name.as_bytes();
390
391 let value: u32 = (u32::from(data[0].checked_sub(NAMECHARBASE).unwrap()) << 26
392 | u32::from(data[1].checked_sub(NAMECHARBASE).unwrap()) << 21
393 | u32::from(data[2].checked_sub(NAMECHARBASE).unwrap()) << 16
394 | name.chars().nth(3).unwrap().to_digit(16).unwrap() << 12
395 | name.chars().nth(4).unwrap().to_digit(16).unwrap() << 8
396 | name.chars().nth(5).unwrap().to_digit(16).unwrap() << 4
397 | name.chars().nth(6).unwrap().to_digit(16).unwrap())
398 .swap_bytes();
399
400 EISAName { value }
401 }
402 }
403
404 impl Aml for EISAName {
to_aml_bytes(&self, bytes: &mut Vec<u8>)405 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
406 self.value.to_aml_bytes(bytes);
407 }
408 }
409
410 pub type Usize = usize;
411
412 impl Aml for Usize {
to_aml_bytes(&self, bytes: &mut Vec<u8>)413 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
414 #[cfg(target_pointer_width = "16")]
415 (*self as u16).to_aml_bytes(bytes);
416 #[cfg(target_pointer_width = "32")]
417 (*self as u32).to_aml_bytes(bytes);
418 #[cfg(target_pointer_width = "64")]
419 (*self as u64).to_aml_bytes(bytes);
420 }
421 }
422
create_aml_string(v: &str) -> Vec<u8>423 fn create_aml_string(v: &str) -> Vec<u8> {
424 let mut data = vec![STRINGOP];
425 data.extend_from_slice(v.as_bytes());
426 data.push(0x0); /* NullChar */
427 data
428 }
429
430 /// implement Aml trait for 'str' so that 'str' can be directly append to the aml vector
431 pub type AmlStr = &'static str;
432
433 impl Aml for AmlStr {
to_aml_bytes(&self, bytes: &mut Vec<u8>)434 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
435 bytes.append(&mut create_aml_string(self));
436 }
437 }
438
439 /// implement Aml trait for 'String'. So purpose with str.
440 pub type AmlString = String;
441
442 impl Aml for AmlString {
to_aml_bytes(&self, bytes: &mut Vec<u8>)443 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
444 bytes.append(&mut create_aml_string(self));
445 }
446 }
447
448 /// ResouceTemplate object. 'children' represents the ACPI objects in it.
449 pub struct ResourceTemplate<'a> {
450 children: Vec<&'a dyn Aml>,
451 }
452
453 impl<'a> Aml for ResourceTemplate<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)454 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
455 let mut bytes = Vec::new();
456
457 // Add buffer data
458 for child in &self.children {
459 child.to_aml_bytes(&mut bytes);
460 }
461
462 // Mark with end and mark checksum as as always valid
463 bytes.push(ENDTAG);
464 bytes.push(0); /* zero checksum byte */
465
466 // Buffer length is an encoded integer including buffer data
467 // and EndTag and checksum byte
468 let mut buffer_length = Vec::new();
469 bytes.len().to_aml_bytes(&mut buffer_length);
470 buffer_length.reverse();
471 for byte in buffer_length {
472 bytes.insert(0, byte);
473 }
474
475 // PkgLength is everything else
476 let mut pkg_length = create_pkg_length(&bytes, true);
477 pkg_length.reverse();
478 for byte in pkg_length {
479 bytes.insert(0, byte);
480 }
481
482 bytes.insert(0, BUFFEROP);
483
484 aml.append(&mut bytes);
485 }
486 }
487
488 impl<'a> ResourceTemplate<'a> {
489 /// Create ResouceTemplate object
new(children: Vec<&'a dyn Aml>) -> Self490 pub fn new(children: Vec<&'a dyn Aml>) -> Self {
491 ResourceTemplate { children }
492 }
493 }
494
495 /// Memory32Fixed object with read_write accessing type, and the base address/length.
496 pub struct Memory32Fixed {
497 read_write: bool, /* true for read & write, false for read only */
498 base: u32,
499 length: u32,
500 }
501
502 impl Memory32Fixed {
503 /// Create Memory32Fixed object.
new(read_write: bool, base: u32, length: u32) -> Self504 pub fn new(read_write: bool, base: u32, length: u32) -> Self {
505 Memory32Fixed {
506 read_write,
507 base,
508 length,
509 }
510 }
511 }
512
513 impl Aml for Memory32Fixed {
to_aml_bytes(&self, bytes: &mut Vec<u8>)514 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
515 bytes.push(MEMORY32FIXEDDESC); /* 32bit Fixed Memory Range Descriptor */
516 bytes.append(&mut 9u16.to_le_bytes().to_vec());
517
518 // 9 bytes of payload
519 bytes.push(self.read_write as u8);
520 bytes.append(&mut self.base.to_le_bytes().to_vec());
521 bytes.append(&mut self.length.to_le_bytes().to_vec());
522 }
523 }
524
525 #[derive(Copy, Clone)]
526 enum AddressSpaceType {
527 Memory,
528 IO,
529 BusNumber,
530 }
531
532 /// AddressSpaceCachable represent cache types for AddressSpace object
533 #[derive(Copy, Clone)]
534 pub enum AddressSpaceCachable {
535 NotCacheable,
536 Cacheable,
537 WriteCombining,
538 PreFetchable,
539 }
540
541 /// AddressSpace structure with type, resouce range and flags to
542 /// construct Memory/IO/BusNumber objects
543 pub struct AddressSpace<T> {
544 type_: AddressSpaceType,
545 min: T,
546 max: T,
547 type_flags: u8,
548 }
549
550 impl<T> AddressSpace<T> {
551 /// Create DWordMemory/QWordMemory object
new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self552 pub fn new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self {
553 AddressSpace {
554 type_: AddressSpaceType::Memory,
555 min,
556 max,
557 type_flags: (cacheable as u8) << 1 | read_write as u8,
558 }
559 }
560
561 /// Create WordIO/DWordIO/QWordIO object
new_io(min: T, max: T) -> Self562 pub fn new_io(min: T, max: T) -> Self {
563 AddressSpace {
564 type_: AddressSpaceType::IO,
565 min,
566 max,
567 type_flags: 3, /* EntireRange */
568 }
569 }
570
571 /// Create WordBusNumber object
new_bus_number(min: T, max: T) -> Self572 pub fn new_bus_number(min: T, max: T) -> Self {
573 AddressSpace {
574 type_: AddressSpaceType::BusNumber,
575 min,
576 max,
577 type_flags: 0,
578 }
579 }
580
push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize)581 fn push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize) {
582 bytes.push(descriptor); /* Word Address Space Descriptor */
583 bytes.append(&mut (length as u16).to_le_bytes().to_vec());
584 bytes.push(self.type_ as u8); /* type */
585 let generic_flags = 1 << 2 /* Min Fixed */ | 1 << 3; /* Max Fixed */
586 bytes.push(generic_flags);
587 bytes.push(self.type_flags);
588 }
589 }
590
591 impl Aml for AddressSpace<u16> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)592 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
593 self.push_header(
594 bytes,
595 WORDADDRSPACEDESC, /* Word Address Space Descriptor */
596 3 + 5 * std::mem::size_of::<u16>(), /* 3 bytes of header + 5 u16 fields */
597 );
598
599 bytes.append(&mut 0u16.to_le_bytes().to_vec()); /* Granularity */
600 bytes.append(&mut self.min.to_le_bytes().to_vec()); /* Min */
601 bytes.append(&mut self.max.to_le_bytes().to_vec()); /* Max */
602 bytes.append(&mut 0u16.to_le_bytes().to_vec()); /* Translation */
603 let len = self.max - self.min + 1;
604 bytes.append(&mut len.to_le_bytes().to_vec()); /* Length */
605 }
606 }
607
608 impl Aml for AddressSpace<u32> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)609 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
610 self.push_header(
611 bytes,
612 DWORDADDRSPACEDESC, /* DWord Address Space Descriptor */
613 3 + 5 * std::mem::size_of::<u32>(), /* 3 bytes of header + 5 u32 fields */
614 );
615
616 bytes.append(&mut 0u32.to_le_bytes().to_vec()); /* Granularity */
617 bytes.append(&mut self.min.to_le_bytes().to_vec()); /* Min */
618 bytes.append(&mut self.max.to_le_bytes().to_vec()); /* Max */
619 bytes.append(&mut 0u32.to_le_bytes().to_vec()); /* Translation */
620 let len = self.max - self.min + 1;
621 bytes.append(&mut len.to_le_bytes().to_vec()); /* Length */
622 }
623 }
624
625 impl Aml for AddressSpace<u64> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)626 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
627 self.push_header(
628 bytes,
629 QWORDADDRSPACEDESC, /* QWord Address Space Descriptor */
630 3 + 5 * std::mem::size_of::<u64>(), /* 3 bytes of header + 5 u64 fields */
631 );
632
633 bytes.append(&mut 0u64.to_le_bytes().to_vec()); /* Granularity */
634 bytes.append(&mut self.min.to_le_bytes().to_vec()); /* Min */
635 bytes.append(&mut self.max.to_le_bytes().to_vec()); /* Max */
636 bytes.append(&mut 0u64.to_le_bytes().to_vec()); /* Translation */
637 let len = self.max - self.min + 1;
638 bytes.append(&mut len.to_le_bytes().to_vec()); /* Length */
639 }
640 }
641
642 /// IO resouce object with the IO range, alignment and length
643 pub struct IO {
644 min: u16,
645 max: u16,
646 alignment: u8,
647 length: u8,
648 }
649
650 impl IO {
651 /// Create IO object
new(min: u16, max: u16, alignment: u8, length: u8) -> Self652 pub fn new(min: u16, max: u16, alignment: u8, length: u8) -> Self {
653 IO {
654 min,
655 max,
656 alignment,
657 length,
658 }
659 }
660 }
661
662 impl Aml for IO {
to_aml_bytes(&self, bytes: &mut Vec<u8>)663 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
664 bytes.push(IOPORTDESC); /* IO Port Descriptor */
665 bytes.push(1); /* IODecode16 */
666 bytes.append(&mut self.min.to_le_bytes().to_vec());
667 bytes.append(&mut self.max.to_le_bytes().to_vec());
668 bytes.push(self.alignment);
669 bytes.push(self.length);
670 }
671 }
672
673 /// Interrupt resouce object with the interrupt characters.
674 pub struct Interrupt {
675 consumer: bool,
676 edge_triggered: bool,
677 active_low: bool,
678 shared: bool,
679 number: u32,
680 }
681
682 impl Interrupt {
683 /// Create Interrupt object
new( consumer: bool, edge_triggered: bool, active_low: bool, shared: bool, number: u32, ) -> Self684 pub fn new(
685 consumer: bool,
686 edge_triggered: bool,
687 active_low: bool,
688 shared: bool,
689 number: u32,
690 ) -> Self {
691 Interrupt {
692 consumer,
693 edge_triggered,
694 active_low,
695 shared,
696 number,
697 }
698 }
699 }
700
701 impl Aml for Interrupt {
to_aml_bytes(&self, bytes: &mut Vec<u8>)702 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
703 bytes.push(EXTIRQDESC); /* Extended IRQ Descriptor */
704 bytes.append(&mut 6u16.to_le_bytes().to_vec());
705 let flags = (self.shared as u8) << 3
706 | (self.active_low as u8) << 2
707 | (self.edge_triggered as u8) << 1
708 | self.consumer as u8;
709 bytes.push(flags);
710 bytes.push(1u8); /* count */
711 bytes.append(&mut self.number.to_le_bytes().to_vec());
712 }
713 }
714
715 /// Device object with its device name and children objects in it.
716 pub struct Device<'a> {
717 path: Path,
718 children: Vec<&'a dyn Aml>,
719 }
720
721 impl<'a> Aml for Device<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)722 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
723 let mut bytes = Vec::new();
724 self.path.to_aml_bytes(&mut bytes);
725 for child in &self.children {
726 child.to_aml_bytes(&mut bytes);
727 }
728
729 let mut pkg_length = create_pkg_length(&bytes, true);
730 pkg_length.reverse();
731 for byte in pkg_length {
732 bytes.insert(0, byte);
733 }
734
735 bytes.insert(0, DEVICEOP); /* DeviceOp */
736 bytes.insert(0, EXTOPPREFIX); /* ExtOpPrefix */
737 aml.append(&mut bytes)
738 }
739 }
740
741 impl<'a> Device<'a> {
742 /// Create Device object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self743 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
744 Device { path, children }
745 }
746 }
747
748 /// Scope object with its name and children objects in it.
749 pub struct Scope<'a> {
750 path: Path,
751 children: Vec<&'a dyn Aml>,
752 }
753
754 impl<'a> Aml for Scope<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)755 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
756 let mut bytes = Vec::new();
757 self.path.to_aml_bytes(&mut bytes);
758 for child in &self.children {
759 child.to_aml_bytes(&mut bytes);
760 }
761
762 let mut pkg_length = create_pkg_length(&bytes, true);
763 pkg_length.reverse();
764 for byte in pkg_length {
765 bytes.insert(0, byte);
766 }
767
768 bytes.insert(0, SCOPEOP);
769 aml.append(&mut bytes)
770 }
771 }
772
773 impl<'a> Scope<'a> {
774 /// Create Scope object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self775 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
776 Scope { path, children }
777 }
778
779 /// Create raw bytes representing a Scope from its children in raw bytes
raw(path: Path, mut children: Vec<u8>) -> Vec<u8>780 pub fn raw(path: Path, mut children: Vec<u8>) -> Vec<u8> {
781 let mut bytes = Vec::new();
782 path.to_aml_bytes(&mut bytes);
783 bytes.append(&mut children);
784 let mut pkg_length = create_pkg_length(&bytes, true);
785 pkg_length.reverse();
786 for byte in pkg_length {
787 bytes.insert(0, byte);
788 }
789 bytes.insert(0, SCOPEOP);
790 bytes
791 }
792 }
793
794 /// Method object with its name, children objects, arguments and serialized character.
795 pub struct Method<'a> {
796 path: Path,
797 children: Vec<&'a dyn Aml>,
798 args: u8,
799 serialized: bool,
800 }
801
802 impl<'a> Method<'a> {
803 /// Create Method object.
new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self804 pub fn new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self {
805 Method {
806 path,
807 children,
808 args,
809 serialized,
810 }
811 }
812 }
813
814 impl<'a> Aml for Method<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)815 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
816 let mut bytes = Vec::new();
817 self.path.to_aml_bytes(&mut bytes);
818 let flags: u8 = (self.args & 0x7) | (self.serialized as u8) << 3;
819 bytes.push(flags);
820 for child in &self.children {
821 child.to_aml_bytes(&mut bytes);
822 }
823
824 let mut pkg_length = create_pkg_length(&bytes, true);
825 pkg_length.reverse();
826 for byte in pkg_length {
827 bytes.insert(0, byte);
828 }
829
830 bytes.insert(0, METHODOP);
831 aml.append(&mut bytes)
832 }
833 }
834
835 /// FieldAccessType defines the field accessing types.
836 #[derive(Clone, Copy)]
837 pub enum FieldAccessType {
838 Any,
839 Byte,
840 Word,
841 DWord,
842 QWord,
843 Buffer,
844 }
845
846 /// FieldLockRule defines the rules whether to use the Global Lock.
847 #[derive(Clone, Copy)]
848 pub enum FieldLockRule {
849 NoLock = 0,
850 Lock = 1,
851 }
852
853 /// FieldUpdateRule defines the rules to update the field.
854 #[derive(Clone, Copy)]
855 pub enum FieldUpdateRule {
856 Preserve = 0,
857 WriteAsOnes = 1,
858 WriteAsZeroes = 2,
859 }
860
861 /// FieldEntry defines the field entry.
862 pub enum FieldEntry {
863 Named([u8; 4], usize),
864 Reserved(usize),
865 }
866
867 /// Field object with the region name, field entries, access type and update rules.
868 pub struct Field {
869 path: Path,
870
871 fields: Vec<FieldEntry>,
872 access_type: FieldAccessType,
873 lock_rule: FieldLockRule,
874 update_rule: FieldUpdateRule,
875 }
876
877 impl Field {
878 /// Create Field object
new( path: Path, access_type: FieldAccessType, lock_rule: FieldLockRule, update_rule: FieldUpdateRule, fields: Vec<FieldEntry>, ) -> Self879 pub fn new(
880 path: Path,
881 access_type: FieldAccessType,
882 lock_rule: FieldLockRule,
883 update_rule: FieldUpdateRule,
884 fields: Vec<FieldEntry>,
885 ) -> Self {
886 Field {
887 path,
888 access_type,
889 lock_rule,
890 update_rule,
891 fields,
892 }
893 }
894 }
895
896 impl Aml for Field {
to_aml_bytes(&self, aml: &mut Vec<u8>)897 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
898 let mut bytes = Vec::new();
899 self.path.to_aml_bytes(&mut bytes);
900
901 let flags: u8 =
902 self.access_type as u8 | (self.lock_rule as u8) << 4 | (self.update_rule as u8) << 5;
903 bytes.push(flags);
904
905 for field in self.fields.iter() {
906 match field {
907 FieldEntry::Named(name, length) => {
908 bytes.extend_from_slice(name);
909 bytes.append(&mut create_pkg_length(&vec![0; *length], false));
910 }
911 FieldEntry::Reserved(length) => {
912 bytes.push(0x0);
913 bytes.append(&mut create_pkg_length(&vec![0; *length], false));
914 }
915 }
916 }
917
918 let mut pkg_length = create_pkg_length(&bytes, true);
919 pkg_length.reverse();
920 for byte in pkg_length {
921 bytes.insert(0, byte);
922 }
923
924 bytes.insert(0, FIELDOP);
925 bytes.insert(0, EXTOPPREFIX);
926 aml.append(&mut bytes)
927 }
928 }
929
930 /// The space type for OperationRegion object
931 #[derive(Clone, Copy)]
932 pub enum OpRegionSpace {
933 SystemMemory,
934 SystemIO,
935 PCIConfig,
936 EmbeddedControl,
937 SMBus,
938 SystemCMOS,
939 PciBarTarget,
940 IPMI,
941 GeneralPurposeIO,
942 GenericSerialBus,
943 }
944
945 /// OperationRegion object with region name, region space type, its offset and length.
946 pub struct OpRegion<'a> {
947 path: Path,
948 space: OpRegionSpace,
949 offset: &'a dyn Aml,
950 length: &'a dyn Aml,
951 }
952
953 impl<'a> OpRegion<'a> {
954 /// Create OperationRegion object.
new(path: Path, space: OpRegionSpace, offset: &'a dyn Aml, length: &'a dyn Aml) -> Self955 pub fn new(path: Path, space: OpRegionSpace, offset: &'a dyn Aml, length: &'a dyn Aml) -> Self {
956 OpRegion {
957 path,
958 space,
959 offset,
960 length,
961 }
962 }
963 }
964
965 impl<'a> Aml for OpRegion<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)966 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
967 let mut bytes = Vec::new();
968 self.path.to_aml_bytes(&mut bytes);
969 bytes.push(self.space as u8);
970 self.offset.to_aml_bytes(&mut bytes); /* RegionOffset */
971 self.length.to_aml_bytes(&mut bytes); /* RegionLen */
972 bytes.insert(0, OPREGIONOP);
973 bytes.insert(0, EXTOPPREFIX);
974 aml.append(&mut bytes)
975 }
976 }
977
978 /// If object with the if condition(predicate) and the body presented by the if_children objects.
979 pub struct If<'a> {
980 predicate: &'a dyn Aml,
981 if_children: Vec<&'a dyn Aml>,
982 }
983
984 impl<'a> If<'a> {
985 /// Create If object.
new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self986 pub fn new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self {
987 If {
988 predicate,
989 if_children,
990 }
991 }
992 }
993
994 impl<'a> Aml for If<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)995 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
996 let mut bytes = Vec::new();
997 self.predicate.to_aml_bytes(&mut bytes);
998 for child in self.if_children.iter() {
999 child.to_aml_bytes(&mut bytes);
1000 }
1001
1002 let mut pkg_length = create_pkg_length(&bytes, true);
1003 pkg_length.reverse();
1004 for byte in pkg_length {
1005 bytes.insert(0, byte);
1006 }
1007
1008 bytes.insert(0, IFOP);
1009 aml.append(&mut bytes)
1010 }
1011 }
1012
1013 /// Else object
1014 pub struct Else<'a> {
1015 body: Vec<&'a dyn Aml>,
1016 }
1017
1018 impl<'a> Else<'a> {
1019 /// Create Else object.
new(body: Vec<&'a dyn Aml>) -> Self1020 pub fn new(body: Vec<&'a dyn Aml>) -> Self {
1021 Else { body }
1022 }
1023 }
1024
1025 impl<'a> Aml for Else<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1026 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1027 let mut bytes = Vec::new();
1028 for child in self.body.iter() {
1029 child.to_aml_bytes(&mut bytes);
1030 }
1031
1032 let mut pkg_length = create_pkg_length(&bytes, true);
1033 pkg_length.reverse();
1034 for byte in pkg_length {
1035 bytes.insert(0, byte);
1036 }
1037
1038 bytes.insert(0, ELSEOP);
1039 aml.append(&mut bytes)
1040 }
1041 }
1042
1043 macro_rules! compare_op {
1044 ($name:ident, $opcode:expr, $invert:expr) => {
1045 /// Compare object with its right part and left part, which are both ACPI Object.
1046 pub struct $name<'a> {
1047 right: &'a dyn Aml,
1048 left: &'a dyn Aml,
1049 }
1050
1051 impl<'a> $name<'a> {
1052 /// Create the compare object method.
1053 pub fn new(left: &'a dyn Aml, right: &'a dyn Aml) -> Self {
1054 $name { left, right }
1055 }
1056 }
1057
1058 impl<'a> Aml for $name<'a> {
1059 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1060 if $invert {
1061 bytes.push(LNOTOP);
1062 }
1063 bytes.push($opcode);
1064 self.left.to_aml_bytes(bytes);
1065 self.right.to_aml_bytes(bytes);
1066 }
1067 }
1068 };
1069 }
1070
1071 compare_op!(Equal, LEQUALOP, false);
1072 compare_op!(LessThan, LLESSOP, false);
1073 compare_op!(GreaterThan, LGREATEROP, false);
1074 compare_op!(NotEqual, LEQUALOP, true);
1075 compare_op!(GreaterEqual, LLESSOP, true);
1076 compare_op!(LessEqual, LGREATEROP, true);
1077
1078 /// Argx object.
1079 pub struct Arg(pub u8);
1080
1081 impl Aml for Arg {
1082 /// Per ACPI spec, there is maximum 7 Argx objects from
1083 /// Arg0 ~ Arg6. Any other Arg object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1084 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1085 assert!(self.0 <= 6);
1086 bytes.push(ARG0OP + self.0);
1087 }
1088 }
1089
1090 /// Localx object.
1091 pub struct Local(pub u8);
1092
1093 impl Aml for Local {
1094 /// Per ACPI spec, there is maximum 8 Localx objects from
1095 /// Local0 ~ Local7. Any other Local object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1096 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1097 assert!(self.0 <= 7);
1098 bytes.push(LOCAL0OP + self.0);
1099 }
1100 }
1101
1102 /// Store object with the ACPI object name which can be stored to and
1103 /// the ACPI object value which is to store.
1104 pub struct Store<'a> {
1105 name: &'a dyn Aml,
1106 value: &'a dyn Aml,
1107 }
1108
1109 impl<'a> Store<'a> {
1110 /// Create Store object.
new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self1111 pub fn new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1112 Store { name, value }
1113 }
1114 }
1115
1116 impl<'a> Aml for Store<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1117 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1118 bytes.push(STOREOP);
1119 self.value.to_aml_bytes(bytes);
1120 self.name.to_aml_bytes(bytes);
1121 }
1122 }
1123
1124 /// Mutex object with a mutex name and a synchronization level.
1125 pub struct Mutex {
1126 path: Path,
1127 sync_level: u8,
1128 }
1129
1130 impl Mutex {
1131 /// Create Mutex object.
new(path: Path, sync_level: u8) -> Self1132 pub fn new(path: Path, sync_level: u8) -> Self {
1133 Self { path, sync_level }
1134 }
1135 }
1136
1137 impl Aml for Mutex {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1138 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1139 bytes.push(EXTOPPREFIX);
1140 bytes.push(MUTEXOP);
1141 self.path.to_aml_bytes(bytes);
1142 bytes.push(self.sync_level);
1143 }
1144 }
1145
1146 /// Acquire object with a Mutex object and timeout value.
1147 pub struct Acquire {
1148 mutex: Path,
1149 timeout: u16,
1150 }
1151
1152 impl Acquire {
1153 /// Create Acquire object.
new(mutex: Path, timeout: u16) -> Self1154 pub fn new(mutex: Path, timeout: u16) -> Self {
1155 Acquire { mutex, timeout }
1156 }
1157 }
1158
1159 impl Aml for Acquire {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1160 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1161 bytes.push(EXTOPPREFIX);
1162 bytes.push(ACQUIREOP);
1163 self.mutex.to_aml_bytes(bytes);
1164 bytes.extend_from_slice(&self.timeout.to_le_bytes());
1165 }
1166 }
1167
1168 /// Release object with a Mutex object to release.
1169 pub struct Release {
1170 mutex: Path,
1171 }
1172
1173 impl Release {
1174 /// Create Release object.
new(mutex: Path) -> Self1175 pub fn new(mutex: Path) -> Self {
1176 Release { mutex }
1177 }
1178 }
1179
1180 impl Aml for Release {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1181 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1182 bytes.push(EXTOPPREFIX);
1183 bytes.push(RELEASEOP);
1184 self.mutex.to_aml_bytes(bytes);
1185 }
1186 }
1187
1188 /// Notify object with an object which is to be notified with the value.
1189 pub struct Notify<'a> {
1190 object: &'a dyn Aml,
1191 value: &'a dyn Aml,
1192 }
1193
1194 impl<'a> Notify<'a> {
1195 /// Create Notify object.
new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self1196 pub fn new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1197 Notify { object, value }
1198 }
1199 }
1200
1201 impl<'a> Aml for Notify<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1202 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1203 bytes.push(NOTIFYOP);
1204 self.object.to_aml_bytes(bytes);
1205 self.value.to_aml_bytes(bytes);
1206 }
1207 }
1208
1209 /// While object with the while condition objects(predicate) and
1210 /// the while body objects(while_children).
1211 pub struct While<'a> {
1212 predicate: &'a dyn Aml,
1213 while_children: Vec<&'a dyn Aml>,
1214 }
1215
1216 impl<'a> While<'a> {
1217 /// Create While object.
new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self1218 pub fn new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self {
1219 While {
1220 predicate,
1221 while_children,
1222 }
1223 }
1224 }
1225
1226 impl<'a> Aml for While<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1227 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1228 let mut bytes = Vec::new();
1229 self.predicate.to_aml_bytes(&mut bytes);
1230 for child in self.while_children.iter() {
1231 child.to_aml_bytes(&mut bytes);
1232 }
1233
1234 let mut pkg_length = create_pkg_length(&bytes, true);
1235 pkg_length.reverse();
1236 for byte in pkg_length {
1237 bytes.insert(0, byte);
1238 }
1239
1240 bytes.insert(0, WHILEOP);
1241 aml.append(&mut bytes)
1242 }
1243 }
1244
1245 macro_rules! object_op {
1246 ($name:ident, $opcode:expr) => {
1247 /// General operation on a object.
1248 pub struct $name<'a> {
1249 a: &'a dyn Aml,
1250 }
1251
1252 impl<'a> $name<'a> {
1253 /// Create the object method.
1254 pub fn new(a: &'a dyn Aml) -> Self {
1255 $name { a }
1256 }
1257 }
1258
1259 impl<'a> Aml for $name<'a> {
1260 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1261 bytes.push($opcode);
1262 self.a.to_aml_bytes(bytes);
1263 }
1264 }
1265 };
1266 }
1267
1268 object_op!(ObjectType, OBJECTTYPEOP);
1269 object_op!(SizeOf, SIZEOFOP);
1270 object_op!(Return, RETURNOP);
1271 object_op!(DeRefOf, DEREFOFOP);
1272
1273 macro_rules! binary_op {
1274 ($name:ident, $opcode:expr) => {
1275 /// General operation object with the operator a/b and a target.
1276 pub struct $name<'a> {
1277 a: &'a dyn Aml,
1278 b: &'a dyn Aml,
1279 target: &'a dyn Aml,
1280 }
1281
1282 impl<'a> $name<'a> {
1283 /// Create the object.
1284 pub fn new(target: &'a dyn Aml, a: &'a dyn Aml, b: &'a dyn Aml) -> Self {
1285 $name { target, a, b }
1286 }
1287 }
1288
1289 impl<'a> Aml for $name<'a> {
1290 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1291 bytes.push($opcode); /* Op for the binary operator */
1292 self.a.to_aml_bytes(bytes);
1293 self.b.to_aml_bytes(bytes);
1294 self.target.to_aml_bytes(bytes);
1295 }
1296 }
1297 };
1298 }
1299
1300 binary_op!(Add, ADDOP);
1301 binary_op!(Concat, CONCATOP);
1302 binary_op!(Subtract, SUBTRACTOP);
1303 binary_op!(Multiply, MULTIPLYOP);
1304 binary_op!(ShiftLeft, SHIFTLEFTOP);
1305 binary_op!(ShiftRight, SHIFTRIGHTOP);
1306 binary_op!(And, ANDOP);
1307 binary_op!(Nand, NANDOP);
1308 binary_op!(Or, OROP);
1309 binary_op!(Nor, NOROP);
1310 binary_op!(Xor, XOROP);
1311 binary_op!(ConcatRes, CONCATRESOP);
1312 binary_op!(Mod, MODOP);
1313 binary_op!(Index, INDEXOP);
1314 binary_op!(ToString, TOSTRINGOP);
1315 binary_op!(CreateDWordField, CREATEDWFIELDOP);
1316 binary_op!(CreateQWordField, CREATEQWFIELDOP);
1317
1318 macro_rules! convert_op {
1319 ($name:ident, $opcode:expr) => {
1320 /// General operation object with the operator a/b and a target.
1321 pub struct $name<'a> {
1322 a: &'a dyn Aml,
1323 target: &'a dyn Aml,
1324 }
1325
1326 impl<'a> $name<'a> {
1327 /// Create the object.
1328 pub fn new(target: &'a dyn Aml, a: &'a dyn Aml) -> Self {
1329 $name { target, a }
1330 }
1331 }
1332
1333 impl<'a> Aml for $name<'a> {
1334 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1335 bytes.push($opcode); /* Op for the binary operator */
1336 self.a.to_aml_bytes(bytes);
1337 self.target.to_aml_bytes(bytes);
1338 }
1339 }
1340 };
1341 }
1342
1343 convert_op!(ToBuffer, TOBUFFEROP);
1344 convert_op!(ToInteger, TOINTEGEROP);
1345
1346 /// Create Field Object.
1347 pub struct CreateField<'a> {
1348 name_string: &'a dyn Aml,
1349 source: &'a dyn Aml,
1350 bit_index: &'a dyn Aml,
1351 bit_num: &'a dyn Aml,
1352 }
1353
1354 impl<'a> CreateField<'a> {
new( name_string: &'a dyn Aml, source: &'a dyn Aml, bit_index: &'a dyn Aml, bit_num: &'a dyn Aml, ) -> Self1355 pub fn new(
1356 name_string: &'a dyn Aml,
1357 source: &'a dyn Aml,
1358 bit_index: &'a dyn Aml,
1359 bit_num: &'a dyn Aml,
1360 ) -> Self {
1361 CreateField {
1362 name_string,
1363 source,
1364 bit_index,
1365 bit_num,
1366 }
1367 }
1368 }
1369
1370 impl<'a> Aml for CreateField<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1371 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1372 bytes.push(EXTOPPREFIX);
1373 bytes.push(CREATEFIELDOP);
1374 self.source.to_aml_bytes(bytes);
1375 self.bit_index.to_aml_bytes(bytes);
1376 self.bit_num.to_aml_bytes(bytes);
1377 self.name_string.to_aml_bytes(bytes);
1378 }
1379 }
1380
1381 /// Mid object with the source, index, length, and result objects.
1382 pub struct Mid<'a> {
1383 source: &'a dyn Aml,
1384 index: &'a dyn Aml,
1385 length: &'a dyn Aml,
1386 result: &'a dyn Aml,
1387 }
1388
1389 impl<'a> Mid<'a> {
new( source: &'a dyn Aml, index: &'a dyn Aml, length: &'a dyn Aml, result: &'a dyn Aml, ) -> Self1390 pub fn new(
1391 source: &'a dyn Aml,
1392 index: &'a dyn Aml,
1393 length: &'a dyn Aml,
1394 result: &'a dyn Aml,
1395 ) -> Self {
1396 Mid {
1397 source,
1398 index,
1399 length,
1400 result,
1401 }
1402 }
1403 }
1404
1405 impl<'a> Aml for Mid<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1406 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1407 bytes.push(MIDOP);
1408 self.source.to_aml_bytes(bytes);
1409 self.index.to_aml_bytes(bytes);
1410 self.length.to_aml_bytes(bytes);
1411 self.result.to_aml_bytes(bytes);
1412 }
1413 }
1414
1415 /// MethodCall object with the method name and parameter objects.
1416 pub struct MethodCall<'a> {
1417 name: Path,
1418 args: Vec<&'a dyn Aml>,
1419 }
1420
1421 impl<'a> MethodCall<'a> {
1422 /// Create MethodCall object.
new(name: Path, args: Vec<&'a dyn Aml>) -> Self1423 pub fn new(name: Path, args: Vec<&'a dyn Aml>) -> Self {
1424 MethodCall { name, args }
1425 }
1426 }
1427
1428 impl<'a> Aml for MethodCall<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1429 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1430 self.name.to_aml_bytes(bytes);
1431 for arg in self.args.iter() {
1432 arg.to_aml_bytes(bytes);
1433 }
1434 }
1435 }
1436
1437 /// Buffer object with the TermArg in it.
1438 pub struct BufferTerm<'a> {
1439 data: &'a dyn Aml,
1440 }
1441
1442 impl<'a> BufferTerm<'a> {
1443 /// Create BufferTerm object.
new(data: &'a dyn Aml) -> Self1444 pub fn new(data: &'a dyn Aml) -> Self {
1445 BufferTerm { data }
1446 }
1447 }
1448
1449 impl<'a> Aml for BufferTerm<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1450 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1451 let mut bytes = Vec::new();
1452 self.data.to_aml_bytes(&mut bytes);
1453
1454 let mut pkg_length = create_pkg_length(&bytes, true);
1455 pkg_length.reverse();
1456 for byte in pkg_length {
1457 bytes.insert(0, byte);
1458 }
1459
1460 bytes.insert(0, BUFFEROP);
1461
1462 aml.append(&mut bytes)
1463 }
1464 }
1465
1466 /// Buffer object with the data in it.
1467 pub struct BufferData {
1468 data: Vec<u8>,
1469 }
1470
1471 impl BufferData {
1472 /// Create BufferData object.
new(data: Vec<u8>) -> Self1473 pub fn new(data: Vec<u8>) -> Self {
1474 BufferData { data }
1475 }
1476 }
1477
1478 impl Aml for BufferData {
to_aml_bytes(&self, aml: &mut Vec<u8>)1479 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1480 let mut bytes = Vec::new();
1481 self.data.len().to_aml_bytes(&mut bytes);
1482 bytes.extend_from_slice(&self.data);
1483
1484 let mut pkg_length = create_pkg_length(&bytes, true);
1485 pkg_length.reverse();
1486 for byte in pkg_length {
1487 bytes.insert(0, byte);
1488 }
1489
1490 bytes.insert(0, BUFFEROP);
1491
1492 aml.append(&mut bytes)
1493 }
1494 }
1495
1496 pub struct Uuid {
1497 name: BufferData,
1498 }
1499
hex2byte(v1: char, v2: char) -> u81500 fn hex2byte(v1: char, v2: char) -> u8 {
1501 let hi = v1.to_digit(16).unwrap() as u8;
1502 assert!(hi <= 15);
1503 let lo = v2.to_digit(16).unwrap() as u8;
1504 assert!(lo <= 15);
1505
1506 (hi << 4) | lo
1507 }
1508
1509 impl Uuid {
1510 // Create Uuid object
1511 // eg. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
new(name: &str) -> Self1512 pub fn new(name: &str) -> Self {
1513 let name_vec: Vec<char> = name.chars().collect();
1514 let mut data = Vec::new();
1515
1516 assert_eq!(name_vec.len(), 36);
1517 assert_eq!(name_vec[8], '-');
1518 assert_eq!(name_vec[13], '-');
1519 assert_eq!(name_vec[18], '-');
1520 assert_eq!(name_vec[23], '-');
1521
1522 // dd - at offset 00
1523 data.push(hex2byte(name_vec[6], name_vec[7]));
1524 // cc - at offset 01
1525 data.push(hex2byte(name_vec[4], name_vec[5]));
1526 // bb - at offset 02
1527 data.push(hex2byte(name_vec[2], name_vec[3]));
1528 // aa - at offset 03
1529 data.push(hex2byte(name_vec[0], name_vec[1]));
1530
1531 // ff - at offset 04
1532 data.push(hex2byte(name_vec[11], name_vec[12]));
1533 // ee - at offset 05
1534 data.push(hex2byte(name_vec[9], name_vec[10]));
1535
1536 // hh - at offset 06
1537 data.push(hex2byte(name_vec[16], name_vec[17]));
1538 // gg - at offset 07
1539 data.push(hex2byte(name_vec[14], name_vec[15]));
1540
1541 // ii - at offset 08
1542 data.push(hex2byte(name_vec[19], name_vec[20]));
1543 // jj - at offset 09
1544 data.push(hex2byte(name_vec[21], name_vec[22]));
1545
1546 // kk - at offset 10
1547 data.push(hex2byte(name_vec[24], name_vec[25]));
1548 // ll - at offset 11
1549 data.push(hex2byte(name_vec[26], name_vec[27]));
1550 // mm - at offset 12
1551 data.push(hex2byte(name_vec[28], name_vec[29]));
1552 // nn - at offset 13
1553 data.push(hex2byte(name_vec[30], name_vec[31]));
1554 // oo - at offset 14
1555 data.push(hex2byte(name_vec[32], name_vec[33]));
1556 // pp - at offset 15
1557 data.push(hex2byte(name_vec[34], name_vec[35]));
1558
1559 Uuid {
1560 name: BufferData::new(data),
1561 }
1562 }
1563 }
1564
1565 impl Aml for Uuid {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1566 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1567 self.name.to_aml_bytes(bytes)
1568 }
1569 }
1570
1571 /// Power Resource object. 'children' represents Power Resource method.
1572 pub struct PowerResource<'a> {
1573 name: Path,
1574 level: u8,
1575 order: u16,
1576 children: Vec<&'a dyn Aml>,
1577 }
1578
1579 impl<'a> PowerResource<'a> {
1580 /// Create Power Resouce object
new(name: Path, level: u8, order: u16, children: Vec<&'a dyn Aml>) -> Self1581 pub fn new(name: Path, level: u8, order: u16, children: Vec<&'a dyn Aml>) -> Self {
1582 PowerResource {
1583 name,
1584 level,
1585 order,
1586 children,
1587 }
1588 }
1589 }
1590
1591 impl<'a> Aml for PowerResource<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1592 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1593 let mut bytes = Vec::new();
1594
1595 // Add name string
1596 self.name.to_aml_bytes(&mut bytes);
1597 // Add system level
1598 bytes.push(self.level);
1599 // Add Resource Order
1600 let orders = self.order.to_le_bytes();
1601 bytes.push(orders[0]);
1602 bytes.push(orders[1]);
1603 // Add child data
1604 for child in &self.children {
1605 child.to_aml_bytes(&mut bytes);
1606 }
1607
1608 // PkgLength
1609 let mut pkg_length = create_pkg_length(&bytes, true);
1610 pkg_length.reverse();
1611 for byte in pkg_length {
1612 bytes.insert(0, byte);
1613 }
1614
1615 bytes.insert(0, POWERRESOURCEOP);
1616 bytes.insert(0, EXTOPPREFIX);
1617
1618 aml.append(&mut bytes);
1619 }
1620 }
1621
1622 #[cfg(test)]
1623 mod tests {
1624 use super::*;
1625
1626 #[test]
test_device()1627 fn test_device() {
1628 /*
1629 Device (_SB.COM1)
1630 {
1631 Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */) // _HID: Hardware ID
1632 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1633 {
1634 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1635 {
1636 0x00000004,
1637 }
1638 IO (Decode16,
1639 0x03F8, // Range Minimum
1640 0x03F8, // Range Maximum
1641 0x00, // Alignment
1642 0x08, // Length
1643 )
1644 }
1645 }
1646 */
1647 let com1_device = [
1648 0x5B, 0x82, 0x30, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31, 0x08, 0x5F,
1649 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01, 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11,
1650 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01, 0x04, 0x00, 0x00, 0x00, 0x47, 0x01,
1651 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1652 ];
1653 let mut aml = Vec::new();
1654
1655 Device::new(
1656 "_SB_.COM1".into(),
1657 vec![
1658 &Name::new("_HID".into(), &EISAName::new("PNP0501")),
1659 &Name::new(
1660 "_CRS".into(),
1661 &ResourceTemplate::new(vec![
1662 &Interrupt::new(true, true, false, false, 4),
1663 &IO::new(0x3f8, 0x3f8, 0, 0x8),
1664 ]),
1665 ),
1666 ],
1667 )
1668 .to_aml_bytes(&mut aml);
1669 assert_eq!(aml, &com1_device[..]);
1670 }
1671
1672 #[test]
test_scope()1673 fn test_scope() {
1674 /*
1675 Scope (_SB.MBRD)
1676 {
1677 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1678 {
1679 Memory32Fixed (ReadWrite,
1680 0xE8000000, // Address Base
1681 0x10000000, // Address Length
1682 )
1683 })
1684 }
1685 */
1686
1687 let mbrd_scope = [
1688 0x10, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x42, 0x52, 0x44, 0x08, 0x5F, 0x43,
1689 0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE8,
1690 0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1691 ];
1692 let mut aml = Vec::new();
1693
1694 Scope::new(
1695 "_SB_.MBRD".into(),
1696 vec![&Name::new(
1697 "_CRS".into(),
1698 &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1699 )],
1700 )
1701 .to_aml_bytes(&mut aml);
1702 assert_eq!(aml, &mbrd_scope[..]);
1703 }
1704
1705 #[test]
test_resource_template()1706 fn test_resource_template() {
1707 /*
1708 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1709 {
1710 Memory32Fixed (ReadWrite,
1711 0xE8000000, // Address Base
1712 0x10000000, // Address Length
1713 )
1714 })
1715 */
1716 let crs_memory_32_fixed = [
1717 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00,
1718 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1719 ];
1720 let mut aml = Vec::new();
1721
1722 Name::new(
1723 "_CRS".into(),
1724 &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1725 )
1726 .to_aml_bytes(&mut aml);
1727 assert_eq!(aml, crs_memory_32_fixed);
1728
1729 /*
1730 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1731 {
1732 WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
1733 0x0000, // Granularity
1734 0x0000, // Range Minimum
1735 0x00FF, // Range Maximum
1736 0x0000, // Translation Offset
1737 0x0100, // Length
1738 ,, )
1739 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1740 0x0000, // Granularity
1741 0x0000, // Range Minimum
1742 0x0CF7, // Range Maximum
1743 0x0000, // Translation Offset
1744 0x0CF8, // Length
1745 ,, , TypeStatic, DenseTranslation)
1746 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1747 0x0000, // Granularity
1748 0x0D00, // Range Minimum
1749 0xFFFF, // Range Maximum
1750 0x0000, // Translation Offset
1751 0xF300, // Length
1752 ,, , TypeStatic, DenseTranslation)
1753 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1754 0x00000000, // Granularity
1755 0x000A0000, // Range Minimum
1756 0x000BFFFF, // Range Maximum
1757 0x00000000, // Translation Offset
1758 0x00020000, // Length
1759 ,, , AddressRangeMemory, TypeStatic)
1760 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
1761 0x00000000, // Granularity
1762 0xC0000000, // Range Minimum
1763 0xFEBFFFFF, // Range Maximum
1764 0x00000000, // Translation Offset
1765 0x3EC00000, // Length
1766 ,, , AddressRangeMemory, TypeStatic)
1767 QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1768 0x0000000000000000, // Granularity
1769 0x0000000800000000, // Range Minimum
1770 0x0000000FFFFFFFFF, // Range Maximum
1771 0x0000000000000000, // Translation Offset
1772 0x0000000800000000, // Length
1773 ,, , AddressRangeMemory, TypeStatic)
1774 })
1775 */
1776
1777 // WordBusNumber from above
1778 let crs_word_bus_number = [
1779 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x15, 0x0A, 0x12, 0x88, 0x0D, 0x00, 0x02, 0x0C,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x79, 0x00,
1781 ];
1782 aml.clear();
1783
1784 Name::new(
1785 "_CRS".into(),
1786 &ResourceTemplate::new(vec![&AddressSpace::new_bus_number(0x0u16, 0xffu16)]),
1787 )
1788 .to_aml_bytes(&mut aml);
1789 assert_eq!(aml, &crs_word_bus_number);
1790
1791 // WordIO blocks (x 2) from above
1792 let crs_word_io = [
1793 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x25, 0x0A, 0x22, 0x88, 0x0D, 0x00, 0x01, 0x0C,
1794 0x03, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0C, 0x00, 0x00, 0xF8, 0x0C, 0x88, 0x0D, 0x00,
1795 0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF3, 0x79,
1796 0x00,
1797 ];
1798 aml.clear();
1799
1800 Name::new(
1801 "_CRS".into(),
1802 &ResourceTemplate::new(vec![
1803 &AddressSpace::new_io(0x0u16, 0xcf7u16),
1804 &AddressSpace::new_io(0xd00u16, 0xffffu16),
1805 ]),
1806 )
1807 .to_aml_bytes(&mut aml);
1808 assert_eq!(aml, &crs_word_io[..]);
1809
1810 // DWordMemory blocks (x 2) from above
1811 let crs_dword_memory = [
1812 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x39, 0x0A, 0x36, 0x87, 0x17, 0x00, 0x00, 0x0C,
1813 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xFF, 0xFF, 0x0B, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x87, 0x17, 0x00, 0x00, 0x0C, 0x01, 0x00,
1815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xBF, 0xFE, 0x00, 0x00, 0x00,
1816 0x00, 0x00, 0x00, 0xC0, 0x3E, 0x79, 0x00,
1817 ];
1818 aml.clear();
1819
1820 Name::new(
1821 "_CRS".into(),
1822 &ResourceTemplate::new(vec![
1823 &AddressSpace::new_memory(
1824 AddressSpaceCachable::Cacheable,
1825 true,
1826 0xa_0000u32,
1827 0xb_ffffu32,
1828 ),
1829 &AddressSpace::new_memory(
1830 AddressSpaceCachable::NotCacheable,
1831 true,
1832 0xc000_0000u32,
1833 0xfebf_ffffu32,
1834 ),
1835 ]),
1836 )
1837 .to_aml_bytes(&mut aml);
1838 assert_eq!(aml, &crs_dword_memory[..]);
1839
1840 // QWordMemory from above
1841 let crs_qword_memory = [
1842 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x33, 0x0A, 0x30, 0x8A, 0x2B, 0x00, 0x00, 0x0C,
1843 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1844 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x79,
1846 0x00,
1847 ];
1848 aml.clear();
1849 Name::new(
1850 "_CRS".into(),
1851 &ResourceTemplate::new(vec![&AddressSpace::new_memory(
1852 AddressSpaceCachable::Cacheable,
1853 true,
1854 0x8_0000_0000u64,
1855 0xf_ffff_ffffu64,
1856 )]),
1857 )
1858 .to_aml_bytes(&mut aml);
1859
1860 assert_eq!(aml, &crs_qword_memory[..]);
1861
1862 /*
1863 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1864 {
1865 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1866 {
1867 0x00000004,
1868 }
1869 IO (Decode16,
1870 0x03F8, // Range Minimum
1871 0x03F8, // Range Maximum
1872 0x00, // Alignment
1873 0x08, // Length
1874 )
1875 })
1876
1877 */
1878 let interrupt_io_data = [
1879 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01,
1880 0x04, 0x00, 0x00, 0x00, 0x47, 0x01, 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1881 ];
1882 aml.clear();
1883 Name::new(
1884 "_CRS".into(),
1885 &ResourceTemplate::new(vec![
1886 &Interrupt::new(true, true, false, false, 4),
1887 &IO::new(0x3f8, 0x3f8, 0, 0x8),
1888 ]),
1889 )
1890 .to_aml_bytes(&mut aml);
1891
1892 assert_eq!(aml, &interrupt_io_data[..]);
1893 }
1894
1895 #[test]
test_pkg_length()1896 fn test_pkg_length() {
1897 assert_eq!(create_pkg_length(&[0u8; 62], true), vec![63]);
1898 assert_eq!(
1899 create_pkg_length(&[0u8; 64], true),
1900 vec![1 << 6 | (66 & 0xf), 66 >> 4]
1901 );
1902 assert_eq!(
1903 create_pkg_length(&[0u8; 4096], true),
1904 vec![
1905 2 << 6 | (4099 & 0xf) as u8,
1906 (4099 >> 4) as u8,
1907 (4099 >> 12) as u8
1908 ]
1909 );
1910 }
1911
1912 #[test]
test_package()1913 fn test_package() {
1914 /*
1915 Name (_S5, Package (0x01) // _S5_: S5 System State
1916 {
1917 0x05
1918 })
1919 */
1920 let s5_sleep_data = [0x08, 0x5F, 0x53, 0x35, 0x5F, 0x12, 0x04, 0x01, 0x0A, 0x05];
1921 let mut aml = Vec::new();
1922
1923 Name::new("_S5_".into(), &Package::new(vec![&5u8])).to_aml_bytes(&mut aml);
1924
1925 assert_eq!(s5_sleep_data.to_vec(), aml);
1926 }
1927
1928 #[test]
test_eisa_name()1929 fn test_eisa_name() {
1930 let mut aml = Vec::new();
1931 Name::new("_HID".into(), &EISAName::new("PNP0501")).to_aml_bytes(&mut aml);
1932 assert_eq!(
1933 aml,
1934 [0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01],
1935 )
1936 }
1937 #[test]
test_name_path()1938 fn test_name_path() {
1939 let mut aml = Vec::new();
1940 (&"_SB_".into() as &Path).to_aml_bytes(&mut aml);
1941 assert_eq!(aml, [0x5Fu8, 0x53, 0x42, 0x5F]);
1942 aml.clear();
1943 (&"\\_SB_".into() as &Path).to_aml_bytes(&mut aml);
1944 assert_eq!(aml, [0x5C, 0x5F, 0x53, 0x42, 0x5F]);
1945 aml.clear();
1946 (&"_SB_.COM1".into() as &Path).to_aml_bytes(&mut aml);
1947 assert_eq!(aml, [0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31]);
1948 aml.clear();
1949 (&"_SB_.PCI0._HID".into() as &Path).to_aml_bytes(&mut aml);
1950 assert_eq!(
1951 aml,
1952 [0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x48, 0x49, 0x44]
1953 );
1954 }
1955
1956 #[test]
test_numbers()1957 fn test_numbers() {
1958 let mut aml = Vec::new();
1959 128u8.to_aml_bytes(&mut aml);
1960 assert_eq!(aml, [0x0a, 0x80]);
1961 aml.clear();
1962 1024u16.to_aml_bytes(&mut aml);
1963 assert_eq!(aml, [0x0b, 0x0, 0x04]);
1964 aml.clear();
1965 (16u32 << 20).to_aml_bytes(&mut aml);
1966 assert_eq!(aml, [0x0c, 0x00, 0x00, 0x0, 0x01]);
1967 aml.clear();
1968 0xdeca_fbad_deca_fbadu64.to_aml_bytes(&mut aml);
1969 assert_eq!(aml, [0x0e, 0xad, 0xfb, 0xca, 0xde, 0xad, 0xfb, 0xca, 0xde]);
1970 aml.clear();
1971
1972 // u8
1973 0x00_u8.to_aml_bytes(&mut aml);
1974 assert_eq!(aml, [0x00]);
1975 aml.clear();
1976 0x01_u8.to_aml_bytes(&mut aml);
1977 assert_eq!(aml, [0x01]);
1978 aml.clear();
1979 0x86_u8.to_aml_bytes(&mut aml);
1980 assert_eq!(aml, [0x0a, 0x86]);
1981 aml.clear();
1982
1983 // u16
1984 0x00_u16.to_aml_bytes(&mut aml);
1985 assert_eq!(aml, [0x00]);
1986 aml.clear();
1987 0x01_u16.to_aml_bytes(&mut aml);
1988 assert_eq!(aml, [0x01]);
1989 aml.clear();
1990 0x86_u16.to_aml_bytes(&mut aml);
1991 assert_eq!(aml, [0x0a, 0x86]);
1992 aml.clear();
1993 0xF00D_u16.to_aml_bytes(&mut aml);
1994 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
1995 aml.clear();
1996
1997 // u32
1998 0x00_u32.to_aml_bytes(&mut aml);
1999 assert_eq!(aml, [0x00]);
2000 aml.clear();
2001 0x01_u32.to_aml_bytes(&mut aml);
2002 assert_eq!(aml, [0x01]);
2003 aml.clear();
2004 0x86_u32.to_aml_bytes(&mut aml);
2005 assert_eq!(aml, [0x0a, 0x86]);
2006 aml.clear();
2007 0xF00D_u32.to_aml_bytes(&mut aml);
2008 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
2009 aml.clear();
2010 0xDECAF_u32.to_aml_bytes(&mut aml);
2011 assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
2012 aml.clear();
2013
2014 // u64
2015 0x00_u64.to_aml_bytes(&mut aml);
2016 assert_eq!(aml, [0x00]);
2017 aml.clear();
2018 0x01_u64.to_aml_bytes(&mut aml);
2019 assert_eq!(aml, [0x01]);
2020 aml.clear();
2021 0x86_u64.to_aml_bytes(&mut aml);
2022 assert_eq!(aml, [0x0a, 0x86]);
2023 aml.clear();
2024 0xF00D_u64.to_aml_bytes(&mut aml);
2025 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
2026 aml.clear();
2027 0xDECAF_u64.to_aml_bytes(&mut aml);
2028 assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
2029 aml.clear();
2030 0xDECAFC0FFEE_u64.to_aml_bytes(&mut aml);
2031 assert_eq!(aml, [0x0e, 0xee, 0xff, 0xc0, 0xaf, 0xec, 0x0d, 0x00, 0x00]);
2032 aml.clear();
2033
2034 // usize
2035 0x00_usize.to_aml_bytes(&mut aml);
2036 assert_eq!(aml, [0x00]);
2037 aml.clear();
2038 0x01_usize.to_aml_bytes(&mut aml);
2039 assert_eq!(aml, [0x01]);
2040 aml.clear();
2041 0x86_usize.to_aml_bytes(&mut aml);
2042 assert_eq!(aml, [0x0a, 0x86]);
2043 aml.clear();
2044 0xF00D_usize.to_aml_bytes(&mut aml);
2045 assert_eq!(aml, [0x0b, 0x0d, 0xf0]);
2046 aml.clear();
2047 0xDECAF_usize.to_aml_bytes(&mut aml);
2048 assert_eq!(aml, [0x0c, 0xaf, 0xec, 0x0d, 0x00]);
2049 aml.clear();
2050 #[cfg(target_pointer_width = "64")]
2051 {
2052 0xDECAFC0FFEE_usize.to_aml_bytes(&mut aml);
2053 assert_eq!(aml, [0x0e, 0xee, 0xff, 0xc0, 0xaf, 0xec, 0x0d, 0x00, 0x00]);
2054 aml.clear();
2055 }
2056 }
2057
2058 #[test]
test_name()2059 fn test_name() {
2060 let mut aml = Vec::new();
2061 Name::new("_SB_.PCI0._UID".into(), &0x1234u16).to_aml_bytes(&mut aml);
2062 assert_eq!(
2063 aml,
2064 [
2065 0x08, /* NameOp */
2066 0x2F, /* MultiNamePrefix */
2067 0x03, /* 3 name parts */
2068 0x5F, 0x53, 0x42, 0x5F, /* _SB_ */
2069 0x50, 0x43, 0x49, 0x30, /* PCI0 */
2070 0x5F, 0x55, 0x49, 0x44, /* _UID */
2071 0x0b, /* WordPrefix */
2072 0x34, 0x12
2073 ]
2074 );
2075 }
2076
2077 #[test]
test_string()2078 fn test_string() {
2079 let mut aml = Vec::new();
2080 (&"ACPI" as &dyn Aml).to_aml_bytes(&mut aml);
2081 assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
2082 aml.clear();
2083 "ACPI".to_owned().to_aml_bytes(&mut aml);
2084 assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
2085 }
2086
2087 #[test]
test_method()2088 fn test_method() {
2089 let mut aml = Vec::new();
2090 Method::new("_STA".into(), 0, false, vec![&Return::new(&0xfu8)]).to_aml_bytes(&mut aml);
2091 assert_eq!(
2092 aml,
2093 [0x14, 0x09, 0x5F, 0x53, 0x54, 0x41, 0x00, 0xA4, 0x0A, 0x0F]
2094 );
2095 }
2096
2097 #[test]
test_field()2098 fn test_field() {
2099 /*
2100 Field (PRST, ByteAcc, NoLock, WriteAsZeros)
2101 {
2102 Offset (0x04),
2103 CPEN, 1,
2104 CINS, 1,
2105 CRMV, 1,
2106 CEJ0, 1,
2107 Offset (0x05),
2108 CCMD, 8
2109 }
2110
2111 */
2112
2113 let field_data = [
2114 0x5Bu8, 0x81, 0x23, 0x50, 0x52, 0x53, 0x54, 0x41, 0x00, 0x20, 0x43, 0x50, 0x45, 0x4E,
2115 0x01, 0x43, 0x49, 0x4E, 0x53, 0x01, 0x43, 0x52, 0x4D, 0x56, 0x01, 0x43, 0x45, 0x4A,
2116 0x30, 0x01, 0x00, 0x04, 0x43, 0x43, 0x4D, 0x44, 0x08,
2117 ];
2118 let mut aml = Vec::new();
2119
2120 Field::new(
2121 "PRST".into(),
2122 FieldAccessType::Byte,
2123 FieldLockRule::NoLock,
2124 FieldUpdateRule::WriteAsZeroes,
2125 vec![
2126 FieldEntry::Reserved(32),
2127 FieldEntry::Named(*b"CPEN", 1),
2128 FieldEntry::Named(*b"CINS", 1),
2129 FieldEntry::Named(*b"CRMV", 1),
2130 FieldEntry::Named(*b"CEJ0", 1),
2131 FieldEntry::Reserved(4),
2132 FieldEntry::Named(*b"CCMD", 8),
2133 ],
2134 )
2135 .to_aml_bytes(&mut aml);
2136 assert_eq!(aml, &field_data[..]);
2137
2138 /*
2139 Field (PRST, DWordAcc, Lock, Preserve)
2140 {
2141 CSEL, 32,
2142 Offset (0x08),
2143 CDAT, 32
2144 }
2145 */
2146
2147 let field_data = [
2148 0x5Bu8, 0x81, 0x12, 0x50, 0x52, 0x53, 0x54, 0x13, 0x43, 0x53, 0x45, 0x4C, 0x20, 0x00,
2149 0x20, 0x43, 0x44, 0x41, 0x54, 0x20,
2150 ];
2151 aml.clear();
2152
2153 Field::new(
2154 "PRST".into(),
2155 FieldAccessType::DWord,
2156 FieldLockRule::Lock,
2157 FieldUpdateRule::Preserve,
2158 vec![
2159 FieldEntry::Named(*b"CSEL", 32),
2160 FieldEntry::Reserved(32),
2161 FieldEntry::Named(*b"CDAT", 32),
2162 ],
2163 )
2164 .to_aml_bytes(&mut aml);
2165 assert_eq!(aml, &field_data[..]);
2166 }
2167
2168 #[test]
test_op_region()2169 fn test_op_region() {
2170 /*
2171 OperationRegion (PRST, SystemIO, 0x0CD8, 0x0C)
2172 */
2173 let op_region_data = [
2174 0x5Bu8, 0x80, 0x50, 0x52, 0x53, 0x54, 0x01, 0x0B, 0xD8, 0x0C, 0x0A, 0x0C,
2175 ];
2176 let mut aml = Vec::new();
2177
2178 OpRegion::new(
2179 "PRST".into(),
2180 OpRegionSpace::SystemIO,
2181 &0xcd8_usize,
2182 &0xc_usize,
2183 )
2184 .to_aml_bytes(&mut aml);
2185 assert_eq!(aml, &op_region_data[..]);
2186 }
2187
2188 #[test]
test_arg_if()2189 fn test_arg_if() {
2190 /*
2191 Method(TEST, 1, NotSerialized) {
2192 If (Arg0 == Zero) {
2193 Return(One)
2194 }
2195 Return(Zero)
2196 }
2197 */
2198 let arg_if_data = [
2199 0x14, 0x0F, 0x54, 0x45, 0x53, 0x54, 0x01, 0xA0, 0x06, 0x93, 0x68, 0x00, 0xA4, 0x01,
2200 0xA4, 0x00,
2201 ];
2202 let mut aml = Vec::new();
2203
2204 Method::new(
2205 "TEST".into(),
2206 1,
2207 false,
2208 vec![
2209 &If::new(&Equal::new(&Arg(0), &ZERO), vec![&Return::new(&ONE)]),
2210 &Return::new(&ZERO),
2211 ],
2212 )
2213 .to_aml_bytes(&mut aml);
2214 assert_eq!(aml, &arg_if_data);
2215 }
2216
2217 #[test]
test_local_if()2218 fn test_local_if() {
2219 /*
2220 Method(TEST, 0, NotSerialized) {
2221 Local0 = One
2222 If (Local0 == Zero) {
2223 Return(One)
2224 }
2225 Return(Zero)
2226 }
2227 */
2228 let local_if_data = [
2229 0x14, 0x12, 0x54, 0x45, 0x53, 0x54, 0x00, 0x70, 0x01, 0x60, 0xA0, 0x06, 0x93, 0x60,
2230 0x00, 0xA4, 0x01, 0xA4, 0x00,
2231 ];
2232 let mut aml = Vec::new();
2233
2234 Method::new(
2235 "TEST".into(),
2236 0,
2237 false,
2238 vec![
2239 &Store::new(&Local(0), &ONE),
2240 &If::new(&Equal::new(&Local(0), &ZERO), vec![&Return::new(&ONE)]),
2241 &Return::new(&ZERO),
2242 ],
2243 )
2244 .to_aml_bytes(&mut aml);
2245 assert_eq!(aml, &local_if_data);
2246 }
2247
2248 #[test]
test_mutex()2249 fn test_mutex() {
2250 /*
2251 Device (_SB_.MHPC)
2252 {
2253 Name (_HID, EisaId("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
2254 Mutex (MLCK, 0x00)
2255 Method (TEST, 0, NotSerialized)
2256 {
2257 Acquire (MLCK, 0xFFFF)
2258 Local0 = One
2259 Release (MLCK)
2260 }
2261 }
2262 */
2263
2264 let mutex_data = [
2265 0x5B, 0x82, 0x33, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2266 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x5B, 0x01, 0x4D, 0x4C, 0x43, 0x4B,
2267 0x00, 0x14, 0x17, 0x54, 0x45, 0x53, 0x54, 0x00, 0x5B, 0x23, 0x4D, 0x4C, 0x43, 0x4B,
2268 0xFF, 0xFF, 0x70, 0x01, 0x60, 0x5B, 0x27, 0x4D, 0x4C, 0x43, 0x4B,
2269 ];
2270 let mut aml = Vec::new();
2271
2272 let mutex = Mutex::new("MLCK".into(), 0);
2273 Device::new(
2274 "_SB_.MHPC".into(),
2275 vec![
2276 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2277 &mutex,
2278 &Method::new(
2279 "TEST".into(),
2280 0,
2281 false,
2282 vec![
2283 &Acquire::new("MLCK".into(), 0xffff),
2284 &Store::new(&Local(0), &ONE),
2285 &Release::new("MLCK".into()),
2286 ],
2287 ),
2288 ],
2289 )
2290 .to_aml_bytes(&mut aml);
2291 assert_eq!(aml, &mutex_data[..]);
2292 }
2293
2294 #[test]
test_notify()2295 fn test_notify() {
2296 /*
2297 Device (_SB.MHPC)
2298 {
2299 Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
2300 Method (TEST, 0, NotSerialized)
2301 {
2302 Notify (MHPC, One) // Device Check
2303 }
2304 }
2305 */
2306 let notify_data = [
2307 0x5B, 0x82, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2308 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x0C, 0x54, 0x45, 0x53, 0x54,
2309 0x00, 0x86, 0x4D, 0x48, 0x50, 0x43, 0x01,
2310 ];
2311 let mut aml = Vec::new();
2312
2313 Device::new(
2314 "_SB_.MHPC".into(),
2315 vec![
2316 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2317 &Method::new(
2318 "TEST".into(),
2319 0,
2320 false,
2321 vec![&Notify::new(&Path::new("MHPC"), &ONE)],
2322 ),
2323 ],
2324 )
2325 .to_aml_bytes(&mut aml);
2326 assert_eq!(aml, ¬ify_data[..]);
2327 }
2328
2329 #[test]
test_while()2330 fn test_while() {
2331 /*
2332 Device (_SB.MHPC)
2333 {
2334 Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
2335 Method (TEST, 0, NotSerialized)
2336 {
2337 Local0 = Zero
2338 While ((Local0 < 0x04))
2339 {
2340 Local0 += One
2341 }
2342 }
2343 }
2344 */
2345
2346 let while_data = [
2347 0x5B, 0x82, 0x28, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
2348 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x13, 0x54, 0x45, 0x53, 0x54,
2349 0x00, 0x70, 0x00, 0x60, 0xA2, 0x09, 0x95, 0x60, 0x0A, 0x04, 0x72, 0x60, 0x01, 0x60,
2350 ];
2351 let mut aml = Vec::new();
2352
2353 Device::new(
2354 "_SB_.MHPC".into(),
2355 vec![
2356 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2357 &Method::new(
2358 "TEST".into(),
2359 0,
2360 false,
2361 vec![
2362 &Store::new(&Local(0), &ZERO),
2363 &While::new(
2364 &LessThan::new(&Local(0), &4usize),
2365 vec![&Add::new(&Local(0), &Local(0), &ONE)],
2366 ),
2367 ],
2368 ),
2369 ],
2370 )
2371 .to_aml_bytes(&mut aml);
2372 assert_eq!(aml, &while_data[..])
2373 }
2374
2375 #[test]
test_method_call()2376 fn test_method_call() {
2377 /*
2378 Method (TST1, 1, NotSerialized)
2379 {
2380 TST2 (One, One)
2381 }
2382
2383 Method (TST2, 2, NotSerialized)
2384 {
2385 TST1 (One)
2386 }
2387 */
2388 let test_data = [
2389 0x14, 0x0C, 0x54, 0x53, 0x54, 0x31, 0x01, 0x54, 0x53, 0x54, 0x32, 0x01, 0x01, 0x14,
2390 0x0B, 0x54, 0x53, 0x54, 0x32, 0x02, 0x54, 0x53, 0x54, 0x31, 0x01,
2391 ];
2392
2393 let mut methods = Vec::new();
2394 Method::new(
2395 "TST1".into(),
2396 1,
2397 false,
2398 vec![&MethodCall::new("TST2".into(), vec![&ONE, &ONE])],
2399 )
2400 .to_aml_bytes(&mut methods);
2401 Method::new(
2402 "TST2".into(),
2403 2,
2404 false,
2405 vec![&MethodCall::new("TST1".into(), vec![&ONE])],
2406 )
2407 .to_aml_bytes(&mut methods);
2408 assert_eq!(&methods[..], &test_data[..])
2409 }
2410
2411 #[test]
test_buffer()2412 fn test_buffer() {
2413 /*
2414 Name (_MAT, Buffer (0x08) // _MAT: Multiple APIC Table Entry
2415 {
2416 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 /* ........ */
2417 })
2418 */
2419 let buffer_data = [
2420 0x08, 0x5F, 0x4D, 0x41, 0x54, 0x11, 0x0B, 0x0A, 0x08, 0x00, 0x08, 0x00, 0x00, 0x01,
2421 0x00, 0x00, 0x00,
2422 ];
2423 let mut aml = Vec::new();
2424
2425 Name::new(
2426 "_MAT".into(),
2427 &BufferData::new(vec![0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00]),
2428 )
2429 .to_aml_bytes(&mut aml);
2430 assert_eq!(aml, &buffer_data[..])
2431 }
2432 }
2433