rust-osdev / acpi

Rust library for parsing ACPI tables and interpreting AML
Apache License 2.0
203 stars 65 forks source link

AML: Incorrect read_region/write_region handling #193

Open alnyan opened 1 year ago

alnyan commented 1 year ago

While working with real DSDT and comparing reads/writes to what ACPICA does, I found out there are several issues with how reads/writes to regions are done:

I caught these issues while running AML of ThinkPad T430 DSDT, specifically, it has the following code (excerpt):

    OperationRegion (MNVS, SystemMemory, 0xDAF9D018, 0x1000)
    OperationRegion (SMI0, SystemIO, 0xB2, 0x01)

    Field (SMI0, ByteAcc, NoLock, Preserve)
    {
        APMC, 8
    }

    Field (MNVS, AnyAcc, NoLock, Preserve)
    {
        Offset (0xFC0),
        CMD, 8,
        ERR, 32,
        PAR0, 32,
        PAR1, 32,
        PAR2, 32,
        PAR3, 32
    }

    Mutex (MSMI, 0x07)
    Method (SMI, 5, NotSerialized)
    {
        Acquire (MSMI, 0xFFFF)

        CMD = Arg0
        ERR = 0x01
        PAR0 = Arg1
        PAR1 = Arg2
        PAR2 = Arg3
        PAR3 = Arg4
        APMC = 0xF5

        While ((ERR == 0x01))
        {
            Sleep (0x01)
            APMC = 0xF5
        }

        Release (MSMI)
    }

    Method (VUPS, 0, NotSerialized)
    {
        SMI (0x01, 0x01, 0x02, 0x00, 0x00)
    }

This code seems to be intended to generate a SMI for some graphics card management stuff, but when testing, it actually got stuck waiting for ERR to become != 0x01.

When comparing addresses of reads/writes generated by the acpi crate and what ACPICA does, I found out: