15295Srandyf /*
25295Srandyf * CDDL HEADER START
35295Srandyf *
45295Srandyf * The contents of this file are subject to the terms of the
55295Srandyf * Common Development and Distribution License (the "License").
65295Srandyf * You may not use this file except in compliance with the License.
75295Srandyf *
85295Srandyf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95295Srandyf * or http://www.opensolaris.org/os/licensing.
105295Srandyf * See the License for the specific language governing permissions
115295Srandyf * and limitations under the License.
125295Srandyf *
135295Srandyf * When distributing Covered Code, include this CDDL HEADER in each
145295Srandyf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155295Srandyf * If applicable, add the following below this CDDL HEADER, with the
165295Srandyf * fields enclosed by brackets "[]" replaced with your own identifying
175295Srandyf * information: Portions Copyright [yyyy] [name of copyright owner]
185295Srandyf *
195295Srandyf * CDDL HEADER END
205295Srandyf */
215295Srandyf
225295Srandyf /*
23*9980SDana.Myers@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245295Srandyf * Use is subject to license terms.
255295Srandyf */
265295Srandyf
275295Srandyf #include <sys/types.h>
285295Srandyf #include <sys/smp_impldefs.h>
295295Srandyf #include <sys/promif.h>
305295Srandyf
315295Srandyf #include <sys/kmem.h>
325295Srandyf #include <sys/archsystm.h>
335295Srandyf #include <sys/cpuvar.h>
345295Srandyf #include <sys/pte.h>
355295Srandyf #include <vm/seg_kmem.h>
365295Srandyf #include <sys/epm.h>
375732Srandyf #include <sys/cpr.h>
385295Srandyf #include <sys/machsystm.h>
395295Srandyf #include <sys/clock.h>
405295Srandyf
415295Srandyf #include <sys/cpr_wakecode.h>
425295Srandyf #include <sys/acpi/acpi.h>
435295Srandyf
445295Srandyf #ifdef OLDPMCODE
455295Srandyf #include "acpi.h"
465295Srandyf #endif
475295Srandyf
485295Srandyf #include <sys/x86_archext.h>
495295Srandyf #include <sys/reboot.h>
505295Srandyf #include <sys/cpu_module.h>
515295Srandyf #include <sys/kdi.h>
525295Srandyf
535295Srandyf /*
545295Srandyf * S3 stuff
555295Srandyf */
565295Srandyf
575295Srandyf int acpi_rtc_wake = 0x0; /* wake in N seconds */
585295Srandyf
595295Srandyf #if 0 /* debug */
605295Srandyf static uint8_t branchbuf[64 * 1024]; /* for the HDT branch trace stuff */
615295Srandyf #endif /* debug */
625295Srandyf
635295Srandyf extern int boothowto;
645295Srandyf
655295Srandyf #define BOOTCPU 0 /* cpu 0 is always the boot cpu */
665295Srandyf
675295Srandyf extern void kernel_wc_code(void);
685295Srandyf extern tod_ops_t *tod_ops;
695295Srandyf extern int flushes_require_xcalls;
705295Srandyf extern int tsc_gethrtime_enable;
715295Srandyf
725295Srandyf extern cpuset_t cpu_ready_set;
735295Srandyf extern void *(*cpu_pause_func)(void *);
745295Srandyf
755295Srandyf
765295Srandyf
775295Srandyf /*
785295Srandyf * This is what we've all been waiting for!
795295Srandyf */
805295Srandyf int
acpi_enter_sleepstate(s3a_t * s3ap)815295Srandyf acpi_enter_sleepstate(s3a_t *s3ap)
825295Srandyf {
835295Srandyf ACPI_PHYSICAL_ADDRESS wakephys = s3ap->s3a_wakephys;
845295Srandyf caddr_t wakevirt = rm_platter_va;
855295Srandyf /*LINTED*/
865295Srandyf wakecode_t *wp = (wakecode_t *)wakevirt;
875295Srandyf uint_t Sx = s3ap->s3a_state;
885295Srandyf
895295Srandyf PT(PT_SWV);
905295Srandyf /* Set waking vector */
915295Srandyf if (AcpiSetFirmwareWakingVector(wakephys) != AE_OK) {
925295Srandyf PT(PT_SWV_FAIL);
935295Srandyf PMD(PMD_SX, ("Can't SetFirmwareWakingVector(%lx)\n",
945295Srandyf (long)wakephys))
955295Srandyf goto insomnia;
965295Srandyf }
975295Srandyf
985295Srandyf PT(PT_EWE);
995295Srandyf /* Enable wake events */
1005295Srandyf if (AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, 0) != AE_OK) {
1015295Srandyf PT(PT_EWE_FAIL);
1025295Srandyf PMD(PMD_SX, ("Can't EnableEvent(POWER_BUTTON)\n"))
1035295Srandyf }
1045295Srandyf if (acpi_rtc_wake > 0) {
1057851SDana.Myers@Sun.COM /* clear the RTC bit first */
106*9980SDana.Myers@Sun.COM (void) AcpiWriteBitRegister(ACPI_BITREG_RT_CLOCK_STATUS, 1);
1075295Srandyf PT(PT_RTCW);
1085295Srandyf if (AcpiEnableEvent(ACPI_EVENT_RTC, 0) != AE_OK) {
1095295Srandyf PT(PT_RTCW_FAIL);
1105295Srandyf PMD(PMD_SX, ("Can't EnableEvent(RTC)\n"))
1115295Srandyf }
1125295Srandyf
1135295Srandyf /*
1145295Srandyf * Set RTC to wake us in a wee while.
1155295Srandyf */
1165295Srandyf mutex_enter(&tod_lock);
1175295Srandyf PT(PT_TOD);
1185295Srandyf TODOP_SETWAKE(tod_ops, acpi_rtc_wake);
1195295Srandyf mutex_exit(&tod_lock);
1205295Srandyf }
1215295Srandyf
1225295Srandyf /*
1235295Srandyf * Prepare for sleep ... could've done this earlier?
1245295Srandyf */
1255295Srandyf PT(PT_SXP);
1265295Srandyf PMD(PMD_SX, ("Calling AcpiEnterSleepStatePrep(%d) ...\n", Sx))
1275295Srandyf if (AcpiEnterSleepStatePrep(Sx) != AE_OK) {
1285295Srandyf PMD(PMD_SX, ("... failed\n!"))
1295295Srandyf goto insomnia;
1305295Srandyf }
1315295Srandyf
1325295Srandyf switch (s3ap->s3a_test_point) {
1335295Srandyf case DEVICE_SUSPEND_TO_RAM:
1345732Srandyf case FORCE_SUSPEND_TO_RAM:
1355295Srandyf case LOOP_BACK_PASS:
1365295Srandyf return (0);
1375295Srandyf case LOOP_BACK_FAIL:
1385295Srandyf return (1);
1395295Srandyf default:
1405732Srandyf ASSERT(s3ap->s3a_test_point == LOOP_BACK_NONE);
1415295Srandyf }
1425295Srandyf
1435295Srandyf /*
1445295Srandyf * Tell the hardware to sleep.
1455295Srandyf */
1465295Srandyf PT(PT_SXE);
1475295Srandyf PMD(PMD_SX, ("Calling AcpiEnterSleepState(%d) ...\n", Sx))
1485295Srandyf if (AcpiEnterSleepState(Sx) != AE_OK) {
1495295Srandyf PT(PT_SXE_FAIL);
1505295Srandyf PMD(PMD_SX, ("... failed!\n"))
1515295Srandyf }
1525295Srandyf
1535295Srandyf insomnia:
1545295Srandyf PT(PT_INSOM);
1555295Srandyf /* cleanup is done in the caller */
1565295Srandyf return (1);
1575295Srandyf }
1585295Srandyf
1595295Srandyf int
acpi_exit_sleepstate(s3a_t * s3ap)1605295Srandyf acpi_exit_sleepstate(s3a_t *s3ap)
1615295Srandyf {
1625295Srandyf int Sx = s3ap->s3a_state;
1635295Srandyf
1645295Srandyf PT(PT_WOKE);
1655295Srandyf PMD(PMD_SX, ("!We woke up!\n"))
1665295Srandyf
1675295Srandyf PT(PT_LSS);
1685295Srandyf if (AcpiLeaveSleepState(Sx) != AE_OK) {
1695295Srandyf PT(PT_LSS_FAIL);
1705295Srandyf PMD(PMD_SX, ("Problem with LeaveSleepState!\n"))
1715295Srandyf }
1725295Srandyf
1737651SPhi.Tran@Sun.COM PT(PT_CPB);
1747651SPhi.Tran@Sun.COM if (AcpiClearEvent(ACPI_EVENT_POWER_BUTTON) != AE_OK) {
1757651SPhi.Tran@Sun.COM PT(PT_CPB_FAIL);
1767651SPhi.Tran@Sun.COM PMD(PMD_SX, ("Problem w/ ClearEvent(POWER_BUTTON)\n"))
1775295Srandyf }
1785295Srandyf if (acpi_rtc_wake > 0 &&
1795295Srandyf AcpiDisableEvent(ACPI_EVENT_RTC, 0) != AE_OK) {
1805295Srandyf PT(PT_DRTC_FAIL);
1815295Srandyf PMD(PMD_SX, ("Problem w/ DisableEvent(RTC)\n"))
1825295Srandyf }
1835295Srandyf
1845295Srandyf PMD(PMD_SX, ("Exiting acpi_sleepstate() => 0\n"))
1855295Srandyf
1865295Srandyf return (0);
1875295Srandyf }
188