VirtualBox

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

Last change on this file since 94368 was 80721, checked in by vboxsync, 5 years ago

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

  • Property svn:eol-style set to native
File size: 4.3 KB
Line 
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 FfsBuffer = 0xFFFFFFFF;
99 Status = gBS->AllocatePages (
100 AllocateMaxAddress,
101 EfiBootServicesCode,
102 Pages,
103 &FfsBuffer
104 );
105 ASSERT_EFI_ERROR (Status);
106 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
107 //
108 // Align buffer on section boundary
109 //
110 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
111 ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
112 //
113 // Load the image to our new buffer
114 //
115 Status = PeCoffLoaderLoadImage (&ImageContext);
116 ASSERT_EFI_ERROR (Status);
117
118 //
119 // Relocate the image in our new buffer
120 //
121 Status = PeCoffLoaderRelocateImage (&ImageContext);
122 ASSERT_EFI_ERROR (Status);
123
124 //
125 // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
126 //
127 gBS->FreePool (Buffer);
128
129 //
130 // Flush the instruction cache so the image data is written before we execute it
131 //
132 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
133
134 DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));
135 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST);
136 if (EFI_ERROR (Status)) {
137 DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));
138 gBS->FreePages (FfsBuffer, Pages);
139 }
140
141 //
142 // return error to unload >4G copy, if we already relocate itself to <4G.
143 //
144 return EFI_ALREADY_STARTED;
145}
Note: See TracBrowser for help on using the repository browser.

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