]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkNorthCluster / Smm / DxeSmm / QncSmmDispatcher / QNC / QNCSmmSx.c
CommitLineData
9b6bbcdb
MK
1/** @file\r
2File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.\r
3\r
4Copyright (c) 2013-2015 Intel Corporation.\r
5\r
c9f231d0 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
9b6bbcdb
MK
7\r
8\r
9**/\r
10\r
11//\r
12// Include common header file for this module.\r
13//\r
14#include "CommonHeader.h"\r
15\r
16#include "QNCSmmHelpers.h"\r
17\r
18CONST QNC_SMM_SOURCE_DESC SX_SOURCE_DESC = {\r
19 QNC_SMM_NO_FLAGS,\r
20 {\r
21 {\r
22 {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIE}}, S_QNC_GPE0BLK_SMIE, N_QNC_GPE0BLK_SMIE_SLP\r
23 },\r
24 NULL_BIT_DESC_INITIALIZER\r
25 },\r
26 {\r
27 {\r
28 {GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIS}}, S_QNC_GPE0BLK_SMIS, N_QNC_GPE0BLK_SMIS_SLP\r
29 }\r
30 }\r
31};\r
32\r
33VOID\r
34SxGetContext(\r
35 IN DATABASE_RECORD *Record,\r
36 OUT QNC_SMM_CONTEXT *Context\r
37 )\r
38{\r
39 UINT32 Pm1Cnt;\r
40\r
41 Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);\r
42\r
43 //\r
44 // By design, the context phase will always be ENTRY\r
45 //\r
46 Context->Sx.Phase = SxEntry;\r
47\r
48 //\r
49 // Map the PM1_CNT register's SLP_TYP bits to the context type\r
50 //\r
51 switch (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) {\r
52\r
53 case V_S0:\r
54 Context->Sx.Type = SxS0;\r
55 break;\r
56\r
57 case V_S3:\r
58 Context->Sx.Type = SxS3;\r
59 break;\r
60\r
61 case V_S4:\r
62 Context->Sx.Type = SxS4;\r
63 break;\r
64\r
65 case V_S5:\r
66 Context->Sx.Type = SxS5;\r
67 break;\r
68\r
69 default:\r
70 ASSERT (FALSE);\r
71 break;\r
72 };\r
73}\r
74\r
75BOOLEAN\r
76SxCmpContext (\r
77 IN QNC_SMM_CONTEXT *Context1,\r
78 IN QNC_SMM_CONTEXT *Context2\r
79 )\r
80{\r
81 return (BOOLEAN)(Context1->Sx.Type == Context2->Sx.Type);\r
82}\r
83\r
84VOID\r
85QNCSmmSxGoToSleep(\r
86 VOID\r
87 )\r
88/*++\r
89\r
90Routine Description:\r
91\r
92 When we get an SMI that indicates that we are transitioning to a sleep state,\r
93 we need to actually transition to that state. We do this by disabling the\r
94 "SMI on sleep enable" feature, which generates an SMI when the operating system\r
95 tries to put the system to sleep, and then physically putting the system to sleep.\r
96\r
97Returns:\r
98\r
99 None.\r
100\r
101--*/\r
102{\r
103 UINT32 Pm1Cnt;\r
104\r
105 //\r
106 // Flush cache into memory before we go to sleep. It is necessary for S3 sleep\r
107 // because we may update memory in SMM Sx sleep handlers -- the updates are in cache now\r
108 //\r
109 AsmWbinvd();\r
110\r
111 //\r
112 // Disable SMIs\r
113 //\r
114 QNCSmmClearSource (&SX_SOURCE_DESC );\r
115 QNCSmmDisableSource (&SX_SOURCE_DESC);\r
116\r
117 //\r
118 // Clear Sleep Type Enable\r
119 //\r
120 IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIE, (UINT16)(~B_QNC_GPE0BLK_SMIE_SLP));\r
121\r
122 // clear sleep SMI status\r
123 IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS, (UINT16)(S_QNC_GPE0BLK_SMIS));\r
124\r
125 //\r
126 // Now that SMIs are disabled, write to the SLP_EN bit again to trigger the sleep\r
127 //\r
128 Pm1Cnt = IoOr32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, B_QNC_PM1BLK_PM1C_SLPEN);\r
129\r
130 //\r
131 // The system just went to sleep. If the sleep state was S1, then code execution will resume\r
132 // here when the system wakes up.\r
133 //\r
134 Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);\r
135 if ((Pm1Cnt & B_QNC_PM1BLK_PM1C_SCIEN) == 0) {\r
136 //\r
137 // An ACPI OS isn't present, clear the sleep information\r
138 //\r
139 Pm1Cnt &= ~B_QNC_PM1BLK_PM1C_SLPTP;\r
140 Pm1Cnt |= V_S0;\r
141\r
142 IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Pm1Cnt);\r
143 }\r
144\r
145 QNCSmmClearSource (&SX_SOURCE_DESC);\r
146 QNCSmmEnableSource (&SX_SOURCE_DESC);\r
147}\r