1mod display;
2pub mod resource_template;
3
4use alloc::{
5 boxed::Box,
6 collections::{BTreeMap, BTreeSet},
7 format,
8 string::String,
9 vec::Vec,
10};
11use resource_template::ResourceTemplate;
12use tracing::trace;
13
14#[derive(Debug, Clone)]
15#[allow(dead_code)]
16pub enum AmlParseError {
17 UnexpectedEndOfCode,
18 InvalidPkgLengthLead,
19 InvalidTermArgInPackage,
20 RemainingBytes(usize),
21 CannotMoveBackward,
22 InvalidTarget(u8),
23 NameObjectNotContainingDataObject,
24 UnalignedFieldElementOffset,
25 InvalidAccessType,
26 InvalidExtendedAttrib(u8),
27 InvalidFieldUpdateRule,
28 ReservedFieldSet,
29 ResourceTemplateReservedTag,
30 ReservedValue,
31 InvalidResourceTemplate,
32}
33
34pub fn parse_aml(code: &[u8]) -> Result<AmlCode, AmlParseError> {
35 let mut methods = BTreeMap::new();
36 let mut names = BTreeSet::new();
37 let mut parser = Parser {
38 code,
39 pos: 0,
40 state: State::new(&mut methods, &mut names),
41 };
42 parser.parse_root()
43}
44
45#[derive(Debug, Clone)]
46pub struct AmlCode {
47 pub(super) term_list: Vec<AmlTerm>,
48}
49
50#[derive(Debug, Clone)]
51pub enum IntegerData {
52 ConstZero,
53 ConstOne,
54 ConstOnes,
55 ByteConst(u8),
56 WordConst(u16),
57 DWordConst(u32),
58 QWordConst(u64),
59}
60
61#[allow(dead_code)]
62impl IntegerData {
63 #[inline]
64 pub fn as_u8(&self) -> Option<u8> {
65 match self {
66 Self::ByteConst(byte) => Some(*byte),
67 Self::ConstZero => Some(0),
68 Self::ConstOne => Some(1),
69 Self::ConstOnes => Some(0xFF),
70 _ => None,
71 }
72 }
73
74 #[inline]
75 pub fn as_u16(&self) -> Option<u16> {
76 match self {
77 Self::WordConst(word) => Some(*word),
78 Self::ConstOnes => Some(0xFFFF),
79 _ => self.as_u8().map(|byte| byte.into()),
80 }
81 }
82
83 #[inline]
84 pub fn as_u32(&self) -> Option<u32> {
85 match self {
86 Self::DWordConst(dword) => Some(*dword),
87 Self::ConstOnes => Some(0xFFFFFFFF),
88 _ => self.as_u16().map(|word| word.into()),
89 }
90 }
91
92 #[inline]
93 pub fn as_u64(&self) -> u64 {
94 match self {
95 Self::QWordConst(qword) => *qword,
96 Self::ConstOnes => 0xFFFFFFFFFFFFFFFF,
97 _ => self
98 .as_u32()
99 .map(|dword| dword.into())
100 .expect("Can't fail, all branches are covered"),
101 }
102 }
103}
104
105#[derive(Debug, Clone)]
110pub enum UnresolvedDataObject {
111 Integer(IntegerData),
112 Buffer(Buffer),
113 ResourceTemplate(ResourceTemplate),
114 Package(u8, Vec<PackageElement<UnresolvedDataObject>>),
115 VarPackage(Box<TermArg>, Vec<PackageElement<UnresolvedDataObject>>),
116 String(String),
117 EisaId(String),
118}
119
120#[derive(Debug, Clone)]
123pub enum PackageElement<D> {
124 DataObject(D),
125 Name(String),
126}
127
128#[allow(dead_code)]
129impl<T> PackageElement<T> {
130 pub fn as_data(&self) -> Option<&T> {
131 match self {
132 Self::DataObject(data) => Some(data),
133 _ => None,
134 }
135 }
136
137 pub fn as_name(&self) -> Option<&str> {
138 match self {
139 Self::Name(name) => Some(name),
140 _ => None,
141 }
142 }
143}
144
145#[derive(Debug, Clone)]
146pub struct Buffer {
147 pub(super) size: Box<TermArg>,
148 pub(super) data: Vec<u8>,
149}
150
151#[derive(Debug, Clone)]
152pub enum AmlTerm {
153 Scope(ScopeObj),
154 Region(RegionObj),
155 Field(FieldDef),
156 IndexField(IndexFieldDef),
157 Device(ScopeObj),
158 Processor(ProcessorDeprecated),
159 PowerResource(PowerResource),
160 Method(MethodObj),
161 NameObj(String, UnresolvedDataObject),
162 Alias(String, String),
163 ToHexString(TermArg, Box<Target>),
164 ToBuffer(TermArg, Box<Target>),
165 ToDecimalString(TermArg, Box<Target>),
166 ToInteger(TermArg, Box<Target>),
167 Mid(TermArg, TermArg, TermArg, Box<Target>),
168 Add(TermArg, TermArg, Box<Target>),
169 Concat(TermArg, TermArg, Box<Target>),
170 Subtract(TermArg, TermArg, Box<Target>),
171 Multiply(TermArg, TermArg, Box<Target>),
172 Divide(TermArg, TermArg, Box<Target>, Box<Target>),
173 ShiftLeft(TermArg, TermArg, Box<Target>),
174 ShiftRight(TermArg, TermArg, Box<Target>),
175 And(TermArg, TermArg, Box<Target>),
176 Nand(TermArg, TermArg, Box<Target>),
177 Or(TermArg, TermArg, Box<Target>),
178 Nor(TermArg, TermArg, Box<Target>),
179 Xor(TermArg, TermArg, Box<Target>),
180 Not(TermArg, Box<Target>),
181 SizeOf(Box<Target>),
182 Store(TermArg, Box<Target>),
183 RefOf(Box<Target>),
184 Increment(Box<Target>),
185 Decrement(Box<Target>),
186 While(PredicateBlock),
187 If(PredicateBlock),
188 Else(Vec<AmlTerm>),
189 Noop,
190 Return(TermArg),
191 Break,
192 LAnd(TermArg, TermArg),
193 LOr(TermArg, TermArg),
194 LNot(TermArg),
195 LNotEqual(TermArg, TermArg),
196 LLessEqual(TermArg, TermArg),
197 LGreaterEqual(TermArg, TermArg),
198 LEqual(TermArg, TermArg),
199 LGreater(TermArg, TermArg),
200 LLess(TermArg, TermArg),
201 FindSetLeftBit(TermArg, Box<Target>),
202 FindSetRightBit(TermArg, Box<Target>),
203 DerefOf(TermArg),
204 ConcatRes(TermArg, TermArg, Box<Target>),
205 Mod(TermArg, TermArg, Box<Target>),
206 Notify(Box<Target>, TermArg),
207 Index(TermArg, TermArg, Box<Target>),
208 Mutex(String, u8),
209 Event(String),
210 CondRefOf(Box<Target>, Box<Target>),
211 CreateFieldOp(TermArg, TermArg, TermArg, String),
212 Acquire(Box<Target>, u16),
213 Signal(Box<Target>),
214 Wait(Box<Target>, TermArg),
215 Reset(Box<Target>),
216 Release(Box<Target>),
217 Stall(TermArg),
218 Sleep(TermArg),
219 CreateDWordField(TermArg, TermArg, String),
220 CreateWordField(TermArg, TermArg, String),
221 CreateByteField(TermArg, TermArg, String),
222 CreateBitField(TermArg, TermArg, String),
223 CreateQWordField(TermArg, TermArg, String),
224 MethodCall(String, Vec<TermArg>),
225 ObjectType(Box<Target>),
226}
227
228#[derive(Debug, Clone)]
229pub enum TermArg {
230 Expression(Box<AmlTerm>),
231 DataObject(UnresolvedDataObject),
232 Arg(u8),
233 Local(u8),
234 Name(String),
235}
236
237#[derive(Debug, Clone)]
238pub enum Target {
239 None,
240 Arg(u8),
241 Local(u8),
242 Name(String),
243 Debug,
244 DerefOf(TermArg),
245 RefOf(Box<Target>),
246 Index(TermArg, TermArg, Box<Target>),
247}
248
249#[derive(Debug, Clone)]
250pub enum ScopeType {
251 Device,
252 Scope,
253}
254
255#[derive(Debug, Clone)]
256pub struct ScopeObj {
257 pub(super) ty: ScopeType,
258 pub(super) name: String,
259 pub(super) term_list: Vec<AmlTerm>,
260}
261
262impl ScopeObj {
263 fn parse(parser: &mut Parser, ty: ScopeType) -> Result<Self, AmlParseError> {
264 let mut inner = parser.get_inner_parser()?;
265 let name = inner.parse_name()?;
266
267 trace!("scope name: {}", name);
268 let term_list = inner.parse_term_list()?;
269 inner.check_empty()?;
270 Ok(Self {
271 ty,
272 name,
273 term_list,
274 })
275 }
276}
277
278#[derive(Debug, Clone)]
279#[allow(clippy::upper_case_acronyms)]
280#[allow(non_camel_case_types)]
281pub enum RegionSpace {
282 SystemMemory,
283 SystemIO,
284 PCI_Config,
285 EmbeddedControl,
286 SMBus,
287 SystemCMOS,
288 PciBarTarget,
289 IPMI,
290 GeneralPurposeIO,
291 GenericSerialBus,
292 PCC,
293 FFixedHW,
295 Other(u8),
296}
297
298impl From<u8> for RegionSpace {
299 fn from(space: u8) -> Self {
300 match space {
301 0 => Self::SystemMemory,
302 1 => Self::SystemIO,
303 2 => Self::PCI_Config,
304 3 => Self::EmbeddedControl,
305 4 => Self::SMBus,
306 5 => Self::SystemCMOS,
307 6 => Self::PciBarTarget,
308 7 => Self::IPMI,
309 8 => Self::GeneralPurposeIO,
310 9 => Self::GenericSerialBus,
311 10 => Self::PCC,
312 _ => Self::Other(space),
313 }
314 }
315}
316
317#[derive(Debug, Clone)]
318pub struct RegionObj {
319 pub(super) name: String,
320 pub(super) region_space: RegionSpace,
321 pub(super) region_offset: TermArg,
322 pub(super) region_length: TermArg,
323}
324
325impl RegionObj {
326 fn parse(parser: &mut Parser) -> Result<Self, AmlParseError> {
327 let name = parser.parse_name()?;
328 trace!("region name: {}", name);
329 let region_space = parser.get_next_byte()?.into();
330 let region_offset = parser.parse_term_arg()?;
331 trace!("region offset: {:?}", region_offset);
332 let region_length = parser.parse_term_arg()?;
333 trace!("region length: {:?}", region_length);
334 Ok(Self {
335 name,
336 region_space,
337 region_offset,
338 region_length,
339 })
340 }
341}
342
343#[derive(Debug, Clone)]
344pub enum AccessType {
345 Any,
347 Byte,
348 Word,
349 DWord,
350 QWord,
351 Buffer,
352}
353
354impl TryFrom<u8> for AccessType {
355 type Error = AmlParseError;
356
357 fn try_from(value: u8) -> Result<Self, Self::Error> {
358 match value & 0b1111 {
359 0 => Ok(Self::Any),
360 1 => Ok(Self::Byte),
361 2 => Ok(Self::Word),
362 3 => Ok(Self::DWord),
363 4 => Ok(Self::QWord),
364 5 => Ok(Self::Buffer),
365 _ => Err(AmlParseError::InvalidAccessType),
366 }
367 }
368}
369
370#[derive(Debug, Clone)]
371pub enum FieldUpdateRule {
372 Preserve,
373 WriteAsOnes,
374 WriteAsZeros,
375}
376
377impl TryFrom<u8> for FieldUpdateRule {
378 type Error = AmlParseError;
379
380 fn try_from(value: u8) -> Result<Self, Self::Error> {
381 match value & 0b111 {
382 0 => Ok(Self::Preserve),
383 1 => Ok(Self::WriteAsOnes),
384 2 => Ok(Self::WriteAsZeros),
385 _ => Err(AmlParseError::InvalidFieldUpdateRule),
386 }
387 }
388}
389
390#[derive(Debug, Clone)]
391pub struct FieldDef {
392 pub(super) name: String,
393 pub(super) access_type: AccessType,
394 pub(super) need_lock: bool,
395 pub(super) update_rule: FieldUpdateRule,
396 pub(super) fields: Vec<FieldElement>,
397}
398
399impl FieldDef {
400 fn parse(parser: &mut Parser) -> Result<Self, AmlParseError> {
401 let mut inner = parser.get_inner_parser()?;
402 let name = inner.parse_name()?;
403 trace!("field name: {}", name);
404 let (flags, field_list) = inner.parse_fields_list_and_flags()?;
405
406 let access_type = flags.try_into()?;
407 let need_lock = (flags & (1 << 4)) != 0;
408 let update_rule = (flags >> 5).try_into()?;
409
410 Ok(Self {
411 name,
412 access_type,
413 need_lock,
414 update_rule,
415 fields: field_list,
416 })
417 }
418}
419
420#[derive(Debug, Clone)]
421pub struct IndexFieldDef {
422 pub(super) name: String,
423 pub(super) index_name: String,
424 pub(super) access_type: AccessType,
425 pub(super) need_lock: bool,
426 pub(super) update_rule: FieldUpdateRule,
427 pub(super) fields: Vec<FieldElement>,
428}
429
430impl IndexFieldDef {
431 fn parse(parser: &mut Parser) -> Result<Self, AmlParseError> {
432 let mut inner = parser.get_inner_parser()?;
433 let name = inner.parse_name()?;
434 trace!("index-field name: {}", name);
435 let index_name = inner.parse_name()?;
436 trace!("index-field index_name: {}", index_name);
437 let (flags, field_list) = inner.parse_fields_list_and_flags()?;
438
439 let access_type = flags.try_into()?;
440 let need_lock = (flags & (1 << 4)) != 0;
441 let update_rule = (flags >> 5).try_into()?;
442
443 Ok(Self {
444 name,
445 index_name,
446 access_type,
447 need_lock,
448 update_rule,
449 fields: field_list,
450 })
451 }
452}
453
454#[derive(Debug, Clone)]
455pub enum AccessAttrib {
456 ByteValue(u8),
458
459 Bytes(u8),
460 RawBytes(u8),
461 RawProcessBytes(u8),
462 Quick,
463 SendRecv,
464 Byte,
465 Word,
466 Block,
467 ProcessCall,
468 BlockProcessCall,
469}
470
471#[derive(Debug, Clone)]
472pub enum FieldConnection {
473 Buffer(Buffer),
474 Name(String),
475}
476
477#[derive(Debug, Clone)]
478pub enum FieldElement {
479 Offset(usize),
480 Named(String, usize),
481 Access(AccessType, AccessAttrib),
482 Connection(FieldConnection),
483}
484
485#[derive(Debug, Clone)]
486pub struct MethodObj {
487 pub(super) name: String,
488 pub(super) num_args: u8,
489 pub(super) is_serialized: bool,
490 pub(super) sync_level: u8,
491 pub(super) term_list: Vec<AmlTerm>,
492}
493
494impl MethodObj {
495 fn parse(parser: &mut Parser) -> Result<Self, AmlParseError> {
496 let mut inner = parser.get_inner_parser()?;
497 let name = inner.parse_name()?;
498 trace!("method name: {}", name);
499 let flags = inner.get_next_byte()?;
500 trace!("method flags: {:x}", flags);
501 let term_list = inner.parse_term_list()?;
502 inner.check_empty()?;
503
504 let num_args = flags & 0b111;
505 let is_serialized = (flags & (1 << 3)) != 0;
506 let sync_level = (flags >> 4) & 0b1111;
507
508 Ok(Self {
509 name,
510 num_args,
511 is_serialized,
512 sync_level,
513 term_list,
514 })
515 }
516}
517
518#[derive(Debug, Clone)]
519pub struct PredicateBlock {
520 predicate: TermArg,
521 term_list: Vec<AmlTerm>,
522}
523
524impl PredicateBlock {
525 fn parse(parser: &mut Parser) -> Result<Self, AmlParseError> {
526 let mut inner = parser.get_inner_parser()?;
527
528 let predicate = inner.parse_term_arg()?;
529 trace!("pred predicate: {:?}", predicate);
530 let term_list = inner.parse_term_list()?;
531 inner.check_empty()?;
532
533 Ok(Self {
534 predicate,
535 term_list,
536 })
537 }
538}
539
540#[derive(Debug, Clone)]
541pub struct ProcessorDeprecated {
542 pub(super) name: String,
543 pub(super) unk1: u8,
544 pub(super) unk2: u32,
545 pub(super) unk3: u8,
546 pub(super) term_list: Vec<AmlTerm>,
547}
548
549impl ProcessorDeprecated {
550 fn parse(parser: &mut Parser) -> Result<Self, AmlParseError> {
551 let mut inner = parser.get_inner_parser()?;
552 let name = inner.parse_name()?;
553 trace!("processor name: {}", name);
554 let unk1 = inner.get_next_byte()?;
555 trace!("processor unk1: {:x}", unk1);
556 let unk2 = u32::from_le_bytes([
557 inner.get_next_byte()?,
558 inner.get_next_byte()?,
559 inner.get_next_byte()?,
560 inner.get_next_byte()?,
561 ]);
562 trace!("processor unk2: {:x}", unk2);
563 let unk3 = inner.get_next_byte()?;
564 trace!("processor unk3: {:x}", unk3);
565 let term_list = inner.parse_term_list()?;
566 inner.check_empty()?;
567 Ok(Self {
568 name,
569 unk1,
570 unk2,
571 unk3,
572 term_list,
573 })
574 }
575}
576
577#[derive(Debug, Clone)]
578pub struct PowerResource {
579 pub(super) name: String,
580 pub(super) system_level: u8,
581 pub(super) resource_order: u16,
582 pub(super) term_list: Vec<AmlTerm>,
583}
584
585impl PowerResource {
586 fn parse(parser: &mut Parser) -> Result<Self, AmlParseError> {
587 let mut inner = parser.get_inner_parser()?;
588 let name = inner.parse_name()?;
589 trace!("power-resource name: {}", name);
590 let system_level = inner.get_next_byte()?;
591 trace!("power-resource system_level: {:x}", system_level);
592 let resource_order = u16::from_le_bytes([inner.get_next_byte()?, inner.get_next_byte()?]);
593 trace!("power-resource resource_order: {:x}", resource_order);
594 let term_list = inner.parse_term_list()?;
595 inner.check_empty()?;
596 Ok(Self {
597 name,
598 system_level,
599 resource_order,
600 term_list,
601 })
602 }
603}
604
605type StateMethodsList<'a> = &'a mut BTreeMap<String, usize>;
606type StateNamesList<'a> = &'a mut BTreeSet<String>;
607
608#[derive(Debug)]
610struct State<'a> {
611 methods: StateMethodsList<'a>,
613 names: StateNamesList<'a>,
615}
616
617impl<'a> State<'a> {
618 fn new(methods: StateMethodsList<'a>, names: StateNamesList<'a>) -> State<'a> {
619 State { methods, names }
620 }
621
622 fn clone_state(&mut self) -> State<'_> {
624 State {
625 methods: self.methods,
626 names: self.names,
627 }
628 }
629
630 fn find_name(&self, name: &str) -> bool {
631 trace!("finding name {name:?}, {:?}", self.names);
632 let short_name = &name[name.len() - 4..];
633 self.names.contains(name) || self.names.contains(short_name)
634 }
635
636 fn find_method(&self, name: &str) -> Option<usize> {
637 trace!("finding method {name:?}");
638 let method_name = &name[name.len() - 4..];
641 trace!("methods: {:?}", self.methods);
642 self.methods.get(method_name).copied()
643 }
644
645 fn add_method(&mut self, name: &str, arg_count: usize) {
646 trace!("adding method {name:?}");
647 let method_name = &name[name.len() - 4..];
648 self.methods.insert(String::from(method_name), arg_count);
649 }
650
651 fn add_name(&mut self, name: String) {
652 trace!("adding name {name:?}");
653 self.names.insert(name);
654 }
655}
656
657pub struct Parser<'a> {
658 code: &'a [u8],
659 pos: usize,
660 state: State<'a>,
661}
662
663impl Parser<'_> {
664 fn remaining_bytes(&self) -> usize {
665 self.code.len() - self.pos
666 }
667
668 fn get_next_byte(&mut self) -> Result<u8, AmlParseError> {
669 if self.pos >= self.code.len() {
670 return Err(AmlParseError::UnexpectedEndOfCode);
671 }
672 let byte = self.code[self.pos];
673 self.pos += 1;
674 Ok(byte)
675 }
676
677 fn peek_next_byte(&self) -> Result<u8, AmlParseError> {
678 if self.pos >= self.code.len() {
679 return Err(AmlParseError::UnexpectedEndOfCode);
680 }
681 Ok(self.code[self.pos])
682 }
683
684 fn forward(&mut self, n: usize) -> Result<(), AmlParseError> {
685 if self.pos + n > self.code.len() {
686 return Err(AmlParseError::UnexpectedEndOfCode);
687 }
688 self.pos += n;
689 Ok(())
690 }
691
692 fn backward(&mut self, n: usize) -> Result<(), AmlParseError> {
693 if self.pos == 0 {
694 return Err(AmlParseError::CannotMoveBackward);
695 }
696 self.pos -= n;
697 Ok(())
698 }
699
700 fn get_pkg_length(&mut self) -> Result<usize, AmlParseError> {
701 let lead_byte = self.get_next_byte()?;
702 let following_bytes = lead_byte >> 6;
703
704 trace!("pkglen: lead byte: {:x}", lead_byte);
705
706 let mut length: usize;
707 if following_bytes == 0 {
708 return Ok((lead_byte & 0b0011_1111) as usize - 1);
710 } else {
711 if (lead_byte >> 4) & 0b11 != 0 {
713 return Err(AmlParseError::InvalidPkgLengthLead);
714 }
715 length = lead_byte as usize & 0b0000_1111;
716 }
717 trace!("len now start: {:x}", length);
718
719 for i in 0..following_bytes {
720 let byte = self.get_next_byte()?;
721 length |= (byte as usize) << (8 * i + 4);
722 trace!("len now: {:x}", length);
723 }
724 Ok(length - following_bytes as usize - 1)
726 }
727
728 fn get_inner_parser(&mut self) -> Result<Parser<'_>, AmlParseError> {
729 let pkg_length = self.get_pkg_length()?;
730 trace!("inner pkg length: {:x}", pkg_length);
731
732 let inner_parser = Parser {
733 code: &self.code[self.pos..self.pos + pkg_length],
734 pos: 0,
735 state: self.state.clone_state(),
736 };
737 self.pos += pkg_length;
738 Ok(inner_parser)
739 }
740
741 fn clone_parser(&mut self) -> Parser<'_> {
743 Parser {
744 code: self.code,
745 pos: self.pos,
746 state: self.state.clone_state(),
747 }
748 }
749
750 fn check_empty(&self) -> Result<(), AmlParseError> {
751 if self.pos != self.code.len() {
752 return Err(AmlParseError::RemainingBytes(self.code.len() - self.pos));
753 }
754 Ok(())
755 }
756
757 fn parse_term(&mut self) -> Result<AmlTerm, AmlParseError> {
758 let byte = self.get_next_byte()?;
759 let term = self.try_parse_term(byte)?;
760
761 if let Some(term) = term {
762 Ok(term)
763 } else {
764 todo!("opcode: {:x}", byte)
765 }
766 }
767
768 fn predict_possible_args(&mut self, expect_data_after: bool, name: &str) -> usize {
769 let mut inner = self.clone_parser();
772
773 let mut n_args = 0;
774 for _ in 0..7 {
776 match inner.parse_term_arg() {
779 Ok(TermArg::Name(var_name)) => {
780 if name == var_name {
783 return 0;
784 }
785 }
786 Ok(TermArg::Expression(amlterm)) => match amlterm.as_ref() {
787 AmlTerm::Store(_, _)
788 | AmlTerm::Notify(_, _)
789 | AmlTerm::Release(_)
790 | AmlTerm::Reset(_)
791 | AmlTerm::Signal(_)
792 | AmlTerm::Wait(_, _)
793 | AmlTerm::Sleep(_)
794 | AmlTerm::Stall(_)
795 | AmlTerm::Acquire(_, _)
796 | AmlTerm::CondRefOf(_, _)
797 | AmlTerm::Break
798 | AmlTerm::Return(_)
799 | AmlTerm::Noop
800 | AmlTerm::Else(_)
801 | AmlTerm::If(_)
802 | AmlTerm::While(_)
803 | AmlTerm::Scope(_)
804 | AmlTerm::Region(_)
805 | AmlTerm::Field(_)
806 | AmlTerm::IndexField(_)
807 | AmlTerm::Device(_)
808 | AmlTerm::Processor(_)
809 | AmlTerm::PowerResource(_)
810 | AmlTerm::Method(_)
811 | AmlTerm::NameObj(_, _)
812 | AmlTerm::Alias(_, _)
813 | AmlTerm::ToHexString(_, _)
814 | AmlTerm::ToBuffer(_, _)
815 | AmlTerm::ToDecimalString(_, _)
816 | AmlTerm::ToInteger(_, _)
817 | AmlTerm::Mutex(_, _)
818 | AmlTerm::Event(_)
819 | AmlTerm::CreateDWordField(_, _, _)
820 | AmlTerm::CreateWordField(_, _, _)
821 | AmlTerm::CreateByteField(_, _, _)
822 | AmlTerm::CreateBitField(_, _, _)
823 | AmlTerm::CreateQWordField(_, _, _) => break,
824 AmlTerm::Add(_, _, t)
825 | AmlTerm::Concat(_, _, t)
826 | AmlTerm::Subtract(_, _, t)
827 | AmlTerm::Multiply(_, _, t)
828 | AmlTerm::Divide(_, _, _, t)
829 | AmlTerm::ShiftLeft(_, _, t)
830 | AmlTerm::ShiftRight(_, _, t)
831 | AmlTerm::And(_, _, t)
832 | AmlTerm::Nand(_, _, t)
833 | AmlTerm::Or(_, _, t)
834 | AmlTerm::Nor(_, _, t)
835 | AmlTerm::Xor(_, _, t)
836 | AmlTerm::Not(_, t)
837 | AmlTerm::ConcatRes(_, _, t)
838 | AmlTerm::Mod(_, _, t)
839 | AmlTerm::Index(_, _, t)
840 if !matches!(t.as_ref(), Target::None) =>
841 {
842 break;
844 }
845 _ => {}
846 },
847 Err(e) => {
848 if let AmlParseError::UnexpectedEndOfCode = e {
849 if n_args > 0 && expect_data_after && inner.remaining_bytes() == 0 {
851 n_args -= 1;
852 }
853 return n_args;
854 }
855 break;
856 }
857 _ => {}
858 }
859
860 n_args += 1;
861 }
862 n_args
863 }
864
865 fn try_parse_term(&mut self, opcode: u8) -> Result<Option<AmlTerm>, AmlParseError> {
866 trace!("opcode: {:x}", opcode);
867
868 let term = match opcode {
869 0x06 => {
870 let original_name = self.parse_name()?;
871 let aliased_name = self.parse_name()?;
872 self.state.add_name(aliased_name.clone());
873 self.state.add_name(original_name.clone());
874
875 AmlTerm::Alias(original_name, aliased_name)
876 }
877 0x08 => {
878 let name = self.parse_name()?;
879 self.state.add_name(name.clone());
880
881 let mut data_object = self
882 .try_parse_data_object()?
883 .ok_or(AmlParseError::NameObjectNotContainingDataObject)?;
884
885 if let UnresolvedDataObject::Integer(IntegerData::DWordConst(data)) = data_object {
886 if name.contains("ID") {
887 data_object = UnresolvedDataObject::EisaId(Self::parse_eisa_id(data))
888 }
889 }
890
891 AmlTerm::NameObj(name, data_object)
892 }
893 0x10 => AmlTerm::Scope(ScopeObj::parse(self, ScopeType::Scope)?),
894 0x14 => {
895 let method = MethodObj::parse(self)?;
896 self.state
897 .add_method(&method.name, method.num_args as usize);
898 AmlTerm::Method(method)
899 }
900 0x5b => {
901 let inner_opcode = self.get_next_byte()?;
903
904 match inner_opcode {
905 0x01 => AmlTerm::Mutex(self.parse_name()?, self.get_next_byte()?),
906 0x02 => AmlTerm::Event(self.parse_name()?),
907 0x12 => AmlTerm::CondRefOf(self.parse_target()?, self.parse_target()?),
908 0x13 => AmlTerm::CreateFieldOp(
909 self.parse_term_arg()?,
910 self.parse_term_arg()?,
911 self.parse_term_arg()?,
912 self.parse_name()?,
913 ),
914 0x21 => AmlTerm::Stall(self.parse_term_arg()?),
915 0x22 => AmlTerm::Sleep(self.parse_term_arg()?),
916 0x23 => AmlTerm::Acquire(
917 self.parse_target()?,
918 u16::from_le_bytes([self.get_next_byte()?, self.get_next_byte()?]),
919 ),
920 0x24 => AmlTerm::Signal(self.parse_target()?),
921 0x25 => AmlTerm::Wait(self.parse_target()?, self.parse_term_arg()?),
922 0x26 => AmlTerm::Reset(self.parse_target()?),
923 0x27 => AmlTerm::Release(self.parse_target()?),
924 0x80 => AmlTerm::Region(RegionObj::parse(self)?),
925 0x81 => AmlTerm::Field(FieldDef::parse(self)?),
926 0x82 => AmlTerm::Device(ScopeObj::parse(self, ScopeType::Device)?),
927 0x83 => AmlTerm::Processor(ProcessorDeprecated::parse(self)?),
928 0x84 => AmlTerm::PowerResource(PowerResource::parse(self)?),
929 0x86 => AmlTerm::IndexField(IndexFieldDef::parse(self)?),
930 _ => todo!("extra opcode: {:x}", inner_opcode),
931 }
932 }
933 0x70 => AmlTerm::Store(self.parse_term_arg()?, self.parse_target()?),
934 0x71 => AmlTerm::RefOf(self.parse_target()?),
935 0x72 => AmlTerm::Add(
936 self.parse_term_arg()?,
937 self.parse_term_arg()?,
938 self.parse_target()?,
939 ),
940 0x73 => AmlTerm::Concat(
941 self.parse_term_arg()?,
942 self.parse_term_arg()?,
943 self.parse_target()?,
944 ),
945 0x74 => AmlTerm::Subtract(
946 self.parse_term_arg()?,
947 self.parse_term_arg()?,
948 self.parse_target()?,
949 ),
950 0x75 => AmlTerm::Increment(self.parse_target()?),
951 0x76 => AmlTerm::Decrement(self.parse_target()?),
952 0x77 => AmlTerm::Multiply(
953 self.parse_term_arg()?,
954 self.parse_term_arg()?,
955 self.parse_target()?,
956 ),
957 0x78 => AmlTerm::Divide(
958 self.parse_term_arg()?,
959 self.parse_term_arg()?,
960 self.parse_target()?,
961 self.parse_target()?,
962 ),
963 0x79 => AmlTerm::ShiftLeft(
964 self.parse_term_arg_non_method_arg()?,
965 self.parse_term_arg()?,
966 self.parse_target()?,
967 ),
968 0x7A => AmlTerm::ShiftRight(
969 self.parse_term_arg_non_method_arg()?,
970 self.parse_term_arg()?,
971 self.parse_target()?,
972 ),
973 0x7B => AmlTerm::And(
974 self.parse_term_arg_non_method_arg()?,
975 self.parse_term_arg()?,
976 self.parse_target()?,
977 ),
978 0x7C => AmlTerm::Nand(
979 self.parse_term_arg()?,
980 self.parse_term_arg()?,
981 self.parse_target()?,
982 ),
983 0x7D => AmlTerm::Or(
984 self.parse_term_arg()?,
985 self.parse_term_arg()?,
986 self.parse_target()?,
987 ),
988 0x7E => AmlTerm::Nor(
989 self.parse_term_arg()?,
990 self.parse_term_arg()?,
991 self.parse_target()?,
992 ),
993 0x7F => AmlTerm::Xor(
994 self.parse_term_arg()?,
995 self.parse_term_arg()?,
996 self.parse_target()?,
997 ),
998 0x80 => AmlTerm::Not(self.parse_term_arg()?, self.parse_target()?),
999 0x81 => AmlTerm::FindSetLeftBit(self.parse_term_arg()?, self.parse_target()?),
1000 0x82 => AmlTerm::FindSetRightBit(self.parse_term_arg()?, self.parse_target()?),
1001 0x83 => AmlTerm::DerefOf(self.parse_term_arg()?),
1002 0x84 => AmlTerm::ConcatRes(
1003 self.parse_term_arg()?,
1004 self.parse_term_arg()?,
1005 self.parse_target()?,
1006 ),
1007 0x85 => AmlTerm::Mod(
1008 self.parse_term_arg()?,
1009 self.parse_term_arg()?,
1010 self.parse_target()?,
1011 ),
1012 0x86 => AmlTerm::Notify(self.parse_target()?, self.parse_term_arg()?),
1013 0x87 => AmlTerm::SizeOf(self.parse_target()?),
1014 0x88 => AmlTerm::Index(
1015 self.parse_term_arg()?,
1016 self.parse_term_arg()?,
1017 self.parse_target()?,
1018 ),
1019 0x8A..=0x8D | 0x8F => {
1020 let term1 = self.parse_term_arg()?;
1021 let term2 = self.parse_term_arg()?;
1022 let name = self.parse_name()?;
1023 self.state.add_name(name.clone());
1024
1025 match opcode {
1026 0x8A => AmlTerm::CreateDWordField(term1, term2, name),
1027 0x8B => AmlTerm::CreateWordField(term1, term2, name),
1028 0x8C => AmlTerm::CreateByteField(term1, term2, name),
1029 0x8D => AmlTerm::CreateBitField(term1, term2, name),
1030 0x8F => AmlTerm::CreateQWordField(term1, term2, name),
1031 _ => unreachable!(),
1032 }
1033 }
1034 0x8E => AmlTerm::ObjectType(self.parse_target()?),
1035 0x90 => AmlTerm::LAnd(self.parse_term_arg()?, self.parse_term_arg()?),
1036 0x91 => AmlTerm::LOr(self.parse_term_arg()?, self.parse_term_arg()?),
1037 0x92 => {
1038 let next_byte = self.peek_next_byte()?;
1039 match next_byte {
1040 0x93 => {
1041 self.forward(1)?;
1042 AmlTerm::LNotEqual(self.parse_term_arg()?, self.parse_term_arg()?)
1043 }
1044 0x94 => {
1045 self.forward(1)?;
1046 AmlTerm::LLessEqual(self.parse_term_arg()?, self.parse_term_arg()?)
1047 }
1048 0x95 => {
1049 self.forward(1)?;
1050 AmlTerm::LGreaterEqual(self.parse_term_arg()?, self.parse_term_arg()?)
1051 }
1052 _ => AmlTerm::LNot(self.parse_term_arg()?),
1053 }
1054 }
1055 0x93 => AmlTerm::LEqual(self.parse_term_arg()?, self.parse_term_arg()?),
1056 0x94 => AmlTerm::LGreater(self.parse_term_arg()?, self.parse_term_arg()?),
1057 0x95 => AmlTerm::LLess(self.parse_term_arg()?, self.parse_term_arg()?),
1058 0x96 => AmlTerm::ToBuffer(self.parse_term_arg()?, self.parse_target()?),
1059 0x97 => AmlTerm::ToDecimalString(self.parse_term_arg()?, self.parse_target()?),
1060 0x98 => AmlTerm::ToHexString(self.parse_term_arg()?, self.parse_target()?),
1061 0x99 => AmlTerm::ToInteger(self.parse_term_arg()?, self.parse_target()?),
1062 0x9E => AmlTerm::Mid(
1063 self.parse_term_arg()?,
1064 self.parse_term_arg()?,
1065 self.parse_term_arg()?,
1066 self.parse_target()?,
1067 ),
1068 0xA0 => AmlTerm::If(PredicateBlock::parse(self)?),
1069 0xA1 => {
1070 let mut inner = self.get_inner_parser()?;
1071 let else_list = inner.parse_term_list()?;
1072 inner.check_empty()?;
1073
1074 AmlTerm::Else(else_list)
1075 }
1076 0xA2 => AmlTerm::While(PredicateBlock::parse(self)?),
1077 0xA3 => AmlTerm::Noop,
1078 0xA4 => AmlTerm::Return(self.parse_term_arg_last()?),
1080 0xA5 => AmlTerm::Break,
1081 _ => {
1082 trace!("try parse name");
1083 self.backward(1)?;
1085 let Some(name) = self.try_parse_name()? else {
1086 return Ok(None);
1087 };
1088 assert!(!name.is_empty());
1089 let n_args = self
1090 .state
1091 .find_method(&name)
1092 .unwrap_or_else(|| self.predict_possible_args(false, &name));
1093
1094 let mut args = Vec::new();
1095 for _ in 0..n_args {
1096 args.push(self.parse_term_arg()?);
1097 }
1098
1099 AmlTerm::MethodCall(name, args)
1100 }
1101 };
1102 trace!("{:x?}", term);
1103
1104 Ok(Some(term))
1105 }
1106
1107 fn parse_term_arg_non_method_arg(&mut self) -> Result<TermArg, AmlParseError> {
1113 self.parse_term_arg_general(false, true)
1115 }
1116
1117 fn parse_term_arg_last(&mut self) -> Result<TermArg, AmlParseError> {
1119 self.parse_term_arg_general(true, false)
1120 }
1121
1122 fn parse_term_arg(&mut self) -> Result<TermArg, AmlParseError> {
1123 self.parse_term_arg_general(true, true)
1124 }
1125
1126 fn parse_package_element(
1127 &mut self,
1128 ) -> Result<PackageElement<UnresolvedDataObject>, AmlParseError> {
1129 if let Some(data_object) = self.try_parse_data_object()? {
1130 return Ok(PackageElement::DataObject(data_object));
1131 }
1132
1133 if let Some(name) = self.try_parse_name()? {
1134 return Ok(PackageElement::Name(name));
1135 }
1136
1137 Err(AmlParseError::InvalidTermArgInPackage)
1138 }
1139
1140 fn parse_eisa_id(id: u32) -> String {
1141 let byte2 = (id >> 16) & 0xFF;
1143 let byte3 = (id >> 24) & 0xFF;
1145
1146 let manufacturer_byte0 = id & 0xFF;
1148 let manufacturer_byte1 = (id >> 8) & 0xFF;
1150
1151 let manufacturer_list: [u32; 3] = [
1153 manufacturer_byte0 >> 2,
1154 ((manufacturer_byte0 & 0x03) << 3) | (manufacturer_byte1 >> 5),
1155 manufacturer_byte1 & 0x1F,
1156 ];
1157
1158 let manuf: String = manufacturer_list
1160 .iter()
1161 .map(|&c| (c + 0x40) as u8 as char)
1162 .collect();
1163
1164 format!("{manuf}{byte2:02X}{byte3:02X}")
1165 }
1166
1167 fn try_parse_data_object(&mut self) -> Result<Option<UnresolvedDataObject>, AmlParseError> {
1168 let lead_byte = self.get_next_byte()?;
1169
1170 let result = match lead_byte {
1171 0x0 => UnresolvedDataObject::Integer(IntegerData::ConstZero),
1172 0x1 => UnresolvedDataObject::Integer(IntegerData::ConstOne),
1173 0xA => {
1174 let data = self.get_next_byte()?;
1175 UnresolvedDataObject::Integer(IntegerData::ByteConst(data))
1176 }
1177 0xB => {
1178 let data = u16::from_le_bytes([self.get_next_byte()?, self.get_next_byte()?]);
1179 UnresolvedDataObject::Integer(IntegerData::WordConst(data))
1180 }
1181 0xC => {
1182 let data = u32::from_le_bytes([
1183 self.get_next_byte()?,
1184 self.get_next_byte()?,
1185 self.get_next_byte()?,
1186 self.get_next_byte()?,
1187 ]);
1188 UnresolvedDataObject::Integer(IntegerData::DWordConst(data))
1189 }
1190 0x0D => {
1191 let mut str = String::new();
1192 loop {
1193 let byte = self.get_next_byte()?;
1194 trace!("byte: {:x}", byte);
1195 if byte == 0 {
1196 break;
1197 }
1198 str.push(byte as char);
1199 }
1200 UnresolvedDataObject::String(str)
1201 }
1202 0xE => {
1203 let data = u64::from_le_bytes([
1204 self.get_next_byte()?,
1205 self.get_next_byte()?,
1206 self.get_next_byte()?,
1207 self.get_next_byte()?,
1208 self.get_next_byte()?,
1209 self.get_next_byte()?,
1210 self.get_next_byte()?,
1211 self.get_next_byte()?,
1212 ]);
1213 UnresolvedDataObject::Integer(IntegerData::QWordConst(data))
1214 }
1215 0x11 => {
1216 let mut inner = self.get_inner_parser()?;
1217 let buf_size = inner.parse_term_arg()?;
1218
1219 let buffer = Buffer {
1220 size: Box::new(buf_size),
1221 data: inner.code[inner.pos..].to_vec(),
1223 };
1224
1225 if let Some(resource_template) = ResourceTemplate::try_parse_buffer(&buffer)? {
1226 UnresolvedDataObject::ResourceTemplate(resource_template)
1227 } else {
1228 UnresolvedDataObject::Buffer(buffer)
1229 }
1230 }
1231 0x12 => {
1232 let mut inner = self.get_inner_parser()?;
1233 let package_size = inner.get_next_byte()?;
1234 trace!("package size: {:x}", package_size);
1235 let mut package_elements = Vec::new();
1236 while inner.pos < inner.code.len() {
1237 package_elements.push(inner.parse_package_element()?);
1238 trace!("package element: {:?}", package_elements.last());
1239 }
1240 inner.check_empty()?;
1241 UnresolvedDataObject::Package(package_size, package_elements)
1242 }
1243 0x13 => {
1244 let mut inner = self.get_inner_parser()?;
1245 let package_size = inner.parse_term_arg()?;
1246 let mut package_elements = Vec::new();
1247 trace!("varpackage size: {:x?}", package_size);
1248 while inner.pos < inner.code.len() {
1249 package_elements.push(inner.parse_package_element()?);
1250 trace!("varpackage element: {:?}", package_elements.last());
1251 }
1252 inner.check_empty()?;
1253 UnresolvedDataObject::VarPackage(Box::new(package_size), package_elements)
1254 }
1255 0xFF => UnresolvedDataObject::Integer(IntegerData::ConstOnes),
1256 _ => {
1257 self.backward(1)?;
1258 return Ok(None);
1259 }
1260 };
1261
1262 Ok(Some(result))
1263 }
1264
1265 fn parse_term_arg_general(
1266 &mut self,
1267 can_call_method: bool,
1268 expect_data_after: bool,
1269 ) -> Result<TermArg, AmlParseError> {
1270 if let Some(data_object) = self.try_parse_data_object()? {
1271 return Ok(TermArg::DataObject(data_object));
1272 }
1273
1274 let lead_byte = self.get_next_byte()?;
1275
1276 if let Some(local) = self.try_parse_local(lead_byte)? {
1277 Ok(TermArg::Local(local))
1278 } else if let Some(arg) = self.try_parse_arg(lead_byte)? {
1279 Ok(TermArg::Arg(arg))
1280 } else {
1281 self.backward(1)?;
1282 if let Some(name) = self.try_parse_name()? {
1283 assert!(!name.is_empty());
1284 let option_nargs = self.state.find_method(&name).or_else(|| {
1285 if self.state.find_name(&name) {
1286 None
1287 } else if can_call_method {
1288 trace!("predicting possible args for {name}");
1289 let possible_args = self.predict_possible_args(expect_data_after, &name);
1290 trace!("got possible args: {possible_args} {name}");
1291 if possible_args == 0 {
1293 self.state.add_name(name.clone());
1294 None
1295 } else {
1296 Some(possible_args)
1297 }
1298 } else {
1299 self.state.add_name(name.clone());
1301 None
1302 }
1303 });
1304 if let Some(n_args) = option_nargs {
1305 let mut args = Vec::new();
1306 for _ in 0..n_args {
1307 args.push(self.parse_term_arg()?);
1308 }
1309
1310 Ok(TermArg::Expression(Box::new(AmlTerm::MethodCall(
1311 name, args,
1312 ))))
1313 } else {
1314 Ok(TermArg::Name(name))
1315 }
1316 } else {
1317 self.forward(1)?;
1319
1320 if let Some(term) = self
1321 .try_parse_term(lead_byte)?
1322 .map(|term| TermArg::Expression(Box::new(term)))
1323 {
1324 Ok(term)
1325 } else {
1326 todo!("term arg lead byte: {:x}", lead_byte)
1327 }
1328 }
1329 }
1330 }
1331
1332 fn try_parse_name(&mut self) -> Result<Option<String>, AmlParseError> {
1333 let name_char_byte = self.peek_next_byte()?;
1334
1335 fn parse_name_path(parser: &mut Parser) -> Result<String, AmlParseError> {
1336 let byte = parser.get_next_byte()?;
1337 let mut str = String::new();
1338
1339 if byte == 0 {
1340 return Ok(str);
1341 }
1342
1343 str.push(byte as char);
1344
1345 for _ in 0..3 {
1347 let byte = parser.get_next_byte()?;
1348 match byte {
1349 b'A'..=b'Z' | b'_' | b'0'..=b'9' => {
1350 str.push(byte as char);
1351 }
1352 _ => panic!("invalid name path char: {:x} so far {str:?}", byte),
1353 }
1354 }
1355
1356 Ok(str)
1357 }
1358
1359 trace!("name char byte: {:x}", name_char_byte);
1360
1361 match name_char_byte {
1362 0 => {
1363 self.forward(1)?;
1364 Ok(Some(String::new()))
1365 }
1366 b'A'..=b'Z' | b'_' => Ok(Some(parse_name_path(self)?)),
1368 b'\\' => {
1372 self.forward(1)?;
1373 let name = self.parse_name()?;
1374 Ok(Some(format!("\\{name}")))
1375 }
1376 b'^' => {
1378 let mut str = String::new();
1379 while self.peek_next_byte()? == b'^' {
1380 self.forward(1)?;
1381 str.push('^');
1382 }
1383 str += &self.parse_name()?;
1384
1385 Ok(Some(str))
1386 }
1387 b'.' => {
1388 self.forward(1)?;
1389 let seg1 = parse_name_path(self)?;
1390 let seg2 = parse_name_path(self)?;
1391 Ok(Some(format!("{seg1}.{seg2}")))
1392 }
1393 b'/' => {
1394 self.forward(1)?;
1395 let count = self.get_next_byte()?;
1396 let mut str = String::new();
1397 for i in 0..count {
1398 str += &parse_name_path(self)?;
1399 if i != count - 1 {
1400 str += ".";
1401 }
1402 }
1403 Ok(Some(str))
1404 }
1405 _ => Ok(None),
1406 }
1407 }
1408
1409 fn parse_name(&mut self) -> Result<String, AmlParseError> {
1410 let peek = self.peek_next_byte()?;
1411 let name = self.try_parse_name()?;
1412
1413 if let Some(name) = name {
1414 Ok(name)
1415 } else {
1416 todo!("char not valid {:X}", peek)
1417 }
1418 }
1419
1420 fn try_parse_local(&mut self, lead: u8) -> Result<Option<u8>, AmlParseError> {
1421 match lead {
1422 0x60..=0x67 => {
1423 Ok(Some(lead - 0x60))
1425 }
1426 _ => Ok(None),
1427 }
1428 }
1429
1430 fn try_parse_arg(&mut self, lead: u8) -> Result<Option<u8>, AmlParseError> {
1431 match lead {
1432 0x68..=0x6E => {
1433 Ok(Some(lead - 0x68))
1435 }
1436 _ => Ok(None),
1437 }
1438 }
1439
1440 fn parse_target(&mut self) -> Result<Box<Target>, AmlParseError> {
1441 let lead_byte = self.peek_next_byte()?;
1442
1443 let x = match lead_byte {
1444 0x0 => {
1445 self.forward(1)?;
1446 Ok(Target::None)
1447 }
1448 0x5b => {
1449 self.forward(1)?;
1450 let next_byte = self.get_next_byte()?;
1451 assert_eq!(next_byte, 0x31);
1452 Ok(Target::Debug)
1453 }
1454 0x71 => {
1455 panic!("typeref opcode")
1457 }
1458 _ => {
1459 if let Some(local) = self.try_parse_local(lead_byte)? {
1460 self.forward(1)?;
1461 Ok(Target::Local(local))
1462 } else if let Some(arg) = self.try_parse_arg(lead_byte)? {
1463 self.forward(1)?;
1464 Ok(Target::Arg(arg))
1465 } else if let Some(name) = self.try_parse_name()? {
1466 Ok(Target::Name(name))
1467 } else {
1468 self.forward(1)?;
1469 if let Some(term) =
1470 self.try_parse_term(lead_byte)?.and_then(|term| match term {
1471 AmlTerm::Index(term_arg1, term_arg2, target) => {
1472 Some(Target::Index(term_arg1, term_arg2, target))
1473 }
1474 AmlTerm::RefOf(target) => Some(Target::RefOf(target)),
1475 AmlTerm::DerefOf(term_arg) => Some(Target::DerefOf(term_arg)),
1476 _ => None,
1477 })
1478 {
1479 trace!("mmmm: {:x?}", term);
1480 Ok(term)
1481 } else {
1482 Err(AmlParseError::InvalidTarget(lead_byte))
1483 }
1484 }
1485 }
1486 };
1487 trace!("target: {:x?}", x);
1488 x.map(Box::new)
1489 }
1490
1491 fn parse_term_list(&mut self) -> Result<Vec<AmlTerm>, AmlParseError> {
1492 let mut term_list = Vec::new();
1493 while self.pos < self.code.len() {
1494 let term = self.parse_term()?;
1495 term_list.push(term);
1496 }
1497 if self.remaining_bytes() != 0 {
1498 return Err(AmlParseError::RemainingBytes(self.remaining_bytes()));
1499 }
1500 Ok(term_list)
1501 }
1502
1503 fn parse_fields_list_and_flags(mut self) -> Result<(u8, Vec<FieldElement>), AmlParseError> {
1504 let flags = self.get_next_byte()?;
1505 trace!("field flags: {:x}", flags);
1506 let mut field_list = Vec::new();
1507
1508 let mut fields_pos_bits = 0;
1509
1510 while self.pos < self.code.len() {
1511 let lead = self.peek_next_byte()?;
1512
1513 let field = match lead {
1514 0 => {
1515 self.forward(1)?;
1516 let pkg_length = self.get_pkg_length()?;
1517 trace!("reserved field element pkg length: {:x}", pkg_length);
1518 fields_pos_bits += pkg_length + 1;
1520 if !fields_pos_bits.is_multiple_of(8) {
1521 return Err(AmlParseError::UnalignedFieldElementOffset);
1522 }
1523 FieldElement::Offset(fields_pos_bits / 8)
1524 }
1525 1 => {
1526 self.forward(1)?;
1527 let access_byte = self.get_next_byte()?;
1528 let access_attrib_byte = self.get_next_byte()?;
1529
1530 let access_attrib = match access_byte >> 6 {
1531 0 => match access_attrib_byte {
1532 0x2 => AccessAttrib::Quick,
1533 0x4 => AccessAttrib::SendRecv,
1534 0x6 => AccessAttrib::Byte,
1535 0x8 => AccessAttrib::Word,
1536 0xA => AccessAttrib::Block,
1537 0xC => AccessAttrib::ProcessCall,
1538 0xD => AccessAttrib::BlockProcessCall,
1539 _ => AccessAttrib::ByteValue(access_attrib_byte),
1540 },
1541 1 => AccessAttrib::Bytes(access_attrib_byte),
1542 2 => AccessAttrib::RawBytes(access_attrib_byte),
1543 3 => AccessAttrib::RawProcessBytes(access_attrib_byte),
1544 _ => unreachable!(),
1545 };
1546
1547 FieldElement::Access(access_byte.try_into()?, access_attrib)
1548 }
1549 2 => {
1550 self.forward(1)?;
1551
1552 let mut clone = self.clone_parser();
1553 let data_object = clone.try_parse_data_object()?;
1554 let connection_field =
1555 if let Some(UnresolvedDataObject::Buffer(buffer)) = data_object {
1556 FieldConnection::Buffer(buffer)
1557 } else {
1558 FieldConnection::Name(self.parse_name()?)
1560 };
1561
1562 FieldElement::Connection(connection_field)
1563 }
1564 3 => {
1565 self.forward(1)?;
1566 let access_byte = self.get_next_byte()?;
1567 let extended_attrib = self.get_next_byte()?;
1568 let access_length = self.get_next_byte()?;
1569
1570 let access_attrib = match extended_attrib {
1571 0xB => AccessAttrib::Bytes(access_length),
1572 0xE => AccessAttrib::RawBytes(access_length),
1573 0xF => AccessAttrib::RawProcessBytes(access_length),
1574 _ => return Err(AmlParseError::InvalidExtendedAttrib(extended_attrib)),
1575 };
1576
1577 FieldElement::Access(access_byte.try_into()?, access_attrib)
1578 }
1579 _ => {
1580 let len_now = self.pos;
1581 let name = self.parse_name()?;
1582 self.state.add_name(name.clone());
1583 assert_eq!(self.pos - len_now, 4); trace!("field element name: {}", name);
1585 let pkg_length = self.get_pkg_length()?;
1586 trace!("field element pkg length: {:x}", pkg_length);
1587 let size_bits = pkg_length + 1;
1588 fields_pos_bits += size_bits;
1589 FieldElement::Named(name, size_bits)
1591 }
1592 };
1593 field_list.push(field);
1594 }
1595
1596 self.check_empty()?;
1597
1598 Ok((flags, field_list))
1599 }
1600
1601 fn parse_root(&mut self) -> Result<AmlCode, AmlParseError> {
1602 let term_list = self.parse_term_list()?;
1603 trace!("{:?}", term_list);
1604
1605 Ok(AmlCode { term_list })
1606 }
1607}