| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 | use crate::{value::AmlValue, AmlError};use bit_field::BitField;use byteorder::{ByteOrder, LittleEndian};#[derive(Debug)]pub enum Resource {    Irq(IrqDescriptor),}/// Parse a `ResourceDescriptor`. Returns `AmlError::IncompatibleValueConversion` if the passed value is not a/// `Buffer`.pub(crate) fn resource_descriptor(descriptor: &AmlValue) -> Result<Resource, AmlError> {    if let AmlValue::Buffer { bytes, size: _ } = descriptor {        /*         * If bit 7 of Byte 0 is set, it's a large descriptor. If not, it's a small descriptor.         */        if bytes[0].get_bit(7) {            /*             * We're parsing a large item. The descriptor type is encoded in Bits 0-6 of Byte 0. Valid types:             *      0x00: Reserved             *      0x01: 24-bit Memory Range Descriptor             *      0x02: Generic Register Descriptor             *      0x03: Reserved             *      0x04: Vendor-defined Descriptor             *      0x05: 32-bit Memory Range Descriptor             *      0x06: 32-bit Fixed Memory Range Descriptor             *      0x07: Address Space Resource Descriptor             *      0x08: Word Address Space Descriptor             *      0x09: Extended Interrupt Descriptor             *      0x0a: QWord Address Space Descriptor             *      0x0b: Extended Address Space Descriptor             *      0x0c: GPIO Connection Descriptor             *      0x0d: Pin Function Descriptor             *      0x0e: GenericSerialBus Connection Descriptor             *      0x0f: Pin Configuration Descriptor             *      0x10: Pin Group Descriptor             *      0x11: Pin Group Function Descriptor             *      0x12: Pin Group Configuration Descriptor             *      0x13-0x7f: Reserved             *             * Byte 1 contains bits 0-7 of the length, and Byte 2 contains bits 8-15 of the length. Subsequent             * bytes contain the actual data items.             */            let descriptor_type = bytes[0].get_bits(0..7);            match descriptor_type {                0x01 => unimplemented!(),                0x02 => unimplemented!(),                0x03 => unimplemented!(),                0x04 => unimplemented!(),                0x05 => unimplemented!(),                0x06 => unimplemented!(),                0x07 => unimplemented!(),                0x08 => unimplemented!(),                0x09 => extended_interrupt_descriptor(bytes),                0x0a => unimplemented!(),                0x0b => unimplemented!(),                0x0c => unimplemented!(),                0x0d => unimplemented!(),                0x0e => unimplemented!(),                0x0f => unimplemented!(),                0x10 => unimplemented!(),                0x11 => unimplemented!(),                0x12 => unimplemented!(),                0x00 | 0x13..=0x7f => Err(AmlError::ReservedResourceType),                0x80..=0xff => unreachable!(),            }        } else {            /*             * We're parsing a small descriptor. Byte 0 has the format:             *    | Bits        | Field             |             *    |-------------|-------------------|             *    | 0-2         | Length - n bytes  |             *    | 3-6         | Small item type   |             *    | 7           | 0 = small item    |             *             * The valid types are:             *      0x00-0x03: Reserved             *      0x04: IRQ Format Descriptor             *      0x05: DMA Format Descriptor             *      0x06: Start Dependent Functions Descriptor             *      0x07: End Dependent Functions Descriptor             *      0x08: IO Port Descriptor             *      0x09: Fixed Location IO Port Descriptor             *      0x0A: Fixed DMA Descriptor             *      0x0B-0x0D: Reserved             *      0x0E: Vendor Defined Descriptor             *      0x0F: End Tag Descriptor             */            unimplemented!()        }    } else {        Err(AmlError::IncompatibleValueConversion)    }}#[derive(Debug)]pub enum InterruptTrigger {    Edge,    Level,}#[derive(Debug)]pub enum InterruptPolarity {    ActiveHigh,    ActiveLow,}#[derive(Debug)]pub struct IrqDescriptor {    pub is_consumer: bool,    pub trigger: InterruptTrigger,    pub polarity: InterruptPolarity,    pub is_shared: bool,    pub is_wake_capable: bool,    /*     * NOTE: We currently only support the cases where a descriptor only contains a single interrupt     * number.     */    pub irq: u32,}fn extended_interrupt_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {    /*     * --- Extended Interrupt Descriptor ---     * Byte 3 contains the Interrupt Vector Flags:     *      Bit 0: 1 if device consumes the resource, 0 if it produces it     *      Bit 1: 1 if edge-triggered, 0 if level-triggered     *      Bit 2: 1 = active-high, 0 = active-low     *      Bit 3: 1 if interrupt is shared with other devices     *      Bit 4: 1 if this interrupt is capable of waking the system, 0 if it is not     * Byte 4 contains the number of interrupt numbers that follow. When this descriptor is     * returned from `_CRS` or send to `_SRS`, this field must be 1.     *     * From Byte 5 onwards, there are `n` interrupt numbers, each of which is encoded as a     * 4-byte little-endian number.     *     * NOTE: We only support the case where there is a single interrupt number.     */    if bytes.len() < 9 {        return Err(AmlError::ResourceDescriptorTooShort);    }    let number_of_interrupts = bytes[4] as usize;    assert_eq!(number_of_interrupts, 1);    let irq = LittleEndian::read_u32(&[bytes[5], bytes[6], bytes[7], bytes[8]]);    Ok(Resource::Irq(IrqDescriptor {        is_consumer: bytes[3].get_bit(0),        trigger: if bytes[3].get_bit(1) { InterruptTrigger::Edge } else { InterruptTrigger::Level },        polarity: if bytes[3].get_bit(2) { InterruptPolarity::ActiveLow } else { InterruptPolarity::ActiveHigh },        is_shared: bytes[3].get_bit(3),        is_wake_capable: bytes[3].get_bit(4),        irq,    }))}
 |