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