Page 1 of 2

ACPI Machine Language

Posted: Thu Aug 25, 2022 3:35 am
by devc1
Sorry for the lots of topics, I was stuck in interrupt pins and I started parsing the ACPI AML using my own code (of course!), I did great my parser reads the same code in qemu_dsdt.asl and it is not yet complete.

- How to get INTA/INTB/INTC/INTD (where are they in qemu_dsdt.asl?) I assume something with PRTA/PRTB/PRTC/PRTD Right ?
- the reset/shutdown buttons in QEMU doesn't work ?
- How to handle SCI Interrupt if I receive one on real hardware it keeps spamming (I assume the DSDT tells us how ?)
- What is that _DBG Field ?
- I think I should first fully parse the DSDT and then read the whole ACPI Specification ??
- Can someone explain to me the interresting fields in a DSDT and in QEMU's one (_PRT, _S5, _RTC)
- I don't use RTC Interrupts now but I didn't receive them in VirtualBox

Atleast say something if you can't answer all the questions ;) Wish you a good advanture !

Re: ACPI Machine Language

Posted: Thu Aug 25, 2022 5:28 am
by nexos
The ACPI specification should answer all these questions and more.

Yes, you will have to read the entire spec :wink:

Re: ACPI Machine Language

Posted: Thu Aug 25, 2022 6:23 am
by rdos
Just note that ACPI is not very useful anymore. You will also need to identify yourself as a recent Windows version, otherwise ACPI might create a non-functional setup for you since BIOS manufacturers assume it's Windows that is installed.

Re: ACPI Machine Language

Posted: Thu Aug 25, 2022 6:53 am
by qookie
devc1 wrote: - How to get INTA/INTB/INTC/INTD (where are they in qemu_dsdt.asl?) I assume something with PRTA/PRTB/PRTC/PRTD Right ?
...
- Can someone explain to me the interresting fields in a DSDT and the in QEMU's one (_PRT, _S5, _RTC)
_PRT is a method that returns a routing table for the PCI pin IRQs (Pin Routing Table?). The object it returns is afaics a package of packages, which contain the PCI device address (slot, function; segment and bus are determined by which object you called _PRT on), which pins it applies to, the GSI/link object and IRQ flags. That said, unless you're targeting older systems, you could just rely on MSIs, since iirc all PCIe devices are required by spec to support them.

_S5 is a function that returns a package of values (or just a package directly) that you need to use to enter sleep state 5 (soft off).

Re: ACPI Machine Language

Posted: Thu Aug 25, 2022 1:53 pm
by devc1
Well ACPI is actually useful, my old laptop has only EHCI which does not support MSI and I got a full driver for it, I may want to use power management, locate different buses, locate the RTC device and maybe use fancy OS functions such as Hibernating the Computer.

AND ! I mean by a modern computer : X64 APIC ACPI Computers with HPET.

Re: ACPI Machine Language

Posted: Fri Aug 26, 2022 2:34 am
by rdos
devc1 wrote:Well ACPI is actually useful, my old laptop has only EHCI which does not support MSI and I got a full driver for it, I may want to use power management, locate different buses, locate the RTC device and maybe use fancy OS functions such as Hibernating the Computer.

AND ! I mean by a modern computer : X64 APIC ACPI Computers with HPET.
I don't think you need (or should use) ACPI to determine if your EHCI controller supports MSI or not. You should figure this out through PCI and the EHCI controller.

As for HPET, I check for it in the HPET ACPI table (not through AML), but if it is not there I assume it is a 0xFED00000. I then check it to make sure it's functional. I think skipping ACPI here will not make much of a difference since HPET always seems to be mapped to the same address.

The RTC is always at the same address, so checking ACPI will not make much of a difference.

Generally, you find modern devices through PCI, or through USB descriptors, not through ACPI.

As for power management, I find this pretty redundant and something only mature OSes typically care about. Not to mention that this is a mess, and there are several other interfaces for power management you will need to use & understand as well. It's also device dependent.

So, the only real use of ACPI is to identify IRQ mappings for devices that doesn't support MSI or MSI-X. Although, this is possible to do with probing too. The latter is much simpler than implementing an ACPI parser. Actually, I don't load the ACPI driver on older computers that lack an APIC interrupt controller.

Re: ACPI Machine Language

Posted: Fri Aug 26, 2022 3:39 pm
by devc1
I've not completed reading the answer but first : I check for MSI support through PCI and there is no MSI!
So I need to parse the DSDT to get the correspendant IRQ number for the interrupt pin.
However AHCI has MSI, XHCI forcibly has MSI-X but EHCI does not have MSI nor MSI-X on my main PC (PCIe 3.0) and my old laptop.

I already have HPET as my main timer for GetHighPrecisionTime(), Sleep() and MicroSleep() ::) APIC Timer is used for task scheduling

Yes, HPET is Always mapped at the same address

Re: ACPI Machine Language

Posted: Fri Aug 26, 2022 3:49 pm
by devc1
Thanks for your effort on the answer, I think there is a small misunderstanding which is that I want to use ACPI to locate devices, I wan't ACPI just for SCI handling, PCI IRQ Mapping, Sleeping States, Maybe tunning the CPU...

I am trying to build something like a mature OS, currently my AML Parser is in developement and I am not finding any problem.

I think you should not use the HPET (as you said) if it is not declared in the ACPI tables.

I got a full driver for EHCI in QEMU as the irq pin had the same irq number :)

How to identify to ACPI ? : everyone talks about that you need to identify as Windows to use the get all the ACPI features.

Re: ACPI Machine Language

Posted: Sat Aug 27, 2022 1:05 am
by nullplan
devc1 wrote:How to identify to ACPI ? : everyone talks about that you need to identify as Windows to use the get all the ACPI features.
The AML will sometimes call a method called _OSI. That method gets a string argument and returns true or false. Your OS must provide the implementation. And because firmware authors don't care about any OS besides Windows, you must return true for most strings starting with "Windows", or else the firmware assumes you are an old version of Windows and won't give you some features that those old versions could not take advantage of. Linux did return true for _OSI("Linux") for a while, but that just kept causing problems, and now they return false to that query unless the system is on a white list. On Apple hardware, you might need to return true for _OSI("Darwin") as well. Here is a list of all the strings used in ACPICA:

Code: Select all

static struct acpi_interface_info acpi_default_supported_interfaces[] = {
	/* Operating System Vendor Strings */

	{"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000},	/* Windows 2000 */
	{"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP},	/* Windows XP */
	{"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1},	/* Windows XP SP1 */
	{"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003},	/* Windows Server 2003 */
	{"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2},	/* Windows XP SP2 */
	{"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1},	/* Windows Server 2003 SP1 - Added 03/2006 */
	{"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA},	/* Windows vista - Added 03/2006 */
	{"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008},	/* Windows Server 2008 - Added 09/2009 */
	{"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1},	/* Windows Vista SP1 - Added 09/2009 */
	{"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2},	/* Windows Vista SP2 - Added 09/2010 */
	{"Windows 2009", NULL, 0, ACPI_OSI_WIN_7},	/* Windows 7 and Server 2008 R2 - Added 09/2009 */
	{"Windows 2012", NULL, 0, ACPI_OSI_WIN_8},	/* Windows 8 and Server 2012 - Added 08/2012 */
	{"Windows 2013", NULL, 0, ACPI_OSI_WIN_8_1},	/* Windows 8.1 and Server 2012 R2 - Added 01/2014 */
	{"Windows 2015", NULL, 0, ACPI_OSI_WIN_10},	/* Windows 10 - Added 03/2015 */
	{"Windows 2016", NULL, 0, ACPI_OSI_WIN_10_RS1},	/* Windows 10 version 1607 - Added 12/2017 */
	{"Windows 2017", NULL, 0, ACPI_OSI_WIN_10_RS2},	/* Windows 10 version 1703 - Added 12/2017 */
	{"Windows 2017.2", NULL, 0, ACPI_OSI_WIN_10_RS3},	/* Windows 10 version 1709 - Added 02/2018 */
	{"Windows 2018", NULL, 0, ACPI_OSI_WIN_10_RS4},	/* Windows 10 version 1803 - Added 11/2018 */
	{"Windows 2018.2", NULL, 0, ACPI_OSI_WIN_10_RS5},	/* Windows 10 version 1809 - Added 11/2018 */
	{"Windows 2019", NULL, 0, ACPI_OSI_WIN_10_19H1},	/* Windows 10 version 1903 - Added 08/2019 */

	/* Feature Group Strings */

	{"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},

	/*
	 * All "optional" feature group strings (features that are implemented
	 * by the host) should be dynamically modified to VALID by the host via
	 * acpi_install_interface or acpi_update_interfaces. Such optional feature
	 * group strings are set as INVALID by default here.
	 */

	{"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
	{"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
	{"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
	{"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
	{"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}
};
However, you sometimes need to disable older versions of Windows because of firmware bugs if you return true to those. Linux looks at the DMI strings to figure it out, and common targets for disablement are Windows Vista and Windows 8. There does not appear to be a universal way of doing it. You can only try the default list, and if things go wrong, dynamically change that list based on the mainboard you are working on.

Re: ACPI Machine Language

Posted: Sat Aug 27, 2022 7:24 am
by devc1
How is the firmware going to call that function, I only know that the OS can decode methods in ACPI and call them, how does this work ? Is the firmware who calls _OSI ? In the Linux documentation it says that _OSI superseds the _OS method to detect if a specific feature is available for e.g. _OSI("3.0 Thermal Model") so can it be called multiple times ? Does the firmware call it using SCI ?
And how to handle SCI ?

Thanks !

Re: ACPI Machine Language

Posted: Sat Aug 27, 2022 12:32 pm
by nullplan
devc1 wrote:How is the firmware going to call that function, I only know that the OS can decode methods in ACPI and call them, how does this work ? Is the firmware who calls _OSI ? In the Linux documentation it says that _OSI superseds the _OS method to detect if a specific feature is available for e.g. _OSI("3.0 Thermal Model") so can it be called multiple times ? Does the firmware call it using SCI ?
And how to handle SCI ?

Thanks !
I don't know the specifics since I intend on using ACPICA. However, if you disassemble your ACPI tables you will probably find references to _OSI in some places, and the firmware interpreter just knows that that function is special, and is implemented in the interpreter itself. So it is just a magic name, I suppose. And yes, the function returns true for multiple different strings.

As for SCI, I have no idea. I will just leave ACPICA to it.

Re: ACPI Machine Language

Posted: Sun Aug 28, 2022 12:41 am
by Ethin
rdos wrote:Just note that ACPI is not very useful anymore.
... What? Unless ACPI recently got superseded by something better, its still pretty much required and very useful. Mind pointing me to its successor? Clearly it has one if its "not very useful anymore".

Re: ACPI Machine Language

Posted: Sun Aug 28, 2022 4:42 am
by xeyes
Ethin wrote:
rdos wrote:Just note that ACPI is not very useful anymore.
... What? Unless ACPI recently got superseded by something better, its still pretty much required and very useful. Mind pointing me to its successor? Clearly it has one if its "not very useful anymore".
While they are closely related, there are still some differences between current and useful, and also, between ACPI and AML.

For AML, personally, I no longer find it worth it to build with ACPICA now. It adds a few MBs, which is huge for a small hobby kernel, in terms of both size and build time.

The only features I got from AML are:
shutdown, which the BIOS will happily do with a simple button press.
_BCL, which doesn't even work on many machines.

Maybe it will be a fun side project to package ACPICA as a user space app later, so kernel size and build time aren't affected. It would still need access to powerful syscalls that give direct hardware accesses, and a right of first refusal to SCI. Almost sounds like what a micro kernel might do for its userspace drivers?

For ACPI tables, I find them easy to parse, don't need a huge VM that is always running in ring0, and provide a lot of useful info.

Just my 2 cents though, whether something is useful or not, is sometimes best described by "One Man's Trash is Another Man's Treasure".

Re: ACPI Machine Language

Posted: Sun Aug 28, 2022 12:07 pm
by Ethin
I mean, ACPI is both current and kinda required. Shutdown can be done by pressing a button but that's forced shutdown, which is rarely a wise idea especially when you've gotten your FS layer going and programs are able to read/write to files and such -- its easy to cause file corruption or any number of other problems. But you need ACPI; without it, a lot of features are denied to you. Current is indeed a problem though; the ACPI specification is current but its common to find computers that follow an older version of the spec, which isn't exactly helpful. ACPI has a lot of problems but until a successor comes a long that entirely replaces it (I really hope this happens soon and its made by smarter people who leave a lot less up to the firmware) we don't really have any other choices unless you want to make a purely realmode/protected mode OS and you never want to use long mode at all.

Re: ACPI Machine Language

Posted: Mon Aug 29, 2022 2:03 am
by rdos
Like several others here, I use ACPICA as my ACPI implementation. I use a rather old version since newer versions doesn't seem to work on some hardware, and neither Linux nor Windows rely on it anymore.

Power button shutdown only works on some hardware, and it is not very useful. If I want to turn off a computer, I can just press the power button for five seconds. Always works.

Doing a RESET is another thing that sometimes works with ACPI and sometimes not. I need to have a config setting for not doing RESET using ACPI on at least one computer. My standard method is to cause a tripple fault, and this works on all computers except for one, but on that one I have a watchdog that can trigger RESET.

Getting the IRQ mappings only is useful on a bit dated hardware where PCI devices doesn't have MSI or MSI-X. This is getting rarer. On hardware with a PIC, the IRQ numbers in PCI are correct and so no need for the ACPI method. Thus, this part of ACPI will get less and less useful. One also should note that older USB interfaces, like UHCI, OHCI and EHCI often doesn't work neither with the ACPI mappings nor with the PIC IRQ numbers. A simple solution for this is to use a 1 ms timer instead. I have this as a fallback for all these three USB interfaces. XHCI will typically support MSI or MSI-X. Thus, for USB hardware, ACPI IRQ mappings certainly are not required.

The ACPI core throttling & frequency objects that at least in theory should be usable for regulating frequency on cores, typically are missing. The only sane method in this area is to use AMDs and Intels processor drivers, or to write them yourself. In short, ACPI is not useful here, and it is more or less indepedent on how old or new your hardware is.

There is also another problem I've encountered. My HP laptop would do RESET after a while if I didn't do the ACPI initialization pretending to be a recent Windows version. That kind of stuff really sucks, but it's part of what people should expect out there. BIOS manufacturers have many different methods for ensuring you are running an up-to-date Windows version. They can do this because of SMI, an interface that never should have been invented.

I don't think there will be a new interface in this area. Things are moving towards chip manufacturers supplying processor drivers & device drivers for major OSes (Windows and Linux), and seldom provide enough documentation for doing them yourself. There are some very common interfaces that are well documented, like USB, AHCI, and Realteks network drivers, but if you go outside of this, you often will be out of luck. Another problem is that many chip manufacturers release more or less beta-versions of their chips, which then need to be patched using special interfaces. Of course, if you don't have Linux driver source, you will be out of luck here too, or get a sub-optimal function of the device.