public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH edk-platforms v1 0/4] enable USB on HiKey960
@ 2018-08-20 10:31 Haojian Zhuang
  2018-08-20 10:31 ` [PATCH edk-platforms v1 1/4] Platform/Hisilicon: add UsbSerialNumberLib Haojian Zhuang
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Haojian Zhuang @ 2018-08-20 10:31 UTC (permalink / raw)
  To: edk2-devel

Changelog:
v1:
  * Add UsbSerialNumberLib.
  * Enable USB device driver on HiKey960 platform.

Haojian Zhuang (4):
  Platform/Hisilicon: add UsbSerialNumberLib
  Platform/HiKey960: add platform usb driver
  Platform/HiKey960: add fastboot platform driver
  Platform/HiKey960: enable usb device driver

 Platform/Hisilicon/HiKey960/HiKey960.dec           |   3 +
 Platform/Hisilicon/HiKey960/HiKey960.dsc           |  13 +
 Platform/Hisilicon/HiKey960/HiKey960.fdf           |   3 +
 .../HiKey960FastbootDxe/HiKey960FastbootDxe.c      | 758 +++++++++++++++++++++
 .../HiKey960FastbootDxe/HiKey960FastbootDxe.inf    |  63 ++
 .../HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c       | 382 +++++++++++
 .../HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf     |  52 ++
 .../Include/Library/UsbSerialNumberLib.h           |  59 ++
 .../UsbSerialNumberLib/UsbSerialNumberLib.c        | 341 +++++++++
 .../UsbSerialNumberLib/UsbSerialNumberLib.dec      |  32 +
 .../UsbSerialNumberLib/UsbSerialNumberLib.inf      |  45 ++
 11 files changed, 1751 insertions(+)
 create mode 100644 Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c
 create mode 100644 Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
 create mode 100644 Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c
 create mode 100644 Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
 create mode 100644 Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h
 create mode 100644 Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c
 create mode 100644 Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
 create mode 100644 Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-- 
2.7.4



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH edk-platforms v1 1/4] Platform/Hisilicon: add UsbSerialNumberLib
  2018-08-20 10:31 [PATCH edk-platforms v1 0/4] enable USB on HiKey960 Haojian Zhuang
@ 2018-08-20 10:31 ` Haojian Zhuang
  2018-10-04 16:48   ` Leif Lindholm
  2018-08-20 10:31 ` [PATCH edk-platforms v1 2/4] Platform/HiKey960: add platform usb driver Haojian Zhuang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Haojian Zhuang @ 2018-08-20 10:31 UTC (permalink / raw)
  To: edk2-devel

Add UsbSerialNumberLib. The Library could generate USB Serial Number
that is used in USB device driver. And it could load/save the USB
Serial Number into storage device.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec               |  32 ++
 Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf               |  45 +++
 Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h |  59 ++++
 Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c                 | 341 ++++++++++++++++++++
 4 files changed, 477 insertions(+)

diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
new file mode 100644
index 000000000000..4b8b2e047ed9
--- /dev/null
+++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
@@ -0,0 +1,32 @@
+#
+#  Copyright (c) 2018, Linaro Limited. All rights reserved.
+#
+#  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]
+  DEC_SPECIFICATION              = 0x00010019
+  PACKAGE_NAME                   = UsbSerialNumberPkg
+  PACKAGE_GUID                   = dcd67420-4220-4b01-a8ba-1fa97fda1678
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+  Include                        # Root include for the package
+
+[Guids.common]
+  gUsbSerialNumberTokenSpaceGuid = { 0x0572f26b, 0x1a88, 0x49c2, { 0xb6, 0x98, 0x4d, 0xe0, 0xd0, 0x2a, 0xfe, 0x09 } }
diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf
new file mode 100644
index 000000000000..70ea086d324e
--- /dev/null
+++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf
@@ -0,0 +1,45 @@
+#/** @file
+#
+#  Copyright (c) 2018, Linaro. All rights reserved.
+#
+#  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                    = 0x00010019
+  BASE_NAME                      = UsbSerialNumberLib
+  FILE_GUID                      = 88709c56-2a76-4a13-8bcf-427970b7e32a
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = UsbSerialNumberLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+  VALID_ARCHITECTURES           = ARM AARCH64
+
+[Sources]
+  UsbSerialNumberLib.c
+
+[LibraryClasses]
+  ArmGenericTimerCounterLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiLib
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h b/Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h
new file mode 100644
index 000000000000..d3307153ff11
--- /dev/null
+++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h
@@ -0,0 +1,59 @@
+/** @file
+
+  Copyright (c) 2017, Linaro. All rights reserved.
+
+  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.
+
+**/
+
+#ifndef __USB_SERIAL_NUMBER_LIB_H__
+#define __USB_SERIAL_NUMBER_LIB_H__
+
+#include <Uefi.h>
+
+#define SERIAL_NUMBER_SIZE                      17
+
+typedef struct {
+  UINT64        Magic;
+  UINT64        Data;
+  CHAR16        UnicodeSN[SERIAL_NUMBER_SIZE];
+} RANDOM_SERIAL_NUMBER;
+
+EFI_STATUS
+GenerateUsbSNBySeed (
+  IN  UINT32                  Seed,
+  OUT RANDOM_SERIAL_NUMBER   *RandomSN
+  );
+
+EFI_STATUS
+GenerateUsbSN (
+  OUT CHAR16                 *UnicodeSN
+  );
+
+EFI_STATUS
+AssignUsbSN (
+  IN  CHAR8                  *AsciiCmd,
+  OUT CHAR16                 *UnicodeSN
+  );
+
+EFI_STATUS
+LoadSNFromBlock (
+  IN  EFI_HANDLE              FlashHandle,
+  IN  EFI_LBA                 Lba,
+  OUT CHAR16                 *UnicodeSN
+  );
+
+EFI_STATUS
+StoreSNToBlock (
+  IN EFI_HANDLE               FlashHandle,
+  IN EFI_LBA                  Lba,
+  IN CHAR16                  *UnicodeSN
+  );
+
+#endif /* __USB_SERIAL_NUMBER_LIB_H__ */
diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c
new file mode 100644
index 000000000000..98552f5f72fc
--- /dev/null
+++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c
@@ -0,0 +1,341 @@
+/** @file
+
+  Copyright (c) 2018, Linaro. All rights reserved.
+
+  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.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/ArmGenericTimerCounterLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UsbSerialNumberLib.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+
+#define SERIAL_NUMBER_LEN                16
+#define SERIAL_NUMBER_SIZE               17
+
+#define RANDOM_MAX                       0x7FFFFFFFFFFFFFFF
+#define RANDOM_MAGIC                     0x9A4DBEAF
+
+STATIC
+EFI_STATUS
+GenerateRandomData (
+  IN  UINT32              Seed,
+  OUT UINT64              *RandomData
+  )
+{
+  INT64                   Quotient, Remainder, Tmp;
+
+  if (RandomData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Quotient = (INT64) Seed / 127773;
+  Remainder = (INT64) Seed % 127773;
+  Tmp = (16807 * Remainder) - (2836 * Quotient);
+  if (Tmp < 0) {
+    Tmp += RANDOM_MAX;
+  }
+  Tmp = Tmp % ((UINT64)RANDOM_MAX + 1);
+  *RandomData = (UINT64)Tmp;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GenerateUsbSNBySeed (
+  IN  UINT32                  Seed,
+  OUT RANDOM_SERIAL_NUMBER    *RandomSN
+  )
+{
+  EFI_STATUS               Status;
+  UINT64                   Tmp;
+
+  if (RandomSN == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  ZeroMem (RandomSN, sizeof (RANDOM_SERIAL_NUMBER));
+  Status = GenerateRandomData (Seed, &Tmp);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  RandomSN->Data = (Tmp << 32) | Seed;
+  UnicodeSPrint (
+    RandomSN->UnicodeSN,
+    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
+    L"%lx",
+    RandomSN->Data
+    );
+  RandomSN->Magic = RANDOM_MAGIC;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GenerateUsbSN (
+  OUT CHAR16                  *UnicodeSN
+  )
+{
+  EFI_STATUS               Status;
+  UINT64                   Tmp;
+  UINT32                   Seed;
+  RANDOM_SERIAL_NUMBER     RandomSN;
+
+  if (UnicodeSN == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  ZeroMem (&RandomSN, sizeof (RANDOM_SERIAL_NUMBER));
+  Seed = ArmGenericTimerGetSystemCount ();
+  Status = GenerateRandomData (Seed, &Tmp);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  RandomSN.Data = (Tmp << 32) | Seed;
+  UnicodeSPrint (
+    RandomSN.UnicodeSN,
+    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
+    L"%lx",
+    RandomSN.Data
+    );
+  StrCpyS (UnicodeSN, SERIAL_NUMBER_SIZE * sizeof (CHAR16), RandomSN.UnicodeSN);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AssignUsbSN (
+  IN  CHAR8                   *AsciiCmd,
+  OUT CHAR16                  *UnicodeSN
+  )
+{
+  CHAR8                       Data;
+  UINTN                       Index;
+  RANDOM_SERIAL_NUMBER        RandomSN;
+
+  if ((AsciiCmd == NULL) || (UnicodeSN == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  for (Index = 0; Index < SERIAL_NUMBER_LEN; Index++) {
+    Data = *(AsciiCmd + Index);
+    if (((Data >= '0') && (Data <= '9')) ||
+        ((Data >= 'A') && (Data <= 'F'))) {
+      continue;
+    }
+    //
+    // Always use with upper case
+    //
+    if ((Data >= 'a') && (Data <= 'f')) {
+      *(AsciiCmd + Index) = Data - 'a' + 'A';
+      continue;
+    }
+    if (Data == '\0') {
+      break;
+    }
+    return EFI_INVALID_PARAMETER;
+  }
+  ZeroMem (&RandomSN, sizeof (RANDOM_SERIAL_NUMBER));
+  AsciiStrToUnicodeStr (AsciiCmd, RandomSN.UnicodeSN);
+  StrCpyS (UnicodeSN, SERIAL_NUMBER_SIZE * sizeof (CHAR16), RandomSN.UnicodeSN);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LoadSNFromBlock (
+  IN  EFI_HANDLE              FlashHandle,
+  IN  EFI_LBA                 Lba,
+  OUT CHAR16                  *UnicodeSN
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_BLOCK_IO_PROTOCOL       *BlockIoProtocol;
+  VOID                        *DataPtr;
+  BOOLEAN                     Found = FALSE;
+  UINT32                      Seed;
+  RANDOM_SERIAL_NUMBER        *RandomSN;
+  UINTN                       NumPages;
+  CHAR16                      UnicodeStr[SERIAL_NUMBER_SIZE];
+
+  if (UnicodeSN == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Status = gBS->OpenProtocol (
+                  FlashHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &BlockIoProtocol,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_WARN,
+      "Warning: Couldn't open block device (status: %r)\n",
+      Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  NumPages = EFI_SIZE_TO_PAGES (BlockIoProtocol->Media->BlockSize);
+  DataPtr = AllocatePages (NumPages);
+  if (DataPtr == NULL) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+  Status = BlockIoProtocol->ReadBlocks (
+                              BlockIoProtocol,
+                              BlockIoProtocol->Media->MediaId,
+                              Lba,
+                              BlockIoProtocol->Media->BlockSize,
+                              DataPtr
+                              );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "Warning: Failed on reading blocks\n"));
+    goto Exit;
+  }
+
+  Seed = ArmGenericTimerGetSystemCount ();
+  RandomSN = (RANDOM_SERIAL_NUMBER *)DataPtr;
+  if (RandomSN->Magic == RANDOM_MAGIC) {
+    Found = TRUE;
+    //
+    // Verify the unicode string.
+    //
+    ZeroMem (UnicodeStr, SERIAL_NUMBER_SIZE * sizeof (CHAR16));
+    UnicodeSPrint (
+      UnicodeStr,
+      SERIAL_NUMBER_SIZE * sizeof (CHAR16),
+      L"%lx",
+      RandomSN->Data
+      );
+    if (StrLen (RandomSN->UnicodeSN) != StrLen (UnicodeStr)) {
+      Found = FALSE;
+    }
+    if (StrnCmp (RandomSN->UnicodeSN, UnicodeStr, StrLen (UnicodeStr)) != 0) {
+      Found = FALSE;
+    }
+  }
+  if (Found == FALSE) {
+    Status = GenerateUsbSNBySeed (Seed, RandomSN);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_WARN, "Warning: Failed to generate serial number\n"));
+      goto Exit;
+    }
+    //
+    // Update SN to block device
+    //
+    Status = BlockIoProtocol->WriteBlocks (
+                                BlockIoProtocol,
+                                BlockIoProtocol->Media->MediaId,
+                                Lba,
+                                BlockIoProtocol->Media->BlockSize,
+                                DataPtr
+                                );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_WARN, "Warning: Failed on writing blocks\n"));
+      goto Exit;
+    }
+  }
+  CopyMem (
+    UnicodeSN,
+    RandomSN->UnicodeSN,
+    SERIAL_NUMBER_SIZE * sizeof (CHAR16)
+    );
+Exit:
+  FreePages (DataPtr, NumPages);
+  return Status;
+}
+
+EFI_STATUS
+StoreSNToBlock (
+  IN EFI_HANDLE               FlashHandle,
+  IN EFI_LBA                  Lba,
+  IN CHAR16                   *UnicodeSN
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_BLOCK_IO_PROTOCOL       *BlockIoProtocol;
+  VOID                        *DataPtr;
+  UINTN                       NumPages;
+  RANDOM_SERIAL_NUMBER        *RandomSN;
+  CHAR16                      UnicodeStr[SERIAL_NUMBER_SIZE];
+
+  if (UnicodeSN == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Status = gBS->OpenProtocol (
+                  FlashHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &BlockIoProtocol,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_WARN,
+      "Warning: Couldn't open block device (status: %r)\n",
+      Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+  NumPages = EFI_SIZE_TO_PAGES (BlockIoProtocol->Media->BlockSize);
+  DataPtr = AllocatePages (NumPages);
+  if (DataPtr == NULL) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+  ZeroMem (DataPtr, BlockIoProtocol->Media->BlockSize);
+  RandomSN = (RANDOM_SERIAL_NUMBER *)DataPtr;
+  RandomSN->Magic = RANDOM_MAGIC;
+  StrnCpyS (
+    RandomSN->UnicodeSN,
+    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
+    UnicodeSN,
+    StrSize (UnicodeSN)
+    );
+  RandomSN->Data = StrHexToUint64 (RandomSN->UnicodeSN);
+
+  //
+  // Verify the unicode string.
+  //
+  ZeroMem (UnicodeStr, SERIAL_NUMBER_SIZE * sizeof (CHAR16));
+  UnicodeSPrint (
+    UnicodeStr,
+    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
+    L"%lx",
+    RandomSN->Data
+    );
+  if (StrLen (RandomSN->UnicodeSN) != StrLen (UnicodeStr)) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+  if (StrnCmp (RandomSN->UnicodeSN, UnicodeStr, StrLen (UnicodeStr)) != 0) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Exit;
+  }
+
+  Status = BlockIoProtocol->WriteBlocks (
+                              BlockIoProtocol,
+                              BlockIoProtocol->Media->MediaId,
+                              Lba,
+                              BlockIoProtocol->Media->BlockSize,
+                              DataPtr
+                              );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "Warning: Failed on writing blocks\n"));
+    goto Exit;
+  }
+Exit:
+  FreePages (DataPtr, NumPages);
+  return Status;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH edk-platforms v1 2/4] Platform/HiKey960: add platform usb driver
  2018-08-20 10:31 [PATCH edk-platforms v1 0/4] enable USB on HiKey960 Haojian Zhuang
  2018-08-20 10:31 ` [PATCH edk-platforms v1 1/4] Platform/Hisilicon: add UsbSerialNumberLib Haojian Zhuang
@ 2018-08-20 10:31 ` Haojian Zhuang
  2018-08-20 10:31 ` [PATCH edk-platforms v1 3/4] Platform/HiKey960: add fastboot platform driver Haojian Zhuang
  2018-08-20 10:31 ` [PATCH edk-platforms v1 4/4] Platform/HiKey960: enable usb device driver Haojian Zhuang
  3 siblings, 0 replies; 6+ messages in thread
From: Haojian Zhuang @ 2018-08-20 10:31 UTC (permalink / raw)
  To: edk2-devel

Register the callbacks of Designware USB 3.0 driver on HiKey960
platform.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf |  52 +++
 Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c   | 382 ++++++++++++++++++++
 2 files changed, 434 insertions(+)

diff --git a/Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf b/Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
new file mode 100644
index 000000000000..121a76da57a2
--- /dev/null
+++ b/Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
@@ -0,0 +1,52 @@
+#/** @file
+#
+#  Copyright (c) 2018, Linaro. All rights reserved.
+#
+#  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                    = 0x00010019
+  BASE_NAME                      = HiKey960UsbDxe
+  FILE_GUID                      = 9998be97-6fb6-40f6-a98d-d797dc7b9d32
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = HiKey960UsbEntryPoint
+
+[Sources.common]
+  HiKey960UsbDxe.c
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  TimerLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UsbSerialNumberLib
+
+[Protocols]
+  gDwUsbProtocolGuid
+  gEfiBlockIoProtocolGuid
+  gEfiDriverBindingProtocolGuid
+
+[Packages]
+  EmbeddedPkg/Drivers/DwUsb3Dxe/DwUsb3Dxe.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/Hisilicon/HiKey960/HiKey960.dec
+  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
+  Silicon/Hisilicon/Hi3660/Hi3660.dec
+
+[Pcd]
+  gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+
+[Depex]
+  TRUE
diff --git a/Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c b/Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c
new file mode 100644
index 000000000000..d8b7997b7382
--- /dev/null
+++ b/Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.c
@@ -0,0 +1,382 @@
+/** @file
+*
+*  Copyright (c) 2018, Linaro. All rights reserved.
+*
+*  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.
+*
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UsbSerialNumberLib.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/DwUsb.h>
+
+#include <Hi3660.h>
+
+#define USB_EYE_PARAM                  0x01c466e3
+#define USB_PHY_TX_VBOOST_LVL          5
+
+#define DWC3_PHY_RX_OVRD_IN_HI         0x1006
+#define DWC3_PHY_RX_SCOPE_VDCC         0x1026
+
+#define RX_SCOPE_LFPS_EN               (1 << 0)
+
+#define TX_VBOOST_LVL_MASK             7
+#define TX_VBOOST_LVL(x)               ((x) & TX_VBOOST_LVL_MASK)
+
+#define SERIAL_NUMBER_LBA              20
+
+STATIC EFI_HANDLE mFlashHandle;
+
+UINTN
+HiKey960GetUsbMode (
+  IN VOID
+  )
+{
+  return USB_DEVICE_MODE;
+}
+
+VOID
+HiKey960UsbPhyCrWaitAck (
+  VOID
+  )
+{
+  INT32                Timeout = 1000;
+  UINT32               Data;
+
+  while (TRUE) {
+    Data = MmioRead32 (USB3OTG_PHY_CR_STS);
+    if ((Data & USB3OTG_PHY_CR_ACK) == USB3OTG_PHY_CR_ACK) {
+      return;
+    }
+    MicroSecondDelay (50);
+    if (Timeout-- <= 0) {
+      DEBUG ((DEBUG_ERROR, "Wait PHY_CR_ACK timeout!\n"));
+      return;
+    }
+  }
+}
+
+VOID
+HiKey960UsbPhyCrSetAddr (
+  IN UINT32            Addr
+  )
+{
+  //
+  // set addr
+  //
+  MmioWrite32 (
+    USB3OTG_PHY_CR_CTRL,
+    USB3OTG_PHY_CR_DATA_IN (Addr)
+    );
+  MicroSecondDelay (100);
+  //
+  // cap addr
+  //
+  MmioOr32 (USB3OTG_PHY_CR_CTRL, USB3OTG_PHY_CR_CAP_ADDR);
+  HiKey960UsbPhyCrWaitAck ();
+  MmioWrite32 (USB3OTG_PHY_CR_CTRL, 0);
+}
+
+UINT16
+HiKey960UsbPhyCrRead (
+  IN UINT32            Addr
+  )
+{
+  INT32                Timeout = 1000;
+  UINT32               Data;
+
+  HiKey960UsbPhyCrSetAddr (Addr);
+  MmioWrite32 (USB3OTG_PHY_CR_CTRL, USB3OTG_PHY_CR_READ);
+  MicroSecondDelay (100);
+
+  while (TRUE) {
+    Data = MmioRead32 (USB3OTG_PHY_CR_STS);
+    if ((Data & USB3OTG_PHY_CR_ACK) == USB3OTG_PHY_CR_ACK) {
+      DEBUG ((
+        DEBUG_INFO,
+        "Addr 0x%x, Data Out:0x%x\n",
+        Addr,
+        USB3OTG_PHY_CR_DATA_OUT(Data)
+        ));
+      break;
+    }
+    MicroSecondDelay (50);
+    if (Timeout-- <= 0) {
+      DEBUG ((DEBUG_ERROR, "Wait PHY_CR_ACK timeout!\n"));
+      break;
+    }
+  }
+  MmioWrite32 (USB3OTG_PHY_CR_CTRL, 0);
+  return (UINT16)USB3OTG_PHY_CR_DATA_OUT(Data);
+}
+
+VOID
+HiKey960UsbPhyCrWrite (
+  IN UINT32            Addr,
+  IN UINT32            Value
+  )
+{
+  UINT32               Data;
+
+  HiKey960UsbPhyCrSetAddr (Addr);
+  Data = USB3OTG_PHY_CR_DATA_IN(Value);
+  MmioWrite32 (USB3OTG_PHY_CR_CTRL, Data);
+
+  Data = MmioRead32 (USB3OTG_PHY_CR_CTRL);
+  Data |= USB3OTG_PHY_CR_CAP_DATA;
+  MmioWrite32 (USB3OTG_PHY_CR_CTRL, Data);
+  HiKey960UsbPhyCrWaitAck ();
+
+  MmioWrite32 (USB3OTG_PHY_CR_CTRL, 0);
+  MmioWrite32 (USB3OTG_PHY_CR_CTRL, USB3OTG_PHY_CR_WRITE);
+  HiKey960UsbPhyCrWaitAck ();
+}
+
+VOID
+HiKey960UsbSetEyeDiagramParam (
+  VOID
+  )
+{
+  UINT32               Data;
+
+  /* set eye diagram for usb 2.0 */
+  MmioWrite32 (USB3OTG_CTRL4, USB_EYE_PARAM);
+  /* set eye diagram for usb 3.0 */
+  HiKey960UsbPhyCrRead (DWC3_PHY_RX_OVRD_IN_HI);
+  HiKey960UsbPhyCrWrite (DWC3_PHY_RX_OVRD_IN_HI, BIT11 | BIT9 | BIT8 |BIT7);
+  HiKey960UsbPhyCrRead (DWC3_PHY_RX_OVRD_IN_HI);
+
+  /* enable RX_SCOPE_LFPS_EN for usb 3.0 */
+  Data = HiKey960UsbPhyCrRead (DWC3_PHY_RX_SCOPE_VDCC);
+  Data |= RX_SCOPE_LFPS_EN;
+  HiKey960UsbPhyCrWrite (DWC3_PHY_RX_SCOPE_VDCC, Data);
+  HiKey960UsbPhyCrRead (DWC3_PHY_RX_SCOPE_VDCC);
+
+  Data = MmioRead32 (USB3OTG_CTRL6);
+  Data &= ~TX_VBOOST_LVL_MASK;
+  Data = TX_VBOOST_LVL (USB_PHY_TX_VBOOST_LVL);
+  MmioWrite32 (USB3OTG_CTRL6, Data);
+  DEBUG ((
+    DEBUG_INFO,
+    "set ss phy tx vboost lvl 0x%x\n",
+    MmioRead32 (USB3OTG_CTRL6)
+    ));
+}
+
+STATIC
+VOID
+HiKey960UsbReset (
+  VOID
+  )
+{
+  MmioWrite32 (CRG_PERRSTEN4, PERRSTEN4_USB3OTG);
+  MmioWrite32 (CRG_PERRSTEN4, PERRSTEN4_USB3OTGPHY_POR);
+  MmioWrite32 (
+    CRG_PERRSTEN4,
+    PERRSTEN4_USB3OTG_MUX | PERRSTEN4_USB3OTG_AHBIF | PERRSTEN4_USB3OTG_32K
+    );
+  MmioWrite32 (
+    CRG_PERDIS4,
+    PEREN4_GT_ACLK_USB3OTG | PEREN4_GT_CLK_USB3OTG_REF
+    );
+
+  MmioAnd32 (PCTRL_CTRL24, ~PCTRL_CTRL24_USB3PHY_3MUX1_SEL);
+  //
+  // disable
+  //
+  MmioWrite32 (PCTRL_CTRL3, (PCTRL_CTRL3_USB_TXCO_EN << 16) | 0);
+  MicroSecondDelay (10000);
+}
+
+STATIC
+VOID
+HiKey960UsbRelease (
+  VOID
+  )
+{
+  /* enable USB REFCLK ISO */
+  MmioWrite32 (CRG_ISODIS, PERISOEN_USB_REFCLK_ISO_EN);
+  /* enable USB_TXCO_EN */
+  MmioWrite32 (PCTRL_CTRL3, (PCTRL_CTRL3_USB_TXCO_EN << 16) | PCTRL_CTRL3_USB_TXCO_EN);
+
+  MmioAnd32 (PCTRL_CTRL24, ~PCTRL_CTRL24_USB3PHY_3MUX1_SEL);
+
+  MmioWrite32 (
+    CRG_PEREN4,
+    PEREN4_GT_ACLK_USB3OTG | PEREN4_GT_CLK_USB3OTG_REF
+    );
+  MmioWrite32 (
+    CRG_PERRSTDIS4,
+    PERRSTEN4_USB3OTG_MUX | PERRSTEN4_USB3OTG_AHBIF | PERRSTEN4_USB3OTG_32K
+    );
+
+  MmioWrite32 (CRG_PERRSTEN4, PERRSTEN4_USB3OTG | PERRSTEN4_USB3OTGPHY_POR);
+
+  /* enable PHY REF CLK */
+  MmioOr32 (USB3OTG_CTRL0, USB3OTG_CTRL0_SC_USB3PHY_ABB_GT_EN);
+
+  MmioOr32 (USB3OTG_CTRL7, USB3OTG_CTRL7_REF_SSP_EN);
+
+  /* exit from IDDQ mode */
+  MmioAnd32 (
+    USB3OTG_CTRL2,
+    ~(USB3OTG_CTRL2_TEST_POWERDOWN_SSP | USB3OTG_CTRL2_TEST_POWERDOWN_HSP)
+    );
+  MicroSecondDelay (100000);
+
+  MmioWrite32 (CRG_PERRSTDIS4, PERRSTEN4_USB3OTGPHY_POR);
+  MmioWrite32 (CRG_PERRSTDIS4, PERRSTEN4_USB3OTG);
+  MicroSecondDelay (10000);
+  MmioOr32 (USB3OTG_CTRL3, USB3OTG_CTRL3_VBUSVLDEXT | USB3OTG_CTRL3_VBUSVLDEXTSEL);
+  MicroSecondDelay (100000);
+
+  HiKey960UsbSetEyeDiagramParam ();
+}
+
+EFI_STATUS
+HiKey960UsbPhyInit (
+  IN UINT8        Mode
+  )
+{
+  HiKey960UsbReset ();
+  MicroSecondDelay (10000);
+  HiKey960UsbRelease ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetLang (
+  OUT CHAR16            *Lang,
+  OUT UINT8             *Length
+  )
+{
+  if ((Lang == NULL) || (Length == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Lang[0] = 0x409;
+  *Length = sizeof (CHAR16);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetManuFacturer (
+  OUT CHAR16            *ManuFacturer,
+  OUT UINT8             *Length
+  )
+{
+  UINTN                  VariableSize;
+  CHAR16                 DataUnicode[MANU_FACTURER_STRING_LENGTH];
+
+  if ((ManuFacturer == NULL) || (Length == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  VariableSize = MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16);
+  ZeroMem (DataUnicode, MANU_FACTURER_STRING_LENGTH * sizeof(CHAR16));
+  StrCpy (DataUnicode, L"96Boards");
+  CopyMem (ManuFacturer, DataUnicode, VariableSize);
+  *Length = VariableSize;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetProduct (
+  OUT CHAR16            *Product,
+  OUT UINT8             *Length
+  )
+{
+  UINTN                  VariableSize;
+  CHAR16                 DataUnicode[PRODUCT_STRING_LENGTH];
+
+  if ((Product == NULL) || (Length == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  VariableSize = PRODUCT_STRING_LENGTH * sizeof (CHAR16);
+  ZeroMem (DataUnicode, PRODUCT_STRING_LENGTH * sizeof(CHAR16));
+  StrCpy (DataUnicode, L"HiKey960");
+  CopyMem (Product, DataUnicode, VariableSize);
+  *Length = VariableSize;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbGetSerialNo (
+  OUT CHAR16            *SerialNo,
+  OUT UINT8             *Length
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
+
+  if (mFlashHandle == 0) {
+    FlashDevicePath = ConvertTextToDevicePath (
+                        (CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath)
+                        );
+    Status = gBS->LocateDevicePath (
+                    &gEfiBlockIoProtocolGuid,
+                    &FlashDevicePath,
+                    &mFlashHandle
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "Warning: Couldn't locate Android NVM device (status: %r)\n",
+        Status
+        ));
+      //
+      // Failing to locate partitions should not prevent to do other
+      // Android FastBoot actions
+      //
+      return EFI_SUCCESS;
+    }
+  }
+
+  if ((SerialNo == NULL) || (Length == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  Status = LoadSNFromBlock (mFlashHandle, SERIAL_NUMBER_LBA, SerialNo);
+  *Length = StrSize (SerialNo);
+  return Status;
+}
+
+DW_USB_PROTOCOL mDwUsbDevice = {
+  HiKey960UsbGetLang,
+  HiKey960UsbGetManuFacturer,
+  HiKey960UsbGetProduct,
+  HiKey960UsbGetSerialNo,
+  HiKey960UsbPhyInit
+};
+
+EFI_STATUS
+EFIAPI
+HiKey960UsbEntryPoint (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  return gBS->InstallProtocolInterface (
+                &ImageHandle,
+                &gDwUsbProtocolGuid,
+                EFI_NATIVE_INTERFACE,
+                &mDwUsbDevice
+                );
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH edk-platforms v1 3/4] Platform/HiKey960: add fastboot platform driver
  2018-08-20 10:31 [PATCH edk-platforms v1 0/4] enable USB on HiKey960 Haojian Zhuang
  2018-08-20 10:31 ` [PATCH edk-platforms v1 1/4] Platform/Hisilicon: add UsbSerialNumberLib Haojian Zhuang
  2018-08-20 10:31 ` [PATCH edk-platforms v1 2/4] Platform/HiKey960: add platform usb driver Haojian Zhuang
@ 2018-08-20 10:31 ` Haojian Zhuang
  2018-08-20 10:31 ` [PATCH edk-platforms v1 4/4] Platform/HiKey960: enable usb device driver Haojian Zhuang
  3 siblings, 0 replies; 6+ messages in thread
From: Haojian Zhuang @ 2018-08-20 10:31 UTC (permalink / raw)
  To: edk2-devel

Implement the Android Fastboot protocol in HiKey960 platform.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf |  63 ++
 Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c   | 758 ++++++++++++++++++++
 2 files changed, 821 insertions(+)

diff --git a/Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf b/Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
new file mode 100644
index 000000000000..1771d41828d4
--- /dev/null
+++ b/Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
@@ -0,0 +1,63 @@
+#/** @file
+#
+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2018, Linaro. All rights reserved.
+#
+#  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                    = 0x00010019
+  BASE_NAME                      = HiKey960FastbootDxe
+  FILE_GUID                      = 80f046c6-d5ba-4916-a656-2e2b28d32304
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = HiKey960FastbootPlatformEntryPoint
+
+[Sources.common]
+  HiKey960FastbootDxe.c
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CacheMaintenanceLib
+  DebugLib
+  DevicePathLib
+  IoLib
+  MemoryAllocationLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  UsbSerialNumberLib
+  TimerLib
+
+[Protocols]
+  gAndroidFastbootPlatformProtocolGuid
+  gEfiBlockIoProtocolGuid
+  gEfiDevicePathToTextProtocolGuid
+  gEfiDiskIoProtocolGuid
+  gEfiEraseBlockProtocolGuid
+  gEfiSimpleTextOutProtocolGuid
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/Hisilicon/HiKey960/HiKey960.dec
+  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor
+  gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+  gHiKey960TokenSpaceGuid.PcdArmFastbootFlashLimit
+  gHiKey960TokenSpaceGuid.PcdXloaderDevicePath
diff --git a/Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c b/Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c
new file mode 100644
index 000000000000..5e99a9f93ca4
--- /dev/null
+++ b/Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.c
@@ -0,0 +1,758 @@
+/** @file
+
+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2018, Linaro. All rights reserved.
+
+  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 Android Fastboot Platform protocol, to be used by the
+  Fastboot UEFI application, for Hisilicon HiKey960 platform.
+*/
+
+#include <Protocol/AndroidFastbootPlatform.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/EraseBlock.h>
+#include <Protocol/SimpleTextOut.h>
+
+#include <Protocol/DevicePathToText.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UsbSerialNumberLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
+
+#define PARTITION_NAME_MAX_LENGTH        (72/2)
+
+#define SERIAL_NUMBER_LBA                20
+
+#define RANDOM_MAX                       0x7FFFFFFFFFFFFFFF
+#define RANDOM_MAGIC                     0x9A4DBEAF
+
+#define ADB_REBOOT_ADDRESS               0x32100000
+#define ADB_REBOOT_BOOTLOADER            0x77665500
+
+#define UFS_BLOCK_SIZE                   4096
+
+typedef struct _FASTBOOT_PARTITION_LIST {
+  LIST_ENTRY  Link;
+  CHAR16      PartitionName[PARTITION_NAME_MAX_LENGTH];
+  EFI_LBA     StartingLBA;
+  EFI_LBA     EndingLBA;
+} FASTBOOT_PARTITION_LIST;
+
+STATIC LIST_ENTRY                       mPartitionListHead;
+STATIC EFI_HANDLE                       mFlashHandle;
+STATIC EFI_BLOCK_IO_PROTOCOL           *mFlashBlockIo;
+STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut;
+
+/*
+  Helper to free the partition list
+*/
+STATIC
+VOID
+FreePartitionList (
+  VOID
+  )
+{
+  FASTBOOT_PARTITION_LIST *Entry;
+  FASTBOOT_PARTITION_LIST *NextEntry;
+
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (
+                                              &mPartitionListHead,
+                                              &Entry->Link
+                                              );
+    RemoveEntryList (&Entry->Link);
+    FreePool (Entry);
+
+    Entry = NextEntry;
+  }
+}
+
+/*
+  Read the PartitionName fields from the GPT partition entries, putting them
+  into an allocated array that should later be freed.
+*/
+STATIC
+EFI_STATUS
+ReadPartitionEntries (
+  IN  EFI_BLOCK_IO_PROTOCOL *BlockIo,
+  OUT EFI_PARTITION_ENTRY  **PartitionEntries,
+  OUT UINTN                 *PartitionNumbers
+  )
+{
+  UINT32                      MediaId;
+  EFI_PARTITION_TABLE_HEADER *GptHeader;
+  EFI_PARTITION_ENTRY        *Entry;
+  EFI_STATUS                  Status;
+  VOID                       *Buffer;
+  UINTN                       PageCount;
+  UINTN                       BlockSize;
+  UINTN                       Count, EndLBA;
+
+  if ((PartitionEntries == NULL) || (PartitionNumbers == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  MediaId = BlockIo->Media->MediaId;
+  BlockSize = BlockIo->Media->BlockSize;
+
+  //
+  // Read size of Partition entry and number of entries from GPT header
+  //
+
+  PageCount = EFI_SIZE_TO_PAGES (6 * BlockSize);
+  Buffer = AllocatePages (PageCount);
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = BlockIo->ReadBlocks (
+                      BlockIo,
+                      MediaId,
+                      0,
+                      PageCount * EFI_PAGE_SIZE,
+                      Buffer
+                      );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  GptHeader = (EFI_PARTITION_TABLE_HEADER *)(Buffer + BlockSize);
+
+  //
+  // Check there is a GPT on the media
+  //
+  if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID ||
+      GptHeader->MyLBA != 1) {
+    DEBUG ((DEBUG_ERROR,
+      "Fastboot platform: No GPT on flash. "
+      "Fastboot on Versatile Express does not support MBR.\n"
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  Entry = (EFI_PARTITION_ENTRY *)(Buffer + (2 * BlockSize));
+  EndLBA = GptHeader->FirstUsableLBA - 1;
+  Count = 0;
+  while (1) {
+    if ((Entry->StartingLBA > EndLBA) &&
+        (Entry->EndingLBA <= GptHeader->LastUsableLBA)) {
+      Count++;
+      EndLBA = Entry->EndingLBA;
+      Entry++;
+    } else {
+      break;
+    }
+  }
+  if (Count == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (Count > GptHeader->NumberOfPartitionEntries) {
+    Count = GptHeader->NumberOfPartitionEntries;
+  }
+
+  *PartitionEntries = (EFI_PARTITION_ENTRY *)((UINTN)Buffer + (2 * BlockSize));
+  *PartitionNumbers = Count;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LoadPtable (
+  VOID
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePathDup;
+  UINTN                               PartitionNumbers = 0;
+  UINTN                               LoopIndex;
+  EFI_PARTITION_ENTRY                *PartitionEntries = NULL;
+  FASTBOOT_PARTITION_LIST            *Entry;
+
+  InitializeListHead (&mPartitionListHead);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSimpleTextOutProtocolGuid,
+                  NULL,
+                  (VOID **) &mTextOut
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "Fastboot platform: Couldn't open Text Output Protocol: %r\n", Status
+      ));
+    return Status;
+  }
+
+  //
+  // Get EFI_HANDLES for all the partitions on the block devices pointed to by
+  // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
+  // There's no way to find all of a device's children, so we get every handle
+  // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
+  // that don't represent partitions on the flash device.
+  //
+  FlashDevicePath = ConvertTextToDevicePath (
+                      (CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath)
+                      );
+
+  //
+  // Create another device path pointer because LocateDevicePath will modify it.
+  //
+  FlashDevicePathDup = FlashDevicePath;
+  Status = gBS->LocateDevicePath (
+                  &gEfiBlockIoProtocolGuid,
+                  &FlashDevicePathDup,
+                  &mFlashHandle
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Warning: Couldn't locate Android NVM device (status: %r)\n",
+      Status
+      ));
+    //
+    // Failing to locate partitions should not prevent to do other Android
+    // FastBoot actions.
+    //
+    return EFI_SUCCESS;
+  }
+
+
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &mFlashBlockIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Fastboot platform: Couldn't open Android NVM device (status: %r)\n",
+      Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Read the GPT partition entry array into memory so we can get the
+  // partition names.
+  //
+  Status = ReadPartitionEntries (
+             mFlashBlockIo,
+             &PartitionEntries,
+             &PartitionNumbers
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Warning: Failed to read partitions from Android NVM device (status: %r)\n",
+      Status
+      ));
+    //
+    // Failing to locate partitions should not prevent to do other Android
+    // FastBoot actions.
+    //
+    return EFI_SUCCESS;
+  }
+  for (LoopIndex = 0; LoopIndex < PartitionNumbers; LoopIndex++) {
+    //
+    // Create entry
+    //
+    Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
+    if (Entry == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      FreePartitionList ();
+      goto Exit;
+    }
+    StrnCpy (
+      Entry->PartitionName,
+      PartitionEntries[LoopIndex].PartitionName,
+      PARTITION_NAME_MAX_LENGTH
+      );
+    Entry->StartingLBA = PartitionEntries[LoopIndex].StartingLBA;
+    Entry->EndingLBA = PartitionEntries[LoopIndex].EndingLBA;
+    InsertTailList (&mPartitionListHead, &Entry->Link);
+  }
+Exit:
+  FreePages (
+    (VOID *)((UINTN)PartitionEntries - (2 * mFlashBlockIo->Media->BlockSize)),
+    EFI_SIZE_TO_PAGES (6 * mFlashBlockIo->Media->BlockSize)
+    );
+  return Status;
+}
+
+/*
+  Initialise: Open the Android NVM device and find the partitions on it. Save
+  them in a list along with the "PartitionName" fields for their GPT entries.
+  We will use these partition names as the key in
+  HiKey960FastbootPlatformFlashPartition.
+*/
+EFI_STATUS
+HiKey960FastbootPlatformInit (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+
+  Status = LoadPtable ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  return Status;
+}
+
+VOID
+HiKey960FastbootPlatformUnInit (
+  VOID
+  )
+{
+  FreePartitionList ();
+}
+
+EFI_STATUS
+HiKey960FlashPtable (
+  IN UINTN   Size,
+  IN VOID   *Image
+  )
+{
+  EFI_STATUS               Status;
+  Status = mFlashBlockIo->WriteBlocks (
+                            mFlashBlockIo,
+                            mFlashBlockIo->Media->MediaId,
+                            0,
+                            Size,
+                            Image
+                            );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status));
+    return Status;
+  }
+  FreePartitionList ();
+  Status = LoadPtable ();
+  return Status;
+}
+
+EFI_STATUS
+HiKey960ErasePtable (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+
+  {
+    VOID         *DataPtr;
+    UINTN         Lba;
+
+    DataPtr = AllocatePages (1);
+    ZeroMem (DataPtr, EFI_PAGE_SIZE);
+    for (Lba = 0; Lba < 6; Lba++) {
+      Status = mFlashBlockIo->WriteBlocks (
+                          mFlashBlockIo,
+                          mFlashBlockIo->Media->MediaId,
+                          Lba,
+                          EFI_PAGE_SIZE,
+                          DataPtr
+                          );
+      if (EFI_ERROR (Status)) {
+        goto Exit;
+      }
+    }
+Exit:
+    FreePages (DataPtr, 1);
+  }
+  FreePartitionList ();
+  return Status;
+}
+
+EFI_STATUS
+HiKey960FlashXloader (
+  IN UINTN   Size,
+  IN VOID   *Image
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_DEVICE_PATH_PROTOCOL         *DevicePath;
+  EFI_HANDLE                        Handle;
+  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
+  EFI_DISK_IO_PROTOCOL             *DiskIo;
+
+  DevicePath = ConvertTextToDevicePath (
+                 (CHAR16*)FixedPcdGetPtr (PcdXloaderDevicePath)
+                 );
+
+  Status = gBS->LocateDevicePath (
+                  &gEfiBlockIoProtocolGuid,
+                  &DevicePath,
+                  &Handle
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Warning: Couldn't locate xloader device (status: %r)\n",
+      Status
+      ));
+    return Status;
+  }
+
+  Status = gBS->OpenProtocol (
+                  Handle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &BlockIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Fastboot platform: Couldn't open xloader device (status: %r)\n",
+      Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+  Status = gBS->OpenProtocol (
+                  Handle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **) &DiskIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = DiskIo->WriteDisk (
+                     DiskIo,
+                     BlockIo->Media->MediaId,
+                     0,
+                     Size,
+                     Image
+                     );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status));
+    return Status;
+  }
+  return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformFlashPartition (
+  IN CHAR8  *PartitionName,
+  IN UINTN   Size,
+  IN VOID   *Image
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    PartitionSize;
+  FASTBOOT_PARTITION_LIST *Entry;
+  CHAR16                   PartitionNameUnicode[60];
+  BOOLEAN                  PartitionFound;
+  EFI_DISK_IO_PROTOCOL    *DiskIo;
+  UINTN                    BlockSize;
+
+  //
+  // Support the pseudo partition name, such as "ptable".
+  //
+  if (AsciiStrCmp (PartitionName, "ptable") == 0) {
+    return HiKey960FlashPtable (Size, Image);
+  } else if (AsciiStrCmp (PartitionName, "xloader") == 0) {
+    return HiKey960FlashXloader (Size, Image);
+  }
+
+  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+  PartitionFound = FALSE;
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    //
+    // Search the partition list for the partition named by PartitionName
+    //
+    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+      PartitionFound = TRUE;
+      break;
+    }
+
+   Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (
+                                         &mPartitionListHead,
+                                         &(Entry)->Link
+                                         );
+  }
+  if (!PartitionFound) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Check image will fit on device
+  //
+  BlockSize = mFlashBlockIo->Media->BlockSize;
+  PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * BlockSize;
+  if (PartitionSize < Size) {
+    DEBUG ((DEBUG_ERROR, "Partition not big enough.\n"));
+    DEBUG ((
+      DEBUG_ERROR,
+      "Partition Size:\t%ld\nImage Size:\t%ld\n",
+      PartitionSize,
+      Size
+      ));
+    return EFI_VOLUME_FULL;
+  }
+
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **) &DiskIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = DiskIo->WriteDisk (
+                     DiskIo,
+                     mFlashBlockIo->Media->MediaId,
+                     Entry->StartingLBA * BlockSize,
+                     Size,
+                     Image
+                     );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Failed to write %d bytes into 0x%x, Status:%r\n",
+      Size,
+      Entry->StartingLBA * BlockSize,
+      Status
+      ));
+    return Status;
+  }
+
+  mFlashBlockIo->FlushBlocks(mFlashBlockIo);
+  MicroSecondDelay (50000);
+
+  return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformErasePartition (
+  IN CHAR8 *PartitionName
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ERASE_BLOCK_PROTOCOL   *EraseBlockProtocol;
+  UINTN                       Size;
+  BOOLEAN                     PartitionFound;
+  CHAR16                      PartitionNameUnicode[60];
+  FASTBOOT_PARTITION_LIST    *Entry;
+
+  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+
+  //
+  // Support the pseudo partition name, such as "ptable".
+  //
+  if (AsciiStrCmp (PartitionName, "ptable") == 0) {
+    return HiKey960ErasePtable ();
+  }
+
+  PartitionFound = FALSE;
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    //
+    // Search the partition list for the partition named by PartitionName
+    //
+    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+      PartitionFound = TRUE;
+      break;
+    }
+    Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
+  }
+  if (!PartitionFound) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiEraseBlockProtocolGuid,
+                  (VOID **) &EraseBlockProtocol,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Size = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
+  Status = EraseBlockProtocol->EraseBlocks (
+                                 EraseBlockProtocol,
+                                 mFlashBlockIo->Media->MediaId,
+                                 Entry->StartingLBA,
+                                 NULL,
+                                 Size
+                                 );
+  return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformGetVar (
+  IN  CHAR8   *Name,
+  OUT CHAR8   *Value
+  )
+{
+  EFI_STATUS               Status = EFI_SUCCESS;
+  UINT64                   PartitionSize;
+  FASTBOOT_PARTITION_LIST *Entry;
+  CHAR16                   PartitionNameUnicode[60];
+  BOOLEAN                  PartitionFound;
+  CHAR16                   UnicodeSN[SERIAL_NUMBER_SIZE];
+
+  if (!AsciiStrCmp (Name, "max-download-size")) {
+    AsciiStrCpy (Value, FixedPcdGetPtr (PcdArmFastbootFlashLimit));
+  } else if (!AsciiStrCmp (Name, "product")) {
+    AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));
+  } else if (!AsciiStrCmp (Name, "serialno")) {
+    Status = LoadSNFromBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
+    UnicodeStrToAsciiStr (UnicodeSN, Value);
+  } else if ( !AsciiStrnCmp (Name, "partition-size", 14)) {
+    AsciiStrToUnicodeStr ((Name + 15), PartitionNameUnicode);
+    PartitionFound = FALSE;
+    Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+    while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+      //
+      // Search the partition list for the partition named by PartitionName
+      //
+      if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+        PartitionFound = TRUE;
+        break;
+      }
+
+     Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (
+                                           &mPartitionListHead,
+                                           &(Entry)->Link
+                                           );
+    }
+    if (!PartitionFound) {
+      *Value = '\0';
+      return EFI_NOT_FOUND;
+    }
+
+    PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) *
+                    mFlashBlockIo->Media->BlockSize;
+    DEBUG ((
+      DEBUG_ERROR,
+      "Fastboot platform: check for partition-size:%a 0X%llx\n",
+      Name,
+      PartitionSize
+      ));
+    AsciiSPrint (Value, 12, "0x%llx", PartitionSize);
+  } else if ( !AsciiStrnCmp (Name, "partition-type", 14)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "Fastboot platform: check for partition-type:%a\n",
+        (Name + 15)
+        ));
+    if ( !AsciiStrnCmp  ( (Name + 15) , "system", 6) ||        \
+         !AsciiStrnCmp  ( (Name + 15) , "userdata", 8) ||      \
+         !AsciiStrnCmp  ( (Name + 15) , "cache", 5)) {
+      AsciiStrCpy (Value, "ext4");
+    } else {
+      AsciiStrCpy (Value, "raw");
+    }
+  } else if ( !AsciiStrCmp (Name, "erase-block-size")) {
+    AsciiSPrint (Value, 12, "0x%llx", UFS_BLOCK_SIZE);
+  } else if ( !AsciiStrCmp (Name, "logical-block-size")) {
+    AsciiSPrint (Value, 12, "0x%llx", UFS_BLOCK_SIZE);
+  } else {
+    *Value = '\0';
+  }
+  return Status;
+}
+
+EFI_STATUS
+HiKey960FastbootPlatformOemCommand (
+  IN  CHAR8   *Command
+  )
+{
+  EFI_STATUS   Status;
+  CHAR16       UnicodeSN[SERIAL_NUMBER_SIZE];
+  UINTN        Size;
+
+  Size = AsciiStrLen ("serialno");
+  if (AsciiStrCmp (Command, "Demonstrate") == 0) {
+    DEBUG ((DEBUG_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));
+    return EFI_SUCCESS;
+  } else if (AsciiStrnCmp (Command, "serialno", Size) == 0) {
+    while (*(Command + Size) == ' ') {
+      Size++;
+    }
+    if (AsciiStrnCmp (Command + Size, "set", AsciiStrLen ("set")) == 0) {
+      Size += AsciiStrLen ("set");
+      while (*(Command + Size) == ' ') {
+        Size++;
+      }
+      Status = AssignUsbSN (Command + Size, UnicodeSN);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "Failed to set USB Serial Number.\n"));
+        return Status;
+      }
+    } else {
+      Status = GenerateUsbSN (UnicodeSN);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "Failed to generate USB Serial Number.\n"));
+        return Status;
+      }
+    }
+    Status = StoreSNToBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
+    return Status;
+  } else if (AsciiStrCmp (Command, "reboot-bootloader") == 0) {
+    MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_BOOTLOADER);
+    WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
+    return EFI_SUCCESS;
+  } else {
+    DEBUG ((DEBUG_ERROR,
+      "HiKey960: Unrecognised Fastboot OEM command: %a\n",
+      Command
+      ));
+    return EFI_NOT_FOUND;
+  }
+}
+
+FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = {
+  HiKey960FastbootPlatformInit,
+  HiKey960FastbootPlatformUnInit,
+  HiKey960FastbootPlatformFlashPartition,
+  HiKey960FastbootPlatformErasePartition,
+  HiKey960FastbootPlatformGetVar,
+  HiKey960FastbootPlatformOemCommand,
+};
+
+EFI_STATUS
+EFIAPI
+HiKey960FastbootPlatformEntryPoint (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  return gBS->InstallProtocolInterface (
+                &ImageHandle,
+                &gAndroidFastbootPlatformProtocolGuid,
+                EFI_NATIVE_INTERFACE,
+                &mPlatformProtocol
+                );
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH edk-platforms v1 4/4] Platform/HiKey960: enable usb device driver
  2018-08-20 10:31 [PATCH edk-platforms v1 0/4] enable USB on HiKey960 Haojian Zhuang
                   ` (2 preceding siblings ...)
  2018-08-20 10:31 ` [PATCH edk-platforms v1 3/4] Platform/HiKey960: add fastboot platform driver Haojian Zhuang
@ 2018-08-20 10:31 ` Haojian Zhuang
  3 siblings, 0 replies; 6+ messages in thread
From: Haojian Zhuang @ 2018-08-20 10:31 UTC (permalink / raw)
  To: edk2-devel

Enable Designware USB 3.0 device driver on HiKey960 platform.
Android Fastboot application is based on the USB driver.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Platform/Hisilicon/HiKey960/HiKey960.dec |  3 +++
 Platform/Hisilicon/HiKey960/HiKey960.dsc | 13 +++++++++++++
 Platform/Hisilicon/HiKey960/HiKey960.fdf |  3 +++
 3 files changed, 19 insertions(+)

diff --git a/Platform/Hisilicon/HiKey960/HiKey960.dec b/Platform/Hisilicon/HiKey960/HiKey960.dec
index aa5a0caf52e5..c925ae6c5eb5 100644
--- a/Platform/Hisilicon/HiKey960/HiKey960.dec
+++ b/Platform/Hisilicon/HiKey960/HiKey960.dec
@@ -33,3 +33,6 @@ [PcdsFixedAtBuild.common]
   gHiKey960TokenSpaceGuid.PcdAndroidBootFile|{ 0x36, 0x8b, 0x73, 0x3a, 0xc5, 0xb9, 0x63, 0x47, 0xab, 0xbd, 0x6c, 0xbd, 0x4b, 0x25, 0xf9, 0xff }|VOID*|0x00000002
   gHiKey960TokenSpaceGuid.PcdAndroidFastbootFile|{ 0x2a, 0x50, 0x88, 0x95, 0x70, 0x53, 0xe3, 0x11, 0x86, 0x31, 0xd7, 0xc5, 0x95, 0x13, 0x64, 0xc8 }|VOID*|0x00000003
   gHiKey960TokenSpaceGuid.PcdSdBootDevicePath|L""|VOID*|0x00000004
+  gHiKey960TokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L""|VOID*|0x00000005
+  gHiKey960TokenSpaceGuid.PcdArmFastbootFlashLimit|L""|VOID*|0x00000006
+  gHiKey960TokenSpaceGuid.PcdXloaderDevicePath|L""|VOID*|0x00000007
diff --git a/Platform/Hisilicon/HiKey960/HiKey960.dsc b/Platform/Hisilicon/HiKey960/HiKey960.dsc
index 1ce306da5b50..2b65254ba255 100644
--- a/Platform/Hisilicon/HiKey960/HiKey960.dsc
+++ b/Platform/Hisilicon/HiKey960/HiKey960.dsc
@@ -52,6 +52,8 @@ [LibraryClasses.common]
   # USB Requirements
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
 
+  UsbSerialNumberLib|Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf
+
   # Network Libraries
   UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
   NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
@@ -59,6 +61,8 @@ [LibraryClasses.common]
   IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
   UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
 
+  DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+
 [LibraryClasses.common.SEC]
   PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
   ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
@@ -82,6 +86,7 @@ [PcdsFeatureFlag.common]
 [PcdsFixedAtBuild.common]
   gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
 
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|"hikey960"
   gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Alpha"
 
   # System Memory (3GB)
@@ -123,6 +128,11 @@ [PcdsFixedAtBuild.common]
   gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
 
   #
+  # DW USB3 controller
+  #
+  gDwUsb3DxeTokenSpaceGuid.PcdDwUsb3DxeBaseAddress|0xFF100000
+
+  #
   #
   # Fastboot
   #
@@ -216,6 +226,9 @@ [Components.common]
   #
   # USB Peripheral Support
   #
+  Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
+  EmbeddedPkg/Drivers/DwUsb3Dxe/DwUsb3Dxe.inf
+  Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
   EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
 
   #
diff --git a/Platform/Hisilicon/HiKey960/HiKey960.fdf b/Platform/Hisilicon/HiKey960/HiKey960.fdf
index d4fe4c46b818..8addf49d1647 100644
--- a/Platform/Hisilicon/HiKey960/HiKey960.fdf
+++ b/Platform/Hisilicon/HiKey960/HiKey960.fdf
@@ -151,6 +151,9 @@ [FV.FvMain]
   #
   # USB Peripheral Support
   #
+  INF Platform/Hisilicon/HiKey960/HiKey960UsbDxe/HiKey960UsbDxe.inf
+  INF EmbeddedPkg/Drivers/DwUsb3Dxe/DwUsb3Dxe.inf
+  INF Platform/Hisilicon/HiKey960/HiKey960FastbootDxe/HiKey960FastbootDxe.inf
   INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
 
   #
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH edk-platforms v1 1/4] Platform/Hisilicon: add UsbSerialNumberLib
  2018-08-20 10:31 ` [PATCH edk-platforms v1 1/4] Platform/Hisilicon: add UsbSerialNumberLib Haojian Zhuang
@ 2018-10-04 16:48   ` Leif Lindholm
  0 siblings, 0 replies; 6+ messages in thread
From: Leif Lindholm @ 2018-10-04 16:48 UTC (permalink / raw)
  To: Haojian Zhuang; +Cc: edk2-devel, Ard Biesheuvel

Ah, here's UsbSerialNumberLib. Got it.
(Please mention dependencies on other patchsets in the cover-letter.)

Please wrap these 3 sets together into a single one, with patches in
dependency order, for v2.

I will comment on this patch aftes I'm done with DwUsb2.

/
    Leif

On Mon, Aug 20, 2018 at 06:31:46PM +0800, Haojian Zhuang wrote:
> Add UsbSerialNumberLib. The Library could generate USB Serial Number
> that is used in USB device driver. And it could load/save the USB
> Serial Number into storage device.
> 
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec               |  32 ++
>  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf               |  45 +++
>  Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h |  59 ++++
>  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c                 | 341 ++++++++++++++++++++
>  4 files changed, 477 insertions(+)
> 
> diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
> new file mode 100644
> index 000000000000..4b8b2e047ed9
> --- /dev/null
> +++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
> @@ -0,0 +1,32 @@
> +#
> +#  Copyright (c) 2018, Linaro Limited. All rights reserved.
> +#
> +#  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]
> +  DEC_SPECIFICATION              = 0x00010019
> +  PACKAGE_NAME                   = UsbSerialNumberPkg
> +  PACKAGE_GUID                   = dcd67420-4220-4b01-a8ba-1fa97fda1678
> +  PACKAGE_VERSION                = 0.1
> +
> +################################################################################
> +#
> +# Include Section - list of Include Paths that are provided by this package.
> +#                   Comments are used for Keywords and Module Types.
> +#
> +# Supported Module Types:
> +#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
> +#
> +################################################################################
> +[Includes.common]
> +  Include                        # Root include for the package
> +
> +[Guids.common]
> +  gUsbSerialNumberTokenSpaceGuid = { 0x0572f26b, 0x1a88, 0x49c2, { 0xb6, 0x98, 0x4d, 0xe0, 0xd0, 0x2a, 0xfe, 0x09 } }
> diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf
> new file mode 100644
> index 000000000000..70ea086d324e
> --- /dev/null
> +++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf
> @@ -0,0 +1,45 @@
> +#/** @file
> +#
> +#  Copyright (c) 2018, Linaro. All rights reserved.
> +#
> +#  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                    = 0x00010019
> +  BASE_NAME                      = UsbSerialNumberLib
> +  FILE_GUID                      = 88709c56-2a76-4a13-8bcf-427970b7e32a
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = UsbSerialNumberLib
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +  VALID_ARCHITECTURES           = ARM AARCH64
> +
> +[Sources]
> +  UsbSerialNumberLib.c
> +
> +[LibraryClasses]
> +  ArmGenericTimerCounterLib
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiLib
> +
> +[Protocols]
> +  gEfiBlockIoProtocolGuid
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdePkg/MdePkg.dec
> +  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
> diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h b/Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h
> new file mode 100644
> index 000000000000..d3307153ff11
> --- /dev/null
> +++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/Include/Library/UsbSerialNumberLib.h
> @@ -0,0 +1,59 @@
> +/** @file
> +
> +  Copyright (c) 2017, Linaro. All rights reserved.
> +
> +  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.
> +
> +**/
> +
> +#ifndef __USB_SERIAL_NUMBER_LIB_H__
> +#define __USB_SERIAL_NUMBER_LIB_H__
> +
> +#include <Uefi.h>
> +
> +#define SERIAL_NUMBER_SIZE                      17
> +
> +typedef struct {
> +  UINT64        Magic;
> +  UINT64        Data;
> +  CHAR16        UnicodeSN[SERIAL_NUMBER_SIZE];
> +} RANDOM_SERIAL_NUMBER;
> +
> +EFI_STATUS
> +GenerateUsbSNBySeed (
> +  IN  UINT32                  Seed,
> +  OUT RANDOM_SERIAL_NUMBER   *RandomSN
> +  );
> +
> +EFI_STATUS
> +GenerateUsbSN (
> +  OUT CHAR16                 *UnicodeSN
> +  );
> +
> +EFI_STATUS
> +AssignUsbSN (
> +  IN  CHAR8                  *AsciiCmd,
> +  OUT CHAR16                 *UnicodeSN
> +  );
> +
> +EFI_STATUS
> +LoadSNFromBlock (
> +  IN  EFI_HANDLE              FlashHandle,
> +  IN  EFI_LBA                 Lba,
> +  OUT CHAR16                 *UnicodeSN
> +  );
> +
> +EFI_STATUS
> +StoreSNToBlock (
> +  IN EFI_HANDLE               FlashHandle,
> +  IN EFI_LBA                  Lba,
> +  IN CHAR16                  *UnicodeSN
> +  );
> +
> +#endif /* __USB_SERIAL_NUMBER_LIB_H__ */
> diff --git a/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c
> new file mode 100644
> index 000000000000..98552f5f72fc
> --- /dev/null
> +++ b/Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.c
> @@ -0,0 +1,341 @@
> +/** @file
> +
> +  Copyright (c) 2018, Linaro. All rights reserved.
> +
> +  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.
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/ArmGenericTimerCounterLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UsbSerialNumberLib.h>
> +
> +#include <Protocol/BlockIo.h>
> +#include <Protocol/DevicePath.h>
> +
> +#define SERIAL_NUMBER_LEN                16
> +#define SERIAL_NUMBER_SIZE               17
> +
> +#define RANDOM_MAX                       0x7FFFFFFFFFFFFFFF
> +#define RANDOM_MAGIC                     0x9A4DBEAF
> +
> +STATIC
> +EFI_STATUS
> +GenerateRandomData (
> +  IN  UINT32              Seed,
> +  OUT UINT64              *RandomData
> +  )
> +{
> +  INT64                   Quotient, Remainder, Tmp;
> +
> +  if (RandomData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  Quotient = (INT64) Seed / 127773;
> +  Remainder = (INT64) Seed % 127773;
> +  Tmp = (16807 * Remainder) - (2836 * Quotient);
> +  if (Tmp < 0) {
> +    Tmp += RANDOM_MAX;
> +  }
> +  Tmp = Tmp % ((UINT64)RANDOM_MAX + 1);
> +  *RandomData = (UINT64)Tmp;
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GenerateUsbSNBySeed (
> +  IN  UINT32                  Seed,
> +  OUT RANDOM_SERIAL_NUMBER    *RandomSN
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT64                   Tmp;
> +
> +  if (RandomSN == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  ZeroMem (RandomSN, sizeof (RANDOM_SERIAL_NUMBER));
> +  Status = GenerateRandomData (Seed, &Tmp);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  RandomSN->Data = (Tmp << 32) | Seed;
> +  UnicodeSPrint (
> +    RandomSN->UnicodeSN,
> +    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
> +    L"%lx",
> +    RandomSN->Data
> +    );
> +  RandomSN->Magic = RANDOM_MAGIC;
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +GenerateUsbSN (
> +  OUT CHAR16                  *UnicodeSN
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT64                   Tmp;
> +  UINT32                   Seed;
> +  RANDOM_SERIAL_NUMBER     RandomSN;
> +
> +  if (UnicodeSN == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  ZeroMem (&RandomSN, sizeof (RANDOM_SERIAL_NUMBER));
> +  Seed = ArmGenericTimerGetSystemCount ();
> +  Status = GenerateRandomData (Seed, &Tmp);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  RandomSN.Data = (Tmp << 32) | Seed;
> +  UnicodeSPrint (
> +    RandomSN.UnicodeSN,
> +    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
> +    L"%lx",
> +    RandomSN.Data
> +    );
> +  StrCpyS (UnicodeSN, SERIAL_NUMBER_SIZE * sizeof (CHAR16), RandomSN.UnicodeSN);
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AssignUsbSN (
> +  IN  CHAR8                   *AsciiCmd,
> +  OUT CHAR16                  *UnicodeSN
> +  )
> +{
> +  CHAR8                       Data;
> +  UINTN                       Index;
> +  RANDOM_SERIAL_NUMBER        RandomSN;
> +
> +  if ((AsciiCmd == NULL) || (UnicodeSN == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  for (Index = 0; Index < SERIAL_NUMBER_LEN; Index++) {
> +    Data = *(AsciiCmd + Index);
> +    if (((Data >= '0') && (Data <= '9')) ||
> +        ((Data >= 'A') && (Data <= 'F'))) {
> +      continue;
> +    }
> +    //
> +    // Always use with upper case
> +    //
> +    if ((Data >= 'a') && (Data <= 'f')) {
> +      *(AsciiCmd + Index) = Data - 'a' + 'A';
> +      continue;
> +    }
> +    if (Data == '\0') {
> +      break;
> +    }
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  ZeroMem (&RandomSN, sizeof (RANDOM_SERIAL_NUMBER));
> +  AsciiStrToUnicodeStr (AsciiCmd, RandomSN.UnicodeSN);
> +  StrCpyS (UnicodeSN, SERIAL_NUMBER_SIZE * sizeof (CHAR16), RandomSN.UnicodeSN);
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +LoadSNFromBlock (
> +  IN  EFI_HANDLE              FlashHandle,
> +  IN  EFI_LBA                 Lba,
> +  OUT CHAR16                  *UnicodeSN
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_BLOCK_IO_PROTOCOL       *BlockIoProtocol;
> +  VOID                        *DataPtr;
> +  BOOLEAN                     Found = FALSE;
> +  UINT32                      Seed;
> +  RANDOM_SERIAL_NUMBER        *RandomSN;
> +  UINTN                       NumPages;
> +  CHAR16                      UnicodeStr[SERIAL_NUMBER_SIZE];
> +
> +  if (UnicodeSN == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  Status = gBS->OpenProtocol (
> +                  FlashHandle,
> +                  &gEfiBlockIoProtocolGuid,
> +                  (VOID **) &BlockIoProtocol,
> +                  gImageHandle,
> +                  NULL,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_WARN,
> +      "Warning: Couldn't open block device (status: %r)\n",
> +      Status
> +      ));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  NumPages = EFI_SIZE_TO_PAGES (BlockIoProtocol->Media->BlockSize);
> +  DataPtr = AllocatePages (NumPages);
> +  if (DataPtr == NULL) {
> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +  Status = BlockIoProtocol->ReadBlocks (
> +                              BlockIoProtocol,
> +                              BlockIoProtocol->Media->MediaId,
> +                              Lba,
> +                              BlockIoProtocol->Media->BlockSize,
> +                              DataPtr
> +                              );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_WARN, "Warning: Failed on reading blocks\n"));
> +    goto Exit;
> +  }
> +
> +  Seed = ArmGenericTimerGetSystemCount ();
> +  RandomSN = (RANDOM_SERIAL_NUMBER *)DataPtr;
> +  if (RandomSN->Magic == RANDOM_MAGIC) {
> +    Found = TRUE;
> +    //
> +    // Verify the unicode string.
> +    //
> +    ZeroMem (UnicodeStr, SERIAL_NUMBER_SIZE * sizeof (CHAR16));
> +    UnicodeSPrint (
> +      UnicodeStr,
> +      SERIAL_NUMBER_SIZE * sizeof (CHAR16),
> +      L"%lx",
> +      RandomSN->Data
> +      );
> +    if (StrLen (RandomSN->UnicodeSN) != StrLen (UnicodeStr)) {
> +      Found = FALSE;
> +    }
> +    if (StrnCmp (RandomSN->UnicodeSN, UnicodeStr, StrLen (UnicodeStr)) != 0) {
> +      Found = FALSE;
> +    }
> +  }
> +  if (Found == FALSE) {
> +    Status = GenerateUsbSNBySeed (Seed, RandomSN);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_WARN, "Warning: Failed to generate serial number\n"));
> +      goto Exit;
> +    }
> +    //
> +    // Update SN to block device
> +    //
> +    Status = BlockIoProtocol->WriteBlocks (
> +                                BlockIoProtocol,
> +                                BlockIoProtocol->Media->MediaId,
> +                                Lba,
> +                                BlockIoProtocol->Media->BlockSize,
> +                                DataPtr
> +                                );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_WARN, "Warning: Failed on writing blocks\n"));
> +      goto Exit;
> +    }
> +  }
> +  CopyMem (
> +    UnicodeSN,
> +    RandomSN->UnicodeSN,
> +    SERIAL_NUMBER_SIZE * sizeof (CHAR16)
> +    );
> +Exit:
> +  FreePages (DataPtr, NumPages);
> +  return Status;
> +}
> +
> +EFI_STATUS
> +StoreSNToBlock (
> +  IN EFI_HANDLE               FlashHandle,
> +  IN EFI_LBA                  Lba,
> +  IN CHAR16                   *UnicodeSN
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_BLOCK_IO_PROTOCOL       *BlockIoProtocol;
> +  VOID                        *DataPtr;
> +  UINTN                       NumPages;
> +  RANDOM_SERIAL_NUMBER        *RandomSN;
> +  CHAR16                      UnicodeStr[SERIAL_NUMBER_SIZE];
> +
> +  if (UnicodeSN == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  Status = gBS->OpenProtocol (
> +                  FlashHandle,
> +                  &gEfiBlockIoProtocolGuid,
> +                  (VOID **) &BlockIoProtocol,
> +                  gImageHandle,
> +                  NULL,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_WARN,
> +      "Warning: Couldn't open block device (status: %r)\n",
> +      Status
> +      ));
> +    return EFI_DEVICE_ERROR;
> +  }
> +  NumPages = EFI_SIZE_TO_PAGES (BlockIoProtocol->Media->BlockSize);
> +  DataPtr = AllocatePages (NumPages);
> +  if (DataPtr == NULL) {
> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +  ZeroMem (DataPtr, BlockIoProtocol->Media->BlockSize);
> +  RandomSN = (RANDOM_SERIAL_NUMBER *)DataPtr;
> +  RandomSN->Magic = RANDOM_MAGIC;
> +  StrnCpyS (
> +    RandomSN->UnicodeSN,
> +    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
> +    UnicodeSN,
> +    StrSize (UnicodeSN)
> +    );
> +  RandomSN->Data = StrHexToUint64 (RandomSN->UnicodeSN);
> +
> +  //
> +  // Verify the unicode string.
> +  //
> +  ZeroMem (UnicodeStr, SERIAL_NUMBER_SIZE * sizeof (CHAR16));
> +  UnicodeSPrint (
> +    UnicodeStr,
> +    SERIAL_NUMBER_SIZE * sizeof (CHAR16),
> +    L"%lx",
> +    RandomSN->Data
> +    );
> +  if (StrLen (RandomSN->UnicodeSN) != StrLen (UnicodeStr)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto Exit;
> +  }
> +  if (StrnCmp (RandomSN->UnicodeSN, UnicodeStr, StrLen (UnicodeStr)) != 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto Exit;
> +  }
> +
> +  Status = BlockIoProtocol->WriteBlocks (
> +                              BlockIoProtocol,
> +                              BlockIoProtocol->Media->MediaId,
> +                              Lba,
> +                              BlockIoProtocol->Media->BlockSize,
> +                              DataPtr
> +                              );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_WARN, "Warning: Failed on writing blocks\n"));
> +    goto Exit;
> +  }
> +Exit:
> +  FreePages (DataPtr, NumPages);
> +  return Status;
> +}
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-10-04 16:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-20 10:31 [PATCH edk-platforms v1 0/4] enable USB on HiKey960 Haojian Zhuang
2018-08-20 10:31 ` [PATCH edk-platforms v1 1/4] Platform/Hisilicon: add UsbSerialNumberLib Haojian Zhuang
2018-10-04 16:48   ` Leif Lindholm
2018-08-20 10:31 ` [PATCH edk-platforms v1 2/4] Platform/HiKey960: add platform usb driver Haojian Zhuang
2018-08-20 10:31 ` [PATCH edk-platforms v1 3/4] Platform/HiKey960: add fastboot platform driver Haojian Zhuang
2018-08-20 10:31 ` [PATCH edk-platforms v1 4/4] Platform/HiKey960: enable usb device driver Haojian Zhuang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox