VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/IntelFspWrapperPkg/FspNotifyDxe/LoadBelow4G.c@ 58464

Last change on this file since 58464 was 58464, checked in by vboxsync, 9 years ago

EFI/Firmware: Export new files and directories.

  • Property svn:eol-style set to native
File size: 4.7 KB
Line 
1/** @file
2
3Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
4
5This program and the accompanying materials
6are licensed and made available under the terms and conditions
7of the BSD License which accompanies this distribution. The
8full text of the license may be found at
9http://opensource.org/licenses/bsd-license.php
10
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16#include <Uefi.h>
17#include <Library/BaseLib.h>
18#include <Library/UefiDriverEntryPoint.h>
19#include <Library/BaseMemoryLib.h>
20#include <Library/DebugLib.h>
21#include <Library/PeCoffLib.h>
22#include <Library/UefiBootServicesTableLib.h>
23#include <Library/DxeServicesLib.h>
24#include <Library/CacheMaintenanceLib.h>
25#include <Library/UefiLib.h>
26
27/**
28 Relocate this image under 4G memory.
29
30 @param ImageHandle Handle of driver image.
31 @param SystemTable Pointer to system table.
32
33 @retval EFI_SUCCESS Image successfully relocated.
34 @retval EFI_ABORTED Failed to relocate image.
35
36**/
37EFI_STATUS
38RelocateImageUnder4GIfNeeded (
39 IN EFI_HANDLE ImageHandle,
40 IN EFI_SYSTEM_TABLE *SystemTable
41 )
42{
43 EFI_STATUS Status;
44 UINT8 *Buffer;
45 UINTN BufferSize;
46 EFI_HANDLE NewImageHandle;
47 UINTN Pages;
48 EFI_PHYSICAL_ADDRESS FfsBuffer;
49 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
50 VOID *Interface;
51
52 //
53 // If it is already <4G, no need do relocate
54 //
55 if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {
56 return EFI_SUCCESS;
57 }
58
59 //
60 // If locate gEfiCallerIdGuid success, it means 2nd entry.
61 //
62 Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);
63 if (!EFI_ERROR (Status)) {
64 DEBUG ((EFI_D_INFO, "FspNotifyDxe - 2nd entry\n"));
65 return EFI_SUCCESS;
66 }
67
68 DEBUG ((EFI_D_INFO, "FspNotifyDxe - 1st entry\n"));
69
70 //
71 // Here we install a dummy handle
72 //
73 NewImageHandle = NULL;
74 Status = gBS->InstallProtocolInterface (
75 &NewImageHandle,
76 &gEfiCallerIdGuid,
77 EFI_NATIVE_INTERFACE,
78 NULL
79 );
80 ASSERT_EFI_ERROR (Status);
81
82 //
83 // Reload image itself to <4G mem
84 //
85 Status = GetSectionFromAnyFv (
86 &gEfiCallerIdGuid,
87 EFI_SECTION_PE32,
88 0,
89 (VOID **) &Buffer,
90 &BufferSize
91 );
92 ASSERT_EFI_ERROR (Status);
93 ImageContext.Handle = Buffer;
94 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
95 //
96 // Get information about the image being loaded
97 //
98 Status = PeCoffLoaderGetImageInfo (&ImageContext);
99 ASSERT_EFI_ERROR (Status);
100 if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
101 Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment));
102 } else {
103 Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize);
104 }
105 FfsBuffer = 0xFFFFFFFF;
106 Status = gBS->AllocatePages (
107 AllocateMaxAddress,
108 EfiBootServicesCode,
109 Pages,
110 &FfsBuffer
111 );
112 ASSERT_EFI_ERROR (Status);
113 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
114 //
115 // Align buffer on section boundry
116 //
117 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
118 ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1));
119 //
120 // Load the image to our new buffer
121 //
122 Status = PeCoffLoaderLoadImage (&ImageContext);
123 ASSERT_EFI_ERROR (Status);
124
125 //
126 // Relocate the image in our new buffer
127 //
128 Status = PeCoffLoaderRelocateImage (&ImageContext);
129 ASSERT_EFI_ERROR (Status);
130
131 //
132 // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
133 //
134 gBS->FreePool (Buffer);
135
136 //
137 // Flush the instruction cache so the image data is written before we execute it
138 //
139 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
140
141 DEBUG ((EFI_D_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));
142 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST);
143 if (EFI_ERROR (Status)) {
144 DEBUG ((EFI_D_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));
145 gBS->FreePages (FfsBuffer, Pages);
146 }
147
148 //
149 // return error to unload >4G copy, if we already relocate itself to <4G.
150 //
151 return EFI_ALREADY_STARTED;
152}
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