Changeset 58459 in vbox for trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/PeiMemoryAllocationLib
- Timestamp:
- Oct 28, 2015 8:17:18 PM (9 years ago)
- Location:
- trunk/src/VBox/Devices/EFI/Firmware
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/Firmware
-
Property svn:mergeinfo
set to (toggle deleted branches)
/vendor/edk2/current 103735-103757
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
r48674 r58459 3 3 based on PeiService for PEI phase drivers. 4 4 5 Copyright (c) 2006 - 201 0, Intel Corporation. All rights reserved.<BR>5 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 6 6 This program and the accompanying materials 7 7 are licensed and made available under the terms and conditions of the BSD License … … 22 22 #include <Library/BaseMemoryLib.h> 23 23 #include <Library/DebugLib.h> 24 #include <Library/HobLib.h> 24 25 25 26 … … 45 46 EFI_STATUS Status; 46 47 EFI_PHYSICAL_ADDRESS Memory; 48 EFI_MEMORY_TYPE RequestType; 49 EFI_PEI_HOB_POINTERS Hob; 47 50 48 51 if (Pages == 0) { … … 50 53 } 51 54 52 Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory); 55 RequestType = MemoryType; 56 if (MemoryType == EfiReservedMemoryType) { 57 // 58 // PEI AllocatePages() doesn't support EfiReservedMemoryType. 59 // Change RequestType to EfiBootServicesData for memory allocation. 60 // 61 RequestType = EfiBootServicesData; 62 } 63 64 Status = PeiServicesAllocatePages (RequestType, Pages, &Memory); 53 65 if (EFI_ERROR (Status)) { 54 66 return NULL; 55 67 } 68 69 if (MemoryType == EfiReservedMemoryType) { 70 // 71 // Memory type needs to be updated to EfiReservedMemoryType. Per PI spec Volume 1, 72 // PEI AllocatePages() will automate the creation of the Memory Allocation HOB types. 73 // Search Memory Allocation HOB and find the matched memory region, 74 // then change its memory type to EfiReservedMemoryType. 75 // 76 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); 77 while (Hob.Raw != NULL && Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress != Memory) { 78 Hob.Raw = GET_NEXT_HOB (Hob); 79 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw); 80 } 81 ASSERT (Hob.Raw != NULL); 82 Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiReservedMemoryType; 83 } 84 56 85 return (VOID *) (UINTN) Memory; 57 86 } … … 161 190 NULL is returned. 162 191 If Alignment is not a power of two and Alignment is not zero, then ASSERT(). 192 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). 163 193 164 194 @param MemoryType The type of memory to allocate. … … 178 208 ) 179 209 { 180 VOID *Memory; 181 UINTN AlignmentMask; 210 EFI_PHYSICAL_ADDRESS Memory; 211 EFI_PHYSICAL_ADDRESS AlignedMemory; 212 EFI_PEI_HOB_POINTERS Hob; 213 BOOLEAN SkipBeforeMemHob; 214 BOOLEAN SkipAfterMemHob; 215 EFI_PHYSICAL_ADDRESS HobBaseAddress; 216 UINT64 HobLength; 217 EFI_MEMORY_TYPE HobMemoryType; 218 UINTN TotalPages; 182 219 183 220 // … … 192 229 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. 193 230 // 194 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); 231 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); 232 195 233 // 196 234 // We would rather waste some memory to save PEI code size. 197 // 198 Memory = InternalAllocatePages (MemoryType, Pages + EFI_SIZE_TO_PAGES (Alignment)); 199 if (Alignment == 0) { 200 AlignmentMask = Alignment; 235 // meaning in addition to the requested size for the aligned mem, 236 // we simply reserve an overhead memory equal to Alignmemt(page-aligned), no matter what. 237 // The overhead mem size could be reduced later with more involved malloc mechanisms 238 // (e.g., somthing that can detect the alignment boundary before allocating memory or 239 // can request that memory be allocated at a certain address that is aleady aligned). 240 // 241 TotalPages = Pages + (Alignment <= EFI_PAGE_SIZE ? 0 : EFI_SIZE_TO_PAGES(Alignment)); 242 Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) InternalAllocatePages (MemoryType, TotalPages); 243 if (Memory == 0) { 244 DEBUG((DEBUG_INFO, "Out of memory resource! \n")); 245 return NULL; 246 } 247 DEBUG ((DEBUG_INFO, "Allocated Memory unaligned: Address = 0x%LX, Pages = 0x%X, Type = %d \n", Memory, TotalPages, (UINTN) MemoryType)); 248 249 // 250 // Alignment calculation 251 // 252 AlignedMemory = Memory; 253 if (Alignment > EFI_PAGE_SIZE) { 254 AlignedMemory = ALIGN_VALUE (Memory, Alignment); 255 } 256 DEBUG ((DEBUG_INFO, "After aligning to 0x%X bytes: Address = 0x%LX, Pages = 0x%X \n", Alignment, AlignedMemory, Pages)); 257 258 // 259 // In general three HOBs cover the total allocated space. 260 // The aligned portion is covered by the aligned mem HOB and 261 // the unaligned(to be freed) portions before and after the aligned portion are covered by newly created HOBs. 262 // 263 // Before mem HOB covers the region between "Memory" and "AlignedMemory" 264 // Aligned mem HOB covers the region between "AlignedMemory" and "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)" 265 // After mem HOB covers the region between "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)" and "Memory + EFI_PAGES_TO_SIZE(TotalPages)" 266 // 267 // The before or after mem HOBs need to be skipped under special cases where the aligned portion 268 // touches either the top or bottom of the original allocated space. 269 // 270 SkipBeforeMemHob = FALSE; 271 SkipAfterMemHob = FALSE; 272 if (Memory == AlignedMemory) { 273 SkipBeforeMemHob = TRUE; 274 } 275 if ((Memory + EFI_PAGES_TO_SIZE(TotalPages)) == (AlignedMemory + EFI_PAGES_TO_SIZE(Pages))) { 276 // 277 // This condition is never met in the current implementation. 278 // There is always some after-mem since the overhead mem(used in TotalPages) 279 // is no less than Alignment. 280 // 281 SkipAfterMemHob = TRUE; 282 } 283 284 // 285 // Search for the mem HOB referring to the original(unaligned) allocation 286 // and update the size and type if needed. 287 // 288 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); 289 while (Hob.Raw != NULL) { 290 if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == Memory) { 291 break; 292 } 293 Hob.Raw = GET_NEXT_HOB (Hob); 294 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw); 295 } 296 ASSERT (Hob.Raw != NULL); 297 if (SkipBeforeMemHob) { 298 // 299 // Use this HOB as aligned mem HOB as there is no portion before it. 300 // 301 HobLength = EFI_PAGES_TO_SIZE(Pages); 302 Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength; 201 303 } else { 202 AlignmentMask = Alignment - 1; 203 } 204 return (VOID *) (UINTN) (((UINTN) Memory + AlignmentMask) & ~AlignmentMask); 304 // 305 // Use this HOB as before mem HOB and create a new HOB for the aligned portion 306 // 307 HobLength = (AlignedMemory - Memory); 308 Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength; 309 Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiConventionalMemory; 310 } 311 312 HobBaseAddress = Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; 313 HobMemoryType = Hob.MemoryAllocation->AllocDescriptor.MemoryType; 314 315 // 316 // Build the aligned mem HOB if needed 317 // 318 if (!SkipBeforeMemHob) { 319 DEBUG((DEBUG_INFO, "Updated before-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", 320 HobBaseAddress, HobLength, (UINTN) HobMemoryType)); 321 322 HobBaseAddress = AlignedMemory; 323 HobLength = EFI_PAGES_TO_SIZE(Pages); 324 HobMemoryType = MemoryType; 325 326 BuildMemoryAllocationHob ( 327 HobBaseAddress, 328 HobLength, 329 HobMemoryType 330 ); 331 332 DEBUG((DEBUG_INFO, "Created aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", 333 HobBaseAddress, HobLength, (UINTN) HobMemoryType)); 334 } else { 335 if (HobBaseAddress != 0) { 336 DEBUG((DEBUG_INFO, "Updated aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", 337 HobBaseAddress, HobLength, (UINTN) HobMemoryType)); 338 } 339 } 340 341 342 // 343 // Build the after mem HOB if needed 344 // 345 if (!SkipAfterMemHob) { 346 HobBaseAddress = AlignedMemory + EFI_PAGES_TO_SIZE(Pages); 347 HobLength = (Memory + EFI_PAGES_TO_SIZE(TotalPages)) - (AlignedMemory + EFI_PAGES_TO_SIZE(Pages)); 348 HobMemoryType = EfiConventionalMemory; 349 350 BuildMemoryAllocationHob ( 351 HobBaseAddress, 352 HobLength, 353 HobMemoryType 354 ); 355 356 DEBUG((DEBUG_INFO, "Created after-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n", 357 HobBaseAddress, HobLength, (UINTN) HobMemoryType)); 358 } 359 360 return (VOID *) (UINTN) AlignedMemory; 205 361 } 206 362 … … 214 370 215 371 If Alignment is not a power of two and Alignment is not zero, then ASSERT(). 372 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). 216 373 217 374 @param Pages The number of 4 KB pages to allocate. … … 242 399 243 400 If Alignment is not a power of two and Alignment is not zero, then ASSERT(). 401 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). 244 402 245 403 @param Pages The number of 4 KB pages to allocate. … … 270 428 271 429 If Alignment is not a power of two and Alignment is not zero, then ASSERT(). 430 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). 272 431 273 432 @param Pages The number of 4 KB pages to allocate. -
trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
r48674 r58459 5 5 # Free operations are ignored. 6 6 # 7 # Copyright (c) 2007 - 201 0, Intel Corporation. All rights reserved.<BR>7 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 8 8 # 9 9 # This program and the accompanying materials … … 20 20 INF_VERSION = 0x00010005 21 21 BASE_NAME = PeiMemoryAllocationLib 22 MODULE_UNI_FILE = PeiMemoryAllocationLib.uni 22 23 FILE_GUID = b694e0dc-cd4e-4b30-885b-9c164ed3e74a 23 24 MODULE_TYPE = PEIM … … 41 42 BaseMemoryLib 42 43 PeiServicesLib 44 HobLib 43 45
Note:
See TracChangeset
for help on using the changeset viewer.