1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
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 METHODOP: u8 = 0x14;
28 const DUALNAMEPREFIX: u8 = 0x2e;
29 const MULTINAMEPREFIX: u8 = 0x2f;
30 const NAMECHARBASE: u8 = 0x40;
31
32 const EXTOPPREFIX: u8 = 0x5b;
33 const MUTEXOP: u8 = 0x01;
34 const ACQUIREOP: u8 = 0x23;
35 const RELEASEOP: u8 = 0x27;
36 const OPREGIONOP: u8 = 0x80;
37 const FIELDOP: u8 = 0x81;
38 const DEVICEOP: u8 = 0x82;
39
40 const LOCAL0OP: u8 = 0x60;
41 const ARG0OP: u8 = 0x68;
42 const STOREOP: u8 = 0x70;
43 const ADDOP: u8 = 0x72;
44 const CONCATOP: u8 = 0x73;
45 const SUBTRACTOP: u8 = 0x74;
46 const MULTIPLYOP: u8 = 0x77;
47 const SHIFTLEFTOP: u8 = 0x79;
48 const SHIFTRIGHTOP: u8 = 0x7a;
49 const ANDOP: u8 = 0x7b;
50 const NANDOP: u8 = 0x7c;
51 const OROP: u8 = 0x7d;
52 const NOROP: u8 = 0x7e;
53 const XOROP: u8 = 0x7f;
54 const CONCATRESOP: u8 = 0x84;
55 const MODOP: u8 = 0x85;
56 const NOTIFYOP: u8 = 0x86;
57 const INDEXOP: u8 = 0x88;
58 const CREATEDWFIELDOP: u8 = 0x8a;
59 const LEQUALOP: u8 = 0x93;
60 const LLESSOP: u8 = 0x95;
61 const TOSTRINGOP: u8 = 0x9c;
62 const IFOP: u8 = 0xa0;
63 const ELSEOP: u8 = 0xa1;
64 const WHILEOP: u8 = 0xa2;
65 const RETURNOP: u8 = 0xa4;
66 const ONESOP: u8 = 0xff;
67
68 // AML resouce data fields
69 const IOPORTDESC: u8 = 0x47;
70 const ENDTAG: u8 = 0x79;
71 const MEMORY32FIXEDDESC: u8 = 0x86;
72 const DWORDADDRSPACEDESC: u8 = 0x87;
73 const WORDADDRSPACEDESC: u8 = 0x88;
74 const EXTIRQDESC: u8 = 0x89;
75 const QWORDADDRSPACEDESC: u8 = 0x8A;
76
77 /// Zero object in ASL.
78 pub const ZERO: Zero = Zero {};
79 pub struct Zero {}
80
81 impl Aml for Zero {
to_aml_bytes(&self, bytes: &mut Vec<u8>)82 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
83 bytes.append(&mut vec![ZEROOP]);
84 }
85 }
86
87 /// One object in ASL.
88 pub const ONE: One = One {};
89 pub struct One {}
90
91 impl Aml for One {
to_aml_bytes(&self, bytes: &mut Vec<u8>)92 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
93 bytes.append(&mut vec![ONEOP]);
94 }
95 }
96
97 /// Ones object represents all bits 1.
98 pub const ONES: Ones = Ones {};
99 pub struct Ones {}
100
101 impl Aml for Ones {
to_aml_bytes(&self, bytes: &mut Vec<u8>)102 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
103 bytes.append(&mut vec![ONESOP]);
104 }
105 }
106
107 /// Represents Namestring to construct ACPI objects like
108 /// Name/Device/Method/Scope and so on...
109 pub struct Path {
110 root: bool,
111 name_parts: Vec<[u8; 4]>,
112 }
113
114 impl Aml for Path {
to_aml_bytes(&self, bytes: &mut Vec<u8>)115 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
116 if self.root {
117 bytes.push(b'\\');
118 }
119
120 match self.name_parts.len() {
121 0 => panic!("Name cannot be empty"),
122 1 => {}
123 2 => {
124 bytes.push(DUALNAMEPREFIX);
125 }
126 n => {
127 bytes.push(MULTINAMEPREFIX);
128 bytes.push(n as u8);
129 }
130 };
131
132 for part in self.name_parts.clone().iter_mut() {
133 bytes.append(&mut part.to_vec());
134 }
135 }
136 }
137
138 impl Path {
139 /// Per ACPI Spec, the Namestring split by "." has 4 bytes long. So any name
140 /// not has 4 bytes will not be accepted.
new(name: &str) -> Self141 pub fn new(name: &str) -> Self {
142 let root = name.starts_with('\\');
143 let offset = root as usize;
144 let mut name_parts = Vec::new();
145 for part in name[offset..].split('.') {
146 assert_eq!(part.len(), 4);
147 let mut name_part = [0u8; 4];
148 name_part.copy_from_slice(part.as_bytes());
149 name_parts.push(name_part);
150 }
151
152 Path { root, name_parts }
153 }
154 }
155
156 impl From<&str> for Path {
from(s: &str) -> Self157 fn from(s: &str) -> Self {
158 Path::new(s)
159 }
160 }
161
162 pub type Byte = u8;
163
164 impl Aml for Byte {
to_aml_bytes(&self, bytes: &mut Vec<u8>)165 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
166 bytes.push(BYTEPREFIX);
167 bytes.push(*self);
168 }
169 }
170
171 pub type Word = u16;
172
173 impl Aml for Word {
to_aml_bytes(&self, bytes: &mut Vec<u8>)174 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
175 bytes.push(WORDPREFIX);
176 bytes.append(&mut self.to_le_bytes().to_vec());
177 }
178 }
179
180 pub type DWord = u32;
181
182 impl Aml for DWord {
to_aml_bytes(&self, bytes: &mut Vec<u8>)183 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
184 bytes.push(DWORDPREFIX);
185 bytes.append(&mut self.to_le_bytes().to_vec());
186 }
187 }
188
189 pub type QWord = u64;
190
191 impl Aml for QWord {
to_aml_bytes(&self, bytes: &mut Vec<u8>)192 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
193 bytes.push(QWORDPREFIX);
194 bytes.append(&mut self.to_le_bytes().to_vec());
195 }
196 }
197
198 /// Name object. bytes represents the raw AML data for it.
199 pub struct Name {
200 bytes: Vec<u8>,
201 }
202
203 impl Aml for Name {
to_aml_bytes(&self, bytes: &mut Vec<u8>)204 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
205 bytes.append(&mut self.bytes.clone());
206 }
207 }
208
209 impl Name {
210 /// Create Name object:
211 ///
212 /// * `path` - The namestring.
213 /// * `inner` - AML objects contained in this namespace.
new(path: Path, inner: &dyn Aml) -> Self214 pub fn new(path: Path, inner: &dyn Aml) -> Self {
215 let mut bytes = vec![NAMEOP];
216 path.to_aml_bytes(&mut bytes);
217 inner.to_aml_bytes(&mut bytes);
218 Name { bytes }
219 }
220
221 /// Create Field name object
222 ///
223 /// * 'field_name' - name string
new_field_name(field_name: &str) -> Self224 pub fn new_field_name(field_name: &str) -> Self {
225 let mut bytes: Vec<u8> = Vec::new();
226 bytes.extend_from_slice(field_name.as_bytes());
227 Name { bytes }
228 }
229 }
230
231 /// Package object. 'children' represents the ACPI objects contained in this package.
232 pub struct Package<'a> {
233 children: Vec<&'a dyn Aml>,
234 }
235
236 impl<'a> Aml for Package<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)237 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
238 let mut bytes = vec![self.children.len() as u8];
239 for child in &self.children {
240 child.to_aml_bytes(&mut bytes);
241 }
242
243 let mut pkg_length = create_pkg_length(&bytes, true);
244 pkg_length.reverse();
245 for byte in pkg_length {
246 bytes.insert(0, byte);
247 }
248
249 bytes.insert(0, PACKAGEOP);
250
251 aml.append(&mut bytes);
252 }
253 }
254
255 impl<'a> Package<'a> {
256 /// Create Package object:
new(children: Vec<&'a dyn Aml>) -> Self257 pub fn new(children: Vec<&'a dyn Aml>) -> Self {
258 Package { children }
259 }
260 }
261
262 /*
263
264 From the ACPI spec for PkgLength:
265
266 "The high 2 bits of the first byte reveal how many follow bytes are in the PkgLength. If the
267 PkgLength has only one byte, bit 0 through 5 are used to encode the package length (in other
268 words, values 0-63). If the package length value is more than 63, more than one byte must be
269 used for the encoding in which case bit 4 and 5 of the PkgLeadByte are reserved and must be zero.
270 If the multiple bytes encoding is used, bits 0-3 of the PkgLeadByte become the least significant 4
271 bits of the resulting package length value. The next ByteData will become the next least
272 significant 8 bits of the resulting value and so on, up to 3 ByteData bytes. Thus, the maximum
273 package length is 2**28."
274
275 */
276
277 /* 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>278 fn create_pkg_length(data: &[u8], include_self: bool) -> Vec<u8> {
279 let mut result = Vec::new();
280
281 /* PkgLength is inclusive and includes the length bytes */
282 let length_length = if data.len() < (2usize.pow(6) - 1) {
283 1
284 } else if data.len() < (2usize.pow(12) - 2) {
285 2
286 } else if data.len() < (2usize.pow(20) - 3) {
287 3
288 } else {
289 4
290 };
291
292 let length = data.len() + if include_self { length_length } else { 0 };
293
294 match length_length {
295 1 => result.push(length as u8),
296 2 => {
297 result.push((1u8 << 6) | (length & 0xf) as u8);
298 result.push((length >> 4) as u8)
299 }
300 3 => {
301 result.push((2u8 << 6) | (length & 0xf) as u8);
302 result.push((length >> 4) as u8);
303 result.push((length >> 12) as u8);
304 }
305 _ => {
306 result.push((3u8 << 6) | (length & 0xf) as u8);
307 result.push((length >> 4) as u8);
308 result.push((length >> 12) as u8);
309 result.push((length >> 20) as u8);
310 }
311 }
312
313 result
314 }
315
316 /// EISAName object. 'value' means the encoded u32 EisaIdString.
317 pub struct EISAName {
318 value: DWord,
319 }
320
321 impl EISAName {
322 /// Per ACPI Spec, the EisaIdString must be a String
323 /// object of the form UUUNNNN, where U is an uppercase letter
324 /// and N is a hexadecimal digit. No asterisks or other characters
325 /// are allowed in the string.
new(name: &str) -> Self326 pub fn new(name: &str) -> Self {
327 assert_eq!(name.len(), 7);
328
329 let data = name.as_bytes();
330
331 let value: u32 = (u32::from(data[0].checked_sub(NAMECHARBASE).unwrap()) << 26
332 | u32::from(data[1].checked_sub(NAMECHARBASE).unwrap()) << 21
333 | u32::from(data[2].checked_sub(NAMECHARBASE).unwrap()) << 16
334 | name.chars().nth(3).unwrap().to_digit(16).unwrap() << 12
335 | name.chars().nth(4).unwrap().to_digit(16).unwrap() << 8
336 | name.chars().nth(5).unwrap().to_digit(16).unwrap() << 4
337 | name.chars().nth(6).unwrap().to_digit(16).unwrap())
338 .swap_bytes();
339
340 EISAName { value }
341 }
342 }
343
344 impl Aml for EISAName {
to_aml_bytes(&self, bytes: &mut Vec<u8>)345 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
346 self.value.to_aml_bytes(bytes);
347 }
348 }
349
create_integer(v: usize, bytes: &mut Vec<u8>)350 fn create_integer(v: usize, bytes: &mut Vec<u8>) {
351 if v <= u8::max_value().into() {
352 (v as u8).to_aml_bytes(bytes);
353 } else if v <= u16::max_value().into() {
354 (v as u16).to_aml_bytes(bytes);
355 } else if v <= u32::max_value() as usize {
356 (v as u32).to_aml_bytes(bytes);
357 } else {
358 (v as u64).to_aml_bytes(bytes);
359 }
360 }
361
362 pub type Usize = usize;
363
364 impl Aml for Usize {
to_aml_bytes(&self, bytes: &mut Vec<u8>)365 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
366 create_integer(*self, bytes);
367 }
368 }
369
create_aml_string(v: &str) -> Vec<u8>370 fn create_aml_string(v: &str) -> Vec<u8> {
371 let mut data = vec![STRINGOP];
372 data.extend_from_slice(v.as_bytes());
373 data.push(0x0); /* NullChar */
374 data
375 }
376
377 /// implement Aml trait for 'str' so that 'str' can be directly append to the aml vector
378 pub type AmlStr = &'static str;
379
380 impl Aml for AmlStr {
to_aml_bytes(&self, bytes: &mut Vec<u8>)381 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
382 bytes.append(&mut create_aml_string(self));
383 }
384 }
385
386 /// implement Aml trait for 'String'. So purpose with str.
387 pub type AmlString = String;
388
389 impl Aml for AmlString {
to_aml_bytes(&self, bytes: &mut Vec<u8>)390 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
391 bytes.append(&mut create_aml_string(self));
392 }
393 }
394
395 /// ResouceTemplate object. 'children' represents the ACPI objects in it.
396 pub struct ResourceTemplate<'a> {
397 children: Vec<&'a dyn Aml>,
398 }
399
400 impl<'a> Aml for ResourceTemplate<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)401 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
402 let mut bytes = Vec::new();
403
404 // Add buffer data
405 for child in &self.children {
406 child.to_aml_bytes(&mut bytes);
407 }
408
409 // Mark with end and mark checksum as as always valid
410 bytes.push(ENDTAG);
411 bytes.push(0); /* zero checksum byte */
412
413 // Buffer length is an encoded integer including buffer data
414 // and EndTag and checksum byte
415 let mut buffer_length = Vec::new();
416 bytes.len().to_aml_bytes(&mut buffer_length);
417 buffer_length.reverse();
418 for byte in buffer_length {
419 bytes.insert(0, byte);
420 }
421
422 // PkgLength is everything else
423 let mut pkg_length = create_pkg_length(&bytes, true);
424 pkg_length.reverse();
425 for byte in pkg_length {
426 bytes.insert(0, byte);
427 }
428
429 bytes.insert(0, BUFFEROP);
430
431 aml.append(&mut bytes);
432 }
433 }
434
435 impl<'a> ResourceTemplate<'a> {
436 /// Create ResouceTemplate object
new(children: Vec<&'a dyn Aml>) -> Self437 pub fn new(children: Vec<&'a dyn Aml>) -> Self {
438 ResourceTemplate { children }
439 }
440 }
441
442 /// Memory32Fixed object with read_write accessing type, and the base address/length.
443 pub struct Memory32Fixed {
444 read_write: bool, /* true for read & write, false for read only */
445 base: u32,
446 length: u32,
447 }
448
449 impl Memory32Fixed {
450 /// Create Memory32Fixed object.
new(read_write: bool, base: u32, length: u32) -> Self451 pub fn new(read_write: bool, base: u32, length: u32) -> Self {
452 Memory32Fixed {
453 read_write,
454 base,
455 length,
456 }
457 }
458 }
459
460 impl Aml for Memory32Fixed {
to_aml_bytes(&self, bytes: &mut Vec<u8>)461 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
462 bytes.push(MEMORY32FIXEDDESC); /* 32bit Fixed Memory Range Descriptor */
463 bytes.append(&mut 9u16.to_le_bytes().to_vec());
464
465 // 9 bytes of payload
466 bytes.push(self.read_write as u8);
467 bytes.append(&mut self.base.to_le_bytes().to_vec());
468 bytes.append(&mut self.length.to_le_bytes().to_vec());
469 }
470 }
471
472 #[derive(Copy, Clone)]
473 enum AddressSpaceType {
474 Memory,
475 IO,
476 BusNumber,
477 }
478
479 /// AddressSpaceCachable represent cache types for AddressSpace object
480 #[derive(Copy, Clone)]
481 pub enum AddressSpaceCachable {
482 NotCacheable,
483 Cacheable,
484 WriteCombining,
485 PreFetchable,
486 }
487
488 /// AddressSpace structure with type, resouce range and flags to
489 /// construct Memory/IO/BusNumber objects
490 pub struct AddressSpace<T> {
491 type_: AddressSpaceType,
492 min: T,
493 max: T,
494 type_flags: u8,
495 }
496
497 impl<T> AddressSpace<T> {
498 /// Create DWordMemory/QWordMemory object
new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self499 pub fn new_memory(cacheable: AddressSpaceCachable, read_write: bool, min: T, max: T) -> Self {
500 AddressSpace {
501 type_: AddressSpaceType::Memory,
502 min,
503 max,
504 type_flags: (cacheable as u8) << 1 | read_write as u8,
505 }
506 }
507
508 /// Create WordIO/DWordIO/QWordIO object
new_io(min: T, max: T) -> Self509 pub fn new_io(min: T, max: T) -> Self {
510 AddressSpace {
511 type_: AddressSpaceType::IO,
512 min,
513 max,
514 type_flags: 3, /* EntireRange */
515 }
516 }
517
518 /// Create WordBusNumber object
new_bus_number(min: T, max: T) -> Self519 pub fn new_bus_number(min: T, max: T) -> Self {
520 AddressSpace {
521 type_: AddressSpaceType::BusNumber,
522 min,
523 max,
524 type_flags: 0,
525 }
526 }
527
push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize)528 fn push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize) {
529 bytes.push(descriptor); /* Word Address Space Descriptor */
530 bytes.append(&mut (length as u16).to_le_bytes().to_vec());
531 bytes.push(self.type_ as u8); /* type */
532 let generic_flags = 1 << 2 /* Min Fixed */ | 1 << 3; /* Max Fixed */
533 bytes.push(generic_flags);
534 bytes.push(self.type_flags);
535 }
536 }
537
538 impl Aml for AddressSpace<u16> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)539 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
540 self.push_header(
541 bytes,
542 WORDADDRSPACEDESC, /* Word Address Space Descriptor */
543 3 + 5 * std::mem::size_of::<u16>(), /* 3 bytes of header + 5 u16 fields */
544 );
545
546 bytes.append(&mut 0u16.to_le_bytes().to_vec()); /* Granularity */
547 bytes.append(&mut self.min.to_le_bytes().to_vec()); /* Min */
548 bytes.append(&mut self.max.to_le_bytes().to_vec()); /* Max */
549 bytes.append(&mut 0u16.to_le_bytes().to_vec()); /* Translation */
550 let len = self.max - self.min + 1;
551 bytes.append(&mut len.to_le_bytes().to_vec()); /* Length */
552 }
553 }
554
555 impl Aml for AddressSpace<u32> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)556 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
557 self.push_header(
558 bytes,
559 DWORDADDRSPACEDESC, /* DWord Address Space Descriptor */
560 3 + 5 * std::mem::size_of::<u32>(), /* 3 bytes of header + 5 u32 fields */
561 );
562
563 bytes.append(&mut 0u32.to_le_bytes().to_vec()); /* Granularity */
564 bytes.append(&mut self.min.to_le_bytes().to_vec()); /* Min */
565 bytes.append(&mut self.max.to_le_bytes().to_vec()); /* Max */
566 bytes.append(&mut 0u32.to_le_bytes().to_vec()); /* Translation */
567 let len = self.max - self.min + 1;
568 bytes.append(&mut len.to_le_bytes().to_vec()); /* Length */
569 }
570 }
571
572 impl Aml for AddressSpace<u64> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)573 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
574 self.push_header(
575 bytes,
576 QWORDADDRSPACEDESC, /* QWord Address Space Descriptor */
577 3 + 5 * std::mem::size_of::<u64>(), /* 3 bytes of header + 5 u64 fields */
578 );
579
580 bytes.append(&mut 0u64.to_le_bytes().to_vec()); /* Granularity */
581 bytes.append(&mut self.min.to_le_bytes().to_vec()); /* Min */
582 bytes.append(&mut self.max.to_le_bytes().to_vec()); /* Max */
583 bytes.append(&mut 0u64.to_le_bytes().to_vec()); /* Translation */
584 let len = self.max - self.min + 1;
585 bytes.append(&mut len.to_le_bytes().to_vec()); /* Length */
586 }
587 }
588
589 /// IO resouce object with the IO range, alignment and length
590 pub struct IO {
591 min: u16,
592 max: u16,
593 alignment: u8,
594 length: u8,
595 }
596
597 impl IO {
598 /// Create IO object
new(min: u16, max: u16, alignment: u8, length: u8) -> Self599 pub fn new(min: u16, max: u16, alignment: u8, length: u8) -> Self {
600 IO {
601 min,
602 max,
603 alignment,
604 length,
605 }
606 }
607 }
608
609 impl Aml for IO {
to_aml_bytes(&self, bytes: &mut Vec<u8>)610 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
611 bytes.push(IOPORTDESC); /* IO Port Descriptor */
612 bytes.push(1); /* IODecode16 */
613 bytes.append(&mut self.min.to_le_bytes().to_vec());
614 bytes.append(&mut self.max.to_le_bytes().to_vec());
615 bytes.push(self.alignment);
616 bytes.push(self.length);
617 }
618 }
619
620 /// Interrupt resouce object with the interrupt characters.
621 pub struct Interrupt {
622 consumer: bool,
623 edge_triggered: bool,
624 active_low: bool,
625 shared: bool,
626 number: u32,
627 }
628
629 impl Interrupt {
630 /// Create Interrupt object
new( consumer: bool, edge_triggered: bool, active_low: bool, shared: bool, number: u32, ) -> Self631 pub fn new(
632 consumer: bool,
633 edge_triggered: bool,
634 active_low: bool,
635 shared: bool,
636 number: u32,
637 ) -> Self {
638 Interrupt {
639 consumer,
640 edge_triggered,
641 active_low,
642 shared,
643 number,
644 }
645 }
646 }
647
648 impl Aml for Interrupt {
to_aml_bytes(&self, bytes: &mut Vec<u8>)649 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
650 bytes.push(EXTIRQDESC); /* Extended IRQ Descriptor */
651 bytes.append(&mut 6u16.to_le_bytes().to_vec());
652 let flags = (self.shared as u8) << 3
653 | (self.active_low as u8) << 2
654 | (self.edge_triggered as u8) << 1
655 | self.consumer as u8;
656 bytes.push(flags);
657 bytes.push(1u8); /* count */
658 bytes.append(&mut self.number.to_le_bytes().to_vec());
659 }
660 }
661
662 /// Device object with its device name and children objects in it.
663 pub struct Device<'a> {
664 path: Path,
665 children: Vec<&'a dyn Aml>,
666 }
667
668 impl<'a> Aml for Device<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)669 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
670 let mut bytes = Vec::new();
671 self.path.to_aml_bytes(&mut bytes);
672 for child in &self.children {
673 child.to_aml_bytes(&mut bytes);
674 }
675
676 let mut pkg_length = create_pkg_length(&bytes, true);
677 pkg_length.reverse();
678 for byte in pkg_length {
679 bytes.insert(0, byte);
680 }
681
682 bytes.insert(0, DEVICEOP); /* DeviceOp */
683 bytes.insert(0, EXTOPPREFIX); /* ExtOpPrefix */
684 aml.append(&mut bytes)
685 }
686 }
687
688 impl<'a> Device<'a> {
689 /// Create Device object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self690 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
691 Device { path, children }
692 }
693 }
694
695 /// Scope object with its name and children objects in it.
696 pub struct Scope<'a> {
697 path: Path,
698 children: Vec<&'a dyn Aml>,
699 }
700
701 impl<'a> Aml for Scope<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)702 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
703 let mut bytes = Vec::new();
704 self.path.to_aml_bytes(&mut bytes);
705 for child in &self.children {
706 child.to_aml_bytes(&mut bytes);
707 }
708
709 let mut pkg_length = create_pkg_length(&bytes, true);
710 pkg_length.reverse();
711 for byte in pkg_length {
712 bytes.insert(0, byte);
713 }
714
715 bytes.insert(0, SCOPEOP);
716 aml.append(&mut bytes)
717 }
718 }
719
720 impl<'a> Scope<'a> {
721 /// Create Scope object
new(path: Path, children: Vec<&'a dyn Aml>) -> Self722 pub fn new(path: Path, children: Vec<&'a dyn Aml>) -> Self {
723 Scope { path, children }
724 }
725 }
726
727 /// Method object with its name, children objects, arguments and serialized character.
728 pub struct Method<'a> {
729 path: Path,
730 children: Vec<&'a dyn Aml>,
731 args: u8,
732 serialized: bool,
733 }
734
735 impl<'a> Method<'a> {
736 /// Create Method object.
new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self737 pub fn new(path: Path, args: u8, serialized: bool, children: Vec<&'a dyn Aml>) -> Self {
738 Method {
739 path,
740 children,
741 args,
742 serialized,
743 }
744 }
745 }
746
747 impl<'a> Aml for Method<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)748 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
749 let mut bytes = Vec::new();
750 self.path.to_aml_bytes(&mut bytes);
751 let flags: u8 = (self.args & 0x7) | (self.serialized as u8) << 3;
752 bytes.push(flags);
753 for child in &self.children {
754 child.to_aml_bytes(&mut bytes);
755 }
756
757 let mut pkg_length = create_pkg_length(&bytes, true);
758 pkg_length.reverse();
759 for byte in pkg_length {
760 bytes.insert(0, byte);
761 }
762
763 bytes.insert(0, METHODOP);
764 aml.append(&mut bytes)
765 }
766 }
767
768 /// Return object with its return value.
769 pub struct Return<'a> {
770 value: &'a dyn Aml,
771 }
772
773 impl<'a> Return<'a> {
774 /// Create Return object
new(value: &'a dyn Aml) -> Self775 pub fn new(value: &'a dyn Aml) -> Self {
776 Return { value }
777 }
778 }
779
780 impl<'a> Aml for Return<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)781 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
782 bytes.push(RETURNOP);
783 self.value.to_aml_bytes(bytes);
784 }
785 }
786
787 /// FiledAccessType defines the filed accessing types.
788 #[derive(Clone, Copy)]
789 pub enum FieldAccessType {
790 Any,
791 Byte,
792 Word,
793 DWord,
794 QWord,
795 Buffer,
796 }
797
798 /// FiledUpdateRule defines the rules to update the filed.
799 #[derive(Clone, Copy)]
800 pub enum FieldUpdateRule {
801 Preserve = 0,
802 WriteAsOnes = 1,
803 WriteAsZeroes = 2,
804 }
805
806 /// FiledEntry defines the filed entry.
807 pub enum FieldEntry {
808 Named([u8; 4], usize),
809 Reserved(usize),
810 }
811
812 /// Field object with the region name, filed entries, access type and update rules.
813 pub struct Field {
814 path: Path,
815
816 fields: Vec<FieldEntry>,
817 access_type: FieldAccessType,
818 update_rule: FieldUpdateRule,
819 }
820
821 impl Field {
822 /// Create Field object
new( path: Path, access_type: FieldAccessType, update_rule: FieldUpdateRule, fields: Vec<FieldEntry>, ) -> Self823 pub fn new(
824 path: Path,
825 access_type: FieldAccessType,
826 update_rule: FieldUpdateRule,
827 fields: Vec<FieldEntry>,
828 ) -> Self {
829 Field {
830 path,
831 access_type,
832 update_rule,
833 fields,
834 }
835 }
836 }
837
838 impl Aml for Field {
to_aml_bytes(&self, aml: &mut Vec<u8>)839 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
840 let mut bytes = Vec::new();
841 self.path.to_aml_bytes(&mut bytes);
842
843 let flags: u8 = self.access_type as u8 | (self.update_rule as u8) << 5;
844 bytes.push(flags);
845
846 for field in self.fields.iter() {
847 match field {
848 FieldEntry::Named(name, length) => {
849 bytes.extend_from_slice(name);
850 bytes.append(&mut create_pkg_length(&vec![0; *length], false));
851 }
852 FieldEntry::Reserved(length) => {
853 bytes.push(0x0);
854 bytes.append(&mut create_pkg_length(&vec![0; *length], false));
855 }
856 }
857 }
858
859 let mut pkg_length = create_pkg_length(&bytes, true);
860 pkg_length.reverse();
861 for byte in pkg_length {
862 bytes.insert(0, byte);
863 }
864
865 bytes.insert(0, FIELDOP);
866 bytes.insert(0, EXTOPPREFIX);
867 aml.append(&mut bytes)
868 }
869 }
870
871 /// The space type for OperationRegion object
872 #[derive(Clone, Copy)]
873 pub enum OpRegionSpace {
874 SystemMemory,
875 SystemIO,
876 PCIConfig,
877 EmbeddedControl,
878 SMBus,
879 SystemCMOS,
880 PciBarTarget,
881 IPMI,
882 GeneralPurposeIO,
883 GenericSerialBus,
884 }
885
886 /// OperationRegion object with region name, region space type, its offset and length.
887 pub struct OpRegion {
888 path: Path,
889 space: OpRegionSpace,
890 offset: usize,
891 length: usize,
892 }
893
894 impl OpRegion {
895 /// Create OperationRegion object.
new(path: Path, space: OpRegionSpace, offset: usize, length: usize) -> Self896 pub fn new(path: Path, space: OpRegionSpace, offset: usize, length: usize) -> Self {
897 OpRegion {
898 path,
899 space,
900 offset,
901 length,
902 }
903 }
904 }
905
906 impl Aml for OpRegion {
to_aml_bytes(&self, aml: &mut Vec<u8>)907 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
908 let mut bytes = Vec::new();
909 self.path.to_aml_bytes(&mut bytes);
910 bytes.push(self.space as u8);
911 self.offset.to_aml_bytes(&mut bytes); /* RegionOffset */
912 self.length.to_aml_bytes(&mut bytes); /* RegionLen */
913 bytes.insert(0, OPREGIONOP);
914 bytes.insert(0, EXTOPPREFIX);
915 aml.append(&mut bytes)
916 }
917 }
918
919 /// If object with the if condition(predicate) and the body presented by the if_children objects.
920 pub struct If<'a> {
921 predicate: &'a dyn Aml,
922 if_children: Vec<&'a dyn Aml>,
923 }
924
925 impl<'a> If<'a> {
926 /// Create If object.
new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self927 pub fn new(predicate: &'a dyn Aml, if_children: Vec<&'a dyn Aml>) -> Self {
928 If {
929 predicate,
930 if_children,
931 }
932 }
933 }
934
935 impl<'a> Aml for If<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)936 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
937 let mut bytes = Vec::new();
938 self.predicate.to_aml_bytes(&mut bytes);
939 for child in self.if_children.iter() {
940 child.to_aml_bytes(&mut bytes);
941 }
942
943 let mut pkg_length = create_pkg_length(&bytes, true);
944 pkg_length.reverse();
945 for byte in pkg_length {
946 bytes.insert(0, byte);
947 }
948
949 bytes.insert(0, IFOP);
950 aml.append(&mut bytes)
951 }
952 }
953
954 /// Else object
955 pub struct Else<'a> {
956 body: Vec<&'a dyn Aml>,
957 }
958
959 impl<'a> Else<'a> {
960 /// Create Else object.
new(body: Vec<&'a dyn Aml>) -> Self961 pub fn new(body: Vec<&'a dyn Aml>) -> Self {
962 Else { body }
963 }
964 }
965
966 impl<'a> Aml for Else<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)967 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
968 let mut bytes = Vec::new();
969 for child in self.body.iter() {
970 child.to_aml_bytes(&mut bytes);
971 }
972
973 let mut pkg_length = create_pkg_length(&bytes, true);
974 pkg_length.reverse();
975 for byte in pkg_length {
976 bytes.insert(0, byte);
977 }
978
979 bytes.insert(0, ELSEOP);
980 aml.append(&mut bytes)
981 }
982 }
983
984 /// Equal object with its right part and left part, which are both ACPI objects.
985 pub struct Equal<'a> {
986 right: &'a dyn Aml,
987 left: &'a dyn Aml,
988 }
989
990 impl<'a> Equal<'a> {
991 /// Create Equal object.
new(left: &'a dyn Aml, right: &'a dyn Aml) -> Self992 pub fn new(left: &'a dyn Aml, right: &'a dyn Aml) -> Self {
993 Equal { left, right }
994 }
995 }
996
997 impl<'a> Aml for Equal<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)998 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
999 bytes.push(LEQUALOP);
1000 self.left.to_aml_bytes(bytes);
1001 self.right.to_aml_bytes(bytes);
1002 }
1003 }
1004
1005 /// LessThan object with its right part and left part, which are both ACPI objects.
1006 pub struct LessThan<'a> {
1007 right: &'a dyn Aml,
1008 left: &'a dyn Aml,
1009 }
1010
1011 impl<'a> LessThan<'a> {
1012 /// Create LessThan object.
new(left: &'a dyn Aml, right: &'a dyn Aml) -> Self1013 pub fn new(left: &'a dyn Aml, right: &'a dyn Aml) -> Self {
1014 LessThan { left, right }
1015 }
1016 }
1017
1018 impl<'a> Aml for LessThan<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1019 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1020 bytes.push(LLESSOP);
1021 self.left.to_aml_bytes(bytes);
1022 self.right.to_aml_bytes(bytes);
1023 }
1024 }
1025
1026 /// Argx object.
1027 pub struct Arg(pub u8);
1028
1029 impl Aml for Arg {
1030 /// Per ACPI spec, there is maximum 7 Argx objects from
1031 /// Arg0 ~ Arg6. Any other Arg object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1032 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1033 assert!(self.0 <= 6);
1034 bytes.push(ARG0OP + self.0);
1035 }
1036 }
1037
1038 /// Localx object.
1039 pub struct Local(pub u8);
1040
1041 impl Aml for Local {
1042 /// Per ACPI spec, there is maximum 8 Localx objects from
1043 /// Local0 ~ Local7. Any other Local object will not be accepted.
to_aml_bytes(&self, bytes: &mut Vec<u8>)1044 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1045 assert!(self.0 <= 7);
1046 bytes.push(LOCAL0OP + self.0);
1047 }
1048 }
1049
1050 /// Store object with the ACPI object name which can be stored to and
1051 /// the ACPI object value which is to store.
1052 pub struct Store<'a> {
1053 name: &'a dyn Aml,
1054 value: &'a dyn Aml,
1055 }
1056
1057 impl<'a> Store<'a> {
1058 /// Create Store object.
new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self1059 pub fn new(name: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1060 Store { name, value }
1061 }
1062 }
1063
1064 impl<'a> Aml for Store<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1065 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1066 bytes.push(STOREOP);
1067 self.value.to_aml_bytes(bytes);
1068 self.name.to_aml_bytes(bytes);
1069 }
1070 }
1071
1072 /// Mutex object with a mutex name and a synchronization level.
1073 pub struct Mutex {
1074 path: Path,
1075 sync_level: u8,
1076 }
1077
1078 impl Mutex {
1079 /// Create Mutex object.
new(path: Path, sync_level: u8) -> Self1080 pub fn new(path: Path, sync_level: u8) -> Self {
1081 Self { path, sync_level }
1082 }
1083 }
1084
1085 impl Aml for Mutex {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1086 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1087 bytes.push(EXTOPPREFIX);
1088 bytes.push(MUTEXOP);
1089 self.path.to_aml_bytes(bytes);
1090 bytes.push(self.sync_level);
1091 }
1092 }
1093
1094 /// Acquire object with a Mutex object and timeout value.
1095 pub struct Acquire {
1096 mutex: Path,
1097 timeout: u16,
1098 }
1099
1100 impl Acquire {
1101 /// Create Acquire object.
new(mutex: Path, timeout: u16) -> Self1102 pub fn new(mutex: Path, timeout: u16) -> Self {
1103 Acquire { mutex, timeout }
1104 }
1105 }
1106
1107 impl Aml for Acquire {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1108 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1109 bytes.push(EXTOPPREFIX);
1110 bytes.push(ACQUIREOP);
1111 self.mutex.to_aml_bytes(bytes);
1112 bytes.extend_from_slice(&self.timeout.to_le_bytes());
1113 }
1114 }
1115
1116 /// Release object with a Mutex object to release.
1117 pub struct Release {
1118 mutex: Path,
1119 }
1120
1121 impl Release {
1122 /// Create Release object.
new(mutex: Path) -> Self1123 pub fn new(mutex: Path) -> Self {
1124 Release { mutex }
1125 }
1126 }
1127
1128 impl Aml for Release {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1129 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1130 bytes.push(EXTOPPREFIX);
1131 bytes.push(RELEASEOP);
1132 self.mutex.to_aml_bytes(bytes);
1133 }
1134 }
1135
1136 /// Notify object with an object which is to be notified with the value.
1137 pub struct Notify<'a> {
1138 object: &'a dyn Aml,
1139 value: &'a dyn Aml,
1140 }
1141
1142 impl<'a> Notify<'a> {
1143 /// Create Notify object.
new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self1144 pub fn new(object: &'a dyn Aml, value: &'a dyn Aml) -> Self {
1145 Notify { object, value }
1146 }
1147 }
1148
1149 impl<'a> Aml for Notify<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1150 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1151 bytes.push(NOTIFYOP);
1152 self.object.to_aml_bytes(bytes);
1153 self.value.to_aml_bytes(bytes);
1154 }
1155 }
1156
1157 /// While object with the while condition objects(predicate) and
1158 /// the while body objects(while_children).
1159 pub struct While<'a> {
1160 predicate: &'a dyn Aml,
1161 while_children: Vec<&'a dyn Aml>,
1162 }
1163
1164 impl<'a> While<'a> {
1165 /// Create While object.
new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self1166 pub fn new(predicate: &'a dyn Aml, while_children: Vec<&'a dyn Aml>) -> Self {
1167 While {
1168 predicate,
1169 while_children,
1170 }
1171 }
1172 }
1173
1174 impl<'a> Aml for While<'a> {
to_aml_bytes(&self, aml: &mut Vec<u8>)1175 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1176 let mut bytes = Vec::new();
1177 self.predicate.to_aml_bytes(&mut bytes);
1178 for child in self.while_children.iter() {
1179 child.to_aml_bytes(&mut bytes);
1180 }
1181
1182 let mut pkg_length = create_pkg_length(&bytes, true);
1183 pkg_length.reverse();
1184 for byte in pkg_length {
1185 bytes.insert(0, byte);
1186 }
1187
1188 bytes.insert(0, WHILEOP);
1189 aml.append(&mut bytes)
1190 }
1191 }
1192
1193 macro_rules! binary_op {
1194 ($name:ident, $opcode:expr) => {
1195 /// General operation object with the operator a/b and a target.
1196 pub struct $name<'a> {
1197 a: &'a dyn Aml,
1198 b: &'a dyn Aml,
1199 target: &'a dyn Aml,
1200 }
1201
1202 impl<'a> $name<'a> {
1203 /// Create the object.
1204 pub fn new(target: &'a dyn Aml, a: &'a dyn Aml, b: &'a dyn Aml) -> Self {
1205 $name { target, a, b }
1206 }
1207 }
1208
1209 impl<'a> Aml for $name<'a> {
1210 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1211 bytes.push($opcode); /* Op for the binary operator */
1212 self.a.to_aml_bytes(bytes);
1213 self.b.to_aml_bytes(bytes);
1214 self.target.to_aml_bytes(bytes);
1215 }
1216 }
1217 };
1218 }
1219
1220 binary_op!(Add, ADDOP);
1221 binary_op!(Concat, CONCATOP);
1222 binary_op!(Subtract, SUBTRACTOP);
1223 binary_op!(Multiply, MULTIPLYOP);
1224 binary_op!(ShiftLeft, SHIFTLEFTOP);
1225 binary_op!(ShiftRight, SHIFTRIGHTOP);
1226 binary_op!(And, ANDOP);
1227 binary_op!(Nand, NANDOP);
1228 binary_op!(Or, OROP);
1229 binary_op!(Nor, NOROP);
1230 binary_op!(Xor, XOROP);
1231 binary_op!(ConcatRes, CONCATRESOP);
1232 binary_op!(Mod, MODOP);
1233 binary_op!(Index, INDEXOP);
1234 binary_op!(ToString, TOSTRINGOP);
1235 binary_op!(CreateDWordField, CREATEDWFIELDOP);
1236
1237 /// MethodCall object with the method name and parameter objects.
1238 pub struct MethodCall<'a> {
1239 name: Path,
1240 args: Vec<&'a dyn Aml>,
1241 }
1242
1243 impl<'a> MethodCall<'a> {
1244 /// Create MethodCall object.
new(name: Path, args: Vec<&'a dyn Aml>) -> Self1245 pub fn new(name: Path, args: Vec<&'a dyn Aml>) -> Self {
1246 MethodCall { name, args }
1247 }
1248 }
1249
1250 impl<'a> Aml for MethodCall<'a> {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1251 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1252 self.name.to_aml_bytes(bytes);
1253 for arg in self.args.iter() {
1254 arg.to_aml_bytes(bytes);
1255 }
1256 }
1257 }
1258
1259 /// Buffer object with the data in it.
1260 pub struct Buffer {
1261 data: Vec<u8>,
1262 }
1263
1264 impl Buffer {
1265 /// Create Buffer object.
new(data: Vec<u8>) -> Self1266 pub fn new(data: Vec<u8>) -> Self {
1267 Buffer { data }
1268 }
1269 }
1270
1271 impl Aml for Buffer {
to_aml_bytes(&self, aml: &mut Vec<u8>)1272 fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
1273 let mut bytes = Vec::new();
1274 self.data.len().to_aml_bytes(&mut bytes);
1275 bytes.extend_from_slice(&self.data);
1276
1277 let mut pkg_length = create_pkg_length(&bytes, true);
1278 pkg_length.reverse();
1279 for byte in pkg_length {
1280 bytes.insert(0, byte);
1281 }
1282
1283 bytes.insert(0, BUFFEROP);
1284
1285 aml.append(&mut bytes)
1286 }
1287 }
1288
1289 pub struct Uuid {
1290 name: Buffer,
1291 }
1292
hex2byte(v1: char, v2: char) -> u81293 fn hex2byte(v1: char, v2: char) -> u8 {
1294 let hi = v1.to_digit(16).unwrap() as u8;
1295 assert!(hi <= 15);
1296 let lo = v2.to_digit(16).unwrap() as u8;
1297 assert!(lo <= 15);
1298
1299 (hi << 4) | lo
1300 }
1301
1302 impl Uuid {
1303 // Create Uuid object
1304 // eg. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
new(name: &str) -> Self1305 pub fn new(name: &str) -> Self {
1306 let name_vec: Vec<char> = name.chars().collect();
1307 let mut data = Vec::new();
1308
1309 assert_eq!(name_vec.len(), 36);
1310 assert_eq!(name_vec[8], '-');
1311 assert_eq!(name_vec[13], '-');
1312 assert_eq!(name_vec[18], '-');
1313 assert_eq!(name_vec[23], '-');
1314
1315 // dd - at offset 00
1316 data.push(hex2byte(name_vec[6], name_vec[7]));
1317 // cc - at offset 01
1318 data.push(hex2byte(name_vec[4], name_vec[5]));
1319 // bb - at offset 02
1320 data.push(hex2byte(name_vec[2], name_vec[3]));
1321 // aa - at offset 03
1322 data.push(hex2byte(name_vec[0], name_vec[1]));
1323
1324 // ff - at offset 04
1325 data.push(hex2byte(name_vec[11], name_vec[12]));
1326 // ee - at offset 05
1327 data.push(hex2byte(name_vec[9], name_vec[10]));
1328
1329 // hh - at offset 06
1330 data.push(hex2byte(name_vec[16], name_vec[17]));
1331 // gg - at offset 07
1332 data.push(hex2byte(name_vec[14], name_vec[15]));
1333
1334 // ii - at offset 08
1335 data.push(hex2byte(name_vec[19], name_vec[20]));
1336 // jj - at offset 09
1337 data.push(hex2byte(name_vec[21], name_vec[22]));
1338
1339 // kk - at offset 10
1340 data.push(hex2byte(name_vec[24], name_vec[25]));
1341 // ll - at offset 11
1342 data.push(hex2byte(name_vec[26], name_vec[27]));
1343 // mm - at offset 12
1344 data.push(hex2byte(name_vec[28], name_vec[29]));
1345 // nn - at offset 13
1346 data.push(hex2byte(name_vec[30], name_vec[31]));
1347 // oo - at offset 14
1348 data.push(hex2byte(name_vec[32], name_vec[33]));
1349 // pp - at offset 15
1350 data.push(hex2byte(name_vec[34], name_vec[35]));
1351
1352 Uuid {
1353 name: Buffer::new(data),
1354 }
1355 }
1356 }
1357
1358 impl Aml for Uuid {
to_aml_bytes(&self, bytes: &mut Vec<u8>)1359 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
1360 self.name.to_aml_bytes(bytes)
1361 }
1362 }
1363
1364 #[cfg(test)]
1365 mod tests {
1366 use super::*;
1367
1368 #[test]
test_device()1369 fn test_device() {
1370 /*
1371 Device (_SB.COM1)
1372 {
1373 Name (_HID, EisaId ("PNP0501") /* 16550A-compatible COM Serial Port */) // _HID: Hardware ID
1374 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1375 {
1376 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1377 {
1378 0x00000004,
1379 }
1380 IO (Decode16,
1381 0x03F8, // Range Minimum
1382 0x03F8, // Range Maximum
1383 0x00, // Alignment
1384 0x08, // Length
1385 )
1386 }
1387 }
1388 */
1389 let com1_device = [
1390 0x5B, 0x82, 0x30, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31, 0x08, 0x5F,
1391 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01, 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11,
1392 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01, 0x04, 0x00, 0x00, 0x00, 0x47, 0x01,
1393 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1394 ];
1395 let mut aml = Vec::new();
1396
1397 Device::new(
1398 "_SB_.COM1".into(),
1399 vec![
1400 &Name::new("_HID".into(), &EISAName::new("PNP0501")),
1401 &Name::new(
1402 "_CRS".into(),
1403 &ResourceTemplate::new(vec![
1404 &Interrupt::new(true, true, false, false, 4),
1405 &IO::new(0x3f8, 0x3f8, 0, 0x8),
1406 ]),
1407 ),
1408 ],
1409 )
1410 .to_aml_bytes(&mut aml);
1411 assert_eq!(aml, &com1_device[..]);
1412 }
1413
1414 #[test]
test_scope()1415 fn test_scope() {
1416 /*
1417 Scope (_SB.MBRD)
1418 {
1419 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1420 {
1421 Memory32Fixed (ReadWrite,
1422 0xE8000000, // Address Base
1423 0x10000000, // Address Length
1424 )
1425 })
1426 }
1427 */
1428
1429 let mbrd_scope = [
1430 0x10, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x42, 0x52, 0x44, 0x08, 0x5F, 0x43,
1431 0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE8,
1432 0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1433 ];
1434 let mut aml = Vec::new();
1435
1436 Scope::new(
1437 "_SB_.MBRD".into(),
1438 vec![&Name::new(
1439 "_CRS".into(),
1440 &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1441 )],
1442 )
1443 .to_aml_bytes(&mut aml);
1444 assert_eq!(aml, &mbrd_scope[..]);
1445 }
1446
1447 #[test]
test_resource_template()1448 fn test_resource_template() {
1449 /*
1450 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1451 {
1452 Memory32Fixed (ReadWrite,
1453 0xE8000000, // Address Base
1454 0x10000000, // Address Length
1455 )
1456 })
1457 */
1458 let crs_memory_32_fixed = [
1459 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x11, 0x0A, 0x0E, 0x86, 0x09, 0x00, 0x01, 0x00,
1460 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x10, 0x79, 0x00,
1461 ];
1462 let mut aml = Vec::new();
1463
1464 Name::new(
1465 "_CRS".into(),
1466 &ResourceTemplate::new(vec![&Memory32Fixed::new(true, 0xE800_0000, 0x1000_0000)]),
1467 )
1468 .to_aml_bytes(&mut aml);
1469 assert_eq!(aml, crs_memory_32_fixed);
1470
1471 /*
1472 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1473 {
1474 WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
1475 0x0000, // Granularity
1476 0x0000, // Range Minimum
1477 0x00FF, // Range Maximum
1478 0x0000, // Translation Offset
1479 0x0100, // Length
1480 ,, )
1481 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1482 0x0000, // Granularity
1483 0x0000, // Range Minimum
1484 0x0CF7, // Range Maximum
1485 0x0000, // Translation Offset
1486 0x0CF8, // Length
1487 ,, , TypeStatic, DenseTranslation)
1488 WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
1489 0x0000, // Granularity
1490 0x0D00, // Range Minimum
1491 0xFFFF, // Range Maximum
1492 0x0000, // Translation Offset
1493 0xF300, // Length
1494 ,, , TypeStatic, DenseTranslation)
1495 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1496 0x00000000, // Granularity
1497 0x000A0000, // Range Minimum
1498 0x000BFFFF, // Range Maximum
1499 0x00000000, // Translation Offset
1500 0x00020000, // Length
1501 ,, , AddressRangeMemory, TypeStatic)
1502 DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
1503 0x00000000, // Granularity
1504 0xC0000000, // Range Minimum
1505 0xFEBFFFFF, // Range Maximum
1506 0x00000000, // Translation Offset
1507 0x3EC00000, // Length
1508 ,, , AddressRangeMemory, TypeStatic)
1509 QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
1510 0x0000000000000000, // Granularity
1511 0x0000000800000000, // Range Minimum
1512 0x0000000FFFFFFFFF, // Range Maximum
1513 0x0000000000000000, // Translation Offset
1514 0x0000000800000000, // Length
1515 ,, , AddressRangeMemory, TypeStatic)
1516 })
1517 */
1518
1519 // WordBusNumber from above
1520 let crs_word_bus_number = [
1521 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x15, 0x0A, 0x12, 0x88, 0x0D, 0x00, 0x02, 0x0C,
1522 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x79, 0x00,
1523 ];
1524 aml.clear();
1525
1526 Name::new(
1527 "_CRS".into(),
1528 &ResourceTemplate::new(vec![&AddressSpace::new_bus_number(0x0u16, 0xffu16)]),
1529 )
1530 .to_aml_bytes(&mut aml);
1531 assert_eq!(aml, &crs_word_bus_number);
1532
1533 // WordIO blocks (x 2) from above
1534 let crs_word_io = [
1535 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x25, 0x0A, 0x22, 0x88, 0x0D, 0x00, 0x01, 0x0C,
1536 0x03, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0C, 0x00, 0x00, 0xF8, 0x0C, 0x88, 0x0D, 0x00,
1537 0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF3, 0x79,
1538 0x00,
1539 ];
1540 aml.clear();
1541
1542 Name::new(
1543 "_CRS".into(),
1544 &ResourceTemplate::new(vec![
1545 &AddressSpace::new_io(0x0u16, 0xcf7u16),
1546 &AddressSpace::new_io(0xd00u16, 0xffffu16),
1547 ]),
1548 )
1549 .to_aml_bytes(&mut aml);
1550 assert_eq!(aml, &crs_word_io[..]);
1551
1552 // DWordMemory blocks (x 2) from above
1553 let crs_dword_memory = [
1554 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x39, 0x0A, 0x36, 0x87, 0x17, 0x00, 0x00, 0x0C,
1555 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xFF, 0xFF, 0x0B, 0x00, 0x00,
1556 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x87, 0x17, 0x00, 0x00, 0x0C, 0x01, 0x00,
1557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xBF, 0xFE, 0x00, 0x00, 0x00,
1558 0x00, 0x00, 0x00, 0xC0, 0x3E, 0x79, 0x00,
1559 ];
1560 aml.clear();
1561
1562 Name::new(
1563 "_CRS".into(),
1564 &ResourceTemplate::new(vec![
1565 &AddressSpace::new_memory(
1566 AddressSpaceCachable::Cacheable,
1567 true,
1568 0xa_0000u32,
1569 0xb_ffffu32,
1570 ),
1571 &AddressSpace::new_memory(
1572 AddressSpaceCachable::NotCacheable,
1573 true,
1574 0xc000_0000u32,
1575 0xfebf_ffffu32,
1576 ),
1577 ]),
1578 )
1579 .to_aml_bytes(&mut aml);
1580 assert_eq!(aml, &crs_dword_memory[..]);
1581
1582 // QWordMemory from above
1583 let crs_qword_memory = [
1584 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x33, 0x0A, 0x30, 0x8A, 0x2B, 0x00, 0x00, 0x0C,
1585 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1586 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x79,
1588 0x00,
1589 ];
1590 aml.clear();
1591 Name::new(
1592 "_CRS".into(),
1593 &ResourceTemplate::new(vec![&AddressSpace::new_memory(
1594 AddressSpaceCachable::Cacheable,
1595 true,
1596 0x8_0000_0000u64,
1597 0xf_ffff_ffffu64,
1598 )]),
1599 )
1600 .to_aml_bytes(&mut aml);
1601
1602 assert_eq!(aml, &crs_qword_memory[..]);
1603
1604 /*
1605 Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
1606 {
1607 Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
1608 {
1609 0x00000004,
1610 }
1611 IO (Decode16,
1612 0x03F8, // Range Minimum
1613 0x03F8, // Range Maximum
1614 0x00, // Alignment
1615 0x08, // Length
1616 )
1617 })
1618
1619 */
1620 let interrupt_io_data = [
1621 0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01,
1622 0x04, 0x00, 0x00, 0x00, 0x47, 0x01, 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
1623 ];
1624 aml.clear();
1625 Name::new(
1626 "_CRS".into(),
1627 &ResourceTemplate::new(vec![
1628 &Interrupt::new(true, true, false, false, 4),
1629 &IO::new(0x3f8, 0x3f8, 0, 0x8),
1630 ]),
1631 )
1632 .to_aml_bytes(&mut aml);
1633
1634 assert_eq!(aml, &interrupt_io_data[..]);
1635 }
1636
1637 #[test]
test_pkg_length()1638 fn test_pkg_length() {
1639 assert_eq!(create_pkg_length(&[0u8; 62], true), vec![63]);
1640 assert_eq!(
1641 create_pkg_length(&[0u8; 64], true),
1642 vec![1 << 6 | (66 & 0xf), 66 >> 4]
1643 );
1644 assert_eq!(
1645 create_pkg_length(&[0u8; 4096], true),
1646 vec![
1647 2 << 6 | (4099 & 0xf) as u8,
1648 (4099 >> 4) as u8,
1649 (4099 >> 12) as u8
1650 ]
1651 );
1652 }
1653
1654 #[test]
test_package()1655 fn test_package() {
1656 /*
1657 Name (_S5, Package (0x01) // _S5_: S5 System State
1658 {
1659 0x05
1660 })
1661 */
1662 let s5_sleep_data = [0x08, 0x5F, 0x53, 0x35, 0x5F, 0x12, 0x04, 0x01, 0x0A, 0x05];
1663 let mut aml = Vec::new();
1664
1665 Name::new("_S5_".into(), &Package::new(vec![&5u8])).to_aml_bytes(&mut aml);
1666
1667 assert_eq!(s5_sleep_data.to_vec(), aml);
1668 }
1669
1670 #[test]
test_eisa_name()1671 fn test_eisa_name() {
1672 let mut aml = Vec::new();
1673 Name::new("_HID".into(), &EISAName::new("PNP0501")).to_aml_bytes(&mut aml);
1674 assert_eq!(
1675 aml,
1676 [0x08, 0x5F, 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x05, 0x01],
1677 )
1678 }
1679 #[test]
test_name_path()1680 fn test_name_path() {
1681 let mut aml = Vec::new();
1682 (&"_SB_".into() as &Path).to_aml_bytes(&mut aml);
1683 assert_eq!(aml, [0x5Fu8, 0x53, 0x42, 0x5F]);
1684 aml.clear();
1685 (&"\\_SB_".into() as &Path).to_aml_bytes(&mut aml);
1686 assert_eq!(aml, [0x5C, 0x5F, 0x53, 0x42, 0x5F]);
1687 aml.clear();
1688 (&"_SB_.COM1".into() as &Path).to_aml_bytes(&mut aml);
1689 assert_eq!(aml, [0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31]);
1690 aml.clear();
1691 (&"_SB_.PCI0._HID".into() as &Path).to_aml_bytes(&mut aml);
1692 assert_eq!(
1693 aml,
1694 [0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x48, 0x49, 0x44]
1695 );
1696 }
1697
1698 #[test]
test_numbers()1699 fn test_numbers() {
1700 let mut aml = Vec::new();
1701 128u8.to_aml_bytes(&mut aml);
1702 assert_eq!(aml, [0x0a, 0x80]);
1703 aml.clear();
1704 1024u16.to_aml_bytes(&mut aml);
1705 assert_eq!(aml, [0x0b, 0x0, 0x04]);
1706 aml.clear();
1707 (16u32 << 20).to_aml_bytes(&mut aml);
1708 assert_eq!(aml, [0x0c, 0x00, 0x00, 0x0, 0x01]);
1709 aml.clear();
1710 0xdeca_fbad_deca_fbadu64.to_aml_bytes(&mut aml);
1711 assert_eq!(aml, [0x0e, 0xad, 0xfb, 0xca, 0xde, 0xad, 0xfb, 0xca, 0xde]);
1712 }
1713
1714 #[test]
test_name()1715 fn test_name() {
1716 let mut aml = Vec::new();
1717 Name::new("_SB_.PCI0._UID".into(), &0x1234u16).to_aml_bytes(&mut aml);
1718 assert_eq!(
1719 aml,
1720 [
1721 0x08, /* NameOp */
1722 0x2F, /* MultiNamePrefix */
1723 0x03, /* 3 name parts */
1724 0x5F, 0x53, 0x42, 0x5F, /* _SB_ */
1725 0x50, 0x43, 0x49, 0x30, /* PCI0 */
1726 0x5F, 0x55, 0x49, 0x44, /* _UID */
1727 0x0b, /* WordPrefix */
1728 0x34, 0x12
1729 ]
1730 );
1731 }
1732
1733 #[test]
test_string()1734 fn test_string() {
1735 let mut aml = Vec::new();
1736 (&"ACPI" as &dyn Aml).to_aml_bytes(&mut aml);
1737 assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
1738 aml.clear();
1739 "ACPI".to_owned().to_aml_bytes(&mut aml);
1740 assert_eq!(aml, [0x0d, b'A', b'C', b'P', b'I', 0]);
1741 }
1742
1743 #[test]
test_method()1744 fn test_method() {
1745 let mut aml = Vec::new();
1746 Method::new("_STA".into(), 0, false, vec![&Return::new(&0xfu8)]).to_aml_bytes(&mut aml);
1747 assert_eq!(
1748 aml,
1749 [0x14, 0x09, 0x5F, 0x53, 0x54, 0x41, 0x00, 0xA4, 0x0A, 0x0F]
1750 );
1751 }
1752
1753 #[test]
test_field()1754 fn test_field() {
1755 /*
1756 Field (PRST, ByteAcc, NoLock, WriteAsZeros)
1757 {
1758 Offset (0x04),
1759 CPEN, 1,
1760 CINS, 1,
1761 CRMV, 1,
1762 CEJ0, 1,
1763 Offset (0x05),
1764 CCMD, 8
1765 }
1766
1767 */
1768
1769 let field_data = [
1770 0x5Bu8, 0x81, 0x23, 0x50, 0x52, 0x53, 0x54, 0x41, 0x00, 0x20, 0x43, 0x50, 0x45, 0x4E,
1771 0x01, 0x43, 0x49, 0x4E, 0x53, 0x01, 0x43, 0x52, 0x4D, 0x56, 0x01, 0x43, 0x45, 0x4A,
1772 0x30, 0x01, 0x00, 0x04, 0x43, 0x43, 0x4D, 0x44, 0x08,
1773 ];
1774 let mut aml = Vec::new();
1775
1776 Field::new(
1777 "PRST".into(),
1778 FieldAccessType::Byte,
1779 FieldUpdateRule::WriteAsZeroes,
1780 vec![
1781 FieldEntry::Reserved(32),
1782 FieldEntry::Named(*b"CPEN", 1),
1783 FieldEntry::Named(*b"CINS", 1),
1784 FieldEntry::Named(*b"CRMV", 1),
1785 FieldEntry::Named(*b"CEJ0", 1),
1786 FieldEntry::Reserved(4),
1787 FieldEntry::Named(*b"CCMD", 8),
1788 ],
1789 )
1790 .to_aml_bytes(&mut aml);
1791 assert_eq!(aml, &field_data[..]);
1792
1793 /*
1794 Field (PRST, DWordAcc, NoLock, Preserve)
1795 {
1796 CSEL, 32,
1797 Offset (0x08),
1798 CDAT, 32
1799 }
1800 */
1801
1802 let field_data = [
1803 0x5Bu8, 0x81, 0x12, 0x50, 0x52, 0x53, 0x54, 0x03, 0x43, 0x53, 0x45, 0x4C, 0x20, 0x00,
1804 0x20, 0x43, 0x44, 0x41, 0x54, 0x20,
1805 ];
1806 aml.clear();
1807
1808 Field::new(
1809 "PRST".into(),
1810 FieldAccessType::DWord,
1811 FieldUpdateRule::Preserve,
1812 vec![
1813 FieldEntry::Named(*b"CSEL", 32),
1814 FieldEntry::Reserved(32),
1815 FieldEntry::Named(*b"CDAT", 32),
1816 ],
1817 )
1818 .to_aml_bytes(&mut aml);
1819 assert_eq!(aml, &field_data[..]);
1820 }
1821
1822 #[test]
test_op_region()1823 fn test_op_region() {
1824 /*
1825 OperationRegion (PRST, SystemIO, 0x0CD8, 0x0C)
1826 */
1827 let op_region_data = [
1828 0x5Bu8, 0x80, 0x50, 0x52, 0x53, 0x54, 0x01, 0x0B, 0xD8, 0x0C, 0x0A, 0x0C,
1829 ];
1830 let mut aml = Vec::new();
1831
1832 OpRegion::new("PRST".into(), OpRegionSpace::SystemIO, 0xcd8, 0xc).to_aml_bytes(&mut aml);
1833 assert_eq!(aml, &op_region_data[..]);
1834 }
1835
1836 #[test]
test_arg_if()1837 fn test_arg_if() {
1838 /*
1839 Method(TEST, 1, NotSerialized) {
1840 If (Arg0 == Zero) {
1841 Return(One)
1842 }
1843 Return(Zero)
1844 }
1845 */
1846 let arg_if_data = [
1847 0x14, 0x0F, 0x54, 0x45, 0x53, 0x54, 0x01, 0xA0, 0x06, 0x93, 0x68, 0x00, 0xA4, 0x01,
1848 0xA4, 0x00,
1849 ];
1850 let mut aml = Vec::new();
1851
1852 Method::new(
1853 "TEST".into(),
1854 1,
1855 false,
1856 vec![
1857 &If::new(&Equal::new(&Arg(0), &ZERO), vec![&Return::new(&ONE)]),
1858 &Return::new(&ZERO),
1859 ],
1860 )
1861 .to_aml_bytes(&mut aml);
1862 assert_eq!(aml, &arg_if_data);
1863 }
1864
1865 #[test]
test_local_if()1866 fn test_local_if() {
1867 /*
1868 Method(TEST, 0, NotSerialized) {
1869 Local0 = One
1870 If (Local0 == Zero) {
1871 Return(One)
1872 }
1873 Return(Zero)
1874 }
1875 */
1876 let local_if_data = [
1877 0x14, 0x12, 0x54, 0x45, 0x53, 0x54, 0x00, 0x70, 0x01, 0x60, 0xA0, 0x06, 0x93, 0x60,
1878 0x00, 0xA4, 0x01, 0xA4, 0x00,
1879 ];
1880 let mut aml = Vec::new();
1881
1882 Method::new(
1883 "TEST".into(),
1884 0,
1885 false,
1886 vec![
1887 &Store::new(&Local(0), &ONE),
1888 &If::new(&Equal::new(&Local(0), &ZERO), vec![&Return::new(&ONE)]),
1889 &Return::new(&ZERO),
1890 ],
1891 )
1892 .to_aml_bytes(&mut aml);
1893 assert_eq!(aml, &local_if_data);
1894 }
1895
1896 #[test]
test_mutex()1897 fn test_mutex() {
1898 /*
1899 Device (_SB_.MHPC)
1900 {
1901 Name (_HID, EisaId("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
1902 Mutex (MLCK, 0x00)
1903 Method (TEST, 0, NotSerialized)
1904 {
1905 Acquire (MLCK, 0xFFFF)
1906 Local0 = One
1907 Release (MLCK)
1908 }
1909 }
1910 */
1911
1912 let mutex_data = [
1913 0x5B, 0x82, 0x33, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
1914 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x5B, 0x01, 0x4D, 0x4C, 0x43, 0x4B,
1915 0x00, 0x14, 0x17, 0x54, 0x45, 0x53, 0x54, 0x00, 0x5B, 0x23, 0x4D, 0x4C, 0x43, 0x4B,
1916 0xFF, 0xFF, 0x70, 0x01, 0x60, 0x5B, 0x27, 0x4D, 0x4C, 0x43, 0x4B,
1917 ];
1918 let mut aml = Vec::new();
1919
1920 let mutex = Mutex::new("MLCK".into(), 0);
1921 Device::new(
1922 "_SB_.MHPC".into(),
1923 vec![
1924 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
1925 &mutex,
1926 &Method::new(
1927 "TEST".into(),
1928 0,
1929 false,
1930 vec![
1931 &Acquire::new("MLCK".into(), 0xffff),
1932 &Store::new(&Local(0), &ONE),
1933 &Release::new("MLCK".into()),
1934 ],
1935 ),
1936 ],
1937 )
1938 .to_aml_bytes(&mut aml);
1939 assert_eq!(aml, &mutex_data[..]);
1940 }
1941
1942 #[test]
test_notify()1943 fn test_notify() {
1944 /*
1945 Device (_SB.MHPC)
1946 {
1947 Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
1948 Method (TEST, 0, NotSerialized)
1949 {
1950 Notify (MHPC, One) // Device Check
1951 }
1952 }
1953 */
1954 let notify_data = [
1955 0x5B, 0x82, 0x21, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
1956 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x0C, 0x54, 0x45, 0x53, 0x54,
1957 0x00, 0x86, 0x4D, 0x48, 0x50, 0x43, 0x01,
1958 ];
1959 let mut aml = Vec::new();
1960
1961 Device::new(
1962 "_SB_.MHPC".into(),
1963 vec![
1964 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
1965 &Method::new(
1966 "TEST".into(),
1967 0,
1968 false,
1969 vec![&Notify::new(&Path::new("MHPC"), &ONE)],
1970 ),
1971 ],
1972 )
1973 .to_aml_bytes(&mut aml);
1974 assert_eq!(aml, ¬ify_data[..]);
1975 }
1976
1977 #[test]
test_while()1978 fn test_while() {
1979 /*
1980 Device (_SB.MHPC)
1981 {
1982 Name (_HID, EisaId ("PNP0A06") /* Generic Container Device */) // _HID: Hardware ID
1983 Method (TEST, 0, NotSerialized)
1984 {
1985 Local0 = Zero
1986 While ((Local0 < 0x04))
1987 {
1988 Local0 += One
1989 }
1990 }
1991 }
1992 */
1993
1994 let while_data = [
1995 0x5B, 0x82, 0x28, 0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x4D, 0x48, 0x50, 0x43, 0x08, 0x5F,
1996 0x48, 0x49, 0x44, 0x0C, 0x41, 0xD0, 0x0A, 0x06, 0x14, 0x13, 0x54, 0x45, 0x53, 0x54,
1997 0x00, 0x70, 0x00, 0x60, 0xA2, 0x09, 0x95, 0x60, 0x0A, 0x04, 0x72, 0x60, 0x01, 0x60,
1998 ];
1999 let mut aml = Vec::new();
2000
2001 Device::new(
2002 "_SB_.MHPC".into(),
2003 vec![
2004 &Name::new("_HID".into(), &EISAName::new("PNP0A06")),
2005 &Method::new(
2006 "TEST".into(),
2007 0,
2008 false,
2009 vec![
2010 &Store::new(&Local(0), &ZERO),
2011 &While::new(
2012 &LessThan::new(&Local(0), &4usize),
2013 vec![&Add::new(&Local(0), &Local(0), &ONE)],
2014 ),
2015 ],
2016 ),
2017 ],
2018 )
2019 .to_aml_bytes(&mut aml);
2020 assert_eq!(aml, &while_data[..])
2021 }
2022
2023 #[test]
test_method_call()2024 fn test_method_call() {
2025 /*
2026 Method (TST1, 1, NotSerialized)
2027 {
2028 TST2 (One, One)
2029 }
2030
2031 Method (TST2, 2, NotSerialized)
2032 {
2033 TST1 (One)
2034 }
2035 */
2036 let test_data = [
2037 0x14, 0x0C, 0x54, 0x53, 0x54, 0x31, 0x01, 0x54, 0x53, 0x54, 0x32, 0x01, 0x01, 0x14,
2038 0x0B, 0x54, 0x53, 0x54, 0x32, 0x02, 0x54, 0x53, 0x54, 0x31, 0x01,
2039 ];
2040
2041 let mut methods = Vec::new();
2042 Method::new(
2043 "TST1".into(),
2044 1,
2045 false,
2046 vec![&MethodCall::new("TST2".into(), vec![&ONE, &ONE])],
2047 )
2048 .to_aml_bytes(&mut methods);
2049 Method::new(
2050 "TST2".into(),
2051 2,
2052 false,
2053 vec![&MethodCall::new("TST1".into(), vec![&ONE])],
2054 )
2055 .to_aml_bytes(&mut methods);
2056 assert_eq!(&methods[..], &test_data[..])
2057 }
2058
2059 #[test]
test_buffer()2060 fn test_buffer() {
2061 /*
2062 Name (_MAT, Buffer (0x08) // _MAT: Multiple APIC Table Entry
2063 {
2064 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 /* ........ */
2065 })
2066 */
2067 let buffer_data = [
2068 0x08, 0x5F, 0x4D, 0x41, 0x54, 0x11, 0x0B, 0x0A, 0x08, 0x00, 0x08, 0x00, 0x00, 0x01,
2069 0x00, 0x00, 0x00,
2070 ];
2071 let mut aml = Vec::new();
2072
2073 Name::new(
2074 "_MAT".into(),
2075 &Buffer::new(vec![0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00]),
2076 )
2077 .to_aml_bytes(&mut aml);
2078 assert_eq!(aml, &buffer_data[..])
2079 }
2080 }
2081