123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- use crate::{name_object::AmlName, AmlError};
- use alloc::{boxed::Box, string::String, vec::Vec};
- use bit_field::BitField;
- #[derive(Clone, Copy, PartialEq, Eq, Debug)]
- pub enum RegionSpace {
- SystemMemory,
- SystemIo,
- PciConfig,
- EmbeddedControl,
- SMBus,
- SystemCmos,
- PciBarTarget,
- IPMI,
- GeneralPurposeIo,
- GenericSerialBus,
- OemDefined(u8),
- }
- #[derive(Clone, Copy, PartialEq, Eq, Debug)]
- pub enum FieldAccessType {
- Any,
- Byte,
- Word,
- DWord,
- QWord,
- Buffer,
- Reserved,
- }
- #[derive(Clone, Copy, PartialEq, Eq, Debug)]
- pub enum FieldUpdateRule {
- Preserve,
- WriteAsOnes,
- WriteAsZeros,
- }
- // TODO: custom debug impl
- #[derive(Clone, Copy, PartialEq, Eq, Debug)]
- pub struct FieldFlags(u8);
- impl FieldFlags {
- pub fn new(value: u8) -> FieldFlags {
- FieldFlags(value)
- }
- pub fn access_type(&self) -> Result<FieldAccessType, AmlError> {
- match self.0.get_bits(0..4) {
- 0 => Ok(FieldAccessType::Any),
- 1 => Ok(FieldAccessType::Byte),
- 2 => Ok(FieldAccessType::Word),
- 3 => Ok(FieldAccessType::DWord),
- 4 => Ok(FieldAccessType::QWord),
- 5 => Ok(FieldAccessType::Buffer),
- _ => Err(AmlError::InvalidFieldFlags),
- }
- }
- pub fn lock_rule(&self) -> bool {
- self.0.get_bit(4)
- }
- pub fn field_update_rule(&self) -> Result<FieldUpdateRule, AmlError> {
- match self.0.get_bits(5..7) {
- 0 => Ok(FieldUpdateRule::Preserve),
- 1 => Ok(FieldUpdateRule::WriteAsOnes),
- 2 => Ok(FieldUpdateRule::WriteAsZeros),
- _ => Err(AmlError::InvalidFieldFlags),
- }
- }
- }
- #[derive(Clone, Copy, PartialEq, Eq, Debug)]
- pub struct MethodFlags(u8);
- impl MethodFlags {
- pub fn new(value: u8) -> MethodFlags {
- MethodFlags(value)
- }
- pub fn arg_count(&self) -> u8 {
- self.0.get_bits(0..3)
- }
- pub fn serialize(&self) -> bool {
- self.0.get_bit(3)
- }
- pub fn sync_level(&self) -> u8 {
- self.0.get_bits(4..8)
- }
- }
- #[derive(Clone, PartialEq, Eq, Debug)]
- pub enum AmlValue {
- Integer(u64),
- String(String),
- Name(Box<AmlValue>),
- OpRegion { region: RegionSpace, offset: u64, length: u64 },
- Field { region: AmlName, flags: FieldFlags, offset: u64, length: u64 },
- Device,
- Method { flags: MethodFlags, code: Vec<u8> },
- Buffer { bytes: Vec<u8>, size: u64 },
- Processor { id: u8, pblk_address: u32, pblk_len: u8 },
- Mutex { sync_level: u8 },
- Package(Vec<AmlValue>),
- }
- impl AmlValue {
- pub fn as_integer(&self) -> Result<u64, AmlError> {
- match self {
- AmlValue::Integer(value) => Ok(*value),
- AmlValue::Buffer { size, ref bytes } => {
- /*
- * "The first 8 bytes of the buffer are converted to an integer, taking the first
- * byte as the least significant byte of the integer. A zero-length buffer is
- * illegal." - §19.6.140
- *
- * XXX: We return `0` for zero-length buffers because they literally occur in
- * the reference implementation.
- */
- let bytes = if bytes.len() > 8 { &bytes[0..8] } else { bytes };
- Ok(bytes.iter().rev().fold(0: u64, |mut i, &popped| {
- i <<= 8;
- i += popped as u64;
- i
- }))
- }
- _ => Err(AmlError::IncompatibleValueConversion),
- }
- }
- }
|