summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe')
-rw-r--r--src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c272
-rw-r--r--src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf41
2 files changed, 313 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c
new file mode 100644
index 00000000..130b00ad
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c
@@ -0,0 +1,272 @@
+/** @file
+
+ Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/*
+ * 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;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
new file mode 100644
index 00000000..94c804ff
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
@@ -0,0 +1,41 @@
+#/** @file
+#
+# Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[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