3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
4 Copyright (c) 2017, Linaro. All rights reserved.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/AndroidBootImgLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/DevicePathLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
17 #include <Protocol/BlockIo.h>
18 #include <Protocol/DevicePathFromText.h>
20 /* Validate the node is media hard drive type */
22 ValidateAndroidMediaDevicePath (
23 IN EFI_DEVICE_PATH
*DevicePath
26 EFI_DEVICE_PATH_PROTOCOL
*Node
, *NextNode
;
28 NextNode
= DevicePath
;
29 while (NextNode
!= NULL
) {
31 if (Node
->Type
== MEDIA_DEVICE_PATH
&&
32 Node
->SubType
== MEDIA_HARDDRIVE_DP
) {
35 NextNode
= NextDevicePathNode (Node
);
37 return EFI_INVALID_PARAMETER
;
42 AndroidBootAppEntryPoint (
43 IN EFI_HANDLE ImageHandle
,
44 IN EFI_SYSTEM_TABLE
*SystemTable
49 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL
*EfiDevicePathFromTextProtocol
;
50 EFI_DEVICE_PATH
*DevicePath
;
51 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
52 UINT32 MediaId
, BlockSize
;
57 BootPathStr
= (CHAR16
*)PcdGetPtr (PcdAndroidBootDevicePath
);
58 ASSERT (BootPathStr
!= NULL
);
59 Status
= gBS
->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid
, NULL
,
60 (VOID
**)&EfiDevicePathFromTextProtocol
);
61 ASSERT_EFI_ERROR(Status
);
62 DevicePath
= (EFI_DEVICE_PATH
*)EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (BootPathStr
);
63 ASSERT (DevicePath
!= NULL
);
65 Status
= ValidateAndroidMediaDevicePath (DevicePath
);
66 if (EFI_ERROR (Status
)) {
70 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
,
71 &DevicePath
, &Handle
);
72 if (EFI_ERROR (Status
)) {
76 Status
= gBS
->OpenProtocol (
78 &gEfiBlockIoProtocolGuid
,
82 EFI_OPEN_PROTOCOL_GET_PROTOCOL
84 if (EFI_ERROR (Status
)) {
85 DEBUG ((DEBUG_ERROR
, "Failed to get BlockIo: %r\n", Status
));
89 MediaId
= BlockIo
->Media
->MediaId
;
90 BlockSize
= BlockIo
->Media
->BlockSize
;
91 Buffer
= AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER
)));
93 return EFI_BUFFER_TOO_SMALL
;
95 /* Load header of boot.img */
96 Status
= BlockIo
->ReadBlocks (
103 Status
= AndroidBootImgGetImgSize (Buffer
, &BootImgSize
);
104 if (EFI_ERROR (Status
)) {
105 DEBUG ((DEBUG_ERROR
, "Failed to get AndroidBootImg Size: %r\n", Status
));
108 BootImgSize
= ALIGN_VALUE (BootImgSize
, BlockSize
);
109 FreePages (Buffer
, EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER
)));
111 /* Both PartitionStart and PartitionSize are counted as block size. */
112 Buffer
= AllocatePages (EFI_SIZE_TO_PAGES (BootImgSize
));
113 if (Buffer
== NULL
) {
114 return EFI_BUFFER_TOO_SMALL
;
117 /* Load header of boot.img */
118 Status
= BlockIo
->ReadBlocks (
125 if (EFI_ERROR (Status
)) {
126 DEBUG ((DEBUG_ERROR
, "Failed to read blocks: %r\n", Status
));
130 Status
= AndroidBootImgBoot (Buffer
, BootImgSize
);