mirror of https://github.com/acidanthera/audk.git
EmbeddedPkg/AndroidFastbootTransportUsbDxe: Implemented Android FastBoot over USB
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15316 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
4257aa4d4b
commit
d3f99770c0
|
@ -0,0 +1,278 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
/*
|
||||
* Implementation of the FASTBOOT_TRANSPORT_PROTOCOL using the USB_DEVICE_PROTOCOL
|
||||
*/
|
||||
|
||||
#include <Protocol/UsbDevice.h>
|
||||
#include <Protocol/AndroidFastbootTransport.h>
|
||||
#include <Protocol/SimpleTextOut.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
|
||||
STATIC USB_DEVICE_PROTOCOL *mUsbDevice;
|
||||
|
||||
// Configuration attributes:
|
||||
// bit 7 reserved and must be 1, bit 6 means self-powered.
|
||||
#define CONFIG_DESC_ATTRIBUTES (BIT7 | BIT6)
|
||||
|
||||
#define MAX_PACKET_SIZE_BULK 512
|
||||
|
||||
STATIC USB_DEVICE_PROTOCOL *mUsbDevice;
|
||||
STATIC EFI_EVENT mReceiveEvent = NULL;
|
||||
STATIC LIST_ENTRY mPacketList;
|
||||
|
||||
// List type for queued received packets
|
||||
typedef struct _FASTBOOT_USB_PACKET_LIST {
|
||||
LIST_ENTRY Link;
|
||||
VOID *Buffer;
|
||||
UINTN BufferSize;
|
||||
} FASTBOOT_USB_PACKET_LIST;
|
||||
|
||||
|
||||
/*
|
||||
No string descriptors - all string descriptor members are set to 0
|
||||
*/
|
||||
|
||||
STATIC USB_DEVICE_DESCRIPTOR mDeviceDescriptor = {
|
||||
sizeof (USB_DEVICE_DESCRIPTOR), //Length
|
||||
USB_DESC_TYPE_DEVICE, //DescriptorType
|
||||
0x0200, //BcdUSB
|
||||
0xFF, //DeviceClass
|
||||
0, //DeviceSubClass
|
||||
0, //DeviceProtocol
|
||||
64, //MaxPacketSize0
|
||||
FixedPcdGet32 (PcdAndroidFastbootUsbVendorId), //IdVendor
|
||||
FixedPcdGet32 (PcdAndroidFastbootUsbProductId), //IdProduct
|
||||
0, //BcdDevice
|
||||
0, //StrManufacturer
|
||||
0, //StrProduct
|
||||
0, //StrSerialNumber
|
||||
1 //NumConfigurations
|
||||
};
|
||||
|
||||
/*
|
||||
We have one configuration, one interface, and two endpoints (one IN, one OUT)
|
||||
*/
|
||||
|
||||
// Lazy (compile-time) way to concatenate descriptors to pass to the USB device
|
||||
// protocol
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
USB_CONFIG_DESCRIPTOR ConfigDescriptor;
|
||||
USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||
USB_ENDPOINT_DESCRIPTOR EndpointDescriptor1;
|
||||
USB_ENDPOINT_DESCRIPTOR EndpointDescriptor2;
|
||||
} GET_CONFIG_DESCRIPTOR_RESPONSE;
|
||||
#pragma pack()
|
||||
|
||||
STATIC GET_CONFIG_DESCRIPTOR_RESPONSE mGetConfigDescriptorResponse = {
|
||||
{ // USB_CONFIG_DESCRIPTOR
|
||||
sizeof (USB_CONFIG_DESCRIPTOR), //Length;
|
||||
USB_DESC_TYPE_CONFIG, //DescriptorType;
|
||||
sizeof (GET_CONFIG_DESCRIPTOR_RESPONSE), //TotalLength;
|
||||
1, //NumInterfaces;
|
||||
1, //ConfigurationValue;
|
||||
0, //Configuration;
|
||||
CONFIG_DESC_ATTRIBUTES, //Attributes;
|
||||
0 //MaxPower;
|
||||
},
|
||||
{ // USB_INTERFACE_DESCRIPTOR
|
||||
sizeof (USB_INTERFACE_DESCRIPTOR), //Length;
|
||||
USB_DESC_TYPE_INTERFACE, //DescriptorType;
|
||||
0, //InterfaceNumber;
|
||||
0, //AlternateSetting;
|
||||
2, //NumEndpoints;
|
||||
0xFF, //InterfaceClass;
|
||||
// Vendor specific interface subclass and protocol codes.
|
||||
// I found these values in the Fastboot code
|
||||
// (in match_fastboot_with_serial in fastboot.c).
|
||||
0x42, //InterfaceSubClass;
|
||||
0x03, //InterfaceProtocol;
|
||||
0 //Interface;
|
||||
},
|
||||
{ // USB_ENDPOINT_DESCRIPTOR (In Endpoint)
|
||||
sizeof (USB_ENDPOINT_DESCRIPTOR), //Length;
|
||||
USB_DESC_TYPE_ENDPOINT, //DescriptorType;
|
||||
1 | BIT7, //EndpointAddress;
|
||||
0x2, //Attributes;
|
||||
MAX_PACKET_SIZE_BULK, //MaxPacketSize;
|
||||
16 //Interval;
|
||||
},
|
||||
{ // STATIC USB_ENDPOINT_DESCRIPTOR (Out Endpoint)
|
||||
sizeof (USB_ENDPOINT_DESCRIPTOR), //Length;
|
||||
USB_DESC_TYPE_ENDPOINT, //DescriptorType;
|
||||
1, //EndpointAddress;
|
||||
0x2, //Attributes;
|
||||
MAX_PACKET_SIZE_BULK, //MaxPacketSize;
|
||||
16 //Interval;
|
||||
}
|
||||
};
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
DataReceived (
|
||||
IN UINTN Size,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
{
|
||||
FASTBOOT_USB_PACKET_LIST *NewEntry;
|
||||
|
||||
NewEntry = AllocatePool (sizeof (*NewEntry));
|
||||
ASSERT (NewEntry != NULL);
|
||||
|
||||
NewEntry->Buffer = Buffer;
|
||||
NewEntry->BufferSize = Size;
|
||||
|
||||
InsertTailList (&mPacketList, &NewEntry->Link);
|
||||
|
||||
if (mReceiveEvent) {
|
||||
gBS->SignalEvent (mReceiveEvent);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
DataSent (
|
||||
IN UINT8 EndpointIndex
|
||||
)
|
||||
{
|
||||
// Don't care.
|
||||
}
|
||||
|
||||
/*
|
||||
Set up the transport system for use by Fastboot.
|
||||
e.g. For USB this probably means making the device enumerable.
|
||||
*/
|
||||
EFI_STATUS
|
||||
FastbootTransportUsbStart (
|
||||
EFI_EVENT ReceiveEvent
|
||||
)
|
||||
{
|
||||
GET_CONFIG_DESCRIPTOR_RESPONSE *Responses;
|
||||
|
||||
mReceiveEvent = ReceiveEvent;
|
||||
|
||||
mGetConfigDescriptorResponse.ConfigDescriptor.TotalLength = sizeof (GET_CONFIG_DESCRIPTOR_RESPONSE);
|
||||
Responses = &mGetConfigDescriptorResponse;
|
||||
|
||||
InitializeListHead (&mPacketList);
|
||||
|
||||
return mUsbDevice->Start (&mDeviceDescriptor, (VOID **) &Responses, DataReceived, DataSent);
|
||||
}
|
||||
|
||||
/*
|
||||
Function to be called when all Fastboot transactions are finished, to
|
||||
de-initialise the transport system.
|
||||
e.g. A USB OTG system might want to get out of peripheral mode so it can be
|
||||
a USB host.
|
||||
*/
|
||||
EFI_STATUS
|
||||
FastbootTransportUsbStop (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
// not yet implemented in USB
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Send data. This function can be used both for command responses like "OKAY"
|
||||
and for the data phase (the protocol doesn't describe any situation when the
|
||||
latter might be necessary, but does allow it)
|
||||
*/
|
||||
EFI_STATUS
|
||||
FastbootTransportUsbSend (
|
||||
IN UINTN BufferSize,
|
||||
IN CONST VOID *Buffer,
|
||||
IN EFI_EVENT *FatalErrorEvent
|
||||
)
|
||||
{
|
||||
// Current USB protocol is blocking, so ignore FatalErrorEvent
|
||||
return mUsbDevice->Send(1, BufferSize, Buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
When the event has been Signalled to say data is available from the host,
|
||||
this function is used to get data. In order to handle the case where several
|
||||
packets are received before ReceiveEvent's notify function is called, packets
|
||||
received are queued, and each call to this function returns the next packet in
|
||||
the queue. It should therefore be called in a loop, the exit condition being a
|
||||
return of EFI_NOT_READY.
|
||||
|
||||
Parameters:
|
||||
Buffer - The buffer in which to place data
|
||||
BufferSize - The size of Buffer in bytes
|
||||
|
||||
Return EFI_NOT_READY if there is no data available
|
||||
*/
|
||||
EFI_STATUS
|
||||
FastbootTransportUsbReceive (
|
||||
OUT UINTN *BufferSize,
|
||||
OUT VOID **Buffer
|
||||
)
|
||||
{
|
||||
FASTBOOT_USB_PACKET_LIST *Entry;
|
||||
|
||||
if (IsListEmpty (&mPacketList)) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
Entry = (FASTBOOT_USB_PACKET_LIST *) GetFirstNode (&mPacketList);
|
||||
|
||||
*BufferSize = Entry->BufferSize;
|
||||
*Buffer = Entry->Buffer;
|
||||
|
||||
RemoveEntryList (&Entry->Link);
|
||||
FreePool (Entry);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC FASTBOOT_TRANSPORT_PROTOCOL mTransportProtocol = {
|
||||
FastbootTransportUsbStart,
|
||||
FastbootTransportUsbStop,
|
||||
FastbootTransportUsbSend,
|
||||
FastbootTransportUsbReceive
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
FastbootTransportUsbEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Assume there's only one USB peripheral controller.
|
||||
Status = gBS->LocateProtocol (&gUsbDeviceProtocolGuid, NULL, (VOID **) &mUsbDevice);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&ImageHandle,
|
||||
&gAndroidFastbootTransportProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&mTransportProtocol
|
||||
);
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#/** @file
|
||||
#
|
||||
# Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = FastbootTransportUsbDxe
|
||||
FILE_GUID = f6bec3fe-88fb-11e3-ae84-e73b77561c35
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = FastbootTransportUsbEntryPoint
|
||||
|
||||
[Sources.common]
|
||||
FastbootTransportUsb.c
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
|
||||
[Protocols]
|
||||
gEfiDriverBindingProtocolGuid
|
||||
gUsbDeviceProtocolGuid
|
||||
gAndroidFastbootTransportProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
|
||||
[FixedPcd]
|
||||
gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbVendorId
|
||||
gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId
|
|
@ -129,6 +129,16 @@
|
|||
gEmbeddedTokenSpaceGuid.PcdGdbMaxPacketRetryCount|10000000|UINT32|0x0000004c
|
||||
gEmbeddedTokenSpaceGuid.PcdGdbTimerPeriodMilliseconds|250|UINT32|0x0000004d
|
||||
|
||||
#
|
||||
# Android FastBoot
|
||||
#
|
||||
|
||||
# The Android FastBoot utility has hard-coded USB Vendor IDs that it recognises
|
||||
# (and 0xf00d isn't one of them!).
|
||||
# You'll need to pass it "-i 0xf00d" to get it to recognise this device.
|
||||
gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbVendorId|0xf00d|UINT32|0x00000022
|
||||
gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xbeef|UINT32|0x00000023
|
||||
|
||||
[PcdsFixedAtBuild.ARM]
|
||||
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00000010
|
||||
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
|
||||
|
|
|
@ -255,6 +255,7 @@
|
|||
EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
|
||||
|
||||
EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
|
||||
EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
|
||||
|
||||
[Components.IA32, Components.X64, Components.IPF, Components.ARM]
|
||||
EmbeddedPkg/GdbStub/GdbStub.inf
|
||||
|
|
Loading…
Reference in New Issue