I remember that era (and it's still present on some other architectures) - devicetrees were at least a huge improvement over compile-time board config!
> ACPI/UEFI doesn't always give you a clean abstract surface to work with either.
That's putting it lightly. I think the best abstraction would probably land somewhere inside the big gap in the board config headers -> devicetree --------------> ACPI complexity continuum, but I'm not sure it's possible to do that at this point in the game as both sides are so entrenched.
> ACPI is notorious for building in OS checks into it's compiled bytecode to the point that Linux often lies
The problem with ACPI in this dimension is that there's a bidirectional errata game: the bytecode tries to work around the OS and the OS tries to work around the bytecode.
Unfortunately, there was never a real version standard for the Linux firmware interface early on (the _OSI("Linux") debacle), so the only testable versioned ACPI interface is Windows. This means that Linux is basically forced to become a Windows ACPI emulator. I think there are political reasons for this (obviously the 90s and 2000s were a bad time for Linux/Microsoft coexistence) but also just some decisions that look like big engineering mistakes in hindsight - the historic allergy of Linux maintainers to any kind of specified or versioned interface aimed at anything but user land definitely strikes again here.
I think that the versioning/errata issue and the native code trapdoor are the two biggest issues with ACPI (and admittedly both are large enough to drive a bus through); otherwise it's a kind of nasty thing but it fills in nicely for a lot of much nastier ideas and covers a really broad problem space reasonably well.