kernel/acpi/aml/parser/
mod.rs

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/// DataObject representation as it is in the AML, which may contain expressions
106/// that need to be evaluated at runtime
107///
108/// For final result, see [DataObject][super::execution::DataObject]
109#[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/// `D` is the type of data object, it can be [UnresolvedDataObject] or [DataObject][super::execution::DataObject] depending
121/// on the state, either parsed program or executed and returned result
122#[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    // used by ResourceTemplate, so we are not initializing it in `TryFrom<u8>`
294    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    /// Undefined
346    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    /// Special variant that only prints the `u8` value, doesn't have name
457    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/// inner state of the parser to store information about the current scope/position
609#[derive(Debug)]
610struct State<'a> {
611    /// Shared state all method names
612    methods: StateMethodsList<'a>,
613    /// all found names (aliases, fields, etc.)
614    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    /// Renamed to not be confused with `Clone::clone`
623    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        // all methods are shared here, from all scopes
639        // we are assuming that methods with similar names have the same number of arguments
640        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            // subtract the bytes used for the length
709            return Ok((lead_byte & 0b0011_1111) as usize - 1);
710        } else {
711            // bits 4-5 must be zero
712            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        // subtract the bytes used for the length
725        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    /// Renamed to not be confused with `Clone::clone`
742    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        // clone ourselves to search future nodes
770        // TODO: reduce allocations
771        let mut inner = self.clone_parser();
772
773        let mut n_args = 0;
774        // max 7 args
775        for _ in 0..7 {
776            // filter out impossible cases to be a method argument (taken from ACPICA code),
777            // but not exactly the same for simplicity, maybe will need to modify later.
778            match inner.parse_term_arg() {
779                Ok(TermArg::Name(var_name)) => {
780                    // this is an inner expression containing the same name, something like `NAME = NAME + 1`
781                    // in that case, this is not a function, and is just a name
782                    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                        // only allow if target is None
843                        break;
844                    }
845                    _ => {}
846                },
847                Err(e) => {
848                    if let AmlParseError::UnexpectedEndOfCode = e {
849                        // if we took what is not ours, return it
850                        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                // extra ops
902                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            // parse it as if it's a method arg, this fixes issues of us mis-representing the term as a name
1079            0xA4 => AmlTerm::Return(self.parse_term_arg_last()?),
1080            0xA5 => AmlTerm::Break,
1081            _ => {
1082                trace!("try parse name");
1083                // move back once, since we have consumed this byte
1084                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    /// similar to [`Self::parse_term_arg`], but cannot call methods, as in some places method calls are not allowed
1108    ///
1109    /// TODO: This should be removed, as in general a method call is a valid term arg, its just
1110    ///       we break some parts due to us not knowing if a name is a method or not, and prediction predicts wrong and messes up
1111    ///       This happens for `+` and `>>` and `<<`, cases I have seen and know of bugs in the parsing
1112    fn parse_term_arg_non_method_arg(&mut self) -> Result<TermArg, AmlParseError> {
1113        // second arg doesn't matter, not used
1114        self.parse_term_arg_general(false, true)
1115    }
1116
1117    /// similar to [`Self::parse_term_arg`], but doesn't expect to have data after it, i.e. last in statements or something similar
1118    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        // 1st 2 hex of the product id
1142        let byte2 = (id >> 16) & 0xFF;
1143        // 2nd 2 hex of the product id
1144        let byte3 = (id >> 24) & 0xFF;
1145
1146        // 1st 2 hex of the manufacturer id
1147        let manufacturer_byte0 = id & 0xFF;
1148        // 2nd 2 hex of the manufacturer id
1149        let manufacturer_byte1 = (id >> 8) & 0xFF;
1150
1151        // convert 2 bytes to 3 values, each 5 bits
1152        let manufacturer_list: [u32; 3] = [
1153            manufacturer_byte0 >> 2,
1154            ((manufacturer_byte0 & 0x03) << 3) | (manufacturer_byte1 >> 5),
1155            manufacturer_byte1 & 0x1F,
1156        ];
1157
1158        // convert 3 values to 3 characters
1159        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                    // take all remaining data
1222                    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 its 0 and we are inside a method call, probably this is just a named variable
1292                        if possible_args == 0 {
1293                            self.state.add_name(name.clone());
1294                            None
1295                        } else {
1296                            Some(possible_args)
1297                        }
1298                    } else {
1299                        // we didn't find, the name, and we can't use methods, so assume it's a name
1300                        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                // didn't work for `name`, we need to go forward to be back to where we were before
1318                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            // add 3 more
1346            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            // lead name char
1367            b'A'..=b'Z' | b'_' => Ok(Some(parse_name_path(self)?)),
1368            // // digit char
1369            // b'0'..=b'9' => {}
1370            // root char
1371            b'\\' => {
1372                self.forward(1)?;
1373                let name = self.parse_name()?;
1374                Ok(Some(format!("\\{name}")))
1375            }
1376            // parent prefix
1377            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                // local0-local7
1424                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                // arg0-arg6
1434                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                // typeref opcode
1456                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                    // add 1 since we are not using it as normal pkg length
1519                    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                            // didn't work, try a name
1559                            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); // must be a name segment
1584                    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                    // add 1 since we are not using it as normal pkg length
1590                    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}