hwsleep.c revision 114237
144633Skato 241199Skato/****************************************************************************** 333080Skato * 441199Skato * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface 516359Sasami * $Revision: 52 $ 616359Sasami * 716359Sasami *****************************************************************************/ 834458Skato 930329Skato/****************************************************************************** 1016359Sasami * 1116359Sasami * 1. Copyright Notice 1216359Sasami * 1337338Skato * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. 1416359Sasami * All rights reserved. 1537338Skato * 1637338Skato * 2. License 1744082Skato * 1844082Skato * 2.1. This is your license from Intel Corp. under its intellectual property 1929006Skato * rights. You may have additional license terms from the party that provided 2033711Skato * you this software, covering your right to use that party's intellectual 2129006Skato * property rights. 2229006Skato * 2316359Sasami * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2432939Skato * copy of the source code appearing in this file ("Covered Code") an 2516359Sasami * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2616359Sasami * base code distributed originally by Intel ("Original Intel Code") to copy, 2716359Sasami * make derivatives, distribute, use and display any portion of the Covered 2826477Skato * Code in any form, with the right to sublicense such rights; and 2916359Sasami * 3016359Sasami * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3129631Skato * license (with the right to sublicense), under only those claims of Intel 3232092Skato * patents that are infringed by the Original Intel Code, to make, use, sell, 3327844Skato * offer to sell, and import the Covered Code and derivative works thereof 3427844Skato * solely to the minimum extent necessary to exercise the above copyright 3517256Sasami * license, and in no event shall the patent license extend to any additions 3641975Skato * to or modifications of the Original Intel Code. No other license or right 3725572Skato * is granted directly or by implication, estoppel or otherwise; 3825195Skato * 3925195Skato * The above copyright and patent license is granted only if the following 4025195Skato * conditions are met: 4133080Skato * 4233080Skato * 3. Conditions 4333080Skato * 4444633Skato * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4518208Sasami * Redistribution of source code of any substantial portion of the Covered 4631556Skato * Code or modification with rights to further distribute source must include 4727392Skato * the above Copyright Notice, the above License, this list of Conditions, 4827392Skato * and the following Disclaimer and Export Compliance provision. In addition, 4933019Skato * Licensee must cause all Covered Code to which Licensee contributes to 5027391Skato * contain a file documenting the changes Licensee made to create that Covered 5133019Skato * Code and the date of any change. Licensee must include in that file the 5233019Skato * documentation of any changes made by any predecessor Licensee. Licensee 5333019Skato * must include a prominent statement that the modification is derived, 5433019Skato * directly or indirectly, from Original Intel Code. 5533019Skato * 5633019Skato * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5733019Skato * Redistribution of source code of any substantial portion of the Covered 5833019Skato * Code or modification without rights to further distribute source must 5940003Skato * include the following Disclaimer and Export Compliance provision in the 6033019Skato * documentation and/or other materials provided with distribution. In 6133019Skato * addition, Licensee may not authorize further sublicense of source of any 6242163Skato * portion of the Covered Code, and must include terms to the effect that the 6319122Sasami * license from Licensee to its licensee is limited to the intellectual 6429006Skato * property embodied in the software Licensee provides to its licensee, and 6529006Skato * not to intellectual property embodied in modifications its licensee may 6629006Skato * make. 6729006Skato * 6829006Skato * 3.3. Redistribution of Executable. Redistribution in executable form of any 6929006Skato * substantial portion of the Covered Code or modification must reproduce the 7018265Sasami * above Copyright Notice, and the following Disclaimer and Export Compliance 7127692Skato * provision in the documentation and/or other materials provided with the 7229137Skato * distribution. 7333270Skato * 7433270Skato * 3.4. Intel retains all right, title, and interest in and to the Original 7518208Sasami * Intel Code. 7642795Skato * 7742795Skato * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7839347Skato * Intel shall be used in advertising or otherwise to promote the sale, use or 7939347Skato * other dealings in products derived from or relating to the Covered Code 8042795Skato * without prior written authorization from Intel. 8142795Skato * 8227173Skato * 4. Disclaimer and Export Compliance 8327173Skato * 8421773Skato * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8521773Skato * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8639002Skato * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8739002Skato * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8842795Skato * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8942795Skato * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9042795Skato * PARTICULAR PURPOSE. 9142795Skato * 9242795Skato * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9321773Skato * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9418208Sasami * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9518208Sasami * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9618265Sasami * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9725268Skato * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9825268Skato * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9918265Sasami * LIMITED REMEDY. 10018265Sasami * 10140955Skato * 4.3. Licensee shall not export, either directly or indirectly, any of this 10223847Skato * software or system incorporating such software without first obtaining any 10323847Skato * required license or other approval from the U. S. Department of Commerce or 10429533Skato * any other agency or department of the United States Government. In the 10529533Skato * event Licensee exports any such software from the United States or 10629533Skato * re-exports any such software from a foreign destination, Licensee shall 10741775Skato * ensure that the distribution and export/re-export of the software is in 10830553Skato * compliance with all laws, regulations, orders, or other restrictions of the 10944442Skato * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11044442Skato * any of its subsidiaries will export/re-export any technical data, process, 11142283Skato * software, or service, directly or indirectly, to any country for which the 11242283Skato * United States government or any agency thereof requires an export license, 11342283Skato * other governmental approval, or letter of assurance, without first obtaining 11442283Skato * such license, approval or letter. 11542283Skato * 11642283Skato *****************************************************************************/ 11742283Skato 11842283Skato#include "acpi.h" 11942283Skato 12042283Skato#define _COMPONENT ACPI_HARDWARE 12142283Skato ACPI_MODULE_NAME ("hwsleep") 12242283Skato 12342283Skato 12442283Skato/****************************************************************************** 12542283Skato * 12642283Skato * FUNCTION: AcpiSetFirmwareWakingVector 12742283Skato * 12842283Skato * PARAMETERS: PhysicalAddress - Physical address of ACPI real mode 12942283Skato * entry point. 13042283Skato * 13138225Skato * RETURN: Status 13238225Skato * 13342163Skato * DESCRIPTION: Access function for dFirmwareWakingVector field in FACS 13442163Skato * 13542163Skato ******************************************************************************/ 13642163Skato 13742163SkatoACPI_STATUS 13842163SkatoAcpiSetFirmwareWakingVector ( 13942163Skato ACPI_PHYSICAL_ADDRESS PhysicalAddress) 14042163Skato{ 14142163Skato 14242163Skato ACPI_FUNCTION_TRACE ("AcpiSetFirmwareWakingVector"); 14342163Skato 14442163Skato 14542163Skato /* Set the vector */ 14642163Skato 14742163Skato if (AcpiGbl_CommonFACS.VectorWidth == 32) 14842163Skato { 14942163Skato *(ACPI_CAST_PTR (UINT32, AcpiGbl_CommonFACS.FirmwareWakingVector)) 15042163Skato = (UINT32) PhysicalAddress; 15142163Skato } 15242163Skato else 15342163Skato { 15442163Skato *AcpiGbl_CommonFACS.FirmwareWakingVector 15544633Skato = PhysicalAddress; 15642163Skato } 15742163Skato 15842163Skato return_ACPI_STATUS (AE_OK); 15942163Skato} 16042163Skato 16142163Skato 16242163Skato/****************************************************************************** 16342163Skato * 16442163Skato * FUNCTION: AcpiGetFirmwareWakingVector 16542163Skato * 16642163Skato * PARAMETERS: *PhysicalAddress - Output buffer where contents of 16742163Skato * the FirmwareWakingVector field of 16844633Skato * the FACS will be stored. 16944633Skato * 17044633Skato * RETURN: Status 17144633Skato * 17244633Skato * DESCRIPTION: Access function for FirmwareWakingVector field in FACS 17344633Skato * 17444633Skato ******************************************************************************/ 17542163Skato 17642163SkatoACPI_STATUS 17738225SkatoAcpiGetFirmwareWakingVector ( 17833715Skato ACPI_PHYSICAL_ADDRESS *PhysicalAddress) 17933715Skato{ 18036690Skato 18133715Skato ACPI_FUNCTION_TRACE ("AcpiGetFirmwareWakingVector"); 18234405Skato 18334405Skato 18434405Skato if (!PhysicalAddress) 18533715Skato { 18633715Skato return_ACPI_STATUS (AE_BAD_PARAMETER); 18734643Skato } 18833715Skato 18933715Skato /* Get the vector */ 19039347Skato 191 if (AcpiGbl_CommonFACS.VectorWidth == 32) 192 { 193 *PhysicalAddress = (ACPI_PHYSICAL_ADDRESS) 194 *(ACPI_CAST_PTR (UINT32, AcpiGbl_CommonFACS.FirmwareWakingVector)); 195 } 196 else 197 { 198 *PhysicalAddress = 199 *AcpiGbl_CommonFACS.FirmwareWakingVector; 200 } 201 202 return_ACPI_STATUS (AE_OK); 203} 204 205 206/****************************************************************************** 207 * 208 * FUNCTION: AcpiEnterSleepStatePrep 209 * 210 * PARAMETERS: SleepState - Which sleep state to enter 211 * 212 * RETURN: Status 213 * 214 * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) 215 * This function must execute with interrupts enabled. 216 * We break sleeping into 2 stages so that OSPM can handle 217 * various OS-specific tasks between the two steps. 218 * 219 ******************************************************************************/ 220 221ACPI_STATUS 222AcpiEnterSleepStatePrep ( 223 UINT8 SleepState) 224{ 225 ACPI_STATUS Status; 226 ACPI_OBJECT_LIST ArgList; 227 ACPI_OBJECT Arg; 228 229 230 ACPI_FUNCTION_TRACE ("AcpiEnterSleepStatePrep"); 231 232 233 /* 234 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. 235 */ 236 Status = AcpiGetSleepTypeData (SleepState, 237 &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 238 if (ACPI_FAILURE (Status)) 239 { 240 return_ACPI_STATUS (Status); 241 } 242 243 /* Setup parameter object */ 244 245 ArgList.Count = 1; 246 ArgList.Pointer = &Arg; 247 248 Arg.Type = ACPI_TYPE_INTEGER; 249 Arg.Integer.Value = SleepState; 250 251 /* Run the _PTS and _GTS methods */ 252 253 Status = AcpiEvaluateObject (NULL, "\\_PTS", &ArgList, NULL); 254 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 255 { 256 return_ACPI_STATUS (Status); 257 } 258 259 Status = AcpiEvaluateObject (NULL, "\\_GTS", &ArgList, NULL); 260 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 261 { 262 return_ACPI_STATUS (Status); 263 } 264 265 return_ACPI_STATUS (AE_OK); 266} 267 268 269/****************************************************************************** 270 * 271 * FUNCTION: AcpiEnterSleepState 272 * 273 * PARAMETERS: SleepState - Which sleep state to enter 274 * 275 * RETURN: Status 276 * 277 * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) 278 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 279 * 280 ******************************************************************************/ 281 282ACPI_STATUS 283AcpiEnterSleepState ( 284 UINT8 SleepState) 285{ 286 UINT32 PM1AControl; 287 UINT32 PM1BControl; 288 ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; 289 ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; 290 UINT32 InValue; 291 ACPI_STATUS Status; 292 293 294 ACPI_FUNCTION_TRACE ("AcpiEnterSleepState"); 295 296 297 if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) || 298 (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX)) 299 { 300 ACPI_REPORT_ERROR (("Sleep values out of range: A=%X B=%X\n", 301 AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB)); 302 return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 303 } 304 305 306 SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A); 307 SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE); 308 309 /* Clear wake status */ 310 311 Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_LOCK); 312 if (ACPI_FAILURE (Status)) 313 { 314 return_ACPI_STATUS (Status); 315 } 316 317 Status = AcpiHwClearAcpiStatus(); 318 if (ACPI_FAILURE (Status)) 319 { 320 return_ACPI_STATUS (Status); 321 } 322 323 /* Disable BM arbitration */ 324 325 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_LOCK); 326 if (ACPI_FAILURE (Status)) 327 { 328 return_ACPI_STATUS (Status); 329 } 330 331 Status = AcpiHwDisableNonWakeupGpes(); 332 if (ACPI_FAILURE (Status)) 333 { 334 return_ACPI_STATUS (Status); 335 } 336 337 /* Get current value of PM1A control */ 338 339 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1AControl); 340 if (ACPI_FAILURE (Status)) 341 { 342 return_ACPI_STATUS (Status); 343 } 344 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", SleepState)); 345 346 /* Clear SLP_EN and SLP_TYP fields */ 347 348 PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask | SleepEnableRegInfo->AccessBitMask); 349 PM1BControl = PM1AControl; 350 351 /* Insert SLP_TYP bits */ 352 353 PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition); 354 PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition); 355 356 /* Write #1: fill in SLP_TYP data */ 357 358 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 359 if (ACPI_FAILURE (Status)) 360 { 361 return_ACPI_STATUS (Status); 362 } 363 364 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 365 if (ACPI_FAILURE (Status)) 366 { 367 return_ACPI_STATUS (Status); 368 } 369 370 /* Insert SLP_ENABLE bit */ 371 372 PM1AControl |= SleepEnableRegInfo->AccessBitMask; 373 PM1BControl |= SleepEnableRegInfo->AccessBitMask; 374 375 /* Write #2: SLP_TYP + SLP_EN */ 376 377 ACPI_FLUSH_CPU_CACHE (); 378 379 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 380 if (ACPI_FAILURE (Status)) 381 { 382 return_ACPI_STATUS (Status); 383 } 384 385 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 386 if (ACPI_FAILURE (Status)) 387 { 388 return_ACPI_STATUS (Status); 389 } 390 391 /* 392 * Wait a second, then try again. This is to get S4/5 to work on all machines. 393 */ 394 if (SleepState > ACPI_STATE_S3) 395 { 396 /* 397 * We wait so long to allow chipsets that poll this reg very slowly to 398 * still read the right value. Ideally, this entire block would go 399 * away entirely. 400 */ 401 AcpiOsStall (10000000); 402 403 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, 404 SleepEnableRegInfo->AccessBitMask); 405 if (ACPI_FAILURE (Status)) 406 { 407 return_ACPI_STATUS (Status); 408 } 409 } 410 411 /* Wait until we enter sleep state */ 412 413 do 414 { 415 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue, ACPI_MTX_DO_NOT_LOCK); 416 if (ACPI_FAILURE (Status)) 417 { 418 return_ACPI_STATUS (Status); 419 } 420 421 /* Spin until we wake */ 422 423 } while (!InValue); 424 425 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK); 426 if (ACPI_FAILURE (Status)) 427 { 428 return_ACPI_STATUS (Status); 429 } 430 431 return_ACPI_STATUS (AE_OK); 432} 433 434 435/****************************************************************************** 436 * 437 * FUNCTION: AcpiEnterSleepStateS4bios 438 * 439 * PARAMETERS: None 440 * 441 * RETURN: Status 442 * 443 * DESCRIPTION: Perform a S4 bios request. 444 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 445 * 446 ******************************************************************************/ 447 448ACPI_STATUS 449AcpiEnterSleepStateS4bios ( 450 void) 451{ 452 UINT32 InValue; 453 ACPI_STATUS Status; 454 455 456 ACPI_FUNCTION_TRACE ("AcpiEnterSleepStateS4bios"); 457 458 AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); 459 AcpiHwClearAcpiStatus(); 460 461 AcpiHwDisableNonWakeupGpes(); 462 463 ACPI_FLUSH_CPU_CACHE(); 464 465 Status = AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, (ACPI_INTEGER) AcpiGbl_FADT->S4BiosReq, 8); 466 467 do { 468 AcpiOsStall(1000); 469 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue, ACPI_MTX_DO_NOT_LOCK); 470 if (ACPI_FAILURE (Status)) 471 { 472 return_ACPI_STATUS (Status); 473 } 474 } while (!InValue); 475 476 return_ACPI_STATUS (AE_OK); 477} 478 479 480/****************************************************************************** 481 * 482 * FUNCTION: AcpiLeaveSleepState 483 * 484 * PARAMETERS: SleepState - Which sleep state we just exited 485 * 486 * RETURN: Status 487 * 488 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 489 * 490 ******************************************************************************/ 491 492ACPI_STATUS 493AcpiLeaveSleepState ( 494 UINT8 SleepState) 495{ 496 ACPI_OBJECT_LIST ArgList; 497 ACPI_OBJECT Arg; 498 ACPI_STATUS Status; 499 500 501 ACPI_FUNCTION_TRACE ("AcpiLeaveSleepState"); 502 503 504 /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ 505 506 AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID; 507 508 /* Setup parameter object */ 509 510 ArgList.Count = 1; 511 ArgList.Pointer = &Arg; 512 513 Arg.Type = ACPI_TYPE_INTEGER; 514 Arg.Integer.Value = SleepState; 515 516 /* Ignore any errors from these methods */ 517 518 Status = AcpiEvaluateObject (NULL, "\\_BFS", &ArgList, NULL); 519 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 520 { 521 ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", AcpiFormatException (Status))); 522 } 523 524 Status = AcpiEvaluateObject (NULL, "\\_WAK", &ArgList, NULL); 525 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 526 { 527 ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", AcpiFormatException (Status))); 528 } 529 530 /* _WAK returns stuff - do we want to look at it? */ 531 532 Status = AcpiHwEnableNonWakeupGpes(); 533 if (ACPI_FAILURE (Status)) 534 { 535 return_ACPI_STATUS (Status); 536 } 537 538 /* Disable BM arbitration */ 539 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); 540 541 return_ACPI_STATUS (Status); 542} 543