Skip to content

Rewrite acpi crate and entire AML interpreter #246

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

Open
wants to merge 97 commits into
base: main
Choose a base branch
from

Conversation

IsaacWoods
Copy link
Member

@IsaacWoods IsaacWoods commented Mar 25, 2025

This (entirely too large) PR represents work I've been doing over the last few months to address a large number of bugs in both the acpi and aml crates, and generally improve the quality of the library. While this work is nowhere near complete, it represents the library getting back to a point where I think it is reasonable for projects to use it (in that it is more correct than the current interpreter in all circumstances), and is already too unwieldy to rebase against other PRs that are waiting for review/merging.

For contributors awaiting PRs being merged, I apologise for this derailing your contributions, and I am happy to assist in rebasing your changes/creating new patches with you credited as authors. I will review current PRs when I have time.

Summary of changes

Firstly, the acpi crate has undergone major reworking to simplify logic surrounding table mapping and RSDT enumeration. This should fix #245.

Previous work on allowing fallible allocations has been removed, as it added significant complexity for little real-world gain at this time - if the ecosystem around fallible allocation in Rust improves in the future, I'm not against re-adding these capabilities. The split between the portion of the library that can be used without an allocator vs requiring one has been made clearer, with allocating methods being moved under the higher-level platform module.

This PR also deprecates the aml crate, bringing the interpreter into the acpi crate under a feature-flag. This simplifies the most common use-cases of the library, and was effectively required for ergonomic handling of some AML operations that require us to handle static ACPI tables. Future work with the ACPI event system will likely require closer coupling between the previously-separate parts of the library, as well.

I am imagining that these changes will be published as acpi v6.0.0, with the aml crate being marked as deprecated and receiving no future updates.

Remaining tasks

  • Consider final situation with AcpiHandler vs acpi::aml::Handler - do we want to merge them, make AcpiHandler a supertrait (perhaps being renamed RegionMapper or similar as this is the only functionality it needs to provide)?
  • Consider adding flags to mapped regions - some may need to be real backing memory (e.g. MMIO, the FACS) vs simply-contain-the-correct-data (e.g. tables)
  • Change GenericAddress to have arbitrary field widths - apparently required by the PCC (see acpi: add support for PCC table #233)
  • DefMatch
  • DefVarPackage
  • DefLoad
  • DefLoadTable
  • DefDataRegion
  • DefToBuffer
  • DefToInteger
  • DefToString
  • DefToDecimalString
  • DefToHexString
  • DefCopyObject
  • DefNotify
  • Correctly handle references in more places
  • Be more lenient with name collisions (see what other interpreters do)
  • Connect fields
  • Extended access fields
  • Custom field address space handlers
  • Handle bank and index field accesses
  • Add pre-defined objects to namespace
  • Fix Clippy complaints
  • Fix object mutable access situation
  • Mechanism to enter ACPI mode
  • New Readme to reflect new features of the library

Feedback

I would welcome feedback on the new APIs, crate layout, or changes I should consider before publishing a new major version of acpi. I particularly welcome feedback + bug-reports from people who have integrated acpi into a kernel or other project.

cc @rw-vanc - I would be interested in any concerns re Redox moving to the new version of the crate, and any further work you'd be interested in.
cc @usadson - this should fix #245. Thank you for your report.

I don't really understand why this had a lifetime instead of constructing
the slice for the lifetime of `self`, but this cleans stuff up a fair bit
both in the library and for users.
Still need to do a bunch of bit fiddling stuff to facilitate actually reading
and storing to them.
@rw-van
Copy link

rw-van commented Apr 2, 2025

I have a real-world AML file that is producing an opcode error. I am AFK, but do you want the whole file or just the opcode that is producing the error?

@IsaacWoods
Copy link
Member Author

Whole file please.

This necessitated also unwrapping more references for package and buffer
lengths. This may need to be done elsewhere.
@rust-osdev rust-osdev deleted a comment from rw-vanc Apr 3, 2025
@IsaacWoods
Copy link
Member Author

Thanks for the reports. Interpreting the files via the test harness, both do produce errors, although not the same one.
Are you running these on the real hardware? Both tables are doing top-level field reads which obviously I can not emulate correctly.

The HP laptop produces NameCollision(AmlName([Root, Segment("GMIO"), Segment("PXCS")])) for me. I think we'll need to be more lenient in how name collisions are handled.

The Dell table produces ObjectNotOfExpectedType { expected: Integer, got: Integer } for me. This is seen where we're not correctly dereferencing an object during an operation, which I suspected we needed to do more of. I'll need to write some more instrumentation to be able to tell which op is actually producing that.

Reassuringly, the interpreter in its current state seems to munch through quite a lot of those tables, which do include some weird stuff. I'll get these fixed when I can. Please do report any new problems you come across.

@usadson
Copy link

usadson commented Apr 4, 2025

I found similar cases as well, but thought it was something on my side. I found ObjectNotOfExpectedType { expected: Integer, got: Integer } but also sometimes ObjectNotOfExpectedType { expected: Buffer, got: Buffer } IIRC

@IsaacWoods
Copy link
Member Author

@rw-vanc I have fixed issues with name collisions and the use of a Local within an operation region definition which fix the two dumps you posted.

I have also added some rudimentary tracing of in-flight operations which make it much easier to find where the issue is with errors like these. It can be seen at the trace log-level.

@usadson it's very possible the same problem is happening elsewhere. I'll have a look around, but if you have dumps that aren't parsing, using the tracing might help find the issue. You can also drop me dumps and I can have a look - probs easiest to PM me the dump on the rust-osdev Zulip.

@rw-vanc
Copy link
Contributor

rw-vanc commented Apr 7, 2025

Thanks. I will test with the AML tester. I tried to merge the new code into Redox but we are using a different compiler version, and I don't have time to deal with that this month. We are going to try to get on the latest Rust compiler in a few months, but when I get time (and when you feel like the AML parser is ready) I will fork and patch for the older compiler, so we can do more real-world testing.
https://gitlab.redox-os.org/redox-os/redox/-/blob/master/rust-toolchain.toml?ref_type=heads

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

Successfully merging this pull request may close these issues.

Invalid safety assumption in SdtHeaderIterator
4 participants