Skip to content

Commit fe877bd

Browse files
committed
aml: support parsing of bank and index fields
1 parent 86b47eb commit fe877bd

File tree

3 files changed

+167
-53
lines changed

3 files changed

+167
-53
lines changed

aml/src/lib.rs

Lines changed: 118 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use alloc::{
1818
use bit_field::BitField;
1919
use core::mem;
2020
use namespace::{AmlName, Namespace, NamespaceLevelKind};
21-
use object::{MethodFlags, Object, ObjectType, ReferenceKind};
21+
use object::{FieldFlags, FieldUnit, FieldUnitKind, MethodFlags, Object, ObjectType, ReferenceKind};
2222
use op_region::{OpRegion, RegionSpace};
2323
use spinning_top::Spinlock;
2424

@@ -384,6 +384,31 @@ where
384384
context.contribute_arg(Argument::Object(Arc::new(Object::Integer(typ))));
385385
}
386386
Opcode::SizeOf => self.do_size_of(&mut context, op)?,
387+
Opcode::BankField => {
388+
let [
389+
Argument::TrackedPc(start_pc),
390+
Argument::PkgLength(pkg_length),
391+
Argument::Namestring(region_name),
392+
Argument::Namestring(bank_name),
393+
Argument::Object(bank_value),
394+
] = &op.arguments[..]
395+
else {
396+
panic!()
397+
};
398+
let Object::Integer(bank_value) = **bank_value else { panic!() };
399+
400+
let field_flags = context.next()?;
401+
402+
let (region, bank) = {
403+
let namespace = self.namespace.lock();
404+
let (_, region) = namespace.search(region_name, &context.current_scope)?;
405+
let (_, bank) = namespace.search(bank_name, &context.current_scope)?;
406+
(region, bank)
407+
};
408+
409+
let kind = FieldUnitKind::Bank { region, bank, bank_value };
410+
self.parse_field_list(&mut context, kind, *start_pc, *pkg_length, field_flags)?;
411+
}
387412
_ => panic!("Unexpected operation has created in-flight op!"),
388413
}
389414
}
@@ -628,55 +653,44 @@ where
628653
let start_pc = context.current_block.pc;
629654
let pkg_length = context.pkglength()?;
630655
let region_name = context.namestring()?;
631-
let flags = context.next()?;
656+
let field_flags = context.next()?;
632657

633658
let region = self.namespace.lock().get(region_name.resolve(&context.current_scope)?)?.clone();
659+
let kind = FieldUnitKind::Normal { region };
660+
self.parse_field_list(&mut context, kind, start_pc, pkg_length, field_flags)?;
661+
}
662+
Opcode::BankField => {
663+
let start_pc = context.current_block.pc;
664+
let pkg_length = context.pkglength()?;
665+
let region_name = context.namestring()?;
666+
let bank_name = context.namestring()?;
634667

635-
const RESERVED_FIELD: u8 = 0x00;
636-
const ACCESS_FIELD: u8 = 0x01;
637-
const CONNECT_FIELD: u8 = 0x02;
638-
const EXTENDED_ACCESS_FIELD: u8 = 0x03;
639-
640-
let mut field_offset = 0;
641-
642-
while context.current_block.pc < (start_pc + pkg_length) {
643-
match context.next()? {
644-
RESERVED_FIELD => {
645-
let length = context.pkglength()?;
646-
field_offset += length;
647-
}
648-
ACCESS_FIELD => {
649-
let access_type = context.next()?;
650-
let access_attrib = context.next()?;
651-
todo!()
652-
// TODO
653-
}
654-
CONNECT_FIELD => {
655-
// TODO: either consume a namestring or `BufferData` (it's not
656-
// clear what a buffer data acc is lmao)
657-
todo!("Connect field :(");
658-
}
659-
EXTENDED_ACCESS_FIELD => {
660-
todo!("Extended access field :(");
661-
}
662-
_ => {
663-
context.current_block.pc -= 1;
664-
// TODO: this should only ever be a nameseg really...
665-
let field_name = context.namestring()?;
666-
let field_length = context.pkglength()?;
667-
// TODO: do something with the flags, and also detect when this
668-
// should be a bank or index field
669-
let field = Object::FieldUnit(object::FieldUnit::Normal {
670-
region: region.clone(),
671-
bit_index: field_offset,
672-
bit_length: field_length,
673-
});
674-
self.namespace
675-
.lock()
676-
.insert(field_name.resolve(&context.current_scope)?, Arc::new(field))?;
677-
}
678-
}
679-
}
668+
context.start_in_flight_op(OpInFlight::new_with(
669+
Opcode::BankField,
670+
vec![
671+
Argument::TrackedPc(start_pc),
672+
Argument::PkgLength(pkg_length),
673+
Argument::Namestring(region_name),
674+
Argument::Namestring(bank_name),
675+
],
676+
1,
677+
));
678+
}
679+
Opcode::IndexField => {
680+
let start_pc = context.current_block.pc;
681+
let pkg_length = context.pkglength()?;
682+
let index_name = context.namestring()?;
683+
let data_name = context.namestring()?;
684+
let field_flags = context.next()?;
685+
686+
let (index, data) = {
687+
let namespace = self.namespace.lock();
688+
let (_, index) = namespace.search(&index_name, &context.current_scope)?;
689+
let (_, data) = namespace.search(&data_name, &context.current_scope)?;
690+
(index, data)
691+
};
692+
let kind = FieldUnitKind::Index { index, data };
693+
self.parse_field_list(&mut context, kind, start_pc, pkg_length, field_flags)?;
680694
}
681695
Opcode::Device | Opcode::ThermalZone => {
682696
let start_pc = context.current_block.pc;
@@ -735,8 +749,6 @@ where
735749
let old_scope = mem::replace(&mut context.current_scope, new_scope);
736750
context.start_new_block(BlockKind::Scope { old_scope }, remaining_length);
737751
}
738-
Opcode::IndexField => todo!(),
739-
Opcode::BankField => todo!(),
740752
Opcode::DataRegion => todo!(),
741753
Opcode::Local(local) => {
742754
let local = context.locals[local as usize].clone();
@@ -872,6 +884,63 @@ where
872884
}
873885
}
874886

887+
fn parse_field_list(
888+
&self,
889+
context: &mut MethodContext,
890+
kind: FieldUnitKind,
891+
start_pc: usize,
892+
pkg_length: usize,
893+
flags: u8,
894+
) -> Result<(), AmlError> {
895+
const RESERVED_FIELD: u8 = 0x00;
896+
const ACCESS_FIELD: u8 = 0x01;
897+
const CONNECT_FIELD: u8 = 0x02;
898+
const EXTENDED_ACCESS_FIELD: u8 = 0x03;
899+
900+
let mut field_offset = 0;
901+
902+
while context.current_block.pc < (start_pc + pkg_length) {
903+
match context.next()? {
904+
RESERVED_FIELD => {
905+
let length = context.pkglength()?;
906+
field_offset += length;
907+
}
908+
ACCESS_FIELD => {
909+
let access_type = context.next()?;
910+
let access_attrib = context.next()?;
911+
todo!()
912+
// TODO
913+
}
914+
CONNECT_FIELD => {
915+
// TODO: either consume a namestring or `BufferData` (it's not
916+
// clear what a buffer data acc is lmao)
917+
todo!("Connect field :(");
918+
}
919+
EXTENDED_ACCESS_FIELD => {
920+
todo!("Extended access field :(");
921+
}
922+
_ => {
923+
context.current_block.pc -= 1;
924+
// TODO: this should only ever be a nameseg really...
925+
let field_name = context.namestring()?;
926+
let field_length = context.pkglength()?;
927+
928+
let field = Object::FieldUnit(FieldUnit {
929+
kind: kind.clone(),
930+
bit_index: field_offset,
931+
bit_length: field_length,
932+
flags: FieldFlags(flags),
933+
});
934+
self.namespace.lock().insert(field_name.resolve(&context.current_scope)?, Arc::new(field))?;
935+
936+
field_offset += field_length;
937+
}
938+
}
939+
}
940+
941+
Ok(())
942+
}
943+
875944
fn do_binary_maths(&self, context: &mut MethodContext, op: OpInFlight) -> Result<(), AmlError> {
876945
let [Argument::Object(left), Argument::Object(right), Argument::Object(target)] = &op.arguments[0..2]
877946
else {

aml/src/object.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,23 @@ impl Object {
121121
}
122122

123123
#[derive(Debug)]
124-
pub enum FieldUnit {
125-
Normal { region: Arc<Object>, bit_index: usize, bit_length: usize },
126-
Bank,
127-
Index,
124+
pub struct FieldUnit {
125+
pub kind: FieldUnitKind,
126+
pub flags: FieldFlags,
127+
pub bit_index: usize,
128+
pub bit_length: usize,
128129
}
129130

131+
#[derive(Clone, Debug)]
132+
pub enum FieldUnitKind {
133+
Normal { region: Arc<Object> },
134+
Bank { region: Arc<Object>, bank: Arc<Object>, bank_value: u64 },
135+
Index { index: Arc<Object>, data: Arc<Object> },
136+
}
137+
138+
#[derive(Clone, Copy, Debug)]
139+
pub struct FieldFlags(pub u8);
140+
130141
#[derive(Clone, Copy, Debug)]
131142
pub struct MethodFlags(pub u8);
132143

tests/fields.asl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
DefinitionBlock("fields.aml", "DSDT", 1, "RSACPI", "BUFFLD", 1) {
2+
OperationRegion(GIO0, SystemIO, 0x125, 0x100)
3+
4+
Field(GIO0, ByteAcc, NoLock, Preserve) {
5+
GLB1, 1,
6+
GLB2, 1,
7+
Offset(1),
8+
BNK1, 4,
9+
10+
Offset(2),
11+
IDX0, 8,
12+
DAT0, 8
13+
}
14+
15+
BankField(GIO0, BNK1, 0, ByteAcc, NoLock, Preserve) {
16+
Offset(0x30),
17+
FET0, 1,
18+
FET1, 1
19+
}
20+
21+
BankField(GIO0, BNK1, 1, ByteAcc, NoLock, Preserve) {
22+
Offset(0x30),
23+
BLVL, 7,
24+
BAC, 1
25+
}
26+
27+
IndexField(IDX0, DAT0, ByteAcc, NoLock, Preserve) {
28+
FET2, 1,
29+
FET3, 1,
30+
Offset(0x2f),
31+
, 7,
32+
FET4, 1
33+
}
34+
}

0 commit comments

Comments
 (0)