blob: afe20f85847014438b02e64730fa14e969a350d9 [file] [log] [blame]
Levi Yun21058312024-09-23 08:18:14 +01001/** @file
2 HOB Library implementation for Standalone MM Core.
3
4Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
6
7SPDX-License-Identifier: BSD-2-Clause-Patent
8
9**/
10
11#include <Guid/MemoryAllocationHob.h>
12
13#include <Library/BaseMemoryLib.h>
14#include <Library/DebugLib.h>
15#include <Library/HobLib.h>
16
17#include <PiMm.h>
18
19//
20// Cache copy of HobList pointer.
21//
22VOID *gHobList = NULL;
23
24VOID *
25CreateHob (
26 IN UINT16 HobType,
27 IN UINT16 HobLength
28 )
29{
30 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
31 EFI_HOB_GENERIC_HEADER *HobEnd;
32 EFI_PHYSICAL_ADDRESS FreeMemory;
33 VOID *Hob;
34
35 HandOffHob = GetHobList ();
36
37 //
38 // Check Length to avoid data overflow.
39 //
40 if (HobLength > MAX_UINT16 - 0x7) {
41 return NULL;
42 }
43
44 HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
45
46 FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
47
48 if (FreeMemory < HobLength) {
49 return NULL;
50 }
51
52 Hob = (VOID *)(UINTN)HandOffHob->EfiEndOfHobList;
53 ((EFI_HOB_GENERIC_HEADER *)Hob)->HobType = HobType;
54 ((EFI_HOB_GENERIC_HEADER *)Hob)->HobLength = HobLength;
55 ((EFI_HOB_GENERIC_HEADER *)Hob)->Reserved = 0;
56
57 HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)Hob + HobLength);
58 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
59
60 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
61 HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);
62 HobEnd->Reserved = 0;
63 HobEnd++;
64 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
65
66 return Hob;
67}
68
69/**
70 Builds a HOB for a loaded PE32 module.
71
72 This function builds a HOB for a loaded PE32 module.
73 If ModuleName is NULL, then ASSERT().
74 If there is no additional space for HOB creation, then ASSERT().
75
76 @param ModuleName The GUID File Name of the module.
77 @param MemoryAllocationModule The 64 bit physical address of the module.
78 @param ModuleLength The length of the module in bytes.
79 @param EntryPoint The 64 bit physical address of the module entry point.
80
81**/
82VOID
83EFIAPI
84BuildModuleHob (
85 IN CONST EFI_GUID *ModuleName,
86 IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
87 IN UINT64 ModuleLength,
88 IN EFI_PHYSICAL_ADDRESS EntryPoint
89 )
90{
91 EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;
92
93 ASSERT (
94 ((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
95 ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0)
96 );
97
98 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
99 ASSERT (Hob != NULL);
100 if (Hob == NULL) {
101 return;
102 }
103
104 CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
105 Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
106 Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;
107 Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;
108
109 //
110 // Zero the reserved space to match HOB spec
111 //
112 ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
113
114 CopyGuid (&Hob->ModuleName, ModuleName);
115 Hob->EntryPoint = EntryPoint;
116}
117
118/**
119 Builds a HOB that describes a chunk of system memory.
120
121 This function builds a HOB that describes a chunk of system memory.
122 If there is no additional space for HOB creation, then ASSERT().
123
124 @param ResourceType The type of resource described by this HOB.
125 @param ResourceAttribute The resource attributes of the memory described by this HOB.
126 @param PhysicalStart The 64 bit physical address of memory described by this HOB.
127 @param NumberOfBytes The length of the memory described by this HOB in bytes.
128
129**/
130VOID
131EFIAPI
132BuildResourceDescriptorHob (
133 IN EFI_RESOURCE_TYPE ResourceType,
134 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
135 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
136 IN UINT64 NumberOfBytes
137 )
138{
139 EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
140
141 Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
142 ASSERT (Hob != NULL);
143 if (Hob == NULL) {
144 return;
145 }
146
147 Hob->ResourceType = ResourceType;
148 Hob->ResourceAttribute = ResourceAttribute;
149 Hob->PhysicalStart = PhysicalStart;
150 Hob->ResourceLength = NumberOfBytes;
151}
152
153/**
154 Builds a GUID HOB with a certain data length.
155
156 This function builds a customized HOB tagged with a GUID for identification
157 and returns the start address of GUID HOB data so that caller can fill the customized data.
158 The HOB Header and Name field is already stripped.
159 If Guid is NULL, then ASSERT().
160 If there is no additional space for HOB creation, then ASSERT().
161 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
162
163 @param Guid The GUID to tag the customized HOB.
164 @param DataLength The size of the data payload for the GUID HOB.
165
166 @return The start address of GUID HOB data.
167
168**/
169VOID *
170EFIAPI
171BuildGuidHob (
172 IN CONST EFI_GUID *Guid,
173 IN UINTN DataLength
174 )
175{
176 EFI_HOB_GUID_TYPE *Hob;
177
178 //
179 // Make sure that data length is not too long.
180 //
181 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
182
183 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength));
184 ASSERT (Hob != NULL);
185 if (Hob == NULL) {
186 return NULL;
187 }
188
189 CopyGuid (&Hob->Name, Guid);
190 return Hob + 1;
191}
192
193/**
194 Copies a data buffer to a newly-built HOB.
195
196 This function builds a customized HOB tagged with a GUID for identification,
197 copies the input data to the HOB data field and returns the start address of the GUID HOB data.
198 The HOB Header and Name field is already stripped.
199 If Guid is NULL, then ASSERT().
200 If Data is NULL and DataLength > 0, then ASSERT().
201 If there is no additional space for HOB creation, then ASSERT().
202 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
203
204 @param Guid The GUID to tag the customized HOB.
205 @param Data The data to be copied into the data field of the GUID HOB.
206 @param DataLength The size of the data payload for the GUID HOB.
207
208 @return The start address of GUID HOB data.
209
210**/
211VOID *
212EFIAPI
213BuildGuidDataHob (
214 IN CONST EFI_GUID *Guid,
215 IN VOID *Data,
216 IN UINTN DataLength
217 )
218{
219 VOID *HobData;
220
221 ASSERT (Data != NULL || DataLength == 0);
222
223 HobData = BuildGuidHob (Guid, DataLength);
224
225 return CopyMem (HobData, Data, DataLength);
226}
227
228/**
229 Builds a Firmware Volume HOB.
230
231 This function builds a Firmware Volume HOB.
232 If there is no additional space for HOB creation, then ASSERT().
233
234 @param BaseAddress The base address of the Firmware Volume.
235 @param Length The size of the Firmware Volume in bytes.
236
237**/
238VOID
239EFIAPI
240BuildFvHob (
241 IN EFI_PHYSICAL_ADDRESS BaseAddress,
242 IN UINT64 Length
243 )
244{
245 EFI_HOB_FIRMWARE_VOLUME *Hob;
246
247 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
248 ASSERT (Hob != NULL);
249 if (Hob == NULL) {
250 return;
251 }
252
253 Hob->BaseAddress = BaseAddress;
254 Hob->Length = Length;
255}
256
257/**
258 Builds a EFI_HOB_TYPE_FV2 HOB.
259
260 This function builds a EFI_HOB_TYPE_FV2 HOB.
261 If there is no additional space for HOB creation, then ASSERT().
262
263 @param BaseAddress The base address of the Firmware Volume.
264 @param Length The size of the Firmware Volume in bytes.
265 @param FvName The name of the Firmware Volume.
266 @param FileName The name of the file.
267
268**/
269VOID
270EFIAPI
271BuildFv2Hob (
272 IN EFI_PHYSICAL_ADDRESS BaseAddress,
273 IN UINT64 Length,
274 IN CONST EFI_GUID *FvName,
275 IN CONST EFI_GUID *FileName
276 )
277{
278 EFI_HOB_FIRMWARE_VOLUME2 *Hob;
279
280 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
281 ASSERT (Hob != NULL);
282 if (Hob == NULL) {
283 return;
284 }
285
286 Hob->BaseAddress = BaseAddress;
287 Hob->Length = Length;
288 CopyGuid (&Hob->FvName, FvName);
289 CopyGuid (&Hob->FileName, FileName);
290}
291
292/**
293 Builds a HOB for the CPU.
294
295 This function builds a HOB for the CPU.
296 If there is no additional space for HOB creation, then ASSERT().
297
298 @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
299 @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
300
301**/
302VOID
303EFIAPI
304BuildCpuHob (
305 IN UINT8 SizeOfMemorySpace,
306 IN UINT8 SizeOfIoSpace
307 )
308{
309 EFI_HOB_CPU *Hob;
310
311 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
312 ASSERT (Hob != NULL);
313 if (Hob == NULL) {
314 return;
315 }
316
317 Hob->SizeOfMemorySpace = SizeOfMemorySpace;
318 Hob->SizeOfIoSpace = SizeOfIoSpace;
319
320 //
321 // Zero the reserved space to match HOB spec
322 //
323 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
324}
325
326/**
327 Builds a HOB for the memory allocation.
328
329 This function builds a HOB for the memory allocation.
330 If there is no additional space for HOB creation, then ASSERT().
331
332 @param BaseAddress The 64 bit physical address of the memory.
333 @param Length The length of the memory allocation in bytes.
334 @param MemoryType Type of memory allocated by this HOB.
335
336**/
337VOID
338EFIAPI
339BuildMemoryAllocationHob (
340 IN EFI_PHYSICAL_ADDRESS BaseAddress,
341 IN UINT64 Length,
342 IN EFI_MEMORY_TYPE MemoryType
343 )
344{
345 EFI_HOB_MEMORY_ALLOCATION *Hob;
346
347 ASSERT (
348 ((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
349 ((Length & (EFI_PAGE_SIZE - 1)) == 0)
350 );
351
352 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
353 ASSERT (Hob != NULL);
354 if (Hob == NULL) {
355 return;
356 }
357
358 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
359 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
360 Hob->AllocDescriptor.MemoryLength = Length;
361 Hob->AllocDescriptor.MemoryType = MemoryType;
362 //
363 // Zero the reserved space to match HOB spec
364 //
365 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
366}
367