VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c

最後變更 在這個檔案是 99404,由 vboxsync 提交於 2 年 前

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 4.3 KB
 
1/** @file
2
3Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8
9#include <Uefi.h>
10#include <Library/BaseLib.h>
11#include <Library/UefiDriverEntryPoint.h>
12#include <Library/BaseMemoryLib.h>
13#include <Library/DebugLib.h>
14#include <Library/PeCoffLib.h>
15#include <Library/UefiBootServicesTableLib.h>
16#include <Library/DxeServicesLib.h>
17#include <Library/CacheMaintenanceLib.h>
18#include <Library/UefiLib.h>
19
20/**
21 Relocate this image under 4G memory.
22
23 @param ImageHandle Handle of driver image.
24 @param SystemTable Pointer to system table.
25
26 @retval EFI_SUCCESS Image successfully relocated.
27 @retval EFI_ABORTED Failed to relocate image.
28
29**/
30EFI_STATUS
31RelocateImageUnder4GIfNeeded (
32 IN EFI_HANDLE ImageHandle,
33 IN EFI_SYSTEM_TABLE *SystemTable
34 )
35{
36 EFI_STATUS Status;
37 UINT8 *Buffer;
38 UINTN BufferSize;
39 EFI_HANDLE NewImageHandle;
40 UINTN Pages;
41 EFI_PHYSICAL_ADDRESS FfsBuffer;
42 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
43 VOID *Interface;
44
45 //
46 // If it is already <4G, no need do relocate
47 //
48 if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {
49 return EFI_SUCCESS;
50 }
51
52 //
53 // If locate gEfiCallerIdGuid success, it means 2nd entry.
54 //
55 Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);
56 if (!EFI_ERROR (Status)) {
57 DEBUG ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n"));
58 return EFI_SUCCESS;
59 }
60
61 DEBUG ((DEBUG_INFO, "FspNotifyDxe - 1st entry\n"));
62
63 //
64 // Here we install a dummy handle
65 //
66 NewImageHandle = NULL;
67 Status = gBS->InstallProtocolInterface (
68 &NewImageHandle,
69 &gEfiCallerIdGuid,
70 EFI_NATIVE_INTERFACE,
71 NULL
72 );
73 ASSERT_EFI_ERROR (Status);
74
75 //
76 // Reload image itself to <4G mem
77 //
78 Status = GetSectionFromAnyFv (
79 &gEfiCallerIdGuid,
80 EFI_SECTION_PE32,
81 0,
82 (VOID **)&Buffer,
83 &BufferSize
84 );
85 ASSERT_EFI_ERROR (Status);
86 ImageContext.Handle = Buffer;
87 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
88 //
89 // Get information about the image being loaded
90 //
91 Status = PeCoffLoaderGetImageInfo (&ImageContext);
92 ASSERT_EFI_ERROR (Status);
93 if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
94 Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment));
95 } else {
96 Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);
97 }
98
99 FfsBuffer = 0xFFFFFFFF;
100 Status = gBS->AllocatePages (
101 AllocateMaxAddress,
102 EfiBootServicesCode,
103 Pages,
104 &FfsBuffer
105 );
106 ASSERT_EFI_ERROR (Status);
107 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
108 //
109 // Align buffer on section boundary
110 //
111 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
112 ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
113 //
114 // Load the image to our new buffer
115 //
116 Status = PeCoffLoaderLoadImage (&ImageContext);
117 ASSERT_EFI_ERROR (Status);
118
119 //
120 // Relocate the image in our new buffer
121 //
122 Status = PeCoffLoaderRelocateImage (&ImageContext);
123 ASSERT_EFI_ERROR (Status);
124
125 //
126 // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
127 //
128 gBS->FreePool (Buffer);
129
130 //
131 // Flush the instruction cache so the image data is written before we execute it
132 //
133 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
134
135 DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));
136 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImageHandle, gST);
137 if (EFI_ERROR (Status)) {
138 DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));
139 gBS->FreePages (FfsBuffer, Pages);
140 }
141
142 //
143 // return error to unload >4G copy, if we already relocate itself to <4G.
144 //
145 return EFI_ALREADY_STARTED;
146}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette