Discussion:
[PATCH] Add ACPI translator and shutdown RPC that turns off pc
Damien Zammit
2018-11-24 23:48:39 UTC
Permalink
Hi all,

I have written a new RPC that is called from startup for shutting down
the pc. It has been tested on QEMU and successfully powers off the
machine causing the qemu window to disappear without manually closing it
when you type "halt" as root and it goes through the proper shutdown
sequence first.

In summary, the startup translator does its shutdown sequence, then
calls the shutdown translator which calls into the ACPI translator to
fetch the ACPI registers for shutdown and values to write, then writes
the correct shutdown sequence to the IO.

The reason for all the indirection is that the acpi tables can be reused
for other purposes than just shutdown, and it makes sense to put the
shutdown sequence as a separate RPC so that other machine specific
shutdown sequences can be added later, not just for x86.

Please see attached 3 patches for a complete working implementation.

Thanks,
Damien
Kalle Olavi Niemitalo
2018-11-25 08:58:07 UTC
Permalink
+ /* Enable ACPI */
+ outb(acpi_en, smi_cmd);
+ for (i = 0; i < 300; i++)
+ {
+ if ( (inw(pm1a_ctl) & SCI_EN) == SCI_EN)
+ break;
+ }
Perhaps this code should first check whether the SCI_EN bit is
already set, as described in ACPI 5.0 section 4.8.2.5
"Legacy/ACPI Select and the SCI Interrupt", and skip the outb if
so. Section 5.2.9 "Fixed ACPI Description Table (FADT)" says the
SMI_CMD field of FADT can be zero.
+ /* try sleep state 5 first */
+ outw(SLP_TYP5 | SLP_EN, pm1a_ctl);
+
+ /* if we reach here then above did not work */
+ outw(SLP_TYP0 | SLP_EN, pm1a_ctl);
More about these below.
+#define SLP_TYP0 (0x0 << 10)
+#define SLP_TYP5 (0x5 << 10)
This hardcodes QEMU-specific values. ACPI 5.0 section 7.3.4 says
the values for PM1a_CNT.SLP_TYP must be read from the \S0-\S5
objects. The DSDT of my laptop has:

Name (_S5, Package (0x04) // _S5_: S5 System State
{
0x07,
Zero,
Zero,
Zero
})

so PM1a_CNT.SLP_TYP on this system should be 7, not 5. However,
implementing this properly would require an AML interpreter; the
DSDT of my laptop also has:

If (LEqual (S3DS, One))
{
Name (_S3, Package (0x04) // _S3_: S3 System State
{
0x05,
Zero,
Zero,
Zero
})
}

and defines S3DS as a field in an OperationRegion, so OSPM
would have to understand those concepts in order to know
whether \_S3 exists. I assume a similar construct is possible
for \_S5.

Maybe it's good enough if S5 works on QEMU. In that case though,
I would like to see a comment warning about this limitation.
Damien Zammit
2018-11-25 10:10:11 UTC
Permalink
Hi Kalle,
Post by Kalle Olavi Niemitalo
Perhaps this code should first check whether the SCI_EN bit is
already set, as described in ACPI 5.0 section 4.8.2.5
"Legacy/ACPI Select and the SCI Interrupt", and skip the outb if
so. Section 5.2.9 "Fixed ACPI Description Table (FADT)" says the
SMI_CMD field of FADT can be zero.
Thanks for the information, I will do this.
Post by Kalle Olavi Niemitalo
+#define SLP_TYP0 (0x0 << 10)
+#define SLP_TYP5 (0x5 << 10)
This hardcodes QEMU-specific values. ACPI 5.0 section 7.3.4 says
the values for PM1a_CNT.SLP_TYP must be read from the \S0-\S5
objects.
Damn, I want to avoid putting a whole AML interpreter into hurd.
I thought the sleep value for S5 == 0x5 but clearly this is not the
case. Now that you have pointed this out, I dont know how to make this
work for all cases without putting an AML interpreter into hurd as you said.
Post by Kalle Olavi Niemitalo
If (LEqual (S3DS, One))
{
Name (_S3, Package (0x04) // _S3_: S3 System State
{
0x05,
Zero,
Zero,
Zero
})
}
Surely S5 always has to exist, how else do you power off the machine?
Some machines don't have suspend S3. Maybe I can do some clever walk of
the binary to find the _S5 object and extract the SLP_TYP value instead
of a whole AML interpreter?
Post by Kalle Olavi Niemitalo
Maybe it's good enough if S5 works on QEMU. In that case though,
I would like to see a comment warning about this limitation.
For now I will indeed add a comment stating the limitation.

Thanks for review!
Damien
Kalle Olavi Niemitalo
2018-11-25 10:25:03 UTC
Permalink
Post by Damien Zammit
Surely S5 always has to exist, how else do you power off the machine?
There could perhaps be an Else branch with different values.

Loading...