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