]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c
EmbeddedPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / EmbeddedPkg / Application / AndroidBoot / AndroidBootApp.c
1 /** @file
2
3 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
4 Copyright (c) 2017, Linaro. All rights reserved.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
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>
16
17 #include <Protocol/BlockIo.h>
18 #include <Protocol/DevicePathFromText.h>
19
20 /* Validate the node is media hard drive type */
21 EFI_STATUS
22 ValidateAndroidMediaDevicePath (
23 IN EFI_DEVICE_PATH *DevicePath
24 )
25 {
26 EFI_DEVICE_PATH_PROTOCOL *Node, *NextNode;
27
28 NextNode = DevicePath;
29 while (NextNode != NULL) {
30 Node = NextNode;
31 if (Node->Type == MEDIA_DEVICE_PATH &&
32 Node->SubType == MEDIA_HARDDRIVE_DP) {
33 return EFI_SUCCESS;
34 }
35 NextNode = NextDevicePathNode (Node);
36 }
37 return EFI_INVALID_PARAMETER;
38 }
39
40 EFI_STATUS
41 EFIAPI
42 AndroidBootAppEntryPoint (
43 IN EFI_HANDLE ImageHandle,
44 IN EFI_SYSTEM_TABLE *SystemTable
45 )
46 {
47 EFI_STATUS Status;
48 CHAR16 *BootPathStr;
49 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
50 EFI_DEVICE_PATH *DevicePath;
51 EFI_BLOCK_IO_PROTOCOL *BlockIo;
52 UINT32 MediaId, BlockSize;
53 VOID *Buffer;
54 EFI_HANDLE Handle;
55 UINTN BootImgSize;
56
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);
64
65 Status = ValidateAndroidMediaDevicePath (DevicePath);
66 if (EFI_ERROR (Status)) {
67 return Status;
68 }
69
70 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,
71 &DevicePath, &Handle);
72 if (EFI_ERROR (Status)) {
73 return Status;
74 }
75
76 Status = gBS->OpenProtocol (
77 Handle,
78 &gEfiBlockIoProtocolGuid,
79 (VOID **) &BlockIo,
80 gImageHandle,
81 NULL,
82 EFI_OPEN_PROTOCOL_GET_PROTOCOL
83 );
84 if (EFI_ERROR (Status)) {
85 DEBUG ((DEBUG_ERROR, "Failed to get BlockIo: %r\n", Status));
86 return Status;
87 }
88
89 MediaId = BlockIo->Media->MediaId;
90 BlockSize = BlockIo->Media->BlockSize;
91 Buffer = AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));
92 if (Buffer == NULL) {
93 return EFI_BUFFER_TOO_SMALL;
94 }
95 /* Load header of boot.img */
96 Status = BlockIo->ReadBlocks (
97 BlockIo,
98 MediaId,
99 0,
100 BlockSize,
101 Buffer
102 );
103 Status = AndroidBootImgGetImgSize (Buffer, &BootImgSize);
104 if (EFI_ERROR (Status)) {
105 DEBUG ((DEBUG_ERROR, "Failed to get AndroidBootImg Size: %r\n", Status));
106 return Status;
107 }
108 BootImgSize = ALIGN_VALUE (BootImgSize, BlockSize);
109 FreePages (Buffer, EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));
110
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;
115 }
116
117 /* Load header of boot.img */
118 Status = BlockIo->ReadBlocks (
119 BlockIo,
120 MediaId,
121 0,
122 BootImgSize,
123 Buffer
124 );
125 if (EFI_ERROR (Status)) {
126 DEBUG ((DEBUG_ERROR, "Failed to read blocks: %r\n", Status));
127 goto EXIT;
128 }
129
130 Status = AndroidBootImgBoot (Buffer, BootImgSize);
131
132 EXIT:
133 return Status;
134 }