Skip to content

Commit a142637

Browse files
committed
Platform/Intel: Create MmPlatformHobProducerLib instance
Create MmPlatformHobProducerLib instance for QSP boot Signed-off-by: Dun Tan <[email protected]>
1 parent 3f08401 commit a142637

File tree

2 files changed

+361
-0
lines changed

2 files changed

+361
-0
lines changed
Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
/** @file
2+
Platform specific HOB producer Library implementation for Standalone MM Core.
3+
4+
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
5+
SPDX-License-Identifier: BSD-2-Clause-Patent
6+
7+
**/
8+
9+
#include <Uefi.h>
10+
#include <PiPei.h>
11+
12+
#include <Library/DebugLib.h>
13+
#include <Library/BaseMemoryLib.h>
14+
#include <Library/BaseLib.h>
15+
#include <Library/MemoryAllocationLib.h>
16+
#include <Library/HobLib.h>
17+
#include <Library/MmPlatformHobProducerLib.h>
18+
19+
#include <Guid/SmramMemoryReserve.h>
20+
21+
typedef struct {
22+
EFI_PHYSICAL_ADDRESS Base;
23+
UINT64 Length;
24+
} MM_PLATFORM_MEMORY_REGION;
25+
26+
/**
27+
Initialize the EFI_HOB_GENERIC_HEADER based on input Hob.
28+
29+
@param[in] Hob Pointer to the new HOB buffer.
30+
@param[in] HobType Type of the new HOB.
31+
@param[in] HobLength Length of the new HOB to allocate.
32+
33+
**/
34+
VOID
35+
MmCreateHob (
36+
IN VOID *Hob,
37+
IN UINT16 HobType,
38+
IN UINT16 HobLength
39+
)
40+
{
41+
//
42+
// Check Length to avoid data overflow.
43+
//
44+
ASSERT (HobLength < MAX_UINT16 - 0x7);
45+
46+
((EFI_HOB_GENERIC_HEADER *)Hob)->HobType = HobType;
47+
((EFI_HOB_GENERIC_HEADER *)Hob)->HobLength = HobLength;
48+
((EFI_HOB_GENERIC_HEADER *)Hob)->Reserved = 0;
49+
}
50+
51+
/**
52+
Builds a EFI_HOB_TYPE_RESOURCE_DESCRIPTOR HOB.
53+
54+
@param[in] Hob Pointer to the new HOB buffer.
55+
@param[in] ResourceType The type of resource described by this HOB.
56+
@param[in] ResourceAttribute The resource attributes of the memory described by this HOB.
57+
@param[in] PhysicalStart The 64 bit physical address of memory described by this HOB.
58+
@param[in] NumberOfBytes The length of the memory described by this HOB in bytes.
59+
60+
**/
61+
VOID
62+
MmBuildResourceDescriptorHob (
63+
IN EFI_HOB_RESOURCE_DESCRIPTOR *Hob,
64+
IN EFI_RESOURCE_TYPE ResourceType,
65+
IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
66+
IN EFI_PHYSICAL_ADDRESS PhysicalStart,
67+
IN UINT64 NumberOfBytes
68+
)
69+
{
70+
ASSERT (Hob != NULL);
71+
MmCreateHob (Hob, EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
72+
73+
Hob->ResourceType = ResourceType;
74+
Hob->ResourceAttribute = ResourceAttribute;
75+
Hob->PhysicalStart = PhysicalStart;
76+
Hob->ResourceLength = NumberOfBytes;
77+
}
78+
79+
/**
80+
Calculate the maximum support address.
81+
82+
@return the maximum support address.
83+
**/
84+
static
85+
UINT8
86+
MmCalculateMaximumSupportAddress (
87+
VOID
88+
)
89+
{
90+
UINT32 RegEax;
91+
UINT8 PhysicalAddressBits;
92+
VOID *Hob;
93+
94+
//
95+
// Get physical address bits supported.
96+
//
97+
Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
98+
if (Hob != NULL) {
99+
PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
100+
} else {
101+
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
102+
if (RegEax >= 0x80000008) {
103+
AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
104+
PhysicalAddressBits = (UINT8)RegEax;
105+
} else {
106+
PhysicalAddressBits = 36;
107+
}
108+
}
109+
110+
return PhysicalAddressBits;
111+
}
112+
113+
/**
114+
Builds resource HOB list for all MMIO range.
115+
116+
This function treats all all ranges outside the system memory range and smram range
117+
as mmio and builds resource HOB list for all MMIO range.
118+
119+
@param[in] Create FALSE to indicate Buffer is not used and the return buffer size
120+
is increased by the required buffer size.
121+
@param[in] MemoryRegion MM_PLATFORM_MEMORY_REGION that describes all system memory range.
122+
@param[in] Count Number of MM_PLATFORM_MEMORY_REGION.
123+
@param[in] Buffer The pointer of new HOB buffer.
124+
125+
@return The expected/used buffer size.
126+
**/
127+
UINTN
128+
MmBuildHobForMmio (
129+
IN BOOLEAN Create,
130+
IN MM_PLATFORM_MEMORY_REGION *MemoryRegion,
131+
IN UINTN Count,
132+
IN UINT8 *Buffer
133+
)
134+
{
135+
UINT64 PreviousAddress;
136+
UINT64 Base;
137+
UINT64 Limit;
138+
UINT8 PhysicalAddressBits;
139+
UINTN Index;
140+
UINTN BufferSize;
141+
142+
Index = 0;
143+
PreviousAddress = 0;
144+
PhysicalAddressBits = MmCalculateMaximumSupportAddress ();
145+
Limit = LShiftU64 (1, PhysicalAddressBits);
146+
BufferSize = 0;
147+
148+
for (Index = 0; Index <= Count; Index++) {
149+
//
150+
// When Index is equal to Count, Base covers the very last region.
151+
//
152+
Base = (Index == Count) ? Limit : MemoryRegion[Index].Base;
153+
if (Base > PreviousAddress) {
154+
if (Create) {
155+
MmBuildResourceDescriptorHob (
156+
(EFI_HOB_RESOURCE_DESCRIPTOR *)(Buffer + BufferSize),
157+
EFI_RESOURCE_MEMORY_MAPPED_IO,
158+
0,
159+
PreviousAddress,
160+
Base - PreviousAddress
161+
);
162+
}
163+
164+
BufferSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR);
165+
}
166+
167+
if (Index < Count) {
168+
PreviousAddress = MemoryRegion[Index].Base + MemoryRegion[Index].Length;
169+
}
170+
}
171+
172+
return BufferSize;
173+
}
174+
175+
/**
176+
Function to compare 2 MM_PLATFORM_MEMORY_REGION pointer based on Base.
177+
178+
@param[in] Buffer1 pointer to MP_INFORMATION2_HOB_DATA poiner to compare
179+
@param[in] Buffer2 pointer to second MP_INFORMATION2_HOB_DATA pointer to compare
180+
181+
@retval 0 Buffer1 equal to Buffer2
182+
@retval <0 Buffer1 is less than Buffer2
183+
@retval >0 Buffer1 is greater than Buffer2
184+
**/
185+
static
186+
INTN
187+
EFIAPI
188+
MmMemoryDescriptorCompare (
189+
IN CONST VOID *Buffer1,
190+
IN CONST VOID *Buffer2
191+
)
192+
{
193+
if (((MM_PLATFORM_MEMORY_REGION *)Buffer1)->Base > ((MM_PLATFORM_MEMORY_REGION *)Buffer2)->Base) {
194+
return 1;
195+
} else if (((MM_PLATFORM_MEMORY_REGION *)Buffer1)->Base < ((MM_PLATFORM_MEMORY_REGION *)Buffer2)->Base) {
196+
return -1;
197+
}
198+
199+
return 0;
200+
}
201+
202+
/**
203+
Create the platform specific HOB list which StandaloneMm Core needed.
204+
205+
This function build the platform specific HOB list needed by StandaloneMm Core
206+
based on the PEI HOB list.
207+
208+
@param[in] Buffer The free buffer to be used for HOB creation.
209+
@param[in, out] BufferSize The buffer size.
210+
On return, the expected/used size.
211+
212+
@retval RETURN_INVALID_PARAMETER BufferSize is NULL.
213+
@retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation.
214+
BufferSize is updated to indicate the expected buffer size.
215+
When the input BufferSize is bigger than the expected buffer size,
216+
the BufferSize value will be changed the used buffer size.
217+
@retval RETURN_SUCCESS The HOB list is created successfully.
218+
219+
**/
220+
EFI_STATUS
221+
EFIAPI
222+
CreateMmPlatformHob (
223+
IN VOID *Buffer,
224+
IN OUT UINTN *BufferSize
225+
)
226+
{
227+
VOID *HobList;
228+
EFI_PEI_HOB_POINTERS Hob;
229+
EFI_PEI_HOB_POINTERS FirstResHob;
230+
UINTN Count;
231+
UINTN Index;
232+
MM_PLATFORM_MEMORY_REGION *MemoryRegion;
233+
MM_PLATFORM_MEMORY_REGION SortBuffer;
234+
UINTN RequiredSize;
235+
EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHob;
236+
237+
if (BufferSize == NULL) {
238+
return RETURN_INVALID_PARAMETER;
239+
}
240+
241+
if ((*BufferSize != 0) && (Buffer == NULL)) {
242+
return RETURN_INVALID_PARAMETER;
243+
}
244+
245+
Count = 0;
246+
RequiredSize = 0;
247+
HobList = GetHobList ();
248+
ASSERT (HobList != NULL);
249+
250+
//
251+
// Count the Resource HOB number
252+
//
253+
Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
254+
FirstResHob = Hob;
255+
while (Hob.Raw != NULL) {
256+
if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
257+
Count++;
258+
}
259+
260+
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, GET_NEXT_HOB (Hob));
261+
}
262+
263+
//
264+
// Count the gEfiSmmSmramMemoryGuid Descriptor number
265+
//
266+
Hob.Raw = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);
267+
ASSERT (Hob.Raw != NULL);
268+
SmramHob = GET_GUID_HOB_DATA (Hob.Raw);
269+
Count += SmramHob->NumberOfSmmReservedRegions;
270+
271+
MemoryRegion = AllocatePool (Count * sizeof (MM_PLATFORM_MEMORY_REGION));
272+
ASSERT (MemoryRegion != NULL);
273+
274+
//
275+
// Cache gEfiSmmSmramMemoryGuid Descriptor
276+
//
277+
Index = 0;
278+
while (Index < SmramHob->NumberOfSmmReservedRegions) {
279+
MemoryRegion[Index].Base = SmramHob->Descriptor[Index].PhysicalStart;
280+
MemoryRegion[Index].Length = SmramHob->Descriptor[Index].PhysicalSize;
281+
Index++;
282+
}
283+
284+
//
285+
// Cache resource HOB
286+
//
287+
Hob = FirstResHob;
288+
while (Hob.Raw != NULL) {
289+
if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
290+
MemoryRegion[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
291+
MemoryRegion[Index].Length = Hob.ResourceDescriptor->ResourceLength;
292+
Index++;
293+
}
294+
295+
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, GET_NEXT_HOB (Hob));
296+
}
297+
298+
ASSERT (Index == Count);
299+
300+
//
301+
// Perform QuickSort for all MM_PLATFORM_MEMORY_REGION range for calculating the MMIO
302+
//
303+
QuickSort (MemoryRegion, Count, sizeof (MM_PLATFORM_MEMORY_REGION), (BASE_SORT_COMPARE)MmMemoryDescriptorCompare, &SortBuffer);
304+
305+
//
306+
// Calculate needed buffer size.
307+
//
308+
RequiredSize = MmBuildHobForMmio (FALSE, MemoryRegion, Count, NULL);
309+
310+
if (*BufferSize < RequiredSize) {
311+
*BufferSize = RequiredSize;
312+
FreePool (MemoryRegion);
313+
return EFI_BUFFER_TOO_SMALL;
314+
}
315+
316+
//
317+
// Build resource HOB for MMIO range.
318+
//
319+
*BufferSize = MmBuildHobForMmio (TRUE, MemoryRegion, Count, Buffer);
320+
FreePool (MemoryRegion);
321+
322+
return EFI_SUCCESS;
323+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## @file
2+
# Instance of platform specific HOB Producer Library for Standalone MM Core.
3+
#
4+
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
5+
#
6+
# SPDX-License-Identifier: BSD-2-Clause-Patent
7+
#
8+
#
9+
##
10+
11+
[Defines]
12+
INF_VERSION = 0x00010017
13+
BASE_NAME = MmPlatformHobProducerLib
14+
FILE_GUID = 98700A68-CB99-4B2A-97DC-F0A0C8755EE7
15+
MODULE_TYPE = PEIM
16+
VERSION_STRING = 1.0
17+
LIBRARY_CLASS = MmPlatformHobProducerLib
18+
19+
#
20+
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
21+
#
22+
23+
[Sources]
24+
MmPlatformHobProducerLib.c
25+
26+
[Packages]
27+
MdePkg/MdePkg.dec
28+
UefiCpuPkg/UefiCpuPkg.dec
29+
SimicsOpenBoardPkg/OpenBoardPkg.dec
30+
31+
[LibraryClasses]
32+
BaseMemoryLib
33+
DebugLib
34+
MemoryAllocationLib
35+
HobLib
36+
37+
[Guids]
38+
gEfiSmmSmramMemoryGuid

0 commit comments

Comments
 (0)