Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AML: Incorrect read_region/write_region handling #193

Open
2 tasks
alnyan opened this issue Aug 29, 2023 · 0 comments
Open
2 tasks

AML: Incorrect read_region/write_region handling #193

alnyan opened this issue Aug 29, 2023 · 0 comments

Comments

@alnyan
Copy link
Contributor

alnyan commented Aug 29, 2023

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:

  • Incorrect calculation of final access addresses/IO ports: typically, ***_region does let address = (region_base + offset), which is incorrect, because we're trying to add bytes (region_base) to bits (offset) here, which yields incorrect addresses
  • Not sure if this is intended behavior, but when the address isssue is fixed, the functions allow misaligned access to memory/IO, e.g. trying to read_u32(0xdaf9dfe5)

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:

  • ACPICA only does byte accesses there, so misalignment is not a problem (and the region's AnyAcc allows this)
  • ACPICA accesses addresses 0xdaf9dfd8..0xdaf9dfe9, while the acpi crate accesses 0xdafa4e18..0xdafa4ea0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant