hikey: Add UEFI sources for reference

UEFI needs to be built outside Android build system.
Please follow the instructions in README.

The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e

Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Application/Ebl/Ebl.efi b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Application/Ebl/Ebl.efi
new file mode 100644
index 0000000..50c6aaa
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Application/Ebl/Ebl.efi
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Application/Ebl/Ebl.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Application/Ebl/Ebl.inf
new file mode 100644
index 0000000..3c1c216
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Application/Ebl/Ebl.inf
@@ -0,0 +1,37 @@
+#/** @file

+# EBL Applicaiton

+#

+# This is a shell application that will display Hello World.

+# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 Section - statements that will be processed to create a Makefile.

+#

+################################################################################

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Ebl

+  FILE_GUID                      = 3CEF354A-3B7A-4519-AD70-72A134698311

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = EdkBootLoaderEntry

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+[Binaries.common]

+  PE32|Ebl.efi|*

+

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/Bds.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/Bds.c
new file mode 100644
index 0000000..deffd91
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/Bds.c
@@ -0,0 +1,864 @@
+/** @file

+*

+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 "BdsInternal.h"

+

+#include <Library/PcdLib.h>

+#include <Library/PerformanceLib.h>

+

+#include <Protocol/Bds.h>

+#include <Protocol/NorFlashProtocol.h>

+#include <Library/BspUartLib.h>

+#include <libfdt_env.h>

+#include <Protocol/NandFlashProtocol.h>

+

+char gpoint3[2][100] = {{0}};
+

+#ifndef U8

+typedef unsigned char   U8;

+#endif

+

+#define EFI_SET_TIMER_TO_SECOND      10000000

+#define FLASH_ECC_RESADDR            0x31000000

+#define FLASH_ECC_RESADDR_OFFSET     0x1000000

+#define RAM_TEST_WORK_TAG            (0x5A5A5A5A) 

+#define RAM_TEST_NOWORK_TAG          (0x0A0A0A0A) 

+

+EFI_HANDLE mImageHandle;

+static int skip_enter_bootwrapper;

+

+//************************************************

+#define SEEK_SET  0

+#define SEEK_CUR  1

+#define SEEK_END  2

+#define EOF     (-1)

+

+#define CPBSP_BASE_ID  (0x0)

+#define M_bootload                            (26 << 16)

+#define M_common                              (0 << 16)

+#define M_common_PARAMETER_ERR                (M_common | 1)

+#define M_bootload_LOADVXWORKS_FAIL           (CPBSP_BASE_ID | M_bootload | 7)

+

+#define GET_CHAR_FROM_COM(timeout)   BspGetChar(timeout*23000)

+

+/* max number of image which you can choice,there are two file name for NODEB*/

+#define PRODUCT_FILENUM       2

+U32 g_ulProductVerSelectNum = PRODUCT_FILENUM;

+#define BOOTUP_CONFIG_FILE           "Bootup.ini"   /* bootup config file */

+

+STATUS BootTovxWorks( void );

+void BSP_GetProductFileName(char* cProductVerName);

+U32 BSP_LoadVxworks (char *pFileName);

+STATUS  BSP_LoadVxworksByName( char *fileName );

+

+extern EFI_STATUS

+BootLinuxAtagLoader (

+  IN LIST_ENTRY *BootOptionsList

+  );

+EFI_STATUS

+BootGo (

+  IN LIST_ENTRY *BootOptionsList

+  );

+

+//************************************************

+//estimate size of Linux kernel,the size for copying file to DDR isn't bigger than this

+#define TEXT_SIZE                       0x400000

+#define MONITOR_SIZE                    0x400000

+#define KERNEL_SIZE                     0xa00000

+#define FILESYSTEM_SIZE                 0x1800000

+

+//actual size of copying file to DDR, it should not bigger than estimate size

+#define TEXT_COPY_SIZE                  0x8000

+#define MONITOR_COPY_SIZE               0x8000

+#define KERNEL_COPY_SIZE                0xa00000

+#define FILESYSTEM_COPY_SIZE            0x1800000

+

+//address of Linux in NORFLASH

+#define TEXT_FLASH_BASE                 (PcdGet32(PcdNorFlashBase) + 0x1000000)

+#define MONITOR_FLASH_BASE              (TEXT_FLASH_BASE + TEXT_SIZE)

+#define KERNEL_FLASH_BASE               (MONITOR_FLASH_BASE + MONITOR_SIZE)

+#define FILESYSTEM_FLASH_BASE           (KERNEL_FLASH_BASE + KERNEL_SIZE)

+

+//address of Linux in NANDFlash

+#define TEXT_BLOCKNUM_NANDFLASH         (0)

+#define MONITOR_BLOCKNUM_NANDFLASH      (TEXT_BLOCKNUM_NANDFLASH + TEXT_SIZE / 0x20000)

+#define KERNEL_BLOCKNUM_NANDFLASH       (MONITOR_BLOCKNUM_NANDFLASH + MONITOR_SIZE / 0x20000)

+#define FILESYSTEM_BLOCKNUM_NANDFLASH   (KERNEL_BLOCKNUM_NANDFLASH + KERNEL_SIZE / 0x20000)

+

+STATIC

+EFI_STATUS

+GetConsoleDevicePathFromVariable (

+  IN  CHAR16*             ConsoleVarName,

+  IN  CHAR16*             DefaultConsolePaths,

+  OUT EFI_DEVICE_PATH**   DevicePaths

+  )

+{

+  EFI_STATUS                Status;

+  UINTN                     Size;

+  EFI_DEVICE_PATH_PROTOCOL* DevicePathInstances;

+  EFI_DEVICE_PATH_PROTOCOL* DevicePathInstance;

+  CHAR16*                   DevicePathStr;

+  CHAR16*                   NextDevicePathStr;

+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;

+

+  Status = GetGlobalEnvironmentVariable (ConsoleVarName, NULL, NULL, (VOID**)&DevicePathInstances);

+  if (EFI_ERROR(Status)) {

+    // In case no default console device path has been defined we assume a driver handles the console (eg: SimpleTextInOutSerial)

+    if ((DefaultConsolePaths == NULL) || (DefaultConsolePaths[0] == L'\0')) {

+      *DevicePaths = NULL;

+      return EFI_SUCCESS;

+    }

+

+    Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);

+    ASSERT_EFI_ERROR(Status);

+

+    DevicePathInstances = NULL;

+

+    // Extract the Device Path instances from the multi-device path string

+    while ((DefaultConsolePaths != NULL) && (DefaultConsolePaths[0] != L'\0')) {

+      NextDevicePathStr = StrStr (DefaultConsolePaths, L";");

+      if (NextDevicePathStr == NULL) {

+        DevicePathStr = DefaultConsolePaths;

+        DefaultConsolePaths = NULL;

+      } else {

+        DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DefaultConsolePaths + 1) * sizeof(CHAR16), DefaultConsolePaths);

+        *(DevicePathStr + (NextDevicePathStr - DefaultConsolePaths)) = L'\0';

+        DefaultConsolePaths = NextDevicePathStr;

+        if (DefaultConsolePaths[0] == L';') {

+          DefaultConsolePaths++;

+        }

+      }

+

+      DevicePathInstance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);

+      ASSERT(DevicePathInstance != NULL);

+      DevicePathInstances = AppendDevicePathInstance (DevicePathInstances, DevicePathInstance);

+

+      if (NextDevicePathStr != NULL) {

+        FreePool (DevicePathStr);

+      }

+      FreePool (DevicePathInstance);

+    }

+

+    // Set the environment variable with this device path multi-instances

+    Size = GetDevicePathSize (DevicePathInstances);

+    if (Size > 0) {

+      gRT->SetVariable (

+          ConsoleVarName,

+          &gEfiGlobalVariableGuid,

+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+          Size,

+          DevicePathInstances

+          );

+    } else {

+      Status = EFI_INVALID_PARAMETER;

+    }

+  }

+

+  if (!EFI_ERROR(Status)) {

+    *DevicePaths = DevicePathInstances;

+  }

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+InitializeConsolePipe (

+  IN EFI_DEVICE_PATH    *ConsoleDevicePaths,

+  IN EFI_GUID           *Protocol,

+  OUT EFI_HANDLE        *Handle,

+  OUT VOID*             *Interface

+  )

+{

+  EFI_STATUS                Status;

+  UINTN                     Size;

+  UINTN                     NoHandles;

+  EFI_HANDLE                *Buffer;

+  EFI_DEVICE_PATH_PROTOCOL* DevicePath;

+

+  // Connect all the Device Path Consoles

+  while (ConsoleDevicePaths != NULL) {

+    DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size);

+

+    Status = BdsConnectDevicePath (DevicePath, Handle, NULL);

+    DEBUG_CODE_BEGIN();

+      if (EFI_ERROR(Status)) {

+        // We convert back to the text representation of the device Path

+        EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+        CHAR16* DevicePathTxt;

+        EFI_STATUS Status;

+

+        Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+        if (!EFI_ERROR(Status)) {

+          DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE);

+

+          DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status));

+

+          FreePool (DevicePathTxt);

+        }

+      }

+    DEBUG_CODE_END();

+

+    // If the console splitter driver is not supported by the platform then use the first Device Path

+    // instance for the console interface.

+    if (!EFI_ERROR(Status) && (*Interface == NULL)) {

+      Status = gBS->HandleProtocol (*Handle, Protocol, Interface);

+    }

+  }

+

+  // No Device Path has been defined for this console interface. We take the first protocol implementation

+  if (*Interface == NULL) {

+    Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);

+    if (EFI_ERROR (Status)) {

+      BdsConnectAllDrivers();

+      Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);

+    }

+

+    if (!EFI_ERROR(Status)) {

+      *Handle = Buffer[0];

+      Status = gBS->HandleProtocol (*Handle, Protocol, Interface);

+      ASSERT_EFI_ERROR(Status);

+    }

+    FreePool (Buffer);

+  } else {

+    Status = EFI_SUCCESS;

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+InitializeConsole (

+  VOID

+  )

+{

+  EFI_STATUS                Status;

+  EFI_DEVICE_PATH*          ConOutDevicePaths;

+  EFI_DEVICE_PATH*          ConInDevicePaths;

+  EFI_DEVICE_PATH*          ConErrDevicePaths;

+

+  // By getting the Console Device Paths from the environment variables before initializing the console pipe, we

+  // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface

+  // of newly installed console drivers

+  Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConOutDevicePaths);

+  ASSERT_EFI_ERROR (Status);

+  Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr(PcdDefaultConInPaths), &ConInDevicePaths);

+  ASSERT_EFI_ERROR (Status);

+  Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConErrDevicePaths);

+  ASSERT_EFI_ERROR (Status);

+

+  // Initialize the Consoles

+  Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut);

+  ASSERT_EFI_ERROR (Status);

+  Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn);

+  ASSERT_EFI_ERROR (Status);

+  Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr);

+  if (EFI_ERROR(Status)) {

+    // In case of error, we reuse the console output for the error output

+    gST->StandardErrorHandle = gST->ConsoleOutHandle;

+    gST->StdErr = gST->ConOut;

+  }

+

+  // Free Memory allocated for reading the UEFI Variables

+  if (ConOutDevicePaths) {

+    FreePool (ConOutDevicePaths);

+  }

+  if (ConInDevicePaths) {

+    FreePool (ConInDevicePaths);

+  }

+  if (ConErrDevicePaths) {

+    FreePool (ConErrDevicePaths);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+DefineDefaultBootEntries (

+  VOID

+  )

+{

+  BDS_LOAD_OPTION*                    BdsLoadOption;

+  UINTN                               Size;

+  EFI_STATUS                          Status;

+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;

+  EFI_DEVICE_PATH*                    BootDevicePath;

+  UINT8*                              OptionalData;

+  UINTN                               OptionalDataSize;

+  ARM_BDS_LOADER_ARGUMENTS*           BootArguments;

+  ARM_BDS_LOADER_TYPE                 BootType;

+  EFI_DEVICE_PATH*                    InitrdPath;

+  UINTN                               InitrdSize;

+  UINTN                               CmdLineSize;

+  UINTN                               CmdLineAsciiSize;

+  CHAR16*                             DefaultBootArgument;

+  CHAR8*                              AsciiDefaultBootArgument;

+

+  //

+  // If Boot Order does not exist then create a default entry

+  //

+  Size = 0;

+  Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL);

+  if (Status == EFI_NOT_FOUND) {

+    if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) {

+      return EFI_UNSUPPORTED;

+    }

+

+    Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);

+    if (EFI_ERROR(Status)) {

+      // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe)

+      DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n"));

+      return Status;

+    }

+    BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath));

+

+    DEBUG_CODE_BEGIN();

+      // We convert back to the text representation of the device Path to see if the initial text is correct

+      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+      CHAR16* DevicePathTxt;

+

+      Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+      ASSERT_EFI_ERROR(Status);

+      DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE);

+

+      ASSERT (StrCmp ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath), DevicePathTxt) == 0);

+

+      FreePool (DevicePathTxt);

+    DEBUG_CODE_END();

+

+    // Create the entry is the Default values are correct

+    if (BootDevicePath != NULL) {

+      BootType = (ARM_BDS_LOADER_TYPE)PcdGet32 (PcdDefaultBootType);

+

+      // We do not support NULL pointer

+      ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL);

+

+      //

+      // Logic to handle ASCII or Unicode default parameters

+      //

+      if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') {

+        CmdLineSize = 0;

+        CmdLineAsciiSize = 0;

+        DefaultBootArgument = NULL;

+        AsciiDefaultBootArgument = NULL;

+      } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) {

+        // The command line is a Unicode string

+        DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument);

+        CmdLineSize = StrSize (DefaultBootArgument);

+

+        // Initialize ASCII variables

+        CmdLineAsciiSize = CmdLineSize / 2;

+        AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize);

+        if (AsciiDefaultBootArgument == NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+        UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument);

+      } else {

+        // The command line is a ASCII string

+        AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument);

+        CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument);

+

+        // Initialize ASCII variables

+        CmdLineSize = CmdLineAsciiSize * 2;

+        DefaultBootArgument = AllocatePool (CmdLineSize);

+        if (DefaultBootArgument == NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+        AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument);

+      }

+

+      if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {

+        InitrdPath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath));

+        InitrdSize = GetDevicePathSize (InitrdPath);

+

+        OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineAsciiSize + InitrdSize;

+        BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize);

+        if (BootArguments == NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+        BootArguments->LinuxArguments.CmdLineSize = CmdLineAsciiSize;

+        BootArguments->LinuxArguments.InitrdSize = InitrdSize;

+

+        CopyMem ((VOID*)(BootArguments + 1), AsciiDefaultBootArgument, CmdLineAsciiSize);

+        CopyMem ((VOID*)((UINTN)(BootArguments + 1) + CmdLineAsciiSize), InitrdPath, InitrdSize);

+

+        OptionalData = (UINT8*)BootArguments;

+      } else {

+        OptionalData = (UINT8*)DefaultBootArgument;

+        OptionalDataSize = CmdLineSize;

+      }

+

+      BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,

+        (CHAR16*)PcdGetPtr(PcdDefaultBootDescription),

+        BootDevicePath,

+        BootType,

+        OptionalData,

+        OptionalDataSize,

+        &BdsLoadOption

+        );

+      FreePool (BdsLoadOption);

+

+      if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) {

+        FreePool (AsciiDefaultBootArgument);

+      } else if (DefaultBootArgument != NULL) {

+        FreePool (DefaultBootArgument);

+      }

+    } else {

+      Status = EFI_UNSUPPORTED;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+StartDefaultBootOnTimeout (

+  VOID

+  )

+{

+  UINTN               Size;

+  UINT16              Timeout;

+  UINT16              *TimeoutPtr;

+  EFI_EVENT           WaitList[2];

+  UINTN               WaitIndex;

+  UINT16              *BootOrder;

+  UINTN               BootOrderSize;

+  UINTN               Index;

+  CHAR16              BootVariableName[9];

+  EFI_STATUS          Status;

+  EFI_INPUT_KEY       Key;

+

+  Size = sizeof(UINT16);

+  Timeout = (UINT16)PcdGet16 (PcdPlatformBootTimeOut);

+  Status = GetGlobalEnvironmentVariable (L"Timeout", &Timeout, &Size, (VOID**)&TimeoutPtr);

+  if (!EFI_ERROR (Status)) {

+    Timeout = *TimeoutPtr;

+    FreePool (TimeoutPtr);

+  }

+

+  if (Timeout != 0xFFFF) {

+    if (Timeout > 0) {

+      // Create the waiting events (keystroke and 1sec timer)

+      gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &WaitList[0]);

+      gBS->SetTimer (WaitList[0], TimerPeriodic, EFI_SET_TIMER_TO_SECOND);

+      WaitList[1] = gST->ConIn->WaitForKey;

+

+      // Start the timer

+      WaitIndex = 0;

+      Print(L"The default boot selection will start in ");

+      while ((Timeout > 0) && (WaitIndex == 0)) {

+        Print(L"%3d seconds",Timeout);

+        gBS->WaitForEvent (2, WaitList, &WaitIndex);

+        if (WaitIndex == 0) {

+          Print(L"\b\b\b\b\b\b\b\b\b\b\b");

+          Timeout--;

+        }

+      }

+      // Discard key in the buffer

+      do {

+      	Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+      } while(!EFI_ERROR(Status));

+      gBS->CloseEvent (WaitList[0]);

+      Print(L"\n\r");

+    }

+

+    // In case of Timeout we start the default boot selection

+    if (Timeout == 0) {

+      // Get the Boot Option Order from the environment variable (a default value should have been created)

+      GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);

+

+      for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {

+        UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOrder[Index]);

+        Status = BdsStartBootOption (BootVariableName);

+        if(!EFI_ERROR(Status)){

+        	// Boot option returned successfully, hence don't need to start next boot option

+        	break;

+        }

+        // In case of success, we should not return from this call.

+      }

+      FreePool (BootOrder);

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+//copy image from NANDFLASH to DDR,file in NANDFLASH must be block align

+EFI_STATUS CopyNandToMem(void* Dest, UINT32 StartBlockNum, UINT32 LengthCopy)

+{

+    EFI_NAND_DRIVER_PROTOCOL   *nandDriver= NULL;

+    EFI_STATUS          Status;

+    NAND_CMD_INFO_STRU ulNandCMDInfo = {0, 0, 0};

+    UINT8 *pucData = NULL;

+    UINT32 ulChunkNum = 0;

+    UINT32 BlockNumCopy = 0;

+    UINT32 i = 0;

+    UINT32 PagePerBlock = 0;

+    UINT32 PageNumCopy = 0;

+

+    DEBUG((EFI_D_ERROR, "[%a : %d]\n", __FUNCTION__, __LINE__));

+    Status = gBS->LocateProtocol (&gNANDDriverProtocolGuid, NULL, (VOID *) &nandDriver);

+    if (EFI_ERROR(Status))

+    {

+        DEBUG((EFI_D_ERROR, "[%a : %d]LocateProtocol:gNANDDriverProtocolGuid fail!\n", __FUNCTION__, __LINE__));

+        return EFI_ABORTED;

+    }

+

+    ulNandCMDInfo = nandDriver->NandFlashGetCMDInfo(nandDriver);

+    if(0 != LengthCopy % ulNandCMDInfo.ulBlockSize)

+    {

+        DEBUG((EFI_D_ERROR, "[%a : %d]input parameter ERROR!\n", __FUNCTION__, __LINE__));

+        return EFI_ABORTED;

+    }

+

+    if (NULL == (pucData = (UINT8*)AllocatePool(ulNandCMDInfo.ulPageSize)))

+    {

+        DEBUG((EFI_D_ERROR, "[%a : %d]Apply buffer failed!\n", __FUNCTION__, __LINE__));

+        return EFI_BAD_BUFFER_SIZE;

+    }

+    

+    PagePerBlock = ulNandCMDInfo.ulBlockSize / ulNandCMDInfo.ulPageSize;

+    BlockNumCopy = (0 == LengthCopy % ulNandCMDInfo.ulBlockSize) ? (LengthCopy / ulNandCMDInfo.ulBlockSize) : (LengthCopy / ulNandCMDInfo.ulBlockSize + 1);

+    PageNumCopy = PagePerBlock * BlockNumCopy;

+    DEBUG((EFI_D_ERROR, "[%a : %d]PageNumCopy = %x!\n", __FUNCTION__, __LINE__, PageNumCopy));

+    for(i = 0;i < PageNumCopy; i++)

+    {

+        //calculate chunk number of your want to read in NANDFLASH

+        ulChunkNum = StartBlockNum * PagePerBlock + i;

+        gBS->SetMem(pucData, ulNandCMDInfo.ulPageSize, 0);

+        Status = (int)nandDriver->NandFlashReadEcc(nandDriver, ulChunkNum, 0, ulNandCMDInfo.ulPageSize, pucData, NULL);

+        if(EFI_SUCCESS != Status)

+        {

+            DEBUG((EFI_D_ERROR, "[%a : %d]NandFlashReadEcc ERROR!\n", __FUNCTION__, __LINE__));

+            gBS->FreePool(pucData);

+            return EFI_ABORTED;

+        }

+        memcpy((void *)((UINT32)Dest + i * ulNandCMDInfo.ulPageSize), (void *)pucData, ulNandCMDInfo.ulPageSize);

+    }

+    gBS->FreePool(pucData);

+    return EFI_SUCCESS;

+}
+#define NANDFLASHREAD 1
+
+static void ReadBootwrapper(void)
+{
+    void *buf;
+    NAND_CMD_INFO_STRU ulNandCMDInfo = { 0 };
+    #ifdef NANDFLASHREAD
+    EFI_NAND_DRIVER_PROTOCOL *nandDriver = NULL;
+
+    gBS->LocateProtocol (&gNANDDriverProtocolGuid, NULL, (VOID *) &nandDriver);
+    ulNandCMDInfo = nandDriver->NandFlashGetCMDInfo(nandDriver);
+    #endif
+    buf = AllocatePool(ulNandCMDInfo.ulBlockSize);
+
+    (VOID)AsciiPrint("\nCopy Bootwrapper from FLASH to SRAM...");
+
+    #ifdef NANDFLASHREAD
+        CopyNandToMem(buf, TEXT_BLOCKNUM_NANDFLASH, ulNandCMDInfo.ulBlockSize);
+        memcpy((void *)TEXT_SRAM_BASE, buf, TEXT_COPY_SIZE);
+        (VOID)AsciiPrint("\nThe .text file is transmitted ok!\n");
+    #else
+         /* copy.text */
+        memcpy((void *)TEXT_SRAM_BASE, (void *)TEXT_FLASH_BASE, TEXT_COPY_SIZE);
+        (VOID)AsciiPrint("\nThe .text file is transmitted ok!\n");
+    #endif
+
+    #ifdef NANDFLASHREAD
+         /* copy .monitor */
+        CopyNandToMem(buf, MONITOR_BLOCKNUM_NANDFLASH, ulNandCMDInfo.ulBlockSize);
+        memcpy((void *)MONITOR_SRAM_BASE, buf, MONITOR_COPY_SIZE);
+        (VOID)AsciiPrint("The .monitor file is transmitted ok!\n");
+    #else
+         /* copy .monitor */
+        memcpy((void *)MONITOR_SRAM_BASE, (void *)MONITOR_FLASH_BASE, MONITOR_COPY_SIZE);
+        (VOID)AsciiPrint("The .monitor file is transmitted ok!\n");
+    #endif
+
+    gBS->FreePool(buf);
+}
+
+static void ReadNandFileSystem(void)
+{
+    #ifdef NANDFLASHREAD
+        CopyNandToMem((VOID *)FILESYSTEM_DDR_BASE, FILESYSTEM_BLOCKNUM_NANDFLASH, FILESYSTEM_COPY_SIZE);
+        (VOID)AsciiPrint("THE .FILESYSTEM FILE IS TRANSMITTED OK!\n");
+    #else
+        memcpy((VOID *)FILESYSTEM_DDR_BASE, (VOID *)FILESYSTEM_FLASH_BASE, FILESYSTEM_COPY_SIZE);
+        (VOID)AsciiPrint("THE .FILESYSTEM FILE IS TRANSMITTED OK!\n");
+    #endif
+}
+
+/**
+  This function uses policy data from the platform to determine what operating
+  system or system utility should be loaded and invoked.  This function call
+  also optionally make the use of user input to determine the operating system 

+  or system utility to be loaded and invoked.  When the DXE Core has dispatched 

+  all the drivers on the dispatch queue, this function is called.  This 

+  function will attempt to connect the boot devices required to load and invoke 

+  the selected operating system or system utility.  During this process, 

+  additional firmware volumes may be discovered that may contain addition DXE 

+  drivers that can be dispatched by the DXE Core.   If a boot device cannot be 

+  fully connected, this function calls the DXE Service Dispatch() to allow the 

+  DXE drivers from any newly discovered firmware volumes to be dispatched.  

+  Then the boot device connection can be attempted again.  If the same boot 

+  device connection operation fails twice in a row, then that boot device has 

+  failed, and should be skipped.  This function should never return.

+

+  @param  This             The EFI_BDS_ARCH_PROTOCOL instance.

+

+  @return None.

+

+**/

+

+VOID

+EFIAPI

+BdsEntry (

+  IN EFI_BDS_ARCH_PROTOCOL  *This

+  )

+{

+  UINTN               Size;

+  EFI_STATUS          Status;

+  //STATUS              Result;

+  UINT16             *BootNext;

+  UINTN               BootNextSize;

+  CHAR16              BootVariableName[9];

+  EFI_NAND_DRIVER_PROTOCOL   *nandDriver= NULL;

+

+  //UNI_NOR_FLASH_PROTOCOL        *Flash;

+

+  PERF_END   (NULL, "DXE", NULL, 0);

+  //U32 buffer[9];

+

+  char ckeyValue = 0 ;

+  LIST_ENTRY  BootOptionsList;

+  //

+  // Declare the Firmware Vendor

+  //

+  if (FixedPcdGetPtr(PcdFirmwareVendor) != NULL) {

+    Size = 0x100;

+    gST->FirmwareVendor = AllocateRuntimePool (Size);

+    ASSERT (gST->FirmwareVendor != NULL);

+    UnicodeSPrint (gST->FirmwareVendor, Size, L"%a EFI %a %a", PcdGetPtr(PcdFirmwareVendor), __DATE__, __TIME__);

+  }

+

+  // If BootNext environment variable is defined then we just load it !

+  BootNextSize = sizeof(UINT16);

+  Status = GetGlobalEnvironmentVariable (L"BootNext", NULL, &BootNextSize, (VOID**)&BootNext);

+  if (!EFI_ERROR(Status)) {

+    ASSERT(BootNextSize == sizeof(UINT16));

+

+    // Generate the requested Boot Entry variable name

+    UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", *BootNext);

+

+    // Set BootCurrent variable

+    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,

+              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+              BootNextSize, BootNext);

+

+    FreePool (BootNext);

+

+    // Start the requested Boot Entry

+    Status = BdsStartBootOption (BootVariableName);

+    if (Status != EFI_NOT_FOUND) {

+      // BootNext has not been succeeded launched

+      if (EFI_ERROR(Status)) {

+        Print(L"Fail to start BootNext.\n");

+      }

+

+      // Delete the BootNext environment variable

+      gRT->SetVariable (L"BootNext", &gEfiGlobalVariableGuid,

+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+          0, NULL);

+    }

+

+    // Clear BootCurrent variable

+    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,

+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+        0, NULL);

+  }

+

+  // If Boot Order does not exist then create a default entry

+  DefineDefaultBootEntries ();

+

+  // Now we need to setup the EFI System Table with information about the console devices.

+  InitializeConsole ();

+  

+    Status = gBS->LocateProtocol (&gNANDDriverProtocolGuid, NULL, (VOID *) &nandDriver);

+    if (EFI_ERROR(Status))

+    {

+        DEBUG((EFI_D_ERROR, "LocateProtocol:gNANDDriverProtocolGuid fail!\n"));

+    }

+    

+    DEBUG((EFI_D_ERROR, "NandFlashInit start\n"));

+    Status = (int)nandDriver->NandFlashInit(nandDriver);

+    if(EFI_SUCCESS != Status)

+    {

+        DEBUG((EFI_D_ERROR, "NAND Flash Init Error! Status = %r\n", Status));

+    }

+    else

+    {

+        DEBUG((EFI_D_ERROR, "NAND Flash Init OK! Status = %r\n", Status));

+    }

+

+

+    (VOID)AsciiPrint("\n\rAuto boot or not ?(Press 's' to Boot Menu)"); 

+    (VOID)AsciiPrint("\n\rNow wait for 2 seconds...\n");

+    

+    ckeyValue = GET_CHAR_FROM_COM(2);

+

+    if ( 0x73 != ckeyValue )   

+    {

+        (VOID)AsciiPrint("\n\rNot Press 's', Start Auto Boot!\n"); 

+        Status = gBS->LocateProtocol (&gNANDDriverProtocolGuid, NULL, (VOID *) &nandDriver);

+        if (EFI_ERROR(Status))

+        {

+            DEBUG((EFI_D_ERROR, "LocateProtocol:gNANDDriverProtocolGuid fail!\n"));

+        }

+
+        //Status = BootMenuMain ();
+        //ASSERT_EFI_ERROR (Status);
+
+        #if 1
+
+        /*2.copy image from FLASH to DDR,and start*/
+        (VOID)AsciiPrint("\nTransmit  OS from FLASH to DDR now, please wait!");
+
+        #ifdef NANDFLASHREAD
+             /* copy.kernel */
+            CopyNandToMem((void *)KERNEL_DDR_BASE, KERNEL_BLOCKNUM_NANDFLASH, KERNEL_COPY_SIZE);

+            (VOID)AsciiPrint("\nThe .kernel file is transmitted ok!\n");

+        #else

+             /* copy.kernel */

+            memcpy((void *)KERNEL_DDR_BASE, (void *)KERNEL_FLASH_BASE, KERNEL_COPY_SIZE);

+            (VOID)AsciiPrint("\nThe .kernel file is transmitted ok!\n");

+        #endif

+//        /* compare kernel in FLASH and the same file in DDR*/

+//        if (CompareMem((void *)KERNEL_DDR_BASE, (void *)KERNEL_FLASH_BASE, KERNEL_COPY_SIZE) != 0)

+//        {

+//            (VOID)AsciiPrint("The .kernel file check fail!\n");

+//            //return;

+//        }

+//        else

+//        {

+//            (VOID)AsciiPrint("The .kernel file check sucess!\n\n");

+//        }

+

+//        /* compare initrd in FLASH and the same file in DDR*/

+//        if (CompareMem((void *)FILESYSTEM_DDR_BASE, (void *)FILESYSTEM_FLASH_BASE, FILESYSTEM_COPY_SIZE) != 0)

+//        {

+//            (VOID)AsciiPrint("The .filesystem file check fail!\n");

+//            //return;

+//        }

+//        else

+//        {

+//            (VOID)AsciiPrint("The .filesystem file check sucess!\n\n");

+//        }

+

+        /*---------------OS-----------------*/

+        skip_enter_bootwrapper = 1;

+        BootOptionList (&BootOptionsList);

+        BootGo (&BootOptionsList);

+        #endif

+    }

+    (VOID)AsciiPrint("Press 's', Start Boot Menu!\n\n"); 

+  

+  // Timer before initiating the default boot selection

+  StartDefaultBootOnTimeout ();

+

+  // Start the Boot Menu

+  Status = BootMenuMain ();

+  ASSERT_EFI_ERROR (Status);

+
+}
+
+long bootwrapper_saved_stack;
+static void EnterBootwrapper(void)
+{
+#if !defined(__thumb__)
+#error Please compile in thumb mode
+#endif
+
+  /*
+   * This chunk of assembly enters the bootwrapper code, then
+   * immediately returns here and recovers all clobbered registers
+   */
+  asm volatile("ldr	r0, =return_from_bootwrapper	\n\
+		orr	r0, r0, #1			\n\
+		ldr	r4, =bootwrapper_saved_stack	\n\
+		str	sp, [r4]			\n\
+		b	RunBootwrapper			\n\
+		return_from_bootwrapper:		\n\
+		ldr	r4, =bootwrapper_saved_stack	\n\
+		ldr	sp, [r4]"
+		: :
+		: "cc", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
+		  "r9", "r10", "r11", "r12", "r14");
+}
+
+/**
+  EFI Exit Event
+
+  Exiting EFI Boot Services can only mean we're bootstrapping into a real OS.
+  So let's copy the bootwrapper code into place to make sure the OS can use it.
+
+  @param[in]  Event   The Event that is being processed
+  @param[in]  Context Event Context
+**/
+
+static EFI_EVENT EfiExitBootServicesEvent;
+
+VOID
+EFIAPI
+ExitBootServicesEvent (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  ReadBootwrapper();
+  ReadNandFileSystem();
+
+  if (skip_enter_bootwrapper)
+    return;
+
+  EnterBootwrapper();
+}
+
+EFI_BDS_ARCH_PROTOCOL  gBdsProtocol = {
+  BdsEntry,
+};
+

+EFI_STATUS

+EFIAPI

+BdsInitialize (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  mImageHandle = ImageHandle;

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ImageHandle,

+                  &gEfiBdsArchProtocolGuid, &gBdsProtocol,

+                  NULL

+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  // Register for an ExitBootServicesEvent
+  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/Bds.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/Bds.inf
new file mode 100644
index 0000000..f7416bf
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/Bds.inf
@@ -0,0 +1,84 @@
+#/** @file

+#  

+#  Component description file for Bds module

+#  

+#  Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = ArmPlatformBds

+  FILE_GUID                      = 5a50aa81-c3ae-4608-a0e3-41a2e69baf94 

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = BdsInitialize

+

+[Sources.common]

+  Bds.c

+  BdsHelper.c

+  BootMenu.c

+  BootOption.c

+  BootOptionSupport.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  HisiPkg/HisiPlatformPkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+

+[LibraryClasses]

+  BdsLib

+  TimerLib

+  PerformanceLib

+  UefiBootServicesTableLib

+  DxeServicesTableLib

+  UefiDriverEntryPoint

+  DebugLib

+  PrintLib

+  BaseLib

+  ArmLib

+  BspUartLib

+  

+[Guids]

+  gEfiFileSystemInfoGuid

+  gArmGlobalVariableGuid

+

+[Protocols]

+  gEfiBdsArchProtocolGuid

+  gEfiBlockIoProtocolGuid

+  gEfiSimpleTextInProtocolGuid

+  gEfiPxeBaseCodeProtocolGuid

+  gEfiSimpleNetworkProtocolGuid

+  gEfiDevicePathToTextProtocolGuid

+  gUniNorFlashProtocolGuid

+  gNANDDriverProtocolGuid

+

+[Pcd]

+  gArmPlatformTokenSpaceGuid.PcdFirmwareVendor

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootType

+  gArmPlatformTokenSpaceGuid.PcdFdtDevicePath

+  gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut

+  gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths

+  gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths

+  gHwTokenSpaceGuid.PcdNorFlashBase

+  

+[Depex]

+  TRUE

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BdsHelper.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BdsHelper.c
new file mode 100644
index 0000000..c07b8af
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BdsHelper.c
@@ -0,0 +1,416 @@
+/** @file

+*

+*  Copyright (c) 2011 - 2014, ARM 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.             

+*

+**/

+

+#include "BdsInternal.h"

+

+EFI_STATUS

+EditHIInputStr (

+  IN OUT CHAR16  *CmdLine,

+  IN     UINTN   MaxCmdLine

+  )

+{

+  UINTN           CmdLineIndex;

+  UINTN           WaitIndex;

+  CHAR8           Char;

+  EFI_INPUT_KEY   Key;

+  EFI_STATUS      Status;

+

+  // The command line must be at least one character long

+  ASSERT (MaxCmdLine > 0);

+

+  // Ensure the last character of the buffer is the NULL character

+  CmdLine[MaxCmdLine - 1] = '\0';

+

+  Print (CmdLine);

+

+  // To prevent a buffer overflow, we only allow to enter (MaxCmdLine-1) characters

+  for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) {

+    Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);

+    ASSERT_EFI_ERROR (Status);

+

+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+    ASSERT_EFI_ERROR (Status);

+

+    // Unicode character is valid when Scancode is NUll

+    if (Key.ScanCode == SCAN_NULL) {

+      // Scan code is NUll, hence read Unicode character

+      Char = (CHAR8)Key.UnicodeChar;

+    } else {

+      Char = CHAR_NULL;

+    }

+

+    if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {

+      CmdLine[CmdLineIndex] = '\0';

+      Print (L"\r\n");

+

+      return EFI_SUCCESS;

+    } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){

+      if (CmdLineIndex != 0) {

+        CmdLineIndex--;

+        Print (L"\b \b");

+      }

+    } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {

+      return EFI_INVALID_PARAMETER;

+    } else if (CmdLineIndex < (MaxCmdLine-1)) {

+      CmdLine[CmdLineIndex++] = Key.UnicodeChar;

+      Print (L"%c", Key.UnicodeChar);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+GetHIInputStr (

+  IN OUT CHAR16  *CmdLine,

+  IN     UINTN   MaxCmdLine

+  )

+{

+  EFI_STATUS  Status;

+

+  // For a new input just passed an empty string

+  CmdLine[0] = L'\0';

+

+  Status = EditHIInputStr (CmdLine, MaxCmdLine);

+

+  return Status;

+}

+

+EFI_STATUS

+EditHIInputAscii (

+  IN OUT CHAR8   *CmdLine,

+  IN     UINTN   MaxCmdLine

+  )

+{

+  CHAR16*     Str;

+  EFI_STATUS  Status;

+

+  Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));

+  AsciiStrToUnicodeStr (CmdLine, Str);

+

+  Status = EditHIInputStr (Str, MaxCmdLine);

+  if (!EFI_ERROR(Status)) {

+    UnicodeStrToAsciiStr (Str, CmdLine);

+  }

+  FreePool (Str);

+

+  return Status;

+}

+

+EFI_STATUS

+GetHIInputAscii (

+  IN OUT CHAR8   *CmdLine,

+  IN     UINTN   MaxCmdLine

+  )

+{

+  // For a new input just passed an empty string

+  CmdLine[0] = '\0';

+

+  return EditHIInputAscii (CmdLine,MaxCmdLine);

+}

+

+EFI_STATUS

+GetHIInputInteger (

+  OUT UINTN   *Integer

+  )

+{

+  CHAR16      CmdLine[255];

+  EFI_STATUS  Status;

+

+  CmdLine[0] = '\0';

+  Status = EditHIInputStr (CmdLine, 255);

+  if (!EFI_ERROR(Status)) {

+    *Integer = StrDecimalToUintn (CmdLine);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+GetHIInputIP (

+  OUT EFI_IP_ADDRESS   *Ip

+  )

+{

+  CHAR16  CmdLine[255];

+  CHAR16  *Str;

+  EFI_STATUS  Status;

+

+  CmdLine[0] = '\0';

+  Status = EditHIInputStr (CmdLine,255);

+  if (!EFI_ERROR(Status)) {

+    Str = CmdLine;

+    Ip->v4.Addr[0] = (UINT8)StrDecimalToUintn (Str);

+

+    Str = StrStr (Str, L".");

+    if (Str == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    Ip->v4.Addr[1] = (UINT8)StrDecimalToUintn (++Str);

+

+    Str = StrStr (Str, L".");

+    if (Str == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    Ip->v4.Addr[2] = (UINT8)StrDecimalToUintn (++Str);

+

+    Str = StrStr (Str, L".");

+    if (Str == NULL) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    Ip->v4.Addr[3] = (UINT8)StrDecimalToUintn (++Str);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+GetHIInputBoolean (

+  OUT BOOLEAN *Value

+  )

+{

+  CHAR16      CmdBoolean[2];

+  EFI_STATUS  Status;

+

+  while(1) {

+    Print (L"[y/n] ");

+    Status = GetHIInputStr (CmdBoolean, 2);

+    if (EFI_ERROR(Status)) {

+      return Status;

+    } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) {

+      if (Value) *Value = TRUE;

+      return EFI_SUCCESS;

+    } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) {

+      if (Value) *Value = FALSE;

+      return EFI_SUCCESS;

+    }

+  }

+}

+

+BOOLEAN

+HasFilePathEfiExtension (

+  IN CHAR16* FilePath

+  )

+{

+  return (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".EFI") == 0) ||

+         (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".efi") == 0);

+}

+

+// Return the last non end-type Device Path Node from a Device Path

+EFI_DEVICE_PATH*

+GetLastDevicePathNode (

+  IN EFI_DEVICE_PATH*  DevicePath

+  )

+{

+  EFI_DEVICE_PATH*     PrevDevicePathNode;

+

+  PrevDevicePathNode = DevicePath;

+  while (!IsDevicePathEndType (DevicePath)) {

+    PrevDevicePathNode = DevicePath;

+    DevicePath = NextDevicePathNode (DevicePath);

+  }

+

+  return PrevDevicePathNode;

+}

+

+EFI_STATUS

+GenerateDeviceDescriptionName (

+  IN  EFI_HANDLE  Handle,

+  IN OUT CHAR16*  Description

+  )

+{

+  EFI_STATUS                        Status;

+  EFI_COMPONENT_NAME_PROTOCOL*      ComponentName2Protocol;

+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;

+  CHAR16*                           DriverName;

+  CHAR16*                           DevicePathTxt;

+  EFI_DEVICE_PATH*                  DevicePathNode;

+

+  ComponentName2Protocol = NULL;

+  Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);

+  if (!EFI_ERROR(Status)) {

+    //TODO: Fixme. we must find the best langague

+    Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);

+    if (!EFI_ERROR(Status)) {

+      StrnCpy (Description, DriverName, BOOT_DEVICE_DESCRIPTION_MAX);

+    }

+  }

+

+  if (EFI_ERROR(Status)) {

+    // Use the lastest non null entry of the Device path as a description

+    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);

+    if (EFI_ERROR(Status)) {

+      return Status;

+    }

+

+    // Convert the last non end-type Device Path Node in text for the description

+    DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);

+    Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+    ASSERT_EFI_ERROR(Status);

+    DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePathNode, TRUE, TRUE);

+    StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);

+    FreePool (DevicePathTxt);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsStartBootOption (

+  IN CHAR16* BootOption

+  )

+{

+  EFI_STATUS          Status;

+  BDS_LOAD_OPTION     *BdsLoadOption;

+

+  Status = BootOptionFromLoadOptionVariable (BootOption, &BdsLoadOption);

+  if (!EFI_ERROR(Status)) {

+    Status = BootOptionStart (BdsLoadOption);

+    FreePool (BdsLoadOption);

+

+    if (!EFI_ERROR(Status)) {

+      Status = EFI_SUCCESS;

+    } else {

+      Status = EFI_NOT_STARTED;

+    }

+  } else {

+    Status = EFI_NOT_FOUND;

+  }

+  return Status;

+}

+

+UINTN

+GetUnalignedDevicePathSize (

+  IN EFI_DEVICE_PATH* DevicePath

+  )

+{

+  UINTN Size;

+  EFI_DEVICE_PATH* AlignedDevicePath;

+

+  if ((UINTN)DevicePath & 0x1) {

+    AlignedDevicePath = DuplicateDevicePath (DevicePath);

+    Size = GetDevicePathSize (AlignedDevicePath);

+    FreePool (AlignedDevicePath);

+  } else {

+    Size = GetDevicePathSize (DevicePath);

+  }

+  return Size;

+}

+

+EFI_DEVICE_PATH*

+GetAlignedDevicePath (

+  IN EFI_DEVICE_PATH* DevicePath

+  )

+{

+  if ((UINTN)DevicePath & 0x1) {

+    return DuplicateDevicePath (DevicePath);

+  } else {

+    return DevicePath;

+  }

+}

+

+BOOLEAN

+IsUnicodeString (

+  IN VOID* String

+  )

+{

+  // We do not support NULL pointer

+  ASSERT (String != NULL);

+

+  if (*(CHAR16*)String < 0x100) {

+    //Note: We could get issue if the string is an empty Ascii string...

+    return TRUE;

+  } else {

+    return FALSE;

+  }

+}

+

+/*

+ * Try to detect if the given string is an ASCII or Unicode string

+ *

+ * There are actually few limitation to this function but it is mainly to give

+ * a user friendly output.

+ *

+ * Some limitations:

+ *   - it only supports unicode string that use ASCII character (< 0x100)

+ *   - single character ASCII strings are interpreted as Unicode string

+ *   - string cannot be longer than 2 x BOOT_DEVICE_OPTION_MAX (600 bytes)

+ *

+ * @param String    Buffer that might contain a Unicode or Ascii string

+ * @param IsUnicode If not NULL this boolean value returns if the string is an

+ *                  ASCII or Unicode string.

+ */

+BOOLEAN

+IsPrintableString (

+  IN  VOID*    String,

+  OUT BOOLEAN *IsUnicode

+  )

+{

+  BOOLEAN UnicodeDetected;

+  BOOLEAN IsPrintable;

+  UINTN Index;

+  CHAR16 Character;

+

+  // We do not support NULL pointer

+  ASSERT (String != NULL);

+

+  // Test empty string

+  if (*(CHAR16*)String == L'\0') {

+    if (IsUnicode) {

+      *IsUnicode = TRUE;

+    }

+    return TRUE;

+  } else if (*(CHAR16*)String == '\0') {

+    if (IsUnicode) {

+      *IsUnicode = FALSE;

+    }

+    return TRUE;

+  }

+

+  // Limitation: if the string is an ASCII single character string. This comparison

+  // will assume it is a Unicode string.

+  if (*(CHAR16*)String < 0x100) {

+    UnicodeDetected = TRUE;

+  } else {

+    UnicodeDetected = FALSE;

+  }

+

+  IsPrintable = FALSE;

+  for (Index = 0; Index < BOOT_DEVICE_OPTION_MAX * 2; Index++) {

+    if (UnicodeDetected) {

+      Character = ((CHAR16*)String)[Index];

+    } else {

+      Character = ((CHAR8*)String)[Index];

+    }

+

+    if (Character == '\0') {

+      // End of the string

+      IsPrintable = TRUE;

+      break;

+    } else if ((Character < 0x20) || (Character > 0x7f)) {

+      // We only support the range of printable ASCII character

+      IsPrintable = FALSE;

+      break;

+    }

+  }

+

+  if (IsPrintable && IsUnicode) {

+    *IsUnicode = UnicodeDetected;

+  }

+

+  return IsPrintable;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BdsInternal.h b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BdsInternal.h
new file mode 100644
index 0000000..0b0d11e
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BdsInternal.h
@@ -0,0 +1,287 @@
+/** @file

+*

+*  Copyright (c) 2011-2014, ARM 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.

+*

+**/

+

+#ifndef _BDSINTERNAL_H_

+#define _BDSINTERNAL_H_

+

+#include <PiDxe.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BdsLib.h>

+#include <Library/DebugLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/UefiLib.h>

+#include <Library/PrintLib.h>

+#include <Library/PcdLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+

+#include <Protocol/DevicePathFromText.h>

+#include <Protocol/DevicePathToText.h>

+

+#include <Guid/GlobalVariable.h>

+

+#define BOOT_DEVICE_DESCRIPTION_MAX   100

+#define BOOT_DEVICE_FILEPATH_MAX      100

+#define BOOT_DEVICE_OPTION_MAX        300

+#define BOOT_DEVICE_ADDRESS_MAX       (sizeof(L"0x0000000000000000"))

+

+//address of Linux in DDR

+#define TEXT_SRAM_BASE                  0xe00f0000

+#define MONITOR_SRAM_BASE               0xe00f8000

+#define KERNEL_DDR_BASE                 0x10008000

+#define FILESYSTEM_DDR_BASE             0x10d00000

+

+#define ARM_BDS_OPTIONAL_DATA_SIGNATURE   SIGNATURE_32('a', 'b', 'o', 'd')

+

+#define IS_ARM_BDS_BOOTENTRY(ptr)  \

+  (((ptr)->OptionalData != NULL) && \

+   (ReadUnaligned32 ((CONST UINT32*)&((ARM_BDS_LOADER_OPTIONAL_DATA*)((ptr)->OptionalData))->Header.Signature) \

+      == ARM_BDS_OPTIONAL_DATA_SIGNATURE))

+

+#define UPDATE_BOOT_ENTRY L"Update entry: "

+#define DELETE_BOOT_ENTRY L"Delete entry: "

+

+typedef enum {

+    BDS_LOADER_EFI_APPLICATION = 0,

+    BDS_LOADER_KERNEL_LINUX_ATAG,

+    BDS_LOADER_KERNEL_LINUX_FDT,

+} ARM_BDS_LOADER_TYPE;

+

+typedef struct {

+  UINT16                     CmdLineSize;

+  UINT16                     InitrdSize;

+

+  // These following fields have variable length and are packed:

+  //CHAR8                      *CmdLine;

+  //EFI_DEVICE_PATH_PROTOCOL   *InitrdPathList;

+} ARM_BDS_LINUX_ARGUMENTS;

+

+typedef union {

+  ARM_BDS_LINUX_ARGUMENTS    LinuxArguments;

+} ARM_BDS_LOADER_ARGUMENTS;

+

+typedef struct {

+  UINT32                     Signature;

+  ARM_BDS_LOADER_TYPE        LoaderType;

+} ARM_BDS_LOADER_OPTIONAL_DATA_HEADER;

+

+typedef struct {

+  ARM_BDS_LOADER_OPTIONAL_DATA_HEADER Header;

+  ARM_BDS_LOADER_ARGUMENTS            Arguments;

+} ARM_BDS_LOADER_OPTIONAL_DATA;

+

+typedef struct {

+  LIST_ENTRY                  Link;

+  BDS_LOAD_OPTION*            BdsLoadOption;

+} BDS_LOAD_OPTION_ENTRY;

+

+typedef enum {

+  BDS_DEVICE_FILESYSTEM = 0,

+  BDS_DEVICE_MEMMAP,

+  BDS_DEVICE_PXE,

+  BDS_DEVICE_TFTP,

+  BDS_DEVICE_MAX

+} BDS_SUPPORTED_DEVICE_TYPE;

+

+typedef struct {

+  LIST_ENTRY                          Link;

+  CHAR16                              Description[BOOT_DEVICE_DESCRIPTION_MAX];

+  EFI_DEVICE_PATH_PROTOCOL*           DevicePathProtocol;

+  struct _BDS_LOAD_OPTION_SUPPORT*    Support;

+} BDS_SUPPORTED_DEVICE;

+

+#define SUPPORTED_BOOT_DEVICE_FROM_LINK(a)   BASE_CR(a, BDS_SUPPORTED_DEVICE, Link)

+

+typedef struct _BDS_LOAD_OPTION_SUPPORT {

+  BDS_SUPPORTED_DEVICE_TYPE   Type;

+  EFI_STATUS    (*ListDevices)(IN OUT LIST_ENTRY* BdsLoadOptionList);

+  BOOLEAN       (*IsSupported)(IN  EFI_DEVICE_PATH *DevicePath);

+  EFI_STATUS    (*CreateDevicePathNode)(IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes, OUT BOOLEAN *RequestBootType);

+  EFI_STATUS    (*UpdateDevicePathNode)(IN EFI_DEVICE_PATH *OldDevicePath, IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath, OUT BOOLEAN *RequestBootType);

+} BDS_LOAD_OPTION_SUPPORT;

+

+#define LOAD_OPTION_ENTRY_FROM_LINK(a)  BASE_CR(a, BDS_LOAD_OPTION_ENTRY, Link)

+#define LOAD_OPTION_FROM_LINK(a)        ((BDS_LOAD_OPTION_ENTRY*)BASE_CR(a, BDS_LOAD_OPTION_ENTRY, Link))->BdsLoadOption

+

+EFI_STATUS

+BootDeviceListSupportedInit (

+  IN OUT LIST_ENTRY *SupportedDeviceList

+  );

+

+EFI_STATUS

+BootDeviceListSupportedFree (

+  IN LIST_ENTRY *SupportedDeviceList,

+  IN BDS_SUPPORTED_DEVICE *Except

+  );

+

+EFI_STATUS

+BootDeviceGetDeviceSupport (

+  IN  EFI_DEVICE_PATH           *DevicePath,

+  OUT BDS_LOAD_OPTION_SUPPORT   **DeviceSupport

+  );

+

+EFI_STATUS

+GetHIInputStr (

+  IN OUT CHAR16  *CmdLine,

+  IN     UINTN   MaxCmdLine

+  );

+

+EFI_STATUS

+EditHIInputStr (

+  IN OUT CHAR16  *CmdLine,

+  IN     UINTN   MaxCmdLine

+  );

+

+EFI_STATUS

+GetHIInputAscii (

+  IN OUT CHAR8   *CmdLine,

+  IN     UINTN   MaxCmdLine

+  );

+

+EFI_STATUS

+EditHIInputAscii (

+  IN OUT CHAR8   *CmdLine,

+  IN     UINTN   MaxCmdLine

+  );

+

+EFI_STATUS

+GetHIInputInteger (

+  IN OUT UINTN   *Integer

+  );

+

+EFI_STATUS

+GetHIInputIP (

+  OUT EFI_IP_ADDRESS   *Ip

+  );

+

+EFI_STATUS

+GetHIInputBoolean (

+  OUT BOOLEAN *Value

+  );

+

+BOOLEAN

+HasFilePathEfiExtension (

+  IN CHAR16* FilePath

+  );

+

+EFI_DEVICE_PATH*

+GetLastDevicePathNode (

+  IN EFI_DEVICE_PATH*  DevicePath

+  );

+

+EFI_STATUS

+BdsStartBootOption (

+  IN CHAR16* BootOption

+  );

+

+UINTN

+GetUnalignedDevicePathSize (

+  IN EFI_DEVICE_PATH* DevicePath

+  );

+

+EFI_DEVICE_PATH*

+GetAlignedDevicePath (

+  IN EFI_DEVICE_PATH* DevicePath

+  );

+

+EFI_STATUS

+GenerateDeviceDescriptionName (

+  IN  EFI_HANDLE  Handle,

+  IN OUT CHAR16*  Description

+  );

+

+EFI_STATUS

+BootOptionList (

+  IN OUT LIST_ENTRY *BootOptionList

+  );

+

+EFI_STATUS

+BootOptionParseLoadOption (

+  IN  EFI_LOAD_OPTION EfiLoadOption,

+  IN  UINTN           EfiLoadOptionSize,

+  OUT BDS_LOAD_OPTION **BdsLoadOption

+  );

+

+EFI_STATUS

+BootOptionStart (

+  IN BDS_LOAD_OPTION *BootOption

+  );

+

+EFI_STATUS

+BootOptionCreate (

+  IN  UINT32                    Attributes,

+  IN  CHAR16*                   BootDescription,

+  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,

+  IN  ARM_BDS_LOADER_TYPE       BootType,

+  IN  UINT8*                    OptionalData,

+  IN  UINTN                     OptionalDataSize,

+  OUT BDS_LOAD_OPTION**         BdsLoadOption

+  );

+

+EFI_STATUS

+BootOptionUpdate (

+  IN  BDS_LOAD_OPTION*          BdsLoadOption,

+  IN  UINT32                    Attributes,

+  IN  CHAR16*                   BootDescription,

+  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,

+  IN  ARM_BDS_LOADER_TYPE       BootType,

+  IN UINT8*                     OptionalData,

+  IN UINTN                      OptionalDataSize

+  );

+

+EFI_STATUS

+BootOptionDelete (

+  IN  BDS_LOAD_OPTION *BootOption

+  );

+

+EFI_STATUS

+BootDeviceGetType (

+  IN  EFI_DEVICE_PATH* DevicePath,

+  OUT ARM_BDS_LOADER_TYPE *BootType,

+  OUT UINT32 *Attributes

+  );

+

+EFI_STATUS

+BootMenuMain (

+  VOID

+  );

+

+BOOLEAN

+IsUnicodeString (

+  IN VOID* String

+  );

+

+/*

+ * Try to detect if the given string is an ASCII or Unicode string

+ *

+ * There are actually few limitation to this function but it is mainly to give

+ * a user friendly output.

+ *

+ * Some limitations:

+ *   - it only supports unicode string that use ASCII character (< 0x100)

+ *   - single character ASCII strings are interpreted as Unicode string

+ *   - string cannot be longer than 2 x BOOT_DEVICE_OPTION_MAX (600 bytes)

+ *

+ * @param String    Buffer that might contain a Unicode or Ascii string

+ * @param IsUnicode If not NULL this boolean value returns if the string is an

+ *                  ASCII or Unicode string.

+ */

+BOOLEAN

+IsPrintableString (

+  IN  VOID*    String,

+  OUT BOOLEAN *IsUnicode

+  );

+

+#endif /* _BDSINTERNAL_H_ */

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootMenu.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootMenu.c
new file mode 100644
index 0000000..3cbafb5
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootMenu.c
@@ -0,0 +1,978 @@
+/** @file

+*

+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 "BdsInternal.h"

+#include <Guid/ArmGlobalVariableHob.h>

+#include <Library/ArmLib.h>

+#include <Library/BrdCommon.h>

+

+typedef  int (*LinuxEntry)();

+

+extern EFI_HANDLE mImageHandle;

+extern BDS_LOAD_OPTION_SUPPORT *BdsLoadOptionSupportList;

+extern EFI_STATUS

+ShutdownUefiBootServices (

+  VOID

+  );

+

+EFI_STATUS

+SelectBootDevice (

+  OUT BDS_SUPPORTED_DEVICE** SupportedBootDevice

+  )

+{

+  EFI_STATUS  Status;

+  LIST_ENTRY  SupportedDeviceList;

+  UINTN       SupportedDeviceCount;

+  LIST_ENTRY* Entry;

+  UINTN       SupportedDeviceSelected;

+  UINTN       Index;

+

+  //

+  // List the Boot Devices supported

+  //

+

+  // Start all the drivers first

+  BdsConnectAllDrivers ();

+

+  // List the supported devices

+  Status = BootDeviceListSupportedInit (&SupportedDeviceList);

+  ASSERT_EFI_ERROR(Status);

+

+  SupportedDeviceCount = 0;

+  for (Entry = GetFirstNode (&SupportedDeviceList);

+       !IsNull (&SupportedDeviceList,Entry);

+       Entry = GetNextNode (&SupportedDeviceList,Entry)

+       )

+  {

+    *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);

+    Print(L"[%d] %s\n",SupportedDeviceCount+1,(*SupportedBootDevice)->Description);

+

+    DEBUG_CODE_BEGIN();

+      CHAR16*                           DevicePathTxt;

+      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+

+      Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+      ASSERT_EFI_ERROR(Status);

+      DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText ((*SupportedBootDevice)->DevicePathProtocol,TRUE,TRUE);

+

+      Print(L"\t- %s\n",DevicePathTxt);

+

+      FreePool(DevicePathTxt);

+    DEBUG_CODE_END();

+

+    SupportedDeviceCount++;

+  }

+

+  if (SupportedDeviceCount == 0) {

+    Print(L"There is no supported device.\n");

+    Status = EFI_ABORTED;

+    goto EXIT;

+  }

+

+  //

+  // Select the Boot Device

+  //

+  SupportedDeviceSelected = 0;

+  while (SupportedDeviceSelected == 0) {

+    Print(L"Select the Boot Device: ");

+    Status = GetHIInputInteger (&SupportedDeviceSelected);

+    if (EFI_ERROR(Status)) {

+      Status = EFI_ABORTED;

+      goto EXIT;

+    } else if ((SupportedDeviceSelected == 0) || (SupportedDeviceSelected > SupportedDeviceCount)) {

+      Print(L"Invalid input (max %d)\n",SupportedDeviceCount);

+      SupportedDeviceSelected = 0;

+    }

+  }

+

+  //

+  // Get the Device Path for the selected boot device

+  //

+  Index = 1;

+  for (Entry = GetFirstNode (&SupportedDeviceList);

+       !IsNull (&SupportedDeviceList,Entry);

+       Entry = GetNextNode (&SupportedDeviceList,Entry)

+       )

+  {

+    if (Index == SupportedDeviceSelected) {

+      *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);

+      break;

+    }

+    Index++;

+  }

+

+EXIT:

+  BootDeviceListSupportedFree (&SupportedDeviceList, *SupportedBootDevice);

+  return Status;

+}

+

+EFI_STATUS

+BootMenuAddBootOption (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  EFI_STATUS                Status;

+  BDS_SUPPORTED_DEVICE*     SupportedBootDevice;

+  ARM_BDS_LOADER_ARGUMENTS* BootArguments;

+  CHAR16                    BootDescription[BOOT_DEVICE_DESCRIPTION_MAX];

+  CHAR8                     AsciiCmdLine[BOOT_DEVICE_OPTION_MAX];

+  CHAR16                    CmdLine[BOOT_DEVICE_OPTION_MAX];

+  UINT32                    Attributes;

+  ARM_BDS_LOADER_TYPE       BootType;

+  BDS_LOAD_OPTION_ENTRY     *BdsLoadOptionEntry;

+  EFI_DEVICE_PATH           *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNodes;

+  EFI_DEVICE_PATH_PROTOCOL  *InitrdPathNodes;

+  EFI_DEVICE_PATH_PROTOCOL  *InitrdPath;

+  UINTN                     CmdLineSize;

+  BOOLEAN                   InitrdSupport;

+  UINTN                     InitrdSize;

+  UINT8*                    OptionalData;

+  UINTN                     OptionalDataSize;

+  BOOLEAN                   RequestBootType;

+

+  Attributes                = 0;

+  SupportedBootDevice = NULL;

+

+  // List the Boot Devices supported

+  Status = SelectBootDevice (&SupportedBootDevice);

+  if (EFI_ERROR(Status)) {

+    Status = EFI_ABORTED;

+    goto EXIT;

+  }

+

+  // Create the specific device path node

+  RequestBootType = TRUE;

+  Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes, &RequestBootType);

+  if (EFI_ERROR(Status)) {

+    Status = EFI_ABORTED;

+    goto EXIT;

+  }

+  // Append the Device Path to the selected device path

+  DevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)DevicePathNodes);

+  if (DevicePath == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+

+  if (RequestBootType) {

+    Status = BootDeviceGetType (DevicePath, &BootType, &Attributes);

+    if (EFI_ERROR(Status)) {

+      Status = EFI_ABORTED;

+      goto EXIT;

+    }

+  } else {

+    BootType = BDS_LOADER_EFI_APPLICATION;

+  }

+

+  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {

+    Print(L"Add an initrd: ");

+    Status = GetHIInputBoolean (&InitrdSupport);

+    if (EFI_ERROR(Status)) {

+      Status = EFI_ABORTED;

+      goto EXIT;

+    }

+

+    if (InitrdSupport) {

+      // Create the specific device path node

+      Status = SupportedBootDevice->Support->CreateDevicePathNode (L"initrd", &InitrdPathNodes, NULL);

+      if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd

+        Status = EFI_ABORTED;

+        goto EXIT;

+      }

+

+      if (InitrdPathNodes != NULL) {

+        // Append the Device Path to the selected device path

+        InitrdPath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes);

+        if (InitrdPath == NULL) {

+          Status = EFI_OUT_OF_RESOURCES;

+          goto EXIT;

+        }

+      } else {

+        InitrdPath = NULL;

+      }

+    } else {

+      InitrdPath = NULL;

+    }

+

+    Print(L"Arguments to pass to the binary: ");

+    Status = GetHIInputAscii (AsciiCmdLine, BOOT_DEVICE_OPTION_MAX);

+    if (EFI_ERROR(Status)) {

+      Status = EFI_ABORTED;

+      goto FREE_DEVICE_PATH;

+    }

+

+    CmdLineSize = AsciiStrSize (AsciiCmdLine);

+    InitrdSize = GetDevicePathSize (InitrdPath);

+

+    OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize;

+    BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize);

+

+    BootArguments->LinuxArguments.CmdLineSize = CmdLineSize;

+    BootArguments->LinuxArguments.InitrdSize = InitrdSize;

+    CopyMem ((VOID*)(&BootArguments->LinuxArguments + 1), CmdLine, CmdLineSize);

+    CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize);

+

+    OptionalData = (UINT8*)BootArguments;

+  } else {

+    Print (L"Arguments to pass to the EFI Application: ");

+    Status = GetHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX);

+    if (EFI_ERROR (Status)) {

+      Status = EFI_ABORTED;

+      goto EXIT;

+    }

+

+    OptionalData = (UINT8*)CmdLine;

+    OptionalDataSize = StrSize (CmdLine);

+  }

+

+  Print(L"Description for this new Entry: ");

+  Status = GetHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX);

+  if (EFI_ERROR(Status)) {

+    Status = EFI_ABORTED;

+    goto FREE_DEVICE_PATH;

+  }

+

+  // Create new entry

+  BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof(BDS_LOAD_OPTION_ENTRY));

+  Status = BootOptionCreate (Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOptionEntry->BdsLoadOption);

+  if (!EFI_ERROR(Status)) {

+    InsertTailList (BootOptionsList, &BdsLoadOptionEntry->Link);

+  }

+

+FREE_DEVICE_PATH:

+  FreePool (DevicePath);

+

+EXIT:

+  if (Status == EFI_ABORTED) {

+    Print(L"\n");

+  }

+  FreePool(SupportedBootDevice);

+  return Status;

+}

+

+STATIC

+EFI_STATUS

+BootMenuSelectBootOption (

+  IN  LIST_ENTRY*               BootOptionsList,

+  IN  CONST CHAR16*             InputStatement,

+  OUT BDS_LOAD_OPTION_ENTRY**   BdsLoadOptionEntry

+  )

+{

+  EFI_STATUS                    Status;

+  LIST_ENTRY*                   Entry;

+  BDS_LOAD_OPTION*              BdsLoadOption;

+  UINTN                         BootOptionSelected;

+  UINTN                         BootOptionCount;

+  UINTN                         Index;

+  BOOLEAN                       IsUnicode;

+

+  // Display the list of supported boot devices

+  BootOptionCount = 0;

+  for (Entry = GetFirstNode (BootOptionsList);

+       !IsNull (BootOptionsList,Entry);

+       Entry = GetNextNode (BootOptionsList, Entry)

+       )

+  {

+    BdsLoadOption = LOAD_OPTION_FROM_LINK(Entry);

+

+    Print (L"[%d] %s\n", (BootOptionCount + 1), BdsLoadOption->Description);

+

+    DEBUG_CODE_BEGIN();

+      CHAR16*                           DevicePathTxt;

+      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+      ARM_BDS_LOADER_TYPE               LoaderType;

+      ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;

+

+      Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+      ASSERT_EFI_ERROR(Status);

+      DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(BdsLoadOption->FilePathList,TRUE,TRUE);

+

+      Print(L"\t- %s\n",DevicePathTxt);

+      OptionalData = BdsLoadOption->OptionalData;

+      if (IS_ARM_BDS_BOOTENTRY (BdsLoadOption)) {

+        LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);

+        if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT)) {

+          Print (L"\t- Arguments: %a\n",&OptionalData->Arguments.LinuxArguments + 1);

+        }

+      } else if (OptionalData != NULL) {

+        if (IsPrintableString (OptionalData, &IsUnicode)) {

+          if (IsUnicode) {

+            Print (L"\t- Arguments: %s\n", OptionalData);

+          } else {

+            AsciiPrint ("\t- Arguments: %a\n", OptionalData);

+          }

+        }

+      }

+

+      FreePool(DevicePathTxt);

+    DEBUG_CODE_END();

+

+    BootOptionCount++;

+  }

+

+  // Check if a valid boot option(s) is found

+  if (BootOptionCount == 0) {

+    if (StrCmp (InputStatement, DELETE_BOOT_ENTRY) == 0) {

+      Print (L"Nothing to remove!\n");

+    } else if (StrCmp (InputStatement, UPDATE_BOOT_ENTRY) == 0) {

+      Print (L"Couldn't find valid boot entries\n");

+    } else{

+      Print (L"No supported Boot Entry.\n");

+    }

+

+    return EFI_NOT_FOUND;

+  }

+

+  // Get the index of the boot device to delete

+  BootOptionSelected = 0;

+  while (BootOptionSelected == 0) {

+    Print(InputStatement);

+    Status = GetHIInputInteger (&BootOptionSelected);

+    if (EFI_ERROR(Status)) {

+      return Status;

+    } else if ((BootOptionSelected == 0) || (BootOptionSelected > BootOptionCount)) {

+      Print(L"Invalid input (max %d)\n",BootOptionCount);

+      BootOptionSelected = 0;

+    }

+  }

+

+  // Get the structure of the Boot device to delete

+  Index = 1;

+  for (Entry = GetFirstNode (BootOptionsList);

+       !IsNull (BootOptionsList, Entry);

+       Entry = GetNextNode (BootOptionsList,Entry)

+       )

+  {

+    if (Index == BootOptionSelected) {

+      *BdsLoadOptionEntry = LOAD_OPTION_ENTRY_FROM_LINK(Entry);

+      break;

+    }

+    Index++;

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BootMenuRemoveBootOption (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  EFI_STATUS                    Status;

+  BDS_LOAD_OPTION_ENTRY*        BootOptionEntry;

+

+  Status = BootMenuSelectBootOption (BootOptionsList, DELETE_BOOT_ENTRY, &BootOptionEntry);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  // If the Boot Option was attached to a list remove it

+  if (!IsListEmpty (&BootOptionEntry->Link)) {

+    // Remove the entry from the list

+    RemoveEntryList (&BootOptionEntry->Link);

+  }

+

+  // Delete the BDS Load option structures

+  BootOptionDelete (BootOptionEntry->BdsLoadOption);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BootMenuUpdateBootOption (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  EFI_STATUS                    Status;

+  BDS_LOAD_OPTION_ENTRY         *BootOptionEntry;

+  BDS_LOAD_OPTION               *BootOption;

+  BDS_LOAD_OPTION_SUPPORT*      DeviceSupport;

+  ARM_BDS_LOADER_ARGUMENTS*     BootArguments;

+  CHAR16                        BootDescription[BOOT_DEVICE_DESCRIPTION_MAX];

+  CHAR8                         CmdLine[BOOT_DEVICE_OPTION_MAX];

+  CHAR16                        UnicodeCmdLine[BOOT_DEVICE_OPTION_MAX];

+  EFI_DEVICE_PATH               *DevicePath;

+  EFI_DEVICE_PATH               *TempInitrdPath;

+  ARM_BDS_LOADER_TYPE           BootType;

+  ARM_BDS_LOADER_OPTIONAL_DATA* LoaderOptionalData;

+  ARM_BDS_LINUX_ARGUMENTS*      LinuxArguments;

+  EFI_DEVICE_PATH               *InitrdPathNodes;

+  EFI_DEVICE_PATH               *InitrdPath;

+  UINTN                         InitrdSize;

+  UINTN                         CmdLineSize;

+  BOOLEAN                       InitrdSupport;

+  UINT8*                        OptionalData;

+  UINTN                         OptionalDataSize;

+  BOOLEAN                       RequestBootType;

+  BOOLEAN                       IsPrintable;

+  BOOLEAN                       IsUnicode;

+

+  Status = BootMenuSelectBootOption (BootOptionsList, UPDATE_BOOT_ENTRY, &BootOptionEntry);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+  BootOption = BootOptionEntry->BdsLoadOption;

+

+  // Get the device support for this Boot Option

+  Status = BootDeviceGetDeviceSupport (BootOption->FilePathList, &DeviceSupport);

+  if (EFI_ERROR(Status)) {

+    Print(L"Not possible to retrieve the supported device for the update\n");

+    return EFI_UNSUPPORTED;

+  }

+

+  RequestBootType = TRUE;

+  Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath, &RequestBootType);

+  if (EFI_ERROR(Status)) {

+    Status = EFI_ABORTED;

+    goto EXIT;

+  }

+

+  if (RequestBootType) {

+    Status = BootDeviceGetType (DevicePath, &BootType, &BootOption->Attributes);

+    if (EFI_ERROR(Status)) {

+      Status = EFI_ABORTED;

+      goto EXIT;

+    }

+  }

+

+  LoaderOptionalData = BootOption->OptionalData;

+  if (LoaderOptionalData != NULL) {

+    BootType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((UINT32 *)(&LoaderOptionalData->Header.LoaderType));

+  } else {

+    BootType = BDS_LOADER_EFI_APPLICATION;

+  }

+

+  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {

+    LinuxArguments = &LoaderOptionalData->Arguments.LinuxArguments;

+

+    CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);

+

+    InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);

+    if (InitrdSize > 0) {

+      Print(L"Keep the initrd: ");

+    } else {

+      Print(L"Add an initrd: ");

+    }

+    Status = GetHIInputBoolean (&InitrdSupport);

+    if (EFI_ERROR(Status)) {

+      Status = EFI_ABORTED;

+      goto EXIT;

+    }

+

+    if (InitrdSupport) {

+      if (InitrdSize > 0) {

+        // Case we update the initrd device path

+        Status = DeviceSupport->UpdateDevicePathNode ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize), L"initrd", &InitrdPath, NULL);

+        if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {// EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd

+          Status = EFI_ABORTED;

+          goto EXIT;

+        }

+        InitrdSize = GetDevicePathSize (InitrdPath);

+      } else {

+        // Case we create the initrd device path

+

+        Status = DeviceSupport->CreateDevicePathNode (L"initrd", &InitrdPathNodes, NULL);

+        if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd

+          Status = EFI_ABORTED;

+          goto EXIT;

+        }

+

+        if (InitrdPathNodes != NULL) {

+          // Duplicate Linux kernel Device Path

+          TempInitrdPath = DuplicateDevicePath (BootOption->FilePathList);

+          // Replace Linux kernel Node by EndNode

+          SetDevicePathEndNode (GetLastDevicePathNode (TempInitrdPath));

+          // Append the Device Path to the selected device path

+          InitrdPath = AppendDevicePath (TempInitrdPath, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes);

+          FreePool (TempInitrdPath);

+          if (InitrdPath == NULL) {

+            Status = EFI_OUT_OF_RESOURCES;

+            goto EXIT;

+          }

+          InitrdSize = GetDevicePathSize (InitrdPath);

+        } else {

+          InitrdPath = NULL;

+        }

+      }

+    } else {

+      InitrdSize = 0;

+    }

+

+    Print(L"Arguments to pass to the binary: ");

+    if (CmdLineSize > 0) {

+      AsciiStrnCpy(CmdLine, (CONST CHAR8*)(LinuxArguments + 1), CmdLineSize);

+    } else {

+      CmdLine[0] = '\0';

+    }

+    Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX);

+    if (EFI_ERROR(Status)) {

+      Status = EFI_ABORTED;

+      goto FREE_DEVICE_PATH;

+    }

+

+    CmdLineSize = AsciiStrSize (CmdLine);

+

+    OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize;

+    BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize);

+    BootArguments->LinuxArguments.CmdLineSize = CmdLineSize;

+    BootArguments->LinuxArguments.InitrdSize = InitrdSize;

+    CopyMem (&BootArguments->LinuxArguments + 1, CmdLine, CmdLineSize);

+    CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize);

+

+    OptionalData = (UINT8*)BootArguments;

+  } else {

+    Print (L"Arguments to pass to the EFI Application: ");

+

+    if (BootOption->OptionalDataSize > 0) {

+      IsPrintable = IsPrintableString (BootOption->OptionalData, &IsUnicode);

+      if (IsPrintable) {

+        if (IsUnicode) {

+          StrnCpy (UnicodeCmdLine, BootOption->OptionalData, BootOption->OptionalDataSize / 2);

+        } else {

+          AsciiStrnCpy (CmdLine, BootOption->OptionalData, BootOption->OptionalDataSize);

+        }

+      }

+    } else {

+      UnicodeCmdLine[0] = L'\0';

+      IsPrintable = TRUE;

+      IsUnicode = TRUE;

+    }

+

+    // We do not request arguments for OptionalData that cannot be printed

+    if (IsPrintable) {

+      if (IsUnicode) {

+        Status = EditHIInputStr (UnicodeCmdLine, BOOT_DEVICE_OPTION_MAX);

+        if (EFI_ERROR (Status)) {

+          Status = EFI_ABORTED;

+          goto FREE_DEVICE_PATH;

+        }

+

+        OptionalData = (UINT8*)UnicodeCmdLine;

+        OptionalDataSize = StrSize (UnicodeCmdLine);

+      } else {

+        Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX);

+        if (EFI_ERROR (Status)) {

+          Status = EFI_ABORTED;

+          goto FREE_DEVICE_PATH;

+        }

+

+        OptionalData = (UINT8*)CmdLine;

+        OptionalDataSize = AsciiStrSize (CmdLine);

+      }

+    } else {

+      // We keep the former OptionalData

+      OptionalData = BootOption->OptionalData;

+      OptionalDataSize = BootOption->OptionalDataSize;

+    }

+  }

+

+  Print(L"Description for this new Entry: ");

+  StrnCpy (BootDescription, BootOption->Description, BOOT_DEVICE_DESCRIPTION_MAX);

+  Status = EditHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX);

+  if (EFI_ERROR(Status)) {

+    Status = EFI_ABORTED;

+    goto FREE_DEVICE_PATH;

+  }

+

+  // Update the entry

+  Status = BootOptionUpdate (BootOption, BootOption->Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);

+

+FREE_DEVICE_PATH:

+  FreePool (DevicePath);

+

+EXIT:

+  if (Status == EFI_ABORTED) {

+    Print(L"\n");

+  }

+  return Status;

+}

+

+EFI_STATUS

+UpdateFdtPath (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  EFI_STATUS                Status;

+  UINTN                     FdtDevicePathSize;

+  BDS_SUPPORTED_DEVICE      *SupportedBootDevice;

+  EFI_DEVICE_PATH_PROTOCOL  *FdtDevicePathNodes;

+  EFI_DEVICE_PATH_PROTOCOL  *FdtDevicePath;

+

+  Status = SelectBootDevice (&SupportedBootDevice);

+  if (EFI_ERROR(Status)) {

+    Status = EFI_ABORTED;

+    goto EXIT;

+  }

+

+  // Create the specific device path node

+  Status = SupportedBootDevice->Support->CreateDevicePathNode (L"FDT blob", &FdtDevicePathNodes, NULL);

+  if (EFI_ERROR(Status)) {

+    Status = EFI_ABORTED;

+    goto EXIT;

+  }

+

+  if (FdtDevicePathNodes != NULL) {

+    // Append the Device Path node to the select device path

+    FdtDevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, FdtDevicePathNodes);

+    FdtDevicePathSize = GetDevicePathSize (FdtDevicePath);

+    Status = gRT->SetVariable (

+                    (CHAR16*)L"Fdt",

+                    &gArmGlobalVariableGuid,

+                    EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,

+                    FdtDevicePathSize,

+                    FdtDevicePath

+                    );

+    ASSERT_EFI_ERROR(Status);

+  } else {

+    gRT->SetVariable (

+           (CHAR16*)L"Fdt",

+           &gArmGlobalVariableGuid,

+           EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,

+           0,

+           NULL

+           );

+    ASSERT_EFI_ERROR(Status);

+  }

+

+EXIT:

+  if (Status == EFI_ABORTED) {

+    Print(L"\n");

+  }

+  FreePool(SupportedBootDevice);

+  return Status;

+}

+

+struct BOOT_MANAGER_ENTRY {

+  CONST CHAR16* Description;

+  EFI_STATUS (*Callback) (IN LIST_ENTRY *BootOptionsList);

+} BootManagerEntries[] = {

+    { L"Add Boot Device Entry", BootMenuAddBootOption },

+    { L"Update Boot Device Entry", BootMenuUpdateBootOption },

+    { L"Remove Boot Device Entry", BootMenuRemoveBootOption },

+    { L"Update FDT path", UpdateFdtPath },

+};

+

+EFI_STATUS

+BootMenuManager (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  UINTN Index;

+  UINTN OptionSelected;

+  UINTN BootManagerEntryCount;

+  EFI_STATUS Status;

+

+  BootManagerEntryCount = sizeof(BootManagerEntries) / sizeof(struct BOOT_MANAGER_ENTRY);

+

+  while (TRUE) {

+    // Display Boot Manager menu

+    for (Index = 0; Index < BootManagerEntryCount; Index++) {

+      Print(L"[%d] %s\n",Index+1,BootManagerEntries[Index]);

+    }

+    Print(L"[%d] Return to main menu\n",Index+1);

+

+    // Select which entry to call

+    Print(L"Choice: ");

+    Status = GetHIInputInteger (&OptionSelected);

+    if (EFI_ERROR(Status) || (OptionSelected == (BootManagerEntryCount+1))) {

+      if (EFI_ERROR(Status)) {

+        Print(L"\n");

+      }

+      return EFI_SUCCESS;

+    } else if ((OptionSelected > 0) && (OptionSelected <= BootManagerEntryCount))  {

+      BootManagerEntries[OptionSelected-1].Callback (BootOptionsList);

+    }

+  }

+  // Should never go here

+}

+

+EFI_STATUS

+BootEBL (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  EFI_STATUS Status;

+

+  // Start EFI Shell

+  Status = BdsLoadApplication (mImageHandle, (CHAR16 *)L"Ebl", 0, NULL);

+  if (Status == EFI_NOT_FOUND) {

+    Print ((CHAR16 *)L"Error: EFI Application not found.\n");

+  } else if (EFI_ERROR(Status)) {

+    Print ((CHAR16 *)L"Error: Status Code: 0x%X\n",(UINT32)Status);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+BootShell (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  EFI_STATUS Status;

+

+  // Start EFI Shell

+  Status = BdsLoadApplication (mImageHandle, L"Shell", 0, NULL);

+  if (Status == EFI_NOT_FOUND) {

+    Print (L"Error: EFI Application not found.\n");

+  } else if (EFI_ERROR(Status)) {

+    Print (L"Error: Status Code: 0x%X\n",(UINT32)Status);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+Reboot (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+Shutdown (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  gRT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+BootLinuxAtagLoader (

+  IN LIST_ENTRY *BootOptionsList

+  )

+{

+  EFI_STATUS Status;

+

+  Status = BdsLoadApplication (mImageHandle, (CHAR16 *)L"LinuxAtagLoader", 0, NULL);

+  if (Status == EFI_NOT_FOUND) {

+    Print ((CHAR16 *)L"Error: EFI Application linuxloader not found.\n");

+  } else if (EFI_ERROR(Status)) {

+    Print ((CHAR16 *)L"Error: Status Code: 0x%X\n",(UINT32)Status);

+  }

+

+  return Status;

+}

+

+EFI_STATUS LoadLinuxAtSecEnd()

+{

+    LinuxEntry entry = (LinuxEntry)(TEXT_SRAM_BASE);

+    EFI_STATUS Status = EFI_SUCCESS;

+    ArmDisableDataCache();

+    ArmCleanInvalidateDataCache();

+    ArmDisableInstructionCache ();

+    ArmInvalidateInstructionCache ();

+    ArmDisableMmu();

+    DEBUG(( EFI_D_ERROR, "MOVE PC TEXT_SRAM_BASE\n"));

+    (void)entry();

+    return Status;

+}

+

+EFI_STATUS RunBootwrapper(unsigned long kernel_entry)
+{

+  EFI_STATUS Status;

+

+  *(UINTN*)(UINTN)(0xe302b000 + 0x18) = 0;

+  *(UINTN*)(UINTN)(0xe302b000 + 0x1c) = 0;

+

+  *(volatile UINT32 *)(0xe0000000 + 0x100) = TEXT_SRAM_BASE;

+  *(volatile UINT32 *)(TEXT_SRAM_BASE + 0x800) = kernel_entry;
+

+  ArmCleanDataCache();

+  *(UINT8*)(0xf4007000) = 'G';

+  Status = LoadLinuxAtSecEnd();

+  if (EFI_ERROR(Status))

+  {

+      (VOID)AsciiPrint ("GoCmd error!\n");

+  }

+

+  return Status;

+}

+

+EFI_STATUS
+BootGo (
+  IN LIST_ENTRY *BootOptionsList
+  )
+{
+  EFI_STATUS Status;
+
+  Status = ShutdownUefiBootServices ();
+  if(EFI_ERROR(Status)) {
+  DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
+  }
+
+  Status = RunBootwrapper(KERNEL_DDR_BASE);
+
+  return Status;
+}
+
+struct BOOT_MAIN_ENTRY {

+  CONST CHAR16* Description;

+  EFI_STATUS (*Callback) (IN LIST_ENTRY *BootOptionsList);

+} BootMainEntries[] = {

+    { L"Boot Manager", BootMenuManager },

+    { L"EBL", BootEBL },

+    { L"Shell", BootShell },

+    { L"Reboot", Reboot },

+    { L"Shutdown", Shutdown },

+    { L"GO", BootGo },

+};

+

+

+EFI_STATUS

+BootMenuMain (

+  VOID

+  )

+{

+  LIST_ENTRY                    BootOptionsList;

+  UINTN                         OptionCount;

+  UINTN                         BootOptionCount;

+  EFI_STATUS                    Status;

+  LIST_ENTRY*                   Entry;

+  BDS_LOAD_OPTION*              BootOption;

+  UINTN                         BootOptionSelected;

+  UINTN                         Index;

+  UINTN                         BootMainEntryCount;

+  BOOLEAN                       IsUnicode;

+

+  BootOption         = NULL;

+  BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY);

+

+  while (TRUE) {

+    // Get Boot#### list

+    BootOptionList (&BootOptionsList);

+

+    OptionCount = 1;

+

+    // Display the Boot options

+    for (Entry = GetFirstNode (&BootOptionsList);

+         !IsNull (&BootOptionsList,Entry);

+         Entry = GetNextNode (&BootOptionsList,Entry)

+         )

+    {

+      BootOption = LOAD_OPTION_FROM_LINK(Entry);

+

+      Print(L"[%d] %s\n", OptionCount, BootOption->Description);

+

+      DEBUG_CODE_BEGIN();

+        CHAR16*                           DevicePathTxt;

+        EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;

+        ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;

+        UINTN                             CmdLineSize;

+        ARM_BDS_LOADER_TYPE               LoaderType;

+

+        Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);

+        if (EFI_ERROR(Status)) {

+          // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe)

+          DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n"));

+          return Status;

+        }

+        DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE);

+

+        Print(L"\t- %s\n",DevicePathTxt);

+

+        // If it is a supported BootEntry then print its details

+        if (IS_ARM_BDS_BOOTENTRY (BootOption)) {

+          OptionalData = BootOption->OptionalData;

+          LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);

+          if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT)) {

+            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.InitrdSize) > 0) {

+              CmdLineSize = ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize);

+              DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (

+                  GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(&OptionalData->Arguments.LinuxArguments + 1) + CmdLineSize)), TRUE, TRUE);

+              Print(L"\t- Initrd: %s\n", DevicePathTxt);

+            }

+            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize) > 0) {

+              Print(L"\t- Arguments: %a\n", (&OptionalData->Arguments.LinuxArguments + 1));

+            }

+          }

+

+          switch (LoaderType) {

+            case BDS_LOADER_EFI_APPLICATION:

+              Print(L"\t- LoaderType: EFI Application\n");

+              break;

+

+            case BDS_LOADER_KERNEL_LINUX_ATAG:

+              Print(L"\t- LoaderType: Linux kernel with ATAG support\n");

+              break;

+

+            case BDS_LOADER_KERNEL_LINUX_FDT:

+              Print(L"\t- LoaderType: Linux kernel with FDT support\n");

+              break;

+

+            default:

+              Print(L"\t- LoaderType: Not recognized (%d)\n", LoaderType);

+          }

+        } else if (BootOption->OptionalData != NULL) {

+          if (IsPrintableString (BootOption->OptionalData, &IsUnicode)) {

+            if (IsUnicode) {

+              Print (L"\t- Arguments: %s\n", BootOption->OptionalData);

+            } else {

+              AsciiPrint ("\t- Arguments: %a\n", BootOption->OptionalData);

+            }

+          }

+        }

+        FreePool(DevicePathTxt);

+      DEBUG_CODE_END();

+

+      OptionCount++;

+    }

+    BootOptionCount = OptionCount-1;

+

+    // Display the hardcoded Boot entries

+    for (Index = 0; Index < BootMainEntryCount; Index++) {

+      Print(L"[%d] %s\n",OptionCount,BootMainEntries[Index]);

+      OptionCount++;

+    }

+

+    // Request the boot entry from the user

+    BootOptionSelected = 0;

+    while (BootOptionSelected == 0) {

+      Print(L"Start: ");

+      Status = GetHIInputInteger (&BootOptionSelected);

+      if (EFI_ERROR(Status) || (BootOptionSelected == 0) || (BootOptionSelected > OptionCount)) {

+        Print(L"Invalid input (max %d)\n",(OptionCount-1));

+        BootOptionSelected = 0;

+      }

+    }

+

+    // Start the selected entry

+    if (BootOptionSelected > BootOptionCount) {

+      // Start the hardcoded entry

+      Status = BootMainEntries[BootOptionSelected - BootOptionCount - 1].Callback (&BootOptionsList);

+    } else {

+      // Find the selected entry from the Boot#### list

+      Index = 1;

+      for (Entry = GetFirstNode (&BootOptionsList);

+           !IsNull (&BootOptionsList,Entry);

+           Entry = GetNextNode (&BootOptionsList,Entry)

+           )

+      {

+        if (Index == BootOptionSelected) {

+          BootOption = LOAD_OPTION_FROM_LINK(Entry);

+          break;

+        }

+        Index++;

+      }

+

+      Status = BootOptionStart (BootOption);

+    }

+  }

+  // Should never go here

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootOption.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootOption.c
new file mode 100644
index 0000000..52c9d83
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootOption.c
@@ -0,0 +1,407 @@
+/** @file

+*

+*  Copyright (c) 2011-2013, ARM 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.

+*

+**/

+

+#include <Guid/ArmGlobalVariableHob.h>

+#include "BdsInternal.h"

+

+extern EFI_HANDLE mImageHandle;

+

+EFI_STATUS

+BootOptionStart (

+  IN BDS_LOAD_OPTION *BootOption

+  )

+{

+  EFI_STATUS                            Status;

+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL*   EfiDevicePathFromTextProtocol;

+  UINT32                                LoaderType;

+  ARM_BDS_LOADER_OPTIONAL_DATA*         OptionalData;

+  ARM_BDS_LINUX_ARGUMENTS*              LinuxArguments;

+  EFI_DEVICE_PATH_PROTOCOL*             FdtDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL*             DefaultFdtDevicePath;

+  UINTN                                 FdtDevicePathSize;

+  UINTN                                 CmdLineSize;

+  UINTN                                 InitrdSize;

+  EFI_DEVICE_PATH*                      Initrd;

+  UINT16                                LoadOptionIndexSize;

+

+  if (IS_ARM_BDS_BOOTENTRY (BootOption)) {

+    Status = EFI_UNSUPPORTED;

+    OptionalData = BootOption->OptionalData;

+    LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);

+

+    if (LoaderType == BDS_LOADER_EFI_APPLICATION) {

+      if ((BootOption->Attributes & LOAD_OPTION_CATEGORY_BOOT) == 0) {

+        // Need to connect every drivers to ensure no dependencies are missing for the application

+        BdsConnectAllDrivers ();

+      }

+

+      Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, 0, NULL);

+    } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {

+      LinuxArguments = &(OptionalData->Arguments.LinuxArguments);

+      CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);

+      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);

+

+      if (InitrdSize > 0) {

+        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));

+      } else {

+        Initrd = NULL;

+      }

+

+      Status = BdsBootLinuxAtag (BootOption->FilePathList,

+                                 Initrd, // Initrd

+                                 (CHAR8*)(LinuxArguments + 1)); // CmdLine

+    } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {

+      LinuxArguments = &(OptionalData->Arguments.LinuxArguments);

+      CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);

+      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);

+

+      if (InitrdSize > 0) {

+        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));

+      } else {

+        Initrd = NULL;

+      }

+

+      // Get the default FDT device path

+      Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);

+      ASSERT_EFI_ERROR(Status);

+      DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));

+

+      // Get the FDT device path

+      FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);

+      Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid,

+                 DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);

+      ASSERT_EFI_ERROR(Status);

+

+      Status = BdsBootLinuxFdt (BootOption->FilePathList,

+                                Initrd, // Initrd

+                                (CHAR8*)(LinuxArguments + 1),

+                                FdtDevicePath);

+

+      FreePool (DefaultFdtDevicePath);

+      FreePool (FdtDevicePath);

+    }

+  } else {

+    // Connect all the drivers if the EFI Application is not a EFI OS Loader

+    if ((BootOption->Attributes & LOAD_OPTION_CATEGORY_BOOT) == 0) {

+      BdsConnectAllDrivers ();

+    }

+

+    // Set BootCurrent variable

+    LoadOptionIndexSize = sizeof(UINT16);

+    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,

+              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+              LoadOptionIndexSize, &(BootOption->LoadOptionIndex));

+

+    Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData);

+

+    // Clear BootCurrent variable

+    LoadOptionIndexSize = sizeof(UINT16);

+    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,

+              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+              0, NULL);

+  }

+

+  return Status;

+}

+

+EFI_STATUS

+BootOptionList (

+  IN OUT LIST_ENTRY *BootOptionList

+  )

+{

+  EFI_STATUS                    Status;

+  UINTN                         Index;

+  UINT16*                       BootOrder;

+  UINTN                         BootOrderSize;

+  BDS_LOAD_OPTION*              BdsLoadOption;

+  BDS_LOAD_OPTION_ENTRY*        BdsLoadOptionEntry;

+

+  InitializeListHead (BootOptionList);

+

+  // Get the Boot Option Order from the environment variable

+  Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {

+    Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption);

+    if (!EFI_ERROR(Status)) {

+      BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool(sizeof(BDS_LOAD_OPTION_ENTRY));

+      BdsLoadOptionEntry->BdsLoadOption = BdsLoadOption;

+      InsertTailList (BootOptionList,&BdsLoadOptionEntry->Link);

+    }

+  }

+

+  FreePool (BootOrder);

+

+  return EFI_SUCCESS;

+}

+

+STATIC

+EFI_STATUS

+BootOptionSetFields (

+  IN BDS_LOAD_OPTION*           BootOption,

+  IN UINT32                     Attributes,

+  IN CHAR16*                    BootDescription,

+  IN EFI_DEVICE_PATH_PROTOCOL*  DevicePath,

+  IN ARM_BDS_LOADER_TYPE        BootType,

+  IN UINT8*                     OptionalData,

+  IN UINTN                      OptionalDataSize

+  )

+{

+  EFI_LOAD_OPTION               EfiLoadOption;

+  UINTN                         EfiLoadOptionSize;

+  UINTN                         BootDescriptionSize;

+  UINT16                        FilePathListLength;

+  UINT8*                        EfiLoadOptionPtr;

+  UINT8*                        InitrdPathListPtr;

+  ARM_BDS_LINUX_ARGUMENTS*      DestLinuxArguments;

+  ARM_BDS_LINUX_ARGUMENTS*      SrcLinuxArguments;

+  ARM_BDS_LOADER_ARGUMENTS*     BootArguments;

+

+  // If we are overwriting an existent Boot Option then we have to free previously allocated memory

+  if (BootOption->LoadOption) {

+    FreePool (BootOption->LoadOption);

+  }

+

+  BootDescriptionSize = StrSize (BootDescription);

+

+  // Fixup the size in case of entry specific to ArmPlatformPkg/Bds

+  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {

+    OptionalDataSize += sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);

+  }

+

+  // Compute the size of the FilePath list

+  FilePathListLength = GetUnalignedDevicePathSize (DevicePath);

+

+  // Allocate the memory for the EFI Load Option

+  EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + OptionalDataSize;

+  EfiLoadOption = (EFI_LOAD_OPTION)AllocatePool(EfiLoadOptionSize);

+  EfiLoadOptionPtr = EfiLoadOption;

+

+  //

+  // Populate the EFI Load Option and BDS Boot Option structures

+  //

+

+  // Attributes fields

+  BootOption->Attributes = Attributes;

+  *(UINT32*)EfiLoadOptionPtr = Attributes;

+  EfiLoadOptionPtr += sizeof(UINT32);

+

+  // FilePath List fields

+  BootOption->FilePathListLength = FilePathListLength;

+  *(UINT16*)EfiLoadOptionPtr = FilePathListLength;

+  EfiLoadOptionPtr += sizeof(UINT16);

+

+  // Boot description fields

+  BootOption->Description = (CHAR16*)EfiLoadOptionPtr;

+  CopyMem (EfiLoadOptionPtr, BootDescription, BootDescriptionSize);

+  EfiLoadOptionPtr += BootDescriptionSize;

+

+  // File path fields

+  BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr;

+  CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength);

+  EfiLoadOptionPtr += FilePathListLength;

+

+  // Optional Data fields, Do unaligned writes

+  BootOption->OptionalData = EfiLoadOptionPtr;

+

+  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {

+    // Write the header

+    WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE);

+    WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType);

+

+    BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)OptionalData;

+    SrcLinuxArguments = &(BootArguments->LinuxArguments);

+    DestLinuxArguments = &((ARM_BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxArguments;

+

+    WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->CmdLineSize), SrcLinuxArguments->CmdLineSize);

+    WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->InitrdSize), SrcLinuxArguments->InitrdSize);

+

+    if (SrcLinuxArguments->CmdLineSize > 0) {

+      CopyMem ((VOID*)(DestLinuxArguments + 1), (VOID*)(SrcLinuxArguments + 1), SrcLinuxArguments->CmdLineSize);

+    }

+

+    if (SrcLinuxArguments->InitrdSize > 0) {

+      InitrdPathListPtr = (UINT8*)((UINTN)(DestLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize);

+      CopyMem (InitrdPathListPtr, (VOID*)((UINTN)(SrcLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize), SrcLinuxArguments->InitrdSize);

+    }

+  } else {

+    CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize);

+  }

+  BootOption->OptionalDataSize = OptionalDataSize;

+

+  // If this function is called at the creation of the Boot Device entry (not at the update) the

+  // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry

+  if (BootOption->LoadOptionSize == 0) {

+    BootOption->LoadOptionIndex = BootOptionAllocateBootIndex ();

+  }

+

+  // Fill the EFI Load option fields

+  BootOption->LoadOption = EfiLoadOption;

+  BootOption->LoadOptionSize = EfiLoadOptionSize;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BootOptionCreate (

+  IN  UINT32                    Attributes,

+  IN  CHAR16*                   BootDescription,

+  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,

+  IN  ARM_BDS_LOADER_TYPE       BootType,

+  IN  UINT8*                    OptionalData,

+  IN  UINTN                     OptionalDataSize,

+  OUT BDS_LOAD_OPTION**         BdsLoadOption

+  )

+{

+  EFI_STATUS                    Status;

+  BDS_LOAD_OPTION_ENTRY*        BootOptionEntry;

+  BDS_LOAD_OPTION*              BootOption;

+  CHAR16                        BootVariableName[9];

+  UINT16*                       BootOrder;

+  UINTN                         BootOrderSize;

+

+  //

+  // Allocate and fill the memory for the BDS Load Option structure

+  //

+  BootOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof (BDS_LOAD_OPTION_ENTRY));

+  InitializeListHead (&BootOptionEntry->Link);

+  BootOptionEntry->BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));

+

+  BootOption = BootOptionEntry->BdsLoadOption;

+  BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);

+

+  //

+  // Set the related environment variables

+  //

+

+  // Create Boot#### environment variable

+  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);

+  Status = gRT->SetVariable (

+      BootVariableName,

+      &gEfiGlobalVariableGuid,

+      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+      BootOption->LoadOptionSize,

+      BootOption->LoadOption

+      );

+

+  // Add the new Boot Index to the list

+  Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);

+  if (!EFI_ERROR(Status)) {

+    BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder);

+    // Add the new index at the end

+    BootOrder[BootOrderSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;

+    BootOrderSize += sizeof(UINT16);

+  } else {

+    // BootOrder does not exist. Create it

+    BootOrderSize = sizeof(UINT16);

+    BootOrder = &(BootOption->LoadOptionIndex);

+  }

+

+  // Update (or Create) the BootOrder environment variable

+  Status = gRT->SetVariable (

+      L"BootOrder",

+      &gEfiGlobalVariableGuid,

+      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+      BootOrderSize,

+      BootOrder

+      );

+

+  // We only free it if the UEFI Variable 'BootOrder' was already existing

+  if (BootOrderSize > sizeof(UINT16)) {

+    FreePool (BootOrder);

+  }

+

+  *BdsLoadOption = BootOption;

+  return Status;

+}

+

+EFI_STATUS

+BootOptionUpdate (

+  IN  BDS_LOAD_OPTION*          BdsLoadOption,

+  IN  UINT32                    Attributes,

+  IN  CHAR16*                   BootDescription,

+  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,

+  IN  ARM_BDS_LOADER_TYPE       BootType,

+  IN UINT8*                     OptionalData,

+  IN UINTN                      OptionalDataSize

+  )

+{

+  EFI_STATUS      Status;

+  CHAR16          BootVariableName[9];

+

+  // Update the BDS Load Option structure

+  BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);

+

+  // Update the related environment variables

+  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex);

+

+  Status = gRT->SetVariable (

+      BootVariableName,

+      &gEfiGlobalVariableGuid,

+      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+      BdsLoadOption->LoadOptionSize,

+      BdsLoadOption->LoadOption

+      );

+

+  return Status;

+}

+

+EFI_STATUS

+BootOptionDelete (

+  IN  BDS_LOAD_OPTION *BootOption

+  )

+{

+  UINTN         Index;

+  UINTN         BootOrderSize;

+  UINT16*       BootOrder;

+  UINTN         BootOrderCount;

+  EFI_STATUS    Status;

+

+  // Remove the entry from the BootOrder environment variable

+  Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);

+  if (!EFI_ERROR(Status)) {

+    BootOrderCount = BootOrderSize / sizeof(UINT16);

+

+    // Find the index of the removed entry

+    for (Index = 0; Index < BootOrderCount; Index++) {

+      if (BootOrder[Index] == BootOption->LoadOptionIndex) {

+        // If it the last entry we do not need to rearrange the BootOrder list

+        if (Index + 1 != BootOrderCount) {

+          CopyMem (

+            &BootOrder[Index],

+            &BootOrder[Index + 1],

+            (BootOrderCount - (Index + 1)) * sizeof(UINT16)

+            );

+        }

+        break;

+      }

+    }

+

+    // Update the BootOrder environment variable

+    Status = gRT->SetVariable (

+        L"BootOrder",

+        &gEfiGlobalVariableGuid,

+        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+        BootOrderSize - sizeof(UINT16),

+        BootOrder

+        );

+  }

+

+  FreePool (BootOrder);

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootOptionSupport.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootOptionSupport.c
new file mode 100644
index 0000000..dc70dc4
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Bds/BootOptionSupport.c
@@ -0,0 +1,942 @@
+/** @file

+*

+*  Copyright (c) 2011-2014, ARM 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.

+*

+**/

+

+#include "BdsInternal.h"

+

+#include <Library/NetLib.h>

+

+#include <Protocol/BlockIo.h>

+#include <Protocol/DevicePathToText.h>

+#include <Protocol/PxeBaseCode.h>

+#include <Protocol/SimpleFileSystem.h>

+#include <Protocol/SimpleNetwork.h>

+

+#include <Guid/FileSystemInfo.h>

+

+#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))

+

+EFI_STATUS

+BdsLoadOptionFileSystemList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  );

+

+EFI_STATUS

+BdsLoadOptionFileSystemCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+EFI_STATUS

+BdsLoadOptionFileSystemUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+BOOLEAN

+BdsLoadOptionFileSystemIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  );

+

+EFI_STATUS

+BdsLoadOptionMemMapList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  );

+

+EFI_STATUS

+BdsLoadOptionMemMapCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+EFI_STATUS

+BdsLoadOptionMemMapUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+BOOLEAN

+BdsLoadOptionMemMapIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  );

+

+EFI_STATUS

+BdsLoadOptionPxeList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  );

+

+EFI_STATUS

+BdsLoadOptionPxeCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+EFI_STATUS

+BdsLoadOptionPxeUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+BOOLEAN

+BdsLoadOptionPxeIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  );

+

+EFI_STATUS

+BdsLoadOptionTftpList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  );

+

+EFI_STATUS

+BdsLoadOptionTftpCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+EFI_STATUS

+BdsLoadOptionTftpUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  );

+

+BOOLEAN

+BdsLoadOptionTftpIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  );

+

+BDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList[] = {

+  {

+    BDS_DEVICE_FILESYSTEM,

+    BdsLoadOptionFileSystemList,

+    BdsLoadOptionFileSystemIsSupported,

+    BdsLoadOptionFileSystemCreateDevicePath,

+    BdsLoadOptionFileSystemUpdateDevicePath

+  },

+  {

+    BDS_DEVICE_MEMMAP,

+    BdsLoadOptionMemMapList,

+    BdsLoadOptionMemMapIsSupported,

+    BdsLoadOptionMemMapCreateDevicePath,

+    BdsLoadOptionMemMapUpdateDevicePath

+  },

+  {

+    BDS_DEVICE_PXE,

+    BdsLoadOptionPxeList,

+    BdsLoadOptionPxeIsSupported,

+    BdsLoadOptionPxeCreateDevicePath,

+    BdsLoadOptionPxeUpdateDevicePath

+  },

+  {

+    BDS_DEVICE_TFTP,

+    BdsLoadOptionTftpList,

+    BdsLoadOptionTftpIsSupported,

+    BdsLoadOptionTftpCreateDevicePath,

+    BdsLoadOptionTftpUpdateDevicePath

+  }

+};

+

+EFI_STATUS

+BootDeviceListSupportedInit (

+  IN OUT LIST_ENTRY *SupportedDeviceList

+  )

+{

+  UINTN   Index;

+

+  // Initialize list of supported devices

+  InitializeListHead (SupportedDeviceList);

+

+  for (Index = 0; Index < BDS_DEVICE_MAX; Index++) {

+    BdsLoadOptionSupportList[Index].ListDevices (SupportedDeviceList);

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BootDeviceListSupportedFree (

+  IN LIST_ENTRY *SupportedDeviceList,

+  IN BDS_SUPPORTED_DEVICE *Except

+  )

+{

+  LIST_ENTRY  *Entry;

+  BDS_SUPPORTED_DEVICE* SupportedDevice;

+

+  Entry = GetFirstNode (SupportedDeviceList);

+  while (Entry != SupportedDeviceList) {

+    SupportedDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);

+    Entry = RemoveEntryList (Entry);

+    if (SupportedDevice != Except) {

+      FreePool (SupportedDevice);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BootDeviceGetDeviceSupport (

+  IN  EFI_DEVICE_PATH           *DevicePath,

+  OUT BDS_LOAD_OPTION_SUPPORT   **DeviceSupport

+  )

+{

+  UINTN Index;

+

+  // Find which supported device is the most appropriate

+  for (Index = 0; Index < BDS_DEVICE_MAX; Index++) {

+    if (BdsLoadOptionSupportList[Index].IsSupported (DevicePath)) {

+      *DeviceSupport = &BdsLoadOptionSupportList[Index];

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+EFI_STATUS

+BootDeviceGetType (

+  IN  EFI_DEVICE_PATH* DevicePath,

+  OUT ARM_BDS_LOADER_TYPE *BootType,

+  OUT UINT32 *Attributes

+  )

+{

+  EFI_STATUS              Status;

+  BOOLEAN                 IsEfiApp;

+  BOOLEAN                 IsBootLoader;

+  BOOLEAN                 HasFDTSupport;

+  CHAR16*                 FileName;

+  EFI_DEVICE_PATH*        PrevDevicePathNode;

+  EFI_DEVICE_PATH*        DevicePathNode;

+  EFI_PHYSICAL_ADDRESS    Image;

+  UINTN                   FileSize;

+  EFI_IMAGE_DOS_HEADER*   DosHeader;

+  UINTN                   PeCoffHeaderOffset;

+  EFI_IMAGE_NT_HEADERS32* NtHeader;

+

+  //

+  // Check if the last node of the device path is a FilePath node

+  //

+  PrevDevicePathNode = NULL;

+  DevicePathNode = DevicePath;

+  while ((DevicePathNode != NULL) && !IsDevicePathEnd (DevicePathNode)) {

+    PrevDevicePathNode = DevicePathNode;

+    DevicePathNode = NextDevicePathNode (DevicePathNode);

+  }

+

+  if ((PrevDevicePathNode != NULL) &&

+      (PrevDevicePathNode->Type == MEDIA_DEVICE_PATH) &&

+      (PrevDevicePathNode->SubType == MEDIA_FILEPATH_DP))

+  {

+    FileName = ((FILEPATH_DEVICE_PATH*)PrevDevicePathNode)->PathName;

+  } else {

+    FileName = NULL;

+  }

+

+  if (FileName == NULL) {

+    Print(L"Is an EFI Application? ");

+    Status = GetHIInputBoolean (&IsEfiApp);

+    if (EFI_ERROR(Status)) {

+      return EFI_ABORTED;

+    }

+  } else if (HasFilePathEfiExtension(FileName)) {

+    IsEfiApp = TRUE;

+  } else {

+    // Check if the file exist

+    Status = BdsLoadImage (DevicePath, AllocateAnyPages, &Image, &FileSize);

+    if (!EFI_ERROR (Status)) {

+

+      DosHeader = (EFI_IMAGE_DOS_HEADER *)(UINTN) Image;

+      if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+        //

+        // DOS image header is present,

+        // so read the PE header after the DOS image header.

+        //

+        PeCoffHeaderOffset = DosHeader->e_lfanew;

+      } else {

+        PeCoffHeaderOffset = 0;

+      }

+

+      //

+      // Check PE/COFF image.

+      //

+      NtHeader = (EFI_IMAGE_NT_HEADERS32 *)(UINTN) (Image + PeCoffHeaderOffset);

+      if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) {

+        IsEfiApp = FALSE;

+      } else {

+        IsEfiApp = TRUE;

+      }

+

+      // Free memory

+      gBS->FreePages (Image, EFI_SIZE_TO_PAGES(FileSize));

+    } else {

+      // If we did not manage to open it then ask for the type

+      Print(L"Is an EFI Application? ");

+      Status = GetHIInputBoolean (&IsEfiApp);

+      if (EFI_ERROR(Status)) {

+        return EFI_ABORTED;

+      }

+    }

+  }

+

+  if (IsEfiApp) {

+    Print(L"Is your application is an OS loader? ");

+    Status = GetHIInputBoolean (&IsBootLoader);

+    if (EFI_ERROR(Status)) {

+      return EFI_ABORTED;

+    }

+    if (!IsBootLoader) {

+      *Attributes |= LOAD_OPTION_CATEGORY_APP;

+    }

+    *BootType = BDS_LOADER_EFI_APPLICATION;

+  } else {

+    Print(L"Has FDT support? ");

+    Status = GetHIInputBoolean (&HasFDTSupport);

+    if (EFI_ERROR(Status)) {

+      return EFI_ABORTED;

+    }

+    if (HasFDTSupport) {

+      *BootType = BDS_LOADER_KERNEL_LINUX_FDT;

+    } else {

+      *BootType = BDS_LOADER_KERNEL_LINUX_ATAG;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLoadOptionFileSystemList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  )

+{

+  EFI_STATUS                        Status;

+  UINTN                             HandleCount;

+  EFI_HANDLE                        *HandleBuffer;

+  UINTN                             Index;

+  BDS_SUPPORTED_DEVICE              *SupportedDevice;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL*  FileProtocol;

+  EFI_FILE_HANDLE                   Fs;

+  UINTN                             Size;

+  EFI_FILE_SYSTEM_INFO*             FsInfo;

+  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;

+

+  // List all the Simple File System Protocols

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < HandleCount; Index++) {

+    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);

+    if (!EFI_ERROR(Status)) {

+      // Allocate BDS Supported Device structure

+      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE));

+

+      FileProtocol = NULL;

+      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileProtocol);

+      ASSERT_EFI_ERROR(Status);

+

+      FileProtocol->OpenVolume (FileProtocol, &Fs);

+

+      // Generate a Description from the file system

+      Size = 0;

+      FsInfo = NULL;

+      Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);

+      if (Status == EFI_BUFFER_TOO_SMALL) {

+        FsInfo = AllocatePool (Size);

+        Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);

+      }

+      UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"%s (%d MB)",FsInfo->VolumeLabel,(UINT32)(FsInfo->VolumeSize / (1024 * 1024)));

+      FreePool(FsInfo);

+      Fs->Close (Fs);

+

+      SupportedDevice->DevicePathProtocol = DevicePathProtocol;

+      SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_FILESYSTEM];

+

+      InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLoadOptionFileSystemCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  EFI_STATUS  Status;

+  FILEPATH_DEVICE_PATH* FilePathDevicePath;

+  CHAR16      BootFilePath[BOOT_DEVICE_FILEPATH_MAX];

+  UINTN       BootFilePathSize;

+

+  Print(L"File path of the %s: ", FileName);

+  Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  BootFilePathSize = StrSize (BootFilePath);

+  if (BootFilePathSize == 2) {

+    *DevicePathNodes = NULL;

+    return EFI_NOT_FOUND;

+  }

+

+  // Create the FilePath Device Path node

+  FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH);

+  FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;

+  FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;

+  SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);

+  CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);

+  SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));

+  *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath;

+

+  return Status;

+}

+

+EFI_STATUS

+BdsLoadOptionFileSystemUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  EFI_STATUS  Status;

+  CHAR16      BootFilePath[BOOT_DEVICE_FILEPATH_MAX];

+  UINTN       BootFilePathSize;

+  FILEPATH_DEVICE_PATH* EndingDevicePath;

+  FILEPATH_DEVICE_PATH* FilePathDevicePath;

+  EFI_DEVICE_PATH*  DevicePath;

+

+  DevicePath = DuplicateDevicePath (OldDevicePath);

+

+  EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);

+ 

+  Print(L"File path of the %s: ", FileName);

+  StrnCpy (BootFilePath, EndingDevicePath->PathName, BOOT_DEVICE_FILEPATH_MAX);

+  Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);

+  if (EFI_ERROR(Status)) {

+    return Status;

+  }

+

+  BootFilePathSize = StrSize(BootFilePath);

+  if (BootFilePathSize == 2) {

+    *NewDevicePath = NULL;

+    return EFI_NOT_FOUND;

+  }

+

+  // Create the FilePath Device Path node

+  FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);

+  FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;

+  FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;

+  SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);

+  CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);

+

+  // Generate the new Device Path by replacing the last node by the updated node

+  SetDevicePathEndNode (EndingDevicePath);

+  *NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath);

+  FreePool(DevicePath);

+

+  return EFI_SUCCESS;

+}

+

+BOOLEAN

+BdsLoadOptionFileSystemIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  )

+{

+  EFI_DEVICE_PATH*  DevicePathNode;

+

+  DevicePathNode = GetLastDevicePathNode (DevicePath);

+

+  return IS_DEVICE_PATH_NODE(DevicePathNode,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP);

+}

+

+STATIC

+BOOLEAN

+IsParentDevicePath (

+  IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,

+  IN EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath

+  )

+{

+  UINTN ParentSize;

+  UINTN ChildSize;

+

+  ParentSize = GetDevicePathSize (ParentDevicePath);

+  ChildSize = GetDevicePathSize (ChildDevicePath);

+

+  if (ParentSize > ChildSize) {

+    return FALSE;

+  }

+

+  if (CompareMem (ParentDevicePath, ChildDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+EFI_STATUS

+BdsLoadOptionMemMapList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  )

+{

+  EFI_STATUS                        Status;

+  UINTN                             HandleCount;

+  EFI_HANDLE                        *HandleBuffer;

+  UINTN                             DevicePathHandleCount;

+  EFI_HANDLE                        *DevicePathHandleBuffer;

+  BOOLEAN                           IsParent;

+  UINTN                             Index;

+  UINTN                             Index2;

+  BDS_SUPPORTED_DEVICE              *SupportedDevice;

+  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;

+  EFI_DEVICE_PATH*                  DevicePath;

+

+  // List all the BlockIo Protocols

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &HandleBuffer);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < HandleCount; Index++) {

+    // We only select the handle WITH a Device Path AND not part of Media (to avoid duplication with HardDisk, CDROM, etc)

+    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);

+    if (!EFI_ERROR(Status)) {

+      // BlockIo is not part of Media Device Path

+      DevicePath = DevicePathProtocol;

+      while (!IsDevicePathEndType (DevicePath) && (DevicePathType (DevicePath) != MEDIA_DEVICE_PATH)) {

+        DevicePath = NextDevicePathNode (DevicePath);

+      }

+      if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {

+        continue;

+      }

+

+      // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child

+      Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &DevicePathHandleCount, &DevicePathHandleBuffer);

+      ASSERT_EFI_ERROR (Status);

+      IsParent = FALSE;

+      for (Index2 = 0; (Index2 < DevicePathHandleCount) && !IsParent; Index2++) {

+        if (HandleBuffer[Index] != DevicePathHandleBuffer[Index2]) {

+          gBS->HandleProtocol (DevicePathHandleBuffer[Index2], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);

+          if (IsParentDevicePath (DevicePathProtocol, DevicePath)) {

+            IsParent = TRUE;

+          }

+        }

+      }

+      if (IsParent) {

+        continue;

+      }

+

+      // Allocate BDS Supported Device structure

+      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));

+

+      Status = GenerateDeviceDescriptionName (HandleBuffer[Index], SupportedDevice->Description);

+      ASSERT_EFI_ERROR (Status);

+

+      SupportedDevice->DevicePathProtocol = DevicePathProtocol;

+      SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_MEMMAP];

+

+      InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLoadOptionMemMapCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  EFI_STATUS              Status;

+  MEMMAP_DEVICE_PATH      *MemMapDevicePath;

+  CHAR16                  StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];

+  CHAR16                  StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];

+

+  Print(L"Starting Address of the %s: ", FileName);

+  Status = GetHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  Print(L"Ending Address of the %s: ", FileName);

+  Status = GetHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  // Create the MemMap Device Path Node

+  MemMapDevicePath = (MEMMAP_DEVICE_PATH*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH) + END_DEVICE_PATH_LENGTH);

+  MemMapDevicePath->Header.Type = HARDWARE_DEVICE_PATH;

+  MemMapDevicePath->Header.SubType = HW_MEMMAP_DP;

+  SetDevicePathNodeLength (MemMapDevicePath, sizeof(MEMMAP_DEVICE_PATH));

+  MemMapDevicePath->MemoryType = EfiBootServicesData;

+  MemMapDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);

+  MemMapDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);

+

+  // Set a Device Path End Node after the Memory Map Device Path Node

+  SetDevicePathEndNode (MemMapDevicePath + 1);

+  *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath;

+

+  return Status;

+}

+

+EFI_STATUS

+BdsLoadOptionMemMapUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  EFI_STATUS          Status;

+  CHAR16              StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];

+  CHAR16              StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];

+  MEMMAP_DEVICE_PATH* EndingDevicePath;

+  EFI_DEVICE_PATH*    DevicePath;

+

+  DevicePath = DuplicateDevicePath (OldDevicePath);

+  EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);

+

+  Print(L"Starting Address of the %s: ", FileName);

+  UnicodeSPrint (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->StartingAddress);

+  Status = EditHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  Print(L"Ending Address of the %s: ", FileName);

+  UnicodeSPrint (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->EndingAddress);

+  Status = EditHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  EndingDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);

+  EndingDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);

+

+  if (EFI_ERROR(Status)) {

+    FreePool(DevicePath);

+  } else {

+    *NewDevicePath = DevicePath;

+  }

+

+  return Status;

+}

+

+BOOLEAN

+BdsLoadOptionMemMapIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  )

+{

+  EFI_DEVICE_PATH*  DevicePathNode;

+

+  DevicePathNode = GetLastDevicePathNode (DevicePath);

+

+  return IS_DEVICE_PATH_NODE(DevicePathNode,HARDWARE_DEVICE_PATH,HW_MEMMAP_DP);

+}

+

+EFI_STATUS

+BdsLoadOptionPxeList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  )

+{

+  EFI_STATUS                        Status;

+  UINTN                             HandleCount;

+  EFI_HANDLE                        *HandleBuffer;

+  UINTN                             Index;

+  BDS_SUPPORTED_DEVICE              *SupportedDevice;

+  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;

+  EFI_SIMPLE_NETWORK_PROTOCOL*      SimpleNet;

+  CHAR16                            DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];

+  EFI_MAC_ADDRESS                   *Mac;

+

+  // List all the PXE Protocols

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < HandleCount; Index++) {

+    // We only select the handle WITH a Device Path AND the PXE Protocol

+    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);

+    if (!EFI_ERROR(Status)) {

+      // Allocate BDS Supported Device structure

+      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));

+

+      Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);

+      if (!EFI_ERROR(Status)) {

+        Mac = &SimpleNet->Mode->CurrentAddress;

+        UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0],  Mac->Addr[1],  Mac->Addr[2],  Mac->Addr[3],  Mac->Addr[4],  Mac->Addr[5]);

+      } else {

+        Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);

+        ASSERT_EFI_ERROR (Status);

+      }

+      UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"PXE on %s",DeviceDescription);

+

+      SupportedDevice->DevicePathProtocol = DevicePathProtocol;

+      SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_PXE];

+

+      InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLoadOptionPxeCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);

+  SetDevicePathEndNode (*DevicePathNodes);

+

+  if (RequestBootType) {

+    *RequestBootType = FALSE;

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLoadOptionPxeUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  ASSERT (0);

+  return EFI_UNSUPPORTED;

+}

+

+BOOLEAN

+BdsLoadOptionPxeIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  )

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE Handle;

+  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;

+  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBcProtocol;

+

+  Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);

+  if (EFI_ERROR(Status)) {

+    return FALSE;

+  }

+

+  if (!IsDevicePathEnd(RemainingDevicePath)) {

+    return FALSE;

+  }

+

+  Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  } else {

+    return TRUE;

+  }

+}

+

+EFI_STATUS

+BdsLoadOptionTftpList (

+  IN OUT LIST_ENTRY* BdsLoadOptionList

+  )

+{

+  EFI_STATUS                        Status;

+  UINTN                             HandleCount;

+  EFI_HANDLE                        *HandleBuffer;

+  UINTN                             Index;

+  BDS_SUPPORTED_DEVICE              *SupportedDevice;

+  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;

+  EFI_SIMPLE_NETWORK_PROTOCOL*      SimpleNet;

+  CHAR16                            DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];

+  EFI_MAC_ADDRESS                   *Mac;

+

+  // List all the PXE Protocols

+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  for (Index = 0; Index < HandleCount; Index++) {

+    // We only select the handle WITH a Device Path AND the PXE Protocol AND the TFTP Protocol (the TFTP protocol is required to start PXE)

+    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);

+    if (!EFI_ERROR(Status)) {

+      // Allocate BDS Supported Device structure

+      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));

+

+      Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);

+      if (!EFI_ERROR(Status)) {

+        Mac = &SimpleNet->Mode->CurrentAddress;

+        UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0],  Mac->Addr[1],  Mac->Addr[2],  Mac->Addr[3],  Mac->Addr[4],  Mac->Addr[5]);

+      } else {

+        Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);

+        ASSERT_EFI_ERROR (Status);

+      }

+      UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"TFTP on %s",DeviceDescription);

+

+      SupportedDevice->DevicePathProtocol = DevicePathProtocol;

+      SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];

+

+      InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);

+    }

+  }

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+BdsLoadOptionTftpCreateDevicePath (

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathNodes,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  EFI_STATUS    Status;

+  BOOLEAN       IsDHCP;

+  EFI_IP_ADDRESS  LocalIp;

+  EFI_IP_ADDRESS  RemoteIp;

+  IPv4_DEVICE_PATH*   IPv4DevicePathNode;

+  FILEPATH_DEVICE_PATH* FilePathDevicePath;

+  CHAR16      BootFilePath[BOOT_DEVICE_FILEPATH_MAX];

+  UINTN       BootFilePathSize;

+

+  Print(L"Get the IP address from DHCP: ");

+  Status = GetHIInputBoolean (&IsDHCP);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  if (!IsDHCP) {

+    Print(L"Get the static IP address: ");

+    Status = GetHIInputIP (&LocalIp);

+    if (EFI_ERROR(Status)) {

+      return EFI_ABORTED;

+    }

+  }

+

+  Print(L"Get the TFTP server IP address: ");

+  Status = GetHIInputIP (&RemoteIp);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  Print(L"File path of the %s : ", FileName);

+  Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);

+  if (EFI_ERROR(Status)) {

+    return EFI_ABORTED;

+  }

+

+  BootFilePathSize = StrSize(BootFilePath);

+  if (BootFilePathSize == 2) {

+    return EFI_NOT_FOUND;

+  }

+

+  // Allocate the memory for the IPv4 + File Path Device Path Nodes

+  IPv4DevicePathNode = (IPv4_DEVICE_PATH*)AllocatePool(sizeof(IPv4_DEVICE_PATH) + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH);

+

+  // Create the IPv4 Device Path

+  IPv4DevicePathNode->Header.Type    = MESSAGING_DEVICE_PATH;

+  IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP;

+  SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH));

+  CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));

+  CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));

+  IPv4DevicePathNode->LocalPort  = 0;

+  IPv4DevicePathNode->RemotePort = 0;

+  IPv4DevicePathNode->Protocol = EFI_IP_PROTO_TCP;

+  IPv4DevicePathNode->StaticIpAddress = (IsDHCP != TRUE);

+

+  // Create the FilePath Device Path node

+  FilePathDevicePath = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1);

+  FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;

+  FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;

+  SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);

+  CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);

+

+  // Set the End Device Path Node

+  SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));

+  *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode;

+

+  return Status;

+}

+

+EFI_STATUS

+BdsLoadOptionTftpUpdateDevicePath (

+  IN EFI_DEVICE_PATH            *OldDevicePath,

+  IN CHAR16*                    FileName,

+  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath,

+  OUT BOOLEAN                   *RequestBootType

+  )

+{

+  ASSERT (0);

+  return EFI_UNSUPPORTED;

+}

+

+BOOLEAN

+BdsLoadOptionTftpIsSupported (

+  IN  EFI_DEVICE_PATH           *DevicePath

+  )

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE Handle;

+  EFI_DEVICE_PATH  *RemainingDevicePath;

+  EFI_DEVICE_PATH  *NextDevicePath;

+  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBcProtocol;

+

+  Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);

+  if (EFI_ERROR(Status)) {

+    return FALSE;

+  }

+

+  // Validate the Remaining Device Path

+  if (IsDevicePathEnd(RemainingDevicePath)) {

+    return FALSE;

+  }

+  if (!IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv4_DP) &&

+      !IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv6_DP)) {

+    return FALSE;

+  }

+  NextDevicePath = NextDevicePathNode (RemainingDevicePath);

+  if (IsDevicePathEnd(NextDevicePath)) {

+    return FALSE;

+  }

+  if (!IS_DEVICE_PATH_NODE(NextDevicePath,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP)) {

+    return FALSE;

+  }

+

+  Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  } else {

+    return TRUE;

+  }

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.dsc b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.dsc
new file mode 100644
index 0000000..fa4377e
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.dsc
@@ -0,0 +1,333 @@
+#

+#  Copyright (c) 2011-2012, Hisilicon Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 Section - statements that will be processed to create a Makefile.

+#

+################################################################################

+[Defines]

+  PLATFORM_NAME                  = D01-A15_MPCore

+  PLATFORM_GUID                  = 3a91a0f8-3af4-409d-a71d-a199dc134357

+  PLATFORM_VERSION               = 0.1

+  DSC_SPECIFICATION              = 0x00010005

+  OUTPUT_DIRECTORY               = Build/D01

+  SUPPORTED_ARCHITECTURES        = ARM

+  BUILD_TARGETS                  = DEBUG|RELEASE

+  SKUID_IDENTIFIER               = DEFAULT

+  FLASH_DEFINITION               = HisiPkg/D01BoardPkg/D01BoardPkg.fdf

+

+!include HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc

+

+[LibraryClasses.common]

+  ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf

+  ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf

+  ArmPlatformLib|HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01Lib.inf

+  

+  ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf

+  NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf

+

+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf 

+  

+

+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf

+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf

+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf

+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf

+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf

+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf

+

+[LibraryClasses.common.SEC]

+  ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf

+  ArmPlatformSecLib|HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/D01SecLib.inf

+  ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf

+

+[BuildOptions]

+

+  RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 --fpu=softvfp -I$(WORKSPACE)/HisiPkg/Include/Platform

+

+  GCC:*_*_ARM_PLATFORM_FLAGS == -march=armv7-a -I$(WORKSPACE)/HisiPkg/Include/Platform

+

+  XCODE:*_*_ARM_PLATFORM_FLAGS == -arch armv7 -I$(WORKSPACE)/HisiPkg/Include/Platform

+

+################################################################################

+#

+# Pcd Section - list of all EDK II PCD Entries defined by this Platform

+#

+################################################################################

+

+[PcdsFeatureFlag.common]

+!ifdef $(EDK2_SKIP_PEICORE)

+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE

+  gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|TRUE

+!endif

+  

+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.

+  #  It could be set FALSE to save size.

+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE

+  

+[PcdsFixedAtBuild.common]

+

+  gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM D01"

+  

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D01"

+

+  gArmPlatformTokenSpaceGuid.PcdCoreCount|2

+

+  #

+  # NV Storage PCDs. Use base of 0x0C000000 for NOR1

+  #

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0xf10C0000

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00010000

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0xf10D0000

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00010000

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0xf10E0000

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00010000

+

+  gArmTokenSpaceGuid.PcdVFPEnabled|0

+  

+  # Stacks for MPCores in Secure World

+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x40000000

+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x8000

+  

+  # Stacks for MPCores in Monitor Mode

+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x40028000

+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x8000

+

+  gHwTokenSpaceGuid.PcdEmbeddedBiosVersion|"Linaro_BIOS_V1.9"

+      

+ 

+  # System Memory (1GB) 

+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x10000000

+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x60000000

+  

+  # Size of the region used by UEFI in permanent memory (Reserved 64MB)

+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x60000000

+    

+  #

+  # ARM Pcds

+  #

+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000040000000

+  #

+  # ARM PrimeCell

+  #

+

+  

+  ## PL011 - Serial Terminal

+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xe4007000

+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200

+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8

+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1

+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1

+

+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod|10000

+

+  

+  #

+  # ARM PL390 General Interrupt Controller

+  #

+  gArmTokenSpaceGuid.PcdGicDistributorBase|0xe0C01000

+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xe0C02000

+

+  #

+  # ARM OS Loader

+  #

+  # Versatile Express machine type (ARM VERSATILE EXPRESS = 2272) required for ARM Linux: 

+  gArmTokenSpaceGuid.PcdArmMachineType|0xffffffff

+  #gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"SemiHosting"

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Ramdisk"

+  #gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/zImage"

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenMsg(06ED4DD0-FF78-11D3-BDC4-00A0C94053D1,0000000000000000)/uImage"

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenMsg(06ED4DD0-FF78-11D3-BDC4-00A0C94053D1,0000000000000000)/initrd"

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"mem=256M console=ttyAMA0,115200"

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootType|1

+

+  # Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)

+  #gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi();VenHw(407B4008-BF5B-11DF-9547-CF16E0D72085)"

+  #gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"

+  #gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut|10

+

+  #

+  # ARM L2x0 PCDs

+  #

+  gArmTokenSpaceGuid.PcdL2x0ControllerBase|0xeE00A000

+  

+  #

+  # ARM Architectual Timer Frequency

+  #

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|50000000

+

+  gHwTokenSpaceGuid.PcdNorFlashBase|0xf0000000

+

+  gHwTokenSpaceGuid.PcdGPIO0Base|0xe4000000

+  gArmTokenSpaceGuid.PcdSysCtrlBase|0xe3e00000

+  gArmTokenSpaceGuid.PcdTimerBase|0xe3000000

+  gArmTokenSpaceGuid.PcdTimer0InterruptNum|130

+  

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"EVB_SECURE_UEFI_BIOS"

+  

+################################################################################

+#

+# Components Section - list of all EDK II Modules needed by this Platform

+#

+################################################################################

+[Components.common]

+  

+  #

+  # SEC

+  #

+  HisiPkg/D01BoardPkg/Sec/Sec/Sec.inf {

+    <LibraryClasses>

+      # Use the implementation which set the Secure bits

+      #ArmGicLib|HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf

+      ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf

+  }

+  

+  #

+  # PEI Phase modules

+  #

+!ifndef $(EDK2_SKIP_PEICORE)

+  ArmPlatformPkg/PrePi/PeiMPCore.inf{

+    <LibraryClasses>

+      ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf

+      ArmPlatformLib|HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01Lib.inf

+      ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf

+  }

+!else

+  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf {

+    <LibraryClasses>

+      ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf

+  }

+  MdeModulePkg/Core/Pei/PeiMain.inf

+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {

+    <LibraryClasses>

+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf

+  }

+  ArmPlatformPkg/PlatformPei/PlatformPeim.inf

+  #ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf

+  ArmPkg/Drivers/CpuPei/CpuPei.inf

+  IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf

+  Nt32Pkg/BootModePei/BootModePei.inf

+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf

+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {

+    <LibraryClasses>

+      NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf

+  }

+!endif

+

+  #

+  # DXE

+  #

+  MdeModulePkg/Core/Dxe/DxeMain.inf {

+    <LibraryClasses>

+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf

+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf

+  }

+

+  #

+  # Architectural Protocols

+  #

+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf

+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf

+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf

+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf

+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf

+  #MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf 

+  EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf

+  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf

+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf

+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf

+

+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf

+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf

+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf

+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf

+  EmbeddedPkg/SerialDxe/SerialDxe.inf

+

+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf

+

+  HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf

+  #ArmPkg/Drivers/ArmGic/ArmGicDxe.inf

+

+  #ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf

+  #ArmPkg/Drivers/TimerDxe/TimerDxe.inf

+  HisiPkg/Drivers/TimerDxe/TimerDxe.inf

+  #ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf

+  #ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf 

+  MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf

+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf

+  #HisiPkg/Drivers/WatchDogDriver/WatchDogDriver.inf

+  #

+

+  #

+  # Semi-hosting filesystem

+  #

+  #ArmPkg/Filesystem/SemihostFs/SemihostFs.inf

+  

+  # RamDisk filesystem

+  #

+  HisiPkg/Drivers/ramdisk/ramdisk.inf

+

+  #HisiPkg/Drivers/FlashDriver/FlashDriver.inf

+  

+  #HisiPkg/Drivers/NandFlash/NandFlashDxe.inf

+

+  #

+  # Multimedia Card Interface

+  #

+  #EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf

+  #ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf

+  

+  #

+  # FAT filesystem + GPT/MBR partitioning

+  #

+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf

+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf

+  #FatPkg/EnhancedFatDxe/Fat.inf

+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf

+

+  #

+  # network

+  #

+  #HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.inf

+  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf

+  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf

+  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf

+  MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf

+  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf

+  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf

+  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf

+  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf

+  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf

+  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf

+  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf

+

+  #

+  # Application

+  #  

+  #EmbeddedPkg/Ebl/Ebl.inf

+  #HisiPkg/D01BoardPkg/Application/Ebl/Ebl.inf

+

+  #

+  # Bds

+  #

+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf

+  HisiPkg/D01BoardPkg/Bds/Bds.inf

+

+  HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.inf

+

+  #HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf

+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf

+  

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc
new file mode 100644
index 0000000..d915c35
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc
@@ -0,0 +1,354 @@
+#

+#  Copyright (c) 2011-2012, Hisilicon Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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.

+#

+#

+

+[LibraryClasses.common]

+!if $(TARGET) == RELEASE

+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf

+!else

+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf

+!endif

+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf

+

+  UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf

+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf

+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf

+

+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf

+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf

+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf

+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf

+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf

+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf

+

+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf

+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf

+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf

+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf

+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf

+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf

+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf

+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf

+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf

+  

+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf

+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf

+

+  #

+  # Assume everything is fixed at build

+  #

+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf

+

+  # 1/123 faster than Stm or Vstm version

+  BaseMemoryLib|ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf

+

+  # ARM Architectural Libraries

+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf

+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf

+  CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf

+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf

+  DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf

+

+  #ArmGicLib|HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf

+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf

+

+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf

+

+  # Versatile Express Specific Libraries

+  EfiResetSystemLib|ArmPlatformPkg/ArmVExpressPkg/Library/ResetSystemLib/ResetSystemLib.inf

+  # ARM PL031 RTC Driver

+  #RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf

+  RealTimeClockLib|HisiPkg/D01BoardPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf

+  # ARM PL354 SMC Driver

+  PL35xSmcLib|ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf

+  # ARM PL011 UART Driver

+

+

+  SerialPortLib|HisiPkg/Library/SerialPortLib/SerialPortLib.inf

+  SerialPortExtLib|HisiPkg/Library/SerialPortLib/SerialPortLib.inf

+

+  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf

+  #SerialPortLib|ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf

+  #SerialPortExtLib|EmbeddedPkg/Library/TemplateSerialPortExtLib/TemplateSerialPortExtLib.inf

+

+  #PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf

+  #SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf

+  #SerialPortExtLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortExtLib.inf

+  ResetWdtLib|HisiPkg/D01BoardPkg/Library/ResetWdtLib/ResetWdtLib.inf

+  BspUartLib|HisiPkg/Library/BspUartLib/BspUartLib.inf

+  PinIoLib|HisiPkg/Library/PinIoLib/PinIoLib.inf

+	  

+  # ARM SP804 Dual Timer Driver

+  TimerLib|ArmPlatformPkg/Library/SP804TimerLib/SP804TimerLib.inf

+

+  UefiDevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf

+

+  # EBL Related Libraries  

+  EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf

+  EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf

+  EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf

+  EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf

+

+  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf

+

+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf

+  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf

+  

+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf

+

+  # BDS Libraries

+  BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf

+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf

+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf

+

+

+[LibraryClasses.common.SEC]

+  ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf

+  ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Sec/SecArmPlatformGlobalVariableLib.inf

+

+  DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf

+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf

+

+#!ifdef $(EDK2_SKIP_PEICORE)

+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf

+  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf

+  LzmaDecompressLib|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf

+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf

+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf

+  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf

+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf

+  PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf

+  MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf

+#!endif

+

+  # Trustzone Support

+  ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf

+

+[LibraryClasses.common.PEI_CORE]

+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf

+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf

+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf

+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf

+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf

+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf

+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf

+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf

+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf

+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf

+

+  ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf

+  PeiServicesTablePointerLib|ArmPlatformPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf

+

+[LibraryClasses.common.PEIM]

+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf

+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf

+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf

+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf

+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf

+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf

+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf

+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf

+  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf

+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf

+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf

+

+  ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf

+  PeiServicesTablePointerLib|ArmPlatformPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf

+

+[LibraryClasses.common.DXE_CORE]

+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf

+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf

+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf

+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf

+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf

+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf

+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf

+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf

+

+[LibraryClasses.common.DXE_DRIVER]

+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf

+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf

+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf

+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf

+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

+  ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Dxe/DxeArmPlatformGlobalVariableLib.inf

+

+  GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf

+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf

+

+

+[LibraryClasses.common.UEFI_APPLICATION]

+  UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf

+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf

+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf

+

+[LibraryClasses.common.UEFI_DRIVER]

+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf

+  UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf

+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf

+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf

+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

+

+[LibraryClasses.common.DXE_RUNTIME_DRIVER]

+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf

+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf

+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf

+

+[LibraryClasses.ARM]

+  #

+  # It is not possible to prevent the ARM compiler for generic intrinsic functions.

+  # This library provides the instrinsic functions generate by a given compiler.

+  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.

+  #

+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

+  # Add support for GCC stack protector

+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf

+

+[BuildOptions]

+  RVCT:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG

+

+  GCC:RELEASE_*_*_CC_FLAGS    = -DMDEPKG_NDEBUG

+

+  XCODE:RELEASE_*_*_CC_FLAGS     = -DMDEPKG_NDEBUG

+

+

+################################################################################

+#

+# Pcd Section - list of all EDK II PCD Entries defined by this Platform

+#

+################################################################################

+

+[PcdsFeatureFlag.common]

+  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE

+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE

+  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE

+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE

+  

+  #

+  # Control what commands are supported from the UI

+  # Turn these on and off to add features or save size

+  #  

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|TRUE

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd|TRUE

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd|TRUE

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd|TRUE

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable|FALSE

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd|FALSE

+

+  gEmbeddedTokenSpaceGuid.PcdCacheEnable|TRUE

+  

+  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress

+  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE

+  

+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE

+  

+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE

+

+[PcdsFixedAtBuild.common]

+  gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM D01"

+  

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"D01"

+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32

+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000

+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000

+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF

+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1

+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0

+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320

+

+  # DEBUG_ASSERT_ENABLED       0x01

+  # DEBUG_PRINT_ENABLED        0x02

+  # DEBUG_CODE_ENABLED         0x04

+  # CLEAR_MEMORY_ENABLED       0x08

+  # ASSERT_BREAKPOINT_ENABLED  0x10

+  # ASSERT_DEADLOOP_ENABLED    0x20

+!if $(TARGET) == RELEASE

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f

+!else

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f

+!endif

+

+  #  DEBUG_INIT      0x00000001  // Initialization

+  #  DEBUG_WARN      0x00000002  // Warnings

+  #  DEBUG_LOAD      0x00000004  // Load events

+  #  DEBUG_FS        0x00000008  // EFI File system

+  #  DEBUG_POOL      0x00000010  // Alloc & Free's

+  #  DEBUG_PAGE      0x00000020  // Alloc & Free's

+  #  DEBUG_INFO      0x00000040  // Verbose

+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE Dispatchers

+  #  DEBUG_VARIABLE  0x00000100  // Variable

+  #  DEBUG_BM        0x00000400  // Boot Manager

+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver

+  #  DEBUG_NET       0x00004000  // SNI Driver

+  #  DEBUG_UNDI      0x00010000  // UNDI Driver

+  #  DEBUG_LOADFILE  0x00020000  // UNDI Driver

+  #  DEBUG_EVENT     0x00080000  // Event messages

+  #  DEBUG_ERROR     0x80000000  // Error

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000

+

+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07

+

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|""

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07

+  gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000

+  

+  #

+  # Optional feature to help prevent EFI memory map fragments

+  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob

+  # Values are in EFI Pages (4K). DXE Core will make sure that

+  # at least this much of each type of memory can be allocated

+  # from a single memory range. This way you only end up with

+  # maximum of two fragements for each type in the memory map

+  # (the memory used, and the free memory that was prereserved

+  # but not used).

+  #

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|50

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|20

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20

+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0

+    

+  #

+  # ARM Pcds

+  #

+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000000000000

+  

+  #

+  # ARM PrimeCell

+  #

+

+  #

+  # ARM OS Loader

+  #

+  # Versatile Express machine type (ARM VERSATILE EXPRESS = 2272) required for ARM Linux: 

+  gArmTokenSpaceGuid.PcdArmMachineType|2272

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux from NorFlash"

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/MemoryMapped(0x0,0xED000000,0xED400000)"

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|""

+  gArmPlatformTokenSpaceGuid.PcdDefaultBootType|1

+  

+  # Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)

+  gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi();VenHw(CE660500-824D-11E0-AC72-0002A5D5C51B)"

+  gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"

+  gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut|10

+

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.fdf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.fdf
new file mode 100644
index 0000000..f191849
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/D01BoardPkg.fdf
@@ -0,0 +1,369 @@
+# FLASH layout file for ARM VE.

+#

+#  Copyright (c) 2011, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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.

+#

+

+################################################################################

+#

+# FD Section

+# The [FD] Section is made up of the definition statements and a

+# description of what goes into  the Flash Device Image.  Each FD section

+# defines one flash "device" image.  A flash device image may be one of

+# the following: Removable media bootable image (like a boot floppy

+# image,) an Option ROM image (that would be "flashed" into an add-in

+# card,) a System "Flash"  image (that would be burned into a system's

+# flash) or an Update ("Capsule") image that will be used to update and

+# existing system flash.

+#

+################################################################################

+

+[FD.D01]

+BaseAddress   = 0xf0100000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.

+Size          = 0x00100000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device

+ErasePolarity = 1

+

+# This one is tricky, it must be: BlockSize * NumBlocks = Size

+BlockSize     = 0x00001000

+NumBlocks     = 0x100

+

+################################################################################

+#

+# Following are lists of FD Region layout which correspond to the locations of different

+# images within the flash device.

+#

+# Regions must be defined in ascending order and may not overlap.

+#

+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by

+# the pipe "|" character, followed by the size of the region, also in hex with the leading

+# "0x" characters. Like:

+# Offset|Size

+# PcdOffsetCName|PcdSizeCName

+# RegionType <FV, DATA, or FILE>

+#

+################################################################################

+

+0x00000000|0x00020000

+gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize

+FV = FVMAIN_SEC

+

+0x00020000|0x000e0000

+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize

+FV = FVMAIN_COMPACT

+

+

+################################################################################

+#

+# FV Section

+#

+# [FV] section is used to define what components or modules are placed within a flash

+# device file.  This section also defines order the components and modules are positioned

+# within the image.  The [FV] section consists of define statements, set statements and

+# module statements.

+#

+################################################################################

+

+[FV.FVMAIN_SEC]

+FvAlignment        = 8

+ERASE_POLARITY     = 1

+MEMORY_MAPPED      = TRUE

+STICKY_WRITE       = TRUE

+LOCK_CAP           = TRUE

+LOCK_STATUS        = TRUE

+WRITE_DISABLED_CAP = TRUE

+WRITE_ENABLED_CAP  = TRUE

+WRITE_STATUS       = TRUE

+WRITE_LOCK_CAP     = TRUE

+WRITE_LOCK_STATUS  = TRUE

+READ_DISABLED_CAP  = TRUE

+READ_ENABLED_CAP   = TRUE

+READ_STATUS        = TRUE

+READ_LOCK_CAP      = TRUE

+READ_LOCK_STATUS   = TRUE

+

+  INF HisiPkg/D01BoardPkg/Sec/Sec/Sec.inf

+

+

+[FV.FvMain]

+BlockSize          = 0x40

+NumBlocks          = 0         # This FV gets compressed so make it just big enough

+FvAlignment        = 8         # FV alignment and FV attributes setting.

+ERASE_POLARITY     = 1

+MEMORY_MAPPED      = TRUE

+STICKY_WRITE       = TRUE

+LOCK_CAP           = TRUE

+LOCK_STATUS        = TRUE

+WRITE_DISABLED_CAP = TRUE

+WRITE_ENABLED_CAP  = TRUE

+WRITE_STATUS       = TRUE

+WRITE_LOCK_CAP     = TRUE

+WRITE_LOCK_STATUS  = TRUE

+READ_DISABLED_CAP  = TRUE

+READ_ENABLED_CAP   = TRUE

+READ_STATUS        = TRUE

+READ_LOCK_CAP      = TRUE

+READ_LOCK_STATUS   = TRUE

+

+  INF MdeModulePkg/Core/Dxe/DxeMain.inf

+

+  #

+  # PI DXE Drivers producing Architectural Protocols (EFI Services)

+  #

+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf

+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf

+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf

+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf

+  #INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

+  #INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf

+  INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf

+  #INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf

+  INF EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf

+  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf

+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf

+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf

+

+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf

+

+  #

+  # Multiple Console IO support

+  #

+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf

+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf

+  #INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf

+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf

+  INF EmbeddedPkg/SerialDxe/SerialDxe.inf

+

+  INF HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf

+  #INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf

+  INF HisiPkg/Drivers/TimerDxe/TimerDxe.inf

+

+  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf

+  INF HisiPkg/Drivers/WatchDogDriver/WatchDogDriver.inf

+

+  INF HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.inf

+

+  #

+  # Semi-hosting filesystem

+  #

+  #INF ArmPkg/Filesystem/SemihostFs/SemihostFs.inf

+

+  # RamDisk filesystem

+  INF HisiPkg/Drivers/ramdisk/ramdisk.inf

+

+  #NorFlash Driver

+  INF HisiPkg/Drivers/FlashDriver/FlashDriver.inf

+

+

+  INF HisiPkg/Drivers/NandFlash/NandFlashDxe.inf

+

+  #

+  # FAT filesystem + GPT/MBR partitioning

+  #

+  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf

+  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf

+  #INF FatPkg/EnhancedFatDxe/Fat.inf

+  INF  RuleOverride = BINARY FatBinPkg/EnhancedFatDxe/Fat.inf

+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf

+

+

+  INF HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf

+  INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf

+

+  #

+  # Multimedia Card Interface

+  #

+  #INF EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf

+  #INF ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf

+

+  #

+  # network

+  #

+  INF HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.inf

+  INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf

+  INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf

+  INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf

+  INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf

+  INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf

+  INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf

+  INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf

+  INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf

+  INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf

+  INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf

+  INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf

+

+  #

+  # UEFI application (Shell Embedded Boot Loader)

+  #

+  INF HisiPkg/D01BoardPkg/Application/Ebl/Ebl.inf

+  INF ShellBinPkg/UefiShell/UefiShell.inf

+

+  #

+  # Bds

+  #

+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf

+  INF HisiPkg/D01BoardPkg/Bds/Bds.inf

+

+[FV.FVMAIN_COMPACT]

+FvAlignment        = 8

+ERASE_POLARITY     = 1

+MEMORY_MAPPED      = TRUE

+STICKY_WRITE       = TRUE

+LOCK_CAP           = TRUE

+LOCK_STATUS        = TRUE

+WRITE_DISABLED_CAP = TRUE

+WRITE_ENABLED_CAP  = TRUE

+WRITE_STATUS       = TRUE

+WRITE_LOCK_CAP     = TRUE

+WRITE_LOCK_STATUS  = TRUE

+READ_DISABLED_CAP  = TRUE

+READ_ENABLED_CAP   = TRUE

+READ_STATUS        = TRUE

+READ_LOCK_CAP      = TRUE

+READ_LOCK_STATUS   = TRUE

+

+#!if $(EDK2_SKIP_PEICORE) == 1

+  INF ArmPlatformPkg/PrePi/PeiMPCore.inf

+#!else

+#  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf

+#  INF MdeModulePkg/Core/Pei/PeiMain.inf

+#  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf

+#  INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf

+#  INF ArmPkg/Drivers/CpuPei/CpuPei.inf

+#  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf

+#  INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf

+#  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf

+#  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf

+#!endif

+

+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {

+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {

+      SECTION FV_IMAGE = FVMAIN

+    }

+  }

+

+

+################################################################################

+#

+# Rules are use with the [FV] section's module INF type to define

+# how an FFS file is created for a given INF file. The following Rule are the default

+# rules for the different module type. User can add the customized rules to define the

+# content of the FFS file.

+#

+################################################################################

+

+

+############################################################################

+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #

+############################################################################

+#

+#[Rule.Common.DXE_DRIVER]

+#  FILE DRIVER = $(NAMED_GUID) {

+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex

+#    COMPRESS PI_STD {

+#      GUIDED {

+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi

+#        UI       STRING="$(MODULE_NAME)" Optional

+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)

+#      }

+#    }

+#  }

+#

+############################################################################

+

+[Rule.Common.SEC]

+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {

+    TE  TE    Align = 32                $(INF_OUTPUT)/$(MODULE_NAME).efi

+  }

+

+[Rule.Common.SEC.BINARY]

+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {

+    TE  TE    Align = 32                |.efi

+  }

+

+[Rule.Common.PEI_CORE]

+  FILE PEI_CORE = $(NAMED_GUID) {

+    TE     TE                           $(INF_OUTPUT)/$(MODULE_NAME).efi

+    UI     STRING ="$(MODULE_NAME)" Optional

+  }

+

+[Rule.Common.PEIM]

+  FILE PEIM = $(NAMED_GUID) {

+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex

+     TE       TE                        $(INF_OUTPUT)/$(MODULE_NAME).efi

+     UI       STRING="$(MODULE_NAME)" Optional

+  }

+

+[Rule.Common.PEIM.TIANOCOMPRESSED]

+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {

+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex

+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {

+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi

+      UI        STRING="$(MODULE_NAME)" Optional

+    }

+  }

+

+[Rule.Common.DXE_CORE]

+  FILE DXE_CORE = $(NAMED_GUID) {

+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi

+    UI       STRING="$(MODULE_NAME)" Optional

+  }

+

+[Rule.Common.UEFI_DRIVER]

+  FILE DRIVER = $(NAMED_GUID) {

+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex

+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi

+    UI           STRING="$(MODULE_NAME)" Optional

+  }

+

+[Rule.Common.UEFI_DRIVER.BINARY]

+  FILE DRIVER = $(NAMED_GUID) {

+    DXE_DEPEX    DXE_DEPEX              Optional |.depex

+    PE32         PE32                   |.efi

+    UI           STRING="$(MODULE_NAME)" Optional

+  }

+

+[Rule.Common.DXE_DRIVER]

+  FILE DRIVER = $(NAMED_GUID) {

+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex

+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi

+    UI           STRING="$(MODULE_NAME)" Optional

+  }

+[Rule.Common.DXE_DRIVER.BINARY]

+  FILE DRIVER = $(NAMED_GUID) {

+  DXE_DEPEX    DXE_DEPEX              Optional |.depex

+  PE32         PE32                   |.efi

+  UI           STRING="$(MODULE_NAME)" Optional

+  }

+

+[Rule.Common.DXE_RUNTIME_DRIVER]

+  FILE DRIVER = $(NAMED_GUID) {

+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex

+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi

+    UI           STRING="$(MODULE_NAME)" Optional

+  }

+

+[Rule.Common.UEFI_APPLICATION]

+  FILE APPLICATION = $(NAMED_GUID) {

+    UI     STRING ="$(MODULE_NAME)" Optional

+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi

+  }

+

+[Rule.Common.UEFI_APPLICATION.BINARY]

+  FILE APPLICATION = $(NAMED_GUID) {

+  PE32      PE32                    |.efi

+  UI        STRING="$(MODULE_NAME)" Optional

+}

+

+[Rule.Common.USER_DEFINED]

+  FILE FREEFORM = $(NAMED_GUID) {

+    RAW ACPI  Optional            |.acpi

+    RAW ASL   Optional            |.aml

+  }

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.efi b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.efi
new file mode 100644
index 0000000..69b7ef7
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.efi
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.inf
new file mode 100644
index 0000000..aa2b600
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Drivers/SnpPV600Dxe/SnpPV600Dxe.inf
@@ -0,0 +1,32 @@
+## @file

+# Component name for module SnpPV600Dxe

+# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = SnpPV600Dxe

+  FILE_GUID                      = 3247F15F-3612-4803-BD4E-4104D7EF944A

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InitializeSnpPV600Driver

+  UNLOAD_IMAGE                   = SnpPV600Unload

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+[Binaries.common]

+  PE32|SnpPV600Dxe.efi|*

+

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01Lib.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01Lib.inf
new file mode 100644
index 0000000..52b26cf
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01Lib.inf
@@ -0,0 +1,53 @@
+#/* @file

+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = RTSMArmD01Lib

+  FILE_GUID                      = b98a6cb7-d472-4128-ad62-a7347f85ce13

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmPlatformLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  IoLib

+  ArmLib

+  MemoryAllocationLib

+  SerialPortLib

+

+[Sources.common]

+  RTSM.c

+  RTSMMem.c  

+  RTSMHelper.asm    | RVCT

+  RTSMHelper.S      | GCC

+

+[FeaturePcd]

+  gEmbeddedTokenSpaceGuid.PcdCacheEnable

+  gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping

+  gArmPlatformTokenSpaceGuid.PcdStandalone

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdSystemMemoryBase

+  gArmTokenSpaceGuid.PcdSystemMemorySize

+  gArmTokenSpaceGuid.PcdFvBaseAddress

+

+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask

+  gArmTokenSpaceGuid.PcdArmPrimaryCore

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01LibSec.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01LibSec.inf
new file mode 100644
index 0000000..68cdbc9
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/D01LibSec.inf
@@ -0,0 +1,51 @@
+#/* @file

+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = RTSMArmD01LibSec

+  FILE_GUID                      = a79eed97-4b98-4974-9690-37b32d6a5b56

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmPlatformLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  IoLib

+  ArmLib

+  SerialPortLib

+

+[Sources.common]

+  RTSM.c

+  RTSMHelper.asm    | RVCT

+  RTSMHelper.S      | GCC

+

+[FeaturePcd]

+  gEmbeddedTokenSpaceGuid.PcdCacheEnable

+  gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping

+  gArmPlatformTokenSpaceGuid.PcdStandalone

+

+[FixedPcd]

+  gArmTokenSpaceGuid.PcdSystemMemoryBase

+  gArmTokenSpaceGuid.PcdSystemMemorySize

+  gArmTokenSpaceGuid.PcdFvBaseAddress

+

+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask

+  gArmTokenSpaceGuid.PcdArmPrimaryCore

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSM.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSM.c
new file mode 100644
index 0000000..eaaf5ab
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSM.c
@@ -0,0 +1,212 @@
+/** @file

+*

+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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/IoLib.h>

+#include <Library/ArmPlatformLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+#include <Ppi/ArmMpCoreInfo.h>

+

+#include <ArmPlatform.h>

+

+UINTN

+ArmGetCpuCountPerCluster (

+  VOID

+  );

+

+ARM_CORE_INFO mVersatileExpressMpCoreInfoTable[] = {

+  {

+    // Cluster 0, Core 0

+    0x0, 0x0,

+

+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+    (UINT64)0xFFFFFFFF

+  },

+  {

+    // Cluster 0, Core 1

+    0x0, 0x1,

+

+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+    (UINT64)0xFFFFFFFF

+  },

+  {

+    // Cluster 0, Core 2

+    0x0, 0x2,

+

+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+    (UINT64)0xFFFFFFFF

+  },

+  {

+    // Cluster 0, Core 3

+    0x0, 0x3,

+

+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+    (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+    (UINT64)0xFFFFFFFF

+  },

+  {

+      // Cluster 1, Core 0

+      0x1, 0x0,

+

+      // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+      (UINT64)0xFFFFFFFF

+    },

+  {

+      // Cluster 1, Core 1

+      0x1, 0x1,

+

+      // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+      (UINT64)0xFFFFFFFF

+    },

+  {

+      // Cluster 1, Core 2

+      0x1, 0x2,

+

+      // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+      (UINT64)0xFFFFFFFF

+    },

+  {

+      // Cluster 1, Core 3

+      0x1, 0x3,

+

+      // MP Core MailBox Set/Get/Clear Addresses and Clear Value

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,

+      (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,

+      (UINT64)0xFFFFFFFF

+    }

+};

+

+/**

+  Return the current Boot Mode

+

+  This function returns the boot reason on the platform

+

+  @return   Return the current Boot Mode of the platform

+

+**/

+EFI_BOOT_MODE

+ArmPlatformGetBootMode (

+  VOID

+  )

+{

+  return BOOT_WITH_FULL_CONFIGURATION;

+}

+

+/**

+  Initialize controllers that must setup in the normal world

+

+  This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim

+  in the PEI phase.

+

+**/

+RETURN_STATUS

+ArmPlatformInitialize (

+  IN  UINTN                     MpId

+  )

+{

+  if (!(((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore))) {

+    return RETURN_SUCCESS;

+  }

+

+  // Disable memory remapping and return to normal mapping

+  MmioOr32 (SP810_CTRL_BASE, BIT8);

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Initialize the system (or sometimes called permanent) memory

+

+  This memory is generally represented by the DRAM.

+

+**/

+VOID

+ArmPlatformInitializeSystemMemory (

+  VOID

+  )

+{

+  // Nothing to do here

+}

+

+EFI_STATUS

+PrePeiCoreGetMpCoreInfo (

+  OUT UINTN                   *CoreCount,

+  OUT ARM_CORE_INFO           **ArmCoreTable

+  )

+{

+#if 0

+  UINT32   ProcType;

+

+  ProcType = MmioRead32 (ARM_VE_SYS_PROCID0_REG) & ARM_VE_SYS_PROC_ID_MASK;

+  if ((ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A9) || (ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A15)) {

+    // Only support one cluster

+    *CoreCount    = ArmGetCpuCountPerCluster ();

+    *ArmCoreTable = mVersatileExpressMpCoreInfoTable;

+    return EFI_SUCCESS;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+#else

+

+    *CoreCount    = 2 * ArmGetCpuCountPerCluster ();

+    *ArmCoreTable = mVersatileExpressMpCoreInfoTable;

+

+    return EFI_SUCCESS;

+#endif

+}

+

+// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore

+EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;

+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };

+

+EFI_PEI_PPI_DESCRIPTOR      gPlatformPpiTable[] = {

+  {

+    EFI_PEI_PPI_DESCRIPTOR_PPI,

+    &mArmMpCoreInfoPpiGuid,

+    &mMpCoreInfoPpi

+  }

+};

+

+VOID

+ArmPlatformGetPlatformPpiList (

+  OUT UINTN                   *PpiListSize,

+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList

+  )

+{

+  *PpiListSize = sizeof(gPlatformPpiTable);

+  *PpiList = gPlatformPpiTable;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMHelper.S b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMHelper.S
new file mode 100644
index 0000000..ee5ce30
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMHelper.S
@@ -0,0 +1,117 @@
+#

+#  Copyright (c) 2011, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 <AsmMacroIoLib.h>

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/PcdLib.h>

+#include <AutoGen.h>

+#include "AsmMacroIoLib.inc"

+

+#include <Chipset/ArmCortexA9.h>

+

+.text

+.align 2

+

+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)

+GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)

+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)

+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)

+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)

+

+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)

+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)

+

+ASM_PFX(ArmPlatformPeiBootAction):

+  bx    lr

+

+# IN None

+# OUT r0 = SCU Base Address

+ASM_PFX(ArmGetScuBaseAddress):

+  # Read Configuration Base Address Register. ArmCBar cannot be called to get

+  # the Configuration BAR as a stack is not necessary setup. The SCU is at the

+  # offset 0x0000 from the Private Memory Region.

+  mrc   p15, 4, r0, c15, c0, 0

+  bx    lr

+

+//UINTN

+//ArmPlatformGetPrimaryCoreMpId (

+//  VOID

+//  );

+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):

+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)

+  ldr   r0, [r0]

+  bx    lr

+

+# IN None

+# OUT r0 = number of cores present in the system

+ASM_PFX(ArmGetCpuCountPerCluster):

+  stmfd SP!, {r1-r2}

+

+  # Read CP15 MIDR

+  mrc   p15, 0, r1, c0, c0, 0

+

+  # Check if the CPU is A15

+  mov   r1, r1, LSR #4

+  LoadConstantToReg (ARM_CPU_TYPE_MASK, r0)

+  and   r1, r1, r0

+

+  LoadConstantToReg (ARM_CPU_TYPE_A15, r0)

+  cmp   r1, r0

+  beq   _Read_cp15_reg

+

+_CPU_is_not_A15:

+  mov   r2, lr                           @ Save link register

+  bl    ArmGetScuBaseAddress             @ Read SCU Base Address

+  mov   lr, r2                           @ Restore link register val

+  ldr   r0, [r0, #A9_SCU_CONFIG_OFFSET]     @ Read SCU Config reg to get CPU count

+  b     _Return

+

+_Read_cp15_reg:

+  mrc   p15, 1, r0, c9, c0, 2            @ Read C9 register of CP15 to get CPU count

+  lsr   r0, #24

+

+_Return:

+  and   r0, r0, #3

+  # Add '1' to the number of CPU on the Cluster

+  add   r0, r0, #1

+  ldmfd SP!, {r1-r2}

+  bx lr

+

+//UINTN

+//ArmPlatformIsPrimaryCore (

+//  IN UINTN MpId

+//  );

+ASM_PFX(ArmPlatformIsPrimaryCore):

+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, r1)

+  ldr   r1, [r1]

+  and   r0, r0, r1

+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r1)

+  ldr   r1, [r1]

+  cmp   r0, r1

+  moveq r0, #1

+  movne r0, #0

+  bx 	lr

+

+//UINTN

+//ArmPlatformGetCorePosition (

+//  IN UINTN MpId

+//  );

+ASM_PFX(ArmPlatformGetCorePosition):

+  and   r1, r0, #ARM_CORE_MASK

+  and   r0, r0, #ARM_CLUSTER_MASK

+  add   r0, r1, r0, LSR #7

+  bx    lr

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED 

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMHelper.asm b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMHelper.asm
new file mode 100644
index 0000000..d1d3863
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMHelper.asm
@@ -0,0 +1,125 @@
+//

+//  Copyright (c) 2011, ARM Limited. All rights reserved.

+//  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 <AsmMacroIoLib.h>

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/PcdLib.h>

+

+#include <Chipset/ArmCortexA9.h>

+

+#include <AutoGen.h>

+

+  INCLUDE AsmMacroIoLib.inc

+

+  EXPORT    ArmPlatformPeiBootAction

+  EXPORT    ArmGetCpuCountPerCluster

+  EXPORT    ArmPlatformIsPrimaryCore

+  EXPORT    ArmPlatformGetPrimaryCoreMpId

+  EXPORT    ArmPlatformGetCorePosition

+

+  IMPORT    _gPcd_FixedAtBuild_PcdArmPrimaryCore

+  IMPORT    _gPcd_FixedAtBuild_PcdArmPrimaryCoreMask

+

+  AREA RTSMHelper, CODE, READONLY

+

+ArmPlatformPeiBootAction FUNCTION

+  bx    lr

+  ENDFUNC

+

+// IN None

+// OUT r0 = SCU Base Address

+ArmGetScuBaseAddress FUNCTION

+  // Read Configuration Base Address Register. ArmCBar cannot be called to get

+  // the Configuration BAR as a stack is not necessary setup. The SCU is at the

+  // offset 0x0000 from the Private Memory Region.

+  mrc   p15, 4, r0, c15, c0, 0

+  bx  lr

+  ENDFUNC

+

+//UINTN

+//ArmPlatformGetPrimaryCoreMpId (

+//  VOID

+//  );

+ArmPlatformGetPrimaryCoreMpId FUNCTION

+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)

+  ldr   r0, [r0]

+  bx    lr

+  ENDFUNC

+

+// IN None

+// OUT r0 = number of cores present in the system

+ArmGetCpuCountPerCluster FUNCTION

+  stmfd SP!, {r1-r2}

+

+  // Read CP15 MIDR

+  mrc   p15, 0, r1, c0, c0, 0

+

+  // Check if the CPU is A15

+  mov   r1, r1, LSR #4

+  mov   r0, #ARM_CPU_TYPE_MASK

+  and   r1, r1, r0

+

+  mov   r0, #ARM_CPU_TYPE_A15

+  cmp   r1, r0

+  beq   _Read_cp15_reg

+

+_CPU_is_not_A15

+  mov   r2, lr                              ; Save link register

+  bl    ArmGetScuBaseAddress                ; Read SCU Base Address

+  mov   lr, r2                              ; Restore link register val

+  ldr   r0, [r0, #A9_SCU_CONFIG_OFFSET]     ; Read SCU Config reg to get CPU count

+  b     _Return

+

+_Read_cp15_reg

+  mrc   p15, 1, r0, c9, c0, 2            ; Read C9 register of CP15 to get CPU count

+  lsr   r0, #24

+

+

+_Return

+  and   r0, r0, #3

+  // Add '1' to the number of CPU on the Cluster

+  add   r0, r0, #1

+  ldmfd SP!, {r1-r2}

+  bx lr

+  ENDFUNC

+

+//UINTN

+//ArmPlatformIsPrimaryCore (

+//  IN UINTN MpId

+//  );

+ArmPlatformIsPrimaryCore FUNCTION

+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, r1)

+  ldr   r1, [r1]

+  and   r0, r0, r1

+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r1)

+  ldr   r1, [r1]

+  cmp   r0, r1

+  moveq r0, #1

+  movne r0, #0

+  bx 	lr

+  ENDFUNC

+

+//UINTN

+//ArmPlatformGetCorePosition (

+//  IN UINTN MpId

+//  );

+ArmPlatformGetCorePosition FUNCTION

+  and   r1, r0, #ARM_CORE_MASK

+  and   r0, r0, #ARM_CLUSTER_MASK

+  add   r0, r1, r0, LSR #7

+  bx    lr

+  ENDFUNC

+

+  END

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMMem.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMMem.c
new file mode 100644
index 0000000..93f856f
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01LibRTSM/RTSMMem.c
@@ -0,0 +1,86 @@
+/** @file

+*

+*  Copyright (c) 2011, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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/ArmPlatformLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/IoLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <ArmPlatform.h>

+

+// Number of Virtual Memory Map Descriptors without a Logic Tile

+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          8

+

+// DDR attributes

+#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK

+#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED

+

+/**

+  Return the Virtual Memory Map of your platform

+

+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.

+

+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-

+                                    Virtual Memory mapping. This array must be ended by a zero-filled

+                                    entry

+

+**/

+VOID

+ArmPlatformGetVirtualMemoryMap (

+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap

+  )

+{

+  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;

+  UINTN                         Index = 0;

+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;

+

+  ASSERT(VirtualMemoryMap != NULL);

+

+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));

+  if (VirtualMemoryTable == NULL) {

+      return;

+  }

+

+  if (FeaturePcdGet(PcdCacheEnable) == TRUE) {

+      CacheAttributes = DDR_ATTRIBUTES_CACHED;

+  } else {

+      CacheAttributes = DDR_ATTRIBUTES_UNCACHED;

+  }

+  // memory

+  VirtualMemoryTable[Index].PhysicalBase = 0;

+  VirtualMemoryTable[Index].VirtualBase = 0;

+  VirtualMemoryTable[Index].Length = 0xe0000000;

+  VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;

+

+  // register

+  VirtualMemoryTable[++Index].PhysicalBase = 0xe0000000;

+  VirtualMemoryTable[Index].VirtualBase = 0xe0000000;

+  VirtualMemoryTable[Index].Length = 0x0e000000;

+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;

+

+  // flash

+  VirtualMemoryTable[++Index].PhysicalBase = 0xf0000000;

+  VirtualMemoryTable[Index].VirtualBase = 0xf0000000;

+  VirtualMemoryTable[Index].Length = 0x10000000;

+  VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;

+     

+  // End of Table

+  VirtualMemoryTable[++Index].PhysicalBase = 0;

+  VirtualMemoryTable[Index].VirtualBase = 0;

+  VirtualMemoryTable[Index].Length = 0;

+  VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;

+

+  *VirtualMemoryMap = VirtualMemoryTable;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/D01SecLib.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/D01SecLib.inf
new file mode 100644
index 0000000..2a88d39
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/D01SecLib.inf
@@ -0,0 +1,24 @@
+#/* @file

+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = RTSMArmD01SecLib

+  FILE_GUID                      = 1fdaabb0-ab7d-480c-91ff-428dc1546f3a

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmPlatformSecLib

+

+[binaries.common]

+  LIB|RTSMArmD01SecLib.lib

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.lib b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.lib
new file mode 100644
index 0000000..a52a060
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.lib
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
new file mode 100644
index 0000000..fc7c23d
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
@@ -0,0 +1,649 @@
+/** @file

+  Implement EFI RealTimeClock runtime services via RTC Lib.

+

+  Currently this driver does not support runtime virtual calling.

+

+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+  Copyright (c) 2011-2013, 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.

+

+**/

+

+#include <Uefi.h>

+#include <PiDxe.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+#include <Library/IoLib.h>

+#include <Library/RealTimeClockLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/PcdLib.h>

+#include <Library/ArmPlatformSysConfigLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Protocol/RealTimeClock.h>

+#include <Guid/GlobalVariable.h>

+#include <Drivers/PL031RealTimeClock.h>

+#include <Library/ArmArchTimer.h>

+#include <ArmPlatform.h>

+

+STATIC CONST CHAR16  mTimeZoneVariableName[] = L"PL031RtcTimeZone";

+STATIC CONST CHAR16  mDaylightVariableName[] = L"PL031RtcDaylight";

+STATIC BOOLEAN       mPL031Initialized = FALSE;

+

+EFI_STATUS

+IdentifyPL031 (

+  VOID

+  )

+{

+  EFI_STATUS    Status;

+

+  // Check if this is a PrimeCell Peripheral

+  if (  (MmioRead8 (PL031_RTC_PCELL_ID0) != 0x0D)

+      || (MmioRead8 (PL031_RTC_PCELL_ID1) != 0xF0)

+      || (MmioRead8 (PL031_RTC_PCELL_ID2) != 0x05)

+      || (MmioRead8 (PL031_RTC_PCELL_ID3) != 0xB1)) {

+    Status = EFI_NOT_FOUND;

+    goto EXIT;

+  }

+

+  // Check if this PrimeCell Peripheral is the PL031 Real Time Clock

+  if (  (MmioRead8 (PL031_RTC_PERIPH_ID0) != 0x31)

+      || (MmioRead8 (PL031_RTC_PERIPH_ID1) != 0x10)

+      || ((MmioRead8 (PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)

+      || (MmioRead8 (PL031_RTC_PERIPH_ID3) != 0x00)) {

+    Status = EFI_NOT_FOUND;

+    goto EXIT;

+  }

+

+  Status = EFI_SUCCESS;

+

+  EXIT:

+  return Status;

+}

+

+EFI_STATUS

+InitializePL031 (

+  VOID

+  )

+{

+  EFI_STATUS    Status;

+

+  // Prepare the hardware

+  Status = IdentifyPL031();

+  if (EFI_ERROR (Status)) {

+    goto EXIT;

+  }

+

+  // Ensure interrupts are masked. We do not want RTC interrupts in UEFI

+  if ((MmioRead32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {

+    MmioOr32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);

+  }

+

+  // Clear any existing interrupts

+  if ((MmioRead32 (PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {

+    MmioOr32 (PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);

+  }

+

+  // Start the clock counter

+  if ((MmioRead32 (PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {

+    MmioOr32 (PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);

+  }

+

+  mPL031Initialized = TRUE;

+

+  EXIT:

+  return Status;

+}

+

+/**

+  Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME

+ **/

+VOID

+EpochToEfiTime (

+  IN  UINTN     EpochSeconds,

+  OUT EFI_TIME  *Time

+  )

+{

+  UINTN         a;

+  UINTN         b;

+  UINTN         c;

+  UINTN         d;

+  UINTN         g;

+  UINTN         j;

+  UINTN         m;

+  UINTN         y;

+  UINTN         da;

+  UINTN         db;

+  UINTN         dc;

+  UINTN         dg;

+  UINTN         hh;

+  UINTN         mm;

+  UINTN         ss;

+  UINTN         J;

+

+  J  = (EpochSeconds / 86400) + 2440588;

+  j  = J + 32044;

+  g  = j / 146097;

+  dg = j % 146097;

+  c  = (((dg / 36524) + 1) * 3) / 4;

+  dc = dg - (c * 36524);

+  b  = dc / 1461;

+  db = dc % 1461;

+  a  = (((db / 365) + 1) * 3) / 4;

+  da = db - (a * 365);

+  y  = (g * 400) + (c * 100) + (b * 4) + a;

+  m  = (((da * 5) + 308) / 153) - 2;

+  d  = da - (((m + 4) * 153) / 5) + 122;

+

+  Time->Year  = y - 4800 + ((m + 2) / 12);

+  Time->Month = ((m + 2) % 12) + 1;

+  Time->Day   = d + 1;

+

+  ss = EpochSeconds % 60;

+  a  = (EpochSeconds - ss) / 60;

+  mm = a % 60;

+  b = (a - mm) / 60;

+  hh = b % 24;

+

+  Time->Hour        = hh;

+  Time->Minute      = mm;

+  Time->Second      = ss;

+  Time->Nanosecond  = 0;

+

+}

+

+/**

+  Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC)

+ **/

+UINTN

+EfiTimeToEpoch (

+  IN  EFI_TIME  *Time

+  )

+{

+  UINTN a;

+  UINTN y;

+  UINTN m;

+  UINTN JulianDate;  // Absolute Julian Date representation of the supplied Time

+  UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY

+  UINTN EpochSeconds;

+

+  a = (14 - Time->Month) / 12 ;

+  y = Time->Year + 4800 - a;

+  m = Time->Month + (12*a) - 3;

+

+  JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045;

+

+  ASSERT (JulianDate >= EPOCH_JULIAN_DATE);

+  EpochDays = JulianDate - EPOCH_JULIAN_DATE;

+

+  EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;

+

+  return EpochSeconds;

+}

+

+BOOLEAN

+IsLeapYear (

+  IN EFI_TIME   *Time

+  )

+{

+  if (Time->Year % 4 == 0) {

+    if (Time->Year % 100 == 0) {

+      if (Time->Year % 400 == 0) {

+        return TRUE;

+      } else {

+        return FALSE;

+      }

+    } else {

+      return TRUE;

+    }

+  } else {

+    return FALSE;

+  }

+}

+

+BOOLEAN

+DayValid (

+  IN  EFI_TIME  *Time

+  )

+{

+  INTN  DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

+

+  if (Time->Day < 1 ||

+      Time->Day > DayOfMonth[Time->Month - 1] ||

+      (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))

+     ) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Returns the current time and date information, and the time-keeping capabilities

+  of the hardware platform.

+

+  @param  Time                   A pointer to storage to receive a snapshot of the current time.

+  @param  Capabilities           An optional pointer to a buffer to receive the real time clock

+                                 device's capabilities.

+

+  @retval EFI_SUCCESS            The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER  Time is NULL.

+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.

+  @retval EFI_SECURITY_VIOLATION The time could not be retrieved due to an authentication failure.

+

+**/

+EFI_STATUS

+EFIAPI

+LibGetTime (

+  OUT EFI_TIME                *Time,

+  OUT EFI_TIME_CAPABILITIES   *Capabilities

+  )

+{

+  EFI_STATUS  Status = EFI_SUCCESS;

+  UINT64      Temp;

+  UINT32      EpochSeconds;

+  INT16       TimeZone = 0;

+  UINT8       Daylight = 0;

+  UINTN       Size;

+

+#if 0

+  // Initialize the hardware if not already done

+  if (!mPL031Initialized) {

+    Status = InitializePL031 ();

+    if (EFI_ERROR (Status)) {

+      goto EXIT;

+    }

+  }

+#endif

+  // Snapshot the time as early in the function call as possible

+  // On some platforms we may have access to a battery backed up hardware clock.

+  // If such RTC exists try to use it first.

+  Status = ArmPlatformSysConfigGet (SYS_CFG_RTC, &EpochSeconds);

+  if (Status == EFI_UNSUPPORTED) {

+    // Battery backed up hardware RTC does not exist, revert to PL031

+    ArmArchTimerReadReg(CntPct,&Temp);

+    EpochSeconds = Temp / PcdGet32(PcdArmArchTimerFreqInHz);

+    //EpochSeconds = MmioRead32 (PL031_RTC_DR_DATA_REGISTER);

+

+    Status = EFI_SUCCESS;

+  } else if (EFI_ERROR (Status)) {

+    // Battery backed up hardware RTC exists but could not be read due to error. Abort.

+    goto EXIT;

+  } else {

+    // Battery backed up hardware RTC exists and we read the time correctly from it.

+    // Now sync the PL031 to the new time.

+    MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);

+  }

+

+  // Ensure Time is a valid pointer

+  if (Time == NULL) {

+    Status = EFI_INVALID_PARAMETER;

+    goto EXIT;

+  }

+

+  // Get the current time zone information from non-volatile storage

+  Size = sizeof (TimeZone);

+  Status = gRT->GetVariable (

+                  (CHAR16 *)mTimeZoneVariableName,

+                  &gEfiCallerIdGuid,

+                  NULL,

+                  &Size,

+                  (VOID *)&TimeZone

+                  );

+

+  if (EFI_ERROR (Status)) {

+    ASSERT(Status != EFI_INVALID_PARAMETER);

+    ASSERT(Status != EFI_BUFFER_TOO_SMALL);

+

+    if (Status != EFI_NOT_FOUND)

+      goto EXIT;

+

+    // The time zone variable does not exist in non-volatile storage, so create it.

+    Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;

+    // Store it

+    Status = gRT->SetVariable (

+                    (CHAR16 *)mTimeZoneVariableName,

+                    &gEfiCallerIdGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    Size,

+                    (VOID *)&(Time->TimeZone)

+                    );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((

+        EFI_D_ERROR,

+        "LibGetTime: Failed to save %s variable to non-volatile storage, Status = %r\n",

+        mTimeZoneVariableName,

+        Status

+        ));

+      goto EXIT;

+    }

+  } else {

+    // Got the time zone

+    Time->TimeZone = TimeZone;

+

+    // Check TimeZone bounds:   -1440 to 1440 or 2047

+    if (((Time->TimeZone < -1440) || (Time->TimeZone > 1440))

+        && (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE)) {

+      Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;

+    }

+

+    // Adjust for the correct time zone

+    if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {

+      EpochSeconds += Time->TimeZone * SEC_PER_MIN;

+    }

+  }

+

+  // Get the current daylight information from non-volatile storage

+  Size = sizeof (Daylight);

+  Status = gRT->GetVariable (

+                  (CHAR16 *)mDaylightVariableName,

+                  &gEfiCallerIdGuid,

+                  NULL,

+                  &Size,

+                  (VOID *)&Daylight

+                  );

+

+  if (EFI_ERROR (Status)) {

+    ASSERT(Status != EFI_INVALID_PARAMETER);

+    ASSERT(Status != EFI_BUFFER_TOO_SMALL);

+

+    if (Status != EFI_NOT_FOUND)

+      goto EXIT;

+

+    // The daylight variable does not exist in non-volatile storage, so create it.

+    Time->Daylight = 0;

+    // Store it

+    Status = gRT->SetVariable (

+                    (CHAR16 *)mDaylightVariableName,

+                    &gEfiCallerIdGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    Size,

+                    (VOID *)&(Time->Daylight)

+                    );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((

+        EFI_D_ERROR,

+        "LibGetTime: Failed to save %s variable to non-volatile storage, Status = %r\n",

+        mDaylightVariableName,

+        Status

+        ));

+      goto EXIT;

+    }

+  } else {

+    // Got the daylight information

+    Time->Daylight = Daylight;

+

+    // Adjust for the correct period

+    if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {

+      // Convert to adjusted time, i.e. spring forwards one hour

+      EpochSeconds += SEC_PER_HOUR;

+    }

+  }

+

+  // Convert from internal 32-bit time to UEFI time

+  EpochToEfiTime (EpochSeconds, Time);

+

+  // Update the Capabilities info

+  if (Capabilities != NULL) {

+    // PL031 runs at frequency 1Hz

+    Capabilities->Resolution  = PL031_COUNTS_PER_SECOND;

+    // Accuracy in ppm multiplied by 1,000,000, e.g. for 50ppm set 50,000,000

+    Capabilities->Accuracy    = (UINT32)PcdGet32 (PcdPL031RtcPpmAccuracy);

+    // FALSE: Setting the time does not clear the values below the resolution level

+    Capabilities->SetsToZero  = FALSE;

+  }

+

+  EXIT:

+  return Status;

+}

+

+

+/**

+  Sets the current local time and date information.

+

+  @param  Time                  A pointer to the current time.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+LibSetTime (

+  IN  EFI_TIME                *Time

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       EpochSeconds;

+

+  // Check the input parameters are within the range specified by UEFI

+  if ((Time->Year   < 1900) ||

+       (Time->Year   > 9999) ||

+       (Time->Month  < 1   ) ||

+       (Time->Month  > 12  ) ||

+       (!DayValid (Time)    ) ||

+       (Time->Hour   > 23  ) ||

+       (Time->Minute > 59  ) ||

+       (Time->Second > 59  ) ||

+       (Time->Nanosecond > 999999999) ||

+       (!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) ||

+       (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))

+    ) {

+    Status = EFI_INVALID_PARAMETER;

+    goto EXIT;

+  }

+

+  // Because the PL031 is a 32-bit counter counting seconds,

+  // the maximum time span is just over 136 years.

+  // Time is stored in Unix Epoch format, so it starts in 1970,

+  // Therefore it can not exceed the year 2106.

+  if ((Time->Year < 1970) || (Time->Year >= 2106)) {

+    Status = EFI_UNSUPPORTED;

+    goto EXIT;

+  }

+

+  // Initialize the hardware if not already done

+  if (!mPL031Initialized) {

+    Status = InitializePL031 ();

+    if (EFI_ERROR (Status)) {

+      goto EXIT;

+    }

+  }

+

+  EpochSeconds = EfiTimeToEpoch (Time);

+

+  // Adjust for the correct time zone, i.e. convert to UTC time zone

+  if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {

+    EpochSeconds -= Time->TimeZone * SEC_PER_MIN;

+  }

+

+  // TODO: Automatic Daylight activation

+

+  // Adjust for the correct period

+  if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {

+    // Convert to un-adjusted time, i.e. fall back one hour

+    EpochSeconds -= SEC_PER_HOUR;

+  }

+

+  // On some platforms we may have access to a battery backed up hardware clock.

+  //

+  // If such RTC exists then it must be updated first, before the PL031,

+  // to minimise any time drift. This is important because the battery backed-up

+  // RTC maintains the master time for the platform across reboots.

+  //

+  // If such RTC does not exist then the following function returns UNSUPPORTED.

+  Status = ArmPlatformSysConfigSet (SYS_CFG_RTC, EpochSeconds);

+  if ((EFI_ERROR (Status)) && (Status != EFI_UNSUPPORTED)){

+    // Any status message except SUCCESS and UNSUPPORTED indicates a hardware failure.

+    goto EXIT;

+  }

+

+

+  // Set the PL031

+  MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);

+

+  // The accesses to Variable Services can be very slow, because we may be writing to Flash.

+  // Do this after having set the RTC.

+

+  // Save the current time zone information into non-volatile storage

+  Status = gRT->SetVariable (

+                  (CHAR16 *)mTimeZoneVariableName,

+                  &gEfiCallerIdGuid,

+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                  sizeof (Time->TimeZone),

+                  (VOID *)&(Time->TimeZone)

+                  );

+  if (EFI_ERROR (Status)) {

+      DEBUG ((

+        EFI_D_ERROR,

+        "LibSetTime: Failed to save %s variable to non-volatile storage, Status = %r\n",

+        mTimeZoneVariableName,

+        Status

+        ));

+    goto EXIT;

+  }

+

+  // Save the current daylight information into non-volatile storage

+  Status = gRT->SetVariable (

+                  (CHAR16 *)mDaylightVariableName,

+                  &gEfiCallerIdGuid,

+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                  sizeof(Time->Daylight),

+                  (VOID *)&(Time->Daylight)

+                  );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((

+      EFI_D_ERROR,

+      "LibSetTime: Failed to save %s variable to non-volatile storage, Status = %r\n",

+      mDaylightVariableName,

+      Status

+      ));

+    goto EXIT;

+  }

+

+  EXIT:

+  return Status;

+}

+

+

+/**

+  Returns the current wakeup alarm clock setting.

+

+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.

+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.

+  @param  Time                  The current alarm setting.

+

+  @retval EFI_SUCCESS           The alarm settings were returned.

+  @retval EFI_INVALID_PARAMETER Any parameter is NULL.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+LibGetWakeupTime (

+  OUT BOOLEAN     *Enabled,

+  OUT BOOLEAN     *Pending,

+  OUT EFI_TIME    *Time

+  )

+{

+  // Not a required feature

+  return EFI_UNSUPPORTED;

+}

+

+

+/**

+  Sets the system wakeup alarm clock time.

+

+  @param  Enabled               Enable or disable the wakeup alarm.

+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.

+

+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If

+                                Enable is FALSE, then the wakeup alarm was disabled.

+  @retval EFI_INVALID_PARAMETER A time field is out of range.

+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.

+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.

+

+**/

+EFI_STATUS

+EFIAPI

+LibSetWakeupTime (

+  IN BOOLEAN      Enabled,

+  OUT EFI_TIME    *Time

+  )

+{

+  // Not a required feature

+  return EFI_UNSUPPORTED;

+}

+

+

+

+/**

+  This is the declaration of an EFI image entry point. This can be the entry point to an application

+  written to this specification, an EFI boot service driver, or an EFI runtime driver.

+

+  @param  ImageHandle           Handle that identifies the loaded image.

+  @param  SystemTable           System Table for this image.

+

+  @retval EFI_SUCCESS           The operation completed successfully.

+

+**/

+EFI_STATUS

+EFIAPI

+LibRtcInitialize (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+{

+  EFI_STATUS    Status;

+  EFI_HANDLE    Handle;

+

+  // Setup the setters and getters

+  gRT->GetTime       = LibGetTime;

+  gRT->SetTime       = LibSetTime;

+  gRT->GetWakeupTime = LibGetWakeupTime;

+  gRT->SetWakeupTime = LibSetWakeupTime;

+

+  // Install the protocol

+  Handle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Handle,

+                  &gEfiRealTimeClockArchProtocolGuid,  NULL,

+                  NULL

+                 );

+

+  return Status;

+}

+

+

+/**

+  Fixup internal data so that EFI can be call in virtual mode.

+  Call the passed in Child Notify event and convert any pointers in

+  lib to virtual mode.

+

+  @param[in]    Event   The Event that is being processed

+  @param[in]    Context Event Context

+**/

+VOID

+EFIAPI

+LibRtcVirtualNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+{

+  //

+  // Only needed if you are going to support the OS calling RTC functions in virtual mode.

+  // You will need to call EfiConvertPointer (). To convert any stored physical addresses

+  // to virtual address. After the OS transitions to calling in virtual mode, all future

+  // runtime calls will be made in virtual mode.

+  //

+  return;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
new file mode 100644
index 0000000..99165b7
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
@@ -0,0 +1,45 @@
+#/** @file

+#

+# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>

+# Copyright (c) 2011-2013, 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                      = PL031RealTimeClockLib

+  FILE_GUID                      = 470DFB96-E205-4515-A75E-2E60F853E79D

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = RealTimeClockLib

+

+[Sources.common]

+  PL031RealTimeClockLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  ArmPkg/ArmPkg.dec

+

+[LibraryClasses]

+  IoLib

+  UefiLib

+  DebugLib

+  PcdLib

+  ArmPlatformSysConfigLib

+  ArmLib

+

+[Pcd]

+  gArmPlatformTokenSpaceGuid.PcdPL031RtcBase

+  gArmPlatformTokenSpaceGuid.PcdPL031RtcPpmAccuracy

+

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/ResetWdtLib/ResetWdtLib.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/ResetWdtLib/ResetWdtLib.c
new file mode 100644
index 0000000..fde422e
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/ResetWdtLib/ResetWdtLib.c
@@ -0,0 +1,37 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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/ResetWdtLib.h>

+#include <Library/DebugLib.h>

+#include <Library/SerialPortLib/SerialPortLib.h>  

+

+void Delay(unsigned long ulCount)

+{

+    unsigned int ulRet, ulNumber;

+    for(ulRet = 0; ulRet < 2; ulRet++)

+    {

+        ulNumber = ulCount;

+        while ( ulNumber-- )

+        {

+            ;

+        }

+    }

+}

+void WDT_ResetWatchdog(void)

+{

+    outl_wdt((inl_wdt(GPIO3_BASE_ADDR) | GPIO_MASK(21)), GPIO3_BASE_ADDR);

+    Delay(100);

+    outl_wdt((inl_wdt(GPIO3_BASE_ADDR) & (~GPIO_MASK(21))), GPIO3_BASE_ADDR);

+    return;

+}

+

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/ResetWdtLib/ResetWdtLib.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/ResetWdtLib/ResetWdtLib.inf
new file mode 100644
index 0000000..221cc00
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Library/ResetWdtLib/ResetWdtLib.inf
@@ -0,0 +1,41 @@
+#/** @file

+#  

+#  Component discription file for NorFlashDxe module

+#  

+#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = ResetWdtLib

+  FILE_GUID                      = 16D53E86-7EA6-47bd-862F-511FD9B8ABF0

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ResetWdtLib

+

+

+[Sources.common]

+  ResetWdtLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  HisiPkg/HisiPlatformPkg.dec

+  

+[LibraryClasses]

+  BaseLib

+  DebugLib

+  DebugAgentLib

+  SerialPortLib

+  

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Arch.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Arch.c
new file mode 100644
index 0000000..85df081
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Arch.c
@@ -0,0 +1,25 @@
+/** @file

+*

+*  Copyright (c) 2013, ARM 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.

+*

+**/

+

+#include <Chipset/ArmV7.h>

+

+VOID

+EFIAPI

+ArmSecArchTrustzoneInit (

+  VOID

+  )

+{

+  // Write to CP15 Non-secure Access Control Register

+  ArmWriteNsacr (PcdGet32 (PcdArmNsacr));

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Helper.S b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Helper.S
new file mode 100644
index 0000000..dd0a572
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Helper.S
@@ -0,0 +1,88 @@
+#========================================================================================

+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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.             

+#

+#=======================================================================================

+

+#start of the code section

+.text 

+.align 3

+

+GCC_ASM_EXPORT(return_from_exception)

+GCC_ASM_EXPORT(enter_monitor_mode)

+GCC_ASM_EXPORT(copy_cpsr_into_spsr)

+GCC_ASM_EXPORT(set_non_secure_mode)

+

+# r0: Monitor World EntryPoint

+# r1: MpId

+# r2: SecBootMode

+# r3: Secure Monitor mode stack

+ASM_PFX(enter_monitor_mode):

+    cmp     r3, #0                      @ If a Secure Monitor stack base has not been defined then use the Secure stack

+    moveq   r3, sp

+

+    mrs     r4, cpsr                    @ Save current mode (SVC) in r4

+    bic     r5, r4, #0x1f               @ Clear all mode bits

+    orr     r5, r5, #0x16               @ Set bits for Monitor mode

+    msr     cpsr_cxsf, r5               @ We are now in Monitor Mode

+

+    mov     sp, r3                      @ Set the stack of the Monitor Mode

+

+    mov     lr, r0                      @ Use the pass entrypoint as lr

+    

+    msr     spsr_cxsf, r4               @ Use saved mode for the MOVS jump to the kernel

+

+    mov     r4, r0                      @ Swap EntryPoint and MpId registers

+    mov     r0, r1

+    mov     r1, r2

+    mov     r2, r3

+

+    bx      r4

+

+# We cannot use the instruction 'movs pc, lr' because the caller can be written either in ARM or Thumb2 assembler.

+# When we will jump into this function, we will set the CPSR flag to ARM assembler. By copying directly 'lr' into

+# 'pc'; we will not change the CPSR flag and it will crash.

+# The way to fix this limitation is to do the movs into the ARM assmbler code and then do a 'bx'.

+ASM_PFX(return_from_exception):

+    ldr     lr, returned_exception

+

+    #The following instruction breaks the code.

+    #movs    pc, lr

+    mrs     r2, cpsr

+    bic     r2, r2, #0x1f

+    orr     r2, r2, #0x13

+    msr     cpsr_c, r2

+

+returned_exception:                           @ We are now in non-secure state

+    bx      r0

+

+# Save the current Program Status Register (PSR) into the Saved PSR

+ASM_PFX(copy_cpsr_into_spsr):

+    mrs     r0, cpsr

+    msr     spsr_cxsf, r0

+    bx      lr

+

+# Set the Non Secure Mode

+ASM_PFX(set_non_secure_mode):

+    push    { r1 }

+    and	    r0, r0, #0x1f     @ Keep only the mode bits

+    mrs     r1, spsr          @ Read the spsr

+    bic     r1, r1, #0x1f     @ Clear all mode bits

+    orr	    r1, r1, r0

+    msr     spsr_cxsf, r1     @ write back spsr (may have caused a mode switch)

+    isb

+    pop     { r1 }

+    bx      lr                @ return (hopefully thumb-safe!)

+

+dead:

+    b       dead

+    

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Helper.asm b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Helper.asm
new file mode 100644
index 0000000..4903e54
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/Helper.asm
@@ -0,0 +1,80 @@
+//

+//  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+//  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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.             

+//

+//

+

+    EXPORT  return_from_exception

+    EXPORT  enter_monitor_mode

+    EXPORT  copy_cpsr_into_spsr

+    EXPORT  set_non_secure_mode

+    

+    AREA   Helper, CODE, READONLY

+

+// r0: Monitor World EntryPoint

+// r1: MpId

+// r2: SecBootMode

+// r3: Secure Monitor mode stack

+enter_monitor_mode FUNCTION

+    cmp     r3, #0                      // If a Secure Monitor stack base has not been defined then use the Secure stack

+    moveq   r3, sp

+

+    mrs     r4, cpsr                    // Save current mode (SVC) in r4

+    bic     r5, r4, #0x1f               // Clear all mode bits

+    orr     r5, r5, #0x16               // Set bits for Monitor mode

+    msr     cpsr_cxsf, r5               // We are now in Monitor Mode

+

+    mov     sp, r3                      // Set the stack of the Monitor Mode

+

+    mov     lr, r0                      // Use the pass entrypoint as lr

+    

+    msr     spsr_cxsf, r4               // Use saved mode for the MOVS jump to the kernel

+

+    mov     r4, r0                      // Swap EntryPoint and MpId registers

+    mov     r0, r1

+    mov     r1, r2

+    mov     r2, r3

+

+    bx      r4

+    ENDFUNC

+

+// We cannot use the instruction 'movs pc, lr' because the caller can be written either in ARM or Thumb2 assembler.

+// When we will jump into this function, we will set the CPSR flag to ARM assembler. By copying directly 'lr' into

+// 'pc'; we will not change the CPSR flag and it will crash.

+// The way to fix this limitation is to do the movs into the ARM assmbler code and then do a 'bx'.

+return_from_exception

+    adr     lr, returned_exception

+    movs    pc, lr

+returned_exception                           // We are now in non-secure state

+    bx      r0

+

+// Save the current Program Status Register (PSR) into the Saved PSR

+copy_cpsr_into_spsr

+    mrs     r0, cpsr

+    msr     spsr_cxsf, r0

+    bx      lr

+

+// Set the Non Secure Mode

+set_non_secure_mode

+    push    { r1 }

+    and     r0, r0, #0x1f     // Keep only the mode bits

+    mrs     r1, spsr          // Read the spsr

+    bic     r1, r1, #0x1f     // Clear all mode bits

+    orr	    r1, r1, r0

+    msr     spsr_cxsf, r1     // write back spsr (may have caused a mode switch)

+    isb

+    pop     { r1 }

+    bx      lr                // return (hopefully thumb-safe!)

+

+dead

+    B       dead

+    

+    END

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/SecEntryPoint.S b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/SecEntryPoint.S
new file mode 100644
index 0000000..85fccff
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/SecEntryPoint.S
@@ -0,0 +1,137 @@
+//

+//  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+//  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 <AutoGen.h>

+#include <AsmMacroIoLib.h>

+#include "SecInternal.h"

+

+.text

+.align 3

+

+GCC_ASM_IMPORT(CEntryPoint)

+GCC_ASM_IMPORT(ArmPlatformSecBootAction)

+GCC_ASM_IMPORT(ArmPlatformSecBootMemoryInit)

+GCC_ASM_IMPORT(ArmDisableInterrupts)

+GCC_ASM_IMPORT(ArmDisableCachesAndMmu)

+GCC_ASM_IMPORT(ArmReadMpidr)

+GCC_ASM_IMPORT(ArmCallWFE)

+GCC_ASM_EXPORT(_ModuleEntryPoint)

+

+StartupAddr:        .word       ASM_PFX(CEntryPoint)

+

+// Convert the (ClusterId,CoreId) into a Core Position

+// 0x0F03 is the magic value for ARM_CORE_MASK | ARM_CLUSTER_MASK

+//Core is 0-1 bits and cluster is 8-11 bits

+#define GetCorePositionFromMpId(Pos, MpId, Tmp)    \

+	ldr   Tmp, =0x0F03 ;                             \

+	and   MpId, Tmp ;                                \

+	lsr   Pos, MpId, #6 ;                            \

+	and   Tmp, MpId, #3 ;                            \

+	add   Pos, Pos, Tmp

+

+ASM_PFX(_ModuleEntryPoint):

+  // First ensure all interrupts are disabled

+  bl    ASM_PFX(ArmDisableInterrupts)

+

+  // Ensure that the MMU and caches are off

+  bl    ASM_PFX(ArmDisableCachesAndMmu)

+

+  // By default, we are doing a cold boot

+  mov   r10, #ARM_SEC_COLD_BOOT

+

+  // Jump to Platform Specific Boot Action function

+  blx   ASM_PFX(ArmPlatformSecBootAction)

+

+_IdentifyCpu:

+  // Identify CPU ID

+  bl    ASM_PFX(ArmReadMpidr)

+  // Get ID of this CPU in Multicore system

+  LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)

+  and   r5, r0, r1

+  

+  // Is it the Primary Core ?

+  LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3)

+  cmp   r5, r3

+  // Only the primary core initialize the memory (SMC)

+  beq   _InitMem

+  

+_WaitInitMem:

+  // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized

+  // Otherwise we have to wait the Primary Core to finish the initialization

+  cmp   r10, #ARM_SEC_COLD_BOOT

+  bne   _SetupSecondaryCoreStack

+

+  // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)

+  bl    ASM_PFX(ArmCallWFE)

+  // Now the Init Mem is initialized, we setup the secondary core stacks

+  b     _SetupSecondaryCoreStack

+  

+_InitMem:

+  // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized

+  cmp   r10, #ARM_SEC_COLD_BOOT

+  bne   _SetupPrimaryCoreStack

+

+  // Initialize Init Boot Memory

+  bl    ASM_PFX(ArmPlatformSecBootMemoryInit)

+  

+  // Only Primary CPU could run this line (the secondary cores have jumped from _IdentifyCpu to _SetupStack)

+  LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r5)

+

+_SetupPrimaryCoreStack:

+  // Get the top of the primary stacks (and the base of the secondary stacks)

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)

+  add   r1, r1, r2

+

+  LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), r2)

+

+  // The reserved space for global variable must be 8-bytes aligned for pushing

+  // 64-bit variable on the stack

+  SetPrimaryStack (r1, r2, r3)

+  b     _PrepareArguments

+

+_SetupSecondaryCoreStack:

+  // Get the top of the primary stacks (and the base of the secondary stacks)

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)

+  add   r1, r1, r2

+

+  // Get the Core Position (ClusterId * 4) + CoreId

+  GetCorePositionFromMpId(r0, r5, r2)

+  // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack

+  add   r0, r0, #1

+

+  // StackOffset = CorePos * StackSize

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)

+  mul   r0, r0, r2

+  // SP = StackBase + StackOffset

+  add   sp, r1, r0

+

+_PrepareArguments:

+  // Move sec startup address into a data register

+  // Ensure we're jumping to FV version of the code (not boot remapped alias)

+  ldr   r3, StartupAddr

+  

+  ORR	 r3, r3, #(0xf0 << 24)

+  ORR	 r3, r3, #(0x10 << 16)

+  

+  // Jump to SEC C code

+  //    r0 = mp_id

+  //    r1 = Boot Mode

+  mov   r0, r5

+  mov   r1, r10

+  blx   r3

+  

+_NeverReturn:

+  b _NeverReturn

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/SecEntryPoint.asm b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/SecEntryPoint.asm
new file mode 100644
index 0000000..ff24bc5
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Arm/SecEntryPoint.asm
@@ -0,0 +1,148 @@
+//

+//  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+//  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 <AutoGen.h>

+#include <AsmMacroIoLib.h>

+#include "SecInternal.h"

+

+  INCLUDE AsmMacroIoLib.inc

+  

+  IMPORT  CEntryPoint

+  IMPORT  ArmPlatformSecBootAction

+  IMPORT  ArmPlatformSecBootMemoryInit

+  IMPORT  ArmDisableInterrupts

+  IMPORT  ArmDisableCachesAndMmu

+  IMPORT  ArmReadMpidr

+  IMPORT  ArmCallWFE

+  EXPORT  _ModuleEntryPoint

+

+  PRESERVE8

+  AREA    SecEntryPoint, CODE, READONLY

+  

+StartupAddr        DCD      CEntryPoint

+CTRL_M_BIT		EQU 	(1 << 0)

+CTRL_C_BIT		EQU 	(1 << 2)

+CTRL_B_BIT		EQU 	(1 << 7)

+CTRL_I_BIT		EQU 	(1 << 12)

+

+_ModuleEntryPoint FUNCTION

+  // First ensure all interrupts are disabled

+  ;blx   ArmDisableInterrupts

+	cpsie	if

+	isb

+

+  // Ensure that the MMU and caches are off

+  ;blx   ArmDisableCachesAndMmu

+	mrc   p15, 0, r0, c1, c0, 0 		  ; Get control register

+	bic	r0, r0, #CTRL_M_BIT 			; Disable MMU

+	bic	r0, r0, #CTRL_C_BIT 			; Disable D Cache

+	bic	r0, r0, #CTRL_I_BIT 			; Disable I Cache

+	mcr	p15, 0, r0, c1, c0, 0			; Write control register

+	dsb

+	isb

+

+  // By default, we are doing a cold boot

+  ;mov   r10, #ARM_SEC_COLD_BOOT

+

+  // Jump to Platform Specific Boot Action function

+  blx   ArmPlatformSecBootAction

+

+_IdentifyCpu 

+  // Identify CPU ID

+  bl    ArmReadMpidr

+  // Get ID of this CPU in Multicore system

+  LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)

+  and   r5, r0, r1

+  

+  // Is it the Primary Core ?

+  LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3)

+  cmp   r5, r3

+  // Only the primary core initialize the memory (SMC)

+  beq   _InitMem

+  

+_WaitInitMem

+  // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized

+  // Otherwise we have to wait the Primary Core to finish the initialization

+  cmp   r10, #ARM_SEC_COLD_BOOT

+  bne   _SetupSecondaryCoreStack

+

+  // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)

+  bl    ArmCallWFE

+  // Now the Init Mem is initialized, we setup the secondary core stacks

+  b     _SetupSecondaryCoreStack

+  

+_InitMem

+  // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized

+  ;cmp   r10, #ARM_SEC_COLD_BOOT

+  ;bne   _SetupPrimaryCoreStack

+

+  // Initialize Init Boot Memory

+  bl    ArmPlatformSecBootMemoryInit

+  

+  // Only Primary CPU could run this line (the secondary cores have jumped from _IdentifyCpu to _SetupStack)

+  ;LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r5)

+

+;_SetupPrimaryCoreStack

+  ;// Get the top of the primary stacks (and the base of the secondary stacks)

+  ;LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)

+  ;LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)

+  ;add   r1, r1, r2

+

+  ;LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), r2)

+

+  ;// The reserved space for global variable must be 8-bytes aligned for pushing

+  ;// 64-bit variable on the stack

+  ;SetPrimaryStack (r1, r2, r3)

+  b     _PrepareArguments

+

+_SetupSecondaryCoreStack

+  // Get the top of the primary stacks (and the base of the secondary stacks)

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)

+  add   r1, r1, r2

+

+  // Get the Core Position (ClusterId * 4) + CoreId

+  ;GetCorePositionFromMpId(r0, r5, r2)

+  lsr	r0, r5, #6

+  and	r2, r5, #3

+  add	r0, r0, r2

+  // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack

+  add   r0, r0, #1

+

+  // StackOffset = CorePos * StackSize

+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)

+  mul   r0, r0, r2

+  // SP = StackBase + StackOffset

+  add   sp, r1, r0

+

+_PrepareArguments

+  // Move sec startup address into a data register

+  // Ensure we're jumping to FV version of the code (not boot remapped alias)

+  ldr   r3, StartupAddr

+  

+  ORR	 r3, r3, #(0xf0 << 24)

+  ORR	 r3, r3, #(0x10 << 16)

+  

+  // Jump to SEC C code

+  //    r0 = mp_id

+  //    r1 = Boot Mode

+  mov   r0, r5

+  mov   r1, r10

+  

+  blx   r3

+  ENDFUNC

+  

+_NeverReturn

+  b _NeverReturn

+  END

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Sec.c b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Sec.c
new file mode 100644
index 0000000..c77e72e
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Sec.c
@@ -0,0 +1,197 @@
+/** @file

+*  Main file supporting the SEC Phase on ARM Platforms

+*

+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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/ArmTrustedMonitorLib.h>

+#include <Library/DebugAgentLib.h>

+#include <Library/PrintLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/SerialPortLib.h>

+#include <Library/ArmGicLib.h>

+

+#include "SecInternal.h"

+

+#define SerialPrint(txt)  SerialPortWrite ((UINT8*)txt, AsciiStrLen(txt)+1);

+VOID

+CEntryPoint (

+  IN  UINTN                     MpId,

+  IN  UINTN                     SecBootMode

+  )

+{

+  CHAR8           Buffer[100];

+  UINTN           CharCount;

+  UINTN           JumpAddress;

+

+  // Invalidate the data cache. Doesn't have to do the Data cache clean.

+  ArmInvalidateDataCache();

+

+  // Invalidate Instruction Cache

+  ArmInvalidateInstructionCache();

+

+  // Invalidate I & D TLBs

+  ArmInvalidateTlb();

+

+  // CPU specific settings

+  ArmCpuSetup (MpId);

+

+  // Enable Floating Point Coprocessor if supported by the platform

+  if (FixedPcdGet32 (PcdVFPEnabled)) {

+    ArmEnableVFP();

+  }

+

+  // Initialize peripherals that must be done at the early stage

+  // Example: Some L2 controller, interconnect, clock, DMC, etc

+  ArmPlatformSecInitialize (MpId);

+

+  // Primary CPU clears out the SCU tag RAMs, secondaries wait

+  if ((((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore)) && (SecBootMode == ARM_SEC_COLD_BOOT)) {

+    if (ArmIsMpCore()) {

+      // Signal for the initial memory is configured (event: BOOT_MEM_INIT)

+      ArmCallSEV ();

+    }

+

+    // SEC phase needs to run library constructors by hand. This assumes we are linked against the SerialLib

+    // In non SEC modules the init call is in autogenerated code.

+    SerialPortInitialize ();

+

+    // Start talking

+    if (FixedPcdGetBool (PcdTrustzoneSupport)) {

+      CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Secure UEFI firmware %s built at %a on %a\n\r",

+          (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);

+    } else {

+      CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Boot firmware %s built at %a on %a\n\r",

+          (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);

+    }

+    SerialPortWrite ((UINT8 *) Buffer, CharCount);

+

+    // Initialize the Debug Agent for Source Level Debugging

+    InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL);

+    SaveAndSetDebugTimerInterrupt (TRUE);

+

+    // Enable the GIC distributor and CPU Interface

+    // - no other Interrupts are enabled,  doesn't have to worry about the priority.

+    // - all the cores are in secure state, use secure SGI's

+    ArmGicEnableDistributor (PcdGet32(PcdGicDistributorBase));

+    ArmGicEnableInterruptInterface (PcdGet32(PcdGicInterruptInterfaceBase));

+  } else {

+    // Enable the GIC CPU Interface

+    ArmGicEnableInterruptInterface (PcdGet32(PcdGicInterruptInterfaceBase));

+  }

+

+  // Enable Full Access to CoProcessors

+  ArmWriteCpacr (CPACR_CP_FULL_ACCESS);

+

+  // Test if Trustzone is supported on this platform

+  if (FixedPcdGetBool (PcdTrustzoneSupport)) {

+    if (ArmIsMpCore()) {

+      // Setup SMP in Non Secure world

+      ArmCpuSetupSmpNonSecure (GET_CORE_ID(MpId));

+    }

+

+    // Either we use the Secure Stacks for Secure Monitor (in this case (Base == 0) && (Size == 0))

+    // Or we use separate Secure Monitor stacks (but (Base != 0) && (Size != 0))

+    ASSERT (((PcdGet32(PcdCPUCoresSecMonStackBase) == 0) && (PcdGet32(PcdCPUCoreSecMonStackSize) == 0)) ||

+            ((PcdGet32(PcdCPUCoresSecMonStackBase) != 0) && (PcdGet32(PcdCPUCoreSecMonStackSize) != 0)));

+

+    // Enter Monitor Mode

+    enter_monitor_mode ((UINTN)TrustedWorldInitialization, MpId, SecBootMode, (VOID*)(PcdGet32(PcdCPUCoresSecMonStackBase) + (PcdGet32(PcdCPUCoreSecMonStackSize) * (ArmPlatformGetCorePosition(MpId) + 1))));

+  } else {

+    if (((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore)) {

+      SerialPrint ("Trust Zone Configuration is disabled\n\r");

+    }

+

+    // With Trustzone support the transition from Sec to Normal world is done by return_from_exception().

+    // If we want to keep this function call we need to ensure the SVC's SPSR point to the same Program

+    // Status Register as the the current one (CPSR).

+    copy_cpsr_into_spsr ();

+

+    // Call the Platform specific function to execute additional actions if required

+    JumpAddress = PcdGet64 (PcdFvBaseAddress);
+    ArmPlatformSecExtraAction (MpId, &JumpAddress);

+

+    NonTrustedWorldTransition (MpId, JumpAddress);

+  }

+  ASSERT (0); // We must never return from the above function

+}

+

+VOID

+TrustedWorldInitialization (

+  IN  UINTN                     MpId,

+  IN  UINTN                     SecBootMode

+  )

+{

+  UINTN   JumpAddress;

+

+  //-------------------- Monitor Mode ---------------------

+

+  // Set up Monitor World (Vector Table, etc)

+  ArmSecureMonitorWorldInitialize ();

+

+  // Transfer the interrupt to Non-secure World

+  ArmGicSetupNonSecure (MpId, PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase));

+

+  // Initialize platform specific security policy

+  ArmPlatformSecTrustzoneInit (MpId);

+

+  // Setup the Trustzone Chipsets

+  if (SecBootMode == ARM_SEC_COLD_BOOT) {

+    if (((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore)) {

+      if (ArmIsMpCore()) {

+        // Signal the secondary core the Security settings is done (event: EVENT_SECURE_INIT)

+        ArmCallSEV ();

+      }

+    } else {

+      // The secondary cores need to wait until the Trustzone chipsets configuration is done

+      // before switching to Non Secure World

+

+      // Wait for the Primary Core to finish the initialization of the Secure World (event: EVENT_SECURE_INIT)

+      ArmCallWFE ();

+    }

+  }

+

+  // Call the Platform specific function to execute additional actions if required

+  JumpAddress = PcdGet64 (PcdFvBaseAddress);
+  ArmPlatformSecExtraAction (MpId, &JumpAddress);

+

+  // Write to CP15 Non-secure Access Control Register

+  ArmWriteNsacr (PcdGet32 (PcdArmNsacr));

+

+  /* set SMP bit */

+  ArmWriteAuxCr(ArmReadAuxCr() | BIT6);

+

+  // CP15 Secure Configuration Register

+  ArmWriteScr (PcdGet32 (PcdArmScr));

+

+  NonTrustedWorldTransition (MpId, JumpAddress);

+}

+

+VOID

+NonTrustedWorldTransition (

+  IN  UINTN                     MpId,

+  IN  UINTN                     JumpAddress

+  )

+{

+  // If PcdArmNonSecModeTransition is defined then set this specific mode to CPSR before the transition

+  // By not set, the mode for Non Secure World is SVC

+  if (PcdGet32 (PcdArmNonSecModeTransition) != 0) {

+    set_non_secure_mode ((ARM_PROCESSOR_MODE)PcdGet32 (PcdArmNonSecModeTransition));

+  }

+

+  return_from_exception (JumpAddress);

+  //-------------------- Non Secure Mode ---------------------

+

+  // PEI Core should always load and never return

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Sec.inf b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Sec.inf
new file mode 100644
index 0000000..edb3d03
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/Sec.inf
@@ -0,0 +1,83 @@
+#/** @file

+#  SEC - Reset vector code that jumps to C and loads DXE core

+#  

+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = ArmPlatformSec

+  FILE_GUID                      = c536bbfe-c813-4e48-9f90-01fe1ecf9d54

+  MODULE_TYPE                    = SEC

+  VERSION_STRING                 = 1.0

+

+[Sources]

+  Sec.c

+

+[Sources.ARM]

+  Arm/Arch.c

+  Arm/Helper.asm           | RVCT

+  Arm/Helper.S             | GCC

+  Arm/SecEntryPoint.S      | GCC

+  Arm/SecEntryPoint.asm    | RVCT

+  

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  ArmCpuLib

+  ArmLib

+  ArmPlatformSecLib

+  ArmTrustedMonitorLib

+  BaseLib

+  DebugLib

+  DebugAgentLib

+  IoLib

+  ArmGicLib

+  PrintLib

+  SerialPortLib

+  

+[FeaturePcd]

+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec

+  

+[FixedPcd]

+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString

+

+  gArmTokenSpaceGuid.PcdTrustzoneSupport

+  gArmTokenSpaceGuid.PcdVFPEnabled

+  

+  gArmTokenSpaceGuid.PcdArmScr

+  gArmTokenSpaceGuid.PcdArmNsacr

+  gArmTokenSpaceGuid.PcdArmNonSecModeTransition

+  

+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask

+  gArmTokenSpaceGuid.PcdArmPrimaryCore

+  

+  gArmTokenSpaceGuid.PcdSecureFvBaseAddress

+  gArmTokenSpaceGuid.PcdSecureFvSize

+  

+  gArmTokenSpaceGuid.PcdFvBaseAddress

+  

+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase

+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize

+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize

+  gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase

+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize

+  

+  gArmTokenSpaceGuid.PcdGicDistributorBase

+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase

+  

+  gArmPlatformTokenSpaceGuid.PcdSecGlobalVariableSize  

diff --git a/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/SecInternal.h b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/SecInternal.h
new file mode 100644
index 0000000..856fb0a
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/D01BoardPkg/Sec/Sec/SecInternal.h
@@ -0,0 +1,84 @@
+/** @file

+*  Main file supporting the SEC Phase on ARM PLatforms

+*

+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __SEC_H__

+#define __SEC_H__

+

+#include <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/ArmCpuLib.h>

+#include <Library/ArmPlatformLib.h>

+#include <Library/ArmPlatformSecLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+#define IS_ALIGNED(Address, Align) (((UINTN)Address & (Align-1)) == 0)

+

+VOID

+TrustedWorldInitialization (

+  IN  UINTN                     MpId,

+  IN  UINTN                     SecBootMode

+  );

+

+VOID

+NonTrustedWorldTransition (

+  IN  UINTN                     MpId,

+  IN  UINTN                     JumpAddress

+  );

+

+VOID

+ArmSetupGicNonSecure (

+  IN  INTN                  GicDistributorBase,

+  IN  INTN                  GicInterruptInterfaceBase

+);

+

+VOID

+enter_monitor_mode (

+  IN UINTN                  MonitorEntryPoint,

+  IN UINTN                  MpId,

+  IN UINTN                  SecBootMode,

+  IN VOID*                  MonitorStackBase

+  );

+

+VOID

+return_from_exception (

+  IN UINTN                  NonSecureBase

+  );

+

+VOID

+copy_cpsr_into_spsr (

+  VOID

+  );

+

+VOID

+set_non_secure_mode (

+  IN ARM_PROCESSOR_MODE     Mode

+  );

+

+VOID

+SecCommonExceptionEntry (

+  IN UINT32 Entry,

+  IN UINTN  LR

+  );

+

+VOID

+EFIAPI

+ArmSecArchTrustzoneInit (

+  VOID

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf b/uefi/linaro-edk2/HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf
new file mode 100644
index 0000000..22ee49c
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf
@@ -0,0 +1,38 @@
+##

+#/** @file

+# AtaAtapiPassThru driver to provide native IDE/AHCI mode support.

+# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = AtaAtapiPassThruDxe

+  FILE_GUID                      = 5E523CB4-D397-4986-87BD-A6DD8B22F455

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = InitializeAtaAtapiPassThru

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+#  DRIVER_BINDING                =  gAtaAtapiPassThruDriverBinding                         

+#  COMPONENT_NAME                =  gAtaAtapiPassThruComponentName

+#  COMPONENT_NAME2               =  gAtaAtapiPassThruComponentName2                         

+#

+#

+[Binaries.common]

+  PE32|AtaAtapiPassThruDxe.efi|*

+

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThruDxe.efi b/uefi/linaro-edk2/HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThruDxe.efi
new file mode 100755
index 0000000..258f427
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThruDxe.efi
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.depex b/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.depex
new file mode 100644
index 0000000..2a47cc2
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.depex
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.efi b/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.efi
new file mode 100644
index 0000000..85f7b47
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.efi
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.inf b/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.inf
new file mode 100644
index 0000000..46067c9
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/FlashDriver/FlashDriver.inf
@@ -0,0 +1,32 @@
+#/** @file

+# Component name for module FlashDriver

+# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = FlashDriver

+  FILE_GUID                      = E29977F9-20A4-4551-B0EC-BCE246592E72

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InitializeFlash

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32

+#

+[Binaries.common]

+  DXE_DEPEX|FlashDriver.depex

+  PE32|FlashDriver.efi|*

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c
new file mode 100644
index 0000000..5f90250
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01Gic.c
@@ -0,0 +1,41 @@
+/** @file

+*

+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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/IoLib.h>

+#include <Library/ArmGicLib.h>

+#include <Library/PcdLib.h>

+

+UINTN

+EFIAPI

+ArmGicGetMaxNumInterrupts (

+  IN  INTN          GicDistributorBase

+  )

+{

+  return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);

+}

+

+VOID

+EFIAPI

+ArmGicSendSgiTo (

+  IN  INTN          GicDistributorBase,

+  IN  INTN          TargetListFilter,

+  IN  INTN          CPUTargetList,

+  IN  INTN          SgiId

+  )

+{

+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);

+}

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c
new file mode 100644
index 0000000..a4dfa66
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.c
@@ -0,0 +1,425 @@
+/*++

+

+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>

+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>

+Portions copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>

+Copyright (c) Huawei Technologies Co., Ltd. 2013. 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.

+

+Module Name:

+

+  Gic.c

+

+Abstract:

+

+  Driver implementing the GIC interrupt controller protocol

+

+--*/

+

+#include <PiDxe.h>

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Library/PcdLib.h>

+#include <Library/IoLib.h>

+#include <Library/ArmGicLib.h>

+

+#include <Protocol/Cpu.h>

+#include <Protocol/HardwareInterrupt.h>

+

+#define ARM_GIC_DEFAULT_PRIORITY  0x80

+

+extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol;

+

+//

+// Notifications

+//

+EFI_EVENT EfiExitBootServicesEvent      = (EFI_EVENT)NULL;

+

+// Maximum Number of Interrupts

+UINTN mGicNumInterrupts                 = 0;

+

+HARDWARE_INTERRUPT_HANDLER  *gRegisteredInterruptHandlers = NULL;

+

+/**

+  Register Handler for the specified interrupt source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+  @param Handler  Callback for interrupt. NULL to unregister

+

+  @retval EFI_SUCCESS Source was updated to support Handler.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+RegisterInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source,

+  IN HARDWARE_INTERRUPT_HANDLER         Handler

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  gRegisteredInterruptHandlers[Source] = Handler;

+

+  // If the interrupt handler is unregistered then disable the interrupt

+  if (NULL == Handler){

+       return This->DisableInterruptSource (This, Source);

+  } else {

+       return This->EnableInterruptSource (This, Source);

+  }

+}

+

+/**

+  Enable interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt enabled.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+EnableInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  UINT32    RegOffset;

+  UINTN     RegShift;

+

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  // Calculate enable register offset and bit position

+  RegOffset = Source / 32;

+  RegShift = Source % 32;

+

+  // Write set-enable register

+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset), 1 << RegShift);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Disable interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt disabled.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+DisableInterruptSource (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  UINT32    RegOffset;

+  UINTN     RegShift;

+

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  // Calculate enable register offset and bit position

+  RegOffset = Source / 32;

+  RegShift = Source % 32;

+

+  // Write set-enable register

+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDICER + (4*RegOffset), 1 << RegShift);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Return current state of interrupt source Source.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+  @param InterruptState  TRUE: source enabled, FALSE: source disabled.

+

+  @retval EFI_SUCCESS       InterruptState is valid

+  @retval EFI_DEVICE_ERROR  InterruptState is not valid

+

+**/

+EFI_STATUS

+EFIAPI

+GetInterruptSourceState (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source,

+  IN BOOLEAN                            *InterruptState

+  )

+{

+  UINT32    RegOffset;

+  UINTN     RegShift;

+

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  // calculate enable register offset and bit position

+  RegOffset = Source / 32;

+  RegShift = Source % 32;

+

+  if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset)) & (1<<RegShift)) == 0) {

+    *InterruptState = FALSE;

+  } else {

+    *InterruptState = TRUE;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Signal to the hardware that the End Of Intrrupt state

+  has been reached.

+

+  @param This     Instance pointer for this protocol

+  @param Source   Hardware source of the interrupt

+

+  @retval EFI_SUCCESS       Source interrupt EOI'ed.

+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.

+

+**/

+EFI_STATUS

+EFIAPI

+EndOfInterrupt (

+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,

+  IN HARDWARE_INTERRUPT_SOURCE          Source

+  )

+{

+  if (Source > mGicNumInterrupts) {

+    ASSERT(FALSE);

+    return EFI_UNSUPPORTED;

+  }

+

+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCEIOR, Source);

+  return EFI_SUCCESS;

+}

+

+/**

+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.

+

+  @param  InterruptType    Defines the type of interrupt or exception that

+                           occurred on the processor.This parameter is processor architecture specific.

+  @param  SystemContext    A pointer to the processor context when

+                           the interrupt occurred on the processor.

+

+  @return None

+

+**/

+VOID

+EFIAPI

+IrqInterruptHandler (

+  IN EFI_EXCEPTION_TYPE           InterruptType,

+  IN EFI_SYSTEM_CONTEXT           SystemContext

+  )

+{

+  UINT32                      GicInterrupt;

+  HARDWARE_INTERRUPT_HANDLER  InterruptHandler;

+

+  GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIAR);

+

+  // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).

+  if (GicInterrupt >= mGicNumInterrupts) {

+    // The special interrupt do not need to be acknowledge

+    return;

+  }

+

+  InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];

+  if (InterruptHandler != NULL) {

+    // Call the registered interrupt handler.

+    InterruptHandler (GicInterrupt, SystemContext);

+  } else {

+    DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));

+  }

+

+  EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt);

+}

+

+//

+// Making this global saves a few bytes in image size

+//

+EFI_HANDLE  gHardwareInterruptHandle = NULL;

+

+//

+// The protocol instance produced by this driver

+//

+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {

+  RegisterInterruptSource,

+  EnableInterruptSource,

+  DisableInterruptSource,

+  GetInterruptSourceState,

+  EndOfInterrupt

+};

+

+/**

+  Shutdown our hardware

+

+  DXE Core will disable interrupts and turn off the timer and disable interrupts

+  after all the event handlers have run.

+

+  @param[in]  Event   The Event that is being processed

+  @param[in]  Context Event Context

+**/

+VOID

+EFIAPI

+ExitBootServicesEvent (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+{

+  UINTN    Index;

+

+  // Acknowledge all pending interrupts

+  for (Index = 0; Index < mGicNumInterrupts; Index++) {

+    DisableInterruptSource (&gHardwareInterruptProtocol, Index);

+  }

+

+  for (Index = 0; Index < mGicNumInterrupts; Index++) {

+    EndOfInterrupt (&gHardwareInterruptProtocol, Index);

+  }

+

+  // Disable Gic Interface

+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x0);

+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0x0);

+

+  // Disable Gic Distributor

+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x0);

+}

+

+/**

+  Initialize the state information for the CPU Architectural Protocol

+

+  @param  ImageHandle   of the loaded driver

+  @param  SystemTable   Pointer to the System Table

+

+  @retval EFI_SUCCESS           Protocol registered

+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure

+  @retval EFI_DEVICE_ERROR      Hardware problems

+

+**/

+EFI_STATUS

+InterruptDxeInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_STATUS              Status;

+  UINTN                   Index;

+  UINT32                  RegOffset;

+  UINTN                   RegShift;

+  EFI_CPU_ARCH_PROTOCOL   *Cpu;

+  UINT32                  CpuTarget;

+

+  // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0

+  DEBUG_CODE_BEGIN();

+  if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) {

+    DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n"));

+  }

+  DEBUG_CODE_END();

+

+  // Make sure the Interrupt Controller Protocol is not already installed in the system.

+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);

+

+  mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase));

+

+  for (Index = 0; Index < mGicNumInterrupts; Index++) {

+    DisableInterruptSource (&gHardwareInterruptProtocol, Index);

+

+    // Set Priority

+    RegOffset = Index / 4;

+    RegShift = (Index % 4) * 8;

+    MmioAndThenOr32 (

+      PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset),

+      ~(0xff << RegShift),

+      ARM_GIC_DEFAULT_PRIORITY << RegShift

+      );

+  }

+  // Configure interrupts for Primary Cpu

+  CpuTarget = (1 << PcdGet32 (PcdGicPrimaryCoreId));

+  CpuTarget |= CpuTarget << 16;

+  for (Index = 0; Index < (mGicNumInterrupts / 2); Index++) {

+    MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), CpuTarget);

+  }

+

+  // Set binary point reg to 0x7 (no preemption)

+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7);

+

+  // Set priority mask reg to 0xff to allow all priorities through

+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff);

+

+  // Enable gic cpu interface

+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1);

+

+  // Enable gic distributor

+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x1);

+

+  // Initialize the array for the Interrupt Handlers

+  gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &gHardwareInterruptHandle,

+                  &gHardwareInterruptProtocolGuid,   &gHardwareInterruptProtocol,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Get the CPU protocol that this driver requires.

+  //

+  Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);

+  ASSERT_EFI_ERROR(Status);

+

+  //

+  // Unregister the default exception handler.

+  //

+  Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL);

+  ASSERT_EFI_ERROR(Status);

+

+  //

+  // Register to receive interrupts

+  //

+  Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler);

+  ASSERT_EFI_ERROR(Status);

+

+  // Register for an ExitBootServicesEvent

+  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf
new file mode 100644
index 0000000..6ade9e6
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicDxe.inf
@@ -0,0 +1,59 @@
+#/** @file

+#

+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+#  Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>

+#  Copyright Huawei Technologies Co., Ltd. 1998-2013. 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                    = 0x00010005

+  BASE_NAME                      = HisiliconD01GicDxe

+  FILE_GUID                      = DE371F7C-DEC4-4D21-ADF1-593ABCC15882

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InterruptDxeInitialize

+

+

+[Sources.common]

+  HisiliconD01Gic.c

+  HisiliconD01GicDxe.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  HisiPkg/HisiPlatformPkg.dec

+

+[LibraryClasses]

+  BaseLib

+  UefiLib

+  UefiBootServicesTableLib

+  DebugLib

+  PrintLib

+  MemoryAllocationLib

+  UefiDriverEntryPoint

+  IoLib

+

+[Protocols]

+  gHardwareInterruptProtocolGuid

+  gEfiCpuArchProtocolGuid

+

+[FixedPcd.common]

+  gArmTokenSpaceGuid.PcdGicDistributorBase

+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase

+

+  gArmTokenSpaceGuid.PcdArmPrimaryCore

+  gHwTokenSpaceGuid.PcdGicPrimaryCoreId

+

+[Depex]

+  gEfiCpuArchProtocolGuid

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf
new file mode 100644
index 0000000..6d6c66f
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicLib.inf
@@ -0,0 +1,32 @@
+#/* @file

+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = HisiliconD01GicLib

+  FILE_GUID                      = 03d05ee4-cdeb-458c-9dfc-993f09bdf405

+  MODULE_TYPE                    = SEC

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmGicLib

+

+[Sources]

+  HisiliconD01Gic.c

+  HisiliconD01GicNonSec.c

+

+[LibraryClasses]

+  IoLib

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  MdePkg/MdePkg.dec

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicNonSec.c b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicNonSec.c
new file mode 100644
index 0000000..17a2cd1
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicNonSec.c
@@ -0,0 +1,45 @@
+/** @file

+*

+*  Copyright (c) 2011, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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/IoLib.h>

+#include <Library/ArmGicLib.h>

+

+

+VOID

+EFIAPI

+ArmGicEnableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  /*

+  * Enable the CPU interface in Non-Secure world

+  * Note: The ICCICR register is banked when Security extensions are implemented

+  */

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1);

+}

+

+VOID

+EFIAPI

+ArmGicEnableDistributor (

+  IN  INTN          GicDistributorBase

+  )

+{

+  /*

+   * Enable GIC distributor in Non-Secure world.

+   * Note: The ICDDCR register is banked when Security extensions are implemented

+   */

+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);

+}

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSec.c b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSec.c
new file mode 100644
index 0000000..d097b8a
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSec.c
@@ -0,0 +1,132 @@
+/** @file

+*

+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 <Base.h>

+#include <Library/ArmLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/ArmGicLib.h>

+

+/*

+ * This function configures the all interrupts to be Non-secure.

+ *

+ */

+VOID

+EFIAPI

+ArmGicSetupNonSecure (

+  IN  UINTN         MpId,

+  IN  INTN          GicDistributorBase,

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  UINTN InterruptId;

+  UINTN CachedPriorityMask;

+  UINTN Index;

+

+  CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);

+

+  // Set priority Mask so that no interrupts get through to CPU

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);

+

+  // Check if there are any pending interrupts

+  //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.

+  while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) {

+    // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal

+    InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);

+

+    // Write to End of interrupt signal

+    MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);

+  }

+

+  // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).

+  if (((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore)) {

+    // Ensure all GIC interrupts are Non-Secure

+    for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {

+      MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);

+    }

+  } else {

+    // The secondary cores only set the Non Secure bit to their banked PPIs

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);

+  }

+

+  // Ensure all interrupts can get through the priority mask

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);

+}

+

+/*

+ * This function configures the interrupts set by the mask to be secure.

+ *

+ */

+VOID

+EFIAPI

+ArmGicSetSecureInterrupts (

+  IN  UINTN         GicDistributorBase,

+  IN  UINTN*        GicSecureInterruptMask,

+  IN  UINTN         GicSecureInterruptMaskSize

+  )

+{

+  UINTN  Index;

+  UINT32 InterruptStatus;

+

+  // We must not have more interrupts defined by the mask than the number of available interrupts

+  ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32));

+

+  // Set all the interrupts defined by the mask as Secure

+  for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) {

+    InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));

+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));

+  }

+}

+

+VOID

+EFIAPI

+ArmGicEnableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  // Set Priority Mask to allow interrupts

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);

+

+  // Enable CPU interface in Secure world

+  // Enable CPU interface in Non-secure World

+  // Signal Secure Interrupts to CPU using FIQ line *

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,

+      ARM_GIC_ICCICR_ENABLE_SECURE |

+      ARM_GIC_ICCICR_ENABLE_NS |

+      ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);

+}

+

+VOID

+EFIAPI

+ArmGicDisableInterruptInterface (

+  IN  INTN          GicInterruptInterfaceBase

+  )

+{

+  UINT32    ControlValue;

+

+  // Disable CPU interface in Secure world and Non-secure World

+  ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);

+  MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));

+}

+

+VOID

+EFIAPI

+ArmGicEnableDistributor (

+  IN  INTN          GicDistributorBase

+  )

+{

+  // Turn on the GIC distributor

+  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);

+}

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf
new file mode 100644
index 0000000..07a16a4
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/HisiliconD01Gic/HisiliconD01GicSecLib.inf
@@ -0,0 +1,41 @@
+#/* @file

+#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = HisiliconD01GicSecLib

+  FILE_GUID                      = 85f3cf80-b5f4-11df-9855-0002a5d5c51b

+  MODULE_TYPE                    = SEC

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ArmGicLib

+

+[Sources]

+  HisiliconD01Gic.c

+  HisiliconD01GicSec.c

+

+[Packages]

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+

+[LibraryClasses]

+  ArmLib

+  DebugLib

+  IoLib

+  PcdLib

+

+[FixedPcd.common]

+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask

+  gArmTokenSpaceGuid.PcdArmPrimaryCore

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.c b/uefi/linaro-edk2/HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.c
new file mode 100644
index 0000000..8c52684
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.c
@@ -0,0 +1,309 @@
+/** @file

+  Timer Architecture Protocol driver of the ARM flavor

+

+  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include "Protocol/LinuxAtagListProtocol.h"

+#include <Library/PcdLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Protocol/NorFlashProtocol.h>

+

+#define  LINUX_ATAG_FLASH_OFFSET        0x1200000 

+#define  LINUX_ATAG_FLASH_SIZE          0x1000    

+

+#define  LINUX_ATAG_MAGIC_FLAG          0x01

+#define  INITRD_OFFSET                  0x40

+#define  INITRD_SIZE_OFFSET             0x0c

+

+typedef struct{

+    UINT32              MagicFlag;

+    UINT32              Checksum;

+    LINUX_ATAG_LIST     LinuxAtagList;

+}LINUX_ATAG_FLASH_DATA;

+

+

+VOID GetDefaultLinuxAtag(

+    IN OUT  LINUX_ATAG_LIST        *LinuxAtagList 

+)

+{

+    LinuxAtagList->core_tag.flags = PcdGet32(PcdDefaultCoreTagFlags);

+    LinuxAtagList->core_tag.pagesize = PcdGet32(PcdDefaultCoreTagPageSize);

+    LinuxAtagList->core_tag.rootdev = PcdGet32(PcdDefaultCoreTagRootdev);

+

+    LinuxAtagList->mem_tag.start = PcdGet32(PcdDefaultMemTagStart);

+    LinuxAtagList->mem_tag.size = PcdGet32(PcdDefaultMemTagSize);

+

+    LinuxAtagList->initrd2_tag.start = PcdGet32(PcdtinitrdStart) + INITRD_OFFSET;

+    LinuxAtagList->initrd2_tag.size = SwapBytes32(*(volatile UINT32*)(PcdGet32(PcdtinitrdStart) + INITRD_SIZE_OFFSET));

+

+    (VOID)AsciiStrCpy(LinuxAtagList->cmdline_tag.cmdline, (CHAR8*)PcdGetPtr(PcdDefaultCmdlineTagCmdline));

+

+    LinuxAtagList->bootcmd_tag.addr = PcdGet32(PcdBootcmdAddr);

+    LinuxAtagList->cpuinfo_tag.invalid = 0xffffffff;

+    

+#if 0   

+    DEBUG((EFI_D_ERROR, "core_tag.flags = 0x%08x \n", LinuxAtagList->core_tag.flags));

+    DEBUG((EFI_D_ERROR, "core_tag.pagesize = 0x%08x \n", LinuxAtagList->core_tag.pagesize));

+    DEBUG((EFI_D_ERROR, "core_tag.rootdev = 0x%08x \n", LinuxAtagList->core_tag.rootdev));

+    

+    DEBUG((EFI_D_ERROR, "mem_tag.start = 0x%08x \n", LinuxAtagList->mem_tag.start));

+    DEBUG((EFI_D_ERROR, "mem_tag.size = 0x%08x \n", LinuxAtagList->mem_tag.size));

+    

+    DEBUG((EFI_D_ERROR, "initrd2_tag.start = 0x%08x \n", LinuxAtagList->initrd2_tag.start));

+    //DEBUG((EFI_D_ERROR, "initrd2_tag.size = 0x%08x \n", SwapBytes32(LinuxAtagList->initrd2_tag.size)));

+    DEBUG((EFI_D_ERROR, "initrd2_tag.size come from initrd file, now can not be gotten \n"));

+    

+    DEBUG((EFI_D_ERROR, "cmdline_tag.cmdline = %a \n", LinuxAtagList->cmdline_tag.cmdline));

+    DEBUG((EFI_D_ERROR, "bootcmd_tag.addr = %a \n", LinuxAtagList->bootcmd_tag.addr));

+    DEBUG((EFI_D_ERROR, "cpuinfo_tag.invalid = %a \n", LinuxAtagList->cpuinfo_tag.invalid));

+#endif

+}

+

+EFI_STATUS

+GetLinuxAtag(

+    IN LINUX_ATAG_LIST_PROTOCOL   *This,

+    IN OUT  LINUX_ATAG_LIST        *LinuxAtagList 

+    )

+{

+    EFI_STATUS  Status;

+    UNI_NOR_FLASH_PROTOCOL        *Flash;

+    LINUX_ATAG_FLASH_DATA      *FlashData;

+    

+    //load Flash Protocol

+    Status = gBS->LocateProtocol (&gUniNorFlashProtocolGuid, NULL, (VOID **) &Flash);

+    if (EFI_ERROR(Status))

+    {

+        DEBUG((EFI_D_ERROR, "Locate gOemFlashDriverProtocolGuid Error, Status = %r\n", Status));

+        goto ERROR;

+    }

+    else

+    {

+        Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  LINUX_ATAG_FLASH_SIZE,

+                  (VOID**) &FlashData

+                  );

+        if (NULL == FlashData)

+        {

+            DEBUG((EFI_D_ERROR, "AllocatePool  Error, Status = %r\n", Status));

+            goto ERROR;

+        }

+        else

+        {

+            Status = Flash->Read(Flash, LINUX_ATAG_FLASH_OFFSET, (UINT8 *)FlashData, sizeof(LINUX_ATAG_FLASH_DATA));

+            if (EFI_ERROR(Status))

+            {

+                DEBUG((EFI_D_ERROR, "flashRead Error, Status = %r\n", Status));

+                if (NULL != FlashData)

+                {

+                    (VOID)gBS->FreePool(FlashData);

+                }

+                goto ERROR;

+            }

+            else

+            {

+                #if 0   

+                    DEBUG((EFI_D_ERROR, "core_tag.flags = 0x%08x \n", FlashData->LinuxAtagList.core_tag.flags));

+                    DEBUG((EFI_D_ERROR, "core_tag.pagesize = 0x%08x \n", FlashData->LinuxAtagList.core_tag.pagesize));

+                    DEBUG((EFI_D_ERROR, "core_tag.rootdev = 0x%08x \n", FlashData->LinuxAtagList.core_tag.rootdev));

+                    

+                    DEBUG((EFI_D_ERROR, "mem_tag.start = 0x%08x \n", FlashData->LinuxAtagList.mem_tag.start));

+                    DEBUG((EFI_D_ERROR, "mem_tag.size = 0x%08x \n", FlashData->LinuxAtagList.mem_tag.size));

+                    

+                    DEBUG((EFI_D_ERROR, "initrd2_tag.start = 0x%08x \n", FlashData->LinuxAtagList.initrd2_tag.start));

+                    //DEBUG((EFI_D_ERROR, "initrd2_tag.size = 0x%08x \n", SwapBytes32(LinuxAtagList->initrd2_tag.size)));

+                    DEBUG((EFI_D_ERROR, "initrd2_tag.size come from initrd file, now can not be gotten \n"));

+                    

+                    DEBUG((EFI_D_ERROR, "cmdline_tag.cmdline = %a \n", FlashData->LinuxAtagList.cmdline_tag.cmdline));

+                #endif

+                if ((LINUX_ATAG_MAGIC_FLAG == FlashData->MagicFlag) && (FlashData->Checksum == CalculateCheckSum32((CONST UINT32*)&(FlashData->LinuxAtagList), sizeof(LINUX_ATAG_LIST))))

+                {

+                    gBS->CopyMem(LinuxAtagList, &(FlashData->LinuxAtagList), sizeof(LINUX_ATAG_LIST));

+                    

+                    #if 0   

+                        DEBUG((EFI_D_ERROR, "!!!!!!!!!!!!!!!!!!\n"));

+                        DEBUG((EFI_D_ERROR, "core_tag.flags = 0x%08x \n", FlashData->LinuxAtagList.core_tag.flags));

+                        DEBUG((EFI_D_ERROR, "core_tag.pagesize = 0x%08x \n", FlashData->LinuxAtagList.core_tag.pagesize));

+                        DEBUG((EFI_D_ERROR, "core_tag.rootdev = 0x%08x \n", FlashData->LinuxAtagList.core_tag.rootdev));

+                        

+                        DEBUG((EFI_D_ERROR, "mem_tag.start = 0x%08x \n", FlashData->LinuxAtagList.mem_tag.start));

+                        DEBUG((EFI_D_ERROR, "mem_tag.size = 0x%08x \n", FlashData->LinuxAtagList.mem_tag.size));

+                        

+                        DEBUG((EFI_D_ERROR, "initrd2_tag.start = 0x%08x \n", FlashData->LinuxAtagList.initrd2_tag.start));

+                        //DEBUG((EFI_D_ERROR, "initrd2_tag.size = 0x%08x \n", SwapBytes32(LinuxAtagList->initrd2_tag.size)));

+                        DEBUG((EFI_D_ERROR, "initrd2_tag.size come from initrd file, now can not be gotten \n"));

+                        

+                        DEBUG((EFI_D_ERROR, "cmdline_tag.cmdline = %a \n", FlashData->LinuxAtagList.cmdline_tag.cmdline));

+                        DEBUG((EFI_D_ERROR, "@@@@@@@@@@@@@@@@@@@@\n"));

+                    #endif

+                    #if 0   

+                        DEBUG((EFI_D_ERROR, "core_tag.flags = 0x%08x \n", LinuxAtagList->core_tag.flags));

+                        DEBUG((EFI_D_ERROR, "core_tag.pagesize = 0x%08x \n", LinuxAtagList->core_tag.pagesize));

+                        DEBUG((EFI_D_ERROR, "core_tag.rootdev = 0x%08x \n", LinuxAtagList->core_tag.rootdev));

+                        

+                        DEBUG((EFI_D_ERROR, "mem_tag.start = 0x%08x \n", LinuxAtagList->mem_tag.start));

+                        DEBUG((EFI_D_ERROR, "mem_tag.size = 0x%08x \n", LinuxAtagList->mem_tag.size));

+                        

+                        DEBUG((EFI_D_ERROR, "initrd2_tag.start = 0x%08x \n", LinuxAtagList->initrd2_tag.start));

+                        //DEBUG((EFI_D_ERROR, "initrd2_tag.size = 0x%08x \n", SwapBytes32(LinuxAtagList->initrd2_tag.size)));

+                        DEBUG((EFI_D_ERROR, "initrd2_tag.size come from initrd file, now can not be gotten \n"));

+                        

+                        DEBUG((EFI_D_ERROR, "cmdline_tag.cmdline = %a \n", LinuxAtagList->cmdline_tag.cmdline));

+                        //DEBUG((EFI_D_ERROR, "#########################\n"));

+                    #endif

+                    if (NULL != FlashData)

+                    {

+                        (VOID)gBS->FreePool(FlashData);

+                    }

+                    return EFI_SUCCESS;

+                }

+                else

+                {

+                    if (NULL != FlashData)

+                    {

+                        (VOID)gBS->FreePool(FlashData);

+                    }

+                    goto ERROR;

+                }

+            }

+        }

+    }

+

+ERROR:

+    DEBUG((EFI_D_ERROR, "Get default linux atag list\n"));

+    GetDefaultLinuxAtag(LinuxAtagList);

+    DEBUG((EFI_D_ERROR, "Get default linux atag list ok!\n"));

+    return EFI_SUCCESS;

+}

+

+EFI_STATUS

+SetLinuxAtag(

+    IN LINUX_ATAG_LIST_PROTOCOL   *This,

+    IN LINUX_ATAG_LIST             *LinuxAtagList 

+    )

+{

+    EFI_STATUS  Status;

+    UNI_NOR_FLASH_PROTOCOL  *Flash;

+    LINUX_ATAG_FLASH_DATA      *FlashData;

+    

+    //load Flash Protocol

+    Status = gBS->LocateProtocol (&gUniNorFlashProtocolGuid, NULL, (VOID **) &Flash);

+    if (EFI_ERROR(Status))

+    {

+        DEBUG((EFI_D_ERROR, "Locate gUniNorFlashProtocolGuid Error, Status = %r\n", Status));

+        return Status;

+    }

+    else

+    {

+        

+        Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  LINUX_ATAG_FLASH_SIZE,

+                  (VOID**) &FlashData

+                  );

+        if (NULL == FlashData)

+        {

+            DEBUG((EFI_D_ERROR, "AllocatePool  Error, Status = %r\n", Status));

+            return Status;

+        }

+        else

+        {

+            (VOID)ZeroMem(FlashData, LINUX_ATAG_FLASH_SIZE);

+            

+            FlashData->MagicFlag = LINUX_ATAG_MAGIC_FLAG;

+            FlashData->Checksum = CalculateCheckSum32((CONST UINT32*)LinuxAtagList, sizeof(LINUX_ATAG_LIST));

+            gBS->CopyMem(&(FlashData->LinuxAtagList), LinuxAtagList, sizeof(LINUX_ATAG_LIST));

+            

+            #if 0   

+                DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+                DEBUG((EFI_D_ERROR, "core_tag.flags = 0x%08x \n", LinuxAtagList->core_tag.flags));

+                DEBUG((EFI_D_ERROR, "core_tag.pagesize = 0x%08x \n", LinuxAtagList->core_tag.pagesize));

+                DEBUG((EFI_D_ERROR, "core_tag.rootdev = 0x%08x \n", LinuxAtagList->core_tag.rootdev));

+                

+                DEBUG((EFI_D_ERROR, "mem_tag.start = 0x%08x \n", LinuxAtagList->mem_tag.start));

+                DEBUG((EFI_D_ERROR, "mem_tag.size = 0x%08x \n", LinuxAtagList->mem_tag.size));

+                

+                DEBUG((EFI_D_ERROR, "initrd2_tag.start = 0x%08x \n", LinuxAtagList->initrd2_tag.start));

+                //DEBUG((EFI_D_ERROR, "initrd2_tag.size = 0x%08x \n", SwapBytes32(LinuxAtagList->initrd2_tag.size)));

+                DEBUG((EFI_D_ERROR, "initrd2_tag.size come from initrd file, now can not be gotten \n"));

+                

+                DEBUG((EFI_D_ERROR, "cmdline_tag.cmdline = %a \n", LinuxAtagList->cmdline_tag.cmdline));

+            #endif

+            Status = Flash->Write(Flash, LINUX_ATAG_FLASH_OFFSET, (UINT8 *)FlashData, sizeof(LINUX_ATAG_FLASH_DATA));

+            if (EFI_ERROR(Status))

+            {

+                DEBUG((EFI_D_ERROR, "flashWrite LINUX_ATAG_LIST Error, Status = %r\n", Status));

+            }

+            

+            #if 0   

+                DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+                DEBUG((EFI_D_ERROR, "core_tag.flags = 0x%08x \n", FlashData->LinuxAtagList.core_tag.flags));

+                DEBUG((EFI_D_ERROR, "core_tag.pagesize = 0x%08x \n", FlashData->LinuxAtagList.core_tag.pagesize));

+                DEBUG((EFI_D_ERROR, "core_tag.rootdev = 0x%08x \n", FlashData->LinuxAtagList.core_tag.rootdev));

+                

+                DEBUG((EFI_D_ERROR, "mem_tag.start = 0x%08x \n", FlashData->LinuxAtagList.mem_tag.start));

+                DEBUG((EFI_D_ERROR, "mem_tag.size = 0x%08x \n", FlashData->LinuxAtagList.mem_tag.size));

+                

+                DEBUG((EFI_D_ERROR, "initrd2_tag.start = 0x%08x \n", FlashData->LinuxAtagList.initrd2_tag.start));

+                //DEBUG((EFI_D_ERROR, "initrd2_tag.size = 0x%08x \n", SwapBytes32(LinuxAtagList->initrd2_tag.size)));

+                DEBUG((EFI_D_ERROR, "initrd2_tag.size come from initrd file, now can not be gotten \n"));

+                

+                DEBUG((EFI_D_ERROR, "cmdline_tag.cmdline = %a \n", FlashData->LinuxAtagList.cmdline_tag.cmdline));

+            #endif

+            

+            if (NULL != FlashData)

+            {

+                (VOID)gBS->FreePool(FlashData);

+            }

+            return Status;

+        }

+    }

+}

+

+

+LINUX_ATAG_LIST_PROTOCOL mLinuxAtagListProtocol = 

+{

+    GetLinuxAtag,

+    SetLinuxAtag

+};

+

+

+

+EFI_STATUS

+EFIAPI

+LinuxAtagListInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+    EFI_STATUS  Status;

+

+

+    Status = gBS->InstallProtocolInterface(

+                  &ImageHandle,

+                  &gLinuxAtagListProtocolGuid,      

+                  EFI_NATIVE_INTERFACE,

+                  &mLinuxAtagListProtocol

+                  );

+    if (EFI_ERROR (Status))

+    {

+        DEBUG((EFI_D_ERROR, "Install gLinuxAtagListProtocolGuid %r \n", Status));

+    }

+

+  return Status;

+}

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.inf b/uefi/linaro-edk2/HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.inf
new file mode 100644
index 0000000..7829329
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.inf
@@ -0,0 +1,68 @@
+#/** @file

+#  Component name for module WatchdogDriver

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = LinuxAtagListInitialize

+  FILE_GUID                      = 49ea041e-6752-42ca-b0b1-4444333346b7 

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = LinuxAtagListInitialize

+

+[Sources.common]

+  LinuxAtagList.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  HisiPkg/HisiPlatformPkg.dec 

+

+[LibraryClasses]

+  ArmLib

+  BaseLib

+  UefiLib

+  UefiBootServicesTableLib

+  BaseMemoryLib

+  DebugLib

+  UefiDriverEntryPoint

+  BaseMemoryLib

+

+[Guids]

+

+[Protocols]

+  gLinuxAtagListProtocolGuid

+  gUniNorFlashProtocolGuid

+  

+[Pcd]

+  gHwTokenSpaceGuid.PcdDefaultCoreTagFlags

+  gHwTokenSpaceGuid.PcdDefaultCoreTagPageSize

+  gHwTokenSpaceGuid.PcdDefaultCoreTagRootdev

+

+  gHwTokenSpaceGuid.PcdDefaultMemTagStart

+  gHwTokenSpaceGuid.PcdDefaultMemTagSize

+

+  #gHwTokenSpaceGuid.PcdDefaultInitrd2TagStart

+  #gHwTokenSpaceGuid.PcdDefaultInitrd2TagSize

+

+  gHwTokenSpaceGuid.PcduImageStart

+  gHwTokenSpaceGuid.PcdtinitrdStart

+  gHwTokenSpaceGuid.PcdBootcmdAddr

+

+  gHwTokenSpaceGuid.PcdDefaultCmdlineTagCmdline

+

+[Depex]

+  TRUE

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandDxe.depex b/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandDxe.depex
new file mode 100644
index 0000000..2a47cc2
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandDxe.depex
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandDxe.efi b/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandDxe.efi
new file mode 100644
index 0000000..d13ec8e
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandDxe.efi
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandFlashDxe.inf b/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandFlashDxe.inf
new file mode 100644
index 0000000..c9faf56
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/NandFlash/NandFlashDxe.inf
@@ -0,0 +1,26 @@
+#/** @file

+# Component name for module NandDxe

+# Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = NandDxe

+  FILE_GUID                      = 811320E3-5B13-42a5-8EA5-6A1ED0922ADB

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = InitializeNANDFlash

+[Binaries.common]

+  DXE_DEPEX|NandDxe.depex

+  PE32|NandDxe.efi|*

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/TimerDxe/TimerDxe.c b/uefi/linaro-edk2/HisiPkg/Drivers/TimerDxe/TimerDxe.c
new file mode 100644
index 0000000..77bc73c
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/TimerDxe/TimerDxe.c
@@ -0,0 +1,557 @@
+/** @file

+  Timer Architecture Protocol driver of the ARM flavor

+

+  Copyright (c) 2011 ARM Ltd. All rights reserved.<BR>

+  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 <PiDxe.h>

+

+#include <Library/ArmLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Library/PcdLib.h>

+#include <Library/IoLib.h>

+#include <Library/ArmArchTimer.h>

+

+#include <Protocol/Timer.h>

+#include <Protocol/HardwareInterrupt.h>

+

+// The notification function to call on every timer interrupt.

+EFI_TIMER_NOTIFY      mTimerNotifyFunction     = (EFI_TIMER_NOTIFY)NULL;

+EFI_EVENT             EfiExitBootServicesEvent = (EFI_EVENT)NULL;

+

+// The current period of the timer interrupt

+UINT64 mTimerPeriod = 0;

+

+// Cached copy of the Hardware Interrupt protocol instance

+EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;

+

+#define SRE_HITIMER_ADDR 0xe3000000

+

+#define SRE_HITIMER32_OFFSET (0x00000020)

+

+/****************** Timer32 register addresses offset start ***********************/

+#define SRE_HITIMER32_LOAD_OFFSET              (0x0)

+#define SRE_HITIMER32_VALUE_OFFSET             (0x4)

+#define SRE_HITIMER32_CNTL_OFFSET              (0x8)

+#define SRE_HITIMER32_INTC_OFFSET              (0xC)

+#define SRE_HITIMER32_RIS_OFFSET               (0x10)

+#define SRE_HITIMER32_MIS_OFFSET               (0x0014)

+#define SRE_HITIMER32_BGLOAD_OFFSET            (0x18)

+/****************** end ******************************/

+

+#define SRE_HITIMER_NUM                        48

+#define SRE_HITIMER64_START_INDEX              32

+#define SRE_HITIMER_ENCLK_SEL_BIT              (1 << 7)   /* Timer enable flag */

+

+

+#define SRE_HITIMER_CLK_IN_FREQ                187500000

+#define SRE_HITIMER_MICROSECOND_PER_SECOND     1000000

+

+#define SRE_HITIMER_DEFAULT_TICKS              100

+#define SRE_HITIMER_RELOAD_TICKS               1

+

+#define SRE_HITIMER_INT_CLEAR                  (0x01)

+#define SRE_HITIMER_CNTL_ENABLE                (0x80)

+#define SRE_HITIMER_CNTL_MODE                  (0x40)

+#define SRE_HITIMER_CNTL_IRQ_ENABLE            (0x20)

+#define SRE_HITIMER_CNTL_SIZEMODE              (0x2)

+

+

+#define SRE_HITIMER_CNTL_MODE_ONCE             0

+#define SRE_HITIMER_CNTL_MODE_CYCLE            1

+#define SRE_HITIMER_CNTL_IRQ_ON                1

+#define SRE_HITIMER_CNTL_IRQ_OFF               0

+

+

+#define SRE_D01_HITIMER01_INTVEC             (256)

+#define SRE_D01_HITIMER23_INTVEC             (257)

+#define SRE_D01_HITIMER45_INTVEC             (258)

+#define SRE_D01_HITIMER67_INTVEC             (259)

+#define SRE_D01_HITIMER89_INTVEC             (260)

+#define SRE_D01_HITIMER1011_INTVEC           (261)

+#define SRE_D01_HITIMER1213_INTVEC           (262)

+#define SRE_D01_HITIMER1415_INTVEC           (263)

+#define SRE_D01_HITIMER1617_INTVEC           (264)

+#define SRE_D01_HITIMER1819_INTVEC           (265)

+#define SRE_D01_HITIMER2021_INTVEC           (266)

+#define SRE_D01_HITIMER2223_INTVEC           (267)

+#define SRE_D01_HITIMER2425_INTVEC           (268)

+#define SRE_D01_HITIMER2627_INTVEC           (269)

+#define SRE_D01_HITIMER2829_INTVEC           (270)

+#define SRE_D01_HITIMER3031_INTVEC           (271)

+#define SRE_D01_HITIMER3233_INTVEC           (272)

+#define SRE_D01_HITIMER3435_INTVEC           (273)

+#define SRE_D01_HITIMER3637_INTVEC           (274)

+#define SRE_D01_HITIMER3839_INTVEC           (275)

+#define SRE_D01_HITIMER4041_INTVEC           (276)

+#define SRE_D01_HITIMER4243_INTVEC           (277)

+#define SRE_D01_HITIMER4445_INTVEC           (278)

+#define SRE_D01_HITIMER4647_INTVEC           (279)

+

+UINT32 gRegBase = SRE_HITIMER_ADDR;

+#define SC_CTRL 0xe3e00000

+

+void HITIMER_Start()

+{

+               UINT32 ulRegAddr;

+               UINT32 ulVal = 0;

+               UINT32 ulMask;

+

+        ulVal = *(UINT32*)SC_CTRL;

+        ulVal |= BIT17 | BIT16 | BIT18 | BIT19;

+        *(UINT32*)SC_CTRL = ulVal;

+

+               /*timer mode*/

+               ulMask = SRE_HITIMER_CNTL_MODE; //BIT6

+               ulRegAddr = gRegBase + SRE_HITIMER32_CNTL_OFFSET;

+               ulVal = *(UINT32*)ulRegAddr;

+               ulVal = ulVal;

+               ulVal |= ulMask; /*cycle*/

+        *(UINT32*)ulRegAddr = ulVal;

+

+               /*int mode*/

+               ulMask = SRE_HITIMER_CNTL_IRQ_ENABLE; //BIT5

+               ulRegAddr = gRegBase + SRE_HITIMER32_CNTL_OFFSET;

+               ulVal = *(UINT32*)ulRegAddr;

+               ulVal = ulVal;

+               ulVal |= ulMask;

+        //DEBUG((EFI_D_ERROR, "int mode = %0x at %0x\n", ulVal, ulRegAddr));

+               *(UINT32*)ulRegAddr = ulVal;

+

+               /*start up*/

+               ulMask = (SRE_HITIMER_ENCLK_SEL_BIT | SRE_HITIMER_CNTL_SIZEMODE); //BIT7 | BIT1

+               ulRegAddr = gRegBase + SRE_HITIMER32_CNTL_OFFSET;

+               ulVal = *(UINT32*)ulRegAddr;

+               ulVal = ulVal;

+               ulVal |= ulMask;

+        //DEBUG((EFI_D_ERROR, "start up = %0x at %0x\n", ulVal, ulRegAddr));

+               *(UINT32*)ulRegAddr = ulVal;

+

+}

+

+void HITMER_ClearInt()

+{

+       UINT32 ulRegAddr;

+       UINT32 ulVal = 0;

+

+

+       ulRegAddr = gRegBase + SRE_HITIMER32_INTC_OFFSET;

+       ulVal = SRE_HITIMER_INT_CLEAR;

+    //DEBUG((EFI_D_ERROR, "HITMER_ClearInt = %0x at %0x\n", ulVal, ulRegAddr));

+       *(UINT32*)ulRegAddr = ulVal;

+

+}

+

+void DisableTimer()

+{

+       UINT32 ulRegAddr;

+       UINT32 ulVal = 0;

+       UINT32 ulMask;

+

+       /*disable*/

+       ulMask = SRE_HITIMER_ENCLK_SEL_BIT;

+       ulRegAddr = gRegBase + SRE_HITIMER32_CNTL_OFFSET;

+       ulVal = *(UINT32*)ulRegAddr;

+       ulVal = ulVal;

+       ulVal &= (~ulMask);

+    //DEBUG((EFI_D_ERROR, "DisableTimer = %0x at %0x\n", ulVal, ulRegAddr));

+       *(UINT32*)ulRegAddr = ulVal;

+

+}

+

+void EnableTimer()

+{

+       UINT32 ulRegAddr;

+       UINT32 ulVal = 1;

+       UINT32 ulMask;

+

+       /*disable*/

+       ulMask = SRE_HITIMER_ENCLK_SEL_BIT;

+       ulRegAddr = gRegBase + SRE_HITIMER32_CNTL_OFFSET;

+       ulVal = *(UINT32*)ulRegAddr;

+       ulVal = ulVal;

+       ulVal |= ulMask;

+    //DEBUG((EFI_D_ERROR, "EnableTimer = %0x at %0x\n", ulVal, ulRegAddr));

+       *(UINT32*)ulRegAddr = ulVal;

+

+}

+

+/**

+  This function registers the handler NotifyFunction so it is called every time

+  the timer interrupt fires.  It also passes the amount of time since the last

+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the

+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is

+  returned.  If the CPU does not support registering a timer interrupt handler,

+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler

+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.

+  If an attempt is made to unregister a handler when a handler is not registered,

+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to

+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR

+  is returned.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  NotifyFunction   The function to call when a timer interrupt fires. This

+                           function executes at TPL_HIGH_LEVEL. The DXE Core will

+                           register a handler for the timer interrupt, so it can know

+                           how much time has passed. This information is used to

+                           signal timer based events. NULL will unregister the handler.

+  @retval EFI_SUCCESS           The timer handler was registered.

+  @retval EFI_UNSUPPORTED       The platform does not support timer interrupts.

+  @retval EFI_ALREADY_STARTED   NotifyFunction is not NULL, and a handler is already

+                                registered.

+  @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not

+                                previously registered.

+  @retval EFI_DEVICE_ERROR      The timer handler could not be registered.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverRegisterHandler (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN EFI_TIMER_NOTIFY         NotifyFunction

+  )

+{

+  if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  mTimerNotifyFunction = NotifyFunction;

+

+  return EFI_SUCCESS;

+}

+

+/**

+    Disable the timer

+**/

+VOID

+EFIAPI

+ExitBootServicesEvent (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+{

+  DisableTimer ();

+}

+

+/**

+

+  This function adjusts the period of timer interrupts to the value specified

+  by TimerPeriod.  If the timer period is updated, then the selected timer

+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If

+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.

+  If an error occurs while attempting to update the timer period, then the

+  timer hardware will be put back in its state prior to this call, and

+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt

+  is disabled.  This is not the same as disabling the CPU's interrupts.

+  Instead, it must either turn off the timer hardware, or it must adjust the

+  interrupt controller so that a CPU interrupt is not generated when the timer

+  interrupt fires.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod      The rate to program the timer interrupt in 100 nS units. If

+                           the timer hardware is not programmable, then EFI_UNSUPPORTED is

+                           returned. If the timer is programmable, then the timer period

+                           will be rounded up to the nearest timer period that is supported

+                           by the timer hardware. If TimerPeriod is set to 0, then the

+                           timer interrupts will be disabled.

+

+

+  @retval EFI_SUCCESS           The timer period was changed.

+  @retval EFI_UNSUPPORTED       The platform cannot change the period of the timer interrupt.

+  @retval EFI_DEVICE_ERROR      The timer period could not be changed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverSetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This,

+  IN UINT64                   TimerPeriod

+  )

+{

+  UINT64      TimerTicks;

+

+  UINT32 ulRegAddr;

+

+  // always disable the timer

+  DisableTimer ();

+

+  if (TimerPeriod != 0) {

+    // Convert TimerPeriod to micro sec units

+    #if 0

+    TimerTicks = DivU64x32 (TimerPeriod, 10);

+

+    TimerTicks = MultU64x32 (TimerTicks, (PcdGet32(PcdArmArchTimerFreqInHz)/1000000));

+    #endif

+

+    TimerTicks = DivU64x32 (TimerPeriod, 100);

+    TimerTicks = MultU64x32 (TimerTicks, (PcdGet32(PcdArmArchTimerFreqInHz)/100000));

+

+    //ArmArchTimerSetTimerVal((UINTN)TimerTicks);

+

+    ulRegAddr = gRegBase + SRE_HITIMER32_LOAD_OFFSET;

+    //DEBUG((EFI_D_ERROR, "TimerTicks1 = %0x at %0x ======\n", TimerTicks, ulRegAddr));

+    *(UINT32*)ulRegAddr = TimerTicks;

+    ulRegAddr = gRegBase + SRE_HITIMER32_BGLOAD_OFFSET;

+    //DEBUG((EFI_D_ERROR, "TimerTicks2 = %0x at %0x  \n", TimerTicks, ulRegAddr));

+    *(UINT32*)ulRegAddr = TimerTicks;

+

+    // Enable the timer

+    EnableTimer ();

+  }

+

+  // Save the new timer period

+  mTimerPeriod = TimerPeriod;

+  return EFI_SUCCESS;

+}

+

+/**

+  This function retrieves the period of timer interrupts in 100 ns units,

+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod

+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is

+  returned, then the timer is currently disabled.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+  @param  TimerPeriod      A pointer to the timer period to retrieve in 100 ns units. If

+                           0 is returned, then the timer is currently disabled.

+

+

+  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.

+  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGetTimerPeriod (

+  IN EFI_TIMER_ARCH_PROTOCOL   *This,

+  OUT UINT64                   *TimerPeriod

+  )

+{

+  if (TimerPeriod == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *TimerPeriod = mTimerPeriod;

+  return EFI_SUCCESS;

+}

+

+/**

+  This function generates a soft timer interrupt. If the platform does not support soft

+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.

+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()

+  service, then a soft timer interrupt will be generated. If the timer interrupt is

+  enabled when this service is called, then the registered handler will be invoked. The

+  registered handler should not be able to distinguish a hardware-generated timer

+  interrupt from a software-generated timer interrupt.

+

+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.

+

+  @retval EFI_SUCCESS           The soft timer interrupt was generated.

+  @retval EFI_UNSUPPORTED       The platform does not support the generation of soft timer interrupts.

+

+**/

+EFI_STATUS

+EFIAPI

+TimerDriverGenerateSoftInterrupt (

+  IN EFI_TIMER_ARCH_PROTOCOL  *This

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  Interface structure for the Timer Architectural Protocol.

+

+  @par Protocol Description:

+  This protocol provides the services to initialize a periodic timer

+  interrupt, and to register a handler that is called each time the timer

+  interrupt fires.  It may also provide a service to adjust the rate of the

+  periodic timer interrupt.  When a timer interrupt occurs, the handler is

+  passed the amount of time that has passed since the previous timer

+  interrupt.

+

+  @param RegisterHandler

+  Registers a handler that will be called each time the

+  timer interrupt fires.  TimerPeriod defines the minimum

+  time between timer interrupts, so TimerPeriod will also

+  be the minimum time between calls to the registered

+  handler.

+

+  @param SetTimerPeriod

+  Sets the period of the timer interrupt in 100 nS units.

+  This function is optional, and may return EFI_UNSUPPORTED.

+  If this function is supported, then the timer period will

+  be rounded up to the nearest supported timer period.

+

+

+  @param GetTimerPeriod

+  Retrieves the period of the timer interrupt in 100 nS units.

+

+  @param GenerateSoftInterrupt

+  Generates a soft timer interrupt that simulates the firing of

+  the timer interrupt. This service can be used to invoke the   registered handler if the timer interrupt has been masked for

+  a period of time.

+

+**/

+EFI_TIMER_ARCH_PROTOCOL   gTimer = {

+  TimerDriverRegisterHandler,

+  TimerDriverSetTimerPeriod,

+  TimerDriverGetTimerPeriod,

+  TimerDriverGenerateSoftInterrupt

+};

+

+/**

+

+  C Interrupt Handler called in the interrupt context when Source interrupt is active.

+

+

+  @param Source         Source of the interrupt. Hardware routing off a specific platform defines

+                        what source means.

+

+  @param SystemContext  Pointer to system register context. Mostly used by debuggers and will

+                        update the system context after the return from the interrupt if

+                        modified. Don't change these values unless you know what you are doing

+

+**/

+VOID

+EFIAPI

+TimerInterruptHandler (

+  IN  HARDWARE_INTERRUPT_SOURCE   Source,

+  IN  EFI_SYSTEM_CONTEXT          SystemContext

+  )

+{

+  EFI_TPL      OriginalTPL;

+

+  //

+  // DXE core uses this callback for the EFI timer tick. The DXE core uses locks

+  // that raise to TPL_HIGH and then restore back to current level. Thus we need

+  // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.

+  //

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  // Check if the timer interrupt is active

+  //if ((*(UINT32*)(gRegBase + SRE_HITIMER32_RIS_OFFSET)) & BIT0) {

+      //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+    HITMER_ClearInt();

+

+    // Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers

+    gInterrupt->EndOfInterrupt (gInterrupt, Source);

+

+

+    if (mTimerNotifyFunction) {

+      mTimerNotifyFunction (mTimerPeriod);

+    }

+

+    // Reload the Timer

+    //TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod));

+  //}

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  // Enable timer interrupts

+  //gInterrupt->EnableInterruptSource (gInterrupt, Source);

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  gBS->RestoreTPL (OriginalTPL);

+}

+

+

+

+

+/**

+  Initialize the state information for the Timer Architectural Protocol and

+  the Timer Debug support protocol that allows the debugger to break into a

+  running program.

+

+  @param  ImageHandle   of the loaded driver

+  @param  SystemTable   Pointer to the System Table

+

+  @retval EFI_SUCCESS           Protocol registered

+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure

+  @retval EFI_DEVICE_ERROR      Hardware problems

+

+**/

+EFI_STATUS

+EFIAPI

+TimerInitialize (

+  IN EFI_HANDLE         ImageHandle,

+  IN EFI_SYSTEM_TABLE   *SystemTable

+  )

+{

+  EFI_HANDLE  Handle = NULL;

+  EFI_STATUS  Status;

+

+

+  // Find the interrupt controller protocol.  ASSERT if not found.

+  Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);

+  ASSERT_EFI_ERROR (Status);

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  // Disable the timer

+  Status = TimerDriverSetTimerPeriod (&gTimer, 0);

+  ASSERT_EFI_ERROR (Status);

+

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+  // Install secure and Non-secure interrupt handlers

+  // Note: Because it is not possible to determine the security state of the

+  // CPU dynamically, we just install interrupt handler for both sec and non-sec

+  // timer PPI

+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, 256, TimerInterruptHandler);

+  ASSERT_EFI_ERROR (Status);

+

+  //Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum), TimerInterruptHandler);

+  //ASSERT_EFI_ERROR (Status);

+

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+  // Unmask timer interrupts

+  HITIMER_Start();

+

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  // Set up default timer

+  Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD

+  ASSERT_EFI_ERROR (Status);

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  // Install the Timer Architectural Protocol onto a new handle

+  Status = gBS->InstallMultipleProtocolInterfaces(

+                  &Handle,

+                  &gEfiTimerArchProtocolGuid,      &gTimer,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR(Status);

+  //DEBUG((EFI_D_ERROR, "[DJ]: %a : %d\n", __FUNCTION__, __LINE__));

+

+  // enable Secure timer interrupts

+  Status = gInterrupt->EnableInterruptSource (gInterrupt, 256);

+

+  // enable NonSecure timer interrupts

+  //Status = gInterrupt->EnableInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum));

+

+  // Register for an ExitBootServicesEvent

+  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/TimerDxe/TimerDxe.inf b/uefi/linaro-edk2/HisiPkg/Drivers/TimerDxe/TimerDxe.inf
new file mode 100644
index 0000000..9661cd1
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/TimerDxe/TimerDxe.inf
@@ -0,0 +1,60 @@
+#/** @file

+#

+#    Component description file for Timer DXE module

+#

+#  Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = ArmTimerDxe

+  FILE_GUID                      = 49ea041e-6752-42ca-b0b1-7344fe2546b7

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = TimerInitialize

+

+[Sources.common]

+  TimerDxe.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  EmbeddedPkg/EmbeddedPkg.dec

+  ArmPkg/ArmPkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+

+[LibraryClasses]

+  ArmLib

+  BaseLib

+  UefiRuntimeServicesTableLib

+  UefiLib

+  UefiBootServicesTableLib

+  BaseMemoryLib

+  DebugLib

+  UefiDriverEntryPoint

+  IoLib

+

+[Guids]

+

+[Protocols]

+  gEfiTimerArchProtocolGuid

+  gHardwareInterruptProtocolGuid

+

+[Pcd.common]

+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod

+  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum

+  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum

+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz

+

+[Depex]

+  gHardwareInterruptProtocolGuid

+  
\ No newline at end of file
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchDogDriver.inf b/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchDogDriver.inf
new file mode 100644
index 0000000..5cb0b4c
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchDogDriver.inf
@@ -0,0 +1,25 @@
+#/** @file

+#  Component name for module WatchdogDriver

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = WatchdogDriver

+  FILE_GUID                      = 93B70004-9FC5-11d4-9A4B-0090283FC14D

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+

+  ENTRY_POINT                    = WdtClearWatchdogEntry

+[Binaries.common]

+  DXE_DEPEX|WatchdogDriver.depex

+  PE32|WatchdogDriver.efi|*

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchdogDriver.depex b/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchdogDriver.depex
new file mode 100644
index 0000000..03d5718
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchdogDriver.depex
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchdogDriver.efi b/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchdogDriver.efi
new file mode 100644
index 0000000..ea56802
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/WatchDogDriver/WatchdogDriver.efi
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.c b/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.c
new file mode 100644
index 0000000..cb64907
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.c
@@ -0,0 +1,573 @@
+/*

+ * Copyright (c) 1999, 2000

+ * Intel Corporation.

+ * All rights reserved.

+ *  Copyright (c) Huawei Technologies Co., Ltd. 2013. All rights reserved.

+ * 

+ * Redistribution and use in source and binary forms, with or without modification,

+ * are permitted provided that the following conditions are met:

+ * 

+ * 1. Redistributions of source code must retain the above copyright notice,

+ *    this list of conditions and the following disclaimer.

+ * 

+ * 2. Redistributions in binary form must reproduce the above copyright notice,

+ *    this list of conditions and the following disclaimer in the documentation

+ *    and/or other materials provided with the distribution.

+ * 

+ * 3. All advertising materials mentioning features or use of this software must

+ *    display the following acknowledgement:

+ * 

+ *    This product includes software developed by Intel Corporation and its

+ *    contributors.

+ * 

+ * 4. Neither the name of Intel Corporation or its contributors may be used to

+ *    endorse or promote products derived from this software without specific

+ *    prior written permission.

+ * 

+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR

+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON

+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * 

+ */

+#include <Uefi.h>

+

+#include <Protocol/BlockIo.h>

+#include <Protocol/LoadedImage.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/UefiDriverEntryPoint.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Library/BaseLib.h>

+#include <Library/MemoryAllocationLib.h>

+

+#include <Library/DevicePathLib.h>

+#include "./ramdisk.h"

+

+#define DEFAULT_DISK_SIZE	30		/* in MBs */

+

+UINT32		GetDiskSize( EFI_HANDLE ImageHandle );

+

+/* Embedded version string for VERS utility */

+//static char v[] = "version_number=1.00 ";

+

+/* EFI device path definition */

+static RAM_DISK_DEVICE_PATH RamDiskDevicePath =

+{

+    {
+       MESSAGING_DEVICE_PATH,
+       MSG_VENDOR_DP,
+       {
+            sizeof(RAM_DISK_DEVICE_PATH) - END_DEVICE_PATH_LENGTH,
+           0
+       },
+    },
+	// {06ED4DD0-FF78-11d3-BDC4-00A0C94053D1}

+       {
+        0x6ed4dd0, 0xff78, 0x11d3,
+        {0xbd, 0xc4, 0x0, 0xa0, 0xc9, 0x40, 0x53, 0xd1},
+    },
+       {0,0,0,0,0,0,0,0},      // ID assigned below
+       {
+        END_DEVICE_PATH_TYPE,
+           END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+            END_DEVICE_PATH_LENGTH,
+               0
+        },
+    },
+};

+

+/* Lookup table of total sectors vs. cluster size.

+ * Ramdisk sizes between 0x20D0 (4.1MB) and 0x100000 (512MB) sectors are valid FAT16 drive sizes.

+ */

+/* #define MIN_DISK_SIZE	5 */

+#define MIN_DISK_SIZE	1

+#define	MAX_DISK_SIZE	512

+static FAT16TABLE fat16tbl[] =

+{

+	/* {0x000020D0, 0}, */

+	{0x00000800, 1},	/* 800 sectors * 1 sec/cluster * 512 bytes = 1 M */

+	{0x00001000, 1},	/* 1000 sectors * 1 sec/cluster * 512 bytes = 2 M */

+	{0x00001800, 1},	/* 1800 sectors * 1 sec/cluster * 512 bytes = 3 M */

+	{0x00007FA8, 2},

+	{0x00040000, 4},

+	{0x00080000, 8},

+	{0x00100000,16},

+	{0xFFFFFFFF, 0}

+};

+

+VOID CopyBOOTSEC(VOID* Start,BOOTSEC* bsc)

+{

+UINT32 index=0;

+UINT8* pStart=(UINT8*)Start;

+

+CopyMem(&(pStart[index]), &(bsc->BS_jmpBoot[0]), sizeof(bsc->BS_jmpBoot));

+index+=sizeof(bsc->BS_jmpBoot);

+

+CopyMem(&(pStart[index]), &(bsc->BS_OEMName[0]), sizeof(bsc->BS_OEMName));

+index+=sizeof(bsc->BS_OEMName);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_BytsPerSec), sizeof(bsc->BPB_BytsPerSec));

+index+=sizeof(bsc->BPB_BytsPerSec);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_SecPerClus), sizeof(bsc->BPB_SecPerClus));

+index+=sizeof(bsc->BPB_SecPerClus);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_RsvdSecCnt), sizeof(bsc->BPB_RsvdSecCnt));

+index+=sizeof(bsc->BPB_RsvdSecCnt);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_NumFATs), sizeof(bsc->BPB_NumFATs));

+index+=sizeof(bsc->BPB_NumFATs);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_NumFATs), sizeof(bsc->BPB_NumFATs));

+index+=sizeof(bsc->BPB_NumFATs);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_RootEntCnt), sizeof(bsc->BPB_RootEntCnt));

+index+=sizeof(bsc->BPB_RootEntCnt);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_TotSec16), sizeof(bsc->BPB_TotSec16));

+index+=sizeof(bsc->BPB_TotSec16);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_Media), sizeof(bsc->BPB_Media));

+index+=sizeof(bsc->BPB_Media);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_FATSz16), sizeof(bsc->BPB_FATSz16));

+index+=sizeof(bsc->BPB_FATSz16);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_SecPerTrk), sizeof(bsc->BPB_SecPerTrk));

+index+=sizeof(bsc->BPB_SecPerTrk);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_NumHeads), sizeof(bsc->BPB_NumHeads));

+index+=sizeof(bsc->BPB_NumHeads);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_HiddSec), sizeof(bsc->BPB_HiddSec));

+index+=sizeof(bsc->BPB_HiddSec);

+

+CopyMem(&(pStart[index]), &(bsc->BPB_TotSec32), sizeof(bsc->BPB_TotSec32));

+index+=sizeof(bsc->BPB_TotSec32);

+

+CopyMem(&(pStart[index]), &(bsc->BS_DrvNum), sizeof(bsc->BS_DrvNum));

+index+=sizeof(bsc->BS_DrvNum);

+

+CopyMem(&(pStart[index]), &(bsc->BS_Reserved1), sizeof(bsc->BS_Reserved1));

+index+=sizeof(bsc->BS_Reserved1);

+

+CopyMem(&(pStart[index]), &(bsc->BS_BootSig), sizeof(bsc->BS_BootSig));

+index+=sizeof(bsc->BS_BootSig);

+

+CopyMem(&(pStart[index]), &(bsc->BS_VolID), sizeof(bsc->BS_VolID));

+index+=sizeof(bsc->BS_VolID);

+

+CopyMem(&(pStart[index]), &(bsc->BS_VolLab[0]), sizeof(bsc->BS_VolLab));

+index+=sizeof(bsc->BS_VolLab);

+

+CopyMem(&(pStart[index]), &(bsc->BS_FilSysType[0]), sizeof(bsc->BS_FilSysType));

+index+=sizeof(bsc->BS_FilSysType);

+

+CopyMem(&(pStart[index]), &(bsc->BS_Code[0]), sizeof(bsc->BS_Code));

+index+=sizeof(bsc->BS_Code);

+

+CopyMem(&(pStart[index]), &(bsc->BS_Sig), sizeof(bsc->BS_Sig));

+

+}

+

+/*++

+

+Routine Description:

+

+  Convert hex string to uint

+

+Arguments:

+

+  Str  -  The string

+  

+Returns:

+

+--*/

+STATIC UINTN Atoi ( CHAR16  *str)

+{

+    UINTN   u;

+    CHAR16  c;

+    UINTN   m;

+    UINTN   n;

+

+    ASSERT (str != NULL);

+

+    m = (UINTN) -1 / 10;

+    n = (UINTN) -1 % 10;

+    //

+    // skip preceeding white space

+    //

+    while (*str && (*str == ' ')) 

+    {

+        str += 1;

+    }

+    //

+    // convert digits

+    //

+    u = 0;

+    c = *(str++);

+    while (c) 

+    {

+        if ((c >= '0') && (c <= '9'))

+        {

+            if ((u >= m) && ((c - '0') > (INTN) n)) 

+            {

+                return (UINTN) -1;

+            }

+

+            u = (u * 10) + c - '0';

+        } 

+        else 

+        {

+            break;

+        }

+

+        c = *(str++);

+    }

+

+    return u;

+}

+

+/* Helper function to compute cluster size

+ * vs. total sectors on drive.

+ */

+STATIC UINT8 size2spc(UINT32 ts)

+{

+	int i = 0;

+	

+	while(fat16tbl[i].size != 0xFFFFFFFF)

+	{

+		if(ts <= fat16tbl[i].size)

+			return fat16tbl[i].spc;

+		++i;

+	}

+	

+	return 0;

+}

+

+UINT8 TestSize(UINT32 ts)

+{

+	int i = 0;

+	

+	while(fat16tbl[i].size != 0xFFFFFFFF)

+	{

+		if(ts <= fat16tbl[i].size)

+			return fat16tbl[i].spc;

+		++i;

+	}

+	

+	return 0;

+}

+

+EFI_SYSTEM_TABLE	BackupSystemTable;

+

+/*

+ * Entry point for RamDisk driver.

+ */

+

+EFI_STATUS InitializeRamDiskDriver(

+	IN EFI_HANDLE       ImageHandle,

+	IN EFI_SYSTEM_TABLE *SystemTable)

+{

+	EFI_STATUS           Status;

+	RAM_DISK_DEV         *RamDiskDev;

+	UINT32               RamDiskSize;

+	UINT32               NumPages;

+	UINT32               BlockSize;

+	UINT64               DiskId;

+

+	/*

+	 * Make a copy of the system table to workaround load command bug

+	 */

+	CopyMem(&BackupSystemTable,SystemTable,sizeof(BackupSystemTable));

+

+	/*

+	 * Initialize EFI library

+	 */

+	//InitializeLib(ImageHandle,&BackupSystemTable);

+

+	/* IA64 compiler is removing version string (unused?) so I use it */

+	//v[0] = 'v';

+

+	/*

+	 *  Set the disk size

+	 */

+	RamDiskSize = GetDiskSize(ImageHandle);

+	BlockSize   = 512;

+

+	/* Allocate storage for ramdisk device info on the heap.

+	 */

+	RamDiskDev = AllocateZeroPool(sizeof(RAM_DISK_DEV));

+	if(RamDiskDev == NULL)

+		return EFI_OUT_OF_RESOURCES;

+

+	/*

+	 * Compute the number of 4KB pages needed by the ramdisk and allocate the memory.

+	 */

+	NumPages = RamDiskSize / EFI_PAGE_SIZE;

+	if(NumPages % RamDiskSize)

+		NumPages++;

+

+	Status = gBS->AllocatePages(AllocateAnyPages,EfiBootServicesData,NumPages,&RamDiskDev->Start);

+	if(EFI_ERROR(Status)) {

+		FreePool(RamDiskDev);

+		return Status;

+	}

+

+	/*

+	 * Initialize the ramdisk's device info.

+	 */

+	(void)gBS->GetNextMonotonicCount(&DiskId);

+	CopyMem(&RamDiskDevicePath.DiskId, &DiskId, sizeof(DiskId));

+

+	RamDiskDev->Signature            = PBLOCK_DEVICE_SIGNATURE;

+	RamDiskDev->BlkIo.Revision       = EFI_BLOCK_IO_INTERFACE_REVISION;

+	RamDiskDev->BlkIo.Media          = &RamDiskDev->Media;

+	RamDiskDev->Media.RemovableMedia = FALSE;

+	RamDiskDev->Media.MediaPresent   = TRUE;

+	

+	RamDiskDev->Media.LastBlock        = RamDiskSize/BlockSize - 1;

+	RamDiskDev->Media.BlockSize        = BlockSize;

+	RamDiskDev->Media.LogicalPartition = TRUE;

+	RamDiskDev->Media.ReadOnly         = FALSE;

+	RamDiskDev->Media.WriteCaching     = TRUE;

+	

+	RamDiskDev->BlkIo.ReadBlocks  = RamDiskReadBlocks;

+	RamDiskDev->BlkIo.WriteBlocks = RamDiskWriteBlocks;

+	RamDiskDev->BlkIo.FlushBlocks = RamDiskFlushBlocks;

+	

+	RamDiskDev->DevicePath = DuplicateDevicePath((EFI_DEVICE_PATH*)&RamDiskDevicePath);

+	

+	/*

+	 * Build a FAT16 file system on the ramdisk.

+	 */

+	FormatRamdisk((VOID*)(UINTN)RamDiskDev->Start,RamDiskSize);

+	

+	/*

+	 * Install the device.

+	 */

+

+	Status = gBS->InstallMultipleProtocolInterfaces(

+	&ImageHandle,

+	&gEfiBlockIoProtocolGuid,

+	&RamDiskDev->BlkIo,

+	&gEfiDevicePathProtocolGuid,

+	RamDiskDev->DevicePath,

+	NULL);

+

+DEBUG((EFI_D_ERROR,"ramdisk:blckio install. Status=%r\n",Status));

+	return Status;

+}

+

+UINT32

+GetDiskSize( EFI_HANDLE ImageHandle )

+{

+	EFI_STATUS			Status;

+	EFI_LOADED_IMAGE	*Image;

+	UINT32				DiskSize = DEFAULT_DISK_SIZE;

+

+	/*

+	 * Check load options to see if they want to specify disk size in MBs

+	 */

+	Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (void**)&Image);

+	if (!EFI_ERROR(Status)) {

+		if (Image->LoadOptions && Image->LoadOptionsSize) {

+#define MAX_ARG_SIZE		32

+			CHAR16	Size[ MAX_ARG_SIZE ];

+			CHAR16	*CmdLine = Image->LoadOptions;

+			INT32	CmdLen   = (INT32)Image->LoadOptionsSize;

+

+			/*

+			 * Get past program name

+			 */

+			while( CmdLen > 0 && *CmdLine != L' ' ) {

+				CmdLen -= sizeof(CHAR16);

+				CmdLine++;

+			}

+

+			if ( CmdLen > 0 ) {

+				/*

+				 * Make sure we're null terminated

+				 */

+				CopyMem( Size, CmdLine, MIN(CmdLen, sizeof(Size)));

+				Size[MAX_ARG_SIZE - 1] = 0;

+

+				/*

+				 *  Atoi() will skip any leading white space

+				 */

+				DiskSize = (UINT32)Atoi(Size);

+				if (DiskSize == 0)

+					DiskSize = DEFAULT_DISK_SIZE;

+				DiskSize = MAX(DiskSize, MIN_DISK_SIZE);

+				DiskSize = MIN(DiskSize, MAX_DISK_SIZE);

+			}

+		}

+	}

+

+	return (DiskSize * 1024 * 1024);

+}

+

+/* Given a block of memory representing a ramdisk, build a pseudo-boot sector

+ * and initialize the drive.

+ *

+ * Assumes the global boot sector structure g_bs has been filled out with the

+ * static information the boot sector requires.  Also assumes the ramdisk size

+ * is between 4.1MB and 512MB as appropriate for FAT16 file system.

+ */

+STATIC VOID FormatRamdisk(

+	IN VOID*  pStart,

+	IN UINT32 Size)

+{

+	UINT32 TotalSectors,RootDirSectors,FatSz,tmp1,tmp2;

+	UINT8 *Fat1,*Fat2;

+    BOOTSEC g_bs={

+	/* BS_jmpBoot     */ {0xeb,0x0,0x90},

+	/* BS_OEMName     */ {'E','F','I','R','D','I','S','K'},

+	/* BPB_BytsPerSec */ 512,

+	/* BPB_SecPerClus */ 0,

+	/* BPB_RsvdSecCnt */ 1,

+	/* BPB_NumFATs    */ 2,

+	/* BPB_RootEntCnt */ 512,

+	/* BPB_TotSec16   */ 0,

+	/* BPB_Media      */ 0xF8,

+	/* BPB_FATSz16    */ 0,

+	/* BPB_SecPerTrk  */ 0,

+	/* BPB_NumHeads   */ 0,

+	/* BPB_HiddSec    */ 0,

+	/* BPB_TotSec32   */ 0,

+	/* BS_DrvNum      */ 0,

+	/* BS_Reserved1   */ 0,

+	/* BS_BootSig     */ 0x29,

+	/* BS_VolID       */ 0,

+	/* BS_VolLab      */ {'N','O',' ','N','A','M','E',' ',' ',' '},

+	/* BS_FilSysType  */ {'F','A','T','1','6',' ',' ',' '}

+};

+

+	/* The boot signature needs to be filled out */

+	g_bs.BS_Sig = 0xAA55;

+

+	/* Compute the total sectors and appropriate cluster size */

+	TotalSectors = Size / g_bs.BPB_BytsPerSec;

+	g_bs.BPB_SecPerClus = size2spc(TotalSectors);

+	ASSERT(g_bs.BPB_SecPerClus != 0);

+

+	/* Compute how many root directory sectors are needed */

+	RootDirSectors = (g_bs.BPB_RootEntCnt * 32 + g_bs.BPB_BytsPerSec - 1) / g_bs.BPB_BytsPerSec;

+

+	/* Compute how many sectors are required per FAT */

+	tmp1 = TotalSectors - (g_bs.BPB_RsvdSecCnt + RootDirSectors);

+	tmp2 = 256 * g_bs.BPB_SecPerClus + g_bs.BPB_NumFATs;

+	FatSz = (tmp1 + tmp2 - 1) / tmp2;

+	ASSERT(FatSz <= 0xFFFF);

+

+	/* Store the total sectors and fat size values */

+	if(TotalSectors > 0xFFFF)

+		g_bs.BPB_TotSec32 = TotalSectors;

+	else

+		g_bs.BPB_TotSec16 = (UINT16)TotalSectors;

+

+	g_bs.BPB_FATSz16 = (UINT16)FatSz;

+

+	/* The FAT table and root directory need to be all zeroes.

+	 * We'll zero the whole drive.

+	 */

+	ZeroMem(pStart,Size);

+	

+	/* Write the completed boot sector to the ramdisk */

+	CopyMem(pStart,&g_bs,512);

+

+	/* Compute the starting offsets of the two FATs */

+	Fat1 = (UINT8*)pStart + g_bs.BPB_RsvdSecCnt * 512;

+	Fat2 = (UINT8*)pStart + (g_bs.BPB_RsvdSecCnt + FatSz) * 512;

+

+	/* Initialize FAT1 */

+	Fat1[0] = g_bs.BPB_Media;

+	Fat1[1] = 0xFF;

+	Fat1[2] = 0xFF;

+	Fat1[3] = 0xFF;

+

+	/* Initialize FAT2 */

+	Fat2[0] = g_bs.BPB_Media;

+	Fat2[1] = 0xFF;

+	Fat2[2] = 0xFF;

+	Fat2[3] = 0xFF;

+}

+

+/* Implementation of block I/O read */

+STATIC EFI_STATUS RamDiskReadBlocks(

+	IN EFI_BLOCK_IO *This,

+	IN UINT32       MediaId,

+	IN EFI_LBA      LBA,

+	IN UINTN        BufferSize,

+	OUT VOID        *Buffer)

+{

+	EFI_BLOCK_IO_MEDIA   *Media;

+	RAM_DISK_DEV         *RamDiskDev;

+	EFI_PHYSICAL_ADDRESS RamDiskLBA;

+

+	Media = This->Media;

+

+	if(BufferSize % Media->BlockSize != 0)

+		return EFI_BAD_BUFFER_SIZE;

+

+	if(LBA > Media->LastBlock)

+		return EFI_DEVICE_ERROR;

+

+	if(LBA + BufferSize / Media->BlockSize - 1 > Media->LastBlock)

+		return EFI_DEVICE_ERROR;

+

+	RamDiskDev = RAM_DISK_FROM_THIS(This);

+	RamDiskLBA = RamDiskDev->Start + MultU64x32(LBA,Media->BlockSize);

+	CopyMem(Buffer,(VOID*)(UINTN)RamDiskLBA,BufferSize);

+

+	return EFI_SUCCESS;

+}

+

+

+/* Implementation of block I/O write */

+STATIC EFI_STATUS RamDiskWriteBlocks(

+	IN EFI_BLOCK_IO *This,

+	IN UINT32       MediaId,

+	IN EFI_LBA      LBA,

+	IN UINTN        BufferSize,

+	IN VOID         *Buffer)

+{

+	EFI_BLOCK_IO_MEDIA   *Media;

+	RAM_DISK_DEV         *RamDiskDev;

+	EFI_PHYSICAL_ADDRESS RamDiskLBA;

+

+	Media = This->Media;

+	if(Media->ReadOnly)

+		return EFI_WRITE_PROTECTED;

+

+	if(BufferSize % Media->BlockSize != 0)

+		return EFI_BAD_BUFFER_SIZE;

+

+	if(LBA > Media->LastBlock)

+		return EFI_DEVICE_ERROR;

+

+	if(LBA + BufferSize / Media->BlockSize - 1 > Media->LastBlock)

+		return EFI_DEVICE_ERROR;

+

+	RamDiskDev = RAM_DISK_FROM_THIS(This);

+	RamDiskLBA = RamDiskDev->Start + MultU64x32(LBA,Media->BlockSize);

+	CopyMem((VOID*)(UINTN)RamDiskLBA,Buffer,BufferSize);

+

+	return EFI_SUCCESS;

+}

+

+/* Implementation of block I/O flush */

+STATIC EFI_STATUS RamDiskFlushBlocks(

+	IN EFI_BLOCK_IO *This)

+{

+	return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.h b/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.h
new file mode 100644
index 0000000..ff816c7
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.h
@@ -0,0 +1,134 @@
+/*

+ * Copyright (c) 1999, 2000

+ * Intel Corporation.

+ * All rights reserved.

+ *  Copyright (c) Huawei Technologies Co., Ltd. 2013. All rights reserved.

+ * 

+ * Redistribution and use in source and binary forms, with or without modification,

+ * are permitted provided that the following conditions are met:

+ * 

+ * 1. Redistributions of source code must retain the above copyright notice,

+ *    this list of conditions and the following disclaimer.

+ * 

+ * 2. Redistributions in binary form must reproduce the above copyright notice,

+ *    this list of conditions and the following disclaimer in the documentation

+ *    and/or other materials provided with the distribution.

+ * 

+ * 3. All advertising materials mentioning features or use of this software must

+ *    display the following acknowledgement:

+ * 

+ *    This product includes software developed by Intel Corporation and its

+ *    contributors.

+ * 

+ * 4. Neither the name of Intel Corporation or its contributors may be used to

+ *    endorse or promote products derived from this software without specific

+ *    prior written permission.

+ * 

+ * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR

+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON

+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * 

+ */

+ 

+#ifndef _FATFILESYSTEM_H_

+#define _FATFILESYSTEM_H_

+

+#pragma pack(1)

+/* RAM disk device path structure.

+ * Will use Vendor Messaging Device Path.

+ */

+typedef struct sRAM_DISK_DEVICE_PATH

+{

+	EFI_DEVICE_PATH Header;

+	EFI_GUID        Guid;

+	UINT8			DiskId[8];

+	EFI_DEVICE_PATH EndDevicePath;

+} RAM_DISK_DEVICE_PATH;

+

+/* FAT16 boot sector definition */

+typedef struct sBOOTSEC

+{

+	UINT8  BS_jmpBoot[3];

+	UINT8  BS_OEMName[8];

+	UINT16 BPB_BytsPerSec;

+	UINT8  BPB_SecPerClus;

+	UINT16 BPB_RsvdSecCnt;

+	UINT8  BPB_NumFATs;

+	UINT16 BPB_RootEntCnt;

+	UINT16 BPB_TotSec16;

+	UINT8  BPB_Media;

+	UINT16 BPB_FATSz16;

+	UINT16 BPB_SecPerTrk;

+	UINT16 BPB_NumHeads;

+	UINT32 BPB_HiddSec;

+	UINT32 BPB_TotSec32;

+	UINT8  BS_DrvNum;

+	UINT8  BS_Reserved1;

+	UINT8  BS_BootSig;

+	UINT32 BS_VolID;

+	UINT8  BS_VolLab[11];

+	UINT8  BS_FilSysType[8];

+	UINT8  BS_Code[448];

+	UINT16 BS_Sig;

+} BOOTSEC;

+

+#pragma pack()

+

+/* structure for total sectors to cluster size lookup */

+typedef struct sFAT16TABLE

+{

+	UINTN size;

+	UINT8  spc;

+} FAT16TABLE;

+

+#define PBLOCK_DEVICE_SIGNATURE SIGNATURE_32('r', 'd', 's', 'k')

+

+/* Ramdisk device info structure */

+typedef struct sRAM_DISKDEV

+{

+	UINTN                Signature;

+	EFI_HANDLE           Handle;

+	EFI_PHYSICAL_ADDRESS Start;

+	EFI_BLOCK_IO         BlkIo;

+	EFI_BLOCK_IO_MEDIA   Media;

+	EFI_DEVICE_PATH      *DevicePath;

+} RAM_DISK_DEV;

+

+/* Macro finds the device info structure given a ramdisk BlkIo interface */

+#define RAM_DISK_FROM_THIS(a) CR(a,RAM_DISK_DEV,BlkIo,PBLOCK_DEVICE_SIGNATURE)

+

+/* Prototypes */

+EFI_STATUS InitializeRamDiskDriver(

+	IN EFI_HANDLE       ImageHandle,

+	IN EFI_SYSTEM_TABLE *SystemTable);

+

+STATIC VOID FormatRamdisk(

+	IN VOID*  pStart,

+	IN UINT32 Size);

+

+STATIC EFI_STATUS RamDiskReadBlocks(

+	IN EFI_BLOCK_IO *This,

+	IN UINT32       MediaId,

+	IN EFI_LBA      LBA,

+	IN UINTN        BufferSize,

+	OUT VOID        *Buffer);

+

+STATIC EFI_STATUS RamDiskWriteBlocks(

+	IN EFI_BLOCK_IO *This,

+	IN UINT32       MediaId,

+	IN EFI_LBA      LBA,

+	IN UINTN        BufferSize,

+	IN VOID         *Buffer);

+

+STATIC EFI_STATUS RamDiskFlushBlocks(

+	IN EFI_BLOCK_IO *This);

+

+#endif

+

diff --git a/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.inf b/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.inf
new file mode 100644
index 0000000..964fc49
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Drivers/ramdisk/ramdisk.inf
@@ -0,0 +1,58 @@
+#/*++

+#

+# Copyright (c) 2004, Intel Corporation  

+# Copyright (c) Huawei Technologies Co., Ltd. 2013. All rights reserved.                                                       

+# 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.             

+# 

+#  Module Name:

+#

+#    

+#Mem.c 

+#

+#  Abstract:

+#

+#    Component description file for set cmd reg module.

+#

+#--*/

+[Defines]

+

+INF_VERSION                    = 0x00010005

+BASE_NAME                      = ramdisk

+FILE_GUID                      = A8D2D6E6-D256-4c7a-B835-D6D1422212DB

+MODULE_TYPE                    = UEFI_DRIVER

+VERSION_STRING                 = 1.0

+ENTRY_POINT                    = InitializeRamDiskDriver

+

+[Sources]

+ramdisk.c

+ramdisk.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+#  PV600Pkg/PV600Pkg.dec

+

+[LibraryClasses]

+  MemoryAllocationLib

+  BaseLib

+  UefiLib

+  UefiDriverEntryPoint

+  

+  BaseMemoryLib

+  #DebugLib

+  #PcdLib

+  #UefiRuntimeServicesTableLib

+  #UefiBootServicesTableLib

+  

+[Protocols]

+   gEfiBlockIoProtocolGuid

+   gEfiLoadedImageProtocolGuid

+

+

+    

diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.c
new file mode 100644
index 0000000..fb4c082
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.c
@@ -0,0 +1,444 @@
+/** @file
+  This file implement the Variable Protocol for the block device.
+
+  Copyright (c) 2015, Linaro Limited. All rights reserved.
+  Copyright (c) 2015, Hisilicon 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.
+
+**/
+
+#include <Guid/VariableFormat.h>
+#include <Guid/SystemNvDataGuid.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/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include "BlockVariableDxe.h"
+
+
+STATIC EFI_PHYSICAL_ADDRESS      mMapNvStorageVariableBase;
+
+EFI_STATUS
+EFIAPI
+FvbGetAttributes (
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL    *This,
+  OUT       EFI_FVB_ATTRIBUTES_2                   *Attributes
+  )
+{
+  EFI_FVB_ATTRIBUTES_2 FvbAttributes;
+  FvbAttributes = (EFI_FVB_ATTRIBUTES_2) (
+
+      EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
+      EFI_FVB2_READ_STATUS      | // Reads are currently enabled
+      EFI_FVB2_STICKY_WRITE     | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+      EFI_FVB2_MEMORY_MAPPED    | // It is memory mapped
+      EFI_FVB2_ERASE_POLARITY     // After erasure all bits take this value (i.e. '1')
+
+      );
+  FvbAttributes |= EFI_FVB2_WRITE_STATUS      | // Writes are currently enabled
+                   EFI_FVB2_WRITE_ENABLED_CAP;  // Writes may be enabled
+
+  *Attributes = FvbAttributes;
+
+  DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbSetAttributes(
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL  *This,
+  IN OUT    EFI_FVB_ATTRIBUTES_2                 *Attributes
+  )
+{
+  DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes));
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL  *This,
+  OUT       EFI_PHYSICAL_ADDRESS                 *Address
+  )
+{
+  *Address = mMapNvStorageVariableBase;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL  *This,
+  IN        EFI_LBA                              Lba,
+  OUT       UINTN                                *BlockSize,
+  OUT       UINTN                                *NumberOfBlocks
+  )
+{
+  BLOCK_VARIABLE_INSTANCE       *Instance;
+
+  Instance = CR (This, BLOCK_VARIABLE_INSTANCE, FvbProtocol, BLOCK_VARIABLE_SIGNATURE);
+  *BlockSize = (UINTN) Instance->Media.BlockSize;
+  *NumberOfBlocks = PcdGet32 (PcdNvStorageVariableBlockCount);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbRead (
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL   *This,
+  IN        EFI_LBA                               Lba,
+  IN        UINTN                                 Offset,
+  IN OUT    UINTN                                 *NumBytes,
+  IN OUT    UINT8                                 *Buffer
+  )
+{
+  BLOCK_VARIABLE_INSTANCE       *Instance;
+  EFI_BLOCK_IO_PROTOCOL         *BlockIo;
+  EFI_STATUS                    Status;
+  UINTN                         Bytes;
+  VOID                          *DataPtr;
+
+  Instance = CR (This, BLOCK_VARIABLE_INSTANCE, FvbProtocol, BLOCK_VARIABLE_SIGNATURE);
+  BlockIo = Instance->BlockIoProtocol;
+  Bytes = (Offset + *NumBytes + Instance->Media.BlockSize - 1) / Instance->Media.BlockSize * Instance->Media.BlockSize;
+  DataPtr = AllocateZeroPool (Bytes);
+  if (DataPtr == NULL) {
+    DEBUG ((EFI_D_ERROR, "FvbWrite: failed to allocate buffer.\n"));
+    return EFI_BUFFER_TOO_SMALL;
+  }
+  WriteBackDataCacheRange (DataPtr, Bytes);
+  InvalidateDataCacheRange (Buffer, *NumBytes);
+  Status = BlockIo->ReadBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba,
+		                Bytes, DataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "FvbRead StartLba:%x, Lba:%x, Offset:%x, Status:%x\n",
+	    Instance->StartLba, Lba, Offset, Status));
+    goto exit;
+  }
+  CopyMem (Buffer, DataPtr + Offset, *NumBytes);
+  WriteBackDataCacheRange (Buffer, *NumBytes);
+exit:
+  FreePool (DataPtr);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FvbWrite (
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL   *This,
+  IN        EFI_LBA                               Lba,
+  IN        UINTN                                 Offset,
+  IN OUT    UINTN                                 *NumBytes,
+  IN        UINT8                                 *Buffer
+  )
+{
+  BLOCK_VARIABLE_INSTANCE       *Instance;
+  EFI_BLOCK_IO_PROTOCOL         *BlockIo;
+  EFI_STATUS                    Status;
+  UINTN                         Bytes;
+  VOID                          *DataPtr;
+
+  Instance = CR (This, BLOCK_VARIABLE_INSTANCE, FvbProtocol, BLOCK_VARIABLE_SIGNATURE);
+  BlockIo = Instance->BlockIoProtocol;
+  Bytes = (Offset + *NumBytes + Instance->Media.BlockSize - 1) / Instance->Media.BlockSize * Instance->Media.BlockSize;
+  DataPtr = AllocateZeroPool (Bytes);
+  if (DataPtr == NULL) {
+    DEBUG ((EFI_D_ERROR, "FvbWrite: failed to allocate buffer.\n"));
+    return EFI_BUFFER_TOO_SMALL;
+  }
+  WriteBackDataCacheRange (DataPtr, Bytes);
+  Status = BlockIo->ReadBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba,
+                                Bytes, DataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "FvbWrite: failed on reading blocks.\n"));
+    goto exit;
+  }
+  CopyMem (DataPtr + Offset, Buffer, *NumBytes);
+  WriteBackDataCacheRange (DataPtr, Bytes);
+  Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba,
+                                 Bytes, DataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "FvbWrite StartLba:%x, Lba:%x, Offset:%x, Status:%x\n",
+            Instance->StartLba, Lba, Offset, Status));
+  }
+  // Sometimes the variable isn't flushed into block device if it's the last flush operation.
+  // So flush it again.
+  Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, Instance->StartLba + Lba,
+                                 Bytes, DataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "FvbWrite StartLba:%x, Lba:%x, Offset:%x, Status:%x\n",
+            Instance->StartLba, Lba, Offset, Status));
+  }
+exit:
+  FreePool (DataPtr);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  ...
+  )
+{
+  return EFI_SUCCESS;
+}
+
+STATIC BLOCK_VARIABLE_INSTANCE   mBlockVariableInstance = {
+  .Signature      = BLOCK_VARIABLE_SIGNATURE,
+  .Media          = {
+    .MediaId                       = 0,
+    .RemovableMedia                = FALSE,
+    .MediaPresent                  = TRUE,
+    .LogicalPartition              = TRUE,
+    .ReadOnly                      = FALSE,
+    .WriteCaching                  = FALSE,
+    .BlockSize                     = 0,
+    .IoAlign                       = 4,
+    .LastBlock                     = 0,
+    .LowestAlignedLba              = 0,
+    .LogicalBlocksPerPhysicalBlock = 0,
+  },
+  .FvbProtocol    = {
+    .GetAttributes        = FvbGetAttributes,
+    .SetAttributes        = FvbSetAttributes,
+    .GetPhysicalAddress   = FvbGetPhysicalAddress,
+    .GetBlockSize         = FvbGetBlockSize,
+    .Read                 = FvbRead,
+    .Write                = FvbWrite,
+    .EraseBlocks          = FvbEraseBlocks,
+  }
+};
+
+EFI_STATUS
+ValidateFvHeader (
+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader
+  )
+{
+  UINT16                      Checksum, TempChecksum;
+  VARIABLE_STORE_HEADER       *VariableStoreHeader;
+  UINTN                       VariableStoreLength;
+  UINTN                       FvLength;
+
+  FvLength = (UINTN) (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
+      PcdGet32(PcdFlashNvStorageFtwSpareSize));
+
+  //
+  // Verify the header revision, header signature, length
+  // Length of FvBlock cannot be 2**64-1
+  // HeaderLength cannot be an odd number
+  //
+  if (   (FwVolHeader->Revision  != EFI_FVH_REVISION)
+      || (FwVolHeader->Signature != EFI_FVH_SIGNATURE)
+      || (FwVolHeader->FvLength  != FvLength)
+      )
+  {
+    DEBUG ((EFI_D_ERROR, "ValidateFvHeader: No Firmware Volume header present\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  // Check the Firmware Volume Guid
+  if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) {
+    DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Firmware Volume Guid non-compatible\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  // Verify the header checksum
+  TempChecksum = FwVolHeader->Checksum;
+  FwVolHeader->Checksum = 0;
+  Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength);
+  if (Checksum != TempChecksum) {
+    DEBUG ((EFI_D_ERROR, "ValidateFvHeader: FV checksum is invalid (Checksum:0x%X)\n",Checksum));
+    return EFI_NOT_FOUND;
+  }
+  FwVolHeader->Checksum = Checksum;
+
+  VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FwVolHeader + FwVolHeader->HeaderLength);
+
+  // Check the Variable Store Guid
+  if( CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) == FALSE ) {
+    DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Guid non-compatible\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength;
+  if (VariableStoreHeader->Size != VariableStoreLength) {
+    DEBUG ((EFI_D_ERROR, "ValidateFvHeader: Variable Store Length does not match\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitNonVolatileVariableStore (
+  IN BLOCK_VARIABLE_INSTANCE      *Instance,
+  IN VOID                         *Headers,
+  IN UINTN                        HeadersLength
+  )
+{
+  EFI_FIRMWARE_VOLUME_HEADER            *FirmwareVolumeHeader;
+  EFI_STATUS                            Status;
+  VARIABLE_STORE_HEADER                 *VariableStoreHeader;
+
+  // Check if the size of the area is at least one block size
+  ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->BlockIoProtocol->Media->BlockSize > 0));
+  ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->BlockIoProtocol->Media->BlockSize > 0));
+  ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->BlockIoProtocol->Media->BlockSize > 0));
+
+  //
+  // EFI_FIRMWARE_VOLUME_HEADER
+  //
+  FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Headers;
+  CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
+  FirmwareVolumeHeader->FvLength =
+      PcdGet32(PcdFlashNvStorageVariableSize) +
+      PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
+      PcdGet32(PcdFlashNvStorageFtwSpareSize);
+  FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE;
+  FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) (
+                                            EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
+                                            EFI_FVB2_READ_STATUS        | // Reads are currently enabled
+                                            EFI_FVB2_STICKY_WRITE       | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+                                            EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
+                                            EFI_FVB2_ERASE_POLARITY     | // After erasure all bits take this value (i.e. '1')
+                                            EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
+                                            EFI_FVB2_WRITE_ENABLED_CAP    // Writes may be enabled
+                                        );
+  FirmwareVolumeHeader->HeaderLength          = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY);
+  FirmwareVolumeHeader->Revision              = EFI_FVH_REVISION;
+  FirmwareVolumeHeader->BlockMap[0].NumBlocks = PcdGet32 (PcdNvStorageVariableBlockCount);
+  FirmwareVolumeHeader->BlockMap[0].Length    = Instance->BlockIoProtocol->Media->BlockSize;
+  // BlockMap Terminator
+  FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
+  FirmwareVolumeHeader->BlockMap[1].Length    = 0;
+  FirmwareVolumeHeader->Checksum = 0;
+  FirmwareVolumeHeader->Checksum = CalculateSum16 ((UINT16*)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength);
+
+  //
+  // VARIABLE_STORE_HEADER
+  //
+  VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)FirmwareVolumeHeader + FirmwareVolumeHeader->HeaderLength);
+  CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
+  VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength;
+  VariableStoreHeader->Format            = VARIABLE_STORE_FORMATTED;
+  VariableStoreHeader->State             = VARIABLE_STORE_HEALTHY;
+
+  Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers);
+  return Status;
+}
+
+EFI_STATUS
+BlockVariableDxeInitialize (
+  IN EFI_HANDLE                   ImageHandle,
+  IN EFI_SYSTEM_TABLE             *SystemTable
+  )
+{
+  EFI_HANDLE                      Handle;
+  EFI_STATUS                      Status;
+  BLOCK_VARIABLE_INSTANCE         *Instance = &mBlockVariableInstance;
+  UINT32                          Count;
+  EFI_LBA                         Lba;
+  UINTN                           NvStorageSize;
+  EFI_DEVICE_PATH_PROTOCOL        *NvBlockDevicePath;
+  UINT8                           *NvStorageData;
+  VOID                            *Headers;
+  UINTN                           HeadersLength;
+
+  Instance->Signature = BLOCK_VARIABLE_SIGNATURE;
+
+  HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER);
+  Headers = AllocateZeroPool(HeadersLength);
+  if (Headers == NULL) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to allocate memory of Headers\n", __func__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Lba = (EFI_LBA) PcdGet32 (PcdNvStorageVariableBlockLba);
+  Count = PcdGet32 (PcdNvStorageVariableBlockCount);
+  Instance->Media.BlockSize = PcdGet32 (PcdNvStorageVariableBlockSize);
+  NvStorageSize = Count * Instance->Media.BlockSize;
+  Instance->StartLba = Lba;
+  HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER);
+  if (NvStorageSize < HeadersLength) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+  NvStorageData = (UINT8 *) (UINTN) PcdGet32(PcdFlashNvStorageVariableBase);
+  mMapNvStorageVariableBase = PcdGet32(PcdFlashNvStorageVariableBase);
+  NvBlockDevicePath = &Instance->DevicePath;
+  NvBlockDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdNvStorageVariableBlockDevicePath));
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &NvBlockDevicePath,
+                                  &Instance->Handle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate NVM device (status: %r)\n", Status));
+    return EFI_INVALID_PARAMETER;
+  }
+  Status = gBS->OpenProtocol (
+		      Instance->Handle,
+                      &gEfiBlockIoProtocolGuid,
+		      (VOID **) &Instance->BlockIoProtocol,
+                      gImageHandle,
+                      NULL,
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                      );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Warning: Couldn't open NVM device (status: %r)\n", Status));
+    return EFI_DEVICE_ERROR;
+  }
+  WriteBackDataCacheRange (Instance, sizeof(BLOCK_VARIABLE_INSTANCE));
+
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+		  &Handle,
+		  &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
+		  NULL
+		  );
+  if (EFI_ERROR (Status)) {
+    goto exit;
+  }
+
+  Status = FvbRead (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = ValidateFvHeader (Headers);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a, Found invalid Fv Header\n", __func__));
+
+    // Erase all the block device that is reserved for variable storage
+    Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, Count, EFI_LBA_LIST_TERMINATOR);
+    if (EFI_ERROR (Status)) {
+      goto exit;
+    }
+
+    Status = InitNonVolatileVariableStore (Instance, Headers, HeadersLength);
+    if (EFI_ERROR (Status)) {
+      goto exit;
+    }
+  }
+
+  if (NvStorageSize > ((EFI_FIRMWARE_VOLUME_HEADER*)Headers)->FvLength) {
+    NvStorageSize = ((EFI_FIRMWARE_VOLUME_HEADER*)Headers)->FvLength;
+    NvStorageSize = ((NvStorageSize + Instance->Media.BlockSize - 1) / Instance->Media.BlockSize) * Instance->Media.BlockSize;
+  }
+  Status = FvbRead (&Instance->FvbProtocol, 0, 0, &NvStorageSize, NvStorageData);
+
+exit:
+  return Status;
+}
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.h b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.h
new file mode 100644
index 0000000..a8f95e8
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.h
@@ -0,0 +1,51 @@
+/** @file  NorFlashDxe.h
+
+  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+  Copyright (c) 2015, Hisilicon Ltd. 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 __VARIABLE_DXE_H__
+#define __VARIABLE_DXE_H__
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+#define BLOCK_VARIABLE_SIGNATURE                       SIGNATURE_32('b', 'l', 'k', '0')
+
+typedef struct _BLOCK_VARIABLE_INSTANCE                BLOCK_VARIABLE_INSTANCE;
+
+typedef struct {
+  VENDOR_DEVICE_PATH                  Vendor;
+  EFI_DEVICE_PATH_PROTOCOL            End;
+} BLOCK_DEVICE_PATH;
+
+struct _BLOCK_VARIABLE_INSTANCE {
+  UINT32                              Signature;
+  EFI_HANDLE                          Handle;
+
+  BOOLEAN                             Initialized;
+
+  UINTN                               Size;
+  EFI_LBA                             StartLba;
+
+  EFI_BLOCK_IO_MEDIA                  Media;
+  EFI_BLOCK_IO_PROTOCOL               *BlockIoProtocol;
+  EFI_DISK_IO_PROTOCOL                DiskIoProtocol;
+  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
+  EFI_DEVICE_PATH_PROTOCOL            DevicePath;
+
+  VOID*                               ShadowBuffer;
+};
+
+
+#endif /* __VARIABLE_DXE_H__ */
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.inf b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.inf
new file mode 100644
index 0000000..6d4ad91
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.inf
@@ -0,0 +1,65 @@
+#/** @file
+#  INF file for the Variable Protocol implementation for the block device.
+#
+#  Copyright (c) 2015, Linaro Limited. All rights reserved.
+#  Copyright (c) 2015, Hisilicon 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]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BlockVariableDxe
+  FILE_GUID                      = 522fc4a8-46d8-403e-a415-e2dbb1e0ebc0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = BlockVariableDxeInitialize
+
+[Sources.common]
+  BlockVariableDxe.c
+
+[Packages]
+  HisiPkg/HisiPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseLib
+  BaseMemoryLib
+  CacheMaintenanceLib
+  IoLib
+  UefiDriverEntryPoint
+  UefiLib
+  UncachedMemoryAllocationLib
+
+[Guids]
+  gEfiSystemNvDataFvGuid
+  gEfiVariableGuid
+  gEfiEventVirtualAddressChangeGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiBlockIoProtocolGuid			                    ## CONSUMES
+  gEfiFirmwareVolumeBlockProtocolGuid
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase      ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize      ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize      ## CONSUMES
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockCount                  ## CONSUMES
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockSize                   ## CONSUMES
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockLba                    ## CONSUMES
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockDevicePath             ## CONSUMES
+
+[Depex]
+  TRUE
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSd.h b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSd.h
new file mode 100644
index 0000000..44b4276
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSd.h
@@ -0,0 +1,131 @@
+/** @file
+*
+*  Copyright (c) 2014, Linaro Limited. All rights reserved.
+*  Copyright (c) 2014, Hisilicon 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.
+*
+**/
+
+
+#ifndef __DWSD_H__
+#define __DWSD_H__
+
+#include <Protocol/EmbeddedGpio.h>
+
+// DW MMC Registers
+#define DWSD_CTRL		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x000)
+#define DWSD_PWREN		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x004)
+#define DWSD_CLKDIV		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x008)
+#define DWSD_CLKSRC		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x00c)
+#define DWSD_CLKENA		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x010)
+#define DWSD_TMOUT		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x014)
+#define DWSD_CTYPE		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x018)
+#define DWSD_BLKSIZ		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x01c)
+#define DWSD_BYTCNT		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x020)
+#define DWSD_INTMASK		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x024)
+#define DWSD_CMDARG		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x028)
+#define DWSD_CMD		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x02c)
+#define DWSD_RESP0		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x030)
+#define DWSD_RESP1		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x034)
+#define DWSD_RESP2		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x038)
+#define DWSD_RESP3		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x03c)
+#define DWSD_RINTSTS		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x044)
+#define DWSD_STATUS		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x048)
+#define DWSD_FIFOTH		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x04c)
+#define DWSD_TCBCNT		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x05c)
+#define DWSD_TBBCNT		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x060)
+#define DWSD_DEBNCE		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x064)
+#define DWSD_UHSREG		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x074)
+#define DWSD_BMOD		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x080)
+#define DWSD_DBADDR		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x088)
+#define DWSD_IDSTS		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x08c)
+#define DWSD_IDINTEN		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x090)
+#define DWSD_DSCADDR		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x094)
+#define DWSD_BUFADDR		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x098)
+#define DWSD_CARDTHRCTL		((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x100)
+#define DWSD_FIFO_START         ((UINT32)PcdGet32 (PcdDwSdBaseAddress) + 0x200)
+
+#define CMD_UPDATE_CLK				0x80202000
+#define CMD_START_BIT				(1 << 31)
+
+#define MMC_8BIT_MODE				(1 << 16)
+
+#define BIT_CMD_RESPONSE_EXPECT			(1 << 6)
+#define BIT_CMD_LONG_RESPONSE			(1 << 7)
+#define BIT_CMD_CHECK_RESPONSE_CRC		(1 << 8)
+#define BIT_CMD_DATA_EXPECTED			(1 << 9)
+#define BIT_CMD_READ				(0 << 10)
+#define BIT_CMD_WRITE				(1 << 10)
+#define BIT_CMD_BLOCK_TRANSFER			(0 << 11)
+#define BIT_CMD_STREAM_TRANSFER			(1 << 11)
+#define BIT_CMD_SEND_AUTO_STOP			(1 << 12)
+#define BIT_CMD_WAIT_PRVDATA_COMPLETE		(1 << 13)
+#define BIT_CMD_STOP_ABORT_CMD			(1 << 14)
+#define BIT_CMD_SEND_INIT			(1 << 15)
+#define BIT_CMD_UPDATE_CLOCK_ONLY		(1 << 21)
+#define BIT_CMD_READ_CEATA_DEVICE		(1 << 22)
+#define BIT_CMD_CCS_EXPECTED			(1 << 23)
+#define BIT_CMD_ENABLE_BOOT			(1 << 24)
+#define BIT_CMD_EXPECT_BOOT_ACK			(1 << 25)
+#define BIT_CMD_DISABLE_BOOT			(1 << 26)
+#define BIT_CMD_MANDATORY_BOOT			(0 << 27)
+#define BIT_CMD_ALTERNATE_BOOT			(1 << 27)
+#define BIT_CMD_VOLT_SWITCH			(1 << 28)
+#define BIT_CMD_USE_HOLD_REG			(1 << 29)
+#define BIT_CMD_START				(1 << 31)
+
+#define DWSD_INT_EBE			(1 << 15)	/* End-bit Err */
+#define DWSD_INT_SBE			(1 << 13)	/* Start-bit  Err */
+#define DWSD_INT_HLE			(1 << 12)	/* Hardware-lock Err */
+#define DWSD_INT_FRUN			(1 << 11)	/* FIFO UN/OV RUN */
+#define DWSD_INT_DRT			(1 << 9)	/* Data timeout */
+#define DWSD_INT_RTO			(1 << 8)	/* Response timeout */
+#define DWSD_INT_DCRC			(1 << 7)	/* Data CRC err */
+#define DWSD_INT_RCRC			(1 << 6)	/* Response CRC err */
+#define DWSD_INT_RXDR			(1 << 5)
+#define DWSD_INT_TXDR			(1 << 4)
+#define DWSD_INT_DTO			(1 << 3)	/* Data trans over */
+#define DWSD_INT_CMD_DONE		(1 << 2)
+#define DWSD_INT_RE			(1 << 1)
+
+#define DWSD_IDMAC_DES0_DIC		(1 << 1)
+#define DWSD_IDMAC_DES0_LD		(1 << 2)
+#define DWSD_IDMAC_DES0_FS		(1 << 3)
+#define DWSD_IDMAC_DES0_CH		(1 << 4)
+#define DWSD_IDMAC_DES0_ER		(1 << 5)
+#define DWSD_IDMAC_DES0_CES		(1 << 30)
+#define DWSD_IDMAC_DES0_OWN		(1 << 31)
+#define DWSD_IDMAC_DES1_BS1(x)		((x) & 0x1fff)
+#define DWSD_IDMAC_DES2_BS2(x)		(((x) & 0x1fff) << 13)
+#define DWSD_IDMAC_SWRESET		(1 << 0)
+#define DWSD_IDMAC_FB			(1 << 1)
+#define DWSD_IDMAC_ENABLE		(1 << 7)
+
+#define EMMC_FIX_RCA				6
+
+/* bits in MMC0_CTRL */
+#define DWSD_CTRL_RESET		(1 << 0)
+#define DWSD_CTRL_FIFO_RESET		(1 << 1)
+#define DWSD_CTRL_DMA_RESET		(1 << 2)
+#define DWSD_CTRL_INT_EN		(1 << 4)
+#define DWSD_CTRL_DMA_EN		(1 << 5)
+#define DWSD_CTRL_IDMAC_EN		(1 << 25)
+#define DWSD_CTRL_RESET_ALL		(DWSD_CTRL_RESET | DWSD_CTRL_FIFO_RESET | DWSD_CTRL_DMA_RESET)
+
+#define DWSD_STS_DATA_BUSY		(1 << 9)
+
+#define DWSD_FIFO_TWMARK(x)		(x & 0xfff)
+#define DWSD_FIFO_RWMARK(x)		((x & 0x1ff) << 16)
+#define DWSD_DMA_BURST_SIZE(x)		((x & 0x7) << 28)
+
+#define DWSD_CARD_RD_THR(x)		((x & 0xfff) << 16)
+#define DWSD_CARD_RD_THR_EN		(1 << 0)
+
+#endif  // __DWSD_H__
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.c
new file mode 100644
index 0000000..dce32e6
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.c
@@ -0,0 +1,837 @@
+/** @file
+  This file implement the MMC Host Protocol for the DesignWare MMC.
+
+  Copyright (c) 2014, Linaro Limited. All rights reserved.
+  Copyright (c) 2014, Hisilicon 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.
+
+**/
+
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+#include <Protocol/MmcHost.h>
+
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+
+#include "DwSd.h"
+
+#define DWSD_DESC_PAGE		1
+#define DWSD_BLOCK_SIZE	        512
+#define DWSD_DMA_BUF_SIZE	(512 * 8)
+
+#define DWSD_DMA_THRESHOLD	16
+
+//#define FIFO
+//#define DUMP_BUF
+
+typedef struct {
+  UINT32		Des0;
+  UINT32		Des1;
+  UINT32		Des2;
+  UINT32		Des3;
+} DWSD_IDMAC_DESCRIPTOR;
+
+EFI_MMC_HOST_PROTOCOL     *gpMmcHost;
+EFI_GUID mDwSdDevicePathGuid = EFI_CALLER_ID_GUID;
+STATIC UINT32 mDwSdCommand;
+STATIC UINT32 mDwSdArgument;
+
+EFI_STATUS
+DwSdSendCommand (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_CMD                    MmcCmd,
+  IN UINT32                     Argument
+  );
+EFI_STATUS
+DwSdReceiveResponse (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_RESPONSE_TYPE          Type,
+  IN UINT32*                    Buffer
+  );
+
+EFI_STATUS
+DwSdReadBlockData (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN EFI_LBA                    Lba,
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  );
+
+BOOLEAN
+DwSdIsPowerOn (
+  VOID
+  )
+{
+    return TRUE;
+}
+
+EFI_STATUS
+DwSdInitialize (
+  VOID
+  )
+{
+    DEBUG ((EFI_D_BLKIO, "DwSdInitialize()"));
+    return EFI_SUCCESS;
+}
+
+BOOLEAN
+DwSdIsCardPresent (
+  IN EFI_MMC_HOST_PROTOCOL     *This
+  )
+{
+  UINT32    Value;
+
+  /*
+   * FIXME
+   * At first, reading GPIO pin shouldn't exist in SD driver. We need to
+   * add some callbacks to handle settings for hardware platform.
+   * In the second, reading GPIO pin should be based on GPIO driver. Now
+   * GPIO driver could only be used for one PL061 gpio controller. And it's
+   * used to detect jumper setting. As a workaround, we have to read the gpio
+   * register instead at here.
+   *
+   */
+  Value = MmioRead32 (0xf8012000 + (1 << 2));
+  if (Value)
+    return FALSE;
+  return TRUE;
+}
+
+BOOLEAN
+DwSdIsReadOnly (
+  IN EFI_MMC_HOST_PROTOCOL     *This
+  )
+{
+  /* FIXME */
+  return FALSE;
+}
+
+BOOLEAN
+DwSdIsDmaSupported (
+  IN EFI_MMC_HOST_PROTOCOL     *This
+  )
+{
+#ifdef FIFO
+  return FALSE;
+#else
+  return TRUE;
+#endif
+}
+
+EFI_STATUS
+DwSdBuildDevicePath (
+  IN EFI_MMC_HOST_PROTOCOL      *This,
+  IN EFI_DEVICE_PATH_PROTOCOL   **DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
+
+  NewDevicePathNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH));
+  CopyGuid (& ((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid, &mDwSdDevicePathGuid);
+
+  *DevicePath = NewDevicePathNode;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DwSdUpdateClock (
+  VOID
+  )
+{
+  UINT32 Data;
+
+  /* CMD_UPDATE_CLK */
+  Data = BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_UPDATE_CLOCK_ONLY |
+	 BIT_CMD_START;
+  MmioWrite32 (DWSD_CMD, Data);
+  while (1) {
+    Data = MmioRead32 (DWSD_CMD);
+    if (!(Data & CMD_START_BIT))
+      break;
+    Data = MmioRead32 (DWSD_RINTSTS);
+    if (Data & DWSD_INT_HLE)
+    {
+      Print (L"failed to update mmc clock frequency\n");
+      return EFI_DEVICE_ERROR;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DwSdSetClock (
+  IN UINTN                     ClockFreq
+  )
+{
+  UINT32 Divider, Rate, Data;
+  EFI_STATUS Status;
+  BOOLEAN Found = FALSE;
+
+  for (Divider = 1; Divider < 256; Divider++) {
+    Rate = PcdGet32 (PcdDwSdClockFrequencyInHz);
+    if ((Rate / (2 * Divider)) <= ClockFreq) {
+      Found = TRUE;
+      break;
+    }
+  }
+  if (Found == FALSE)
+    return EFI_NOT_FOUND;
+
+  // Wait until MMC is idle
+  do {
+    Data = MmioRead32 (DWSD_STATUS);
+  } while (Data & DWSD_STS_DATA_BUSY);
+
+  // Disable MMC clock first
+  MmioWrite32 (DWSD_CLKENA, 0);
+  Status = DwSdUpdateClock ();
+  ASSERT (!EFI_ERROR (Status));
+
+  MmioWrite32 (DWSD_CLKDIV, Divider);
+  Status = DwSdUpdateClock ();
+  ASSERT (!EFI_ERROR (Status));
+
+  // Enable MMC clock
+  MmioWrite32 (DWSD_CLKENA, 1);
+  MmioWrite32 (DWSD_CLKSRC, 0);
+  Status = DwSdUpdateClock ();
+  ASSERT (!EFI_ERROR (Status));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DwSdNotifyState (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_STATE                 State
+  )
+{
+  UINT32      Data;
+  EFI_STATUS  Status;
+
+  switch (State) {
+  case MmcInvalidState:
+    ASSERT (0);
+    break;
+  case MmcHwInitializationState:
+    MmioWrite32 (DWSD_PWREN, 1);
+
+    // If device already turn on then restart it
+    Data = DWSD_CTRL_RESET_ALL;
+    MmioWrite32 (DWSD_CTRL, Data);
+    do {
+      // Wait until reset operation finished
+      Data = MmioRead32 (DWSD_CTRL);
+    } while (Data & DWSD_CTRL_RESET_ALL);
+
+    MmioWrite32 (DWSD_RINTSTS, ~0);
+    MmioWrite32 (DWSD_INTMASK, 0);
+    MmioWrite32 (DWSD_TMOUT, ~0);
+    MmioWrite32 (DWSD_IDINTEN, 0);
+    MmioWrite32 (DWSD_BMOD, DWSD_IDMAC_SWRESET);
+
+    MmioWrite32 (DWSD_BLKSIZ, DWSD_BLOCK_SIZE);
+    do {
+      Data = MmioRead32 (DWSD_BMOD);
+    } while (Data & DWSD_IDMAC_SWRESET);
+
+
+    Data = DWSD_DMA_BURST_SIZE(2) | DWSD_FIFO_TWMARK(8) | DWSD_FIFO_RWMARK(7) | (2 << 28);
+    MmioWrite32 (DWSD_FIFOTH, Data);
+    Data = DWSD_CARD_RD_THR(512) | DWSD_CARD_RD_THR_EN;
+    MmioWrite32 (DWSD_CARDTHRCTL, Data);
+
+    // Set Data Length & Data Timer
+    MmioWrite32 (DWSD_CTYPE, 0);
+    MmioWrite32 (DWSD_DEBNCE, 0x00ffffff);
+
+    // Setup clock that could not be higher than 400KHz.
+    Status = DwSdSetClock (400000);
+    ASSERT (!EFI_ERROR (Status));
+    MicroSecondDelay (100);
+
+    break;
+  case MmcIdleState:
+    break;
+  case MmcReadyState:
+    break;
+  case MmcIdentificationState:
+    break;
+  case MmcStandByState:
+    break;
+  case MmcTransferState:
+    break;
+  case MmcSendingDataState:
+    break;
+  case MmcReceiveDataState:
+    break;
+  case MmcProgrammingState:
+    break;
+  case MmcDisconnectState:
+    break;
+  default:
+    ASSERT (0);
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SendCommand (
+  IN MMC_CMD                    MmcCmd,
+  IN UINT32                     Argument
+  )
+{
+  UINT32      Data, ErrMask;
+
+  MmioWrite32 (DWSD_RINTSTS, ~0);
+  MmioWrite32 (DWSD_CMDARG, Argument);
+  MicroSecondDelay(500);
+  // Wait until MMC is idle
+  do {
+    Data = MmioRead32 (DWSD_STATUS);
+  } while (Data & DWSD_STS_DATA_BUSY);
+
+  MmioWrite32 (DWSD_CMD, MmcCmd);
+
+  ErrMask = DWSD_INT_EBE | DWSD_INT_HLE | DWSD_INT_RTO |
+            DWSD_INT_RCRC | DWSD_INT_RE;
+  ErrMask |= DWSD_INT_DCRC | DWSD_INT_DRT | DWSD_INT_SBE;
+  do {
+    MicroSecondDelay(500);
+    Data = MmioRead32 (DWSD_RINTSTS);
+
+    if (Data & ErrMask) {
+      DEBUG ((EFI_D_ERROR, "Data:%x, ErrMask:%x, TBBCNT:%x, TCBCNT:%x, BYTCNT:%x, BLKSIZ:%x\n", Data, ErrMask, MmioRead32 (DWSD_TBBCNT), MmioRead32 (DWSD_TCBCNT), MmioRead32 (DWSD_BYTCNT), MmioRead32 (DWSD_BLKSIZ)));
+      return EFI_DEVICE_ERROR;
+    }
+    if (Data & DWSD_INT_DTO)	// Transfer Done
+      break;
+  } while (!(Data & DWSD_INT_CMD_DONE));
+  MmcCmd &= 0x3f;
+  if (MmcCmd == 17)
+    MicroSecondDelay(100);
+  else if (MmcCmd != 13)
+    MicroSecondDelay(5000);
+
+  return EFI_SUCCESS;
+}
+
+UINTN ACmd = 0;
+
+EFI_STATUS
+DwSdSendCommand (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_CMD                    MmcCmd,
+  IN UINT32                     Argument
+  )
+{
+  UINT32       Cmd = 0;
+  EFI_STATUS   Status = EFI_SUCCESS;
+  BOOLEAN      Pending = FALSE;
+  UINT32       Data;
+
+  switch (MMC_GET_INDX(MmcCmd)) {
+  case MMC_INDX(0):
+    //Cmd = BIT_CMD_SEND_INIT;
+    Cmd = BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    break;
+  case MMC_INDX(1):
+    Cmd = BIT_CMD_RESPONSE_EXPECT;
+    break;
+  case MMC_INDX(2):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_LONG_RESPONSE |
+           BIT_CMD_CHECK_RESPONSE_CRC | BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    break;
+  case MMC_INDX(3):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    break;
+  case MMC_INDX(6):
+    if (!ACmd) {
+      Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+	    BIT_CMD_DATA_EXPECTED | BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    } else {
+      Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+	    BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    }
+#ifdef FIFO
+    Pending = FALSE;
+    Data = MmioRead32 (DWSD_CTRL);
+    Data |= DWSD_CTRL_FIFO_RESET;
+    MmioWrite32 (DWSD_CTRL, Data);
+    while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
+    };
+#else
+    if (!ACmd)
+      Pending = TRUE;
+#endif
+    break;
+  case MMC_INDX(7):
+    if (Argument)
+        Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+	       BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    else
+        Cmd = 0;
+    break;
+  case MMC_INDX(8):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           //BIT_CMD_DATA_EXPECTED | BIT_CMD_READ |
+           BIT_CMD_READ |
+           BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    break;
+  case MMC_INDX(9):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           BIT_CMD_LONG_RESPONSE | BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    break;
+  case MMC_INDX(12):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           BIT_CMD_STOP_ABORT_CMD;
+    break;
+  case MMC_INDX(13):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
+    break;
+  case MMC_INDX(17):
+  case MMC_INDX(18):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           BIT_CMD_DATA_EXPECTED | BIT_CMD_READ |
+           BIT_CMD_WAIT_PRVDATA_COMPLETE;
+#ifdef FIFO
+    Pending = FALSE;
+    Data = MmioRead32 (DWSD_CTRL);
+    Data |= DWSD_CTRL_FIFO_RESET;
+    MmioWrite32 (DWSD_CTRL, Data);
+    while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
+    };
+#else
+    Pending = TRUE;
+    Data = MmioRead32 (DWSD_CTRL);
+    Data |= DWSD_CTRL_FIFO_RESET;
+    MmioWrite32 (DWSD_CTRL, Data);
+    while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
+    };
+#endif
+    break;
+  case MMC_INDX(24):
+  case MMC_INDX(25):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           BIT_CMD_DATA_EXPECTED | BIT_CMD_WRITE |
+           BIT_CMD_WAIT_PRVDATA_COMPLETE;
+#ifdef FIFO
+    Pending = FALSE;
+    Data = MmioRead32 (DWSD_CTRL);
+    Data |= DWSD_CTRL_FIFO_RESET;
+    MmioWrite32 (DWSD_CTRL, Data);
+    while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
+    };
+#else
+    Pending = TRUE;
+#endif
+    break;
+  case MMC_INDX(30):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           BIT_CMD_DATA_EXPECTED;
+    break;
+  case MMC_INDX(41):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_WAIT_PRVDATA_COMPLETE;
+    break;
+  case MMC_INDX(51):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
+           BIT_CMD_DATA_EXPECTED | BIT_CMD_READ |
+           BIT_CMD_WAIT_PRVDATA_COMPLETE;
+#ifdef FIFO
+    Pending = FALSE;
+    Data = MmioRead32 (DWSD_CTRL);
+    Data |= DWSD_CTRL_FIFO_RESET;
+    MmioWrite32 (DWSD_CTRL, Data);
+    while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
+    };
+#else
+    Pending = TRUE;
+#endif
+    break;
+  case MMC_INDX(55):
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
+    ACmd = 1;
+    break;
+  default:
+    Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
+    break;
+  }
+
+  Cmd |= MMC_GET_INDX(MmcCmd) | BIT_CMD_USE_HOLD_REG | BIT_CMD_START;
+  if (Pending) {
+    mDwSdCommand = Cmd;
+    mDwSdArgument = Argument;
+  } else {
+    mDwSdCommand = 0;
+    mDwSdArgument = 0;
+    Status = SendCommand (Cmd, Argument);
+  }
+  /* Clear ACMD */
+  if (MMC_GET_INDX(MmcCmd) != MMC_INDX(55))
+    ACmd = 0;
+  return Status;
+}
+
+EFI_STATUS
+DwSdReceiveResponse (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_RESPONSE_TYPE          Type,
+  IN UINT32*                    Buffer
+  )
+{
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (   (Type == MMC_RESPONSE_TYPE_R1)
+      || (Type == MMC_RESPONSE_TYPE_R1b)
+      || (Type == MMC_RESPONSE_TYPE_R3)
+      || (Type == MMC_RESPONSE_TYPE_R6)
+      || (Type == MMC_RESPONSE_TYPE_R7))
+  {
+    Buffer[0] = MmioRead32 (DWSD_RESP0);
+  } else if (Type == MMC_RESPONSE_TYPE_R2) {
+    Buffer[0] = MmioRead32 (DWSD_RESP0);
+    Buffer[1] = MmioRead32 (DWSD_RESP1);
+    Buffer[2] = MmioRead32 (DWSD_RESP2);
+    Buffer[3] = MmioRead32 (DWSD_RESP3);
+  }
+  return EFI_SUCCESS;
+}
+
+#ifndef FIFO
+EFI_STATUS
+PrepareDmaData (
+  IN DWSD_IDMAC_DESCRIPTOR*    IdmacDesc,
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  )
+{
+  UINTN  Cnt, Idx, LastIdx, BlockSize;
+  UINT32 Data;
+
+  if (Length % 4) {
+    DEBUG ((EFI_D_ERROR, "Length isn't aligned with 4\n"));
+    return EFI_BAD_BUFFER_SIZE;
+  }
+  if (Length < DWSD_DMA_THRESHOLD) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+  Cnt = (Length + DWSD_DMA_BUF_SIZE - 1) / DWSD_DMA_BUF_SIZE;
+  if (Length > DWSD_BLOCK_SIZE)
+    BlockSize = DWSD_BLOCK_SIZE;
+  else {
+    BlockSize = Length;
+  }
+
+  for (Idx = 0; Idx < Cnt; Idx++) {
+    (IdmacDesc + Idx)->Des0 = DWSD_IDMAC_DES0_OWN | DWSD_IDMAC_DES0_CH |
+	    		      DWSD_IDMAC_DES0_DIC;
+    (IdmacDesc + Idx)->Des1 = DWSD_IDMAC_DES1_BS1(DWSD_DMA_BUF_SIZE);
+    /* Buffer Address */
+    (IdmacDesc + Idx)->Des2 = (UINT32)((UINTN)Buffer + DWSD_DMA_BUF_SIZE * Idx);
+    /* Next Descriptor Address */
+    (IdmacDesc + Idx)->Des3 = (UINT32)((UINTN)IdmacDesc +
+   	                               (sizeof(DWSD_IDMAC_DESCRIPTOR) * (Idx + 1)));
+  }
+  /* First Descriptor */
+  IdmacDesc->Des0 |= DWSD_IDMAC_DES0_FS;
+  /* Last Descriptor */
+  LastIdx = Cnt - 1;
+  (IdmacDesc + LastIdx)->Des0 |= DWSD_IDMAC_DES0_LD;
+  (IdmacDesc + LastIdx)->Des0 &= ~(DWSD_IDMAC_DES0_DIC | DWSD_IDMAC_DES0_CH);
+  (IdmacDesc + LastIdx)->Des1 = DWSD_IDMAC_DES1_BS1(Length -
+   		                (LastIdx * DWSD_DMA_BUF_SIZE));
+  /* Set the Next field of Last Descriptor */
+  (IdmacDesc + LastIdx)->Des3 = 0;
+  MmioWrite32 (DWSD_DBADDR, (UINT32)((UINTN)IdmacDesc));
+
+  Data = MmioRead32 (DWSD_CTRL);
+  Data |= DWSD_CTRL_INT_EN | DWSD_CTRL_DMA_EN | DWSD_CTRL_IDMAC_EN;
+  MmioWrite32 (DWSD_CTRL, Data);
+  Data = MmioRead32 (DWSD_BMOD);
+  Data |= DWSD_IDMAC_ENABLE | DWSD_IDMAC_FB;
+  MmioWrite32 (DWSD_BMOD, Data);
+
+  MmioWrite32 (DWSD_BLKSIZ, BlockSize);
+  MmioWrite32 (DWSD_BYTCNT, Length);
+
+  return EFI_SUCCESS;
+}
+#endif
+
+STATIC
+EFI_STATUS
+ReadFifo (
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  )
+{
+  UINT32      Data, Received, Count;
+#ifdef DUMP_BUF
+  CHAR8       CBuffer[100];
+  UINTN       CharCount, Idx;
+#endif
+
+  Received = 0;
+  Count = (Length + 3) / 4;
+  while (Received < Count) {
+    Data = MmioRead32 (DWSD_RINTSTS);
+    if (Data & DWSD_INT_CMD_DONE) {
+      *(Buffer + Received) = MmioRead32 (DWSD_FIFO_START);
+      Received++;
+    } else {
+      DEBUG ((EFI_D_ERROR, "Received:%d, RINTSTS:%x\n", Received, Data));
+    }
+  }
+  while (1) {
+    Data = MmioRead32 (DWSD_RINTSTS);
+    if (Data & DWSD_INT_DTO)
+      break;
+  }
+#ifdef DUMP_BUF
+  for (Idx = 0; Idx < Length; Idx += 8) {
+    CharCount = AsciiSPrint (CBuffer,sizeof (CBuffer),"#%4x: %x %x %x %x %x %x %x %x\n", Idx,
+	    *((UINT8 *)Buffer + Idx), *((UINT8 *)Buffer + Idx + 1), *((UINT8 *)Buffer + Idx + 2),
+	    *((UINT8 *)Buffer + Idx + 3), *((UINT8 *)Buffer + Idx + 4), *((UINT8 *)Buffer + Idx + 5),
+	    *((UINT8 *)Buffer + Idx + 6), *((UINT8 *)Buffer + Idx + 7));
+    SerialPortWrite ((UINT8 *) CBuffer, CharCount);
+  }
+  DEBUG ((EFI_D_ERROR, "TBB:%x, TCB:%x, BYTCNT:%x, BLKSIZ:%x\n", MmioRead32 (DWSD_TBBCNT), MmioRead32 (DWSD_TCBCNT), MmioRead32 (DWSD_BYTCNT), MmioRead32 (DWSD_BLKSIZ)));
+#else
+  /* FIXME */
+  MicroSecondDelay (1000);
+#endif
+  return EFI_SUCCESS;
+}
+
+#ifdef FIFO
+EFI_STATUS
+DwSdReadBlockData (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN EFI_LBA                    Lba,
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  )
+{
+  return ReadFifo (Length, Buffer);
+}
+#else
+EFI_STATUS
+DwSdReadBlockData (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN EFI_LBA                    Lba,
+  IN UINTN                      Length,
+  IN UINT32*                   Buffer
+  )
+{
+  DWSD_IDMAC_DESCRIPTOR*  IdmacDesc;
+  EFI_STATUS  Status;
+  UINT32      DescPages, CountPerPage, Count, Data;
+#ifdef DUMP_BUF
+  CHAR8       CBuffer[100];
+  UINTN       CharCount, Idx;
+#endif
+
+  CountPerPage = EFI_PAGE_SIZE / 16;
+  Count = (Length + DWSD_DMA_BUF_SIZE - 1) / DWSD_DMA_BUF_SIZE;
+  DescPages = (Count + CountPerPage - 1) / CountPerPage;
+
+  IdmacDesc = (DWSD_IDMAC_DESCRIPTOR *)UncachedAllocatePages (DescPages);
+  if (IdmacDesc == NULL)
+    return EFI_BUFFER_TOO_SMALL;
+
+  InvalidateDataCacheRange (Buffer, Length);
+
+  Status = PrepareDmaData (IdmacDesc, Length, Buffer);
+  if (EFI_ERROR (Status)) {
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+      Data = MmioRead32 (DWSD_CTRL);
+      Data |= DWSD_CTRL_FIFO_RESET;
+      MmioWrite32 (DWSD_CTRL, Data);
+      while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
+      };
+
+      Status = SendCommand (mDwSdCommand, mDwSdArgument);
+      if (EFI_ERROR (Status)) {
+	DEBUG ((EFI_D_ERROR, "Failed to read data from FIFO, mDwSdCommand:%x, mDwSdArgument:%x, Status:%r\n", mDwSdCommand, mDwSdArgument, Status));
+	goto out;
+      }
+      Status = ReadFifo (Length, Buffer);
+    }
+    goto done;
+  } else {
+
+    Status = SendCommand (mDwSdCommand, mDwSdArgument);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_ERROR, "Failed to read data, mDwSdCommand:%x, mDwSdArgument:%x, Status:%r\n", mDwSdCommand, mDwSdArgument, Status));
+      goto out;
+    }
+
+    /* Wait until data transfer finished */
+    while (MmioRead32 (DWSD_TCBCNT) < MmioRead32 (DWSD_BYTCNT)) {
+    }
+
+  }
+done:
+#ifdef DUMP_BUF
+  for (Idx = 0; Idx < Length; Idx += 8) {
+    CharCount = AsciiSPrint (CBuffer,sizeof (CBuffer),"#%4x: %x %x %x %x %x %x %x %x\n", Idx,
+	    *((UINT8 *)Buffer + Idx), *((UINT8 *)Buffer + Idx + 1), *((UINT8 *)Buffer + Idx + 2),
+	    *((UINT8 *)Buffer + Idx + 3), *((UINT8 *)Buffer + Idx + 4), *((UINT8 *)Buffer + Idx + 5),
+	    *((UINT8 *)Buffer + Idx + 6), *((UINT8 *)Buffer + Idx + 7));
+    SerialPortWrite ((UINT8 *) CBuffer, CharCount);
+  }
+  DEBUG ((EFI_D_ERROR, "TBB:%x, TCB:%x, BYTCNT:%x, BLKSIZ:%x\n", MmioRead32 (DWSD_TBBCNT), MmioRead32 (DWSD_TCBCNT), MmioRead32 (DWSD_BYTCNT), MmioRead32 (DWSD_BLKSIZ)));
+#endif
+out:
+  UncachedFreePages (IdmacDesc, DescPages);
+  return Status;
+}
+#endif
+
+#ifdef FIFO
+EFI_STATUS
+DwSdWriteBlockData (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN EFI_LBA                    Lba,
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  )
+{
+  return EFI_SUCCESS;
+}
+#else
+EFI_STATUS
+DwSdWriteBlockData (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN EFI_LBA                    Lba,
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  )
+{
+  DWSD_IDMAC_DESCRIPTOR*  IdmacDesc;
+  EFI_STATUS  Status;
+  UINT32      DescPages, CountPerPage, Count;
+
+  CountPerPage = EFI_PAGE_SIZE / 16;
+  Count = (Length + DWSD_DMA_BUF_SIZE - 1) / DWSD_DMA_BUF_SIZE;
+  DescPages = (Count + CountPerPage - 1) / CountPerPage;
+  IdmacDesc = (DWSD_IDMAC_DESCRIPTOR *)UncachedAllocatePages (DescPages);
+  if (IdmacDesc == NULL)
+    return EFI_BUFFER_TOO_SMALL;
+
+  WriteBackDataCacheRange (Buffer, Length);
+
+  Status = PrepareDmaData (IdmacDesc, Length, Buffer);
+  if (EFI_ERROR (Status))
+    goto out;
+
+  Status = SendCommand (mDwSdCommand, mDwSdArgument);
+out:
+  UncachedFreePages (IdmacDesc, DescPages);
+  return Status;
+}
+#endif
+
+EFI_STATUS
+DwSdSetIos (
+  IN EFI_MMC_HOST_PROTOCOL      *This,
+  IN  UINT32                    BusClockFreq,
+  IN  UINT32                    BusWidth,
+  IN  UINT32                    TimingMode
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  UINT32    Data;
+
+  if (TimingMode != EMMCBACKWARD) {
+    Data = MmioRead32 (DWSD_UHSREG);
+    switch (TimingMode) {
+    case EMMCHS52DDR1V2:
+    case EMMCHS52DDR1V8:
+      Data |= 1 << 16;
+      break;
+    case EMMCHS52:
+    case EMMCHS26:
+      Data &= ~(1 << 16);
+      break;
+    default:
+      return EFI_UNSUPPORTED;
+    }
+    MmioWrite32 (DWSD_UHSREG, Data);
+  }
+
+  switch (BusWidth) {
+  case 1:
+    MmioWrite32 (DWSD_CTYPE, 0);
+    break;
+  case 4:
+    MmioWrite32 (DWSD_CTYPE, 1);
+    break;
+  case 8:
+    MmioWrite32 (DWSD_CTYPE, 1 << 16);
+    break;
+  default:
+    return EFI_UNSUPPORTED;
+  }
+  if (BusClockFreq) {
+    Status = DwSdSetClock (BusClockFreq);
+  }
+  return Status;
+}
+
+EFI_MMC_HOST_PROTOCOL gMciHost = {
+  MMC_HOST_PROTOCOL_REVISION,
+  DwSdIsCardPresent,
+  DwSdIsReadOnly,
+  DwSdIsDmaSupported,
+  DwSdBuildDevicePath,
+  DwSdNotifyState,
+  DwSdSendCommand,
+  DwSdReceiveResponse,
+  DwSdReadBlockData,
+  DwSdWriteBlockData,
+  DwSdSetIos
+};
+
+EFI_STATUS
+DwSdDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+  EFI_HANDLE    Handle;
+
+  Handle = NULL;
+
+  DEBUG ((EFI_D_BLKIO, "DwSdDxeInitialize()\n"));
+
+  //Publish Component Name, BlockIO protocol interfaces
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiMmcHostProtocolGuid,         &gMciHost,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.inf b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.inf
new file mode 100644
index 0000000..20c8179
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.inf
@@ -0,0 +1,56 @@
+#/** @file
+#  INF file for the MMC Host Protocol implementation for the DesignWare MMC.
+#
+#  Copyright (c) 2014, Linaro Limited. All rights reserved.
+#  Copyright (c) 2014, Hisilicon 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]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DwSdDxe
+  FILE_GUID                      = 594bfe73-5e18-4f12-8119-19db8c5fc849
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = DwSdDxeInitialize
+
+[Sources.common]
+  DwSdDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  HisiPkg/HisiPlatformPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseLib
+  BaseMemoryLib
+  CacheMaintenanceLib
+  IoLib
+  TimerLib
+  UefiDriverEntryPoint
+  UefiLib
+  UncachedMemoryAllocationLib
+
+[Protocols]
+  gEfiCpuArchProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEfiMmcHostProtocolGuid
+
+[Pcd]
+  gHwTokenSpaceGuid.PcdDwSdBaseAddress
+  gHwTokenSpaceGuid.PcdDwSdClockFrequencyInHz
+
+[Depex]
+  TRUE
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/Hi6220RegsPeri.h b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/Hi6220RegsPeri.h
new file mode 100644
index 0000000..a03304e
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/Hi6220RegsPeri.h
@@ -0,0 +1,44 @@
+/** @file
+*
+*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Ltd. 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 __HI6220_REGS_PERI_H__
+#define __HI6220_REGS_PERI_H__
+
+#define HI6220_PERI_BASE                0xf7030000
+
+#define SC_PERIPH_RSTEN3                (HI6220_PERI_BASE + 0x330)
+#define SC_PERIPH_RSTDIS3               (HI6220_PERI_BASE + 0x334)
+#define SC_PERIPH_RSTSTAT3              (HI6220_PERI_BASE + 0x338)
+
+/* SC_PERIPH_RSTEN3/RSTDIS3/RSTSTAT3 */
+#define PERIPH_RST3_CSSYS               (1 << 0)
+#define PERIPH_RST3_I2C0                (1 << 1)
+#define PERIPH_RST3_I2C1                (1 << 2)
+#define PERIPH_RST3_I2C2                (1 << 3)
+#define PERIPH_RST3_I2C3                (1 << 4)
+#define PERIPH_RST3_UART1               (1 << 5)
+#define PERIPH_RST3_UART2               (1 << 6)
+#define PERIPH_RST3_UART3               (1 << 7)
+#define PERIPH_RST3_UART4               (1 << 8)
+#define PERIPH_RST3_SSP                 (1 << 9)
+#define PERIPH_RST3_PWM                 (1 << 10)
+#define PERIPH_RST3_BLPWM               (1 << 11)
+#define PERIPH_RST3_TSENSOR             (1 << 12)
+#define PERIPH_RST3_DAPB                (1 << 18)
+#define PERIPH_RST3_HKADC               (1 << 19)
+#define PERIPH_RST3_CODEC_SSI           (1 << 20)
+#define PERIPH_RST3_PMUSSI1             (1 << 22)
+
+#endif /* __HI6220_REGS_PERI_H__ */
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.c
new file mode 100644
index 0000000..dc2da10
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.c
@@ -0,0 +1,183 @@
+/** @file
+*
+*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Ltd. 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/BdsLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Guid/ArmGlobalVariableHob.h>
+
+#include <Protocol/BlockIo.h>
+
+#include "HiKeyDxeInternal.h"
+
+#define SERIAL_NUMBER_LENGTH        16
+#define SERIAL_NUMBER_LBA           1024
+#define SERIAL_NUMBER_BLOCK_SIZE    512
+#define RANDOM_MAGIC                0x9a4dbeaf
+
+struct RandomSerialNo {
+  UINTN              Magic;
+  UINTN              Data;
+  CHAR8              SerialNo[32];
+};
+
+STATIC
+UINTN
+EFIAPI
+HiKeyInitSerialNo (
+  IN   VOID
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           VariableSize;
+  EFI_DEVICE_PATH_PROTOCOL        *BlockDevicePath;
+  EFI_BLOCK_IO_PROTOCOL           *BlockIoProtocol;
+  EFI_HANDLE                      Handle;
+  VOID                            *DataPtr;
+  struct RandomSerialNo           *Random;
+  CHAR16                          DefaultSerialNo[] = L"0123456789abcdef";
+  CHAR16                          SerialNoUnicode[32], DataUnicode[32];
+
+  BlockDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &BlockDevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate block device (status: %r)\n", Status));
+    return EFI_INVALID_PARAMETER;
+  }
+  Status = gBS->OpenProtocol (
+		      Handle,
+                      &gEfiBlockIoProtocolGuid,
+		      (VOID **) &BlockIoProtocol,
+                      gImageHandle,
+                      NULL,
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                      );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Warning: Couldn't open block device (status: %r)\n", Status));
+    return EFI_DEVICE_ERROR;
+  }
+  DataPtr = AllocateZeroPool (SERIAL_NUMBER_BLOCK_SIZE);
+  WriteBackDataCacheRange (DataPtr, SERIAL_NUMBER_BLOCK_SIZE);
+  Status = BlockIoProtocol->ReadBlocks (BlockIoProtocol, BlockIoProtocol->Media->MediaId,
+                                        SERIAL_NUMBER_LBA, SERIAL_NUMBER_BLOCK_SIZE,
+                                        DataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Warning: failed on reading blocks.\n"));
+    goto exit;
+  }
+  InvalidateDataCacheRange (DataPtr, SERIAL_NUMBER_BLOCK_SIZE);
+  Random = (struct RandomSerialNo *)DataPtr;
+  if (Random->Magic != RANDOM_MAGIC) {
+    VariableSize = SERIAL_NUMBER_LENGTH * sizeof (CHAR16);
+    Status = gRT->GetVariable (
+                    (CHAR16 *)L"SerialNo",
+                    &gArmGlobalVariableGuid,
+                    NULL,
+                    &VariableSize,
+                    &DefaultSerialNo
+                    );
+    if (Status == EFI_NOT_FOUND) {
+      Status = gRT->SetVariable (
+                      (CHAR16*)L"SerialNo",
+                      &gArmGlobalVariableGuid,
+                      EFI_VARIABLE_NON_VOLATILE       |
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                      EFI_VARIABLE_RUNTIME_ACCESS,
+                      VariableSize,
+                      DefaultSerialNo
+                      );
+    }
+  } else {
+    AsciiStrToUnicodeStr (Random->SerialNo, SerialNoUnicode);
+    VariableSize = SERIAL_NUMBER_LENGTH * sizeof (CHAR16);
+    Status = gRT->GetVariable (
+                    (CHAR16 *)L"SerialNo",
+                    &gArmGlobalVariableGuid,
+                    NULL,
+                    &VariableSize,
+                    &DataUnicode
+                    );
+    if ((Status == EFI_NOT_FOUND) || StrCmp (DataUnicode, SerialNoUnicode)) {
+      Status = gRT->SetVariable (
+                      (CHAR16*)L"SerialNo",
+                      &gArmGlobalVariableGuid,
+                      EFI_VARIABLE_NON_VOLATILE       |
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                      EFI_VARIABLE_RUNTIME_ACCESS,
+                      VariableSize,
+                      SerialNoUnicode
+                      );
+    }
+  }
+exit:
+  FreePool (DataPtr);
+  return Status;
+}
+
+STATIC
+VOID
+EFIAPI
+HiKeyInitBootDevice (
+  IN VOID
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 VariableSize;
+  CHAR16                DefaultBootDevice[BOOT_DEVICE_LENGTH] = L"sd";
+
+  VariableSize = BOOT_DEVICE_LENGTH * sizeof (CHAR16);
+  Status = gRT->GetVariable (
+                  (CHAR16 *)L"HiKeyBootDevice",
+                  &gArmGlobalVariableGuid,
+                  NULL,
+                  &VariableSize,
+                  &DefaultBootDevice
+                  );
+  if (Status == EFI_NOT_FOUND) {
+    Status = gRT->SetVariable (
+                    (CHAR16*)L"HiKeyBootDevice",
+                    &gArmGlobalVariableGuid,
+                    EFI_VARIABLE_NON_VOLATILE       |
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                    EFI_VARIABLE_RUNTIME_ACCESS,
+                    VariableSize,
+                    DefaultBootDevice
+                    );
+  }
+}
+
+EFI_STATUS
+EFIAPI
+HiKeyEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS           Status;
+
+  HiKeyInitSerialNo ();
+  HiKeyInitBootDevice ();
+  HiKeyInitPeripherals ();
+
+  Status = HiKeyBootMenuInstall ();
+
+  return Status;
+}
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf
new file mode 100644
index 0000000..a16ecaa
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf
@@ -0,0 +1,71 @@
+#
+#  Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.
+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+#  Copyright (c) 2015, Hisilicon Ltd. 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                    = 0x00010005
+  BASE_NAME                      = HiKeyDxe
+  FILE_GUID                      = f567684b-1089-4214-8881-d64b20cbda2f
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = HiKeyEntryPoint
+
+[Sources.common]
+  HiKeyDxe.c
+  InitPeripherals.c
+  InstallBootMenu.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  HisiPkg/HisiPlatformPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  BdsLib
+  CacheMaintenanceLib
+  DebugLib
+  DxeServicesTableLib
+  IoLib
+  PcdLib
+  PrintLib
+  SerialPortLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiLib
+  UefiDriverEntryPoint
+
+[Guids]
+  gArmGlobalVariableGuid
+  gEfiEndOfDxeEventGroupGuid
+  gEfiFileInfoGuid
+  gEfiGlobalVariableGuid
+  gArmPlatformUpdateFdtEventGuid
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiDevicePathFromTextProtocolGuid
+  gEfiDevicePathToTextProtocolGuid
+  gEfiSimpleFileSystemProtocolGuid
+  gEmbeddedGpioProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmPlatformTokenSpaceGuid.PcdFdtDevicePath
+  gHwTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+
+[Depex]
+  TRUE
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxeInternal.h b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxeInternal.h
new file mode 100644
index 0000000..82ff92d
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxeInternal.h
@@ -0,0 +1,42 @@
+/** @file
+*
+*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Ltd. 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 __HIKEY_DXE_INTERNAL_H__
+#define __HIKEY_DXE_INTERNAL_H__
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define BOOT_DEVICE_LENGTH       16
+
+EFI_STATUS
+HiKeyFdtInstall (
+  IN EFI_HANDLE                            ImageHandle
+  );
+
+EFI_STATUS
+HiKeyBootMenuInstall (
+  IN VOID
+  );
+
+EFI_STATUS
+HiKeyInitPeripherals (
+  IN VOID
+  );
+
+#endif // __HIKEY_DXE_INTERNAL_H__
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InitPeripherals.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InitPeripherals.c
new file mode 100644
index 0000000..8ed2ecf
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InitPeripherals.c
@@ -0,0 +1,36 @@
+/** @file
+*
+*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Ltd. 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/IoLib.h>
+
+#include "Hi6220RegsPeri.h"
+
+VOID
+EFIAPI
+HiKeyInitPeripherals (
+  IN VOID
+  )
+{
+  UINT32     Data, Bits;
+
+  /* make I2C0/I2C1/I2C2/SPI0 out of reset */
+  Bits = PERIPH_RST3_I2C0 | PERIPH_RST3_I2C1 | PERIPH_RST3_I2C2 | \
+	 PERIPH_RST3_SSP;
+  MmioWrite32 (SC_PERIPH_RSTDIS3, Bits);
+
+  do {
+    Data = MmioRead32 (SC_PERIPH_RSTSTAT3);
+  } while (Data & Bits);
+}
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InstallBootMenu.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InstallBootMenu.c
new file mode 100644
index 0000000..84fdea1
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InstallBootMenu.c
@@ -0,0 +1,614 @@
+/** @file
+*
+*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Ltd. 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/BdsLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/EmbeddedGpio.h>
+
+#include <Guid/ArmGlobalVariableHob.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/VariableFormat.h>
+
+#include "HiKeyDxeInternal.h"
+
+#define MAX_BOOT_ENTRIES         16
+// Jumper on pin5-6 of J15 determines whether boot to fastboot
+#define DETECT_J15_FASTBOOT      24    // GPIO 3_0
+
+#define USER_LED1                32    // GPIO 4_0
+#define USER_LED2                33    // GPIO 4_1
+#define USER_LED3                34    // GPIO 4_2
+#define USER_LED4                35    // GPIO 4_3
+
+struct HiKeyBootEntry {
+  CHAR16    *Path;
+  CHAR16    *Args;
+  CHAR16    *Description;
+  UINT16     LoadType;
+};
+
+STATIC CONST BOOLEAN mIsEndOfDxeEvent = TRUE;
+STATIC UINT16 *mBootOrder = NULL;
+STATIC UINT16 mBootCount = 0;
+STATIC UINT16 mBootIndex = 0;
+
+#define HIKEY_BOOT_ENTRY_FASTBOOT          0
+#define HIKEY_BOOT_ENTRY_BOOT_EMMC         1    /* boot from eMMC */
+#define HIKEY_BOOT_ENTRY_BOOT_SD           2    /* boot from SD card */
+
+STATIC struct HiKeyBootEntry Entries[] = {
+  [HIKEY_BOOT_ENTRY_FASTBOOT] = {
+    L"VenHw(B549F005-4BD4-4020-A0CB-06F42BDA68C3)/HD(6,GPT,5C0F213C-17E1-4149-88C8-8B50FB4EC70E,0x7000,0x20000)/\\EFI\\BOOT\\FASTBOOT.EFI",
+    NULL,
+    L"fastboot",
+    LOAD_OPTION_CATEGORY_APP
+  },
+  [HIKEY_BOOT_ENTRY_BOOT_EMMC] = {
+    L"VenHw(B549F005-4BD4-4020-A0CB-06F42BDA68C3)/HD(6,GPT,5C0F213C-17E1-4149-88C8-8B50FB4EC70E,0x7000,0x20000)/\\EFI\\BOOT\\GRUBAA64.EFI",
+    NULL,
+    L"boot from eMMC",
+    LOAD_OPTION_CATEGORY_APP
+  },
+  [HIKEY_BOOT_ENTRY_BOOT_SD] = {
+    L"VenHw(594BFE73-5E18-4F12-8119-19DB8C5FC849)/HD(1,MBR,0x00000000,0x3F,0x21FC0)/Image",
+    L"dtb=hi6220-hikey.dtb console=ttyAMA3,115200 earlycon=pl011,0xf7113000 root=/dev/mmcblk1p2 rw rootwait initrd=initrd.img efi=noruntime",
+    L"boot from SD card",
+    LOAD_OPTION_CATEGORY_BOOT
+  }
+};
+
+STATIC
+BOOLEAN
+EFIAPI
+HiKeyVerifyBootEntry (
+  IN CHAR16          *BootVariableName,
+  IN CHAR16          *BootDevicePathText,
+  IN CHAR16          *BootArgs,
+  IN CHAR16          *BootDescription,
+  IN UINT16           LoadOptionAttr
+  )
+{
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *DevicePathToTextProtocol;
+  CHAR16                             *DevicePathText;
+  UINTN                               EfiLoadOptionSize;
+  EFI_LOAD_OPTION                     EfiLoadOption;
+  BDS_LOAD_OPTION                    *LoadOption;
+  EFI_STATUS                          Status;
+  UINTN                               DescriptionLength;
+
+  Status = GetGlobalEnvironmentVariable (BootVariableName, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  if (EfiLoadOption == NULL) {
+    return FALSE;
+  }
+  if (EfiLoadOptionSize < sizeof(UINT32) + sizeof(UINT16) + sizeof(CHAR16) + sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+    return FALSE;
+  }
+  LoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));
+  if (LoadOption == NULL) {
+    return FALSE;
+  }
+
+  LoadOption->LoadOption     = EfiLoadOption;
+  LoadOption->Attributes         = *(UINT32*)EfiLoadOption;
+  LoadOption->FilePathListLength = *(UINT16*)(EfiLoadOption + sizeof(UINT32));
+  LoadOption->Description        = (CHAR16*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16));
+  DescriptionLength              = StrSize (LoadOption->Description);
+  LoadOption->FilePathList       = (EFI_DEVICE_PATH_PROTOCOL*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16) + DescriptionLength);
+  if ((UINTN)((UINTN)LoadOption->FilePathList + LoadOption->FilePathListLength - (UINTN)EfiLoadOption) == EfiLoadOptionSize) {
+    LoadOption->OptionalData     = NULL;
+    LoadOption->OptionalDataSize = 0;
+  } else {
+    LoadOption->OptionalData     = (VOID*)((UINTN)(LoadOption->FilePathList) + LoadOption->FilePathListLength);
+    LoadOption->OptionalDataSize = EfiLoadOptionSize - ((UINTN)LoadOption->OptionalData - (UINTN)EfiLoadOption);
+  }
+
+  if (((BootArgs == NULL) && (LoadOption->OptionalDataSize)) ||
+      (BootArgs && (LoadOption->OptionalDataSize == 0))) {
+    return FALSE;
+  } else if (BootArgs && LoadOption->OptionalDataSize) {
+    if (StrCmp (BootArgs, LoadOption->OptionalData) != 0)
+      return FALSE;
+  }
+  if ((LoadOption->Description == NULL) || (BootDescription == NULL)) {
+    return FALSE;
+  }
+  if (StrCmp (BootDescription, LoadOption->Description) != 0) {
+    return FALSE;
+  }
+  if ((LoadOption->Attributes & LOAD_OPTION_CATEGORY) != (LoadOptionAttr & LOAD_OPTION_CATEGORY)) {
+    return FALSE;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
+  ASSERT_EFI_ERROR(Status);
+  DevicePathText = DevicePathToTextProtocol->ConvertDevicePathToText(LoadOption->FilePathList, TRUE, TRUE);
+  if (StrCmp (DevicePathText, BootDevicePathText) != 0) {
+    return FALSE;
+  }
+
+  FreePool (LoadOption);
+  return TRUE;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+HiKeyCreateBootEntry (
+  IN CHAR16          *DevicePathText,
+  IN CHAR16          *BootArgs,
+  IN CHAR16          *BootDescription,
+  IN UINT16           LoadOption
+  )
+{
+  BDS_LOAD_OPTION                    *BdsLoadOption;
+  EFI_STATUS                          Status;
+  UINTN                               DescriptionSize;
+  UINTN                               BootOrderSize;
+  CHAR16                              BootVariableName[9];
+  UINT8                              *EfiLoadOptionPtr;
+  EFI_DEVICE_PATH_PROTOCOL           *DevicePathNode;
+  UINTN                               NodeLength;
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DevicePathFromTextProtocol;
+
+  if ((DevicePathText == NULL) || (BootDescription == NULL)) {
+    DEBUG ((EFI_D_ERROR, "%a: Invalid Parameters\n", __func__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", mBootCount);
+  if (HiKeyVerifyBootEntry (BootVariableName, DevicePathText, BootArgs, BootDescription, LoadOption) == TRUE) {
+    // The boot entry is already created.
+    Status = EFI_SUCCESS;
+    goto done;
+  }
+
+  BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));
+  ASSERT (BdsLoadOption != NULL);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiDevicePathFromTextProtocolGuid,
+                  NULL,
+                  (VOID**)&DevicePathFromTextProtocol
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  BdsLoadOption->FilePathList = DevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathText);
+  ASSERT (BdsLoadOption->FilePathList != NULL);
+  BdsLoadOption->FilePathListLength = GetDevicePathSize (BdsLoadOption->FilePathList);
+  BdsLoadOption->Attributes = LOAD_OPTION_ACTIVE | (LoadOption & LOAD_OPTION_CATEGORY);
+
+  if (BootArgs) {
+    BdsLoadOption->OptionalDataSize = StrSize (BootArgs);
+    BdsLoadOption->OptionalData = (CHAR16*)AllocateZeroPool (BdsLoadOption->OptionalDataSize);
+    ASSERT (BdsLoadOption->OptionalData != NULL);
+    StrCpy (BdsLoadOption->OptionalData, BootArgs);
+  }
+
+  BdsLoadOption->LoadOptionIndex = mBootCount;
+  DescriptionSize = StrSize (BootDescription);
+  BdsLoadOption->Description = (VOID*)AllocateZeroPool (DescriptionSize);
+  StrCpy (BdsLoadOption->Description, BootDescription);
+
+  BdsLoadOption->LoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + DescriptionSize + BdsLoadOption->FilePathListLength + BdsLoadOption->OptionalDataSize;
+  BdsLoadOption->LoadOption = (EFI_LOAD_OPTION)AllocateZeroPool (BdsLoadOption->LoadOptionSize);
+  ASSERT (BdsLoadOption->LoadOption != NULL);
+
+  EfiLoadOptionPtr = BdsLoadOption->LoadOption;
+
+  //
+  // Populate the EFI Load Option and BDS Boot Option structures
+  //
+
+  // Attributes fields
+  *(UINT32*)EfiLoadOptionPtr = BdsLoadOption->Attributes;
+  EfiLoadOptionPtr += sizeof(UINT32);
+
+  // FilePath List fields
+  *(UINT16*)EfiLoadOptionPtr = BdsLoadOption->FilePathListLength;
+  EfiLoadOptionPtr += sizeof(UINT16);
+
+  // Boot description fields
+  CopyMem (EfiLoadOptionPtr, BdsLoadOption->Description, DescriptionSize);
+  EfiLoadOptionPtr += DescriptionSize;
+
+  // File path fields
+  DevicePathNode = BdsLoadOption->FilePathList;
+  while (!IsDevicePathEndType (DevicePathNode)) {
+    NodeLength = DevicePathNodeLength(DevicePathNode);
+    CopyMem (EfiLoadOptionPtr, DevicePathNode, NodeLength);
+    EfiLoadOptionPtr += NodeLength;
+    DevicePathNode = NextDevicePathNode (DevicePathNode);
+  }
+
+  // Set the End Device Path Type
+  SetDevicePathEndNode (EfiLoadOptionPtr);
+  EfiLoadOptionPtr += sizeof(EFI_DEVICE_PATH);
+
+  // Fill the Optional Data
+  if (BdsLoadOption->OptionalDataSize > 0) {
+    CopyMem (EfiLoadOptionPtr, BdsLoadOption->OptionalData, BdsLoadOption->OptionalDataSize);
+  }
+
+  Status = gRT->SetVariable (
+                  BootVariableName,
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                  BdsLoadOption->LoadOptionSize,
+                  BdsLoadOption->LoadOption
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set BootVariable\n", __func__));
+    return Status;
+  }
+
+done:
+  BootOrderSize = mBootCount * sizeof (UINT16);
+  mBootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof (UINT16), mBootOrder);
+  mBootOrder[mBootCount] = mBootCount;
+  mBootCount++;
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+HiKeyCreateBootOrder (
+  IN    VOID
+  )
+{
+  UINT16             *BootOrder;
+  UINTN               BootOrderSize;
+  UINTN               Index;
+  EFI_STATUS          Status;
+
+  Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);
+  if (EFI_ERROR(Status) == 0) {
+    if (BootOrderSize == mBootCount) {
+      for (Index = 0; Index < mBootCount; Index++) {
+        if (BootOrder[Index] != mBootOrder[Index]) {
+          break;
+        }
+      }
+      if (Index == mBootCount) {
+        // Found BootOrder variable with expected value.
+        return EFI_SUCCESS;
+      }
+    }
+  }
+
+  Status = gRT->SetVariable (
+                  (CHAR16*)L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                  mBootCount * sizeof(UINT16),
+                  mBootOrder
+                  );
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+HiKeyCreateBootNext (
+  IN     VOID
+  )
+{
+  EFI_STATUS          Status;
+  UINT16             *BootNext;
+  UINTN               BootNextSize;
+
+  BootNextSize = sizeof(UINT16);
+  Status = GetGlobalEnvironmentVariable (L"BootNext", NULL, &BootNextSize, (VOID**)&BootNext);
+  if (EFI_ERROR(Status) == 0) {
+    if (BootNextSize == sizeof (UINT16)) {
+      if (*BootNext == mBootOrder[mBootIndex]) {
+        // Found the BootNext variable with expected value.
+        return EFI_SUCCESS;
+      }
+    }
+  }
+  BootNext = &mBootOrder[mBootIndex];
+  Status = gRT->SetVariable (
+                  (CHAR16*)L"BootNext",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                  sizeof (UINT16),
+                  BootNext
+                  );
+  return Status;
+}
+
+STATIC
+VOID
+EFIAPI
+HiKeyTestLed (
+  IN     EMBEDDED_GPIO   *Gpio
+  )
+{
+  EFI_STATUS             Status;
+
+  Status = Gpio->Set (Gpio, USER_LED1, GPIO_MODE_OUTPUT_0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set LED1\n", __func__));
+    return;
+  }
+  Status = Gpio->Set (Gpio, USER_LED2, GPIO_MODE_OUTPUT_1);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set LED2\n", __func__));
+    return;
+  }
+  Status = Gpio->Set (Gpio, USER_LED3, GPIO_MODE_OUTPUT_0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set LED3\n", __func__));
+    return;
+  }
+  Status = Gpio->Set (Gpio, USER_LED4, GPIO_MODE_OUTPUT_1);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set LED4\n", __func__));
+    return;
+  }
+}
+
+STATIC
+VOID
+EFIAPI
+HiKeyDetectJumper (
+  IN     VOID
+  )
+{
+  EMBEDDED_GPIO         *Gpio;
+  EFI_STATUS             Status;
+  UINTN                  Value;
+
+  Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&Gpio);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = Gpio->Set (Gpio, DETECT_J15_FASTBOOT, GPIO_MODE_INPUT);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set jumper as gpio input\n", __func__));
+    return;
+  }
+  Status = Gpio->Get (Gpio, DETECT_J15_FASTBOOT, &Value);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to get value from jumper\n", __func__));
+    return;
+  }
+  if (Value == 1) {
+    // Jump not connected on pin5-6 of J15
+    mBootIndex = 1;
+  } else {
+    mBootIndex = 0;
+  }
+
+  HiKeyTestLed (Gpio);
+}
+
+STATIC
+BOOLEAN
+EFIAPI
+HiKeySDCardIsPresent (
+  IN      VOID
+  )
+{
+  UINT32    Value;
+
+  /*
+   * FIXME
+   * At first, reading GPIO pin shouldn't exist in SD driver. We need to
+   * add some callbacks to handle settings for hardware platform.
+   * In the second, reading GPIO pin should be based on GPIO driver. Now
+   * GPIO driver could only be used for one PL061 gpio controller. And it's
+   * used to detect jumper setting. As a workaround, we have to read the gpio
+   * register instead at here.
+   *
+   */
+  Value = MmioRead32 (0xf8012000 + (1 << 2));
+  if (Value)
+    return FALSE;
+  return TRUE;
+}
+
+STATIC
+VOID
+EFIAPI
+HiKeyCreateFdtVariable (
+  IN CHAR16          *FdtPathText
+  )
+{
+  UINTN                     FdtDevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL *FdtDevicePath;
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DevicePathFromTextProtocol;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiDevicePathFromTextProtocolGuid,
+                  NULL,
+                  (VOID**)&DevicePathFromTextProtocol
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  FdtDevicePath = DevicePathFromTextProtocol->ConvertTextToDevicePath (FdtPathText);
+  ASSERT (FdtDevicePath != NULL);
+
+  FdtDevicePathSize = GetDevicePathSize (FdtDevicePath);
+  Status = gRT->SetVariable (
+                  (CHAR16*)L"Fdt",
+                  &gArmGlobalVariableGuid,
+                  EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                  FdtDevicePathSize,
+                  FdtDevicePath
+                  );
+  ASSERT_EFI_ERROR(Status);
+}
+
+STATIC
+VOID
+EFIAPI
+HiKeyOnEndOfDxe (
+  EFI_EVENT                               Event,
+  VOID                                    *Context
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               VariableSize;
+  UINT16              AutoBoot, Count, Index;
+  CHAR16              BootDevice[BOOT_DEVICE_LENGTH];
+
+  VariableSize = sizeof (UINT16);
+  Status = gRT->GetVariable (
+                  (CHAR16 *)L"HiKeyAutoBoot",
+                  &gArmGlobalVariableGuid,
+                  NULL,
+                  &VariableSize,
+                  (VOID*)&AutoBoot
+                  );
+  if (Status == EFI_NOT_FOUND) {
+    AutoBoot = 1;
+    Status = gRT->SetVariable (
+                    (CHAR16*)L"HiKeyAutoBoot",
+                    &gArmGlobalVariableGuid,
+                    EFI_VARIABLE_NON_VOLATILE       |
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                    EFI_VARIABLE_RUNTIME_ACCESS,
+                    sizeof (UINT16),
+                    &AutoBoot
+                    );
+    ASSERT_EFI_ERROR (Status);
+  } else if (EFI_ERROR (Status) == 0) {
+    if (AutoBoot == 0) {
+      // Select boot entry by manual.
+      // Delete the BootNext environment variable
+      gRT->SetVariable (L"BootNext",
+             &gEfiGlobalVariableGuid,
+             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+             0,
+             NULL);
+      return;
+    }
+  }
+
+  Count = sizeof (Entries) / sizeof (struct HiKeyBootEntry);
+
+  mBootCount = 0;
+  mBootOrder = NULL;
+
+  for (Index = 0; Index < Count; Index++) {
+    Status = HiKeyCreateBootEntry (
+               Entries[Index].Path,
+               Entries[Index].Args,
+               Entries[Index].Description,
+               Entries[Index].LoadType
+               );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  if ((mBootCount == 0) || (mBootCount >= MAX_BOOT_ENTRIES)) {
+    DEBUG ((EFI_D_ERROR, "%a: can't create boot entries\n", __func__));
+    return;
+  }
+
+  Status = HiKeyCreateBootOrder ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set BootOrder variable\n", __func__));
+    return;
+  }
+
+  HiKeyDetectJumper ();
+
+  // Check boot device.
+  // If boot device is eMMC, it's always higher priority.
+  // If boot device is SD card, SD card is higher priority.
+  //    If SD card is present, boot SD. Otherwise, still boot eMMC.
+  VariableSize = BOOT_DEVICE_LENGTH * sizeof (UINT16);
+  Status = gRT->GetVariable (
+                  (CHAR16 *)L"HiKeyBootDevice",
+                  &gArmGlobalVariableGuid,
+                  NULL,
+                  &VariableSize,
+                  &BootDevice
+                  );
+  if (EFI_ERROR (Status) == 0) {
+    if (StrnCmp (BootDevice, L"emmc", StrLen (L"emmc")) == 0) {
+      if (mBootIndex > 0) {
+        mBootIndex = HIKEY_BOOT_ENTRY_BOOT_EMMC;
+      }
+    } else if (StrnCmp (BootDevice, L"sd", StrLen (L"sd")) == 0) {
+      if (mBootIndex > 0) {
+         // If SD card is present, boot from SD card directly.
+         if (HiKeySDCardIsPresent () == TRUE) {
+           mBootIndex = HIKEY_BOOT_ENTRY_BOOT_SD;
+         } else {
+           mBootIndex = HIKEY_BOOT_ENTRY_BOOT_EMMC;
+         }
+      }
+    } else {
+      DEBUG ((EFI_D_ERROR, "%a: invalid boot device (%a) is specified\n", __func__, BootDevice));
+      mBootIndex = HIKEY_BOOT_ENTRY_BOOT_EMMC;
+    }
+  } else {
+    DEBUG ((EFI_D_ERROR, "failed to get HiKeyBootDevice variable, %r\n", Status));
+  }
+
+  // Fdt variable should be aligned with Image path.
+  // In another word, Fdt and Image file should be located in the same path.
+  // Since grub is used for eMMC boot, don't need to assign Fdt and Image path.
+  switch (mBootIndex) {
+  case HIKEY_BOOT_ENTRY_BOOT_SD:
+    HiKeyCreateFdtVariable (L"VenHw(594BFE73-5E18-4F12-8119-19DB8C5FC849)/HD(1,MBR,0x00000000,0x3F,0x21FC0)/hi6220-hikey.dtb");
+    break;
+  }
+
+
+  Status = HiKeyCreateBootNext ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: failed to set BootNext variable\n", __func__));
+    return;
+  }
+}
+
+EFI_STATUS
+HiKeyBootMenuInstall (
+  IN VOID
+  )
+{
+  EFI_STATUS          Status;
+  EFI_EVENT           EndOfDxeEvent;
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  HiKeyOnEndOfDxe,
+                  &mIsEndOfDxeEvent,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastboot.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastboot.c
new file mode 100644
index 0000000..834aa4d
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastboot.c
@@ -0,0 +1,752 @@
+/** @file

+

+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>

+  Copyright (c) 2015, Linaro Ltd. All rights reserved.

+  Copyright (c) 2015, Hisilicon Ltd. 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 HiKey platform.

+*/

+

+#include <Protocol/AndroidFastbootPlatform.h>

+#include <Protocol/BlockIo.h>

+#include <Protocol/DiskIo.h>

+#include <Protocol/SimpleTextOut.h>

+

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/PrintLib.h>

+

+#include <Guid/ArmGlobalVariableHob.h>

+

+#define FLASH_DEVICE_PATH_SIZE(DevPath) ( GetDevicePathSize (DevPath) - \

+                                            sizeof (EFI_DEVICE_PATH_PROTOCOL))

+

+#define PARTITION_NAME_MAX_LENGTH 72/2

+

+#define IS_ALPHA(Char) (((Char) <= L'z' && (Char) >= L'a') || \

+                        ((Char) <= L'Z' && (Char) >= L'Z'))

+#define IS_HEXCHAR(Char) (((Char) <= L'9' && (Char) >= L'0') || \

+                          IS_ALPHA(Char))

+

+#define SERIAL_NUMBER_LENGTH      16

+#define BOOT_DEVICE_LENGTH        16

+

+typedef struct _FASTBOOT_PARTITION_LIST {

+  LIST_ENTRY  Link;

+  CHAR16      PartitionName[PARTITION_NAME_MAX_LENGTH];

+  EFI_HANDLE  PartitionHandle;

+} FASTBOOT_PARTITION_LIST;

+

+STATIC LIST_ENTRY mPartitionListHead;

+

+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

+  )

+{

+  UINTN                       EntrySize;

+  UINTN                       NumEntries;

+  UINTN                       BufferSize;

+  UINT32                      MediaId;

+  EFI_PARTITION_TABLE_HEADER *GptHeader;

+  EFI_STATUS                  Status;

+

+  MediaId = BlockIo->Media->MediaId;

+

+  //

+  // Read size of Partition entry and number of entries from GPT header

+  //

+

+  GptHeader = AllocatePool (BlockIo->Media->BlockSize);

+  if (GptHeader == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = BlockIo->ReadBlocks (BlockIo, MediaId, 1, BlockIo->Media->BlockSize, (VOID *) GptHeader);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  // Check there is a GPT on the media

+  if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID ||

+      GptHeader->MyLBA != 1) {

+    DEBUG ((EFI_D_ERROR,

+      "Fastboot platform: No GPT on flash. "

+      "Fastboot on Versatile Express does not support MBR.\n"

+      ));

+    return EFI_DEVICE_ERROR;

+  }

+

+  EntrySize = GptHeader->SizeOfPartitionEntry;

+  NumEntries = GptHeader->NumberOfPartitionEntries;

+

+  FreePool (GptHeader);

+

+  ASSERT (EntrySize != 0);

+  ASSERT (NumEntries != 0);

+

+  BufferSize = ALIGN_VALUE (EntrySize * NumEntries, BlockIo->Media->BlockSize);

+  *PartitionEntries = AllocatePool (BufferSize);

+  if (PartitionEntries == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  Status = BlockIo->ReadBlocks (BlockIo, MediaId, 2, BufferSize, (VOID *) *PartitionEntries);

+  if (EFI_ERROR (Status)) {

+    FreePool (PartitionEntries);

+    return Status;

+  }

+

+  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

+  HiKeyFastbootPlatformFlashPartition.

+*/

+EFI_STATUS

+HiKeyFastbootPlatformInit (

+  VOID

+  )

+{

+  EFI_STATUS                          Status;

+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePathDup;

+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL           *NextNode;

+  HARDDRIVE_DEVICE_PATH              *PartitionNode;

+  UINTN                               NumHandles;

+  EFI_HANDLE                         *AllHandles;

+  UINTN                               LoopIndex;

+  EFI_HANDLE                          FlashHandle;

+  EFI_BLOCK_IO_PROTOCOL              *FlashBlockIo;

+  EFI_PARTITION_ENTRY                *PartitionEntries;

+  FASTBOOT_PARTITION_LIST            *Entry;

+

+  InitializeListHead (&mPartitionListHead);

+

+  Status = gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (VOID **) &mTextOut);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_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));

+

+  //

+  // Open the Disk IO protocol on the flash device - this will be used to read

+  // partition names out of the GPT entries

+  //

+  // Create another device path pointer because LocateDevicePath will modify it.

+  FlashDevicePathDup = FlashDevicePath;

+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &FlashHandle);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_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 (

+                  FlashHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &FlashBlockIo,

+                  gImageHandle,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_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 (FlashBlockIo, &PartitionEntries);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_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;

+  }

+

+  // Get every Block IO protocol instance installed in the system

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiBlockIoProtocolGuid,

+                  NULL,

+                  &NumHandles,

+                  &AllHandles

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  // Filter out handles that aren't children of the flash device

+  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {

+    // Get the device path for the handle

+    Status = gBS->OpenProtocol (

+                    AllHandles[LoopIndex],

+                    &gEfiDevicePathProtocolGuid,

+                    (VOID **) &DevicePath,

+                    gImageHandle,

+                    NULL,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    ASSERT_EFI_ERROR (Status);

+

+    // Check if it is a sub-device of the flash device

+    if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (FlashDevicePath))) {

+      // Device path starts with path of flash device. Check it isn't the flash

+      // device itself.

+      NextNode = NextDevicePathNode (DevicePath);

+      if (IsDevicePathEndType (NextNode)) {

+        // Create entry

+        Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));

+        if (Entry == NULL) {

+          Status = EFI_OUT_OF_RESOURCES;

+          FreePartitionList ();

+          goto Exit;

+        }

+

+        // Copy handle and partition name

+        Entry->PartitionHandle = AllHandles[LoopIndex];

+        StrCpy (Entry->PartitionName, L"ptable");

+        InsertTailList (&mPartitionListHead, &Entry->Link);

+        continue;

+      }

+

+      // Assert that this device path node represents a partition.

+      ASSERT (NextNode->Type == MEDIA_DEVICE_PATH &&

+              NextNode->SubType == MEDIA_HARDDRIVE_DP);

+

+      PartitionNode = (HARDDRIVE_DEVICE_PATH *) NextNode;

+

+      // Assert that the partition type is GPT. ReadPartitionEntries checks for

+      // presence of a GPT, so we should never find MBR partitions.

+      // ("MBRType" is a misnomer - this field is actually called "Partition

+      //  Format")

+      ASSERT (PartitionNode->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER);

+

+      // The firmware may install a handle for "partition 0", representing the

+      // whole device. Ignore it.

+      if (PartitionNode->PartitionNumber == 0) {

+        continue;

+      }

+

+      //

+      // Add the partition handle to the list

+      //

+

+      // Create entry

+      Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));

+      if (Entry == NULL) {

+        Status = EFI_OUT_OF_RESOURCES;

+        FreePartitionList ();

+        goto Exit;

+      }

+

+      // Copy handle and partition name

+      Entry->PartitionHandle = AllHandles[LoopIndex];

+      StrnCpy (

+        Entry->PartitionName,

+        PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionName, // Partition numbers start from 1.

+        PARTITION_NAME_MAX_LENGTH

+        );

+      InsertTailList (&mPartitionListHead, &Entry->Link);

+

+      // Print a debug message if the partition label is empty or looks like

+      // garbage.

+      if (!IS_ALPHA (Entry->PartitionName[0])) {

+        DEBUG ((EFI_D_ERROR,

+          "Warning: Partition %d doesn't seem to have a GPT partition label. "

+          "You won't be able to flash it with Fastboot.\n",

+          PartitionNode->PartitionNumber

+          ));

+      }

+    }

+  }

+

+Exit:

+  FreePool (PartitionEntries);

+  FreePool (FlashDevicePath);

+  FreePool (AllHandles);

+  return Status;

+

+}

+

+VOID

+HiKeyFastbootPlatformUnInit (

+  VOID

+  )

+{

+  FreePartitionList ();

+}

+

+EFI_STATUS

+HiKeyFastbootPlatformFlashPartition (

+  IN CHAR8  *PartitionName,

+  IN UINTN   Size,

+  IN VOID   *Image

+  )

+{

+  EFI_STATUS               Status;

+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;

+  EFI_DISK_IO_PROTOCOL    *DiskIo;

+  UINT32                   MediaId;

+  UINTN                    PartitionSize;

+  FASTBOOT_PARTITION_LIST *Entry;

+  CHAR16                   PartitionNameUnicode[60];

+  BOOLEAN                  PartitionFound;

+  SPARSE_HEADER           *SparseHeader;

+  CHUNK_HEADER            *ChunkHeader;

+  UINTN                    Offset = 0;

+  UINT32                   Chunk, EntrySize, EntryOffset;

+  VOID                    *Buffer;

+

+

+  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;

+  }

+

+  Status = gBS->OpenProtocol (

+                  Entry->PartitionHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlockIo,

+                  gImageHandle,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "Fastboot platform: couldn't open Block IO for flash: %r\n", Status));

+    return EFI_NOT_FOUND;

+  }

+

+  SparseHeader=(SPARSE_HEADER *)Image;

+

+  if (SparseHeader->Magic == SPARSE_HEADER_MAGIC) {

+    DEBUG ((EFI_D_INFO, "Sparse Magic: 0x%x Major: %d Minor: %d fhs: %d chs: %d bs: %d tbs: %d tcs: %d checksum: %d \n",

+                SparseHeader->Magic, SparseHeader->MajorVersion, SparseHeader->MinorVersion,  SparseHeader->FileHeaderSize,

+                SparseHeader->ChunkHeaderSize, SparseHeader->BlockSize, SparseHeader->TotalBlocks,

+                SparseHeader->TotalChunks, SparseHeader->ImageChecksum));

+    if (SparseHeader->MajorVersion != 1) {

+        DEBUG ((EFI_D_ERROR, "Sparse image version %d.%d not supported.\n",

+                    SparseHeader->MajorVersion, SparseHeader->MinorVersion));

+        return EFI_INVALID_PARAMETER;

+    }

+

+    Size = SparseHeader->BlockSize * SparseHeader->TotalBlocks;

+  }

+

+  // Check image will fit on device

+  PartitionSize = (BlockIo->Media->LastBlock + 1) * BlockIo->Media->BlockSize;

+  if (PartitionSize < Size) {

+    DEBUG ((EFI_D_ERROR, "Partition not big enough.\n"));

+    DEBUG ((EFI_D_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size));

+

+    return EFI_VOLUME_FULL;

+  }

+

+  MediaId = BlockIo->Media->MediaId;

+

+  Status = gBS->OpenProtocol (

+                  Entry->PartitionHandle,

+                  &gEfiDiskIoProtocolGuid,

+                  (VOID **) &DiskIo,

+                  gImageHandle,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  if (SparseHeader->Magic == SPARSE_HEADER_MAGIC) {

+    CHAR16 OutputString[64];

+    UINTN ChunkPrintDensity =

+        SparseHeader->TotalChunks > 1600 ? SparseHeader->TotalChunks / 200 : 32;

+

+    Image += SparseHeader->FileHeaderSize;

+    for (Chunk = 0; Chunk < SparseHeader->TotalChunks; Chunk++) {

+      UINTN WriteSize;

+      ChunkHeader = (CHUNK_HEADER *)Image;

+

+      // Show progress. Don't do it for every packet as outputting text

+      // might be time consuming. ChunkPrintDensity is calculated to

+      // provide an update every half percent change for large

+      // downloads.

+      if (Chunk % ChunkPrintDensity == 0) {

+        UnicodeSPrint(OutputString, sizeof(OutputString),

+                      L"\r%5d / %5d chunks written (%d%%)", Chunk,

+                      SparseHeader->TotalChunks,

+                     (Chunk * 100) / SparseHeader->TotalChunks);

+        mTextOut->OutputString(mTextOut, OutputString);

+      }

+

+      DEBUG ((EFI_D_INFO, "Chunk #%d - Type: 0x%x Size: %d TotalSize: %d Offset %d\n",

+                  (Chunk+1), ChunkHeader->ChunkType, ChunkHeader->ChunkSize,

+                  ChunkHeader->TotalSize, Offset));

+      Image += sizeof(CHUNK_HEADER);

+      WriteSize=(SparseHeader->BlockSize) * ChunkHeader->ChunkSize;

+      switch (ChunkHeader->ChunkType) {

+        case CHUNK_TYPE_RAW:

+          DEBUG ((EFI_D_INFO, "Writing %d at Offset %d\n", WriteSize, Offset));

+          Status = DiskIo->WriteDisk (DiskIo, MediaId, Offset, WriteSize, Image);

+          if (EFI_ERROR (Status)) {

+            return Status;

+          }

+          Image+=WriteSize;

+          break;

+        case CHUNK_TYPE_DONT_CARE:

+          break;

+        case CHUNK_TYPE_CRC32:

+          break;

+        default:

+          DEBUG ((EFI_D_ERROR, "Unknown Chunk Type: 0x%x", ChunkHeader->ChunkType));

+          return EFI_PROTOCOL_ERROR;

+      }

+      Offset += WriteSize;

+    }

+

+    UnicodeSPrint(OutputString, sizeof(OutputString),

+                  L"\r%5d / %5d chunks written (100%%)\r\n",

+                  SparseHeader->TotalChunks, SparseHeader->TotalChunks);

+    mTextOut->OutputString(mTextOut, OutputString);

+  } else {

+    if (AsciiStrCmp (PartitionName, "ptable") == 0) {

+      Buffer = Image;

+      if (AsciiStrnCmp (Buffer, "ENTRYHDR", 8) != 0) {

+        DEBUG ((EFI_D_ERROR, "unknown ptable image\n"));

+        return EFI_UNSUPPORTED;

+      }

+      Buffer += 8;

+      if (AsciiStrnCmp (Buffer, "primary", 7) != 0) {

+        DEBUG ((EFI_D_ERROR, "unknown ptable image\n"));

+        return EFI_UNSUPPORTED;

+      }

+      Buffer += 8;

+      EntryOffset = *(UINT32 *)Buffer * BlockIo->Media->BlockSize;

+      Buffer += 4;

+      EntrySize = *(UINT32 *)Buffer * BlockIo->Media->BlockSize;

+      if ((EntrySize + 512) > Size) {

+        DEBUG ((EFI_D_ERROR, "Entry size doesn't match\n"));

+        return EFI_UNSUPPORTED;

+      }

+      Buffer = Image + 512;

+      Status = DiskIo->WriteDisk (DiskIo, MediaId, EntryOffset, EntrySize, Buffer);

+      if (EFI_ERROR (Status)) {

+        return Status;

+      }

+

+      Buffer = Image + 16 + 12;

+      if (AsciiStrnCmp (Buffer, "ENTRYHDR", 8) != 0)

+        return Status;

+      Buffer += 8;

+      if (AsciiStrnCmp (Buffer, "second", 6) != 0)

+        return Status;

+      Buffer += 8;

+      EntryOffset = *(UINT32 *)Buffer * BlockIo->Media->BlockSize;

+      Buffer += 4;

+      EntrySize = *(UINT32 *)Buffer * BlockIo->Media->BlockSize;

+      if ((EntrySize + 512) > Size) {

+        DEBUG ((EFI_D_ERROR, "Entry size doesn't match\n"));

+        return EFI_UNSUPPORTED;

+      }

+      Buffer = Image + 512;

+      Status = DiskIo->WriteDisk (DiskIo, MediaId, EntryOffset, EntrySize, Buffer);

+    } else {

+      Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image);

+    }

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+  }

+

+  BlockIo->FlushBlocks(BlockIo);

+

+  return Status;

+}

+

+EFI_STATUS

+HiKeyFastbootPlatformErasePartition (

+  IN CHAR8 *PartitionName

+  )

+{

+  EFI_STATUS               Status;

+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;

+  EFI_DISK_IO_PROTOCOL    *DiskIo;

+  UINT32                   MediaId;

+  UINT64                   Offset;

+  UINTN                    PartitionSize;

+  FASTBOOT_PARTITION_LIST *Entry;

+  CHAR16                   PartitionNameUnicode[60];

+  BOOLEAN                  PartitionFound;

+  CHAR8                    Buffer[EFI_PAGE_SIZE];

+

+  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;

+  }

+

+  Status = gBS->OpenProtocol (

+                  Entry->PartitionHandle,

+                  &gEfiBlockIoProtocolGuid,

+                  (VOID **) &BlockIo,

+                  gImageHandle,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "Fastboot platform: couldn't open Block IO for flash: %r\n", Status));

+    return EFI_NOT_FOUND;

+  }

+

+  MediaId = BlockIo->Media->MediaId;

+

+  Status = gBS->OpenProtocol (

+                  Entry->PartitionHandle,

+                  &gEfiDiskIoProtocolGuid,

+                  (VOID **) &DiskIo,

+                  gImageHandle,

+                  NULL,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  PartitionSize = (BlockIo->Media->LastBlock + 1) * BlockIo->Media->BlockSize;

+  if (AsciiStrnCmp (PartitionName, "ptable", 6) == 0) {

+    // partition table (GPT) cost 34 blocks

+    PartitionSize = 34 * BlockIo->Media->BlockSize;

+  }

+

+  SetMem (Buffer, EFI_PAGE_SIZE, 0xff);

+  for (Offset = 0; Offset < PartitionSize; Offset += BlockIo->Media->BlockSize) {

+    Status = DiskIo->WriteDisk (DiskIo, MediaId, Offset, BlockIo->Media->BlockSize, (VOID *)&Buffer);

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_ERROR, "%a: Fail to erase at address 0x%x\n", __func__, Offset));

+      return Status;

+    }

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+HiKeyFastbootPlatformGetVar (

+  IN  CHAR8   *Name,

+  OUT CHAR8   *Value

+  )

+{

+  if (!AsciiStrCmp (Name, "max-download-size")) {

+    AsciiStrCpy (Value, FixedPcdGetPtr (PcdArmFastbootFlashLimit));

+  } else if (AsciiStrCmp (Name, "product")) {

+    AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));

+  } else {

+    *Value = '\0';

+  }

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+HiKeyFastbootPlatformOemCommand (

+  IN  CHAR8   *Command

+  )

+{

+  CHAR16     CommandUnicode[65];

+  CHAR16     BootDevice[BOOT_DEVICE_LENGTH];

+  UINTN      Index = 0, VariableSize;

+  UINT16     AutoBoot, Data;

+  EFI_STATUS Status;

+

+  if (AsciiStrCmp (Command, "Demonstrate") == 0) {

+    DEBUG ((EFI_D_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));

+    return EFI_SUCCESS;

+  } else if (AsciiStrnCmp (Command, "autoboot", AsciiStrLen ("autoboot")) == 0) {

+    Index += sizeof ("autoboot");

+    while (TRUE) {

+      if (Command[Index] == '\0')

+        goto out;

+      else if (Command[Index] == ' ')

+        Index++;

+      else

+        break;

+    }

+    Data = AsciiStrDecimalToUintn (Command + Index);

+

+    VariableSize = sizeof (UINT16);

+    Status = gRT->GetVariable (

+                    (CHAR16 *)L"HiKeyAutoBoot",

+                    &gArmGlobalVariableGuid,

+                    NULL,

+                    &VariableSize,

+                    &AutoBoot

+                    );

+    if ((EFI_ERROR (Status) == 0) && (AutoBoot == Data)) {

+      return EFI_SUCCESS;

+    }

+    AutoBoot = Data;

+    Status = gRT->SetVariable (

+                    (CHAR16*)L"HiKeyAutoBoot",

+                    &gArmGlobalVariableGuid,

+                    EFI_VARIABLE_NON_VOLATILE       |

+                    EFI_VARIABLE_BOOTSERVICE_ACCESS |

+                    EFI_VARIABLE_RUNTIME_ACCESS,

+                    sizeof (UINT16),

+                    &AutoBoot

+                    );

+    return Status;

+  } else if (AsciiStrnCmp (Command, "bootdevice", AsciiStrLen ("bootdevice")) == 0) {

+    Index += sizeof ("bootdevice");

+    while (TRUE) {

+      if (Command[Index] == '\0')

+        goto out;

+      else if (Command[Index] == ' ')

+        Index++;

+      else

+        break;

+    }

+    AsciiStrToUnicodeStr (Command + Index, CommandUnicode);

+    for (Index = 0; Index < BOOT_DEVICE_LENGTH; Index++) {

+      if (IS_ALPHA (CommandUnicode[Index]) == 0)

+        break;

+    }

+    if ((Index == 0) || (Index > BOOT_DEVICE_LENGTH)) {

+      DEBUG ((EFI_D_ERROR,

+        "HiKey: Invalid Fastboot OEM bootdevice command: %s\n",

+        CommandUnicode

+        ));

+      return EFI_NOT_FOUND;

+    }

+

+    VariableSize = BOOT_DEVICE_LENGTH * sizeof (UINT16);

+    Status = gRT->GetVariable (

+                    (CHAR16 *)L"HiKeyBootDevice",

+                    &gArmGlobalVariableGuid,

+                    NULL,

+                    &VariableSize,

+                    &BootDevice

+                    );

+    if (EFI_ERROR (Status) == 0) {

+      Status = gRT->SetVariable (

+                      (CHAR16*)L"HiKeyBootDevice",

+                      &gArmGlobalVariableGuid,

+                      EFI_VARIABLE_NON_VOLATILE       |

+                      EFI_VARIABLE_BOOTSERVICE_ACCESS |

+                      EFI_VARIABLE_RUNTIME_ACCESS,

+                      VariableSize,

+                      CommandUnicode

+                      );

+    }

+    return Status;

+  } else {

+    AsciiStrToUnicodeStr (Command + Index, CommandUnicode);

+    DEBUG ((EFI_D_ERROR,

+      "HiKey: Unrecognised Fastboot OEM command: %s\n",

+      CommandUnicode

+      ));

+    return EFI_NOT_FOUND;

+  }

+out:

+  return EFI_NOT_FOUND;

+}

+

+FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = {

+  HiKeyFastbootPlatformInit,

+  HiKeyFastbootPlatformUnInit,

+  HiKeyFastbootPlatformFlashPartition,

+  HiKeyFastbootPlatformErasePartition,

+  HiKeyFastbootPlatformGetVar,

+  HiKeyFastbootPlatformOemCommand

+};

+

+EFI_STATUS

+EFIAPI

+HiKeyFastbootPlatformEntryPoint (

+  IN EFI_HANDLE                            ImageHandle,

+  IN EFI_SYSTEM_TABLE                      *SystemTable

+  )

+{

+  return gBS->InstallProtocolInterface (

+                &ImageHandle,

+                &gAndroidFastbootPlatformProtocolGuid,

+                EFI_NATIVE_INTERFACE,

+                &mPlatformProtocol

+                );

+}

diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastbootDxe.inf b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
new file mode 100644
index 0000000..84e6d89
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
@@ -0,0 +1,60 @@
+#/** @file

+#

+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>

+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.

+#  Copyright (c) 2015, Hisilicon Ltd. 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                    = 0x00010005

+  BASE_NAME                      = HiKeyFastbootDxe

+  FILE_GUID                      = 8e335c38-c4e1-494e-8011-37a858d9763d

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = HiKeyFastbootPlatformEntryPoint

+

+[Sources.common]

+  HiKeyFastboot.c

+

+[LibraryClasses]

+  BaseLib

+  BaseMemoryLib

+  DebugLib

+  DevicePathLib

+  MemoryAllocationLib

+  PcdLib

+  UefiBootServicesTableLib

+  UefiRuntimeServicesTableLib

+  UefiDriverEntryPoint

+

+[Protocols]

+  gAndroidFastbootPlatformProtocolGuid

+  gEfiBlockIoProtocolGuid

+  gEfiDiskIoProtocolGuid

+  gEfiSimpleTextOutProtocolGuid

+

+[Packages]

+  EmbeddedPkg/EmbeddedPkg.dec

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec

+  ArmPkg/ArmPkg.dec

+  HisiPkg/HisiPlatformPkg.dec

+

+[Guids]

+  gArmGlobalVariableGuid

+

+[Pcd]

+  gArmPlatformTokenSpaceGuid.PcdFirmwareVendor

+  gHwTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath

+  gHwTokenSpaceGuid.PcdArmFastbootFlashLimit

diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.c
new file mode 100644
index 0000000..fd2c956
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.c
@@ -0,0 +1,69 @@
+/** @file
+*
+*  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Ltd. 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/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedGpio.h>
+
+GPIO_CONTROLLER gGpioDevice[]= {
+  { 0xf8011000, 0, 8 },    // GPIO0
+  { 0xf8012000, 8, 8 },    // GPIO1
+  { 0xf8013000, 16, 8 },   // GPIO2
+  { 0xf8014000, 24, 8 },   // GPIO3
+  { 0xf7020000, 32, 8 },   // GPIO4
+  { 0xf7021000, 40, 8 },   // GPIO5
+  { 0xf7022000, 48, 8 },   // GPIO6
+  { 0xf7023000, 56, 8 },   // GPIO7
+  { 0xf7024000, 64, 8 },   // GPIO8
+  { 0xf7025000, 72, 8 },   // GPIO9
+  { 0xf7026000, 80, 8 },   // GPIO10
+  { 0xf7027000, 88, 8 },   // GPIO11
+  { 0xf7028000, 96, 8 },   // GPIO12
+  { 0xf7029000, 104, 8 },  // GPIO13
+  { 0xf702a000, 112, 8 },  // GPIO14
+  { 0xf702b000, 120, 8 },  // GPIO15
+  { 0xf702c000, 128, 8 },  // GPIO16
+  { 0xf702d000, 136, 8 },  // GPIO17
+  { 0xf702e000, 144, 8 },  // GPIO18
+  { 0xf702f000, 152, 8 }   // GPIO19
+};
+
+PLATFORM_GPIO_CONTROLLER gPlatformGpioDevice = {
+  160, 20, gGpioDevice
+};
+
+EFI_STATUS
+EFIAPI
+HiKeyGpioEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  Handle;
+
+  // Install the Embedded Platform GPIO Protocol onto a new handle
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces(
+                  &Handle,
+                  &gPlatformGpioProtocolGuid, &gPlatformGpioDevice,
+                  NULL
+                 );
+  if (EFI_ERROR(Status)) {
+    Status = EFI_OUT_OF_RESOURCES;
+  }
+
+  return Status;
+}
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.inf b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.inf
new file mode 100644
index 0000000..2418d19
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.inf
@@ -0,0 +1,38 @@
+#
+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.
+#  Copyright (c) 2015, Hisilicon Ltd. 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                    = 0x00010005
+  BASE_NAME                      = HiKeyGpio
+  FILE_GUID                      = b51a851c-7bf7-463f-b261-cfb158b7f699
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = HiKeyGpioEntryPoint
+
+[Sources.common]
+  HiKeyGpio.c
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  HisiPkg/HisiPlatformPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gPlatformGpioProtocolGuid
+
+[Depex]
+  BEFORE gArmPL061GpioGuid
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/HiKey.dsc b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/HiKey.dsc
new file mode 100644
index 0000000..b396148
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/HiKey.dsc
@@ -0,0 +1,442 @@
+#
+#  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+#  Copyright (c) 2014-2015, Hisilicon 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 Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = HiKey
+  PLATFORM_GUID                  = bca6cb88-e039-4ee8-8e4e-b781773f4fb6
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/HiKey
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = HisiPkg/HiKeyPkg/HiKey.fdf
+
+[LibraryClasses.common]
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+  ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+
+  ArmPlatformLib|HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+
+  BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+
+  PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+  SerialPortExtLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortExtLib.inf
+  RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+
+  #
+  # Assume everything is fixed at build
+  #
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+
+  # USB Requirements
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+  UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+
+[LibraryClasses.AARCH64]
+  ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+
+[LibraryClasses.common.SEC]
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+  LzmaDecompressLib|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
+  MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[BuildOptions]
+  GCC:*_*_*_PLATFORM_FLAGS == -I$(WORKSPACE)/MdeModulePkg/Include -I$(WORKSPACE)/HisiPkg/HiKeyPkg/Include -I$(WORKSPACE)/HisiPkg/Include/Platform
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+  #
+  # Control what commands are supported from the UI
+  # Turn these on and off to add features or save size
+  #
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|TRUE
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd|TRUE
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd|TRUE
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd|TRUE
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable|FALSE
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable|TRUE
+
+  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
+  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE
+
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+  # DEBUG_ASSERT_ENABLED       0x01
+  # DEBUG_PRINT_ENABLED        0x02
+  # DEBUG_CODE_ENABLED         0x04
+  # CLEAR_MEMORY_ENABLED       0x08
+  # ASSERT_BREAKPOINT_ENABLED  0x10
+  # ASSERT_DEADLOOP_ENABLED    0x20
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+!endif
+
+  #  DEBUG_INIT      0x00000001  // Initialization
+  #  DEBUG_WARN      0x00000002  // Warnings
+  #  DEBUG_LOAD      0x00000004  // Load events
+  #  DEBUG_FS        0x00000008  // EFI File system
+  #  DEBUG_POOL      0x00000010  // Alloc & Free's
+  #  DEBUG_PAGE      0x00000020  // Alloc & Free's
+  #  DEBUG_INFO      0x00000040  // Verbose
+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE Dispatchers
+  #  DEBUG_VARIABLE  0x00000100  // Variable
+  #  DEBUG_BM        0x00000400  // Boot Manager
+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  #  DEBUG_NET       0x00004000  // SNI Driver
+  #  DEBUG_UNDI      0x00010000  // UNDI Driver
+  #  DEBUG_LOADFILE  0x00020000  // UNDI Driver
+  #  DEBUG_EVENT     0x00080000  // Event messages
+  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  #  DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+  #
+  # Optional feature to help prevent EFI memory map fragments
+  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+  # Values are in EFI Pages (4K). DXE Core will make sure that
+  # at least this much of each type of memory can be allocated
+  # from a single memory range. This way you only end up with
+  # maximum of two fragements for each type in the memory map
+  # (the memory used, and the free memory that was prereserved
+  # but not used).
+  #
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|65
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|""
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000
+
+  gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"Linaro HiKey"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"PreAlpha"
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"HiKey"
+
+  #
+  # NV Storage PCDs.
+  #
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockCount|0x00001000
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockSize|0x00000200
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockLba|0x00006000
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockDevicePath|L"VenHw(B549F005-4BD4-4020-A0CB-06F42BDA68C3)/HD(5,GPT,00354BCD-BBCB-4CB3-B5AE-CDEFCB5DAC43)"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x30000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00010000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x30010000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00010000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x30020000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00010000
+
+  # System Memory (1GB)
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00000000
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x3E000000
+
+  # HiKey Dual-Cluster profile
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|8
+  gArmPlatformTokenSpaceGuid.PcdClusterCount|2
+
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+  #
+  # ARM Pcds
+  #
+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000000000000
+
+  #
+  # ARM PrimeCell
+  #
+
+  ## PL011 - Serial Terminal
+  DEFINE SERIAL_BASE = 0xF7113000 # UART3
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|$(SERIAL_BASE)
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+  gArmPlatformTokenSpaceGuid.PL011UartInteger|10
+  gArmPlatformTokenSpaceGuid.PL011UartFractional|26
+
+  ## PL031 RealTimeClock
+  gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0xF8003000
+
+  #
+  # ARM General Interrupt Controller
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0xF6801000
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xF6802000
+
+  #
+  # ARM OS Loader
+  #
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux from eMMC"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(B549F005-4BD4-4020-A0CB-06F42BDA68C3)/HD(6,GPT,5C0F213C-17E1-4149-88C8-8B50FB4EC70E,0x7000,0x20000)/Image"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(B549F005-4BD4-4020-A0CB-06F42BDA68C3)/HD(6,GPT,5C0F213C-17E1-4149-88C8-8B50FB4EC70E,0x7000,0x20000)/initrd.img"
+  gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(B549F005-4BD4-4020-A0CB-06F42BDA68C3)/HD(6,GPT,5C0F213C-17E1-4149-88C8-8B50FB4EC70E,0x7000,0x20000)/hi6220-hikey.dtb"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|L"dtb=hi6220-hikey.dtb console=ttyAMA3,115200 earlycon=pl011,0xf7113000 root=/dev/disk/by-partlabel/system rw rootwait efi=noruntime"
+  gArmPlatformTokenSpaceGuid.PcdDefaultBootType|0
+
+  # Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)
+  gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi();VenHw(CE660500-824D-11E0-AC72-0002A5D5C51B)"
+  gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
+  gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut|10
+
+  # RunAxf support via Dynamic Shell Command protocol
+  # We want to use the Shell Libraries but don't want it to initialise
+  # automatically. We initialise the libraries when the command is called by the
+  # Shell.
+  gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+
+  #
+  # ARM Architectural Timer Frequency
+  #
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|1200000
+  gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod|10000
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod|10000 # expressed in 100ns units, 10,000 x 100 ns = 1,000,000 ns = 1 ms
+
+  #
+  # DW MMC/SD card controller
+  #
+  gEmbeddedTokenSpaceGuid.PcdDwMmcBaseAddress|0xF723D000
+  gEmbeddedTokenSpaceGuid.PcdDwMmcClockFrequencyInHz|100000000
+  gHwTokenSpaceGuid.PcdDwSdBaseAddress|0xF723E000
+  gHwTokenSpaceGuid.PcdDwSdClockFrequencyInHz|24000000
+
+  #
+  # usb controller
+  #
+  gEmbeddedTokenSpaceGuid.PcdDwUsbBaseAddress|0xF72c0000
+  gEmbeddedTokenSpaceGuid.PcdSysCtrlBaseAddress|0xF7030000
+
+  gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbVendorId|0x18d1
+  gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xd00d
+
+  # Device path of block device on which Android Fastboot should flash partitions
+  gHwTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L"VenHw(b549f005-4bd4-4020-a0cb-06f42bda68c3)"
+  # Flash limit 500M/time, for memory concern
+  gHwTokenSpaceGuid.PcdArmFastbootFlashLimit|"524288000"
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+  #
+  # PEI Phase modules
+  #
+  ArmPlatformPkg/PrePi/PeiMPCore.inf {
+    <LibraryClasses>
+      ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
+  }
+
+  #
+  # DXE
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+
+  #
+  # Architectural Protocols
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+  HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # GPIO
+  #
+  ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
+  HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.inf
+
+  #
+  # MMC/SD
+  #
+  EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+  EmbeddedPkg/Drivers/DwMmcDxe/DwMmcDxe.inf
+  HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.inf
+
+  #
+  # USB
+  #
+  EmbeddedPkg/Drivers/DwUsbDxe/DwUsbDxe.inf
+  EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+
+  #
+  # Fastboot
+  #
+  EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
+  HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # HiKey platform driver
+  #
+  HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  ArmPlatformPkg/Bds/Bds.inf
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/HiKey.fdf b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/HiKey.fdf
new file mode 100644
index 0000000..91eb9ba
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/HiKey.fdf
@@ -0,0 +1,329 @@
+#
+#  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+#  Copyright (c) 2014-2015, Hisilicon 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.
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.BL33_AP_UEFI]
+BaseAddress   = 0x35000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
+Size          = 0x000F0000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x00001000
+NumBlocks     = 0xF0
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+0x00000000|0x000F0000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize          = 0x40
+NumBlocks          = 0         # This FV gets compressed so make it just big enough
+FvAlignment        = 8         # FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  INF HisiPkg/Drivers/WatchDogDriver/WatchDogDriver.inf
+
+  #
+  # GPIO
+  #
+  INF ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
+  INF HisiPkg/HiKeyPkg/Drivers/HiKeyGpio/HiKeyGpio.inf
+
+  #
+  # Multimedia Card Interface
+  #
+  INF EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+  INF EmbeddedPkg/Drivers/DwMmcDxe/DwMmcDxe.inf
+  INF HisiPkg/HiKeyPkg/Drivers/DwSdDxe/DwSdDxe.inf
+
+  #
+  # USB
+  #
+  INF EmbeddedPkg/Drivers/DwUsbDxe/DwUsbDxe.inf
+  INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+
+  #
+  # FASTBOOT_PLATFORM_PROTOCOL
+  #
+  INF HisiPkg/HiKeyPkg/Drivers/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  INF FatBinPkg/EnhancedFatDxe/Fat.inf
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  INF HisiPkg/HiKeyPkg/Drivers/BlockVariableDxe/BlockVariableDxe.inf
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # UEFI applications
+  #
+  INF ShellBinPkg/UefiShell/UefiShell.inf
+
+  #
+  # HiKey platform driver
+  #
+  INF HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF ArmPlatformPkg/Bds/Bds.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 8
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF ArmPlatformPkg/PrePi/PeiMPCore.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+#  FILE DRIVER = $(NAMED_GUID) {
+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+#    COMPRESS PI_STD {
+#      GUIDED {
+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+#        UI       STRING="$(MODULE_NAME)" Optional
+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+#      }
+#    }
+#  }
+#
+############################################################################
+
+#
+# These SEC rules are used for ArmPlatformPkg/PrePi module.
+# ArmPlatformPkg/PrePi is declared as a SEC module to make GenFv patch the
+# UEFI Firmware to jump to ArmPlatformPkg/PrePi entrypoint
+#
+[Rule.ARM.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 32                $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.AARCH64.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 4K                $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+# A shim specific rule is required to ensure the alignment is 4K.
+# Otherwise BaseTools pick up the AArch32 alignment (ie: 32)
+[Rule.ARM.SEC.SHIM]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 4K                $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    TE     TE                           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI     STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE       TE                        $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+      UI        STRING="$(MODULE_NAME)" Optional
+    }
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+  DXE_DEPEX    DXE_DEPEX              Optional |.depex
+  PE32         PE32                   |.efi
+  UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI     STRING ="$(MODULE_NAME)" Optional
+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
+
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Include/Hi6220.h b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Include/Hi6220.h
new file mode 100644
index 0000000..d36cae0
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Include/Hi6220.h
@@ -0,0 +1,30 @@
+/** @file
+*
+*  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+*  Copyright (c) 2014-2015, Hisilicon 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.
+*
+**/
+
+#ifndef __HI6220_H__
+#define __HI6220_H__
+
+/***********************************************************************************
+// Platform Memory Map
+************************************************************************************/
+
+// SOC peripherals (UART, I2C, I2S, USB, etc)
+#define HI6220_PERIPH_BASE			0xF4000000
+#define HI6220_PERIPH_SZ			0x05800000
+
+#define MDDRC_AXI_BASE				0xF7120000
+#define AXI_REGION_MAP_OFFSET(x)		(0x100 + (x) * 0x10)
+
+#endif	/* __HI6220_H__ */
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKey.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKey.c
new file mode 100644
index 0000000..8c4bd77
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKey.c
@@ -0,0 +1,160 @@
+/** @file
+*
+*  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+*  Copyright (c) 2014-2015, Hisilicon 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.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+#include <Hi6220.h>
+
+ARM_CORE_INFO mHiKeyInfoTable[] = {
+  {
+    // Cluster 0, Core 0
+    0x0, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 0, Core 1
+    0x0, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 0, Core 2
+    0x0, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 0, Core 3
+    0x0, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 0
+    0x1, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 1
+    0x1, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 2
+    0x1, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  },
+  {
+    // Cluster 1, Core 3
+    0x1, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    (UINT64)0xFFFFFFFF
+  }
+};
+
+/**
+  Return the current Boot Mode
+
+  This function returns the boot reason on the platform
+
+  @return   Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  Initialize controllers that must setup in the normal world
+
+  This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
+  in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+/**
+  Initialize the system (or sometimes called permanent) memory
+
+  This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+  VOID
+  )
+{
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+  OUT UINTN                   *CoreCount,
+  OUT ARM_CORE_INFO           **ArmCoreTable
+  )
+{
+  // Only support one cluster
+  *CoreCount    = sizeof(mHiKeyInfoTable) / sizeof(ARM_CORE_INFO);
+  *ArmCoreTable = mHiKeyInfoTable;
+  return EFI_SUCCESS;
+}
+
+// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
+EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+
+EFI_PEI_PPI_DESCRIPTOR      gPlatformPpiTable[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &mArmMpCoreInfoPpiGuid,
+    &mMpCoreInfoPpi
+  }
+};
+
+VOID
+ArmPlatformGetPlatformPpiList (
+  OUT UINTN                   *PpiListSize,
+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
+  )
+{
+  *PpiListSize = sizeof(gPlatformPpiTable);
+  *PpiList = gPlatformPpiTable;
+}
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyHelper.S b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyHelper.S
new file mode 100644
index 0000000..2657606
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyHelper.S
@@ -0,0 +1,74 @@
+#
+#  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+#  Copyright (c) 2014-2015, Hisilicon 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.
+#
+#
+
+#include <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
+
+
+PrimaryCoreMpid:  .word    0x0
+
+ASM_PFX(ArmPlatformPeiBootAction):
+  // The trusted firmware passes the primary CPU MPID through x0 register.
+  // Save it in a variable.
+  ldr  x1, =PrimaryCoreMpid
+  str  w0, [x1]
+  ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, x1)
+  ldrh  w1, [x1]
+  and   x0, x0, x1
+
+  ldr   x1, =PrimaryCoreMpid
+  ldrh  w1, [x1]
+
+  cmp   w0, w1
+  mov   x0, #1
+  mov   x1, #0
+  csel  x0, x0, x1, eq
+  ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+  ldr   x0, =PrimaryCoreMpid
+  ldrh  w0, [x0]
+  ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+// With this function: CorePos = (ClusterId * 4) + CoreId
+ASM_PFX(ArmPlatformGetCorePosition):
+  and   x1, x0, #ARM_CORE_MASK
+  and   x0, x0, #ARM_CLUSTER_MASK
+  add   x0, x1, x0, LSR #6
+  ret
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyLib.inf b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyLib.inf
new file mode 100644
index 0000000..cad6d97
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyLib.inf
@@ -0,0 +1,52 @@
+#
+#  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+#  Copyright (c) 2014-2015, Hisilicon 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]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = HiKeyLib
+  FILE_GUID                      = 1f6c5192-f35c-462d-877c-8ee3227fff01
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ShellPkg/ShellPkg.dec		## FIXME: Temporary workaround for dependency issue
+
+[LibraryClasses]
+  IoLib
+  ArmLib
+  HobLib
+  MemoryAllocationLib
+  SerialPortLib
+
+[Sources.common]
+  HiKey.c
+  HiKeyMem.c
+
+[Sources.AARCH64]
+  HiKeyHelper.S | GCC
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdCacheEnable
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyMem.c b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyMem.c
new file mode 100644
index 0000000..d7d15b5
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyMem.c
@@ -0,0 +1,189 @@
+/** @file
+*
+*  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+*  Copyright (c) 2014-2015, Hisilicon 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.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Hi6220.h>
+
+// The total number of descriptors, including the final "end-of-table" descriptor.
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 12
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+#define HIKEY_EXTRA_SYSTEM_MEMORY_BASE  0x40000000
+#define HIKEY_EXTRA_SYSTEM_MEMORY_SIZE  0x40000000
+
+STATIC struct HiKeyReservedMemory {
+  EFI_PHYSICAL_ADDRESS         Offset;
+  EFI_PHYSICAL_ADDRESS         Size;
+} HiKeyReservedMemoryBuffer [] = {
+  { 0x05E00000, 0x00100000 },    // MCU
+  { 0x06DFF000, 0x00001000 },    // MAILBOX
+  { 0x0740F000, 0x00001000 },    // MAILBOX
+  { 0x3E000000, 0x02000000 }     // TEE OS
+};
+
+STATIC
+UINT64
+EFIAPI
+HiKeyInitMemorySize (
+  IN VOID
+  )
+{
+  UINT32               Count, Data, MemorySize;
+
+  Count = 0;
+  while (MmioRead32 (MDDRC_AXI_BASE + AXI_REGION_MAP_OFFSET (Count)) != 0) {
+    Count++;
+  }
+  Data = MmioRead32 (MDDRC_AXI_BASE + AXI_REGION_MAP_OFFSET (Count - 1));
+  MemorySize = 16 << ((Data >> 8) & 0x7);
+  MemorySize += Data << 24;
+  return (UINT64) (MemorySize << 20);
+}
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+                                    Virtual Memory mapping. This array must be ended by a zero-filled
+                                    entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+  )
+{
+  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
+  UINTN                         Index = 0, Count, ReservedTop;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+  EFI_PEI_HOB_POINTERS          NextHob;
+  EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
+  UINT64                        ResourceLength;
+  EFI_PHYSICAL_ADDRESS          ResourceTop;
+  UINT64                        MemorySize, AdditionalMemorySize;
+
+  MemorySize = HiKeyInitMemorySize ();
+
+  NextHob.Raw = GetHobList ();
+  Count = sizeof (HiKeyReservedMemoryBuffer) / sizeof (struct HiKeyReservedMemory);
+  while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL)
+  {
+    if (Index >= Count)
+      break;
+    if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+        (HiKeyReservedMemoryBuffer[Index].Offset >= NextHob.ResourceDescriptor->PhysicalStart) &&
+        ((HiKeyReservedMemoryBuffer[Index].Offset + HiKeyReservedMemoryBuffer[Index].Size) <=
+         NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
+    {
+      ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
+      ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
+      ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
+      ReservedTop = HiKeyReservedMemoryBuffer[Index].Offset + HiKeyReservedMemoryBuffer[Index].Size;
+
+      // Create the System Memory HOB for the reserved buffer
+      BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_RESERVED,
+                                  EFI_RESOURCE_ATTRIBUTE_PRESENT,
+                                  HiKeyReservedMemoryBuffer[Index].Offset,
+                                  HiKeyReservedMemoryBuffer[Index].Size);
+      // Update the HOB
+      NextHob.ResourceDescriptor->ResourceLength = HiKeyReservedMemoryBuffer[Index].Offset - NextHob.ResourceDescriptor->PhysicalStart;
+
+      // If there is some memory available on the top of the reserved memory then create a HOB
+      if (ReservedTop < ResourceTop)
+      {
+        BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+                                    ResourceAttributes,
+                                    ReservedTop,
+                                    ResourceTop - ReservedTop);
+      }
+      Index++;
+    }
+    NextHob.Raw = GET_NEXT_HOB (NextHob);
+  }
+
+  AdditionalMemorySize = MemorySize - PcdGet64 (PcdSystemMemorySize);
+  if (AdditionalMemorySize >= SIZE_1GB) {
+    // Declared the additional memory
+    ResourceAttributes =
+        EFI_RESOURCE_ATTRIBUTE_PRESENT |
+        EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+        EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_TESTED;
+
+    BuildResourceDescriptorHob (
+      EFI_RESOURCE_SYSTEM_MEMORY,
+      ResourceAttributes,
+      HIKEY_EXTRA_SYSTEM_MEMORY_BASE,
+      HIKEY_EXTRA_SYSTEM_MEMORY_SIZE);
+  }
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+  if (VirtualMemoryTable == NULL) {
+      return;
+  }
+
+  if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
+      CacheAttributes = DDR_ATTRIBUTES_CACHED;
+  } else {
+      CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
+  }
+
+  Index = 0;
+
+  // Hi6220 SOC peripherals
+  VirtualMemoryTable[Index].PhysicalBase    = HI6220_PERIPH_BASE;
+  VirtualMemoryTable[Index].VirtualBase     = HI6220_PERIPH_BASE;
+  VirtualMemoryTable[Index].Length          = HI6220_PERIPH_SZ;
+  VirtualMemoryTable[Index].Attributes      = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  // DDR - 1GB
+  VirtualMemoryTable[++Index].PhysicalBase  = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase     = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].Length          = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  if (AdditionalMemorySize >= SIZE_1GB) {
+    VirtualMemoryTable[++Index].PhysicalBase = HIKEY_EXTRA_SYSTEM_MEMORY_BASE;
+    VirtualMemoryTable[Index].VirtualBase    = HIKEY_EXTRA_SYSTEM_MEMORY_BASE;
+    VirtualMemoryTable[Index].Length         = HIKEY_EXTRA_SYSTEM_MEMORY_SIZE;
+    VirtualMemoryTable[Index].Attributes     = CacheAttributes;
+  }
+
+  // End of Table
+  VirtualMemoryTable[++Index].PhysicalBase  = 0;
+  VirtualMemoryTable[Index].VirtualBase     = 0;
+  VirtualMemoryTable[Index].Length          = 0;
+  VirtualMemoryTable[Index].Attributes      = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Makefile b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Makefile
new file mode 100644
index 0000000..bf87fd5
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/Makefile
@@ -0,0 +1,90 @@
+#
+#  Copyright (c) 2014-2015, Linaro Limited. All rights reserved.
+#  Copyright (c) 2014-2015, Hisilicon 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.
+#
+
+# Define the following variables to specify an alternative toolchain to the one located in your PATH:
+# - RVCT_TOOLS_PATH: for RVCT and RVCTLINUX toolchains
+# - ARMGCC_TOOLS_PATH: for ARMGCC toolchain
+# - ARMLINUXGCC_TOOLS_PATH: for ARMLINUXGCC
+
+EDK2_TOOLCHAIN ?= GCC48
+GCC48_AARCH64_PREFIX ?= aarch64-linux-gnu-
+EDK2_ARCH ?= AARCH64
+EDK2_BUILD ?= DEBUG
+EDK2_DSC = HisiPkg/HiKeyPkg/HiKey.dsc
+DEST_BIN_ROOT ?=
+
+ifeq ($(EDK2_DSC),"")
+  $(error The Makefile macro 'EDK2_DSC' must be defined with an EDK2 DSC file.)
+endif
+
+ifeq ("$(OS)","Windows_NT")
+export WORKSPACE?=$(PWD)
+export EDK_TOOLS_PATH ?= $(WORKSPACE)\BaseTools
+else
+export WORKSPACE?=$(PWD)
+endif
+
+# Define the destination of the Firmware Image Package (FIP) if not defined
+ifndef HIKEY_FIP
+  ifdef DEST_BIN_ROOT
+    HIKEY_FIP=$(DEST_BIN_ROOT)/fip.bin
+  else
+    HIKEY_FIP=fip.bin
+  endif
+endif
+
+SHELL := /bin/bash
+SILENT ?= @
+ECHO ?= echo
+MAKE ?= make -i -k
+RM ?= rm -f
+CP ?= cp
+
+.PHONY: all clean
+
+EDK2_CONF = Conf/BuildEnv.sh Conf/build_rule.txt Conf/target.txt Conf/tools_def.txt
+
+all: $(EDK2_CONF)
+ifeq ("$(OS)","Windows_NT")
+	build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS)
+else
+	. ./edksetup.sh; GCC47_AARCH64_PREFIX=$(GCC47_AARCH64_PREFIX) build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS)
+endif
+ifeq ("$(OS)","Windows_NT")
+	$(SILENT)$(ECHO) "Warning: The UEFI Firmware must be added to the Firmware Image Package (FIP)."
+else
+	$(SILENT)which fip_create ; \
+	if [ $$? -ne 0 ]; then \
+		$(ECHO) "Warning: 'fip_create' tool is not in the PATH. The UEFI binary will not be added in the Firmware Image Package (FIP)."; \
+	else \
+		fip_create --bl33 $(WORKSPACE)/Build/HiKey/$(EDK2_BUILD)_$(EDK2_TOOLCHAIN)/FV/BL33_AP_UEFI.fd --dump $(HIKEY_FIP); \
+	fi
+endif
+
+$(EDK2_CONF):
+ifeq ("$(OS)","Windows_NT")
+	copy $(EDK_TOOLS_PATH)\Conf\build_rule.template Conf\build_rule.txt
+	copy $(EDK_TOOLS_PATH)\Conf\FrameworkDatabase.template Conf\FrameworkDatabase.txt
+	copy $(EDK_TOOLS_PATH)\Conf\target.template Conf\target.txt
+	copy $(EDK_TOOLS_PATH)\Conf\tools_def.template Conf\tools_def.txt
+else
+	. ./edksetup.sh; $(MAKE) -C BaseTools
+endif
+
+clean:
+ifeq ("$(OS)","Windows_NT")
+	build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS) cleanall
+else
+	. ./edksetup.sh; build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS) cleanall; \
+	rm -Rf $(EDK2_CONF) Conf/.cache
+endif
diff --git a/uefi/linaro-edk2/HisiPkg/HiKeyPkg/NonFree/mcuimage.bin b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/NonFree/mcuimage.bin
new file mode 100644
index 0000000..dcaa786
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HiKeyPkg/NonFree/mcuimage.bin
Binary files differ
diff --git a/uefi/linaro-edk2/HisiPkg/HisiPlatformPkg.dec b/uefi/linaro-edk2/HisiPkg/HisiPlatformPkg.dec
new file mode 100644
index 0000000..af778ab
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/HisiPlatformPkg.dec
@@ -0,0 +1,93 @@
+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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              = 0x00010005

+  PACKAGE_NAME                   = HisiPlatformPkg

+  PACKAGE_GUID                   = c6013a10-758c-4c0d-bd07-e601e6721f86

+  PACKAGE_VERSION                = 0.1

+

+[Includes]              

+  Include

+  Include/Protocol

+  Include/Ppi

+  Include/Library

+  Include/Guid

+  

+[Ppis]

+  

+

+

+[Protocols]

+  gWatchDogProtocolGuid = {0x707ac059, 0xf335, 0x4643, 0xa6, 0x99, 0x5e, 0x3b, 0x9b, 0x82, 0x60, 0x74}

+  gLinuxAtagListProtocolGuid = {0x46f1ef63, 0x24d3, 0x423b, {0x9d, 0x9, 0x8f, 0xc6, 0x77, 0xd0, 0x24, 0x9d}}

+  gUniNorFlashProtocolGuid = {0x86F305EA, 0xDFAC, 0x4A6B, {0x92, 0x77, 0x47, 0x31, 0x2E, 0xCE, 0x42, 0xA}} 

+  gNANDDriverProtocolGuid = {0xf355bcc3, 0x252d, 0x4dee, {0xad, 0x05,0x94, 0xbb, 0x29, 0xc8, 0x4d, 0x46}}
+  

+[Guids.common]
+  gHwTokenSpaceGuid = { 0x99999999, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } }

+  gArmPL061GpioGuid = { 0x5c1997d7, 0x8d45, 0x4f21, { 0xaf, 0x3c, 0x22, 0x06, 0xb8, 0xed, 0x8b, 0xec } }
+  gArmPlatformTokenSpaceGuid   = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } }
+
+

+[PcdsFixedAtBuild]

+  gHwTokenSpaceGuid.PcdDefaultCoreTagFlags|1|UINT32|0x010000006

+  gHwTokenSpaceGuid.PcdDefaultCoreTagPageSize|0x00001000|UINT32|0x01000024

+  gHwTokenSpaceGuid.PcdDefaultCoreTagRootdev|0|UINT32|0x01000002

+  

+  gHwTokenSpaceGuid.PcdDefaultMemTagStart|0x0|UINT32|0x01000003

+  gHwTokenSpaceGuid.PcdDefaultMemTagSize|0x10000000|UINT32|0x01000004

+  

+  gHwTokenSpaceGuid.PcdNorFlashBase|0x30000000|UINT32|0x01000008

+

+  gHwTokenSpaceGuid.PcduImageStart|0x03300000|UINT32|0x01000005

+  gHwTokenSpaceGuid.PcdtinitrdStart|0x03800000|UINT32|0x01000007

+  gHwTokenSpaceGuid.PcdBootcmdAddr|0x00a01000|UINT32|0x010000c

+

+  gHwTokenSpaceGuid.PcdDefaultCmdlineTagCmdline|"mem=256M console=ttyAMA0,115200 quiet"|VOID*|0x010000F

+

+  

+  gHwTokenSpaceGuid.PcdNANDCRegBase|0xe4020000|UINT32|0x0030000b

+  gHwTokenSpaceGuid.PcdNANDBufBase|0xe5000000|UINT32|0x0030000c

+

+  

+  gHwTokenSpaceGuid.PcdGPIO0Base|0x14000000|UINT32|0x00300001

+  gHwTokenSpaceGuid.PcdGPIO1Base|0x14001000|UINT32|0x00300002

+  gHwTokenSpaceGuid.PcdGPIO2Base|0x14002000|UINT32|0x00300003

+  gHwTokenSpaceGuid.PcdGPIO3Base|0x14003000|UINT32|0x00300004

+  gHwTokenSpaceGuid.PcdGPIO4Base|0x14004000|UINT32|0x00300005

+  

+  gArmTokenSpaceGuid.PcdSysCtrlBase|0x00000000|UINT32|0x01000009

+  gArmTokenSpaceGuid.PcdTimerBase|0x00000000|UINT32|0x0100000a

+  gArmTokenSpaceGuid.PcdTimer0InterruptNum|0x00000000|UINT32|0x0100000b

+

+  gHwTokenSpaceGuid.PcdEmbeddedBiosVersion|"ARM Platform"|VOID*|0x00000088

+

+  gHwTokenSpaceGuid.PcdGicPrimaryCoreId|0|UINT32|0x00000043

+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockCount|0|UINT32|0x0100010
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockSize|0|UINT32|0x0100011
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockLba|0|UINT32|0x01000012
+  gHwTokenSpaceGuid.PcdNvStorageVariableBlockDevicePath|L""|VOID*|0x01000013
+
+  gHwTokenSpaceGuid.PcdDwSdBaseAddress|0|UINT32|0x00300011
+  gHwTokenSpaceGuid.PcdDwSdClockFrequencyInHz|0|UINT32|0x00300012
+
+  gHwTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|""|VOID*|0x00300013
+  gHwTokenSpaceGuid.PcdArmFastbootFlashLimit|L""|VOID*|0x00300014
+

+

+[PcdsFeatureFlag]

+

+

+

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Guid/.gitignore b/uefi/linaro-edk2/HisiPkg/Include/Guid/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Guid/.gitignore
diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/BrdCommon.h b/uefi/linaro-edk2/HisiPkg/Include/Library/BrdCommon.h
new file mode 100644
index 0000000..87973a4
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/BrdCommon.h
@@ -0,0 +1,358 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __BRDCOMMON_H

+#define __BRDCOMMON_H

+

+#ifdef __cplusplus

+    extern "C" {

+#endif

+

+

+#define HDF_FIRST_BOOTROM_FLAG                  0x0

+#define HDF_SECOND_BOOTROM_FLAG                 0x1

+

+#define DEFAULT_FIRST_BOOTROM_SPACE_SIZE        (0x200000)

+#define DEFAULT_SECOND_BOOTROM_SPACE_SIZE       (0x700000)

+#define DEFAULT_BSP_PARA_SPACE_SIZE             (0x300000)

+

+

+#define DEFAULT_FIRST_BOOTROM_BINDFILE_SIZE     (0x200000)

+#define DEFAULT_SECOND_BOOTROM_BINDFILE_SIZE    (0x200000)

+

+#define DEFAULT_BOOTLINE_OFFSET_IN_PARA         (0x20000+0x2000)

+

+#define FLASH_BASE_ADDR                         0xf0000000

+

+#define FLASH_FIRST_HDF_ADDR                    (0)  

+#define FLASH_FIRST_HDF_SIZE                    (0x20000)         

+#define FLASH_FIRST_HDF_RSV_SIZE                (0x60000)            

+

+#define FLASH_SECOND_HDF_ADDR                   (FLASH_FIRST_HDF_ADDR + FLASH_FIRST_HDF_SIZE + FLASH_FIRST_HDF_RSV_SIZE)  

+#define FLASH_SECOND_HDF_SIZE                   (FLASH_FIRST_HDF_SIZE)      

+#define FLASH_SECOND_HDF_RSV_SIZE               (FLASH_FIRST_HDF_RSV_SIZE)  

+

+#define FIRST_BOOTROM_ADRS                      (0x100000)//(FLASH_SECOND_HDF_ADDR + FLASH_SECOND_HDF_SIZE + FLASH_SECOND_HDF_RSV_SIZE) 

+

+#define FIRST_BOOTROM_SIZE                      0x200000

+

+#define FLASH_PROTECT_BLOCK0                    (0x0)

+#define FLASH_PROTECT_BLOCK8                    (0x8)

+#define FLASH_PROTECT_BLOCK9                    (0x9)

+#define FLASH_PROTECT_BLOCK10                   (0xa)

+#define FLASH_PROTECT_BLOCK11                   (0xb)

+

+#define RESERVE_AFTER_FIRST_BOOTROM_SIZE        (0x200000)

+#define DDR_DIAGNOSE_START_ADRS                 ((FIRST_BOOTROM_ADRS) + (FIRST_BOOTROM_SIZE) + RESERVE_AFTER_FIRST_BOOTROM_SIZE)

+#define DDR_DIAGNOSE_LENGTH_ADRS                   (DDR_DIAGNOSE_START_ADRS + (0x4))

+

+#define SECOND_BOOTROM_ADRS                     ((FIRST_BOOTROM_ADRS) + (FIRST_BOOTROM_SIZE))  

+#define SECOND_BOOTROM_SIZE                     0x700000   //size of L2 BIOS

+#define BOARD_WORK_INFO_ADRS                    ((SECOND_BOOTROM_ADRS) + (SECOND_BOOTROM_SIZE)) 

+#define BOARD_WORK_INFO_SIZE                    (0x20000)        /* 128K byte*/

+

+#define BOARD_HARD_INFO_ADRS                    ((BOARD_WORK_INFO_ADRS)+(BOARD_WORK_INFO_SIZE))

+#define BOARD_HARD_INFO_SIZE                    (0x20000)        /* 128K byte*/

+

+#define BOARD_AGING_INFO_ADRS                   ((BOARD_HARD_INFO_ADRS)+(BOARD_HARD_INFO_SIZE))  

+#define BOARD_AGING_INFO_SIZE                   (0x18000)        /*   96K byte    */

+

+#define BOARD_AGING_LOG_ADRS                    ((BOARD_AGING_INFO_ADRS)+(BOARD_AGING_INFO_SIZE))   

+#define BOARD_AGING_LOG_SIZE                    (0x8000)        /*   32K byte    */

+#define BOARD_AGING_CHIP_LOG_SIZE               (0x800) 

+

+#define APPLICATION_INFO_ADRS                   ((BOARD_AGING_LOG_ADRS)+(BOARD_AGING_LOG_SIZE))  

+#define APPLICATION_INFO_SIZE                   (0x60000)          /* 128*3K byte    */

+

+#define FLASH_BLOCK_RSV_ADDRS                   (APPLICATION_INFO_ADRS + APPLICATION_INFO_SIZE)

+#define FLASH_BLOCK_RSV_SIZE                    (0xc0000)          /*128*6K byte*/

+

+#define BOARD_DRV_MEND_INFO_ADDRS               (FLASH_BLOCK_RSV_ADDRS + FLASH_BLOCK_RSV_SIZE)

+#define BOARD_DRV_MEND_INFO_SIZE                (0x80000)      /*128*4K byte*/

+

+#define SECOND_BOOTROM_VALID_FLAG_ADDR          (BOARD_WORK_INFO_ADRS + 0)  

+#define SECOND_BOOTROM_VALID_FLAG_SIZE          (0x04)

+#define SECOND_BOOTROM_VALID_FLAG_VALUE         (0x5A5A5A5A)           

+

+#define FLASH_BSP_PARA_START                    ((BOARD_WORK_INFO_ADRS) + 0x2000)  //a00000+0xe0000 

+#define FLASH_BSP_PARA_SIZE                     (0x2000)

+

+#define FAST_STARTUP_VALID_FLAG_ADDR            (FLASH_BSP_PARA_START + FLASH_BSP_PARA_SIZE)

+#define FAST_STARTUP_VALID_FLAG_SIZE            (0x04)

+#define FAST_STARTUP_VALID_FLAG_VALUE           (0x5A5A5A5A)            

+#define FAST_STARTUP_FILE_START_BLOCK_ADDR      (FAST_STARTUP_VALID_FLAG_ADDR + FAST_STARTUP_VALID_FLAG_SIZE)

+#define FAST_STARTUP_FILE_START_BLOCK_SIZE      (0x04)

+#define FAST_STARTUP_FILE_LENGTH_ADDR           (FAST_STARTUP_FILE_START_BLOCK_ADDR + FAST_STARTUP_FILE_START_BLOCK_SIZE)

+#define FAST_STARTUP_FILE_LENGTH_SIZE           (0x04)

+

+#define FLASH_UET_PARA_START                    (BOARD_HARD_INFO_ADRS)      /*BOARD_HARD_INFO_ADRS*/

+

+#define FLASH_UET_PARA_SIZE                     0x2000   

+

+#define SIZE_4KB                                0x00001000

+#define SIZE_2KB                                0x00000800

+#define FLASH_TELNET_USER                       (FLASH_UET_PARA_START + FLASH_UET_PARA_SIZE -SIZE_4KB)

+#define FLASH_TELNET_USER_SIZE                  SIZE_2KB

+#define FLASH_TELNET_USER_SET_FLAG              (FLASH_TELNET_USER +FLASH_TELNET_USER_SIZE)

+#define FLASH_TELNET_USER_SIZE                  SIZE_2KB

+#define FLASH_TELNET_FLAG                       0x5a5aa6a6

+

+#define FLASH_CLOCK_PARA_START                  (APPLICATION_INFO_ADRS + 0x0)

+#define FLASH_CLOCK_PARA_SIZE                   0x1000

+

+#define FLASH_NET_PARA_START                    (APPLICATION_INFO_ADRS + 0x20000)

+#define FLASH_NET_PARA_SIZE                     0x1000

+

+#define FLASH_BSPLOG_PARA_START                 (FLASH_NET_PARA_START + 0x20000)

+#define FLASH_BSPLOG_PARA_SIZE                  0x1000

+

+#define FLASH_UPPER_PARA_START                  (BOARD_DRV_MEND_INFO_ADDRS + BOARD_DRV_MEND_INFO_SIZE)

+#define FLASH_UPPER_PARA_SIZE                   0x200000

+

+#define SECOND_BTRM_TEXT_START                  (FIRST_BOOTROM_ADRS + FIRST_BOOTROM_SIZE)

+

+#define STA_SRAM_MEM_BASE                       0xe0000000//HDFINF_CpuBaseAddrAutoMatch(4)    /*4=SRAM*/ /* 0x2ff00000 */

+#define STA_SRAM_MEM_SIZE                       (0x40000)     /* 256K */

+

+#define CPU_RAM_USED_TOTAL_SIZE                 (0x200)                  

+#define CPU_RAM_USED_START_ADRS                 (STA_SRAM_MEM_BASE)                       

+

+#define CPU_RAM_START_TYPE_ADRS                 (CPU_RAM_USED_START_ADRS)  /*addr : 0x2ff00000*/

+#define CPU_RAM_START_TYPE_SIZE                 (0x04)

+#define BOOTROM_LEVEL1_START_VALUE              (1)                   

+#define BOOTROM_LEVEL2_START_VALUE              (2)                  

+#define SAFE_VERSION_START_VALUE                (0)                   

+#define FAST_VERSION_START_VALUE                (3)                    

+

+#define CPU_RAM_RESET_FLAG_ADRS                 (CPU_RAM_START_TYPE_ADRS + CPU_RAM_START_TYPE_SIZE)/*addr : 0x2ff00004*/

+#define CPU_RAM_RESET_FLAG_SIZE                 (0x04)

+#define CPU_RAM_RESET_FLAG_VALUE                (0x5A5A5A5A)

+#define CPU_PWR_RESET_FLAG_VALUE                (0x4B4B)

+

+#define CPU_RAM_LOAD_IMAGE_ADRS                 (CPU_RAM_RESET_FLAG_ADRS + CPU_RAM_RESET_FLAG_SIZE) /*addr : 0x2ff00008*/

+#define CPU_RAM_LOAD_IMAGE_SIZE                 (0x04)

+

+#define CPU_RAM_EXAM_RESULT_ADRS                (CPU_RAM_LOAD_IMAGE_ADRS + CPU_RAM_LOAD_IMAGE_SIZE)/*addr : 0x2ff0000c*/

+#define CPU_RAM_EXAM_RESULT_SIZE                (40)                   

+

+#define CPU_RAM_SEC_BTRM_FAIL_FLAG_ADRS         (CPU_RAM_EXAM_RESULT_ADRS + CPU_RAM_EXAM_RESULT_SIZE)

+#define CPU_RAM_SEC_BTRM_FAIL_FLAG_SIZE         (0x04)                

+#define CPU_RAM_SEC_BTRM_FAIL_FLAG_VALUE        (0x5A5A5A5A)        

+#define CPU_RAM_SEC_BTRM_FIRST_RUN_VALUE        (0xb0aec7e9)        

+

+#define CPU_RAM_SEC_BTRM_FAIL_COUNTER_ADRS      ((CPU_RAM_SEC_BTRM_FAIL_FLAG_ADRS)+(CPU_RAM_SEC_BTRM_FAIL_FLAG_SIZE))

+#define CPU_RAM_SEC_BTRM_FAIL_COUNTER_SIZE      (0x04)    

+

+#define CPU_RAM_AGING_INFO_ADRS            ((CPU_RAM_SEC_BTRM_FAIL_COUNTER_ADRS)+(CPU_RAM_SEC_BTRM_FAIL_COUNTER_SIZE))

+#define CPU_RAM_AGING_INFO_SIZE            (0x48)            

+

+#define CPU_AGING_STAT_ADRS                ((CPU_RAM_AGING_INFO_ADRS)+(CPU_RAM_AGING_INFO_SIZE))/*addr : 0x2ff00084*/

+#define CPU_AGING_STAT_SIZE                (0x4)

+#define CPU_AGING_STAT_VAL                 (0x5a5a5a5a)

+#define CPU_AGING_STAT_NO_VAL              (0x00000000)

+

+#define CPU_HDF_VER_SELECT_ADRS            ((CPU_AGING_STAT_ADRS)+(CPU_AGING_STAT_SIZE))/*addr : 0x2ff00088*/

+#define CPU_HDF_VER_SELECT_SIZE            (0x4)

+

+#define CPU_RAM_DEC_WDT_TIME_ADDR          ((CPU_HDF_VER_SELECT_ADRS) + CPU_HDF_VER_SELECT_SIZE)/*addr : 0x2ff0008c*/

+#define CPU_RAM_DEC_WDT_TIME_SIZE          (0x4)

+

+#define CPU_RAM_UART_ADDR                  (CPU_RAM_DEC_WDT_TIME_ADDR + CPU_RAM_DEC_WDT_TIME_SIZE)/*addr : 0x2ff00090*/

+#define CPU_RAM_UART_SIZE                  (0x4)

+

+#define CPU_MBIST_AGING_INFO_ADRS          (CPU_RAM_UART_ADDR + CPU_RAM_UART_SIZE) /*addr : 0xaff00094*/

+#define CPU_MBIST_AGING_INFO_SIZE          (64)

+#define MEM_MANAGE_ADDR   				   (CPU_RAM_UART_ADDR + CPU_RAM_UART_SIZE)/*addr : 0xaff00094*/

+#define MEM_MANAGE_SIZE 				   (4*8)

+

+#define CPU_RAM_TEST_FAIL_COUNT_ADDR (MEM_MANAGE_ADDR+MEM_MANAGE_SIZE)/*0x2ff000b4*/

+#define CPU_RAM_TEST_FAIL_COUNT_SIZE (4)

+

+#define FAST_STARTUP_PROCESS_FLAG_ADDR      (CPU_RAM_TEST_FAIL_COUNT_ADDR + CPU_RAM_TEST_FAIL_COUNT_SIZE)/*0x2ff000b8*/

+#define FAST_STARTUP_PROCESS_FLAG_SIZE      (0x4)

+#define FAST_STARTUP_SUCCESS_FLAG       (0x5a5a5a5a)

+#define FAST_STARTUP_FAIL_FLAG          (0x4b4b4b4b)

+

+#define CPU_RAM_HDF_CURRENT_VERSION_ADDR        (FAST_STARTUP_PROCESS_FLAG_ADDR + FAST_STARTUP_PROCESS_FLAG_SIZE) /*0x2ff000bc*/

+#define CPU_RAM_HDF_CURRENT_VERSION_SIZE        (4)

+#define CPU_RAM_HDF_BAK_VERSION_MAGIC_FLAG      (0xb5a4b5a4)

+

+#define CPU_RAM_HDF_RESOLVE_FAIL_COUNT_ADDR     (CPU_RAM_HDF_CURRENT_VERSION_ADDR + CPU_RAM_HDF_CURRENT_VERSION_SIZE) /*0x2ff000c0*/

+#define CPU_RAM_HDF_RESOLVE_FAIL_COUNT_SIZE     (4)

+

+

+

+

+

+#define MCLOAD_INFO_ADDR  0xaff000c4    /*addr : 0xaff000c4*/ 

+#define MClOAD_INFO_SIZE (12*8) 

+

+

+#define CONTROL_SLAVE_STATUS_INFO 0xaff00124   /*addr : 0xaff00124*/ 

+#define CONTROL_SLAVE_STATUS_INFO_SIZE (4*8)

+

+#define CPU_RAM_WFI_STATUS_ADDR                 (CONTROL_SLAVE_STATUS_INFO + CONTROL_SLAVE_STATUS_INFO_SIZE)/*addr : 0xaff00144*/ 

+#define CPU_RAM_WFI_STATUS_SIZE                 (4*8)

+

+#define CPU_RAM_CONTROL_SLAVE_HART_BEAT_ADDR    (CPU_RAM_WFI_STATUS_ADDR + CPU_RAM_WFI_STATUS_SIZE) /*addr : 0xaff00164*/ 

+#define CPU_RAM_CONTROL_SLAVE_HART_BEAT_SIZE    (4*8)

+

+#define CPU_RAM_SLAVE_CORE_TYPE_ADDR            (CPU_RAM_CONTROL_SLAVE_HART_BEAT_ADDR + CPU_RAM_CONTROL_SLAVE_HART_BEAT_SIZE)/*addr : 0xaff00184*/ 

+#define CPU_RAM_SLAVE_CORE_TYPE_SIZE            (4)

+

+#define CPU_RAM_CLUSTER0_SCU_EN_FLAG_ADDR       (CPU_RAM_SLAVE_CORE_TYPE_ADDR + CPU_RAM_SLAVE_CORE_TYPE_SIZE)/*0xaff00188*/

+#define CPU_RAM_CLUSTER0_SCU_EN_FLAG_SIZE       (4)

+#define CPU_RAM_CLUSTER1_SCU_EN_FLAG_ADDR       (CPU_RAM_CLUSTER0_SCU_EN_FLAG_ADDR + CPU_RAM_CLUSTER0_SCU_EN_FLAG_SIZE)/*0xaff0018c*/

+#define CPU_RAM_CLUSTER1_SCU_EN_FLAG_SIZE       (4)

+

+#define CPU_RAM_SCU_EN_FLAG                     (0xaaaaaaaa)

+#define CPU_RAM_SCU_UNEN_FLAG                   (0xbbbbbbbb)

+

+#define CPU_RAM_SLAVE_CORE_RUN_COUNT_ADDR       (CPU_RAM_CLUSTER1_SCU_EN_FLAG_ADDR+CPU_RAM_CLUSTER1_SCU_EN_FLAG_SIZE)/*0xaff00190*/

+#define CPU_RAM_SLAVE_CORE_RUN_COUNT_SIZE       (4)

+

+#define CPU_RAM_CPU1_RST_SRC_ADDR               (CPU_RAM_SLAVE_CORE_RUN_COUNT_ADDR+CPU_RAM_SLAVE_CORE_RUN_COUNT_SIZE)/*0xaff00194*/

+#define CPU_RAM_CPU1_RST_SRC_SIZE               (4)

+

+#define CPU_RAM_SAVE_HIMEM_FLAG                 ((CPU_RAM_CPU1_RST_SRC_ADDR)+(CPU_RAM_CPU1_RST_SRC_SIZE))  /*0xaff00198*/

+#define CPU_RAM_SAVE_HIMEM_FLAG_SIZE            (4)            

+

+#define CPU_RAM_DDR_WRITE_LEVELING_FLAG         ((CPU_RAM_SAVE_HIMEM_FLAG) + (CPU_RAM_SAVE_HIMEM_FLAG_SIZE)) /*0xaff0019c*/

+#define CPU_RAM_DDR_WRITE_LEVELING_SIZE         4

+

+#define CPU_RAM_IPI_BASE_ADDR                   (CPU_RAM_DDR_WRITE_LEVELING_FLAG + CPU_RAM_DDR_WRITE_LEVELING_SIZE) /* 0xAFF001A0 */

+#define CPU_RAM_IPI_SIZE                        (4* 8 * 8)

+

+#define CPU_RAM_STACK_ADRS                      (STA_SRAM_MEM_BASE + STA_SRAM_MEM_SIZE-0x100)

+

+#define FLASH_CPU_CHIP_INDEX                    0  

+#define FLASH_MAX_CHIP_INDEX                    FLASH_CPU_CHIP_INDEX 

+

+

+

+/******************************************************************************

+Memory configuration 

+*******************************************************************************/ 

+#define HDF_COPY_TO_DRAM_ADRS                   (0x900000)  

+

+/*** RAM Information ***/

+#define BSP_LOG_SIZE                            (0x00080000)   

+

+#define BSP_REPORT_MAX_SIZE                     (0x00010000)

+

+#define BSP_REALTIME_REPORT_ADDR                (0x00020000) 

+#define BSP_LASTWORD_REPORT_ADDR                (0x00040000)

+

+#define BSP_FILESYS_RESERVED_ADDR               (0x00030000)

+

+#define TASK_SWITCH_TRACE_BASEADDR              (0x00050000+0x10)/*Addr=0x50000*/

+

+

+#define BSP_WARM_RESET_TABLE_ADRS               (IMAGE_LOW_ADRS - 0x200)

+#define BSP_WARM_RESET_TABLE_SIZE               0X04

+#define BSP_WARM_RESET_TABLE_VALUE              0x3C5AA5C3  

+

+#define BSP_SOFT_RESET_TABLE_ADRS               (BSP_WARM_RESET_TABLE_ADRS + BSP_WARM_RESET_TABLE_SIZE)

+#define BSP_SOFT_RESET_TABLE_SIZE               0x04

+#define BSP_SOFT_RESET_TABLE_VALUE0             0xa5a5a5a5 

+#define BSP_SOFT_RESET_TABLE_VALUE1             0x4b4b4b4b

+#define BSP_SOFT_RESET_TABLE_VALUE2             0         

+

+#define BSP_1588_RESERVED_BEGIN                 (0x5ff800)

+#define BSP_1588_RESERVED_SIZE                  (2048)

+#define BSP_1588_RESERVED_END                   (0x600000)

+

+#define BSP_VECTOR_SAVE_BASEADDR                (0)

+#define BSP_VECTOR_SAVE_SIZE                    (0)

+#define BSP_MEM_RECORD_BASEADDR                 (0x600000)

+#define BSP_MEM_RECORD_MAX_LEN                  (0x300000)

+#define BSP_MEM_RECORD_BAK_BASEADDR             (0)

+#define BSP_MEM_RECORD_BAK_MAX_LEN              (0)

+#define DEDICATED_TASKTCB_INFO_BASEADDR         (0)

+#define DEDICATED_TASKTCB_INFO_MAX_LEN          (0)

+#define ISR_STACK_INFO_BASEADDR                 (0)

+#define ISR_STACK_INFO_MAX_LEN                  (0)

+#define BOARD_REALTIME_RECORD_BASEADDR          (0)

+#define BOARD_REALTIME_RECORD_MAX_LEN           (0)

+

+#define HDF_RAM_MAPAREA_ADDR                    (0x900000)

+#define HDF_RAM_MAPAREA_SIZE                    (0x20000)    /* 128K */

+

+#define FIQ_TASK_INFO_ADDR                      (0x920000)                      

+#define FIQ_STACK_ADDR                          (FIQ_TASK_INFO_ADDR + 0x4000) 

+#define BOARD_NAME   "MPTXb"

+#define SYS_CLK_FREQ                            (13000000)

+

+#define PENDING                                 (0x0)       

+#define RST_HANDLE                              (0x1)     

+#define SYS_INIT                                (0x2)       

+#define USR_INIT                                (0x3)       

+#define USR_ROOT                                (0x4)      

+#define RUNNING                                 (0x5)    

+#define INIT_START                              (0x1)

+#define RUN_NORMAL                              (0x2)

+#define INIT_FAIL                               (0x3)

+#define RUN_ABNORMAL                            (0x4)

+#define RUN_LOOP                                (0x5)

+#define STATUS_NULL                             (0x0)

+

+#define FE_ELE_NET_ID                           0                        

+#define FE_DDI_NET_ID                           1                     

+#define CBUS_NET_ID                             2                     

+#define BACK_NET_ID                             3

+#define MAX_NET_ID                              4    

+

+#define GE_IPADDR_ID                            0                 

+#define TARGET_IPADDR_ID                        1                     

+#define HOST_IPADDR_ID                          2                       

+

+#define PORT_TYPE_DEBUG                         0

+#define PORT_TYPE_CAN                           1

+#define PORT_TYPE_TRAFFIC                       2 

+#define PORT_TYPE_BACK                          3

+#define PORT_TYPE_MAX_NUM                       3

+

+#define PORT_DEBUG_ID                           0

+#define PORT_CAN_ID                             0

+#define PORT_TRAFFIC_ID_0                       0

+#define PORT_TRAFFIC_ID_1                       1

+#define PORT_CAN_DEBUG_ID                       0

+

+#define SC_SYSSTAT15                            (HDFINF_CpuBaseAddrAutoMatch(CPU_SYSCTRL) + 0x444)

+#define SC_MSCPU_BIT                            (20)

+#define SC_MSCPU_MASK                           (0x1)

+#define PORT_INTERLINK_ID                       0

+#define BSP_SLAVE_CPU_START_FLAG_ADDR           0x91b00000

+#define BSP_SLAVE_CPU_START_FLAG                0x5A6A7A8A

+#define BSP_MS_CPU_SHARE_ADDR                   0x91b00004

+#define BSP_CPU1_FILELOAD_MEM_ADDR              (0x92A00000)

+#define BSP_CPU1_FILELOAD_MEM_LEN               (0x2400000)

+#define BSP_MAX_FILE_LENS_FOR_ONE_FILE          (BSP_CPU1_FILELOAD_MEM_ADDR - BSP_MS_CPU_SHARE_ADDR)

+

+#define BSP_CPU1_FILELOAD_OK_FLAG               0x5A576767

+#define  HDF_DDR_Addr (0x900000)

+#define L1_CACHE_MBIST_End 0xA5A5A5A5

+#define L1_CACHE_MBIST_FLAG 0x12345678

+#define L1_CACHE_MBIST_FLAG_B 0x87654321

+#define MBIST_CTRL_ADDR     0x2FF3FCC0

+#define MBIST_STRL_ADDR     0x2FF3FD00

+#define SRAM_HDF_WDT_FLAG1 0x2ff3fc00

+#define SRAM_HDF_WDT_FLAG2 0x2ff3fc04

+#define SRAM_HDF_WDT_FLAG3 0x2ff3fc08

+#ifdef __cplusplus

+}

+#endif

+#endif  /* __BRDCOMMON_H */

+

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/BspUartLib.h b/uefi/linaro-edk2/HisiPkg/Include/Library/BspUartLib.h
new file mode 100644
index 0000000..3faca88
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/BspUartLib.h
@@ -0,0 +1,95 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __BSP_UART_H

+#define __BSP_UART_H

+    

+#ifdef __cplusplus

+        extern "C" {

+#endif 		/* __cplusplus */

+

+#include "Std.h"

+#define UART_SEND_DELAY    (500000)  

+

+#define SERIAL_0_BASE_ADR       0xe4007000

+#define UART_THR_REG         (SERIAL_0_BASE_ADR + UART_RBR)

+#define UART_RBR_REG         (SERIAL_0_BASE_ADR + UART_THR)

+#define UART_DLL_REG         (SERIAL_0_BASE_ADR + UART_DLL)

+#define UART_DLH_REG         (SERIAL_0_BASE_ADR + UART_DLH)

+#define UART_IEL_REG         (SERIAL_0_BASE_ADR + UART_IEL)

+#define UART_IIR_REG         (SERIAL_0_BASE_ADR + UART_IIR)

+#define UART_FCR_REG         (SERIAL_0_BASE_ADR + UART_FCR)

+#define UART_LCR_REG         (SERIAL_0_BASE_ADR + UART_LCR)

+#define UART_LSR_REG         (SERIAL_0_BASE_ADR + UART_LSR)

+#define UART_USR_REG         (SERIAL_0_BASE_ADR + UART_USR)

+

+#define UART_RBR     0x00           

+#define UART_THR     0x00         

+#define UART_DLL     0x00         

+#define UART_DLH     0x04      

+#define UART_IEL     0x04      

+#define UART_IIR     0x08         

+#define UART_FCR     0x08       

+#define UART_LCR     0x0C         

+#define UART_MCR     0x10         

+#define UART_LSR     0x14          

+#define UART_USR     0x7C         

+    

+/* register definitions */

+#define UART_FCR_EN		     0x01		

+#define UART_FCR_RXCLR       0x02		

+#define UART_FCR_TXCLR       0x04	

+#define UART_FCR_CLEARFIFO   0x00     

+

+#define UART_LCR_DLAB   0x80   

+#define UART_LCR_EPS    0x10   

+#define UART_LCR_PEN    0x08    

+#define UART_LCR_STOP   0x04   

+#define UART_LCR_DLS8   0x03    

+#define UART_LCR_DLS7   0x02  

+#define UART_LCR_DLS6   0x01    

+#define UART_LCR_DLS5   0x00  

+

+#define UART_LSR_TEMT       0x40   

+#define UART_LSR_THRE       0x20  

+#define UART_LSR_BI         0x10   

+#define UART_LSR_FE         0x08  

+#define UART_LSR_PE         0x04   

+#define UART_LSR_R          0x02   

+#define UART_LSR_DR         0x01  

+    

+#define UART_USR_BUSY       0x01   

+#define UART_USR_TFNF       0x02  

+#define UART_USR_TFE        0x04   

+#define UART_USR_RFNE       0x08 

+#define UART_USR_RFF        0x10   

+

+#define HI1210_SC_PRECTRL3     0x34

+#define HI1380_SC_PRECTRL1     0x20

+#define HI1380_SC_PRECTRL9     0x50

+

+#ifndef NULL

+#define NULL 0

+#endif

+

+extern void BspSendChar(char scShowChar);

+extern char BspGetChar(U32 ulTimeout);

+

+#ifdef __cplusplus

+     }

+#endif /* __cplusplus */

+ 

+#endif /* __BSP_UART_H */

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/EblProvisionLib.h b/uefi/linaro-edk2/HisiPkg/Include/Library/EblProvisionLib.h
new file mode 100644
index 0000000..8dcc7ba
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/EblProvisionLib.h
@@ -0,0 +1,59 @@
+/**********************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 _PROVISION_PATH_H

+#define _PROVISION_PATH_H

+

+#include <Protocol/DevicePath.h>

+#include <Protocol/DevicePathToText.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+#include <Uefi/UefiBaseType.h>

+#include <Protocol/SimpleFileSystem.h>

+#include <Protocol/SimpleNetwork.h>

+

+typedef struct {

+  CHAR16  *Str;

+  UINTN   Length;

+  UINTN   Capacity;

+} POOL_PRINT;

+

+EFI_FILE_HANDLE

+LibOpenRoot (

+  IN EFI_HANDLE                   DeviceHandle

+  );

+

+EFI_STATUS

+EditHIInputStr (

+  IN OUT CHAR16  *CmdLine,

+  IN     UINTN   MaxCmdLine

+  );

+

+EFI_STATUS

+EditHIInputAscii (

+  IN OUT CHAR8   *CmdLine,

+  IN     UINTN   MaxCmdLine

+  );

+

+EFI_STATUS

+GetHIInputAscii (

+  IN OUT CHAR8   *CmdLine,

+  IN     UINTN   MaxCmdLine

+  );

+

+EFI_STATUS

+GetHIInputInteger (

+  OUT UINTN   *Integer

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/PinIo_Api.h b/uefi/linaro-edk2/HisiPkg/Include/Library/PinIo_Api.h
new file mode 100644
index 0000000..c11ba0c
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/PinIo_Api.h
@@ -0,0 +1,60 @@
+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __PINIO_H__

+#define __PINIO_H__

+

+

+#ifdef __cplusplus

+#if __cplusplus

+extern "C"{

+#endif

+#endif /* __cplusplus */

+

+#include "Std.h"

+#ifndef INPUT_PIN

+#define INPUT_PIN 0

+#endif

+

+#ifndef OUTPUT_PIN

+#define OUTPUT_PIN 1

+#endif

+#ifndef OPEN_DRAIN

+#define OPEN_DRAIN     1

+#endif

+

+#ifndef NO_OPEN_DRAIN

+#define NO_OPEN_DRAIN  0

+#endif

+

+#ifndef LOW_LEVEL

+#define LOW_LEVEL 0

+#endif

+

+#ifndef HIGH_LEVEL

+#define HIGH_LEVEL 1

+#endif

+

+

+extern U32 GetPortLevel( U32 port, U32 pin );

+extern void PortInit( U32 port, U32 pin, U32 dir, U32 openDrain );

+extern void SetPortLevel( U32 port, U32 pin, U32 level );

+

+#ifdef __cplusplus

+#if __cplusplus

+}

+#endif

+#endif /* __cplusplus */

+

+

+#endif /* __PINIO_H__ */

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/ResetWdtLib.h b/uefi/linaro-edk2/HisiPkg/Include/Library/ResetWdtLib.h
new file mode 100644
index 0000000..6b157ad
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/ResetWdtLib.h
@@ -0,0 +1,34 @@
+/*******************************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __WATCHDOG_RESET__

+#define __WATCHDOG_RESET__

+extern void Delay(unsigned long ulCount);

+extern void WDT_ResetWatchdog(void);

+ 

+#define GPIO_MASK(index)                    (0x1UL << index)

+

+#define GPIO3_BASE_ADDR         0xe4003000

+

+#define HIP04_IOPAD_REG          0xe400c000

+#define HIP04_WDOG_PORT          0x1A0        //GPIO98

+#define HIP04_SGMI_PORT          0x1AC        //GPIO101

+#define HIP04_MII_PORT           0x1B0        //GPIO102

+#define HIP04_RST_PORT           0x1B4        //GPIO103

+

+#define writel_wdt(val,addr)                 ((*(volatile unsigned int *)(addr)) = (val))

+#define outl_wdt(val,addr)                   ((void) writel_wdt ((val),addr))

+#define readl_wdt(addr)                      (*(volatile unsigned int *)(addr))

+#define inl_wdt(addr)                        (readl_wdt(addr))

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/Std.h b/uefi/linaro-edk2/HisiPkg/Include/Library/Std.h
new file mode 100644
index 0000000..6064847
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/Std.h
@@ -0,0 +1,147 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __std_H

+#define __std_H

+

+

+#ifndef _ASMLANGUAGE

+

+typedef int STATUS;

+typedef int INT;

+typedef unsigned int size_t;

+

+typedef signed char     S8;

+typedef signed short    S16;

+typedef signed int      S32;

+

+#ifndef VC_DEBUG_MODE

+typedef long long       S64;

+#else

+typedef __int64         S64;

+#endif

+

+#ifndef U8 

+typedef unsigned char   U8;

+#endif

+

+#ifndef U16

+typedef unsigned short  U16;

+#endif

+

+#ifndef U32

+typedef unsigned int    U32;

+#endif

+

+#ifndef VC_DEBUG_MODE

+typedef unsigned long long  U64;

+#else

+typedef unsigned __int64 U64;

+#endif

+

+#ifndef LONG

+typedef long    LONG;

+#endif

+#ifndef CHAR

+typedef char    CHAR;

+#endif

+

+typedef volatile unsigned char  V8;

+typedef volatile unsigned short V16;

+typedef volatile unsigned int   V32;

+

+#ifndef VC_DEBUG_MODE

+typedef volatile unsigned long long  V64;

+#else

+typedef volatile unsigned __int64 V64;

+#endif

+

+#ifndef VC_DEBUG_MODE

+typedef  char           BYTE;

+#endif

+

+typedef  unsigned char  UBYTE;    

+typedef  short          HWORD;    

+typedef  unsigned short UHWORD;    

+

+#ifndef VC_DEBUG_MODE

+/*typedef  long           WORD;*/    

+typedef  unsigned long  UWORD;

+#endif

+

+

+

+

+typedef  volatile char           VBYTE;

+typedef  volatile unsigned char  VUBYTE;    

+typedef  volatile short          VHWORD;    

+typedef  volatile unsigned short VUHWORD;    

+typedef  volatile long           VWORD;    

+typedef  volatile unsigned long  VUWORD;    

+

+#ifndef ERROR

+#define ERROR   -1

+#endif

+

+#ifndef OK

+#define OK      0

+#endif

+#ifndef BOOL

+#define BOOL  int

+#endif

+#ifndef BYTE_SWAP32

+#define BYTE_SWAP32(x)        ((((unsigned)(x) & 0x000000ff) << 24) | \

+			                             (((x) & 0x0000ff00) <<  8) | \

+			                             (((x) & 0x00ff0000) >>  8) | \

+			                             (((x) & 0xff000000) >> 24))

+#endif

+

+#ifndef BYTE_SWAP16

+#define BYTE_SWAP16(x)     ((((x) & 0x00ff) <<8) | \

+                            (((x) & 0xff00) >> 8))

+#endif

+#define CPU_RAM_HDF_BAK_VERSION_FLAG            (0)

+#define CPU_RAM_HDF_MAIN_VERSION_FLAG           (1)

+#define REG_WRITE(addr,data)            (*(volatile UINT32 *)(addr) = (data))

+#define REG_READ(addr,data)             ((data) = *(volatile UINT32 *)(addr))

+

+#define SYS_CTRL_REG_WRITE(offset,data)  (REG_WRITE((offset), (data)))

+#define SYS_CTRL_REG_READ(offset,data)   do \

+                                         { \

+                                            (REG_READ((offset), (data))); \

+                                         }while(0)

+#ifndef MEM_MMU_OFFSET

+//#define MEM_MMU_OFFSET   0x80000000

+#define MEM_MMU_OFFSET   0x00

+#endif

+#define NELEMENTS(array)	(sizeof (array) / sizeof ((array) [0]))

+

+

+#define REG64(Addr) (*(volatile unsigned long long *)(Addr))

+#define REG32(Addr) (*(volatile unsigned int *)(Addr))

+#define REG16(Addr) (*(volatile unsigned short *)(Addr))

+#define REG8(Addr)  (*(volatile unsigned char *)(Addr))

+

+U32 vxImmrGet (void);

+

+#endif

+

+#define SIZE_1        1

+#define SIZE_4        4

+#define SIZE_59      59

+#endif /* __std_H */

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/SysUtilLib.h b/uefi/linaro-edk2/HisiPkg/Include/Library/SysUtilLib.h
new file mode 100644
index 0000000..bf778f4
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/SysUtilLib.h
@@ -0,0 +1,41 @@
+/*************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __SYS_UTIL_LIB__

+#define __SYS_UTIL_LIB__

+

+#include "Std.h"

+ 

+#define SC_PCB_BIT                      (16)

+#define SC_PCB_MASK                     (0xF)

+

+

+extern U32 GET_ClkFreq(U32* psysClkReg);

+extern U32 GET_InterTimerRefPreq(void);

+extern U32 BSP_GetStartBootNo(void);

+

+extern void TMBInit (void);

+extern void sysUsDelay(U32 delay);

+extern void delayUSec(U32 delay);

+extern U32 BSP_GetTimeBaseVal(U32 *pulTimeL, U32 *pulTimeH );

+extern U32 BSP_GetTimeBase(U32 *pulTimeL, U32 *pulTimeH );

+extern void TMB_Read(U32* pulValueHigh, U32* pulValueLow);

+extern int bUnzipPlus(

+    long  lInputLen,   

+    void* pInputBuf,   

+    void* pOutputBuf,   

+    long* plOutputLen, 

+    long  lCheckLen ,  

+    char  compresstype  

+    );

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Library/config.h b/uefi/linaro-edk2/HisiPkg/Include/Library/config.h
new file mode 100644
index 0000000..3911e23
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Library/config.h
@@ -0,0 +1,436 @@
+/* config.h - Mistral OMAP35xx configuration header */

+

+/*

+ * Copyright (c) 2008-2009 Wind River Systems, Inc.

+ * Copyright (c) Huawei Technologies Co., Ltd. 2013. All rights reserved.

+ *

+ * The right to copy, distribute, modify or otherwise make use

+ * of this software may be licensed only pursuant to the terms

+ * of an applicable Wind River license agreement.

+ */

+

+/*

+modification history

+--------------------

+01f,25mar09,m_h  add support for copyback cache & RTP

+01e,19mar09,m_h  Cache is writethrough not copyback

+01d,19feb09,m_h  cleanup

+01c,22jan09,m_h  OneNand Flash Support

+01b,24nov08,m_h  Configure to add networking

+01a,16jun08,m_h  created.

+*/

+

+/*

+DESCRIPTION

+This module contains the configuration parameters for the Mistral OMAP35xx BSP.

+*/

+

+#ifndef __INCconfigh

+#define __INCconfigh

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+/* BSP version/revision identification, before configAll.h */

+

+#define BSP_VER_1_1     1       /* 1.2 is backwards compatible with 1.1 */

+#define BSP_VER_1_2     1

+#define BSP_VERSION     "2.0"

+#define BSP_REV         "/0"   /* 0 for first revision */

+

+//#include <configAll.h>

+/*

+ * vxbus support

+ */

+#ifdef _BSP_BUILD_VXWORKS

+#define INCLUDE_VXBUS

+#else

+#undef INCLUDE_VXBUS

+#endif

+#ifdef INCLUDE_VXBUS

+#define INCLUDE_HWMEM_ALLOC

+#define INCLUDE_VXB_CMDLINE

+

+#define HWMEM_POOL_SIZE 50000

+

+#endif /* INCLUDE_VXBUS */

+

+/*

+ * SYS_MODEL define

+ *

+ */

+

+#define SYS_MODEL "HISILICON - CortexA9 (ARM)"

+

+

+/* Support network devices */

+#define INCLUDE_NET_DAEMON

+#undef INCLUDE_APPL_LOG_UTIL

+#undef INCLUDE_END2_LINKBUFPOOL

+

+#define DEFAULT_BOOT_LINE \

+      "HiFE(0,0)OMC:vxWorks.bin h=192.168.0.200 e=192.168.0.100 u=aa pw=123"

+

+

+

+#ifndef HDF_MASTER_CORE_FLAG

+#define HDF_MASTER_CORE_FLAG    0

+#define HDF_SLAVE_CORE_FLAG     1

+#define HDF_BOOTROM_COMPILE_FLAG    0

+#define HDF_VXWORKS_COMPILE_FLAG    1

+#endif

+

+

+

+

+

+/* Memory configuration */

+#undef  LOCAL_MEM_AUTOSIZE                    /* run-time memory sizing */

+

+#ifndef _BSP_BUILD_VXWORKS

+#ifdef _CONTROL_SLAVE_CORE_IMG

+#define USER_RESERVED_MEM       HDF_GetMemPoolResSizeConfig(HDF_SLAVE_CORE_FLAG,HDF_BOOTROM_COMPILE_FLAG)

+#else

+#define USER_RESERVED_MEM       HDF_GetMemPoolResSizeConfig(HDF_MASTER_CORE_FLAG,HDF_BOOTROM_COMPILE_FLAG)

+#endif

+#else

+#ifdef _CONTROL_SLAVE_CORE_IMG

+#define USER_RESERVED_MEM       HDF_GetMemPoolResSizeConfig(HDF_SLAVE_CORE_FLAG,HDF_VXWORKS_COMPILE_FLAG)

+#else

+#define USER_RESERVED_MEM       HDF_GetMemPoolResSizeConfig(HDF_MASTER_CORE_FLAG,HDF_VXWORKS_COMPILE_FLAG)

+#endif

+#endif

+

+#define LOCAL_MEM_LOCAL_ADRS    (0x0)

+

+

+

+#ifndef _BSP_BUILD_VXWORKS

+#ifdef _CONTROL_SLAVE_CORE_IMG

+#define LOCAL_MEM_SIZE          HDF_GetMemPoolPhyMemTopConfig(HDF_SLAVE_CORE_FLAG,HDF_BOOTROM_COMPILE_FLAG)

+#else

+#define LOCAL_MEM_SIZE          HDF_GetMemPoolPhyMemTopConfig(HDF_MASTER_CORE_FLAG,HDF_BOOTROM_COMPILE_FLAG)

+#endif

+#else

+#ifdef _CONTROL_SLAVE_CORE_IMG

+#define LOCAL_MEM_SIZE          HDF_GetMemPoolPhyMemTopConfig(HDF_SLAVE_CORE_FLAG,HDF_VXWORKS_COMPILE_FLAG)

+#else

+#define LOCAL_MEM_SIZE          HDF_GetMemPoolPhyMemTopConfig(HDF_MASTER_CORE_FLAG,HDF_VXWORKS_COMPILE_FLAG)

+#endif

+

+#endif

+#define LOCAL_MEM_END_ADRS      (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE)

+

+

+/*

+ * Boot ROM is an image written into Flash. Part of the Flash can be

+ * reserved for boot parameters etc. (see the Flash section below).

+ *

+ * The following parameters are defined here and in the Makefile.

+ * They must be kept synchronized; effectively config.h depends on Makefile.

+ * Any changes made here must be made in the Makefile and vice versa.

+ *

+ * ROM_BASE_ADRS is the base of the Flash ROM/EPROM.

+ * ROM_TEXT_ADRS is the entry point of the VxWorks image

+ * ROM_SIZE is the size of the part of the Flash ROM/EPROM allocated to

+ *      the VxWorks image (block size - size of headers)

+ *

+ * Two other constants are used:

+ * ROM_COPY_SIZE is the size of the part of the ROM to be copied into RAM

+ *       (e.g. in uncompressed boot ROM)

+ * ROM_SIZE_TOTAL is the size of the entire Flash ROM (used in sysPhysMemDesc)

+ *

+ * The values are given as literals here to make it easier to ensure

+ * that they are the same as those in the Makefile.

+ */

+

+#undef  RAM_LOW_ADRS

+#undef  RAM_HIGH_ADRS

+

+#define IMAGE_LOW_ADRS   0x00a00000

+

+/* VxWorks entry link address */

+#define VXWORKS_ENTRY    IMAGE_LOW_ADRS

+

+#ifdef _CONTROL_SLAVE_CORE_IMG

+#define RAM_LOW_ADRS     0x00200000  /* VxWorks image entry point */

+#define RAM_HIGH_ADRS    0x03000000  /* RAM address for ROM boot */

+

+#else

+

+#ifndef _BSP_BUILD_VXWORKS

+#define ROM_BASE_ADRS    (HDFINF_GetTextBase())

+#define ROM_TEXT_ADRS    (HDFINF_GetTextBase())

+#define RAM_LOW_ADRS     0x05000000  /* VxWorks image entry point */

+#define RAM_HIGH_ADRS    0x06000000  /* RAM address for ROM boot */

+#else

+#define ROM_BASE_ADRS    0x40200000     /* base of Flash/EPROM */

+#define ROM_TEXT_ADRS    0x40200000     /* code start addr in ROM */

+#define RAM_LOW_ADRS     IMAGE_LOW_ADRS  /* VxWorks image entry point */

+#define RAM_HIGH_ADRS    0x05000000  /* RAM address for ROM boot */

+#endif

+

+#endif

+

+#undef  ROM_SIZE

+#define ROM_SIZE          0x00200000     /* size of ROM holding VxWorks*/

+

+

+/*

+ * Flash/NVRAM memory configuration

+ *

+ * A block of the Flash memory (FLASH_SIZE bytes at FLASH_ADRS) is

+ * reserved for non-volatile storage of data.

+ *

+ */

+

+#undef INCLUDE_FLASH

+

+/* Serial port configuration */

+

+#define N_SIO_CHANNELS    3

+

+#undef  NUM_TTY

+#define NUM_TTY             N_SIO_CHANNELS

+

+#define DEFAULT_BAUD        (HDF_GetUartBaudRate())

+

+/* Console baud rate reconfiguration. */

+#undef  CONSOLE_BAUD_RATE

+#define CONSOLE_BAUD_RATE DEFAULT_BAUD     /* Reconfigure default baud rate */

+

+/*

+ * Define SERIAL_DEBUG to enable debugging

+ * via the serial ports

+ */

+

+#undef SERIAL_DEBUG

+#undef INCLUDE_BOOT_WDB

+

+#undef INCLUDE_WDB

+

+

+

+#if defined(INCLUDE_WDB) || defined (INCLUDE_BOOT_WDB)

+#   undef WDB_COMM_TYPE

+#   undef WDB_TTY_BAUD

+#   undef WDB_TTY_CHANNEL

+#   undef WDB_TTY_DEV_NAME

+#   ifdef SERIAL_DEBUG

+#       define WDB_NO_BAUD_AUTO_CONFIG

+#       define WDB_COMM_TYPE       WDB_COMM_SERIAL /* WDB in Serial mode */

+#       define WDB_TTY_BAUD        38400       /* Baud rate for WDB Connctn */

+#       define WDB_TTY_CHANNEL     1            /* COM PORT #2 */

+#       define WDB_TTY_DEV_NAME    "/tyCo/1"    /* deflt TYCODRV_5_2 dev name */

+#   else /* SERIAL_DEBUG */

+#       define WDB_COMM_TYPE       WDB_COMM_END

+#       define WDB_TTY_BAUD        DEFAULT_BAUD /* Baud rate for WDB Connctn */

+#       define WDB_TTY_CHANNEL     0            /* COM PORT #1 */

+#       define WDB_TTY_DEV_NAME    "/tyCo/0"    /* deflt TYCODRV_5_2 dev name */

+#   endif /* SERIAL_DEBUG */

+#endif /* INCLUDE_WDB || INCLUDE_BOOT_WDB */

+

+

+/*

+ * We use the generic architecture libraries, with caches/MMUs present. A

+ * call to sysHwInit0() is needed from within usrInit before

+ * cacheLibInit() is called.

+ */

+

+/*

+ * Cache/MMU configuration

+ *

+ * Note that when MMU is enabled, cache modes are controlled by

+ * the MMU table entries in sysPhysMemDesc[], not the cache mode

+ * macros defined here.

+ */

+#define SYS_CACHE_UNCACHED_ADRS  0xffffffff/*OMAP35XX_L4_MPU_INTC*/

+

+#   undef  USER_I_CACHE_MODE

+#   define USER_I_CACHE_MODE       CACHE_COPYBACK

+

+#   undef  USER_D_CACHE_MODE

+#   define USER_D_CACHE_MODE       CACHE_COPYBACK

+

+

+/* Include MMU BASIC and CACHE support for command line and project builds */

+

+#   define INCLUDE_MMU_BASIC

+#   define INCLUDE_BOOT_MMU_BASIC

+#   define INCLUDE_CACHE_SUPPORT

+

+#if defined(INCLUDE_MMU_BASIC) || defined(INCLUDE_MMU_FULL)

+#   define INCLUDE_MMU

+#endif /* INCLUDE_MMU_BASIC || INCLUDE_MMU_FULL */

+

+/* Include MMU BASIC and CACHE support for command line and project builds */

+

+#   define INCLUDE_MMU_BASIC

+#   define INCLUDE_BOOT_MMU_BASIC

+#   define INCLUDE_CACHE_SUPPORT

+

+#if defined(INCLUDE_MMU_BASIC) || defined(INCLUDE_MMU_FULL)

+#   define INCLUDE_MMU

+#endif /* INCLUDE_MMU_BASIC || INCLUDE_MMU_FULL */

+

+#ifndef MEM_MMU_OFFSET

+#define MEM_MMU_OFFSET   0x00

+#endif

+

+/*

+ * Network driver configuration.

+ *

+ * De-select unused (default) network drivers selected in configAll.h.

+ */

+

+#undef  INCLUDE_ENP     /* include CMC Ethernet interface*/

+#undef  INCLUDE_EX      /* include Excelan Ethernet interface */

+#undef  INCLUDE_SM_NET      /* include backplane net interface */

+#undef  INCLUDE_SM_SEQ_ADDR /* shared memory network auto address setup */

+

+#define INCLUDE_IPCOM_USE_AUTH_RADIUS

+

+

+/* Enhanced Network Driver (END) Support */

+

+#define INCLUDE_END

+

+#ifdef  INCLUDE_END

+#   ifndef SERIAL_DEBUG

+#       define WBD_AGENT_END

+#   else

+#       undef WBD_AGENT_END

+#   endif /* SERIAL_DEBUG */

+

+#endif  /* INCLUDE_END */

+

+#ifdef _BSP_BUILD_VXWORKS

+#ifndef _CONTROL_SLAVE_CORE_IMG

+#if 1

+#define INCLUDE_USB

+#define INCLUDE_USB_INIT

+

+/*ehci*/

+#define INCLUDE_EHCI

+#define INCLUDE_EHCI_INIT

+#define INCLUDE_EHCI_BUS

+

+/*ohci*/

+#define INCLUDE_OHCI

+#define INCLUDE_OHCI_INIT

+#define INCLUDE_OHCI_BUS

+

+/*MASS STORGY device*/

+#define INCLUDE_USB_MS_BULKONLY

+#define INCLUDE_USB_MS_BULKONLY_INIT

+#define INCLUDE_USB_MS_CBI

+#define INCLUDE_USB_MS_CBI_INIT

+#define INCLUDE_NOR_FILESYS

+#endif

+#endif

+#endif

+

+#define INCLUDE_BSP_WATCHDOG

+

+#ifdef _CONTROL_SLAVE_CORE_IMG

+#undef  _INCLUDE_FILESYS

+#else

+#define  _INCLUDE_FILESYS

+#endif

+

+#undef INCLUDE_TFFS

+

+#ifdef _CONTROL_SLAVE_CORE_IMG

+#undef INCLUDE_DOSFS

+#else

+/*define for FS*/

+#define INCLUDE_DOSFS

+#endif

+

+#define INCLUDE_XBD_RAMDRV /*ramDisk*/

+

+#ifdef INCLUDE_DOSFS

+#define INCLUDE_ERF

+#define INCLUDE_DEVICE_MANAGER

+#define INCLUDE_FS_EVENT_UTIL

+#define INCLUDE_FS_MONITOR

+#define INCLUDE_XBD

+#define INCLUDE_XBD_BLK_DEV

+#define INCLUDE_XBD_TRANS

+#define INCLUDE_DOSFS_DIR_FIXED

+#define INCLUDE_DOSFS_DIR_VFAT

+#define INCLUDE_DOSFS_FAT

+#define INCLUDE_DOSFS_FMT

+#define INCLUDE_DOSFS_CHKDSK

+#define INCLUDE_DOSFS_MAIN

+#endif /* INCLUDE_DOSFS*/

+

+/* I2C not supported */

+#undef INCLUDE_I2C

+

+/* touch screen not supported */

+#undef INCLUDE_TOUCHSCREEN

+

+/*

+ * Interrupt mode.  Preemptive interrupts are not supported by the interrupt

+ * driver so INT_MODE must be set to INT_NON_PREEMPT_MODEL.

+ */

+

+#define INT_MODE    INT_NON_PREEMPT_MODEL

+

+/*

+ * miscellaneous definitions

+ * Note: ISR_STACK_SIZE is defined here rather than in ../all/configAll.h

+ * (as is more usual) because the stack size depends on the interrupt

+ * structure of the BSP.

+ */

+

+#define ISR_STACK_SIZE  0x2000  /* size of ISR stack, in bytes */

+

+/* Optional timestamp support */

+

+#undef  INCLUDE_TIMESTAMP   /* define to include timestamp driver */

+#define INCLUDE_TIMESTAMP

+

+#ifndef INCLUDE_LOADER

+#define INCLUDE_LOADER

+#endif

+#ifndef INCLUDE_LOADER_HOOKS

+#define INCLUDE_LOADER_HOOKS

+#endif

+#ifndef INCLUDE_PTYDRV

+#define INCLUDE_PTYDRV          /* pseudo terminal driver */

+#endif

+/*script*/

+#ifndef INCLUDE_STARTUP_SCRIPT

+#define INCLUDE_STARTUP_SCRIPT

+#endif

+

+

+#define INCLUDE_SHELL_INTERP_C  /* C interpreter */

+#define INCLUDE_SHELL_INTERP_CMD /* shell command interpreter */

+

+#undef SHELL_COMPATIBLE

+#define SHELL_COMPATIBLE        TRUE

+

+#ifndef BSP_BUILD_BASIC_BTRM

+#define INCLUDE_RAWFS

+#define INCLUDE_XBD_RAMDRV

+#endif

+#ifndef _CONTROL_SLAVE_CORE_IMG

+#ifdef _BSP_BUILD_VXWORKS

+#define INCLUDE_SECURITY

+#endif

+#endif

+#ifdef INCLUDE_SECURITY

+#define LOGIN_USER_NAME      "target"

+#endif

+

+#include "BrdCommon.h"

+//#include "configExtend.h"

+

+#ifdef __cplusplus

+}

+#endif

+#endif  /* __INCconfigh */

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Platform/ArmPlatform.h b/uefi/linaro-edk2/HisiPkg/Include/Platform/ArmPlatform.h
new file mode 100644
index 0000000..3943384
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Platform/ArmPlatform.h
@@ -0,0 +1,192 @@
+/** @file

+*  Header defining Versatile Express constants (Base addresses, sizes, flags)

+*

+*  Copyright (c) 2011, ARM Limited. All rights reserved.

+*  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __ARM_D01_H__

+#define __ARM_D01_H__

+

+#define IS_PRIMARY_CORE(MpId) (((MpId) & PcdGet32(PcdArmPrimaryCoreMask)) == PcdGet32(PcdArmPrimaryCore))

+

+

+/***********************************************************************************

+// Motherboard memory-mapped peripherals

+************************************************************************************/

+

+// Define MotherBoard SYS flags offsets (from ARM_VE_BOARD_PERIPH_BASE)

+#define ARM_VE_SYS_ID_REG                         (ARM_VE_BOARD_PERIPH_BASE + 0x00000)

+#define ARM_VE_SYS_SW_REG                         (ARM_VE_BOARD_PERIPH_BASE + 0x00004)

+#define ARM_VE_SYS_LED_REG                        (ARM_VE_BOARD_PERIPH_BASE + 0x00008)

+#define ARM_VE_SYS_FLAGS_REG                      (ARM_VE_BOARD_PERIPH_BASE + 0x00030)

+#define ARM_VE_SYS_FLAGS_SET_REG                  (ARM_VE_BOARD_PERIPH_BASE + 0x00030)

+#define ARM_VE_SYS_FLAGS_CLR_REG                  (ARM_VE_BOARD_PERIPH_BASE + 0x00034)

+#define ARM_VE_SYS_FLAGS_NV_REG                   (ARM_VE_BOARD_PERIPH_BASE + 0x00038)

+#define ARM_VE_SYS_FLAGS_NV_SET_REG               (ARM_VE_BOARD_PERIPH_BASE + 0x00038)

+#define ARM_VE_SYS_FLAGS_NV_CLR_REG               (ARM_VE_BOARD_PERIPH_BASE + 0x0003C)

+#define ARM_VE_SYS_FLASH                          (ARM_VE_BOARD_PERIPH_BASE + 0x0004C)

+#define ARM_VE_SYS_CFGSWR_REG                     (ARM_VE_BOARD_PERIPH_BASE + 0x00058)

+#define ARM_VE_SYS_MISC                           (ARM_VE_BOARD_PERIPH_BASE + 0x00060)

+#define ARM_VE_SYS_PROCID0_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x00084)

+#define ARM_VE_SYS_PROCID1_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x00088)

+#define ARM_VE_SYS_CFGDATA_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x000A0)

+#define ARM_VE_SYS_CFGCTRL_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x000A4)

+#define ARM_VE_SYS_CFGSTAT_REG                    (ARM_VE_BOARD_PERIPH_BASE + 0x000A8)

+

+// SP810 Controller

+#ifndef SP810_CTRL_BASE

+#define SP810_CTRL_BASE                           (ARM_VE_BOARD_PERIPH_BASE + 0x01000)

+#endif

+

+// PL111 Colour LCD Controller - motherboard

+#define PL111_CLCD_MOTHERBOARD_BASE               (ARM_VE_BOARD_PERIPH_BASE + 0x1F000)

+#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID  1

+

+// VRAM offset for the PL111 Colour LCD Controller on the motherboard

+#define VRAM_MOTHERBOARD_BASE                     (ARM_VE_SMB_PERIPH_BASE   + 0x00000)

+

+#define ARM_VE_SYS_PROC_ID_HBI                    0xFFF

+#define ARM_VE_SYS_PROC_ID_MASK                   (UINT32)(0xFFU << 24)

+#define ARM_VE_SYS_PROC_ID_UNSUPPORTED            (UINT32)(0xFFU << 24)

+#define ARM_VE_SYS_PROC_ID_CORTEX_A9              (UINT32)(0x0CU << 24)

+#define ARM_VE_SYS_PROC_ID_CORTEX_A5              (UINT32)(0x12U << 24)

+#define ARM_VE_SYS_PROC_ID_CORTEX_A15             (UINT32)(0x14U << 24)

+

+// Boot Master Select:

+// 0 = Site 1 boot master

+// 1 = Site 2 boot master

+#define ARM_VE_SYS_MISC_MASTERSITE                (1 << 14)

+//

+// Sites where the peripheral is fitted

+//

+#define ARM_VE_UNSUPPORTED                        ~0

+#define ARM_VE_MOTHERBOARD_SITE                   0

+#define ARM_VE_DAUGHTERBOARD_1_SITE               1

+#define ARM_VE_DAUGHTERBOARD_2_SITE               2

+

+#define VIRTUAL_SYS_CFG(site,func)                (((site) << 24) | (func))

+

+//

+// System Configuration Control Functions

+//

+#define SYS_CFG_OSC                               1

+#define SYS_CFG_VOLT                              2

+#define SYS_CFG_AMP                               3

+#define SYS_CFG_TEMP                              4

+#define SYS_CFG_RESET                             5

+#define SYS_CFG_SCC                               6

+#define SYS_CFG_MUXFPGA                           7

+#define SYS_CFG_SHUTDOWN                          8

+#define SYS_CFG_REBOOT                            9

+#define SYS_CFG_DVIMODE                           11

+#define SYS_CFG_POWER                             12

+// Oscillator for Site 1

+#define SYS_CFG_OSC_SITE1                         VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_1_SITE,SYS_CFG_OSC)

+// Oscillator for Site 2

+#define SYS_CFG_OSC_SITE2                         VIRTUAL_SYS_CFG(ARM_VE_DAUGHTERBOARD_2_SITE,SYS_CFG_OSC)

+// Can not access the battery backed-up hardware clock on the Versatile Express motherboard

+#define SYS_CFG_RTC                               VIRTUAL_SYS_CFG(ARM_VE_UNSUPPORTED,1)

+

+//

+// System ID

+//

+// All RTSM VE models have the same System ID : 0x225F500

+//

+// FVP models have a different System ID.

+// Default Base model System ID : 0x00201100

+// [31:28] Rev     - Board revision:          0x0     = Rev A

+// [27:16] HBI     - HBI board number in BCD: 0x020   = v8 Base Platform

+// [15:12] Variant - Build variant of board:  0x1     = Variant B. (GIC 64k map)

+// [11:8]  Plat    - Platform type:           0x1     = Model

+// [7:0]   FPGA    - FPGA build, BCD coded:   0x00

+//

+//HBI = 010 = Foundation Model

+//HBI = 020 = Base Platform

+//

+// And specifically, the GIC register banks start at the following

+// addresses:

+//              Variant = 0             Variant = 1

+//GICD          0x2c001000              0x2f000000

+//GICC          0x2c002000              0x2c000000

+//GICH          0x2c004000              0x2c010000

+//GICV          0x2c006000              0x2c020000

+

+// The default SYS_IDs. These can be changed when starting the model.

+#define ARM_RTSM_SYS_ID                (0x225F500)

+#define ARM_FVP_BASE_SYS_ID            (0x00201100)

+#define ARM_FVP_FOUNDATION_SYS_ID      (0x00101100)

+

+#define ARM_FVP_SYS_ID_VARIANT_MASK    (UINT32)(0xFUL << 12)

+

+

+

+/***********************************************************************************

+// Platform Memory Map

+************************************************************************************/

+

+// Can be NOR0, NOR1, DRAM

+#define ARM_VE_REMAP_BASE                       0x00000000

+#define ARM_VE_REMAP_SZ                         SIZE_64MB

+

+// Motherboard Peripheral and On-chip peripheral

+#define ARM_VE_BOARD_PERIPH_BASE                0x1C010000

+

+// NOR Flash 1

+// There is typo in the reference manual for the Base address of NOR Flash 1

+#define ARM_VE_SMB_NOR0_BASE                    0x08000000

+#define ARM_VE_SMB_NOR0_SZ                      SIZE_64MB

+// NOR Flash 2

+#define ARM_VE_SMB_NOR1_BASE                    0x0C000000

+#define ARM_VE_SMB_NOR1_SZ                      SIZE_64MB

+// SRAM

+#define ARM_VE_SMB_SRAM_BASE                    0x2E000000

+#define ARM_VE_SMB_SRAM_SZ                      SIZE_64KB

+// USB, Ethernet, VRAM

+#define ARM_VE_SMB_PERIPH_BASE                  0x18000000

+#define PL111_CLCD_VRAM_MOTHERBOARD_BASE        ARM_VE_SMB_PERIPH_BASE

+#define ARM_VE_SMB_PERIPH_SZ                    SIZE_64MB

+

+// DRAM

+#define ARM_VE_DRAM_BASE                        PcdGet32 (PcdSystemMemoryBase)

+#define ARM_VE_DRAM_SZ                          PcdGet32 (PcdSystemMemorySize)

+

+// This can be any value since we only support motherboard PL111

+#define LCD_VRAM_CORE_TILE_BASE                 0x00000000

+

+// On-chip peripherals (Snoop Control Unit etc...)

+#define ARM_VE_ON_CHIP_PERIPH_BASE              0x2C000000

+// Note: The TRM says not all the peripherals are implemented

+#define ARM_VE_ON_CHIP_PERIPH_SZ                SIZE_256MB

+

+

+// External AXI between daughterboards (Logic Tile)

+#define ARM_VE_EXT_AXI_BASE                     0x2E010000 // Not modelled

+#define ARM_VE_EXT_AXI_SZ                       0x20000000  /* 512 MB */

+

+/***********************************************************************************

+// Memory-mapped peripherals

+************************************************************************************/

+

+// SP810 Controller

+#undef SP810_CTRL_BASE

+#define SP810_CTRL_BASE                         0x1C020000

+

+// PL111 Colour LCD Controller

+#define PL111_CLCD_SITE                         ARM_VE_MOTHERBOARD_SITE

+#define PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID  1

+#define PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID  1

+

+// VRAM offset for the PL111 Colour LCD Controller on the motherboard

+#define VRAM_MOTHERBOARD_BASE                     (ARM_VE_SMB_PERIPH_BASE   + 0x00000)

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Ppi/.gitignore b/uefi/linaro-edk2/HisiPkg/Include/Ppi/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Ppi/.gitignore
diff --git a/uefi/linaro-edk2/HisiPkg/Include/Protocol/LinuxAtagListProtocol.h b/uefi/linaro-edk2/HisiPkg/Include/Protocol/LinuxAtagListProtocol.h
new file mode 100644
index 0000000..0c95a74
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Protocol/LinuxAtagListProtocol.h
@@ -0,0 +1,178 @@
+/*****************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 _LINUX_ATAG_LIST_PROTOCOL_H_

+#define _LINUX_ATAG_LIST_PROTOCOL_H_

+

+typedef struct {

+  UINT32  flags;

+  UINT32  pagesize;

+  UINT32  rootdev;

+} LINUX_ATAG_CORE;

+

+typedef struct {

+  UINT32  size;

+  UINTN  start;

+} LINUX_ATAG_MEM;

+

+typedef struct {

+  UINT8   x;

+  UINT8   y;

+  UINT16  video_page;

+  UINT8   video_mode;

+  UINT8   video_cols;

+  UINT16  video_ega_bx;

+  UINT8   video_lines;

+  UINT8   video_isvga;

+  UINT16  video_points;

+} LINUX_ATAG_VIDEOTEXT;

+

+typedef struct {

+  UINT32  flags;

+  UINT32  size;

+  UINTN  start;

+} LINUX_ATAG_RAMDISK;

+

+typedef struct {

+  UINT32  start;

+  UINT32  size;

+} LINUX_ATAG_INITRD2;

+

+typedef struct {

+  UINT32  low;

+  UINT32  high;

+} LINUX_ATAG_SERIALNR;

+

+typedef struct {

+  UINT32  rev;

+} LINUX_ATAG_REVISION;

+

+typedef struct {

+  UINT16  lfb_width;

+  UINT16  lfb_height;

+  UINT16  lfb_depth;

+  UINT16  lfb_linelength;

+  UINT32  lfb_base;

+  UINT32  lfb_size;

+  UINT8   red_size;

+  UINT8   red_pos;

+  UINT8   green_size;

+  UINT8   green_pos;

+  UINT8   blue_size;

+  UINT8   blue_pos;

+  UINT8   rsvd_size;

+  UINT8   rsvd_pos;

+} LINUX_ATAG_VIDEOLFB;

+

+typedef struct {

+  CHAR8   cmdline[255];

+} LINUX_ATAG_CMDLINE;

+

+typedef struct {

+  UINT32   addr;

+} LINUX_ATAG_BOOT_CMD;

+

+typedef struct {

+  UINT32   invalid;

+} LINUX_ATAG_CPUINFO;

+

+typedef struct {

+  UINT32  size; /* length of tag in words including this header */

+  UINT32  type;  /* tag type */

+} LINUX_ATAG_HEADER;

+

+typedef VOID (*LINUX_KERNEL)(UINT32 Zero, UINT32 Arch, UINTN ParametersBase);

+

+//

+// ATAG Definitions

+//

+

+#define ATAG_MAX_SIZE        0x3000

+

+/* ATAG : list of possible tags */

+#define ATAG_NONE            0x00000000

+#define ATAG_CORE            0x54410001

+#define ATAG_MEM             0x54410002

+#define ATAG_VIDEOTEXT       0x54410003

+#define ATAG_RAMDISK         0x54410004

+#define ATAG_INITRD2         0x54420005

+#define ATAG_SERIAL          0x54410006

+#define ATAG_REVISION        0x54410007

+#define ATAG_VIDEOLFB        0x54410008

+#define ATAG_CMDLINE         0x54410009

+#define ATAG_ARM_MP_CORE     0x5441000A

+

+#define ATAG_BOOT_CMD            0x5aa50001

+#define ATAG_CPUINFO             0x5aa50002

+

+#define next_tag_address(t)     ((LINUX_ATAG*)((UINT32)(t) + (UINT32)(SwapBytes32((UINT32)((t)->header.size))<<2)))

+#define tag_size(type)       ((UINT32)((sizeof(LINUX_ATAG_HEADER) + sizeof(type)) >> 2))

+

+typedef struct {

+  LINUX_ATAG_HEADER header;

+  union {

+    LINUX_ATAG_CORE         core_tag;

+    LINUX_ATAG_MEM          mem_tag;

+    LINUX_ATAG_VIDEOTEXT    videotext_tag;

+    LINUX_ATAG_RAMDISK      ramdisk_tag;

+    LINUX_ATAG_INITRD2      initrd2_tag;

+    LINUX_ATAG_SERIALNR     serialnr_tag;

+    LINUX_ATAG_REVISION     revision_tag;

+    LINUX_ATAG_VIDEOLFB     videolfb_tag;

+    LINUX_ATAG_CMDLINE      cmdline_tag;    

+    LINUX_ATAG_BOOT_CMD     bootcmd_tag;

+    LINUX_ATAG_CPUINFO      cpuinfo_tag;

+  } body;

+} LINUX_ATAG;

+

+typedef struct _LINUX_ATAG_LIST_PROTOCOL   LINUX_ATAG_LIST_PROTOCOL;

+

+typedef struct 

+{

+    LINUX_ATAG_CORE         core_tag;

+    LINUX_ATAG_MEM          mem_tag;

+    LINUX_ATAG_VIDEOTEXT    videotext_tag;

+    LINUX_ATAG_RAMDISK      ramdisk_tag;

+    LINUX_ATAG_INITRD2      initrd2_tag;

+    LINUX_ATAG_SERIALNR     serialnr_tag;

+    LINUX_ATAG_REVISION     revision_tag;

+    LINUX_ATAG_VIDEOLFB     videolfb_tag;

+    LINUX_ATAG_CMDLINE      cmdline_tag;

+    LINUX_ATAG_BOOT_CMD     bootcmd_tag;

+    LINUX_ATAG_CPUINFO      cpuinfo_tag;

+} LINUX_ATAG_LIST;

+

+typedef 

+EFI_STATUS

+(EFIAPI *GET_LINUX_ATAG_LIST) (

+    IN LINUX_ATAG_LIST_PROTOCOL   *This,

+    IN OUT  LINUX_ATAG_LIST        *LinuxAtagList 

+    );

+

+typedef 

+EFI_STATUS

+(EFIAPI *SET_LINUX_ATAG_LIST) (

+    IN LINUX_ATAG_LIST_PROTOCOL   *This,

+    IN LINUX_ATAG_LIST             *LinuxAtagList 

+    );

+

+typedef struct _LINUX_ATAG_LIST_PROTOCOL

+{

+    GET_LINUX_ATAG_LIST     GetLinuxAtagList;

+    SET_LINUX_ATAG_LIST     SetLinuxAtagList;

+} LINUX_ATAG_LIST_PROTOCOL;

+

+extern EFI_GUID gLinuxAtagListProtocolGuid;

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Protocol/NandFlashProtocol.h b/uefi/linaro-edk2/HisiPkg/Include/Protocol/NandFlashProtocol.h
new file mode 100644
index 0000000..f26d3d0
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Protocol/NandFlashProtocol.h
@@ -0,0 +1,127 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __NANDDRIVER_H__

+#define __NANDDRIVER_H__

+

+

+

+//

+// GUID for EFI HFFS Driver Protocol

+//

+#define EFI_NAND_DRIVER_PROTOCOL_GUID \

+    {0xf355bcc3, 0x252d, 0x4dee, 0xad, 0x05, 0x94, 0xbb, 0x29, 0xc8, 0x4d, 0x46}

+

+

+typedef struct _EFI_NAND_DRIVER_PROTOCOL  EFI_NAND_DRIVER_PROTOCOL;

+

+#if 1

+typedef struct NAND_CMD_INFO

+{

+    UINT32 ulPageSize;                            /* Page size                  */

+    UINT32 ulBlockSize;                            /* Block size                  */

+    UINT32 ulEndBlockNum;

+}NAND_CMD_INFO_STRU;

+#endif

+

+

+typedef

+UINT32 ( *EFI_NAND_DRIVER_INIT)

+(

+    IN EFI_NAND_DRIVER_PROTOCOL   *This

+);

+

+typedef

+UINT32 ( *EFI_NAND_DRIVER_ERASE)

+(

+    IN EFI_NAND_DRIVER_PROTOCOL   *This,

+    IN UINT32 ulBlockNum

+);

+

+typedef

+UINT32 ( *EFI_NAND_DRIVER_WRITE)

+(

+    IN EFI_NAND_DRIVER_PROTOCOL   *This,

+    IN UINT32 ulChunkNum,

+    IN UINT32 ulOffsetInChunk,

+    IN UINT32 ulLength,

+    IN UINT8* pucData

+);

+

+typedef

+UINT32 ( *EFI_NAND_DRIVER_READ)

+(

+    IN EFI_NAND_DRIVER_PROTOCOL   *This,

+    IN UINT32 ulChunkNum,

+    IN UINT32 ulOffsetInChunk,

+    IN UINT32 ulLength,

+    OUT UINT8* pucData

+);

+

+typedef

+UINT32 ( *EFI_NAND_DRIVER_WRITEECC)

+(

+    IN EFI_NAND_DRIVER_PROTOCOL   *This,

+    IN UINT32 ulChunkNum,

+    IN UINT32 ulOffsetInChunk,

+    IN UINT32 ulLength,

+    IN UINT8* pucData

+);

+

+typedef

+UINT32 ( *EFI_NAND_DRIVER_READECC)

+(

+IN EFI_NAND_DRIVER_PROTOCOL   *This,

+    IN UINT32 ulChunkNum,

+    IN UINT32 ulOffsetInChunk,

+    IN UINT32 ulLength,

+    OUT UINT8* pucData,

+    IN OUT UINT32* pulBitFlip

+);

+

+typedef

+UINT32 ( *EFI_NAND_DRIVER_READSPARE)

+(

+    IN EFI_NAND_DRIVER_PROTOCOL   *This,

+    IN UINT32 ulChunkNum,

+    IN UINT32 ulOffsetInChunk,

+    IN UINT32 ulLength,

+    OUT UINT8* pucData

+);

+

+typedef

+NAND_CMD_INFO_STRU ( *EFI_NAND_DRIVER_GETCMDINFO)

+(

+    IN EFI_NAND_DRIVER_PROTOCOL   *This

+);

+

+

+

+

+ 

+typedef struct _EFI_NAND_DRIVER_PROTOCOL {

+    EFI_NAND_DRIVER_INIT        NandFlashInit;

+    EFI_NAND_DRIVER_ERASE       NandFlashErase;

+    EFI_NAND_DRIVER_WRITE       NandFlashWrite;

+    EFI_NAND_DRIVER_READ        NandFlashRead;

+    EFI_NAND_DRIVER_WRITEECC    NandFlashWriteEcc;

+    EFI_NAND_DRIVER_READECC     NandFlashReadEcc;

+    EFI_NAND_DRIVER_READSPARE   NandFlashReadSpare;

+    EFI_NAND_DRIVER_GETCMDINFO    NandFlashGetCMDInfo;

+} EFI_NAND_DRIVER_PROTOCOL;

+

+extern EFI_GUID gNANDDriverProtocolGuid;

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Protocol/NorFlashProtocol.h b/uefi/linaro-edk2/HisiPkg/Include/Protocol/NorFlashProtocol.h
new file mode 100644
index 0000000..11e64d3
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Protocol/NorFlashProtocol.h
@@ -0,0 +1,101 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 _NOR_FLASH_PROTOCOL_H_

+#define _NOR_FLASH_PROTOCOL_H_

+#include <Uefi/UefiBaseType.h>

+

+#define UNI_NOR_FLASH_PROTOCOL_GUID   \

+    {0x86F305EA, 0xDFAC, 0x4A6B, {0x92, 0x77, 0x47, 0x31, 0x2E, 0xCE, 0x42, 0xA}} 

+

+typedef struct _UNI_NOR_FLASH_PROTOCOL UNI_NOR_FLASH_PROTOCOL;

+

+typedef struct {

+    UINT32 ManufacturerID; 

+    UINT32 DeviceID; 

+    UINT32 FlashSize; 

+    UINT32 BlockSize;

+    UINT8 ParallelNum; 

+    UINT8 SeriesNum;

+    UINT32 Base; 

+}NOR_FLASH_INFO_TABLE;

+

+

+typedef 

+EFI_STATUS

+(EFIAPI *UNI_FLASH_ERASE_INTERFACE) (

+    IN UNI_NOR_FLASH_PROTOCOL   *This,

+    IN UINT32                  Offset,

+    IN UINT32                  Length

+    );

+typedef 

+EFI_STATUS

+(EFIAPI *UNI_FLASH_WRITE_INTERFACE) (

+    IN UNI_NOR_FLASH_PROTOCOL   *This,

+    IN  UINT32                 Offset,

+    IN  UINT8                 *Buffer,

+    UINT32                   ulLength

+    );

+

+typedef 

+EFI_STATUS

+(EFIAPI *UNI_FLASH_READ_INTERFACE) (

+    IN UNI_NOR_FLASH_PROTOCOL   *This,

+    IN UINT32                  Offset,

+    IN OUT UINT8              *Buffer,

+    IN UINT32                   ulLen

+    );

+

+typedef

+EFI_STATUS 

+(EFIAPI *UNI_FLASH_GetFlashInfo_INTERFACE) (

+    IN  UNI_NOR_FLASH_PROTOCOL *This,

+    OUT  NOR_FLASH_INFO_TABLE     *FlashInfo

+  );

+

+typedef 

+EFI_STATUS

+(EFIAPI *UNI_FLASH_DIRECT_WRITE_INTERFACE) (

+    IN UNI_NOR_FLASH_PROTOCOL   *This,

+    IN  UINT32                 Offset,

+    IN  UINT8                 *Buffer,

+    UINT32                   ulLength

+    );

+typedef 

+EFI_STATUS

+(EFIAPI *UNI_FLASH_GET_MANUID_INTERFACE) (

+    IN UNI_NOR_FLASH_PROTOCOL   *This,

+    IN  UINT32                 *ManuID

+    );

+

+typedef 

+VOID

+(EFIAPI *UNI_FLASH_CHECK_PROTECT_INTERFACE) (

+    IN  UNI_NOR_FLASH_PROTOCOL *This

+);

+

+struct _UNI_NOR_FLASH_PROTOCOL {

+    UNI_FLASH_ERASE_INTERFACE             Erase;

+    UNI_FLASH_WRITE_INTERFACE             Write;

+    UNI_FLASH_READ_INTERFACE              Read;

+    UNI_FLASH_GetFlashInfo_INTERFACE      GetFlashInfo;

+    UNI_FLASH_CHECK_PROTECT_INTERFACE     CheckFlashProtectFlag;

+    UNI_FLASH_DIRECT_WRITE_INTERFACE      DirectWrite;

+    UNI_FLASH_GET_MANUID_INTERFACE        GetManuID;

+};

+

+extern EFI_GUID gUniNorFlashProtocolGuid;

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Include/Protocol/WatchDogProtocol.h b/uefi/linaro-edk2/HisiPkg/Include/Protocol/WatchDogProtocol.h
new file mode 100644
index 0000000..44f09cb
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Include/Protocol/WatchDogProtocol.h
@@ -0,0 +1,61 @@
+/***************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 _WATCH_DOG_PROTOCOL_H_

+#define _WATCH_GOG_PROTOCOL_H_

+

+#define OEM_WATCH_DOG_PROTOCOL_GUID \

+    {0x707ac059, 0xf335, 0x4643, 0xa6, 0x99, 0x5e, 0x3b, 0x9b, 0x82, 0x60, 0x74}

+	

+

+typedef struct _OEM_WATCH_DOG_PROTOCOL   OEM_WATCH_DOG_PROTOCOL;

+

+typedef

+EFI_STATUS

+(EFIAPI * WATCH_DOG_AUTO_CLEAR_START)(void);

+

+typedef

+EFI_STATUS

+(EFIAPI * WATCH_DOG_AUTO_CLEAR_STOP)(void);

+

+typedef

+EFI_STATUS

+(EFIAPI * WATCH_DOG_FEED_TIME_EXTEND)(UINT32 ulMin);

+

+typedef

+EFI_STATUS

+(EFIAPI * WATCH_DOG_FEED_TIME_RESTORE)(UINT32 ulMin);

+typedef

+VOID

+(EFIAPI * WATCH_DOG_DIAGNOSE_MODE_ENTER)(void);

+

+typedef

+VOID

+(EFIAPI * WATCH_DOG_DIAGNOSE_MODE_EXIT)(void);

+

+

+typedef struct _OEM_WATCH_DOG_PROTOCOL

+{

+    WATCH_DOG_AUTO_CLEAR_START     WtdAutoClearStart;

+    WATCH_DOG_AUTO_CLEAR_STOP       WtdAutoClearStop;

+    WATCH_DOG_FEED_TIME_EXTEND      WtdFeedTimeExtend;

+    WATCH_DOG_FEED_TIME_RESTORE     WtdFeedTimeRestore;

+    WATCH_DOG_DIAGNOSE_MODE_ENTER WtdDiagnoseModeEnter;

+    WATCH_DOG_DIAGNOSE_MODE_EXIT   WtdDiagnoseModeExit;

+    	

+} OEM_WATCH_DOG_PROTOCOL;

+

+#define GLOBAL_VARIABLE_WTD_OF_TIME   L"WTDOverFlowTime"

+

+#endif

diff --git a/uefi/linaro-edk2/HisiPkg/Library/BspUartLib/BspUartLib.c b/uefi/linaro-edk2/HisiPkg/Library/BspUartLib/BspUartLib.c
new file mode 100644
index 0000000..7c313d3
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/BspUartLib/BspUartLib.c
@@ -0,0 +1,159 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 "BspUartLib.h"

+#include "BrdCommon.h"

+#include "config.h"

+#include <Library/DebugLib.h>

+#include <Library/ResetWdtLib.h>

+#include <Library/DebugLib.h>

+

+

+#define BSP_UartDelay(loop) delayuart(2 * loop)

+void delayuart(unsigned long ulCount)

+{

+    unsigned int ulRet, ulNumber;

+    for(ulRet = 0; ulRet < 2; ulRet++)

+    {

+        ulNumber = ulCount;

+        while ( ulNumber-- )

+        {

+            ;

+        }

+    }

+}

+

+

+UINT8 ROM_UartChkSndEnd(void)

+{

+    if(!(*(volatile UINT8 *)UART_LSR_REG & UART_LSR_THRE))

+    {

+        WDT_ResetWatchdog();

+        return 0;

+    }

+    else

+    {

+        return 1;

+    }

+}

+

+void ROM_UartSendChar(UINT8 scShowChar)

+{

+    UINT32 i = 0;

+

+    while(i < UART_SEND_DELAY)

+    {

+        WDT_ResetWatchdog();

+        if ((*(volatile UINT8 *)(UART_USR_REG) & UART_USR_TFNF) == UART_USR_TFNF)

+        {

+            break;

+        }

+        i++;

+    }

+

+    *(volatile UINT8 *)(UART_THR_REG) = scShowChar;

+

+

+    i = 0;

+    while (i < UART_SEND_DELAY)

+    {

+        if (ROM_UartChkSndEnd())

+        {

+            break;

+        }

+        i++;

+    }

+

+    return;

+

+}

+

+void BspSendUintHex(register UINT32 ulData)

+{

+    INT8 Buff[8];

+    INT32 i;

+    UINT32 uTemp = 0x0f;

+

+    for(i = 0; i < 8; i++)

+    {

+        Buff[i] = ((INT8)(ulData & uTemp));

+        ulData = ulData >> 4;

+    }

+

+    ROM_UartSendChar('0');

+    ROM_UartSendChar('x');

+

+    for(i = 0; i < 8; i++)

+    {

+        if(Buff[7 - i] < (char)10)

+        {

+            Buff[7 - i] += '0';

+            ROM_UartSendChar(Buff[7 - i]);

+        }

+        else

+        {

+            Buff[7 - i] = Buff[7 - i] - 10 + 'A';

+            ROM_UartSendChar(Buff[7-i]);

+        }

+    }

+    return;

+

+}

+

+void BspSendString(char *pShow)

+{

+    if( NULL == pShow)

+    {

+        return;

+    }

+    while( *((char *)pShow) )

+    {

+        WDT_ResetWatchdog();

+        ROM_UartSendChar( * ( (char *) pShow ) );

+        pShow++;

+    }

+    return;

+}

+

+char BspGetChar(UINT32 ulTimeOut)

+{

+    UINT32 i = 0;

+    register UINT8 recvchar = 0;

+    for(;;)

+    {

+        if ((*(UINT8 *)(UART_LSR_REG) & UART_LSR_DR) == UART_LSR_DR)

+        {

+            break;

+        }

+        WDT_ResetWatchdog();

+

+        if (i > ulTimeOut)

+        {

+            WDT_ResetWatchdog();

+            return recvchar;

+        }

+        

+        BSP_UartDelay(10000);

+        

+        i++;

+	}

+    recvchar = (*(volatile UINT8 *)(UART_RBR_REG));

+

+    *(volatile UINT8 *)(UART_THR_REG) = recvchar;

+

+    return recvchar;

+}

+

+

diff --git a/uefi/linaro-edk2/HisiPkg/Library/BspUartLib/BspUartLib.inf b/uefi/linaro-edk2/HisiPkg/Library/BspUartLib/BspUartLib.inf
new file mode 100644
index 0000000..4b02b7b
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/BspUartLib/BspUartLib.inf
@@ -0,0 +1,41 @@
+#/** @file

+#  

+#  Component discription file for NorFlashDxe module

+#  

+#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = BspUartLib

+  FILE_GUID                      = 16D53EE6-7EA6-47bd-8E2F-511FD9BCABF0

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BspUartLib

+

+

+[Sources.common]

+  BspUartLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  HisiPkg/HisiPlatformPkg.dec

+  

+[LibraryClasses]

+  BaseLib

+  DebugLib

+  DebugAgentLib

+  ResetWdtLib

+  

diff --git a/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo.c b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo.c
new file mode 100644
index 0000000..ce48829
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo.c
@@ -0,0 +1,38 @@
+/***************************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 "PinIo_Api.h"

+#include "config.h"

+extern void D01_PortInit( U32 ulPortNo, U32 ulPinNo, U32 ulDir, U32 ulOpenDrain );

+extern void D01_SetPortLevel( U32 ulPortNo, U32 ulPinNo, U32 ulLevel );

+extern U32 D01_GetPortLevel( U32 ulPortNo, U32 ulPinNo );

+

+#define BSP_OUTPUT 0

+#define BSP_INPUT 1

+

+void PortInit( U32 ulPortNo, U32 ulPinNo, U32 ulDir, U32 ulOpenDrain )

+{

+    D01_PortInit(ulPortNo, ulPinNo, ulDir,ulOpenDrain);

+}

+

+void SetPortLevel( U32 ulPortNo, U32 ulPinNo, U32 ulLevel)

+{

+    /*lint -e553*/

+    D01_SetPortLevel(ulPortNo, ulPinNo, ulLevel);

+}

+U32 GetPortLevel( U32 ulPortNo, U32 ulPinNo )

+{

+    return D01_GetPortLevel(ulPortNo, ulPinNo);

+}

+

diff --git a/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIoLib.inf b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIoLib.inf
new file mode 100644
index 0000000..276e080
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIoLib.inf
@@ -0,0 +1,43 @@
+#/** @file

+#  

+#  Component discription file for NorFlashDxe module

+#  

+#  Copyright (c) 2011, 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                      = PinIoLib

+  FILE_GUID                      = 16D53EC6-7EA6-47Cd-8E2F-512FD9BCA2F0

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PinIoLib

+

+

+[Sources.common]

+  PinIo.c

+  PinIo_D01.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  HisiPkg/HisiPlatformPkg.dec

+  

+[LibraryClasses]

+  BaseLib

+  PcdLib

+

+[FixedPcd]

+  gHwTokenSpaceGuid.PcdGPIO0Base

+

+  

diff --git a/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo_D01.c b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo_D01.c
new file mode 100644
index 0000000..ba0aa16
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo_D01.c
@@ -0,0 +1,98 @@
+/************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 "PinIo_Api.h"

+#include "PinIo_D01.h"

+#ifndef ERROR

+#define ERROR -1

+#endif

+

+

+extern U32  rom_int_lock(void);

+

+extern void rom_int_unlock(U32 ulLock);

+

+void D01_PortInit( U32 ulPortNo, U32 ulPinNo, U32 ulDir, U32 ulOpenDrain )

+{

+    U32 ulRegVal = 0;    

+    HI_CPU_GPIO_REG_READ(ulPortNo,HI_CPU_GPIO_INT_EN_REG,ulRegVal);

+    ulRegVal &= ~ulPinNo;

+    HI_CPU_GPIO_REG_WRITE(ulPortNo,HI_CPU_GPIO_INT_EN_REG,ulRegVal);

+    

+    HI_CPU_GPIO_REG_READ(ulPortNo,HI_CPU_GPIO_DIR_REG,ulRegVal);

+    if (OUTPUT_PIN == ulDir)

+    {

+        ulRegVal |= ulPinNo;

+    }

+    else

+    {

+        ulRegVal &= ~ulPinNo;

+    }    

+    HI_CPU_GPIO_REG_WRITE(ulPortNo,HI_CPU_GPIO_DIR_REG,ulRegVal);

+    

+    return;

+}

+

+void D01_SetPortLevel( U32 ulPortNo, U32 ulPinNo, U32 ulLevel )

+{

+    U32 ulRegVal = 0; 

+    U32 ulLock = 0;

+    

+    ulLock = rom_int_lock();

+    HI_CPU_GPIO_REG_READ(ulPortNo,HI_CPU_GPIO_OUTPUT_REG,ulRegVal);

+    if (LOW_LEVEL == ulLevel)

+    {

+        ulRegVal &= ~ulPinNo;

+    }

+    else

+    {

+        ulRegVal |= ulPinNo;

+    }

+    HI_CPU_GPIO_REG_WRITE(ulPortNo,HI_CPU_GPIO_OUTPUT_REG,ulRegVal);

+

+    

+    HI_CPU_GPIO_REG_READ(ulPortNo,HI_CPU_GPIO_DIR_REG,ulRegVal);

+    ulRegVal |= ulPinNo;

+    HI_CPU_GPIO_REG_WRITE(ulPortNo,HI_CPU_GPIO_DIR_REG,ulRegVal);

+    

+    HI_CPU_GPIO_REG_READ(ulPortNo,HI_CPU_GPIO_OUTPUT_REG,ulRegVal);

+    if (LOW_LEVEL == ulLevel)

+    {

+        ulRegVal &= ~ulPinNo;

+    }

+    else

+    {

+        ulRegVal |= ulPinNo;

+    }

+    HI_CPU_GPIO_REG_WRITE(ulPortNo,HI_CPU_GPIO_OUTPUT_REG,ulRegVal);

+    rom_int_unlock(ulLock);

+}

+U32 D01_GetPortLevel( U32 ulPortNo, U32 ulPinNo )

+{

+    U32 ulRegVal = 0;    

+    HI_CPU_GPIO_REG_READ(ulPortNo,HI_CPU_GPIO_DIR_REG,ulRegVal);

+    ulRegVal &= ~ulPinNo;

+    HI_CPU_GPIO_REG_WRITE(ulPortNo,HI_CPU_GPIO_DIR_REG,ulRegVal);

+    

+    HI_CPU_GPIO_REG_READ(ulPortNo,HI_CPU_GPIO_INPUT_REG,ulRegVal);

+    

+    if (ulRegVal&ulPinNo)

+    {

+        return HIGH_LEVEL;

+    }

+    else

+    {

+        return LOW_LEVEL;

+    }

+}

diff --git a/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo_D01.h b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo_D01.h
new file mode 100644
index 0000000..1d85e6c
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/PinIoLib/PinIo_D01.h
@@ -0,0 +1,115 @@
+/*****************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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.

+#  

+#**/

+

+

+#ifdef __cplusplus

+#if __cplusplus

+extern "C"{

+#endif

+#endif /* __cplusplus */

+

+#ifndef _PINIO_HI1380_H_

+#define _PINIO_HI1380_H_

+#include <Library/PcdLib.h>

+#ifndef HIGH_LEVEL

+#define HIGH_LEVEL 1

+#endif

+#ifndef LOW_LEVEL

+#define LOW_LEVEL  0

+#endif

+    

+#ifndef INPUT_PIN

+#define INPUT_PIN 0

+#endif

+#ifndef OUTPUT_PIN

+#define OUTPUT_PIN 1

+#endif

+

+#define HI1380_GPIO_PORT_NUM    2

+#define HI1380_GPIO0            0

+#define HI1380_GPIO1            1

+

+

+#define HI1210_GPIO_PORT_NUM    4

+#define HI1210_GPIO0            0

+#define HI1210_GPIO1            1

+#define HI1210_GPIO2            2

+#define HI1210_GPIO3            3

+

+

+#define GPIO0      0x00000001

+#define GPIO1      0x00000002

+#define GPIO2      0x00000004

+#define GPIO3      0x00000008

+#define GPIO4      0x00000010

+#define GPIO5      0x00000020

+#define GPIO6      0x00000040

+#define GPIO7      0x00000080

+#define GPIO8      0x00000100

+#define GPIO9      0x00000200

+#define GPIO10     0x00000400

+#define GPIO11     0x00000800

+#define GPIO12     0x00001000

+#define GPIO13     0x00002000

+#define GPIO14     0x00004000

+#define GPIO15     0x00008000

+#define GPIO16     0x00010000                                

+#define GPIO17     0x00020000                                

+#define GPIO18     0x00040000                                

+#define GPIO19     0x00080000                                

+#define GPIO20     0x00100000                                

+#define GPIO21     0x00200000                                

+#define GPIO22     0x00400000                                

+#define GPIO23     0x00800000                                

+#define GPIO24     0x01000000                                

+#define GPIO25     0x02000000                                

+#define GPIO26     0x04000000 

+#define GPIO27     0x08000000 

+#define GPIO28     0x10000000 

+#define GPIO29     0x20000000 

+#define GPIO30     0x40000000 

+#define GPIO31     0x80000000 

+

+

+#define HI_CPU_GPIO_BASE            PcdGet32(PcdGPIO0Base)

+

+#define HI_CPU_GPIO_OUTPUT_REG      (0x0)  

+#define HI_CPU_GPIO_DIR_REG         (0x4)   

+#define HI_CPU_GPIO_PORT_CTRL_REG   (0x8)   

+#define HI_CPU_GPIO_INT_EN_REG      (0x30)  

+#define HI_CPU_GPIO_INT_MASK_REG    (0x34) 

+#define HI_CPU_GPIO_INT_TYPE_REG    (0x38)  

+#define HI_CPU_GPIO_INT_POLARITY    (0x3c)  

+#define HI_CPU_GPIO_INT_CLR_REG     (0x4c)  

+#define HI_CPU_GPIO_INPUT_REG       (0x50) 

+#define HI_CPU_GPIO_SYNC_REG        (0x60) 

+

+#define HI_CPU_GPIO_REG_READ(port,reg,val)\

+{\

+    val = *(volatile U32 *)(HI_CPU_GPIO_BASE + (port)*0x1000 + (reg));\

+}

+

+#define HI_CPU_GPIO_REG_WRITE(port,reg,val)\

+{\

+    *(volatile U32 *)(HI_CPU_GPIO_BASE + (port)*0x1000 + (reg)) = (val);\

+}

+

+#ifdef __cplusplus

+#if __cplusplus

+}

+#endif

+#endif /* __cplusplus */

+

+#endif

+

diff --git a/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.c b/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.c
new file mode 100644
index 0000000..93cf04a
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.c
@@ -0,0 +1,311 @@
+/** @file

+  UART Serial Port library functions

+

+  Copyright (c) 2006 - 2009, Intel Corporation

+  All rights reserved. 

+  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 <Base.h>

+#include <Library/SerialPortLib.h>

+#include "SerialPortLib.h"

+#include <Uefi/UefiBaseType.h>

+#include <Protocol/SerialIo.h>

+

+VOID SerialInit(VOID)

+{

+    UINT32 ulUartClkFreq;

+

+    *(volatile UINT32 *)(UART_LCR_REG) = UART_LCR_DLS8;

+

+    *(volatile UINT32 *)(UART_FCR_REG) = UART_FCR_EN | UART_FCR_RXCLR | UART_FCR_TXCLR;

+

+    *(volatile UINT32 *)(UART_LCR_REG) = UART_LCR_DLAB | UART_LCR_DLS8;

+

+    ulUartClkFreq = TCXO_CLK_FREQ;

+

+    *(volatile UINT32 *)(UART_DLL_REG) = (ulUartClkFreq / (16 * BAUDRATE) ) & 0xff;

+    *(volatile UINT32 *)(UART_DLH_REG) = ((ulUartClkFreq/ (16 * BAUDRATE) ) >> 8 ) & 0xff;

+

+    *(volatile UINT32 *)(UART_LCR_REG) = UART_LCR_DLS8;

+

+    *(volatile UINT32 *)(UART_IEL_REG) = 0x00;

+

+    *(volatile UINT32 *)(UART_THR_REG) = 0x53;

+

+    return ;

+

+}

+

+

+/**

+  Initialize the serial device hardware.

+  

+  If no initialization is required, then return RETURN_SUCCESS.

+  If the serial device was successfuly initialized, then return RETURN_SUCCESS.

+  If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.

+  

+  @retval RETURN_SUCCESS        The serial device was initialized.

+  @retval RETURN_DEVICE_ERROR   The serail device could not be initialized.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortInitialize (

+  VOID

+  )

+{

+    return RETURN_SUCCESS;

+}

+

+

+UINT8 UART_ChkSndEnd(VOID)

+{

+    if(!(*(UINT8 *)UART_LSR_REG & UART_LSR_THRE))

+    {

+        return 0;

+    }

+    else

+    {

+        return 1;

+    }

+}

+

+/**

+  Write data from buffer to serial device. 

+ 

+  Writes NumberOfBytes data bytes from Buffer to the serial device.  

+  The number of bytes actually written to the serial device is returned.

+  If the return value is less than NumberOfBytes, then the write operation failed.

+

+  If Buffer is NULL, then ASSERT(). 

+

+  If NumberOfBytes is zero, then return 0.

+

+  @param  Buffer           Pointer to the data buffer to be written.

+  @param  NumberOfBytes    Number of bytes to written to the serial device.

+

+  @retval 0                NumberOfBytes is 0.

+  @retval >0               The number of bytes written to the serial device.  

+                           If this value is less than NumberOfBytes, then the read operation failed.

+

+**/

+UINTN

+EFIAPI

+SerialPortWrite (

+  IN UINT8     *Buffer,

+  IN UINTN     NumberOfBytes

+)

+{

+  UINTN  Result;

+

+  if (Buffer == NULL) {

+    return 0;

+  }

+

+  Result = NumberOfBytes;

+

+  while (NumberOfBytes--) {

+

+    SerialPortWriteChar(*Buffer);

+    Buffer++;

+  }

+

+  return Result;

+}

+

+

+/**

+  Reads data from a serial device into a buffer.

+

+  @param  Buffer           Pointer to the data buffer to store the data read from the serial device.

+  @param  NumberOfBytes    Number of bytes to read from the serial device.

+

+  @retval 0                NumberOfBytes is 0.

+  @retval >0               The number of bytes read from the serial device.  

+                           If this value is less than NumberOfBytes, then the read operation failed.

+

+**/

+UINTN

+EFIAPI

+SerialPortRead (

+  OUT UINT8     *Buffer,

+  IN  UINTN     NumberOfBytes

+)

+{

+  UINTN  Result;

+

+  if (NULL == Buffer) {

+    return 0;

+  }

+

+  Result = NumberOfBytes;

+

+  while (NumberOfBytes--) {

+    //

+    // Wait for the serail port to be ready.

+    //

+    *Buffer=SerialPortReadChar();

+    Buffer++ ;

+  }

+

+  return Result;

+}

+

+/**

+  Polls a serial device to see if there is any data waiting to be read.

+

+  Polls aserial device to see if there is any data waiting to be read.

+  If there is data waiting to be read from the serial device, then TRUE is returned.

+  If there is no data waiting to be read from the serial device, then FALSE is returned.

+

+  @retval TRUE             Data is waiting to be read from the serial device.

+  @retval FALSE            There is no data waiting to be read from the serial device.

+

+**/

+BOOLEAN

+EFIAPI

+SerialPortPoll (

+  VOID

+  )

+{

+  return (BOOLEAN) ((*(volatile UINT8 *)(UART_LSR_REG) & UART_LSR_DR) == UART_LSR_DR);

+

+}

+

+VOID SerialPortWriteChar(UINT8 scShowChar)

+{

+    UINT32 ulLoop = 0;

+      

+    while(ulLoop < UART_SEND_DELAY)

+    {

+        if ((*(volatile UINT8 *)(UART_USR_REG) & UART_FCR_RXCLR) == UART_FCR_RXCLR)

+        {

+            break;

+        }

+        

+        ulLoop++;

+    }

+    *(volatile UINT8 *)(UART_THR_REG) = (UINT8)scShowChar;

+

+    ulLoop = 0;

+    while(ulLoop < UART_SEND_DELAY)

+    {

+        if ((*(volatile UINT8 *)(UART_USR_REG) & UART_FCR_TXCLR) == UART_FCR_TXCLR)

+        {

+            break;

+        }

+        ulLoop++;

+    }

+           

+    return;

+}

+

+

+UINT8 SerialPortReadChar(VOID)

+{

+    UINT8 recvchar = 0;

+

+    do

+    {

+        if ((*(volatile UINT8 *)(UART_LSR_REG) & UART_LSR_DR) == UART_LSR_DR)

+        {

+            break;

+        }

+    }while(1);

+

+    recvchar = (*(volatile UINT8 *)(UART_RBR_REG)); 

+    

+    return recvchar;

+}

+

+/**

+  Set new attributes to PL011.

+

+  @param  BaudRate                The baud rate of the serial device. If the baud rate is not supported,

+                                  the speed will be reduced down to the nearest supported one and the

+                                  variable's value will be updated accordingly.

+  @param  ReceiveFifoDepth        The number of characters the device will buffer on input. If the specified

+                                  value is not supported, the variable's value will be reduced down to the

+                                  nearest supported one.

+  @param  Timeout                 If applicable, the number of microseconds the device will wait

+                                  before timing out a Read or a Write operation.

+  @param  Parity                  If applicable, this is the EFI_PARITY_TYPE that is computer or checked

+                                  as each character is transmitted or received. If the device does not

+                                  support parity, the value is the default parity value.

+  @param  DataBits                The number of data bits in each character

+  @param  StopBits                If applicable, the EFI_STOP_BITS_TYPE number of stop bits per character.

+                                  If the device does not support stop bits, the value is the default stop

+                                  bit value.

+

+  @retval EFI_SUCCESS             All attributes were set correctly on the serial device.

+  @retval EFI_INVALID_PARAMETERS  One or more of the attributes has an unsupported value.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortSetAttributes (

+  IN UINT64              BaudRate,

+  IN UINT32              ReceiveFifoDepth,

+  IN UINT32              Timeout,

+  IN EFI_PARITY_TYPE     Parity,

+  IN UINT8               DataBits,

+  IN EFI_STOP_BITS_TYPE  StopBits

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  Set the serial device control bits.

+

+  @param  Control                 Control bits which are to be set on the serial device.

+

+  @retval EFI_SUCCESS             The new control bits were set on the serial device.

+  @retval EFI_UNSUPPORTED         The serial device does not support this operation.

+  @retval EFI_DEVICE_ERROR        The serial device is not functioning correctly.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortSetControl (

+  IN UINT32                  Control

+  )

+{

+  return EFI_UNSUPPORTED;

+}

+

+/**

+  Get the serial device control bits.

+

+  @param  Control                 Control signals read from the serial device.

+

+  @retval EFI_SUCCESS             The control bits were read from the serial device.

+  @retval EFI_DEVICE_ERROR        The serial device is not functioning correctly.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortGetControl (

+  OUT UINT32                  *Control

+  )

+{

+    

+    if (SerialPortPoll ()) {

+        // If a character is pending don't set EFI_SERIAL_INPUT_BUFFER_EMPTY

+        *Control = EFI_SERIAL_OUTPUT_BUFFER_EMPTY;

+    } else {

+        *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY | EFI_SERIAL_OUTPUT_BUFFER_EMPTY;

+    }

+    return EFI_SUCCESS;

+  //return EFI_UNSUPPORTED;

+}

+

diff --git a/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.h b/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.h
new file mode 100644
index 0000000..b8f6f59
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.h
@@ -0,0 +1,109 @@
+/*******************************************************************

+#

+#  

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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 __HISIARM_SERIAL_PORT__

+#define __HISIARM_SERIAL_PORT__

+

+#include <Library/PcdLib.h>

+#define UART_USED_CHANNELS      1

+#define TCXO_CLK_FREQ           168750000

+#define SERIAL_0_BASE_ADR       0xe4007000

+#define REG_VAL                 (*(UINT32 *)0x118) & 0xffff

+#define UART_SEND_DELAY         500000

+#define BAUDRATE                115200

+

+

+#define UART_THR_REG         (SERIAL_0_BASE_ADR + UART_RBR)

+#define UART_RBR_REG         (SERIAL_0_BASE_ADR + UART_THR)

+#define UART_DLL_REG         (SERIAL_0_BASE_ADR + UART_DLL)

+#define UART_DLH_REG         (SERIAL_0_BASE_ADR + UART_DLH)

+#define UART_IEL_REG         (SERIAL_0_BASE_ADR + UART_IEL)

+#define UART_IIR_REG         (SERIAL_0_BASE_ADR + UART_IIR)

+#define UART_FCR_REG         (SERIAL_0_BASE_ADR + UART_FCR)

+#define UART_LCR_REG         (SERIAL_0_BASE_ADR + UART_LCR)

+#define UART_LSR_REG         (SERIAL_0_BASE_ADR + UART_LSR)

+#define UART_USR_REG         (SERIAL_0_BASE_ADR + UART_USR)

+

+#define UART_RBR     0x00       

+#define UART_THR     0x00       

+#define UART_DLL     0x00        

+#define UART_DLH     0x04         

+#define UART_IEL     0x04        

+#define UART_IIR     0x08          

+#define UART_FCR     0x08       

+#define UART_LCR     0x0C          

+#define UART_MCR     0x10          

+#define UART_LSR     0x14          

+#define UART_USR     0x7C          

+

+/* register definitions */

+

+#define UART_FCR_EN		     0x01		

+#define UART_FCR_RXCLR       0x02	

+#define UART_FCR_TXCLR       0x04	

+#define UART_FCR_CLEARFIFO   0x00     

+#define UART_FCR_RXL1        0x00

+#define UART_FCR_RXL4        0x40

+#define UART_FCR_RXL8        0x80

+#define UART_FCR_RXL14       0xc0

+#define UART_FCR_TXL0        0x00

+#define UART_FCR_TXL4        0x20

+#define UART_FCR_TXL8        0x30

+#define UART_FCR_TXL14       0x10

+

+#define UART_LCR_DLAB   0x80    

+#define UART_LCR_EPS    0x10   

+#define UART_LCR_PEN    0x08   

+#define UART_LCR_STOP   0x04   

+#define UART_LCR_DLS8   0x03   

+#define UART_LCR_DLS7   0x02   

+#define UART_LCR_DLS6   0x01   

+#define UART_LCR_DLS5   0x00  

+

+#define UART_DLH_AND_DLL_WIDTH 0xFF 

+

+#define UART_IER_PTIME  0x80   

+#define UART_IER_ELSI   0x04   

+#define UART_IER_ETBEI  0x02   

+#define UART_IER_ERBFI  0x01  

+#define UART_IIR_FIFOSE         0xC0  

+

+#define UART_IIR_InterruptID   0x01    

+#define UART_IIR_INTIDTE       0x02

+#define UART_IIR_INTIDRA       0x04

+#define UART_IIR_INTIDRLS      0x06

+#define UART_IIR_INTMASK       0x0f

+#define UART_IIR_RDA           0x04

+#define UART_IIR_TE            0x02

+#define UART_LSR_TEMT       0x40   

+#define UART_LSR_THRE       0x20    

+#define UART_LSR_BI         0x10   

+#define UART_LSR_FE         0x08   

+#define UART_LSR_PE         0x04    

+#define UART_LSR_R          0x02  

+#define UART_LSR_DR         0x01  

+

+

+#define UART_USR_BUSY  0x01  

+

+#define FIFO_MAXSIZE    16     

+

+

+extern UINT32 UART_UartClkFreq(VOID);

+extern UINT8 UART_ChkSndEnd(VOID);

+extern UINT8 SerialPortReadChar(VOID);

+extern VOID SerialPortWriteChar(UINT8 scShowChar);

+

+#endif

+

diff --git a/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.inf b/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.inf
new file mode 100644
index 0000000..5b75735
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/Library/SerialPortLib/SerialPortLib.inf
@@ -0,0 +1,36 @@
+#/** @file

+#  

+#  Component discription file for NorFlashDxe module

+#  

+#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>

+#  Copyright (c) Huawei Technologies Co., Ltd. 2013. 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                    = 0x00010005

+  BASE_NAME                      = SerialPortLib

+  FILE_GUID                      = 16D53E86-7EA6-47bd-861F-511ED9B8ABE0

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SerialPortLib

+

+

+[Sources.common]

+  SerialPortLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  ArmPlatformPkg/ArmPlatformPkg.dec

+  

+[LibraryClasses]

+  BaseLib

diff --git a/uefi/linaro-edk2/HisiPkg/README b/uefi/linaro-edk2/HisiPkg/README
new file mode 100644
index 0000000..d4e8517
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/README
@@ -0,0 +1,49 @@
+

+=== D01Board OVERVIEW ===

+

+The project aims to support UEFI for D01 Board using the edk2

+code base.

+

+=== STATUS ===

+

+Current capabilities:

+* Uefi Boot from NORFLASH

+

+=== FUTURE PLANS ===

+

+* Support for PXE, SATA, ACPI, USB

+  - KeyBoard, Mouse and MassStorage

+

+=== BUILDING D01 Board ===

+

+Pre-requisites:

+* Build environment capable of build the edk2 MdeModulePkg.

+* A properly configured ASL compiler:

+  - Intel ASL compiler: Available from http://www.acpica.org

+  - Microsoft ASL compiler: Available from http://www.acpi.info

+

+Build the D01BoardPkg by running from the Workspace

+If you are using armcc as your compiler, you can build the project:

+build -D BIOS_L1 -p HisiPkg/D01BoardPkg/D01BoardPkg.dsc -b DEBUG

+If you are using gcc as your compiler, you can build the project:

+ ./uefi-build.sh -b DEBUG d01

+

+Following the edk2 build process, you will find the D01 binaries

+under the $WORKSPACE/Build/*/*/FV directory. You can find the below

+mentioned binary image.

+D01.fd

+

+=== RUNNING D01BoardPkg on the D01 board ===

+* If you can enter into the shell, connet the network cable from the D01 device to the PC terminal

+* Write BIOS to NORFLASH by using comands as follows:

+D01 >ifconfig -s eth0 192.168.10.50 255.255.255.0 192.168.10.1

+D01 >provision 192.168.10.100  -u admin -p admin -f norflash_header

+D01 >writefiletonor 0 norflash_header

+D01 >provision 192.168.10.100  -u admin -p admin -f D01.fd

+D01 >updateL1 D01.fd

+* If the NORFLASH in your board have nothing, you should adopt other method such as JTAG

+* Now the booting device is ready to be used.

+* Connect the Uart cable from the D01 device to the PC terminal.

+* Power ON the Device.

+* The boot message should be visible on the termial.

+* Finally, it should give boot options.

diff --git a/uefi/linaro-edk2/HisiPkg/norflash_header b/uefi/linaro-edk2/HisiPkg/norflash_header
new file mode 100644
index 0000000..83a8818
--- /dev/null
+++ b/uefi/linaro-edk2/HisiPkg/norflash_header
Binary files differ