]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / CompatImageLoaderDxe / CompatImageLoaderDxe.c
CommitLineData
d55cfdc5
AB
1/** @file\r
2 * PE/COFF emulator protocol implementation to start Linux kernel\r
3 * images from non-native firmware\r
4 *\r
5 * Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>\r
6 *\r
7 * SPDX-License-Identifier: BSD-2-Clause-Patent\r
8 *\r
9 */\r
10\r
11#include <PiDxe.h>\r
12\r
13#include <Library/BaseMemoryLib.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/PeCoffLib.h>\r
16#include <Library/UefiBootServicesTableLib.h>\r
17\r
18#include <Protocol/PeCoffImageEmulator.h>\r
19\r
20#pragma pack (1)\r
21typedef struct {\r
ac0a286f
MK
22 UINT8 Type;\r
23 UINT8 Size;\r
24 UINT16 MachineType;\r
25 UINT32 EntryPoint;\r
d55cfdc5
AB
26} PE_COMPAT_TYPE1;\r
27#pragma pack ()\r
28\r
29STATIC\r
30BOOLEAN\r
31EFIAPI\r
32IsImageSupported (\r
ac0a286f
MK
33 IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This,\r
34 IN UINT16 ImageType,\r
35 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL\r
d55cfdc5
AB
36 )\r
37{\r
38 return ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
39}\r
40\r
41STATIC\r
42EFI_IMAGE_ENTRY_POINT\r
43EFIAPI\r
44GetCompatEntryPoint (\r
ac0a286f 45 IN EFI_PHYSICAL_ADDRESS ImageBase\r
d55cfdc5
AB
46 )\r
47{\r
ac0a286f
MK
48 EFI_IMAGE_DOS_HEADER *DosHdr;\r
49 UINTN PeCoffHeaderOffset;\r
50 EFI_IMAGE_NT_HEADERS32 *Pe32;\r
51 EFI_IMAGE_SECTION_HEADER *Section;\r
52 UINTN NumberOfSections;\r
53 PE_COMPAT_TYPE1 *PeCompat;\r
54 UINTN PeCompatEnd;\r
d55cfdc5
AB
55\r
56 DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageBase;\r
57 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
58 return NULL;\r
59 }\r
60\r
61 PeCoffHeaderOffset = DosHdr->e_lfanew;\r
ac0a286f 62 Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageBase + PeCoffHeaderOffset);\r
d55cfdc5
AB
63\r
64 Section = (EFI_IMAGE_SECTION_HEADER *)((UINTN)&Pe32->OptionalHeader +\r
65 Pe32->FileHeader.SizeOfOptionalHeader);\r
66 NumberOfSections = (UINTN)Pe32->FileHeader.NumberOfSections;\r
67\r
68 while (NumberOfSections--) {\r
69 if (!CompareMem (Section->Name, ".compat", sizeof (Section->Name))) {\r
70 //\r
71 // Dereference the section contents to find the mixed mode entry point\r
72 //\r
ac0a286f 73 PeCompat = (PE_COMPAT_TYPE1 *)((UINTN)ImageBase + Section->VirtualAddress);\r
d55cfdc5
AB
74 PeCompatEnd = (UINTN)(VOID *)PeCompat + Section->Misc.VirtualSize;\r
75\r
76 while (PeCompat->Type != 0 && (UINTN)(VOID *)PeCompat < PeCompatEnd) {\r
ac0a286f
MK
77 if ((PeCompat->Type == 1) &&\r
78 (PeCompat->Size >= sizeof (PE_COMPAT_TYPE1)) &&\r
79 EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCompat->MachineType))\r
80 {\r
d55cfdc5
AB
81 return (EFI_IMAGE_ENTRY_POINT)((UINTN)ImageBase + PeCompat->EntryPoint);\r
82 }\r
ac0a286f 83\r
d55cfdc5
AB
84 PeCompat = (PE_COMPAT_TYPE1 *)((UINTN)PeCompat + PeCompat->Size);\r
85 ASSERT ((UINTN)(VOID *)PeCompat < PeCompatEnd);\r
86 }\r
87 }\r
ac0a286f 88\r
d55cfdc5
AB
89 Section++;\r
90 }\r
ac0a286f 91\r
d55cfdc5
AB
92 return NULL;\r
93}\r
94\r
95STATIC\r
96EFI_STATUS\r
97EFIAPI\r
98RegisterImage (\r
ac0a286f
MK
99 IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This,\r
100 IN EFI_PHYSICAL_ADDRESS ImageBase,\r
101 IN UINT64 ImageSize,\r
102 IN OUT EFI_IMAGE_ENTRY_POINT *EntryPoint\r
d55cfdc5
AB
103 )\r
104{\r
ac0a286f 105 EFI_IMAGE_ENTRY_POINT CompatEntryPoint;\r
d55cfdc5
AB
106\r
107 CompatEntryPoint = GetCompatEntryPoint (ImageBase);\r
108 if (CompatEntryPoint == NULL) {\r
109 return EFI_UNSUPPORTED;\r
110 }\r
111\r
112 *EntryPoint = CompatEntryPoint;\r
113 return EFI_SUCCESS;\r
114}\r
115\r
116STATIC\r
117EFI_STATUS\r
118EFIAPI\r
119UnregisterImage (\r
ac0a286f
MK
120 IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This,\r
121 IN EFI_PHYSICAL_ADDRESS ImageBase\r
d55cfdc5
AB
122 )\r
123{\r
124 return EFI_SUCCESS;\r
125}\r
126\r
ac0a286f 127STATIC EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL mCompatLoaderPeCoffEmuProtocol = {\r
d55cfdc5
AB
128 IsImageSupported,\r
129 RegisterImage,\r
130 UnregisterImage,\r
131 EDKII_PECOFF_IMAGE_EMULATOR_VERSION,\r
132 EFI_IMAGE_MACHINE_X64\r
133};\r
134\r
135EFI_STATUS\r
136EFIAPI\r
137CompatImageLoaderDxeEntryPoint (\r
138 IN EFI_HANDLE ImageHandle,\r
139 IN EFI_SYSTEM_TABLE *SystemTable\r
140 )\r
141{\r
ac0a286f
MK
142 return gBS->InstallProtocolInterface (\r
143 &ImageHandle,\r
d55cfdc5
AB
144 &gEdkiiPeCoffImageEmulatorProtocolGuid,\r
145 EFI_NATIVE_INTERFACE,\r
ac0a286f
MK
146 &mCompatLoaderPeCoffEmuProtocol\r
147 );\r
d55cfdc5 148}\r