]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2WrapperPkg / FspWrapperNotifyDxe / LoadBelow4G.c
1 /** @file
2
3 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4
5 SPDX-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 **/
30 EFI_STATUS
31 RelocateImageUnder4GIfNeeded (
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 }