On Fri, Jul 26, 2013 at 06:37:08PM +0200, Gerd Hoffmann wrote: > Qemu commit 9ee59f3 removed the bochs bios apm interface emulation at > port 0x8900. That broke poweroff via APM. Fix it by powering off the > machine using the acpi pm control register. > > Old code is left in, so seabios wil try both poweroff methods. Cleaning > that eventually up is left for another patch, after checking it isn't > needed. Qemu never implemented "Standby" and "Suspend", only > "Shutdown", so it looks like there might be non-qemu use cases (bochs > probably). > > Easiest way to test this is the syslinux poweroff module; modern linux > distros usually have CONFIG_APM turned off. > > Reported-by: Sebastian Herbszt <[email protected]> > Signed-off-by: Gerd Hoffmann <[email protected]> > --- > src/acpi.c | 5 +++++ > src/acpi.h | 1 + > src/apm.c | 2 ++ > 3 files changed, 8 insertions(+) > > diff --git a/src/acpi.c b/src/acpi.c > index 3699898..44ba507 100644 > --- a/src/acpi.c > +++ b/src/acpi.c > @@ -18,6 +18,8 @@ > > #include "acpi-dsdt.hex" > > +u32 acpi_pm1a_cnt VARLOW = PORT_ACPI_PM_BASE + 0x04; > + > static void > build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) > { > @@ -730,9 +732,12 @@ find_acpi_features(void) > if (!fadt) > return; > u32 pm_tmr = le32_to_cpu(fadt->pm_tmr_blk); > + u32 pm1a_cnt = le32_to_cpu(fadt->pm1a_cnt_blk); > dprintf(4, "pm_tmr_blk=%x\n", pm_tmr); > if (pm_tmr) > pmtimer_setup(pm_tmr, 3579); > + if (pm1a_cnt) > + acpi_pm1a_cnt = pm1a_cnt; > > // Theoretically we should check the 'reset_reg_sup' flag, but Windows > // doesn't and thus nobody seems to *set* it. If the table is large > enough > diff --git a/src/acpi.h b/src/acpi.h > index 5d1e104..f0d24d4 100644 > --- a/src/acpi.h > +++ b/src/acpi.h > @@ -36,6 +36,7 @@ struct rsdp_descriptor { /* Root System Descriptor > Pointer */ > }; > > extern struct rsdp_descriptor *RsdpAddr; > +extern u32 acpi_pm1a_cnt; > > /* Table structure from Linux kernel (the ACPI tables are under the > BSD license) */ > diff --git a/src/apm.c b/src/apm.c > index b2eac6d..b3b351c 100644 > --- a/src/apm.c > +++ b/src/apm.c > @@ -12,6 +12,7 @@ > #include "config.h" // CONFIG_* > #include "biosvar.h" // GET_GLOBAL > #include "paravirt.h" // runningOnQEMU > +#include "acpi.h" // acpi_pm_ctl > > static void > out_str(const char *str_cs) > @@ -109,6 +110,7 @@ void > apm_shutdown(void) > { > irq_disable(); > + outw(0x2000, acpi_pm1a_cnt);
This code is also run from 16bit protected mode and 32bit protected mode, so only GET_GLOBAL() access is permitted. Also, it can't default to PORT_ACPI_PM_BASE, because if a valid ACPI table isn't found we don't want to touch random ports. Is the code to write always guaranteed to be 0x2000? -Kevin _______________________________________________ SeaBIOS mailing list [email protected] http://www.seabios.org/mailman/listinfo/seabios
