]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.c
Avoid using code name in comments.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / AcpiVariableHobOnSmramReserveHobThunk / AcpiVariableHobOnSmramReserveHobThunk.c
CommitLineData
a7a0f78b 1/** @file\r
2 This is the driver that produce AcpiVariable hob and slit SmramReserve hob\r
3 for ECP platform.\r
4\r
5Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
6\r
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions\r
9of the BSD License which accompanies this distribution. The\r
10full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include <PiPei.h>\r
19#include <Guid/SmramMemoryReserve.h>\r
1261fe23 20#include <Guid/AcpiS3Context.h>\r
a7a0f78b 21\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/HobLib.h>\r
25#include <Library/PeiServicesLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27\r
28/**\r
29 Retrieves the data structure associated witht he GUIDed HOB of type gEfiSmmPeiSmramMemoryReserveGuid\r
30 \r
31 @retval NULL A HOB of type gEfiSmmPeiSmramMemoryReserveGuid could not be found.\r
32 @retval !NULL A pointer to the GUID data from a HIB of type gEfiSmmPeiSmramMemoryReserveGuid\r
33\r
34**/\r
35EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *\r
36GetSrmamHobData (\r
37 VOID\r
38 )\r
39{\r
40 VOID *GuidHob;\r
41\r
42 //\r
43 // Search SmramMemoryReserve HOB that describes SMRAM region\r
44 //\r
45 GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);\r
46 if (GuidHob == NULL) {\r
47 return NULL;\r
48 }\r
49 return (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)GET_GUID_HOB_DATA (GuidHob);\r
50}\r
51\r
52/**\r
53 This routine will split SmramReserve hob to reserve 1 page for SMRAM content in S3 phase\r
8598a1ed 54 for PI SMM core.\r
a7a0f78b 55 \r
56 @retval EFI_SUCCESS The gEfiSmmPeiSmramMemoryReserveGuid is splited successfully.\r
57 @retval EFI_NOT_FOUND The gEfiSmmPeiSmramMemoryReserveGuid is not found.\r
58\r
59**/\r
60EFI_STATUS\r
61EFIAPI\r
62SplitSmramReserveHob (\r
63 VOID\r
64 )\r
65{\r
66 EFI_HOB_GUID_TYPE *GuidHob;\r
67 EFI_PEI_HOB_POINTERS Hob;\r
68 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock;\r
69 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *NewDescriptorBlock;\r
70 UINTN BufferSize;\r
71 UINTN SmramRanges;\r
72 UINTN Index;\r
73 UINTN SubIndex;\r
74\r
75 //\r
76 // Retrieve the GUID HOB data that contains the set of SMRAM descriptyors\r
77 //\r
78 GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);\r
79 if (GuidHob == NULL) {\r
80 return EFI_NOT_FOUND;\r
81 }\r
82\r
83 DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)GET_GUID_HOB_DATA (GuidHob);\r
84\r
85 //\r
86 // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of SMRAM memory that contains a pointer\r
87 // to the SMM Services Table that is required on the S3 resume path\r
88 //\r
89 SmramRanges = DescriptorBlock->NumberOfSmmReservedRegions;\r
90 BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + (SmramRanges * sizeof (EFI_SMRAM_DESCRIPTOR));\r
91\r
92 Hob.Raw = BuildGuidHob (\r
93 &gEfiSmmPeiSmramMemoryReserveGuid,\r
94 BufferSize\r
95 );\r
96 ASSERT (Hob.Raw);\r
97 NewDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)Hob.Raw;\r
98\r
99 //\r
100 // Copy old EFI_SMRAM_HOB_DESCRIPTOR_BLOCK to new allocated region\r
101 //\r
102 CopyMem ((VOID *)Hob.Raw, DescriptorBlock, BufferSize - sizeof(EFI_SMRAM_DESCRIPTOR));\r
103\r
104 //\r
105 // Increase the number of SMRAM descriptors by 1 to make room for the ALLOCATED descriptor of size EFI_PAGE_SIZE\r
106 //\r
107 NewDescriptorBlock->NumberOfSmmReservedRegions = (UINT32)(SmramRanges + 1);\r
108\r
109 ASSERT (SmramRanges >= 1);\r
110 //\r
8598a1ed 111 // Copy last entry to the end - we assume TSEG is last entry, which is same assumption as Framework CPU/SMM driver\r
a7a0f78b 112 //\r
113 CopyMem (&NewDescriptorBlock->Descriptor[SmramRanges], &NewDescriptorBlock->Descriptor[SmramRanges - 1], sizeof(EFI_SMRAM_DESCRIPTOR));\r
114\r
115 //\r
116 // Update the last but 1 entry in the array with a size of EFI_PAGE_SIZE and put into the ALLOCATED state\r
117 //\r
118 NewDescriptorBlock->Descriptor[SmramRanges - 1].PhysicalSize = EFI_PAGE_SIZE;\r
119 NewDescriptorBlock->Descriptor[SmramRanges - 1].RegionState |= EFI_ALLOCATED;\r
120\r
121 //\r
122 // Reduce the size of the last SMRAM descriptor by EFI_PAGE_SIZE \r
123 //\r
124 NewDescriptorBlock->Descriptor[SmramRanges].PhysicalStart += EFI_PAGE_SIZE;\r
125 NewDescriptorBlock->Descriptor[SmramRanges].CpuStart += EFI_PAGE_SIZE;\r
126 NewDescriptorBlock->Descriptor[SmramRanges].PhysicalSize -= EFI_PAGE_SIZE;\r
127\r
128 //\r
8598a1ed 129 // Now, we have created SmramReserve Hob for SmmAccess drive. But the issue is that, Framework SmmAccess will assume there is 2 SmramReserve region only.\r
a7a0f78b 130 // Reporting 3 SmramReserve region will cause buffer overflow. Moreover, we would like to filter AB-SEG or H-SEG to avoid SMM cache-poisoning issue.\r
131 // So we uses scan SmmReserve Hob to remove AB-SEG or H-SEG.\r
132 //\r
133 for (Index = 0; Index <= SmramRanges; Index++) {\r
134 if (NewDescriptorBlock->Descriptor[Index].PhysicalSize == 0) {\r
135 //\r
136 // Skip zero entry\r
137 //\r
138 continue;\r
139 }\r
140 if (NewDescriptorBlock->Descriptor[Index].PhysicalStart < BASE_1MB) {\r
141 //\r
142 // Find AB-SEG or H-SEG\r
143 // remove this region\r
144 //\r
145 for (SubIndex = Index; SubIndex < NewDescriptorBlock->NumberOfSmmReservedRegions - 1; SubIndex++) {\r
146 CopyMem (&NewDescriptorBlock->Descriptor[SubIndex], &NewDescriptorBlock->Descriptor[SubIndex + 1], sizeof (EFI_SMRAM_DESCRIPTOR));\r
147 }\r
148 //\r
149 // Zero last one\r
150 //\r
151 ZeroMem (&NewDescriptorBlock->Descriptor[SubIndex], sizeof(EFI_SMRAM_DESCRIPTOR));\r
152 //\r
153 // Decrease Number\r
154 //\r
155 NewDescriptorBlock->NumberOfSmmReservedRegions --;\r
156 //\r
157 // Decrease Index to let it test mew entry\r
158 //\r
159 Index --;\r
160 }\r
161 }\r
162\r
163 //\r
164 // Last step, we can scrub old one\r
165 //\r
166 ZeroMem (&GuidHob->Name, sizeof(GuidHob->Name));\r
167\r
168 return EFI_SUCCESS;\r
169}\r
170\r
171/**\r
172 This routine will create AcpiVariable hob to point the reserved smram in S3 phase\r
8598a1ed 173 for PI SMM core.\r
a7a0f78b 174 \r
175 @retval EFI_SUCCESS The gEfiAcpiVariableGuid is created successfully.\r
176 @retval EFI_NOT_FOUND The gEfiSmmPeiSmramMemoryReserveGuid is not found.\r
177\r
178**/\r
179EFI_STATUS\r
180EFIAPI\r
181CreateAcpiVariableHob (\r
182 VOID\r
183 )\r
184{\r
185 EFI_PEI_HOB_POINTERS Hob;\r
186 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock;\r
187 UINTN SmramRanges;\r
188\r
189 //\r
190 // Retrieve the GUID HOB data that contains the set of SMRAM descriptyors\r
191 //\r
192 DescriptorBlock = GetSrmamHobData ();\r
193 if (DescriptorBlock == NULL) {\r
194 return EFI_NOT_FOUND;\r
195 }\r
196\r
197 Hob.Raw = BuildGuidHob (\r
198 &gEfiAcpiVariableGuid,\r
199 sizeof (EFI_SMRAM_DESCRIPTOR)\r
200 );\r
201 ASSERT (Hob.Raw);\r
202\r
203 //\r
204 // It should be already patch, so just copy last but 1 region directly.\r
205 //\r
206 SmramRanges = DescriptorBlock->NumberOfSmmReservedRegions;\r
207 ASSERT (SmramRanges >= 2);\r
208 if (SmramRanges >= 2) {\r
209 CopyMem ((VOID *)Hob.Raw, &DescriptorBlock->Descriptor[SmramRanges - 2], sizeof (EFI_SMRAM_DESCRIPTOR));\r
210 }\r
211\r
212 return EFI_SUCCESS;\r
213}\r
214\r
215/**\r
216 Driver Entry for AcpiVariableHobOnSmramReservHob PEIM\r
217 \r
218 @param FileHandle Handle of the file being invoked.\r
219 @param PeiServices Describes the list of possible PEI Services.\r
220 \r
221 @retval EFI_SUCCESS Success create gEfiAcpiVariableGuid and\r
222 split gEfiSmmPeiSmramMemoryReserveGuid.\r
223 @retval EFI_NOT_FOUND Can not get gEfiSmmPeiSmramMemoryReserveGuid hob\r
224\r
225**/\r
226EFI_STATUS\r
227EFIAPI\r
228AcpiVariableHobEntry (\r
229 IN EFI_PEI_FILE_HANDLE FileHandle,\r
230 IN CONST EFI_PEI_SERVICES **PeiServices\r
231 )\r
232{\r
233 EFI_STATUS Status;\r
234\r
235 //\r
8598a1ed 236 // Split SmramReserve hob, which is required for PI SMM Core for S3.\r
a7a0f78b 237 //\r
238 Status = SplitSmramReserveHob ();\r
239 if (EFI_ERROR (Status)) {\r
240 return Status;\r
241 }\r
242\r
243 //\r
8598a1ed 244 // Create AcpiVariable hob, which is required for PI SMM Core for S3.\r
a7a0f78b 245 //\r
246 Status = CreateAcpiVariableHob ();\r
247\r
248 return Status;\r
249}\r