2 This is the driver that produce AcpiVariable hob and slit SmramReserve hob
5 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions
9 of the BSD License which accompanies this distribution. The
10 full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Guid/SmramMemoryReserve.h>
20 #include <Guid/AcpiVariable.h>
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/HobLib.h>
25 #include <Library/PeiServicesLib.h>
26 #include <Library/BaseMemoryLib.h>
29 Retrieves the data structure associated witht he GUIDed HOB of type gEfiSmmPeiSmramMemoryReserveGuid
31 @retval NULL A HOB of type gEfiSmmPeiSmramMemoryReserveGuid could not be found.
32 @retval !NULL A pointer to the GUID data from a HIB of type gEfiSmmPeiSmramMemoryReserveGuid
35 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*
43 // Search SmramMemoryReserve HOB that describes SMRAM region
45 GuidHob
= GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid
);
46 if (GuidHob
== NULL
) {
49 return (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*)GET_GUID_HOB_DATA (GuidHob
);
53 This routine will split SmramReserve hob to reserve 1 page for SMRAM content in S3 phase
56 @retval EFI_SUCCESS The gEfiSmmPeiSmramMemoryReserveGuid is splited successfully.
57 @retval EFI_NOT_FOUND The gEfiSmmPeiSmramMemoryReserveGuid is not found.
62 SplitSmramReserveHob (
66 EFI_HOB_GUID_TYPE
*GuidHob
;
67 EFI_PEI_HOB_POINTERS Hob
;
68 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*DescriptorBlock
;
69 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*NewDescriptorBlock
;
76 // Retrieve the GUID HOB data that contains the set of SMRAM descriptyors
78 GuidHob
= GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid
);
79 if (GuidHob
== NULL
) {
83 DescriptorBlock
= (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*)GET_GUID_HOB_DATA (GuidHob
);
86 // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of SMRAM memory that contains a pointer
87 // to the SMM Services Table that is required on the S3 resume path
89 SmramRanges
= DescriptorBlock
->NumberOfSmmReservedRegions
;
90 BufferSize
= sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
) + (SmramRanges
* sizeof (EFI_SMRAM_DESCRIPTOR
));
92 Hob
.Raw
= BuildGuidHob (
93 &gEfiSmmPeiSmramMemoryReserveGuid
,
97 NewDescriptorBlock
= (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*)Hob
.Raw
;
100 // Copy old EFI_SMRAM_HOB_DESCRIPTOR_BLOCK to new allocated region
102 CopyMem ((VOID
*)Hob
.Raw
, DescriptorBlock
, BufferSize
- sizeof(EFI_SMRAM_DESCRIPTOR
));
105 // Increase the number of SMRAM descriptors by 1 to make room for the ALLOCATED descriptor of size EFI_PAGE_SIZE
107 NewDescriptorBlock
->NumberOfSmmReservedRegions
= (UINT32
)(SmramRanges
+ 1);
109 ASSERT (SmramRanges
>= 1);
111 // Copy last entry to the end - we assume TSEG is last entry, which is same assumption as R8 CPU/SMM driver
113 CopyMem (&NewDescriptorBlock
->Descriptor
[SmramRanges
], &NewDescriptorBlock
->Descriptor
[SmramRanges
- 1], sizeof(EFI_SMRAM_DESCRIPTOR
));
116 // Update the last but 1 entry in the array with a size of EFI_PAGE_SIZE and put into the ALLOCATED state
118 NewDescriptorBlock
->Descriptor
[SmramRanges
- 1].PhysicalSize
= EFI_PAGE_SIZE
;
119 NewDescriptorBlock
->Descriptor
[SmramRanges
- 1].RegionState
|= EFI_ALLOCATED
;
122 // Reduce the size of the last SMRAM descriptor by EFI_PAGE_SIZE
124 NewDescriptorBlock
->Descriptor
[SmramRanges
].PhysicalStart
+= EFI_PAGE_SIZE
;
125 NewDescriptorBlock
->Descriptor
[SmramRanges
].CpuStart
+= EFI_PAGE_SIZE
;
126 NewDescriptorBlock
->Descriptor
[SmramRanges
].PhysicalSize
-= EFI_PAGE_SIZE
;
129 // Now, we have created SmramReserve Hob for SmmAccess drive. But the issue is that, R8 SmmAccess will assume there is 2 SmramReserve region only.
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.
131 // So we uses scan SmmReserve Hob to remove AB-SEG or H-SEG.
133 for (Index
= 0; Index
<= SmramRanges
; Index
++) {
134 if (NewDescriptorBlock
->Descriptor
[Index
].PhysicalSize
== 0) {
140 if (NewDescriptorBlock
->Descriptor
[Index
].PhysicalStart
< BASE_1MB
) {
142 // Find AB-SEG or H-SEG
143 // remove this region
145 for (SubIndex
= Index
; SubIndex
< NewDescriptorBlock
->NumberOfSmmReservedRegions
- 1; SubIndex
++) {
146 CopyMem (&NewDescriptorBlock
->Descriptor
[SubIndex
], &NewDescriptorBlock
->Descriptor
[SubIndex
+ 1], sizeof (EFI_SMRAM_DESCRIPTOR
));
151 ZeroMem (&NewDescriptorBlock
->Descriptor
[SubIndex
], sizeof(EFI_SMRAM_DESCRIPTOR
));
155 NewDescriptorBlock
->NumberOfSmmReservedRegions
--;
157 // Decrease Index to let it test mew entry
164 // Last step, we can scrub old one
166 ZeroMem (&GuidHob
->Name
, sizeof(GuidHob
->Name
));
172 This routine will create AcpiVariable hob to point the reserved smram in S3 phase
175 @retval EFI_SUCCESS The gEfiAcpiVariableGuid is created successfully.
176 @retval EFI_NOT_FOUND The gEfiSmmPeiSmramMemoryReserveGuid is not found.
181 CreateAcpiVariableHob (
185 EFI_PEI_HOB_POINTERS Hob
;
186 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*DescriptorBlock
;
190 // Retrieve the GUID HOB data that contains the set of SMRAM descriptyors
192 DescriptorBlock
= GetSrmamHobData ();
193 if (DescriptorBlock
== NULL
) {
194 return EFI_NOT_FOUND
;
197 Hob
.Raw
= BuildGuidHob (
198 &gEfiAcpiVariableGuid
,
199 sizeof (EFI_SMRAM_DESCRIPTOR
)
204 // It should be already patch, so just copy last but 1 region directly.
206 SmramRanges
= DescriptorBlock
->NumberOfSmmReservedRegions
;
207 ASSERT (SmramRanges
>= 2);
208 if (SmramRanges
>= 2) {
209 CopyMem ((VOID
*)Hob
.Raw
, &DescriptorBlock
->Descriptor
[SmramRanges
- 2], sizeof (EFI_SMRAM_DESCRIPTOR
));
216 Driver Entry for AcpiVariableHobOnSmramReservHob PEIM
218 @param FileHandle Handle of the file being invoked.
219 @param PeiServices Describes the list of possible PEI Services.
221 @retval EFI_SUCCESS Success create gEfiAcpiVariableGuid and
222 split gEfiSmmPeiSmramMemoryReserveGuid.
223 @retval EFI_NOT_FOUND Can not get gEfiSmmPeiSmramMemoryReserveGuid hob
228 AcpiVariableHobEntry (
229 IN EFI_PEI_FILE_HANDLE FileHandle
,
230 IN CONST EFI_PEI_SERVICES
**PeiServices
236 // Split SmramReserve hob, which is required for R9 SMM Core for S3.
238 Status
= SplitSmramReserveHob ();
239 if (EFI_ERROR (Status
)) {
244 // Create AcpiVariable hob, which is required for R9 SMM Core for S3.
246 Status
= CreateAcpiVariableHob ();