]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmbeddedPkg / Application / AndroidFastboot / Arm / BootAndroidBootImg.c
CommitLineData
f6755908
OM
1/** @file\r
2\r
bd9a5182 3 Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>\r
f6755908 4\r
878b807a 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
f6755908
OM
6\r
7**/\r
8\r
9#include "AndroidFastbootApp.h"\r
10\r
11#include <Protocol/DevicePath.h>\r
fcf41edf 12#include <Protocol/LoadedImage.h>\r
f6755908 13\r
f6755908 14#include <Library/DevicePathLib.h>\r
bd9a5182
OM
15#include <Library/UefiBootServicesTableLib.h>\r
16#include <Library/UefiLib.h>\r
f6755908 17\r
f6755908
OM
18// Device Path representing an image in memory\r
19#pragma pack(1)\r
20typedef struct {\r
e7108d0e
MK
21 MEMMAP_DEVICE_PATH Node1;\r
22 EFI_DEVICE_PATH_PROTOCOL End;\r
f6755908
OM
23} MEMORY_DEVICE_PATH;\r
24#pragma pack()\r
25\r
e7108d0e 26STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate =\r
f6755908
OM
27{\r
28 {\r
29 {\r
30 HARDWARE_DEVICE_PATH,\r
31 HW_MEMMAP_DP,\r
32 {\r
33 (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),\r
34 (UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8),\r
35 },\r
36 }, // Header\r
37 0, // StartingAddress (set at runtime)\r
38 0 // EndingAddress (set at runtime)\r
39 }, // Node1\r
40 {\r
41 END_DEVICE_PATH_TYPE,\r
42 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
b0fdce95 43 { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }\r
f6755908
OM
44 } // End\r
45};\r
46\r
fcf41edf
AB
47/**\r
48 Start an EFI Application from a Device Path\r
49\r
50 @param ParentImageHandle Handle of the calling image\r
51 @param DevicePath Location of the EFI Application\r
52\r
53 @retval EFI_SUCCESS All drivers have been connected\r
54 @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found\r
55 @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.\r
56\r
57**/\r
58STATIC\r
59EFI_STATUS\r
60StartEfiApplication (\r
e7108d0e
MK
61 IN EFI_HANDLE ParentImageHandle,\r
62 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
63 IN UINTN LoadOptionsSize,\r
64 IN VOID *LoadOptions\r
fcf41edf
AB
65 )\r
66{\r
e7108d0e
MK
67 EFI_STATUS Status;\r
68 EFI_HANDLE ImageHandle;\r
69 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
fcf41edf
AB
70\r
71 // Load the image from the device path with Boot Services function\r
e7108d0e
MK
72 Status = gBS->LoadImage (\r
73 TRUE,\r
74 ParentImageHandle,\r
75 DevicePath,\r
76 NULL,\r
77 0,\r
78 &ImageHandle\r
79 );\r
fcf41edf 80 if (EFI_ERROR (Status)) {\r
82e0c422
DB
81 //\r
82 // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created\r
83 // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.\r
84 // If the caller doesn't have the option to defer the execution of an image, we should\r
85 // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.\r
86 //\r
87 if (Status == EFI_SECURITY_VIOLATION) {\r
88 gBS->UnloadImage (ImageHandle);\r
89 }\r
e7108d0e 90\r
fcf41edf
AB
91 return Status;\r
92 }\r
93\r
94 // Passed LoadOptions to the EFI Application\r
95 if (LoadOptionsSize != 0) {\r
e7108d0e
MK
96 Status = gBS->HandleProtocol (\r
97 ImageHandle,\r
98 &gEfiLoadedImageProtocolGuid,\r
99 (VOID **)&LoadedImage\r
100 );\r
fcf41edf
AB
101 if (EFI_ERROR (Status)) {\r
102 return Status;\r
103 }\r
104\r
e7108d0e
MK
105 LoadedImage->LoadOptionsSize = LoadOptionsSize;\r
106 LoadedImage->LoadOptions = LoadOptions;\r
fcf41edf
AB
107 }\r
108\r
109 // Before calling the image, enable the Watchdog Timer for the 5 Minute period\r
110 gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
111 // Start the image\r
112 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
113 // Clear the Watchdog Timer after the image returns\r
114 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
115\r
116 return Status;\r
117}\r
118\r
f6755908
OM
119EFI_STATUS\r
120BootAndroidBootImg (\r
e7108d0e
MK
121 IN UINTN BufferSize,\r
122 IN VOID *Buffer\r
f6755908
OM
123 )\r
124{\r
e7108d0e
MK
125 EFI_STATUS Status;\r
126 CHAR8 KernelArgs[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE];\r
127 VOID *Kernel;\r
128 UINTN KernelSize;\r
129 VOID *Ramdisk;\r
130 UINTN RamdiskSize;\r
131 MEMORY_DEVICE_PATH KernelDevicePath;\r
132 CHAR16 *LoadOptions, *NewLoadOptions;\r
f6755908
OM
133\r
134 Status = ParseAndroidBootImg (\r
e7108d0e
MK
135 Buffer,\r
136 &Kernel,\r
137 &KernelSize,\r
138 &Ramdisk,\r
139 &RamdiskSize,\r
140 KernelArgs\r
141 );\r
f6755908
OM
142 if (EFI_ERROR (Status)) {\r
143 return Status;\r
144 }\r
145\r
146 KernelDevicePath = MemoryDevicePathTemplate;\r
147\r
148 // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to\r
149 // appease GCC.\r
e7108d0e
MK
150 KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel;\r
151 KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KernelSize;\r
f6755908 152\r
34e0bcea
AB
153 // Initialize Linux command line\r
154 LoadOptions = CatSPrint (NULL, L"%a", KernelArgs);\r
155 if (LoadOptions == NULL) {\r
bd9a5182
OM
156 return EFI_OUT_OF_RESOURCES;\r
157 }\r
158\r
34e0bcea 159 if (RamdiskSize != 0) {\r
e7108d0e
MK
160 NewLoadOptions = CatSPrint (\r
161 LoadOptions,\r
162 L" initrd=0x%x,0x%x",\r
163 (UINTN)Ramdisk,\r
164 RamdiskSize\r
165 );\r
34e0bcea
AB
166 FreePool (LoadOptions);\r
167 if (NewLoadOptions == NULL) {\r
168 return EFI_OUT_OF_RESOURCES;\r
169 }\r
e7108d0e 170\r
34e0bcea 171 LoadOptions = NewLoadOptions;\r
bd9a5182
OM
172 }\r
173\r
e7108d0e
MK
174 Status = StartEfiApplication (\r
175 gImageHandle,\r
176 (EFI_DEVICE_PATH_PROTOCOL *)&KernelDevicePath,\r
34e0bcea 177 StrSize (LoadOptions),\r
e7108d0e
MK
178 LoadOptions\r
179 );\r
f6755908 180 if (EFI_ERROR (Status)) {\r
a1878955 181 DEBUG ((DEBUG_ERROR, "Couldn't Boot Linux: %d\n", Status));\r
34e0bcea
AB
182 Status = EFI_DEVICE_ERROR;\r
183 goto FreeLoadOptions;\r
f6755908
OM
184 }\r
185\r
186 // If we got here we do a confused face because BootLinuxFdt returned,\r
187 // reporting success.\r
a1878955 188 DEBUG ((DEBUG_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));\r
f6755908 189 return EFI_SUCCESS;\r
34e0bcea
AB
190\r
191FreeLoadOptions:\r
192 FreePool (LoadOptions);\r
193 return Status;\r
f6755908 194}\r