/** @file Copyright (c) 2013-2014, ARM Ltd. All rights reserved.
Copyright (c) 2017, Linaro. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include /* Validate the node is media hard drive type */ EFI_STATUS ValidateAndroidMediaDevicePath ( IN EFI_DEVICE_PATH *DevicePath ) { EFI_DEVICE_PATH_PROTOCOL *Node, *NextNode; NextNode = DevicePath; while (NextNode != NULL) { Node = NextNode; if (Node->Type == MEDIA_DEVICE_PATH && Node->SubType == MEDIA_HARDDRIVE_DP) { return EFI_SUCCESS; } NextNode = NextDevicePathNode (Node); } return EFI_INVALID_PARAMETER; } EFI_STATUS EFIAPI AndroidBootAppEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; CHAR16 *BootPathStr; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH *DevicePath; EFI_BLOCK_IO_PROTOCOL *BlockIo; UINT32 MediaId, BlockSize; VOID *Buffer; EFI_HANDLE Handle; UINTN BootImgSize; BootPathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath); ASSERT (BootPathStr != NULL); Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); ASSERT_EFI_ERROR(Status); DevicePath = (EFI_DEVICE_PATH *)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr); ASSERT (DevicePath != NULL); Status = ValidateAndroidMediaDevicePath (DevicePath); if (EFI_ERROR (Status)) { return Status; } Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &Handle); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Failed to get BlockIo: %r\n", Status)); return Status; } MediaId = BlockIo->Media->MediaId; BlockSize = BlockIo->Media->BlockSize; Buffer = AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER))); if (Buffer == NULL) { return EFI_BUFFER_TOO_SMALL; } /* Load header of boot.img */ Status = BlockIo->ReadBlocks ( BlockIo, MediaId, 0, BlockSize, Buffer ); Status = AndroidBootImgGetImgSize (Buffer, &BootImgSize); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Failed to get AndroidBootImg Size: %r\n", Status)); return Status; } BootImgSize = ALIGN_VALUE (BootImgSize, BlockSize); FreePages (Buffer, EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER))); /* Both PartitionStart and PartitionSize are counted as block size. */ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (BootImgSize)); if (Buffer == NULL) { return EFI_BUFFER_TOO_SMALL; } /* Load header of boot.img */ Status = BlockIo->ReadBlocks ( BlockIo, MediaId, 0, BootImgSize, Buffer ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Failed to read blocks: %r\n", Status)); goto EXIT; } Status = AndroidBootImgBoot (Buffer, BootImgSize); EXIT: return Status; }