xref: /onnv-gate/usr/src/uts/i86pc/io/ppm/acpisleep.c (revision 9980:13d7f3eec672)
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