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