svn commit: r247881 - in stable/9/sys: amd64/acpica dev/acpica i386/acpica ia64/acpica
Andriy Gapon
avg at FreeBSD.org
Wed Mar 6 10:23:58 UTC 2013
Author: avg
Date: Wed Mar 6 10:23:56 2013
New Revision: 247881
URL: http://svnweb.freebsd.org/changeset/base/247881
Log:
MFC r233579,236403,236408: make interrupt flags management closer to head
r233579: Restore interrupt state after executing AcpiEnterSleepState().
r236403,236408: acpi_wakeup_machdep/acpi_sleep_machdep
The merged changes are modified a bit to account for lots of missing
acpi and acpica MFCs.
For the same reason MFC to stable/8 is not practical.
MFC slackers: iwasaki, jkim
Modified:
stable/9/sys/amd64/acpica/acpi_wakeup.c
stable/9/sys/dev/acpica/acpi.c
stable/9/sys/dev/acpica/acpivar.h
stable/9/sys/i386/acpica/acpi_wakeup.c
stable/9/sys/ia64/acpica/acpi_wakeup.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/sys/amd64/acpica/acpi_wakeup.c
==============================================================================
--- stable/9/sys/amd64/acpica/acpi_wakeup.c Wed Mar 6 09:53:38 2013 (r247880)
+++ stable/9/sys/amd64/acpica/acpi_wakeup.c Wed Mar 6 10:23:56 2013 (r247881)
@@ -76,6 +76,10 @@ static struct pcb **susppcbs;
static void **suspfpusave;
#endif
+#ifdef SMP
+static cpuset_t suspcpus;
+#endif
+
int acpi_restorecpu(uint64_t, vm_offset_t);
static void *acpi_alloc_wakeup_handler(void);
@@ -220,21 +224,14 @@ acpi_wakeup_cpus(struct acpi_softc *sc,
int
acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
-#ifdef SMP
- cpuset_t wakeup_cpus;
-#endif
- register_t rf;
ACPI_STATUS status;
- int ret;
-
- ret = -1;
if (sc->acpi_wakeaddr == 0ul)
- return (ret);
+ return (-1); /* couldn't alloc wake memory */
#ifdef SMP
- wakeup_cpus = all_cpus;
- CPU_CLR(PCPU_GET(cpuid), &wakeup_cpus);
+ suspcpus = all_cpus;
+ CPU_CLR(PCPU_GET(cpuid), &suspcpus);
#endif
if (acpi_resume_beep != 0)
@@ -242,16 +239,15 @@ acpi_sleep_machdep(struct acpi_softc *sc
AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc));
- rf = intr_disable();
intr_suspend();
if (savectx(susppcbs[0])) {
ctx_fpusave(suspfpusave[0]);
#ifdef SMP
- if (!CPU_EMPTY(&wakeup_cpus) &&
- suspend_cpus(wakeup_cpus) == 0) {
+ if (!CPU_EMPTY(&suspcpus) &&
+ suspend_cpus(suspcpus) == 0) {
device_printf(sc->acpi_dev, "Failed to suspend APs\n");
- goto out;
+ return (0); /* couldn't sleep */
}
#endif
@@ -276,41 +272,54 @@ acpi_sleep_machdep(struct acpi_softc *sc
device_printf(sc->acpi_dev,
"AcpiEnterSleepState failed - %s\n",
AcpiFormatException(status));
- goto out;
+ return (0); /* couldn't sleep */
}
for (;;)
ia32_pause();
- } else {
- pmap_init_pat();
- load_cr3(susppcbs[0]->pcb_cr3);
- initializecpu();
- PCPU_SET(switchtime, 0);
- PCPU_SET(switchticks, ticks);
-#ifdef SMP
- if (!CPU_EMPTY(&wakeup_cpus))
- acpi_wakeup_cpus(sc, &wakeup_cpus);
-#endif
- ret = 0;
}
-out:
+ return (1); /* wakeup successfully */
+}
+
+int
+acpi_wakeup_machdep(struct acpi_softc *sc, int state,
+ int sleep_result, int intr_enabled)
+{
+
+ if (sleep_result == -1)
+ return (sleep_result);
+
+ if (intr_enabled == 0) {
+ /* Wakeup MD procedures in interrupt disabled context */
+ if (sleep_result == 1) {
+ pmap_init_pat();
+ load_cr3(susppcbs[0]->pcb_cr3);
+ initializecpu();
+ PCPU_SET(switchtime, 0);
+ PCPU_SET(switchticks, ticks);
#ifdef SMP
- if (!CPU_EMPTY(&wakeup_cpus))
- restart_cpus(wakeup_cpus);
+ if (!CPU_EMPTY(&suspcpus))
+ acpi_wakeup_cpus(sc, &suspcpus);
#endif
+ }
- mca_resume();
- intr_resume();
- intr_restore(rf);
-
- AcpiSetFirmwareWakingVector(0);
+#ifdef SMP
+ if (!CPU_EMPTY(&suspcpus))
+ restart_cpus(suspcpus);
+#endif
+ mca_resume();
+ intr_resume();
+ } else {
+ /* Wakeup MD procedures in interrupt enabled context */
+ AcpiSetFirmwareWakingVector(0);
- if (ret == 0 && mem_range_softc.mr_op != NULL &&
- mem_range_softc.mr_op->reinit != NULL)
- mem_range_softc.mr_op->reinit(&mem_range_softc);
+ if (sleep_result == 1 && mem_range_softc.mr_op != NULL &&
+ mem_range_softc.mr_op->reinit != NULL)
+ mem_range_softc.mr_op->reinit(&mem_range_softc);
+ }
- return (ret);
+ return (sleep_result);
}
static void *
Modified: stable/9/sys/dev/acpica/acpi.c
==============================================================================
--- stable/9/sys/dev/acpica/acpi.c Wed Mar 6 09:53:38 2013 (r247880)
+++ stable/9/sys/dev/acpica/acpi.c Wed Mar 6 10:23:56 2013 (r247881)
@@ -1960,6 +1960,7 @@ static void
acpi_shutdown_final(void *arg, int howto)
{
struct acpi_softc *sc = (struct acpi_softc *)arg;
+ register_t intr;
ACPI_STATUS status;
/*
@@ -1975,13 +1976,15 @@ acpi_shutdown_final(void *arg, int howto
return;
}
device_printf(sc->acpi_dev, "Powering system off\n");
- ACPI_DISABLE_IRQS();
+ intr = intr_disable();
status = AcpiEnterSleepState(ACPI_STATE_S5);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ intr_restore(intr);
device_printf(sc->acpi_dev, "power-off failed - %s\n",
AcpiFormatException(status));
- else {
+ } else {
DELAY(1000000);
+ intr_restore(intr);
device_printf(sc->acpi_dev, "power-off failed - timeout\n");
}
} else if ((howto & RB_HALT) == 0 && sc->acpi_handle_reboot) {
@@ -2652,8 +2655,10 @@ enum acpi_sleep_state {
static ACPI_STATUS
acpi_EnterSleepState(struct acpi_softc *sc, int state)
{
- ACPI_STATUS status;
+ register_t intr;
+ ACPI_STATUS status;
enum acpi_sleep_state slp_state;
+ int sleep_result;
ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
@@ -2733,15 +2738,24 @@ acpi_EnterSleepState(struct acpi_softc *
if (sc->acpi_sleep_delay > 0)
DELAY(sc->acpi_sleep_delay * 1000000);
+ intr = intr_disable();
if (state != ACPI_STATE_S1) {
- acpi_sleep_machdep(sc, state);
+ sleep_result = acpi_sleep_machdep(sc, state);
+ acpi_wakeup_machdep(sc, state, sleep_result, 0);
+ intr_restore(intr);
+
+ /* call acpi_wakeup_machdep() again with interrupt enabled */
+ acpi_wakeup_machdep(sc, state, sleep_result, 1);
+
+ if (sleep_result == -1)
+ goto backout;
/* Re-enable ACPI hardware on wakeup from sleep state 4. */
if (state == ACPI_STATE_S4)
AcpiEnable();
} else {
- ACPI_DISABLE_IRQS();
status = AcpiEnterSleepState(state);
+ intr_restore(intr);
if (ACPI_FAILURE(status)) {
device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n",
AcpiFormatException(status));
Modified: stable/9/sys/dev/acpica/acpivar.h
==============================================================================
--- stable/9/sys/dev/acpica/acpivar.h Wed Mar 6 09:53:38 2013 (r247880)
+++ stable/9/sys/dev/acpica/acpivar.h Wed Mar 6 10:23:56 2013 (r247881)
@@ -434,6 +434,8 @@ int acpi_disabled(char *subsys);
int acpi_machdep_init(device_t dev);
void acpi_install_wakeup_handler(struct acpi_softc *sc);
int acpi_sleep_machdep(struct acpi_softc *sc, int state);
+int acpi_wakeup_machdep(struct acpi_softc *sc, int state,
+ int sleep_result, int intr_enabled);
int acpi_table_quirks(int *quirks);
int acpi_machdep_quirks(int *quirks);
Modified: stable/9/sys/i386/acpica/acpi_wakeup.c
==============================================================================
--- stable/9/sys/i386/acpica/acpi_wakeup.c Wed Mar 6 09:53:38 2013 (r247880)
+++ stable/9/sys/i386/acpica/acpi_wakeup.c Wed Mar 6 10:23:56 2013 (r247881)
@@ -74,6 +74,10 @@ extern struct pcb **susppcbs;
static struct pcb **susppcbs;
#endif
+#ifdef SMP
+static cpuset_t suspcpus;
+#endif
+
static void *acpi_alloc_wakeup_handler(void);
static void acpi_stop_beep(void *);
@@ -212,22 +216,14 @@ acpi_wakeup_cpus(struct acpi_softc *sc,
int
acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
-#ifdef SMP
- cpuset_t wakeup_cpus;
-#endif
- register_t cr3, rf;
ACPI_STATUS status;
- struct pmap *pm;
- int ret;
-
- ret = -1;
if (sc->acpi_wakeaddr == 0ul)
- return (ret);
+ return (-1); /* couldn't alloc wake memory */
#ifdef SMP
- wakeup_cpus = all_cpus;
- CPU_CLR(PCPU_GET(cpuid), &wakeup_cpus);
+ suspcpus = all_cpus;
+ CPU_CLR(PCPU_GET(cpuid), &suspcpus);
#endif
if (acpi_resume_beep != 0)
@@ -235,28 +231,14 @@ acpi_sleep_machdep(struct acpi_softc *sc
AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc));
- rf = intr_disable();
intr_suspend();
- /*
- * Temporarily switch to the kernel pmap because it provides
- * an identity mapping (setup at boot) for the low physical
- * memory region containing the wakeup code.
- */
- pm = kernel_pmap;
- cr3 = rcr3();
-#ifdef PAE
- load_cr3(vtophys(pm->pm_pdpt));
-#else
- load_cr3(vtophys(pm->pm_pdir));
-#endif
-
if (suspendctx(susppcbs[0])) {
#ifdef SMP
- if (!CPU_EMPTY(&wakeup_cpus) &&
- suspend_cpus(wakeup_cpus) == 0) {
+ if (!CPU_EMPTY(&suspcpus) &&
+ suspend_cpus(suspcpus) == 0) {
device_printf(sc->acpi_dev, "Failed to suspend APs\n");
- goto out;
+ return (0); /* couldn't sleep */
}
#endif
@@ -264,8 +246,6 @@ acpi_sleep_machdep(struct acpi_softc *sc
WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));
WAKECODE_FIXUP(wakeup_cr4, register_t, susppcbs[0]->pcb_cr4);
- WAKECODE_FIXUP(wakeup_cr3, register_t, susppcbs[0]->pcb_cr3);
-
WAKECODE_FIXUP(wakeup_pcb, struct pcb *, susppcbs[0]);
/* Call ACPICA to enter the desired sleep state */
@@ -278,41 +258,54 @@ acpi_sleep_machdep(struct acpi_softc *sc
device_printf(sc->acpi_dev,
"AcpiEnterSleepState failed - %s\n",
AcpiFormatException(status));
- goto out;
+ return (0); /* couldn't sleep */
}
for (;;)
ia32_pause();
- } else {
- pmap_init_pat();
- initializecpu();
- PCPU_SET(switchtime, 0);
- PCPU_SET(switchticks, ticks);
+ }
+
+ return (1); /* wakeup successfully */
+}
+
+int
+acpi_wakeup_machdep(struct acpi_softc *sc, int state,
+ int sleep_result, int intr_enabled)
+{
+
+ if (sleep_result == -1)
+ return (sleep_result);
+
+ if (intr_enabled == 0) {
+ /* Wakeup MD procedures in interrupt disabled context */
+ if (sleep_result == 1) {
+ pmap_init_pat();
+ load_cr3(susppcbs[0]->pcb_cr3);
+ initializecpu();
+ PCPU_SET(switchtime, 0);
+ PCPU_SET(switchticks, ticks);
#ifdef SMP
- if (!CPU_EMPTY(&wakeup_cpus))
- acpi_wakeup_cpus(sc, &wakeup_cpus);
+ if (!CPU_EMPTY(&suspcpus))
+ acpi_wakeup_cpus(sc, &suspcpus);
#endif
- ret = 0;
- }
+ }
-out:
#ifdef SMP
- if (!CPU_EMPTY(&wakeup_cpus))
- restart_cpus(wakeup_cpus);
+ if (!CPU_EMPTY(&suspcpus))
+ restart_cpus(suspcpus);
#endif
+ mca_resume();
+ intr_resume();
+ } else {
+ /* Wakeup MD procedures in interrupt enabled context */
+ AcpiSetFirmwareWakingVector(0);
- load_cr3(cr3);
- mca_resume();
- intr_resume();
- intr_restore(rf);
-
- AcpiSetFirmwareWakingVector(0);
-
- if (ret == 0 && mem_range_softc.mr_op != NULL &&
- mem_range_softc.mr_op->reinit != NULL)
- mem_range_softc.mr_op->reinit(&mem_range_softc);
+ if (sleep_result == 1 && mem_range_softc.mr_op != NULL &&
+ mem_range_softc.mr_op->reinit != NULL)
+ mem_range_softc.mr_op->reinit(&mem_range_softc);
+ }
- return (ret);
+ return (sleep_result);
}
static void *
@@ -373,6 +366,16 @@ acpi_install_wakeup_handler(struct acpi_
/* Save pointers to some global data. */
WAKECODE_FIXUP(wakeup_ret, void *, resumectx);
+ /*
+ * Temporarily switch to the kernel pmap because it provides
+ * an identity mapping (setup at boot) for the low physical
+ * memory region containing the wakeup code.
+ */
+#ifdef PAE
+ WAKECODE_FIXUP(wakeup_cr3, register_t, vtophys(kernel_pmap->pm_pdpt));
+#else
+ WAKECODE_FIXUP(wakeup_cr3, register_t, vtophys(kernel_pmap->pm_pdir));
+#endif
if (bootverbose)
device_printf(sc->acpi_dev, "wakeup code va %#x pa %#jx\n",
Modified: stable/9/sys/ia64/acpica/acpi_wakeup.c
==============================================================================
--- stable/9/sys/ia64/acpica/acpi_wakeup.c Wed Mar 6 09:53:38 2013 (r247880)
+++ stable/9/sys/ia64/acpica/acpi_wakeup.c Wed Mar 6 10:23:56 2013 (r247881)
@@ -39,6 +39,13 @@ acpi_sleep_machdep(struct acpi_softc *sc
return (0);
}
+int
+acpi_wakeup_machdep(struct acpi_softc *sc, int state,
+ int sleep_result, int intr_enabled)
+{
+ return (0);
+}
+
void
acpi_install_wakeup_handler(struct acpi_softc *sc)
{
More information about the svn-src-stable-9
mailing list