+++ /dev/null
-/** @file\r
-File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.\r
-\r
-Copyright (c) 2013-2015 Intel Corporation.\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-\r
-**/\r
-\r
-//\r
-// Include common header file for this module.\r
-//\r
-#include "CommonHeader.h"\r
-\r
-#include "QNCSmmHelpers.h"\r
-\r
-CONST QNC_SMM_SOURCE_DESC SX_SOURCE_DESC = {\r
- QNC_SMM_NO_FLAGS,\r
- {\r
- {\r
- {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIE}}, S_QNC_GPE0BLK_SMIE, N_QNC_GPE0BLK_SMIE_SLP\r
- },\r
- NULL_BIT_DESC_INITIALIZER\r
- },\r
- {\r
- {\r
- {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIS}}, S_QNC_GPE0BLK_SMIS, N_QNC_GPE0BLK_SMIS_SLP\r
- }\r
- }\r
-};\r
-\r
-VOID\r
-SxGetContext(\r
- IN DATABASE_RECORD *Record,\r
- OUT QNC_SMM_CONTEXT *Context\r
- )\r
-{\r
- UINT32 Pm1Cnt;\r
-\r
- Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);\r
-\r
- //\r
- // By design, the context phase will always be ENTRY\r
- //\r
- Context->Sx.Phase = SxEntry;\r
-\r
- //\r
- // Map the PM1_CNT register's SLP_TYP bits to the context type\r
- //\r
- switch (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) {\r
-\r
- case V_S0:\r
- Context->Sx.Type = SxS0;\r
- break;\r
-\r
- case V_S3:\r
- Context->Sx.Type = SxS3;\r
- break;\r
-\r
- case V_S4:\r
- Context->Sx.Type = SxS4;\r
- break;\r
-\r
- case V_S5:\r
- Context->Sx.Type = SxS5;\r
- break;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- };\r
-}\r
-\r
-BOOLEAN\r
-SxCmpContext (\r
- IN QNC_SMM_CONTEXT *Context1,\r
- IN QNC_SMM_CONTEXT *Context2\r
- )\r
-{\r
- return (BOOLEAN)(Context1->Sx.Type == Context2->Sx.Type);\r
-}\r
-\r
-VOID\r
-QNCSmmSxGoToSleep(\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- When we get an SMI that indicates that we are transitioning to a sleep state,\r
- we need to actually transition to that state. We do this by disabling the\r
- "SMI on sleep enable" feature, which generates an SMI when the operating system\r
- tries to put the system to sleep, and then physically putting the system to sleep.\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
-{\r
- UINT32 Pm1Cnt;\r
-\r
- //\r
- // Flush cache into memory before we go to sleep. It is necessary for S3 sleep\r
- // because we may update memory in SMM Sx sleep handlers -- the updates are in cache now\r
- //\r
- AsmWbinvd();\r
-\r
- //\r
- // Disable SMIs\r
- //\r
- QNCSmmClearSource (&SX_SOURCE_DESC );\r
- QNCSmmDisableSource (&SX_SOURCE_DESC);\r
-\r
- //\r
- // Clear Sleep Type Enable\r
- //\r
- IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIE, (UINT16)(~B_QNC_GPE0BLK_SMIE_SLP));\r
-\r
- // clear sleep SMI status\r
- IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS, (UINT16)(S_QNC_GPE0BLK_SMIS));\r
-\r
- //\r
- // Now that SMIs are disabled, write to the SLP_EN bit again to trigger the sleep\r
- //\r
- Pm1Cnt = IoOr32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, B_QNC_PM1BLK_PM1C_SLPEN);\r
-\r
- //\r
- // The system just went to sleep. If the sleep state was S1, then code execution will resume\r
- // here when the system wakes up.\r
- //\r
- Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);\r
- if ((Pm1Cnt & B_QNC_PM1BLK_PM1C_SCIEN) == 0) {\r
- //\r
- // An ACPI OS isn't present, clear the sleep information\r
- //\r
- Pm1Cnt &= ~B_QNC_PM1BLK_PM1C_SLPTP;\r
- Pm1Cnt |= V_S0;\r
-\r
- IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Pm1Cnt);\r
- }\r
-\r
- QNCSmmClearSource (&SX_SOURCE_DESC);\r
- QNCSmmEnableSource (&SX_SOURCE_DESC);\r
-}\r