]> git.proxmox.com Git - mirror_edk2.git/blame - UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c
UefiPayloadPkg: Add performance measurement feature
[mirror_edk2.git] / UefiPayloadPkg / PayloadLoaderPeim / PayloadLoaderPeim.c
CommitLineData
fe471d4a
RN
1/** @file\r
2 ELF Load Image Support\r
3\r
4Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include <PiPei.h>\r
10#include <UniversalPayload/UniversalPayload.h>\r
11#include <UniversalPayload/ExtraData.h>\r
12\r
13#include <Ppi/LoadFile.h>\r
14\r
15#include <Library/DebugLib.h>\r
16#include <Library/HobLib.h>\r
17#include <Library/PeiServicesLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20\r
21#include "ElfLib.h"\r
22\r
23/**\r
24 The wrapper function of PeiLoadImageLoadImage().\r
25\r
26 @param This - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
27 @param FileHandle - Pointer to the FFS file header of the image.\r
28 @param ImageAddressArg - Pointer to PE/TE image.\r
29 @param ImageSizeArg - Size of PE/TE image.\r
30 @param EntryPoint - Pointer to entry point of specified image file for output.\r
31 @param AuthenticationState - Pointer to attestation authentication state of image.\r
32\r
33 @return Status of PeiLoadImageLoadImage().\r
34\r
35**/\r
36EFI_STATUS\r
37EFIAPI\r
38PeiLoadFileLoadPayload (\r
39 IN CONST EFI_PEI_LOAD_FILE_PPI *This,\r
40 IN EFI_PEI_FILE_HANDLE FileHandle,\r
e35dd328
MK
41 OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL,\r
42 OUT UINT64 *ImageSizeArg OPTIONAL,\r
fe471d4a
RN
43 OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
44 OUT UINT32 *AuthenticationState\r
45 )\r
46{\r
e5efcf8b
MK
47 EFI_STATUS Status;\r
48 VOID *Elf;\r
49 UNIVERSAL_PAYLOAD_EXTRA_DATA *ExtraData;\r
50 ELF_IMAGE_CONTEXT Context;\r
51 UNIVERSAL_PAYLOAD_INFO_HEADER *PldInfo;\r
52 UINT32 Index;\r
53 UINT16 ExtraDataIndex;\r
54 CHAR8 *SectionName;\r
55 UINTN Offset;\r
56 UINTN Size;\r
57 UINT32 ExtraDataCount;\r
58 UINTN Instance;\r
59 UINTN Length;\r
fe471d4a
RN
60\r
61 //\r
62 // ELF is added to file as RAW section for EDKII bootloader.\r
63 // But RAW section might be added by build tool before the ELF RAW section when alignment is specified for ELF RAW section.\r
64 // Below loop skips the RAW section that doesn't contain valid ELF image.\r
65 //\r
66 Instance = 0;\r
67 do {\r
68 Status = PeiServicesFfsFindSectionData3 (EFI_SECTION_RAW, Instance++, FileHandle, &Elf, AuthenticationState);\r
69 if (EFI_ERROR (Status)) {\r
70 return Status;\r
71 }\r
72\r
73 ZeroMem (&Context, sizeof (Context));\r
74 Status = ParseElfImage (Elf, &Context);\r
75 } while (EFI_ERROR (Status));\r
76\r
77 DEBUG ((\r
e5efcf8b
MK
78 DEBUG_INFO,\r
79 "Payload File Size: 0x%08X, Mem Size: 0x%08x, Reload: %d\n",\r
80 Context.FileSize,\r
81 Context.ImageSize,\r
82 Context.ReloadRequired\r
fe471d4a
RN
83 ));\r
84\r
85 //\r
86 // Get UNIVERSAL_PAYLOAD_INFO_HEADER and number of additional PLD sections.\r
87 //\r
88 PldInfo = NULL;\r
89 ExtraDataCount = 0;\r
90 for (Index = 0; Index < Context.ShNum; Index++) {\r
91 Status = GetElfSectionName (&Context, Index, &SectionName);\r
e5efcf8b 92 if (EFI_ERROR (Status)) {\r
fe471d4a
RN
93 continue;\r
94 }\r
e5efcf8b 95\r
fe471d4a 96 DEBUG ((DEBUG_INFO, "Payload Section[%d]: %a\n", Index, SectionName));\r
e5efcf8b 97 if (AsciiStrCmp (SectionName, UNIVERSAL_PAYLOAD_INFO_SEC_NAME) == 0) {\r
fe471d4a 98 Status = GetElfSectionPos (&Context, Index, &Offset, &Size);\r
e5efcf8b 99 if (!EFI_ERROR (Status)) {\r
fe471d4a
RN
100 PldInfo = (UNIVERSAL_PAYLOAD_INFO_HEADER *)(Context.FileBase + Offset);\r
101 }\r
e5efcf8b 102 } else if (AsciiStrnCmp (SectionName, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH) == 0) {\r
fe471d4a
RN
103 Status = GetElfSectionPos (&Context, Index, &Offset, &Size);\r
104 if (!EFI_ERROR (Status)) {\r
105 ExtraDataCount++;\r
106 }\r
107 }\r
108 }\r
109\r
110 //\r
111 // Report the additional PLD sections through HOB.\r
112 //\r
e5efcf8b 113 Length = sizeof (UNIVERSAL_PAYLOAD_EXTRA_DATA) + ExtraDataCount * sizeof (UNIVERSAL_PAYLOAD_EXTRA_DATA_ENTRY);\r
fe471d4a 114 ExtraData = BuildGuidHob (\r
e5efcf8b
MK
115 &gUniversalPayloadExtraDataGuid,\r
116 Length\r
117 );\r
118 ExtraData->Count = ExtraDataCount;\r
9bf4aee7 119 ExtraData->Header.Revision = UNIVERSAL_PAYLOAD_EXTRA_DATA_REVISION;\r
e5efcf8b 120 ExtraData->Header.Length = (UINT16)Length;\r
fe471d4a
RN
121 if (ExtraDataCount != 0) {\r
122 for (ExtraDataIndex = 0, Index = 0; Index < Context.ShNum; Index++) {\r
123 Status = GetElfSectionName (&Context, Index, &SectionName);\r
e5efcf8b 124 if (EFI_ERROR (Status)) {\r
fe471d4a
RN
125 continue;\r
126 }\r
e5efcf8b
MK
127\r
128 if (AsciiStrnCmp (SectionName, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH) == 0) {\r
fe471d4a
RN
129 Status = GetElfSectionPos (&Context, Index, &Offset, &Size);\r
130 if (!EFI_ERROR (Status)) {\r
131 ASSERT (ExtraDataIndex < ExtraDataCount);\r
132 AsciiStrCpyS (\r
133 ExtraData->Entry[ExtraDataIndex].Identifier,\r
e5efcf8b 134 sizeof (ExtraData->Entry[ExtraDataIndex].Identifier),\r
fe471d4a
RN
135 SectionName + UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH\r
136 );\r
137 ExtraData->Entry[ExtraDataIndex].Base = (UINTN)(Context.FileBase + Offset);\r
138 ExtraData->Entry[ExtraDataIndex].Size = Size;\r
139 ExtraDataIndex++;\r
140 }\r
141 }\r
142 }\r
143 }\r
144\r
e5efcf8b 145 if (Context.ReloadRequired || (Context.PreferredImageAddress != Context.FileBase)) {\r
fe471d4a
RN
146 Context.ImageAddress = AllocatePages (EFI_SIZE_TO_PAGES (Context.ImageSize));\r
147 } else {\r
148 Context.ImageAddress = Context.FileBase;\r
149 }\r
150\r
151 //\r
152 // Load ELF into the required base\r
153 //\r
154 Status = LoadElfImage (&Context);\r
e5efcf8b
MK
155 if (!EFI_ERROR (Status)) {\r
156 *ImageAddressArg = (UINTN)Context.ImageAddress;\r
fe471d4a
RN
157 *EntryPoint = Context.EntryPoint;\r
158 *ImageSizeArg = Context.ImageSize;\r
159 }\r
e5efcf8b 160\r
fe471d4a
RN
161 return Status;\r
162}\r
163\r
e5efcf8b 164EFI_PEI_LOAD_FILE_PPI mPeiLoadFilePpi = {\r
fe471d4a
RN
165 PeiLoadFileLoadPayload\r
166};\r
167\r
e5efcf8b 168EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {\r
fe471d4a
RN
169 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
170 &gEfiPeiLoadFilePpiGuid,\r
171 &mPeiLoadFilePpi\r
172};\r
e5efcf8b 173\r
fe471d4a
RN
174/**\r
175\r
176 Install Pei Load File PPI.\r
177\r
178 @param FileHandle Handle of the file being invoked.\r
179 @param PeiServices Describes the list of possible PEI Services.\r
180\r
181 @retval EFI_SUCESS The entry point executes successfully.\r
182 @retval Others Some error occurs during the execution of this function.\r
183\r
184**/\r
185EFI_STATUS\r
186EFIAPI\r
187InitializePayloadLoaderPeim (\r
188 IN EFI_PEI_FILE_HANDLE FileHandle,\r
189 IN CONST EFI_PEI_SERVICES **PeiServices\r
190 )\r
191{\r
192 EFI_STATUS Status;\r
e5efcf8b 193\r
fe471d4a
RN
194 Status = PeiServicesInstallPpi (&gPpiLoadFilePpiList);\r
195\r
196 return Status;\r
197}\r