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/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.c b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.c
new file mode 100644
index 0000000..50a4b47
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.c
@@ -0,0 +1,103 @@
+/** @file
+*
+* Copyright (c) 2011, 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 "LinuxInternal.h"
+
+#include <Library/PrintLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the application.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ LINUX_LOADER_OPTIONAL_DATA* LinuxOptionalData;
+ EFI_DEVICE_PATH* DevicePathKernel;
+ EFI_DEVICE_PATH* InitrdDevicePath;
+ CHAR16* OptionalDataInitrd;
+ CHAR8* OptionalDataArguments;
+ CHAR16* Initrd;
+
+ Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
+ ASSERT_EFI_ERROR (Status);
+
+ if (LoadedImage->LoadOptionsSize == 0) {
+ Status = LinuxLoaderConfig (LoadedImage);
+ } else {
+ // Ensure the signature is correct
+ LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)LoadedImage->LoadOptions;
+ if (LinuxOptionalData->Signature != LINUX_LOADER_SIGNATURE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Generate the File Path Node for the Linux Kernel
+ DevicePathKernel = FileDevicePath (LoadedImage->DeviceHandle, LINUX_KERNEL_NAME);
+
+ if (LinuxOptionalData->CmdLineLength > 0) {
+ OptionalDataArguments = (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);
+ } else {
+ OptionalDataArguments = NULL;
+ }
+
+ if (LinuxOptionalData->InitrdPathListLength > 0) {
+ if (OptionalDataArguments != NULL) {
+ OptionalDataInitrd = (CHAR16*)(OptionalDataArguments + LinuxOptionalData->CmdLineLength);
+ } else {
+ OptionalDataInitrd = (CHAR16*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);
+ }
+
+ // If pointer not aligned
+ if ((UINTN)OptionalDataInitrd & 0x1) {
+ Initrd = (CHAR16*)AllocateCopyPool (LinuxOptionalData->InitrdPathListLength, OptionalDataInitrd);
+ } else {
+ Initrd = OptionalDataInitrd;
+ }
+
+ InitrdDevicePath = FileDevicePath (LoadedImage->DeviceHandle, Initrd);
+ } else {
+ OptionalDataInitrd = NULL;
+ InitrdDevicePath = NULL;
+ Initrd = NULL;
+ }
+
+ // Load and Start the Linux Kernel (we should never return)
+ Status = BdsBootLinuxAtag (DevicePathKernel, InitrdDevicePath, OptionalDataArguments);
+
+ if ((UINTN)OptionalDataInitrd & 0x1) {
+ FreePool (Initrd);
+ }
+
+ FreePool (DevicePathKernel);
+ if (InitrdDevicePath) {
+ FreePool (InitrdDevicePath);
+ }
+ }
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf
new file mode 100644
index 0000000..dcc2597
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf
@@ -0,0 +1,39 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = LinuxAtagLoader
+ FILE_GUID = a912f198-7f0e-4803-b908-b757b806ec83
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 0.1
+ ENTRY_POINT = UefiMain
+
+[Sources]
+ LinuxAtagLoader.c
+ LinuxConfig.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BdsLib
+ DxeServicesTableLib
+ UefiLib
+ UefiApplicationEntryPoint
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid
+ gEfiDevicePathToTextProtocolGuid
+
diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxConfig.c b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxConfig.c
new file mode 100644
index 0000000..c88dc65
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxConfig.c
@@ -0,0 +1,354 @@
+/** @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 "LinuxInternal.h"
+
+#define DEFAULT_BOOT_ENTRY_DESCRIPTION L"Linux"
+#define MAX_STR_INPUT 300
+#define MAX_ASCII_INPUT 300
+
+typedef enum {
+ LINUX_LOADER_NEW = 1,
+ LINUX_LOADER_UPDATE
+} LINUX_LOADER_ACTION;
+
+STATIC
+EFI_STATUS
+EditHIInputStr (
+ IN OUT CHAR16 *CmdLine,
+ IN UINTN MaxCmdLine
+ )
+{
+ UINTN CmdLineIndex;
+ UINTN WaitIndex;
+ CHAR8 Char;
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+
+ Print (CmdLine);
+
+ 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"\n\r");
+
+ 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 {
+ CmdLine[CmdLineIndex++] = Key.UnicodeChar;
+ Print (L"%c", Key.UnicodeChar);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+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);
+
+ UnicodeStrToAsciiStr (Str, CmdLine);
+ FreePool (Str);
+
+ return Status;
+}
+
+STATIC
+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;
+}
+
+#if 0
+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;
+}
+#endif
+
+EFI_STATUS
+LinuxLoaderConfig (
+ IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage
+ )
+{
+ EFI_STATUS Status;
+ LINUX_LOADER_ACTION Choice;
+ UINTN BootOrderSize;
+ UINT16* BootOrder;
+ UINTN BootOrderCount;
+ UINTN Index;
+ CHAR16 Description[MAX_ASCII_INPUT];
+ CHAR8 CmdLine[MAX_ASCII_INPUT];
+ CHAR16 Initrd[MAX_STR_INPUT];
+ UINT16 InitrdPathListLength;
+ UINT16 CmdLineLength;
+ BDS_LOAD_OPTION* BdsLoadOption;
+ BDS_LOAD_OPTION** SupportedBdsLoadOptions;
+ UINTN SupportedBdsLoadOptionCount;
+ LINUX_LOADER_OPTIONAL_DATA* LinuxOptionalData;
+ EFI_DEVICE_PATH* DevicePathRoot;
+
+ Choice = (LINUX_LOADER_ACTION)0;
+ SupportedBdsLoadOptions = NULL;
+ SupportedBdsLoadOptionCount = 0;
+
+ do {
+ Print (L"[%d] Create new Linux Boot Entry\n",LINUX_LOADER_NEW);
+ Print (L"[%d] Update Linux Boot Entry\n",LINUX_LOADER_UPDATE);
+
+ Print (L"Option: ");
+ Status = GetHIInputInteger ((UINTN*)&Choice);
+ if (Status == EFI_INVALID_PARAMETER) {
+ Print (L"\n");
+ return Status;
+ } else if ((Choice != LINUX_LOADER_NEW) && (Choice != LINUX_LOADER_UPDATE)) {
+ Print (L"Error: the option should be either '%d' or '%d'\n",LINUX_LOADER_NEW,LINUX_LOADER_UPDATE);
+ Status = EFI_INVALID_PARAMETER;
+ }
+ } while (EFI_ERROR(Status));
+
+ if (Choice == LINUX_LOADER_UPDATE) {
+ // If no compatible entry then we just create a new entry
+ Choice = LINUX_LOADER_NEW;
+
+ // Scan the OptionalData of every entry for the correct signature
+ Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);
+ if (!EFI_ERROR(Status)) {
+ BootOrderCount = BootOrderSize / sizeof(UINT16);
+
+ // Allocate an array to handle maximum number of supported Boot Entry
+ SupportedBdsLoadOptions = (BDS_LOAD_OPTION**)AllocatePool(sizeof(BDS_LOAD_OPTION*) * BootOrderCount);
+
+ SupportedBdsLoadOptionCount = 0;
+
+ // Check if the signature is present in the list of the current Boot entries
+ for (Index = 0; Index < BootOrderCount; Index++) {
+ Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption);
+ if (!EFI_ERROR(Status)) {
+ if ((BdsLoadOption->OptionalDataSize >= sizeof(UINT32)) &&
+ (*(UINT32*)BdsLoadOption->OptionalData == LINUX_LOADER_SIGNATURE)) {
+ SupportedBdsLoadOptions[SupportedBdsLoadOptionCount++] = BdsLoadOption;
+ Choice = LINUX_LOADER_UPDATE;
+ }
+ }
+ }
+ }
+ FreePool (BootOrder);
+ }
+
+ if (Choice == LINUX_LOADER_NEW) {
+ Description[0] = '\0';
+ CmdLine[0] = '\0';
+ Initrd[0] = '\0';
+
+ BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));
+
+ 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 (LoadedImage->FilePath, TRUE, TRUE);
+
+ Print(L"EFI OS Loader: %s\n",DevicePathTxt);
+
+ FreePool(DevicePathTxt);
+ DEBUG_CODE_END();
+
+ //
+ // Fill the known fields of BdsLoadOption
+ //
+
+ BdsLoadOption->Attributes = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT;
+
+ // Get the full Device Path for this file
+ Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathRoot);
+ ASSERT_EFI_ERROR(Status);
+
+ BdsLoadOption->FilePathList = AppendDevicePath (DevicePathRoot, LoadedImage->FilePath);
+ BdsLoadOption->FilePathListLength = GetDevicePathSize (BdsLoadOption->FilePathList);
+ } else {
+ if (SupportedBdsLoadOptionCount > 1) {
+ for (Index = 0; Index < SupportedBdsLoadOptionCount; Index++) {
+ Print (L"[%d] %s\n",Index + 1,SupportedBdsLoadOptions[Index]->Description);
+ }
+
+ do {
+ Print (L"Update Boot Entry: ");
+ Status = GetHIInputInteger ((UINTN*)&Choice);
+ if (Status == EFI_INVALID_PARAMETER) {
+ Print (L"\n");
+ return Status;
+ } else if ((Choice < 1) && (Choice > SupportedBdsLoadOptionCount)) {
+ Print (L"Choose entry from 1 to %d\n",SupportedBdsLoadOptionCount);
+ Status = EFI_INVALID_PARAMETER;
+ }
+ } while (EFI_ERROR(Status));
+ BdsLoadOption = SupportedBdsLoadOptions[Choice-1];
+ }
+ StrnCpy (Description, BdsLoadOption->Description, MAX_STR_INPUT);
+
+ LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)BdsLoadOption->OptionalData;
+ if (LinuxOptionalData->CmdLineLength > 0) {
+ CopyMem (CmdLine, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA), LinuxOptionalData->CmdLineLength);
+ } else {
+ CmdLine[0] = '\0';
+ }
+
+ if (LinuxOptionalData->InitrdPathListLength > 0) {
+ CopyMem (Initrd, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA) + LinuxOptionalData->CmdLineLength, LinuxOptionalData->InitrdPathListLength);
+ } else {
+ Initrd[0] = L'\0';
+ }
+ DEBUG((EFI_D_ERROR,"L\n"));
+ }
+
+ // Description
+ Print (L"Description: ");
+ Status = EditHIInputStr (Description, MAX_STR_INPUT);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if (StrLen (Description) == 0) {
+ StrnCpy (Description, DEFAULT_BOOT_ENTRY_DESCRIPTION, MAX_STR_INPUT);
+ }
+ BdsLoadOption->Description = Description;
+
+ // CmdLine
+ Print (L"Command Line: ");
+ Status = EditHIInputAscii (CmdLine, MAX_ASCII_INPUT);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Initrd
+ Print (L"Initrd name: ");
+ Status = EditHIInputStr (Initrd, MAX_STR_INPUT);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ CmdLineLength = AsciiStrLen (CmdLine);
+ if (CmdLineLength > 0) {
+ CmdLineLength += sizeof(CHAR8);
+ }
+
+ InitrdPathListLength = StrLen (Initrd) * sizeof(CHAR16);
+ if (InitrdPathListLength > 0) {
+ InitrdPathListLength += sizeof(CHAR16);
+ }
+
+ BdsLoadOption->OptionalDataSize = sizeof(LINUX_LOADER_OPTIONAL_DATA) + CmdLineLength + InitrdPathListLength;
+
+ LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)AllocatePool (BdsLoadOption->OptionalDataSize);
+ BdsLoadOption->OptionalData = LinuxOptionalData;
+
+ LinuxOptionalData->Signature = LINUX_LOADER_SIGNATURE;
+ LinuxOptionalData->CmdLineLength = CmdLineLength;
+ LinuxOptionalData->InitrdPathListLength = InitrdPathListLength;
+
+ if (CmdLineLength > 0) {
+ CopyMem (LinuxOptionalData + 1, CmdLine, CmdLineLength);
+ }
+ if (InitrdPathListLength > 0) {
+ CopyMem ((UINT8*)(LinuxOptionalData + 1) + CmdLineLength, Initrd, InitrdPathListLength);
+ }
+
+ // Create or Update the boot entry
+ Status = BootOptionToLoadOptionVariable (BdsLoadOption);
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.c b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.c
new file mode 100644
index 0000000..07d0ea7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.c
@@ -0,0 +1,105 @@
+/** @file
+*
+* Copyright (c) 2011, 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 "LinuxInternal.h"
+
+#include <Library/PrintLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the application.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ LINUX_LOADER_OPTIONAL_DATA* LinuxOptionalData;
+ EFI_DEVICE_PATH* DevicePathKernel;
+ EFI_DEVICE_PATH* DevicePathFdt;
+ EFI_DEVICE_PATH* InitrdDevicePath;
+ CHAR16* OptionalDataInitrd;
+ CHAR8* OptionalDataArguments;
+ CHAR16* Initrd;
+
+ Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
+ ASSERT_EFI_ERROR (Status);
+
+ if (LoadedImage->LoadOptionsSize == 0) {
+ Status = LinuxLoaderConfig (LoadedImage);
+ } else {
+ // Ensure the signature is correct
+ LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)LoadedImage->LoadOptions;
+ if (LinuxOptionalData->Signature != LINUX_LOADER_SIGNATURE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Generate the File Path Node for the Linux Kernel & Device Tree blob
+ DevicePathKernel = FileDevicePath (LoadedImage->DeviceHandle, LINUX_KERNEL_NAME);
+ DevicePathFdt = FileDevicePath (LoadedImage->DeviceHandle, FDT_NAME);
+
+ if (LinuxOptionalData->CmdLineLength > 0) {
+ OptionalDataArguments = (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);
+ } else {
+ OptionalDataArguments = NULL;
+ }
+
+ if (LinuxOptionalData->InitrdPathListLength > 0) {
+ if (OptionalDataArguments != NULL) {
+ OptionalDataInitrd = (CHAR16*)(OptionalDataArguments + LinuxOptionalData->CmdLineLength);
+ } else {
+ OptionalDataInitrd = (CHAR16*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);
+ }
+
+ // If pointer not aligned
+ if ((UINTN)OptionalDataInitrd & 0x1) {
+ Initrd = (CHAR16*)AllocateCopyPool (LinuxOptionalData->InitrdPathListLength, OptionalDataInitrd);
+ } else {
+ Initrd = OptionalDataInitrd;
+ }
+
+ InitrdDevicePath = FileDevicePath (LoadedImage->DeviceHandle, Initrd);
+ } else {
+ OptionalDataInitrd = NULL;
+ InitrdDevicePath = NULL;
+ Initrd = NULL;
+ }
+
+ // Load and Start the Linux Kernel (we should never return)
+ Status = BdsBootLinuxFdt (DevicePathKernel, InitrdDevicePath, OptionalDataArguments, DevicePathFdt);
+
+ if ((UINTN)OptionalDataInitrd & 0x1) {
+ FreePool (Initrd);
+ }
+
+ FreePool (DevicePathKernel);
+ if (InitrdDevicePath) {
+ FreePool (InitrdDevicePath);
+ }
+ }
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf
new file mode 100644
index 0000000..55a6969
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf
@@ -0,0 +1,39 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = LinuxFdtLoader
+ FILE_GUID = f536d559-459f-48fa-8bbc-43b554ecae8d
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 0.1
+ ENTRY_POINT = UefiMain
+
+[Sources]
+ LinuxFdtLoader.c
+ LinuxConfig.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BdsLib
+ DxeServicesTableLib
+ UefiLib
+ UefiApplicationEntryPoint
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid
+ gEfiDevicePathToTextProtocolGuid
+
diff --git a/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxInternal.h b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxInternal.h
new file mode 100644
index 0000000..88d786f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Application/LinuxLoader/LinuxInternal.h
@@ -0,0 +1,50 @@
+/** @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.
+*
+**/
+
+#ifndef __LOADER_INTERNAL_H
+#define __LOADER_INTERNAL_H
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BdsLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DevicePathToText.h>
+
+#define LINUX_KERNEL_NAME L"zImage"
+#define FDT_NAME L"platform.dtb"
+
+#define LINUX_LOADER_SIGNATURE SIGNATURE_32('l', 'i', 'l', 'o')
+
+typedef struct {
+ UINT32 Signature;
+ UINT16 CmdLineLength;
+ UINT16 InitrdPathListLength;
+
+ // These following fields have variable length:
+ //CHAR8* CmdLine;
+ //CHAR16* Initrd;
+} LINUX_LOADER_OPTIONAL_DATA;
+
+EFI_STATUS
+LinuxLoaderConfig (
+ IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/ArmPkg.dec b/uefi/linaro-edk2/ArmPkg/ArmPkg.dec
new file mode 100644
index 0000000..ced3929
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/ArmPkg.dec
@@ -0,0 +1,249 @@
+#/** @file
+# ARM processor package.
+#
+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011 - 2015, 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.
+#
+#**/
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = ArmPkg
+ PACKAGE_GUID = 5CFBD99E-3C43-4E7F-8054-9CDEAFF7710F
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+ Include # Root include for the package
+
+[LibraryClasses.common]
+ ArmLib|Include/Library/ArmLib.h
+ SemihostLib|Include/Library/Semihosting.h
+ UncachedMemoryAllocationLib|Include/Library/UncachedMemoryAllocationLib.h
+ DefaultExceptionHandlerLib|Include/Library/DefaultExceptionHandlerLib.h
+ ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h
+
+[Guids.common]
+ gArmTokenSpaceGuid = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }
+
+ ## ARM MPCore table
+ # Include/Guid/ArmMpCoreInfo.h
+ gArmMpCoreInfoGuid = { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
+
+[Ppis]
+ ## Include/Ppi/ArmMpCoreInfo.h
+ gArmMpCoreInfoPpiGuid = { 0x6847cc74, 0xe9ec, 0x4f8f, {0xa2, 0x9d, 0xab, 0x44, 0xe7, 0x54, 0xa8, 0xfc} }
+
+[Protocols.common]
+ gVirtualUncachedPagesProtocolGuid = { 0xAD651C7D, 0x3C22, 0x4DBF, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } }
+
+[PcdsFeatureFlag.common]
+ gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE|BOOLEAN|0x00000001
+
+ # On ARM Architecture with the Security Extension, the address for the
+ # Vector Table can be mapped anywhere in the memory map. It means we can
+ # point the Exception Vector Table to its location in CpuDxe.
+ # By default we copy the Vector Table at PcdGet32(PcdCpuVectorBaseAddress)
+ gArmTokenSpaceGuid.PcdRelocateVectorTable|TRUE|BOOLEAN|0x00000022
+ # Set this PCD to TRUE if the Exception Vector is changed to add debugger support before
+ # it has been configured by the CPU DXE
+ gArmTokenSpaceGuid.PcdDebuggerExceptionSupport|FALSE|BOOLEAN|0x00000032
+
+ # Define if the spin-table mechanism is used by the secondary cores when booting
+ # Linux (instead of PSCI)
+ gArmTokenSpaceGuid.PcdArmLinuxSpinTable|FALSE|BOOLEAN|0x00000033
+
+ # Define if the GICv3 controller should use the GICv2 legacy
+ gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
+
+[PcdsFixedAtBuild.common]
+ gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006
+
+ # This PCD should be a FeaturePcd. But we used this PCD as an '#if' in an ASM file.
+ # Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.
+ gArmTokenSpaceGuid.PcdVFPEnabled|0|UINT32|0x00000024
+
+ gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000080000000|UINT64|0x00000002
+ # This PCD will free the unallocated buffers if their size reach this threshold.
+ # We set the default value to 512MB.
+ gArmTokenSpaceGuid.PcdArmFreeUncachedMemorySizeThreshold|0x20000000|UINT64|0x00000043
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003
+ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xffff0000|UINT32|0x00000004
+ gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005
+
+ #
+ # ARM Secure Firmware PCDs
+ #
+ gArmTokenSpaceGuid.PcdSecureFdBaseAddress|0|UINT64|0x00000015
+ gArmTokenSpaceGuid.PcdSecureFdSize|0|UINT32|0x00000016
+ gArmTokenSpaceGuid.PcdSecureFvBaseAddress|0x0|UINT64|0x0000002F
+ gArmTokenSpaceGuid.PcdSecureFvSize|0x0|UINT32|0x00000030
+
+ #
+ # ARM Normal (or Non Secure) Firmware PCDs
+ #
+ gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B
+ gArmTokenSpaceGuid.PcdFdSize|0|UINT32|0x0000002C
+ gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
+ gArmTokenSpaceGuid.PcdFvSize|0|UINT32|0x0000002E
+
+ #
+ # ARM Hypervisor Firmware PCDs
+ #
+ gArmTokenSpaceGuid.PcdHypFdBaseAddress|0|UINT32|0x0000003A
+ gArmTokenSpaceGuid.PcdHypFdSize|0|UINT32|0x0000003B
+ gArmTokenSpaceGuid.PcdHypFvBaseAddress|0|UINT32|0x0000003C
+ gArmTokenSpaceGuid.PcdHypFvSize|0|UINT32|0x0000003D
+
+ # Use ClusterId + CoreId to identify the PrimaryCore
+ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask|0xF03|UINT32|0x00000031
+ # The Primary Core is ClusterId[0] & CoreId[0]
+ gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037
+
+ #
+ # ARM L2x0 PCDs
+ #
+ gArmTokenSpaceGuid.PcdL2x0ControllerBase|0|UINT32|0x0000001B
+
+ #
+ # BdsLib
+ #
+ gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E
+ # The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory
+ gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F
+ # Maximum file size for TFTP servers that do not support 'tsize' extension
+ gArmTokenSpaceGuid.PcdMaxTftpFileSize|0x01000000|UINT32|0x00000000
+
+
+[PcdsFixedAtBuild.ARM]
+ #
+ # ARM Security Extension
+ #
+
+ # Secure Configuration Register
+ # - BIT0 : NS - Non Secure bit
+ # - BIT1 : IRQ Handler
+ # - BIT2 : FIQ Handler
+ # - BIT3 : EA - External Abort
+ # - BIT4 : FW - F bit writable
+ # - BIT5 : AW - A bit writable
+ # - BIT6 : nET - Not Early Termination
+ # - BIT7 : SCD - Secure Monitor Call Disable
+ # - BIT8 : HCE - Hyp Call enable
+ # - BIT9 : SIF - Secure Instruction Fetch
+ # 0x31 = NS | EA | FW
+ gArmTokenSpaceGuid.PcdArmScr|0x31|UINT32|0x00000038
+
+ # By default we do not do a transition to non-secure mode
+ gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x0|UINT32|0x0000003E
+
+ # The Linux ATAGs are expected to be under 0x4000 (16KB) from the beginning of the System Memory
+ gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset|0x4000|UINT32|0x00000020
+
+ # If the fixed FDT address is not available, then it should be loaded below the kernel.
+ # The recommendation from the Linux kernel is to have the FDT below 16KB.
+ # (see the kernel doc: Documentation/arm/Booting)
+ gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x4000|UINT32|0x00000023
+ # The FDT blob must be loaded at a 64bit aligned address.
+ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x8|UINT32|0x00000026
+
+ # Non Secure Access Control Register
+ # - BIT15 : NSASEDIS - Disable Non-secure Advanced SIMD functionality
+ # - BIT14 : NSD32DIS - Disable Non-secure use of D16-D31
+ # - BIT11 : cp11 - Non-secure access to coprocessor 11 enable
+ # - BIT10 : cp10 - Non-secure access to coprocessor 10 enable
+ # 0xC00 = cp10 | cp11
+ gArmTokenSpaceGuid.PcdArmNsacr|0xC00|UINT32|0x00000039
+
+[PcdsFixedAtBuild.AARCH64]
+ #
+ # AArch64 Security Extension
+ #
+
+ # Secure Configuration Register
+ # - BIT0 : NS - Non Secure bit
+ # - BIT1 : IRQ Handler
+ # - BIT2 : FIQ Handler
+ # - BIT3 : EA - External Abort
+ # - BIT4 : FW - F bit writable
+ # - BIT5 : AW - A bit writable
+ # - BIT6 : nET - Not Early Termination
+ # - BIT7 : SCD - Secure Monitor Call Disable
+ # - BIT8 : HCE - Hyp Call enable
+ # - BIT9 : SIF - Secure Instruction Fetch
+ # - BIT10: RW - Register width control for lower exception levels
+ # - BIT11: SIF - Enables Secure EL1 access to EL1 Architectural Timer
+ # - BIT12: TWI - Trap WFI
+ # - BIT13: TWE - Trap WFE
+ # 0x501 = NS | HCE | RW
+ gArmTokenSpaceGuid.PcdArmScr|0x501|UINT32|0x00000038
+
+ # By default we do transition to EL2 non-secure mode with Stack for EL2.
+ # Mode Description Bits
+ # NS EL2 SP2 all interrupts disabled = 0x3c9
+ # NS EL1 SP1 all interrupts disabled = 0x3c5
+ # Other modes include using SP0 or switching to Aarch32, but these are
+ # not currently supported.
+ gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x3c9|UINT32|0x0000003E
+ # If the fixed FDT address is not available, then it should be loaded above the kernel.
+ # The recommendation from the AArch64 Linux kernel is to have the FDT below 512MB.
+ # (see the kernel doc: Documentation/arm64/booting.txt)
+ gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x20000000|UINT32|0x00000023
+ # The FDT blob must be loaded at a 2MB aligned address.
+ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x00200000|UINT32|0x00000026
+
+
+#
+# These PCDs are also defined as 'PcdsDynamic' to be redefined when using UEFI in a
+# context of virtual machine.
+#
+[PcdsFixedAtBuild.common, PcdsDynamic.common]
+ # System Memory (DRAM): These PCDs define the region of in-built system memory
+ # Some platforms can get DRAM extensions, these additional regions will be declared
+ # to UEFI by ArmPlatformLib
+ gArmTokenSpaceGuid.PcdSystemMemoryBase|0|UINT64|0x00000029
+ gArmTokenSpaceGuid.PcdSystemMemorySize|0|UINT64|0x0000002A
+
+ #
+ # ARM Architectural Timer
+ #
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0|UINT32|0x00000034
+
+ # ARM Architectural Timer Interrupt(GIC PPI) numbers
+ gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035
+ gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
+ gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040
+ gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041
+
+ #
+ # ARM Generic Watchdog
+ #
+
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x2A440000|UINT32|0x00000007
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x2A450000|UINT32|0x00000008
+ gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|93|UINT32|0x00000009
+
+ #
+ # ARM Generic Interrupt Controller
+ #
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C
+ # Base address for the GIC Redistributor region that contains the boot CPU
+ gArmTokenSpaceGuid.PcdGicRedistributorsBase|0|UINT32|0x0000000E
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D
+ gArmTokenSpaceGuid.PcdGicSgiIntId|0|UINT32|0x00000025
diff --git a/uefi/linaro-edk2/ArmPkg/ArmPkg.dsc b/uefi/linaro-edk2/ArmPkg/ArmPkg.dsc
new file mode 100644
index 0000000..be5126c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/ArmPkg.dsc
@@ -0,0 +1,164 @@
+#/** @file
+# ARM processor package.
+#
+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = ArmPkg
+ PLATFORM_GUID = 5CFBD99E-3C43-4E7F-8054-9CDEAFF7710F
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/Arm
+ SUPPORTED_ARCHITECTURES = ARM|AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+
+[BuildOptions]
+ XCODE:*_*_ARM_PLATFORM_FLAGS == -arch armv7
+ GCC:*_*_ARM_PLATFORM_FLAGS == -march=armv7-a -mfpu=neon
+ # We use A15 to get the Secure and Virtualization extensions
+ RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15
+
+ RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
+
+[LibraryClasses.common]
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+
+ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+
+ SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
+ UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+ ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+ ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+ DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
+
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+
+ BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+ FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+
+[LibraryClasses.ARM]
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+
+[LibraryClasses.AARCH64]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+
+[LibraryClasses.common.PEIM]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Dxe/DxeArmPlatformGlobalVariableLib.inf
+
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+ # Add support for GCC stack protector
+ NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+[Components.common]
+ ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+ ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+ ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
+ ArmPkg/Library/ArmLib/Null/NullArmLib.inf
+ ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
+ ArmPkg/Library/BdsLib/BdsLib.inf
+ ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+ ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
+ ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+ ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
+ ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+ ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
+ ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
+ ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
+ ArmPkg/Library/SemihostLib/SemihostLib.inf
+ ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+ ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+
+ ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ ArmPkg/Drivers/CpuPei/CpuPei.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+ ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
+ ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+ ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+ ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+ ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
+
+ ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+ ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
+ ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
+
+ ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+
+ ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf
+
+[Components.ARM]
+ ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
+
+ ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf
+ ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
+ ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
+
+# ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf
+# ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf
+# ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
+# ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
+ ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
+ ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
+
+ ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf
+
+[Components.AARCH64]
+ ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
+ ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
+
+ ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
+ ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
diff --git a/uefi/linaro-edk2/ArmPkg/Contributions.txt b/uefi/linaro-edk2/ArmPkg/Contributions.txt
new file mode 100644
index 0000000..f87cbd7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Contributions.txt
@@ -0,0 +1,218 @@
+
+======================
+= Code Contributions =
+======================
+
+To make a contribution to a TianoCore project, follow these steps.
+1. Create a change description in the format specified below to
+ use in the source control commit log.
+2. Your commit message must include your "Signed-off-by" signature,
+ and "Contributed-under" message.
+3. Your "Contributed-under" message explicitly states that the
+ contribution is made under the terms of the specified
+ contribution agreement. Your "Contributed-under" message
+ must include the name of contribution agreement and version.
+ For example: Contributed-under: TianoCore Contribution Agreement 1.0
+ The "TianoCore Contribution Agreement" is included below in
+ this document.
+4. Submit your code to the TianoCore project using the process
+ that the project documents on its web page. If the process is
+ not documented, then submit the code on development email list
+ for the project.
+5. It is preferred that contributions are submitted using the same
+ copyright license as the base project. When that is not possible,
+ then contributions using the following licenses can be accepted:
+ * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause
+ * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause
+ * MIT: http://opensource.org/licenses/MIT
+ * Python-2.0: http://opensource.org/licenses/Python-2.0
+ * Zlib: http://opensource.org/licenses/Zlib
+
+ Contributions of code put into the public domain can also be
+ accepted.
+
+ Contributions using other licenses might be accepted, but further
+ review will be required.
+
+=====================================================
+= Change Description / Commit Message / Patch Email =
+=====================================================
+
+Your change description should use the standard format for a
+commit message, and must include your "Signed-off-by" signature
+and the "Contributed-under" message.
+
+== Sample Change Description / Commit Message =
+
+=== Start of sample patch email message ===
+
+From: Contributor Name <contributor@example.com>
+Subject: [PATCH] CodeModule: Brief-single-line-summary
+
+Full-commit-message
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Contributor Name <contributor@example.com>
+---
+
+An extra message for the patch email which will not be considered part
+of the commit message can be added here.
+
+Patch content inline or attached
+
+=== End of sample patch email message ===
+
+=== Notes for sample patch email ===
+
+* The first line of commit message is taken from the email's subject
+ line following [PATCH]. The remaining portion of the commit message
+ is the email's content until the '---' line.
+* git format-patch is one way to create this format
+
+=== Definitions for sample patch email ===
+
+* "CodeModule" is a short idenfier for the affected code. For
+ example MdePkg, or MdeModulePkg UsbBusDxe.
+* "Brief-single-line-summary" is a short summary of the change.
+* The entire first line should be less than ~70 characters.
+* "Full-commit-message" a verbose multiple line comment describing
+ the change. Each line should be less than ~70 characters.
+* "Contributed-under" explicitely states that the contribution is
+ made under the terms of the contribtion agreement. This
+ agreement is included below in this document.
+* "Signed-off-by" is the contributor's signature identifying them
+ by their real/legal name and their email address.
+
+========================================
+= TianoCore Contribution Agreement 1.0 =
+========================================
+
+INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
+INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE
+PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE
+TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE
+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR
+REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE
+CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED
+BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS
+AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
+USE THE CONTENT.
+
+Unless otherwise indicated, all Content made available on the TianoCore
+site is provided to you under the terms and conditions of the BSD
+License ("BSD"). A copy of the BSD License is available at
+http://opensource.org/licenses/bsd-license.php
+or when applicable, in the associated License.txt file.
+
+Certain other content may be made available under other licenses as
+indicated in or with such Content. (For example, in a License.txt file.)
+
+You accept and agree to the following terms and conditions for Your
+present and future Contributions submitted to TianoCore site. Except
+for the license granted to Intel hereunder, You reserve all right,
+title, and interest in and to Your Contributions.
+
+== SECTION 1: Definitions ==
+* "You" or "Contributor" shall mean the copyright owner or legal
+ entity authorized by the copyright owner that is making a
+ Contribution hereunder. All other entities that control, are
+ controlled by, or are under common control with that entity are
+ considered to be a single Contributor. For the purposes of this
+ definition, "control" means (i) the power, direct or indirect, to
+ cause the direction or management of such entity, whether by
+ contract or otherwise, or (ii) ownership of fifty percent (50%)
+ or more of the outstanding shares, or (iii) beneficial ownership
+ of such entity.
+* "Contribution" shall mean any original work of authorship,
+ including any modifications or additions to an existing work,
+ that is intentionally submitted by You to the TinaoCore site for
+ inclusion in, or documentation of, any of the Content. For the
+ purposes of this definition, "submitted" means any form of
+ electronic, verbal, or written communication sent to the
+ TianoCore site or its representatives, including but not limited
+ to communication on electronic mailing lists, source code
+ control systems, and issue tracking systems that are managed by,
+ or on behalf of, the TianoCore site for the purpose of
+ discussing and improving the Content, but excluding
+ communication that is conspicuously marked or otherwise
+ designated in writing by You as "Not a Contribution."
+
+== SECTION 2: License for Contributions ==
+* Contributor hereby agrees that redistribution and use of the
+ Contribution in source and binary forms, with or without
+ modification, are permitted provided that the following
+ conditions are met:
+** Redistributions of source code must retain the Contributor's
+ copyright notice, this list of conditions and the following
+ disclaimer.
+** Redistributions in binary form must reproduce the Contributor's
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+* Disclaimer. None of the names of Contributor, Intel, or the names
+ of their respective contributors may be used to endorse or
+ promote products derived from this software without specific
+ prior written permission.
+* Contributor grants a license (with the right to sublicense) under
+ claims of Contributor's patents that Contributor can license that
+ are infringed by the Contribution (as delivered by Contributor) to
+ make, use, distribute, sell, offer for sale, and import the
+ Contribution and derivative works thereof solely to the minimum
+ extent necessary for licensee to exercise the granted copyright
+ license; this patent license applies solely to those portions of
+ the Contribution that are unmodified. No hardware per se is
+ licensed.
+* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE
+ CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "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 THE
+ CONTRIBUTOR 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 THE
+ CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+
+== SECTION 3: Representations ==
+* You represent that You are legally entitled to grant the above
+ license. If your employer(s) has rights to intellectual property
+ that You create that includes Your Contributions, You represent
+ that You have received permission to make Contributions on behalf
+ of that employer, that Your employer has waived such rights for
+ Your Contributions.
+* You represent that each of Your Contributions is Your original
+ creation (see Section 4 for submissions on behalf of others).
+ You represent that Your Contribution submissions include complete
+ details of any third-party license or other restriction
+ (including, but not limited to, related patents and trademarks)
+ of which You are personally aware and which are associated with
+ any part of Your Contributions.
+
+== SECTION 4: Third Party Contributions ==
+* Should You wish to submit work that is not Your original creation,
+ You may submit it to TianoCore site separately from any
+ Contribution, identifying the complete details of its source
+ and of any license or other restriction (including, but not
+ limited to, related patents, trademarks, and license agreements)
+ of which You are personally aware, and conspicuously marking the
+ work as "Submitted on behalf of a third-party: [named here]".
+
+== SECTION 5: Miscellaneous ==
+* Applicable Laws. Any claims arising under or relating to this
+ Agreement shall be governed by the internal substantive laws of
+ the State of Delaware or federal courts located in Delaware,
+ without regard to principles of conflict of laws.
+* Language. This Agreement is in the English language only, which
+ language shall be controlling in all respects, and all versions
+ of this Agreement in any other language shall be for accommodation
+ only and shall not be binding. All communications and notices made
+ or given pursuant to this Agreement, and all documentation and
+ support to be provided, unless otherwise noted, shall be in the
+ English language.
+
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11Lib.c
new file mode 100644
index 0000000..a08b7b1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11Lib.c
@@ -0,0 +1,37 @@
+/** @file
+
+ Copyright (c) 2011-2012, 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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+ArmCpuSetup (
+ IN UINTN MpId
+ )
+{
+ ASSERT(0); //TODO: Implement me
+}
+
+
+VOID
+ArmCpuSetupSmpNonSecure (
+ IN UINTN MpId
+ )
+{
+ ASSERT(0); //TODO: Implement me
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11MpCoreLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11MpCoreLib.inf
new file mode 100644
index 0000000..3a796c1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/Arm11MpCoreLib/Arm11MpCoreLib.inf
@@ -0,0 +1,32 @@
+#/* @file
+# Copyright (c) 2011-2012, 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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Arm11MpCoreLib
+ FILE_GUID = dc8a69e0-6be0-469c-94d3-5e6d71aa9808
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCpuLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ IoLib
+ PcdLib
+
+[Sources.common]
+ Arm11Lib.c
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c
new file mode 100644
index 0000000..a1678fe
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.c
@@ -0,0 +1,65 @@
+/** @file
+
+ Copyright (c) 2011-2012, 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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/ArmGenericTimerCounterLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Chipset/ArmCortexA15.h>
+
+VOID
+ArmCpuSetup (
+ IN UINTN MpId
+ )
+{
+ // Check if Architectural Timer frequency is valid number (should not be 0)
+ ASSERT (PcdGet32 (PcdArmArchTimerFreqInHz));
+ ASSERT(ArmIsArchTimerImplemented () != 0);
+
+ // Enable SWP instructions
+ ArmEnableSWPInstruction ();
+
+ // Enable program flow prediction, if supported.
+ ArmEnableBranchPrediction ();
+
+ // Note: System Counter frequency can only be set in Secure privileged mode,
+ // if security extensions are implemented.
+ ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));
+
+ if (ArmIsMpCore()) {
+ // Turn on SMP coherency
+ ArmSetAuxCrBit (A15_FEATURE_SMP);
+ }
+
+}
+
+
+VOID
+ArmCpuSetupSmpNonSecure (
+ IN UINTN MpId
+ )
+{
+ /*// Make the SCU accessible in Non Secure world
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+ ScuBase = ArmGetScuBaseAddress();
+
+ // Allow NS access to SCU register
+ MmioOr32 (ScuBase + A9_SCU_SACR_OFFSET, 0xf);
+ // Allow NS access to Private Peripherals
+ MmioOr32 (ScuBase + A9_SCU_SSACR_OFFSET, 0xfff);
+ }*/
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
new file mode 100644
index 0000000..bd9a733
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
@@ -0,0 +1,35 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmCortexA15Lib
+ FILE_GUID = 501b1c8f-21d5-4ef5-a565-435b7f0aae2d
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCpuLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ ArmGenericTimerCounterLib
+ PcdLib
+
+[Sources.common]
+ ArmCortexA15Lib.c
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S
new file mode 100644
index 0000000..e5fbc86
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013 - 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 <AsmMacroIoLibV8.h>
+
+.text
+.align 3
+GCC_ASM_EXPORT (ArmReadCpuExCr)
+GCC_ASM_EXPORT (ArmWriteCpuExCr)
+
+ASM_PFX(ArmReadCpuExCr):
+ mrs x0, S3_1_c15_c2_1
+ ret
+
+ASM_PFX(ArmWriteCpuExCr):
+ msr S3_1_c15_c2_1, x0
+ dsb sy
+ isb
+ ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c
new file mode 100644
index 0000000..135bd6b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c
@@ -0,0 +1,81 @@
+/** @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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/ArmGenericTimerCounterLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Chipset/ArmCortexA5x.h>
+
+VOID
+ArmCpuSetup (
+ IN UINTN MpId
+ )
+{
+ // Check if Architectural Timer frequency is valid number (should not be 0)
+ ASSERT (PcdGet32 (PcdArmArchTimerFreqInHz));
+ ASSERT (ArmIsArchTimerImplemented () != 0);
+
+ // Note: System Counter frequency can only be set in Secure privileged mode,
+ // if security extensions are implemented.
+ ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));
+
+ if (ArmIsMpCore ()) {
+ // Turn on SMP coherency
+ ArmSetCpuExCrBit (A5X_FEATURE_SMP);
+ }
+
+ //
+ // If CPU is CortexA57 r0p0 apply Errata: 806969
+ //
+ if ((ArmReadMidr () & ((ARM_CPU_TYPE_MASK << 4) | ARM_CPU_REV_MASK)) ==
+ ((ARM_CPU_TYPE_A57 << 4) | ARM_CPU_REV(0,0))) {
+ // DisableLoadStoreWB
+ ArmSetCpuActlrBit (1ULL << 49);
+ }
+}
+
+VOID
+ArmCpuSetupSmpNonSecure (
+ IN UINTN MpId
+ )
+{
+}
+
+VOID
+EFIAPI
+ArmSetCpuExCrBit (
+ IN UINT64 Bits
+ )
+{
+ UINT64 Value;
+ Value = ArmReadCpuExCr ();
+ Value |= Bits;
+ ArmWriteCpuExCr (Value);
+}
+
+VOID
+EFIAPI
+ArmUnsetCpuExCrBit (
+ IN UINT64 Bits
+ )
+{
+ UINT64 Value;
+ Value = ArmReadCpuExCr ();
+ Value &= ~Bits;
+ ArmWriteCpuExCr (Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
new file mode 100644
index 0000000..e270220
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
@@ -0,0 +1,38 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmCortexA5xLib
+ FILE_GUID = 08107938-85d8-4967-ba65-b673f708fcb2
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCpuLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ ArmGenericTimerCounterLib
+ PcdLib
+
+[Sources.common]
+ ArmCortexA5xLib.c
+
+[Sources.AARCH64]
+ AArch64/ArmCortexA5xHelper.S | GCC
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c
new file mode 100644
index 0000000..e0ba1fa
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.c
@@ -0,0 +1,41 @@
+/** @file
+
+ Copyright (c) 2011, 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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/DebugLib.h>
+
+#include <Chipset/ArmV7.h>
+
+VOID
+ArmCpuSetup (
+ IN UINTN MpId
+ )
+{
+ // Enable SWP instructions
+ ArmEnableSWPInstruction ();
+
+ // Enable program flow prediction, if supported.
+ ArmEnableBranchPrediction ();
+}
+
+VOID
+ArmCpuSetupSmpNonSecure (
+ IN UINTN MpId
+ )
+{
+ // The CortexA8 is a Unicore CPU. We must not initialize SMP for Non Secure Accesses
+ ASSERT(0);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf
new file mode 100644
index 0000000..890958a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA8Lib/ArmCortexA8Lib.inf
@@ -0,0 +1,27 @@
+#/* @file
+# Copyright (c) 2011, 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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmCortexA8Lib
+ FILE_GUID = 34b5745e-f575-44ce-ba2e-df0886807c16
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCpuLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[Sources.common]
+ ArmCortexA8Lib.c
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S
new file mode 100644
index 0000000..5db5861
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.S
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 2011-2012, 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 <AsmMacroIoLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Chipset/ArmCortexA9.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmGetScuBaseAddress)
+
+// 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
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm
new file mode 100644
index 0000000..7150834
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Helper.asm
@@ -0,0 +1,34 @@
+//
+// Copyright (c) 2011-2012, 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 <AsmMacroIoLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Chipset/ArmCortexA9.h>
+
+ INCLUDE AsmMacroIoLib.inc
+
+ EXPORT ArmGetScuBaseAddress
+
+ PRESERVE8
+ AREA ArmCortexA9Helper, CODE, READONLY
+
+// IN None
+// OUT r0 = SCU Base Address
+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
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c
new file mode 100644
index 0000000..4fc6a08
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.c
@@ -0,0 +1,76 @@
+/** @file
+
+ Copyright (c) 2011-2012, 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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+
+#include <Chipset/ArmCortexA9.h>
+
+VOID
+ArmEnableScu (
+ VOID
+ )
+{
+ INTN ScuBase;
+
+ ScuBase = ArmGetScuBaseAddress();
+
+ // Invalidate all: write -1 to SCU Invalidate All register
+ MmioWrite32(ScuBase + A9_SCU_INVALL_OFFSET, 0xffffffff);
+ // Enable SCU
+ MmioWrite32(ScuBase + A9_SCU_CONTROL_OFFSET, 0x1);
+}
+
+VOID
+ArmCpuSetup (
+ IN UINTN MpId
+ )
+{
+ // Enable SWP instructions
+ ArmEnableSWPInstruction ();
+
+ // Enable program flow prediction, if supported.
+ ArmEnableBranchPrediction ();
+
+ // If MPCore then Enable the SCU
+ if (ArmIsMpCore()) {
+ // Signals the Cortex-A9 processor is taking part in coherency
+ ArmSetAuxCrBit (A9_FEATURE_SMP);
+
+ ArmEnableScu ();
+ }
+}
+
+
+VOID
+ArmCpuSetupSmpNonSecure (
+ IN UINTN MpId
+ )
+{
+ INTN ScuBase;
+
+ // Make the SCU accessible in Non Secure world
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+ ScuBase = ArmGetScuBaseAddress();
+
+ // Allow NS access to SCU register
+ MmioOr32 (ScuBase + A9_SCU_SACR_OFFSET, 0xf);
+ // Allow NS access to Private Peripherals
+ MmioOr32 (ScuBase + A9_SCU_SSACR_OFFSET, 0xfff);
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
new file mode 100644
index 0000000..236b0bc
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf
@@ -0,0 +1,37 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmCortexA9Lib
+ FILE_GUID = c9709ea3-1beb-4806-889a-8a1d5e5e1697
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCpuLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ ArmPlatformLib
+ IoLib
+ PcdLib
+
+[Sources.common]
+ ArmCortexA9Lib.c
+ ArmCortexA9Helper.asm | RVCT
+ ArmCortexA9Helper.S | GCC
+
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c
new file mode 100644
index 0000000..9b1815f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c
@@ -0,0 +1,39 @@
+/** @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 <Base.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/ArmGenericTimerCounterLib.h>
+#include <Library/PcdLib.h>
+
+#include <Chipset/ArmAemV8.h>
+
+VOID
+ArmCpuSetup (
+ IN UINTN MpId
+ )
+{
+ // Note: System Counter frequency can only be set in Secure privileged mode,
+ // if security extensions are implemented.
+ ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));
+}
+
+
+VOID
+ArmCpuSetupSmpNonSecure (
+ IN UINTN MpId
+ )
+{
+ // Nothing to do
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
new file mode 100644
index 0000000..1c81220
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
@@ -0,0 +1,34 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmCortexAEMv8Lib
+ FILE_GUID = 8ab5a7e3-86b1-4dd3-a092-09ee801e774b
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmCpuLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmGenericTimerCounterLib
+ PcdLib
+
+[Sources.common]
+ ArmCortexAEMv8Lib.c
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c
new file mode 100644
index 0000000..9da69b2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c
@@ -0,0 +1,47 @@
+/** @file
+*
+* Copyright (c) 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 <Library/ArmLib.h>
+#include <Library/ArmGicLib.h>
+
+#include "GicV3/ArmGicV3Lib.h"
+
+ARM_GIC_ARCH_REVISION
+EFIAPI
+ArmGicGetSupportedArchRevision (
+ VOID
+ )
+{
+ // Ideally we would like to use the GICC IIDR Architecture version here, but
+ // this does not seem to be very reliable as the implementation could easily
+ // get it wrong. It is more reliable to check if the GICv3 System Register
+ // feature is implemented on the CPU. This is also convenient as our GICv3
+ // driver requires SRE. If only Memory mapped access is available we try to
+ // drive the GIC as a v2.
+ if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {
+ // Make sure System Register access is enabled (SRE). This depends on the
+ // higher privilege level giving us permission, otherwise we will either
+ // cause an exception here, or the write doesn't stick in which case we need
+ // to fall back to the GICv2 MMIO interface.
+ // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
+ // at the same exception level.
+ // It is the OS responsibility to set this bit.
+ ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE);
+ if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) {
+ return ARM_GIC_ARCH_REVISION_3;
+ }
+ }
+
+ return ARM_GIC_ARCH_REVISION_2;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c
new file mode 100644
index 0000000..f360a40
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c
@@ -0,0 +1,47 @@
+/** @file
+*
+* Copyright (c) 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 <Library/ArmLib.h>
+#include <Library/ArmGicLib.h>
+
+#include "GicV3/ArmGicV3Lib.h"
+
+ARM_GIC_ARCH_REVISION
+EFIAPI
+ArmGicGetSupportedArchRevision (
+ VOID
+ )
+{
+ // Ideally we would like to use the GICC IIDR Architecture version here, but
+ // this does not seem to be very reliable as the implementation could easily
+ // get it wrong. It is more reliable to check if the GICv3 System Register
+ // feature is implemented on the CPU. This is also convenient as our GICv3
+ // driver requires SRE. If only Memory mapped access is available we try to
+ // drive the GIC as a v2.
+ if (ArmReadIdPfr1 () & ARM_PFR1_GIC) {
+ // Make sure System Register access is enabled (SRE). This depends on the
+ // higher privilege level giving us permission, otherwise we will either
+ // cause an exception here, or the write doesn't stick in which case we need
+ // to fall back to the GICv2 MMIO interface.
+ // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
+ // at the same exception level.
+ // It is the OS responsibility to set this bit.
+ ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE);
+ if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) {
+ return ARM_GIC_ARCH_REVISION_3;
+ }
+ }
+
+ return ARM_GIC_ARCH_REVISION_2;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c
new file mode 100644
index 0000000..a9ccef5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c
@@ -0,0 +1,141 @@
+/*++
+
+Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+--*/
+
+#include "ArmGicDxe.h"
+
+VOID
+EFIAPI
+IrqInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+VOID
+EFIAPI
+ExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+//
+// Making this global saves a few bytes in image size
+//
+EFI_HANDLE gHardwareInterruptHandle = NULL;
+
+//
+// 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);
+ }
+}
+
+EFI_STATUS
+InstallAndRegisterInterruptService (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,
+ IN EFI_EVENT_NOTIFY ExitBootServicesEvent
+ )
+{
+ EFI_STATUS Status;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+
+ // Initialize the array for the Interrupt Handlers
+ gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
+ if (gRegisteredInterruptHandlers == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gHardwareInterruptHandle,
+ &gHardwareInterruptProtocolGuid, InterruptProtocol,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the CPU protocol that this driver requires.
+ //
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Unregister the default exception handler.
+ //
+ Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Register to receive interrupts
+ //
+ Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, InterruptHandler);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Register for an ExitBootServicesEvent
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
new file mode 100644
index 0000000..2bb064f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
@@ -0,0 +1,59 @@
+/*++
+
+Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ArmGicDxe.c
+
+Abstract:
+
+ Driver implementing the GIC interrupt controller protocol
+
+--*/
+
+#include <PiDxe.h>
+
+#include "ArmGicDxe.h"
+
+/**
+ 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
+ @retval EFI_UNSUPPORTED GIC version not supported
+
+**/
+EFI_STATUS
+InterruptDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ ARM_GIC_ARCH_REVISION Revision;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+
+ if (Revision == ARM_GIC_ARCH_REVISION_2) {
+ Status = GicV2DxeInitialize (ImageHandle, SystemTable);
+ } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+ Status = GicV3DxeInitialize (ImageHandle, SystemTable);
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.h b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.h
new file mode 100644
index 0000000..af33aa9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.h
@@ -0,0 +1,67 @@
+/*++
+
+Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+--*/
+
+#ifndef __ARM_GIC_DXE_H__
+#define __ARM_GIC_DXE_H__
+
+#include <Library/ArmGicLib.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/HardwareInterrupt.h>
+
+extern UINTN mGicNumInterrupts;
+extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers;
+
+//
+// Common API
+//
+EFI_STATUS
+InstallAndRegisterInterruptService (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,
+ IN EFI_EVENT_NOTIFY ExitBootServicesEvent
+ );
+
+EFI_STATUS
+EFIAPI
+RegisterInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN HARDWARE_INTERRUPT_HANDLER Handler
+ );
+
+//
+// GicV2 API
+//
+EFI_STATUS
+GicV2DxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+//
+// GicV3 API
+//
+EFI_STATUS
+GicV3DxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
new file mode 100644
index 0000000..e554301
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
@@ -0,0 +1,60 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2012 - 2015, 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 = ArmGicDxe
+ FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InterruptDxeInitialize
+
+[Sources.common]
+ ArmGicDxe.c
+ ArmGicCommonDxe.c
+
+ GicV2/ArmGicV2Dxe.c
+ GicV3/ArmGicV3Dxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmGicLib
+ BaseLib
+ UefiLib
+ UefiBootServicesTableLib
+ DebugLib
+ PrintLib
+ MemoryAllocationLib
+ UefiDriverEntryPoint
+ IoLib
+ PcdLib
+
+[Protocols]
+ gHardwareInterruptProtocolGuid
+ gEfiCpuArchProtocolGuid
+
+[Pcd.common]
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicRedistributorsBase
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+ gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy
+
+[Depex]
+ gEfiCpuArchProtocolGuid
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c
new file mode 100644
index 0000000..48708e3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c
@@ -0,0 +1,314 @@
+/** @file
+*
+* Copyright (c) 2011-2015, 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 <Base.h>
+#include <Library/ArmGicLib.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+
+#include "GicV2/ArmGicV2Lib.h"
+#include "GicV3/ArmGicV3Lib.h"
+
+/**
+ * Return the base address of the GIC redistributor for the current CPU
+ *
+ * @param Revision GIC Revision. The GIC redistributor might have a different
+ * granularity following the GIC revision.
+ *
+ * @retval Base address of the associated GIC Redistributor
+ */
+STATIC
+UINTN
+GicGetCpuRedistributorBase (
+ IN UINTN GicRedistributorBase,
+ IN ARM_GIC_ARCH_REVISION Revision
+ )
+{
+ UINTN Index;
+ UINTN MpId;
+ UINTN CpuAffinity;
+ UINTN Affinity;
+ UINTN GicRedistributorGranularity;
+ UINTN GicCpuRedistributorBase;
+
+ MpId = ArmReadMpidr ();
+ // Define CPU affinity as Affinity0[0:8], Affinity1[9:15], Affinity2[16:23], Affinity3[24:32]
+ // whereas Affinity3 is defined at [32:39] in MPIDR
+ CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) | ((MpId & ARM_CORE_AFF3) >> 8);
+
+ if (Revision == ARM_GIC_ARCH_REVISION_3) {
+ // 2 x 64KB frame: Redistributor control frame + SGI Control & Generation frame
+ GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_SGI_PPI_FRAME_SIZE;
+ } else {
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return 0;
+ }
+
+ GicCpuRedistributorBase = GicRedistributorBase;
+
+ for (Index = 0; Index < PcdGet32 (PcdCoreCount); Index++) {
+ Affinity = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER) >> 32;
+ if (Affinity == CpuAffinity) {
+ return GicCpuRedistributorBase;
+ }
+
+ // Move to the next GIC Redistributor frame
+ GicRedistributorBase += GicRedistributorGranularity;
+ }
+
+ // The Redistributor has not been found for the current CPU
+ ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmGicGetInterfaceIdentification (
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ // Read the GIC Identification Register
+ return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIIDR);
+}
+
+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);
+}
+
+/*
+ * Acknowledge and return the value of the Interrupt Acknowledge Register
+ *
+ * InterruptId is returned separately from the register value because in
+ * the GICv2 the register value contains the CpuId and InterruptId while
+ * in the GICv3 the register value is only the InterruptId.
+ *
+ * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
+ * @param InterruptId InterruptId read from the Interrupt Acknowledge Register
+ *
+ * @retval value returned by the Interrupt Acknowledge Register
+ *
+ */
+UINTN
+EFIAPI
+ArmGicAcknowledgeInterrupt (
+ IN UINTN GicInterruptInterfaceBase,
+ OUT UINTN *InterruptId
+ )
+{
+ UINTN Value;
+ ARM_GIC_ARCH_REVISION Revision;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if (Revision == ARM_GIC_ARCH_REVISION_2) {
+ Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);
+ // InterruptId is required for the caller to know if a valid or spurious
+ // interrupt has been read
+ ASSERT (InterruptId != NULL);
+ if (InterruptId != NULL) {
+ *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;
+ }
+ } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+ Value = ArmGicV3AcknowledgeInterrupt ();
+ } else {
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ // Report Spurious interrupt which is what the above controllers would
+ // return if no interrupt was available
+ Value = 1023;
+ }
+
+ return Value;
+}
+
+VOID
+EFIAPI
+ArmGicEndOfInterrupt (
+ IN UINTN GicInterruptInterfaceBase,
+ IN UINTN Source
+ )
+{
+ ARM_GIC_ARCH_REVISION Revision;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if (Revision == ARM_GIC_ARCH_REVISION_2) {
+ ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);
+ } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+ ArmGicV3EndOfInterrupt (Source);
+ } else {
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ }
+}
+
+VOID
+EFIAPI
+ArmGicEnableInterrupt (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source
+ )
+{
+ UINT32 RegOffset;
+ UINTN RegShift;
+ ARM_GIC_ARCH_REVISION Revision;
+ UINTN GicCpuRedistributorBase;
+
+ // Calculate enable register offset and bit position
+ RegOffset = Source / 32;
+ RegShift = Source % 32;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
+ // Write set-enable register
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);
+ } else {
+ GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
+ if (GicCpuRedistributorBase == 0) {
+ ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+ return;
+ }
+
+ // Write set-enable register
+ MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset), 1 << RegShift);
+ }
+}
+
+VOID
+EFIAPI
+ArmGicDisableInterrupt (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source
+ )
+{
+ UINT32 RegOffset;
+ UINTN RegShift;
+ ARM_GIC_ARCH_REVISION Revision;
+ UINTN GicCpuRedistributorBase;
+
+ // Calculate enable register offset and bit position
+ RegOffset = Source / 32;
+ RegShift = Source % 32;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
+ // Write clear-enable register
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);
+ } else {
+ GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
+ if (GicCpuRedistributorBase == 0) {
+ return;
+ }
+
+ // Write clear-enable register
+ MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + (4 * RegOffset), 1 << RegShift);
+ }
+}
+
+BOOLEAN
+EFIAPI
+ArmGicIsInterruptEnabled (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source
+ )
+{
+ UINT32 RegOffset;
+ UINTN RegShift;
+ ARM_GIC_ARCH_REVISION Revision;
+ UINTN GicCpuRedistributorBase;
+ UINT32 Interrupts;
+
+ // Calculate enable register offset and bit position
+ RegOffset = Source / 32;
+ RegShift = Source % 32;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
+ Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);
+ } else {
+ GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
+ if (GicCpuRedistributorBase == 0) {
+ return 0;
+ }
+
+ // Read set-enable register
+ Interrupts = MmioRead32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset));
+ }
+
+ return ((Interrupts & (1 << RegShift)) != 0);
+}
+
+VOID
+EFIAPI
+ArmGicDisableDistributor (
+ IN INTN GicDistributorBase
+ )
+{
+ // Disable Gic Distributor
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x0);
+}
+
+VOID
+EFIAPI
+ArmGicEnableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ ARM_GIC_ARCH_REVISION Revision;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if (Revision == ARM_GIC_ARCH_REVISION_2) {
+ ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);
+ } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+ ArmGicV3EnableInterruptInterface ();
+ } else {
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ }
+}
+
+VOID
+EFIAPI
+ArmGicDisableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ ARM_GIC_ARCH_REVISION Revision;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if (Revision == ARM_GIC_ARCH_REVISION_2) {
+ ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);
+ } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
+ ArmGicV3DisableInterruptInterface ();
+ } else {
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
new file mode 100644
index 0000000..2ae3fd3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
@@ -0,0 +1,52 @@
+#/* @file
+# Copyright (c) 2011-2015, 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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmGicLib
+ FILE_GUID = 03d05ee4-cdeb-458c-9dfc-993f09bdf405
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmGicLib
+
+[Sources]
+ ArmGicLib.c
+ ArmGicNonSecLib.c
+
+ GicV2/ArmGicV2Lib.c
+ GicV2/ArmGicV2NonSecLib.c
+
+[Sources.ARM]
+ Arm/ArmGicArchLib.c
+ GicV3/Arm/ArmGicV3.S | GCC
+ GicV3/Arm/ArmGicV3.asm | RVCT
+
+[Sources.AARCH64]
+ AArch64/ArmGicArchLib.c
+ GicV3/AArch64/ArmGicV3.S
+
+[LibraryClasses]
+ ArmLib
+ DebugLib
+ IoLib
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+
+[Pcd]
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+[FeaturePcd]
+ gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
new file mode 100644
index 0000000..e2538f1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
@@ -0,0 +1,37 @@
+/** @file
+*
+* Copyright (c) 2011-2015, 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 <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+VOID
+EFIAPI
+ArmGicEnableDistributor (
+ IN INTN GicDistributorBase
+ )
+{
+ ARM_GIC_ARCH_REVISION Revision;
+
+ /*
+ * Enable GIC distributor in Non-Secure world.
+ * Note: The ICDDCR register is banked when Security extensions are implemented
+ */
+ Revision = ArmGicGetSupportedArchRevision ();
+ if (Revision == ARM_GIC_ARCH_REVISION_2) {
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
+ } else {
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
new file mode 100644
index 0000000..1fdd4d7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.c
@@ -0,0 +1,66 @@
+/** @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 <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+#include "GicV2/ArmGicV2Lib.h"
+
+/*
+ * 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
+ArmGicEnableDistributor (
+ IN INTN GicDistributorBase
+ )
+{
+ // Turn on the GIC distributor
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);
+}
+
+VOID
+EFIAPI
+ArmGicSetupNonSecure (
+ IN UINTN MpId,
+ IN INTN GicDistributorBase,
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ ArmGicV2SetupNonSecure (MpId, GicDistributorBase, GicInterruptInterfaceBase);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
new file mode 100644
index 0000000..7d4e49e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
@@ -0,0 +1,53 @@
+#/* @file
+# Copyright (c) 2011-2015, 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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmGicSecLib
+ FILE_GUID = 85f3cf80-b5f4-11df-9855-0002a5d5c51b
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmGicLib
+
+[Sources]
+ ArmGicLib.c
+ ArmGicSecLib.c
+
+ GicV2/ArmGicV2Lib.c
+ GicV2/ArmGicV2SecLib.c
+
+[Sources.ARM]
+ Arm/ArmGicArchLib.c
+ GicV3/Arm/ArmGicV3.S | GCC
+ GicV3/Arm/ArmGicV3.asm | RVCT
+
+[Sources.AARCH64]
+ AArch64/ArmGicArchLib.c
+ GicV3/AArch64/ArmGicV3.S
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ ArmLib
+ DebugLib
+ IoLib
+
+[Pcd]
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+[FeaturePcd]
+ gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
new file mode 100644
index 0000000..743c534
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
@@ -0,0 +1,317 @@
+/*++
+
+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+Portions copyright (c) 2011-2015, 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.
+
+Module Name:
+
+ GicV2/ArmGicV2Dxe.c
+
+Abstract:
+
+ Driver implementing the GicV2 interrupt controller protocol
+
+--*/
+
+#include "ArmGicDxe.h"
+#include "GicV2/ArmGicV2Lib.h"
+
+#define ARM_GIC_DEFAULT_PRIORITY 0x80
+
+extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;
+
+STATIC UINT32 mGicInterruptInterfaceBase;
+STATIC UINT32 mGicDistributorBase;
+
+/**
+ 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_UNSUPPORTED Source interrupt is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+GicV2EnableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmGicEnableInterrupt (mGicDistributorBase, 0, Source);
+
+ 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_UNSUPPORTED Source interrupt is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+GicV2DisableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmGicDisableInterrupt (mGicDistributorBase, 0, Source);
+
+ 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_UNSUPPORTED Source interrupt is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+GicV2GetInterruptSourceState (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN BOOLEAN *InterruptState
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, 0, Source);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Signal to the hardware that the End Of Interrupt 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_UNSUPPORTED Source interrupt is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+GicV2EndOfInterrupt (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmGicV2EndOfInterrupt (mGicInterruptInterfaceBase, 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
+GicV2IrqInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINT32 GicInterrupt;
+ HARDWARE_INTERRUPT_HANDLER InterruptHandler;
+
+ GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
+
+ // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
+ if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= 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));
+ }
+
+ GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
+}
+
+//
+// The protocol instance produced by this driver
+//
+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = {
+ RegisterInterruptSource,
+ GicV2EnableInterruptSource,
+ GicV2DisableInterruptSource,
+ GicV2GetInterruptSourceState,
+ GicV2EndOfInterrupt
+};
+
+/**
+ 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
+GicV2ExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+ UINT32 GicInterrupt;
+
+ // Disable all the interrupts
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
+ }
+
+ // Acknowledge all pending interrupts
+ do {
+ GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
+
+ if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) < mGicNumInterrupts) {
+ GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
+ }
+ } while (!ARM_GIC_IS_SPECIAL_INTERRUPTS (GicInterrupt));
+
+ // Disable Gic Interface
+ ArmGicV2DisableInterruptInterface (mGicInterruptInterfaceBase);
+
+ // Disable Gic Distributor
+ ArmGicDisableDistributor (mGicDistributorBase);
+}
+
+/**
+ 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
+GicV2DxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT32 RegOffset;
+ UINTN RegShift;
+ UINT32 CpuTarget;
+
+ // Make sure the Interrupt Controller Protocol is not already installed in the system.
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
+
+ mGicInterruptInterfaceBase = PcdGet32 (PcdGicInterruptInterfaceBase);
+ mGicDistributorBase = PcdGet32 (PcdGicDistributorBase);
+ mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
+
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
+
+ // Set Priority
+ RegOffset = Index / 4;
+ RegShift = (Index % 4) * 8;
+ MmioAndThenOr32 (
+ mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
+ ~(0xff << RegShift),
+ ARM_GIC_DEFAULT_PRIORITY << RegShift
+ );
+ }
+
+ //
+ // Targets the interrupts to the Primary Cpu
+ //
+
+ // Only Primary CPU will run this code. We can identify our GIC CPU ID by reading
+ // the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each
+ // connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31.
+ // More Info in the GIC Specification about "Interrupt Processor Targets Registers"
+ //
+ // Read the first Interrupt Processor Targets Register (that corresponds to the 4
+ // first SGIs)
+ CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
+
+ // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value
+ // is 0 when we run on a uniprocessor platform.
+ if (CpuTarget != 0) {
+ // The 8 first Interrupt Processor Targets Registers are read-only
+ for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
+ MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);
+ }
+ }
+
+ // Set binary point reg to 0x7 (no preemption)
+ MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCBPR, 0x7);
+
+ // Set priority mask reg to 0xff to allow all priorities through
+ MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0xff);
+
+ // Enable gic cpu interface
+ ArmGicEnableInterruptInterface (mGicInterruptInterfaceBase);
+
+ // Enable gic distributor
+ ArmGicEnableDistributor (mGicDistributorBase);
+
+ Status = InstallAndRegisterInterruptService (
+ &gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent);
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c
new file mode 100644
index 0000000..5ac1d89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.c
@@ -0,0 +1,36 @@
+/** @file
+*
+* Copyright (c) 2013-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 <Library/ArmGicLib.h>
+#include <Library/IoLib.h>
+
+UINTN
+EFIAPI
+ArmGicV2AcknowledgeInterrupt (
+ IN UINTN GicInterruptInterfaceBase
+ )
+{
+ // Read the Interrupt Acknowledge Register
+ return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+}
+
+VOID
+EFIAPI
+ArmGicV2EndOfInterrupt (
+ IN UINTN GicInterruptInterfaceBase,
+ IN UINTN Source
+ )
+{
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Source);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h
new file mode 100644
index 0000000..6803467
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Lib.h
@@ -0,0 +1,54 @@
+/** @file
+*
+* Copyright (c) 2013-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 _ARM_GIC_V2_H_
+#define _ARM_GIC_V2_H_
+
+// Interrupts from 1020 to 1023 are considered as special interrupts (eg: spurious interrupts)
+#define ARM_GIC_IS_SPECIAL_INTERRUPTS(Interrupt) (((Interrupt) >= 1020) && ((Interrupt) <= 1023))
+
+VOID
+EFIAPI
+ArmGicV2SetupNonSecure (
+ IN UINTN MpId,
+ IN INTN GicDistributorBase,
+ IN INTN GicInterruptInterfaceBase
+ );
+
+VOID
+EFIAPI
+ArmGicV2EnableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ );
+
+VOID
+EFIAPI
+ArmGicV2DisableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ );
+
+UINTN
+EFIAPI
+ArmGicV2AcknowledgeInterrupt (
+ IN UINTN GicInterruptInterfaceBase
+ );
+
+VOID
+EFIAPI
+ArmGicV2EndOfInterrupt (
+ IN UINTN GicInterruptInterfaceBase,
+ IN UINTN Source
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c
new file mode 100644
index 0000000..92b764f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2NonSecLib.c
@@ -0,0 +1,42 @@
+/** @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 <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+
+VOID
+EFIAPI
+ArmGicV2EnableInterruptInterface (
+ 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
+ArmGicV2DisableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ // Disable Gic Interface
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x0);
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x0);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c
new file mode 100644
index 0000000..ac1e0e4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2SecLib.c
@@ -0,0 +1,100 @@
+/** @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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.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
+ArmGicV2SetupNonSecure (
+ IN UINTN MpId,
+ IN INTN GicDistributorBase,
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ UINTN InterruptId;
+ UINTN CachedPriorityMask;
+ UINTN Index;
+ UINTN MaxInterrupts;
+
+ CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);
+
+ // Set priority Mask so that no interrupts get through to CPU
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);
+
+ InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+ MaxInterrupts = ArmGicGetMaxNumInterrupts (GicDistributorBase);
+
+ // Only try to clear valid interrupts. Ignore spurious interrupts.
+ while ((InterruptId & 0x3FF) < MaxInterrupts) {
+ // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
+ ArmGicEndOfInterrupt (GicInterruptInterfaceBase, InterruptId);
+
+ // Next
+ InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+ }
+
+ // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+ // Ensure all GIC interrupts are Non-Secure
+ for (Index = 0; Index < (MaxInterrupts / 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);
+}
+
+VOID
+EFIAPI
+ArmGicV2EnableInterruptInterface (
+ 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
+ArmGicV2DisableInterruptInterface (
+ 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));
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
new file mode 100644
index 0000000..c30ae76
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
@@ -0,0 +1,114 @@
+#
+# Copyright (c) 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 <AsmMacroIoLibV8.h>
+
+#define ICC_SRE_EL1 S3_0_C12_C12_5
+#define ICC_SRE_EL2 S3_4_C12_C9_5
+#define ICC_SRE_EL3 S3_6_C12_C12_5
+#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7
+#define ICC_EOIR1_EL1 S3_0_C12_C12_1
+#define ICC_IAR1_EL1 S3_0_C12_C12_0
+#define ICC_PMR_EL1 S3_0_C4_C6_0
+#define ICC_BPR1_EL1 S3_0_C12_C12_3
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmGicV3GetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicV3SetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicV3EnableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3DisableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3EndOfInterrupt)
+GCC_ASM_EXPORT(ArmGicV3AcknowledgeInterrupt)
+GCC_ASM_EXPORT(ArmGicV3SetPriorityMask)
+GCC_ASM_EXPORT(ArmGicV3SetBinaryPointer)
+
+//UINT32
+//EFIAPI
+//ArmGicV3GetControlSystemRegisterEnable (
+// VOID
+// );
+ASM_PFX(ArmGicV3GetControlSystemRegisterEnable):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, ICC_SRE_EL1
+ b 4f
+2: mrs x0, ICC_SRE_EL2
+ b 4f
+3: mrs x0, ICC_SRE_EL3
+4: ret
+
+//VOID
+//EFIAPI
+//ArmGicV3SetControlSystemRegisterEnable (
+// IN UINT32 ControlSystemRegisterEnable
+// );
+ASM_PFX(ArmGicV3SetControlSystemRegisterEnable):
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr ICC_SRE_EL1, x0
+ b 4f
+2: msr ICC_SRE_EL2, x0
+ b 4f
+3: msr ICC_SRE_EL3, x0
+4: isb
+ ret
+
+//VOID
+//ArmGicV3EnableInterruptInterface (
+// VOID
+// );
+ASM_PFX(ArmGicV3EnableInterruptInterface):
+ mov x0, #1
+ msr ICC_IGRPEN1_EL1, x0
+ ret
+
+//VOID
+//ArmGicV3DisableInterruptInterface (
+// VOID
+// );
+ASM_PFX(ArmGicV3DisableInterruptInterface):
+ mov x0, #0
+ msr ICC_IGRPEN1_EL1, x0
+ ret
+
+//VOID
+//ArmGicV3EndOfInterrupt (
+// IN UINTN InterruptId
+// );
+ASM_PFX(ArmGicV3EndOfInterrupt):
+ msr ICC_EOIR1_EL1, x0
+ ret
+
+//UINTN
+//ArmGicV3AcknowledgeInterrupt (
+// VOID
+// );
+ASM_PFX(ArmGicV3AcknowledgeInterrupt):
+ mrs x0, ICC_IAR1_EL1
+ ret
+
+//VOID
+//ArmGicV3SetPriorityMask (
+// IN UINTN Priority
+// );
+ASM_PFX(ArmGicV3SetPriorityMask):
+ msr ICC_PMR_EL1, x0
+ ret
+
+//VOID
+//ArmGicV3SetBinaryPointer (
+// IN UINTN BinaryPoint
+// );
+ASM_PFX(ArmGicV3SetBinaryPointer):
+ msr ICC_BPR1_EL1, x0
+ ret
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
new file mode 100644
index 0000000..af14b91
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 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 <AsmMacroIoLib.h>
+#include <Library/ArmLib.h>
+
+// For the moment we assume this will run in SVC mode on ARMv7
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmGicV3GetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicV3SetControlSystemRegisterEnable)
+GCC_ASM_EXPORT(ArmGicV3EnableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3DisableInterruptInterface)
+GCC_ASM_EXPORT(ArmGicV3EndOfInterrupt)
+GCC_ASM_EXPORT(ArmGicV3AcknowledgeInterrupt)
+GCC_ASM_EXPORT(ArmGicV3SetPriorityMask)
+GCC_ASM_EXPORT(ArmGicV3SetBinaryPointer)
+
+//UINT32
+//EFIAPI
+//ArmGicGetControlSystemRegisterEnable (
+// VOID
+// );
+ASM_PFX(ArmGicV3GetControlSystemRegisterEnable):
+ mrc p15, 0, r0, c12, c12, 5 // ICC_SRE
+ bx lr
+
+//VOID
+//EFIAPI
+//ArmGicSetControlSystemRegisterEnable (
+// IN UINT32 ControlSystemRegisterEnable
+// );
+ASM_PFX(ArmGicV3SetControlSystemRegisterEnable):
+ mcr p15, 0, r0, c12, c12, 5 // ICC_SRE
+ isb
+ bx lr
+
+//VOID
+//ArmGicV3EnableInterruptInterface (
+// VOID
+// );
+ASM_PFX(ArmGicV3EnableInterruptInterface):
+ mov r0, #1
+ mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
+ bx lr
+
+//VOID
+//ArmGicV3DisableInterruptInterface (
+// VOID
+// );
+ASM_PFX(ArmGicV3DisableInterruptInterface):
+ mov r0, #0
+ mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
+ bx lr
+
+//VOID
+//ArmGicV3EndOfInterrupt (
+// IN UINTN InterruptId
+// );
+ASM_PFX(ArmGicV3EndOfInterrupt):
+ mcr p15, 0, r0, c12, c12, 1 //ICC_EOIR1
+ bx lr
+
+//UINTN
+//ArmGicV3AcknowledgeInterrupt (
+// VOID
+// );
+ASM_PFX(ArmGicV3AcknowledgeInterrupt):
+ mrc p15, 0, r0, c12, c8, 0 //ICC_IAR1
+ bx lr
+
+//VOID
+//ArmGicV3SetPriorityMask (
+// IN UINTN Priority
+// );
+ASM_PFX(ArmGicV3SetPriorityMask):
+ mcr p15, 0, r0, c4, c6, 0 //ICC_PMR
+ bx lr
+
+//VOID
+//ArmGicV3SetBinaryPointer (
+// IN UINTN BinaryPoint
+// );
+ASM_PFX(ArmGicV3SetBinaryPointer):
+ mcr p15, 0, r0, c12, c12, 3 //ICC_BPR1
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
new file mode 100644
index 0000000..92c3236
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.asm
@@ -0,0 +1,96 @@
+//
+// Copyright (c) 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.
+//
+//
+
+// For the moment we assume this will run in SVC mode on ARMv7
+
+ EXPORT ArmGicV3GetControlSystemRegisterEnable
+ EXPORT ArmGicV3SetControlSystemRegisterEnable
+ EXPORT ArmGicV3EnableInterruptInterface
+ EXPORT ArmGicV3DisableInterruptInterface
+ EXPORT ArmGicV3EndOfInterrupt
+ EXPORT ArmGicV3AcknowledgeInterrupt
+ EXPORT ArmGicV3SetPriorityMask
+ EXPORT ArmGicV3SetBinaryPointer
+
+ AREA ArmGicV3, CODE, READONLY
+
+//UINT32
+//EFIAPI
+//ArmGicGetControlSystemRegisterEnable (
+// VOID
+// );
+ArmGicV3GetControlSystemRegisterEnable
+ mrc p15, 0, r0, c12, c12, 5 // ICC_SRE
+ bx lr
+
+//VOID
+//EFIAPI
+//ArmGicSetControlSystemRegisterEnable (
+// IN UINT32 ControlSystemRegisterEnable
+// );
+ArmGicV3SetControlSystemRegisterEnable
+ mcr p15, 0, r0, c12, c12, 5 // ICC_SRE
+ isb
+ bx lr
+
+//VOID
+//ArmGicV3EnableInterruptInterface (
+// VOID
+// );
+ArmGicV3EnableInterruptInterface
+ mov r0, #1
+ mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
+ bx lr
+
+//VOID
+//ArmGicV3DisableInterruptInterface (
+// VOID
+// );
+ArmGicV3DisableInterruptInterface
+ mov r0, #0
+ mcr p15, 0, r0, c12, c12, 7 // ICC_IGRPEN1
+ bx lr
+
+//VOID
+//ArmGicV3EndOfInterrupt (
+// IN UINTN InterruptId
+// );
+ArmGicV3EndOfInterrupt
+ mcr p15, 0, r0, c12, c12, 1 //ICC_EOIR1
+ bx lr
+
+//UINTN
+//ArmGicV3AcknowledgeInterrupt (
+// VOID
+// );
+ArmGicV3AcknowledgeInterrupt
+ mrc p15, 0, r0, c12, c8, 0 //ICC_IAR1
+ bx lr
+
+//VOID
+//ArmGicV3SetPriorityMask (
+// IN UINTN Priority
+// );
+ArmGicV3SetPriorityMask
+ mcr p15, 0, r0, c4, c6, 0 //ICC_PMR
+ bx lr
+
+//VOID
+//ArmGicV3SetBinaryPointer (
+// IN UINTN BinaryPoint
+// );
+ArmGicV3SetBinaryPointer
+ mcr p15, 0, r0, c12, c12, 3 //ICC_BPR1
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
new file mode 100644
index 0000000..f3bf191
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
@@ -0,0 +1,301 @@
+/** @file
+*
+* Copyright (c) 2011-2015, 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 "ArmGicDxe.h"
+#include "GicV3/ArmGicV3Lib.h"
+
+#define ARM_GIC_DEFAULT_PRIORITY 0x80
+
+extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol;
+
+STATIC UINTN mGicDistributorBase;
+STATIC UINTN mGicRedistributorsBase;
+
+/**
+ 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
+GicV3EnableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmGicEnableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);
+
+ 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
+GicV3DisableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmGicDisableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);
+
+ 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
+GicV3GetInterruptSourceState (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN BOOLEAN *InterruptState
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, mGicRedistributorsBase, Source);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Signal to the hardware that the End Of Interrupt 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
+GicV3EndOfInterrupt (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmGicV3EndOfInterrupt (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
+GicV3IrqInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINT32 GicInterrupt;
+ HARDWARE_INTERRUPT_HANDLER InterruptHandler;
+
+ GicInterrupt = ArmGicV3AcknowledgeInterrupt ();
+
+ // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the
+ // number of interrupt (ie: Spurious interrupt).
+ if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= 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));
+ }
+
+ GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);
+}
+
+//
+// The protocol instance produced by this driver
+//
+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol = {
+ RegisterInterruptSource,
+ GicV3EnableInterruptSource,
+ GicV3DisableInterruptSource,
+ GicV3GetInterruptSourceState,
+ GicV3EndOfInterrupt
+};
+
+/**
+ 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
+GicV3ExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ // Acknowledge all pending interrupts
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
+ }
+
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, Index);
+ }
+
+ // Disable Gic Interface
+ ArmGicV3DisableInterruptInterface ();
+
+ // Disable Gic Distributor
+ ArmGicDisableDistributor (mGicDistributorBase);
+}
+
+/**
+ 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
+GicV3DxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT32 RegOffset;
+ UINTN RegShift;
+ UINT64 CpuTarget;
+ UINT64 MpId;
+
+ // Make sure the Interrupt Controller Protocol is not already installed in the system.
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
+
+ mGicDistributorBase = PcdGet32 (PcdGicDistributorBase);
+ mGicRedistributorsBase = PcdGet32 (PcdGicRedistributorsBase);
+ mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
+
+ //
+ // We will be driving this GIC in native v3 mode, i.e., with Affinity
+ // Routing enabled. So ensure that the ARE bit is set.
+ //
+ if (!FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
+ MmioOr32 (mGicDistributorBase + ARM_GIC_ICDDCR, ARM_GIC_ICDDCR_ARE);
+ }
+
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
+
+ // Set Priority
+ RegOffset = Index / 4;
+ RegShift = (Index % 4) * 8;
+ MmioAndThenOr32 (
+ mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
+ ~(0xff << RegShift),
+ ARM_GIC_DEFAULT_PRIORITY << RegShift
+ );
+ }
+
+ //
+ // Targets the interrupts to the Primary Cpu
+ //
+
+ MpId = ArmReadMpidr ();
+ CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
+
+ // Route the SPIs to the primary CPU. SPIs start at the INTID 32
+ for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {
+ MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM);
+ }
+
+ // Set binary point reg to 0x7 (no preemption)
+ ArmGicV3SetBinaryPointer (0x7);
+
+ // Set priority mask reg to 0xff to allow all priorities through
+ ArmGicV3SetPriorityMask (0xff);
+
+ // Enable gic cpu interface
+ ArmGicV3EnableInterruptInterface ();
+
+ // Enable gic distributor
+ ArmGicEnableDistributor (mGicDistributorBase);
+
+ Status = InstallAndRegisterInterruptService (
+ &gHardwareInterruptV3Protocol, GicV3IrqInterruptHandler, GicV3ExitBootServicesEvent);
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
new file mode 100644
index 0000000..794e878
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
@@ -0,0 +1,68 @@
+/** @file
+*
+* Copyright (c) 2014-2015, 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 _ARM_GIC_V3_H_
+#define _ARM_GIC_V3_H_
+
+#define ICC_SRE_EL2_SRE (1 << 0)
+
+#define ARM_GICD_IROUTER_IRM BIT31
+
+UINT32
+EFIAPI
+ArmGicV3GetControlSystemRegisterEnable (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGicV3SetControlSystemRegisterEnable (
+ IN UINT32 ControlSystemRegisterEnable
+ );
+
+VOID
+EFIAPI
+ArmGicV3EnableInterruptInterface (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGicV3DisableInterruptInterface (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmGicV3AcknowledgeInterrupt (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGicV3EndOfInterrupt (
+ IN UINTN Source
+ );
+
+VOID
+ArmGicV3SetBinaryPointer (
+ IN UINTN BinaryPoint
+ );
+
+VOID
+ArmGicV3SetPriorityMask (
+ IN UINTN Priority
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c
new file mode 100644
index 0000000..ce1c6ce
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c
@@ -0,0 +1,154 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CpuDxe.h"
+
+#include <Chipset/AArch64.h>
+
+VOID
+ExceptionHandlersStart (
+ VOID
+ );
+
+VOID
+ExceptionHandlersEnd (
+ VOID
+ );
+
+VOID
+CommonExceptionEntry (
+ VOID
+ );
+
+VOID
+AsmCommonExceptionEntry (
+ VOID
+ );
+
+
+EFI_EXCEPTION_CALLBACK gExceptionHandlers[MAX_AARCH64_EXCEPTION + 1];
+EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_AARCH64_EXCEPTION + 1];
+
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ if (InterruptType > MAX_AARCH64_EXCEPTION) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ gExceptionHandlers[InterruptType] = InterruptHandler;
+
+ return EFI_SUCCESS;
+}
+
+
+
+VOID
+EFIAPI
+CommonCExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ if (ExceptionType <= MAX_AARCH64_EXCEPTION) {
+ if (gExceptionHandlers[ExceptionType]) {
+ gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);
+ return;
+ }
+ } else {
+ DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %016lx\n", ExceptionType, SystemContext.SystemContextAArch64->ELR));
+ ASSERT (FALSE);
+ }
+
+ DefaultExceptionHandler (ExceptionType, SystemContext);
+}
+
+
+
+EFI_STATUS
+InitializeExceptions (
+ IN EFI_CPU_ARCH_PROTOCOL *Cpu
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN IrqEnabled;
+ BOOLEAN FiqEnabled;
+
+ Status = EFI_SUCCESS;
+ ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers));
+
+ //
+ // Disable interrupts
+ //
+ Cpu->GetInterruptState (Cpu, &IrqEnabled);
+ Cpu->DisableInterrupt (Cpu);
+
+ //
+ // EFI does not use the FIQ, but a debugger might so we must disable
+ // as we take over the exception vectors.
+ //
+ FiqEnabled = ArmGetFiqState ();
+ ArmDisableFiq ();
+
+ // The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure 'Align=4K'
+ // is defined into your FDF for this module.
+ ASSERT (((UINTN)ExceptionHandlersStart & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
+
+ // We do not copy the Exception Table at PcdGet32(PcdCpuVectorBaseAddress). We just set Vector
+ // Base Address to point into CpuDxe code.
+ ArmWriteVBar ((UINTN)ExceptionHandlersStart);
+
+ if (FiqEnabled) {
+ ArmEnableFiq ();
+ }
+
+ if (IrqEnabled) {
+ //
+ // Restore interrupt state
+ //
+ Status = Cpu->EnableInterrupt (Cpu);
+ }
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
new file mode 100644
index 0000000..2682f4f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
@@ -0,0 +1,394 @@
+//
+// Copyright (c) 2011 - 2014 ARM LTD. All rights reserved.<BR>
+// Portion of Copyright (c) 2014 NVIDIA Corporation. 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 <Library/PcdLib.h>
+#include <AsmMacroIoLibV8.h>
+
+/*
+ This is the stack constructed by the exception handler (low address to high address).
+ X0 to FAR makes up the EFI_SYSTEM_CONTEXT for AArch64.
+
+ UINT64 X0; 0x000
+ UINT64 X1; 0x008
+ UINT64 X2; 0x010
+ UINT64 X3; 0x018
+ UINT64 X4; 0x020
+ UINT64 X5; 0x028
+ UINT64 X6; 0x030
+ UINT64 X7; 0x038
+ UINT64 X8; 0x040
+ UINT64 X9; 0x048
+ UINT64 X10; 0x050
+ UINT64 X11; 0x058
+ UINT64 X12; 0x060
+ UINT64 X13; 0x068
+ UINT64 X14; 0x070
+ UINT64 X15; 0x078
+ UINT64 X16; 0x080
+ UINT64 X17; 0x088
+ UINT64 X18; 0x090
+ UINT64 X19; 0x098
+ UINT64 X20; 0x0a0
+ UINT64 X21; 0x0a8
+ UINT64 X22; 0x0b0
+ UINT64 X23; 0x0b8
+ UINT64 X24; 0x0c0
+ UINT64 X25; 0x0c8
+ UINT64 X26; 0x0d0
+ UINT64 X27; 0x0d8
+ UINT64 X28; 0x0e0
+ UINT64 FP; 0x0e8 // x29 - Frame Pointer
+ UINT64 LR; 0x0f0 // x30 - Link Register
+ UINT64 SP; 0x0f8 // x31 - Stack Pointer
+
+ // FP/SIMD Registers. 128bit if used as Q-regs.
+ UINT64 V0[2]; 0x100
+ UINT64 V1[2]; 0x110
+ UINT64 V2[2]; 0x120
+ UINT64 V3[2]; 0x130
+ UINT64 V4[2]; 0x140
+ UINT64 V5[2]; 0x150
+ UINT64 V6[2]; 0x160
+ UINT64 V7[2]; 0x170
+ UINT64 V8[2]; 0x180
+ UINT64 V9[2]; 0x190
+ UINT64 V10[2]; 0x1a0
+ UINT64 V11[2]; 0x1b0
+ UINT64 V12[2]; 0x1c0
+ UINT64 V13[2]; 0x1d0
+ UINT64 V14[2]; 0x1e0
+ UINT64 V15[2]; 0x1f0
+ UINT64 V16[2]; 0x200
+ UINT64 V17[2]; 0x210
+ UINT64 V18[2]; 0x220
+ UINT64 V19[2]; 0x230
+ UINT64 V20[2]; 0x240
+ UINT64 V21[2]; 0x250
+ UINT64 V22[2]; 0x260
+ UINT64 V23[2]; 0x270
+ UINT64 V24[2]; 0x280
+ UINT64 V25[2]; 0x290
+ UINT64 V26[2]; 0x2a0
+ UINT64 V27[2]; 0x2b0
+ UINT64 V28[2]; 0x2c0
+ UINT64 V29[2]; 0x2d0
+ UINT64 V30[2]; 0x2e0
+ UINT64 V31[2]; 0x2f0
+
+ // System Context
+ UINT64 ELR; 0x300 // Exception Link Register
+ UINT64 SPSR; 0x308 // Saved Processor Status Register
+ UINT64 FPSR; 0x310 // Floating Point Status Register
+ UINT64 ESR; 0x318 // Exception syndrome register
+ UINT64 FAR; 0x320 // Fault Address Register
+ UINT64 Padding;0x328 // Required for stack alignment
+*/
+
+GCC_ASM_EXPORT(ExceptionHandlersStart)
+GCC_ASM_EXPORT(ExceptionHandlersEnd)
+GCC_ASM_EXPORT(CommonExceptionEntry)
+GCC_ASM_EXPORT(AsmCommonExceptionEntry)
+GCC_ASM_EXPORT(CommonCExceptionHandler)
+
+.text
+.align 11
+
+#define GP_CONTEXT_SIZE (32 * 8)
+#define FP_CONTEXT_SIZE (32 * 16)
+#define SYS_CONTEXT_SIZE ( 6 * 8) // 5 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)
+
+// Cannot str x31 directly
+#define ALL_GP_REGS \
+ REG_PAIR (x0, x1, 0x000, GP_CONTEXT_SIZE); \
+ REG_PAIR (x2, x3, 0x010, GP_CONTEXT_SIZE); \
+ REG_PAIR (x4, x5, 0x020, GP_CONTEXT_SIZE); \
+ REG_PAIR (x6, x7, 0x030, GP_CONTEXT_SIZE); \
+ REG_PAIR (x8, x9, 0x040, GP_CONTEXT_SIZE); \
+ REG_PAIR (x10, x11, 0x050, GP_CONTEXT_SIZE); \
+ REG_PAIR (x12, x13, 0x060, GP_CONTEXT_SIZE); \
+ REG_PAIR (x14, x15, 0x070, GP_CONTEXT_SIZE); \
+ REG_PAIR (x16, x17, 0x080, GP_CONTEXT_SIZE); \
+ REG_PAIR (x18, x19, 0x090, GP_CONTEXT_SIZE); \
+ REG_PAIR (x20, x21, 0x0a0, GP_CONTEXT_SIZE); \
+ REG_PAIR (x22, x23, 0x0b0, GP_CONTEXT_SIZE); \
+ REG_PAIR (x24, x25, 0x0c0, GP_CONTEXT_SIZE); \
+ REG_PAIR (x26, x27, 0x0d0, GP_CONTEXT_SIZE); \
+ REG_PAIR (x28, x29, 0x0e0, GP_CONTEXT_SIZE); \
+ REG_ONE (x30, 0x0f0, GP_CONTEXT_SIZE);
+
+// In order to save the SP we need to put it somewhere else first.
+// STR only works with XZR/WZR directly
+#define SAVE_SP \
+ add x1, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE); \
+ REG_ONE (x1, 0x0f8, GP_CONTEXT_SIZE);
+
+#define ALL_FP_REGS \
+ REG_PAIR (q0, q1, 0x000, FP_CONTEXT_SIZE); \
+ REG_PAIR (q2, q3, 0x020, FP_CONTEXT_SIZE); \
+ REG_PAIR (q4, q5, 0x040, FP_CONTEXT_SIZE); \
+ REG_PAIR (q6, q7, 0x060, FP_CONTEXT_SIZE); \
+ REG_PAIR (q8, q9, 0x080, FP_CONTEXT_SIZE); \
+ REG_PAIR (q10, q11, 0x0a0, FP_CONTEXT_SIZE); \
+ REG_PAIR (q12, q13, 0x0c0, FP_CONTEXT_SIZE); \
+ REG_PAIR (q14, q15, 0x0e0, FP_CONTEXT_SIZE); \
+ REG_PAIR (q16, q17, 0x100, FP_CONTEXT_SIZE); \
+ REG_PAIR (q18, q19, 0x120, FP_CONTEXT_SIZE); \
+ REG_PAIR (q20, q21, 0x140, FP_CONTEXT_SIZE); \
+ REG_PAIR (q22, q23, 0x160, FP_CONTEXT_SIZE); \
+ REG_PAIR (q24, q25, 0x180, FP_CONTEXT_SIZE); \
+ REG_PAIR (q26, q27, 0x1a0, FP_CONTEXT_SIZE); \
+ REG_PAIR (q28, q29, 0x1c0, FP_CONTEXT_SIZE); \
+ REG_PAIR (q30, q31, 0x1e0, FP_CONTEXT_SIZE);
+
+#define ALL_SYS_REGS \
+ REG_PAIR (x1, x2, 0x000, SYS_CONTEXT_SIZE); \
+ REG_PAIR (x3, x4, 0x010, SYS_CONTEXT_SIZE); \
+ REG_ONE (x5, 0x020, SYS_CONTEXT_SIZE);
+
+//
+// This code gets copied to the ARM vector table
+// VectorTableStart - VectorTableEnd gets copied
+//
+ASM_PFX(ExceptionHandlersStart):
+
+//
+// Current EL with SP0 : 0x0 - 0x180
+//
+.align 7
+ASM_PFX(SynchronousExceptionSP0):
+ b ASM_PFX(SynchronousExceptionEntry)
+
+.align 7
+ASM_PFX(IrqSP0):
+ b ASM_PFX(IrqEntry)
+
+.align 7
+ASM_PFX(FiqSP0):
+ b ASM_PFX(FiqEntry)
+
+.align 7
+ASM_PFX(SErrorSP0):
+ b ASM_PFX(SErrorEntry)
+
+//
+// Current EL with SPx: 0x200 - 0x380
+//
+.align 7
+ASM_PFX(SynchronousExceptionSPx):
+ b ASM_PFX(SynchronousExceptionEntry)
+
+.align 7
+ASM_PFX(IrqSPx):
+ b ASM_PFX(IrqEntry)
+
+.align 7
+ASM_PFX(FiqSPx):
+ b ASM_PFX(FiqEntry)
+
+.align 7
+ASM_PFX(SErrorSPx):
+ b ASM_PFX(SErrorEntry)
+
+//
+// Lower EL using AArch64 : 0x400 - 0x580
+//
+.align 7
+ASM_PFX(SynchronousExceptionA64):
+ b ASM_PFX(SynchronousExceptionEntry)
+
+.align 7
+ASM_PFX(IrqA64):
+ b ASM_PFX(IrqEntry)
+
+.align 7
+ASM_PFX(FiqA64):
+ b ASM_PFX(FiqEntry)
+
+.align 7
+ASM_PFX(SErrorA64):
+ b ASM_PFX(SErrorEntry)
+
+//
+// Lower EL using AArch32 : 0x0 - 0x180
+//
+.align 7
+ASM_PFX(SynchronousExceptionA32):
+ b ASM_PFX(SynchronousExceptionEntry)
+
+.align 7
+ASM_PFX(IrqA32):
+ b ASM_PFX(IrqEntry)
+
+.align 7
+ASM_PFX(FiqA32):
+ b ASM_PFX(FiqEntry)
+
+.align 7
+ASM_PFX(SErrorA32):
+ b ASM_PFX(SErrorEntry)
+
+
+#undef REG_PAIR
+#undef REG_ONE
+#define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE) stp REG1, REG2, [sp, #(OFFSET-CONTEXT_SIZE)]
+#define REG_ONE(REG1, OFFSET, CONTEXT_SIZE) stur REG1, [sp, #(OFFSET-CONTEXT_SIZE)]
+
+ASM_PFX(SynchronousExceptionEntry):
+ // Move the stackpointer so we can reach our structure with the str instruction.
+ sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
+
+ // Save all the General regs before touching x0 and x1.
+ // This does not save r31(SP) as it is special. We do that later.
+ ALL_GP_REGS
+
+ // Record the type of exception that occurred.
+ mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS
+
+ // Jump to our general handler to deal with all the common parts and process the exception.
+ ldr x1, ASM_PFX(CommonExceptionEntry)
+ br x1
+
+ASM_PFX(IrqEntry):
+ sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
+ ALL_GP_REGS
+ mov x0, #EXCEPT_AARCH64_IRQ
+ ldr x1, ASM_PFX(CommonExceptionEntry)
+ br x1
+
+ASM_PFX(FiqEntry):
+ sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
+ ALL_GP_REGS
+ mov x0, #EXCEPT_AARCH64_FIQ
+ ldr x1, ASM_PFX(CommonExceptionEntry)
+ br x1
+
+ASM_PFX(SErrorEntry):
+ sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
+ ALL_GP_REGS
+ mov x0, #EXCEPT_AARCH64_SERROR
+ ldr x1, ASM_PFX(CommonExceptionEntry)
+ br x1
+
+
+//
+// This gets patched by the C code that patches in the vector table
+//
+.align 3
+ASM_PFX(CommonExceptionEntry):
+ .8byte ASM_PFX(AsmCommonExceptionEntry)
+
+ASM_PFX(ExceptionHandlersEnd):
+
+
+
+//
+// This code runs from CpuDxe driver loaded address. It is patched into
+// CommonExceptionEntry.
+//
+ASM_PFX(AsmCommonExceptionEntry):
+ /* NOTE:
+ We have to break up the save code because the immediate value to be used
+ with the SP is too big to do it all in one step so we need to shuffle the SP
+ along as we go. (we only have 9bits of immediate to work with) */
+
+ // Save the current Stack pointer before we start modifying it.
+ SAVE_SP
+
+ // Preserve the stack pointer we came in with before we modify it
+ EL1_OR_EL2(x1)
+1:mrs x1, elr_el1 // Exception Link Register
+ mrs x2, spsr_el1 // Saved Processor Status Register 32bit
+ mrs x3, fpsr // Floating point Status Register 32bit
+ mrs x4, esr_el1 // EL1 Exception syndrome register 32bit
+ mrs x5, far_el1 // EL1 Fault Address Register
+ b 3f
+
+2:mrs x1, elr_el2 // Exception Link Register
+ mrs x2, spsr_el2 // Saved Processor Status Register 32bit
+ mrs x3, fpsr // Floating point Status Register 32bit
+ mrs x4, esr_el2 // EL2 Exception syndrome register 32bit
+ mrs x5, far_el2 // EL2 Fault Address Register
+
+ // Adjust SP to save next set
+3:add sp, sp, #FP_CONTEXT_SIZE
+
+ // Push FP regs to Stack.
+ ALL_FP_REGS
+
+ // Adjust SP to save next set
+ add sp, sp, #SYS_CONTEXT_SIZE
+
+ // Save the SYS regs
+ ALL_SYS_REGS
+
+ // Point to top of struct after all regs saved
+ sub sp, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
+
+ // x0 still holds the exception type.
+ // Set x1 to point to the top of our struct on the Stack
+ mov x1, sp
+
+// CommonCExceptionHandler (
+// IN EFI_EXCEPTION_TYPE ExceptionType, R0
+// IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
+// )
+
+ // Call the handler as defined above
+
+ // For now we spin in the handler if we received an abort of some kind.
+ // We do not try to recover.
+ bl ASM_PFX(CommonCExceptionHandler) // Call exception handler
+
+
+// Defines for popping from stack
+
+#undef REG_PAIR
+#undef REG_ONE
+#define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE) ldp REG1, REG2, [sp, #(OFFSET-CONTEXT_SIZE)]
+#define REG_ONE(REG1, OFFSET, CONTEXT_SIZE) ldur REG1, [sp, #(OFFSET-CONTEXT_SIZE)]
+
+ // Adjust SP to pop system registers
+ add sp, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
+ ALL_SYS_REGS
+
+ EL1_OR_EL2(x6)
+1:msr elr_el1, x1 // Exception Link Register
+ msr spsr_el1,x2 // Saved Processor Status Register 32bit
+ msr fpsr, x3 // Floating point Status Register 32bit
+ msr esr_el1, x4 // EL1 Exception syndrome register 32bit
+ msr far_el1, x5 // EL1 Fault Address Register
+ b 3f
+2:msr elr_el2, x1 // Exception Link Register
+ msr spsr_el2,x2 // Saved Processor Status Register 32bit
+ msr fpsr, x3 // Floating point Status Register 32bit
+ msr esr_el2, x4 // EL2 Exception syndrome register 32bit
+ msr far_el2, x5 // EL2 Fault Address Register
+
+3:// pop all regs and return from exception.
+ sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)
+ ALL_GP_REGS
+
+ // Adjust SP to pop next set
+ add sp, sp, #FP_CONTEXT_SIZE
+ // Pop FP regs to Stack.
+ ALL_FP_REGS
+
+ // Adjust SP to be where we started from when we came into the handler.
+ // The handler can not change the SP.
+ add sp, sp, #SYS_CONTEXT_SIZE
+
+ eret
+
+#undef REG_PAIR
+#undef REG_ONE
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
new file mode 100644
index 0000000..6cba121
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
@@ -0,0 +1,341 @@
+/*++
+
+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+Portions 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 <Library/MemoryAllocationLib.h>
+#include "CpuDxe.h"
+
+#define TT_ATTR_INDX_INVALID ((UINT32)~0)
+
+STATIC
+UINT64
+GetFirstPageAttribute (
+ IN UINT64 *FirstLevelTableAddress,
+ IN UINTN TableLevel
+ )
+{
+ UINT64 FirstEntry;
+
+ // Get the first entry of the table
+ FirstEntry = *FirstLevelTableAddress;
+
+ if ((TableLevel != 3) && (FirstEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
+ // Only valid for Levels 0, 1 and 2
+
+ // Get the attribute of the subsequent table
+ return GetFirstPageAttribute ((UINT64*)(FirstEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TableLevel + 1);
+ } else if (((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) ||
+ ((TableLevel == 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3)))
+ {
+ return FirstEntry & TT_ATTR_INDX_MASK;
+ } else {
+ return TT_ATTR_INDX_INVALID;
+ }
+}
+
+STATIC
+UINT64
+GetNextEntryAttribute (
+ IN UINT64 *TableAddress,
+ IN UINTN EntryCount,
+ IN UINTN TableLevel,
+ IN UINT64 BaseAddress,
+ IN OUT UINT32 *PrevEntryAttribute,
+ IN OUT UINT64 *StartGcdRegion
+ )
+{
+ UINTN Index;
+ UINT64 Entry;
+ UINT32 EntryAttribute;
+ UINT32 EntryType;
+ EFI_STATUS Status;
+ UINTN NumberOfDescriptors;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
+
+ // Get the memory space map from GCD
+ MemorySpaceMap = NULL;
+ Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
+ ASSERT_EFI_ERROR (Status);
+
+ // We cannot get more than 3-level page table
+ ASSERT (TableLevel <= 3);
+
+ // While the top level table might not contain TT_ENTRY_COUNT entries;
+ // the subsequent ones should be filled up
+ for (Index = 0; Index < EntryCount; Index++) {
+ Entry = TableAddress[Index];
+ EntryType = Entry & TT_TYPE_MASK;
+ EntryAttribute = Entry & TT_ATTR_INDX_MASK;
+
+ // If Entry is a Table Descriptor type entry then go through the sub-level table
+ if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
+ ((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {
+ if ((*PrevEntryAttribute == TT_ATTR_INDX_INVALID) || (EntryAttribute != *PrevEntryAttribute)) {
+ if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
+ // Update GCD with the last region
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
+ *StartGcdRegion,
+ (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,
+ PageAttributeToGcdAttribute (*PrevEntryAttribute));
+ }
+
+ // Start of the new region
+ *StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
+ *PrevEntryAttribute = EntryAttribute;
+ } else {
+ continue;
+ }
+ } else if (EntryType == TT_TYPE_TABLE_ENTRY) {
+ // Table Entry type is only valid for Level 0, 1, 2
+ ASSERT (TableLevel < 3);
+
+ // Increase the level number and scan the sub-level table
+ GetNextEntryAttribute ((UINT64*)(Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE),
+ TT_ENTRY_COUNT, TableLevel + 1,
+ (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),
+ PrevEntryAttribute, StartGcdRegion);
+ } else {
+ if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
+ // Update GCD with the last region
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
+ *StartGcdRegion,
+ (BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))) - *StartGcdRegion,
+ PageAttributeToGcdAttribute (*PrevEntryAttribute));
+
+ // Start of the new region
+ *StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
+ *PrevEntryAttribute = TT_ATTR_INDX_INVALID;
+ }
+ }
+ }
+
+ FreePool (MemorySpaceMap);
+
+ return BaseAddress + (EntryCount * TT_ADDRESS_AT_LEVEL(TableLevel));
+}
+
+EFI_STATUS
+SyncCacheConfig (
+ IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
+ )
+{
+ EFI_STATUS Status;
+ UINT32 PageAttribute = 0;
+ UINT64 *FirstLevelTableAddress;
+ UINTN TableLevel;
+ UINTN TableCount;
+ UINTN NumberOfDescriptors;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
+ UINTN Tcr;
+ UINTN T0SZ;
+ UINT64 BaseAddressGcdRegion;
+ UINT64 EndAddressGcdRegion;
+
+ // This code assumes MMU is enabled and filed with section translations
+ ASSERT (ArmMmuEnabled ());
+
+ //
+ // Get the memory space map from GCD
+ //
+ MemorySpaceMap = NULL;
+ Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
+ ASSERT_EFI_ERROR (Status);
+
+ // The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
+ // to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
+ // GetMemoryAttributes function for GCD to get this so we must resort to calling GCD (as if we were
+ // a client) to update its copy of the attributes. This is bad architecture and should be replaced
+ // with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.
+
+ // Obtain page table base
+ FirstLevelTableAddress = (UINT64*)(ArmGetTTBR0BaseAddress ());
+
+ // Get Translation Control Register value
+ Tcr = ArmGetTCR ();
+ // Get Address Region Size
+ T0SZ = Tcr & TCR_T0SZ_MASK;
+
+ // Get the level of the first table for the indicated Address Region Size
+ GetRootTranslationTableInfo (T0SZ, &TableLevel, &TableCount);
+
+ // First Attribute of the Page Tables
+ PageAttribute = GetFirstPageAttribute (FirstLevelTableAddress, TableLevel);
+
+ // We scan from the start of the memory map (ie: at the address 0x0)
+ BaseAddressGcdRegion = 0x0;
+ EndAddressGcdRegion = GetNextEntryAttribute (FirstLevelTableAddress,
+ TableCount, TableLevel,
+ BaseAddressGcdRegion,
+ &PageAttribute, &BaseAddressGcdRegion);
+
+ // Update GCD with the last region if valid
+ if (PageAttribute != TT_ATTR_INDX_INVALID) {
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
+ BaseAddressGcdRegion,
+ EndAddressGcdRegion - BaseAddressGcdRegion,
+ PageAttributeToGcdAttribute (PageAttribute));
+ }
+
+ FreePool (MemorySpaceMap);
+
+ return EFI_SUCCESS;
+}
+
+UINT64
+EfiAttributeToArmAttribute (
+ IN UINT64 EfiAttributes
+ )
+{
+ UINT64 ArmAttributes;
+
+ switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) {
+ case EFI_MEMORY_UC:
+ ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY;
+ break;
+ case EFI_MEMORY_WC:
+ ArmAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
+ break;
+ case EFI_MEMORY_WT:
+ ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH;
+ break;
+ case EFI_MEMORY_WB:
+ ArmAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK;
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "EfiAttributeToArmAttribute: 0x%lX attributes is not supported.\n", EfiAttributes));
+ ASSERT (0);
+ ArmAttributes = TT_ATTR_INDX_DEVICE_MEMORY;
+ }
+
+ // Set the access flag to match the block attributes
+ ArmAttributes |= TT_AF;
+
+ // Determine protection attributes
+ if (EfiAttributes & EFI_MEMORY_WP) {
+ ArmAttributes |= TT_AP_RO_RO;
+ }
+
+ // Process eXecute Never attribute
+ if (EfiAttributes & EFI_MEMORY_XP) {
+ ArmAttributes |= TT_PXN_MASK;
+ }
+
+ return ArmAttributes;
+}
+
+// This function will recursively go down the page table to find the first block address linked to 'BaseAddress'.
+// And then the function will identify the size of the region that has the same page table attribute.
+EFI_STATUS
+GetMemoryRegionRec (
+ IN UINT64 *TranslationTable,
+ IN UINTN TableLevel,
+ IN UINT64 *LastBlockEntry,
+ IN OUT UINTN *BaseAddress,
+ OUT UINTN *RegionLength,
+ OUT UINTN *RegionAttributes
+ )
+{
+ EFI_STATUS Status;
+ UINT64 *NextTranslationTable;
+ UINT64 *BlockEntry;
+ UINT64 BlockEntryType;
+ UINT64 EntryType;
+
+ if (TableLevel != 3) {
+ BlockEntryType = TT_TYPE_BLOCK_ENTRY;
+ } else {
+ BlockEntryType = TT_TYPE_BLOCK_ENTRY_LEVEL3;
+ }
+
+ // Find the block entry linked to the Base Address
+ BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, TableLevel, *BaseAddress);
+ EntryType = *BlockEntry & TT_TYPE_MASK;
+
+ if ((TableLevel < 3) && (EntryType == TT_TYPE_TABLE_ENTRY)) {
+ NextTranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
+
+ // The entry is a page table, so we go to the next level
+ Status = GetMemoryRegionRec (
+ NextTranslationTable, // Address of the next level page table
+ TableLevel + 1, // Next Page Table level
+ (UINTN*)TT_LAST_BLOCK_ADDRESS(NextTranslationTable, TT_ENTRY_COUNT),
+ BaseAddress, RegionLength, RegionAttributes);
+
+ // In case of 'Success', it means the end of the block region has been found into the upper
+ // level translation table
+ if (!EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+ } else if (EntryType == BlockEntryType) {
+ // We have found the BlockEntry attached to the address. We save its start address (the start
+ // address might be before the 'BaseAdress') and attributes
+ *BaseAddress = *BaseAddress & ~(TT_ADDRESS_AT_LEVEL(TableLevel) - 1);
+ *RegionLength = 0;
+ *RegionAttributes = *BlockEntry & TT_ATTRIBUTES_MASK;
+ } else {
+ // We have an 'Invalid' entry
+ return EFI_UNSUPPORTED;
+ }
+
+ while (BlockEntry <= LastBlockEntry) {
+ if ((*BlockEntry & TT_ATTRIBUTES_MASK) == *RegionAttributes) {
+ *RegionLength = *RegionLength + TT_BLOCK_ENTRY_SIZE_AT_LEVEL(TableLevel);
+ } else {
+ // In case we have found the end of the region we return success
+ return EFI_SUCCESS;
+ }
+ BlockEntry++;
+ }
+
+ // If we have reached the end of the TranslationTable and we have not found the end of the region then
+ // we return EFI_NOT_FOUND.
+ // The caller will continue to look for the memory region at its level
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+GetMemoryRegion (
+ IN OUT UINTN *BaseAddress,
+ OUT UINTN *RegionLength,
+ OUT UINTN *RegionAttributes
+ )
+{
+ EFI_STATUS Status;
+ UINT64 *TranslationTable;
+ UINTN TableLevel;
+ UINTN EntryCount;
+ UINTN T0SZ;
+
+ ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL));
+
+ TranslationTable = ArmGetTTBR0BaseAddress ();
+
+ T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
+ // Get the Table info from T0SZ
+ GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount);
+
+ Status = GetMemoryRegionRec (TranslationTable, TableLevel,
+ (UINTN*)TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount),
+ BaseAddress, RegionLength, RegionAttributes);
+
+ // If the region continues up to the end of the root table then GetMemoryRegionRec()
+ // will return EFI_NOT_FOUND
+ if (Status == EFI_NOT_FOUND) {
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.S b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.S
new file mode 100644
index 0000000..c82618a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.S
@@ -0,0 +1,191 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ExceptionHandlersStart)
+GCC_ASM_EXPORT(ExceptionHandlersEnd)
+GCC_ASM_EXPORT(CommonExceptionEntry)
+GCC_ASM_EXPORT(AsmCommonExceptionEntry)
+GCC_ASM_EXPORT(CommonCExceptionHandler)
+
+ASM_PFX(ExceptionHandlersStart):
+
+ASM_PFX(Reset):
+ b ASM_PFX(ResetEntry)
+
+ASM_PFX(UndefinedInstruction):
+ b ASM_PFX(UndefinedInstructionEntry)
+
+ASM_PFX(SoftwareInterrupt):
+ b ASM_PFX(SoftwareInterruptEntry)
+
+ASM_PFX(PrefetchAbort):
+ b ASM_PFX(PrefetchAbortEntry)
+
+ASM_PFX(DataAbort):
+ b ASM_PFX(DataAbortEntry)
+
+ASM_PFX(ReservedException):
+ b ASM_PFX(ReservedExceptionEntry)
+
+ASM_PFX(Irq):
+ b ASM_PFX(IrqEntry)
+
+ASM_PFX(Fiq):
+ b ASM_PFX(FiqEntry)
+
+ASM_PFX(ResetEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#0
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(UndefinedInstructionEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov r0,#1
+ ldr r1,ASM_PFX(CommonExceptionEntry)
+ bx r1
+
+ASM_PFX(SoftwareInterruptEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov r0,#2
+ ldr r1,ASM_PFX(CommonExceptionEntry)
+ bx r1
+
+ASM_PFX(PrefetchAbortEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov r0,#3
+ ldr r1,ASM_PFX(CommonExceptionEntry)
+ bx r1
+
+ASM_PFX(DataAbortEntry):
+ sub LR,LR,#8
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov r0,#4
+ ldr r1,ASM_PFX(CommonExceptionEntry)
+ bx r1
+
+ASM_PFX(ReservedExceptionEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov r0,#5
+ ldr r1,ASM_PFX(CommonExceptionEntry)
+ bx r1
+
+ASM_PFX(IrqEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov r0,#6
+ ldr r1,ASM_PFX(CommonExceptionEntry)
+ bx r1
+
+ASM_PFX(FiqEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov r0,#7
+ ldr r1,ASM_PFX(CommonExceptionEntry)
+ bx r1
+
+ASM_PFX(CommonExceptionEntry):
+ .byte 0x12
+ .byte 0x34
+ .byte 0x56
+ .byte 0x78
+
+ASM_PFX(ExceptionHandlersEnd):
+
+ASM_PFX(AsmCommonExceptionEntry):
+ mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
+ str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
+
+ mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
+ str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+
+ mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
+ str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+
+ mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
+ str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+
+ ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
+ str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+ and r1, r1, #0x1f @ Check to see if User or System Mode
+ cmp r1, #0x1f
+ cmpne r1, #0x10
+ add R2, SP, #0x38 @ Store it in EFI_SYSTEM_CONTEXT_ARM.LR
+ ldmneed r2, {lr}^ @ User or System mode, use unbanked register
+ ldmneed r2, {lr} @ All other modes used banked register
+
+ ldr R1, [SP, #0x58] @ PC is the LR pushed by srsdb
+ str R1, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+ sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
+ str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+
+ @ R0 is exception type
+ mov R1,SP @ Prepare System Context pointer as an argument for the exception handler
+ blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
+
+ ldr R2,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
+ str R2,[SP,#0x5c] @ Store it back to srsdb stack slot so it can be restored
+
+ ldr R2,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
+ str R2,[SP,#0x58] @ Store it back to srsdb stack slot so it can be restored
+
+ ldmfd SP!,{R0-R12} @ Restore general purpose registers
+ @ Exception handler can not change SP or LR as we would blow chunks
+
+ add SP,SP,#0x20 @ Clear out the remaining stack space
+ ldmfd SP!,{LR} @ restore the link register for this context
+ rfefd SP! @ return from exception via srsdb stack slot
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.asm b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.asm
new file mode 100644
index 0000000..9f09a0b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV4/ExceptionSupport.asm
@@ -0,0 +1,152 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+ EXPORT ExceptionHandlersStart
+ EXPORT ExceptionHandlersEnd
+ EXPORT CommonExceptionEntry
+ EXPORT AsmCommonExceptionEntry
+ IMPORT CommonCExceptionHandler
+
+ PRESERVE8
+ AREA DxeExceptionHandlers, CODE, READONLY
+
+ExceptionHandlersStart
+
+Reset
+ b ResetEntry
+
+UndefinedInstruction
+ b UndefinedInstructionEntry
+
+SoftwareInterrupt
+ b SoftwareInterruptEntry
+
+PrefetchAbort
+ b PrefetchAbortEntry
+
+DataAbort
+ b DataAbortEntry
+
+ReservedException
+ b ReservedExceptionEntry
+
+Irq
+ b IrqEntry
+
+Fiq
+ b FiqEntry
+
+ResetEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#0
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+UndefinedInstructionEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#1
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+SoftwareInterruptEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#2
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+PrefetchAbortEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#3
+ SUB LR,LR,#4
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+DataAbortEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#4
+ SUB LR,LR,#8
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+ReservedExceptionEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#5
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+IrqEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#6
+ SUB LR,LR,#4
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+FiqEntry
+ stmfd SP!,{R0-R1}
+ mov R0,#7
+ SUB LR,LR,#4
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+CommonExceptionEntry
+ dcd 0x12345678
+
+ExceptionHandlersEnd
+
+AsmCommonExceptionEntry
+ mrc p15, 0, r1, c6, c0, 2 ; Read IFAR
+ stmfd SP!,{R1} ; Store the IFAR
+
+ mrc p15, 0, r1, c5, c0, 1 ; Read IFSR
+ stmfd SP!,{R1} ; Store the IFSR
+
+ mrc p15, 0, r1, c6, c0, 0 ; Read DFAR
+ stmfd SP!,{R1} ; Store the DFAR
+
+ mrc p15, 0, r1, c5, c0, 0 ; Read DFSR
+ stmfd SP!,{R1} ; Store the DFSR
+
+ mrs R1,SPSR ; Read SPSR (which is the pre-exception CPSR)
+ stmfd SP!,{R1} ; Store the SPSR
+
+ stmfd SP!,{LR} ; Store the link register (which is the pre-exception PC)
+ stmfd SP,{SP,LR}^ ; Store user/system mode stack pointer and link register
+ nop ; Required by ARM architecture
+ SUB SP,SP,#0x08 ; Adjust stack pointer
+ stmfd SP!,{R2-R12} ; Store general purpose registers
+
+ ldr R3,[SP,#0x50] ; Read saved R1 from the stack (it was saved by the exception entry routine)
+ ldr R2,[SP,#0x4C] ; Read saved R0 from the stack (it was saved by the exception entry routine)
+ stmfd SP!,{R2-R3} ; Store general purpose registers R0 and R1
+
+ mov R1,SP ; Prepare System Context pointer as an argument for the exception handler
+
+ sub SP,SP,#4 ; Adjust SP to preserve 8-byte alignment
+ blx CommonCExceptionHandler ; Call exception handler
+ add SP,SP,#4 ; Adjust SP back to where we were
+
+ ldr R2,[SP,#0x40] ; Load CPSR from context, in case it has changed
+ MSR SPSR_cxsf,R2 ; Store it back to the SPSR to be restored when exiting this handler
+
+ ldmfd SP!,{R0-R12} ; Restore general purpose registers
+ ldm SP,{SP,LR}^ ; Restore user/system mode stack pointer and link register
+ nop ; Required by ARM architecture
+ add SP,SP,#0x08 ; Adjust stack pointer
+ ldmfd SP!,{LR} ; Restore the link register (which is the pre-exception PC)
+ add SP,SP,#0x1C ; Clear out the remaining stack space
+ movs PC,LR ; Return from exception
+
+ END
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c
new file mode 100644
index 0000000..4b05199
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c
@@ -0,0 +1,234 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2014, ARM Limited. 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 "CpuDxe.h"
+
+//FIXME: Will not compile on non-ARMv7 builds
+#include <Chipset/ArmV7.h>
+
+VOID
+ExceptionHandlersStart (
+ VOID
+ );
+
+VOID
+ExceptionHandlersEnd (
+ VOID
+ );
+
+VOID
+CommonExceptionEntry (
+ VOID
+ );
+
+VOID
+AsmCommonExceptionEntry (
+ VOID
+ );
+
+
+EFI_EXCEPTION_CALLBACK gExceptionHandlers[MAX_ARM_EXCEPTION + 1];
+EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_ARM_EXCEPTION + 1];
+
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ if (InterruptType > MAX_ARM_EXCEPTION) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ gExceptionHandlers[InterruptType] = InterruptHandler;
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+VOID
+EFIAPI
+CommonCExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ if (ExceptionType <= MAX_ARM_EXCEPTION) {
+ if (gExceptionHandlers[ExceptionType]) {
+ gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);
+ return;
+ }
+ } else {
+ DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %08x\n", ExceptionType, SystemContext.SystemContextArm->PC));
+ ASSERT (FALSE);
+ }
+
+ if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {
+ //
+ // ARM JTAG debuggers some times use this vector, so it is not an error to get one
+ //
+ return;
+ }
+
+ DefaultExceptionHandler (ExceptionType, SystemContext);
+}
+
+
+
+EFI_STATUS
+InitializeExceptions (
+ IN EFI_CPU_ARCH_PROTOCOL *Cpu
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINTN Length;
+ UINTN Index;
+ BOOLEAN IrqEnabled;
+ BOOLEAN FiqEnabled;
+ EFI_PHYSICAL_ADDRESS Base;
+ UINT32 *VectorBase;
+
+ Status = EFI_SUCCESS;
+ ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers));
+
+ //
+ // Disable interrupts
+ //
+ Cpu->GetInterruptState (Cpu, &IrqEnabled);
+ Cpu->DisableInterrupt (Cpu);
+
+ //
+ // EFI does not use the FIQ, but a debugger might so we must disable
+ // as we take over the exception vectors.
+ //
+ FiqEnabled = ArmGetFiqState ();
+ ArmDisableFiq ();
+
+ if (FeaturePcdGet(PcdRelocateVectorTable) == TRUE) {
+ //
+ // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.
+ //
+ Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
+
+ // Check if the exception vector is in the low address
+ if (PcdGet32 (PcdCpuVectorBaseAddress) == 0x0) {
+ // Set SCTLR.V to 0 to enable VBAR to be used
+ ArmSetLowVectors ();
+ } else {
+ ArmSetHighVectors ();
+ }
+
+ //
+ // Reserve space for the exception handlers
+ //
+ Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);
+ VectorBase = (UINT32 *)(UINTN)Base;
+ Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);
+ // If the request was for memory that's not in the memory map (which is often the case for 0x00000000
+ // on embedded systems, for example, we don't want to hang up. So we'll check here for a status of
+ // EFI_NOT_FOUND, and continue in that case.
+ if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (FeaturePcdGet(PcdDebuggerExceptionSupport) == TRUE) {
+ // Save existing vector table, in case debugger is already hooked in
+ CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));
+ }
+
+ // Copy our assembly code into the page that contains the exception vectors.
+ CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);
+
+ //
+ // Patch in the common Assembly exception handler
+ //
+ Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;
+ *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;
+
+ //
+ // Initialize the C entry points for interrupts
+ //
+ for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {
+ if (!FeaturePcdGet(PcdDebuggerExceptionSupport) ||
+ (gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {
+ // Exception handler contains branch to vector location (jmp $) so no handler
+ // NOTE: This code assumes vectors are ARM and not Thumb code
+ Status = RegisterInterruptHandler (Index, NULL);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ // If the debugger has already hooked put its vector back
+ VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];
+ }
+ }
+
+ // Flush Caches since we updated executable stuff
+ InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);
+
+ //Note: On ARM processor with the Security Extension, the Vector Table can be located anywhere in the memory.
+ // The Vector Base Address Register defines the location
+ ArmWriteVBar (PcdGet32(PcdCpuVectorBaseAddress));
+ } else {
+ // The Vector table must be 32-byte aligned
+ if (((UINT32)ExceptionHandlersStart & ARM_VECTOR_TABLE_ALIGNMENT) != 0) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // We do not copy the Exception Table at PcdGet32(PcdCpuVectorBaseAddress). We just set Vector Base Address to point into CpuDxe code.
+ ArmWriteVBar ((UINT32)ExceptionHandlersStart);
+ }
+
+ if (FiqEnabled) {
+ ArmEnableFiq ();
+ }
+
+ if (IrqEnabled) {
+ //
+ // Restore interrupt state
+ //
+ Status = Cpu->EnableInterrupt (Cpu);
+ }
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S
new file mode 100644
index 0000000..3433b99
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S
@@ -0,0 +1,303 @@
+#------------------------------------------------------------------------------
+#
+# Use ARMv6 instruction to operate on a single stack
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2014, ARM Limited. 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 <Library/PcdLib.h>
+
+/*
+
+This is the stack constructed by the exception handler (low address to high address)
+ # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
+ Reg Offset
+ === ======
+ R0 0x00 # stmfd SP!,{R0-R12}
+ R1 0x04
+ R2 0x08
+ R3 0x0c
+ R4 0x10
+ R5 0x14
+ R6 0x18
+ R7 0x1c
+ R8 0x20
+ R9 0x24
+ R10 0x28
+ R11 0x2c
+ R12 0x30
+ SP 0x34 # reserved via subtraction 0x20 (32) from SP
+ LR 0x38
+ PC 0x3c
+ CPSR 0x40
+ DFSR 0x44
+ DFAR 0x48
+ IFSR 0x4c
+ IFAR 0x50
+
+ LR 0x54 # SVC Link register (we need to restore it)
+
+ LR 0x58 # pushed by srsfd
+ CPSR 0x5c
+
+ */
+
+
+GCC_ASM_EXPORT(ExceptionHandlersStart)
+GCC_ASM_EXPORT(ExceptionHandlersEnd)
+GCC_ASM_EXPORT(CommonExceptionEntry)
+GCC_ASM_EXPORT(AsmCommonExceptionEntry)
+GCC_ASM_EXPORT(CommonCExceptionHandler)
+
+.text
+#if !defined(__APPLE__)
+.fpu neon @ makes vpush/vpop assemble
+#endif
+.align 5
+
+
+//
+// This code gets copied to the ARM vector table
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
+//
+ASM_PFX(ExceptionHandlersStart):
+
+ASM_PFX(Reset):
+ b ASM_PFX(ResetEntry)
+
+ASM_PFX(UndefinedInstruction):
+ b ASM_PFX(UndefinedInstructionEntry)
+
+ASM_PFX(SoftwareInterrupt):
+ b ASM_PFX(SoftwareInterruptEntry)
+
+ASM_PFX(PrefetchAbort):
+ b ASM_PFX(PrefetchAbortEntry)
+
+ASM_PFX(DataAbort):
+ b ASM_PFX(DataAbortEntry)
+
+ASM_PFX(ReservedException):
+ b ASM_PFX(ReservedExceptionEntry)
+
+ASM_PFX(Irq):
+ b ASM_PFX(IrqEntry)
+
+ASM_PFX(Fiq):
+ b ASM_PFX(FiqEntry)
+
+ASM_PFX(ResetEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ @ We are already in SVC mode
+
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#0 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(UndefinedInstructionEntry):
+ sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#1 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(SoftwareInterruptEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ @ We are already in SVC mode
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#2 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(PrefetchAbortEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#3 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(DataAbortEntry):
+ sub LR,LR,#8
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#4
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(ReservedExceptionEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#5
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(IrqEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#6 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(FiqEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+ @ Since we have already switch to SVC R8_fiq - R12_fiq
+ @ never get used or saved
+ mov R0,#7 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+//
+// This gets patched by the C code that patches in the vector table
+//
+ASM_PFX(CommonExceptionEntry):
+ .word ASM_PFX(AsmCommonExceptionEntry)
+
+ASM_PFX(ExceptionHandlersEnd):
+
+//
+// This code runs from CpuDxe driver loaded address. It is patched into
+// CommonExceptionEntry.
+//
+ASM_PFX(AsmCommonExceptionEntry):
+ mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
+ str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
+
+ mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
+ str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+
+ mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
+ str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+
+ mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
+ str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+
+ ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
+ str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+
+ add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R3, R1, #0x1f @ Check CPSR to see if User or System Mode
+ cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R3, #0x10 @
+ stmeqed R2, {lr}^ @ save unbanked lr
+ @ else
+ stmneed R2, {lr} @ save SVC lr
+
+
+ ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
+ @ Check to see if we have to adjust for Thumb entry
+ sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType == 2)) {
+ cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb
+ bhi NoAdjustNeeded
+
+ tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
+ addne R5, R5, #2 @ PC += 2;
+ strne R5,[SP,#0x58] @ Update LR value pushed by srsfd
+
+NoAdjustNeeded:
+
+ str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+ add R1, SP, #0x60 @ We pushed 0x60 bytes on the stack
+ str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+
+ @ R0 is ExceptionType
+ mov R1,SP @ R1 is SystemContext
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpush {d0-d15} @ save vstm registers in case they are used in optimizations
+#endif
+
+ mov R4, SP @ Save current SP
+ tst R4, #4
+ subne SP, SP, #4 @ Adjust SP if not 8-byte aligned
+
+/*
+VOID
+EFIAPI
+CommonCExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType, R0
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
+ )
+
+*/
+ blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
+
+ mov SP, R4 @ Restore SP
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpop {d0-d15}
+#endif
+
+ ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
+ mcr p15, 0, R1, c5, c0, 1 @ Write IFSR
+
+ ldr R1, [SP, #0x44] @ Restore EFI_SYSTEM_CONTEXT_ARM.DFSR
+ mcr p15, 0, R1, c5, c0, 0 @ Write DFSR
+
+ ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
+ str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
+
+ ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
+ str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
+
+ add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
+ add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R1, R1, #0x1f @ Check to see if User or System Mode
+ cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R1, #0x10 @
+ ldmeqed R2, {lr}^ @ restore unbanked lr
+ @ else
+ ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
+
+ ldmfd SP!,{R0-R12} @ Restore general purpose registers
+ @ Exception handler can not change SP
+
+ add SP,SP,#0x20 @ Clear out the remaining stack space
+ ldmfd SP!,{LR} @ restore the link register for this context
+ rfefd SP! @ return from exception via srsfd stack slot
+
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm
new file mode 100644
index 0000000..b28ff9f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm
@@ -0,0 +1,301 @@
+//------------------------------------------------------------------------------
+//
+// Use ARMv6 instruction to operate on a single stack
+//
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+// Copyright (c) 2014, ARM Limited. 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 <Library/PcdLib.h>
+
+/*
+
+This is the stack constructed by the exception handler (low address to high address)
+ # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
+ Reg Offset
+ === ======
+ R0 0x00 # stmfd SP!,{R0-R12}
+ R1 0x04
+ R2 0x08
+ R3 0x0c
+ R4 0x10
+ R5 0x14
+ R6 0x18
+ R7 0x1c
+ R8 0x20
+ R9 0x24
+ R10 0x28
+ R11 0x2c
+ R12 0x30
+ SP 0x34 # reserved via subtraction 0x20 (32) from SP
+ LR 0x38
+ PC 0x3c
+ CPSR 0x40
+ DFSR 0x44
+ DFAR 0x48
+ IFSR 0x4c
+ IFAR 0x50
+
+ LR 0x54 # SVC Link register (we need to restore it)
+
+ LR 0x58 # pushed by srsfd
+ CPSR 0x5c
+
+ */
+
+
+ EXPORT ExceptionHandlersStart
+ EXPORT ExceptionHandlersEnd
+ EXPORT CommonExceptionEntry
+ EXPORT AsmCommonExceptionEntry
+ IMPORT CommonCExceptionHandler
+
+ PRESERVE8
+ AREA DxeExceptionHandlers, CODE, READONLY, CODEALIGN, ALIGN=5
+
+//
+// This code gets copied to the ARM vector table
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
+//
+ExceptionHandlersStart
+
+Reset
+ b ResetEntry
+
+UndefinedInstruction
+ b UndefinedInstructionEntry
+
+SoftwareInterrupt
+ b SoftwareInterruptEntry
+
+PrefetchAbort
+ b PrefetchAbortEntry
+
+DataAbort
+ b DataAbortEntry
+
+ReservedException
+ b ReservedExceptionEntry
+
+Irq
+ b IrqEntry
+
+Fiq
+ b FiqEntry
+
+ResetEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ ; We are already in SVC mode
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#0 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+UndefinedInstructionEntry
+ sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#1 ; ExceptionType
+ ldr R1,CommonExceptionEntry;
+ bx R1
+
+SoftwareInterruptEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ ; We are already in SVC mode
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#2 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+PrefetchAbortEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#3 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+DataAbortEntry
+ sub LR,LR,#8
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#4 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+ReservedExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#5 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+IrqEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#6 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+FiqEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+ ; Since we have already switch to SVC R8_fiq - R12_fiq
+ ; never get used or saved
+ mov R0,#7 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+//
+// This gets patched by the C code that patches in the vector table
+//
+CommonExceptionEntry
+ dcd AsmCommonExceptionEntry
+
+ExceptionHandlersEnd
+
+//
+// This code runs from CpuDxe driver loaded address. It is patched into
+// CommonExceptionEntry.
+//
+AsmCommonExceptionEntry
+ mrc p15, 0, R1, c6, c0, 2 ; Read IFAR
+ str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
+
+ mrc p15, 0, R1, c5, c0, 1 ; Read IFSR
+ str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+
+ mrc p15, 0, R1, c6, c0, 0 ; Read DFAR
+ str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+
+ mrc p15, 0, R1, c5, c0, 0 ; Read DFSR
+ str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+
+ ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack
+ str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+
+ add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R3, R1, #0x1f ; Check CPSR to see if User or System Mode
+ cmp R3, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R3, #0x10 ;
+ stmeqed R2, {lr}^ ; save unbanked lr
+ ; else
+ stmneed R2, {lr} ; save SVC lr
+
+
+ ldr R5, [SP, #0x58] ; PC is the LR pushed by srsfd
+ ; Check to see if we have to adjust for Thumb entry
+ sub r4, r0, #1 ; if (ExceptionType == 1 || ExceptionType == 2)) {
+ cmp r4, #1 ; // UND & SVC have differnt LR adjust for Thumb
+ bhi NoAdjustNeeded
+
+ tst r1, #0x20 ; if ((CPSR & T)) == T) { // Thumb Mode on entry
+ addne R5, R5, #2 ; PC += 2;
+ strne R5,[SP,#0x58] ; Update LR value pushed by srsfd
+
+NoAdjustNeeded
+
+ str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+ add R1, SP, #0x60 ; We pushed 0x60 bytes on the stack
+ str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+
+ ; R0 is ExceptionType
+ mov R1,SP ; R1 is SystemContext
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpush {d0-d15} ; save vstm registers in case they are used in optimizations
+#endif
+
+ mov R4, SP ; Save current SP
+ tst R4, #4
+ subne SP, SP, #4 ; Adjust SP if not 8-byte aligned
+
+/*
+VOID
+EFIAPI
+CommonCExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType, R0
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
+ )
+
+*/
+ blx CommonCExceptionHandler ; Call exception handler
+
+ mov SP, R4 ; Restore SP
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpop {d0-d15}
+#endif
+
+ ldr R1, [SP, #0x4c] ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
+ mcr p15, 0, R1, c5, c0, 1 ; Write IFSR
+
+ ldr R1, [SP, #0x44] ; Restore EFI_SYSTEM_CONTEXT_ARM.DFSR
+ mcr p15, 0, R1, c5, c0, 0 ; Write DFSR
+
+ ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC
+ str R1,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored
+
+ ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR
+ str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored
+
+ add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry
+ add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R1, R1, #0x1f ; Check to see if User or System Mode
+ cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R1, #0x10 ;
+ ldmeqed R2, {lr}^ ; restore unbanked lr
+ ; else
+ ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR}
+
+ ldmfd SP!,{R0-R12} ; Restore general purpose registers
+ ; Exception handler can not change SP
+
+ add SP,SP,#0x20 ; Clear out the remaining stack space
+ ldmfd SP!,{LR} ; restore the link register for this context
+ rfefd SP! ; return from exception via srsfd stack slot
+
+ END
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c
new file mode 100644
index 0000000..63da8ba
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c
@@ -0,0 +1,880 @@
+/*++
+
+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+Portions copyright (c) 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 <Library/MemoryAllocationLib.h>
+#include "CpuDxe.h"
+
+// First Level Descriptors
+typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR;
+
+// Second Level Descriptors
+typedef UINT32 ARM_PAGE_TABLE_ENTRY;
+
+EFI_STATUS
+SectionToGcdAttributes (
+ IN UINT32 SectionAttributes,
+ OUT UINT64 *GcdAttributes
+ )
+{
+ *GcdAttributes = 0;
+
+ // determine cacheability attributes
+ switch(SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {
+ case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED:
+ *GcdAttributes |= EFI_MEMORY_UC;
+ break;
+ case TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE:
+ *GcdAttributes |= EFI_MEMORY_UC;
+ break;
+ case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:
+ *GcdAttributes |= EFI_MEMORY_WT;
+ break;
+ case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC:
+ *GcdAttributes |= EFI_MEMORY_WB;
+ break;
+ case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE:
+ *GcdAttributes |= EFI_MEMORY_WC;
+ break;
+ case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC:
+ *GcdAttributes |= EFI_MEMORY_WB;
+ break;
+ case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE:
+ *GcdAttributes |= EFI_MEMORY_UC;
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ // determine protection attributes
+ switch(SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {
+ case TT_DESCRIPTOR_SECTION_AP_NO_NO: // no read, no write
+ //*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;
+ break;
+
+ case TT_DESCRIPTOR_SECTION_AP_RW_NO:
+ case TT_DESCRIPTOR_SECTION_AP_RW_RW:
+ // normal read/write access, do not add additional attributes
+ break;
+
+ // read only cases map to write-protect
+ case TT_DESCRIPTOR_SECTION_AP_RO_NO:
+ case TT_DESCRIPTOR_SECTION_AP_RO_RO:
+ *GcdAttributes |= EFI_MEMORY_WP;
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ // now process eXectue Never attribute
+ if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {
+ *GcdAttributes |= EFI_MEMORY_XP;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PageToGcdAttributes (
+ IN UINT32 PageAttributes,
+ OUT UINT64 *GcdAttributes
+ )
+{
+ *GcdAttributes = 0;
+
+ // determine cacheability attributes
+ switch(PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {
+ case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:
+ *GcdAttributes |= EFI_MEMORY_UC;
+ break;
+ case TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE:
+ *GcdAttributes |= EFI_MEMORY_UC;
+ break;
+ case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:
+ *GcdAttributes |= EFI_MEMORY_WT;
+ break;
+ case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC:
+ *GcdAttributes |= EFI_MEMORY_WB;
+ break;
+ case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE:
+ *GcdAttributes |= EFI_MEMORY_WC;
+ break;
+ case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC:
+ *GcdAttributes |= EFI_MEMORY_WB;
+ break;
+ case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE:
+ *GcdAttributes |= EFI_MEMORY_UC;
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ // determine protection attributes
+ switch(PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) {
+ case TT_DESCRIPTOR_PAGE_AP_NO_NO: // no read, no write
+ //*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;
+ break;
+
+ case TT_DESCRIPTOR_PAGE_AP_RW_NO:
+ case TT_DESCRIPTOR_PAGE_AP_RW_RW:
+ // normal read/write access, do not add additional attributes
+ break;
+
+ // read only cases map to write-protect
+ case TT_DESCRIPTOR_PAGE_AP_RO_NO:
+ case TT_DESCRIPTOR_PAGE_AP_RO_RO:
+ *GcdAttributes |= EFI_MEMORY_WP;
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ // now process eXectue Never attribute
+ if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {
+ *GcdAttributes |= EFI_MEMORY_XP;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SyncCacheConfigPage (
+ IN UINT32 SectionIndex,
+ IN UINT32 FirstLevelDescriptor,
+ IN UINTN NumberOfDescriptors,
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
+ IN OUT EFI_PHYSICAL_ADDRESS *NextRegionBase,
+ IN OUT UINT64 *NextRegionLength,
+ IN OUT UINT32 *NextSectionAttributes
+ )
+{
+ EFI_STATUS Status;
+ UINT32 i;
+ volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable;
+ UINT32 NextPageAttributes = 0;
+ UINT32 PageAttributes = 0;
+ UINT32 BaseAddress;
+ UINT64 GcdAttributes;
+
+ // Get the Base Address from FirstLevelDescriptor;
+ BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
+
+ // Convert SectionAttributes into PageAttributes
+ NextPageAttributes =
+ TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(*NextSectionAttributes,0) |
+ TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(*NextSectionAttributes);
+
+ // obtain page table base
+ SecondLevelTable = (ARM_PAGE_TABLE_ENTRY *)(FirstLevelDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
+
+ for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
+ if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
+ // extract attributes (cacheability and permissions)
+ PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK);
+
+ if (NextPageAttributes == 0) {
+ // start on a new region
+ *NextRegionLength = 0;
+ *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
+ NextPageAttributes = PageAttributes;
+ } else if (PageAttributes != NextPageAttributes) {
+ // Convert Section Attributes into GCD Attributes
+ Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
+ ASSERT_EFI_ERROR (Status);
+
+ // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
+
+ // start on a new region
+ *NextRegionLength = 0;
+ *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
+ NextPageAttributes = PageAttributes;
+ }
+ } else if (NextPageAttributes != 0) {
+ // Convert Page Attributes into GCD Attributes
+ Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
+ ASSERT_EFI_ERROR (Status);
+
+ // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
+
+ *NextRegionLength = 0;
+ *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);
+ NextPageAttributes = 0;
+ }
+ *NextRegionLength += TT_DESCRIPTOR_PAGE_SIZE;
+ }
+
+ // Convert back PageAttributes into SectionAttributes
+ *NextSectionAttributes =
+ TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(NextPageAttributes,0) |
+ TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(NextPageAttributes);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SyncCacheConfig (
+ IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
+ )
+{
+ EFI_STATUS Status;
+ UINT32 i;
+ EFI_PHYSICAL_ADDRESS NextRegionBase;
+ UINT64 NextRegionLength;
+ UINT32 NextSectionAttributes = 0;
+ UINT32 SectionAttributes = 0;
+ UINT64 GcdAttributes;
+ volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
+ UINTN NumberOfDescriptors;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
+
+
+ DEBUG ((EFI_D_PAGE, "SyncCacheConfig()\n"));
+
+ // This code assumes MMU is enabled and filed with section translations
+ ASSERT (ArmMmuEnabled ());
+
+ //
+ // Get the memory space map from GCD
+ //
+ MemorySpaceMap = NULL;
+ Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
+ ASSERT_EFI_ERROR (Status);
+
+
+ // The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs
+ // to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a
+ // GetMemoryAttributes function for GCD to get this so we must resort to calling GCD (as if we were
+ // a client) to update its copy of the attributes. This is bad architecture and should be replaced
+ // with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.
+
+ // obtain page table base
+ FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());
+
+ // Get the first region
+ NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
+
+ // iterate through each 1MB descriptor
+ NextRegionBase = NextRegionLength = 0;
+ for (i=0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {
+ if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
+ // extract attributes (cacheability and permissions)
+ SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
+
+ if (NextSectionAttributes == 0) {
+ // start on a new region
+ NextRegionLength = 0;
+ NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
+ NextSectionAttributes = SectionAttributes;
+ } else if (SectionAttributes != NextSectionAttributes) {
+ // Convert Section Attributes into GCD Attributes
+ Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
+ ASSERT_EFI_ERROR (Status);
+
+ // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
+
+ // start on a new region
+ NextRegionLength = 0;
+ NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
+ NextSectionAttributes = SectionAttributes;
+ }
+ NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
+ } else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(FirstLevelTable[i])) {
+ Status = SyncCacheConfigPage (
+ i,FirstLevelTable[i],
+ NumberOfDescriptors, MemorySpaceMap,
+ &NextRegionBase,&NextRegionLength,&NextSectionAttributes);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ // We do not support yet 16MB sections
+ ASSERT ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) != TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION);
+
+ // start on a new region
+ if (NextSectionAttributes != 0) {
+ // Convert Section Attributes into GCD Attributes
+ Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
+ ASSERT_EFI_ERROR (Status);
+
+ // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
+
+ NextRegionLength = 0;
+ NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
+ NextSectionAttributes = 0;
+ }
+ NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;
+ }
+ } // section entry loop
+
+ if (NextSectionAttributes != 0) {
+ // Convert Section Attributes into GCD Attributes
+ Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);
+ ASSERT_EFI_ERROR (Status);
+
+ // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
+ SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);
+ }
+
+ FreePool (MemorySpaceMap);
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+UpdatePageEntries (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask
+ )
+{
+ EFI_STATUS Status;
+ UINT32 EntryValue;
+ UINT32 EntryMask;
+ UINT32 FirstLevelIdx;
+ UINT32 Offset;
+ UINT32 NumPageEntries;
+ UINT32 Descriptor;
+ UINT32 p;
+ UINT32 PageTableIndex;
+ UINT32 PageTableEntry;
+ UINT32 CurrentPageTableEntry;
+ VOID *Mva;
+
+ volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
+ volatile ARM_PAGE_TABLE_ENTRY *PageTable;
+
+ Status = EFI_SUCCESS;
+
+ // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
+ // EntryValue: values at bit positions specified by EntryMask
+ EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK;
+ EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
+ // Although the PI spec is unclear on this the GCD guarantees that only
+ // one Attribute bit is set at a time, so we can safely use a switch statement
+ switch (Attributes) {
+ case EFI_MEMORY_UC:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
+ // map to strongly ordered
+ EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
+ break;
+
+ case EFI_MEMORY_WC:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
+ // map to normal non-cachable
+ EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
+ break;
+
+ case EFI_MEMORY_WT:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
+ // write through with no-allocate
+ EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
+ break;
+
+ case EFI_MEMORY_WB:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
+ // write back (with allocate)
+ EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
+ break;
+
+ case EFI_MEMORY_WP:
+ case EFI_MEMORY_XP:
+ case EFI_MEMORY_UCE:
+ // cannot be implemented UEFI definition unclear for ARM
+ // Cause a page fault if these ranges are accessed.
+ EntryValue = TT_DESCRIPTOR_PAGE_TYPE_FAULT;
+ DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ // Obtain page table base
+ FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
+
+ // Calculate number of 4KB page table entries to change
+ NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;
+
+ // Iterate for the number of 4KB pages to change
+ Offset = 0;
+ for(p = 0; p < NumPageEntries; p++) {
+ // Calculate index into first level translation table for page table value
+
+ FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
+ ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
+
+ // Read the descriptor from the first level page table
+ Descriptor = FirstLevelTable[FirstLevelIdx];
+
+ // Does this descriptor need to be converted from section entry to 4K pages?
+ if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
+ Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
+ if (EFI_ERROR(Status)) {
+ // Exit for loop
+ break;
+ }
+
+ // Re-read descriptor
+ Descriptor = FirstLevelTable[FirstLevelIdx];
+ }
+
+ // Obtain page table base address
+ PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);
+
+ // Calculate index into the page table
+ PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
+ ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
+
+ // Get the entry
+ CurrentPageTableEntry = PageTable[PageTableIndex];
+
+ // Mask off appropriate fields
+ PageTableEntry = CurrentPageTableEntry & ~EntryMask;
+
+ // Mask in new attributes and/or permissions
+ PageTableEntry |= EntryValue;
+
+ if (VirtualMask != 0) {
+ // Make this virtual address point at a physical page
+ PageTableEntry &= ~VirtualMask;
+ }
+
+ if (CurrentPageTableEntry != PageTableEntry) {
+ Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
+ if ((CurrentPageTableEntry & TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) == TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) {
+ // The current section mapping is cacheable so Clean/Invalidate the MVA of the page
+ // Note assumes switch(Attributes), not ARMv7 possibilities
+ WriteBackInvalidateDataCacheRange (Mva, TT_DESCRIPTOR_PAGE_SIZE);
+ }
+
+ // Only need to update if we are changing the entry
+ PageTable[PageTableIndex] = PageTableEntry;
+ ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);
+ }
+
+ Status = EFI_SUCCESS;
+ Offset += TT_DESCRIPTOR_PAGE_SIZE;
+
+ } // End first level translation table loop
+
+ return Status;
+}
+
+
+
+EFI_STATUS
+UpdateSectionEntries (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 EntryMask;
+ UINT32 EntryValue;
+ UINT32 FirstLevelIdx;
+ UINT32 NumSections;
+ UINT32 i;
+ UINT32 CurrentDescriptor;
+ UINT32 Descriptor;
+ VOID *Mva;
+ volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
+
+ // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
+ // EntryValue: values at bit positions specified by EntryMask
+
+ // Make sure we handle a section range that is unmapped
+ EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK;
+ EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
+
+ // Although the PI spec is unclear on this the GCD guarantees that only
+ // one Attribute bit is set at a time, so we can safely use a switch statement
+ switch(Attributes) {
+ case EFI_MEMORY_UC:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
+ // map to strongly ordered
+ EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
+ break;
+
+ case EFI_MEMORY_WC:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
+ // map to normal non-cachable
+ EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
+ break;
+
+ case EFI_MEMORY_WT:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
+ // write through with no-allocate
+ EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
+ break;
+
+ case EFI_MEMORY_WB:
+ // modify cacheability attributes
+ EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
+ // write back (with allocate)
+ EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
+ break;
+
+ case EFI_MEMORY_WP:
+ case EFI_MEMORY_XP:
+ case EFI_MEMORY_RP:
+ case EFI_MEMORY_UCE:
+ // cannot be implemented UEFI definition unclear for ARM
+ // Cause a page fault if these ranges are accessed.
+ EntryValue = TT_DESCRIPTOR_SECTION_TYPE_FAULT;
+ DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));
+ break;
+
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ // obtain page table base
+ FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
+
+ // calculate index into first level translation table for start of modification
+ FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
+ ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
+
+ // calculate number of 1MB first level entries this applies to
+ NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;
+
+ // iterate through each descriptor
+ for(i=0; i<NumSections; i++) {
+ CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
+
+ // has this descriptor already been coverted to pages?
+ if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {
+ // forward this 1MB range to page table function instead
+ Status = UpdatePageEntries ((FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, TT_DESCRIPTOR_SECTION_SIZE, Attributes, VirtualMask);
+ } else {
+ // still a section entry
+
+ // mask off appropriate fields
+ Descriptor = CurrentDescriptor & ~EntryMask;
+
+ // mask in new attributes and/or permissions
+ Descriptor |= EntryValue;
+ if (VirtualMask != 0) {
+ Descriptor &= ~VirtualMask;
+ }
+
+ if (CurrentDescriptor != Descriptor) {
+ Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
+ if ((CurrentDescriptor & TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) == TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) {
+ // The current section mapping is cacheable so Clean/Invalidate the MVA of the section
+ // Note assumes switch(Attributes), not ARMv7 possabilities
+ WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB);
+ }
+
+ // Only need to update if we are changing the descriptor
+ FirstLevelTable[FirstLevelIdx + i] = Descriptor;
+ ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);
+ }
+
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+ConvertSectionToPages (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PageTableAddr;
+ UINT32 FirstLevelIdx;
+ UINT32 SectionDescriptor;
+ UINT32 PageTableDescriptor;
+ UINT32 PageDescriptor;
+ UINT32 Index;
+
+ volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
+ volatile ARM_PAGE_TABLE_ENTRY *PageTable;
+
+ DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
+
+ // Obtain page table base
+ FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
+
+ // Calculate index into first level translation table for start of modification
+ FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
+ ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
+
+ // Get section attributes and convert to page attributes
+ SectionDescriptor = FirstLevelTable[FirstLevelIdx];
+ PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);
+
+ // Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, 1, &PageTableAddr);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;
+
+ // Write the page table entries out
+ for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
+ PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) | PageDescriptor;
+ }
+
+ // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks
+ WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, TT_DESCRIPTOR_PAGE_SIZE);
+
+ // Formulate page table entry, Domain=0, NS=0
+ PageTableDescriptor = (((UINTN)PageTableAddr) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
+
+ // Write the page table entry out, replacing section entry
+ FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+SetMemoryAttributes (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask
+ )
+{
+ EFI_STATUS Status;
+
+ if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) {
+ // Is the base and length a multiple of 1 MB?
+ DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));
+ Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask);
+ } else {
+ // Base and/or length is not a multiple of 1 MB
+ DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));
+ Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask);
+ }
+
+ // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks
+ // flush and invalidate pages
+ //TODO: Do we really need to invalidate the caches everytime we change the memory attributes ?
+ ArmCleanInvalidateDataCache ();
+
+ ArmInvalidateInstructionCache ();
+
+ // Invalidate all TLB entries so changes are synced
+ ArmInvalidateTlb ();
+
+ return Status;
+}
+
+UINT64
+EfiAttributeToArmAttribute (
+ IN UINT64 EfiAttributes
+ )
+{
+ UINT64 ArmAttributes;
+
+ switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) {
+ case EFI_MEMORY_UC:
+ // Map to strongly ordered
+ ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
+ break;
+
+ case EFI_MEMORY_WC:
+ // Map to normal non-cachable
+ ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
+ break;
+
+ case EFI_MEMORY_WT:
+ // Write through with no-allocate
+ ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
+ break;
+
+ case EFI_MEMORY_WB:
+ // Write back (with allocate)
+ ArmAttributes = TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
+ break;
+
+ case EFI_MEMORY_WP:
+ case EFI_MEMORY_XP:
+ case EFI_MEMORY_RP:
+ case EFI_MEMORY_UCE:
+ default:
+ // Cannot be implemented UEFI definition unclear for ARM
+ // Cause a page fault if these ranges are accessed.
+ ArmAttributes = TT_DESCRIPTOR_SECTION_TYPE_FAULT;
+ DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): Unsupported attribute %x will page fault on access\n", EfiAttributes));
+ break;
+ }
+
+ // Determine protection attributes
+ if (EfiAttributes & EFI_MEMORY_WP) {
+ ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
+ } else {
+ ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
+ }
+
+ // Determine eXecute Never attribute
+ if (EfiAttributes & EFI_MEMORY_XP) {
+ ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
+ }
+
+ return ArmAttributes;
+}
+
+EFI_STATUS
+GetMemoryRegionPage (
+ IN UINT32 *PageTable,
+ IN OUT UINTN *BaseAddress,
+ OUT UINTN *RegionLength,
+ OUT UINTN *RegionAttributes
+ )
+{
+ UINT32 PageAttributes;
+ UINT32 TableIndex;
+ UINT32 PageDescriptor;
+
+ // Convert the section attributes into page attributes
+ PageAttributes = ConvertSectionAttributesToPageAttributes (*RegionAttributes, 0);
+
+ // Calculate index into first level translation table for start of modification
+ TableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
+ ASSERT (TableIndex < TRANSLATION_TABLE_PAGE_COUNT);
+
+ // Go through the page table to find the end of the section
+ for (; TableIndex < TRANSLATION_TABLE_PAGE_COUNT; TableIndex++) {
+ // Get the section at the given index
+ PageDescriptor = PageTable[TableIndex];
+
+ if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_FAULT) {
+ // Case: End of the boundary of the region
+ return EFI_SUCCESS;
+ } else if ((PageDescriptor & TT_DESCRIPTOR_PAGE_TYPE_PAGE) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
+ if ((PageDescriptor & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK) == PageAttributes) {
+ *RegionLength = *RegionLength + TT_DESCRIPTOR_PAGE_SIZE;
+ } else {
+ // Case: End of the boundary of the region
+ return EFI_SUCCESS;
+ }
+ } else {
+ // We do not support Large Page yet. We return EFI_SUCCESS that means end of the region.
+ ASSERT(0);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+GetMemoryRegion (
+ IN OUT UINTN *BaseAddress,
+ OUT UINTN *RegionLength,
+ OUT UINTN *RegionAttributes
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TableIndex;
+ UINT32 PageAttributes;
+ UINT32 PageTableIndex;
+ UINT32 SectionDescriptor;
+ ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
+ UINT32 *PageTable;
+
+ // Initialize the arguments
+ *RegionLength = 0;
+
+ // Obtain page table base
+ FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
+
+ // Calculate index into first level translation table for start of modification
+ TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
+ ASSERT (TableIndex < TRANSLATION_TABLE_SECTION_COUNT);
+
+ // Get the section at the given index
+ SectionDescriptor = FirstLevelTable[TableIndex];
+
+ // If 'BaseAddress' belongs to the section then round it to the section boundary
+ if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||
+ ((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION))
+ {
+ *BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK;
+ *RegionAttributes = SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK;
+ } else {
+ // Otherwise, we round it to the page boundary
+ *BaseAddress = (*BaseAddress) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK;
+
+ // Get the attribute at the page table level (Level 2)
+ PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
+
+ // Calculate index into first level translation table for start of modification
+ PageTableIndex = ((*BaseAddress) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
+ ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
+
+ PageAttributes = PageTable[PageTableIndex] & TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK;
+ *RegionAttributes = TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY (PageAttributes, 0) |
+ TT_DESCRIPTOR_CONVERT_TO_SECTION_AP (PageAttributes);
+ }
+
+ for (;TableIndex < TRANSLATION_TABLE_SECTION_COUNT; TableIndex++) {
+ // Get the section at the given index
+ SectionDescriptor = FirstLevelTable[TableIndex];
+
+ // If the entry is a level-2 page table then we scan it to find the end of the region
+ if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (SectionDescriptor)) {
+ // Extract the page table location from the descriptor
+ PageTable = (UINT32*)(SectionDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);
+
+ // Scan the page table to find the end of the region.
+ Status = GetMemoryRegionPage (PageTable, BaseAddress, RegionLength, RegionAttributes);
+
+ // If we have found the end of the region (Status == EFI_SUCCESS) then we exit the for-loop
+ if (Status == EFI_SUCCESS) {
+ break;
+ }
+ } else if (((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) ||
+ ((SectionDescriptor & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION)) {
+ if ((SectionDescriptor & TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK) != *RegionAttributes) {
+ // If the attributes of the section differ from the one targeted then we exit the loop
+ break;
+ } else {
+ *RegionLength = *RegionLength + TT_DESCRIPTOR_SECTION_SIZE;
+ }
+ } else {
+ // If we are on an invalid section then it means it is the end of our section.
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.c
new file mode 100644
index 0000000..0c49acb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.c
@@ -0,0 +1,280 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011, 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 "CpuDxe.h"
+
+#include <Guid/IdleLoopEvent.h>
+
+BOOLEAN mInterruptState = FALSE;
+
+
+/**
+ This function flushes the range of addresses from Start to Start+Length
+ from the processor's data cache. If Start is not aligned to a cache line
+ boundary, then the bytes before Start to the preceding cache line boundary
+ are also flushed. If Start+Length is not aligned to a cache line boundary,
+ then the bytes past Start+Length to the end of the next cache line boundary
+ are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
+ supported. If the data cache is fully coherent with all DMA operations, then
+ this function can just return EFI_SUCCESS. If the processor does not support
+ flushing a range of the data cache, then the entire data cache can be flushed.
+
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.
+ @param Start The beginning physical address to flush from the processor's data
+ cache.
+ @param Length The number of bytes to flush from the processor's data cache. This
+ function may flush more bytes than Length specifies depending upon
+ the granularity of the flush operation that the processor supports.
+ @param FlushType Specifies the type of flush operation to perform.
+
+ @retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
+ the processor's data cache.
+ @retval EFI_UNSUPPORTEDT The processor does not support the cache flush type specified
+ by FlushType.
+ @retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
+ from the processor's data cache.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType
+ )
+{
+
+ switch (FlushType) {
+ case EfiCpuFlushTypeWriteBack:
+ WriteBackDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
+ break;
+ case EfiCpuFlushTypeInvalidate:
+ InvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
+ break;
+ case EfiCpuFlushTypeWriteBackInvalidate:
+ WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)Start, (UINTN)Length);
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function enables interrupt processing by the processor.
+
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.
+
+ @retval EFI_SUCCESS Interrupts are enabled on the processor.
+ @retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ ArmEnableInterrupts ();
+
+ mInterruptState = TRUE;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function disables interrupt processing by the processor.
+
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.
+
+ @retval EFI_SUCCESS Interrupts are disabled on the processor.
+ @retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ ArmDisableInterrupts ();
+
+ mInterruptState = FALSE;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function retrieves the processor's current interrupt state a returns it in
+ State. If interrupts are currently enabled, then TRUE is returned. If interrupts
+ are currently disabled, then FALSE is returned.
+
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.
+ @param State A pointer to the processor's current interrupt state. Set to TRUE if
+ interrupts are enabled and FALSE if interrupts are disabled.
+
+ @retval EFI_SUCCESS The processor's current interrupt state was returned in State.
+ @retval EFI_INVALID_PARAMETER State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ OUT BOOLEAN *State
+ )
+{
+ if (State == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *State = mInterruptState;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function generates an INIT on the processor. If this function succeeds, then the
+ processor will be reset, and control will not be returned to the caller. If InitType is
+ not supported by this processor, or the processor cannot programmatically generate an
+ INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error
+ occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.
+
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.
+ @param InitType The type of processor INIT to perform.
+
+ @retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen.
+ @retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported
+ by this processor.
+ @retval EFI_DEVICE_ERROR The processor INIT failed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_CPU_INIT_TYPE InitType
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+CpuRegisterInterruptHandler (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ return RegisterInterruptHandler (InterruptType, InterruptHandler);
+}
+
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN UINT32 TimerIndex,
+ OUT UINT64 *TimerValue,
+ OUT UINT64 *TimerPeriod OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Callback function for idle events.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+IdleLoopEventCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ CpuSleep ();
+}
+
+//
+// Globals used to initialize the protocol
+//
+EFI_HANDLE mCpuHandle = NULL;
+EFI_CPU_ARCH_PROTOCOL mCpu = {
+ CpuFlushCpuDataCache,
+ CpuEnableInterrupt,
+ CpuDisableInterrupt,
+ CpuGetInterruptState,
+ CpuInit,
+ CpuRegisterInterruptHandler,
+ CpuGetTimerValue,
+ CpuSetMemoryAttributes,
+ 0, // NumberOfTimers
+ 4, // DmaBufferAlignment
+};
+
+EFI_STATUS
+CpuDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT IdleLoopEvent;
+
+ InitializeExceptions (&mCpu);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mCpuHandle,
+ &gEfiCpuArchProtocolGuid, &mCpu,
+ &gVirtualUncachedPagesProtocolGuid, &gVirtualUncachedPages,
+ NULL
+ );
+
+ //
+ // Make sure GCD and MMU settings match. This API calls gDS->SetMemorySpaceAttributes ()
+ // and that calls EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes, so this code needs to go
+ // after the protocol is installed
+ //
+ SyncCacheConfig (&mCpu);
+
+ // If the platform is a MPCore system then install the Configuration Table describing the
+ // secondary core states
+ if (ArmIsMpCore()) {
+ PublishArmProcessorTable();
+ }
+
+ //
+ // Setup a callback for idle events
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IdleLoopEventCallback,
+ NULL,
+ &gIdleLoopEventGuid,
+ &IdleLoopEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.h
new file mode 100644
index 0000000..d16abe4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.h
@@ -0,0 +1,182 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, 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.
+
+**/
+
+#ifndef __CPU_DXE_ARM_EXCEPTION_H__
+#define __CPU_DXE_ARM_EXCEPTION_H__
+
+#include <Uefi.h>
+
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/UefiLib.h>
+#include <Library/CpuLib.h>
+#include <Library/DefaultExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+
+#include <Guid/DebugImageInfoTable.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/DebugSupport.h>
+#include <Protocol/DebugSupportPeriodicCallback.h>
+#include <Protocol/VirtualUncachedPages.h>
+#include <Protocol/LoadedImage.h>
+
+
+#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \
+ EFI_MEMORY_WC | \
+ EFI_MEMORY_WT | \
+ EFI_MEMORY_WB | \
+ EFI_MEMORY_UCE \
+ )
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterDebuggerInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+EFI_STATUS
+InitializeExceptions (
+ IN EFI_CPU_ARCH_PROTOCOL *Cpu
+ );
+
+EFI_STATUS
+SyncCacheConfig (
+ IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
+ );
+
+EFI_STATUS
+ConvertSectionToPages (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress
+ );
+
+/**
+ * Publish ARM Processor Data table in UEFI SYSTEM Table.
+ * @param HobStart Pointer to the beginning of the HOB List from PEI.
+ *
+ * Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.
+ * If the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory
+ * and a pointer is assigned to it in ARM processor table. Then the ARM processor table is
+ * installed in EFI configuration table.
+**/
+VOID
+EFIAPI
+PublishArmProcessorTable(
+ VOID
+ );
+
+EFI_STATUS
+SetMemoryAttributes (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask
+ );
+
+// The ARM Attributes might be defined on 64-bit (case of the long format description table)
+UINT64
+EfiAttributeToArmAttribute (
+ IN UINT64 EfiAttributes
+ );
+
+EFI_STATUS
+GetMemoryRegion (
+ IN OUT UINTN *BaseAddress,
+ OUT UINTN *RegionLength,
+ OUT UINTN *RegionAttributes
+ );
+
+VOID
+GetRootTranslationTableInfo (
+ IN UINTN T0SZ,
+ OUT UINTN *TableLevel,
+ OUT UINTN *TableEntryCount
+ );
+
+EFI_STATUS
+SetGcdMemorySpaceAttributes (
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
+ IN UINTN NumberOfDescriptors,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+extern VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages;
+
+#endif // __CPU_DXE_ARM_EXCEPTION_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
new file mode 100644
index 0000000..01f65a3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
@@ -0,0 +1,93 @@
+#/** @file
+#
+# DXE CPU driver
+#
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+# 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.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmCpuDxe
+ FILE_GUID = B8D9777E-D72A-451F-9BDB-BAFB52A68415
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = CpuDxeInitialize
+
+[Sources.Common]
+ CpuDxe.c
+ CpuDxe.h
+ CpuMpCore.c
+ CpuMmuCommon.c
+
+#
+# Prior to ARMv6 we have multiple stacks, one per mode
+#
+# ArmV4/ExceptionSupport.asm | RVCT
+# ArmV4/ExceptionSupport.S | GCC
+
+#
+# ARMv6 or later uses a single stack via srs/stm instructions
+#
+
+[Sources.ARM]
+ ArmV6/Mmu.c
+ ArmV6/Exception.c
+ ArmV6/ExceptionSupport.asm | RVCT
+ ArmV6/ExceptionSupport.S | GCC
+
+[Sources.AARCH64]
+ AArch64/Mmu.c
+ AArch64/Exception.c
+ AArch64/ExceptionSupport.S
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ ArmLib
+ BaseMemoryLib
+ CacheMaintenanceLib
+ CpuLib
+ DebugLib
+ DefaultExceptionHandlerLib
+ DxeServicesTableLib
+ HobLib
+ PeCoffGetEntryPointLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+ gEfiDebugSupportPeriodicCallbackProtocolGuid
+ gVirtualUncachedPagesProtocolGuid
+
+[Guids]
+ gEfiDebugImageInfoTableGuid
+ gArmMpCoreInfoGuid
+ gIdleLoopEventGuid
+
+[Pcd.common]
+ gArmTokenSpaceGuid.PcdVFPEnabled
+ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
+
+[FeaturePcd.common]
+ gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport
+ gArmTokenSpaceGuid.PcdRelocateVectorTable
+ gArmTokenSpaceGuid.PcdDebuggerExceptionSupport
+
+[Depex]
+ TRUE
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
new file mode 100644
index 0000000..723604d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
@@ -0,0 +1,282 @@
+/** @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 "CpuDxe.h"
+
+/**
+ Searches memory descriptors covered by given memory range.
+
+ This function searches into the Gcd Memory Space for descriptors
+ (from StartIndex to EndIndex) that contains the memory range
+ specified by BaseAddress and Length.
+
+ @param MemorySpaceMap Gcd Memory Space Map as array.
+ @param NumberOfDescriptors Number of descriptors in map.
+ @param BaseAddress BaseAddress for the requested range.
+ @param Length Length for the requested range.
+ @param StartIndex Start index into the Gcd Memory Space Map.
+ @param EndIndex End index into the Gcd Memory Space Map.
+
+ @retval EFI_SUCCESS Search successfully.
+ @retval EFI_NOT_FOUND The requested descriptors does not exist.
+
+**/
+EFI_STATUS
+SearchGcdMemorySpaces (
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
+ IN UINTN NumberOfDescriptors,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ OUT UINTN *StartIndex,
+ OUT UINTN *EndIndex
+ )
+{
+ UINTN Index;
+
+ *StartIndex = 0;
+ *EndIndex = 0;
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {
+ if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&
+ (BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {
+ *StartIndex = Index;
+ }
+ if (((BaseAddress + Length - 1) >= MemorySpaceMap[Index].BaseAddress) &&
+ ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {
+ *EndIndex = Index;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ Sets the attributes for a specified range in Gcd Memory Space Map.
+
+ This function sets the attributes for a specified range in
+ Gcd Memory Space Map.
+
+ @param MemorySpaceMap Gcd Memory Space Map as array
+ @param NumberOfDescriptors Number of descriptors in map
+ @param BaseAddress BaseAddress for the range
+ @param Length Length for the range
+ @param Attributes Attributes to set
+
+ @retval EFI_SUCCESS Memory attributes set successfully
+ @retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space
+
+**/
+EFI_STATUS
+SetGcdMemorySpaceAttributes (
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
+ IN UINTN NumberOfDescriptors,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN StartIndex;
+ UINTN EndIndex;
+ EFI_PHYSICAL_ADDRESS RegionStart;
+ UINT64 RegionLength;
+
+ DEBUG ((DEBUG_GCD, "SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",
+ BaseAddress, BaseAddress + Length, Attributes));
+
+ // We do not support a smaller granularity than 4KB on ARM Architecture
+ if ((Length & EFI_PAGE_MASK) != 0) {
+ DEBUG ((DEBUG_WARN,
+ "Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",
+ Length));
+ }
+
+ //
+ // Get all memory descriptors covered by the memory range
+ //
+ Status = SearchGcdMemorySpaces (
+ MemorySpaceMap,
+ NumberOfDescriptors,
+ BaseAddress,
+ Length,
+ &StartIndex,
+ &EndIndex
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Go through all related descriptors and set attributes accordingly
+ //
+ for (Index = StartIndex; Index <= EndIndex; Index++) {
+ if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
+ continue;
+ }
+ //
+ // Calculate the start and end address of the overlapping range
+ //
+ if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {
+ RegionStart = BaseAddress;
+ } else {
+ RegionStart = MemorySpaceMap[Index].BaseAddress;
+ }
+ if ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)) {
+ RegionLength = BaseAddress + Length - RegionStart;
+ } else {
+ RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
+ }
+ //
+ // Set memory attributes according to MTRR attribute and the original attribute of descriptor
+ //
+ gDS->SetMemorySpaceAttributes (
+ RegionStart,
+ RegionLength,
+ (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function modifies the attributes for the memory region specified by BaseAddress and
+ Length from their current attributes to the attributes specified by Attributes.
+
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes The bit mask of attributes to set for the memory region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
+ BaseAddress and Length cannot be modified.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
+ the memory resource range.
+ @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
+ resource range specified by BaseAddress and Length.
+ The bit mask of attributes is not support for the memory resource
+ range specified by BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 EfiAttributes
+ )
+{
+ EFI_STATUS Status;
+ UINTN ArmAttributes;
+ UINTN RegionBaseAddress;
+ UINTN RegionLength;
+ UINTN RegionArmAttributes;
+
+ if ((BaseAddress & (SIZE_4KB - 1)) != 0) {
+ // Minimum granularity is SIZE_4KB (4KB on ARM)
+ DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum ganularity is SIZE_4KB\n", BaseAddress, Length, EfiAttributes));
+ return EFI_UNSUPPORTED;
+ }
+
+ // Convert the 'Attribute' into ARM Attribute
+ ArmAttributes = EfiAttributeToArmAttribute (EfiAttributes);
+
+ // Get the region starting from 'BaseAddress' and its 'Attribute'
+ RegionBaseAddress = BaseAddress;
+ Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes);
+
+ // Data & Instruction Caches are flushed when we set new memory attributes.
+ // So, we only set the attributes if the new region is different.
+ if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||
+ ((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))
+ {
+ return SetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0);
+ } else {
+ return EFI_SUCCESS;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+CpuConvertPagesToUncachedVirtualAddress (
+ IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN UINTN Length,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask,
+ OUT UINT64 *Attributes OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
+
+ if (Attributes != NULL) {
+ Status = gDS->GetMemorySpaceDescriptor (Address, &GcdDescriptor);
+ if (!EFI_ERROR (Status)) {
+ *Attributes = GcdDescriptor.Attributes;
+ }
+ }
+
+ //
+ // Make this address range page fault if accessed. If it is a DMA buffer than this would
+ // be the PCI address. Code should always use the CPU address, and we will or in VirtualMask
+ // to that address.
+ //
+ Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_WP, 0);
+ if (!EFI_ERROR (Status)) {
+ Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);
+ }
+
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuConvertPagesToUncachedVirtualAddress()\n Unmapped 0x%08lx Mapped 0x%08lx 0x%x bytes\n", Address, Address | VirtualMask, Length));
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+CpuReconvertPages (
+ IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN UINTN Length,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuReconvertPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));
+
+ //
+ // Unmap the aliased Address
+ //
+ Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Restore atttributes
+ //
+ Status = SetMemoryAttributes (Address, Length, Attributes, 0);
+ }
+
+ return Status;
+}
+
+
+VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {
+ CpuConvertPagesToUncachedVirtualAddress,
+ CpuReconvertPages
+};
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMpCore.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMpCore.c
new file mode 100644
index 0000000..81d858e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuDxe/CpuMpCore.c
@@ -0,0 +1,103 @@
+/** @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 <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/ArmMpCoreInfo.h>
+
+ARM_PROCESSOR_TABLE mArmProcessorTableTemplate = {
+ {
+ EFI_ARM_PROCESSOR_TABLE_SIGNATURE,
+ 0,
+ EFI_ARM_PROCESSOR_TABLE_REVISION,
+ EFI_ARM_PROCESSOR_TABLE_OEM_ID,
+ EFI_ARM_PROCESSOR_TABLE_OEM_TABLE_ID,
+ EFI_ARM_PROCESSOR_TABLE_OEM_REVISION,
+ EFI_ARM_PROCESSOR_TABLE_CREATOR_ID,
+ EFI_ARM_PROCESSOR_TABLE_CREATOR_REVISION,
+ { 0 },
+ 0
+ }, //ARM Processor table header
+ 0, // Number of entries in ARM processor Table
+ NULL // ARM Processor Table
+};
+
+/** Publish ARM Processor Data table in UEFI SYSTEM Table.
+ * @param: HobStart Pointer to the beginning of the HOB List from PEI.
+ *
+ * Description : This function iterates through HOB list and finds ARM processor Table Entry HOB.
+ * If the ARM processor Table Entry HOB is found, the HOB data is copied to run-time memory
+ * and a pointer is assigned to it in ARM processor table. Then the ARM processor table is
+ * installed in EFI configuration table.
+**/
+VOID
+EFIAPI
+PublishArmProcessorTable (
+ VOID
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetHobList ();
+
+ // Iterate through the HOBs and find if there is ARM PROCESSOR ENTRY HOB
+ for (; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
+ // Check for Correct HOB type
+ if ((GET_HOB_TYPE (Hob)) == EFI_HOB_TYPE_GUID_EXTENSION) {
+ // Check for correct GUID type
+ if (CompareGuid(&(Hob.Guid->Name), &gArmMpCoreInfoGuid)) {
+ ARM_PROCESSOR_TABLE *ArmProcessorTable;
+ EFI_STATUS Status;
+
+ // Allocate Runtime memory for ARM processor table
+ ArmProcessorTable = (ARM_PROCESSOR_TABLE*)AllocateRuntimePool(sizeof(ARM_PROCESSOR_TABLE));
+
+ // Check if the memory allocation is succesful or not
+ ASSERT(NULL != ArmProcessorTable);
+
+ // Set ARM processor table to default values
+ CopyMem(ArmProcessorTable,&mArmProcessorTableTemplate,sizeof(ARM_PROCESSOR_TABLE));
+
+ // Fill in Length fields of ARM processor table
+ ArmProcessorTable->Header.Length = sizeof(ARM_PROCESSOR_TABLE);
+ ArmProcessorTable->Header.DataLen = GET_GUID_HOB_DATA_SIZE(Hob);
+
+ // Fill in Identifier(ARM processor table GUID)
+ ArmProcessorTable->Header.Identifier = gArmMpCoreInfoGuid;
+
+ // Set Number of ARM core entries in the Table
+ ArmProcessorTable->NumberOfEntries = GET_GUID_HOB_DATA_SIZE(Hob)/sizeof(ARM_CORE_INFO);
+
+ // Allocate runtime memory for ARM processor Table entries
+ ArmProcessorTable->ArmCpus = (ARM_CORE_INFO*)AllocateRuntimePool (
+ ArmProcessorTable->NumberOfEntries * sizeof(ARM_CORE_INFO));
+
+ // Check if the memory allocation is succesful or not
+ ASSERT(NULL != ArmProcessorTable->ArmCpus);
+
+ // Copy ARM Processor Table data from HOB list to newly allocated memory
+ CopyMem(ArmProcessorTable->ArmCpus,GET_GUID_HOB_DATA(Hob), ArmProcessorTable->Header.DataLen);
+
+ // Install the ARM Processor table into EFI system configuration table
+ Status = gBS->InstallConfigurationTable (&gArmMpCoreInfoGuid, ArmProcessorTable);
+
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.c b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.c
new file mode 100755
index 0000000..d54f42a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.c
@@ -0,0 +1,91 @@
+/**@file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 Hewlett Packard Corporation. All rights reserved.<BR>
+Copyright (c) 2011-2013, ARM Limited. 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.
+
+Module Name:
+
+ MemoryInit.c
+
+Abstract:
+
+ PEIM to provide fake memory init
+
+**/
+
+
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Ppi/ArmMpCoreInfo.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/ArmLib.h>
+
+/*++
+
+Routine Description:
+
+Arguments:
+
+ FileHandle - Handle of the file being invoked.
+ PeiServices - Describes the list of possible PEI Services.
+
+Returns:
+
+ Status - EFI_SUCCESS if the boot mode could be set
+
+--*/
+EFI_STATUS
+EFIAPI
+InitializeCpuPeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
+ UINTN ArmCoreCount;
+ ARM_CORE_INFO *ArmCoreInfoTable;
+
+ // Enable program flow prediction, if supported.
+ ArmEnableBranchPrediction ();
+
+ // Publish the CPU memory and io spaces sizes
+ BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
+
+ // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
+ Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID**)&ArmMpCoreInfoPpi);
+ if (!EFI_ERROR(Status)) {
+ // Build the MP Core Info Table
+ ArmCoreCount = 0;
+ Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
+ if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
+ // Build MPCore Info HOB
+ BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.inf b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.inf
new file mode 100755
index 0000000..eafccd6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/CpuPei/CpuPei.inf
@@ -0,0 +1,58 @@
+## @file
+# Component description file for BootMode module
+#
+# This module provides platform specific function to detect boot mode.
+# Copyright (c) 2006 - 2010, Intel Corporation. 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 = CpuPei
+ FILE_GUID = 2FD8B7AD-F8FA-4021-9FC0-0AA572147CDC
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeCpuPeim
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM
+#
+
+[Sources]
+ CpuPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ ArmLib
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
+
+[Guids]
+ gArmMpCoreInfoGuid
+
+[FixedPcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
new file mode 100644
index 0000000..578fd1e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
@@ -0,0 +1,29 @@
+/** @file
+*
+* Copyright (c) 2013-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 __GENERIC_WATCHDOG_H__
+#define __GENERIC_WATCHDOG_H__
+
+// Refresh Frame:
+#define GENERIC_WDOG_REFRESH_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogRefreshBase) + 0x000)
+
+// Control Frame:
+#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x000)
+#define GENERIC_WDOG_OFFSET_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x008)
+#define GENERIC_WDOG_COMPARE_VALUE_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x010)
+
+// Values of bit 0 of the Control/Status Register
+#define GENERIC_WDOG_ENABLED 1
+#define GENERIC_WDOG_DISABLED 0
+
+#endif // __GENERIC_WATCHDOG_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
new file mode 100644
index 0000000..b1d9c02
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -0,0 +1,354 @@
+/** @file
+*
+* Copyright (c) 2013-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 <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ArmGenericTimerCounterLib.h>
+
+#include <Protocol/WatchdogTimer.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include "GenericWatchdog.h"
+
+// The number of 100ns periods (the unit of time passed to these functions)
+// in a second
+#define TIME_UNITS_PER_SECOND 10000000
+
+// Tick frequency of the generic timer that is the basis of the generic watchdog
+UINTN mTimerFrequencyHz = 0;
+
+// In cases where the compare register was set manually, information about
+// how long the watchdog was asked to wait cannot be retrieved from hardware.
+// It is therefore stored here. 0 means the timer is not running.
+UINT64 mNumTimerTicks = 0;
+
+EFI_HARDWARE_INTERRUPT_PROTOCOL *mInterruptProtocol;
+
+EFI_STATUS
+WatchdogWriteOffsetRegister (
+ UINT32 Value
+ )
+{
+ return MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
+}
+
+EFI_STATUS
+WatchdogWriteCompareRegister (
+ UINT64 Value
+ )
+{
+ return MmioWrite64 (GENERIC_WDOG_COMPARE_VALUE_REG, Value);
+}
+
+EFI_STATUS
+WatchdogEnable (
+ VOID
+ )
+{
+ return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_ENABLED);
+}
+
+EFI_STATUS
+WatchdogDisable (
+ VOID
+ )
+{
+ return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);
+}
+
+/**
+ On exiting boot services we must make sure the Watchdog Timer
+ is stopped.
+**/
+VOID
+EFIAPI
+WatchdogExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ WatchdogDisable ();
+ mNumTimerTicks = 0;
+}
+
+/*
+ This function is called when the watchdog's first signal (WS0) goes high.
+ It uses the ResetSystem Runtime Service to reset the board.
+*/
+VOID
+EFIAPI
+WatchdogInterruptHandler (
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out.";
+
+ WatchdogDisable ();
+
+ mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
+
+ gRT->ResetSystem (
+ EfiResetCold,
+ EFI_TIMEOUT,
+ StrSize (ResetString),
+ &ResetString
+ );
+
+ // If we got here then the reset didn't work
+ ASSERT (FALSE);
+}
+
+/**
+ This function registers the handler NotifyFunction so it is called every time
+ the watchdog timer expires. It also passes the amount of time since the last
+ handler call to the NotifyFunction.
+ If NotifyFunction is not NULL and a handler is not already registered,
+ then the new handler is registered and EFI_SUCCESS is returned.
+ If NotifyFunction is NULL, and a handler is already registered,
+ then that handler is unregistered.
+ 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.
+
+ @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 watchdog timer handler was registered.
+ @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.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogRegisterHandler (
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+ IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
+ )
+{
+ // ERROR: This function is not supported.
+ // The watchdog will reset the board
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ This function sets the amount of time to wait before firing the watchdog
+ timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog
+ timer is disabled.
+
+ @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod The amount of time in 100 nS units to wait before the watchdog
+ timer is fired. If TimerPeriod is zero, then the watchdog
+ timer is disabled.
+
+ @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time
+ 100 nS units.
+ @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device
+ error.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogSetTimerPeriod (
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+ IN UINT64 TimerPeriod // In 100ns units
+ )
+{
+ UINTN SystemCount;
+ EFI_STATUS Status;
+
+ // if TimerPerdiod is 0, this is a request to stop the watchdog.
+ if (TimerPeriod == 0) {
+ mNumTimerTicks = 0;
+ return WatchdogDisable ();
+ }
+
+ // Work out how many timer ticks will equate to TimerPeriod
+ mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
+
+ //
+ // If the number of required ticks is greater than the max number the
+ // watchdog's offset register (WOR) can hold, we need to manually compute and
+ // set the compare register (WCV)
+ //
+ if (mNumTimerTicks > MAX_UINT32) {
+ //
+ // We need to enable the watchdog *before* writing to the compare register,
+ // because enabling the watchdog causes an "explicit refresh", which
+ // clobbers the compare register (WCV). In order to make sure this doesn't
+ // trigger an interrupt, set the offset to max.
+ //
+ Status = WatchdogWriteOffsetRegister (MAX_UINT32);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ WatchdogEnable ();
+ SystemCount = ArmGenericTimerGetSystemCount ();
+ Status = WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
+ } else {
+ Status = WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
+ WatchdogEnable ();
+ }
+
+ return Status;
+}
+
+/**
+ 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
+WatchdogGetTimerPeriod (
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+ OUT UINT64 *TimerPeriod
+ )
+{
+ if (TimerPeriod == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Interface structure for the Watchdog Architectural Protocol.
+
+ @par Protocol Description:
+ This protocol provides a service to set the amount of time to wait
+ before firing the watchdog timer, and it also provides a service to
+ register a handler that is invoked when the watchdog timer fires.
+
+ @par When the watchdog timer fires, control will be passed to a handler
+ if one has been registered. If no handler has been registered,
+ or the registered handler returns, then the system will be
+ reset by calling the Runtime Service ResetSystem().
+
+ @param RegisterHandler
+ Registers a handler that will be called each time the
+ watchdogtimer interrupt fires. TimerPeriod defines the minimum
+ time between timer interrupts, so TimerPeriod will also
+ be the minimum time between calls to the registered
+ handler.
+ NOTE: If the watchdog resets the system in hardware, then
+ this function will not have any chance of executing.
+
+ @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.
+
+**/
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
+ (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) WatchdogRegisterHandler,
+ (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) WatchdogSetTimerPeriod,
+ (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) WatchdogGetTimerPeriod
+};
+
+EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
+
+EFI_STATUS
+EFIAPI
+GenericWatchdogEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ //
+ // Make sure the Watchdog Timer Architectural Protocol has not been installed
+ // in the system yet.
+ // This will avoid conflicts with the universal watchdog
+ //
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
+
+ mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
+ ASSERT (mTimerFrequencyHz != 0);
+
+ // Register for an ExitBootServicesEvent
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,
+ WatchdogExitBootServicesEvent, NULL, &EfiExitBootServicesEvent
+ );
+ if (!EFI_ERROR (Status)) {
+ // Install interrupt handler
+ Status = gBS->LocateProtocol (
+ &gHardwareInterruptProtocolGuid,
+ NULL,
+ (VOID **)&mInterruptProtocol
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = mInterruptProtocol->RegisterInterruptSource (
+ mInterruptProtocol,
+ FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
+ WatchdogInterruptHandler
+ );
+ if (!EFI_ERROR (Status)) {
+ // Install the Timer Architectural Protocol onto a new handle
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,
+ NULL
+ );
+ }
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ // The watchdog failed to initialize
+ ASSERT (FALSE);
+ }
+
+ mNumTimerTicks = 0;
+ WatchdogDisable ();
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
new file mode 100644
index 0000000..fece14c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2013-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.
+#
+
+[Defines]
+ INF_VERSION = 0x00010016
+ BASE_NAME = GenericWatchdogDxe
+ FILE_GUID = 0619f5c2-4858-4caa-a86a-73a21a18df6b
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = GenericWatchdogEntry
+
+[Sources.common]
+ GenericWatchdogDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ ArmGenericTimerCounterLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ PcdLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiRuntimeServicesTableLib
+
+[Pcd.common]
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
+ gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
+
+[Protocols]
+ gEfiWatchdogTimerArchProtocolGuid
+ gHardwareInterruptProtocolGuid
+
+[Depex]
+ gHardwareInterruptProtocolGuid
diff --git a/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.c
new file mode 100644
index 0000000..d0a819f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.c
@@ -0,0 +1,428 @@
+/** @file
+ Timer Architecture Protocol driver of the ARM flavor
+
+ 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 <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/ArmGenericTimerCounterLib.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;
+// The latest Timer Tick calculated for mTimerPeriod
+UINT64 mTimerTicks = 0;
+// Number of elapsed period since the last Timer interrupt
+UINT64 mElapsedPeriod = 1;
+
+// Cached copy of the Hardware Interrupt protocol instance
+EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
+
+/**
+ 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
+ )
+{
+ ArmGenericTimerDisableTimer ();
+}
+
+/**
+
+ 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 CounterValue;
+ UINT64 TimerTicks;
+ EFI_TPL OriginalTPL;
+
+ // Always disable the timer
+ ArmGenericTimerDisableTimer ();
+
+ if (TimerPeriod != 0) {
+ // mTimerTicks = TimerPeriod in 1ms unit x Frequency.10^-3
+ // = TimerPeriod.10^-4 x Frequency.10^-3
+ // = (TimerPeriod x Frequency) x 10^-7
+ TimerTicks = MultU64x32 (TimerPeriod, ArmGenericTimerGetTimerFreq ());
+ TimerTicks = DivU64x32 (TimerTicks, 10000000U);
+
+ // Raise TPL to update the mTimerTicks and mTimerPeriod to ensure these values
+ // are coherent in the interrupt handler
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ mTimerTicks = TimerTicks;
+ mTimerPeriod = TimerPeriod;
+ mElapsedPeriod = 1;
+
+ gBS->RestoreTPL (OriginalTPL);
+
+ // Get value of the current timer
+ CounterValue = ArmGenericTimerGetSystemCount ();
+ // Set the interrupt in Current Time + mTimerTick
+ ArmGenericTimerSetCompareVal (CounterValue + mTimerTicks);
+
+ // Enable the timer
+ ArmGenericTimerEnableTimer ();
+ } else {
+ // Save the new timer period
+ mTimerPeriod = TimerPeriod;
+ // Reset the elapsed period
+ mElapsedPeriod = 1;
+ }
+
+ 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;
+ UINT64 CurrentValue;
+ UINT64 CompareValue;
+
+ //
+ // 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.
+ //
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ // Check if the timer interrupt is active
+ if ((ArmGenericTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {
+
+ // Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
+ gInterrupt->EndOfInterrupt (gInterrupt, Source);
+
+ if (mTimerNotifyFunction) {
+ mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod);
+ }
+
+ //
+ // Reload the Timer
+ //
+
+ // Get current counter value
+ CurrentValue = ArmGenericTimerGetSystemCount ();
+ // Get the counter value to compare with
+ CompareValue = ArmGenericTimerGetCompareVal ();
+
+ // This loop is needed in case we missed interrupts (eg: case when the interrupt handling
+ // has taken longer than mTickPeriod).
+ // Note: Physical Counter is counting up
+ mElapsedPeriod = 0;
+ do {
+ CompareValue += mTimerTicks;
+ mElapsedPeriod++;
+ } while (CompareValue < CurrentValue);
+
+ // Set next compare value
+ ArmGenericTimerSetCompareVal (CompareValue);
+ ArmGenericTimerEnableTimer ();
+ }
+
+ // Enable timer interrupts
+ gInterrupt->EnableInterruptSource (gInterrupt, Source);
+
+ 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;
+ UINTN TimerCtrlReg;
+
+ if (ArmIsArchTimerImplemented () == 0) {
+ DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n"));
+ ASSERT (0);
+ }
+
+ // Find the interrupt controller protocol. ASSERT if not found.
+ Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
+ ASSERT_EFI_ERROR (Status);
+
+ // Disable the timer
+ TimerCtrlReg = ArmGenericTimerGetTimerCtrlReg ();
+ TimerCtrlReg |= ARM_ARCH_TIMER_IMASK;
+ TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;
+ ArmGenericTimerSetTimerCtrlReg (TimerCtrlReg);
+ Status = TimerDriverSetTimerPeriod (&gTimer, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ // 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, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerHypIntrNum), TimerInterruptHandler);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum), TimerInterruptHandler);
+ ASSERT_EFI_ERROR (Status);
+
+ // Set up default timer
+ Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
+ ASSERT_EFI_ERROR (Status);
+
+ // Install the Timer Architectural Protocol onto a new handle
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiTimerArchProtocolGuid, &gTimer,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ // Everything is ready, unmask and enable timer interrupts
+ TimerCtrlReg = ARM_ARCH_TIMER_ENABLE;
+ ArmGenericTimerSetTimerCtrlReg (TimerCtrlReg);
+
+ // 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/ArmPkg/Drivers/TimerDxe/TimerDxe.inf b/uefi/linaro-edk2/ArmPkg/Drivers/TimerDxe/TimerDxe.inf
new file mode 100644
index 0000000..3f34515
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/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>
+# 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
+ ArmGenericTimerCounterLib
+
+[Guids]
+
+[Protocols]
+ gEfiTimerArchProtocolGuid
+ gHardwareInterruptProtocolGuid
+
+[Pcd.common]
+ gEmbeddedTokenSpaceGuid.PcdTimerPeriod
+ gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
+ gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
+ gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
+ gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
+
+[Depex]
+ gHardwareInterruptProtocolGuid
diff --git a/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
new file mode 100644
index 0000000..6efdad9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
@@ -0,0 +1,1205 @@
+/** @file
+ Support a Semi Host file system over a debuggers JTAG
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.h>
+#include <Guid/FileSystemVolumeLabelInfo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SemihostLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include "SemihostFs.h"
+
+#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs"
+
+STATIC CHAR16 *mSemihostFsLabel;
+
+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
+ VolumeOpen
+};
+
+EFI_FILE gSemihostFsFile = {
+ EFI_FILE_PROTOCOL_REVISION,
+ FileOpen,
+ FileClose,
+ FileDelete,
+ FileRead,
+ FileWrite,
+ FileGetPosition,
+ FileSetPosition,
+ FileGetInfo,
+ FileSetInfo,
+ FileFlush
+};
+
+//
+// Device path for semi-hosting. It contains our autogened Caller ID GUID.
+//
+typedef struct {
+ VENDOR_DEVICE_PATH Guid;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} SEMIHOST_DEVICE_PATH;
+
+SEMIHOST_DEVICE_PATH gDevicePath = {
+ {
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
+ EFI_CALLER_ID_GUID
+ },
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
+};
+
+typedef struct {
+ LIST_ENTRY Link;
+ UINT64 Signature;
+ EFI_FILE File;
+ CHAR8 *FileName;
+ UINT64 OpenMode;
+ UINT32 Position;
+ UINTN SemihostHandle;
+ BOOLEAN IsRoot;
+ EFI_FILE_INFO Info;
+} SEMIHOST_FCB;
+
+#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
+#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE)
+#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE);
+
+EFI_HANDLE gInstallHandle = NULL;
+LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList);
+
+SEMIHOST_FCB *
+AllocateFCB (
+ VOID
+ )
+{
+ SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
+
+ if (Fcb != NULL) {
+ CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));
+ Fcb->Signature = SEMIHOST_FCB_SIGNATURE;
+ }
+
+ return Fcb;
+}
+
+VOID
+FreeFCB (
+ IN SEMIHOST_FCB *Fcb
+ )
+{
+ // Remove Fcb from gFileList.
+ RemoveEntryList (&Fcb->Link);
+
+ // To help debugging...
+ Fcb->Signature = 0;
+
+ FreePool (Fcb);
+}
+
+
+
+EFI_STATUS
+VolumeOpen (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE **Root
+ )
+{
+ SEMIHOST_FCB *RootFcb = NULL;
+
+ if (Root == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RootFcb = AllocateFCB ();
+ if (RootFcb == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RootFcb->IsRoot = TRUE;
+ RootFcb->Info.Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
+
+ InsertTailList (&gFileList, &RootFcb->Link);
+
+ *Root = &RootFcb->File;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Open a file on the host system by means of the semihosting interface.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to source location.
+ @param[out] NewHandle A pointer to the location to return the opened
+ handle for the new file.
+ @param[in] FileName The Null-terminated string of the name of the file
+ to be opened.
+ @param[in] OpenMode The mode to open the file : Read or Read/Write or
+ Read/Write/Create
+ @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these
+ are the attribute bits for the newly created file. The
+ mnemonics of the attribute bits are : EFI_FILE_READ_ONLY,
+ EFI_FILE_HIDDEN, EFI_FILE_SYSTEM, EFI_FILE_RESERVED,
+ EFI_FILE_DIRECTORY and EFI_FILE_ARCHIVE.
+
+ @retval EFI_SUCCESS The file was open.
+ @retval EFI_NOT_FOUND The specified file could not be found.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible
+ with the semi-hosting interface.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
+EFI_STATUS
+FileOpen (
+ IN EFI_FILE *This,
+ OUT EFI_FILE **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ SEMIHOST_FCB *FileFcb;
+ RETURN_STATUS Return;
+ EFI_STATUS Status;
+ UINTN SemihostHandle;
+ CHAR8 *AsciiFileName;
+ UINT32 SemihostMode;
+ UINTN Length;
+
+ if ((FileName == NULL) || (NewHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( (OpenMode != EFI_FILE_MODE_READ) &&
+ (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
+ (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((OpenMode & EFI_FILE_MODE_CREATE) &&
+ (Attributes & EFI_FILE_DIRECTORY) ) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+ AsciiFileName = AllocatePool (StrLen (FileName) + 1);
+ if (AsciiFileName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ UnicodeStrToAsciiStr (FileName, AsciiFileName);
+
+ // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
+ if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
+ (AsciiStrCmp (AsciiFileName, "/") == 0) ||
+ (AsciiStrCmp (AsciiFileName, "") == 0) ||
+ (AsciiStrCmp (AsciiFileName, ".") == 0) ) {
+ FreePool (AsciiFileName);
+ return (VolumeOpen (&gSemihostFs, NewHandle));
+ }
+
+ //
+ // No control is done here concerning the file path. It is passed
+ // as it is to the host operating system through the semi-hosting
+ // interface. We first try to open the file in the read or update
+ // mode even if the file creation has been asked for. That way, if
+ // the file already exists, it is not truncated to zero length. In
+ // write mode (bit SEMIHOST_FILE_MODE_WRITE up), if the file already
+ // exists, it is reset to an empty file.
+ //
+ if (OpenMode == EFI_FILE_MODE_READ) {
+ SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY;
+ } else {
+ SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
+ }
+ Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
+
+ if (RETURN_ERROR (Return)) {
+ if (OpenMode & EFI_FILE_MODE_CREATE) {
+ //
+ // In the create if does not exist case, if the opening in update
+ // mode failed, create it and open it in update mode. The update
+ // mode allows for both read and write from and to the file.
+ //
+ Return = SemihostFileOpen (
+ AsciiFileName,
+ SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE,
+ &SemihostHandle
+ );
+ if (RETURN_ERROR (Return)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Error;
+ }
+ } else {
+ Status = EFI_NOT_FOUND;
+ goto Error;
+ }
+ }
+
+ // Allocate a control block and fill it
+ FileFcb = AllocateFCB ();
+ if (FileFcb == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ FileFcb->FileName = AsciiFileName;
+ FileFcb->SemihostHandle = SemihostHandle;
+ FileFcb->Position = 0;
+ FileFcb->IsRoot = 0;
+ FileFcb->OpenMode = OpenMode;
+
+ Return = SemihostFileLength (SemihostHandle, &Length);
+ if (RETURN_ERROR (Return)) {
+ Status = EFI_DEVICE_ERROR;
+ FreeFCB (FileFcb);
+ goto Error;
+ }
+
+ FileFcb->Info.FileSize = Length;
+ FileFcb->Info.PhysicalSize = Length;
+ FileFcb->Info.Attribute = (OpenMode & EFI_FILE_MODE_CREATE) ? Attributes : 0;
+
+ InsertTailList (&gFileList, &FileFcb->Link);
+
+ *NewHandle = &FileFcb->File;
+
+ return EFI_SUCCESS;
+
+Error:
+
+ FreePool (AsciiFileName);
+
+ return Status;
+}
+
+/**
+ Worker function that truncate a file specified by its name to a given size.
+
+ @param[in] FileName The Null-terminated string of the name of the file to be opened.
+ @param[in] Size The target size for the file.
+
+ @retval EFI_SUCCESS The file was truncated.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+
+**/
+STATIC
+EFI_STATUS
+TruncateFile (
+ IN CHAR8 *FileName,
+ IN UINTN Size
+ )
+{
+ EFI_STATUS Status;
+ RETURN_STATUS Return;
+ UINTN FileHandle;
+ UINT8 *Buffer;
+ UINTN Remaining;
+ UINTN Read;
+ UINTN ToRead;
+
+ Status = EFI_DEVICE_ERROR;
+ FileHandle = 0;
+ Buffer = NULL;
+
+ Return = SemihostFileOpen (
+ FileName,
+ SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY,
+ &FileHandle
+ );
+ if (RETURN_ERROR (Return)) {
+ goto Error;
+ }
+
+ Buffer = AllocatePool (Size);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ Read = 0;
+ Remaining = Size;
+ while (Remaining > 0) {
+ ToRead = Remaining;
+ Return = SemihostFileRead (FileHandle, &ToRead, Buffer + Read);
+ if (RETURN_ERROR (Return)) {
+ goto Error;
+ }
+ Remaining -= ToRead;
+ Read += ToRead;
+ }
+
+ Return = SemihostFileClose (FileHandle);
+ FileHandle = 0;
+ if (RETURN_ERROR (Return)) {
+ goto Error;
+ }
+
+ Return = SemihostFileOpen (
+ FileName,
+ SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY,
+ &FileHandle
+ );
+ if (RETURN_ERROR (Return)) {
+ goto Error;
+ }
+
+ if (Size > 0) {
+ Return = SemihostFileWrite (FileHandle, &Size, Buffer);
+ if (RETURN_ERROR (Return)) {
+ goto Error;
+ }
+ }
+
+ Status = EFI_SUCCESS;
+
+Error:
+
+ if (FileHandle != 0) {
+ SemihostFileClose (FileHandle);
+ }
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+
+ return (Status);
+
+}
+
+/**
+ Close a specified file handle.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to close.
+
+ @retval EFI_SUCCESS The file was closed.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL.
+
+**/
+EFI_STATUS
+FileClose (
+ IN EFI_FILE *This
+ )
+{
+ SEMIHOST_FCB *Fcb;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(This);
+
+ if (!Fcb->IsRoot) {
+ SemihostFileClose (Fcb->SemihostHandle);
+ //
+ // The file size might have been reduced from its actual
+ // size on the host file system with FileSetInfo(). In
+ // that case, the file has to be truncated.
+ //
+ if (Fcb->Info.FileSize < Fcb->Info.PhysicalSize) {
+ TruncateFile (Fcb->FileName, Fcb->Info.FileSize);
+ }
+ FreePool (Fcb->FileName);
+ }
+
+ FreeFCB (Fcb);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Close and delete a file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to delete.
+
+ @retval EFI_SUCCESS The file was closed and deleted.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL.
+
+**/
+EFI_STATUS
+FileDelete (
+ IN EFI_FILE *This
+ )
+{
+ SEMIHOST_FCB *Fcb;
+ RETURN_STATUS Return;
+ CHAR8 *FileName;
+ UINTN NameSize;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS (This);
+
+ if (!Fcb->IsRoot) {
+ // Get the filename from the Fcb
+ NameSize = AsciiStrLen (Fcb->FileName);
+ FileName = AllocatePool (NameSize + 1);
+
+ AsciiStrCpy (FileName, Fcb->FileName);
+
+ // Close the file if it's open. Disregard return status,
+ // since it might give an error if the file isn't open.
+ This->Close (This);
+
+ // Call the semihost interface to delete the file.
+ Return = SemihostFileRemove (FileName);
+ if (RETURN_ERROR (Return)) {
+ return EFI_WARN_DELETE_FAILURE;
+ }
+ return EFI_SUCCESS;
+ } else {
+ return EFI_WARN_DELETE_FAILURE;
+ }
+}
+
+/**
+ Read data from an open file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to read data from.
+ @param[in out] BufferSize On input, the size of the Buffer. On output, the
+ amount of data returned in Buffer. In both cases,
+ the size is measured in bytes.
+ @param[out] Buffer The buffer into which the data is read.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR On entry, the current file position is
+ beyond the end of the file, or the semi-hosting
+ interface reported an error while performing the
+ read operation.
+ @retval EFI_INVALID_PARAMETER At least one of the three input pointers is NULL.
+
+**/
+EFI_STATUS
+FileRead (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ SEMIHOST_FCB *Fcb;
+ EFI_STATUS Status;
+ RETURN_STATUS Return;
+
+ if ((This == NULL) || (BufferSize == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS (This);
+
+ if (Fcb->IsRoot) {
+ // The semi-hosting interface does not allow to list files on the host machine.
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = EFI_SUCCESS;
+ if (Fcb->Position >= Fcb->Info.FileSize) {
+ *BufferSize = 0;
+ if (Fcb->Position > Fcb->Info.FileSize) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ } else {
+ Return = SemihostFileRead (Fcb->SemihostHandle, BufferSize, Buffer);
+ if (RETURN_ERROR (Return)) {
+ Status = EFI_DEVICE_ERROR;
+ } else {
+ Fcb->Position += *BufferSize;
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Worker function that extends the size of an open file.
+
+ The extension is filled with zeros.
+
+ @param[in] Fcb Internal description of the opened file
+ @param[in] Size The number of bytes, the file has to be extended.
+
+ @retval EFI_SUCCESS The file was extended.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+
+**/
+STATIC
+EFI_STATUS
+ExtendFile (
+ IN SEMIHOST_FCB *Fcb,
+ IN UINTN Size
+ )
+{
+ RETURN_STATUS Return;
+ UINTN Remaining;
+ CHAR8 WriteBuffer[128];
+ UINTN WriteNb;
+ UINTN WriteSize;
+
+ Return = SemihostFileSeek (Fcb->SemihostHandle, Fcb->Info.FileSize);
+ if (RETURN_ERROR (Return)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Remaining = Size;
+ SetMem (WriteBuffer, 0, sizeof(WriteBuffer));
+ while (Remaining > 0) {
+ WriteNb = MIN (Remaining, sizeof(WriteBuffer));
+ WriteSize = WriteNb;
+ Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer);
+ if (RETURN_ERROR (Return)) {
+ return EFI_DEVICE_ERROR;
+ }
+ Remaining -= WriteNb;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write data to an open file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to write data to.
+ @param[in out] BufferSize On input, the size of the Buffer. On output, the
+ size of the data actually written. In both cases,
+ the size is measured in bytes.
+ @param[in] Buffer The buffer of data to write.
+
+ @retval EFI_SUCCESS The data was written.
+ @retval EFI_ACCESS_DENIED Attempt to write into a read only file or
+ in a file opened in read only mode.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_INVALID_PARAMETER At least one of the three input pointers is NULL.
+
+**/
+EFI_STATUS
+FileWrite (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ SEMIHOST_FCB *Fcb;
+ EFI_STATUS Status;
+ UINTN WriteSize;
+ RETURN_STATUS Return;
+ UINTN Length;
+
+ if ((This == NULL) || (BufferSize == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS (This);
+
+ // We cannot write a read-only file
+ if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
+ || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // If the position has been set past the end of the file, first grow the
+ // file from its current size "Fcb->Info.FileSize" to "Fcb->Position"
+ // size, filling the gap with zeros.
+ //
+ if (Fcb->Position > Fcb->Info.FileSize) {
+ Status = ExtendFile (Fcb, Fcb->Position - Fcb->Info.FileSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Fcb->Info.FileSize = Fcb->Position;
+ }
+
+ WriteSize = *BufferSize;
+ Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
+ if (RETURN_ERROR (Return)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Fcb->Position += *BufferSize;
+ if (Fcb->Position > Fcb->Info.FileSize) {
+ Fcb->Info.FileSize = Fcb->Position;
+ }
+
+ Return = SemihostFileLength (Fcb->SemihostHandle, &Length);
+ if (RETURN_ERROR (Return)) {
+ return EFI_DEVICE_ERROR;
+ }
+ Fcb->Info.PhysicalSize = Length;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to get the current position on.
+ @param[out] Position The address to return the file's current position value.
+
+ @retval EFI_SUCCESS The position was returned.
+ @retval EFI_INVALID_PARAMETER The parameter "This" or "Position" is NULL.
+
+**/
+EFI_STATUS
+FileGetPosition (
+ IN EFI_FILE *This,
+ OUT UINT64 *Position
+ )
+{
+ SEMIHOST_FCB *Fcb;
+
+ if ((This == NULL) || (Position == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(This);
+
+ *Position = Fcb->Position;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to set the requested position on.
+ @param[in] Position The byte position from the start of the file to set.
+
+ @retval EFI_SUCCESS The position was set.
+ @retval EFI_DEVICE_ERROR The semi-hosting positionning operation failed.
+ @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
+ directories.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL.
+
+**/
+EFI_STATUS
+FileSetPosition (
+ IN EFI_FILE *This,
+ IN UINT64 Position
+ )
+{
+ SEMIHOST_FCB *Fcb;
+ RETURN_STATUS Return;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS (This);
+
+ if (Fcb->IsRoot) {
+ if (Position != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ else {
+ //
+ // UEFI Spec section 12.5:
+ // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to
+ // be set to the end of the file."
+ //
+ if (Position == 0xFFFFFFFFFFFFFFFF) {
+ Position = Fcb->Info.FileSize;
+ }
+ Return = SemihostFileSeek (Fcb->SemihostHandle, MIN (Position, Fcb->Info.FileSize));
+ if (RETURN_ERROR (Return)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ Fcb->Position = Position;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return information about a file.
+
+ @param[in] Fcb A pointer to the description of an open file.
+ @param[in out] BufferSize The size, in bytes, of Buffer.
+ @param[out] Buffer A pointer to the data buffer to return. Not NULL if
+ "*BufferSize" is greater than 0.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to return the information.
+ BufferSize has been updated with the size needed to
+ complete the request.
+**/
+STATIC
+EFI_STATUS
+GetFileInfo (
+ IN SEMIHOST_FCB *Fcb,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_FILE_INFO *Info = NULL;
+ UINTN NameSize = 0;
+ UINTN ResultSize;
+ UINTN Index;
+
+ if (Fcb->IsRoot == TRUE) {
+ ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
+ } else {
+ NameSize = AsciiStrLen (Fcb->FileName) + 1;
+ ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16);
+ }
+
+ if (*BufferSize < ResultSize) {
+ *BufferSize = ResultSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Info = Buffer;
+
+ // Copy the current file info
+ CopyMem (Info, &Fcb->Info, SIZE_OF_EFI_FILE_INFO);
+
+ // Fill in the structure
+ Info->Size = ResultSize;
+
+ if (Fcb->IsRoot == TRUE) {
+ Info->FileName[0] = L'\0';
+ } else {
+ for (Index = 0; Index < NameSize; Index++) {
+ Info->FileName[Index] = Fcb->FileName[Index];
+ }
+ }
+
+ *BufferSize = ResultSize;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return information about a file system.
+
+ @param[in] Fcb A pointer to the description of an open file
+ which belongs to the file system, the information
+ is requested for.
+ @param[in out] BufferSize The size, in bytes, of Buffer.
+ @param[out] Buffer A pointer to the data buffer to return. Not NULL if
+ "*BufferSize" is greater than 0.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to return the information.
+ BufferSize has been updated with the size needed to
+ complete the request.
+
+**/
+STATIC
+EFI_STATUS
+GetFilesystemInfo (
+ IN SEMIHOST_FCB *Fcb,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_FILE_SYSTEM_INFO *Info;
+ EFI_STATUS Status;
+ UINTN ResultSize;
+
+ ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (mSemihostFsLabel);
+
+ if (*BufferSize >= ResultSize) {
+ ZeroMem (Buffer, ResultSize);
+ Status = EFI_SUCCESS;
+
+ Info = Buffer;
+
+ Info->Size = ResultSize;
+ Info->ReadOnly = FALSE;
+ Info->VolumeSize = 0;
+ Info->FreeSpace = 0;
+ Info->BlockSize = 0;
+
+ StrCpy (Info->VolumeLabel, mSemihostFsLabel);
+ } else {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = ResultSize;
+ return Status;
+}
+
+/**
+ Return information about a file or a file system.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle the requested information is for.
+ @param[in] InformationType The type identifier for the information being requested :
+ EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+ EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ @param[in out] BufferSize The size, in bytes, of Buffer.
+ @param[out] Buffer A pointer to the data buffer to return. The type of the
+ data inside the buffer is indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to return the information.
+ BufferSize has been updated with the size needed to
+ complete the request.
+ @retval EFI_INVALID_PARAMETER The parameter "This" or "InformationType" or "BufferSize"
+ is NULL or "Buffer" is NULL and "*Buffersize" is greater
+ than 0.
+
+**/
+EFI_STATUS
+FileGetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ SEMIHOST_FCB *Fcb;
+ EFI_STATUS Status;
+ UINTN ResultSize;
+
+ if ((This == NULL) ||
+ (InformationType == NULL) ||
+ (BufferSize == NULL) ||
+ ((Buffer == NULL) && (*BufferSize > 0)) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(This);
+
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+ Status = GetFilesystemInfo (Fcb, BufferSize, Buffer);
+ } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+ Status = GetFileInfo (Fcb, BufferSize, Buffer);
+ } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ ResultSize = StrSize (mSemihostFsLabel);
+
+ if (*BufferSize >= ResultSize) {
+ StrCpy (Buffer, mSemihostFsLabel);
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = ResultSize;
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ return Status;
+}
+
+/**
+ Set information about a file.
+
+ @param[in] Fcb A pointer to the description of the open file.
+ @param[in] Info A pointer to the file information to write.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the
+ EFI_FILE_DIRECTORY Attribute.
+ @retval EFI_ACCESS_DENIED The file is a read-only file or has been
+ opened in read-only mode and an attempt is
+ being made to modify a field other than
+ Attribute.
+ @retval EFI_WRITE_PROTECTED An attempt is being made to modify a
+ read-only attribute.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_OUT_OF_RESOURCES A allocation needed to process the request failed.
+
+**/
+STATIC
+EFI_STATUS
+SetFileInfo (
+ IN SEMIHOST_FCB *Fcb,
+ IN EFI_FILE_INFO *Info
+ )
+{
+ EFI_STATUS Status;
+ RETURN_STATUS Return;
+ BOOLEAN FileSizeIsDifferent;
+ BOOLEAN FileNameIsDifferent;
+ BOOLEAN ReadOnlyIsDifferent;
+ CHAR8 *AsciiFileName;
+ UINTN FileSize;
+ UINTN Length;
+ UINTN SemihostHandle;
+
+ //
+ // A directory can not be changed to a file and a file can
+ // not be changed to a directory.
+ //
+ if (((Info->Attribute & EFI_FILE_DIRECTORY) != 0) != Fcb->IsRoot) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ AsciiFileName = AllocatePool (StrLen (Info->FileName) + 1);
+ if (AsciiFileName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ UnicodeStrToAsciiStr (Info->FileName, AsciiFileName);
+
+ FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize);
+ FileNameIsDifferent = (AsciiStrCmp (AsciiFileName, Fcb->FileName) != 0);
+ ReadOnlyIsDifferent = CompareMem (
+ &Info->CreateTime,
+ &Fcb->Info.CreateTime,
+ 3 * sizeof (EFI_TIME)
+ ) != 0;
+
+ //
+ // For a read-only file or a file opened in read-only mode, only
+ // the Attribute field can be modified. As the root directory is
+ // read-only (i.e. VolumeOpen()), this protects the root directory
+ // description.
+ //
+ if ((Fcb->OpenMode == EFI_FILE_MODE_READ) ||
+ (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) ) {
+ if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) {
+ Status = EFI_ACCESS_DENIED;
+ goto Error;
+ }
+ }
+
+ if (ReadOnlyIsDifferent) {
+ Status = EFI_WRITE_PROTECTED;
+ goto Error;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+
+ if (FileSizeIsDifferent) {
+ FileSize = Info->FileSize;
+ if (Fcb->Info.FileSize < FileSize) {
+ Status = ExtendFile (Fcb, FileSize - Fcb->Info.FileSize);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ //
+ // The read/write position from the host file system point of view
+ // is at the end of the file. If the position from this module
+ // point of view is smaller than the new file size, then
+ // ask the host file system to move to that position.
+ //
+ if (Fcb->Position < FileSize) {
+ FileSetPosition (&Fcb->File, Fcb->Position);
+ }
+ }
+ Fcb->Info.FileSize = FileSize;
+
+ Return = SemihostFileLength (Fcb->SemihostHandle, &Length);
+ if (RETURN_ERROR (Return)) {
+ goto Error;
+ }
+ Fcb->Info.PhysicalSize = Length;
+ }
+
+ //
+ // Note down in RAM the Attribute field but we can not ask
+ // for its modification to the host file system as the
+ // semi-host interface does not provide this feature.
+ //
+ Fcb->Info.Attribute = Info->Attribute;
+
+ if (FileNameIsDifferent) {
+ Return = SemihostFileOpen (
+ AsciiFileName,
+ SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY,
+ &SemihostHandle
+ );
+ if (!RETURN_ERROR (Return)) {
+ SemihostFileClose (SemihostHandle);
+ Status = EFI_ACCESS_DENIED;
+ goto Error;
+ }
+
+ Return = SemihostFileRename (Fcb->FileName, AsciiFileName);
+ if (RETURN_ERROR (Return)) {
+ goto Error;
+ }
+ FreePool (Fcb->FileName);
+ Fcb->FileName = AsciiFileName;
+ AsciiFileName = NULL;
+ }
+
+ Status = EFI_SUCCESS;
+
+Error:
+ if (AsciiFileName != NULL) {
+ FreePool (AsciiFileName);
+ }
+
+ return Status;
+}
+
+/**
+ Set information about a file or a file system.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle the information is for.
+ @param[in] InformationType The type identifier for the information being set :
+ EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+ EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ @param[in] BufferSize The size, in bytes, of Buffer.
+ @param[in] Buffer A pointer to the data buffer to write. The type of the
+ data inside the buffer is indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the
+ EFI_FILE_DIRECTORY Attribute.
+ @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and
+ the file is a read-only file or has been
+ opened in read-only mode and an attempt is
+ being made to modify a field other than
+ Attribute.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+ @retval EFI_WRITE_PROTECTED An attempt is being made to modify a
+ read-only attribute.
+ @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by
+ the data inside the buffer.
+ @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request failed.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
+EFI_STATUS
+FileSetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ SEMIHOST_FCB *Fcb;
+ EFI_FILE_INFO *Info;
+ EFI_FILE_SYSTEM_INFO *SystemInfo;
+ CHAR16 *VolumeLabel;
+
+ if ((This == NULL) || (InformationType == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS (This);
+
+ if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+ Info = Buffer;
+ if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (BufferSize < Info->Size) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ return SetFileInfo (Fcb, Info);
+ } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+ SystemInfo = Buffer;
+ if (SystemInfo->Size <
+ (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (BufferSize < SystemInfo->Size) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ Buffer = SystemInfo->VolumeLabel;
+
+ if (StrSize (Buffer) > 0) {
+ VolumeLabel = AllocateCopyPool (StrSize (Buffer), Buffer);
+ if (VolumeLabel != NULL) {
+ FreePool (mSemihostFsLabel);
+ mSemihostFsLabel = VolumeLabel;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else if (!CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ return EFI_UNSUPPORTED;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+EFI_STATUS
+FileFlush (
+ IN EFI_FILE *File
+ )
+{
+ SEMIHOST_FCB *Fcb;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ if (Fcb->IsRoot) {
+ return EFI_SUCCESS;
+ } else {
+ if ((Fcb->Info.Attribute & EFI_FILE_READ_ONLY)
+ || !(Fcb->OpenMode & EFI_FILE_MODE_WRITE)) {
+ return EFI_ACCESS_DENIED;
+ } else {
+ return EFI_SUCCESS;
+ }
+ }
+}
+
+EFI_STATUS
+SemihostFsEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_NOT_FOUND;
+
+ if (SemihostConnectionSupported ()) {
+ mSemihostFsLabel = AllocateCopyPool (StrSize (DEFAULT_SEMIHOST_FS_LABEL), DEFAULT_SEMIHOST_FS_LABEL);
+ if (mSemihostFsLabel == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gInstallHandle,
+ &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,
+ &gEfiDevicePathProtocolGuid, &gDevicePath,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ FreePool (mSemihostFsLabel);
+ }
+ }
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h
new file mode 100644
index 0000000..9339574
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h
@@ -0,0 +1,252 @@
+/** @file
+ Support a Semi Host file system over a debuggers JTAG
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+
+#ifndef __SEMIHOST_FS_H__
+#define __SEMIHOST_FS_H__
+
+EFI_STATUS
+VolumeOpen (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE **Root
+ );
+
+/**
+ Open a file on the host system by means of the semihosting interface.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to source location.
+ @param[out] NewHandle A pointer to the location to return the opened
+ handle for the new file.
+ @param[in] FileName The Null-terminated string of the name of the file
+ to be opened.
+ @param[in] OpenMode The mode to open the file : Read or Read/Write or
+ Read/Write/Create
+ @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these
+ are the attribute bits for the newly created file. The
+ mnemonics of the attribute bits are : EFI_FILE_READ_ONLY,
+ EFI_FILE_HIDDEN, EFI_FILE_SYSTEM, EFI_FILE_RESERVED,
+ EFI_FILE_DIRECTORY and EFI_FILE_ARCHIVE.
+
+ @retval EFI_SUCCESS The file was open.
+ @retval EFI_NOT_FOUND The specified file could not be found.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible
+ with the semi-hosting interface.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
+EFI_STATUS
+FileOpen (
+ IN EFI_FILE *This,
+ OUT EFI_FILE **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ );
+
+/**
+ Close a specified file handle.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to close.
+
+ @retval EFI_SUCCESS The file was closed.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL.
+
+**/
+EFI_STATUS
+FileClose (
+ IN EFI_FILE *This
+ );
+
+/**
+ Close and delete a file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to delete.
+
+ @retval EFI_SUCCESS The file was closed and deleted.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL.
+
+**/
+EFI_STATUS
+FileDelete (
+ IN EFI_FILE *This
+ );
+
+/**
+ Read data from an open file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to read data from.
+ @param[in out] BufferSize On input, the size of the Buffer. On output, the
+ amount of data returned in Buffer. In both cases,
+ the size is measured in bytes.
+ @param[out] Buffer The buffer into which the data is read.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR On entry, the current file position is
+ beyond the end of the file, or the semi-hosting
+ interface reported an error while performing the
+ read operation.
+ @retval EFI_INVALID_PARAMETER The parameter "This" or the parameter "Buffer"
+ is NULL.
+**/
+EFI_STATUS
+FileRead (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Write data to an open file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to write data to.
+ @param[in out] BufferSize On input, the size of the Buffer. On output, the
+ size of the data actually written. In both cases,
+ the size is measured in bytes.
+ @param[in] Buffer The buffer of data to write.
+
+ @retval EFI_SUCCESS The data was written.
+ @retval EFI_ACCESS_DENIED Attempt to write into a read only file or
+ in a file opened in read only mode.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_INVALID_PARAMETER The parameter "This" or the parameter "Buffer"
+ is NULL.
+
+**/
+EFI_STATUS
+FileWrite (
+ IN EFI_FILE *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+/**
+ Return a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to get the current position on.
+ @param[out] Position The address to return the file's current position value.
+
+ @retval EFI_SUCCESS The position was returned.
+ @retval EFI_INVALID_PARAMETER Position is a NULL pointer.
+
+**/
+EFI_STATUS
+FileGetPosition (
+ IN EFI_FILE *File,
+ OUT UINT64 *Position
+ );
+
+/**
+ Set a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to set the requested position on.
+ @param[in] Position The byte position from the start of the file to set.
+
+ @retval EFI_SUCCESS The position was set.
+ @retval EFI_DEVICE_ERROR The semi-hosting positionning operation failed.
+ @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
+ directories.
+
+**/
+EFI_STATUS
+FileSetPosition (
+ IN EFI_FILE *File,
+ IN UINT64 Position
+ );
+
+/**
+ Return information about a file or a file system.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle the requested information is for.
+ @param[in] InformationType The type identifier for the information being requested :
+ EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+ EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ @param[in out] BufferSize The size, in bytes, of Buffer.
+ @param[out] Buffer A pointer to the data buffer to return. The type of the
+ data inside the buffer is indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to return the information.
+ BufferSize has been updated with the size needed to
+ complete the request.
+ @retval EFI_INVALID_PARAMETER The parameter "This" or the parameter "Buffer"
+ is NULL.
+
+**/
+EFI_STATUS
+FileGetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Set information about a file or a file system.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle the information is for.
+ @param[in] InformationType The type identifier for the information being set :
+ EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+ EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ @param[in] BufferSize The size, in bytes, of Buffer.
+ @param[in] Buffer A pointer to the data buffer to write. The type of the
+ data inside the buffer is indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the
+ EFI_FILE_DIRECTORY Attribute.
+ @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and
+ the file is a read-only file or has been
+ opened in read-only mode and an attempt is
+ being made to modify a field other than
+ Attribute.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+ @retval EFI_WRITE_PROTECTED An attempt is being made to modify a
+ read-only attribute.
+ @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by
+ the data inside the buffer.
+ @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request failed.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
+EFI_STATUS
+FileSetInfo (
+ IN EFI_FILE *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+EFI_STATUS
+FileFlush (
+ IN EFI_FILE *File
+ );
+
+#endif // __SEMIHOST_FS_H__
+
diff --git a/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
new file mode 100644
index 0000000..164df2d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
@@ -0,0 +1,48 @@
+#/** @file
+# Support a Semi Host file system over a debuggers JTAG
+#
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+# Portions copyright (c) 2011 - 2013, ARM 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 = SemihostFs
+ FILE_GUID = C5B9C74A-6D72-4719-99AB-C59F199091EB
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = SemihostFsEntryPoint
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/SemihostFs.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ SemihostLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Guids]
+ gEfiFileSystemInfoGuid
+ gEfiFileInfoGuid
+ gEfiFileSystemVolumeLabelInfoIdGuid
+
+[Protocols]
+ gEfiSimpleFileSystemProtocolGuid
+ gEfiDevicePathProtocolGuid
+
diff --git a/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.h b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.h
new file mode 100644
index 0000000..6904bdc
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.h
@@ -0,0 +1,303 @@
+/** @file
+ Macros to work around lack of Apple support for LDR register, =expr
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011-2012, 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.
+
+**/
+
+
+#ifndef __MACRO_IO_LIB_H__
+#define __MACRO_IO_LIB_H__
+
+#if defined(__APPLE__)
+
+//
+// ldr reg, =expr does not work with current Apple tool chain. So do the work our selves
+//
+
+// returns _Data in R0 and _Address in R1
+#define MmioWrite32(_Address, _Data) \
+ ldr r1, [pc, #8] ; \
+ ldr r0, [pc, #8] ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_Data) ; \
+1:
+
+// returns _Data in R0 and _Address in R1, and _OrData in r2
+#define MmioOr32(_Address, _OrData) \
+ ldr r1, [pc, #16] ; \
+ ldr r2, [pc, #16] ; \
+ ldr r0, [r1] ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_OrData) ; \
+1:
+
+// returns _Data in R0 and _Address in R1, and _OrData in r2
+#define MmioAnd32(_Address, _AndData) \
+ ldr r1, [pc, #16] ; \
+ ldr r2, [pc, #16] ; \
+ ldr r0, [r1] ; \
+ and r0, r0, r2 ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_AndData) ; \
+1:
+
+// returns result in R0, _Address in R1, and _OrData in r2
+#define MmioAndThenOr32(_Address, _AndData, _OrData) \
+ ldr r1, [pc, #24] ; \
+ ldr r0, [r1] ; \
+ ldr r2, [pc, #20] ; \
+ and r0, r0, r2 ; \
+ ldr r2, [pc, #16] ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_AndData) ; \
+ .long (_OrData) ; \
+1:
+
+// returns _Data in _Reg and _Address in R1
+#define MmioWriteFromReg32(_Address, _Reg) \
+ ldr r1, [pc, #4] ; \
+ str _Reg, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+1:
+
+
+// returns _Data in R0 and _Address in R1
+#define MmioRead32(_Address) \
+ ldr r1, [pc, #4] ; \
+ ldr r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+1:
+
+// returns _Data in Reg and _Address in R1
+#define MmioReadToReg32(_Address, _Reg) \
+ ldr r1, [pc, #4] ; \
+ ldr _Reg, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+1:
+
+
+// load R0 with _Data
+#define LoadConstant(_Data) \
+ ldr r0, [pc, #0] ; \
+ b 1f ; \
+ .long (_Data) ; \
+1:
+
+// load _Reg with _Data
+#define LoadConstantToReg(_Data, _Reg) \
+ ldr _Reg, [pc, #0] ; \
+ b 1f ; \
+ .long (_Data) ; \
+1:
+
+// load _Reg with _Data if eq
+#define LoadConstantToRegIfEq(_Data, _Reg) \
+ ldreq _Reg, [pc, #0] ; \
+ b 1f ; \
+ .long (_Data) ; \
+1:
+
+// Reserve a region at the top of the Primary Core stack
+// for Global variables for the XIP phase
+#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
+ and Tmp, GlobalSize, #7 ; \
+ rsbne Tmp, Tmp, #8 ; \
+ add GlobalSize, GlobalSize, Tmp ; \
+ sub sp, StackTop, GlobalSize ; \
+ ; \
+ mov Tmp, sp ; \
+ mov GlobalSize, #0x0 ; \
+_SetPrimaryStackInitGlobals: ; \
+ cmp Tmp, StackTop ; \
+ beq _SetPrimaryStackEnd ; \
+ str GlobalSize, [Tmp], #4 ; \
+ b _SetPrimaryStackInitGlobals ; \
+_SetPrimaryStackEnd:
+
+// Initialize the Global Variable with '0'
+#define InitializePrimaryStack(GlobalSize, Tmp1) \
+ and Tmp1, GlobalSize, #7 ; \
+ rsbne Tmp1, Tmp1, #8 ; \
+ add GlobalSize, GlobalSize, Tmp1 ; \
+ ; \
+ mov Tmp1, sp ; \
+ sub sp, GlobalSize ; \
+ mov GlobalSize, #0x0 ; \
+_InitializePrimaryStackLoop: ; \
+ cmp Tmp1, sp ; \
+ bls _InitializePrimaryStackEnd ; \
+ str GlobalSize, [Tmp1, #-4]! ; \
+ b _InitializePrimaryStackLoop ; \
+_InitializePrimaryStackEnd:
+
+#elif defined (__GNUC__)
+
+#define MmioWrite32(Address, Data) \
+ ldr r1, =Address ; \
+ ldr r0, =Data ; \
+ str r0, [r1]
+
+#define MmioOr32(Address, OrData) \
+ ldr r1, =Address ; \
+ ldr r2, =OrData ; \
+ ldr r0, [r1] ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1]
+
+#define MmioAnd32(Address, AndData) \
+ ldr r1, =Address ; \
+ ldr r2, =AndData ; \
+ ldr r0, [r1] ; \
+ and r0, r0, r2 ; \
+ str r0, [r1]
+
+#define MmioAndThenOr32(Address, AndData, OrData) \
+ ldr r1, =Address ; \
+ ldr r0, [r1] ; \
+ ldr r2, =AndData ; \
+ and r0, r0, r2 ; \
+ ldr r2, =OrData ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1]
+
+#define MmioWriteFromReg32(Address, Reg) \
+ ldr r1, =Address ; \
+ str Reg, [r1]
+
+#define MmioRead32(Address) \
+ ldr r1, =Address ; \
+ ldr r0, [r1]
+
+#define MmioReadToReg32(Address, Reg) \
+ ldr r1, =Address ; \
+ ldr Reg, [r1]
+
+#define LoadConstant(Data) \
+ ldr r0, =Data
+
+#define LoadConstantToReg(Data, Reg) \
+ ldr Reg, =Data
+
+#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
+ and Tmp, GlobalSize, #7 ; \
+ rsbne Tmp, Tmp, #8 ; \
+ add GlobalSize, GlobalSize, Tmp ; \
+ sub sp, StackTop, GlobalSize ; \
+ ; \
+ mov Tmp, sp ; \
+ mov GlobalSize, #0x0 ; \
+_SetPrimaryStackInitGlobals: ; \
+ cmp Tmp, StackTop ; \
+ beq _SetPrimaryStackEnd ; \
+ str GlobalSize, [Tmp], #4 ; \
+ b _SetPrimaryStackInitGlobals ; \
+_SetPrimaryStackEnd:
+
+// Initialize the Global Variable with '0'
+#define InitializePrimaryStack(GlobalSize, Tmp1) \
+ and Tmp1, GlobalSize, #7 ; \
+ rsbne Tmp1, Tmp1, #8 ; \
+ add GlobalSize, GlobalSize, Tmp1 ; \
+ ; \
+ mov Tmp1, sp ; \
+ sub sp, GlobalSize ; \
+ mov GlobalSize, #0x0 ; \
+_InitializePrimaryStackLoop: ; \
+ cmp Tmp1, sp ; \
+ bls _InitializePrimaryStackEnd ; \
+ str GlobalSize, [Tmp1, #-4]! ; \
+ b _InitializePrimaryStackLoop ; \
+_InitializePrimaryStackEnd:
+
+#else
+
+//
+// Use ARM assembly macros, form armasam
+//
+// Less magic in the macros if ldr reg, =expr works
+//
+
+// returns _Data in R0 and _Address in R1
+
+
+
+#define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data
+
+
+
+
+// returns Data in R0 and Address in R1, and OrData in r2
+#define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData
+
+
+// returns _Data in R0 and _Address in R1, and _OrData in r2
+
+
+#define MmioAnd32(Address, AndData) MmioAnd32Macro Address, AndData
+
+// returns result in R0, _Address in R1, and _OrData in r2
+
+
+#define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData
+
+
+// returns _Data in _Reg and _Address in R1
+
+
+#define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg
+
+// returns _Data in R0 and _Address in R1
+
+
+#define MmioRead32(Address) MmioRead32Macro Address
+
+// returns _Data in Reg and _Address in R1
+
+
+#define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg
+
+
+// load R0 with _Data
+
+
+#define LoadConstant(Data) LoadConstantMacro Data
+
+// load _Reg with _Data
+
+
+#define LoadConstantToReg(Data, Reg) LoadConstantToRegMacro Data, Reg
+
+// conditional load testing eq flag
+#define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg
+
+#define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp
+
+// Initialize the Global Variable with '0'
+#define InitializePrimaryStack(GlobalSize, Tmp1) InitializePrimaryStack GlobalSize, Tmp1
+
+#endif
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.inc b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.inc
new file mode 100644
index 0000000..301bd89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLib.inc
@@ -0,0 +1,121 @@
+;%HEADER%
+;/** @file
+; Macros to work around lack of Apple support for LDR register, =expr
+;
+; Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+; Copyright (c) 2011-2012, 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.
+;
+;**/
+
+
+ MACRO
+ MmioWrite32Macro $Address, $Data
+ ldr r1, = ($Address)
+ ldr r0, = ($Data)
+ str r0, [r1]
+ MEND
+
+ MACRO
+ MmioOr32Macro $Address, $OrData
+ ldr r1, =($Address)
+ ldr r2, =($OrData)
+ ldr r0, [r1]
+ orr r0, r0, r2
+ str r0, [r1]
+ MEND
+
+ MACRO
+ MmioAnd32Macro $Address, $AndData
+ ldr r1, =($Address)
+ ldr r2, =($AndData)
+ ldr r0, [r1]
+ and r0, r0, r2
+ str r0, [r1]
+ MEND
+
+ MACRO
+ MmioAndThenOr32Macro $Address, $AndData, $OrData
+ ldr r1, =($Address)
+ ldr r0, [r1]
+ ldr r2, =($AndData)
+ and r0, r0, r2
+ ldr r2, =($OrData)
+ orr r0, r0, r2
+ str r0, [r1]
+ MEND
+
+ MACRO
+ MmioWriteFromReg32Macro $Address, $Reg
+ ldr r1, =($Address)
+ str $Reg, [r1]
+ MEND
+
+ MACRO
+ MmioRead32Macro $Address
+ ldr r1, =($Address)
+ ldr r0, [r1]
+ MEND
+
+ MACRO
+ MmioReadToReg32Macro $Address, $Reg
+ ldr r1, =($Address)
+ ldr $Reg, [r1]
+ MEND
+
+ MACRO
+ LoadConstantMacro $Data
+ ldr r0, =($Data)
+ MEND
+
+ MACRO
+ LoadConstantToRegMacro $Data, $Reg
+ ldr $Reg, =($Data)
+ MEND
+
+ ; The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
+ ; Note: Global Size will be modified
+ MACRO
+ SetPrimaryStack $StackTop, $GlobalSize, $Tmp
+ and $Tmp, $GlobalSize, #7
+ rsbne $Tmp, $Tmp, #8
+ add $GlobalSize, $GlobalSize, $Tmp
+ sub sp, $StackTop, $GlobalSize
+
+ ; Set all the global variables to 0
+ mov $Tmp, sp
+ mov $GlobalSize, #0x0
+_SetPrimaryStackInitGlobals
+ cmp $Tmp, $StackTop
+ beq _SetPrimaryStackEnd
+ str $GlobalSize, [$Tmp], #4
+ b _SetPrimaryStackInitGlobals
+_SetPrimaryStackEnd
+ MEND
+
+ MACRO
+ InitializePrimaryStack $GlobalSize, $Tmp1
+ and $Tmp1, $GlobalSize, #7
+ rsbne $Tmp1, $Tmp1, #8
+ add $GlobalSize, $GlobalSize, $Tmp1
+
+ mov $Tmp1, sp
+ sub sp, $GlobalSize
+ ; Set all the global variables to 0
+ mov $GlobalSize, #0x0
+_InitializePrimaryStackLoop
+ cmp $Tmp1, sp
+ bls _InitializePrimaryStackEnd
+ str $GlobalSize, [$Tmp1, #-4]!
+ b _InitializePrimaryStackLoop
+_InitializePrimaryStackEnd
+ MEND
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLibV8.h b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLibV8.h
new file mode 100644
index 0000000..2ee1081
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/AsmMacroIoLibV8.h
@@ -0,0 +1,110 @@
+/** @file
+ Macros to work around lack of Clang support for LDR register, =expr
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __MACRO_IO_LIBV8_H__
+#define __MACRO_IO_LIBV8_H__
+
+#define SetPrimaryStack(StackTop, GlobalSize, Tmp, Tmp1) \
+ ands Tmp, GlobalSize, #15 ; \
+ mov Tmp1, #16 ; \
+ sub Tmp1, Tmp1, Tmp ; \
+ csel Tmp, Tmp1, Tmp, ne ; \
+ add GlobalSize, GlobalSize, Tmp ; \
+ sub sp, StackTop, GlobalSize ; \
+ ; \
+ mov Tmp, sp ; \
+ mov GlobalSize, #0x0 ; \
+_SetPrimaryStackInitGlobals: ; \
+ cmp Tmp, StackTop ; \
+ b.eq _SetPrimaryStackEnd ; \
+ str GlobalSize, [Tmp], #8 ; \
+ b _SetPrimaryStackInitGlobals ; \
+_SetPrimaryStackEnd:
+
+// Initialize the Global Variable with '0'
+#define InitializePrimaryStack(GlobalSize, Tmp1, Tmp2) \
+ and Tmp1, GlobalSize, #15 ; \
+ mov Tmp2, #16 ; \
+ sub Tmp2, Tmp2, Tmp1 ; \
+ add GlobalSize, GlobalSize, Tmp2 ; \
+ ; \
+ mov Tmp1, sp ; \
+ sub sp, sp, GlobalSize ; \
+ mov GlobalSize, #0x0 ; \
+_InitializePrimaryStackLoop: ; \
+ mov Tmp2, sp ; \
+ cmp Tmp1, Tmp2 ; \
+ bls _InitializePrimaryStackEnd ; \
+ str GlobalSize, [Tmp1, #-8]! ; \
+ b _InitializePrimaryStackLoop ; \
+_InitializePrimaryStackEnd:
+
+// CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1
+// This only selects between EL1 and EL2, else we die.
+// Provide the Macro with a safe temp xreg to use.
+#define EL1_OR_EL2(SAFE_XREG) \
+ mrs SAFE_XREG, CurrentEL ;\
+ cmp SAFE_XREG, #0x8 ;\
+ b.eq 2f ;\
+ cmp SAFE_XREG, #0x4 ;\
+ b.ne . ;// We should never get here
+// EL1 code starts here
+
+// CurrentEL : 0xC = EL3; 8 = EL2; 4 = EL1
+// This only selects between EL1 and EL2 and EL3, else we die.
+// Provide the Macro with a safe temp xreg to use.
+#define EL1_OR_EL2_OR_EL3(SAFE_XREG) \
+ mrs SAFE_XREG, CurrentEL ;\
+ cmp SAFE_XREG, #0xC ;\
+ b.eq 3f ;\
+ cmp SAFE_XREG, #0x8 ;\
+ b.eq 2f ;\
+ cmp SAFE_XREG, #0x4 ;\
+ b.ne . ;// We should never get here
+// EL1 code starts here
+#if defined(__clang__)
+
+// load x0 with _Data
+#define LoadConstant(_Data) \
+ ldr x0, 1f ; \
+ b 2f ; \
+.align(8) ; \
+1: \
+ .8byte (_Data) ; \
+2:
+
+// load _Reg with _Data
+#define LoadConstantToReg(_Data, _Reg) \
+ ldr _Reg, 1f ; \
+ b 2f ; \
+.align(8) ; \
+1: \
+ .8byte (_Data) ; \
+2:
+
+#elif defined (__GNUC__)
+
+#define LoadConstant(Data) \
+ ldr x0, =Data
+
+#define LoadConstantToReg(Data, Reg) \
+ ldr Reg, =Data
+
+#endif // __GNUC__
+
+#endif // __MACRO_IO_LIBV8_H__
+
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64.h
new file mode 100644
index 0000000..0400740
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64.h
@@ -0,0 +1,189 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __AARCH64_H__
+#define __AARCH64_H__
+
+#include <Chipset/AArch64Mmu.h>
+#include <Chipset/ArmArchTimer.h>
+
+// ARM Interrupt ID in Exception Table
+#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_AARCH64_IRQ
+
+// CPACR - Coprocessor Access Control Register definitions
+#define CPACR_TTA_EN (1UL << 28)
+#define CPACR_FPEN_EL1 (1UL << 20)
+#define CPACR_FPEN_FULL (3UL << 20)
+#define CPACR_CP_FULL_ACCESS 0x300000
+
+// Coprocessor Trap Register (CPTR)
+#define AARCH64_CPTR_TFP (1 << 10)
+
+// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions
+#define AARCH64_PFR0_FP (0xF << 16)
+#define AARCH64_PFR0_GIC (0xF << 24)
+
+// SCR - Secure Configuration Register definitions
+#define SCR_NS (1 << 0)
+#define SCR_IRQ (1 << 1)
+#define SCR_FIQ (1 << 2)
+#define SCR_EA (1 << 3)
+#define SCR_FW (1 << 4)
+#define SCR_AW (1 << 5)
+
+// MIDR - Main ID Register definitions
+#define ARM_CPU_TYPE_MASK 0xFFF
+#define ARM_CPU_TYPE_AEMv8 0xD0F
+#define ARM_CPU_TYPE_A53 0xD03
+#define ARM_CPU_TYPE_A57 0xD07
+#define ARM_CPU_TYPE_A15 0xC0F
+#define ARM_CPU_TYPE_A9 0xC09
+#define ARM_CPU_TYPE_A5 0xC05
+
+#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) )
+#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF))
+
+// Hypervisor Configuration Register
+#define ARM_HCR_FMO BIT3
+#define ARM_HCR_IMO BIT4
+#define ARM_HCR_AMO BIT5
+#define ARM_HCR_TSC BIT19
+#define ARM_HCR_TGE BIT27
+
+// Exception Syndrome Register
+#define AARCH64_ESR_EC(Ecr) ((0x3F << 26) & (Ecr))
+#define AARCH64_ESR_ISS(Ecr) ((0x1FFFFFF) & (Ecr))
+
+#define AARCH64_ESR_EC_SMC32 (0x13 << 26)
+#define AARCH64_ESR_EC_SMC64 (0x17 << 26)
+
+// AArch64 Exception Level
+#define AARCH64_EL3 0xC
+#define AARCH64_EL2 0x8
+#define AARCH64_EL1 0x4
+
+// Saved Program Status Register definitions
+#define SPSR_A BIT8
+#define SPSR_I BIT7
+#define SPSR_F BIT6
+
+#define SPSR_AARCH32 BIT4
+
+#define SPSR_AARCH32_MODE_USER 0x0
+#define SPSR_AARCH32_MODE_FIQ 0x1
+#define SPSR_AARCH32_MODE_IRQ 0x2
+#define SPSR_AARCH32_MODE_SVC 0x3
+#define SPSR_AARCH32_MODE_ABORT 0x7
+#define SPSR_AARCH32_MODE_UNDEF 0xB
+#define SPSR_AARCH32_MODE_SYS 0xF
+
+// Counter-timer Hypervisor Control register definitions
+#define CNTHCTL_EL2_EL1PCTEN BIT0
+#define CNTHCTL_EL2_EL1PCEN BIT1
+
+#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 11)-1)
+
+VOID
+EFIAPI
+ArmEnableSWPInstruction (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadCbar (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadTpidrurw (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteTpidrurw (
+ UINTN Value
+ );
+
+UINTN
+EFIAPI
+ArmGetTCR (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmSetTCR (
+ UINTN Value
+ );
+
+UINTN
+EFIAPI
+ArmGetMAIR (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmSetMAIR (
+ UINTN Value
+ );
+
+VOID
+EFIAPI
+ArmDisableAlignmentCheck (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableAlignmentCheck (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDisableAllExceptions (
+ VOID
+ );
+
+VOID
+ArmWriteHcr (
+ IN UINTN Hcr
+ );
+
+UINTN
+ArmReadCurrentEL (
+ VOID
+ );
+
+UINT64
+PageAttributeToGcdAttribute (
+ IN UINT64 PageAttributes
+ );
+
+UINT64
+GcdAttributeToPageAttribute (
+ IN UINT64 GcdAttributes
+ );
+
+UINTN
+ArmWriteCptr (
+ IN UINT64 Cptr
+ );
+
+#endif // __AARCH64_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64Mmu.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64Mmu.h
new file mode 100644
index 0000000..77a96ec
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/AArch64Mmu.h
@@ -0,0 +1,211 @@
+/** @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.
+*
+**/
+
+#ifndef __AARCH64_MMU_H_
+#define __AARCH64_MMU_H_
+
+//
+// Memory Attribute Indirection register Definitions
+//
+#define MAIR_ATTR_DEVICE_MEMORY 0x0ULL
+#define MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE 0x44ULL
+#define MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH 0xBBULL
+#define MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK 0xFFULL
+
+#define MAIR_ATTR(n,value) ((value) << (((n) >> 2)*8))
+
+//
+// Long-descriptor Translation Table format
+//
+
+// Return the smallest offset from the table level.
+// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0
+#define TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel) (12 + ((3 - (TableLevel)) * 9))
+
+#define TT_BLOCK_ENTRY_SIZE_AT_LEVEL(Level) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(Level))
+
+// Get the associated entry in the given Translation Table
+#define TT_GET_ENTRY_FOR_ADDRESS(TranslationTable, Level, Address) \
+ ((UINTN)(TranslationTable) + ((((UINTN)(Address) >> TT_ADDRESS_OFFSET_AT_LEVEL(Level)) & (BIT9-1)) * sizeof(UINT64)))
+
+// Return the smallest address granularity from the table level.
+// The first offset starts at 12bit. There are 4 levels of 9-bit address range from level 3 to level 0
+#define TT_ADDRESS_AT_LEVEL(TableLevel) (1ULL << TT_ADDRESS_OFFSET_AT_LEVEL(TableLevel))
+
+#define TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount) \
+ ((UINT64*)((EFI_PHYSICAL_ADDRESS)(TranslationTable) + (((EntryCount) - 1) * sizeof(UINT64))))
+
+// There are 512 entries per table when 4K Granularity
+#define TT_ENTRY_COUNT 512
+#define TT_ALIGNMENT_BLOCK_ENTRY BIT12
+#define TT_ALIGNMENT_DESCRIPTION_TABLE BIT12
+
+#define TT_ADDRESS_MASK_BLOCK_ENTRY (0xFFFFFFFULL << 12)
+#define TT_ADDRESS_MASK_DESCRIPTION_TABLE (0xFFFFFFFULL << 12)
+
+#define TT_TYPE_MASK 0x3
+#define TT_TYPE_TABLE_ENTRY 0x3
+#define TT_TYPE_BLOCK_ENTRY 0x1
+#define TT_TYPE_BLOCK_ENTRY_LEVEL3 0x3
+
+#define TT_ATTR_INDX_MASK (0x7 << 2)
+#define TT_ATTR_INDX_DEVICE_MEMORY (0x0 << 2)
+#define TT_ATTR_INDX_MEMORY_NON_CACHEABLE (0x1 << 2)
+#define TT_ATTR_INDX_MEMORY_WRITE_THROUGH (0x2 << 2)
+#define TT_ATTR_INDX_MEMORY_WRITE_BACK (0x3 << 2)
+
+#define TT_AP_MASK (0x3UL << 6)
+#define TT_AP_NO_RW (0x0UL << 6)
+#define TT_AP_RW_RW (0x1UL << 6)
+#define TT_AP_NO_RO (0x2UL << 6)
+#define TT_AP_RO_RO (0x3UL << 6)
+
+#define TT_NS BIT5
+#define TT_AF BIT10
+
+#define TT_PXN_MASK BIT53
+#define TT_UXN_MASK BIT54
+
+#define TT_ATTRIBUTES_MASK ((0xFFFULL << 52) | (0x3FFULL << 2))
+
+#define TT_TABLE_PXN BIT59
+#define TT_TABLE_XN BIT60
+#define TT_TABLE_NS BIT63
+
+#define TT_TABLE_AP_MASK (BIT62 | BIT61)
+#define TT_TABLE_AP_NO_PERMISSION (0x0ULL << 61)
+#define TT_TABLE_AP_EL0_NO_ACCESS (0x1ULL << 61)
+#define TT_TABLE_AP_NO_WRITE_ACCESS (0x2ULL << 61)
+
+//
+// Translation Control Register
+//
+#define TCR_T0SZ_MASK 0x3F
+
+#define TCR_PS_4GB (0 << 16)
+#define TCR_PS_64GB (1 << 16)
+#define TCR_PS_1TB (2 << 16)
+#define TCR_PS_4TB (3 << 16)
+#define TCR_PS_16TB (4 << 16)
+#define TCR_PS_256TB (5 << 16)
+
+#define TCR_TG0_4KB (0 << 14)
+
+#define TCR_IPS_4GB (0ULL << 32)
+#define TCR_IPS_64GB (1ULL << 32)
+#define TCR_IPS_1TB (2ULL << 32)
+#define TCR_IPS_4TB (3ULL << 32)
+#define TCR_IPS_16TB (4ULL << 32)
+#define TCR_IPS_256TB (5ULL << 32)
+
+
+#define TTBR_ASID_FIELD (48)
+#define TTBR_ASID_MASK (0xFF << TTBR_ASID_FIELD)
+#define TTBR_BADDR_MASK (0xFFFFFFFFFFFF ) // The width of this field depends on the values in TxSZ. Addr occupies bottom 48bits
+
+#define TCR_EL1_T0SZ_FIELD (0)
+#define TCR_EL1_EPD0_FIELD (7)
+#define TCR_EL1_IRGN0_FIELD (8)
+#define TCR_EL1_ORGN0_FIELD (10)
+#define TCR_EL1_SH0_FIELD (12)
+#define TCR_EL1_TG0_FIELD (14)
+#define TCR_EL1_T1SZ_FIELD (16)
+#define TCR_EL1_A1_FIELD (22)
+#define TCR_EL1_EPD1_FIELD (23)
+#define TCR_EL1_IRGN1_FIELD (24)
+#define TCR_EL1_ORGN1_FIELD (26)
+#define TCR_EL1_SH1_FIELD (28)
+#define TCR_EL1_TG1_FIELD (30)
+#define TCR_EL1_IPS_FIELD (32)
+#define TCR_EL1_AS_FIELD (36)
+#define TCR_EL1_TBI0_FIELD (37)
+#define TCR_EL1_TBI1_FIELD (38)
+#define TCR_EL1_T0SZ_MASK (0x1F << TCR_EL1_T0SZ_FIELD)
+#define TCR_EL1_EPD0_MASK (0x1 << TCR_EL1_EPD0_FIELD)
+#define TCR_EL1_IRGN0_MASK (0x3 << TCR_EL1_IRGN0_FIELD)
+#define TCR_EL1_ORGN0_MASK (0x3 << TCR_EL1_ORGN0_FIELD)
+#define TCR_EL1_SH0_MASK (0x3 << TCR_EL1_SH0_FIELD)
+#define TCR_EL1_TG0_MASK (0x1 << TCR_EL1_TG0_FIELD)
+#define TCR_EL1_T1SZ_MASK (0x1F << TCR_EL1_T1SZ_FIELD)
+#define TCR_EL1_A1_MASK (0x1 << TCR_EL1_A1_FIELD)
+#define TCR_EL1_EPD1_MASK (0x1 << TCR_EL1_EPD1_FIELD)
+#define TCR_EL1_IRGN1_MASK (0x3 << TCR_EL1_IRGN1_FIELD)
+#define TCR_EL1_ORGN1_MASK (0x3 << TCR_EL1_ORGN1_FIELD)
+#define TCR_EL1_SH1_MASK (0x3 << TCR_EL1_SH1_FIELD)
+#define TCR_EL1_TG1_MASK (0x1 << TCR_EL1_TG1_FIELD)
+#define TCR_EL1_IPS_MASK (0x7 << TCR_EL1_IPS_FIELD)
+#define TCR_EL1_AS_MASK (0x1 << TCR_EL1_AS_FIELD)
+#define TCR_EL1_TBI0_MASK (0x1 << TCR_EL1_TBI0_FIELD)
+#define TCR_EL1_TBI1_MASK (0x1 << TCR_EL1_TBI1_FIELD)
+
+
+#define VTCR_EL23_T0SZ_FIELD (0)
+#define VTCR_EL23_IRGN0_FIELD (8)
+#define VTCR_EL23_ORGN0_FIELD (10)
+#define VTCR_EL23_SH0_FIELD (12)
+#define TCR_EL23_TG0_FIELD (14)
+#define VTCR_EL23_PS_FIELD (16)
+#define TCR_EL23_T0SZ_MASK (0x1F << VTCR_EL23_T0SZ_FIELD)
+#define TCR_EL23_IRGN0_MASK (0x3 << VTCR_EL23_IRGN0_FIELD)
+#define TCR_EL23_ORGN0_MASK (0x3 << VTCR_EL23_ORGN0_FIELD)
+#define TCR_EL23_SH0_MASK (0x3 << VTCR_EL23_SH0_FIELD)
+#define TCR_EL23_TG0_MASK (0x1 << TCR_EL23_TG0_FIELD)
+#define TCR_EL23_PS_MASK (0x7 << VTCR_EL23_PS_FIELD)
+
+
+#define VTCR_EL2_T0SZ_FIELD (0)
+#define VTCR_EL2_SL0_FIELD (6)
+#define VTCR_EL2_IRGN0_FIELD (8)
+#define VTCR_EL2_ORGN0_FIELD (10)
+#define VTCR_EL2_SH0_FIELD (12)
+#define VTCR_EL2_TG0_FIELD (14)
+#define VTCR_EL2_PS_FIELD (16)
+#define VTCR_EL2_T0SZ_MASK (0x1F << VTCR_EL2_T0SZ_FIELD)
+#define VTCR_EL2_SL0_MASK (0x1F << VTCR_EL2_SL0_FIELD)
+#define VTCR_EL2_IRGN0_MASK (0x3 << VTCR_EL2_IRGN0_FIELD)
+#define VTCR_EL2_ORGN0_MASK (0x3 << VTCR_EL2_ORGN0_FIELD)
+#define VTCR_EL2_SH0_MASK (0x3 << VTCR_EL2_SH0_FIELD)
+#define VTCR_EL2_TG0_MASK (0x1 << VTCR_EL2_TG0_FIELD)
+#define VTCR_EL2_PS_MASK (0x7 << VTCR_EL2_PS_FIELD)
+
+
+#define TCR_RGN_OUTER_NON_CACHEABLE (0x0 << 10)
+#define TCR_RGN_OUTER_WRITE_BACK_ALLOC (0x1 << 10)
+#define TCR_RGN_OUTER_WRITE_THROUGH (0x2 << 10)
+#define TCR_RGN_OUTER_WRITE_BACK_NO_ALLOC (0x3 << 10)
+
+#define TCR_RGN_INNER_NON_CACHEABLE (0x0 << 8)
+#define TCR_RGN_INNER_WRITE_BACK_ALLOC (0x1 << 8)
+#define TCR_RGN_INNER_WRITE_THROUGH (0x2 << 8)
+#define TCR_RGN_INNER_WRITE_BACK_NO_ALLOC (0x3 << 8)
+
+#define TCR_SH_NON_SHAREABLE (0x0 << 12)
+#define TCR_SH_OUTER_SHAREABLE (0x2 << 12)
+#define TCR_SH_INNER_SHAREABLE (0x3 << 12)
+
+#define TCR_PASZ_32BITS_4GB (0x0)
+#define TCR_PASZ_36BITS_64GB (0x1)
+#define TCR_PASZ_40BITS_1TB (0x2)
+#define TCR_PASZ_42BITS_4TB (0x3)
+#define TCR_PASZ_44BITS_16TB (0x4)
+#define TCR_PASZ_48BITS_256TB (0x5)
+
+// The value written to the T*SZ fields are defined as 2^(64-T*SZ). So a 39Bit
+// Virtual address range for 512GB of virtual space sets T*SZ to 25
+#define INPUT_ADDRESS_SIZE_TO_TxSZ(a) (64 - a)
+
+// Uses LPAE Page Table format
+
+#endif // __AARCH64_MMU_H_
+
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM1176JZ-S.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM1176JZ-S.h
new file mode 100644
index 0000000..ba24bcb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM1176JZ-S.h
@@ -0,0 +1,127 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011-2012, 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 __ARM1176JZ_S_H__
+#define __ARM1176JZ_S_H__
+
+// Domain Access Control Register
+#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
+
+#define TRANSLATION_TABLE_SIZE (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1)
+
+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
+
+// Translation table descriptor types
+#define TT_DESCRIPTOR_TYPE_MASK ((1UL << 18) | (3UL << 0))
+#define TT_DESCRIPTOR_TYPE_PAGE_TABLE ((0UL << 18) | (1UL << 0))
+#define TT_DESCRIPTOR_TYPE_SECTION ((0UL << 18) | (2UL << 0))
+#define TT_DESCRIPTOR_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))
+
+// Section descriptor definitions
+#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
+
+#define TT_DESCRIPTOR_SECTION_NS_MASK (1UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS (1UL << 19)
+
+#define TT_DESCRIPTOR_SECTION_NG_MASK (1UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17)
+
+#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16)
+
+#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_NO_NO ((0UL << 15) | (0UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_NO ((0UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RO ((0UL << 15) | (2UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_NO ((1UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (3UL << 10))
+
+#define TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE (0UL)
+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE (1UL)
+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE (2UL)
+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE (3UL)
+
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_MASK ((1UL << 14) | (3UL << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_NON_CACHEABLE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_ALLOCATE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE << 12))
+
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_MASK (3UL << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_NON_CACHEABLE (TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_ALLOCATE (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE (TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE << 2)
+
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK (TT_DESCRIPTOR_OUTER_CACHE_POLICY_MASK | TT_DESCRIPTOR_INNER_CACHE_POLICY_MASK)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE (TT_DESCRIPTOR_OUTER_CACHE_POLICY_NON_CACHEABLE | TT_DESCRIPTOR_INNER_CACHE_POLICY_NON_CACHEABLE)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_ALLOCATE | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_ALLOCATE)
+
+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
+#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5)
+
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
+
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK(NonSecure) (TT_DESCRIPTOR_TYPE_SECTION | \
+ (NonSecure ? TT_DESCRIPTOR_SECTION_NS : 0) | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(NonSecure) (TT_DESCRIPTOR_TYPE_SECTION | \
+ (NonSecure ? TT_DESCRIPTOR_SECTION_NS : 0) | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
+#define TT_DESCRIPTOR_SECTION_UNCACHED(NonSecure) (TT_DESCRIPTOR_TYPE_SECTION | \
+ (NonSecure ? TT_DESCRIPTOR_SECTION_NS : 0) | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
+
+#define CPACR_CP_FULL_ACCESS 0x0FFFFFFF
+
+// NSACR - Non-Secure Access Control Register definitions
+#define NSACR_CP(cp) ((1 << (cp)) & 0x3FFF)
+#define NSACR_PLE 0
+#define NSACR_TL 0
+#define NSACR_NS_SMP 0
+
+// SCR - Secure Configuration Register definitions
+#define SCR_NS (1 << 0)
+#define SCR_IRQ (1 << 1)
+#define SCR_FIQ (1 << 2)
+#define SCR_EA (1 << 3)
+#define SCR_FW (1 << 4)
+#define SCR_AW (1 << 5)
+
+#endif // __ARM1176JZ_S_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM926EJ-S.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM926EJ-S.h
new file mode 100644
index 0000000..4ef1103
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ARM926EJ-S.h
@@ -0,0 +1,71 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+
+#ifndef __ARM926EJ_S_H__
+#define __ARM926EJ_S_H__
+
+// Domain Access Control Register
+#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
+
+#define TRANSLATION_TABLE_SIZE (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1)
+
+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
+
+// Translation table descriptor types
+#define TT_DESCRIPTOR_TYPE_MASK (3UL << 0)
+#define TT_DESCRIPTOR_TYPE_FAULT (0UL << 0)
+#define TT_DESCRIPTOR_TYPE_COARSE ((1UL << 0) | (1UL << 4))
+#define TT_DESCRIPTOR_TYPE_SECTION ((2UL << 0) | (1UL << 4))
+#define TT_DESCRIPTOR_TYPE_FINE ((3UL << 0) | (1UL << 4))
+
+// Section descriptor definitions
+#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
+
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK (3UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED (0UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_BUFFERED (1UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH (2UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK (3UL << 2)
+
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_MASK (3UL << 10)
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_NONE (1UL << 10)
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_ONLY (2UL << 10)
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE (3UL << 10)
+
+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
+#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0xF) << 5)
+
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
+
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK | \
+ TT_DESCRIPTOR_TYPE_SECTION)
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH | \
+ TT_DESCRIPTOR_TYPE_SECTION)
+#define TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED | \
+ TT_DESCRIPTOR_TYPE_SECTION)
+
+#endif // __ARM926EJ_S_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmAemV8.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmAemV8.h
new file mode 100644
index 0000000..a64a921
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmAemV8.h
@@ -0,0 +1,21 @@
+/** @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.
+
+**/
+
+#ifndef __ARM_AEM_V8_H__
+#define __ARM_AEM_V8_H__
+
+#include <Chipset/AArch64.h>
+
+#endif //__ARM_AEM_V8_H__
+
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmArchTimer.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmArchTimer.h
new file mode 100644
index 0000000..1caad3d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmArchTimer.h
@@ -0,0 +1,139 @@
+/** @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.
+*
+**/
+
+#ifndef __ARM_ARCH_TIMER_H_
+#define __ARM_ARCH_TIMER_H_
+
+UINTN
+EFIAPI
+ArmReadCntFrq (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntFrq (
+ UINTN FreqInHz
+ );
+
+UINT64
+EFIAPI
+ArmReadCntPct (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadCntkCtl (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntkCtl (
+ UINTN Val
+ );
+
+UINTN
+EFIAPI
+ArmReadCntpTval (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntpTval (
+ UINTN Val
+ );
+
+UINTN
+EFIAPI
+ArmReadCntpCtl (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntpCtl (
+ UINTN Val
+ );
+
+UINTN
+EFIAPI
+ArmReadCntvTval (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntvTval (
+ UINTN Val
+ );
+
+UINTN
+EFIAPI
+ArmReadCntvCtl (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntvCtl (
+ UINTN Val
+ );
+
+UINT64
+EFIAPI
+ArmReadCntvCt (
+ VOID
+ );
+
+UINT64
+EFIAPI
+ArmReadCntpCval (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntpCval (
+ UINT64 Val
+ );
+
+UINT64
+EFIAPI
+ArmReadCntvCval (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntvCval (
+ UINT64 Val
+ );
+
+UINT64
+EFIAPI
+ArmReadCntvOff (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCntvOff (
+ UINT64 Val
+ );
+
+#endif // __ARM_ARCH_TIMER_H_
+
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA15.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA15.h
new file mode 100644
index 0000000..5f71567
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA15.h
@@ -0,0 +1,25 @@
+/** @file
+
+ Copyright (c) 2012, 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 __ARM_CORTEX_A15_H__
+#define __ARM_CORTEX_A15_H__
+
+#include <Chipset/ArmV7.h>
+
+//
+// Cortex A15 feature bit definitions
+//
+#define A15_FEATURE_SMP (1<<6)
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA5x.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA5x.h
new file mode 100644
index 0000000..ba3d519
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA5x.h
@@ -0,0 +1,50 @@
+/** @file
+
+ Copyright (c) 2012-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 __ARM_CORTEX_A5x_H__
+#define __ARM_CORTEX_A5x_H__
+
+//
+// Cortex A5x feature bit definitions
+//
+#define A5X_FEATURE_SMP (1 << 6)
+
+//
+// Helper functions to access CPU Extended Control Register
+//
+UINT64
+EFIAPI
+ArmReadCpuExCr (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCpuExCr (
+ IN UINT64 Val
+ );
+
+VOID
+EFIAPI
+ArmSetCpuExCrBit (
+ IN UINT64 Bits
+ );
+
+VOID
+EFIAPI
+ArmUnsetCpuExCrBit (
+ IN UINT64 Bits
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA9.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA9.h
new file mode 100644
index 0000000..af9a300
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmCortexA9.h
@@ -0,0 +1,65 @@
+/** @file
+
+ Copyright (c) 2011, 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 __ARM_CORTEX_A9_H__
+#define __ARM_CORTEX_A9_H__
+
+#include <Chipset/ArmV7.h>
+
+//
+// Cortex A9 feature bit definitions
+//
+#define A9_FEATURE_PARITY (1<<9)
+#define A9_FEATURE_AOW (1<<8)
+#define A9_FEATURE_EXCL (1<<7)
+#define A9_FEATURE_SMP (1<<6)
+#define A9_FEATURE_FOZ (1<<3)
+#define A9_FEATURE_DPREF (1<<2)
+#define A9_FEATURE_HINT (1<<1)
+#define A9_FEATURE_FWD (1<<0)
+
+//
+// Cortex A9 Watchdog
+//
+#define ARM_A9_WATCHDOG_REGION 0x600
+
+#define ARM_A9_WATCHDOG_LOAD_REGISTER 0x20
+#define ARM_A9_WATCHDOG_CONTROL_REGISTER 0x28
+
+#define ARM_A9_WATCHDOG_WATCHDOG_MODE (1 << 3)
+#define ARM_A9_WATCHDOG_TIMER_MODE (0 << 3)
+#define ARM_A9_WATCHDOG_SINGLE_SHOT (0 << 1)
+#define ARM_A9_WATCHDOG_AUTORELOAD (1 << 1)
+#define ARM_A9_WATCHDOG_ENABLE 1
+
+//
+// SCU register offsets & masks
+//
+#define A9_SCU_CONTROL_OFFSET 0x0
+#define A9_SCU_CONFIG_OFFSET 0x4
+#define A9_SCU_INVALL_OFFSET 0xC
+#define A9_SCU_FILT_START_OFFSET 0x40
+#define A9_SCU_FILT_END_OFFSET 0x44
+#define A9_SCU_SACR_OFFSET 0x50
+#define A9_SCU_SSACR_OFFSET 0x54
+
+
+UINTN
+EFIAPI
+ArmGetScuBaseAddress (
+ VOID
+ );
+
+#endif
+
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7.h
new file mode 100644
index 0000000..ceb3217
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7.h
@@ -0,0 +1,127 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARM_V7_H__
+#define __ARM_V7_H__
+
+#include <Chipset/ArmV7Mmu.h>
+#include <Chipset/ArmArchTimer.h>
+
+// ARM Interrupt ID in Exception Table
+#define ARM_ARCH_EXCEPTION_IRQ EXCEPT_ARM_IRQ
+
+// ID_PFR1 - ARM Processor Feature Register 1 definitions
+#define ARM_PFR1_SEC (0xFUL << 4)
+#define ARM_PFR1_TIMER (0xFUL << 16)
+#define ARM_PFR1_GIC (0xFUL << 28)
+
+// Domain Access Control Register
+#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
+
+// CPSR - Coprocessor Status Register definitions
+#define CPSR_MODE_USER 0x10
+#define CPSR_MODE_FIQ 0x11
+#define CPSR_MODE_IRQ 0x12
+#define CPSR_MODE_SVC 0x13
+#define CPSR_MODE_ABORT 0x17
+#define CPSR_MODE_HYP 0x1A
+#define CPSR_MODE_UNDEFINED 0x1B
+#define CPSR_MODE_SYSTEM 0x1F
+#define CPSR_MODE_MASK 0x1F
+#define CPSR_ASYNC_ABORT (1 << 8)
+#define CPSR_IRQ (1 << 7)
+#define CPSR_FIQ (1 << 6)
+
+
+// CPACR - Coprocessor Access Control Register definitions
+#define CPACR_CP_DENIED(cp) 0x00
+#define CPACR_CP_PRIV(cp) ((0x1 << ((cp) << 1)) & 0x0FFFFFFF)
+#define CPACR_CP_FULL(cp) ((0x3 << ((cp) << 1)) & 0x0FFFFFFF)
+#define CPACR_ASEDIS (1 << 31)
+#define CPACR_D32DIS (1 << 30)
+#define CPACR_CP_FULL_ACCESS 0x0FFFFFFF
+
+// NSACR - Non-Secure Access Control Register definitions
+#define NSACR_CP(cp) ((1 << (cp)) & 0x3FFF)
+#define NSACR_NSD32DIS (1 << 14)
+#define NSACR_NSASEDIS (1 << 15)
+#define NSACR_PLE (1 << 16)
+#define NSACR_TL (1 << 17)
+#define NSACR_NS_SMP (1 << 18)
+#define NSACR_RFR (1 << 19)
+
+// SCR - Secure Configuration Register definitions
+#define SCR_NS (1 << 0)
+#define SCR_IRQ (1 << 1)
+#define SCR_FIQ (1 << 2)
+#define SCR_EA (1 << 3)
+#define SCR_FW (1 << 4)
+#define SCR_AW (1 << 5)
+
+// MIDR - Main ID Register definitions
+#define ARM_CPU_TYPE_MASK 0xFFF
+#define ARM_CPU_TYPE_AEMv8 0xD0F
+#define ARM_CPU_TYPE_A53 0xD03
+#define ARM_CPU_TYPE_A57 0xD07
+#define ARM_CPU_TYPE_A15 0xC0F
+#define ARM_CPU_TYPE_A9 0xC09
+#define ARM_CPU_TYPE_A5 0xC05
+
+#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) )
+#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF))
+
+#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 5)-1)
+
+VOID
+EFIAPI
+ArmEnableSWPInstruction (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadCbar (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadTpidrurw (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteTpidrurw (
+ UINTN Value
+ );
+
+UINT32
+EFIAPI
+ArmReadNsacr (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteNsacr (
+ IN UINT32 Nsacr
+ );
+
+#endif // __ARM_V7_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7Mmu.h b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7Mmu.h
new file mode 100644
index 0000000..24ab175
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Chipset/ArmV7Mmu.h
@@ -0,0 +1,231 @@
+/** @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.
+*
+**/
+
+#ifndef __ARMV7_MMU_H_
+#define __ARMV7_MMU_H_
+
+#define TTBR_NOT_OUTER_SHAREABLE BIT5
+#define TTBR_RGN_OUTER_NON_CACHEABLE 0
+#define TTBR_RGN_OUTER_WRITE_BACK_ALLOC BIT3
+#define TTBR_RGN_OUTER_WRITE_THROUGH BIT4
+#define TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC (BIT3|BIT4)
+#define TTBR_SHAREABLE BIT1
+#define TTBR_NON_SHAREABLE 0
+#define TTBR_INNER_CACHEABLE BIT0
+#define TTBR_NON_INNER_CACHEABLE BIT0
+#define TTBR_RGN_INNER_NON_CACHEABLE 0
+#define TTBR_RGN_INNER_WRITE_BACK_ALLOC BIT6
+#define TTBR_RGN_INNER_WRITE_THROUGH BIT0
+#define TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC (BIT0|BIT6)
+
+#define TTBR_WRITE_THROUGH_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )
+#define TTBR_WRITE_BACK_NO_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC )
+#define TTBR_NON_CACHEABLE ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE )
+#define TTBR_WRITE_BACK_ALLOC ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )
+
+
+#define TRANSLATION_TABLE_SECTION_COUNT 4096
+#define TRANSLATION_TABLE_SECTION_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)
+#define TRANSLATION_TABLE_SECTION_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)
+#define TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK (TRANSLATION_TABLE_SECTION_ALIGNMENT - 1)
+
+#define TRANSLATION_TABLE_PAGE_COUNT 256
+#define TRANSLATION_TABLE_PAGE_SIZE (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)
+#define TRANSLATION_TABLE_PAGE_ALIGNMENT (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)
+#define TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK (TRANSLATION_TABLE_PAGE_ALIGNMENT - 1)
+
+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
+
+// Translation table descriptor types
+#define TT_DESCRIPTOR_SECTION_TYPE_MASK ((1UL << 18) | (3UL << 0))
+#define TT_DESCRIPTOR_SECTION_TYPE_FAULT (0UL << 0)
+#define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE (1UL << 0)
+#define TT_DESCRIPTOR_SECTION_TYPE_SECTION ((0UL << 18) | (2UL << 0))
+#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))
+#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE)
+
+// Translation table descriptor types
+#define TT_DESCRIPTOR_PAGE_TYPE_MASK (3UL << 0)
+#define TT_DESCRIPTOR_PAGE_TYPE_FAULT (0UL << 0)
+#define TT_DESCRIPTOR_PAGE_TYPE_PAGE (2UL << 0)
+#define TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN (3UL << 0)
+#define TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE (1UL << 0)
+
+// Section descriptor definitions
+#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
+
+#define TT_DESCRIPTOR_SECTION_NS_MASK (1UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS (1UL << 19)
+
+#define TT_DESCRIPTOR_SECTION_NG_MASK (1UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17)
+
+#define TT_DESCRIPTOR_PAGE_NG_MASK (1UL << 11)
+#define TT_DESCRIPTOR_PAGE_NG_GLOBAL (0UL << 11)
+#define TT_DESCRIPTOR_PAGE_NG_LOCAL (1UL << 11)
+
+#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16)
+
+#define TT_DESCRIPTOR_PAGE_S_MASK (1UL << 10)
+#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED (0UL << 10)
+#define TT_DESCRIPTOR_PAGE_S_SHARED (1UL << 10)
+
+#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_NO_NO ((0UL << 15) | (0UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_NO ((0UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RO ((0UL << 15) | (2UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_NO ((1UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (3UL << 10))
+
+#define TT_DESCRIPTOR_PAGE_AP_MASK ((1UL << 9) | (3UL << 4))
+#define TT_DESCRIPTOR_PAGE_AP_NO_NO ((0UL << 9) | (0UL << 4))
+#define TT_DESCRIPTOR_PAGE_AP_RW_NO ((0UL << 9) | (1UL << 4))
+#define TT_DESCRIPTOR_PAGE_AP_RW_RO ((0UL << 9) | (2UL << 4))
+#define TT_DESCRIPTOR_PAGE_AP_RW_RW ((0UL << 9) | (3UL << 4))
+#define TT_DESCRIPTOR_PAGE_AP_RO_NO ((1UL << 9) | (1UL << 4))
+#define TT_DESCRIPTOR_PAGE_AP_RO_RO ((1UL << 9) | (3UL << 4))
+
+#define TT_DESCRIPTOR_SECTION_XN_MASK (0x1UL << 4)
+#define TT_DESCRIPTOR_PAGE_XN_MASK (0x1UL << 0)
+#define TT_DESCRIPTOR_LARGEPAGE_XN_MASK (0x1UL << 15)
+
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK (1UL << 3)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE ((1UL << 12) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2))
+
+#define TT_DESCRIPTOR_PAGE_SIZE (0x00001000)
+
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK ((3UL << 6) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_PAGE_CACHEABLE_MASK (1UL << 3)
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 6) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 6) | (0UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 6) | (1UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 6) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE ((1UL << 6) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 6) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 6) | (0UL << 3) | (0UL << 2))
+
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_CACHEABLE ((1UL << 12) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2))
+
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK)
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK)
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc) ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK)
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc,IsLargePage) ((IsLargePage)? \
+ ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) << 11) & TT_DESCRIPTOR_LARGEPAGE_XN_MASK): \
+ ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_PAGE_XN_MASK))
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc,IsLargePage) (IsLargePage? \
+ (((Desc) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK): \
+ (((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))))
+
+#define TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(Desc) ((((Desc) & TT_DESCRIPTOR_PAGE_AP_MASK) << 6) & TT_DESCRIPTOR_SECTION_AP_MASK)
+
+#define TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(Desc,IsLargePage) (IsLargePage? \
+ (((Desc) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK): \
+ (((((Desc) & (0x3 << 6)) << 6) | (Desc & (0x3 << 2)))))
+
+#define TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK (TT_DESCRIPTOR_SECTION_NS_MASK | TT_DESCRIPTOR_SECTION_NG_MASK | \
+ TT_DESCRIPTOR_SECTION_S_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | \
+ TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK)
+
+#define TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK (TT_DESCRIPTOR_PAGE_NG_MASK | TT_DESCRIPTOR_PAGE_S_MASK | \
+ TT_DESCRIPTOR_PAGE_AP_MASK | TT_DESCRIPTOR_PAGE_XN_MASK | \
+ TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK)
+
+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
+#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5)
+
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
+#define TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK (0xFFFFFC00)
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
+#define TT_DESCRIPTOR_SECTION_BASE_SHIFT 20
+
+#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK (0xFFFFF000)
+#define TT_DESCRIPTOR_PAGE_INDEX_MASK (0x000FF000)
+#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a) ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK)
+#define TT_DESCRIPTOR_PAGE_BASE_SHIFT 12
+
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
+ ((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
+ ((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
+#define TT_DESCRIPTOR_SECTION_DEVICE(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
+ ((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
+#define TT_DESCRIPTOR_SECTION_UNCACHED(NonSecure) (TT_DESCRIPTOR_SECTION_TYPE_SECTION | \
+ ((NonSecure) ? TT_DESCRIPTOR_SECTION_NS : 0) | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
+
+#define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
+ TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
+ TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
+ TT_DESCRIPTOR_PAGE_AP_RW_RW | \
+ TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC)
+#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
+ TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
+ TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
+ TT_DESCRIPTOR_PAGE_AP_RW_RW | \
+ TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
+#define TT_DESCRIPTOR_PAGE_DEVICE (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
+ TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
+ TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
+ TT_DESCRIPTOR_PAGE_AP_RW_RW | \
+ TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE)
+#define TT_DESCRIPTOR_PAGE_UNCACHED (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \
+ TT_DESCRIPTOR_PAGE_NG_GLOBAL | \
+ TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \
+ TT_DESCRIPTOR_PAGE_AP_RW_RW | \
+ TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE)
+
+UINT32
+ConvertSectionAttributesToPageAttributes (
+ IN UINT32 SectionAttributes,
+ IN BOOLEAN IsLargePage
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Guid/ArmMpCoreInfo.h b/uefi/linaro-edk2/ArmPkg/Include/Guid/ArmMpCoreInfo.h
new file mode 100644
index 0000000..07dec5d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Guid/ArmMpCoreInfo.h
@@ -0,0 +1,66 @@
+/** @file
+*
+* Copyright (c) 2011, 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 __ARM_MP_CORE_INFO_GUID_H_
+#define __ARM_MP_CORE_INFO_GUID_H_
+
+#define MAX_CPUS_PER_MPCORE_SYSTEM 0x04
+#define SCU_CONFIG_REG_OFFSET 0x04
+#define MPIDR_U_BIT_MASK 0x40000000
+
+typedef struct {
+ UINT32 ClusterId;
+ UINT32 CoreId;
+
+ // MP Core Mailbox
+ EFI_PHYSICAL_ADDRESS MailboxSetAddress;
+ EFI_PHYSICAL_ADDRESS MailboxGetAddress;
+ EFI_PHYSICAL_ADDRESS MailboxClearAddress;
+ UINT64 MailboxClearValue;
+} ARM_CORE_INFO;
+
+typedef struct{
+ UINT64 Signature;
+ UINT32 Length;
+ UINT32 Revision;
+ UINT64 OemId;
+ UINT64 OemTableId;
+ UINTN OemRevision;
+ UINTN CreatorId;
+ UINTN CreatorRevision;
+ EFI_GUID Identifier;
+ UINTN DataLen;
+} ARM_PROCESSOR_TABLE_HEADER;
+
+typedef struct {
+ ARM_PROCESSOR_TABLE_HEADER Header;
+ UINTN NumberOfEntries;
+ ARM_CORE_INFO *ArmCpus;
+} ARM_PROCESSOR_TABLE;
+
+
+#define ARM_MP_CORE_INFO_GUID \
+ { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} }
+
+#define EFI_ARM_PROCESSOR_TABLE_SIGNATURE SIGNATURE_64 ('C', 'P', 'U', 'T', 'A', 'B', 'L', 'E')
+#define EFI_ARM_PROCESSOR_TABLE_REVISION 0x00010000 //1.0
+#define EFI_ARM_PROCESSOR_TABLE_OEM_ID SIGNATURE_64('A','R','M',' ', 'L', 't', 'd', ' ')
+#define EFI_ARM_PROCESSOR_TABLE_OEM_TABLE_ID SIGNATURE_64('V', 'E', 'R', 'S', 'A', 'T', 'I', 'L')
+#define EFI_ARM_PROCESSOR_TABLE_OEM_REVISION 0x00000001
+#define EFI_ARM_PROCESSOR_TABLE_CREATOR_ID 0xA5A5A5A5
+#define EFI_ARM_PROCESSOR_TABLE_CREATOR_REVISION 0x01000001
+
+extern EFI_GUID gArmMpCoreInfoGuid;
+
+#endif /* MPCOREINFO_H_ */
diff --git a/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmStdSmc.h b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
new file mode 100644
index 0000000..593a3ce
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmStdSmc.h
@@ -0,0 +1,96 @@
+/** @file
+*
+* Copyright (c) 2012-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 __ARM_STD_SMC_H__
+#define __ARM_STD_SMC_H__
+
+/*
+ * SMC function IDs for Standard Service queries
+ */
+
+#define ARM_SMC_ID_STD_CALL_COUNT 0x8400ff00
+#define ARM_SMC_ID_STD_UID 0x8400ff01
+/* 0x8400ff02 is reserved */
+#define ARM_SMC_ID_STD_REVISION 0x8400ff03
+
+/*
+ * The 'Standard Service Call UID' is supposed to return the Standard
+ * Service UUID. This is a 128-bit value.
+ */
+#define ARM_SMC_STD_UUID0 0x108d905b
+#define ARM_SMC_STD_UUID1 0x47e8f863
+#define ARM_SMC_STD_UUID2 0xfbc02dae
+#define ARM_SMC_STD_UUID3 0xe2f64156
+
+/*
+ * ARM Standard Service Calls revision numbers
+ * The current revision is: 0.1
+ */
+#define ARM_SMC_STD_REVISION_MAJOR 0x0
+#define ARM_SMC_STD_REVISION_MINOR 0x1
+
+/*
+ * Power State Coordination Interface (PSCI) calls cover a subset of the
+ * Standard Service Call range.
+ * The list below is not exhaustive.
+ */
+#define ARM_SMC_ID_PSCI_VERSION 0x84000000
+#define ARM_SMC_ID_PSCI_CPU_SUSPEND_AARCH64 0xc4000001
+#define ARM_SMC_ID_PSCI_CPU_SUSPEND_AARCH32 0x84000001
+#define ARM_SMC_ID_PSCI_CPU_OFF 0x84000002
+#define ARM_SMC_ID_PSCI_CPU_ON_AARCH64 0xc4000003
+#define ARM_SMC_ID_PSCI_CPU_ON_AARCH32 0x84000003
+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_AARCH64 0xc4000004
+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_AARCH32 0x84000004
+#define ARM_SMC_ID_PSCI_MIGRATE_AARCH64 0xc4000005
+#define ARM_SMC_ID_PSCI_MIGRATE_AARCH32 0x84000005
+#define ARM_SMC_ID_PSCI_SYSTEM_OFF 0x84000008
+#define ARM_SMC_ID_PSCI_SYSTEM_RESET 0x84000009
+
+/* The current PSCI version is: 0.2 */
+#define ARM_SMC_PSCI_VERSION_MAJOR 0
+#define ARM_SMC_PSCI_VERSION_MINOR 2
+#define ARM_SMC_PSCI_VERSION \
+ ((ARM_SMC_PSCI_VERSION_MAJOR << 16) | ARM_SMC_PSCI_VERSION_MINOR)
+
+/* PSCI return error codes */
+#define ARM_SMC_PSCI_RET_SUCCESS 0
+#define ARM_SMC_PSCI_RET_NOT_SUPPORTED -1
+#define ARM_SMC_PSCI_RET_INVALID_PARAMS -2
+#define ARM_SMC_PSCI_RET_DENIED -3
+#define ARM_SMC_PSCI_RET_ALREADY_ON -4
+#define ARM_SMC_PSCI_RET_ON_PENDING -5
+#define ARM_SMC_PSCI_RET_INTERN_FAIL -6
+#define ARM_SMC_PSCI_RET_NOT_PRESENT -7
+#define ARM_SMC_PSCI_RET_DISABLED -8
+
+#define ARM_SMC_PSCI_TARGET_CPU32(Aff2, Aff1, Aff0) \
+ ((((Aff2) & 0xFF) << 16) | (((Aff1) & 0xFF) << 8) | ((Aff0) & 0xFF))
+
+#define ARM_SMC_PSCI_TARGET_CPU64(Aff3, Aff2, Aff1, Aff0) \
+ ((((Aff3) & 0xFFULL) << 32) | (((Aff2) & 0xFF) << 16) | (((Aff1) & 0xFF) << 8) | ((Aff0) & 0xFF))
+
+#define ARM_SMC_PSCI_TARGET_GET_AFF0(TargetId) ((TargetId) & 0xFF)
+#define ARM_SMC_PSCI_TARGET_GET_AFF1(TargetId) (((TargetId) >> 8) & 0xFF)
+
+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_0 0
+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_1 1
+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_2 2
+#define ARM_SMC_ID_PSCI_AFFINITY_LEVEL_3 3
+
+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_ON 0
+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_OFF 1
+#define ARM_SMC_ID_PSCI_AFFINITY_INFO_ON_PENDING 2
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h
new file mode 100644
index 0000000..71b4327
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/IndustryStandard/ArmTrustZoneSmc.h
@@ -0,0 +1,161 @@
+/** @file
+*
+* Copyright (c) 2012-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.
+*
+**/
+
+#ifndef __ARM_TRUSTZONE_SMC_H__
+#define __ARM_TRUSTZONE_SMC_H__
+
+#define ARM_TRUSTZONE_UID_4LETTERID 0x1
+#define ARM_TRUSTZONE_UID_MD5 0x2
+
+#define ARM_TRUSTZONE_ARM_UID 0x40524d48 // "ARMH"
+
+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,Region) (((UINTN)(Rx) >= (UINTN)ARM_TRUSTZONE_##Region##_SMC_ID_START) && ((UINTN)(Rx) <= (UINTN)ARM_TRUSTZONE_##Region##_SMC_ID_END))
+
+#define IS_ARM_TRUSTZONE_DEPRECIATED_SMC(Rx) ((UINTN)(Rx) <= (UINTN)ARM_TRUSTZONE_DEPRECIATED_SMC_ID_END)
+#define IS_ARM_TRUSTZONE_TRUSTED_OS_SMC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,TRUSTED_OS)
+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,ARM_FAST)
+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,SIP_FAST)
+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,ODM_FAST)
+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,OEM_FAST)
+#define IS_ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,TRUSTED_USER_FAST)
+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC(Rx,TRUSTED_OS_FAST)
+
+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,Region) ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_PRESENCE)
+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,Region) (((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID) || \
+ ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+1) || \
+ ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+2) || \
+ ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+3) || \
+ ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_UID+4))
+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,Region) (((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_REVISION) || \
+ ((Rx) == ARM_TRUSTZONE_##Region##_SMC_ID_REVISION+1))
+#define IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,Region) (((Rx) >= ARM_TRUSTZONE_##Region##_SMC_ID_RPC_START) && \
+ ((Rx) <= ARM_TRUSTZONE_##Region##_SMC_ID_RPC_END))
+
+#define ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,Region) ((Rx) - ARM_TRUSTZONE_##Region##_SMC_ID_UID)
+#define ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,Region) ((Rx) - ARM_TRUSTZONE_##Region##_SMC_ID_REVISION)
+#define ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,Region) ((Rx) - ARM_TRUSTZONE_##Region##_SMC_ID_RPC_START)
+
+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_RPC_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,TRUSTED_OS)
+
+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,ARM_FAST)
+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,ARM_FAST)
+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_REVISION(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,ARM_FAST)
+#define IS_ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,ARM_FAST)
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,ARM_FAST)
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_REVISION_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,ARM_FAST)
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,ARM_FAST)
+
+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_PRESENCE(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,ODM_FAST)
+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_UID(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,ODM_FAST)
+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_REVISION(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,ODM_FAST)
+#define IS_ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,ODM_FAST)
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_UID_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,ODM_FAST)
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_REVISION_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,ODM_FAST)
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,ODM_FAST)
+
+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_PRESENCE(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,OEM_FAST)
+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_UID(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,OEM_FAST)
+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_REVISION(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,OEM_FAST)
+#define IS_ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,OEM_FAST)
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_UID_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,OEM_FAST)
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_REVISION_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,OEM_FAST)
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,OEM_FAST)
+
+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_PRESENCE(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,SIP_FAST)
+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_UID(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,SIP_FAST)
+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_REVISION(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,SIP_FAST)
+#define IS_ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,SIP_FAST)
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_UID_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,SIP_FAST)
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_REVISION_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,SIP_FAST)
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,SIP_FAST)
+
+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_RPC_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,TRUSTED_USER_FAST)
+
+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_PRESENCE(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_PRESENCE(Rx,TRUSTED_OS_FAST)
+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_UID(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID(Rx,TRUSTED_OS_FAST)
+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_REVISION(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION(Rx,TRUSTED_OS_FAST)
+#define IS_ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC(Rx) IS_ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC(Rx,TRUSTED_OS_FAST)
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_UID_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_UID_INDEX(Rx,TRUSTED_OS_FAST)
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_REVISION_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_REVISION_INDEX(Rx,TRUSTED_OS_FAST)
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC_INDEX(Rx) ARM_TRUSTZONE_SUPPORTED_SMC_ID_RPC_INDEX(Rx,TRUSTED_OS_FAST)
+
+
+#define ARM_TRUSTZONE_DEPRECIATED_SMC_ID_START 0x00000000
+#define ARM_TRUSTZONE_DEPRECIATED_SMC_ID_END 0x01FFFFFF
+
+
+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_START 0x02000000
+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_END 0x1FFFFFFF
+
+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_RPC_START 0x02000000
+#define ARM_TRUSTZONE_TRUSTED_OS_SMC_ID_RPC_END 0x1FFFFFFF
+
+
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_START 0x80000000
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_END 0x80FFFFFF
+
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC_START 0x80000000
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_RPC_END 0x80FFFEFF
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_PRESENCE 0x80FFFF00
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_UID 0x80FFFF10
+#define ARM_TRUSTZONE_ARM_FAST_SMC_ID_REVISION 0x80FFFF20
+
+
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_START 0x81000000
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_END 0x81FFFFFF
+
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC_START 0x81000000
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_RPC_END 0x81FFFEFF
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_PRESENCE 0x81FFFF00
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_UID 0x81FFFF10
+#define ARM_TRUSTZONE_SIP_FAST_SMC_ID_REVISION 0x81FFFF20
+
+
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_START 0x82000000
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_END 0x82FFFFFF
+
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC_START 0x82000000
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_RPC_END 0x82FFFEFF
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_PRESENCE 0x82FFFF00
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_UID 0x82FFFF10
+#define ARM_TRUSTZONE_ODM_FAST_SMC_ID_REVISION 0x82FFFF20
+
+
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_START 0x83000000
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_END 0x83FFFFFF
+
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC_START 0x83000000
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_RPC_END 0x83FFFEFF
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_PRESENCE 0x83FFFF00
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_UID 0x83FFFF10
+#define ARM_TRUSTZONE_OEM_FAST_SMC_ID_REVISION 0x83FFFF20
+
+
+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_START 0xF0000000
+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_END 0xF1FFFFFF
+
+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_RPC_START 0xF0000000
+#define ARM_TRUSTZONE_TRUSTED_USER_FAST_SMC_ID_RPC_END 0xF1FFFEFF
+
+
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_START 0xF2000000
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_END 0xFFFFFFFF
+
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC_START 0xF2000000
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_RPC_END 0xFFFFFEFF
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_PRESENCE 0xF2FFFF00
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_UID 0xF2FFFF10
+#define ARM_TRUSTZONE_TRUSTED_OS_FAST_SMC_ID_REVISION 0xF2FFFF20
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmArchTimer.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmArchTimer.h
new file mode 100644
index 0000000..876c1f6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmArchTimer.h
@@ -0,0 +1,55 @@
+/** @file
+
+ 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.
+
+**/
+
+#ifndef __ARM_ARCH_TIMER_H__
+#define __ARM_ARCH_TIMER_H__
+
+#define ARM_ARCH_TIMER_ENABLE (1 << 0)
+#define ARM_ARCH_TIMER_IMASK (1 << 1)
+#define ARM_ARCH_TIMER_ISTATUS (1 << 2)
+
+typedef enum {
+ CntFrq = 0,
+ CntPct,
+ CntkCtl,
+ CntpTval,
+ CntpCtl,
+ CntvTval,
+ CntvCtl,
+ CntvCt,
+ CntpCval,
+ CntvCval,
+ CntvOff,
+ CnthCtl,
+ CnthpTval,
+ CnthpCtl,
+ CnthpCval,
+ RegMaximum
+} ARM_ARCH_TIMER_REGS;
+
+VOID
+EFIAPI
+ArmArchTimerReadReg (
+ IN ARM_ARCH_TIMER_REGS Reg,
+ OUT VOID *DstBuf
+ );
+
+VOID
+EFIAPI
+ArmArchTimerWriteReg (
+ IN ARM_ARCH_TIMER_REGS Reg,
+ IN VOID *SrcBuf
+ );
+
+#endif // __ARM_ARCH_TIMER_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmCpuLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmCpuLib.h
new file mode 100644
index 0000000..0c41599
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmCpuLib.h
@@ -0,0 +1,28 @@
+/** @file
+
+ Copyright (c) 2011-2012, 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 __ARMCPU_LIB__
+#define __ARMCPU_LIB__
+
+VOID
+ArmCpuSetup (
+ IN UINTN MpId
+ );
+
+VOID
+ArmCpuSetupSmpNonSecure (
+ IN UINTN MpId
+ );
+
+#endif // __ARMCPU_LIB__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmDisassemblerLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmDisassemblerLib.h
new file mode 100644
index 0000000..d6a493f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmDisassemblerLib.h
@@ -0,0 +1,43 @@
+/** @file
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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.
+
+**/
+
+#ifndef __ARM_DISASSEBLER_LIB_H__
+#define __ARM_DISASSEBLER_LIB_H__
+
+/**
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
+ point to next instructin.
+
+ We cheat and only decode instructions that access
+ memory. If the instruction is not found we dump the instruction in hex.
+
+ @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
+ @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
+ @param Extended TRUE dump hex for instruction too.
+ @param ItBlock Size of IT Block
+ @param Buf Buffer to sprintf disassembly into.
+ @param Size Size of Buf in bytes.
+
+**/
+VOID
+DisassembleInstruction (
+ IN UINT8 **OpCodePtr,
+ IN BOOLEAN Thumb,
+ IN BOOLEAN Extended,
+ IN OUT UINT32 *ItBlock,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGenericTimerCounterLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGenericTimerCounterLib.h
new file mode 100644
index 0000000..805025b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGenericTimerCounterLib.h
@@ -0,0 +1,85 @@
+/** @file
+
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2014, Linaro 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.
+
+**/
+
+#ifndef __ARM_GENERIC_TIMER_COUNTER_LIB_H__
+#define __ARM_GENERIC_TIMER_COUNTER_LIB_H__
+
+VOID
+EFIAPI
+ArmGenericTimerEnableTimer (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGenericTimerDisableTimer (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerFreq (
+ IN UINTN FreqInHz
+ );
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerFreq (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerVal (
+ IN UINTN Value
+ );
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerVal (
+ VOID
+ );
+
+UINT64
+EFIAPI
+ArmGenericTimerGetSystemCount (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerCtrlReg (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerCtrlReg (
+ UINTN Value
+ );
+
+UINT64
+EFIAPI
+ArmGenericTimerGetCompareVal (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmGenericTimerSetCompareVal (
+ IN UINT64 Value
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGicLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGicLib.h
new file mode 100644
index 0000000..e2a4818
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmGicLib.h
@@ -0,0 +1,234 @@
+/** @file
+*
+* Copyright (c) 2011-2015, 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 __ARMGIC_H
+#define __ARMGIC_H
+
+//
+// GIC definitions
+//
+typedef enum {
+ ARM_GIC_ARCH_REVISION_2,
+ ARM_GIC_ARCH_REVISION_3
+} ARM_GIC_ARCH_REVISION;
+
+//
+// GIC Distributor
+//
+#define ARM_GIC_ICDDCR 0x000 // Distributor Control Register
+#define ARM_GIC_ICDICTR 0x004 // Interrupt Controller Type Register
+#define ARM_GIC_ICDIIDR 0x008 // Implementer Identification Register
+
+// Each reg base below repeats for Number of interrupts / 4 (see GIC spec)
+#define ARM_GIC_ICDISR 0x080 // Interrupt Security Registers
+#define ARM_GIC_ICDISER 0x100 // Interrupt Set-Enable Registers
+#define ARM_GIC_ICDICER 0x180 // Interrupt Clear-Enable Registers
+#define ARM_GIC_ICDSPR 0x200 // Interrupt Set-Pending Registers
+#define ARM_GIC_ICDICPR 0x280 // Interrupt Clear-Pending Registers
+#define ARM_GIC_ICDABR 0x300 // Active Bit Registers
+
+// Each reg base below repeats for Number of interrupts / 4
+#define ARM_GIC_ICDIPR 0x400 // Interrupt Priority Registers
+
+// Each reg base below repeats for Number of interrupts
+#define ARM_GIC_ICDIPTR 0x800 // Interrupt Processor Target Registers
+#define ARM_GIC_ICDICFR 0xC00 // Interrupt Configuration Registers
+
+#define ARM_GIC_ICDPPISR 0xD00 // PPI Status register
+
+// just one of these
+#define ARM_GIC_ICDSGIR 0xF00 // Software Generated Interrupt Register
+
+// GICv3 specific registers
+#define ARM_GICD_IROUTER 0x6100 // Interrupt Routing Registers
+
+// the Affinity Routing Enable (ARE) bit in GICD_CTLR
+#define ARM_GIC_ICDDCR_ARE (1 << 4)
+
+//
+// GIC Redistributor
+//
+
+#define ARM_GICR_CTLR_FRAME_SIZE SIZE_64KB
+#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB
+
+// GIC Redistributor Control frame
+#define ARM_GICR_TYPER 0x0008 // Redistributor Type Register
+
+// GIC SGI & PPI Redistributor frame
+#define ARM_GICR_ISENABLER 0x0100 // Interrupt Set-Enable Registers
+#define ARM_GICR_ICENABLER 0x0180 // Interrupt Clear-Enable Registers
+
+//
+// GIC Cpu interface
+//
+#define ARM_GIC_ICCICR 0x00 // CPU Interface Control Register
+#define ARM_GIC_ICCPMR 0x04 // Interrupt Priority Mask Register
+#define ARM_GIC_ICCBPR 0x08 // Binary Point Register
+#define ARM_GIC_ICCIAR 0x0C // Interrupt Acknowledge Register
+#define ARM_GIC_ICCEIOR 0x10 // End Of Interrupt Register
+#define ARM_GIC_ICCRPR 0x14 // Running Priority Register
+#define ARM_GIC_ICCPIR 0x18 // Highest Pending Interrupt Register
+#define ARM_GIC_ICCABPR 0x1C // Aliased Binary Point Register
+#define ARM_GIC_ICCIIDR 0xFC // Identification Register
+
+#define ARM_GIC_ICDSGIR_FILTER_TARGETLIST 0x0
+#define ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE 0x1
+#define ARM_GIC_ICDSGIR_FILTER_ITSELF 0x2
+
+// Bit-masks to configure the CPU Interface Control register
+#define ARM_GIC_ICCICR_ENABLE_SECURE 0x01
+#define ARM_GIC_ICCICR_ENABLE_NS 0x02
+#define ARM_GIC_ICCICR_ACK_CTL 0x04
+#define ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ 0x08
+#define ARM_GIC_ICCICR_USE_SBPR 0x10
+
+// Bit Mask for GICC_IIDR
+#define ARM_GIC_ICCIIDR_GET_PRODUCT_ID(IccIidr) (((IccIidr) >> 20) & 0xFFF)
+#define ARM_GIC_ICCIIDR_GET_ARCH_VERSION(IccIidr) (((IccIidr) >> 16) & 0xF)
+#define ARM_GIC_ICCIIDR_GET_REVISION(IccIidr) (((IccIidr) >> 12) & 0xF)
+#define ARM_GIC_ICCIIDR_GET_IMPLEMENTER(IccIidr) ((IccIidr) & 0xFFF)
+
+// Bit Mask for
+#define ARM_GIC_ICCIAR_ACKINTID 0x3FF
+
+ARM_GIC_ARCH_REVISION
+EFIAPI
+ArmGicGetSupportedArchRevision (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmGicGetInterfaceIdentification (
+ IN INTN GicInterruptInterfaceBase
+ );
+
+//
+// GIC Secure interfaces
+//
+VOID
+EFIAPI
+ArmGicSetupNonSecure (
+ IN UINTN MpId,
+ IN INTN GicDistributorBase,
+ IN INTN GicInterruptInterfaceBase
+ );
+
+VOID
+EFIAPI
+ArmGicSetSecureInterrupts (
+ IN UINTN GicDistributorBase,
+ IN UINTN* GicSecureInterruptMask,
+ IN UINTN GicSecureInterruptMaskSize
+ );
+
+VOID
+EFIAPI
+ArmGicEnableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ );
+
+VOID
+EFIAPI
+ArmGicDisableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ );
+
+VOID
+EFIAPI
+ArmGicEnableDistributor (
+ IN INTN GicDistributorBase
+ );
+
+VOID
+EFIAPI
+ArmGicDisableDistributor (
+ IN INTN GicDistributorBase
+ );
+
+UINTN
+EFIAPI
+ArmGicGetMaxNumInterrupts (
+ IN INTN GicDistributorBase
+ );
+
+VOID
+EFIAPI
+ArmGicSendSgiTo (
+ IN INTN GicDistributorBase,
+ IN INTN TargetListFilter,
+ IN INTN CPUTargetList,
+ IN INTN SgiId
+ );
+
+/*
+ * Acknowledge and return the value of the Interrupt Acknowledge Register
+ *
+ * InterruptId is returned separately from the register value because in
+ * the GICv2 the register value contains the CpuId and InterruptId while
+ * in the GICv3 the register value is only the InterruptId.
+ *
+ * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
+ * @param InterruptId InterruptId read from the Interrupt Acknowledge Register
+ *
+ * @retval value returned by the Interrupt Acknowledge Register
+ *
+ */
+UINTN
+EFIAPI
+ArmGicAcknowledgeInterrupt (
+ IN UINTN GicInterruptInterfaceBase,
+ OUT UINTN *InterruptId
+ );
+
+VOID
+EFIAPI
+ArmGicEndOfInterrupt (
+ IN UINTN GicInterruptInterfaceBase,
+ IN UINTN Source
+ );
+
+UINTN
+EFIAPI
+ArmGicSetPriorityMask (
+ IN INTN GicInterruptInterfaceBase,
+ IN INTN PriorityMask
+ );
+
+VOID
+EFIAPI
+ArmGicEnableInterrupt (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source
+ );
+
+VOID
+EFIAPI
+ArmGicDisableInterrupt (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source
+ );
+
+BOOLEAN
+EFIAPI
+ArmGicIsInterruptEnabled (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmHvcLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmHvcLib.h
new file mode 100644
index 0000000..4e9d1c4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmHvcLib.h
@@ -0,0 +1,46 @@
+/** @file
+*
+* Copyright (c) 2012-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 __ARM_HVC_LIB__
+#define __ARM_HVC_LIB__
+
+/**
+ * The size of the HVC arguments are different between AArch64 and AArch32.
+ * The native size is used for the arguments.
+ */
+typedef struct {
+ UINTN Arg0;
+ UINTN Arg1;
+ UINTN Arg2;
+ UINTN Arg3;
+ UINTN Arg4;
+ UINTN Arg5;
+ UINTN Arg6;
+ UINTN Arg7;
+} ARM_HVC_ARGS;
+
+/**
+ Trigger an HVC call
+
+ HVC calls can take up to 8 arguments and return up to 4 return values.
+ Therefore, the 4 first fields in the ARM_HVC_ARGS structure are used
+ for both input and output values.
+
+**/
+VOID
+ArmCallHvc (
+ IN OUT ARM_HVC_ARGS *Args
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmLib.h
new file mode 100644
index 0000000..9effb3e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmLib.h
@@ -0,0 +1,668 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011 - 2015, 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.
+
+**/
+
+#ifndef __ARM_LIB__
+#define __ARM_LIB__
+
+#include <Uefi/UefiBaseType.h>
+
+#ifdef MDE_CPU_ARM
+ #ifdef ARM_CPU_ARMv6
+ #include <Chipset/ARM1176JZ-S.h>
+ #else
+ #include <Chipset/ArmV7.h>
+ #endif
+#elif defined(MDE_CPU_AARCH64)
+ #include <Chipset/AArch64.h>
+#else
+ #error "Unknown chipset."
+#endif
+
+typedef enum {
+ ARM_CACHE_TYPE_WRITE_BACK,
+ ARM_CACHE_TYPE_UNKNOWN
+} ARM_CACHE_TYPE;
+
+typedef enum {
+ ARM_CACHE_ARCHITECTURE_UNIFIED,
+ ARM_CACHE_ARCHITECTURE_SEPARATE,
+ ARM_CACHE_ARCHITECTURE_UNKNOWN
+} ARM_CACHE_ARCHITECTURE;
+
+typedef struct {
+ ARM_CACHE_TYPE Type;
+ ARM_CACHE_ARCHITECTURE Architecture;
+ BOOLEAN DataCachePresent;
+ UINTN DataCacheSize;
+ UINTN DataCacheAssociativity;
+ UINTN DataCacheLineLength;
+ BOOLEAN InstructionCachePresent;
+ UINTN InstructionCacheSize;
+ UINTN InstructionCacheAssociativity;
+ UINTN InstructionCacheLineLength;
+} ARM_CACHE_INFO;
+
+/**
+ * The UEFI firmware must not use the ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_* attributes.
+ *
+ * The Non Secure memory attribute (ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_*) should only
+ * be used in Secure World to distinguished Secure to Non-Secure memory.
+ */
+typedef enum {
+ ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED = 0,
+ ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED,
+ ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK,
+ ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK,
+ ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH,
+ ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH,
+ ARM_MEMORY_REGION_ATTRIBUTE_DEVICE,
+ ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE
+} ARM_MEMORY_REGION_ATTRIBUTES;
+
+#define IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(attr) ((UINT32)(attr) & 1)
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS PhysicalBase;
+ EFI_VIRTUAL_ADDRESS VirtualBase;
+ UINT64 Length;
+ ARM_MEMORY_REGION_ATTRIBUTES Attributes;
+} ARM_MEMORY_REGION_DESCRIPTOR;
+
+typedef VOID (*CACHE_OPERATION)(VOID);
+typedef VOID (*LINE_OPERATION)(UINTN);
+
+//
+// ARM Processor Mode
+//
+typedef enum {
+ ARM_PROCESSOR_MODE_USER = 0x10,
+ ARM_PROCESSOR_MODE_FIQ = 0x11,
+ ARM_PROCESSOR_MODE_IRQ = 0x12,
+ ARM_PROCESSOR_MODE_SUPERVISOR = 0x13,
+ ARM_PROCESSOR_MODE_ABORT = 0x17,
+ ARM_PROCESSOR_MODE_HYP = 0x1A,
+ ARM_PROCESSOR_MODE_UNDEFINED = 0x1B,
+ ARM_PROCESSOR_MODE_SYSTEM = 0x1F,
+ ARM_PROCESSOR_MODE_MASK = 0x1F
+} ARM_PROCESSOR_MODE;
+
+//
+// ARM Cpu IDs
+//
+#define ARM_CPU_IMPLEMENTER_MASK (0xFFU << 24)
+#define ARM_CPU_IMPLEMENTER_ARMLTD (0x41U << 24)
+#define ARM_CPU_IMPLEMENTER_DEC (0x44U << 24)
+#define ARM_CPU_IMPLEMENTER_MOT (0x4DU << 24)
+#define ARM_CPU_IMPLEMENTER_QUALCOMM (0x51U << 24)
+#define ARM_CPU_IMPLEMENTER_MARVELL (0x56U << 24)
+
+#define ARM_CPU_PRIMARY_PART_MASK (0xFFF << 4)
+#define ARM_CPU_PRIMARY_PART_CORTEXA5 (0xC05 << 4)
+#define ARM_CPU_PRIMARY_PART_CORTEXA7 (0xC07 << 4)
+#define ARM_CPU_PRIMARY_PART_CORTEXA8 (0xC08 << 4)
+#define ARM_CPU_PRIMARY_PART_CORTEXA9 (0xC09 << 4)
+#define ARM_CPU_PRIMARY_PART_CORTEXA15 (0xC0F << 4)
+
+//
+// ARM MP Core IDs
+//
+#define ARM_CORE_AFF0 0xFF
+#define ARM_CORE_AFF1 (0xFF << 8)
+#define ARM_CORE_AFF2 (0xFF << 16)
+#define ARM_CORE_AFF3 (0xFFULL << 32)
+
+#define ARM_CORE_MASK ARM_CORE_AFF0
+#define ARM_CLUSTER_MASK ARM_CORE_AFF1
+#define GET_CORE_ID(MpId) ((MpId) & ARM_CORE_MASK)
+#define GET_CLUSTER_ID(MpId) (((MpId) & ARM_CLUSTER_MASK) >> 8)
+#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId))
+#define PRIMARY_CORE_ID (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK)
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+ VOID
+ );
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmCacheInformation (
+ OUT ARM_CACHE_INFO *CacheInfo
+ );
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmDataCacheSize (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+ VOID
+ );
+
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmIsArchTimerImplemented (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadIdPfr0 (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadIdPfr1 (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmCacheInfo (
+ VOID
+ );
+
+BOOLEAN
+EFIAPI
+ArmIsMpCore (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmInvalidateDataCache (
+ VOID
+ );
+
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmCleanDataCacheToPoU (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmInvalidateInstructionCache (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmInvalidateDataCacheEntryByMVA (
+ IN UINTN Address
+ );
+
+VOID
+EFIAPI
+ArmCleanDataCacheEntryByMVA (
+ IN UINTN Address
+ );
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCacheEntryByMVA (
+ IN UINTN Address
+ );
+
+VOID
+EFIAPI
+ArmInvalidateDataCacheEntryBySetWay (
+ IN UINTN SetWayFormat
+ );
+
+VOID
+EFIAPI
+ArmCleanDataCacheEntryBySetWay (
+ IN UINTN SetWayFormat
+ );
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCacheEntryBySetWay (
+ IN UINTN SetWayFormat
+ );
+
+VOID
+EFIAPI
+ArmEnableDataCache (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDisableDataCache (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableInstructionCache (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDisableInstructionCache (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableMmu (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDisableMmu (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableCachesAndMmu (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDisableCachesAndMmu (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableInterrupts (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmDisableInterrupts (
+ VOID
+ );
+
+BOOLEAN
+EFIAPI
+ArmGetInterruptState (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableAsynchronousAbort (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmDisableAsynchronousAbort (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableIrq (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmDisableIrq (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableFiq (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmDisableFiq (
+ VOID
+ );
+
+BOOLEAN
+EFIAPI
+ArmGetFiqState (
+ VOID
+ );
+
+/**
+ * Invalidate Data and Instruction TLBs
+ */
+VOID
+EFIAPI
+ArmInvalidateTlb (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmUpdateTranslationTableEntry (
+ IN VOID *TranslationTableEntry,
+ IN VOID *Mva
+ );
+
+VOID
+EFIAPI
+ArmSetDomainAccessControl (
+ IN UINT32 Domain
+ );
+
+VOID
+EFIAPI
+ArmSetTTBR0 (
+ IN VOID *TranslationTableBase
+ );
+
+VOID *
+EFIAPI
+ArmGetTTBR0BaseAddress (
+ VOID
+ );
+
+RETURN_STATUS
+EFIAPI
+ArmConfigureMmu (
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
+ OUT VOID **TranslationTableBase OPTIONAL,
+ OUT UINTN *TranslationTableSize OPTIONAL
+ );
+
+BOOLEAN
+EFIAPI
+ArmMmuEnabled (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmEnableBranchPrediction (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDisableBranchPrediction (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmSetLowVectors (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmSetHighVectors (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDrainWriteBuffer (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDataMemoryBarrier (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmDataSyncronizationBarrier (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmInstructionSynchronizationBarrier (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteVBar (
+ IN UINTN VectorBase
+ );
+
+UINTN
+EFIAPI
+ArmReadVBar (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteAuxCr (
+ IN UINT32 Bit
+ );
+
+UINT32
+EFIAPI
+ArmReadAuxCr (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmSetAuxCrBit (
+ IN UINT32 Bits
+ );
+
+VOID
+EFIAPI
+ArmUnsetAuxCrBit (
+ IN UINT32 Bits
+ );
+
+VOID
+EFIAPI
+ArmCallSEV (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmCallWFE (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmCallWFI (
+
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadMpidr (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadMidr (
+ VOID
+ );
+
+UINT32
+EFIAPI
+ArmReadCpacr (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCpacr (
+ IN UINT32 Access
+ );
+
+VOID
+EFIAPI
+ArmEnableVFP (
+ VOID
+ );
+
+/**
+ Get the Secure Configuration Register value
+
+ @return Value read from the Secure Configuration Register
+
+**/
+UINT32
+EFIAPI
+ArmReadScr (
+ VOID
+ );
+
+/**
+ Set the Secure Configuration Register
+
+ @param Value Value to write to the Secure Configuration Register
+
+**/
+VOID
+EFIAPI
+ArmWriteScr (
+ IN UINT32 Value
+ );
+
+UINT32
+EFIAPI
+ArmReadMVBar (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteMVBar (
+ IN UINT32 VectorMonitorBase
+ );
+
+UINT32
+EFIAPI
+ArmReadSctlr (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadHVBar (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteHVBar (
+ IN UINTN HypModeVectorBase
+ );
+
+
+//
+// Helper functions for accessing CPU ACTLR
+//
+
+UINTN
+EFIAPI
+ArmReadCpuActlr (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCpuActlr (
+ IN UINTN Val
+ );
+
+VOID
+EFIAPI
+ArmSetCpuActlrBit (
+ IN UINTN Bits
+ );
+
+VOID
+EFIAPI
+ArmUnsetCpuActlrBit (
+ IN UINTN Bits
+ );
+
+#endif // __ARM_LIB__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/ArmSmcLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmSmcLib.h
new file mode 100644
index 0000000..168e3bb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/ArmSmcLib.h
@@ -0,0 +1,46 @@
+/** @file
+*
+* Copyright (c) 2012-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 __ARM_SMC_LIB__
+#define __ARM_SMC_LIB__
+
+/**
+ * The size of the SMC arguments are different between AArch64 and AArch32.
+ * The native size is used for the arguments.
+ */
+typedef struct {
+ UINTN Arg0;
+ UINTN Arg1;
+ UINTN Arg2;
+ UINTN Arg3;
+ UINTN Arg4;
+ UINTN Arg5;
+ UINTN Arg6;
+ UINTN Arg7;
+} ARM_SMC_ARGS;
+
+/**
+ Trigger an SMC call
+
+ SMC calls can take up to 7 arguments and return up to 4 return values.
+ Therefore, the 4 first fields in the ARM_SMC_ARGS structure are used
+ for both input and output values.
+
+**/
+VOID
+ArmCallSmc (
+ IN OUT ARM_SMC_ARGS *Args
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/BdsLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/BdsLib.h
new file mode 100644
index 0000000..9fa6870
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/BdsLib.h
@@ -0,0 +1,225 @@
+/** @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.
+*
+**/
+
+#ifndef __BDS_ENTRY_H__
+#define __BDS_ENTRY_H__
+
+typedef UINT8* EFI_LOAD_OPTION;
+
+/**
+ This is defined by the UEFI specs, don't change it
+**/
+typedef struct {
+ UINT16 LoadOptionIndex;
+ EFI_LOAD_OPTION LoadOption;
+ UINTN LoadOptionSize;
+
+ UINT32 Attributes;
+ UINT16 FilePathListLength;
+ CHAR16 *Description;
+ EFI_DEVICE_PATH_PROTOCOL *FilePathList;
+
+ VOID* OptionalData;
+ UINTN OptionalDataSize;
+} BDS_LOAD_OPTION;
+
+/**
+ Connect a Device Path and return the handle of the driver that support this DevicePath
+
+ @param DevicePath Device Path of the File to connect
+ @param Handle Handle of the driver that support this DevicePath
+ @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath
+
+ @retval EFI_SUCCESS A driver that matches the Device Path has been found
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
+
+**/
+EFI_STATUS
+BdsConnectDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ );
+
+/**
+ Connect all DXE drivers
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsConnectAllDrivers (
+ VOID
+ );
+
+/**
+ Return the value of a global variable defined by its VariableName.
+ The variable must be defined with the VendorGuid gEfiGlobalVariableGuid.
+
+ @param VariableName A Null-terminated string that is the name of the vendor's
+ variable.
+ @param DefaultValue Value returned by the function if the variable does not exist
+ @param DataSize On input, the size in bytes of the return Data buffer.
+ On output the size of data returned in Data.
+ @param Value Value read from the UEFI Variable or copy of the default value
+ if the UEFI Variable does not exist
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+GetGlobalEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ );
+
+/**
+ Return the value of the variable defined by its VariableName and VendorGuid
+
+ @param VariableName A Null-terminated string that is the name of the vendor's
+ variable.
+ @param VendorGuid A unique identifier for the vendor.
+ @param DefaultValue Value returned by the function if the variable does not exist
+ @param DataSize On input, the size in bytes of the return Data buffer.
+ On output the size of data returned in Data.
+ @param Value Value read from the UEFI Variable or copy of the default value
+ if the UEFI Variable does not exist
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+GetEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN EFI_GUID* VendorGuid,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ );
+
+EFI_STATUS
+BootOptionFromLoadOptionIndex (
+ IN UINT16 LoadOptionIndex,
+ OUT BDS_LOAD_OPTION** BdsLoadOption
+ );
+
+EFI_STATUS
+BootOptionFromLoadOptionVariable (
+ IN CHAR16* BootVariableName,
+ OUT BDS_LOAD_OPTION** BdsLoadOption
+ );
+
+EFI_STATUS
+BootOptionToLoadOptionVariable (
+ IN BDS_LOAD_OPTION* BdsLoadOption
+ );
+
+UINT16
+BootOptionAllocateBootIndex (
+ VOID
+ );
+
+/**
+ Start a Linux kernel from a Device Path
+
+ @param LinuxKernel Device Path to the Linux Kernel
+ @param Parameters Linux kernel arguments
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsBootLinuxAtag (
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
+ IN CONST CHAR8* Arguments
+ );
+
+/**
+ Start a Linux kernel from a Device Path
+
+ @param LinuxKernel Device Path to the Linux Kernel
+ @param Parameters Linux kernel arguments
+ @param Fdt Device Path to the Flat Device Tree
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsBootLinuxFdt (
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
+ IN CONST CHAR8* Arguments,
+ IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
+ );
+
+/**
+ Start an EFI Application from a Device Path
+
+ @param ParentImageHandle Handle of the calling image
+ @param DevicePath Location of the EFI Application
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsStartEfiApplication (
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINTN LoadOptionsSize,
+ IN VOID* LoadOptions
+ );
+
+/**
+ Start an EFI Application from any Firmware Volume
+
+ @param EfiApp EFI Application Name
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsLoadApplication (
+ IN EFI_HANDLE ParentImageHandle,
+ IN CHAR16* EfiApp,
+ IN UINTN LoadOptionsSize,
+ IN VOID* LoadOptions
+ );
+
+EFI_STATUS
+BdsLoadImage (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *FileSize
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h
new file mode 100644
index 0000000..5c7d7e2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h
@@ -0,0 +1,31 @@
+/** @file
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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.
+
+**/
+
+#ifndef __DEFAULT_EXCEPTION_HANDLER_LIB_H__
+#define __DEFAULT_EXCEPTION_HANDLER_LIB_H__
+
+/**
+ This is the default action to take on an unexpected exception
+
+ @param ExceptionType Type of the exception
+ @param SystemContext Register state at the time of the Exception
+
+**/
+VOID
+DefaultExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/SemihostLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/SemihostLib.h
new file mode 100644
index 0000000..4a91593
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/SemihostLib.h
@@ -0,0 +1,138 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions copyright (c) 2011, 2012, 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.
+
+**/
+
+#ifndef __SEMIHOSTING_H__
+#define __SEMIHOSTING_H__
+
+/*
+ *
+ * Please refer to ARM RVDS 3.0 Compiler and Libraries Guide for more information
+ * about the semihosting interface.
+ *
+ */
+
+#define SEMIHOST_FILE_MODE_READ (0 << 2)
+#define SEMIHOST_FILE_MODE_WRITE (1 << 2)
+#define SEMIHOST_FILE_MODE_APPEND (2 << 2)
+#define SEMIHOST_FILE_MODE_UPDATE (1 << 1)
+#define SEMIHOST_FILE_MODE_BINARY (1 << 0)
+#define SEMIHOST_FILE_MODE_ASCII (0 << 0)
+
+BOOLEAN
+SemihostConnectionSupported (
+ VOID
+ );
+
+RETURN_STATUS
+SemihostFileOpen (
+ IN CHAR8 *FileName,
+ IN UINT32 Mode,
+ OUT UINTN *FileHandle
+ );
+
+RETURN_STATUS
+SemihostFileSeek (
+ IN UINTN FileHandle,
+ IN UINTN Offset
+ );
+
+RETURN_STATUS
+SemihostFileRead (
+ IN UINTN FileHandle,
+ IN OUT UINTN *Length,
+ OUT VOID *Buffer
+ );
+
+RETURN_STATUS
+SemihostFileWrite (
+ IN UINTN FileHandle,
+ IN OUT UINTN *Length,
+ IN VOID *Buffer
+ );
+
+RETURN_STATUS
+SemihostFileClose (
+ IN UINTN FileHandle
+ );
+
+RETURN_STATUS
+SemihostFileLength (
+ IN UINTN FileHandle,
+ OUT UINTN *Length
+ );
+
+/**
+ Get a temporary name for a file from the host running the debug agent.
+
+ @param[out] Buffer Pointer to the buffer where the temporary name has to
+ be stored
+ @param[in] Identifier File name identifier (integer in the range 0 to 255)
+ @param[in] Length Length of the buffer to store the temporary name
+
+ @retval RETURN_SUCCESS Temporary name returned
+ @retval RETURN_INVALID_PARAMETER Invalid buffer address
+ @retval RETURN_ABORTED Temporary name not returned
+
+**/
+RETURN_STATUS
+SemihostFileTmpName(
+ OUT VOID *Buffer,
+ IN UINT8 Identifier,
+ IN UINTN Length
+ );
+
+RETURN_STATUS
+SemihostFileRemove (
+ IN CHAR8 *FileName
+ );
+
+/**
+ Rename a specified file.
+
+ @param[in] FileName Name of the file to rename.
+ @param[in] NewFileName The new name of the file.
+
+ @retval RETURN_SUCCESS File Renamed
+ @retval RETURN_INVALID_PARAMETER Either the current or the new name is not specified
+ @retval RETURN_ABORTED Rename failed
+
+**/
+RETURN_STATUS
+SemihostFileRename(
+ IN CHAR8 *FileName,
+ IN CHAR8 *NewFileName
+ );
+
+CHAR8
+SemihostReadCharacter (
+ VOID
+ );
+
+VOID
+SemihostWriteCharacter (
+ IN CHAR8 Character
+ );
+
+VOID
+SemihostWriteString (
+ IN CHAR8 *String
+ );
+
+UINT32
+SemihostSystem (
+ IN CHAR8 *CommandLine
+ );
+
+#endif // __SEMIHOSTING_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h b/uefi/linaro-edk2/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h
new file mode 100644
index 0000000..a49d8d3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h
@@ -0,0 +1,665 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+
+#ifndef __UNCACHED_MEMORY_ALLOCATION_LIB_H__
+#define __UNCACHED_MEMORY_ALLOCATION_LIB_H__
+
+/**
+ Converts a cached or uncached address to a physical address suitable for use in SoC registers.
+
+ @param VirtualAddress The pointer to convert.
+
+ @return The physical address of the supplied virtual pointer.
+
+**/
+EFI_PHYSICAL_ADDRESS
+ConvertToPhysicalAddress (
+ IN VOID *VirtualAddress
+ );
+
+/**
+ Converts a cached or uncached address to a cached address.
+
+ @param Address The pointer to convert.
+
+ @return The address of the cached memory location corresponding to the input address.
+
+**/
+VOID *
+ConvertToCachedAddress (
+ IN VOID *Address
+ );
+
+/**
+ Converts a cached or uncached address to an uncached address.
+
+ @param Address The pointer to convert.
+
+ @return The address of the uncached memory location corresponding to the input address.
+
+**/
+VOID *
+ConvertToUncachedAddress (
+ IN VOID *Address
+ );
+
+/**
+ Allocates one or more 4KB pages of type EfiBootServicesData.
+
+ Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
+ allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
+ is returned. If there is not enough memory remaining to satisfy the request, then NULL is
+ returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocatePages (
+ IN UINTN Pages
+ );
+
+/**
+ Allocates one or more 4KB pages of type EfiRuntimeServicesData.
+
+ Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
+ allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
+ is returned. If there is not enough memory remaining to satisfy the request, then NULL is
+ returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateRuntimePages (
+ IN UINTN Pages
+ );
+
+/**
+ Allocates one or more 4KB pages of type EfiReservedMemoryType.
+
+ Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
+ allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
+ is returned. If there is not enough memory remaining to satisfy the request, then NULL is
+ returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateReservedPages (
+ IN UINTN Pages
+ );
+
+/**
+ Frees one or more 4KB pages that were previously allocated with one of the page allocation
+ functions in the Memory Allocation Library.
+
+ Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
+ must have been allocated on a previous call to the page allocation services of the Memory
+ Allocation Library.
+ If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
+ then ASSERT().
+ If Pages is zero, then ASSERT().
+
+ @param Buffer Pointer to the buffer of pages to free.
+ @param Pages The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+UncachedFreePages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ );
+
+/**
+ Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
+ alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
+ returned. If there is not enough memory at the specified alignment remaining to satisfy the
+ request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedPages (
+ IN UINTN Pages,
+ IN UINTN Alignment
+ );
+
+/**
+ Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
+ alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
+ returned. If there is not enough memory at the specified alignment remaining to satisfy the
+ request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimePages (
+ IN UINTN Pages,
+ IN UINTN Alignment
+ );
+
+/**
+ Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
+ alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
+ returned. If there is not enough memory at the specified alignment remaining to satisfy the
+ request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedPages (
+ IN UINTN Pages,
+ IN UINTN Alignment
+ );
+
+/**
+ Frees one or more 4KB pages that were previously allocated with one of the aligned page
+ allocation functions in the Memory Allocation Library.
+
+ Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
+ must have been allocated on a previous call to the aligned page allocation services of the Memory
+ Allocation Library.
+ If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
+ Library, then ASSERT().
+ If Pages is zero, then ASSERT().
+
+ @param Buffer Pointer to the buffer of pages to free.
+ @param Pages The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+UncachedFreeAlignedPages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ );
+
+/**
+ Allocates a buffer of type EfiBootServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
+ pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocatePool (
+ IN UINTN AllocationSize
+ );
+
+/**
+ Allocates a buffer of type EfiRuntimeServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
+ a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateRuntimePool (
+ IN UINTN AllocationSize
+ );
+
+/**
+ Allocates a buffer of type EfieservedMemoryType.
+
+ Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns
+ a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateReservedPool (
+ IN UINTN AllocationSize
+ );
+
+/**
+ Allocates and zeros a buffer of type EfiBootServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
+ buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
+ valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
+ request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate and zero.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateZeroPool (
+ IN UINTN AllocationSize
+ );
+
+/**
+ Allocates and zeros a buffer of type EfiRuntimeServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
+ buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
+ valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
+ request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate and zero.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateRuntimeZeroPool (
+ IN UINTN AllocationSize
+ );
+
+/**
+ Allocates and zeros a buffer of type EfiReservedMemoryType.
+
+ Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
+ buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
+ valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
+ request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate and zero.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateReservedZeroPool (
+ IN UINTN AllocationSize
+ );
+
+/**
+ Copies a buffer to an allocated buffer of type EfiBootServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
+ AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory remaining to satisfy the request, then NULL is returned.
+ If Buffer is NULL, then ASSERT().
+ If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate and zero.
+ @param Buffer The buffer to copy to the allocated buffer.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ );
+
+/**
+ Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
+ AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory remaining to satisfy the request, then NULL is returned.
+ If Buffer is NULL, then ASSERT().
+ If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate and zero.
+ @param Buffer The buffer to copy to the allocated buffer.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ );
+
+/**
+ Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
+
+ Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
+ AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory remaining to satisfy the request, then NULL is returned.
+ If Buffer is NULL, then ASSERT().
+ If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate and zero.
+ @param Buffer The buffer to copy to the allocated buffer.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateReservedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ );
+
+/**
+ Frees a buffer that was previously allocated with one of the pool allocation functions in the
+ Memory Allocation Library.
+
+ Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
+ pool allocation services of the Memory Allocation Library.
+ If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
+ then ASSERT().
+
+ @param Buffer Pointer to the buffer to free.
+
+**/
+VOID
+EFIAPI
+UncachedFreePool (
+ IN VOID *Buffer
+ );
+
+/**
+ Allocates a buffer of type EfiBootServicesData at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
+ alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
+ then a valid buffer of 0 size is returned. If there is not enough memory at the specified
+ alignment remaining to satisfy the request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ );
+
+/**
+ Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
+ alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
+ then a valid buffer of 0 size is returned. If there is not enough memory at the specified
+ alignment remaining to satisfy the request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimePool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ );
+
+/**
+ Allocates a buffer of type EfieservedMemoryType at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
+ alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
+ then a valid buffer of 0 size is returned. If there is not enough memory at the specified
+ alignment remaining to satisfy the request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ );
+
+/**
+ Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
+ alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
+ returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ );
+
+/**
+ Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
+ alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
+ returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimeZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ );
+
+/**
+ Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
+ alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
+ allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
+ is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
+ returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ );
+
+/**
+ Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an
+ alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
+ then a valid buffer of 0 size is returned. If there is not enough memory at the specified
+ alignment remaining to satisfy the request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Buffer The buffer to copy to the allocated buffer.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ );
+
+/**
+ Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an
+ alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
+ then a valid buffer of 0 size is returned. If there is not enough memory at the specified
+ alignment remaining to satisfy the request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Buffer The buffer to copy to the allocated buffer.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ );
+
+/**
+ Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
+
+ Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an
+ alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
+ then a valid buffer of 0 size is returned. If there is not enough memory at the specified
+ alignment remaining to satisfy the request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param AllocationSize The number of bytes to allocate.
+ @param Buffer The buffer to copy to the allocated buffer.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ );
+
+/**
+ Frees a buffer that was previously allocated with one of the aligned pool allocation functions
+ in the Memory Allocation Library.
+
+ Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
+ aligned pool allocation services of the Memory Allocation Library.
+ If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation
+ Library, then ASSERT().
+
+ @param Buffer Pointer to the buffer to free.
+
+**/
+VOID
+EFIAPI
+UncachedFreeAlignedPool (
+ IN VOID *Buffer
+ );
+
+VOID
+EFIAPI
+UncachedSafeFreePool (
+ IN VOID *Buffer
+ );
+
+#endif // __UNCACHED_MEMORY_ALLOCATION_LIB_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Ppi/ArmMpCoreInfo.h b/uefi/linaro-edk2/ArmPkg/Include/Ppi/ArmMpCoreInfo.h
new file mode 100644
index 0000000..fdacd81
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Ppi/ArmMpCoreInfo.h
@@ -0,0 +1,58 @@
+/** @file
+*
+* Copyright (c) 2011, 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 __ARM_MP_CORE_INFO_PPI_H__
+#define __ARM_MP_CORE_INFO_PPI_H__
+
+#include <Guid/ArmMpCoreInfo.h>
+
+#define ARM_MP_CORE_INFO_PPI_GUID \
+ { 0x6847cc74, 0xe9ec, 0x4f8f, {0xa2, 0x9d, 0xab, 0x44, 0xe7, 0x54, 0xa8, 0xfc} }
+
+/**
+ This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * ARM_MP_CORE_INFO_GET) (
+ OUT UINTN *ArmCoreCount,
+ OUT ARM_CORE_INFO **ArmCoreTable
+);
+
+///
+/// This service abstracts the ability to migrate contents of the platform early memory store.
+/// Note: The name EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI is different from the current PI 1.2 spec.
+/// This PPI was optional.
+///
+typedef struct {
+ ARM_MP_CORE_INFO_GET GetMpCoreInfo;
+} ARM_MP_CORE_INFO_PPI;
+
+extern EFI_GUID gArmMpCoreInfoPpiGuid;
+extern EFI_GUID gArmMpCoreInfoGuid;
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Include/Protocol/VirtualUncachedPages.h b/uefi/linaro-edk2/ArmPkg/Include/Protocol/VirtualUncachedPages.h
new file mode 100644
index 0000000..0822184
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Include/Protocol/VirtualUncachedPages.h
@@ -0,0 +1,60 @@
+/** @file
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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.
+
+**/
+
+#ifndef __VIRTUAL_UNCACHED_PAGES_ROTOCOL_H__
+#define __VIRTUAL_UNCACHED_PAGES_ROTOCOL_H__
+
+//
+// Protocol GUID
+//
+#define VIRTUAL_UNCACHED_PAGES_PROTOCOL_GUID { 0xAD651C7D, 0x3C22, 0x4DBF, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } }
+
+
+
+//
+// Protocol interface structure
+//
+typedef struct _VIRTUAL_UNCACHED_PAGES_PROTOCOL VIRTUAL_UNCACHED_PAGES_PROTOCOL;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *CONVERT_PAGES_TO_UNCACHED_VIRTUAL_ADDRESS) (
+ IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN UINTN Length,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask,
+ OUT UINT64 *Attributes OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *FREE_CONVERTED_PAGES) (
+ IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN UINTN Length,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask,
+ IN UINT64 Attributes
+ );
+
+
+
+struct _VIRTUAL_UNCACHED_PAGES_PROTOCOL {
+ CONVERT_PAGES_TO_UNCACHED_VIRTUAL_ADDRESS ConvertPages;
+ FREE_CONVERTED_PAGES RevertPages;
+};
+
+extern EFI_GUID gVirtualUncachedPagesProtocolGuid;
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
new file mode 100644
index 0000000..a0e4f58
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
@@ -0,0 +1,231 @@
+/** @file
+ Generic ARM implementation of TimerLib.h
+
+ 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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/ArmGenericTimerCounterLib.h>
+
+#define TICKS_PER_MICRO_SEC (PcdGet32 (PcdArmArchTimerFreqInHz)/1000000U)
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+ VOID
+ )
+{
+ //
+ // Check if the ARM Generic Timer Extension is implemented.
+ //
+ if (ArmIsArchTimerImplemented ()) {
+ UINTN TimerFreq;
+
+ //
+ // Check if Architectural Timer frequency is pre-determined by the platform
+ // (ie. nonzero).
+ //
+ if (PcdGet32 (PcdArmArchTimerFreqInHz) != 0) {
+ //
+ // Check if ticks/uS is not 0. The Architectural timer runs at constant
+ // frequency, irrespective of CPU frequency. According to General Timer
+ // Ref manual, lower bound of the frequency is in the range of 1-10MHz.
+ //
+ ASSERT (TICKS_PER_MICRO_SEC);
+
+#ifdef MDE_CPU_ARM
+ //
+ // Only set the frequency for ARMv7. We expect the secure firmware to
+ // have already done it.
+ // If the security extension is not implemented, set Timer Frequency
+ // here.
+ //
+ if ((ArmReadIdPfr1 () & ARM_PFR1_SEC) == 0x0) {
+ ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));
+ }
+#endif
+ }
+
+ //
+ // Architectural Timer Frequency must be set in the Secure privileged
+ // mode (if secure extension is supported).
+ // If the reset value (0) is returned, just ASSERT.
+ //
+ TimerFreq = ArmGenericTimerGetTimerFreq ();
+ ASSERT (TimerFreq != 0);
+ } else {
+ DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence this library can not be used.\n"));
+ ASSERT (0);
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+ @param MicroSeconds The minimum number of microseconds to delay.
+
+ @return The value of MicroSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+ IN UINTN MicroSeconds
+ )
+{
+ UINT64 TimerTicks64;
+ UINT64 SystemCounterVal;
+ UINT64 (EFIAPI
+ *MultU64xN) (
+ IN UINT64 Multiplicand,
+ IN UINTN Multiplier
+ );
+ UINTN TimerFreq;
+
+#ifdef MDE_CPU_ARM
+ MultU64xN = MultU64x32;
+#else
+ MultU64xN = MultU64x64;
+#endif
+
+ TimerFreq = PcdGet32 (PcdArmArchTimerFreqInHz);
+ if (TimerFreq == 0) {
+ TimerFreq = ArmGenericTimerGetTimerFreq ();
+ }
+
+ // Calculate counter ticks that can represent requested delay:
+ // = MicroSeconds x TICKS_PER_MICRO_SEC
+ // = MicroSeconds x Frequency.10^-6
+ TimerTicks64 = DivU64x32 (
+ MultU64xN (
+ MicroSeconds,
+ TimerFreq
+ ),
+ 1000000U
+ );
+
+ // Read System Counter value
+ SystemCounterVal = ArmGenericTimerGetSystemCount ();
+
+ TimerTicks64 += SystemCounterVal;
+
+ // Wait until delay count is expired.
+ while (SystemCounterVal < TimerTicks64) {
+ SystemCounterVal = ArmGenericTimerGetSystemCount ();
+ }
+
+ return MicroSeconds;
+}
+
+
+/**
+ Stalls the CPU for at least the given number of nanoseconds.
+
+ Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+ When the timer frequency is 1MHz, each tick corresponds to 1 microsecond.
+ Therefore, the nanosecond delay will be rounded up to the nearest 1 microsecond.
+
+ @param NanoSeconds The minimum number of nanoseconds to delay.
+
+ @return The value of NanoSeconds inputed.
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+ IN UINTN NanoSeconds
+ )
+{
+ UINTN MicroSeconds;
+
+ // Round up to 1us Tick Number
+ MicroSeconds = NanoSeconds / 1000;
+ MicroSeconds += ((NanoSeconds % 1000) == 0) ? 0 : 1;
+
+ MicroSecondDelay (MicroSeconds);
+
+ return NanoSeconds;
+}
+
+/**
+ Retrieves the current value of a 64-bit free running performance counter.
+
+ The counter can either count up by 1 or count down by 1. If the physical
+ performance counter counts by a larger increment, then the counter values
+ must be translated. The properties of the counter can be retrieved from
+ GetPerformanceCounterProperties().
+
+ @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+ VOID
+ )
+{
+ // Just return the value of system count
+ return ArmGenericTimerGetSystemCount ();
+}
+
+/**
+ Retrieves the 64-bit frequency in Hz and the range of performance counter
+ values.
+
+ If StartValue is not NULL, then the value that the performance counter starts
+ with immediately after is it rolls over is returned in StartValue. If
+ EndValue is not NULL, then the value that the performance counter end with
+ immediately before it rolls over is returned in EndValue. The 64-bit
+ frequency of the performance counter in Hz is always returned. If StartValue
+ is less than EndValue, then the performance counter counts up. If StartValue
+ is greater than EndValue, then the performance counter counts down. For
+ example, a 64-bit free running counter that counts up would have a StartValue
+ of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+ that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+ @param StartValue The value the performance counter starts with when it
+ rolls over.
+ @param EndValue The value that the performance counter ends with before
+ it rolls over.
+
+ @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+ OUT UINT64 *StartValue, OPTIONAL
+ OUT UINT64 *EndValue OPTIONAL
+ )
+{
+ if (StartValue != NULL) {
+ // Timer starts with the reload value
+ *StartValue = (UINT64)0ULL ;
+ }
+
+ if (EndValue != NULL) {
+ // Timer counts down to 0x0
+ *EndValue = 0xFFFFFFFFFFFFFFFFUL;
+ }
+
+ return (UINT64)ArmGenericTimerGetTimerFreq ();
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
new file mode 100644
index 0000000..03a4b1e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
@@ -0,0 +1,38 @@
+#/** @file
+#
+# Copyright (c) 2011 - 2014, ARM Limited. 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 = ArmArchTimerLib
+ FILE_GUID = 82da1b44-d2d6-4a7d-bbf0-a0cb67964034
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib
+ CONSTRUCTOR = TimerConstructor
+
+[Sources.common]
+ ArmArchTimerLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ ArmLib
+ BaseLib
+ ArmGenericTimerCounterLib
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c
new file mode 100644
index 0000000..8501e5c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c
@@ -0,0 +1,127 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ 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 <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+CacheRangeOperation (
+ IN VOID *Start,
+ IN UINTN Length,
+ IN CACHE_OPERATION CacheOperation,
+ IN LINE_OPERATION LineOperation
+ )
+{
+ UINTN ArmCacheLineLength = ArmDataCacheLineLength();
+ UINTN ArmCacheLineAlignmentMask = ArmCacheLineLength - 1;
+ UINTN ArmCacheOperationThreshold = PcdGet32(PcdArmCacheOperationThreshold);
+
+ if ((CacheOperation != NULL) && (Length >= ArmCacheOperationThreshold)) {
+ ArmDrainWriteBuffer ();
+ CacheOperation ();
+ } else {
+ // Align address (rounding down)
+ UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
+ UINTN EndAddress = (UINTN)Start + Length;
+
+ // Perform the line operation on an address in each cache line
+ while (AlignedAddress < EndAddress) {
+ LineOperation(AlignedAddress);
+ AlignedAddress += ArmCacheLineLength;
+ }
+ }
+}
+
+VOID
+EFIAPI
+InvalidateInstructionCache (
+ VOID
+ )
+{
+ ArmCleanDataCache();
+ ArmInvalidateInstructionCache();
+}
+
+VOID
+EFIAPI
+InvalidateDataCache (
+ VOID
+ )
+{
+ ArmInvalidateDataCache();
+}
+
+VOID *
+EFIAPI
+InvalidateInstructionCacheRange (
+ IN VOID *Address,
+ IN UINTN Length
+ )
+{
+ CacheRangeOperation (Address, Length, ArmCleanDataCacheToPoU, ArmCleanDataCacheEntryByMVA);
+ ArmInvalidateInstructionCache ();
+ return Address;
+}
+
+VOID
+EFIAPI
+WriteBackInvalidateDataCache (
+ VOID
+ )
+{
+ ArmCleanInvalidateDataCache();
+}
+
+VOID *
+EFIAPI
+WriteBackInvalidateDataCacheRange (
+ IN VOID *Address,
+ IN UINTN Length
+ )
+{
+ CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCache, ArmCleanInvalidateDataCacheEntryByMVA);
+ return Address;
+}
+
+VOID
+EFIAPI
+WriteBackDataCache (
+ VOID
+ )
+{
+ ArmCleanDataCache();
+}
+
+VOID *
+EFIAPI
+WriteBackDataCacheRange (
+ IN VOID *Address,
+ IN UINTN Length
+ )
+{
+ CacheRangeOperation(Address, Length, ArmCleanDataCache, ArmCleanDataCacheEntryByMVA);
+ return Address;
+}
+
+VOID *
+EFIAPI
+InvalidateDataCacheRange (
+ IN VOID *Address,
+ IN UINTN Length
+ )
+{
+ CacheRangeOperation(Address, Length, NULL, ArmInvalidateDataCacheEntryByMVA);
+ return Address;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
new file mode 100644
index 0000000..5910db0
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
@@ -0,0 +1,36 @@
+#/** @file
+# Implement CacheMaintenanceLib for ARM architectures
+#
+# Copyright (c) 2008, Apple Inc. 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 = ArmCacheMaintenanceLib
+ FILE_GUID = 1A20BE1F-33AD-450C-B49A-7123FCA8B7F9
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CacheMaintenanceLib
+
+[Sources.common]
+ ArmCacheMaintenanceLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ ArmLib
+ BaseLib
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/Aarch64Disassembler.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/Aarch64Disassembler.c
new file mode 100644
index 0000000..3ecae77
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/Aarch64Disassembler.c
@@ -0,0 +1,48 @@
+/** @file
+ Default exception handler
+
+ Copyright (c) 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 <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ArmDisassemblerLib.h>
+
+/**
+ Place a disassembly of of **OpCodePtr into buffer, and update OpCodePtr to
+ point to next instruction.
+
+ @param OpCodePtrPtr Pointer to pointer of instruction to disassemble.
+ @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
+ @param Extended TRUE dump hex for instruction too.
+ @param ItBlock Size of IT Block
+ @param Buf Buffer to sprintf disassembly into.
+ @param Size Size of Buf in bytes.
+
+**/
+VOID
+DisassembleInstruction (
+ IN UINT8 **OpCodePtr,
+ IN BOOLEAN Thumb,
+ IN BOOLEAN Extended,
+ IN OUT UINT32 *ItBlock,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size
+ )
+{
+ // Not yet supported for AArch64.
+ // Put error in the buffer as we have no return code and the buffer may be
+ // printed directly so needs a '\0'.
+ AsciiSPrint (Buf, Size, "AArch64 not supported");
+ return;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
new file mode 100644
index 0000000..29a8d44
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
@@ -0,0 +1,457 @@
+/** @file
+ Default exception handler
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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 <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ArmDisassemblerLib.h>
+
+CHAR8 *gCondition[] = {
+ "EQ",
+ "NE",
+ "CS",
+ "CC",
+ "MI",
+ "PL",
+ "VS",
+ "VC",
+ "HI",
+ "LS",
+ "GE",
+ "LT",
+ "GT",
+ "LE",
+ "",
+ "2"
+};
+
+#define COND(_a) gCondition[((_a) >> 28)]
+
+CHAR8 *gReg[] = {
+ "r0",
+ "r1",
+ "r2",
+ "r3",
+ "r4",
+ "r5",
+ "r6",
+ "r7",
+ "r8",
+ "r9",
+ "r10",
+ "r11",
+ "r12",
+ "sp",
+ "lr",
+ "pc"
+};
+
+CHAR8 *gLdmAdr[] = {
+ "DA",
+ "IA",
+ "DB",
+ "IB"
+};
+
+CHAR8 *gLdmStack[] = {
+ "FA",
+ "FD",
+ "EA",
+ "ED"
+};
+
+#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
+
+
+#define SIGN(_U) ((_U) ? "" : "-")
+#define WRITE(_W) ((_W) ? "!" : "")
+#define BYTE(_B) ((_B) ? "B":"")
+#define USER(_B) ((_B) ? "^" : "")
+
+CHAR8 mMregListStr[4*15 + 1];
+
+CHAR8 *
+MRegList (
+ UINT32 OpCode
+ )
+{
+ UINTN Index, Start, End;
+ CHAR8 *Str;
+ BOOLEAN First;
+
+ Str = mMregListStr;
+ *Str = '\0';
+ AsciiStrCat (Str, "{");
+ for (Index = 0, First = TRUE; Index <= 15; Index++) {
+ if ((OpCode & (1 << Index)) != 0) {
+ Start = End = Index;
+ for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {
+ End = Index;
+ }
+
+ if (!First) {
+ AsciiStrCat (Str, ",");
+ } else {
+ First = FALSE;
+ }
+
+ if (Start == End) {
+ AsciiStrCat (Str, gReg[Start]);
+ AsciiStrCat (Str, ", ");
+ } else {
+ AsciiStrCat (Str, gReg[Start]);
+ AsciiStrCat (Str, "-");
+ AsciiStrCat (Str, gReg[End]);
+ }
+ }
+ }
+ if (First) {
+ AsciiStrCat (Str, "ERROR");
+ }
+ AsciiStrCat (Str, "}");
+
+ // BugBug: Make caller pass in buffer it is cleaner
+ return mMregListStr;
+}
+
+CHAR8 *
+FieldMask (
+ IN UINT32 Mask
+ )
+{
+ return "";
+}
+
+UINT32
+RotateRight (
+ IN UINT32 Op,
+ IN UINT32 Shift
+ )
+{
+ return (Op >> Shift) | (Op << (32 - Shift));
+}
+
+
+/**
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
+ point to next instructin.
+
+ We cheat and only decode instructions that access
+ memory. If the instruction is not found we dump the instruction in hex.
+
+ @param OpCodePtr Pointer to pointer of ARM instruction to disassemble.
+ @param Buf Buffer to sprintf disassembly into.
+ @param Size Size of Buf in bytes.
+ @param Extended TRUE dump hex for instruction too.
+
+**/
+VOID
+DisassembleArmInstruction (
+ IN UINT32 **OpCodePtr,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size,
+ IN BOOLEAN Extended
+ )
+{
+ UINT32 OpCode = **OpCodePtr;
+ CHAR8 *Type, *Root;
+ BOOLEAN I, P, U, B, W, L, S, H;
+ UINT32 Rn, Rd, Rm;
+ UINT32 imode, offset_8, offset_12;
+ UINT32 Index;
+ UINT32 shift_imm, shift;
+
+ I = (OpCode & BIT25) == BIT25;
+ P = (OpCode & BIT24) == BIT24;
+ U = (OpCode & BIT23) == BIT23;
+ B = (OpCode & BIT22) == BIT22; // Also called S
+ W = (OpCode & BIT21) == BIT21;
+ L = (OpCode & BIT20) == BIT20;
+ S = (OpCode & BIT6) == BIT6;
+ H = (OpCode & BIT5) == BIT5;
+ Rn = (OpCode >> 16) & 0xf;
+ Rd = (OpCode >> 12) & 0xf;
+ Rm = (OpCode & 0xf);
+
+
+ if (Extended) {
+ Index = AsciiSPrint (Buf, Size, "0x%08x ", OpCode);
+ Buf += Index;
+ Size -= Index;
+ }
+
+ // LDREX, STREX
+ if ((OpCode & 0x0fe000f0) == 0x01800090) {
+ if (L) {
+ // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]
+ AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]);
+ } else {
+ // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
+ AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]);
+ }
+ return;
+ }
+
+ // LDM/STM
+ if ((OpCode & 0x0e000000) == 0x08000000) {
+ if (L) {
+ // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
+ // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
+ // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
+ AsciiSPrint (Buf, Size, "LDM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B));
+ } else {
+ // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
+ // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
+ AsciiSPrint (Buf, Size, "STM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (W), MRegList (OpCode), USER (B));
+ }
+ return;
+ }
+
+ // LDR/STR Address Mode 2
+ if ( ((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {
+ offset_12 = OpCode & 0xfff;
+ if ((OpCode & 0xfd70f000 ) == 0xf550f000) {
+ Index = AsciiSPrint (Buf, Size, "PLD");
+ } else {
+ Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", L ? "LDR" : "STR", COND (OpCode), BYTE (B), (!(P) && W) ? "T":"", gReg[Rd]);
+ }
+ if (P) {
+ if (!I) {
+ // A5.2.2 [<Rn>, #+/-<offset_12>]
+ // A5.2.5 [<Rn>, #+/-<offset_12>]
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (U), offset_12, WRITE (W));
+ } else if ((OpCode & 0x03000ff0) == 0x03000000) {
+ // A5.2.3 [<Rn>, +/-<Rm>]
+ // A5.2.6 [<Rn>, +/-<Rm>]!
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (U), WRITE (W));
+ } else {
+ // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
+ // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
+ shift_imm = (OpCode >> 7) & 0x1f;
+ shift = (OpCode >> 5) & 0x3;
+ if (shift == 0x0) {
+ Type = "LSL";
+ } else if (shift == 0x1) {
+ Type = "LSR";
+ if (shift_imm == 0) {
+ shift_imm = 32;
+ }
+ } else if (shift == 0x12) {
+ Type = "ASR";
+ } else if (shift_imm == 0) {
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));
+ return;
+ } else {
+ Type = "ROR";
+ }
+
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm, WRITE (W));
+ }
+ } else { // !P
+ if (!I) {
+ // A5.2.8 [<Rn>], #+/-<offset_12>
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (U), offset_12);
+ } else if ((OpCode & 0x03000ff0) == 0x03000000) {
+ // A5.2.9 [<Rn>], +/-<Rm>
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);
+ } else {
+ // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
+ shift_imm = (OpCode >> 7) & 0x1f;
+ shift = (OpCode >> 5) & 0x3;
+
+ if (shift == 0x0) {
+ Type = "LSL";
+ } else if (shift == 0x1) {
+ Type = "LSR";
+ if (shift_imm == 0) {
+ shift_imm = 32;
+ }
+ } else if (shift == 0x12) {
+ Type = "ASR";
+ } else if (shift_imm == 0) {
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);
+ // FIx me
+ return;
+ } else {
+ Type = "ROR";
+ }
+
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm);
+ }
+ }
+ return;
+ }
+
+ if ((OpCode & 0x0e000000) == 0x00000000) {
+ // LDR/STR address mode 3
+ // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>
+ if (L) {
+ if (!S) {
+ Root = "LDR%aH %a, ";
+ } else if (!H) {
+ Root = "LDR%aSB %a, ";
+ } else {
+ Root = "LDR%aSH %a, ";
+ }
+ } else {
+ if (!S) {
+ Root = "STR%aH %a ";
+ } else if (!H) {
+ Root = "LDR%aD %a ";
+ } else {
+ Root = "STR%aD %a ";
+ }
+ }
+
+ Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]);
+
+ S = (OpCode & BIT6) == BIT6;
+ H = (OpCode & BIT5) == BIT5;
+ offset_8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;
+ if (P & !W) {
+ // Immediate offset/index
+ if (B) {
+ // A5.3.2 [<Rn>, #+/-<offset_8>]
+ // A5.3.4 [<Rn>, #+/-<offset_8>]!
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (U), offset_8, WRITE (W));
+ } else {
+ // A5.3.3 [<Rn>, +/-<Rm>]
+ // A5.3.5 [<Rn>, +/-<Rm>]!
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));
+ }
+ } else {
+ // Register offset/index
+ if (B) {
+ // A5.3.6 [<Rn>], #+/-<offset_8>
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (U), offset_8);
+ } else {
+ // A5.3.7 [<Rn>], +/-<Rm>
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);
+ }
+ }
+ return;
+ }
+
+ if ((OpCode & 0x0fb000f0) == 0x01000050) {
+ // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
+ // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
+ AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (B), gReg[Rd], gReg[Rm], gReg[Rn]);
+ return;
+ }
+
+ if ((OpCode & 0xfe5f0f00) == 0xf84d0500) {
+ // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}
+ AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (W));
+ return;
+ }
+
+ if ((OpCode & 0xfe500f00) == 0xf8100500) {
+ // A4.1.59 RFE<addressing_mode> <Rn>{!}
+ AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (W));
+ return;
+ }
+
+ if ((OpCode & 0xfff000f0) == 0xe1200070) {
+ // A4.1.7 BKPT <immed_16>
+ AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);
+ return;
+ }
+
+ if ((OpCode & 0xfff10020) == 0xf1000000) {
+ // A4.1.16 CPS<effect> <iflags> {, #<mode>}
+ if (((OpCode >> 6) & 0x7) == 0) {
+ AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));
+ } else {
+ imode = (OpCode >> 18) & 0x3;
+ Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");
+ if ((OpCode & BIT17) != 0) {
+ AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);
+ }
+ }
+ return;
+ }
+
+ if ((OpCode & 0x0f000000) == 0x0f000000) {
+ // A4.1.107 SWI{<cond>} <immed_24>
+ AsciiSPrint (Buf, Size, "SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);
+ return;
+ }
+
+ if ((OpCode & 0x0fb00000) == 0x01000000) {
+ // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR
+ AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], B ? "SPSR" : "CPSR");
+ return;
+ }
+
+
+ if ((OpCode & 0x0db00000) == 0x03200000) {
+ // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
+ if (I) {
+ // MSR{<cond>} CPSR_<fields>, #<immediate>
+ AsciiSPrint (Buf, Size, "MRS%a %a_%a, #0x%x", COND (OpCode), B ? "SPSR" : "CPSR", FieldMask ((OpCode >> 16) & 0xf), RotateRight (OpCode & 0xf, ((OpCode >> 8) & 0xf) *2));
+ } else {
+ // MSR{<cond>} CPSR_<fields>, <Rm>
+ AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), B ? "SPSR" : "CPSR", gReg[Rd]);
+ }
+ return;
+ }
+
+ if ((OpCode & 0xff000010) == 0xfe000000) {
+ // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
+ AsciiSPrint (Buf, Size, "CDP%a 0x%x, 0x%x, CR%d, CR%d, CR%d, 0x%x", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, Rn, Rd, Rm, (OpCode >> 5) &0x7);
+ return;
+ }
+
+ if ((OpCode & 0x0e000000) == 0x0c000000) {
+ // A4.1.19 LDC and A4.1.96 SDC
+ if ((OpCode & 0xf0000000) == 0xf0000000) {
+ Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", L ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);
+ } else {
+ Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", L ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);
+ }
+
+ if (!P) {
+ if (!W) {
+ // A5.5.5.5 [<Rn>], <option>
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff);
+ } else {
+ // A.5.5.4 [<Rn>], #+/-<offset_8>*4
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (U), OpCode & 0xff);
+ }
+ } else {
+ // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (U), OpCode & 0xff, WRITE (W));
+ }
+
+ }
+
+ if ((OpCode & 0x0f000010) == 0x0e000010) {
+ // A4.1.32 MRC2, MCR2
+ AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, CR%d, CR%d, 0x%x", L ? "MRC":"MCR", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], Rn, Rm, (OpCode >> 5) &0x7);
+ return;
+ }
+
+ if ((OpCode & 0x0ff00000) == 0x0c400000) {
+ // A4.1.33 MRRC2, MCRR2
+ AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, %a, CR%d", L ? "MRRC":"MCRR", COND (OpCode), (OpCode >> 4) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], gReg[Rn], Rm);
+ return;
+ }
+
+ AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);
+
+ *OpCodePtr += 1;
+ return;
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
new file mode 100644
index 0000000..bb51e30
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
@@ -0,0 +1,40 @@
+#/** @file
+# ARM Disassembler library
+#
+# Copyright (c) 2008, Apple Inc. 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 = ArmDisassemblerLib
+ FILE_GUID = 7ACEC173-F15D-426C-8F2F-BD86B4183EF1
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmDisassemblerLib
+
+
+[Sources.ARM]
+ ArmDisassembler.c
+ ThumbDisassembler.c
+
+[Sources.AARCH64]
+ Aarch64Disassembler.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ PrintLib
+ DebugLib
+ PeCoffGetEntryPointLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
new file mode 100644
index 0000000..5bad3af
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c
@@ -0,0 +1,1064 @@
+/** @file
+ Thumb Dissassembler. Still a work in progress.
+
+ Wrong output is a bug, so please fix it.
+ Hex output means there is not yet an entry or a decode bug.
+ gOpThumb[] are Thumb 16-bit, and gOpThumb2[] work on the 32-bit
+ 16-bit stream of Thumb2 instruction. Then there are big case
+ statements to print everything out. If you are adding instructions
+ try to reuse existing case entries if possible.
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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 <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+
+extern CHAR8 *gCondition[];
+
+extern CHAR8 *gReg[];
+
+// Thumb address modes
+#define LOAD_STORE_FORMAT1 1
+#define LOAD_STORE_FORMAT1_H 101
+#define LOAD_STORE_FORMAT1_B 111
+#define LOAD_STORE_FORMAT2 2
+#define LOAD_STORE_FORMAT3 3
+#define LOAD_STORE_FORMAT4 4
+#define LOAD_STORE_MULTIPLE_FORMAT1 5
+#define PUSH_FORMAT 6
+#define POP_FORMAT 106
+#define IMMED_8 7
+#define CONDITIONAL_BRANCH 8
+#define UNCONDITIONAL_BRANCH 9
+#define UNCONDITIONAL_BRANCH_SHORT 109
+#define BRANCH_EXCHANGE 10
+#define DATA_FORMAT1 11
+#define DATA_FORMAT2 12
+#define DATA_FORMAT3 13
+#define DATA_FORMAT4 14
+#define DATA_FORMAT5 15
+#define DATA_FORMAT6_SP 16
+#define DATA_FORMAT6_PC 116
+#define DATA_FORMAT7 17
+#define DATA_FORMAT8 19
+#define CPS_FORMAT 20
+#define ENDIAN_FORMAT 21
+#define DATA_CBZ 22
+#define ADR_FORMAT 23
+#define IT_BLOCK 24
+
+// Thumb2 address modes
+#define B_T3 200
+#define B_T4 201
+#define BL_T2 202
+#define POP_T2 203
+#define POP_T3 204
+#define STM_FORMAT 205
+#define LDM_REG_IMM12_SIGNED 206
+#define LDM_REG_IMM12_LSL 207
+#define LDM_REG_IMM8 208
+#define LDM_REG_IMM12 209
+#define LDM_REG_INDIRECT_LSL 210
+#define LDM_REG_IMM8_SIGNED 211
+#define LDRD_REG_IMM8 212
+#define LDREXB 213
+#define LDREXD 214
+#define SRS_FORMAT 215
+#define RFE_FORMAT 216
+#define LDRD_REG_IMM8_SIGNED 217
+#define ADD_IMM12 218
+#define ADD_IMM5 219
+#define ADR_THUMB2 220
+#define CMN_THUMB2 221
+#define ASR_IMM5 222
+#define ASR_3REG 223
+#define BFC_THUMB2 224
+#define CDP_THUMB2 225
+#define THUMB2_NO_ARGS 226
+#define THUMB2_2REGS 227
+#define ADD_IMM5_2REG 228
+#define CPD_THUMB2 229
+#define THUMB2_4REGS 230
+#define ADD_IMM12_1REG 231
+#define THUMB2_IMM16 232
+#define MRC_THUMB2 233
+#define MRRC_THUMB2 234
+#define THUMB2_MRS 235
+#define THUMB2_MSR 236
+
+
+
+
+typedef struct {
+ CHAR8 *Start;
+ UINT32 OpCode;
+ UINT32 Mask;
+ UINT32 AddressMode;
+} THUMB_INSTRUCTIONS;
+
+THUMB_INSTRUCTIONS gOpThumb[] = {
+// Thumb 16-bit instrucitons
+// Op Mask Format
+ { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 }, // ADC <Rndn>, <Rm>
+ { "ADR", 0xa000, 0xf800, ADR_FORMAT }, // ADR <Rd>, <label>
+ { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },
+ { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },
+ { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 },
+ { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 }, // A8.6.9
+ { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC },
+ { "ADD" , 0xa800, 0xf800, DATA_FORMAT6_SP },
+ { "ADD" , 0xb000, 0xff80, DATA_FORMAT7 },
+
+ { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 },
+
+ { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 },
+ { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 },
+
+ { "B" , 0xd000, 0xf000, CONDITIONAL_BRANCH },
+ { "B" , 0xe000, 0xf800, UNCONDITIONAL_BRANCH_SHORT },
+ { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE },
+ { "BX" , 0x4700, 0xff87, BRANCH_EXCHANGE },
+
+ { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 },
+ { "BKPT", 0xdf00, 0xff00, IMMED_8 },
+ { "CBZ", 0xb100, 0xfd00, DATA_CBZ },
+ { "CBNZ", 0xb900, 0xfd00, DATA_CBZ },
+ { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 },
+
+ { "CMP" , 0x2800, 0xf800, DATA_FORMAT3 },
+ { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 },
+ { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 },
+
+ { "CPS" , 0xb660, 0xffe8, CPS_FORMAT },
+ { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },
+ { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },
+
+ { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },
+ { "LDR" , 0x6800, 0xf800, LOAD_STORE_FORMAT1 }, // LDR <Rt>, [<Rn> {,#<imm>}]
+ { "LDR" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>]
+ { "LDR" , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },
+ { "LDR" , 0x9800, 0xf800, LOAD_STORE_FORMAT4 }, // LDR <Rt>, [SP, #<imm>]
+ { "LDRB" , 0x7800, 0xf800, LOAD_STORE_FORMAT1_B },
+ { "LDRB" , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>]
+ { "LDRH" , 0x8800, 0xf800, LOAD_STORE_FORMAT1_H },
+ { "LDRH" , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },
+ { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>]
+ { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },
+
+ { "MOVS", 0x0000, 0xffc0, DATA_FORMAT5 }, // LSL with imm5 == 0 is a MOVS, so this must go before LSL
+ { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 },
+ { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },
+ { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },
+ { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },
+ { "LSRS", 0x0800, 0xf800, DATA_FORMAT4 }, // LSRS <Rd>, <Rm>, #<imm5>
+
+ { "MOVS", 0x2000, 0xf800, DATA_FORMAT3 },
+ { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },
+ { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },
+
+ { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },
+ { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },
+ { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },
+ { "ORR" , 0x4300, 0xffc0, DATA_FORMAT5 },
+ { "POP" , 0xbc00, 0xfe00, POP_FORMAT },
+ { "PUSH", 0xb400, 0xfe00, PUSH_FORMAT },
+
+ { "REV" , 0xba00, 0xffc0, DATA_FORMAT5 },
+ { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 },
+ { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 },
+
+ { "ROR" , 0x41c0, 0xffc0, DATA_FORMAT5 },
+ { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },
+ { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT },
+
+ { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },
+ { "STR" , 0x6000, 0xf800, LOAD_STORE_FORMAT1 }, // STR <Rt>, [<Rn> {,#<imm>}]
+ { "STR" , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>]
+ { "STR" , 0x9000, 0xf800, LOAD_STORE_FORMAT4 }, // STR <Rt>, [SP, #<imm>]
+ { "STRB" , 0x7000, 0xf800, LOAD_STORE_FORMAT1_B }, // STRB <Rt>, [<Rn>, #<imm5>]
+ { "STRB" , 0x5400, 0xfe00, LOAD_STORE_FORMAT2 }, // STRB <Rt>, [<Rn>, <Rm>]
+ { "STRH" , 0x8000, 0xf800, LOAD_STORE_FORMAT1_H }, // STRH <Rt>, [<Rn>{,#<imm>}]
+ { "STRH" , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 }, // STRH <Rt>, [<Rn>, <Rm>]
+
+ { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },
+ { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },
+ { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },
+ { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },
+
+ { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },
+
+ { "SWI" , 0xdf00, 0xff00, IMMED_8 },
+ { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },
+ { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },
+ { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },
+ { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },
+ { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 },
+
+ { "IT", 0xbf00, 0xff00, IT_BLOCK }
+
+};
+
+THUMB_INSTRUCTIONS gOpThumb2[] = {
+//Instruct OpCode OpCode Mask Addressig Mode
+
+ { "ADR", 0xf2af0000, 0xfbff8000, ADR_THUMB2 }, // ADDR <Rd>, <label> ;Needs to go before ADDW
+ { "CMN", 0xf1100f00, 0xfff08f00, CMN_THUMB2 }, // CMN <Rn>, #<const> ;Needs to go before ADD
+ { "CMN", 0xeb100f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN <Rn>, <Rm> {,<shift> #<const>}
+ { "CMP", 0xf1a00f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const>
+ { "TEQ", 0xf0900f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const>
+ { "TEQ", 0xea900f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN <Rn>, <Rm> {,<shift> #<const>}
+ { "TST", 0xf0100f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const>
+ { "TST", 0xea100f00, 0xfff08f00, ADD_IMM5_2REG }, // TST <Rn>, <Rm> {,<shift> #<const>}
+
+ { "MOV", 0xf04f0000, 0xfbef8000, ADD_IMM12_1REG }, // MOV <Rd>, #<const>
+ { "MOVW", 0xf2400000, 0xfbe08000, THUMB2_IMM16 }, // MOVW <Rd>, #<const>
+ { "MOVT", 0xf2c00000, 0xfbe08000, THUMB2_IMM16 }, // MOVT <Rd>, #<const>
+
+ { "ADC", 0xf1400000, 0xfbe08000, ADD_IMM12 }, // ADC{S} <Rd>, <Rn>, #<const>
+ { "ADC", 0xeb400000, 0xffe08000, ADD_IMM5 }, // ADC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "ADD", 0xf1000000, 0xfbe08000, ADD_IMM12 }, // ADD{S} <Rd>, <Rn>, #<const>
+ { "ADD", 0xeb000000, 0xffe08000, ADD_IMM5 }, // ADD{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "ADDW", 0xf2000000, 0xfbe08000, ADD_IMM12 }, // ADDW{S} <Rd>, <Rn>, #<const>
+ { "AND", 0xf0000000, 0xfbe08000, ADD_IMM12 }, // AND{S} <Rd>, <Rn>, #<const>
+ { "AND", 0xea000000, 0xffe08000, ADD_IMM5 }, // AND{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "BIC", 0xf0200000, 0xfbe08000, ADD_IMM12 }, // BIC{S} <Rd>, <Rn>, #<const>
+ { "BIC", 0xea200000, 0xffe08000, ADD_IMM5 }, // BIC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "EOR", 0xf0800000, 0xfbe08000, ADD_IMM12 }, // EOR{S} <Rd>, <Rn>, #<const>
+ { "EOR", 0xea800000, 0xffe08000, ADD_IMM5 }, // EOR{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "ORN", 0xf0600000, 0xfbe08000, ADD_IMM12 }, // ORN{S} <Rd>, <Rn>, #<const>
+ { "ORN", 0xea600000, 0xffe08000, ADD_IMM5 }, // ORN{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "ORR", 0xf0400000, 0xfbe08000, ADD_IMM12 }, // ORR{S} <Rd>, <Rn>, #<const>
+ { "ORR", 0xea400000, 0xffe08000, ADD_IMM5 }, // ORR{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "RSB", 0xf1c00000, 0xfbe08000, ADD_IMM12 }, // RSB{S} <Rd>, <Rn>, #<const>
+ { "RSB", 0xebc00000, 0xffe08000, ADD_IMM5 }, // RSB{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "SBC", 0xf1600000, 0xfbe08000, ADD_IMM12 }, // SBC{S} <Rd>, <Rn>, #<const>
+ { "SBC", 0xeb600000, 0xffe08000, ADD_IMM5 }, // SBC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+ { "SUB", 0xf1a00000, 0xfbe08000, ADD_IMM12 }, // SUB{S} <Rd>, <Rn>, #<const>
+ { "SUB", 0xeba00000, 0xffe08000, ADD_IMM5 }, // SUB{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>}
+
+ { "ASR", 0xea4f0020, 0xffef8030, ASR_IMM5 }, // ARS <Rd>, <Rm> #<const>} imm3:imm2
+ { "ASR", 0xfa40f000, 0xffe0f0f0, ASR_3REG }, // ARS <Rd>, <Rn>, <Rm>
+ { "LSR", 0xea4f0010, 0xffef8030, ASR_IMM5 }, // LSR <Rd>, <Rm> #<const>} imm3:imm2
+ { "LSR", 0xfa20f000, 0xffe0f0f0, ASR_3REG }, // LSR <Rd>, <Rn>, <Rm>
+ { "ROR", 0xea4f0030, 0xffef8030, ASR_IMM5 }, // ROR <Rd>, <Rm> #<const>} imm3:imm2
+ { "ROR", 0xfa60f000, 0xffe0f0f0, ASR_3REG }, // ROR <Rd>, <Rn>, <Rm>
+
+ { "BFC", 0xf36f0000, 0xffff8010, BFC_THUMB2 }, // BFC <Rd>, #<lsb>, #<width>
+ { "BIC", 0xf3600000, 0xfff08010, BFC_THUMB2 }, // BIC <Rn>, <Rd>, #<lsb>, #<width>
+ { "SBFX", 0xf3400000, 0xfff08010, BFC_THUMB2 }, // SBFX <Rn>, <Rd>, #<lsb>, #<width>
+ { "UBFX", 0xf3c00000, 0xfff08010, BFC_THUMB2 }, // UBFX <Rn>, <Rd>, #<lsb>, #<width>
+
+ { "CPD", 0xee000000, 0xff000010, CPD_THUMB2 }, // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>
+ { "CPD2", 0xfe000000, 0xff000010, CPD_THUMB2 }, // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>
+
+ { "MRC", 0xee100000, 0xff100000, MRC_THUMB2 }, // MRC <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>
+ { "MRC2", 0xfe100000, 0xff100000, MRC_THUMB2 }, // MRC2 <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>
+ { "MRRC", 0xec500000, 0xfff00000, MRRC_THUMB2 }, // MRRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>
+ { "MRRC2", 0xfc500000, 0xfff00000, MRRC_THUMB2 }, // MRR2 <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>
+
+ { "MRS", 0xf3ef8000, 0xfffff0ff, THUMB2_MRS }, // MRS <Rd>, CPSR
+ { "MSR", 0xf3808000, 0xfff0fcff, THUMB2_MSR }, // MSR CPSR_fs, <Rn>
+
+ { "CLREX", 0xf3bf8f2f, 0xfffffff, THUMB2_NO_ARGS }, // CLREX
+
+ { "CLZ", 0xfab0f080, 0xfff0f0f0, THUMB2_2REGS }, // CLZ <Rd>,<Rm>
+ { "MOV", 0xec4f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOV <Rd>,<Rm>
+ { "MOVS", 0xec5f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOVS <Rd>,<Rm>
+ { "RBIT", 0xfb90f0a0, 0xfff0f0f0, THUMB2_2REGS }, // RBIT <Rd>,<Rm>
+ { "REV", 0xfb90f080, 0xfff0f0f0, THUMB2_2REGS }, // REV <Rd>,<Rm>
+ { "REV16", 0xfa90f090, 0xfff0f0f0, THUMB2_2REGS }, // REV16 <Rd>,<Rm>
+ { "REVSH", 0xfa90f0b0, 0xfff0f0f0, THUMB2_2REGS }, // REVSH <Rd>,<Rm>
+ { "RRX", 0xea4f0030, 0xfffff0f0, THUMB2_2REGS }, // RRX <Rd>,<Rm>
+ { "RRXS", 0xea5f0030, 0xfffff0f0, THUMB2_2REGS }, // RRXS <Rd>,<Rm>
+
+ { "MLA", 0xfb000000, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>
+ { "MLS", 0xfb000010, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra>
+
+
+ { "SMLABB", 0xfb100000, 0xfff000f0, THUMB2_4REGS }, // SMLABB <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLABT", 0xfb100010, 0xfff000f0, THUMB2_4REGS }, // SMLABT <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLABB", 0xfb100020, 0xfff000f0, THUMB2_4REGS }, // SMLATB <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLATT", 0xfb100030, 0xfff000f0, THUMB2_4REGS }, // SMLATT <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLAWB", 0xfb300000, 0xfff000f0, THUMB2_4REGS }, // SMLAWB <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLAWT", 0xfb300010, 0xfff000f0, THUMB2_4REGS }, // SMLAWT <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLSD", 0xfb400000, 0xfff000f0, THUMB2_4REGS }, // SMLSD <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLSDX", 0xfb400010, 0xfff000f0, THUMB2_4REGS }, // SMLSDX <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMMLA", 0xfb500000, 0xfff000f0, THUMB2_4REGS }, // SMMLA <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMMLAR", 0xfb500010, 0xfff000f0, THUMB2_4REGS }, // SMMLAR <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMMLS", 0xfb600000, 0xfff000f0, THUMB2_4REGS }, // SMMLS <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMMLSR", 0xfb600010, 0xfff000f0, THUMB2_4REGS }, // SMMLSR <Rd>, <Rn>, <Rm>, <Ra>
+ { "USADA8", 0xfb700000, 0xfff000f0, THUMB2_4REGS }, // USADA8 <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLAD", 0xfb200000, 0xfff000f0, THUMB2_4REGS }, // SMLAD <Rd>, <Rn>, <Rm>, <Ra>
+ { "SMLADX", 0xfb200010, 0xfff000f0, THUMB2_4REGS }, // SMLADX <Rd>, <Rn>, <Rm>, <Ra>
+
+
+ { "B", 0xf0008000, 0xf800d000, B_T3 }, // B<c> <label>
+ { "B", 0xf0009000, 0xf800d000, B_T4 }, // B<c> <label>
+ { "BL", 0xf000d000, 0xf800d000, B_T4 }, // BL<c> <label>
+ { "BLX", 0xf000c000, 0xf800d000, BL_T2 }, // BLX<c> <label>
+
+ { "POP", 0xe8bd0000, 0xffff2000, POP_T2 }, // POP <registers>
+ { "POP", 0xf85d0b04, 0xffff0fff, POP_T3 }, // POP <register>
+ { "PUSH", 0xe8ad0000, 0xffffa000, POP_T2 }, // PUSH <registers>
+ { "PUSH", 0xf84d0d04, 0xffff0fff, POP_T3 }, // PUSH <register>
+ { "STM" , 0xe8800000, 0xffd0a000, STM_FORMAT }, // STM <Rn>{!},<registers>
+ { "STMDB", 0xe9800000, 0xffd0a000, STM_FORMAT }, // STMDB <Rn>{!},<registers>
+ { "LDM" , 0xe8900000, 0xffd02000, STM_FORMAT }, // LDM <Rn>{!},<registers>
+ { "LDMDB", 0xe9100000, 0xffd02000, STM_FORMAT }, // LDMDB <Rn>{!},<registers>
+
+ { "LDR", 0xf8d00000, 0xfff00000, LDM_REG_IMM12 }, // LDR <rt>, [<rn>, {, #<imm12>]}
+ { "LDRB", 0xf8900000, 0xfff00000, LDM_REG_IMM12 }, // LDRB <rt>, [<rn>, {, #<imm12>]}
+ { "LDRH", 0xf8b00000, 0xfff00000, LDM_REG_IMM12 }, // LDRH <rt>, [<rn>, {, #<imm12>]}
+ { "LDRSB", 0xf9900000, 0xfff00000, LDM_REG_IMM12 }, // LDRSB <rt>, [<rn>, {, #<imm12>]}
+ { "LDRSH", 0xf9b00000, 0xfff00000, LDM_REG_IMM12 }, // LDRSH <rt>, [<rn>, {, #<imm12>]}
+
+ { "LDR", 0xf85f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDR <Rt>, <label>
+ { "LDRB", 0xf81f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRB <Rt>, <label>
+ { "LDRH", 0xf83f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRH <Rt>, <label>
+ { "LDRSB", 0xf91f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRSB <Rt>, <label>
+ { "LDRSH", 0xf93f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRSB <Rt>, <label>
+
+ { "LDR", 0xf8500000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDR <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+ { "LDRB", 0xf8100000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRB <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+ { "LDRH", 0xf8300000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRH <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+ { "LDRSB", 0xf9100000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRSB <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+ { "LDRSH", 0xf9300000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRSH <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+
+ { "LDR", 0xf8500800, 0xfff00800, LDM_REG_IMM8 }, // LDR <rt>, [<rn>, {, #<imm8>]}
+ { "LDRBT", 0xf8100e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRBT <rt>, [<rn>, {, #<imm8>]}
+ { "LDRHT", 0xf8300e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRHT <rt>, [<rn>, {, #<imm8>]}
+ { "LDRSB", 0xf9100800, 0xfff00800, LDM_REG_IMM8 }, // LDRHT <rt>, [<rn>, {, #<imm8>]} {!} form?
+ { "LDRSBT",0xf9100e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRHBT <rt>, [<rn>, {, #<imm8>]} {!} form?
+ { "LDRSH" ,0xf9300800, 0xfff00800, LDM_REG_IMM8 }, // LDRSH <rt>, [<rn>, {, #<imm8>]}
+ { "LDRSHT",0xf9300e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRSHT <rt>, [<rn>, {, #<imm8>]}
+ { "LDRT", 0xf8500e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRT <rt>, [<rn>, {, #<imm8>]}
+
+ { "LDRD", 0xe8500000, 0xfe500000, LDRD_REG_IMM8_SIGNED }, // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}
+ { "LDRD", 0xe8500000, 0xfe500000, LDRD_REG_IMM8 }, // LDRD <rt>, <rt2>, <label>
+
+ { "LDREX", 0xe8500f00, 0xfff00f00, LDM_REG_IMM8 }, // LDREX <Rt>, [Rn, {#imm8}]]
+ { "LDREXB", 0xe8d00f4f, 0xfff00fff, LDREXB }, // LDREXB <Rt>, [<Rn>]
+ { "LDREXH", 0xe8d00f5f, 0xfff00fff, LDREXB }, // LDREXH <Rt>, [<Rn>]
+
+ { "LDREXD", 0xe8d00f4f, 0xfff00fff, LDREXD }, // LDREXD <Rt>, <Rt2>, [<Rn>]
+
+ { "STR", 0xf8c00000, 0xfff00000, LDM_REG_IMM12 }, // STR <rt>, [<rn>, {, #<imm12>]}
+ { "STRB", 0xf8800000, 0xfff00000, LDM_REG_IMM12 }, // STRB <rt>, [<rn>, {, #<imm12>]}
+ { "STRH", 0xf8a00000, 0xfff00000, LDM_REG_IMM12 }, // STRH <rt>, [<rn>, {, #<imm12>]}
+
+ { "STR", 0xf8400000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STR <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+ { "STRB", 0xf8000000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STRB <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+ { "STRH", 0xf8200000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STRH <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+
+ { "STR", 0xf8400800, 0xfff00800, LDM_REG_IMM8 }, // STR <rt>, [<rn>, {, #<imm8>]}
+ { "STRH", 0xf8200800, 0xfff00800, LDM_REG_IMM8 }, // STRH <rt>, [<rn>, {, #<imm8>]}
+ { "STRBT", 0xf8000e00, 0xfff00f00, LDM_REG_IMM8 }, // STRBT <rt>, [<rn>, {, #<imm8>]}
+ { "STRHT", 0xf8200e00, 0xfff00f00, LDM_REG_IMM8 }, // STRHT <rt>, [<rn>, {, #<imm8>]}
+ { "STRT", 0xf8400e00, 0xfff00f00, LDM_REG_IMM8 }, // STRT <rt>, [<rn>, {, #<imm8>]}
+
+ { "STRD", 0xe8400000, 0xfe500000, LDRD_REG_IMM8_SIGNED }, // STRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}
+
+ { "STREX", 0xe8400f00, 0xfff00f00, LDM_REG_IMM8 }, // STREX <Rt>, [Rn, {#imm8}]]
+ { "STREXB", 0xe8c00f4f, 0xfff00fff, LDREXB }, // STREXB <Rd>, <Rt>, [<Rn>]
+ { "STREXH", 0xe8c00f5f, 0xfff00fff, LDREXB }, // STREXH <Rd>, <Rt>, [<Rn>]
+
+ { "STREXD", 0xe8d00f4f, 0xfff00fff, LDREXD }, // STREXD <Rd>, <Rt>, <Rt2>, [<Rn>]
+
+ { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT }, // SRSDB<c> SP{!},#<mode>
+ { "SRS" , 0xe98dc000, 0xffdffff0, SRS_FORMAT }, // SRS{IA}<c> SP{!},#<mode>
+ { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT }, // RFEDB<c> <Rn>{!}
+ { "RFE" , 0xe990c000, 0xffd0ffff, RFE_FORMAT } // RFE{IA}<c> <Rn>{!}
+};
+
+CHAR8 *gShiftType[] = {
+ "LSL",
+ "LSR",
+ "ASR",
+ "ROR"
+};
+
+CHAR8 mThumbMregListStr[4*15 + 1];
+
+CHAR8 *
+ThumbMRegList (
+ UINT32 RegBitMask
+ )
+{
+ UINTN Index, Start, End;
+ CHAR8 *Str;
+ BOOLEAN First;
+
+ Str = mThumbMregListStr;
+ *Str = '\0';
+ AsciiStrCat (Str, "{");
+
+ for (Index = 0, First = TRUE; Index <= 15; Index++) {
+ if ((RegBitMask & (1 << Index)) != 0) {
+ Start = End = Index;
+ for (Index++; ((RegBitMask & (1 << Index)) != 0) && (Index <= 9); Index++) {
+ End = Index;
+ }
+
+ if (!First) {
+ AsciiStrCat (Str, ",");
+ } else {
+ First = FALSE;
+ }
+
+ if (Start == End) {
+ AsciiStrCat (Str, gReg[Start]);
+ } else {
+ AsciiStrCat (Str, gReg[Start]);
+ AsciiStrCat (Str, "-");
+ AsciiStrCat (Str, gReg[End]);
+ }
+ }
+ }
+ if (First) {
+ AsciiStrCat (Str, "ERROR");
+ }
+ AsciiStrCat (Str, "}");
+
+ // BugBug: Make caller pass in buffer it is cleaner
+ return mThumbMregListStr;
+}
+
+UINT32
+SignExtend32 (
+ IN UINT32 Data,
+ IN UINT32 TopBit
+ )
+{
+ if (((Data & TopBit) == 0) || (TopBit == BIT31)) {
+ return Data;
+ }
+
+ do {
+ TopBit <<= 1;
+ Data |= TopBit;
+ } while ((TopBit & BIT31) != BIT31);
+
+ return Data;
+}
+
+//
+// Some instructions specify the PC is always considered aligned
+// The PC is after the instruction that is excuting. So you pass
+// in the instruction address and you get back the aligned answer
+//
+UINT32
+PCAlign4 (
+ IN UINT32 Data
+ )
+{
+ return (Data + 4) & 0xfffffffc;
+}
+
+/**
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
+ point to next instructin.
+
+ We cheat and only decode instructions that access
+ memory. If the instruction is not found we dump the instruction in hex.
+
+ @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
+ @param Buf Buffer to sprintf disassembly into.
+ @param Size Size of Buf in bytes.
+ @param Extended TRUE dump hex for instruction too.
+
+**/
+VOID
+DisassembleThumbInstruction (
+ IN UINT16 **OpCodePtrPtr,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size,
+ OUT UINT32 *ItBlock,
+ IN BOOLEAN Extended
+ )
+{
+ UINT16 *OpCodePtr;
+ UINT16 OpCode;
+ UINT32 OpCode32;
+ UINT32 Index;
+ UINT32 Offset;
+ UINT16 Rd, Rn, Rm, Rt, Rt2;
+ BOOLEAN H1, H2, imod;
+ //BOOLEAN ItFlag;
+ UINT32 PC, Target, msbit, lsbit;
+ CHAR8 *Cond;
+ BOOLEAN S, J1, J2, P, U, W;
+ UINT32 coproc, opc1, opc2, CRd, CRn, CRm;
+ UINT32 Mask;
+
+ OpCodePtr = *OpCodePtrPtr;
+ OpCode = **OpCodePtrPtr;
+
+ // Thumb2 is a stream of 16-bit instructions not a 32-bit instruction.
+ OpCode32 = (((UINT32)OpCode) << 16) | *(OpCodePtr + 1);
+
+ // These register names match branch form, but not others
+ Rd = OpCode & 0x7;
+ Rn = (OpCode >> 3) & 0x7;
+ Rm = (OpCode >> 6) & 0x7;
+ H1 = (OpCode & BIT7) != 0;
+ H2 = (OpCode & BIT6) != 0;
+ imod = (OpCode & BIT4) != 0;
+ PC = (UINT32)(UINTN)OpCodePtr;
+
+ // Increment by the minimum instruction size, Thumb2 could be bigger
+ *OpCodePtrPtr += 1;
+
+ // Manage IT Block ItFlag TRUE means we are in an IT block
+ /*if (*ItBlock != 0) {
+ ItFlag = TRUE;
+ *ItBlock -= 1;
+ } else {
+ ItFlag = FALSE;
+ }*/
+
+ for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {
+ if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {
+ if (Extended) {
+ Offset = AsciiSPrint (Buf, Size, "0x%04x %-6a", OpCode, gOpThumb[Index].Start);
+ } else {
+ Offset = AsciiSPrint (Buf, Size, "%-6a", gOpThumb[Index].Start);
+ }
+ switch (gOpThumb[Index].AddressMode) {
+ case LOAD_STORE_FORMAT1:
+ // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 4) & 0x7c);
+ return;
+ case LOAD_STORE_FORMAT1_H:
+ // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 5) & 0x3e);
+ return;
+ case LOAD_STORE_FORMAT1_B:
+ // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 6) & 0x1f);
+ return;
+
+ case LOAD_STORE_FORMAT2:
+ // A6.5.1 <Rd>, [<Rn>, <Rm>]
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, Rn, Rm);
+ return;
+ case LOAD_STORE_FORMAT3:
+ // A6.5.1 <Rd>, [PC, #<8_bit_offset>]
+ Target = (OpCode & 0xff) << 2;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x] ;0x%08x", (OpCode >> 8) & 7, Target, PCAlign4 (PC) + Target);
+ return;
+ case LOAD_STORE_FORMAT4:
+ // Rt, [SP, #imm8]
+ Target = (OpCode & 0xff) << 2;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, Target);
+ return;
+
+ case LOAD_STORE_MULTIPLE_FORMAT1:
+ // <Rn>!, {r0-r7}
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode & 0xff));
+ return;
+
+ case POP_FORMAT:
+ // POP {r0-r7,pc}
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT15 : 0)));
+ return;
+
+ case PUSH_FORMAT:
+ // PUSH {r0-r7,lr}
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT14 : 0)));
+ return;
+
+
+ case IMMED_8:
+ // A6.7 <immed_8>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff);
+ return;
+
+ case CONDITIONAL_BRANCH:
+ // A6.3.1 B<cond> <target_address>
+ // Patch in the condition code. A little hack but based on "%-6a"
+ Cond = gCondition[(OpCode >> 8) & 0xf];
+ Buf[Offset-5] = *Cond++;
+ Buf[Offset-4] = *Cond;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend32 ((OpCode & 0xff) << 1, BIT8));
+ return;
+ case UNCONDITIONAL_BRANCH_SHORT:
+ // A6.3.2 B <target_address>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend32 ((OpCode & 0x3ff) << 1, BIT11));
+ return;
+
+ case BRANCH_EXCHANGE:
+ // A6.3.3 BX|BLX <Rm>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[Rn | (H2 ? 8:0)]);
+ return;
+
+ case DATA_FORMAT1:
+ // A6.4.3 <Rd>, <Rn>, <Rm>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm);
+ return;
+ case DATA_FORMAT2:
+ // A6.4.3 <Rd>, <Rn>, #3_bit_immed
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm);
+ return;
+ case DATA_FORMAT3:
+ // A6.4.3 <Rd>|<Rn>, #imm8
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, #0x%x", (OpCode >> 8) & 7, OpCode & 0xff);
+ return;
+ case DATA_FORMAT4:
+ // A6.4.3 <Rd>|<Rm>, #immed_5
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f);
+ return;
+ case DATA_FORMAT5:
+ // A6.4.3 <Rd>|<Rm>, <Rm>|<Rs>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn);
+ return;
+ case DATA_FORMAT6_SP:
+ // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2);
+ return;
+ case DATA_FORMAT6_PC:
+ // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2);
+ return;
+ case DATA_FORMAT7:
+ // A6.4.3 SP, SP, #<7_Bit_immed>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp, 0x%x", (OpCode & 0x7f)*4);
+ return;
+ case DATA_FORMAT8:
+ // A6.4.3 <Rd>|<Rn>, <Rm>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]);
+ return;
+
+ case CPS_FORMAT:
+ // A7.1.24
+ AsciiSPrint (&Buf[Offset], Size - Offset, "%a %a%a%a", imod ? "ID":"IE", ((OpCode & BIT2) == 0) ? "":"a", ((OpCode & BIT1) == 0) ? "":"i", ((OpCode & BIT0) == 0) ? "":"f");
+ return;
+
+ case ENDIAN_FORMAT:
+ // A7.1.24
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE");
+ return;
+
+ case DATA_CBZ:
+ // CB{N}Z <Rn>, <Lable>
+ Target = ((OpCode >> 2) & 0x3e) | (((OpCode & BIT9) == BIT9) ? BIT6 : 0);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[Rd], PC + 4 + Target);
+ return;
+
+ case ADR_FORMAT:
+ // ADR <Rd>, <Label>
+ Target = (OpCode & 0xff) << 2;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[(OpCode >> 8) & 7], PCAlign4 (PC) + Target);
+ return;
+
+ case IT_BLOCK:
+ // ITSTATE = cond:mask OpCode[7:4]:OpCode[3:0]
+ // ITSTATE[7:5] == cond[3:1]
+ // ITSTATE[4] == 1st Instruction cond[0]
+ // ITSTATE[3] == 2st Instruction cond[0]
+ // ITSTATE[2] == 3st Instruction cond[0]
+ // ITSTATE[1] == 4st Instruction cond[0]
+ // ITSTATE[0] == 1 4 instruction IT block. 0 means 0,1,2 or 3 instructions
+ // 1st one in ITSTATE low bits defines the number of instructions
+ Mask = (OpCode & 0xf);
+ if ((Mask & 0x1) == 0x1) {
+ *ItBlock = 4;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E", (Mask & BIT1)?"T":"E");
+ } else if ((OpCode & 0x3) == 0x2) {
+ *ItBlock = 3;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E");
+ } else if ((OpCode & 0x7) == 0x4) {
+ *ItBlock = 2;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, "%a", (Mask & BIT3)?"T":"E");
+ } else if ((OpCode & 0xf) == 0x8) {
+ *ItBlock = 1;
+ }
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gCondition[(OpCode >> 4) & 0xf]);
+ return;
+ }
+ }
+ }
+
+
+ // Thumb2 are 32-bit instructions
+ *OpCodePtrPtr += 1;
+ Rt = (OpCode32 >> 12) & 0xf;
+ Rt2 = (OpCode32 >> 8) & 0xf;
+ Rd = (OpCode32 >> 8) & 0xf;
+ Rm = (OpCode32 & 0xf);
+ Rn = (OpCode32 >> 16) & 0xf;
+ for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) {
+ if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) {
+ if (Extended) {
+ Offset = AsciiSPrint (Buf, Size, "0x%04x %-6a", OpCode32, gOpThumb2[Index].Start);
+ } else {
+ Offset = AsciiSPrint (Buf, Size, " %-6a", gOpThumb2[Index].Start);
+ }
+ switch (gOpThumb2[Index].AddressMode) {
+ case B_T3:
+ Cond = gCondition[(OpCode32 >> 22) & 0xf];
+ Buf[Offset-5] = *Cond++;
+ Buf[Offset-4] = *Cond;
+ // S:J2:J1:imm6:imm11:0
+ Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3f000);
+ Target |= ((OpCode32 & BIT11) == BIT11)? BIT19 : 0; // J2
+ Target |= ((OpCode32 & BIT13) == BIT13)? BIT18 : 0; // J1
+ Target |= ((OpCode32 & BIT26) == BIT26)? BIT20 : 0; // S
+ Target = SignExtend32 (Target, BIT20);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target);
+ return;
+ case B_T4:
+ // S:I1:I2:imm10:imm11:0
+ Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3ff000);
+ S = (OpCode32 & BIT26) == BIT26;
+ J1 = (OpCode32 & BIT13) == BIT13;
+ J2 = (OpCode32 & BIT11) == BIT11;
+ Target |= (!(J2 ^ S) ? BIT22 : 0); // I2
+ Target |= (!(J1 ^ S) ? BIT23 : 0); // I1
+ Target |= (S ? BIT24 : 0); // S
+ Target = SignExtend32 (Target, BIT24);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target);
+ return;
+
+ case BL_T2:
+ // BLX S:I1:I2:imm10:imm11:0
+ Target = ((OpCode32 << 1) & 0xffc) + ((OpCode32 >> 4) & 0x3ff000);
+ S = (OpCode32 & BIT26) == BIT26;
+ J1 = (OpCode32 & BIT13) == BIT13;
+ J2 = (OpCode32 & BIT11) == BIT11;
+ Target |= (!(J2 ^ S) ? BIT23 : 0); // I2
+ Target |= (!(J1 ^ S) ? BIT24 : 0); // I1
+ Target |= (S ? BIT25 : 0); // S
+ Target = SignExtend32 (Target, BIT25);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PCAlign4 (PC) + Target);
+ return;
+
+ case POP_T2:
+ // <reglist> some must be zero, handled in table
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList (OpCode32 & 0xffff));
+ return;
+
+ case POP_T3:
+ // <register>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[(OpCode32 >> 12) & 0xf]);
+ return;
+
+ case STM_FORMAT:
+ // <Rn>{!}, <registers>
+ W = (OpCode32 & BIT21) == BIT21;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, %a", gReg[(OpCode32 >> 16) & 0xf], W ? "!":"", ThumbMRegList (OpCode32 & 0xffff));
+ return;
+
+ case LDM_REG_IMM12_SIGNED:
+ // <rt>, <label>
+ Target = OpCode32 & 0xfff;
+ if ((OpCode32 & BIT23) == 0) {
+ // U == 0 means subtrack, U == 1 means add
+ Target = -Target;
+ }
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[(OpCode32 >> 12) & 0xf], PCAlign4 (PC) + Target);
+ return;
+
+ case LDM_REG_INDIRECT_LSL:
+ // <rt>, [<rn>, <rm> {, LSL #<imm2>]}
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a, %a", gReg[Rt], gReg[Rn], gReg[Rm]);
+ if (((OpCode32 >> 4) & 3) == 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, "]");
+ } else {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL #%d]", (OpCode32 >> 4) & 3);
+ }
+ return;
+
+ case LDM_REG_IMM12:
+ // <rt>, [<rn>, {, #<imm12>]}
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]);
+ if ((OpCode32 & 0xfff) == 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, "]");
+ } else {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ", #0x%x]", OpCode32 & 0xfff);
+ }
+ return;
+
+ case LDM_REG_IMM8:
+ // <rt>, [<rn>, {, #<imm8>}]{!}
+ W = (OpCode32 & BIT8) == BIT8;
+ U = (OpCode32 & BIT9) == BIT9;
+ P = (OpCode32 & BIT10) == BIT10;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]);
+ if (P) {
+ if ((OpCode32 & 0xff) == 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, "]%a", W?"!":"");
+ } else {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-" , OpCode32 & 0xff, W?"!":"");
+ }
+ } else {
+ AsciiSPrint (&Buf[Offset], Size - Offset, "], #%a0x%x", U?"":"-", OpCode32 & 0xff);
+ }
+ return;
+
+ case LDRD_REG_IMM8_SIGNED:
+ // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!}
+ P = (OpCode32 & BIT24) == BIT24; // index = P
+ U = (OpCode32 & BIT23) == BIT23;
+ W = (OpCode32 & BIT21) == BIT21;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, [%a", gReg[Rt], gReg[Rt2], gReg[Rn]);
+ if (P) {
+ if ((OpCode32 & 0xff) == 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, "]");
+ } else {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-", (OpCode32 & 0xff) << 2, W?"!":"");
+ }
+ } else {
+ if ((OpCode32 & 0xff) != 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x", U?"":"-", (OpCode32 & 0xff) << 2);
+ }
+ }
+ return;
+
+ case LDRD_REG_IMM8:
+ // LDRD <rt>, <rt2>, <label>
+ Target = (OpCode32 & 0xff) << 2;
+ if ((OpCode32 & BIT23) == 0) {
+ // U == 0 means subtrack, U == 1 means add
+ Target = -Target;
+ }
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rt], gReg[Rt2], PC + 4 + Target);
+ return;
+
+ case LDREXB:
+ // LDREXB <Rt>, [Rn]
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a]", gReg[Rt], gReg[Rn]);
+ return;
+
+ case LDREXD:
+ // LDREXD <Rt>, <Rt2>, [<Rn>]
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, ,%a, [%a]", gReg[Rt], gReg[Rt2], gReg[Rn]);
+ return;
+
+ case SRS_FORMAT:
+ // SP{!}, #<mode>
+ W = (OpCode32 & BIT21) == BIT21;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " SP%a, #0x%x", W?"!":"", OpCode32 & 0x1f);
+ return;
+
+ case RFE_FORMAT:
+ // <Rn>{!}
+ W = (OpCode32 & BIT21) == BIT21;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, #0x%x", gReg[Rn], W?"!":"");
+ return;
+
+ case ADD_IMM12:
+ // ADD{S} <Rd>, <Rn>, #<const> i:imm3:imm8
+ if ((OpCode32 & BIT20) == BIT20) {
+ Buf[Offset - 3] = 'S'; // assume %-6a
+ }
+ Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #0x%x", gReg[Rd], gReg[Rn], Target);
+ return;
+
+ case ADD_IMM12_1REG:
+ // MOV{S} <Rd>, #<const> i:imm3:imm8
+ if ((OpCode32 & BIT20) == BIT20) {
+ Buf[Offset - 3] = 'S'; // assume %-6a
+ }
+ Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target);
+ return;
+
+ case THUMB2_IMM16:
+ // MOVW <Rd>, #<const> i:imm3:imm8
+ Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);
+ Target |= ((OpCode32 >> 4) & 0xf0000);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target);
+ return;
+
+ case ADD_IMM5:
+ // ADC{S} <Rd>, <Rn>, <Rm> {,LSL #<const>} imm3:imm2
+ if ((OpCode32 & BIT20) == BIT20) {
+ Buf[Offset - 3] = 'S'; // assume %-6a
+ }
+ Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm]);
+ if (Target != 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target);
+ }
+ return;
+
+ case ADD_IMM5_2REG:
+ // CMP <Rn>, <Rm> {,LSL #<const>} imm3:imm2
+ Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rn], gReg[Rm]);
+ if (Target != 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target);
+ }
+
+
+ case ASR_IMM5:
+ // ARS <Rd>, <Rm> #<const>} imm3:imm2
+ if ((OpCode32 & BIT20) == BIT20) {
+ Buf[Offset - 3] = 'S'; // assume %-6a
+ }
+ Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a #%d", gReg[Rd], gReg[Rm], Target);
+ return;
+
+ case ASR_3REG:
+ // ARS <Rd>, <Rn>, <Rm>
+ if ((OpCode32 & BIT20) == BIT20) {
+ Buf[Offset - 3] = 'S'; // assume %-6a
+ }
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a %a", gReg[Rd], gReg[Rn], gReg[Rm]);
+ return;
+
+ case ADR_THUMB2:
+ // ADDR <Rd>, <label>
+ Target = (OpCode32 & 0xff) | ((OpCode32 >> 8) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);
+ if ((OpCode & (BIT23 | BIT21)) == (BIT23 | BIT21)) {
+ Target = PCAlign4 (PC) - Target;
+ } else {
+ Target = PCAlign4 (PC) + Target;
+ }
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, 0x%08x", gReg[Rd], Target);
+ return;
+
+ case CMN_THUMB2:
+ // CMN <Rn>, #<const>}
+ Target = (OpCode32 & 0xff) | ((OpCode >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0);
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rn], Target);
+ return;
+
+ case BFC_THUMB2:
+ // BFI <Rd>, <Rn>, #<lsb>, #<width>
+ msbit = OpCode32 & 0x1f;
+ lsbit = ((OpCode32 >> 6) & 3) | ((OpCode >> 10) & 0x1c);
+ if ((Rn == 0xf) & (AsciiStrCmp (gOpThumb2[Index].Start, "BFC") == 0)){
+ // BFC <Rd>, #<lsb>, #<width>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #%d, #%d", gReg[Rd], lsbit, msbit - lsbit + 1);
+ } else if (AsciiStrCmp (gOpThumb2[Index].Start, "BFI") == 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit - lsbit + 1);
+ } else {
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit + 1);
+ }
+ return;
+
+ case CPD_THUMB2:
+ // <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2>
+ coproc = (OpCode32 >> 8) & 0xf;
+ opc1 = (OpCode32 >> 20) & 0xf;
+ opc2 = (OpCode32 >> 5) & 0x7;
+ CRd = (OpCode32 >> 12) & 0xf;
+ CRn = (OpCode32 >> 16) & 0xf;
+ CRm = OpCode32 & 0xf;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,c%d,c%d,c%d", coproc, opc1, CRd, CRn, CRm);
+ if (opc2 != 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);
+ }
+ return;
+
+ case MRC_THUMB2:
+ // MRC <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2>
+ coproc = (OpCode32 >> 8) & 0xf;
+ opc1 = (OpCode32 >> 20) & 0xf;
+ opc2 = (OpCode32 >> 5) & 0x7;
+ CRn = (OpCode32 >> 16) & 0xf;
+ CRm = OpCode32 & 0xf;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,c%d,c%d", coproc, opc1, gReg[Rt], CRn, CRm);
+ if (opc2 != 0) {
+ AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2);
+ }
+ return;
+
+ case MRRC_THUMB2:
+ // MRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>,<opc2>
+ coproc = (OpCode32 >> 8) & 0xf;
+ opc1 = (OpCode32 >> 20) & 0xf;
+ CRn = (OpCode32 >> 16) & 0xf;
+ CRm = OpCode32 & 0xf;
+ Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,%a,c%d", coproc, opc1, gReg[Rt], gReg[Rt2], CRm);
+ return;
+
+ case THUMB2_2REGS:
+ // <Rd>, <Rm>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd], gReg[Rm]);
+ return;
+
+ case THUMB2_4REGS:
+ // <Rd>, <Rn>, <Rm>, <Ra>
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm], gReg[Rt]);
+ return;
+
+ case THUMB2_MRS:
+ // MRS <Rd>, CPSR
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, CPSR", gReg[Rd]);
+ return;
+
+ case THUMB2_MSR:
+ // MRS CPSR_<fields>, <Rd>
+ Target = (OpCode32 >> 10) & 3;
+ AsciiSPrint (&Buf[Offset], Size - Offset, " CPSR_%a%a, %a", (Target & 2) == 0 ? "":"f", (Target & 1) == 0 ? "":"s", gReg[Rd]);
+ return;
+
+ case THUMB2_NO_ARGS:
+ default:
+ break;
+ }
+ }
+ }
+
+ AsciiSPrint (Buf, Size, "0x%08x", OpCode32);
+}
+
+
+
+VOID
+DisassembleArmInstruction (
+ IN UINT32 **OpCodePtr,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size,
+ IN BOOLEAN Extended
+ );
+
+
+/**
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
+ point to next instructin.
+
+ We cheat and only decode instructions that access
+ memory. If the instruction is not found we dump the instruction in hex.
+
+ @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
+ @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
+ @param Extended TRUE dump hex for instruction too.
+ @param ItBlock Size of IT Block
+ @param Buf Buffer to sprintf disassembly into.
+ @param Size Size of Buf in bytes.
+
+**/
+VOID
+DisassembleInstruction (
+ IN UINT8 **OpCodePtr,
+ IN BOOLEAN Thumb,
+ IN BOOLEAN Extended,
+ IN OUT UINT32 *ItBlock,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size
+ )
+{
+ if (Thumb) {
+ DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size, ItBlock, Extended);
+ } else {
+ DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size, Extended);
+ }
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c
new file mode 100755
index 0000000..12b1940
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.c
@@ -0,0 +1,284 @@
+/** @file
+ Generic ARM implementation of DmaLib.h
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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 <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/DmaLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ArmLib.h>
+
+#include <Protocol/Cpu.h>
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS HostAddress;
+ EFI_PHYSICAL_ADDRESS DeviceAddress;
+ UINTN NumberOfBytes;
+ DMA_MAP_OPERATION Operation;
+ BOOLEAN DoubleBuffer;
+} MAP_INFO_INSTANCE;
+
+
+
+EFI_CPU_ARCH_PROTOCOL *gCpu;
+UINTN gCacheAlignment = 0;
+
+/**
+ Provides the DMA controller-specific addresses needed to access system memory.
+
+ Operation is relative to the DMA bus master.
+
+ @param Operation Indicates if the bus master is going to read or write to system memory.
+ @param HostAddress The system memory address to map to the DMA controller.
+ @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
+ that were mapped.
+ @param DeviceAddress The resulting map address for the bus master controller to use to
+ access the hosts HostAddress.
+ @param Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+
+**/
+EFI_STATUS
+EFIAPI
+DmaMap (
+ IN DMA_MAP_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ EFI_STATUS Status;
+ MAP_INFO_INSTANCE *Map;
+ VOID *Buffer;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
+
+ if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Operation >= MapOperationMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *DeviceAddress = ConvertToPhysicalAddress (HostAddress);
+
+ // Remember range so we can flush on the other side
+ Map = AllocatePool (sizeof (MAP_INFO_INSTANCE));
+ if (Map == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Mapping = Map;
+
+ if ((((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) ||
+ ((*NumberOfBytes % gCacheAlignment) != 0)) {
+
+ // Get the cacheability of the region
+ Status = gDS->GetMemorySpaceDescriptor (*DeviceAddress, &GcdDescriptor);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // If the mapped buffer is not an uncached buffer
+ if ( (GcdDescriptor.Attributes != EFI_MEMORY_WC) &&
+ (GcdDescriptor.Attributes != EFI_MEMORY_UC) )
+ {
+ //
+ // If the buffer does not fill entire cache lines we must double buffer into
+ // uncached memory. Device (PCI) address becomes uncached page.
+ //
+ Map->DoubleBuffer = TRUE;
+ Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {
+ CopyMem (Buffer, HostAddress, *NumberOfBytes);
+ }
+
+ *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;
+ } else {
+ Map->DoubleBuffer = FALSE;
+ }
+ } else {
+ Map->DoubleBuffer = FALSE;
+
+ // Flush the Data Cache (should not have any effect if the memory region is uncached)
+ gCpu->FlushDataCache (gCpu, *DeviceAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);
+
+ if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {
+ // In case the buffer is used for instance to send command to a PCI controller, we must ensure the memory is uncached
+ Status = gDS->SetMemorySpaceAttributes (*DeviceAddress & ~(BASE_4KB - 1), ALIGN_VALUE (*NumberOfBytes, BASE_4KB), EFI_MEMORY_WC);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ Map->HostAddress = (UINTN)HostAddress;
+ Map->DeviceAddress = *DeviceAddress;
+ Map->NumberOfBytes = *NumberOfBytes;
+ Map->Operation = Operation;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Completes the DmaMapBusMasterRead(), DmaMapBusMasterWrite(), or DmaMapBusMasterCommonBuffer()
+ operation and releases any corresponding resources.
+
+ @param Mapping The mapping value returned from DmaMap*().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+
+**/
+EFI_STATUS
+EFIAPI
+DmaUnmap (
+ IN VOID *Mapping
+ )
+{
+ MAP_INFO_INSTANCE *Map;
+
+ if (Mapping == NULL) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Map = (MAP_INFO_INSTANCE *)Mapping;
+
+ if (Map->DoubleBuffer) {
+ if ((Map->Operation == MapOperationBusMasterWrite) || (Map->Operation == MapOperationBusMasterCommonBuffer)) {
+ CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes);
+ }
+
+ DmaFreeBuffer (EFI_SIZE_TO_PAGES (Map->NumberOfBytes), (VOID *)(UINTN)Map->DeviceAddress);
+
+ } else {
+ if (Map->Operation == MapOperationBusMasterWrite) {
+ //
+ // Make sure we read buffer from uncached memory and not the cache
+ //
+ gCpu->FlushDataCache (gCpu, Map->HostAddress, Map->NumberOfBytes, EfiCpuFlushTypeInvalidate);
+ }
+ }
+
+ FreePool (Map);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Allocates pages that are suitable for an DmaMap() of type MapOperationBusMasterCommonBuffer.
+ mapping.
+
+ @param MemoryType The type of memory to allocate, EfiBootServicesData or
+ EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the
+ allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+DmaAllocateBuffer (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress
+ )
+{
+ if (HostAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
+ //
+ // We used uncached memory to keep coherency
+ //
+ if (MemoryType == EfiBootServicesData) {
+ *HostAddress = UncachedAllocatePages (Pages);
+ } else if (MemoryType == EfiRuntimeServicesData) {
+ *HostAddress = UncachedAllocateRuntimePages (Pages);
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Frees memory that was allocated with DmaAllocateBuffer().
+
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with DmaAllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+DmaFreeBuffer (
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+{
+ if (HostAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UncachedFreePages (HostAddress, Pages);
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+ArmDmaLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ // Get the Cpu protocol for later use
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
+ ASSERT_EFI_ERROR(Status);
+
+ gCacheAlignment = ArmDataCacheLineLength ();
+
+ return Status;
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
new file mode 100755
index 0000000..20228d2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
@@ -0,0 +1,50 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = ArmDmaLib
+ FILE_GUID = F1BD6B36-B705-43aa-8A28-33F58ED85EFB
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DmaLib
+ CONSTRUCTOR = ArmDmaLibConstructor
+
+[Sources.common]
+ ArmDmaLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+
+
+[LibraryClasses]
+ DebugLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ UncachedMemoryAllocationLib
+ IoLib
+ BaseMemoryLib
+ ArmLib
+
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[Guids]
+
+[Pcd]
+
+[Depex]
+ gEfiCpuArchProtocolGuid
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.c
new file mode 100644
index 0000000..826827f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.c
@@ -0,0 +1,139 @@
+/** @file
+
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2014, Linaro 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 <Library/ArmGenericTimerCounterLib.h>
+#include <Library/ArmArchTimer.h>
+
+VOID
+EFIAPI
+ArmGenericTimerEnableTimer (
+ VOID
+ )
+{
+ UINTN TimerCtrlReg;
+
+ ArmArchTimerReadReg (CntpCtl, (VOID *)&TimerCtrlReg);
+ TimerCtrlReg |= ARM_ARCH_TIMER_ENABLE;
+ ArmArchTimerWriteReg (CntpCtl, (VOID *)&TimerCtrlReg);
+}
+
+VOID
+EFIAPI
+ArmGenericTimerDisableTimer (
+ VOID
+ )
+{
+ UINTN TimerCtrlReg;
+
+ ArmArchTimerReadReg (CntpCtl, (VOID *)&TimerCtrlReg);
+ TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;
+ ArmArchTimerWriteReg (CntpCtl, (VOID *)&TimerCtrlReg);
+}
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerFreq (
+ IN UINTN FreqInHz
+ )
+{
+ ArmArchTimerWriteReg (CntFrq, (VOID *)&FreqInHz);
+}
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerFreq (
+ VOID
+ )
+{
+ UINTN ArchTimerFreq = 0;
+ ArmArchTimerReadReg (CntFrq, (VOID *)&ArchTimerFreq);
+ return ArchTimerFreq;
+}
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerVal (
+ VOID
+ )
+{
+ UINTN ArchTimerValue;
+ ArmArchTimerReadReg (CntpTval, (VOID *)&ArchTimerValue);
+
+ return ArchTimerValue;
+}
+
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerVal (
+ IN UINTN Value
+ )
+{
+ ArmArchTimerWriteReg (CntpTval, (VOID *)&Value);
+}
+
+UINT64
+EFIAPI
+ArmGenericTimerGetSystemCount (
+ VOID
+ )
+{
+ UINT64 SystemCount;
+ ArmArchTimerReadReg (CntPct, (VOID *)&SystemCount);
+
+ return SystemCount;
+}
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerCtrlReg (
+ VOID
+ )
+{
+ UINTN Value;
+ ArmArchTimerReadReg (CntpCtl, (VOID *)&Value);
+
+ return Value;
+}
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerCtrlReg (
+ UINTN Value
+ )
+{
+ ArmArchTimerWriteReg (CntpCtl, (VOID *)&Value);
+}
+
+UINT64
+EFIAPI
+ArmGenericTimerGetCompareVal (
+ VOID
+ )
+{
+ UINT64 Value;
+ ArmArchTimerReadReg (CntpCval, (VOID *)&Value);
+
+ return Value;
+}
+
+VOID
+EFIAPI
+ArmGenericTimerSetCompareVal (
+ IN UINT64 Value
+ )
+{
+ ArmArchTimerWriteReg (CntpCval, (VOID *)&Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
new file mode 100644
index 0000000..5420608
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
@@ -0,0 +1,33 @@
+#/** @file
+# Implement ArmGenericTimerCounterLib using the physical timer
+#
+# Copyright (c) 2014, Linaro 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 = ArmGenericTimerPhyCounterLib
+ FILE_GUID = 7A07E61D-9967-407F-AE85-2EB0B50BEF2C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmGenericTimerCounterLib
+
+[Sources]
+ ArmGenericTimerPhyCounterLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ BaseLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c
new file mode 100644
index 0000000..f99c852
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c
@@ -0,0 +1,149 @@
+/** @file
+
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2014, Linaro 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 <Library/ArmGenericTimerCounterLib.h>
+#include <Library/ArmArchTimer.h>
+
+VOID
+EFIAPI
+ArmGenericTimerEnableTimer (
+ VOID
+ )
+{
+ UINTN TimerCtrlReg;
+
+ ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg);
+ TimerCtrlReg |= ARM_ARCH_TIMER_ENABLE;
+
+ //
+ // When running under KVM, we need to unmask the interrupt on the timer side
+ // as KVM will mask it when servicing the interrupt at the hypervisor level
+ // and delivering the virtual timer interrupt to the guest. Otherwise, the
+ // interrupt will fire again, trapping into the hypervisor again, etc. etc.
+ // This is scheduled to be fixed on the KVM side, but there is no harm in
+ // leaving this in once KVM gets fixed.
+ //
+ TimerCtrlReg &= ~ARM_ARCH_TIMER_IMASK;
+ ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg);
+}
+
+VOID
+EFIAPI
+ArmGenericTimerDisableTimer (
+ VOID
+ )
+{
+ UINTN TimerCtrlReg;
+
+ ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg);
+ TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;
+ ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg);
+}
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerFreq (
+ IN UINTN FreqInHz
+ )
+{
+ ArmArchTimerWriteReg (CntFrq, (VOID *)&FreqInHz);
+}
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerFreq (
+ VOID
+ )
+{
+ UINTN ArchTimerFreq = 0;
+ ArmArchTimerReadReg (CntFrq, (VOID *)&ArchTimerFreq);
+ return ArchTimerFreq;
+}
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerVal (
+ VOID
+ )
+{
+ UINTN ArchTimerValue;
+ ArmArchTimerReadReg (CntvTval, (VOID *)&ArchTimerValue);
+
+ return ArchTimerValue;
+}
+
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerVal (
+ IN UINTN Value
+ )
+{
+ ArmArchTimerWriteReg (CntvTval, (VOID *)&Value);
+}
+
+UINT64
+EFIAPI
+ArmGenericTimerGetSystemCount (
+ VOID
+ )
+{
+ UINT64 SystemCount;
+ ArmArchTimerReadReg (CntvCt, (VOID *)&SystemCount);
+
+ return SystemCount;
+}
+
+UINTN
+EFIAPI
+ArmGenericTimerGetTimerCtrlReg (
+ VOID
+ )
+{
+ UINTN Value;
+ ArmArchTimerReadReg (CntvCtl, (VOID *)&Value);
+
+ return Value;
+}
+
+VOID
+EFIAPI
+ArmGenericTimerSetTimerCtrlReg (
+ UINTN Value
+ )
+{
+ ArmArchTimerWriteReg (CntvCtl, (VOID *)&Value);
+}
+
+UINT64
+EFIAPI
+ArmGenericTimerGetCompareVal (
+ VOID
+ )
+{
+ UINT64 Value;
+ ArmArchTimerReadReg (CntvCval, (VOID *)&Value);
+
+ return Value;
+}
+
+VOID
+EFIAPI
+ArmGenericTimerSetCompareVal (
+ IN UINT64 Value
+ )
+{
+ ArmArchTimerWriteReg (CntvCval, (VOID *)&Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
new file mode 100644
index 0000000..9267dc3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf
@@ -0,0 +1,33 @@
+#/** @file
+# Implement ArmGenericTimerCounterLib using the virtual timer
+#
+# Copyright (c) 2014, Linaro 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 = ArmGenericTimerVirtCounterLib
+ FILE_GUID = 3C0D77CC-4F27-49C8-B25C-2D01D81ED4D8
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmGenericTimerCounterLib
+
+[Sources]
+ ArmGenericTimerVirtCounterLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ BaseLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S
new file mode 100644
index 0000000..99a1d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S
@@ -0,0 +1,42 @@
+//
+// Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+// Copyright (c) 2014, Linaro Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmCallHvc)
+
+ASM_PFX(ArmCallHvc):
+ // Push x0 on the stack - The stack must always be quad-word aligned
+ str x0, [sp, #-16]!
+
+ // Load the HVC arguments values into the appropriate registers
+ ldp x6, x7, [x0, #48]
+ ldp x4, x5, [x0, #32]
+ ldp x2, x3, [x0, #16]
+ ldp x0, x1, [x0, #0]
+
+ hvc #0
+
+ // Pop the ARM_HVC_ARGS structure address from the stack into x9
+ ldr x9, [sp], #16
+
+ // Store the HVC returned values into the ARM_HVC_ARGS structure.
+ // A HVC call can return up to 4 values
+ stp x2, x3, [x9, #16]
+ stp x0, x1, [x9, #0]
+
+ mov x0, x9
+
+ ret
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S
new file mode 100644
index 0000000..25ceb6a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+// Copyright (c) 2014, Linaro Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+.text
+.align 3
+.arch_extension virt
+
+GCC_ASM_EXPORT(ArmCallHvc)
+
+ASM_PFX(ArmCallHvc):
+ push {r4-r8}
+ // r0 will be popped just after the HVC call
+ push {r0}
+
+ // Load the HVC arguments values into the appropriate registers
+ ldr r7, [r0, #28]
+ ldr r6, [r0, #24]
+ ldr r5, [r0, #20]
+ ldr r4, [r0, #16]
+ ldr r3, [r0, #12]
+ ldr r2, [r0, #8]
+ ldr r1, [r0, #4]
+ ldr r0, [r0, #0]
+
+ hvc #0
+
+ // Pop the ARM_HVC_ARGS structure address from the stack into r8
+ pop {r8}
+
+ // Load the HVC returned values into the appropriate registers
+ // A HVC call can return up to 4 values - we do not need to store back r4-r7.
+ str r3, [r8, #12]
+ str r2, [r8, #8]
+ str r1, [r8, #4]
+ str r0, [r8, #0]
+
+ mov r0, r8
+
+ // Restore the registers r4-r8
+ pop {r4-r8}
+
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm
new file mode 100644
index 0000000..bac26fb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.asm
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+// Copyright (c) 2014, Linaro Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+ EXPORT ArmCallHvc
+
+ AREA ArmHvc, CODE, READONLY
+
+ArmCallHvc
+ push {r4-r8}
+ // r0 will be popped just after the HVC call
+ push {r0}
+
+ // Load the HVC arguments values into the appropriate registers
+ ldr r7, [r0, #28]
+ ldr r6, [r0, #24]
+ ldr r5, [r0, #20]
+ ldr r4, [r0, #16]
+ ldr r3, [r0, #12]
+ ldr r2, [r0, #8]
+ ldr r1, [r0, #4]
+ ldr r0, [r0, #0]
+
+ hvc #0
+
+ // Pop the ARM_HVC_ARGS structure address from the stack into r8
+ pop {r8}
+
+ // Load the HVC returned values into the appropriate registers
+ // A HVC call can return up to 4 values - we do not need to store back r4-r7.
+ str r3, [r8, #12]
+ str r2, [r8, #8]
+ str r1, [r8, #4]
+ str r0, [r8, #0]
+
+ mov r0, r8
+
+ // Restore the registers r4-r8
+ pop {r4-r8}
+
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
new file mode 100644
index 0000000..92efac5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
@@ -0,0 +1,32 @@
+#/** @file
+#
+# Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2014, Linaro 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 = ArmHvcLib
+ FILE_GUID = E594959A-D150-44D3-963B-BA90329D3D9A
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmHvcLib
+
+[Sources.ARM]
+ Arm/ArmHvc.asm | RVCT
+ Arm/ArmHvc.S | GCC
+
+[Sources.AARCH64]
+ AArch64/ArmHvc.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimer.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimer.c
new file mode 100644
index 0000000..63ce197
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimer.c
@@ -0,0 +1,168 @@
+/** @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 <Uefi.h>
+#include <Chipset/AArch64.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include "AArch64Lib.h"
+#include "ArmLibPrivate.h"
+#include <Library/ArmArchTimer.h>
+
+VOID
+EFIAPI
+ArmArchTimerReadReg (
+ IN ARM_ARCH_TIMER_REGS Reg,
+ OUT VOID *DstBuf
+ )
+{
+ // Check if the Generic/Architecture timer is implemented
+ if (ArmIsArchTimerImplemented ()) {
+
+ switch (Reg) {
+
+ case CntFrq:
+ *((UINTN *)DstBuf) = ArmReadCntFrq ();
+ break;
+
+ case CntPct:
+ *((UINT64 *)DstBuf) = ArmReadCntPct ();
+ break;
+
+ case CntkCtl:
+ *((UINTN *)DstBuf) = ArmReadCntkCtl();
+ break;
+
+ case CntpTval:
+ *((UINTN *)DstBuf) = ArmReadCntpTval ();
+ break;
+
+ case CntpCtl:
+ *((UINTN *)DstBuf) = ArmReadCntpCtl ();
+ break;
+
+ case CntvTval:
+ *((UINTN *)DstBuf) = ArmReadCntvTval ();
+ break;
+
+ case CntvCtl:
+ *((UINTN *)DstBuf) = ArmReadCntvCtl ();
+ break;
+
+ case CntvCt:
+ *((UINT64 *)DstBuf) = ArmReadCntvCt ();
+ break;
+
+ case CntpCval:
+ *((UINT64 *)DstBuf) = ArmReadCntpCval ();
+ break;
+
+ case CntvCval:
+ *((UINT64 *)DstBuf) = ArmReadCntvCval ();
+ break;
+
+ case CntvOff:
+ *((UINT64 *)DstBuf) = ArmReadCntvOff ();
+ break;
+
+ case CnthCtl:
+ case CnthpTval:
+ case CnthpCtl:
+ case CnthpCval:
+ DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));
+ break;
+
+ default:
+ DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));
+ }
+ } else {
+ DEBUG ((EFI_D_ERROR, "Attempt to read ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));
+ ASSERT (0);
+ }
+}
+
+VOID
+EFIAPI
+ArmArchTimerWriteReg (
+ IN ARM_ARCH_TIMER_REGS Reg,
+ IN VOID *SrcBuf
+ )
+{
+ // Check if the Generic/Architecture timer is implemented
+ if (ArmIsArchTimerImplemented ()) {
+
+ switch (Reg) {
+
+ case CntFrq:
+ ArmWriteCntFrq (*((UINTN *)SrcBuf));
+ break;
+
+ case CntPct:
+ DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTPCT \n"));
+ break;
+
+ case CntkCtl:
+ ArmWriteCntkCtl (*((UINTN *)SrcBuf));
+ break;
+
+ case CntpTval:
+ ArmWriteCntpTval (*((UINTN *)SrcBuf));
+ break;
+
+ case CntpCtl:
+ ArmWriteCntpCtl (*((UINTN *)SrcBuf));
+ break;
+
+ case CntvTval:
+ ArmWriteCntvTval (*((UINTN *)SrcBuf));
+ break;
+
+ case CntvCtl:
+ ArmWriteCntvCtl (*((UINTN *)SrcBuf));
+ break;
+
+ case CntvCt:
+ DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTVCT \n"));
+ break;
+
+ case CntpCval:
+ ArmWriteCntpCval (*((UINT64 *)SrcBuf) );
+ break;
+
+ case CntvCval:
+ ArmWriteCntvCval (*((UINT64 *)SrcBuf) );
+ break;
+
+ case CntvOff:
+ ArmWriteCntvOff (*((UINT64 *)SrcBuf));
+ break;
+
+ case CnthCtl:
+ case CnthpTval:
+ case CnthpCtl:
+ case CnthpCval:
+ DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));
+ break;
+
+ default:
+ DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));
+ }
+ } else {
+ DEBUG ((EFI_D_ERROR, "Attempt to write to ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));
+ ASSERT (0);
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S
new file mode 100644
index 0000000..1ac0108
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S
@@ -0,0 +1,140 @@
+#------------------------------------------------------------------------------
+#
+# 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmReadCntFrq)
+GCC_ASM_EXPORT(ArmWriteCntFrq)
+GCC_ASM_EXPORT(ArmReadCntPct)
+GCC_ASM_EXPORT(ArmReadCntkCtl)
+GCC_ASM_EXPORT(ArmWriteCntkCtl)
+GCC_ASM_EXPORT(ArmReadCntpTval)
+GCC_ASM_EXPORT(ArmWriteCntpTval)
+GCC_ASM_EXPORT(ArmReadCntpCtl)
+GCC_ASM_EXPORT(ArmWriteCntpCtl)
+GCC_ASM_EXPORT(ArmReadCntvTval)
+GCC_ASM_EXPORT(ArmWriteCntvTval)
+GCC_ASM_EXPORT(ArmReadCntvCtl)
+GCC_ASM_EXPORT(ArmWriteCntvCtl)
+GCC_ASM_EXPORT(ArmReadCntvCt)
+GCC_ASM_EXPORT(ArmReadCntpCval)
+GCC_ASM_EXPORT(ArmWriteCntpCval)
+GCC_ASM_EXPORT(ArmReadCntvCval)
+GCC_ASM_EXPORT(ArmWriteCntvCval)
+GCC_ASM_EXPORT(ArmReadCntvOff)
+GCC_ASM_EXPORT(ArmWriteCntvOff)
+
+ASM_PFX(ArmReadCntFrq):
+ mrs x0, cntfrq_el0 // Read CNTFRQ
+ ret
+
+
+# NOTE - Can only write while at highest implemented EL level (EL3 on model). Else ReadOnly (EL2, EL1, EL0)
+ASM_PFX(ArmWriteCntFrq):
+ msr cntfrq_el0, x0 // Write to CNTFRQ
+ ret
+
+
+ASM_PFX(ArmReadCntPct):
+ mrs x0, cntpct_el0 // Read CNTPCT (Physical counter register)
+ ret
+
+
+ASM_PFX(ArmReadCntkCtl):
+ mrs x0, cntkctl_el1 // Read CNTK_CTL (Timer PL1 Control Register)
+ ret
+
+
+ASM_PFX(ArmWriteCntkCtl):
+ mrs x0, cntkctl_el1 // Write to CNTK_CTL (Timer PL1 Control Register)
+ ret
+
+
+ASM_PFX(ArmReadCntpTval):
+ mrs x0, cntp_tval_el0 // Read CNTP_TVAL (PL1 physical timer value register)
+ ret
+
+
+ASM_PFX(ArmWriteCntpTval):
+ msr cntp_tval_el0, x0 // Write to CNTP_TVAL (PL1 physical timer value register)
+ ret
+
+
+ASM_PFX(ArmReadCntpCtl):
+ mrs x0, cntp_ctl_el0 // Read CNTP_CTL (PL1 Physical Timer Control Register)
+ ret
+
+
+ASM_PFX(ArmWriteCntpCtl):
+ msr cntp_ctl_el0, x0 // Write to CNTP_CTL (PL1 Physical Timer Control Register)
+ ret
+
+
+ASM_PFX(ArmReadCntvTval):
+ mrs x0, cntv_tval_el0 // Read CNTV_TVAL (Virtual Timer Value register)
+ ret
+
+
+ASM_PFX(ArmWriteCntvTval):
+ msr cntv_tval_el0, x0 // Write to CNTV_TVAL (Virtual Timer Value register)
+ ret
+
+
+ASM_PFX(ArmReadCntvCtl):
+ mrs x0, cntv_ctl_el0 // Read CNTV_CTL (Virtual Timer Control Register)
+ ret
+
+
+ASM_PFX(ArmWriteCntvCtl):
+ msr cntv_ctl_el0, x0 // Write to CNTV_CTL (Virtual Timer Control Register)
+ ret
+
+
+ASM_PFX(ArmReadCntvCt):
+ mrs x0, cntvct_el0 // Read CNTVCT (Virtual Count Register)
+ ret
+
+
+ASM_PFX(ArmReadCntpCval):
+ mrs x0, cntp_cval_el0 // Read CNTP_CTVAL (Physical Timer Compare Value Register)
+ ret
+
+
+ASM_PFX(ArmWriteCntpCval):
+ msr cntp_cval_el0, x0 // Write to CNTP_CTVAL (Physical Timer Compare Value Register)
+ ret
+
+
+ASM_PFX(ArmReadCntvCval):
+ mrs x0, cntv_cval_el0 // Read CNTV_CTVAL (Virtual Timer Compare Value Register)
+ ret
+
+
+ASM_PFX(ArmWriteCntvCval):
+ msr cntv_cval_el0, x0 // write to CNTV_CTVAL (Virtual Timer Compare Value Register)
+ ret
+
+
+ASM_PFX(ArmReadCntvOff):
+ mrs x0, cntvoff_el2 // Read CNTVOFF (virtual Offset register)
+ ret
+
+
+ASM_PFX(ArmWriteCntvOff):
+ msr cntvoff_el2, x0 // Write to CNTVOFF (Virtual Offset register)
+ ret
+
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
new file mode 100644
index 0000000..a4e1f20
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
@@ -0,0 +1,267 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Chipset/AArch64.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include "AArch64Lib.h"
+#include "ArmLibPrivate.h"
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+ VOID
+ )
+{
+ return ARM_CACHE_TYPE_WRITE_BACK;
+}
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+ VOID
+ )
+{
+ UINT32 CLIDR = ReadCLIDR ();
+
+ return (ARM_CACHE_ARCHITECTURE)CLIDR; // BugBug Fix Me
+}
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+ VOID
+ )
+{
+ UINT32 CLIDR = ReadCLIDR ();
+
+ if ((CLIDR & 0x2) == 0x2) {
+ // Instruction cache exists
+ return TRUE;
+ }
+ if ((CLIDR & 0x7) == 0x4) {
+ // Unified cache
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheSize (
+ VOID
+ )
+{
+ UINT32 NumSets;
+ UINT32 Associativity;
+ UINT32 LineSize;
+ UINT32 CCSIDR = ReadCCSIDR (0);
+
+ LineSize = (1 << ((CCSIDR & 0x7) + 2));
+ Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
+ NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
+
+ // LineSize is in words (4 byte chunks)
+ return NumSets * Associativity * LineSize * 4;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (0);
+
+ return ((CCSIDR >> 3) & 0x3ff) + 1;
+}
+
+UINTN
+ArmDataCacheSets (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (0);
+
+ return ((CCSIDR >> 13) & 0x7fff) + 1;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (0) & 7;
+
+ // * 4 converts to bytes
+ return (1 << (CCSIDR + 2)) * 4;
+}
+
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+ VOID
+ )
+{
+ UINT32 CLIDR = ReadCLIDR ();
+
+ if ((CLIDR & 1) == 1) {
+ // Instruction cache exists
+ return TRUE;
+ }
+ if ((CLIDR & 0x7) == 0x4) {
+ // Unified cache
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+ VOID
+ )
+{
+ UINT32 NumSets;
+ UINT32 Associativity;
+ UINT32 LineSize;
+ UINT32 CCSIDR = ReadCCSIDR (1);
+
+ LineSize = (1 << ((CCSIDR & 0x7) + 2));
+ Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
+ NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
+
+ // LineSize is in words (4 byte chunks)
+ return NumSets * Associativity * LineSize * 4;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (1);
+
+ return ((CCSIDR >> 3) & 0x3ff) + 1;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSets (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (1);
+
+ return ((CCSIDR >> 13) & 0x7fff) + 1;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (1) & 7;
+
+ // * 4 converts to bytes
+ return (1 << (CCSIDR + 2)) * 4;
+}
+
+
+VOID
+AArch64DataCacheOperation (
+ IN AARCH64_CACHE_OPERATION DataCacheOperation
+ )
+{
+ UINTN SavedInterruptState;
+
+ SavedInterruptState = ArmGetInterruptState ();
+ ArmDisableInterrupts();
+
+ AArch64AllDataCachesOperation (DataCacheOperation);
+
+ ArmDrainWriteBuffer ();
+
+ if (SavedInterruptState) {
+ ArmEnableInterrupts ();
+ }
+}
+
+
+VOID
+AArch64PoUDataCacheOperation (
+ IN AARCH64_CACHE_OPERATION DataCacheOperation
+ )
+{
+ UINTN SavedInterruptState;
+
+ SavedInterruptState = ArmGetInterruptState ();
+ ArmDisableInterrupts ();
+
+ AArch64PerformPoUDataCacheOperation (DataCacheOperation);
+
+ ArmDrainWriteBuffer ();
+
+ if (SavedInterruptState) {
+ ArmEnableInterrupts ();
+ }
+}
+
+VOID
+EFIAPI
+ArmInvalidateDataCache (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCacheToPoU (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ AArch64PoUDataCacheOperation (ArmCleanDataCacheEntryBySetWay);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
new file mode 100644
index 0000000..c8bb843
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
@@ -0,0 +1,33 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions 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.
+
+**/
+
+#ifndef __AARCH64_LIB_H__
+#define __AARCH64_LIB_H__
+
+typedef VOID (*AARCH64_CACHE_OPERATION)(UINTN);
+
+
+VOID
+AArch64PerformPoUDataCacheOperation (
+ IN AARCH64_CACHE_OPERATION DataCacheOperation
+ );
+
+VOID
+AArch64AllDataCachesOperation (
+ IN AARCH64_CACHE_OPERATION DataCacheOperation
+ );
+
+#endif // __AARCH64_LIB_H__
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
new file mode 100644
index 0000000..e524784
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Portions 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AArch64Lib
+ FILE_GUID = ef20ddf5-b334-47b3-94cf-52ff44c29138
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.AARCH64]
+ AArch64Lib.c
+ AArch64Mmu.c
+ AArch64ArchTimer.c
+ ArmLibSupportV8.S
+ AArch64Support.S
+ AArch64ArchTimerSupport.S
+
+ ../Common/AArch64/ArmLibSupport.S
+ ../Common/ArmLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
new file mode 100644
index 0000000..3a99e1b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
@@ -0,0 +1,48 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Portions 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 = AArch64LibPrePi
+ FILE_GUID = fd72688d-dbd8-4cf2-91a3-15171dea7816
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ArmLibSupportV8.S
+ AArch64Support.S
+
+ ../Common/AArch64/ArmLibSupport.S
+ ../Common/ArmLib.c
+
+ AArch64Lib.c
+ AArch64Mmu.c
+
+ AArch64ArchTimer.c
+ AArch64ArchTimerSupport.S
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ PrePiLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
new file mode 100644
index 0000000..57ac694
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
@@ -0,0 +1,43 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AArch64Lib
+ FILE_GUID = eb7441e4-3ddf-48b8-a009-14f428b19e49
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ArmLibSupportV8.S
+ AArch64Support.S
+
+ ../Common/AArch64/ArmLibSupport.S
+ ../Common/ArmLib.c
+
+ AArch64Lib.c
+
+ AArch64ArchTimer.c
+ AArch64ArchTimerSupport.S
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
new file mode 100644
index 0000000..f215fe9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
@@ -0,0 +1,701 @@
+/** @file
+* File managing the MMU for ARMv8 architecture
+*
+* 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 <Uefi.h>
+#include <Chipset/AArch64.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include "AArch64Lib.h"
+#include "ArmLibPrivate.h"
+
+// We use this index definition to define an invalid block entry
+#define TT_ATTR_INDX_INVALID ((UINT32)~0)
+
+STATIC
+UINT64
+ArmMemoryAttributeToPageAttribute (
+ IN ARM_MEMORY_REGION_ATTRIBUTES Attributes
+ )
+{
+ switch (Attributes) {
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
+ return TT_ATTR_INDX_MEMORY_WRITE_BACK;
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
+ return TT_ATTR_INDX_MEMORY_WRITE_THROUGH;
+ case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
+ return TT_ATTR_INDX_DEVICE_MEMORY;
+ case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+ return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
+ return TT_ATTR_INDX_MEMORY_WRITE_BACK;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
+ return TT_ATTR_INDX_MEMORY_WRITE_THROUGH;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
+ return TT_ATTR_INDX_DEVICE_MEMORY;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
+ return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
+ default:
+ ASSERT(0);
+ return TT_ATTR_INDX_DEVICE_MEMORY;
+ }
+}
+
+UINT64
+PageAttributeToGcdAttribute (
+ IN UINT64 PageAttributes
+ )
+{
+ UINT64 GcdAttributes;
+
+ switch (PageAttributes & TT_ATTR_INDX_MASK) {
+ case TT_ATTR_INDX_DEVICE_MEMORY:
+ GcdAttributes = EFI_MEMORY_UC;
+ break;
+ case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
+ GcdAttributes = EFI_MEMORY_WC;
+ break;
+ case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
+ GcdAttributes = EFI_MEMORY_WT;
+ break;
+ case TT_ATTR_INDX_MEMORY_WRITE_BACK:
+ GcdAttributes = EFI_MEMORY_WB;
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n", PageAttributes));
+ ASSERT (0);
+ // The Global Coherency Domain (GCD) value is defined as a bit set.
+ // Returning 0 means no attribute has been set.
+ GcdAttributes = 0;
+ }
+
+ // Determine protection attributes
+ if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) || ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
+ // Read only cases map to write-protect
+ GcdAttributes |= EFI_MEMORY_WP;
+ }
+
+ // Process eXecute Never attribute
+ if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0 ) {
+ GcdAttributes |= EFI_MEMORY_XP;
+ }
+
+ return GcdAttributes;
+}
+
+UINT64
+GcdAttributeToPageAttribute (
+ IN UINT64 GcdAttributes
+ )
+{
+ UINT64 PageAttributes;
+
+ switch (GcdAttributes & 0xFF) {
+ case EFI_MEMORY_UC:
+ PageAttributes = TT_ATTR_INDX_DEVICE_MEMORY;
+ break;
+ case EFI_MEMORY_WC:
+ PageAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
+ break;
+ case EFI_MEMORY_WT:
+ PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH;
+ break;
+ case EFI_MEMORY_WB:
+ PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK;
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "GcdAttributeToPageAttribute: 0x%X attributes is not supported.\n", GcdAttributes));
+ ASSERT (0);
+ // If no match has been found then we mark the memory as device memory.
+ // The only side effect of using device memory should be a slow down in the performance.
+ PageAttributes = TT_ATTR_INDX_DEVICE_MEMORY;
+ }
+
+ // Determine protection attributes
+ if (GcdAttributes & EFI_MEMORY_WP) {
+ // Read only cases map to write-protect
+ PageAttributes |= TT_AP_RO_RO;
+ }
+
+ // Process eXecute Never attribute
+ if (GcdAttributes & EFI_MEMORY_XP) {
+ PageAttributes |= (TT_PXN_MASK | TT_UXN_MASK);
+ }
+
+ return PageAttributes;
+}
+
+ARM_MEMORY_REGION_ATTRIBUTES
+GcdAttributeToArmAttribute (
+ IN UINT64 GcdAttributes
+ )
+{
+ switch (GcdAttributes & 0xFF) {
+ case EFI_MEMORY_UC:
+ return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+ case EFI_MEMORY_WC:
+ return ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
+ case EFI_MEMORY_WT:
+ return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH;
+ case EFI_MEMORY_WB:
+ return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
+ default:
+ DEBUG ((EFI_D_ERROR, "GcdAttributeToArmAttribute: 0x%lX attributes is not supported.\n", GcdAttributes));
+ ASSERT (0);
+ return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+ }
+}
+
+// Describe the T0SZ values for each translation table level
+typedef struct {
+ UINTN MinT0SZ;
+ UINTN MaxT0SZ;
+ UINTN LargestT0SZ; // Generally (MaxT0SZ == LargestT0SZ) but at the Level3 Table
+ // the MaxT0SZ is not at the boundary of the table
+} T0SZ_DESCRIPTION_PER_LEVEL;
+
+// Map table for the corresponding Level of Table
+STATIC CONST T0SZ_DESCRIPTION_PER_LEVEL T0SZPerTableLevel[] = {
+ { 16, 24, 24 }, // Table Level 0
+ { 25, 33, 33 }, // Table Level 1
+ { 34, 39, 42 } // Table Level 2
+};
+
+VOID
+GetRootTranslationTableInfo (
+ IN UINTN T0SZ,
+ OUT UINTN *TableLevel,
+ OUT UINTN *TableEntryCount
+ )
+{
+ UINTN Index;
+
+ // Identify the level of the root table from the given T0SZ
+ for (Index = 0; Index < sizeof (T0SZPerTableLevel) / sizeof (T0SZ_DESCRIPTION_PER_LEVEL); Index++) {
+ if (T0SZ <= T0SZPerTableLevel[Index].MaxT0SZ) {
+ break;
+ }
+ }
+
+ // If we have not found the corresponding maximum T0SZ then we use the last one
+ if (Index == sizeof (T0SZPerTableLevel) / sizeof (T0SZ_DESCRIPTION_PER_LEVEL)) {
+ Index--;
+ }
+
+ // Get the level of the root table
+ if (TableLevel) {
+ *TableLevel = Index;
+ }
+
+ // The Size of the Table is 2^(T0SZ-LargestT0SZ)
+ if (TableEntryCount) {
+ *TableEntryCount = 1 << (T0SZPerTableLevel[Index].LargestT0SZ - T0SZ + 1);
+ }
+}
+
+STATIC
+VOID
+LookupAddresstoRootTable (
+ IN UINT64 MaxAddress,
+ OUT UINTN *T0SZ,
+ OUT UINTN *TableEntryCount
+ )
+{
+ UINTN TopBit;
+
+ // Check the parameters are not NULL
+ ASSERT ((T0SZ != NULL) && (TableEntryCount != NULL));
+
+ // Look for the highest bit set in MaxAddress
+ for (TopBit = 63; TopBit != 0; TopBit--) {
+ if ((1ULL << TopBit) & MaxAddress) {
+ // MaxAddress top bit is found
+ TopBit = TopBit + 1;
+ break;
+ }
+ }
+ ASSERT (TopBit != 0);
+
+ // Calculate T0SZ from the top bit of the MaxAddress
+ *T0SZ = 64 - TopBit;
+
+ // Get the Table info from T0SZ
+ GetRootTranslationTableInfo (*T0SZ, NULL, TableEntryCount);
+}
+
+STATIC
+UINT64*
+GetBlockEntryListFromAddress (
+ IN UINT64 *RootTable,
+ IN UINT64 RegionStart,
+ OUT UINTN *TableLevel,
+ IN OUT UINT64 *BlockEntrySize,
+ IN OUT UINT64 **LastBlockEntry
+ )
+{
+ UINTN RootTableLevel;
+ UINTN RootTableEntryCount;
+ UINT64 *TranslationTable;
+ UINT64 *BlockEntry;
+ UINT64 *SubTableBlockEntry;
+ UINT64 BlockEntryAddress;
+ UINTN BaseAddressAlignment;
+ UINTN PageLevel;
+ UINTN Index;
+ UINTN IndexLevel;
+ UINTN T0SZ;
+ UINT64 Attributes;
+ UINT64 TableAttributes;
+
+ // Initialize variable
+ BlockEntry = NULL;
+
+ // Ensure the parameters are valid
+ if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ // Ensure the Region is aligned on 4KB boundary
+ if ((RegionStart & (SIZE_4KB - 1)) != 0) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ // Ensure the required size is aligned on 4KB boundary
+ if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ //
+ // Calculate LastBlockEntry from T0SZ - this is the last block entry of the root Translation table
+ //
+ T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
+ // Get the Table info from T0SZ
+ GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);
+ // The last block of the root table depends on the number of entry in this table
+ *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(RootTable, RootTableEntryCount);
+
+ // If the start address is 0x0 then we use the size of the region to identify the alignment
+ if (RegionStart == 0) {
+ // Identify the highest possible alignment for the Region Size
+ for (BaseAddressAlignment = 0; BaseAddressAlignment < 64; BaseAddressAlignment++) {
+ if ((1 << BaseAddressAlignment) & *BlockEntrySize) {
+ break;
+ }
+ }
+ } else {
+ // Identify the highest possible alignment for the Base Address
+ for (BaseAddressAlignment = 0; BaseAddressAlignment < 64; BaseAddressAlignment++) {
+ if ((1 << BaseAddressAlignment) & RegionStart) {
+ break;
+ }
+ }
+ }
+
+ // Identify the Page Level the RegionStart must belongs to
+ PageLevel = 3 - ((BaseAddressAlignment - 12) / 9);
+
+ // If the required size is smaller than the current block size then we need to go to the page below.
+ // The PageLevel was calculated on the Base Address alignment but did not take in account the alignment
+ // of the allocation size
+ if (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) {
+ // It does not fit so we need to go a page level above
+ PageLevel++;
+ }
+
+ // Expose the found PageLevel to the caller
+ *TableLevel = PageLevel;
+
+ // Now, we have the Table Level we can get the Block Size associated to this table
+ *BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel);
+
+ //
+ // Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries
+ //
+
+ TranslationTable = RootTable;
+ for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {
+ BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart);
+
+ if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {
+ // Go to the next table
+ TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
+
+ // If we are at the last level then update the output
+ if (IndexLevel == PageLevel) {
+ // And get the appropriate BlockEntry at the next level
+ BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel + 1, RegionStart);
+
+ // Set the last block for this new table
+ *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);
+ }
+ } else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {
+ // If we are not at the last level then we need to split this BlockEntry
+ if (IndexLevel != PageLevel) {
+ // Retrieve the attributes from the block entry
+ Attributes = *BlockEntry & TT_ATTRIBUTES_MASK;
+
+ // Convert the block entry attributes into Table descriptor attributes
+ TableAttributes = TT_TABLE_AP_NO_PERMISSION;
+ if (Attributes & TT_PXN_MASK) {
+ TableAttributes = TT_TABLE_PXN;
+ }
+ if (Attributes & TT_UXN_MASK) {
+ TableAttributes = TT_TABLE_XN;
+ }
+ if (Attributes & TT_NS) {
+ TableAttributes = TT_TABLE_NS;
+ }
+
+ // Get the address corresponding at this entry
+ BlockEntryAddress = RegionStart;
+ BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
+ // Shift back to right to set zero before the effective address
+ BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
+
+ // Set the correct entry type for the next page level
+ if ((IndexLevel + 1) == 3) {
+ Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3;
+ } else {
+ Attributes |= TT_TYPE_BLOCK_ENTRY;
+ }
+
+ // Create a new translation table
+ TranslationTable = (UINT64*)AllocatePages (EFI_SIZE_TO_PAGES((TT_ENTRY_COUNT * sizeof(UINT64)) + TT_ALIGNMENT_DESCRIPTION_TABLE));
+ if (TranslationTable == NULL) {
+ return NULL;
+ }
+ TranslationTable = (UINT64*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
+
+ // Populate the newly created lower level table
+ SubTableBlockEntry = TranslationTable;
+ for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
+ *SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
+ SubTableBlockEntry++;
+ }
+
+ // Fill the BlockEntry with the new TranslationTable
+ *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY;
+ // Update the last block entry with the newly created translation table
+ *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);
+
+ // Block Entry points at the beginning of the Translation Table
+ BlockEntry = TranslationTable;
+ }
+ } else {
+ if (IndexLevel != PageLevel) {
+ //
+ // Case when we have an Invalid Entry and we are at a page level above of the one targetted.
+ //
+
+ // Create a new translation table
+ TranslationTable = (UINT64*)AllocatePages (EFI_SIZE_TO_PAGES((TT_ENTRY_COUNT * sizeof(UINT64)) + TT_ALIGNMENT_DESCRIPTION_TABLE));
+ if (TranslationTable == NULL) {
+ return NULL;
+ }
+ TranslationTable = (UINT64*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
+
+ ZeroMem (TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64));
+
+ // Fill the new BlockEntry with the TranslationTable
+ *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY;
+ // Update the last block entry with the newly created translation table
+ *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);
+ } else {
+ //
+ // Case when the new region is part of an existing page table
+ //
+ *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);
+ }
+ }
+ }
+
+ return BlockEntry;
+}
+
+STATIC
+RETURN_STATUS
+FillTranslationTable (
+ IN UINT64 *RootTable,
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
+ )
+{
+ UINT64 Attributes;
+ UINT32 Type;
+ UINT64 RegionStart;
+ UINT64 RemainingRegionLength;
+ UINT64 *BlockEntry;
+ UINT64 *LastBlockEntry;
+ UINT64 BlockEntrySize;
+ UINTN TableLevel;
+
+ // Ensure the Length is aligned on 4KB boundary
+ if ((MemoryRegion->Length == 0) || ((MemoryRegion->Length & (SIZE_4KB - 1)) != 0)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ // Variable initialization
+ Attributes = ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF;
+ RemainingRegionLength = MemoryRegion->Length;
+ RegionStart = MemoryRegion->VirtualBase;
+
+ do {
+ // Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor
+ // such as the the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor
+ BlockEntrySize = RemainingRegionLength;
+ BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);
+ if (BlockEntry == NULL) {
+ // GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ if (TableLevel != 3) {
+ Type = TT_TYPE_BLOCK_ENTRY;
+ } else {
+ Type = TT_TYPE_BLOCK_ENTRY_LEVEL3;
+ }
+
+ do {
+ // Fill the Block Entry with attribute and output block address
+ *BlockEntry = (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;
+
+ // Go to the next BlockEntry
+ RegionStart += BlockEntrySize;
+ RemainingRegionLength -= BlockEntrySize;
+ BlockEntry++;
+ } while ((RemainingRegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));
+ } while (RemainingRegionLength != 0);
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+SetMemoryAttributes (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes,
+ IN EFI_PHYSICAL_ADDRESS VirtualMask
+ )
+{
+ RETURN_STATUS Status;
+ ARM_MEMORY_REGION_DESCRIPTOR MemoryRegion;
+ UINT64 *TranslationTable;
+
+ MemoryRegion.PhysicalBase = BaseAddress;
+ MemoryRegion.VirtualBase = BaseAddress;
+ MemoryRegion.Length = Length;
+ MemoryRegion.Attributes = GcdAttributeToArmAttribute (Attributes);
+
+ TranslationTable = ArmGetTTBR0BaseAddress ();
+
+ Status = FillTranslationTable (TranslationTable, &MemoryRegion);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks
+ // flush and invalidate pages
+ ArmCleanInvalidateDataCache ();
+
+ ArmInvalidateInstructionCache ();
+
+ // Invalidate all TLB entries so changes are synced
+ ArmInvalidateTlb ();
+
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+ArmConfigureMmu (
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
+ OUT VOID **TranslationTableBase OPTIONAL,
+ OUT UINTN *TranslationTableSize OPTIONAL
+ )
+{
+ VOID* TranslationTable;
+ UINTN TranslationTablePageCount;
+ UINT32 TranslationTableAttribute;
+ ARM_MEMORY_REGION_DESCRIPTOR *MemoryTableEntry;
+ UINT64 MaxAddress;
+ UINT64 TopAddress;
+ UINTN T0SZ;
+ UINTN RootTableEntryCount;
+ UINT64 TCR;
+ RETURN_STATUS Status;
+
+ if(MemoryTable == NULL) {
+ ASSERT (MemoryTable != NULL);
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ // Identify the highest address of the memory table
+ MaxAddress = MemoryTable->PhysicalBase + MemoryTable->Length - 1;
+ MemoryTableEntry = MemoryTable;
+ while (MemoryTableEntry->Length != 0) {
+ TopAddress = MemoryTableEntry->PhysicalBase + MemoryTableEntry->Length - 1;
+ if (TopAddress > MaxAddress) {
+ MaxAddress = TopAddress;
+ }
+ MemoryTableEntry++;
+ }
+
+ // Lookup the Table Level to get the information
+ LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount);
+
+ //
+ // Set TCR that allows us to retrieve T0SZ in the subsequent functions
+ //
+ // Ideally we will be running at EL2, but should support EL1 as well.
+ // UEFI should not run at EL3.
+ if (ArmReadCurrentEL () == AARCH64_EL2) {
+ //Note: Bits 23 and 31 are reserved(RES1) bits in TCR_EL2
+ TCR = T0SZ | (1UL << 31) | (1UL << 23) | TCR_TG0_4KB;
+
+ // Set the Physical Address Size using MaxAddress
+ if (MaxAddress < SIZE_4GB) {
+ TCR |= TCR_PS_4GB;
+ } else if (MaxAddress < SIZE_64GB) {
+ TCR |= TCR_PS_64GB;
+ } else if (MaxAddress < SIZE_1TB) {
+ TCR |= TCR_PS_1TB;
+ } else if (MaxAddress < SIZE_4TB) {
+ TCR |= TCR_PS_4TB;
+ } else if (MaxAddress < SIZE_16TB) {
+ TCR |= TCR_PS_16TB;
+ } else if (MaxAddress < SIZE_256TB) {
+ TCR |= TCR_PS_256TB;
+ } else {
+ DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
+ ASSERT (0); // Bigger than 48-bit memory space are not supported
+ return RETURN_UNSUPPORTED;
+ }
+ } else if (ArmReadCurrentEL () == AARCH64_EL1) {
+ TCR = T0SZ | TCR_TG0_4KB;
+
+ // Set the Physical Address Size using MaxAddress
+ if (MaxAddress < SIZE_4GB) {
+ TCR |= TCR_IPS_4GB;
+ } else if (MaxAddress < SIZE_64GB) {
+ TCR |= TCR_IPS_64GB;
+ } else if (MaxAddress < SIZE_1TB) {
+ TCR |= TCR_IPS_1TB;
+ } else if (MaxAddress < SIZE_4TB) {
+ TCR |= TCR_IPS_4TB;
+ } else if (MaxAddress < SIZE_16TB) {
+ TCR |= TCR_IPS_16TB;
+ } else if (MaxAddress < SIZE_256TB) {
+ TCR |= TCR_IPS_256TB;
+ } else {
+ DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
+ ASSERT (0); // Bigger than 48-bit memory space are not supported
+ return RETURN_UNSUPPORTED;
+ }
+ } else {
+ ASSERT (0); // UEFI is only expected to run at EL2 and EL1, not EL3.
+ return RETURN_UNSUPPORTED;
+ }
+
+ // Set TCR
+ ArmSetTCR (TCR);
+
+ // Allocate pages for translation table
+ TranslationTablePageCount = EFI_SIZE_TO_PAGES((RootTableEntryCount * sizeof(UINT64)) + TT_ALIGNMENT_DESCRIPTION_TABLE);
+ TranslationTable = AllocatePages (TranslationTablePageCount);
+ if (TranslationTable == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+ TranslationTable = (VOID*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
+ // We set TTBR0 just after allocating the table to retrieve its location from the subsequent
+ // functions without needing to pass this value across the functions. The MMU is only enabled
+ // after the translation tables are populated.
+ ArmSetTTBR0 (TranslationTable);
+
+ if (TranslationTableBase != NULL) {
+ *TranslationTableBase = TranslationTable;
+ }
+
+ if (TranslationTableSize != NULL) {
+ *TranslationTableSize = RootTableEntryCount * sizeof(UINT64);
+ }
+
+ ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64));
+
+ // Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs
+ ArmDisableMmu ();
+ ArmDisableDataCache ();
+ ArmDisableInstructionCache ();
+
+ // Make sure nothing sneaked into the cache
+ ArmCleanInvalidateDataCache ();
+ ArmInvalidateInstructionCache ();
+
+ TranslationTableAttribute = TT_ATTR_INDX_INVALID;
+ while (MemoryTable->Length != 0) {
+ // Find the memory attribute for the Translation Table
+ if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) &&
+ ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
+ TranslationTableAttribute = MemoryTable->Attributes;
+ }
+
+ Status = FillTranslationTable (TranslationTable, MemoryTable);
+ if (RETURN_ERROR (Status)) {
+ goto FREE_TRANSLATION_TABLE;
+ }
+ MemoryTable++;
+ }
+
+ // Translate the Memory Attributes into Translation Table Register Attributes
+ if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||
+ (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {
+ TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_NON_CACHEABLE | TCR_RGN_INNER_NON_CACHEABLE;
+ } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
+ (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
+ TCR |= TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WRITE_BACK_ALLOC | TCR_RGN_INNER_WRITE_BACK_ALLOC;
+ } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||
+ (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {
+ TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_WRITE_THROUGH | TCR_RGN_INNER_WRITE_THROUGH;
+ } else {
+ // If we failed to find a mapping that contains the root translation table then it probably means the translation table
+ // is not mapped in the given memory map.
+ ASSERT (0);
+ Status = RETURN_UNSUPPORTED;
+ goto FREE_TRANSLATION_TABLE;
+ }
+
+ // Set again TCR after getting the Translation Table attributes
+ ArmSetTCR (TCR);
+
+ ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) | // mapped to EFI_MEMORY_UC
+ MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC
+ MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) | // mapped to EFI_MEMORY_WT
+ MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)); // mapped to EFI_MEMORY_WB
+
+ ArmDisableAlignmentCheck ();
+ ArmEnableInstructionCache ();
+ ArmEnableDataCache ();
+
+ ArmEnableMmu ();
+ return RETURN_SUCCESS;
+
+FREE_TRANSLATION_TABLE:
+ FreePages (TranslationTable, TranslationTablePageCount);
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
new file mode 100644
index 0000000..bdede48
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
@@ -0,0 +1,498 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# 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 <Chipset/AArch64.h>
+#include <AsmMacroIoLibV8.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT (ArmInvalidateInstructionCache)
+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmDrainWriteBuffer)
+GCC_ASM_EXPORT (ArmEnableMmu)
+GCC_ASM_EXPORT (ArmDisableMmu)
+GCC_ASM_EXPORT (ArmDisableCachesAndMmu)
+GCC_ASM_EXPORT (ArmMmuEnabled)
+GCC_ASM_EXPORT (ArmEnableDataCache)
+GCC_ASM_EXPORT (ArmDisableDataCache)
+GCC_ASM_EXPORT (ArmEnableInstructionCache)
+GCC_ASM_EXPORT (ArmDisableInstructionCache)
+GCC_ASM_EXPORT (ArmDisableAlignmentCheck)
+GCC_ASM_EXPORT (ArmEnableAlignmentCheck)
+GCC_ASM_EXPORT (ArmEnableBranchPrediction)
+GCC_ASM_EXPORT (ArmDisableBranchPrediction)
+GCC_ASM_EXPORT (AArch64AllDataCachesOperation)
+GCC_ASM_EXPORT (AArch64PerformPoUDataCacheOperation)
+GCC_ASM_EXPORT (ArmDataMemoryBarrier)
+GCC_ASM_EXPORT (ArmDataSyncronizationBarrier)
+GCC_ASM_EXPORT (ArmInstructionSynchronizationBarrier)
+GCC_ASM_EXPORT (ArmWriteVBar)
+GCC_ASM_EXPORT (ArmReadVBar)
+GCC_ASM_EXPORT (ArmEnableVFP)
+GCC_ASM_EXPORT (ArmCallWFI)
+GCC_ASM_EXPORT (ArmReadMpidr)
+GCC_ASM_EXPORT (ArmReadTpidrurw)
+GCC_ASM_EXPORT (ArmWriteTpidrurw)
+GCC_ASM_EXPORT (ArmIsArchTimerImplemented)
+GCC_ASM_EXPORT (ArmReadIdPfr0)
+GCC_ASM_EXPORT (ArmReadIdPfr1)
+GCC_ASM_EXPORT (ArmWriteHcr)
+GCC_ASM_EXPORT (ArmReadCurrentEL)
+
+.set CTRL_M_BIT, (1 << 0)
+.set CTRL_A_BIT, (1 << 1)
+.set CTRL_C_BIT, (1 << 2)
+.set CTRL_I_BIT, (1 << 12)
+.set CTRL_V_BIT, (1 << 12)
+.set CPACR_VFP_BITS, (3 << 20)
+
+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
+ dc ivac, x0 // Invalidate single data cache line
+ dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmCleanDataCacheEntryByMVA):
+ dc cvac, x0 // Clean single data cache line
+ dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):
+ dc civac, x0 // Clean and invalidate single data cache line
+ dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmInvalidateDataCacheEntryBySetWay):
+ dc isw, x0 // Invalidate this line
+ dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay):
+ dc cisw, x0 // Clean and Invalidate this line
+ dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmCleanDataCacheEntryBySetWay):
+ dc csw, x0 // Clean this line
+ dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmInvalidateInstructionCache):
+ ic iallu // Invalidate entire instruction cache
+ dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmEnableMmu):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Read System control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Read System control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Read System control register EL3
+4: orr x0, x0, #CTRL_M_BIT // Set MMU enable bit
+ EL1_OR_EL2_OR_EL3(x1)
+1: tlbi vmalle1
+ isb
+ msr sctlr_el1, x0 // Write back
+ b 4f
+2: tlbi alle2
+ isb
+ msr sctlr_el2, x0 // Write back
+ b 4f
+3: tlbi alle3
+ isb
+ msr sctlr_el3, x0 // Write back
+4: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableMmu):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Read System Control Register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Read System Control Register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Read System Control Register EL3
+4: and x0, x0, #~CTRL_M_BIT // Clear MMU enable bit
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr sctlr_el1, x0 // Write back
+ tlbi vmalle1
+ b 4f
+2: msr sctlr_el2, x0 // Write back
+ tlbi alle2
+ b 4f
+3: msr sctlr_el3, x0 // Write back
+ tlbi alle3
+4: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableCachesAndMmu):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Get control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Get control register EL3
+4: mov x1, #~(CTRL_M_BIT | CTRL_C_BIT | CTRL_I_BIT) // Disable MMU, D & I caches
+ and x0, x0, x1
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr sctlr_el1, x0 // Write back control register
+ b 4f
+2: msr sctlr_el2, x0 // Write back control register
+ b 4f
+3: msr sctlr_el3, x0 // Write back control register
+4: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmMmuEnabled):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Get control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Get control register EL3
+4: and x0, x0, #CTRL_M_BIT
+ ret
+
+
+ASM_PFX(ArmEnableDataCache):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Get control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Get control register EL3
+4: orr x0, x0, #CTRL_C_BIT // Set C bit
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr sctlr_el1, x0 // Write back control register
+ b 4f
+2: msr sctlr_el2, x0 // Write back control register
+ b 4f
+3: msr sctlr_el3, x0 // Write back control register
+4: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableDataCache):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Get control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Get control register EL3
+4: and x0, x0, #~CTRL_C_BIT // Clear C bit
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr sctlr_el1, x0 // Write back control register
+ b 4f
+2: msr sctlr_el2, x0 // Write back control register
+ b 4f
+3: msr sctlr_el3, x0 // Write back control register
+4: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmEnableInstructionCache):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Get control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Get control register EL3
+4: orr x0, x0, #CTRL_I_BIT // Set I bit
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr sctlr_el1, x0 // Write back control register
+ b 4f
+2: msr sctlr_el2, x0 // Write back control register
+ b 4f
+3: msr sctlr_el3, x0 // Write back control register
+4: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableInstructionCache):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Get control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Get control register EL3
+4: and x0, x0, #~CTRL_I_BIT // Clear I bit
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr sctlr_el1, x0 // Write back control register
+ b 4f
+2: msr sctlr_el2, x0 // Write back control register
+ b 4f
+3: msr sctlr_el3, x0 // Write back control register
+4: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmEnableAlignmentCheck):
+ EL1_OR_EL2(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 3f
+2: mrs x0, sctlr_el2 // Get control register EL2
+3: orr x0, x0, #CTRL_A_BIT // Set A (alignment check) bit
+ EL1_OR_EL2(x1)
+1: msr sctlr_el1, x0 // Write back control register
+ b 3f
+2: msr sctlr_el2, x0 // Write back control register
+3: dsb sy
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableAlignmentCheck):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, sctlr_el1 // Get control register EL1
+ b 4f
+2: mrs x0, sctlr_el2 // Get control register EL2
+ b 4f
+3: mrs x0, sctlr_el3 // Get control register EL3
+4: and x0, x0, #~CTRL_A_BIT // Clear A (alignment check) bit
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr sctlr_el1, x0 // Write back control register
+ b 4f
+2: msr sctlr_el2, x0 // Write back control register
+ b 4f
+3: msr sctlr_el3, x0 // Write back control register
+4: dsb sy
+ isb
+ ret
+
+
+// Always turned on in AArch64. Else implementation specific. Leave in for C compatibility for now
+ASM_PFX(ArmEnableBranchPrediction):
+ ret
+
+
+// Always turned on in AArch64. Else implementation specific. Leave in for C compatibility for now.
+ASM_PFX(ArmDisableBranchPrediction):
+ ret
+
+
+ASM_PFX(AArch64AllDataCachesOperation):
+// We can use regs 0-7 and 9-15 without having to save/restore.
+// Save our link register on the stack. - The stack must always be quad-word aligned
+ str x30, [sp, #-16]!
+ mov x1, x0 // Save Function call in x1
+ mrs x6, clidr_el1 // Read EL1 CLIDR
+ and x3, x6, #0x7000000 // Mask out all but Level of Coherency (LoC)
+ lsr x3, x3, #23 // Left align cache level value - the level is shifted by 1 to the
+ // right to ease the access to CSSELR and the Set/Way operation.
+ cbz x3, L_Finished // No need to clean if LoC is 0
+ mov x10, #0 // Start clean at cache level 0
+ b Loop1
+
+ASM_PFX(AArch64PerformPoUDataCacheOperation):
+// We can use regs 0-7 and 9-15 without having to save/restore.
+// Save our link register on the stack. - The stack must always be quad-word aligned
+ str x30, [sp, #-16]!
+ mov x1, x0 // Save Function call in x1
+ mrs x6, clidr_el1 // Read EL1 CLIDR
+ and x3, x6, #0x38000000 // Mask out all but Point of Unification (PoU)
+ lsr x3, x3, #26 // Left align cache level value - the level is shifted by 1 to the
+ // right to ease the access to CSSELR and the Set/Way operation.
+ cbz x3, L_Finished // No need to clean if LoC is 0
+ mov x10, #0 // Start clean at cache level 0
+
+Loop1:
+ add x2, x10, x10, lsr #1 // Work out 3x cachelevel for cache info
+ lsr x12, x6, x2 // bottom 3 bits are the Cache type for this level
+ and x12, x12, #7 // get those 3 bits alone
+ cmp x12, #2 // what cache at this level?
+ b.lt L_Skip // no cache or only instruction cache at this level
+ msr csselr_el1, x10 // write the Cache Size selection register with current level (CSSELR)
+ isb // isb to sync the change to the CacheSizeID reg
+ mrs x12, ccsidr_el1 // reads current Cache Size ID register (CCSIDR)
+ and x2, x12, #0x7 // extract the line length field
+ add x2, x2, #4 // add 4 for the line length offset (log2 16 bytes)
+ mov x4, #0x400
+ sub x4, x4, #1
+ and x4, x4, x12, lsr #3 // x4 is the max number on the way size (right aligned)
+ clz w5, w4 // w5 is the bit position of the way size increment
+ mov x7, #0x00008000
+ sub x7, x7, #1
+ and x7, x7, x12, lsr #13 // x7 is the max number of the index size (right aligned)
+
+Loop2:
+ mov x9, x4 // x9 working copy of the max way size (right aligned)
+
+Loop3:
+ lsl x11, x9, x5
+ orr x0, x10, x11 // factor in the way number and cache number
+ lsl x11, x7, x2
+ orr x0, x0, x11 // factor in the index number
+
+ blr x1 // Goto requested cache operation
+
+ subs x9, x9, #1 // decrement the way number
+ b.ge Loop3
+ subs x7, x7, #1 // decrement the index
+ b.ge Loop2
+L_Skip:
+ add x10, x10, #2 // increment the cache number
+ cmp x3, x10
+ b.gt Loop1
+
+L_Finished:
+ dsb sy
+ isb
+ ldr x30, [sp], #0x10
+ ret
+
+
+ASM_PFX(ArmDataMemoryBarrier):
+ dmb sy
+ ret
+
+
+ASM_PFX(ArmDataSyncronizationBarrier):
+ASM_PFX(ArmDrainWriteBuffer):
+ dsb sy
+ ret
+
+
+ASM_PFX(ArmInstructionSynchronizationBarrier):
+ isb
+ ret
+
+
+ASM_PFX(ArmWriteVBar):
+ EL1_OR_EL2_OR_EL3(x1)
+1: msr vbar_el1, x0 // Set the Address of the EL1 Vector Table in the VBAR register
+ b 4f
+2: msr vbar_el2, x0 // Set the Address of the EL2 Vector Table in the VBAR register
+ b 4f
+3: msr vbar_el3, x0 // Set the Address of the EL3 Vector Table in the VBAR register
+4: isb
+ ret
+
+ASM_PFX(ArmReadVBar):
+ EL1_OR_EL2_OR_EL3(x1)
+1: mrs x0, vbar_el1 // Set the Address of the EL1 Vector Table in the VBAR register
+ ret
+2: mrs x0, vbar_el2 // Set the Address of the EL2 Vector Table in the VBAR register
+ ret
+3: mrs x0, vbar_el3 // Set the Address of the EL3 Vector Table in the VBAR register
+ ret
+
+
+ASM_PFX(ArmEnableVFP):
+ // Check whether floating-point is implemented in the processor.
+ mov x1, x30 // Save LR
+ bl ArmReadIdPfr0 // Read EL1 Processor Feature Register (PFR0)
+ mov x30, x1 // Restore LR
+ ands x0, x0, #AARCH64_PFR0_FP// Extract bits indicating VFP implementation
+ cmp x0, #0 // VFP is implemented if '0'.
+ b.ne 4f // Exit if VFP not implemented.
+ // FVP is implemented.
+ // Make sure VFP exceptions are not trapped (to any exception level).
+ mrs x0, cpacr_el1 // Read EL1 Coprocessor Access Control Register (CPACR)
+ orr x0, x0, #CPACR_VFP_BITS // Disable FVP traps to EL1
+ msr cpacr_el1, x0 // Write back EL1 Coprocessor Access Control Register (CPACR)
+ mov x1, #AARCH64_CPTR_TFP // TFP Bit for trapping VFP Exceptions
+ EL1_OR_EL2_OR_EL3(x2)
+1:ret // Not configurable in EL1
+2:mrs x0, cptr_el2 // Disable VFP traps to EL2
+ bic x0, x0, x1
+ msr cptr_el2, x0
+ ret
+3:mrs x0, cptr_el3 // Disable VFP traps to EL3
+ bic x0, x0, x1
+ msr cptr_el3, x0
+4:ret
+
+
+ASM_PFX(ArmCallWFI):
+ wfi
+ ret
+
+
+ASM_PFX(ArmReadMpidr):
+ mrs x0, mpidr_el1 // read EL1 MPIDR
+ ret
+
+
+// Keep old function names for C compatibilty for now. Change later?
+ASM_PFX(ArmReadTpidrurw):
+ mrs x0, tpidr_el0 // read tpidr_el0 (v7 TPIDRURW) -> (v8 TPIDR_EL0)
+ ret
+
+
+// Keep old function names for C compatibilty for now. Change later?
+ASM_PFX(ArmWriteTpidrurw):
+ msr tpidr_el0, x0 // write tpidr_el0 (v7 TPIDRURW) -> (v8 TPIDR_EL0)
+ ret
+
+
+// Arch timers are mandatory on AArch64
+ASM_PFX(ArmIsArchTimerImplemented):
+ mov x0, #1
+ ret
+
+
+ASM_PFX(ArmReadIdPfr0):
+ mrs x0, id_aa64pfr0_el1 // Read ID_AA64PFR0 Register
+ ret
+
+
+// Q: id_aa64pfr1_el1 not defined yet. What does this funtion want to access?
+// A: used to setup arch timer. Check if we have security extensions, permissions to set stuff.
+// See: ArmPkg/Library/ArmArchTimerLib/AArch64/ArmArchTimerLib.c
+// Not defined yet, but stick in here for now, should read all zeros.
+ASM_PFX(ArmReadIdPfr1):
+ mrs x0, id_aa64pfr1_el1 // Read ID_PFR1 Register
+ ret
+
+// VOID ArmWriteHcr(UINTN Hcr)
+ASM_PFX(ArmWriteHcr):
+ msr hcr_el2, x0 // Write the passed HCR value
+ ret
+
+// UINTN ArmReadCurrentEL(VOID)
+ASM_PFX(ArmReadCurrentEL):
+ mrs x0, CurrentEL
+ ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
new file mode 100644
index 0000000..8fd4194
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
@@ -0,0 +1,127 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# 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 <AsmMacroIoLibV8.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT (ArmIsMpCore)
+GCC_ASM_EXPORT (ArmEnableAsynchronousAbort)
+GCC_ASM_EXPORT (ArmDisableAsynchronousAbort)
+GCC_ASM_EXPORT (ArmEnableIrq)
+GCC_ASM_EXPORT (ArmDisableIrq)
+GCC_ASM_EXPORT (ArmEnableFiq)
+GCC_ASM_EXPORT (ArmDisableFiq)
+GCC_ASM_EXPORT (ArmEnableInterrupts)
+GCC_ASM_EXPORT (ArmDisableInterrupts)
+GCC_ASM_EXPORT (ArmDisableAllExceptions)
+GCC_ASM_EXPORT (ReadCCSIDR)
+GCC_ASM_EXPORT (ReadCLIDR)
+
+#------------------------------------------------------------------------------
+
+.set MPIDR_U_BIT, (30)
+.set MPIDR_U_MASK, (1 << MPIDR_U_BIT)
+.set DAIF_FIQ_BIT, (1 << 0)
+.set DAIF_IRQ_BIT, (1 << 1)
+.set DAIF_ABORT_BIT, (1 << 2)
+.set DAIF_DEBUG_BIT, (1 << 3)
+.set DAIF_INT_BITS, (DAIF_FIQ_BIT | DAIF_IRQ_BIT)
+.set DAIF_ALL, (DAIF_DEBUG_BIT | DAIF_ABORT_BIT | DAIF_INT_BITS)
+
+
+ASM_PFX(ArmIsMpCore):
+ mrs x0, mpidr_el1 // Read EL1 Mutliprocessor Affinty Reg (MPIDR)
+ and x0, x0, #MPIDR_U_MASK // U Bit clear, the processor is part of a multiprocessor system
+ lsr x0, x0, #MPIDR_U_BIT
+ eor x0, x0, #1
+ ret
+
+
+ASM_PFX(ArmEnableAsynchronousAbort):
+ msr daifclr, #DAIF_ABORT_BIT
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableAsynchronousAbort):
+ msr daifset, #DAIF_ABORT_BIT
+ isb
+ ret
+
+
+ASM_PFX(ArmEnableIrq):
+ msr daifclr, #DAIF_IRQ_BIT
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableIrq):
+ msr daifset, #DAIF_IRQ_BIT
+ isb
+ ret
+
+
+ASM_PFX(ArmEnableFiq):
+ msr daifclr, #DAIF_FIQ_BIT
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableFiq):
+ msr daifset, #DAIF_FIQ_BIT
+ isb
+ ret
+
+
+ASM_PFX(ArmEnableInterrupts):
+ msr daifclr, #DAIF_INT_BITS
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableInterrupts):
+ msr daifset, #DAIF_INT_BITS
+ isb
+ ret
+
+
+ASM_PFX(ArmDisableAllExceptions):
+ msr daifset, #DAIF_ALL
+ isb
+ ret
+
+
+// UINT32
+// ReadCCSIDR (
+// IN UINT32 CSSELR
+// )
+ASM_PFX(ReadCCSIDR):
+ msr csselr_el1, x0 // Write Cache Size Selection Register (CSSELR)
+ isb
+ mrs x0, ccsidr_el1 // Read current Cache Size ID Register (CCSIDR)
+ ret
+
+
+// UINT32
+// ReadCLIDR (
+// IN UINT32 CSSELR
+// )
+ASM_PFX(ReadCLIDR):
+ mrs x0, clidr_el1 // Read Cache Level ID Register
+ ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c
new file mode 100644
index 0000000..8c54b6c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c
@@ -0,0 +1,49 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ 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 <Chipset/ARM1176JZ-S.h>
+
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+EFIAPI
+ArmWriteVBar (
+ IN UINTN VectorBase
+ )
+{
+ ASSERT(FeaturePcdGet (PcdRelocateVectorTable) == TRUE);
+
+ if (VectorBase == 0x0) {
+ ArmSetLowVectors ();
+ } else if (VectorBase == 0xFFFF0000) {
+ ArmSetHighVectors ();
+ } else {
+ // Feature not supported by ARM11. The Vector Table is either at 0x0 or 0xFFFF0000
+ ASSERT(0);
+ }
+}
+
+UINTN
+EFIAPI
+ArmReadVBar (
+ VOID
+ )
+{
+ ASSERT((FeaturePcdGet (PcdRelocateVectorTable) == TRUE) && ((PcdGet32 (PcdCpuVectorBaseAddress) == 0x0) || (PcdGet32 (PcdCpuVectorBaseAddress) == 0xFFFF0000)));
+ return PcdGet32 (PcdCpuVectorBaseAddress);
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.inf
new file mode 100644
index 0000000..32d9299
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.inf
@@ -0,0 +1,51 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = Arm11ArmLib
+ FILE_GUID = 00586300-0E06-4790-AC44-86C56ACBB942
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ Arm11Support.S | GCC
+ Arm11Support.asm | RVCT
+
+ Arm11Lib.c
+ Arm11LibMem.c
+ ../Arm9/Arm9CacheInformation.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FeaturePcd]
+ gArmTokenSpaceGuid.PcdRelocateVectorTable
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
+ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibMem.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibMem.c
new file mode 100644
index 0000000..0f89801
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibMem.c
@@ -0,0 +1,135 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ 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 <Chipset/ARM1176JZ-S.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+VOID
+FillTranslationTable (
+ IN UINT32 *TranslationTable,
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
+ )
+{
+ UINT32 *Entry;
+ UINTN Sections;
+ UINTN Index;
+ UINT32 Attributes;
+ UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
+
+ switch (MemoryRegion->Attributes) {
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
+ break;
+ default:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
+ break;
+ }
+
+ Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
+ Sections = ((( MemoryRegion->Length - 1 ) / TT_DESCRIPTOR_SECTION_SIZE ) + 1 );
+
+ for (Index = 0; Index < Sections; Index++)
+ {
+ *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
+ PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
+ }
+}
+
+RETURN_STATUS
+EFIAPI
+ArmConfigureMmu (
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
+ OUT VOID **TranslationTableBase OPTIONAL,
+ OUT UINTN *TranslationTableSize OPTIONAL
+ )
+{
+ VOID *TranslationTable;
+
+ // Allocate pages for translation table.
+ TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT));
+ if (TranslationTable == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+ TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK);
+
+ if (TranslationTableBase != NULL) {
+ *TranslationTableBase = TranslationTable;
+ }
+
+ if (TranslationTableBase != NULL) {
+ *TranslationTableSize = TRANSLATION_TABLE_SIZE;
+ }
+
+ ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE);
+
+ ArmCleanInvalidateDataCache();
+ ArmInvalidateInstructionCache();
+ ArmInvalidateTlb();
+
+ ArmDisableDataCache();
+ ArmDisableInstructionCache();
+ ArmDisableMmu();
+
+ // Make sure nothing sneaked into the cache
+ ArmCleanInvalidateDataCache();
+ ArmInvalidateInstructionCache();
+
+ while (MemoryTable->Length != 0) {
+ FillTranslationTable(TranslationTable, MemoryTable);
+ MemoryTable++;
+ }
+
+ ArmSetTTBR0(TranslationTable);
+
+ ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
+ DOMAIN_ACCESS_CONTROL_NONE(14) |
+ DOMAIN_ACCESS_CONTROL_NONE(13) |
+ DOMAIN_ACCESS_CONTROL_NONE(12) |
+ DOMAIN_ACCESS_CONTROL_NONE(11) |
+ DOMAIN_ACCESS_CONTROL_NONE(10) |
+ DOMAIN_ACCESS_CONTROL_NONE( 9) |
+ DOMAIN_ACCESS_CONTROL_NONE( 8) |
+ DOMAIN_ACCESS_CONTROL_NONE( 7) |
+ DOMAIN_ACCESS_CONTROL_NONE( 6) |
+ DOMAIN_ACCESS_CONTROL_NONE( 5) |
+ DOMAIN_ACCESS_CONTROL_NONE( 4) |
+ DOMAIN_ACCESS_CONTROL_NONE( 3) |
+ DOMAIN_ACCESS_CONTROL_NONE( 2) |
+ DOMAIN_ACCESS_CONTROL_NONE( 1) |
+ DOMAIN_ACCESS_CONTROL_MANAGER(0));
+
+ ArmEnableInstructionCache();
+ ArmEnableDataCache();
+ ArmEnableMmu();
+
+ return RETURN_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibPrePi.inf
new file mode 100644
index 0000000..94dd03d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibPrePi.inf
@@ -0,0 +1,51 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = Arm11ArmLib
+ FILE_GUID = 8dfb4ea2-3901-44f9-ae54-ca3d50362d2f
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ Arm11Support.S | GCC
+ Arm11Support.asm | RVCT
+
+ Arm11Lib.c
+ Arm11LibMem.c
+ ../Arm9/Arm9CacheInformation.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ PrePiLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FeaturePcd]
+ gArmTokenSpaceGuid.PcdRelocateVectorTable
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
+ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibSec.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibSec.inf
new file mode 100644
index 0000000..69763ed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11LibSec.inf
@@ -0,0 +1,47 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = Arm11LibSec
+ FILE_GUID = bfecdbc7-a860-4993-bc09-8e3ea762a758
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ Arm11Support.S | GCC
+ Arm11Support.asm | RVCT
+
+ Arm11Lib.c
+ ../Arm9/Arm9CacheInformation.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FeaturePcd]
+ gArmTokenSpaceGuid.PcdRelocateVectorTable
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
+ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S
new file mode 100644
index 0000000..25612f3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S
@@ -0,0 +1,257 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011, 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 <AsmMacroIoLib.h>
+
+.text
+.align 2
+GCC_ASM_EXPORT(ArmDisableCachesAndMmu)
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
+GCC_ASM_EXPORT(ArmCleanDataCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCache)
+GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmEnableMmu)
+GCC_ASM_EXPORT(ArmDisableMmu)
+GCC_ASM_EXPORT(ArmMmuEnabled)
+GCC_ASM_EXPORT(ArmEnableDataCache)
+GCC_ASM_EXPORT(ArmDisableDataCache)
+GCC_ASM_EXPORT(ArmEnableInstructionCache)
+GCC_ASM_EXPORT(ArmDisableInstructionCache)
+GCC_ASM_EXPORT(ArmEnableBranchPrediction)
+GCC_ASM_EXPORT(ArmDisableBranchPrediction)
+GCC_ASM_EXPORT(ArmDataMemoryBarrier)
+GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
+GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
+GCC_ASM_EXPORT(ArmSetLowVectors)
+GCC_ASM_EXPORT(ArmSetHighVectors)
+GCC_ASM_EXPORT(ArmIsMpCore)
+GCC_ASM_EXPORT(ArmCallWFI)
+GCC_ASM_EXPORT(ArmReadMpidr)
+GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)
+GCC_ASM_EXPORT(ArmEnableFiq)
+GCC_ASM_EXPORT(ArmDisableFiq)
+GCC_ASM_EXPORT(ArmEnableInterrupts)
+GCC_ASM_EXPORT(ArmDisableInterrupts)
+GCC_ASM_EXPORT (ArmEnableVFP)
+
+Arm11PartNumberMask: .word 0xFFF0
+Arm11PartNumber: .word 0xB020
+
+.set DC_ON, (0x1<<2)
+.set IC_ON, (0x1<<12)
+.set XP_ON, (0x1<<23)
+.set CTRL_M_BIT, (1 << 0)
+.set CTRL_C_BIT, (1 << 2)
+.set CTRL_I_BIT, (1 << 12)
+
+ASM_PFX(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
+ bx LR
+
+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c6, 1 @invalidate single data cache line
+ bx lr
+
+
+ASM_PFX(ArmCleanDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c10, 1 @clean single data cache line
+ bx lr
+
+
+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c14, 1 @clean and invalidate single data cache line
+ bx lr
+
+
+ASM_PFX(ArmCleanDataCache):
+ mcr p15, 0, r0, c7, c10, 0 @ clean entire data cache
+ bx lr
+
+
+ASM_PFX(ArmCleanInvalidateDataCache):
+ mcr p15, 0, r0, c7, c14, 0 @ clean and invalidate entire data cache
+ bx lr
+
+
+ASM_PFX(ArmInvalidateDataCache):
+ mcr p15, 0, r0, c7, c6, 0 @ invalidate entire data cache
+ bx lr
+
+
+ASM_PFX(ArmInvalidateInstructionCache):
+ mcr p15, 0, r0, c7, c5, 0 @invalidate entire instruction cache
+ mov R0,#0
+ mcr p15,0,R0,c7,c5,4 @Flush Prefetch buffer
+ bx lr
+
+ASM_PFX(ArmEnableMmu):
+ mrc p15,0,R0,c1,c0,0
+ orr R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ bx LR
+
+ASM_PFX(ArmMmuEnabled):
+ mrc p15,0,R0,c1,c0,0
+ and R0,R0,#1
+ bx LR
+
+ASM_PFX(ArmDisableMmu):
+ mrc p15,0,R0,c1,c0,0
+ bic R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ mov R0,#0
+ mcr p15,0,R0,c7,c10,4 @Data synchronization barrier
+ mov R0,#0
+ mcr p15,0,R0,c7,c5,4 @Flush Prefetch buffer
+ bx LR
+
+ASM_PFX(ArmEnableDataCache):
+ LoadConstantToReg(DC_ON, R1) @ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ orr R0,R0,R1 @Set C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmDisableDataCache):
+ LoadConstantToReg(DC_ON, R1) @ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ bic R0,R0,R1 @Clear C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmEnableInstructionCache):
+ ldr R1,=IC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ orr R0,R0,R1 @Set I bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmDisableInstructionCache):
+ ldr R1,=IC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ bic R0,R0,R1 @Clear I bit.
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmEnableBranchPrediction):
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ bx LR
+
+ASM_PFX(ArmDisableBranchPrediction):
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ bx LR
+
+ASM_PFX(ArmDataMemoryBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #5
+ bx LR
+
+ASM_PFX(ArmDataSyncronizationBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #4
+ bx LR
+
+ASM_PFX(ArmInstructionSynchronizationBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C5, #4
+ bx LR
+
+ASM_PFX(ArmSetLowVectors):
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 @ clear V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ bx LR
+
+ASM_PFX(ArmSetHighVectors):
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ orr r0, r0, #0x00002000 @ clear V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ bx LR
+
+ASM_PFX(ArmIsMpCore):
+ push { r1 }
+ mrc p15, 0, r0, c0, c0, 0
+ # Extract Part Number to check it is an ARM11MP core (0xB02)
+ LoadConstantToReg (Arm11PartNumberMask, r1)
+ and r0, r0, r1
+ LoadConstantToReg (Arm11PartNumber, r1)
+ cmp r0, r1
+ movne r0, #0
+ pop { r1 }
+ bx lr
+
+ASM_PFX(ArmCallWFI):
+ wfi
+ bx lr
+
+ASM_PFX(ArmReadMpidr):
+ mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
+ bx lr
+
+ASM_PFX(ArmEnableFiq):
+ mrs R0,CPSR
+ bic R0,R0,#0x40 @Enable FIQ interrupts
+ msr CPSR_c,R0
+ bx LR
+
+ASM_PFX(ArmDisableFiq):
+ mrs R0,CPSR
+ orr R1,R0,#0x40 @Disable FIQ interrupts
+ msr CPSR_c,R1
+ tst R0,#0x80
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ASM_PFX(ArmEnableInterrupts):
+ mrs R0,CPSR
+ bic R0,R0,#0x80 @Enable IRQ interrupts
+ msr CPSR_c,R0
+ bx LR
+
+ASM_PFX(ArmDisableInterrupts):
+ mrs R0,CPSR
+ orr R1,R0,#0x80 @Disable IRQ interrupts
+ msr CPSR_c,R1
+ tst R0,#0x80
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ASM_PFX(ArmEnableVFP):
+ # Read CPACR (Coprocessor Access Control Register)
+ mrc p15, 0, r0, c1, c0, 2
+ # Enable VPF access (Full Access to CP10, CP11) (V* instructions)
+ orr r0, r0, #0x00f00000
+ # Write back CPACR (Coprocessor Access Control Register)
+ mcr p15, 0, r0, c1, c0, 2
+ # Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.
+ mov r0, #0x40000000
+ #TODO: Fixme - need compilation flag
+ #fmxr FPEXC, r0
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm
new file mode 100644
index 0000000..53283d1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm
@@ -0,0 +1,157 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+ EXPORT ArmCleanInvalidateDataCache
+ EXPORT ArmCleanDataCache
+ EXPORT ArmInvalidateDataCache
+ EXPORT ArmInvalidateInstructionCache
+ EXPORT ArmInvalidateDataCacheEntryByMVA
+ EXPORT ArmCleanDataCacheEntryByMVA
+ EXPORT ArmCleanInvalidateDataCacheEntryByMVA
+ EXPORT ArmEnableMmu
+ EXPORT ArmDisableMmu
+ EXPORT ArmMmuEnabled
+ EXPORT ArmEnableDataCache
+ EXPORT ArmDisableDataCache
+ EXPORT ArmEnableInstructionCache
+ EXPORT ArmDisableInstructionCache
+ EXPORT ArmEnableBranchPrediction
+ EXPORT ArmDisableBranchPrediction
+ EXPORT ArmDataMemoryBarrier
+ EXPORT ArmDataSyncronizationBarrier
+ EXPORT ArmInstructionSynchronizationBarrier
+
+
+DC_ON EQU ( 0x1:SHL:2 )
+IC_ON EQU ( 0x1:SHL:12 )
+XP_ON EQU ( 0x1:SHL:23 )
+
+
+ AREA ArmCacheLib, CODE, READONLY
+ PRESERVE8
+
+
+ArmInvalidateDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c6, 1 ; invalidate single data cache line
+ bx lr
+
+
+ArmCleanDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c10, 1 ; clean single data cache line
+ bx lr
+
+
+ArmCleanInvalidateDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c14, 1 ; clean and invalidate single data cache line
+ bx lr
+
+
+ArmCleanDataCache
+ mcr p15, 0, r0, c7, c10, 0 ; clean entire data cache
+ bx lr
+
+
+ArmCleanInvalidateDataCache
+ mcr p15, 0, r0, c7, c14, 0 ; clean and invalidate entire data cache
+ bx lr
+
+
+ArmInvalidateDataCache
+ mcr p15, 0, r0, c7, c6, 0 ; invalidate entire data cache
+ bx lr
+
+
+ArmInvalidateInstructionCache
+ mcr p15, 0, r0, c7, c5, 0 ;invalidate entire instruction cache
+ mov R0,#0
+ mcr p15,0,R0,c7,c5,4 ;Flush Prefetch buffer
+ bx lr
+
+ArmEnableMmu
+ mrc p15,0,R0,c1,c0,0
+ orr R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ bx LR
+
+ArmMmuEnabled
+ mrc p15,0,R0,c1,c0,0
+ and R0,R0,#1
+ bx LR
+
+ArmDisableMmu
+ mrc p15,0,R0,c1,c0,0
+ bic R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ mov R0,#0
+ mcr p15,0,R0,c7,c10,4 ;Data synchronization barrier
+ mov R0,#0
+ mcr p15,0,R0,c7,c5,4 ;Flush Prefetch buffer
+ bx LR
+
+ArmEnableDataCache
+ LDR R1,=DC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ ORR R0,R0,R1 ;Set C bit
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmDisableDataCache
+ LDR R1,=DC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ BIC R0,R0,R1 ;Clear C bit
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmEnableInstructionCache
+ LDR R1,=IC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ ORR R0,R0,R1 ;Set I bit
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmDisableInstructionCache
+ LDR R1,=IC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ BIC R0,R0,R1 ;Clear I bit.
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmEnableBranchPrediction
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ bx LR
+
+ArmDisableBranchPrediction
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ bx LR
+
+ASM_PFX(ArmDataMemoryBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #5
+ bx LR
+
+ASM_PFX(ArmDataSyncronizationBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #4
+ bx LR
+
+ASM_PFX(ArmInstructionSynchronizationBarrier):
+ MOV R0, #0
+ MCR P15, #0, R0, C7, C5, #4
+ bx LR
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
new file mode 100644
index 0000000..81661b2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
@@ -0,0 +1,46 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = Arm9ArmLib
+ FILE_GUID = 375D70D3-91E0-4374-A540-68BD959EB184
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ Arm9Support.S | GCC
+ Arm9Support.asm | RVCT
+
+ Arm9Lib.c
+ Arm9CacheInformation.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
new file mode 100644
index 0000000..0730487
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
@@ -0,0 +1,46 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = Arm9ArmLibPrePi
+ FILE_GUID = e9b6011f-ee15-4e59-ab8f-a819a081fa54
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ Arm9Support.S | GCC
+ Arm9Support.asm | RVCT
+
+ Arm9Lib.c
+ Arm9CacheInformation.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ PrePiLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
new file mode 100644
index 0000000..f0b5060
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
@@ -0,0 +1,165 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 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 <Library/ArmLib.h>
+#include "ArmLibPrivate.h"
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+ VOID
+ )
+{
+ switch (CACHE_TYPE (ArmCacheInfo ()))
+ {
+ case CACHE_TYPE_WRITE_BACK: return ARM_CACHE_TYPE_WRITE_BACK;
+ default: return ARM_CACHE_TYPE_UNKNOWN;
+ }
+}
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+ VOID
+ )
+{
+ switch (CACHE_ARCHITECTURE (ArmCacheInfo ()))
+ {
+ case CACHE_ARCHITECTURE_UNIFIED: return ARM_CACHE_ARCHITECTURE_UNIFIED;
+ case CACHE_ARCHITECTURE_SEPARATE: return ARM_CACHE_ARCHITECTURE_SEPARATE;
+ default: return ARM_CACHE_ARCHITECTURE_UNKNOWN;
+ }
+}
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+ VOID
+ )
+{
+ switch (DATA_CACHE_PRESENT (ArmCacheInfo ()))
+ {
+ case CACHE_PRESENT: return TRUE;
+ case CACHE_NOT_PRESENT: return FALSE;
+ default: return FALSE;
+ }
+}
+
+UINTN
+EFIAPI
+ArmDataCacheSize (
+ VOID
+ )
+{
+ switch (DATA_CACHE_SIZE (ArmCacheInfo ()))
+ {
+ case CACHE_SIZE_4_KB: return 4 * 1024;
+ case CACHE_SIZE_8_KB: return 8 * 1024;
+ case CACHE_SIZE_16_KB: return 16 * 1024;
+ case CACHE_SIZE_32_KB: return 32 * 1024;
+ case CACHE_SIZE_64_KB: return 64 * 1024;
+ case CACHE_SIZE_128_KB: return 128 * 1024;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+ VOID
+ )
+{
+ switch (DATA_CACHE_ASSOCIATIVITY (ArmCacheInfo ()))
+ {
+ case CACHE_ASSOCIATIVITY_4_WAY: return 4;
+ case CACHE_ASSOCIATIVITY_DIRECT: return 1;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+ VOID
+ )
+{
+ switch (DATA_CACHE_LINE_LENGTH (ArmCacheInfo ()))
+ {
+ case CACHE_LINE_LENGTH_32_BYTES: return 32;
+ default: return 0;
+ }
+}
+
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_PRESENT (ArmCacheInfo ()))
+ {
+ case CACHE_PRESENT: return TRUE;
+ case CACHE_NOT_PRESENT: return FALSE;
+ default: return FALSE;
+ }
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_SIZE (ArmCacheInfo ()))
+ {
+ case CACHE_SIZE_4_KB: return 4 * 1024;
+ case CACHE_SIZE_8_KB: return 8 * 1024;
+ case CACHE_SIZE_16_KB: return 16 * 1024;
+ case CACHE_SIZE_32_KB: return 32 * 1024;
+ case CACHE_SIZE_64_KB: return 64 * 1024;
+ case CACHE_SIZE_128_KB: return 128 * 1024;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_ASSOCIATIVITY (ArmCacheInfo ()))
+ {
+ case CACHE_ASSOCIATIVITY_8_WAY: return 8;
+ case CACHE_ASSOCIATIVITY_4_WAY: return 4;
+ case CACHE_ASSOCIATIVITY_DIRECT: return 1;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_LINE_LENGTH (ArmCacheInfo ()))
+ {
+ case CACHE_LINE_LENGTH_32_BYTES: return 32;
+ default: return 0;
+ }
+}
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c
new file mode 100644
index 0000000..7432f7b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c
@@ -0,0 +1,134 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ 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 <Chipset/ARM926EJ-S.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+VOID
+FillTranslationTable (
+ IN UINT32 *TranslationTable,
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
+ )
+{
+ UINT32 *Entry;
+ UINTN Sections;
+ UINTN Index;
+ UINT32 Attributes;
+ UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
+
+ switch (MemoryRegion->Attributes) {
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
+ ASSERT(0); // Trustzone is not supported on ARMv5
+ default:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
+ break;
+ }
+
+ Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
+ Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;
+
+ // The current code does not support memory region size that is not aligned on TT_DESCRIPTOR_SECTION_SIZE boundary
+ ASSERT (MemoryRegion->Length % TT_DESCRIPTOR_SECTION_SIZE == 0);
+
+ for (Index = 0; Index < Sections; Index++)
+ {
+ *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
+ PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
+ }
+}
+
+RETURN_STATUS
+EFIAPI
+ArmConfigureMmu (
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
+ OUT VOID **TranslationTableBase OPTIONAL,
+ OUT UINTN *TranslationTableSize OPTIONAL
+ )
+{
+ VOID *TranslationTable;
+
+ // Allocate pages for translation table.
+ TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT));
+ if (TranslationTable == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+ TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK);
+
+ if (TranslationTableBase != NULL) {
+ *TranslationTableBase = TranslationTable;
+ }
+
+ if (TranslationTableBase != NULL) {
+ *TranslationTableSize = TRANSLATION_TABLE_SIZE;
+ }
+
+ ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE);
+
+ ArmCleanInvalidateDataCache();
+ ArmInvalidateInstructionCache();
+ ArmInvalidateTlb();
+
+ ArmDisableDataCache();
+ ArmDisableInstructionCache();
+ ArmDisableMmu();
+
+ // Make sure nothing sneaked into the cache
+ ArmCleanInvalidateDataCache();
+ ArmInvalidateInstructionCache();
+
+ while (MemoryTable->Length != 0) {
+ FillTranslationTable(TranslationTable, MemoryTable);
+ MemoryTable++;
+ }
+
+ ArmSetTTBR0(TranslationTable);
+
+ ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
+ DOMAIN_ACCESS_CONTROL_NONE(14) |
+ DOMAIN_ACCESS_CONTROL_NONE(13) |
+ DOMAIN_ACCESS_CONTROL_NONE(12) |
+ DOMAIN_ACCESS_CONTROL_NONE(11) |
+ DOMAIN_ACCESS_CONTROL_NONE(10) |
+ DOMAIN_ACCESS_CONTROL_NONE( 9) |
+ DOMAIN_ACCESS_CONTROL_NONE( 8) |
+ DOMAIN_ACCESS_CONTROL_NONE( 7) |
+ DOMAIN_ACCESS_CONTROL_NONE( 6) |
+ DOMAIN_ACCESS_CONTROL_NONE( 5) |
+ DOMAIN_ACCESS_CONTROL_NONE( 4) |
+ DOMAIN_ACCESS_CONTROL_NONE( 3) |
+ DOMAIN_ACCESS_CONTROL_NONE( 2) |
+ DOMAIN_ACCESS_CONTROL_NONE( 1) |
+ DOMAIN_ACCESS_CONTROL_MANAGER(0));
+
+ ArmEnableInstructionCache();
+ ArmEnableDataCache();
+ ArmEnableMmu();
+
+ return RETURN_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S
new file mode 100644
index 0000000..c708d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S
@@ -0,0 +1,153 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
+GCC_ASM_EXPORT(ArmCleanDataCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCache)
+GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmEnableMmu)
+GCC_ASM_EXPORT(ArmDisableMmu)
+GCC_ASM_EXPORT(ArmMmuEnabled)
+GCC_ASM_EXPORT(ArmEnableDataCache)
+GCC_ASM_EXPORT(ArmDisableDataCache)
+GCC_ASM_EXPORT(ArmEnableInstructionCache)
+GCC_ASM_EXPORT(ArmDisableInstructionCache)
+GCC_ASM_EXPORT(ArmEnableBranchPrediction)
+GCC_ASM_EXPORT(ArmDisableBranchPrediction)
+GCC_ASM_EXPORT(ArmDataMemoryBarrier)
+GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
+GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
+
+
+.set DC_ON, (1<<2)
+.set IC_ON, (1<<12)
+
+#------------------------------------------------------------------------------
+
+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate single data cache line
+ bx lr
+
+ASM_PFX(ArmCleanDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c10, 1 @ clean single data cache line
+ bx lr
+
+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate single data cache line
+ bx lr
+
+ASM_PFX(ArmEnableInstructionCache):
+ ldr r1,=IC_ON
+ mrc p15,0,r0,c1,c0,0 @Read control register configuration data
+ orr r0,r0,r1 @Set I bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmDisableInstructionCache):
+ ldr r1,=IC_ON
+ mrc p15,0,r0,c1,c0,0 @Read control register configuration data
+ bic r0,r0,r1 @Clear I bit.
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmInvalidateInstructionCache):
+ mov r0,#0
+ mcr p15,0,r0,c7,c5,0 @Invalidate entire Instruction cache.
+ @Also flushes the branch target cache.
+ mov r0,#0
+ mcr p15,0,r0,c7,c10,4 @Data write buffer
+ bx LR
+
+ASM_PFX(ArmEnableMmu):
+ mrc p15,0,R0,c1,c0,0
+ orr R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ bx LR
+
+ASM_PFX(ArmMmuEnabled):
+ mrc p15,0,R0,c1,c0,0
+ and R0,R0,#1
+ bx LR
+
+ASM_PFX(ArmDisableMmu):
+ mrc p15,0,R0,c1,c0,0
+ bic R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ mov R0,#0
+ mcr p15,0,R0,c7,c10,4 @Drain write buffer
+ bx LR
+
+ASM_PFX(ArmEnableDataCache):
+ ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ orr R0,R0,R1 @Set C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmDisableDataCache):
+ ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ bic R0,R0,R1 @Clear C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ bx LR
+
+ASM_PFX(ArmCleanDataCache):
+ mrc p15,0,r15,c7,c10,3
+ bne ASM_PFX(ArmCleanDataCache)
+ mov R0,#0
+ mcr p15,0,R0,c7,c10,4 @Drain write buffer
+ bx LR
+
+ASM_PFX(ArmInvalidateDataCache):
+ mov R0,#0
+ mcr p15,0,R0,c7,c6,0 @Invalidate entire data cache
+ mov R0,#0
+ mcr p15,0,R0,c7,c10,4 @Drain write buffer
+ bx LR
+
+ASM_PFX(ArmCleanInvalidateDataCache):
+ mrc p15,0,r15,c7,c14,3
+ bne ASM_PFX(ArmCleanInvalidateDataCache)
+ mov R0,#0
+ mcr p15,0,R0,c7,c10,4 @Drain write buffer
+ bx LR
+
+ASM_PFX(ArmEnableBranchPrediction):
+ bx LR @Branch prediction is not supported.
+
+ASM_PFX(ArmDisableBranchPrediction):
+ bx LR @Branch prediction is not supported.
+
+ASM_PFX(ArmDataMemoryBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #5 @ check if this is OK?
+ bx LR
+
+ASM_PFX(ArmDataSyncronizationBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #4 @ check if this is OK?
+ bx LR
+
+ASM_PFX(ArmInstructionSynchronizationBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C5, #4 @ check if this is OK?
+ bx LR
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm
new file mode 100644
index 0000000..4aaa546
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm
@@ -0,0 +1,153 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+ EXPORT ArmCleanInvalidateDataCache
+ EXPORT ArmCleanDataCache
+ EXPORT ArmInvalidateDataCache
+ EXPORT ArmInvalidateInstructionCache
+ EXPORT ArmInvalidateDataCacheEntryByMVA
+ EXPORT ArmCleanDataCacheEntryByMVA
+ EXPORT ArmCleanInvalidateDataCacheEntryByMVA
+ EXPORT ArmEnableMmu
+ EXPORT ArmDisableMmu
+ EXPORT ArmMmuEnabled
+ EXPORT ArmEnableDataCache
+ EXPORT ArmDisableDataCache
+ EXPORT ArmEnableInstructionCache
+ EXPORT ArmDisableInstructionCache
+ EXPORT ArmEnableBranchPrediction
+ EXPORT ArmDisableBranchPrediction
+ EXPORT ArmDataMemoryBarrier
+ EXPORT ArmDataSyncronizationBarrier
+ EXPORT ArmInstructionSynchronizationBarrier
+
+
+DC_ON EQU ( 0x1:SHL:2 )
+IC_ON EQU ( 0x1:SHL:12 )
+
+ AREA ArmCacheLib, CODE, READONLY
+ PRESERVE8
+
+
+ArmInvalidateDataCacheEntryByMVA
+ MCR p15, 0, r0, c7, c6, 1 ; invalidate single data cache line
+ BX lr
+
+
+ArmCleanDataCacheEntryByMVA
+ MCR p15, 0, r0, c7, c10, 1 ; clean single data cache line
+ BX lr
+
+
+ArmCleanInvalidateDataCacheEntryByMVA
+ MCR p15, 0, r0, c7, c14, 1 ; clean and invalidate single data cache line
+ BX lr
+
+ArmEnableInstructionCache
+ LDR R1,=IC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ ORR R0,R0,R1 ;Set I bit
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmDisableInstructionCache
+ LDR R1,=IC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ BIC R0,R0,R1 ;Clear I bit.
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmInvalidateInstructionCache
+ MOV R0,#0
+ MCR p15,0,R0,c7,c5,0 ;Invalidate entire instruction cache
+ MOV R0,#0
+ MCR p15,0,R0,c7,c10,4 ;Drain write buffer
+ BX LR
+
+ArmEnableMmu
+ mrc p15,0,R0,c1,c0,0
+ orr R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ bx LR
+
+ArmMmuEnabled
+ mrc p15,0,R0,c1,c0,0
+ and R0,R0,#1
+ bx LR
+
+ArmDisableMmu
+ mrc p15,0,R0,c1,c0,0
+ bic R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ mov R0,#0
+ mcr p15,0,R0,c7,c10,4 ;Drain write buffer
+ bx LR
+
+ArmEnableDataCache
+ LDR R1,=DC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ ORR R0,R0,R1 ;Set C bit
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmDisableDataCache
+ LDR R1,=DC_ON
+ MRC p15,0,R0,c1,c0,0 ;Read control register configuration data
+ BIC R0,R0,R1 ;Clear C bit
+ MCR p15,0,r0,c1,c0,0 ;Write control register configuration data
+ BX LR
+
+ArmCleanDataCache
+ MRC p15,0,r15,c7,c10,3
+ BNE ArmCleanDataCache
+ MOV R0,#0
+ MCR p15,0,R0,c7,c10,4 ;Drain write buffer
+ BX LR
+
+ArmInvalidateDataCache
+ MOV R0,#0
+ MCR p15,0,R0,c7,c6,0 ;Invalidate entire data cache
+ MOV R0,#0
+ MCR p15,0,R0,c7,c10,4 ;Drain write buffer
+ BX LR
+
+ArmCleanInvalidateDataCache
+ MRC p15,0,r15,c7,c14,3
+ BNE ArmCleanInvalidateDataCache
+ MOV R0,#0
+ MCR p15,0,R0,c7,c10,4 ;Drain write buffer
+ BX LR
+
+ArmEnableBranchPrediction
+ bx LR ;Branch prediction is not supported.
+
+ArmDisableBranchPrediction
+ bx LR ;Branch prediction is not supported.
+
+ASM_PFX(ArmDataMemoryBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #5 ; Check to see if this is correct
+ bx LR
+
+ASM_PFX(ArmDataSyncronizationBarrier):
+ mov R0, #0
+ mcr P15, #0, R0, C7, C10, #4 ; Check to see if this is correct
+ bx LR
+
+ASM_PFX(ArmInstructionSynchronizationBarrier):
+ MOV R0, #0
+ MCR P15, #0, R0, C7, C5, #4 ; Check to see if this is correct
+ bx LR
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S
new file mode 100644
index 0000000..b94239f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S
@@ -0,0 +1,113 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# 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 <AsmMacroIoLib.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmIsMpCore)
+GCC_ASM_EXPORT(ArmEnableAsynchronousAbort)
+GCC_ASM_EXPORT(ArmDisableAsynchronousAbort)
+GCC_ASM_EXPORT(ArmEnableIrq)
+GCC_ASM_EXPORT(ArmDisableIrq)
+GCC_ASM_EXPORT(ArmEnableFiq)
+GCC_ASM_EXPORT(ArmDisableFiq)
+GCC_ASM_EXPORT(ArmEnableInterrupts)
+GCC_ASM_EXPORT(ArmDisableInterrupts)
+GCC_ASM_EXPORT(ReadCCSIDR)
+GCC_ASM_EXPORT(ReadCLIDR)
+GCC_ASM_EXPORT(ArmReadNsacr)
+GCC_ASM_EXPORT(ArmWriteNsacr)
+
+#------------------------------------------------------------------------------
+
+ASM_PFX(ArmIsMpCore):
+ mrc p15,0,R0,c0,c0,5
+ // Get Multiprocessing extension (bit31) & U bit (bit30)
+ and R0, R0, #0xC0000000
+ // if (bit31 == 1) && (bit30 == 0) then the processor is part of a multiprocessor system
+ cmp R0, #0x80000000
+ moveq R0, #1
+ movne R0, #0
+ bx LR
+
+ASM_PFX(ArmEnableAsynchronousAbort):
+ cpsie a
+ isb
+ bx LR
+
+ASM_PFX(ArmDisableAsynchronousAbort):
+ cpsid a
+ isb
+ bx LR
+
+ASM_PFX(ArmEnableIrq):
+ cpsie i
+ isb
+ bx LR
+
+ASM_PFX(ArmDisableIrq):
+ cpsid i
+ isb
+ bx LR
+
+ASM_PFX(ArmEnableFiq):
+ cpsie f
+ isb
+ bx LR
+
+ASM_PFX(ArmDisableFiq):
+ cpsid f
+ isb
+ bx LR
+
+ASM_PFX(ArmEnableInterrupts):
+ cpsie if
+ isb
+ bx LR
+
+ASM_PFX(ArmDisableInterrupts):
+ cpsid if
+ isb
+ bx LR
+
+// UINT32
+// ReadCCSIDR (
+// IN UINT32 CSSELR
+// )
+ASM_PFX(ReadCCSIDR):
+ mcr p15,2,r0,c0,c0,0 @ Write Cache Size Selection Register (CSSELR)
+ isb
+ mrc p15,1,r0,c0,c0,0 @ Read current CP15 Cache Size ID Register (CCSIDR)
+ bx lr
+
+// UINT32
+// ReadCLIDR (
+// IN UINT32 CSSELR
+// )
+ASM_PFX(ReadCLIDR):
+ mrc p15,1,r0,c0,c0,1 @ Read CP15 Cache Level ID Register
+ bx lr
+
+ASM_PFX(ArmReadNsacr):
+ mrc p15, 0, r0, c1, c1, 2
+ bx lr
+
+ASM_PFX(ArmWriteNsacr):
+ mcr p15, 0, r0, c1, c1, 2
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm
new file mode 100644
index 0000000..82daa3c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm
@@ -0,0 +1,112 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+// 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT ArmIsMpCore
+ EXPORT ArmEnableAsynchronousAbort
+ EXPORT ArmDisableAsynchronousAbort
+ EXPORT ArmEnableIrq
+ EXPORT ArmDisableIrq
+ EXPORT ArmEnableFiq
+ EXPORT ArmDisableFiq
+ EXPORT ArmEnableInterrupts
+ EXPORT ArmDisableInterrupts
+ EXPORT ReadCCSIDR
+ EXPORT ReadCLIDR
+ EXPORT ArmReadNsacr
+ EXPORT ArmWriteNsacr
+
+ AREA ArmLibSupportV7, CODE, READONLY
+
+
+//------------------------------------------------------------------------------
+
+ArmIsMpCore
+ mrc p15,0,R0,c0,c0,5
+ // Get Multiprocessing extension (bit31) & U bit (bit30)
+ and R0, R0, #0xC0000000
+ // if (bit31 == 1) && (bit30 == 0) then the processor is part of a multiprocessor system
+ cmp R0, #0x80000000
+ moveq R0, #1
+ movne R0, #0
+ bx LR
+
+ArmEnableAsynchronousAbort
+ cpsie a
+ isb
+ bx LR
+
+ArmDisableAsynchronousAbort
+ cpsid a
+ isb
+ bx LR
+
+ArmEnableIrq
+ cpsie i
+ isb
+ bx LR
+
+ArmDisableIrq
+ cpsid i
+ isb
+ bx LR
+
+ArmEnableFiq
+ cpsie f
+ isb
+ bx LR
+
+ArmDisableFiq
+ cpsid f
+ isb
+ bx LR
+
+ArmEnableInterrupts
+ cpsie if
+ isb
+ bx LR
+
+ArmDisableInterrupts
+ cpsid if
+ isb
+ bx LR
+
+// UINT32
+// ReadCCSIDR (
+// IN UINT32 CSSELR
+// )
+ReadCCSIDR
+ mcr p15,2,r0,c0,c0,0 ; Write Cache Size Selection Register (CSSELR)
+ isb
+ mrc p15,1,r0,c0,c0,0 ; Read current CP15 Cache Size ID Register (CCSIDR)
+ bx lr
+
+// UINT32
+// ReadCLIDR (
+// IN UINT32 CSSELR
+// )
+ReadCLIDR
+ mrc p15,1,r0,c0,c0,1 ; Read CP15 Cache Level ID Register
+ bx lr
+
+ArmReadNsacr
+ mrc p15, 0, r0, c1, c1, 2
+ bx lr
+
+ArmWriteNsacr
+ mcr p15, 0, r0, c1, c1, 2
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c
new file mode 100644
index 0000000..49be71b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c
@@ -0,0 +1,168 @@
+/** @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 <Uefi.h>
+#include <Chipset/ArmV7.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include "ArmV7Lib.h"
+#include "ArmLibPrivate.h"
+#include <Library/ArmArchTimer.h>
+
+VOID
+EFIAPI
+ArmArchTimerReadReg (
+ IN ARM_ARCH_TIMER_REGS Reg,
+ OUT VOID *DstBuf
+ )
+{
+ // Check if the Generic/Architecture timer is implemented
+ if (ArmIsArchTimerImplemented ()) {
+ switch (Reg) {
+ case CntFrq:
+ *((UINTN *)DstBuf) = ArmReadCntFrq ();
+ return;
+
+ case CntPct:
+ *((UINT64 *)DstBuf) = ArmReadCntPct ();
+ return;
+
+ case CntkCtl:
+ *((UINTN *)DstBuf) = ArmReadCntkCtl();
+ return;
+
+ case CntpTval:
+ *((UINTN *)DstBuf) = ArmReadCntpTval ();
+ return;
+
+ case CntpCtl:
+ *((UINTN *)DstBuf) = ArmReadCntpCtl ();
+ return;
+
+ case CntvTval:
+ *((UINTN *)DstBuf) = ArmReadCntvTval ();
+ return;
+
+ case CntvCtl:
+ *((UINTN *)DstBuf) = ArmReadCntvCtl ();
+ return;
+
+ case CntvCt:
+ *((UINT64 *)DstBuf) = ArmReadCntvCt ();
+ return;
+
+ case CntpCval:
+ *((UINT64 *)DstBuf) = ArmReadCntpCval ();
+ return;
+
+ case CntvCval:
+ *((UINT64 *)DstBuf) = ArmReadCntvCval ();
+ return;
+
+ case CntvOff:
+ *((UINT64 *)DstBuf) = ArmReadCntvOff ();
+ return;
+
+ case CnthCtl:
+ case CnthpTval:
+ case CnthpCtl:
+ case CnthpCval:
+ DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));
+ break;
+
+ default:
+ DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));
+ }
+ } else {
+ DEBUG ((EFI_D_ERROR, "Attempt to read ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));
+ ASSERT (0);
+ }
+
+ *((UINT64 *)DstBuf) = 0;
+}
+
+VOID
+EFIAPI
+ArmArchTimerWriteReg (
+ IN ARM_ARCH_TIMER_REGS Reg,
+ IN VOID *SrcBuf
+ )
+{
+ // Check if the Generic/Architecture timer is implemented
+ if (ArmIsArchTimerImplemented ()) {
+
+ switch (Reg) {
+
+ case CntFrq:
+ ArmWriteCntFrq (*((UINTN *)SrcBuf));
+ break;
+
+ case CntPct:
+ DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTPCT \n"));
+ break;
+
+ case CntkCtl:
+ ArmWriteCntkCtl (*((UINTN *)SrcBuf));
+ break;
+
+ case CntpTval:
+ ArmWriteCntpTval (*((UINTN *)SrcBuf));
+ break;
+
+ case CntpCtl:
+ ArmWriteCntpCtl (*((UINTN *)SrcBuf));
+ break;
+
+ case CntvTval:
+ ArmWriteCntvTval (*((UINTN *)SrcBuf));
+ break;
+
+ case CntvCtl:
+ ArmWriteCntvCtl (*((UINTN *)SrcBuf));
+ break;
+
+ case CntvCt:
+ DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTVCT \n"));
+ break;
+
+ case CntpCval:
+ ArmWriteCntpCval (*((UINT64 *)SrcBuf) );
+ break;
+
+ case CntvCval:
+ ArmWriteCntvCval (*((UINT64 *)SrcBuf) );
+ break;
+
+ case CntvOff:
+ ArmWriteCntvOff (*((UINT64 *)SrcBuf));
+ break;
+
+ case CnthCtl:
+ case CnthpTval:
+ case CnthpCtl:
+ case CnthpCval:
+ DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));
+ break;
+
+ default:
+ DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));
+ }
+ } else {
+ DEBUG ((EFI_D_ERROR, "Attempt to write to ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));
+ ASSERT (0);
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.S
new file mode 100644
index 0000000..ec4ede5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.S
@@ -0,0 +1,119 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2011, 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+
+GCC_ASM_EXPORT (ArmReadCntFrq)
+GCC_ASM_EXPORT (ArmWriteCntFrq)
+GCC_ASM_EXPORT (ArmReadCntPct)
+GCC_ASM_EXPORT (ArmReadCntkCtl)
+GCC_ASM_EXPORT (ArmWriteCntkCtl)
+GCC_ASM_EXPORT (ArmReadCntpTval)
+GCC_ASM_EXPORT (ArmWriteCntpTval)
+GCC_ASM_EXPORT (ArmReadCntpCtl)
+GCC_ASM_EXPORT (ArmWriteCntpCtl)
+GCC_ASM_EXPORT (ArmReadCntvTval)
+GCC_ASM_EXPORT (ArmWriteCntvTval)
+GCC_ASM_EXPORT (ArmReadCntvCtl)
+GCC_ASM_EXPORT (ArmWriteCntvCtl)
+GCC_ASM_EXPORT (ArmReadCntvCt)
+GCC_ASM_EXPORT (ArmReadCntpCval)
+GCC_ASM_EXPORT (ArmWriteCntpCval)
+GCC_ASM_EXPORT (ArmReadCntvCval)
+GCC_ASM_EXPORT (ArmWriteCntvCval)
+GCC_ASM_EXPORT (ArmReadCntvOff)
+GCC_ASM_EXPORT (ArmWriteCntvOff)
+
+ASM_PFX(ArmReadCntFrq):
+ mrc p15, 0, r0, c14, c0, 0 @ Read CNTFRQ
+ bx lr
+
+ASM_PFX(ArmWriteCntFrq):
+ mcr p15, 0, r0, c14, c0, 0 @ Write to CNTFRQ
+ bx lr
+
+ASM_PFX(ArmReadCntPct):
+ mrrc p15, 0, r0, r1, c14 @ Read CNTPT (Physical counter register)
+ bx lr
+
+ASM_PFX(ArmReadCntkCtl):
+ mrc p15, 0, r0, c14, c1, 0 @ Read CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ASM_PFX(ArmWriteCntkCtl):
+ mcr p15, 0, r0, c14, c1, 0 @ Write to CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ASM_PFX(ArmReadCntpTval):
+ mrc p15, 0, r0, c14, c2, 0 @ Read CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ASM_PFX(ArmWriteCntpTval):
+ mcr p15, 0, r0, c14, c2, 0 @ Write to CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ASM_PFX(ArmReadCntpCtl):
+ mrc p15, 0, r0, c14, c2, 1 @ Read CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ASM_PFX(ArmWriteCntpCtl):
+ mcr p15, 0, r0, c14, c2, 1 @ Write to CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ASM_PFX(ArmReadCntvTval):
+ mrc p15, 0, r0, c14, c3, 0 @ Read CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ASM_PFX(ArmWriteCntvTval):
+ mcr p15, 0, r0, c14, c3, 0 @ Write to CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ASM_PFX(ArmReadCntvCtl):
+ mrc p15, 0, r0, c14, c3, 1 @ Read CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ASM_PFX(ArmWriteCntvCtl):
+ mcr p15, 0, r0, c14, c3, 1 @ Write to CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ASM_PFX(ArmReadCntvCt):
+ mrrc p15, 1, r0, r1, c14 @ Read CNTVCT (Virtual Count Register)
+ bx lr
+
+ASM_PFX(ArmReadCntpCval):
+ mrrc p15, 2, r0, r1, c14 @ Read CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ASM_PFX(ArmWriteCntpCval):
+ mcrr p15, 2, r0, r1, c14 @ Write to CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ASM_PFX(ArmReadCntvCval):
+ mrrc p15, 3, r0, r1, c14 @ Read CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ASM_PFX(ArmWriteCntvCval):
+ mcrr p15, 3, r0, r1, c14 @ write to CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ASM_PFX(ArmReadCntvOff):
+ mrrc p15, 4, r0, r1, c14 @ Read CNTVOFF (virtual Offset register)
+ bx lr
+
+ASM_PFX(ArmWriteCntvOff):
+ mcrr p15, 4, r0, r1, c14 @ Write to CNTVOFF (Virtual Offset register)
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.asm
new file mode 100644
index 0000000..514830d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimerSupport.asm
@@ -0,0 +1,119 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2011, 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.
+//
+//------------------------------------------------------------------------------
+
+ EXPORT ArmReadCntFrq
+ EXPORT ArmWriteCntFrq
+ EXPORT ArmReadCntPct
+ EXPORT ArmReadCntkCtl
+ EXPORT ArmWriteCntkCtl
+ EXPORT ArmReadCntpTval
+ EXPORT ArmWriteCntpTval
+ EXPORT ArmReadCntpCtl
+ EXPORT ArmWriteCntpCtl
+ EXPORT ArmReadCntvTval
+ EXPORT ArmWriteCntvTval
+ EXPORT ArmReadCntvCtl
+ EXPORT ArmWriteCntvCtl
+ EXPORT ArmReadCntvCt
+ EXPORT ArmReadCntpCval
+ EXPORT ArmWriteCntpCval
+ EXPORT ArmReadCntvCval
+ EXPORT ArmWriteCntvCval
+ EXPORT ArmReadCntvOff
+ EXPORT ArmWriteCntvOff
+
+ AREA ArmV7ArchTimerSupport, CODE, READONLY
+ PRESERVE8
+
+ArmReadCntFrq
+ mrc p15, 0, r0, c14, c0, 0 ; Read CNTFRQ
+ bx lr
+
+ArmWriteCntFrq
+ mcr p15, 0, r0, c14, c0, 0 ; Write to CNTFRQ
+ bx lr
+
+ArmReadCntPct
+ mrrc p15, 0, r0, r1, c14 ; Read CNTPT (Physical counter register)
+ bx lr
+
+ArmReadCntkCtl
+ mrc p15, 0, r0, c14, c1, 0 ; Read CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ArmWriteCntkCtl
+ mcr p15, 0, r0, c14, c1, 0 ; Write to CNTK_CTL (Timer PL1 Control Register)
+ bx lr
+
+ArmReadCntpTval
+ mrc p15, 0, r0, c14, c2, 0 ; Read CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ArmWriteCntpTval
+ mcr p15, 0, r0, c14, c2, 0 ; Write to CNTP_TVAL (PL1 physical timer value register)
+ bx lr
+
+ArmReadCntpCtl
+ mrc p15, 0, r0, c14, c2, 1 ; Read CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ArmWriteCntpCtl
+ mcr p15, 0, r0, c14, c2, 1 ; Write to CNTP_CTL (PL1 Physical Timer Control Register)
+ bx lr
+
+ArmReadCntvTval
+ mrc p15, 0, r0, c14, c3, 0 ; Read CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ArmWriteCntvTval
+ mcr p15, 0, r0, c14, c3, 0 ; Write to CNTV_TVAL (Virtual Timer Value register)
+ bx lr
+
+ArmReadCntvCtl
+ mrc p15, 0, r0, c14, c3, 1 ; Read CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ArmWriteCntvCtl
+ mcr p15, 0, r0, c14, c3, 1 ; Write to CNTV_CTL (Virtual Timer Control Register)
+ bx lr
+
+ArmReadCntvCt
+ mrrc p15, 1, r0, r1, c14 ; Read CNTVCT (Virtual Count Register)
+ bx lr
+
+ArmReadCntpCval
+ mrrc p15, 2, r0, r1, c14 ; Read CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ArmWriteCntpCval
+ mcrr p15, 2, r0, r1, c14 ; Write to CNTP_CTVAL (Physical Timer Compare Value Register)
+ bx lr
+
+ArmReadCntvCval
+ mrrc p15, 3, r0, r1, c14 ; Read CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ArmWriteCntvCval
+ mcrr p15, 3, r0, r1, c14 ; write to CNTV_CTVAL (Virtual Timer Compare Value Register)
+ bx lr
+
+ArmReadCntvOff
+ mrrc p15, 4, r0, r1, c14 ; Read CNTVOFF (virtual Offset register)
+ bx lr
+
+ArmWriteCntvOff
+ mcrr p15, 4, r0, r1, c14 ; Write to CNTVOFF (Virtual Offset register)
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c
new file mode 100644
index 0000000..feb6088
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c
@@ -0,0 +1,269 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ 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 <Uefi.h>
+#include <Chipset/ArmV7.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include "ArmV7Lib.h"
+#include "ArmLibPrivate.h"
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+ VOID
+ )
+{
+ return ARM_CACHE_TYPE_WRITE_BACK;
+}
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+ VOID
+ )
+{
+ UINT32 CLIDR = ReadCLIDR ();
+
+ return (ARM_CACHE_ARCHITECTURE)CLIDR; // BugBug Fix Me
+}
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+ VOID
+ )
+{
+ UINT32 CLIDR = ReadCLIDR ();
+
+ if ((CLIDR & 0x2) == 0x2) {
+ // Instruction cache exists
+ return TRUE;
+ }
+ if ((CLIDR & 0x7) == 0x4) {
+ // Unified cache
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheSize (
+ VOID
+ )
+{
+ UINT32 NumSets;
+ UINT32 Associativity;
+ UINT32 LineSize;
+ UINT32 CCSIDR = ReadCCSIDR (0);
+
+ LineSize = (1 << ((CCSIDR & 0x7) + 2));
+ Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
+ NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
+
+ // LineSize is in words (4 byte chunks)
+ return NumSets * Associativity * LineSize * 4;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (0);
+
+ return ((CCSIDR >> 3) & 0x3ff) + 1;
+}
+
+UINTN
+ArmDataCacheSets (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (0);
+
+ return ((CCSIDR >> 13) & 0x7fff) + 1;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (0) & 7;
+
+ // * 4 converts to bytes
+ return (1 << (CCSIDR + 2)) * 4;
+}
+
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+ VOID
+ )
+{
+ UINT32 CLIDR = ReadCLIDR ();
+
+ if ((CLIDR & 1) == 1) {
+ // Instruction cache exists
+ return TRUE;
+ }
+ if ((CLIDR & 0x7) == 0x4) {
+ // Unified cache
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+ VOID
+ )
+{
+ UINT32 NumSets;
+ UINT32 Associativity;
+ UINT32 LineSize;
+ UINT32 CCSIDR = ReadCCSIDR (1);
+
+ LineSize = (1 << ((CCSIDR & 0x7) + 2));
+ Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
+ NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
+
+ // LineSize is in words (4 byte chunks)
+ return NumSets * Associativity * LineSize * 4;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (1);
+
+ return ((CCSIDR >> 3) & 0x3ff) + 1;
+// return 4;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSets (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (1);
+
+ return ((CCSIDR >> 13) & 0x7fff) + 1;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+ VOID
+ )
+{
+ UINT32 CCSIDR = ReadCCSIDR (1) & 7;
+
+ // * 4 converts to bytes
+ return (1 << (CCSIDR + 2)) * 4;
+
+// return 64;
+}
+
+
+VOID
+ArmV7DataCacheOperation (
+ IN ARM_V7_CACHE_OPERATION DataCacheOperation
+ )
+{
+ UINTN SavedInterruptState;
+
+ SavedInterruptState = ArmGetInterruptState ();
+ ArmDisableInterrupts ();
+
+ ArmV7AllDataCachesOperation (DataCacheOperation);
+
+ ArmDrainWriteBuffer ();
+
+ if (SavedInterruptState) {
+ ArmEnableInterrupts ();
+ }
+}
+
+
+VOID
+ArmV7PoUDataCacheOperation (
+ IN ARM_V7_CACHE_OPERATION DataCacheOperation
+ )
+{
+ UINTN SavedInterruptState;
+
+ SavedInterruptState = ArmGetInterruptState ();
+ ArmDisableInterrupts ();
+
+ ArmV7PerformPoUDataCacheOperation (DataCacheOperation);
+
+ ArmDrainWriteBuffer ();
+
+ if (SavedInterruptState) {
+ ArmEnableInterrupts ();
+ }
+}
+
+VOID
+EFIAPI
+ArmInvalidateDataCache (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCacheToPoU (
+ VOID
+ )
+{
+ ArmDrainWriteBuffer ();
+ ArmV7PoUDataCacheOperation (ArmCleanDataCacheEntryBySetWay);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
new file mode 100644
index 0000000..1398d75
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
@@ -0,0 +1,32 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+
+#ifndef __ARM_V7_LIB_H__
+#define __ARM_V7_LIB_H__
+
+typedef VOID (*ARM_V7_CACHE_OPERATION)(UINT32);
+
+
+VOID
+ArmV7PerformPoUDataCacheOperation (
+ IN ARM_V7_CACHE_OPERATION DataCacheOperation
+ );
+
+VOID
+ArmV7AllDataCachesOperation (
+ IN ARM_V7_CACHE_OPERATION DataCacheOperation
+ );
+
+#endif // __ARM_V7_LIB_H__
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
new file mode 100644
index 0000000..55c0ec6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
@@ -0,0 +1,53 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011, 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmV7Lib
+ FILE_GUID = 411cdfd8-f964-4b9d-a3e3-1719a9c15559
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ArmLibSupportV7.S | GCC
+ ArmLibSupportV7.asm | RVCT
+
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ ArmV7Support.S | GCC
+ ArmV7Support.asm | RVCT
+
+ ArmV7Lib.c
+ ArmV7Mmu.c
+
+ ArmV7ArchTimer.c
+ ArmV7ArchTimerSupport.S | GCC
+ ArmV7ArchTimerSupport.asm | RVCT
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
new file mode 100644
index 0000000..bc403d5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
@@ -0,0 +1,53 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = ArmV7LibPrePi
+ FILE_GUID = A150FA0C-F4E8-4207-9BEB-CD6DFB430D73
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ArmLibSupportV7.S | GCC
+ ArmLibSupportV7.asm | RVCT
+
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ ArmV7Support.S | GCC
+ ArmV7Support.asm | RVCT
+
+ ArmV7Lib.c
+ ArmV7Mmu.c
+
+ ArmV7ArchTimer.c
+ ArmV7ArchTimerSupport.S | GCC
+ ArmV7ArchTimerSupport.asm | RVCT
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ PrePiLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
new file mode 100644
index 0000000..4081d1a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
@@ -0,0 +1,47 @@
+#/* @file
+# Copyright (c) 2011, 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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmV7Lib
+ FILE_GUID = 411cdfd8-f964-4b9d-a3e3-1719a9c15559
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ArmLibSupportV7.S | GCC
+ ArmLibSupportV7.asm | RVCT
+
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+ ../Common/ArmLib.c
+
+ ArmV7Support.S | GCC
+ ArmV7Support.asm | RVCT
+
+ ArmV7Lib.c
+
+ ArmV7ArchTimer.c
+ ArmV7ArchTimerSupport.S | GCC
+ ArmV7ArchTimerSupport.asm | RVCT
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
new file mode 100644
index 0000000..d035ff3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
@@ -0,0 +1,303 @@
+/** @file
+* File managing the MMU for ARMv7 architecture
+*
+* 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 <Uefi.h>
+#include <Chipset/ArmV7.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include "ArmV7Lib.h"
+#include "ArmLibPrivate.h"
+
+UINT32
+ConvertSectionAttributesToPageAttributes (
+ IN UINT32 SectionAttributes,
+ IN BOOLEAN IsLargePage
+ )
+{
+ UINT32 PageAttributes;
+
+ PageAttributes = 0;
+ PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
+ PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
+ PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
+ PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
+ PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
+
+ return PageAttributes;
+}
+
+STATIC
+VOID
+PopulateLevel2PageTable (
+ IN UINT32 *SectionEntry,
+ IN UINT32 PhysicalBase,
+ IN UINT32 RemainLength,
+ IN ARM_MEMORY_REGION_ATTRIBUTES Attributes
+ )
+{
+ UINT32* PageEntry;
+ UINT32 Pages;
+ UINT32 Index;
+ UINT32 PageAttributes;
+ UINT32 SectionDescriptor;
+ UINT32 TranslationTable;
+ UINT32 BaseSectionAddress;
+
+ switch (Attributes) {
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
+ PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
+ PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_THROUGH;
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
+ PageAttributes = TT_DESCRIPTOR_PAGE_DEVICE;
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
+ PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
+ break;
+ default:
+ PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
+ break;
+ }
+
+ // Check if the Section Entry has already been populated. Otherwise attach a
+ // Level 2 Translation Table to it
+ if (*SectionEntry != 0) {
+ // The entry must be a page table. Otherwise it exists an overlapping in the memory map
+ if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(*SectionEntry)) {
+ TranslationTable = *SectionEntry & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK;
+ } else if ((*SectionEntry & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
+ // Case where a virtual memory map descriptor overlapped a section entry
+
+ // Allocate a Level2 Page Table for this Section
+ TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
+ TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
+
+ // Translate the Section Descriptor into Page Descriptor
+ SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
+
+ BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
+
+ // Populate the new Level2 Page Table for the section
+ PageEntry = (UINT32*)TranslationTable;
+ for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
+ PageEntry[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseSectionAddress + (Index << 12)) | SectionDescriptor;
+ }
+
+ // Overwrite the section entry to point to the new Level2 Translation Table
+ *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
+ (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
+ TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
+ } else {
+ // We do not support the other section type (16MB Section)
+ ASSERT(0);
+ return;
+ }
+ } else {
+ TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
+ TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
+
+ ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
+
+ *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
+ (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
+ TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
+ }
+
+ PageEntry = ((UINT32 *)(TranslationTable) + ((PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT));
+ Pages = RemainLength / TT_DESCRIPTOR_PAGE_SIZE;
+
+ for (Index = 0; Index < Pages; Index++) {
+ *PageEntry++ = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(PhysicalBase) | PageAttributes;
+ PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
+ }
+
+}
+
+STATIC
+VOID
+FillTranslationTable (
+ IN UINT32 *TranslationTable,
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
+ )
+{
+ UINT32 *SectionEntry;
+ UINT32 Attributes;
+ UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
+ UINT32 RemainLength = MemoryRegion->Length;
+
+ ASSERT(MemoryRegion->Length > 0);
+
+ switch (MemoryRegion->Attributes) {
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
+ Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
+ Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
+ Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);
+ break;
+ case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
+ break;
+ default:
+ Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
+ break;
+ }
+
+ // Get the first section entry for this mapping
+ SectionEntry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
+
+ while (RemainLength != 0) {
+ if (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE == 0) {
+ if (RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
+ // Case: Physical address aligned on the Section Size (1MB) && the length is greater than the Section Size
+ *SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
+ PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
+ } else {
+ // Case: Physical address aligned on the Section Size (1MB) && the length does not fill a section
+ PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
+
+ // It must be the last entry
+ break;
+ }
+ } else {
+ // Case: Physical address NOT aligned on the Section Size (1MB)
+ PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
+ // Aligned the address
+ PhysicalBase = (PhysicalBase + TT_DESCRIPTOR_SECTION_SIZE) & ~(TT_DESCRIPTOR_SECTION_SIZE-1);
+
+ // If it is the last entry
+ if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
+ break;
+ }
+ }
+ RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
+ }
+}
+
+RETURN_STATUS
+EFIAPI
+ArmConfigureMmu (
+ IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
+ OUT VOID **TranslationTableBase OPTIONAL,
+ OUT UINTN *TranslationTableSize OPTIONAL
+ )
+{
+ VOID* TranslationTable;
+ ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
+ UINT32 TTBRAttributes;
+
+ // Allocate pages for translation table.
+ TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
+ if (TranslationTable == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+ TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
+
+ if (TranslationTableBase != NULL) {
+ *TranslationTableBase = TranslationTable;
+ }
+
+ if (TranslationTableSize != NULL) {
+ *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
+ }
+
+ ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
+
+ // By default, mark the translation table as belonging to a uncached region
+ TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
+ while (MemoryTable->Length != 0) {
+ // Find the memory attribute for the Translation Table
+ if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
+ TranslationTableAttribute = MemoryTable->Attributes;
+ }
+
+ FillTranslationTable (TranslationTable, MemoryTable);
+ MemoryTable++;
+ }
+
+ // Translate the Memory Attributes into Translation Table Register Attributes
+ if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||
+ (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {
+ TTBRAttributes = TTBR_NON_CACHEABLE;
+ } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
+ (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
+ TTBRAttributes = TTBR_WRITE_BACK_ALLOC;
+ } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||
+ (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {
+ TTBRAttributes = TTBR_WRITE_THROUGH_NO_ALLOC;
+ } else {
+ ASSERT (0); // No support has been found for the attributes of the memory region that the translation table belongs to.
+ return RETURN_UNSUPPORTED;
+ }
+
+ ArmCleanInvalidateDataCache ();
+ ArmInvalidateInstructionCache ();
+
+ ArmDisableDataCache ();
+ ArmDisableInstructionCache();
+ // TLBs are also invalidated when calling ArmDisableMmu()
+ ArmDisableMmu ();
+
+ // Make sure nothing sneaked into the cache
+ ArmCleanInvalidateDataCache ();
+ ArmInvalidateInstructionCache ();
+
+ ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));
+
+ ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |
+ DOMAIN_ACCESS_CONTROL_NONE(14) |
+ DOMAIN_ACCESS_CONTROL_NONE(13) |
+ DOMAIN_ACCESS_CONTROL_NONE(12) |
+ DOMAIN_ACCESS_CONTROL_NONE(11) |
+ DOMAIN_ACCESS_CONTROL_NONE(10) |
+ DOMAIN_ACCESS_CONTROL_NONE( 9) |
+ DOMAIN_ACCESS_CONTROL_NONE( 8) |
+ DOMAIN_ACCESS_CONTROL_NONE( 7) |
+ DOMAIN_ACCESS_CONTROL_NONE( 6) |
+ DOMAIN_ACCESS_CONTROL_NONE( 5) |
+ DOMAIN_ACCESS_CONTROL_NONE( 4) |
+ DOMAIN_ACCESS_CONTROL_NONE( 3) |
+ DOMAIN_ACCESS_CONTROL_NONE( 2) |
+ DOMAIN_ACCESS_CONTROL_NONE( 1) |
+ DOMAIN_ACCESS_CONTROL_MANAGER(0));
+
+ ArmEnableInstructionCache();
+ ArmEnableDataCache();
+ ArmEnableMmu();
+ return RETURN_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
new file mode 100644
index 0000000..af5ec23
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
@@ -0,0 +1,391 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+
+GCC_ASM_EXPORT (ArmInvalidateInstructionCache)
+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmDrainWriteBuffer)
+GCC_ASM_EXPORT (ArmEnableMmu)
+GCC_ASM_EXPORT (ArmDisableMmu)
+GCC_ASM_EXPORT (ArmDisableCachesAndMmu)
+GCC_ASM_EXPORT (ArmMmuEnabled)
+GCC_ASM_EXPORT (ArmEnableDataCache)
+GCC_ASM_EXPORT (ArmDisableDataCache)
+GCC_ASM_EXPORT (ArmEnableInstructionCache)
+GCC_ASM_EXPORT (ArmDisableInstructionCache)
+GCC_ASM_EXPORT (ArmEnableSWPInstruction)
+GCC_ASM_EXPORT (ArmEnableBranchPrediction)
+GCC_ASM_EXPORT (ArmDisableBranchPrediction)
+GCC_ASM_EXPORT (ArmSetLowVectors)
+GCC_ASM_EXPORT (ArmSetHighVectors)
+GCC_ASM_EXPORT (ArmV7AllDataCachesOperation)
+GCC_ASM_EXPORT (ArmV7PerformPoUDataCacheOperation)
+GCC_ASM_EXPORT (ArmDataMemoryBarrier)
+GCC_ASM_EXPORT (ArmDataSyncronizationBarrier)
+GCC_ASM_EXPORT (ArmInstructionSynchronizationBarrier)
+GCC_ASM_EXPORT (ArmReadVBar)
+GCC_ASM_EXPORT (ArmWriteVBar)
+GCC_ASM_EXPORT (ArmEnableVFP)
+GCC_ASM_EXPORT (ArmCallWFI)
+GCC_ASM_EXPORT (ArmReadCbar)
+GCC_ASM_EXPORT (ArmReadMpidr)
+GCC_ASM_EXPORT (ArmReadTpidrurw)
+GCC_ASM_EXPORT (ArmWriteTpidrurw)
+GCC_ASM_EXPORT (ArmIsArchTimerImplemented)
+GCC_ASM_EXPORT (ArmReadIdPfr1)
+
+.set DC_ON, (0x1<<2)
+.set IC_ON, (0x1<<12)
+.set CTRL_M_BIT, (1 << 0)
+.set CTRL_C_BIT, (1 << 2)
+.set CTRL_B_BIT, (1 << 7)
+.set CTRL_I_BIT, (1 << 12)
+
+
+ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c6, 1 @invalidate single data cache line
+ dsb
+ isb
+ bx lr
+
+ASM_PFX(ArmCleanDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c10, 1 @clean single data cache line
+ dsb
+ isb
+ bx lr
+
+
+ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA):
+ mcr p15, 0, r0, c7, c14, 1 @clean and invalidate single data cache line
+ dsb
+ isb
+ bx lr
+
+
+ASM_PFX(ArmInvalidateDataCacheEntryBySetWay):
+ mcr p15, 0, r0, c7, c6, 2 @ Invalidate this line
+ dsb
+ isb
+ bx lr
+
+
+ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay):
+ mcr p15, 0, r0, c7, c14, 2 @ Clean and Invalidate this line
+ dsb
+ isb
+ bx lr
+
+
+ASM_PFX(ArmCleanDataCacheEntryBySetWay):
+ mcr p15, 0, r0, c7, c10, 2 @ Clean this line
+ dsb
+ isb
+ bx lr
+
+ASM_PFX(ArmInvalidateInstructionCache):
+ mcr p15,0,R0,c7,c5,0 @Invalidate entire instruction cache
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(ArmEnableMmu):
+ mrc p15,0,R0,c1,c0,0
+ orr R0,R0,#1
+ mcr p15,0,R0,c1,c0,0
+ dsb
+ isb
+ bx LR
+
+
+ASM_PFX(ArmDisableMmu):
+ mrc p15,0,R0,c1,c0,0
+ bic R0,R0,#1
+ mcr p15,0,R0,c1,c0,0 @Disable MMU
+
+ mcr p15,0,R0,c8,c7,0 @Invalidate TLB
+ mcr p15,0,R0,c7,c5,6 @Invalidate Branch predictor array
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(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
+ bx LR
+
+ASM_PFX(ArmMmuEnabled):
+ mrc p15,0,R0,c1,c0,0
+ and R0,R0,#1
+ bx LR
+
+ASM_PFX(ArmEnableDataCache):
+ ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ orr R0,R0,R1 @Set C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(ArmDisableDataCache):
+ ldr R1,=DC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ bic R0,R0,R1 @Clear C bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(ArmEnableInstructionCache):
+ ldr R1,=IC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ orr R0,R0,R1 @Set I bit
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(ArmDisableInstructionCache):
+ ldr R1,=IC_ON
+ mrc p15,0,R0,c1,c0,0 @Read control register configuration data
+ bic R0,R0,R1 @Clear I bit.
+ mcr p15,0,r0,c1,c0,0 @Write control register configuration data
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(ArmEnableSWPInstruction):
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000400
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+ bx LR
+
+ASM_PFX(ArmEnableBranchPrediction):
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(ArmDisableBranchPrediction):
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00000800
+ mcr p15, 0, r0, c1, c0, 0
+ dsb
+ isb
+ bx LR
+
+ASM_PFX(ArmSetLowVectors):
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 @ clear V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ASM_PFX(ArmSetHighVectors):
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ orr r0, r0, #0x00002000 @ Set V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ASM_PFX(ArmV7AllDataCachesOperation):
+ stmfd SP!,{r4-r12, LR}
+ mov R1, R0 @ Save Function call in R1
+ mrc p15, 1, R6, c0, c0, 1 @ Read CLIDR
+ ands R3, R6, #0x7000000 @ Mask out all but Level of Coherency (LoC)
+ mov R3, R3, LSR #23 @ Cache level value (naturally aligned)
+ beq L_Finished
+ mov R10, #0
+
+Loop1:
+ add R2, R10, R10, LSR #1 @ Work out 3xcachelevel
+ mov R12, R6, LSR R2 @ bottom 3 bits are the Cache type for this level
+ and R12, R12, #7 @ get those 3 bits alone
+ cmp R12, #2
+ blt L_Skip @ no cache or only instruction cache at this level
+ mcr p15, 2, R10, c0, c0, 0 @ write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
+ isb @ isb to sync the change to the CacheSizeID reg
+ mrc p15, 1, R12, c0, c0, 0 @ reads current Cache Size ID register (CCSIDR)
+ and R2, R12, #0x7 @ extract the line length field
+ add R2, R2, #4 @ add 4 for the line length offset (log2 16 bytes)
+@ ldr R4, =0x3FF
+ mov R4, #0x400
+ sub R4, R4, #1
+ ands R4, R4, R12, LSR #3 @ R4 is the max number on the way size (right aligned)
+ clz R5, R4 @ R5 is the bit position of the way size increment
+@ ldr R7, =0x00007FFF
+ mov R7, #0x00008000
+ sub R7, R7, #1
+ ands R7, R7, R12, LSR #13 @ R7 is the max number of the index size (right aligned)
+
+Loop2:
+ mov R9, R4 @ R9 working copy of the max way size (right aligned)
+
+Loop3:
+ orr R0, R10, R9, LSL R5 @ factor in the way number and cache number into R11
+ orr R0, R0, R7, LSL R2 @ factor in the index number
+
+ blx R1
+
+ subs R9, R9, #1 @ decrement the way number
+ bge Loop3
+ subs R7, R7, #1 @ decrement the index
+ bge Loop2
+L_Skip:
+ add R10, R10, #2 @ increment the cache number
+ cmp R3, R10
+ bgt Loop1
+
+L_Finished:
+ dsb
+ ldmfd SP!, {r4-r12, lr}
+ bx LR
+
+ASM_PFX(ArmV7PerformPoUDataCacheOperation):
+ stmfd SP!,{r4-r12, LR}
+ mov R1, R0 @ Save Function call in R1
+ mrc p15, 1, R6, c0, c0, 1 @ Read CLIDR
+ ands R3, R6, #0x38000000 @ Mask out all but Level of Unification (LoU)
+ mov R3, R3, LSR #26 @ Cache level value (naturally aligned)
+ beq Finished2
+ mov R10, #0
+
+Loop4:
+ add R2, R10, R10, LSR #1 @ Work out 3xcachelevel
+ mov R12, R6, LSR R2 @ bottom 3 bits are the Cache type for this level
+ and R12, R12, #7 @ get those 3 bits alone
+ cmp R12, #2
+ blt Skip2 @ no cache or only instruction cache at this level
+ mcr p15, 2, R10, c0, c0, 0 @ write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
+ isb @ isb to sync the change to the CacheSizeID reg
+ mrc p15, 1, R12, c0, c0, 0 @ reads current Cache Size ID register (CCSIDR)
+ and R2, R12, #0x7 @ extract the line length field
+ add R2, R2, #4 @ add 4 for the line length offset (log2 16 bytes)
+ ldr R4, =0x3FF
+ ands R4, R4, R12, LSR #3 @ R4 is the max number on the way size (right aligned)
+ clz R5, R4 @ R5 is the bit position of the way size increment
+ ldr R7, =0x00007FFF
+ ands R7, R7, R12, LSR #13 @ R7 is the max number of the index size (right aligned)
+
+Loop5:
+ mov R9, R4 @ R9 working copy of the max way size (right aligned)
+
+Loop6:
+ orr R0, R10, R9, LSL R5 @ factor in the way number and cache number into R11
+ orr R0, R0, R7, LSL R2 @ factor in the index number
+
+ blx R1
+
+ subs R9, R9, #1 @ decrement the way number
+ bge Loop6
+ subs R7, R7, #1 @ decrement the index
+ bge Loop5
+Skip2:
+ add R10, R10, #2 @ increment the cache number
+ cmp R3, R10
+ bgt Loop4
+
+Finished2:
+ dsb
+ ldmfd SP!, {r4-r12, lr}
+ bx LR
+
+ASM_PFX(ArmDataMemoryBarrier):
+ dmb
+ bx LR
+
+ASM_PFX(ArmDataSyncronizationBarrier):
+ASM_PFX(ArmDrainWriteBuffer):
+ dsb
+ bx LR
+
+ASM_PFX(ArmInstructionSynchronizationBarrier):
+ isb
+ bx LR
+
+ASM_PFX(ArmReadVBar):
+ # Set the Address of the Vector Table in the VBAR register
+ mrc p15, 0, r0, c12, c0, 0
+ bx lr
+
+ASM_PFX(ArmWriteVBar):
+ # Set the Address of the Vector Table in the VBAR register
+ mcr p15, 0, r0, c12, c0, 0
+ # Ensure the SCTLR.V bit is clear
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 @ clear V bit
+ mcr p15, 0, r0, c1, c0, 0 @ Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx lr
+
+ASM_PFX(ArmEnableVFP):
+ # Read CPACR (Coprocessor Access Control Register)
+ mrc p15, 0, r0, c1, c0, 2
+ # Enable VPF access (Full Access to CP10, CP11) (V* instructions)
+ orr r0, r0, #0x00f00000
+ # Write back CPACR (Coprocessor Access Control Register)
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ # Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.
+ mov r0, #0x40000000
+ mcr p10,#0x7,r0,c8,c0,#0
+ bx lr
+
+ASM_PFX(ArmCallWFI):
+ wfi
+ bx lr
+
+#Note: Return 0 in Uniprocessor implementation
+ASM_PFX(ArmReadCbar):
+ mrc p15, 4, r0, c15, c0, 0 @ Read Configuration Base Address Register
+ bx lr
+
+ASM_PFX(ArmReadMpidr):
+ mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
+ bx lr
+
+ASM_PFX(ArmReadTpidrurw):
+ mrc p15, 0, r0, c13, c0, 2 @ read TPIDRURW
+ bx lr
+
+ASM_PFX(ArmWriteTpidrurw):
+ mcr p15, 0, r0, c13, c0, 2 @ write TPIDRURW
+ bx lr
+
+ASM_PFX(ArmIsArchTimerImplemented):
+ mrc p15, 0, r0, c0, c1, 1 @ Read ID_PFR1
+ and r0, r0, #0x000F0000
+ bx lr
+
+ASM_PFX(ArmReadIdPfr1):
+ mrc p15, 0, r0, c0, c1, 1 @ Read ID_PFR1 Register
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
new file mode 100644
index 0000000..2b13811
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
@@ -0,0 +1,385 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+// 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.
+//
+//------------------------------------------------------------------------------
+
+ EXPORT ArmInvalidateInstructionCache
+ EXPORT ArmInvalidateDataCacheEntryByMVA
+ EXPORT ArmCleanDataCacheEntryByMVA
+ EXPORT ArmCleanInvalidateDataCacheEntryByMVA
+ EXPORT ArmInvalidateDataCacheEntryBySetWay
+ EXPORT ArmCleanDataCacheEntryBySetWay
+ EXPORT ArmCleanInvalidateDataCacheEntryBySetWay
+ EXPORT ArmDrainWriteBuffer
+ EXPORT ArmEnableMmu
+ EXPORT ArmDisableMmu
+ EXPORT ArmDisableCachesAndMmu
+ EXPORT ArmMmuEnabled
+ EXPORT ArmEnableDataCache
+ EXPORT ArmDisableDataCache
+ EXPORT ArmEnableInstructionCache
+ EXPORT ArmDisableInstructionCache
+ EXPORT ArmEnableSWPInstruction
+ EXPORT ArmEnableBranchPrediction
+ EXPORT ArmDisableBranchPrediction
+ EXPORT ArmSetLowVectors
+ EXPORT ArmSetHighVectors
+ EXPORT ArmV7AllDataCachesOperation
+ EXPORT ArmV7PerformPoUDataCacheOperation
+ EXPORT ArmDataMemoryBarrier
+ EXPORT ArmDataSyncronizationBarrier
+ EXPORT ArmInstructionSynchronizationBarrier
+ EXPORT ArmReadVBar
+ EXPORT ArmWriteVBar
+ EXPORT ArmEnableVFP
+ EXPORT ArmCallWFI
+ EXPORT ArmReadCbar
+ EXPORT ArmReadMpidr
+ EXPORT ArmReadTpidrurw
+ EXPORT ArmWriteTpidrurw
+ EXPORT ArmIsArchTimerImplemented
+ EXPORT ArmReadIdPfr1
+
+ AREA ArmV7Support, CODE, READONLY
+ PRESERVE8
+
+DC_ON EQU ( 0x1:SHL:2 )
+IC_ON EQU ( 0x1:SHL:12 )
+CTRL_M_BIT EQU (1 << 0)
+CTRL_C_BIT EQU (1 << 2)
+CTRL_B_BIT EQU (1 << 7)
+CTRL_I_BIT EQU (1 << 12)
+
+
+ArmInvalidateDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c6, 1 ; invalidate single data cache line
+ dsb
+ isb
+ bx lr
+
+ArmCleanDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c10, 1 ; clean single data cache line
+ dsb
+ isb
+ bx lr
+
+
+ArmCleanInvalidateDataCacheEntryByMVA
+ mcr p15, 0, r0, c7, c14, 1 ; clean and invalidate single data cache line
+ dsb
+ isb
+ bx lr
+
+
+ArmInvalidateDataCacheEntryBySetWay
+ mcr p15, 0, r0, c7, c6, 2 ; Invalidate this line
+ dsb
+ isb
+ bx lr
+
+
+ArmCleanInvalidateDataCacheEntryBySetWay
+ mcr p15, 0, r0, c7, c14, 2 ; Clean and Invalidate this line
+ dsb
+ isb
+ bx lr
+
+
+ArmCleanDataCacheEntryBySetWay
+ mcr p15, 0, r0, c7, c10, 2 ; Clean this line
+ dsb
+ isb
+ bx lr
+
+
+ArmInvalidateInstructionCache
+ mcr p15,0,R0,c7,c5,0 ;Invalidate entire instruction cache
+ isb
+ bx LR
+
+ArmEnableMmu
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr R0,R0,#1 ; Set SCTLR.M bit : Enable MMU
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ArmDisableMmu
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic R0,R0,#1 ; Clear SCTLR.M bit : Disable MMU
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+
+ mcr p15,0,R0,c8,c7,0 ; TLBIALL : Invalidate unified TLB
+ mcr p15,0,R0,c7,c5,6 ; BPIALL : Invalidate entire branch predictor array
+ dsb
+ isb
+ bx LR
+
+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
+ bx LR
+
+ArmMmuEnabled
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ and R0,R0,#1
+ bx LR
+
+ArmEnableDataCache
+ ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr R0,R0,R1 ; Set SCTLR.C bit : Data and unified caches enabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ArmDisableDataCache
+ ldr R1,=DC_ON ; Specify SCTLR.C bit : (Data) Cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic R0,R0,R1 ; Clear SCTLR.C bit : Data and unified caches disabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ArmEnableInstructionCache
+ ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr R0,R0,R1 ; Set SCTLR.I bit : Instruction caches enabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ArmDisableInstructionCache
+ ldr R1,=IC_ON ; Specify SCTLR.I bit : Instruction cache enable bit
+ mrc p15,0,R0,c1,c0,0 ; Read SCTLR into R0 (Read control register configuration data)
+ BIC R0,R0,R1 ; Clear SCTLR.I bit : Instruction caches disabled
+ mcr p15,0,R0,c1,c0,0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ArmEnableSWPInstruction
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #0x00000400
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+ bx LR
+
+ArmEnableBranchPrediction
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr r0, r0, #0x00000800 ;
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ArmDisableBranchPrediction
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00000800 ;
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ dsb
+ isb
+ bx LR
+
+ArmSetLowVectors
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 ; clear V bit
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ArmSetHighVectors
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ orr r0, r0, #0x00002000 ; Set V bit
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx LR
+
+ArmV7AllDataCachesOperation
+ stmfd SP!,{r4-r12, LR}
+ mov R1, R0 ; Save Function call in R1
+ mrc p15, 1, R6, c0, c0, 1 ; Read CLIDR
+ ands R3, R6, #&7000000 ; Mask out all but Level of Coherency (LoC)
+ mov R3, R3, LSR #23 ; Cache level value (naturally aligned)
+ beq Finished
+ mov R10, #0
+
+Loop1
+ add R2, R10, R10, LSR #1 ; Work out 3xcachelevel
+ mov R12, R6, LSR R2 ; bottom 3 bits are the Cache type for this level
+ and R12, R12, #7 ; get those 3 bits alone
+ cmp R12, #2
+ blt Skip ; no cache or only instruction cache at this level
+ mcr p15, 2, R10, c0, c0, 0 ; write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
+ isb ; isb to sync the change to the CacheSizeID reg
+ mrc p15, 1, R12, c0, c0, 0 ; reads current Cache Size ID register (CCSIDR)
+ and R2, R12, #&7 ; extract the line length field
+ add R2, R2, #4 ; add 4 for the line length offset (log2 16 bytes)
+ ldr R4, =0x3FF
+ ands R4, R4, R12, LSR #3 ; R4 is the max number on the way size (right aligned)
+ clz R5, R4 ; R5 is the bit position of the way size increment
+ ldr R7, =0x00007FFF
+ ands R7, R7, R12, LSR #13 ; R7 is the max number of the index size (right aligned)
+
+Loop2
+ mov R9, R4 ; R9 working copy of the max way size (right aligned)
+
+Loop3
+ orr R0, R10, R9, LSL R5 ; factor in the way number and cache number into R11
+ orr R0, R0, R7, LSL R2 ; factor in the index number
+
+ blx R1
+
+ subs R9, R9, #1 ; decrement the way number
+ bge Loop3
+ subs R7, R7, #1 ; decrement the index
+ bge Loop2
+Skip
+ add R10, R10, #2 ; increment the cache number
+ cmp R3, R10
+ bgt Loop1
+
+Finished
+ dsb
+ ldmfd SP!, {r4-r12, lr}
+ bx LR
+
+ArmV7PerformPoUDataCacheOperation
+ stmfd SP!,{r4-r12, LR}
+ mov R1, R0 ; Save Function call in R1
+ mrc p15, 1, R6, c0, c0, 1 ; Read CLIDR
+ ands R3, R6, #&38000000 ; Mask out all but Level of Unification (LoU)
+ mov R3, R3, LSR #26 ; Cache level value (naturally aligned)
+ beq Finished2
+ mov R10, #0
+
+Loop4
+ add R2, R10, R10, LSR #1 ; Work out 3xcachelevel
+ mov R12, R6, LSR R2 ; bottom 3 bits are the Cache type for this level
+ and R12, R12, #7 ; get those 3 bits alone
+ cmp R12, #2
+ blt Skip2 ; no cache or only instruction cache at this level
+ mcr p15, 2, R10, c0, c0, 0 ; write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
+ isb ; isb to sync the change to the CacheSizeID reg
+ mrc p15, 1, R12, c0, c0, 0 ; reads current Cache Size ID register (CCSIDR)
+ and R2, R12, #&7 ; extract the line length field
+ add R2, R2, #4 ; add 4 for the line length offset (log2 16 bytes)
+ ldr R4, =0x3FF
+ ands R4, R4, R12, LSR #3 ; R4 is the max number on the way size (right aligned)
+ clz R5, R4 ; R5 is the bit position of the way size increment
+ ldr R7, =0x00007FFF
+ ands R7, R7, R12, LSR #13 ; R7 is the max number of the index size (right aligned)
+
+Loop5
+ mov R9, R4 ; R9 working copy of the max way size (right aligned)
+
+Loop6
+ orr R0, R10, R9, LSL R5 ; factor in the way number and cache number into R11
+ orr R0, R0, R7, LSL R2 ; factor in the index number
+
+ blx R1
+
+ subs R9, R9, #1 ; decrement the way number
+ bge Loop6
+ subs R7, R7, #1 ; decrement the index
+ bge Loop5
+Skip2
+ add R10, R10, #2 ; increment the cache number
+ cmp R3, R10
+ bgt Loop4
+
+Finished2
+ dsb
+ ldmfd SP!, {r4-r12, lr}
+ bx LR
+
+ArmDataMemoryBarrier
+ dmb
+ bx LR
+
+ArmDataSyncronizationBarrier
+ArmDrainWriteBuffer
+ dsb
+ bx LR
+
+ArmInstructionSynchronizationBarrier
+ isb
+ bx LR
+
+ArmReadVBar
+ // Set the Address of the Vector Table in the VBAR register
+ mrc p15, 0, r0, c12, c0, 0
+ bx lr
+
+ArmWriteVBar
+ // Set the Address of the Vector Table in the VBAR register
+ mcr p15, 0, r0, c12, c0, 0
+ // Ensure the SCTLR.V bit is clear
+ mrc p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+ bic r0, r0, #0x00002000 ; clear V bit
+ mcr p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+ isb
+ bx lr
+
+ArmEnableVFP
+ // Read CPACR (Coprocessor Access Control Register)
+ mrc p15, 0, r0, c1, c0, 2
+ // Enable VPF access (Full Access to CP10, CP11) (V* instructions)
+ orr r0, r0, #0x00f00000
+ // Write back CPACR (Coprocessor Access Control Register)
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ // Set EN bit in FPEXC. The Advanced SIMD and VFP extensions are enabled and operate normally.
+ mov r0, #0x40000000
+ mcr p10,#0x7,r0,c8,c0,#0
+ bx lr
+
+ArmCallWFI
+ wfi
+ bx lr
+
+//Note: Return 0 in Uniprocessor implementation
+ArmReadCbar
+ mrc p15, 4, r0, c15, c0, 0 //Read Configuration Base Address Register
+ bx lr
+
+ArmReadMpidr
+ mrc p15, 0, r0, c0, c0, 5 ; read MPIDR
+ bx lr
+
+ArmReadTpidrurw
+ mrc p15, 0, r0, c13, c0, 2 ; read TPIDRURW
+ bx lr
+
+ArmWriteTpidrurw
+ mcr p15, 0, r0, c13, c0, 2 ; write TPIDRURW
+ bx lr
+
+ArmIsArchTimerImplemented
+ mrc p15, 0, r0, c0, c1, 1 ; Read ID_PFR1
+ and r0, r0, #0x000F0000
+ bx lr
+
+ArmReadIdPfr1
+ mrc p15, 0, r0, c0, c1, 1 ; Read ID_PFR1 Register
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S
new file mode 100644
index 0000000..28db98b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S
@@ -0,0 +1,211 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# 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 <AsmMacroIoLibV8.h>
+
+.text
+.align 3
+GCC_ASM_EXPORT (ArmReadMidr)
+GCC_ASM_EXPORT (ArmCacheInfo)
+GCC_ASM_EXPORT (ArmGetInterruptState)
+GCC_ASM_EXPORT (ArmGetFiqState)
+GCC_ASM_EXPORT (ArmGetTTBR0BaseAddress)
+GCC_ASM_EXPORT (ArmSetTTBR0)
+GCC_ASM_EXPORT (ArmGetTCR)
+GCC_ASM_EXPORT (ArmSetTCR)
+GCC_ASM_EXPORT (ArmGetMAIR)
+GCC_ASM_EXPORT (ArmSetMAIR)
+GCC_ASM_EXPORT (ArmWriteCpacr)
+GCC_ASM_EXPORT (ArmWriteAuxCr)
+GCC_ASM_EXPORT (ArmReadAuxCr)
+GCC_ASM_EXPORT (ArmInvalidateTlb)
+GCC_ASM_EXPORT (ArmUpdateTranslationTableEntry)
+GCC_ASM_EXPORT (ArmWriteCptr)
+GCC_ASM_EXPORT (ArmWriteScr)
+GCC_ASM_EXPORT (ArmWriteMVBar)
+GCC_ASM_EXPORT (ArmCallWFE)
+GCC_ASM_EXPORT (ArmCallSEV)
+GCC_ASM_EXPORT (ArmReadCpuActlr)
+GCC_ASM_EXPORT (ArmWriteCpuActlr)
+
+#------------------------------------------------------------------------------
+
+.set DAIF_FIQ_BIT, (1 << 0)
+.set DAIF_IRQ_BIT, (1 << 1)
+
+ASM_PFX(ArmReadMidr):
+ mrs x0, midr_el1 // Read from Main ID Register (MIDR)
+ ret
+
+ASM_PFX(ArmCacheInfo):
+ mrs x0, ctr_el0 // Read from Cache Type Regiter (CTR)
+ ret
+
+ASM_PFX(ArmGetInterruptState):
+ mrs x0, daif
+ tst w0, #DAIF_IRQ_BIT // Check if IRQ is enabled. Enabled if 0.
+ mov w0, #0
+ mov w1, #1
+ csel w0, w1, w0, ne
+ ret
+
+ASM_PFX(ArmGetFiqState):
+ mrs x0, daif
+ tst w0, #DAIF_FIQ_BIT // Check if FIQ is enabled. Enabled if 0.
+ mov w0, #0
+ mov w1, #1
+ csel w0, w1, w0, ne
+ ret
+
+ASM_PFX(ArmWriteCpacr):
+ msr cpacr_el1, x0 // Coprocessor Access Control Reg (CPACR)
+ ret
+
+ASM_PFX(ArmWriteAuxCr):
+ EL1_OR_EL2(x1)
+1:msr actlr_el1, x0 // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3
+ ret
+2:msr actlr_el2, x0 // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3
+ ret
+
+ASM_PFX(ArmReadAuxCr):
+ EL1_OR_EL2(x1)
+1:mrs x0, actlr_el1 // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3
+ ret
+2:mrs x0, actlr_el2 // Aux Control Reg (ACTLR) at EL1. Also available in EL2 and EL3
+ ret
+
+ASM_PFX(ArmSetTTBR0):
+ EL1_OR_EL2_OR_EL3(x1)
+1:msr ttbr0_el1, x0 // Translation Table Base Reg 0 (TTBR0)
+ b 4f
+2:msr ttbr0_el2, x0 // Translation Table Base Reg 0 (TTBR0)
+ b 4f
+3:msr ttbr0_el3, x0 // Translation Table Base Reg 0 (TTBR0)
+4:isb
+ ret
+
+ASM_PFX(ArmGetTTBR0BaseAddress):
+ EL1_OR_EL2(x1)
+1:mrs x0, ttbr0_el1
+ b 3f
+2:mrs x0, ttbr0_el2
+3:LoadConstantToReg(0xFFFFFFFFFFFF, x1) /* Look at bottom 48 bits */
+ and x0, x0, x1
+ isb
+ ret
+
+ASM_PFX(ArmGetTCR):
+ EL1_OR_EL2_OR_EL3(x1)
+1:mrs x0, tcr_el1
+ b 4f
+2:mrs x0, tcr_el2
+ b 4f
+3:mrs x0, tcr_el3
+4:isb
+ ret
+
+ASM_PFX(ArmSetTCR):
+ EL1_OR_EL2_OR_EL3(x1)
+1:msr tcr_el1, x0
+ b 4f
+2:msr tcr_el2, x0
+ b 4f
+3:msr tcr_el3, x0
+4:isb
+ ret
+
+ASM_PFX(ArmGetMAIR):
+ EL1_OR_EL2_OR_EL3(x1)
+1:mrs x0, mair_el1
+ b 4f
+2:mrs x0, mair_el2
+ b 4f
+3:mrs x0, mair_el3
+4:isb
+ ret
+
+ASM_PFX(ArmSetMAIR):
+ EL1_OR_EL2_OR_EL3(x1)
+1:msr mair_el1, x0
+ b 4f
+2:msr mair_el2, x0
+ b 4f
+3:msr mair_el3, x0
+4:isb
+ ret
+
+
+//
+//VOID
+//ArmUpdateTranslationTableEntry (
+// IN VOID *TranslationTableEntry // X0
+// IN VOID *MVA // X1
+// );
+ASM_PFX(ArmUpdateTranslationTableEntry):
+ dc civac, x0 // Clean and invalidate data line
+ dsb sy
+ EL1_OR_EL2_OR_EL3(x0)
+1: tlbi vaae1, x1 // TLB Invalidate VA , EL1
+ b 4f
+2: tlbi vae2, x1 // TLB Invalidate VA , EL2
+ b 4f
+3: tlbi vae3, x1 // TLB Invalidate VA , EL3
+4: dsb sy
+ isb
+ ret
+
+ASM_PFX(ArmInvalidateTlb):
+ EL1_OR_EL2_OR_EL3(x0)
+1: tlbi vmalle1
+ b 4f
+2: tlbi alle2
+ b 4f
+3: tlbi alle3
+4: dsb sy
+ isb
+ ret
+
+ASM_PFX(ArmWriteCptr):
+ msr cptr_el3, x0 // EL3 Coprocessor Trap Reg (CPTR)
+ ret
+
+ASM_PFX(ArmWriteScr):
+ msr scr_el3, x0 // Secure configuration register EL3
+ ret
+
+ASM_PFX(ArmWriteMVBar):
+ msr vbar_el3, x0 // Exception Vector Base address for Monitor on EL3
+ ret
+
+ASM_PFX(ArmCallWFE):
+ wfe
+ ret
+
+ASM_PFX(ArmCallSEV):
+ sev
+ ret
+
+ASM_PFX(ArmReadCpuActlr):
+ mrs x0, S3_1_c15_c2_0
+ ret
+
+ASM_PFX(ArmWriteCpuActlr):
+ msr S3_1_c15_c2_0, x0
+ dsb sy
+ isb
+ ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
new file mode 100644
index 0000000..43842f3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
@@ -0,0 +1,196 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# 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 <AsmMacroIoLib.h>
+
+#ifdef ARM_CPU_ARMv6
+// No memory barriers for ARMv6
+#define isb
+#define dsb
+#endif
+
+.text
+.align 2
+GCC_ASM_EXPORT(ArmReadMidr)
+GCC_ASM_EXPORT(ArmCacheInfo)
+GCC_ASM_EXPORT(ArmGetInterruptState)
+GCC_ASM_EXPORT(ArmGetFiqState)
+GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)
+GCC_ASM_EXPORT(ArmSetTTBR0)
+GCC_ASM_EXPORT(ArmSetDomainAccessControl)
+GCC_ASM_EXPORT(CPSRMaskInsert)
+GCC_ASM_EXPORT(CPSRRead)
+GCC_ASM_EXPORT(ArmReadCpacr)
+GCC_ASM_EXPORT(ArmWriteCpacr)
+GCC_ASM_EXPORT(ArmWriteAuxCr)
+GCC_ASM_EXPORT(ArmReadAuxCr)
+GCC_ASM_EXPORT(ArmInvalidateTlb)
+GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)
+GCC_ASM_EXPORT(ArmReadScr)
+GCC_ASM_EXPORT(ArmWriteScr)
+GCC_ASM_EXPORT(ArmReadMVBar)
+GCC_ASM_EXPORT(ArmWriteMVBar)
+GCC_ASM_EXPORT(ArmReadHVBar)
+GCC_ASM_EXPORT(ArmWriteHVBar)
+GCC_ASM_EXPORT(ArmCallWFE)
+GCC_ASM_EXPORT(ArmCallSEV)
+GCC_ASM_EXPORT(ArmReadSctlr)
+GCC_ASM_EXPORT(ArmReadCpuActlr)
+GCC_ASM_EXPORT(ArmWriteCpuActlr)
+
+#------------------------------------------------------------------------------
+
+ASM_PFX(ArmReadMidr):
+ mrc p15,0,R0,c0,c0,0
+ bx LR
+
+ASM_PFX(ArmCacheInfo):
+ mrc p15,0,R0,c0,c0,1
+ bx LR
+
+ASM_PFX(ArmGetInterruptState):
+ mrs R0,CPSR
+ tst R0,#0x80 @Check if IRQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ASM_PFX(ArmGetFiqState):
+ mrs R0,CPSR
+ tst R0,#0x40 @Check if FIQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ASM_PFX(ArmSetDomainAccessControl):
+ mcr p15,0,r0,c3,c0,0
+ bx lr
+
+ASM_PFX(CPSRMaskInsert): @ on entry, r0 is the mask and r1 is the field to insert
+ stmfd sp!, {r4-r12, lr} @ save all the banked registers
+ mov r3, sp @ copy the stack pointer into a non-banked register
+ mrs r2, cpsr @ read the cpsr
+ bic r2, r2, r0 @ clear mask in the cpsr
+ and r1, r1, r0 @ clear bits outside the mask in the input
+ orr r2, r2, r1 @ set field
+ msr cpsr_cxsf, r2 @ write back cpsr (may have caused a mode switch)
+ isb
+ mov sp, r3 @ restore stack pointer
+ ldmfd sp!, {r4-r12, lr} @ restore registers
+ bx lr @ return (hopefully thumb-safe!)
+
+ASM_PFX(CPSRRead):
+ mrs r0, cpsr
+ bx lr
+
+ASM_PFX(ArmReadCpacr):
+ mrc p15, 0, r0, c1, c0, 2
+ bx lr
+
+ASM_PFX(ArmWriteCpacr):
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ bx lr
+
+ASM_PFX(ArmWriteAuxCr):
+ mcr p15, 0, r0, c1, c0, 1
+ bx lr
+
+ASM_PFX(ArmReadAuxCr):
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ASM_PFX(ArmSetTTBR0):
+ mcr p15,0,r0,c2,c0,0
+ isb
+ bx lr
+
+ASM_PFX(ArmGetTTBR0BaseAddress):
+ mrc p15,0,r0,c2,c0,0
+ LoadConstantToReg(0xFFFFC000, r1)
+ and r0, r0, r1
+ isb
+ bx lr
+
+//
+//VOID
+//ArmUpdateTranslationTableEntry (
+// IN VOID *TranslationTableEntry // R0
+// IN VOID *MVA // R1
+// );
+ASM_PFX(ArmUpdateTranslationTableEntry):
+ mcr p15,0,R0,c7,c14,1 @ DCCIMVAC Clean data cache by MVA
+ dsb
+ mcr p15,0,R1,c8,c7,1 @ TLBIMVA TLB Invalidate MVA
+ mcr p15,0,R9,c7,c5,6 @ BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ASM_PFX(ArmInvalidateTlb):
+ mov r0,#0
+ mcr p15,0,r0,c8,c7,0
+ mcr p15,0,R9,c7,c5,6 @ BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ASM_PFX(ArmReadScr):
+ mrc p15, 0, r0, c1, c1, 0
+ bx lr
+
+ASM_PFX(ArmWriteScr):
+ mcr p15, 0, r0, c1, c1, 0
+ bx lr
+
+ASM_PFX(ArmReadHVBar):
+ mrc p15, 4, r0, c12, c0, 0
+ bx lr
+
+ASM_PFX(ArmWriteHVBar):
+ mcr p15, 4, r0, c12, c0, 0
+ bx lr
+
+ASM_PFX(ArmReadMVBar):
+ mrc p15, 0, r0, c12, c0, 1
+ bx lr
+
+ASM_PFX(ArmWriteMVBar):
+ mcr p15, 0, r0, c12, c0, 1
+ bx lr
+
+ASM_PFX(ArmCallWFE):
+ wfe
+ bx lr
+
+ASM_PFX(ArmCallSEV):
+ sev
+ bx lr
+
+ASM_PFX(ArmReadSctlr):
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bx lr
+
+ASM_PFX(ArmReadCpuActlr):
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ASM_PFX(ArmWriteCpuActlr):
+ mcr p15, 0, r0, c1, c0, 1
+ dsb
+ isb
+ bx lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
new file mode 100644
index 0000000..8864c16
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
@@ -0,0 +1,197 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+// 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 <AsmMacroIoLib.h>
+
+ INCLUDE AsmMacroIoLib.inc
+
+#ifdef ARM_CPU_ARMv6
+// No memory barriers for ARMv6
+#define isb
+#define dsb
+#endif
+
+ EXPORT ArmReadMidr
+ EXPORT ArmCacheInfo
+ EXPORT ArmGetInterruptState
+ EXPORT ArmGetFiqState
+ EXPORT ArmGetTTBR0BaseAddress
+ EXPORT ArmSetTTBR0
+ EXPORT ArmSetDomainAccessControl
+ EXPORT CPSRMaskInsert
+ EXPORT CPSRRead
+ EXPORT ArmReadCpacr
+ EXPORT ArmWriteCpacr
+ EXPORT ArmWriteAuxCr
+ EXPORT ArmReadAuxCr
+ EXPORT ArmInvalidateTlb
+ EXPORT ArmUpdateTranslationTableEntry
+ EXPORT ArmReadScr
+ EXPORT ArmWriteScr
+ EXPORT ArmReadMVBar
+ EXPORT ArmWriteMVBar
+ EXPORT ArmReadHVBar
+ EXPORT ArmWriteHVBar
+ EXPORT ArmCallWFE
+ EXPORT ArmCallSEV
+ EXPORT ArmReadSctlr
+ EXPORT ArmReadCpuActlr
+ EXPORT ArmWriteCpuActlr
+
+ AREA ArmLibSupport, CODE, READONLY
+
+ArmReadMidr
+ mrc p15,0,R0,c0,c0,0
+ bx LR
+
+ArmCacheInfo
+ mrc p15,0,R0,c0,c0,1
+ bx LR
+
+ArmGetInterruptState
+ mrs R0,CPSR
+ tst R0,#0x80 // Check if IRQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ArmGetFiqState
+ mrs R0,CPSR
+ tst R0,#0x40 // Check if FIQ is enabled.
+ moveq R0,#1
+ movne R0,#0
+ bx LR
+
+ArmSetDomainAccessControl
+ mcr p15,0,r0,c3,c0,0
+ bx lr
+
+CPSRMaskInsert // on entry, r0 is the mask and r1 is the field to insert
+ stmfd sp!, {r4-r12, lr} // save all the banked registers
+ mov r3, sp // copy the stack pointer into a non-banked register
+ mrs r2, cpsr // read the cpsr
+ bic r2, r2, r0 // clear mask in the cpsr
+ and r1, r1, r0 // clear bits outside the mask in the input
+ orr r2, r2, r1 // set field
+ msr cpsr_cxsf, r2 // write back cpsr (may have caused a mode switch)
+ isb
+ mov sp, r3 // restore stack pointer
+ ldmfd sp!, {r4-r12, lr} // restore registers
+ bx lr // return (hopefully thumb-safe!) // return (hopefully thumb-safe!)
+
+CPSRRead
+ mrs r0, cpsr
+ bx lr
+
+ArmReadCpacr
+ mrc p15, 0, r0, c1, c0, 2
+ bx lr
+
+ArmWriteCpacr
+ mcr p15, 0, r0, c1, c0, 2
+ isb
+ bx lr
+
+ArmWriteAuxCr
+ mcr p15, 0, r0, c1, c0, 1
+ bx lr
+
+ArmReadAuxCr
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ArmSetTTBR0
+ mcr p15,0,r0,c2,c0,0
+ isb
+ bx lr
+
+ArmGetTTBR0BaseAddress
+ mrc p15,0,r0,c2,c0,0
+ LoadConstantToReg(0xFFFFC000, r1)
+ and r0, r0, r1
+ isb
+ bx lr
+
+//
+//VOID
+//ArmUpdateTranslationTableEntry (
+// IN VOID *TranslationTableEntry // R0
+// IN VOID *MVA // R1
+// );
+ArmUpdateTranslationTableEntry
+ mcr p15,0,R0,c7,c14,1 // DCCIMVAC Clean data cache by MVA
+ dsb
+ mcr p15,0,R1,c8,c7,1 // TLBIMVA TLB Invalidate MVA
+ mcr p15,0,R9,c7,c5,6 // BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ArmInvalidateTlb
+ mov r0,#0
+ mcr p15,0,r0,c8,c7,0
+ mcr p15,0,R9,c7,c5,6 // BPIALL Invalidate Branch predictor array. R9 == NoOp
+ dsb
+ isb
+ bx lr
+
+ArmReadScr
+ mrc p15, 0, r0, c1, c1, 0
+ bx lr
+
+ArmWriteScr
+ mcr p15, 0, r0, c1, c1, 0
+ bx lr
+
+ArmReadHVBar
+ mrc p15, 4, r0, c12, c0, 0
+ bx lr
+
+ArmWriteHVBar
+ mcr p15, 4, r0, c12, c0, 0
+ bx lr
+
+ArmReadMVBar
+ mrc p15, 0, r0, c12, c0, 1
+ bx lr
+
+ArmWriteMVBar
+ mcr p15, 0, r0, c12, c0, 1
+ bx lr
+
+ArmCallWFE
+ wfe
+ bx lr
+
+ArmCallSEV
+ sev
+ bx lr
+
+ArmReadSctlr
+ mrc p15, 0, r0, c1, c0, 0 // Read SCTLR into R0 (Read control register configuration data)
+ bx lr
+
+
+ArmReadCpuActlr
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ArmWriteCpuActlr
+ mcr p15, 0, r0, c1, c0, 1
+ dsb
+ isb
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLib.c
new file mode 100644
index 0000000..d731697
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLib.c
@@ -0,0 +1,92 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include "ArmLibPrivate.h"
+
+VOID
+EFIAPI
+ArmCacheInformation (
+ OUT ARM_CACHE_INFO *CacheInfo
+ )
+{
+ if (CacheInfo != NULL) {
+ CacheInfo->Type = ArmCacheType();
+ CacheInfo->Architecture = ArmCacheArchitecture();
+ CacheInfo->DataCachePresent = ArmDataCachePresent();
+ CacheInfo->DataCacheSize = ArmDataCacheSize();
+ CacheInfo->DataCacheAssociativity = ArmDataCacheAssociativity();
+ CacheInfo->DataCacheLineLength = ArmDataCacheLineLength();
+ CacheInfo->InstructionCachePresent = ArmInstructionCachePresent();
+ CacheInfo->InstructionCacheSize = ArmInstructionCacheSize();
+ CacheInfo->InstructionCacheAssociativity = ArmInstructionCacheAssociativity();
+ CacheInfo->InstructionCacheLineLength = ArmInstructionCacheLineLength();
+ }
+}
+
+VOID
+EFIAPI
+ArmSetAuxCrBit (
+ IN UINT32 Bits
+ )
+{
+ UINT32 val = ArmReadAuxCr();
+ val |= Bits;
+ ArmWriteAuxCr(val);
+}
+
+VOID
+EFIAPI
+ArmUnsetAuxCrBit (
+ IN UINT32 Bits
+ )
+{
+ UINT32 val = ArmReadAuxCr();
+ val &= ~Bits;
+ ArmWriteAuxCr(val);
+}
+
+//
+// Helper functions for accessing CPUACTLR
+//
+
+VOID
+EFIAPI
+ArmSetCpuActlrBit (
+ IN UINTN Bits
+ )
+{
+ UINTN Value;
+ Value = ArmReadCpuActlr ();
+ Value |= Bits;
+ ArmWriteCpuActlr (Value);
+}
+
+VOID
+EFIAPI
+ArmUnsetCpuActlrBit (
+ IN UINTN Bits
+ )
+{
+ UINTN Value;
+ Value = ArmReadCpuActlr ();
+ Value &= ~Bits;
+ ArmWriteCpuActlr (Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h
new file mode 100644
index 0000000..fdd5a26
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h
@@ -0,0 +1,80 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+
+#ifndef __ARM_LIB_PRIVATE_H__
+#define __ARM_LIB_PRIVATE_H__
+
+#define CACHE_SIZE_4_KB (3UL)
+#define CACHE_SIZE_8_KB (4UL)
+#define CACHE_SIZE_16_KB (5UL)
+#define CACHE_SIZE_32_KB (6UL)
+#define CACHE_SIZE_64_KB (7UL)
+#define CACHE_SIZE_128_KB (8UL)
+
+#define CACHE_ASSOCIATIVITY_DIRECT (0UL)
+#define CACHE_ASSOCIATIVITY_4_WAY (2UL)
+#define CACHE_ASSOCIATIVITY_8_WAY (3UL)
+
+#define CACHE_PRESENT (0UL)
+#define CACHE_NOT_PRESENT (1UL)
+
+#define CACHE_LINE_LENGTH_32_BYTES (2UL)
+
+#define SIZE_FIELD_TO_CACHE_SIZE(x) (((x) >> 6) & 0x0F)
+#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x) (((x) >> 3) & 0x07)
+#define SIZE_FIELD_TO_CACHE_PRESENCE(x) (((x) >> 2) & 0x01)
+#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x) (((x) >> 0) & 0x03)
+
+#define DATA_CACHE_SIZE_FIELD(x) (((x) >> 12) & 0x0FFF)
+#define INSTRUCTION_CACHE_SIZE_FIELD(x) (((x) >> 0) & 0x0FFF)
+
+#define DATA_CACHE_SIZE(x) (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
+#define DATA_CACHE_ASSOCIATIVITY(x) (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
+#define DATA_CACHE_PRESENT(x) (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
+#define DATA_CACHE_LINE_LENGTH(x) (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))
+
+#define INSTRUCTION_CACHE_SIZE(x) (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+#define INSTRUCTION_CACHE_ASSOCIATIVITY(x) (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+#define INSTRUCTION_CACHE_PRESENT(x) (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+#define INSTRUCTION_CACHE_LINE_LENGTH(x) (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+
+#define CACHE_TYPE(x) (((x) >> 25) & 0x0F)
+#define CACHE_TYPE_WRITE_BACK (0x0EUL)
+
+#define CACHE_ARCHITECTURE(x) (((x) >> 24) & 0x01)
+#define CACHE_ARCHITECTURE_UNIFIED (0UL)
+#define CACHE_ARCHITECTURE_SEPARATE (1UL)
+
+VOID
+CPSRMaskInsert (
+ IN UINT32 Mask,
+ IN UINT32 Value
+ );
+
+UINT32
+CPSRRead (
+ VOID
+ );
+
+UINT32
+ReadCCSIDR (
+ IN UINT32 CSSELR
+ );
+
+UINT32
+ReadCLIDR (
+ VOID
+ );
+
+#endif // __ARM_LIB_PRIVATE_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c
new file mode 100644
index 0000000..2eeb42e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c
@@ -0,0 +1,106 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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 <Library/ArmLib.h>
+#include "ArmLibPrivate.h"
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+ VOID
+ )
+{
+ return ARM_CACHE_TYPE_UNKNOWN;
+}
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+ VOID
+ )
+{
+ return ARM_CACHE_ARCHITECTURE_UNKNOWN;
+}
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheSize (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+ VOID
+ )
+{
+ return 0;
+}
+
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+ VOID
+ )
+{
+ return 0;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.c
new file mode 100644
index 0000000..e7e9c52
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.c
@@ -0,0 +1,117 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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 <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmInvalidateInstructionCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmInvalidateDataCacheEntryByMVA (
+ IN UINTN Address
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCacheEntryByMVA (
+ IN UINTN Address
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCacheEntryByMVA (
+ IN UINTN Address
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmEnableDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmDisableDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmEnableInstructionCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmDisableInstructionCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.inf
new file mode 100644
index 0000000..21c374f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmLib/Null/NullArmLib.inf
@@ -0,0 +1,45 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = NullArmLib
+ FILE_GUID = 00586300-0E06-4790-AC44-86C56ACBB942
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmLib
+
+[Sources.common]
+ ../Common/ArmLib.c
+
+ NullArmLib.c
+ NullArmCacheInformation.c
+
+[Sources.ARM]
+ ../Common/Arm/ArmLibSupport.S | GCC
+ ../Common/Arm/ArmLibSupport.asm | RVCT
+
+[Sources.AARCH64]
+ ../Common/AArch64/ArmLibSupport.S
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmCacheOperationThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c
new file mode 100644
index 0000000..df4e113
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c
@@ -0,0 +1,96 @@
+/** @file
+ Support ResetSystem Runtime call using PSCI calls
+
+ Note: A similar library is implemented in
+ ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPsciResetSystemLib
+ So similar issues might exist in this implementation too.
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2014, Linaro 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 <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EfiResetSystemLib.h>
+#include <Library/ArmSmcLib.h>
+
+#include <IndustryStandard/ArmStdSmc.h>
+
+/**
+ Resets the entire platform.
+
+ @param ResetType The type of reset to perform.
+ @param ResetStatus The status code for the reset.
+ @param DataSize The size, in bytes, of WatchdogData.
+ @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
+ EfiResetShutdown the data buffer starts with a Null-terminated
+ Unicode string, optionally followed by additional binary data.
+
+**/
+EFI_STATUS
+EFIAPI
+LibResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData OPTIONAL
+ )
+{
+ ARM_SMC_ARGS ArmSmcArgs;
+
+ switch (ResetType) {
+ case EfiResetPlatformSpecific:
+ // Map the platform specific reset as reboot
+ case EfiResetWarm:
+ // Map a warm reset into a cold reset
+ case EfiResetCold:
+ // Send a PSCI 0.2 SYSTEM_RESET command
+ ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
+ break;
+ case EfiResetShutdown:
+ // Send a PSCI 0.2 SYSTEM_OFF command
+ ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
+ break;
+ default:
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ ArmCallSmc (&ArmSmcArgs);
+
+ // We should never be here
+ DEBUG ((EFI_D_ERROR, "%a: PSCI Reset failed\n", __FUNCTION__));
+ CpuDeadLoop ();
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Initialize any infrastructure required for LibResetSystem () to function.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+LibInitializeResetSystem (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
new file mode 100644
index 0000000..9cdde1f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
@@ -0,0 +1,37 @@
+#/** @file
+# Reset System lib using PSCI hypervisor or secure monitor calls
+#
+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+# Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPsciResetSystemLib
+ FILE_GUID = A8F59B69-A105-41C7-8F5A-2C60DD7FD7AA
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = EfiResetSystemLib
+
+[Sources]
+ ArmPsciResetSystemLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+ ArmSmcLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
new file mode 100644
index 0000000..46c1767
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
@@ -0,0 +1,41 @@
+//
+// Copyright (c) 2012-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.
+//
+//
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmCallSmc)
+
+ASM_PFX(ArmCallSmc):
+ // Push x0 on the stack - The stack must always be quad-word aligned
+ str x0, [sp, #-16]!
+
+ // Load the SMC arguments values into the appropriate registers
+ ldp x6, x7, [x0, #48]
+ ldp x4, x5, [x0, #32]
+ ldp x2, x3, [x0, #16]
+ ldp x0, x1, [x0, #0]
+
+ smc #0
+
+ // Pop the ARM_SMC_ARGS structure address from the stack into x9
+ ldr x9, [sp], #16
+
+ // Store the SMC returned values into the ARM_SMC_ARGS structure.
+ // A SMC call can return up to 4 values - we do not need to store back x4-x7.
+ stp x2, x3, [x9, #16]
+ stp x0, x1, [x9, #0]
+
+ mov x0, x9
+
+ ret
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
new file mode 100644
index 0000000..260fb10
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2012-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.
+//
+//
+
+.text
+.align 3
+.arch_extension sec
+
+GCC_ASM_EXPORT(ArmCallSmc)
+
+ASM_PFX(ArmCallSmc):
+ push {r4-r8}
+ // r0 will be popped just after the SMC call
+ push {r0}
+
+ // Load the SMC arguments values into the appropriate registers
+ ldr r7, [r0, #28]
+ ldr r6, [r0, #24]
+ ldr r5, [r0, #20]
+ ldr r4, [r0, #16]
+ ldr r3, [r0, #12]
+ ldr r2, [r0, #8]
+ ldr r1, [r0, #4]
+ ldr r0, [r0, #0]
+
+ smc #0
+
+ // Pop the ARM_SMC_ARGS structure address from the stack into r8
+ pop {r8}
+
+ // Load the SMC returned values into the appropriate registers
+ // A SMC call can return up to 4 values - we do not need to store back r4-r7.
+ str r3, [r8, #12]
+ str r2, [r8, #8]
+ str r1, [r8, #4]
+ str r0, [r8, #0]
+
+ mov r0, r8
+
+ // Restore the registers r4-r8
+ pop {r4-r8}
+
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
new file mode 100644
index 0000000..50580f7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.asm
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2012-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.
+//
+//
+
+ EXPORT ArmCallSmc
+
+ AREA ArmSmc, CODE, READONLY
+
+ArmCallSmc
+ push {r4-r8}
+ // r0 will be popped just after the SMC call
+ push {r0}
+
+ // Load the SMC arguments values into the appropriate registers
+ ldr r7, [r0, #28]
+ ldr r6, [r0, #24]
+ ldr r5, [r0, #20]
+ ldr r4, [r0, #16]
+ ldr r3, [r0, #12]
+ ldr r2, [r0, #8]
+ ldr r1, [r0, #4]
+ ldr r0, [r0, #0]
+
+ smc #0
+
+ // Pop the ARM_SMC_ARGS structure address from the stack into r8
+ pop {r8}
+
+ // Load the SMC returned values into the appropriate registers
+ // A SMC call can return up to 4 values - we do not need to store back r4-r7.
+ str r3, [r8, #12]
+ str r2, [r8, #8]
+ str r1, [r8, #4]
+ str r0, [r8, #0]
+
+ mov r0, r8
+
+ // Restore the registers r4-r8
+ pop {r4-r8}
+
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
new file mode 100644
index 0000000..9f9ba72
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
@@ -0,0 +1,31 @@
+#/** @file
+#
+# Copyright (c) 2012-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 = ArmSmcLib
+ FILE_GUID = eb3f17d5-a3cc-4eac-8912-84162d0f79da
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmSmcLib
+
+[Sources.ARM]
+ Arm/ArmSmc.asm | RVCT
+ Arm/ArmSmc.S | GCC
+
+[Sources.AARCH64]
+ AArch64/ArmSmc.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
new file mode 100644
index 0000000..a6ef0e0
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/AArch64/ArmSmcNull.S
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2012-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.
+//
+//
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmCallSmc)
+
+ASM_PFX(ArmCallSmc):
+ ret
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
new file mode 100644
index 0000000..9eaefd3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.S
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2012-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.
+//
+//
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmCallSmc)
+
+ASM_PFX(ArmCallSmc):
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
new file mode 100644
index 0000000..3d3f554
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/Arm/ArmSmcNull.asm
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2012-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.
+//
+//
+
+ EXPORT ArmCallSmc
+
+ AREA ArmSmc, CODE, READONLY
+
+ArmCallSmc
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
new file mode 100644
index 0000000..6d75c28
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
@@ -0,0 +1,34 @@
+#/** @file
+#
+# ArmSmcLib when no SMC support is desired (might be the case for CPU without the
+# Trustzone support / ARM Security Extension)
+#
+# Copyright (c) 2012-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 = ArmSmcLibNull
+ FILE_GUID = 140e8004-16e1-4de1-a352-c6ef51110ecf
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmSmcLib
+
+[Sources.ARM]
+ Arm/ArmSmcNull.asm | RVCT
+ Arm/ArmSmcNull.S | GCC
+
+[Sources.AARCH64]
+ AArch64/ArmSmcNull.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c
new file mode 100644
index 0000000..71ae02a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c
@@ -0,0 +1,146 @@
+/** @file
+
+ Copyright (c) 2012-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 "MemLibInternals.h"
+
+/**
+ Copy Length bytes from Source to Destination.
+
+ @param DestinationBuffer Target of copy
+ @param SourceBuffer Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+**/
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ //
+ // Declare the local variables that actually move the data elements as
+ // volatile to prevent the optimizer from replacing this function with
+ // the intrinsic memcpy()
+ //
+ volatile UINT8 *Destination8;
+ CONST UINT8 *Source8;
+ volatile UINT32 *Destination32;
+ CONST UINT32 *Source32;
+ volatile UINT64 *Destination64;
+ CONST UINT64 *Source64;
+ UINTN Alignment;
+
+ if ((((UINTN)DestinationBuffer & 0x7) == 0) && (((UINTN)SourceBuffer & 0x7) == 0) && (Length >= 8)) {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination64 = (UINT64*)DestinationBuffer;
+ Source64 = (CONST UINT64*)SourceBuffer;
+ while (Length >= 8) {
+ *(Destination64++) = *(Source64++);
+ Length -= 8;
+ }
+
+ // Finish if there are still some bytes to copy
+ Destination8 = (UINT8*)Destination64;
+ Source8 = (CONST UINT8*)Source64;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination64 = (UINT64*)((UINTN)DestinationBuffer + Length);
+ Source64 = (CONST UINT64*)((UINTN)SourceBuffer + Length);
+
+ // Destination64 and Source64 were aligned on a 64-bit boundary
+ // but if length is not a multiple of 8 bytes then they won't be
+ // anymore.
+
+ Alignment = Length & 0x7;
+ if (Alignment != 0) {
+ Destination8 = (UINT8*)Destination64;
+ Source8 = (CONST UINT8*)Source64;
+
+ while (Alignment-- != 0) {
+ *(--Destination8) = *(--Source8);
+ --Length;
+ }
+ Destination64 = (UINT64*)Destination8;
+ Source64 = (CONST UINT64*)Source8;
+ }
+
+ while (Length > 0) {
+ *(--Destination64) = *(--Source64);
+ Length -= 8;
+ }
+ }
+ } else if ((((UINTN)DestinationBuffer & 0x3) == 0) && (((UINTN)SourceBuffer & 0x3) == 0) && (Length >= 4)) {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination32 = (UINT32*)DestinationBuffer;
+ Source32 = (CONST UINT32*)SourceBuffer;
+ while (Length >= 4) {
+ *(Destination32++) = *(Source32++);
+ Length -= 4;
+ }
+
+ // Finish if there are still some bytes to copy
+ Destination8 = (UINT8*)Destination32;
+ Source8 = (CONST UINT8*)Source32;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination32 = (UINT32*)((UINTN)DestinationBuffer + Length);
+ Source32 = (CONST UINT32*)((UINTN)SourceBuffer + Length);
+
+ // Destination32 and Source32 were aligned on a 32-bit boundary
+ // but if length is not a multiple of 4 bytes then they won't be
+ // anymore.
+
+ Alignment = Length & 0x3;
+ if (Alignment != 0) {
+ Destination8 = (UINT8*)Destination32;
+ Source8 = (CONST UINT8*)Source32;
+
+ while (Alignment-- != 0) {
+ *(--Destination8) = *(--Source8);
+ --Length;
+ }
+ Destination32 = (UINT32*)Destination8;
+ Source32 = (CONST UINT32*)Source8;
+ }
+
+ while (Length > 0) {
+ *(--Destination32) = *(--Source32);
+ Length -= 4;
+ }
+ }
+ } else {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer;
+ Source8 = (CONST UINT8*)SourceBuffer;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer + Length;
+ Source8 = (CONST UINT8*)SourceBuffer + Length;
+ while (Length-- != 0) {
+ *(--Destination8) = *(--Source8);
+ }
+ }
+ }
+ return DestinationBuffer;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/SetMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/SetMem.c
new file mode 100644
index 0000000..368a819
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/AArch64/SetMem.c
@@ -0,0 +1,84 @@
+/** @file
+
+ Copyright (c) 2012-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 "MemLibInternals.h"
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ //
+ // Declare the local variables that actually move the data elements as
+ // volatile to prevent the optimizer from replacing this function with
+ // the intrinsic memset()
+ //
+ volatile UINT8 *Pointer8;
+ volatile UINT32 *Pointer32;
+ volatile UINT64 *Pointer64;
+ UINT32 Value32;
+ UINT64 Value64;
+
+ if ((((UINTN)Buffer & 0x7) == 0) && (Length >= 8)) {
+ // Generate the 64bit value
+ Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
+ Value64 = (((UINT64)Value32) << 32) | Value32;
+
+ Pointer64 = (UINT64*)Buffer;
+ while (Length >= 8) {
+ *(Pointer64++) = Value64;
+ Length -= 8;
+ }
+
+ // Finish with bytes if needed
+ Pointer8 = (UINT8*)Pointer64;
+ while (Length-- > 0) {
+ *(Pointer8++) = Value;
+ }
+ } else if ((((UINTN)Buffer & 0x3) == 0) && (Length >= 4)) {
+ // Generate the 32bit value
+ Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
+
+ Pointer32 = (UINT32*)Buffer;
+ while (Length >= 4) {
+ *(Pointer32++) = Value32;
+ Length -= 4;
+ }
+
+ // Finish with bytes if needed
+ Pointer8 = (UINT8*)Pointer32;
+ while (Length-- > 0) {
+ *(Pointer8++) = Value;
+ }
+ } else {
+ Pointer8 = (UINT8*)Buffer;
+ while (Length-- > 0) {
+ *(Pointer8++) = Value;
+ }
+ }
+ return Buffer;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.S
new file mode 100755
index 0000000..7985b59
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.S
@@ -0,0 +1,171 @@
+#------------------------------------------------------------------------------
+#
+# CopyMem() worker for ARM
+#
+# This file started out as C code that did 64 bit moves if the buffer was
+# 32-bit aligned, else it does a byte copy. It also does a byte copy for
+# any trailing bytes. It was updated to do 32-byte copies using stm/ldm.
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+/**
+ Copy Length bytes from Source to Destination. Overlap is OK.
+
+ This implementation
+
+ @param Destination Target of copy
+ @param Source Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+**/
+.text
+.align 2
+GCC_ASM_EXPORT(InternalMemCopyMem)
+
+ASM_PFX(InternalMemCopyMem):
+ stmfd sp!, {r4-r11, lr}
+ // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)
+ mov r11, r0
+ mov r10, r0
+ mov r12, r2
+ mov r14, r1
+
+memcopy_check_overlapped:
+ cmp r11, r1
+ // If (dest < source)
+ bcc memcopy_check_optim_default
+ // If (dest <= source). But with the previous condition -> If (dest == source)
+ bls memcopy_end
+
+ // If (source + length < dest)
+ rsb r3, r1, r11
+ cmp r12, r3
+ bcc memcopy_check_optim_default
+
+ // If (length == 0)
+ cmp r12, #0
+ beq memcopy_end
+
+ b memcopy_check_optim_overlap
+
+memcopy_check_optim_default:
+ // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)
+ tst r0, #0xF
+ movne r0, #0
+ bne memcopy_default
+ tst r1, #0xF
+ movne r3, #0
+ moveq r3, #1
+ cmp r2, #31
+ movls r0, #0
+ andhi r0, r3, #1
+ b memcopy_default
+
+memcopy_check_optim_overlap:
+ // r10 = dest_end, r14 = source_end
+ add r10, r11, r12
+ add r14, r12, r1
+
+ // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)
+ cmp r2, #31
+ movls r0, #0
+ movhi r0, #1
+ tst r10, #0xF
+ movne r0, #0
+ tst r14, #0xF
+ movne r0, #0
+ b memcopy_overlapped
+
+memcopy_overlapped_non_optim:
+ // We read 1 byte from the end of the source buffer
+ sub r3, r14, #1
+ sub r12, r12, #1
+ ldrb r3, [r3, #0]
+ sub r2, r10, #1
+ cmp r12, #0
+ // We write 1 byte at the end of the dest buffer
+ sub r10, r10, #1
+ sub r14, r14, #1
+ strb r3, [r2, #0]
+ bne memcopy_overlapped_non_optim
+ b memcopy_end
+
+// r10 = dest_end, r14 = source_end
+memcopy_overlapped:
+ // Are we in the optimized case ?
+ cmp r0, #0
+ beq memcopy_overlapped_non_optim
+
+ // Optimized Overlapped - Read 32 bytes
+ sub r14, r14, #32
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ movls r0, #0
+
+ cmp r12, #0
+
+ // Optimized Overlapped - Write 32 bytes
+ sub r10, r10, #32
+ stmia r10, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_overlapped
+ b memcopy_end
+
+memcopy_default_non_optim:
+ // Byte copy
+ ldrb r3, [r14], #1
+ sub r12, r12, #1
+ strb r3, [r10], #1
+
+memcopy_default:
+ cmp r12, #0
+ beq memcopy_end
+
+// r10 = dest, r14 = source
+memcopy_default_loop:
+ cmp r0, #0
+ beq memcopy_default_non_optim
+
+ // Optimized memcopy - Read 32 Bytes
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14!, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ movls r0, #0
+
+ cmp r12, #0
+
+ // Optimized memcopy - Write 32 Bytes
+ stmia r10!, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_default_loop
+
+memcopy_end:
+ mov r0, r11
+ ldmfd sp!, {r4-r11, pc}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.asm
new file mode 100755
index 0000000..0d22d75
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.asm
@@ -0,0 +1,173 @@
+;------------------------------------------------------------------------------
+;
+; CopyMem() worker for ARM
+;
+; This file started out as C code that did 64 bit moves if the buffer was
+; 32-bit aligned, else it does a byte copy. It also does a byte copy for
+; any trailing bytes. It was updated to do 32-byte copies using stm/ldm.
+;
+; Copyright (c) 2008 - 2010, Apple Inc. 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.
+;
+;------------------------------------------------------------------------------
+
+/**
+ Copy Length bytes from Source to Destination. Overlap is OK.
+
+ This implementation
+
+ @param Destination Target of copy
+ @param Source Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+**/
+ EXPORT InternalMemCopyMem
+
+ AREA AsmMemStuff, CODE, READONLY
+
+InternalMemCopyMem
+ stmfd sp!, {r4-r11, lr}
+ // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)
+ mov r11, r0
+ mov r10, r0
+ mov r12, r2
+ mov r14, r1
+
+memcopy_check_overlapped
+ cmp r11, r1
+ // If (dest < source)
+ bcc memcopy_check_optim_default
+ // If (dest <= source). But with the previous condition -> If (dest == source)
+ bls memcopy_end
+
+ // If (source + length < dest)
+ rsb r3, r1, r11
+ cmp r12, r3
+ bcc memcopy_check_optim_default
+
+ // If (length == 0)
+ cmp r12, #0
+ beq memcopy_end
+
+ b memcopy_check_optim_overlap
+
+memcopy_check_optim_default
+ // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)
+ tst r0, #0xF
+ movne r0, #0
+ bne memcopy_default
+ tst r1, #0xF
+ movne r3, #0
+ moveq r3, #1
+ cmp r2, #31
+ movls r0, #0
+ andhi r0, r3, #1
+ b memcopy_default
+
+memcopy_check_optim_overlap
+ // r10 = dest_end, r14 = source_end
+ add r10, r11, r12
+ add r14, r12, r1
+
+ // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)
+ cmp r2, #31
+ movls r0, #0
+ movhi r0, #1
+ tst r10, #0xF
+ movne r0, #0
+ tst r14, #0xF
+ movne r0, #0
+ b memcopy_overlapped
+
+memcopy_overlapped_non_optim
+ // We read 1 byte from the end of the source buffer
+ sub r3, r14, #1
+ sub r12, r12, #1
+ ldrb r3, [r3, #0]
+ sub r2, r10, #1
+ cmp r12, #0
+ // We write 1 byte at the end of the dest buffer
+ sub r10, r10, #1
+ sub r14, r14, #1
+ strb r3, [r2, #0]
+ bne memcopy_overlapped_non_optim
+ b memcopy_end
+
+// r10 = dest_end, r14 = source_end
+memcopy_overlapped
+ // Are we in the optimized case ?
+ cmp r0, #0
+ beq memcopy_overlapped_non_optim
+
+ // Optimized Overlapped - Read 32 bytes
+ sub r14, r14, #32
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ movls r0, #0
+
+ cmp r12, #0
+
+ // Optimized Overlapped - Write 32 bytes
+ sub r10, r10, #32
+ stmia r10, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_overlapped
+ b memcopy_end
+
+memcopy_default_non_optim
+ // Byte copy
+ ldrb r3, [r14], #1
+ sub r12, r12, #1
+ strb r3, [r10], #1
+
+memcopy_default
+ cmp r12, #0
+ beq memcopy_end
+
+// r10 = dest, r14 = source
+memcopy_default_loop
+ cmp r0, #0
+ beq memcopy_default_non_optim
+
+ // Optimized memcopy - Read 32 Bytes
+ sub r12, r12, #32
+ cmp r12, #31
+ ldmia r14!, {r2-r9}
+
+ // If length is less than 32 then disable optim
+ movls r0, #0
+
+ cmp r12, #0
+
+ // Optimized memcopy - Write 32 Bytes
+ stmia r10!, {r2-r9}
+
+ // while (length != 0)
+ bne memcopy_default_loop
+
+memcopy_end
+ mov r0, r11
+ ldmfd sp!, {r4-r11, pc}
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.S
new file mode 100755
index 0000000..c5b4cfe
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.S
@@ -0,0 +1,81 @@
+#------------------------------------------------------------------------------
+#
+# SemMem() worker for ARM
+#
+# This file started out as C code that did 64 bit moves if the buffer was
+# 32-bit aligned, else it does a byte copy. It also does a byte copy for
+# any trailing bytes. It was updated to do 32-byte at a time.
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+**/
+
+.text
+.align 2
+GCC_ASM_EXPORT(InternalMemSetMem)
+
+ASM_PFX(InternalMemSetMem):
+ stmfd sp!, {r4-r11, lr}
+ tst r0, #3
+ movne r3, #0
+ moveq r3, #1
+ cmp r1, #31
+ movls lr, #0
+ andhi lr, r3, #1
+ cmp lr, #0
+ mov r12, r0
+ bne L31
+L32:
+ mov r3, #0
+ b L43
+L31:
+ and r4, r2, #0xff
+ orr r4, r4, r4, LSL #8
+ orr r4, r4, r4, LSL #16
+ mov r5, r4
+ mov r6, r4
+ mov r7, r4
+ mov r8, r4
+ mov r9, r4
+ mov r10, r4
+ mov r11, r4
+ b L32
+L34:
+ cmp lr, #0
+ streqb r2, [r12], #1
+ subeq r1, r1, #1
+ beq L43
+ sub r1, r1, #32
+ cmp r1, #31
+ movls lr, r3
+ stmia r12!, {r4-r11}
+L43:
+ cmp r1, #0
+ bne L34
+ ldmfd sp!, {r4-r11, pc}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.asm
new file mode 100755
index 0000000..a9f29e2
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.asm
@@ -0,0 +1,81 @@
+;------------------------------------------------------------------------------
+;
+; SetMem() worker for ARM
+;
+; This file started out as C code that did 64 bit moves if the buffer was
+; 32-bit aligned, else it does a byte copy. It also does a byte copy for
+; any trailing bytes. It was updated to do 32-byte at a time.
+;
+; Copyright (c) 2008 - 2010, Apple Inc. 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.
+;
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+**/
+
+ EXPORT InternalMemSetMem
+
+ AREA AsmMemStuff, CODE, READONLY
+
+InternalMemSetMem
+ stmfd sp!, {r4-r11, lr}
+ tst r0, #3
+ movne r3, #0
+ moveq r3, #1
+ cmp r1, #31
+ movls lr, #0
+ andhi lr, r3, #1
+ cmp lr, #0
+ mov r12, r0
+ bne L31
+L32
+ mov r3, #0
+ b L43
+L31
+ and r4, r2, #0xff
+ orr r4, r4, r4, LSL #8
+ orr r4, r4, r4, LSL #16
+ mov r5, r4
+ mov r6, r4
+ mov r7, r4
+ mov r8, r4
+ mov r9, r4
+ mov r10, r4
+ mov r11, r4
+ b L32
+L34
+ cmp lr, #0
+ streqb r2, [r12], #1
+ subeq r1, r1, #1
+ beq L43
+ sub r1, r1, #32
+ cmp r1, #31
+ movls lr, r3
+ stmia r12!, {r4-r11}
+L43
+ cmp r1, #0
+ bne L34
+ ldmfd sp!, {r4-r11, pc}
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
new file mode 100755
index 0000000..c2f3e2f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
@@ -0,0 +1,68 @@
+## @file
+# Instance of Base Memory Library with some ARM ldm/stm assembly.
+#
+# This is a copy of the MdePkg BaseMemoryLib with the CopyMem and
+# SetMem worker functions replaced with assembler that uses
+# ldm/stm.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+# Portions 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 = BaseMemoryLibStm
+ FILE_GUID = 4D466AF3-2380-448D-A337-E4033F29F3F7
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BaseMemoryLib
+
+
+#
+# VALID_ARCHITECTURES = ARM AARCH64
+#
+
+
+[Sources.Common]
+ ScanMem64Wrapper.c
+ ScanMem32Wrapper.c
+ ScanMem16Wrapper.c
+ ScanMem8Wrapper.c
+ ZeroMemWrapper.c
+ CompareMemWrapper.c
+ SetMem64Wrapper.c
+ SetMem32Wrapper.c
+ SetMem16Wrapper.c
+ SetMemWrapper.c
+ CopyMemWrapper.c
+ MemLibGeneric.c
+ MemLibGuid.c
+ MemLibInternals.h
+
+[Sources.ARM]
+ Arm/CopyMem.asm
+ Arm/CopyMem.S
+ Arm/SetMem.asm
+ Arm/SetMem.S
+
+[Sources.AARCH64]
+ AArch64/CopyMem.c
+ AArch64/SetMem.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CompareMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CompareMemWrapper.c
new file mode 100755
index 0000000..c83988f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file
+ CompareMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Compares the contents of two buffers.
+
+ This function compares Length bytes of SourceBuffer to Length bytes of DestinationBuffer.
+ If all Length bytes of the two buffers are identical, then 0 is returned. Otherwise, the
+ value returned is the first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+ If Length > 0 and DestinationBuffer is NULL, then ASSERT().
+ If Length > 0 and SourceBuffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+ @param DestinationBuffer Pointer to the destination buffer to compare.
+ @param SourceBuffer Pointer to the source buffer to compare.
+ @param Length Number of bytes to compare.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+CompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (Length == 0 || DestinationBuffer == SourceBuffer) {
+ return 0;
+ }
+ ASSERT (DestinationBuffer != NULL);
+ ASSERT (SourceBuffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));
+
+ return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMem.c
new file mode 100755
index 0000000..b30faed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMem.c
@@ -0,0 +1,62 @@
+/** @file
+ Implementation of the InternalMemCopyMem routine. This function is broken
+ out into its own source file so that it can be excluded from a build for a
+ particular platform easily if an optimized version is desired.
+
+ Copyright (c) 2006 - 2008, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copy Length bytes from Source to Destination.
+
+ @param DestinationBuffer Target of copy
+ @param SourceBuffer Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+**/
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ //
+ // Declare the local variables that actually move the data elements as
+ // volatile to prevent the optimizer from replacing this function with
+ // the intrinsic memcpy()
+ //
+ volatile UINT8 *Destination8;
+ CONST UINT8 *Source8;
+
+ if (SourceBuffer > DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer;
+ Source8 = (CONST UINT8*)SourceBuffer;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer + Length;
+ Source8 = (CONST UINT8*)SourceBuffer + Length;
+ while (Length-- != 0) {
+ *(--Destination8) = *(--Source8);
+ }
+ }
+ return DestinationBuffer;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMemWrapper.c
new file mode 100755
index 0000000..2adfb31
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file
+ CopyMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copies a source buffer to a destination buffer, and returns the destination buffer.
+
+ This function copies Length bytes from SourceBuffer to DestinationBuffer, and returns
+ DestinationBuffer. The implementation must be reentrant, and it must handle the case
+ where SourceBuffer overlaps DestinationBuffer.
+
+ If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+ @param DestinationBuffer Pointer to the destination buffer of the memory copy.
+ @param SourceBuffer Pointer to the source buffer of the memory copy.
+ @param Length Number of bytes to copy from SourceBuffer to DestinationBuffer.
+
+ @return DestinationBuffer.
+
+**/
+VOID *
+EFIAPI
+CopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (Length == 0) {
+ return DestinationBuffer;
+ }
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));
+
+ if (DestinationBuffer == SourceBuffer) {
+ return DestinationBuffer;
+ }
+ return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c
new file mode 100755
index 0000000..ef78748
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c
@@ -0,0 +1,260 @@
+/** @file
+ Architecture Independent Base Memory Library Implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 16-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ do {
+ ((UINT16*)Buffer)[--Length] = Value;
+ } while (Length != 0);
+ return Buffer;
+}
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 32-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ do {
+ ((UINT32*)Buffer)[--Length] = Value;
+ } while (Length != 0);
+ return Buffer;
+}
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 64-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ do {
+ ((UINT64*)Buffer)[--Length] = Value;
+ } while (Length != 0);
+ return Buffer;
+}
+
+/**
+ Set Buffer to 0 for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ return InternalMemSetMem (Buffer, Length, 0);
+}
+
+/**
+ Compares two memory buffers of a given length.
+
+ @param DestinationBuffer First memory buffer
+ @param SourceBuffer Second memory buffer
+ @param Length Length of DestinationBuffer and SourceBuffer memory
+ regions to compare. Must be non-zero.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+InternalMemCompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ while ((--Length != 0) &&
+ (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {
+ DestinationBuffer = (INT8*)DestinationBuffer + 1;
+ SourceBuffer = (INT8*)SourceBuffer + 1;
+ }
+ return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;
+}
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the
+ matching 8-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 8-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ CONST UINT8 *Pointer;
+
+ Pointer = (CONST UINT8*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the
+ matching 16-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 16-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ CONST UINT16 *Pointer;
+
+ Pointer = (CONST UINT16*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the
+ matching 32-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 32-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ CONST UINT32 *Pointer;
+
+ Pointer = (CONST UINT32*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the
+ matching 64-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 64-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ CONST UINT64 *Pointer;
+
+ Pointer = (CONST UINT64*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c
new file mode 100755
index 0000000..2b4ed57
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c
@@ -0,0 +1,132 @@
+/** @file
+ Implementation of GUID functions.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copies a source GUID to a destination GUID.
+
+ This function copies the contents of the 128-bit GUID specified by SourceGuid to
+ DestinationGuid, and returns DestinationGuid.
+
+ If DestinationGuid is NULL, then ASSERT().
+ If SourceGuid is NULL, then ASSERT().
+
+ @param DestinationGuid Pointer to the destination GUID.
+ @param SourceGuid Pointer to the source GUID.
+
+ @return DestinationGuid.
+
+**/
+GUID *
+EFIAPI
+CopyGuid (
+ OUT GUID *DestinationGuid,
+ IN CONST GUID *SourceGuid
+ )
+{
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid)
+ );
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid + 1,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
+ );
+ return DestinationGuid;
+}
+
+/**
+ Compares two GUIDs.
+
+ This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE is returned.
+ If there are any bit differences in the two GUIDs, then FALSE is returned.
+
+ If Guid1 is NULL, then ASSERT().
+ If Guid2 is NULL, then ASSERT().
+
+ @param Guid1 A pointer to a 128 bit GUID.
+ @param Guid2 A pointer to a 128 bit GUID.
+
+ @retval TRUE Guid1 and Guid2 are identical.
+ @retval FALSE Guid1 and Guid2 are not identical.
+
+**/
+BOOLEAN
+EFIAPI
+CompareGuid (
+ IN CONST GUID *Guid1,
+ IN CONST GUID *Guid2
+ )
+{
+ return (CompareMem(Guid1, Guid2, sizeof(GUID)) == 0) ? TRUE : FALSE;
+}
+
+/**
+ Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from
+ the lowest address to the highest address at 128-bit increments for the 128-bit
+ GUID value that matches Guid. If a match is found, then a pointer to the matching
+ GUID in the target buffer is returned. If no match is found, then NULL is returned.
+ If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 128-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Guid Value to search for in the target buffer.
+
+ @return A pointer to the matching Guid in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanGuid (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN CONST GUID *Guid
+ )
+{
+ CONST GUID *GuidPtr;
+
+ ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);
+
+ GuidPtr = (GUID*)Buffer;
+ Buffer = GuidPtr + Length / sizeof (*GuidPtr);
+ while (GuidPtr < (CONST GUID*)Buffer) {
+ if (CompareGuid (GuidPtr, Guid)) {
+ return (VOID*)GuidPtr;
+ }
+ GuidPtr++;
+ }
+ return NULL;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h
new file mode 100755
index 0000000..10c741f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file
+ Declaration of internal functions for Base Memory Library.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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.
+
+**/
+
+#ifndef __MEM_LIB_INTERNALS__
+#define __MEM_LIB_INTERNALS__
+
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Copy Length bytes from Source to Destination.
+
+ @param DestinationBuffer Target of copy
+ @param SourceBuffer Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+**/
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ );
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ );
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 16-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ );
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 32-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ );
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 64-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ );
+
+/**
+ Set Buffer to 0 for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ Compares two memory buffers of a given length.
+
+ @param DestinationBuffer First memory buffer
+ @param SourceBuffer Second memory buffer
+ @param Length Length of DestinationBuffer and SourceBuffer memory
+ regions to compare. Must be non-zero.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+InternalMemCompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ );
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the
+ matching 8-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 8-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ );
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the
+ matching 16-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 16-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ );
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the
+ matching 32-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 32-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ );
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the
+ matching 64-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 64-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem16Wrapper.c
new file mode 100755
index 0000000..1c727b3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file
+ ScanMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the matching 16-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 16-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem32Wrapper.c
new file mode 100755
index 0000000..79ab60c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file
+ ScanMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the matching 32-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 32-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem64Wrapper.c
new file mode 100755
index 0000000..d11e50b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file
+ ScanMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the matching 64-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 64-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem8Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem8Wrapper.c
new file mode 100755
index 0000000..c6c6d5f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file
+ ScanMem8() and ScanMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the matching 8-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for an 8-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+
+ return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);
+}
+
+/**
+ Scans a target buffer for a UINTN sized value, and returns a pointer to the matching
+ UINTN sized value in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a UINTN sized value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMemN (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return ScanMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return ScanMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem.c
new file mode 100755
index 0000000..5c30e9b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem.c
@@ -0,0 +1,53 @@
+/** @file
+ Implementation of the EfiSetMem routine. This function is broken
+ out into its own source file so that it can be excluded from a
+ build for a particular platform easily if an optimized version
+ is desired.
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ //
+ // Declare the local variables that actually move the data elements as
+ // volatile to prevent the optimizer from replacing this function with
+ // the intrinsic memset()
+ //
+ volatile UINT8 *Pointer;
+
+ Pointer = (UINT8*)Buffer;
+ while (Length-- > 0) {
+ *(Pointer++) = Value;
+ }
+ return Buffer;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem16Wrapper.c
new file mode 100755
index 0000000..8129d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 16-bit value specified by
+ Value, and returns Buffer. Value is repeated every 16-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem32Wrapper.c
new file mode 100755
index 0000000..b57ba40
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 32-bit value specified by
+ Value, and returns Buffer. Value is repeated every 32-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem64Wrapper.c
new file mode 100755
index 0000000..f979580
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 64-bit value specified by
+ Value, and returns Buffer. Value is repeated every 64-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is not aligned on a 64-bit boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMemWrapper.c
new file mode 100755
index 0000000..9240c89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file
+ SetMem() and SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a byte value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with Value, and returns Buffer.
+
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+
+ return InternalMemSetMem (Buffer, Length, Value);
+}
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ZeroMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ZeroMemWrapper.c
new file mode 100755
index 0000000..d6c6279
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibStm/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file
+ ZeroMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with zeros, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with zeros, and returns Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill with zeros.
+ @param Length Number of bytes in Buffer to fill with zeros.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+ZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ ASSERT (!(Buffer == NULL && Length > 0));
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ return InternalMemZeroMem (Buffer, Length);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S
new file mode 100755
index 0000000..0a6e039
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S
@@ -0,0 +1,114 @@
+#------------------------------------------------------------------------------
+#
+# CopyMem() worker for ARM
+#
+# This file started out as C code that did 64 bit moves if the buffer was
+# 32-bit aligned, else it does a byte copy. It also does a byte copy for
+# any trailing bytes. Update using VSTM/SLDM to do 128 byte copies.
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+/**
+ Copy Length bytes from Source to Destination. Overlap is OK.
+
+ This implementation
+
+ @param Destination Target of copy
+ @param Source Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+**/
+.text
+.align 2
+GCC_ASM_EXPORT(InternalMemCopyMem)
+
+ASM_PFX(InternalMemCopyMem):
+ stmfd sp!, {r4, r9, lr}
+ tst r0, #3
+ mov r4, r0
+ mov r9, r0
+ mov ip, r2
+ mov lr, r1
+ movne r0, #0
+ bne L4
+ tst r1, #3
+ movne r3, #0
+ moveq r3, #1
+ cmp r2, #127
+ movls r0, #0
+ andhi r0, r3, #1
+L4:
+ cmp r4, r1
+ bcc L26
+ bls L7
+ rsb r3, r1, r4
+ cmp ip, r3
+ bcc L26
+ cmp ip, #0
+ beq L7
+ add r9, r4, ip
+ add lr, ip, r1
+ b L16
+L29:
+ sub ip, ip, #8
+ cmp ip, #7
+ ldrd r2, [lr, #-8]!
+ movls r0, #0
+ cmp ip, #0
+ strd r2, [r9, #-8]!
+ beq L7
+L16:
+ cmp r0, #0
+ bne L29
+ sub r3, lr, #1
+ sub ip, ip, #1
+ ldrb r3, [r3, #0]
+ sub r2, r9, #1
+ cmp ip, #0
+ sub r9, r9, #1
+ sub lr, lr, #1
+ strb r3, [r2, #0]
+ bne L16
+ b L7
+L11:
+ ldrb r3, [lr], #1
+ sub ip, ip, #1
+ strb r3, [r9], #1
+L26:
+ cmp ip, #0
+ beq L7
+L30:
+ cmp r0, #0
+ beq L11
+ sub ip, ip, #128 // 32
+ cmp ip, #127 // 31
+ vldm lr!, {d0-d15}
+ movls r0, #0
+ cmp ip, #0
+ vstm r9!, {d0-d15}
+ bne L30
+L7:
+ dsb
+ mov r0, r4
+ ldmfd sp!, {r4, r9, pc}
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm
new file mode 100755
index 0000000..17b79e5
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm
@@ -0,0 +1,115 @@
+;------------------------------------------------------------------------------
+;
+; CopyMem() worker for ARM
+;
+; This file started out as C code that did 64 bit moves if the buffer was
+; 32-bit aligned, else it does a byte copy. It also does a byte copy for
+; any trailing bytes. Update using VSTM/SLDM to do 128 byte copies.
+;
+; Copyright (c) 2008 - 2010, Apple Inc. 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.
+;
+;------------------------------------------------------------------------------
+
+/**
+ Copy Length bytes from Source to Destination. Overlap is OK.
+
+ This implementation
+
+ @param Destination Target of copy
+ @param Source Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+**/
+ EXPORT InternalMemCopyMem
+
+ AREA AsmMemStuff, CODE, READONLY
+
+InternalMemCopyMem
+ stmfd sp!, {r4, r9, lr}
+ tst r0, #3
+ mov r4, r0
+ mov r9, r0
+ mov ip, r2
+ mov lr, r1
+ movne r0, #0
+ bne L4
+ tst r1, #3
+ movne r3, #0
+ moveq r3, #1
+ cmp r2, #127
+ movls r0, #0
+ andhi r0, r3, #1
+L4
+ cmp r4, r1
+ bcc L26
+ bls L7
+ rsb r3, r1, r4
+ cmp ip, r3
+ bcc L26
+ cmp ip, #0
+ beq L7
+ add r9, r4, ip
+ add lr, ip, r1
+ b L16
+L29
+ sub ip, ip, #8
+ cmp ip, #7
+ ldrd r2, [lr, #-8]!
+ movls r0, #0
+ cmp ip, #0
+ strd r2, [r9, #-8]!
+ beq L7
+L16
+ cmp r0, #0
+ bne L29
+ sub r3, lr, #1
+ sub ip, ip, #1
+ ldrb r3, [r3, #0]
+ sub r2, r9, #1
+ cmp ip, #0
+ sub r9, r9, #1
+ sub lr, lr, #1
+ strb r3, [r2, #0]
+ bne L16
+ b L7
+L11
+ ldrb r3, [lr], #1
+ sub ip, ip, #1
+ strb r3, [r9], #1
+L26
+ cmp ip, #0
+ beq L7
+L30
+ cmp r0, #0
+ beq L11
+ sub ip, ip, #128 // 32
+ cmp ip, #127 // 31
+ vldm lr!, {d0-d15}
+ movls r0, #0
+ cmp ip, #0
+ vstm r9!, {d0-d15}
+ bne L30
+L7
+ dsb
+ mov r0, r4
+ ldmfd sp!, {r4, r9, pc}
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S
new file mode 100755
index 0000000..6a6bb20
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S
@@ -0,0 +1,79 @@
+#------------------------------------------------------------------------------
+#
+# SemMem() worker for ARM
+#
+# This file started out as C code that did 64 bit moves if the buffer was
+# 32-bit aligned, else it does a byte copy. It also does a byte copy for
+# any trailing bytes. Update to use VSTM/VLDM to do 128 byte writes.
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+**/
+
+.text
+.align 2
+GCC_ASM_EXPORT(InternalMemSetMem)
+
+ASM_PFX(InternalMemSetMem):
+ stmfd sp!, {r4-r7, lr}
+ tst r0, #3
+ movne r3, #0
+ moveq r3, #1
+ cmp r1, #127
+ movls lr, #0
+ andhi lr, r3, #1
+ cmp lr, #0
+ mov r12, r0
+ bne L31
+L32:
+ mov r3, #0
+ b L43
+L31:
+ vdup.8 q0,r2
+ vmov q1,q0
+ vmov q2,q0
+ vmov q3,q0
+ vmov q4,q0
+ vmov q5,q0
+ vmov q6,q0
+ vmov q7,q0
+ b L32
+L34:
+ cmp lr, #0
+ streqb r2, [r12], #1
+ subeq r1, r1, #1
+ beq L43
+ sub r1, r1, #128
+ cmp r1, #127
+ cmp r1, #31
+ movls lr, r3
+ vstm r12!, {d0-d15}
+L43:
+ cmp r1, #0
+ bne L34
+ ldmfd sp!, {pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm
new file mode 100755
index 0000000..5226192
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------
+;
+; SetMem() worker for ARM
+;
+; This file started out as C code that did 64 bit moves if the buffer was
+; 32-bit aligned, else it does a byte copy. It also does a byte copy for
+; any trailing bytes. Update to use VSTM/VLDM to do 128 byte writes.
+;
+; Copyright (c) 2008 - 2010, Apple Inc. 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.
+;
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+**/
+
+ EXPORT InternalMemSetMem
+
+ AREA AsmMemStuff, CODE, READONLY
+
+InternalMemSetMem
+ stmfd sp!, {lr}
+ tst r0, #3
+ movne r3, #0
+ moveq r3, #1
+ cmp r1, #127
+ movls lr, #0
+ andhi lr, r3, #1
+ cmp lr, #0
+ mov r12, r0
+ bne L31
+L32
+ mov r3, #0
+ b L43
+L31
+ vdup.8 q0,r2
+ vmov q1,q0
+ vmov q2,q0
+ vmov q3,q0
+ vmov q4,q0
+ vmov q5,q0
+ vmov q6,q0
+ vmov q7,q0
+ b L32
+L34
+ cmp lr, #0
+ streqb r2, [r12], #1
+ subeq r1, r1, #1
+ beq L43
+ sub r1, r1, #128
+ cmp r1, #127
+ movls lr, r3
+ vstm r12!, {d0-d15}
+L43
+ cmp r1, #0
+ bne L34
+ ldmfd sp!, {pc}
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
new file mode 100755
index 0000000..eaff180
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
@@ -0,0 +1,69 @@
+## @file
+# Instance of Base Memory Library with some ARM vldm/vstm assembly.
+#
+# This is a copy of the MdePkg BaseMemoryLib with the CopyMem and
+# SetMem worker functions replaced with assembler that uses
+# vldm/vstm (part of NEON SIMD, optional in ARMv7-A).
+#
+# Note: You need to enable NEON in SEC to use this library
+# // Enable NEON register in case folks want to use them for optimizations (CopyMem)
+# mrc p15, 0, r0, c1, c0, 2
+# orr r0, r0, #0x00f00000 // Enable VPF access (V* instructions)
+# mcr p15, 0, r0, c1, c0, 2
+# mov r0, #0x40000000 // Set EN bit in FPEXC
+# msr FPEXC,r0
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Portions copyright (c) 2010, Apple Inc. 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 = BaseMemoryLibVstm
+ FILE_GUID = 09EE1E8D-7A2E-4573-8117-68A18569C1F5
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BaseMemoryLib
+
+
+#
+# VALID_ARCHITECTURES = ARM
+#
+
+[Sources.ARM]
+ ScanMem64Wrapper.c
+ ScanMem32Wrapper.c
+ ScanMem16Wrapper.c
+ ScanMem8Wrapper.c
+ ZeroMemWrapper.c
+ CompareMemWrapper.c
+ SetMem64Wrapper.c
+ SetMem32Wrapper.c
+ SetMem16Wrapper.c
+ SetMemWrapper.c
+ CopyMemWrapper.c
+ MemLibGeneric.c
+ MemLibGuid.c
+ MemLibInternals.h
+ Arm/CopyMem.asm
+ Arm/CopyMem.S
+ Arm/SetMem.asm
+ Arm/SetMem.S
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c
new file mode 100755
index 0000000..c83988f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file
+ CompareMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Compares the contents of two buffers.
+
+ This function compares Length bytes of SourceBuffer to Length bytes of DestinationBuffer.
+ If all Length bytes of the two buffers are identical, then 0 is returned. Otherwise, the
+ value returned is the first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+ If Length > 0 and DestinationBuffer is NULL, then ASSERT().
+ If Length > 0 and SourceBuffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+ @param DestinationBuffer Pointer to the destination buffer to compare.
+ @param SourceBuffer Pointer to the source buffer to compare.
+ @param Length Number of bytes to compare.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+CompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (Length == 0 || DestinationBuffer == SourceBuffer) {
+ return 0;
+ }
+ ASSERT (DestinationBuffer != NULL);
+ ASSERT (SourceBuffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));
+
+ return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c
new file mode 100755
index 0000000..b30faed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c
@@ -0,0 +1,62 @@
+/** @file
+ Implementation of the InternalMemCopyMem routine. This function is broken
+ out into its own source file so that it can be excluded from a build for a
+ particular platform easily if an optimized version is desired.
+
+ Copyright (c) 2006 - 2008, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copy Length bytes from Source to Destination.
+
+ @param DestinationBuffer Target of copy
+ @param SourceBuffer Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+**/
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ //
+ // Declare the local variables that actually move the data elements as
+ // volatile to prevent the optimizer from replacing this function with
+ // the intrinsic memcpy()
+ //
+ volatile UINT8 *Destination8;
+ CONST UINT8 *Source8;
+
+ if (SourceBuffer > DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer;
+ Source8 = (CONST UINT8*)SourceBuffer;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer + Length;
+ Source8 = (CONST UINT8*)SourceBuffer + Length;
+ while (Length-- != 0) {
+ *(--Destination8) = *(--Source8);
+ }
+ }
+ return DestinationBuffer;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c
new file mode 100755
index 0000000..2adfb31
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file
+ CopyMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copies a source buffer to a destination buffer, and returns the destination buffer.
+
+ This function copies Length bytes from SourceBuffer to DestinationBuffer, and returns
+ DestinationBuffer. The implementation must be reentrant, and it must handle the case
+ where SourceBuffer overlaps DestinationBuffer.
+
+ If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+ @param DestinationBuffer Pointer to the destination buffer of the memory copy.
+ @param SourceBuffer Pointer to the source buffer of the memory copy.
+ @param Length Number of bytes to copy from SourceBuffer to DestinationBuffer.
+
+ @return DestinationBuffer.
+
+**/
+VOID *
+EFIAPI
+CopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (Length == 0) {
+ return DestinationBuffer;
+ }
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));
+
+ if (DestinationBuffer == SourceBuffer) {
+ return DestinationBuffer;
+ }
+ return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c
new file mode 100755
index 0000000..ef78748
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c
@@ -0,0 +1,260 @@
+/** @file
+ Architecture Independent Base Memory Library Implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 16-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ do {
+ ((UINT16*)Buffer)[--Length] = Value;
+ } while (Length != 0);
+ return Buffer;
+}
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 32-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ do {
+ ((UINT32*)Buffer)[--Length] = Value;
+ } while (Length != 0);
+ return Buffer;
+}
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 64-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ do {
+ ((UINT64*)Buffer)[--Length] = Value;
+ } while (Length != 0);
+ return Buffer;
+}
+
+/**
+ Set Buffer to 0 for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ return InternalMemSetMem (Buffer, Length, 0);
+}
+
+/**
+ Compares two memory buffers of a given length.
+
+ @param DestinationBuffer First memory buffer
+ @param SourceBuffer Second memory buffer
+ @param Length Length of DestinationBuffer and SourceBuffer memory
+ regions to compare. Must be non-zero.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+InternalMemCompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ while ((--Length != 0) &&
+ (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {
+ DestinationBuffer = (INT8*)DestinationBuffer + 1;
+ SourceBuffer = (INT8*)SourceBuffer + 1;
+ }
+ return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;
+}
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the
+ matching 8-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 8-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ CONST UINT8 *Pointer;
+
+ Pointer = (CONST UINT8*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the
+ matching 16-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 16-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ CONST UINT16 *Pointer;
+
+ Pointer = (CONST UINT16*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the
+ matching 32-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 32-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ CONST UINT32 *Pointer;
+
+ Pointer = (CONST UINT32*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the
+ matching 64-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 64-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ CONST UINT64 *Pointer;
+
+ Pointer = (CONST UINT64*)Buffer;
+ do {
+ if (*(Pointer++) == Value) {
+ return Pointer;
+ }
+ } while (--Length != 0);
+ return NULL;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c
new file mode 100755
index 0000000..dc9e2c3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c
@@ -0,0 +1,132 @@
+/** @file
+ Implementation of GUID functions.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Copies a source GUID to a destination GUID.
+
+ This function copies the contents of the 128-bit GUID specified by SourceGuid to
+ DestinationGuid, and returns DestinationGuid.
+
+ If DestinationGuid is NULL, then ASSERT().
+ If SourceGuid is NULL, then ASSERT().
+
+ @param DestinationGuid Pointer to the destination GUID.
+ @param SourceGuid Pointer to the source GUID.
+
+ @return DestinationGuid.
+
+**/
+GUID *
+EFIAPI
+CopyGuid (
+ OUT GUID *DestinationGuid,
+ IN CONST GUID *SourceGuid
+ )
+{
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid)
+ );
+ WriteUnaligned64 (
+ (UINT64*)DestinationGuid + 1,
+ ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
+ );
+ return DestinationGuid;
+}
+
+/**
+ Compares two GUIDs.
+
+ This function compares Guid1 to Guid2. If the GUIDs are identical then TRUE is returned.
+ If there are any bit differences in the two GUIDs, then FALSE is returned.
+
+ If Guid1 is NULL, then ASSERT().
+ If Guid2 is NULL, then ASSERT().
+
+ @param Guid1 A pointer to a 128 bit GUID.
+ @param Guid2 A pointer to a 128 bit GUID.
+
+ @retval TRUE Guid1 and Guid2 are identical.
+ @retval FALSE Guid1 and Guid2 are not identical.
+
+**/
+BOOLEAN
+EFIAPI
+CompareGuid (
+ IN CONST GUID *Guid1,
+ IN CONST GUID *Guid2
+ )
+{
+ return (CompareMem(Guid1, Guid2, sizeof(GUID) == 0)) ? TRUE : FALSE;
+}
+
+/**
+ Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from
+ the lowest address to the highest address at 128-bit increments for the 128-bit
+ GUID value that matches Guid. If a match is found, then a pointer to the matching
+ GUID in the target buffer is returned. If no match is found, then NULL is returned.
+ If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 128-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Guid Value to search for in the target buffer.
+
+ @return A pointer to the matching Guid in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanGuid (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN CONST GUID *Guid
+ )
+{
+ CONST GUID *GuidPtr;
+
+ ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);
+
+ GuidPtr = (GUID*)Buffer;
+ Buffer = GuidPtr + Length / sizeof (*GuidPtr);
+ while (GuidPtr < (CONST GUID*)Buffer) {
+ if (CompareGuid (GuidPtr, Guid)) {
+ return (VOID*)GuidPtr;
+ }
+ GuidPtr++;
+ }
+ return NULL;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h
new file mode 100755
index 0000000..10c741f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file
+ Declaration of internal functions for Base Memory Library.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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.
+
+**/
+
+#ifndef __MEM_LIB_INTERNALS__
+#define __MEM_LIB_INTERNALS__
+
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Copy Length bytes from Source to Destination.
+
+ @param DestinationBuffer Target of copy
+ @param SourceBuffer Place to copy from
+ @param Length Number of bytes to copy
+
+ @return Destination
+
+**/
+VOID *
+EFIAPI
+InternalMemCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ );
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ );
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 16-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ );
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 32-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ );
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Count of 64-bit value to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ );
+
+/**
+ Set Buffer to 0 for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ Compares two memory buffers of a given length.
+
+ @param DestinationBuffer First memory buffer
+ @param SourceBuffer Second memory buffer
+ @param Length Length of DestinationBuffer and SourceBuffer memory
+ regions to compare. Must be non-zero.
+
+ @return 0 All Length bytes of the two buffers are identical.
+ @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
+ mismatched byte in DestinationBuffer.
+
+**/
+INTN
+EFIAPI
+InternalMemCompareMem (
+ IN CONST VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ );
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the
+ matching 8-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 8-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ );
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the
+ matching 16-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 16-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ );
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the
+ matching 32-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 32-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ );
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the
+ matching 64-bit value in the target buffer.
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Count of 64-bit value to scan. Must be non-zero.
+ @param Value Value to search for in the target buffer.
+
+ @return Pointer to the first occurrence or NULL if not found.
+
+**/
+CONST VOID *
+EFIAPI
+InternalMemScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c
new file mode 100755
index 0000000..1c727b3
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file
+ ScanMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 16-bit value, and returns a pointer to the matching 16-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 16-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem16 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c
new file mode 100755
index 0000000..79ab60c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file
+ ScanMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 32-bit value, and returns a pointer to the matching 32-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 32-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem32 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c
new file mode 100755
index 0000000..d11e50b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file
+ ScanMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for a 64-bit value, and returns a pointer to the matching 64-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a 64-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem64 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c
new file mode 100755
index 0000000..c6c6d5f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file
+ ScanMem8() and ScanMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Scans a target buffer for an 8-bit value, and returns a pointer to the matching 8-bit value
+ in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for an 8-bit value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMem8 (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ if (Length == 0) {
+ return NULL;
+ }
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+
+ return (VOID*)InternalMemScanMem8 (Buffer, Length, Value);
+}
+
+/**
+ Scans a target buffer for a UINTN sized value, and returns a pointer to the matching
+ UINTN sized value in the target buffer.
+
+ This function searches the target buffer specified by Buffer and Length from the lowest
+ address to the highest address for a UINTN sized value that matches Value. If a match is found,
+ then a pointer to the matching byte in the target buffer is returned. If no match is found,
+ then NULL is returned. If Length is 0, then NULL is returned.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to scan.
+ @param Length Number of bytes in Buffer to scan.
+ @param Value Value to search for in the target buffer.
+
+ @return A pointer to the matching byte in the target buffer or NULL otherwise.
+
+**/
+VOID *
+EFIAPI
+ScanMemN (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return ScanMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return ScanMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem.c
new file mode 100755
index 0000000..5c30e9b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem.c
@@ -0,0 +1,53 @@
+/** @file
+ Implementation of the EfiSetMem routine. This function is broken
+ out into its own source file so that it can be excluded from a
+ build for a particular platform easily if an optimized version
+ is desired.
+
+ Copyright (c) 2006 - 2010, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set
+ @param Value Value of the set operation.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+InternalMemSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ //
+ // Declare the local variables that actually move the data elements as
+ // volatile to prevent the optimizer from replacing this function with
+ // the intrinsic memset()
+ //
+ volatile UINT8 *Pointer;
+
+ Pointer = (UINT8*)Buffer;
+ while (Length-- > 0) {
+ *(Pointer++) = Value;
+ }
+ return Buffer;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c
new file mode 100755
index 0000000..8129d21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 16-bit value specified by
+ Value, and returns Buffer. Value is repeated every 16-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+ If Length is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c
new file mode 100755
index 0000000..b57ba40
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 32-bit value specified by
+ Value, and returns Buffer. Value is repeated every 32-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem32 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT32 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c
new file mode 100755
index 0000000..f979580
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file
+ SetMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the 64-bit value specified by
+ Value, and returns Buffer. Value is repeated every 64-bits in for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+ If Length is not aligned on a 64-bit boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem64 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT64 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);
+ ASSERT ((Length & (sizeof (Value) - 1)) == 0);
+
+ return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c
new file mode 100755
index 0000000..9240c89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file
+ SetMem() and SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a byte value, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with Value, and returns Buffer.
+
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Memory to set.
+ @param Length Number of bytes to set.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+
+ return InternalMemSetMem (Buffer, Length, Value);
+}
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill.
+ @param Length Number of bytes in Buffer to fill.
+ @param Value Value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ZeroMemWrapper.c b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ZeroMemWrapper.c
new file mode 100755
index 0000000..d6c6279
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BaseMemoryLibVstm/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file
+ ZeroMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2009, Intel Corporation. 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 "MemLibInternals.h"
+
+/**
+ Fills a target buffer with zeros, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with zeros, and returns Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill with zeros.
+ @param Length Number of bytes in Buffer to fill with zeros.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+ZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ ASSERT (!(Buffer == NULL && Length > 0));
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ return InternalMemZeroMem (Buffer, Length);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c
new file mode 100644
index 0000000..e094413
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoader.c
@@ -0,0 +1,349 @@
+/** @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 <Library/ArmGicLib.h>
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Library/IoLib.h>
+
+#include "BdsInternal.h"
+#include "BdsLinuxLoader.h"
+
+/*
+ Linux kernel booting: Look at the doc in the Kernel source :
+ Documentation/arm64/booting.txt
+ The kernel image must be placed at the start of the memory to be used by the
+ kernel (2MB aligned) + 0x80000.
+
+ The Device tree blob is expected to be under 2MB and be within the first 512MB
+ of kernel memory and be 2MB aligned.
+
+ A Flattened Device Tree (FDT) used to boot linux needs to be updated before
+ the kernel is started. It needs to indicate how secondary cores are brought up
+ and where they are waiting before loading Linux. The FDT also needs to hold
+ the correct kernel command line and filesystem RAM-disk information.
+ At the moment we do not fully support generating this FDT information at
+ runtime. A prepared FDT should be provided at boot. FDT is the only supported
+ method for booting the AArch64 Linux kernel.
+
+ Linux does not use any runtime services at this time, so we can let it
+ overwrite UEFI.
+*/
+
+
+#define LINUX_ALIGN_VAL (0x080000) // 2MB + 0x80000 mask
+#define LINUX_ALIGN_MASK (0x1FFFFF) // Bottom 21bits
+#define ALIGN_2MB(addr) ALIGN_POINTER(addr , (2*1024*1024))
+
+/* ARM32 and AArch64 kernel handover differ.
+ * x0 is set to FDT base.
+ * x1-x3 are reserved for future use and should be set to zero.
+ */
+typedef VOID (*LINUX_KERNEL64)(UINTN ParametersBase, UINTN Reserved0,
+ UINTN Reserved1, UINTN Reserved2);
+
+/* These externs are used to relocate some ASM code into Linux memory. */
+extern VOID *SecondariesPenStart;
+extern VOID *SecondariesPenEnd;
+extern UINTN *AsmMailboxbase;
+
+
+STATIC
+EFI_STATUS
+PreparePlatformHardware (
+ VOID
+ )
+{
+ //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.
+
+ // Clean before Disable else the Stack gets corrupted with old data.
+ ArmCleanDataCache ();
+ ArmDisableDataCache ();
+ // Invalidate all the entries that might have snuck in.
+ ArmInvalidateDataCache ();
+
+ // Disable and invalidate the instruction cache
+ ArmDisableInstructionCache ();
+ ArmInvalidateInstructionCache ();
+
+ // Turn off MMU
+ ArmDisableMmu();
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+StartLinux (
+ IN EFI_PHYSICAL_ADDRESS LinuxImage,
+ IN UINTN LinuxImageSize,
+ IN EFI_PHYSICAL_ADDRESS FdtBlobBase,
+ IN UINTN FdtBlobSize
+ )
+{
+ EFI_STATUS Status;
+ LINUX_KERNEL64 LinuxKernel = (LINUX_KERNEL64)LinuxImage;
+
+ // Send msg to secondary cores to go to the kernel pen.
+ ArmGicSendSgiTo (PcdGet32(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));
+
+ // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on
+ // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.
+ Status = ShutdownUefiBootServices ();
+ if(EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
+ goto Exit;
+ }
+
+ // Check if the Linux Image is a uImage
+ if (*(UINTN*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {
+ // Assume the Image Entry Point is just after the uImage header (64-byte size)
+ LinuxKernel = (LINUX_KERNEL64)((UINTN)LinuxKernel + 64);
+ LinuxImageSize -= 64;
+ }
+
+ //
+ // Switch off interrupts, caches, mmu, etc
+ //
+ Status = PreparePlatformHardware ();
+ ASSERT_EFI_ERROR(Status);
+
+ // Register and print out performance information
+ PERF_END (NULL, "BDS", NULL, 0);
+ if (PerformanceMeasurementEnabled ()) {
+ PrintPerformance ();
+ }
+
+ //
+ // Start the Linux Kernel
+ //
+
+ // x1-x3 are reserved (set to zero) for future use.
+ LinuxKernel ((UINTN)FdtBlobBase, 0, 0, 0);
+
+ // Kernel should never exit
+ // After Life services are not provided
+ ASSERT(FALSE);
+
+Exit:
+ // Only be here if we fail to start Linux
+ Print (L"ERROR : Can not start the kernel. Status=0x%X\n", Status);
+
+ // Free Runtimee Memory (kernel and FDT)
+ return Status;
+}
+
+
+/**
+ Start a Linux kernel from a Device Path
+
+ @param LinuxKernel Device Path to the Linux Kernel
+ @param Parameters Linux kernel agruments
+ @param Fdt Device Path to the Flat Device Tree
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsBootLinuxAtag (
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
+ IN CONST CHAR8* Arguments
+ )
+{
+ // NOTE : AArch64 Linux kernel does not support ATAG, FDT only.
+ ASSERT(0);
+
+ return RETURN_UNSUPPORTED;
+}
+
+/**
+ Start a Linux kernel from a Device Path
+
+ @param LinuxKernel Device Path to the Linux Kernel
+ @param Parameters Linux kernel agruments
+ @param Fdt Device Path to the Flat Device Tree
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsBootLinuxFdt (
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
+ IN CONST CHAR8* Arguments,
+ IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS PenBaseStatus;
+ UINTN LinuxImageSize;
+ UINTN InitrdImageSize;
+ UINTN InitrdImageBaseSize;
+ UINTN FdtBlobSize;
+ EFI_PHYSICAL_ADDRESS FdtBlobBase;
+ EFI_PHYSICAL_ADDRESS LinuxImage;
+ EFI_PHYSICAL_ADDRESS InitrdImage;
+ EFI_PHYSICAL_ADDRESS InitrdImageBase;
+ ARM_PROCESSOR_TABLE *ArmProcessorTable;
+ ARM_CORE_INFO *ArmCoreInfoTable;
+ UINTN Index;
+ EFI_PHYSICAL_ADDRESS PenBase;
+ UINTN PenSize;
+ UINTN MailBoxBase;
+
+ PenBaseStatus = EFI_UNSUPPORTED;
+ PenSize = 0;
+ InitrdImage = 0;
+ InitrdImageSize = 0;
+ InitrdImageBase = 0;
+ InitrdImageBaseSize = 0;
+
+ PERF_START (NULL, "BDS", NULL, 0);
+
+ //
+ // Load the Linux kernel from a device path
+ //
+
+ // Try to put the kernel at the start of RAM so as to give it access to all memory.
+ // If that fails fall back to try loading it within LINUX_KERNEL_MAX_OFFSET of memory start.
+ LinuxImage = PcdGet64 (PcdSystemMemoryBase) + 0x80000;
+ Status = BdsLoadImage (LinuxKernelDevicePath, AllocateAddress, &LinuxImage, &LinuxImageSize);
+ if (EFI_ERROR(Status)) {
+ // Try again but give the loader more freedom of where to put the image.
+ LinuxImage = LINUX_KERNEL_MAX_OFFSET;
+ Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find Linux kernel (%r).\n", Status);
+ return Status;
+ }
+ }
+ // Adjust the kernel location slightly if required. The kernel needs to be placed at start
+ // of memory (2MB aligned) + 0x80000.
+ if ((LinuxImage & LINUX_ALIGN_MASK) != LINUX_ALIGN_VAL) {
+ LinuxImage = (EFI_PHYSICAL_ADDRESS)CopyMem (ALIGN_2MB(LinuxImage) + 0x80000, (VOID*)(UINTN)LinuxImage, LinuxImageSize);
+ }
+
+ if (InitrdDevicePath) {
+ InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;
+ Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);
+ }
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: Did not find initrd image (%r).\n", Status);
+ goto EXIT_FREE_LINUX;
+ }
+
+ // Check if the initrd is a uInitrd
+ if (*(UINTN*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {
+ // Skip the 64-byte image header
+ InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);
+ InitrdImageSize = InitrdImageBaseSize - 64;
+ } else {
+ InitrdImage = InitrdImageBase;
+ InitrdImageSize = InitrdImageBaseSize;
+ }
+ }
+
+ // Load the FDT binary from a device path.
+ // The FDT will be reloaded later to a more appropriate location for the Linux kernel.
+ FdtBlobBase = LINUX_KERNEL_MAX_OFFSET;
+ Status = BdsLoadImage (FdtDevicePath, AllocateMaxAddress, &FdtBlobBase, &FdtBlobSize);
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find Device Tree blob (%r).\n", Status);
+ goto EXIT_FREE_INITRD;
+ }
+
+ //
+ // Install secondary core pens if the Power State Coordination Interface is not supported
+ //
+ if (FeaturePcdGet (PcdArmLinuxSpinTable)) {
+ // Place Pen at the start of Linux memory. We can then tell Linux to not use this bit of memory
+ PenBase = LinuxImage - 0x80000;
+ PenSize = (UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart;
+
+ // Reserve the memory as RuntimeServices
+ PenBaseStatus = gBS->AllocatePages (AllocateAddress, EfiRuntimeServicesCode, EFI_SIZE_TO_PAGES (PenSize), &PenBase);
+ if (EFI_ERROR (PenBaseStatus)) {
+ Print (L"Warning: Failed to reserve the memory required for the secondary cores at 0x%lX, Status = %r\n", PenBase, PenBaseStatus);
+ // Even if there is a risk of memory corruption we carry on
+ }
+
+ // Put mailboxes below the pen code so we know where they are relative to code.
+ MailBoxBase = (UINTN)PenBase + ((UINTN)&SecondariesPenEnd - (UINTN)&SecondariesPenStart);
+ // Make sure this is 8 byte aligned.
+ if (MailBoxBase % sizeof(MailBoxBase) != 0) {
+ MailBoxBase += sizeof(MailBoxBase) - MailBoxBase % sizeof(MailBoxBase);
+ }
+
+ CopyMem ( (VOID*)(PenBase), (VOID*)&SecondariesPenStart, PenSize);
+
+ // Update the MailboxBase variable used in the pen code
+ *(UINTN*)(PenBase + ((UINTN)&AsmMailboxbase - (UINTN)&SecondariesPenStart)) = MailBoxBase;
+
+ for (Index=0; Index < gST->NumberOfTableEntries; Index++) {
+ // Check for correct GUID type
+ if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+ UINTN i;
+
+ // Get them under our control. Move from depending on 32bit reg(sys_flags) and SWI
+ // to 64 bit addr and WFE
+ ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable;
+ ArmCoreInfoTable = ArmProcessorTable->ArmCpus;
+
+ for (i = 0; i < ArmProcessorTable->NumberOfEntries; i++ ) {
+ // This goes into the SYSFLAGS register for the VE platform. We only have one 32bit reg to use
+ MmioWrite32(ArmCoreInfoTable[i].MailboxSetAddress, (UINTN)PenBase);
+
+ // So FDT can set the mailboxes correctly with the parser. These are 64bit Memory locations.
+ ArmCoreInfoTable[i].MailboxSetAddress = (UINTN)MailBoxBase + i*sizeof(MailBoxBase);
+
+ // Clear the mailboxes for the respective cores
+ *((UINTN*)(ArmCoreInfoTable[i].MailboxSetAddress)) = 0x0;
+ }
+ }
+ }
+ // Flush caches to make sure our pen gets to mem before we free the cores.
+ ArmCleanDataCache();
+ }
+
+ // By setting address=0 we leave the memory allocation to the function
+ Status = PrepareFdt (Arguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);
+ if (EFI_ERROR(Status)) {
+ Print(L"ERROR: Can not load Linux kernel with Device Tree. Status=0x%X\n", Status);
+ goto EXIT_FREE_FDT;
+ }
+
+ return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize);
+
+EXIT_FREE_FDT:
+ if (!EFI_ERROR (PenBaseStatus)) {
+ gBS->FreePages (PenBase, EFI_SIZE_TO_PAGES (PenSize));
+ }
+
+ gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize));
+
+EXIT_FREE_INITRD:
+ if (InitrdDevicePath) {
+ gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));
+ }
+
+EXIT_FREE_LINUX:
+ gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S
new file mode 100644
index 0000000..525c128
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/AArch64/BdsLinuxLoaderHelper.S
@@ -0,0 +1,58 @@
+//
+// 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.
+//
+//
+
+
+/* Secondary core pens for AArch64 Linux booting.
+
+ This code it placed in Linux kernel memory and marked reserved. UEFI ensures
+ that the secondary cores get to this pen and the kernel can then start the
+ cores from here.
+ NOTE: This code must be self-contained.
+*/
+
+#include <Library/ArmLib.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(SecondariesPenStart)
+ASM_GLOBAL SecondariesPenEnd
+
+ASM_PFX(SecondariesPenStart):
+ // Registers x0-x3 are reserved for future use and should be set to zero.
+ mov x0, xzr
+ mov x1, xzr
+ mov x2, xzr
+ mov x3, xzr
+
+ // Get core position. Taken from ArmPlatformGetCorePosition().
+ // Assumes max 4 cores per cluster.
+ mrs x4, mpidr_el1 // Get MPCore register.
+ and x5, x4, #ARM_CORE_MASK // Get core number.
+ and x4, x4, #ARM_CLUSTER_MASK // Get cluster number.
+ add x4, x5, x4, LSR #6 // Add scaled cluster number to core number.
+ lsl x4, x4, 3 // Get mailbox offset for this core.
+ ldr x5, AsmMailboxbase // Get mailbox addr relative to pc (36 bytes ahead).
+ add x4, x4, x5 // Add core mailbox offset to base of mailbox.
+1: ldr x5, [x4] // Load value from mailbox.
+ cmp xzr, x5 // Has the mailbox been set?
+ b.ne 2f // If so break out of loop.
+ wfe // If not, wait a bit.
+ b 1b // Wait over, check if mailbox set again.
+2: br x5 // Jump to mailbox value.
+
+.align 3 // Make sure the variable below is 8 byte aligned.
+ .global AsmMailboxbase
+AsmMailboxbase: .xword 0xdeaddeadbeefbeef
+
+SecondariesPenEnd:
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c
new file mode 100644
index 0000000..33c2798
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c
@@ -0,0 +1,173 @@
+/** @file
+*
+* Copyright (c) 2011-2012, 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 "BdsLinuxLoader.h"
+
+// Point to the current ATAG
+STATIC LINUX_ATAG *mLinuxKernelCurrentAtag;
+
+STATIC
+VOID
+SetupCoreTag (
+ IN UINT32 PageSize
+ )
+{
+ mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_CORE);
+ mLinuxKernelCurrentAtag->header.type = ATAG_CORE;
+
+ mLinuxKernelCurrentAtag->body.core_tag.flags = 1; /* ensure read-only */
+ mLinuxKernelCurrentAtag->body.core_tag.pagesize = PageSize; /* systems PageSize (4k) */
+ mLinuxKernelCurrentAtag->body.core_tag.rootdev = 0; /* zero root device (typically overridden from kernel command line )*/
+
+ // move pointer to next tag
+ mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
+}
+
+STATIC
+VOID
+SetupMemTag (
+ IN UINTN StartAddress,
+ IN UINT32 Size
+ )
+{
+ mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_MEM);
+ mLinuxKernelCurrentAtag->header.type = ATAG_MEM;
+
+ mLinuxKernelCurrentAtag->body.mem_tag.start = StartAddress; /* Start of memory chunk for AtagMem */
+ mLinuxKernelCurrentAtag->body.mem_tag.size = Size; /* Size of memory chunk for AtagMem */
+
+ // move pointer to next tag
+ mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
+}
+
+STATIC
+VOID
+SetupCmdlineTag (
+ IN CONST CHAR8 *CmdLine
+ )
+{
+ UINT32 LineLength;
+
+ // Increment the line length by 1 to account for the null string terminator character
+ LineLength = AsciiStrLen(CmdLine) + 1;
+
+ /* Check for NULL strings.
+ * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.
+ * Remember, you have at least one null string terminator character.
+ */
+ if(LineLength > 1) {
+ mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof(LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2;
+ mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE;
+
+ /* place CommandLine into tag */
+ AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine);
+
+ // move pointer to next tag
+ mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
+ }
+}
+
+STATIC
+VOID
+SetupInitrdTag (
+ IN UINT32 InitrdImage,
+ IN UINT32 InitrdImageSize
+ )
+{
+ mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_INITRD2);
+ mLinuxKernelCurrentAtag->header.type = ATAG_INITRD2;
+
+ mLinuxKernelCurrentAtag->body.initrd2_tag.start = InitrdImage;
+ mLinuxKernelCurrentAtag->body.initrd2_tag.size = InitrdImageSize;
+
+ // Move pointer to next tag
+ mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
+}
+STATIC
+VOID
+SetupEndTag (
+ VOID
+ )
+{
+ // Empty tag ends list; this has zero length and no body
+ mLinuxKernelCurrentAtag->header.type = ATAG_NONE;
+ mLinuxKernelCurrentAtag->header.size = 0;
+
+ /* We can not calculate the next address by using the standard macro:
+ * Params = next_tag_address(Params);
+ * because it relies on the header.size, which here it is 0 (zero).
+ * The easiest way is to add the sizeof(mLinuxKernelCurrentAtag->header).
+ */
+ mLinuxKernelCurrentAtag = (LINUX_ATAG*)((UINT32)mLinuxKernelCurrentAtag + sizeof(mLinuxKernelCurrentAtag->header));
+}
+
+EFI_STATUS
+PrepareAtagList (
+ IN CONST CHAR8* CommandLineString,
+ IN EFI_PHYSICAL_ADDRESS InitrdImage,
+ IN UINTN InitrdImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *AtagBase,
+ OUT UINT32 *AtagSize
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *ResourceLink;
+ LIST_ENTRY ResourceList;
+ EFI_PHYSICAL_ADDRESS AtagStartAddress;
+ BDS_SYSTEM_MEMORY_RESOURCE *Resource;
+
+ AtagStartAddress = LINUX_ATAG_MAX_OFFSET;
+ Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_WARN, "Warning: Failed to allocate Atag at 0x%lX (%r). The Atag will be allocated somewhere else in System Memory.\n", AtagStartAddress, Status));
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ // Ready to setup the atag list
+ mLinuxKernelCurrentAtag = (LINUX_ATAG*)(UINTN)AtagStartAddress;
+
+ // Standard core tag 4k PageSize
+ SetupCoreTag( (UINT32)SIZE_4KB );
+
+ // Physical memory setup
+ GetSystemMemoryResources (&ResourceList);
+ ResourceLink = ResourceList.ForwardLink;
+ while (ResourceLink != NULL && ResourceLink != &ResourceList) {
+ Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceLink;
+ DEBUG((EFI_D_INFO,"- [0x%08X,0x%08X]\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->PhysicalStart+(UINT32)Resource->ResourceLength));
+ SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength );
+ ResourceLink = ResourceLink->ForwardLink;
+ }
+
+ // CommandLine setting root device
+ if (CommandLineString) {
+ SetupCmdlineTag (CommandLineString);
+ }
+
+ if (InitrdImageSize > 0 && InitrdImage != 0) {
+ SetupInitrdTag ((UINT32)InitrdImage, (UINT32)InitrdImageSize);
+ }
+
+ // End of tags
+ SetupEndTag();
+
+ // Calculate atag list size
+ *AtagBase = AtagStartAddress;
+ *AtagSize = (UINT32)mLinuxKernelCurrentAtag - (UINT32)AtagStartAddress + 1;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c
new file mode 100644
index 0000000..42f301d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c
@@ -0,0 +1,315 @@
+/** @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 "BdsLinuxLoader.h"
+
+#define ALIGN32_BELOW(addr) ALIGN_POINTER(addr - 32,32)
+
+#define IS_ADDRESS_IN_REGION(RegionStart, RegionSize, Address) \
+ (((UINTN)(RegionStart) <= (UINTN)(Address)) && ((UINTN)(Address) <= ((UINTN)(RegionStart) + (UINTN)(RegionSize))))
+
+STATIC
+EFI_STATUS
+PreparePlatformHardware (
+ VOID
+ )
+{
+ //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.
+
+ // Clean before Disable else the Stack gets corrupted with old data.
+ ArmCleanDataCache ();
+ ArmDisableDataCache ();
+ // Invalidate all the entries that might have snuck in.
+ ArmInvalidateDataCache ();
+
+ // Invalidate and disable the Instruction cache
+ ArmDisableInstructionCache ();
+ ArmInvalidateInstructionCache ();
+
+ // Turn off MMU
+ ArmDisableMmu();
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+StartLinux (
+ IN EFI_PHYSICAL_ADDRESS LinuxImage,
+ IN UINTN LinuxImageSize,
+ IN EFI_PHYSICAL_ADDRESS KernelParamsAddress,
+ IN UINTN KernelParamsSize,
+ IN UINT32 MachineType
+ )
+{
+ EFI_STATUS Status;
+ LINUX_KERNEL LinuxKernel;
+
+ // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on
+ // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.
+ Status = ShutdownUefiBootServices ();
+ if(EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
+ goto Exit;
+ }
+
+ // Move the kernel parameters to any address inside the first 1MB.
+ // This is necessary because the ARM Linux kernel requires
+ // the FTD / ATAG List to reside entirely inside the first 1MB of
+ // physical memory.
+ //Note: There is no requirement on the alignment
+ if (MachineType != ARM_FDT_MACHINE_TYPE) {
+ if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) {
+ KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);
+ }
+ } else {
+ if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) {
+ KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);
+ }
+ }
+
+ if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) {
+ //Note: There is no requirement on the alignment
+ LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize);
+ } else {
+ LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;
+ }
+
+ // Check if the Linux Image is a uImage
+ if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {
+ // Assume the Image Entry Point is just after the uImage header (64-byte size)
+ LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64);
+ LinuxImageSize -= 64;
+ }
+
+ // Check there is no overlapping between kernel and its parameters
+ // We can only assert because it is too late to fallback to UEFI (ExitBootServices has been called).
+ ASSERT (!IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress) &&
+ !IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress + KernelParamsSize));
+
+ //
+ // Switch off interrupts, caches, mmu, etc
+ //
+ Status = PreparePlatformHardware ();
+ ASSERT_EFI_ERROR(Status);
+
+ // Register and print out performance information
+ PERF_END (NULL, "BDS", NULL, 0);
+ if (PerformanceMeasurementEnabled ()) {
+ PrintPerformance ();
+ }
+
+ //
+ // Start the Linux Kernel
+ //
+
+ // Outside BootServices, so can't use Print();
+ DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));
+
+ // Jump to kernel with register set
+ LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);
+
+ // Kernel should never exit
+ // After Life services are not provided
+ ASSERT(FALSE);
+
+Exit:
+ // Only be here if we fail to start Linux
+ Print (L"ERROR : Can not start the kernel. Status=0x%X\n", Status);
+
+ // Free Runtimee Memory (kernel and FDT)
+ return Status;
+}
+
+/**
+ Start a Linux kernel from a Device Path
+
+ @param LinuxKernel Device Path to the Linux Kernel
+ @param Parameters Linux kernel arguments
+ @param Fdt Device Path to the Flat Device Tree
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsBootLinuxAtag (
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
+ IN CONST CHAR8* CommandLineArguments
+ )
+{
+ EFI_STATUS Status;
+ UINT32 LinuxImageSize;
+ UINT32 InitrdImageBaseSize = 0;
+ UINT32 InitrdImageSize = 0;
+ UINT32 AtagSize;
+ EFI_PHYSICAL_ADDRESS AtagBase;
+ EFI_PHYSICAL_ADDRESS LinuxImage;
+ EFI_PHYSICAL_ADDRESS InitrdImageBase = 0;
+ EFI_PHYSICAL_ADDRESS InitrdImage = 0;
+
+ PERF_START (NULL, "BDS", NULL, 0);
+
+ // Load the Linux kernel from a device path
+ LinuxImage = LINUX_KERNEL_MAX_OFFSET;
+ Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find Linux kernel.\n");
+ return Status;
+ }
+
+ if (InitrdDevicePath) {
+ // Load the initrd near to the Linux kernel
+ InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;
+ Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);
+ }
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find initrd image.\n");
+ goto EXIT_FREE_LINUX;
+ }
+
+ // Check if the initrd is a uInitrd
+ if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {
+ // Skip the 64-byte image header
+ InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);
+ InitrdImageSize = InitrdImageBaseSize - 64;
+ } else {
+ InitrdImage = InitrdImageBase;
+ InitrdImageSize = InitrdImageBaseSize;
+ }
+ }
+
+ //
+ // Setup the Linux Kernel Parameters
+ //
+
+ // By setting address=0 we leave the memory allocation to the function
+ Status = PrepareAtagList (CommandLineArguments, InitrdImage, InitrdImageSize, &AtagBase, &AtagSize);
+ if (EFI_ERROR(Status)) {
+ Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);
+ goto EXIT_FREE_INITRD;
+ }
+
+ return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));
+
+EXIT_FREE_INITRD:
+ if (InitrdDevicePath) {
+ gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));
+ }
+
+EXIT_FREE_LINUX:
+ gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));
+
+ return Status;
+}
+
+/**
+ Start a Linux kernel from a Device Path
+
+ @param LinuxKernel Device Path to the Linux Kernel
+ @param Parameters Linux kernel arguments
+ @param Fdt Device Path to the Flat Device Tree
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsBootLinuxFdt (
+ IN EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
+ IN CONST CHAR8* CommandLineArguments,
+ IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINT32 LinuxImageSize;
+ UINT32 InitrdImageBaseSize = 0;
+ UINT32 InitrdImageSize = 0;
+ UINT32 FdtBlobSize;
+ EFI_PHYSICAL_ADDRESS FdtBlobBase;
+ EFI_PHYSICAL_ADDRESS LinuxImage;
+ EFI_PHYSICAL_ADDRESS InitrdImageBase = 0;
+ EFI_PHYSICAL_ADDRESS InitrdImage = 0;
+
+ PERF_START (NULL, "BDS", NULL, 0);
+
+ // Load the Linux kernel from a device path
+ LinuxImage = LINUX_KERNEL_MAX_OFFSET;
+ Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find Linux kernel.\n");
+ return Status;
+ }
+
+ if (InitrdDevicePath) {
+ InitrdImageBase = LINUX_KERNEL_MAX_OFFSET;
+ Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImageBase, &InitrdImageBaseSize);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImageBase, &InitrdImageBaseSize);
+ }
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find initrd image.\n");
+ goto EXIT_FREE_LINUX;
+ }
+
+ // Check if the initrd is a uInitrd
+ if (*(UINT32*)((UINTN)InitrdImageBase) == LINUX_UIMAGE_SIGNATURE) {
+ // Skip the 64-byte image header
+ InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImageBase + 64);
+ InitrdImageSize = InitrdImageBaseSize - 64;
+ } else {
+ InitrdImage = InitrdImageBase;
+ InitrdImageSize = InitrdImageBaseSize;
+ }
+ }
+
+ // Load the FDT binary from a device path. The FDT will be reloaded later to a more appropriate location for the Linux kernel.
+ FdtBlobBase = 0;
+ Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);
+ if (EFI_ERROR(Status)) {
+ Print (L"ERROR: Did not find Device Tree blob.\n");
+ goto EXIT_FREE_INITRD;
+ }
+
+ // Update the Fdt with the Initrd information. The FDT will increase in size.
+ // By setting address=0 we leave the memory allocation to the function
+ Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);
+ if (EFI_ERROR(Status)) {
+ Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status);
+ goto EXIT_FREE_FDT;
+ }
+
+ return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);
+
+EXIT_FREE_FDT:
+ gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (FdtBlobSize));
+
+EXIT_FREE_INITRD:
+ if (InitrdDevicePath) {
+ gBS->FreePages (InitrdImageBase, EFI_SIZE_TO_PAGES (InitrdImageBaseSize));
+ }
+
+EXIT_FREE_LINUX:
+ gBS->FreePages (LinuxImage, EFI_SIZE_TO_PAGES (LinuxImageSize));
+
+ return Status;
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsAppLoader.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsAppLoader.c
new file mode 100644
index 0000000..2b88bf1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsAppLoader.c
@@ -0,0 +1,144 @@
+/** @file
+*
+* Copyright (c) 2011-2012, 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/DxeServicesLib.h>
+
+STATIC
+EFI_STATUS
+BdsLoadFileFromFirmwareVolume (
+ IN EFI_HANDLE FvHandle,
+ IN CHAR16 *FilePath,
+ IN EFI_FV_FILETYPE FileTypeFilter,
+ OUT EFI_DEVICE_PATH **EfiAppDevicePath
+ )
+{
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+ VOID *Key;
+ EFI_STATUS Status, FileStatus;
+ EFI_GUID NameGuid;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN Size;
+ UINTN UiStringLen;
+ CHAR16 *UiSection;
+ UINT32 Authentication;
+ EFI_DEVICE_PATH *FvDevicePath;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
+
+ Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Length of FilePath
+ UiStringLen = StrLen (FilePath);
+
+ // Allocate Key
+ Key = AllocatePool (FvProtocol->KeySize);
+ ASSERT (Key != NULL);
+ ZeroMem (Key, FvProtocol->KeySize);
+
+ do {
+ // Search in all files
+ FileType = FileTypeFilter;
+
+ Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
+ if (!EFI_ERROR (Status)) {
+ UiSection = NULL;
+ FileStatus = FvProtocol->ReadSection (
+ FvProtocol,
+ &NameGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **)&UiSection,
+ &Size,
+ &Authentication
+ );
+ if (!EFI_ERROR (FileStatus)) {
+ if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
+ //
+ // We found a UiString match.
+ //
+ Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
+
+ // Generate the Device Path for the file
+ //DevicePath = DuplicateDevicePath(FvDevicePath);
+ EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
+ *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
+
+ FreePool (Key);
+ FreePool (UiSection);
+ return FileStatus;
+ }
+ FreePool (UiSection);
+ }
+ }
+ } while (!EFI_ERROR (Status));
+
+ FreePool(Key);
+ return Status;
+}
+
+/**
+ Start an EFI Application from any Firmware Volume
+
+ @param EfiApp EFI Application Name
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsLoadApplication (
+ IN EFI_HANDLE ParentImageHandle,
+ IN CHAR16* EfiApp,
+ IN UINTN LoadOptionsSize,
+ IN VOID* LoadOptions
+ )
+{
+ EFI_STATUS Status;
+ UINTN NoHandles, HandleIndex;
+ EFI_HANDLE *Handles;
+ EFI_DEVICE_PATH *EfiAppDevicePath;
+
+ // Need to connect every drivers to ensure no dependencies are missing for the application
+ Status = BdsConnectAllDrivers();
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
+ return Status;
+ }
+
+ // Search the application in any Firmware Volume
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
+ if (EFI_ERROR (Status) || (NoHandles == 0)) {
+ DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
+ return Status;
+ }
+
+ // Search in all Firmware Volume for the EFI Application
+ for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
+ EfiAppDevicePath = NULL;
+ Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);
+ if (!EFI_ERROR (Status)) {
+ // Start the application
+ Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);
+ return Status;
+ }
+ }
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsFilePath.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsFilePath.c
new file mode 100644
index 0000000..924c61e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsFilePath.c
@@ -0,0 +1,1418 @@
+/** @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/Bds.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/Dhcp4.h>
+#include <Protocol/Mtftp4.h>
+
+
+#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
+
+/* Type and defines to set up the DHCP4 options */
+
+typedef struct {
+ EFI_DHCP4_PACKET_OPTION Head;
+ UINT8 Route;
+} DHCP4_OPTION;
+
+#define DHCP_TAG_PARA_LIST 55
+#define DHCP_TAG_NETMASK 1
+#define DHCP_TAG_ROUTER 3
+
+/*
+ Constant strings and define related to the message indicating the amount of
+ progress in the dowloading of a TFTP file.
+*/
+
+// Frame for the progression slider
+STATIC CONST CHAR16 mTftpProgressFrame[] = L"[ ]";
+
+// Number of steps in the progression slider
+#define TFTP_PROGRESS_SLIDER_STEPS ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3)
+
+// Size in number of characters plus one (final zero) of the message to
+// indicate the progress of a tftp download. The format is "[(progress slider:
+// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There
+// are thus the number of characters in mTftpProgressFrame[] plus 11 characters
+// (2 // spaces, "Kb" and seven characters for the number of KBytes).
+#define TFTP_PROGRESS_MESSAGE_SIZE ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) + 12)
+
+// String to delete the tftp progress message to be able to update it :
+// (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'
+STATIC CONST CHAR16 mTftpProgressDelete[] = L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
+
+
+// Extract the FilePath from the Device Path
+CHAR16*
+BdsExtractFilePathFromDevicePath (
+ IN CONST CHAR16 *StrDevicePath,
+ IN UINTN NumberDevicePathNode
+ )
+{
+ UINTN Node;
+ CHAR16 *Str;
+
+ Str = (CHAR16*)StrDevicePath;
+ Node = 0;
+ while ((Str != NULL) && (*Str != L'\0') && (Node < NumberDevicePathNode)) {
+ if ((*Str == L'/') || (*Str == L'\\')) {
+ Node++;
+ }
+ Str++;
+ }
+
+ if (*Str == L'\0') {
+ return NULL;
+ } else {
+ return Str;
+ }
+}
+
+BOOLEAN
+BdsIsRemovableUsb (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ return ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
+ ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) ||
+ (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)));
+}
+
+EFI_STATUS
+BdsGetDeviceUsb (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** NewDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN UsbIoHandleCount;
+ EFI_HANDLE *UsbIoBuffer;
+ EFI_DEVICE_PATH* UsbIoDevicePath;
+ EFI_DEVICE_PATH* TmpDevicePath;
+ USB_WWID_DEVICE_PATH* WwidDevicePath1;
+ USB_WWID_DEVICE_PATH* WwidDevicePath2;
+ USB_CLASS_DEVICE_PATH* UsbClassDevicePath1;
+ USB_CLASS_DEVICE_PATH* UsbClassDevicePath2;
+
+ // Get all the UsbIo handles
+ UsbIoHandleCount = 0;
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);
+ if (EFI_ERROR (Status) || (UsbIoHandleCount == 0)) {
+ return Status;
+ }
+
+ // Check if one of the handles matches the USB description
+ for (Index = 0; Index < UsbIoHandleCount; Index++) {
+ Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &UsbIoDevicePath);
+ if (!EFI_ERROR (Status)) {
+ TmpDevicePath = UsbIoDevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ // Check if the Device Path node is a USB Removable device Path node
+ if (BdsIsRemovableUsb (TmpDevicePath)) {
+ if (TmpDevicePath->SubType == MSG_USB_WWID_DP) {
+ WwidDevicePath1 = (USB_WWID_DEVICE_PATH*)RemovableDevicePath;
+ WwidDevicePath2 = (USB_WWID_DEVICE_PATH*)TmpDevicePath;
+ if ((WwidDevicePath1->VendorId == WwidDevicePath2->VendorId) &&
+ (WwidDevicePath1->ProductId == WwidDevicePath2->ProductId) &&
+ (CompareMem (WwidDevicePath1+1, WwidDevicePath2+1, DevicePathNodeLength(WwidDevicePath1)-sizeof (USB_WWID_DEVICE_PATH)) == 0))
+ {
+ *DeviceHandle = UsbIoBuffer[Index];
+ // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
+ *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));
+ return EFI_SUCCESS;
+ }
+ } else {
+ UsbClassDevicePath1 = (USB_CLASS_DEVICE_PATH*)RemovableDevicePath;
+ UsbClassDevicePath2 = (USB_CLASS_DEVICE_PATH*)TmpDevicePath;
+ if ((UsbClassDevicePath1->VendorId != 0xFFFF) && (UsbClassDevicePath1->VendorId == UsbClassDevicePath2->VendorId) &&
+ (UsbClassDevicePath1->ProductId != 0xFFFF) && (UsbClassDevicePath1->ProductId == UsbClassDevicePath2->ProductId) &&
+ (UsbClassDevicePath1->DeviceClass != 0xFF) && (UsbClassDevicePath1->DeviceClass == UsbClassDevicePath2->DeviceClass) &&
+ (UsbClassDevicePath1->DeviceSubClass != 0xFF) && (UsbClassDevicePath1->DeviceSubClass == UsbClassDevicePath2->DeviceSubClass) &&
+ (UsbClassDevicePath1->DeviceProtocol != 0xFF) && (UsbClassDevicePath1->DeviceProtocol == UsbClassDevicePath2->DeviceProtocol))
+ {
+ *DeviceHandle = UsbIoBuffer[Index];
+ // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
+ *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+BOOLEAN
+BdsIsRemovableHd (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP);
+}
+
+EFI_STATUS
+BdsGetDeviceHd (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** NewDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN PartitionHandleCount;
+ EFI_HANDLE *PartitionBuffer;
+ EFI_DEVICE_PATH* PartitionDevicePath;
+ EFI_DEVICE_PATH* TmpDevicePath;
+ HARDDRIVE_DEVICE_PATH* HardDriveDevicePath1;
+ HARDDRIVE_DEVICE_PATH* HardDriveDevicePath2;
+
+ // Get all the DiskIo handles
+ PartitionHandleCount = 0;
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &PartitionHandleCount, &PartitionBuffer);
+ if (EFI_ERROR (Status) || (PartitionHandleCount == 0)) {
+ return Status;
+ }
+
+ // Check if one of the handles matches the Hard Disk Description
+ for (Index = 0; Index < PartitionHandleCount; Index++) {
+ Status = gBS->HandleProtocol (PartitionBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &PartitionDevicePath);
+ if (!EFI_ERROR (Status)) {
+ TmpDevicePath = PartitionDevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ // Check if the Device Path node is a HD Removable device Path node
+ if (BdsIsRemovableHd (TmpDevicePath)) {
+ HardDriveDevicePath1 = (HARDDRIVE_DEVICE_PATH*)RemovableDevicePath;
+ HardDriveDevicePath2 = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;
+ if ((HardDriveDevicePath1->SignatureType == HardDriveDevicePath2->SignatureType) &&
+ (CompareGuid ((EFI_GUID *)HardDriveDevicePath1->Signature, (EFI_GUID *)HardDriveDevicePath2->Signature) == TRUE) &&
+ (HardDriveDevicePath1->PartitionNumber == HardDriveDevicePath2->PartitionNumber))
+ {
+ *DeviceHandle = PartitionBuffer[Index];
+ // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
+ *NewDevicePath = AppendDevicePath (PartitionDevicePath, NextDevicePathNode (RemovableDevicePath));
+ return EFI_SUCCESS;
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/*BOOLEAN
+BdsIsRemovableCdrom (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_CDROM_DP);
+}
+
+EFI_STATUS
+BdsGetDeviceCdrom (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** DevicePath
+ )
+{
+ ASSERT(0);
+ return EFI_UNSUPPORTED;
+}*/
+
+typedef BOOLEAN
+(*BDS_IS_REMOVABLE) (
+ IN EFI_DEVICE_PATH* DevicePath
+ );
+
+typedef EFI_STATUS
+(*BDS_GET_DEVICE) (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** DevicePath
+ );
+
+typedef struct {
+ BDS_IS_REMOVABLE IsRemovable;
+ BDS_GET_DEVICE GetDevice;
+} BDS_REMOVABLE_DEVICE_SUPPORT;
+
+BDS_REMOVABLE_DEVICE_SUPPORT RemovableDeviceSupport[] = {
+ { BdsIsRemovableUsb, BdsGetDeviceUsb },
+ { BdsIsRemovableHd, BdsGetDeviceHd },
+ //{ BdsIsRemovableCdrom, BdsGetDeviceCdrom }
+};
+
+STATIC
+BOOLEAN
+IsRemovableDevice (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ UINTN Index;
+ EFI_DEVICE_PATH* TmpDevicePath;
+
+ TmpDevicePath = DevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {
+ if (RemovableDeviceSupport[Index].IsRemovable (TmpDevicePath)) {
+ return TRUE;
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ return FALSE;
+}
+
+STATIC
+EFI_STATUS
+TryRemovableDevice (
+ IN EFI_DEVICE_PATH* DevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** NewDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_DEVICE_PATH* TmpDevicePath;
+ BDS_REMOVABLE_DEVICE_SUPPORT* RemovableDevice;
+ EFI_DEVICE_PATH* RemovableDevicePath;
+ BOOLEAN RemovableFound;
+
+ RemovableDevice = NULL;
+ RemovableDevicePath = NULL;
+ RemovableFound = FALSE;
+ TmpDevicePath = DevicePath;
+
+ while (!IsDevicePathEnd (TmpDevicePath) && !RemovableFound) {
+ for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {
+ RemovableDevice = &RemovableDeviceSupport[Index];
+ if (RemovableDevice->IsRemovable (TmpDevicePath)) {
+ RemovableDevicePath = TmpDevicePath;
+ RemovableFound = TRUE;
+ break;
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ if (!RemovableFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ // Search into the current started drivers
+ Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);
+ if (Status == EFI_NOT_FOUND) {
+ // Connect all the drivers
+ BdsConnectAllDrivers ();
+
+ // Search again into all the drivers
+ Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);
+ }
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+BdsConnectAndUpdateDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ )
+{
+ EFI_DEVICE_PATH* Remaining;
+ EFI_DEVICE_PATH* NewDevicePath;
+ EFI_STATUS Status;
+ EFI_HANDLE PreviousHandle;
+
+ if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PreviousHandle = NULL;
+ do {
+ Remaining = *DevicePath;
+
+ // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
+ // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
+ // to point to the remaining part of the device path
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
+
+ if (!EFI_ERROR (Status)) {
+ if (*Handle == PreviousHandle) {
+ //
+ // If no forward progress is made try invoking the Dispatcher.
+ // A new FV may have been added to the system and new drivers
+ // may now be found.
+ // Status == EFI_SUCCESS means a driver was dispatched
+ // Status == EFI_NOT_FOUND means no new drivers were dispatched
+ //
+ Status = gDS->Dispatch ();
+ }
+
+ if (!EFI_ERROR (Status)) {
+ PreviousHandle = *Handle;
+
+ // Recursive = FALSE: We do not want to start the whole device tree
+ Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
+ }
+ }
+ } while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));
+
+ if (!EFI_ERROR (Status)) {
+ // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
+ // Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
+ Remaining = *DevicePath;
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
+ if (EFI_ERROR (Status)) {
+ // If the last node is a Memory Map Device Path just return EFI_SUCCESS.
+ if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
+ Status = EFI_SUCCESS;
+ }
+ }
+ }
+ } else if (!IsDevicePathEnd (Remaining) && !IsRemovableDevice (Remaining)) {
+
+ /*// If the remaining Device Path is a FilePath or MemoryMap then we consider the Device Path has been loaded correctly
+ if ((Remaining->Type == MEDIA_DEVICE_PATH) && (Remaining->SubType == MEDIA_FILEPATH_DP)) {
+ Status = EFI_SUCCESS;
+ } else if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
+ Status = EFI_SUCCESS;
+ }*/
+
+ //TODO: Should we just return success and leave the caller decide if it is the expected RemainingPath
+ Status = EFI_SUCCESS;
+ } else {
+ Status = TryRemovableDevice (*DevicePath, Handle, &NewDevicePath);
+ if (!EFI_ERROR (Status)) {
+ Status = BdsConnectAndUpdateDevicePath (&NewDevicePath, Handle, RemainingDevicePath);
+ *DevicePath = NewDevicePath;
+ return Status;
+ }
+ }
+
+ if (RemainingDevicePath) {
+ *RemainingDevicePath = Remaining;
+ }
+
+ return Status;
+}
+
+/**
+ Connect a Device Path and return the handle of the driver that support this DevicePath
+
+ @param DevicePath Device Path of the File to connect
+ @param Handle Handle of the driver that support this DevicePath
+ @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath
+
+ @retval EFI_SUCCESS A driver that matches the Device Path has been found
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
+
+**/
+EFI_STATUS
+BdsConnectDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ )
+{
+ return BdsConnectAndUpdateDevicePath (&DevicePath, Handle, RemainingDevicePath);
+}
+
+BOOLEAN
+BdsFileSystemSupport (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;
+
+ Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FsProtocol);
+
+ return (!EFI_ERROR (Status) && IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP));
+}
+
+EFI_STATUS
+BdsFileSystemLoadImage (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS *Image,
+ OUT UINTN *ImageSize
+ )
+{
+ EFI_STATUS Status;
+ FILEPATH_DEVICE_PATH *FilePathDevicePath;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;
+ EFI_FILE_PROTOCOL *Fs;
+ EFI_FILE_INFO *FileInfo;
+ EFI_FILE_PROTOCOL *File;
+ UINTN Size;
+
+ ASSERT (IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP));
+
+ FilePathDevicePath = (FILEPATH_DEVICE_PATH*)RemainingDevicePath;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID**)&FsProtocol,
+ gImageHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Try to Open the volume and get root directory
+ Status = FsProtocol->OpenVolume (FsProtocol, &Fs);
+ if (EFI_ERROR (Status)) {
+ goto CLOSE_PROTOCOL;
+ }
+
+ Status = Fs->Open (Fs, &File, FilePathDevicePath->PathName, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ goto CLOSE_PROTOCOL;
+ }
+
+ Size = 0;
+ File->GetInfo (File, &gEfiFileInfoGuid, &Size, NULL);
+ FileInfo = AllocatePool (Size);
+ Status = File->GetInfo (File, &gEfiFileInfoGuid, &Size, FileInfo);
+ if (EFI_ERROR (Status)) {
+ goto CLOSE_FILE;
+ }
+
+ // Get the file size
+ Size = FileInfo->FileSize;
+ if (ImageSize) {
+ *ImageSize = Size;
+ }
+ FreePool (FileInfo);
+
+ Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);
+ // Try to allocate in any pages if failed to allocate memory at the defined location
+ if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);
+ }
+ if (!EFI_ERROR (Status)) {
+ Status = File->Read (File, &Size, (VOID*)(UINTN)(*Image));
+ }
+
+CLOSE_FILE:
+ File->Close (File);
+
+CLOSE_PROTOCOL:
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ gImageHandle,
+ Handle);
+
+ return Status;
+}
+
+BOOLEAN
+BdsMemoryMapSupport (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath
+ )
+{
+ return IS_DEVICE_PATH_NODE (DevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP) ||
+ IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP);
+}
+
+EFI_STATUS
+BdsMemoryMapLoadImage (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *ImageSize
+ )
+{
+ EFI_STATUS Status;
+ MEMMAP_DEVICE_PATH* MemMapPathDevicePath;
+ UINTN Size;
+
+ if (IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP)) {
+ MemMapPathDevicePath = (MEMMAP_DEVICE_PATH*)RemainingDevicePath;
+ } else {
+ ASSERT (IS_DEVICE_PATH_NODE (DevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP));
+ MemMapPathDevicePath = (MEMMAP_DEVICE_PATH*)DevicePath;
+ }
+
+ Size = MemMapPathDevicePath->EndingAddress - MemMapPathDevicePath->StartingAddress;
+ if (Size == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);
+ // Try to allocate in any pages if failed to allocate memory at the defined location
+ if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(Size), Image);
+ }
+ if (!EFI_ERROR (Status)) {
+ CopyMem ((VOID*)(UINTN)(*Image), (CONST VOID*)(UINTN)MemMapPathDevicePath->StartingAddress, Size);
+
+ if (ImageSize != NULL) {
+ *ImageSize = Size;
+ }
+ }
+
+ return Status;
+}
+
+BOOLEAN
+BdsFirmwareVolumeSupport (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath
+ )
+{
+ return IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP);
+}
+
+EFI_STATUS
+BdsFirmwareVolumeLoadImage (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *ImageSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+ EFI_GUID *FvNameGuid;
+ EFI_SECTION_TYPE SectionType;
+ EFI_FV_FILETYPE FvType;
+ EFI_FV_FILE_ATTRIBUTES Attrib;
+ UINT32 AuthenticationStatus;
+ VOID* ImageBuffer;
+
+ ASSERT (IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP));
+
+ Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FwVol);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)RemainingDevicePath);
+ if (FvNameGuid == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ SectionType = EFI_SECTION_PE32;
+ AuthenticationStatus = 0;
+ //Note: ReadSection at the opposite of ReadFile does not allow to pass ImageBuffer == NULL to get the size of the file.
+ ImageBuffer = NULL;
+ Status = FwVol->ReadSection (
+ FwVol,
+ FvNameGuid,
+ SectionType,
+ 0,
+ &ImageBuffer,
+ ImageSize,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+#if 0
+ // In case the buffer has some address requirements, we must copy the buffer to a buffer following the requirements
+ if (Type != AllocateAnyPages) {
+ Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize),Image);
+ if (!EFI_ERROR (Status)) {
+ CopyMem ((VOID*)(UINTN)(*Image), ImageBuffer, *ImageSize);
+ FreePool (ImageBuffer);
+ }
+ }
+#else
+ // We must copy the buffer into a page allocations. Otherwise, the caller could call gBS->FreePages() on the pool allocation
+ Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);
+ // Try to allocate in any pages if failed to allocate memory at the defined location
+ if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);
+ }
+ if (!EFI_ERROR (Status)) {
+ CopyMem ((VOID*)(UINTN)(*Image), ImageBuffer, *ImageSize);
+ FreePool (ImageBuffer);
+ }
+#endif
+ } else {
+ // Try a raw file, since a PE32 SECTION does not exist
+ Status = FwVol->ReadFile (
+ FwVol,
+ FvNameGuid,
+ NULL,
+ ImageSize,
+ &FvType,
+ &Attrib,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);
+ // Try to allocate in any pages if failed to allocate memory at the defined location
+ if ((Status == EFI_OUT_OF_RESOURCES) && (Type != AllocateAnyPages)) {
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesCode, EFI_SIZE_TO_PAGES(*ImageSize), Image);
+ }
+ if (!EFI_ERROR (Status)) {
+ Status = FwVol->ReadFile (
+ FwVol,
+ FvNameGuid,
+ (VOID*)(UINTN)(*Image),
+ ImageSize,
+ &FvType,
+ &Attrib,
+ &AuthenticationStatus
+ );
+ }
+ }
+ }
+ return Status;
+}
+
+BOOLEAN
+BdsPxeSupport (
+ IN EFI_DEVICE_PATH* DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH* RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PXE_BASE_CODE_PROTOCOL* PxeBcProtocol;
+
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ return FALSE;
+ }
+
+ Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+EFI_STATUS
+BdsPxeLoadImage (
+ IN EFI_DEVICE_PATH* DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH* RemainingDevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS *Image,
+ OUT UINTN *ImageSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOAD_FILE_PROTOCOL *LoadFileProtocol;
+ UINTN BufferSize;
+ EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
+
+ // Get Load File Protocol attached to the PXE protocol
+ Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFileProtocol);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = LoadFileProtocol->LoadFile (LoadFileProtocol, DevicePath, TRUE, &BufferSize, NULL);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Status = gBS->AllocatePages (Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES(BufferSize), Image);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = LoadFileProtocol->LoadFile (LoadFileProtocol, DevicePath, TRUE, &BufferSize, (VOID*)(UINTN)(*Image));
+ if (!EFI_ERROR (Status) && (ImageSize != NULL)) {
+ *ImageSize = BufferSize;
+ }
+ }
+
+ if (Status == EFI_ALREADY_STARTED) {
+ Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
+ if (!EFI_ERROR(Status)) {
+ // If PXE is already started, we stop it
+ Pxe->Stop (Pxe);
+ // And we try again
+ return BdsPxeLoadImage (DevicePath, Handle, RemainingDevicePath, Type, Image, ImageSize);
+ }
+ }
+ return Status;
+}
+
+BOOLEAN
+BdsTftpSupport (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH *NextDevicePath;
+ VOID *Interface;
+
+ // 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, &gEfiDevicePathProtocolGuid,
+ &Interface
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ //
+ // Check that the controller (identified by its handle "Handle") supports the
+ // MTFTPv4 Service Binding Protocol. If it does, it means that it supports the
+ // EFI MTFTPv4 Protocol needed to download the image through TFTP.
+ //
+ Status = gBS->HandleProtocol (
+ Handle, &gEfiMtftp4ServiceBindingProtocolGuid,
+ &Interface
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Worker function that get the size in numbers of bytes of a file from a TFTP
+ server before to download the file.
+
+ @param[in] Mtftp4 MTFTP4 protocol interface
+ @param[in] FilePath Path of the file, Ascii encoded
+ @param[out] FileSize Address where to store the file size in number of
+ bytes.
+
+ @retval EFI_SUCCESS The size of the file was returned.
+ @retval !EFI_SUCCESS The size of the file was not returned.
+
+**/
+STATIC
+EFI_STATUS
+Mtftp4GetFileSize (
+ IN EFI_MTFTP4_PROTOCOL *Mtftp4,
+ IN CHAR8 *FilePath,
+ OUT UINT64 *FileSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_MTFTP4_OPTION ReqOpt[1];
+ EFI_MTFTP4_PACKET *Packet;
+ UINT32 PktLen;
+ EFI_MTFTP4_OPTION *TableOfOptions;
+ EFI_MTFTP4_OPTION *Option;
+ UINT32 OptCnt;
+ UINT8 OptBuf[128];
+
+ ReqOpt[0].OptionStr = (UINT8*)"tsize";
+ OptBuf[0] = '0';
+ OptBuf[1] = 0;
+ ReqOpt[0].ValueStr = OptBuf;
+
+ Status = Mtftp4->GetInfo (
+ Mtftp4,
+ NULL,
+ (UINT8*)FilePath,
+ NULL,
+ 1,
+ ReqOpt,
+ &PktLen,
+ &Packet
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ Status = Mtftp4->ParseOptions (
+ Mtftp4,
+ PktLen,
+ Packet,
+ (UINT32 *) &OptCnt,
+ &TableOfOptions
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ Option = TableOfOptions;
+ while (OptCnt != 0) {
+ if (AsciiStrnCmp ((CHAR8 *)Option->OptionStr, "tsize", 5) == 0) {
+ *FileSize = AsciiStrDecimalToUint64 ((CHAR8 *)Option->ValueStr);
+ break;
+ }
+ OptCnt--;
+ Option++;
+ }
+ FreePool (TableOfOptions);
+
+ if (OptCnt == 0) {
+ Status = EFI_UNSUPPORTED;
+ }
+
+Error :
+
+ return Status;
+}
+
+/**
+ Update the progress of a file download
+ This procedure is called each time a new TFTP packet is received.
+
+ @param[in] This MTFTP4 protocol interface
+ @param[in] Token Parameters for the download of the file
+ @param[in] PacketLen Length of the packet
+ @param[in] Packet Address of the packet
+
+ @retval EFI_SUCCESS All packets are accepted.
+
+**/
+STATIC
+EFI_STATUS
+Mtftp4CheckPacket (
+ IN EFI_MTFTP4_PROTOCOL *This,
+ IN EFI_MTFTP4_TOKEN *Token,
+ IN UINT16 PacketLen,
+ IN EFI_MTFTP4_PACKET *Packet
+ )
+{
+ BDS_TFTP_CONTEXT *Context;
+ CHAR16 Progress[TFTP_PROGRESS_MESSAGE_SIZE];
+ UINT64 NbOfKb;
+ UINTN Index;
+ UINTN LastStep;
+ UINTN Step;
+ UINT64 LastNbOf50Kb;
+ UINT64 NbOf50Kb;
+
+ if ((NTOHS (Packet->OpCode)) == EFI_MTFTP4_OPCODE_DATA) {
+ Context = (BDS_TFTP_CONTEXT*)Token->Context;
+
+ if (Context->DownloadedNbOfBytes == 0) {
+ if (Context->FileSize > 0) {
+ Print (L"%s 0 Kb", mTftpProgressFrame);
+ } else {
+ Print (L" 0 Kb");
+ }
+ }
+
+ //
+ // The data is the packet are prepended with two UINT16 :
+ // . OpCode = EFI_MTFTP4_OPCODE_DATA
+ // . Block = the number of this block of data
+ //
+ Context->DownloadedNbOfBytes += PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block);
+ NbOfKb = Context->DownloadedNbOfBytes / 1024;
+
+ Progress[0] = L'\0';
+ if (Context->FileSize > 0) {
+ LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
+ Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
+ if (Step > LastStep) {
+ Print (mTftpProgressDelete);
+ StrCpy (Progress, mTftpProgressFrame);
+ for (Index = 1; Index < Step; Index++) {
+ Progress[Index] = L'=';
+ }
+ Progress[Step] = L'>';
+
+ UnicodeSPrint (
+ Progress + (sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 1,
+ sizeof (Progress) - sizeof (mTftpProgressFrame),
+ L" %7d Kb",
+ NbOfKb
+ );
+ Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes;
+ }
+ } else {
+ //
+ // Case when we do not know the size of the final file.
+ // We print the updated size every 50KB of downloaded data
+ //
+ LastNbOf50Kb = Context->LastReportedNbOfBytes / (50*1024);
+ NbOf50Kb = Context->DownloadedNbOfBytes / (50*1024);
+ if (NbOf50Kb > LastNbOf50Kb) {
+ Print (L"\b\b\b\b\b\b\b\b\b\b");
+ UnicodeSPrint (Progress, sizeof (Progress), L"%7d Kb", NbOfKb);
+ Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes;
+ }
+ }
+ if (Progress[0] != L'\0') {
+ Print (L"%s", Progress);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Download an image from a TFTP server
+
+ @param[in] DevicePath Device path of the TFTP boot option
+ @param[in] ControllerHandle Handle of the network controller
+ @param[in] RemainingDevicePath Device path of the TFTP boot option but
+ the first node that identifies the network controller
+ @param[in] Type Type to allocate memory pages
+ @param[out] Image Address of the bufer where the image is stored in
+ case of success
+ @param[out] ImageSize Size in number of bytes of the i;age in case of
+ success
+
+ @retval EFI_SUCCESS The image was returned.
+ @retval !EFI_SUCCESS Something went wrong.
+
+**/
+EFI_STATUS
+BdsTftpLoadImage (
+ IN EFI_DEVICE_PATH* DevicePath,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH* RemainingDevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS *Image,
+ OUT UINTN *ImageSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Dhcp4ChildHandle;
+ EFI_DHCP4_PROTOCOL *Dhcp4;
+ BOOLEAN Dhcp4ToStop;
+ EFI_HANDLE Mtftp4ChildHandle;
+ EFI_MTFTP4_PROTOCOL *Mtftp4;
+ DHCP4_OPTION ParaList;
+ EFI_DHCP4_PACKET_OPTION *OptionList[2];
+ EFI_DHCP4_CONFIG_DATA Dhcp4CfgData;
+ EFI_DHCP4_MODE_DATA Dhcp4Mode;
+ EFI_MTFTP4_CONFIG_DATA Mtftp4CfgData;
+ IPv4_DEVICE_PATH *IPv4DevicePathNode;
+ FILEPATH_DEVICE_PATH *FilePathDevicePathNode;
+ CHAR8 *AsciiFilePath;
+ EFI_MTFTP4_TOKEN Mtftp4Token;
+ UINT64 FileSize;
+ UINT64 TftpBufferSize;
+ BDS_TFTP_CONTEXT *TftpContext;
+
+ ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP));
+ IPv4DevicePathNode = (IPv4_DEVICE_PATH*)RemainingDevicePath;
+
+ Dhcp4ChildHandle = NULL;
+ Dhcp4 = NULL;
+ Dhcp4ToStop = FALSE;
+ Mtftp4ChildHandle = NULL;
+ Mtftp4 = NULL;
+ AsciiFilePath = NULL;
+ TftpContext = NULL;
+
+ if (!IPv4DevicePathNode->StaticIpAddress) {
+ //
+ // Using the DHCP4 Service Binding Protocol, create a child handle of the DHCP4 service and
+ // install the DHCP4 protocol on it. Then, open the DHCP protocol.
+ //
+ Status = NetLibCreateServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ &Dhcp4ChildHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->OpenProtocol (
+ Dhcp4ChildHandle,
+ &gEfiDhcp4ProtocolGuid,
+ (VOID **) &Dhcp4,
+ gImageHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ Print (L"Unable to open DHCP4 protocol\n");
+ goto Error;
+ }
+ }
+
+ //
+ // Using the MTFTP4 Service Binding Protocol, create a child handle of the MTFTP4 service and
+ // install the MTFTP4 protocol on it. Then, open the MTFTP4 protocol.
+ //
+ Status = NetLibCreateServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ &gEfiMtftp4ServiceBindingProtocolGuid,
+ &Mtftp4ChildHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->OpenProtocol (
+ Mtftp4ChildHandle,
+ &gEfiMtftp4ProtocolGuid,
+ (VOID **) &Mtftp4,
+ gImageHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ Print (L"Unable to open MTFTP4 protocol\n");
+ goto Error;
+ }
+
+ if (!IPv4DevicePathNode->StaticIpAddress) {
+ //
+ // Configure the DHCP4, all default settings. It is acceptable for the configuration to
+ // fail if the return code is equal to EFI_ACCESS_DENIED which means that the configuration
+ // has been done by another instance of the DHCP4 protocol or that the DHCP configuration
+ // process has been started but is not completed yet.
+ //
+ ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));
+ ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;
+ ParaList.Head.Length = 2;
+ ParaList.Head.Data[0] = DHCP_TAG_NETMASK;
+ ParaList.Route = DHCP_TAG_ROUTER;
+ OptionList[0] = &ParaList.Head;
+ Dhcp4CfgData.OptionCount = 1;
+ Dhcp4CfgData.OptionList = OptionList;
+
+ Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_ACCESS_DENIED) {
+ Print (L"Error while configuring the DHCP4 protocol\n");
+ goto Error;
+ }
+ }
+
+ //
+ // Start the DHCP configuration. This may have already been done thus do not leave in error
+ // if the return code is EFI_ALREADY_STARTED.
+ //
+ Status = Dhcp4->Start (Dhcp4, NULL);
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_ALREADY_STARTED) {
+ Print (L"DHCP configuration failed\n");
+ goto Error;
+ }
+ } else {
+ Dhcp4ToStop = TRUE;
+ }
+
+ Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ if (Dhcp4Mode.State != Dhcp4Bound) {
+ Status = EFI_TIMEOUT;
+ Print (L"DHCP configuration failed\n");
+ goto Error;
+ }
+ }
+
+ //
+ // Configure the TFTP4 protocol
+ //
+
+ ZeroMem (&Mtftp4CfgData, sizeof (EFI_MTFTP4_CONFIG_DATA));
+ Mtftp4CfgData.UseDefaultSetting = FALSE;
+ Mtftp4CfgData.TimeoutValue = 4;
+ Mtftp4CfgData.TryCount = 6;
+
+ if (IPv4DevicePathNode->StaticIpAddress) {
+ CopyMem (&Mtftp4CfgData.StationIp , &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Mtftp4CfgData.SubnetMask, &IPv4DevicePathNode->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Mtftp4CfgData.GatewayIp , &IPv4DevicePathNode->GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
+ } else {
+ CopyMem (&Mtftp4CfgData.StationIp , &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Mtftp4CfgData.SubnetMask, &Dhcp4Mode.SubnetMask , sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Mtftp4CfgData.GatewayIp , &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));
+ }
+
+ CopyMem (&Mtftp4CfgData.ServerIp , &IPv4DevicePathNode->RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS));
+
+ Status = Mtftp4->Configure (Mtftp4, &Mtftp4CfgData);
+ if (EFI_ERROR (Status)) {
+ Print (L"Error while configuring the MTFTP4 protocol\n");
+ goto Error;
+ }
+
+ //
+ // Convert the Unicode path of the file to Ascii
+ //
+
+ FilePathDevicePathNode = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1);
+ AsciiFilePath = AllocatePool ((StrLen (FilePathDevicePathNode->PathName) + 1) * sizeof (CHAR8));
+ if (AsciiFilePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ UnicodeStrToAsciiStr (FilePathDevicePathNode->PathName, AsciiFilePath);
+
+ //
+ // Try to get the size of the file in bytes from the server. If it fails,
+ // start with a 8MB buffer to download the file.
+ //
+ FileSize = 0;
+ if (Mtftp4GetFileSize (Mtftp4, AsciiFilePath, &FileSize) == EFI_SUCCESS) {
+ TftpBufferSize = FileSize;
+ } else {
+ TftpBufferSize = SIZE_8MB;
+ }
+
+ TftpContext = AllocatePool (sizeof (BDS_TFTP_CONTEXT));
+ if (TftpContext == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ TftpContext->FileSize = FileSize;
+
+ for (; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize);
+ TftpBufferSize = (TftpBufferSize + SIZE_8MB) & (~(SIZE_8MB-1))) {
+ //
+ // Allocate a buffer to hold the whole file.
+ //
+ Status = gBS->AllocatePages (
+ Type,
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES (TftpBufferSize),
+ Image
+ );
+ if (EFI_ERROR (Status)) {
+ Print (L"Failed to allocate space for image\n");
+ goto Error;
+ }
+
+ TftpContext->DownloadedNbOfBytes = 0;
+ TftpContext->LastReportedNbOfBytes = 0;
+
+ ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));
+ Mtftp4Token.Filename = (UINT8*)AsciiFilePath;
+ Mtftp4Token.BufferSize = TftpBufferSize;
+ Mtftp4Token.Buffer = (VOID *)(UINTN)*Image;
+ Mtftp4Token.CheckPacket = Mtftp4CheckPacket;
+ Mtftp4Token.Context = (VOID*)TftpContext;
+
+ Print (L"Downloading the file <%s> from the TFTP server\n", FilePathDevicePathNode->PathName);
+ Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);
+ Print (L"\n");
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Print (L"Downloading failed, file larger than expected.\n");
+ continue;
+ } else {
+ goto Error;
+ }
+ }
+
+ *ImageSize = Mtftp4Token.BufferSize;
+ break;
+ }
+
+Error:
+ if (Dhcp4ChildHandle != NULL) {
+ if (Dhcp4 != NULL) {
+ if (Dhcp4ToStop) {
+ Dhcp4->Stop (Dhcp4);
+ }
+ gBS->CloseProtocol (
+ Dhcp4ChildHandle,
+ &gEfiDhcp4ProtocolGuid,
+ gImageHandle,
+ ControllerHandle
+ );
+ }
+ NetLibDestroyServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ Dhcp4ChildHandle
+ );
+ }
+
+ if (Mtftp4ChildHandle != NULL) {
+ if (Mtftp4 != NULL) {
+ if (AsciiFilePath != NULL) {
+ FreePool (AsciiFilePath);
+ }
+ if (TftpContext != NULL) {
+ FreePool (TftpContext);
+ }
+ gBS->CloseProtocol (
+ Mtftp4ChildHandle,
+ &gEfiMtftp4ProtocolGuid,
+ gImageHandle,
+ ControllerHandle
+ );
+ }
+ NetLibDestroyServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ &gEfiMtftp4ServiceBindingProtocolGuid,
+ Mtftp4ChildHandle
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ Print (L"Failed to download the file - Error=%r\n", Status);
+ }
+
+ return Status;
+}
+
+BDS_FILE_LOADER FileLoaders[] = {
+ { BdsFileSystemSupport, BdsFileSystemLoadImage },
+ { BdsFirmwareVolumeSupport, BdsFirmwareVolumeLoadImage },
+ //{ BdsLoadFileSupport, BdsLoadFileLoadImage },
+ { BdsMemoryMapSupport, BdsMemoryMapLoadImage },
+ { BdsPxeSupport, BdsPxeLoadImage },
+ { BdsTftpSupport, BdsTftpLoadImage },
+ { NULL, NULL }
+};
+
+EFI_STATUS
+BdsLoadImageAndUpdateDevicePath (
+ IN OUT EFI_DEVICE_PATH **DevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *FileSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_DEVICE_PATH *RemainingDevicePath;
+ BDS_FILE_LOADER* FileLoader;
+
+ Status = BdsConnectAndUpdateDevicePath (DevicePath, &Handle, &RemainingDevicePath);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FileLoader = FileLoaders;
+ while (FileLoader->Support != NULL) {
+ if (FileLoader->Support (*DevicePath, Handle, RemainingDevicePath)) {
+ return FileLoader->LoadImage (*DevicePath, Handle, RemainingDevicePath, Type, Image, FileSize);
+ }
+ FileLoader++;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+BdsLoadImage (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *FileSize
+ )
+{
+ return BdsLoadImageAndUpdateDevicePath (&DevicePath, Type, Image, FileSize);
+}
+
+/**
+ Start an EFI Application from a Device Path
+
+ @param ParentImageHandle Handle of the calling image
+ @param DevicePath Location of the EFI Application
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsStartEfiApplication (
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINTN LoadOptionsSize,
+ IN VOID* LoadOptions
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE ImageHandle;
+ EFI_PHYSICAL_ADDRESS BinaryBuffer;
+ UINTN BinarySize;
+ EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
+
+ // Find the nearest supported file loader
+ Status = BdsLoadImageAndUpdateDevicePath (&DevicePath, AllocateAnyPages, &BinaryBuffer, &BinarySize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Load the image from the Buffer with Boot Services function
+ Status = gBS->LoadImage (TRUE, ParentImageHandle, DevicePath, (VOID*)(UINTN)BinaryBuffer, BinarySize, &ImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Passed LoadOptions to the EFI Application
+ if (LoadOptionsSize != 0) {
+ Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ LoadedImage->LoadOptionsSize = LoadOptionsSize;
+ LoadedImage->LoadOptions = LoadOptions;
+ }
+
+ // Before calling the image, enable the Watchdog Timer for the 5 Minute period
+ gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
+ // Start the image
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);
+ // Clear the Watchdog Timer after the image returns
+ gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
+
+ return Status;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsHelper.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsHelper.c
new file mode 100644
index 0000000..7f83c2b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsHelper.c
@@ -0,0 +1,359 @@
+/** @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 "BdsInternal.h"
+
+#include <Library/HobLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+
+STATIC CHAR8 *mTokenList[] = {
+ /*"SEC",*/
+ "PEI",
+ "DXE",
+ "BDS",
+ NULL
+};
+
+EFI_STATUS
+ShutdownUefiBootServices (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN MemoryMapSize;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ UINTN MapKey;
+ UINTN DescriptorSize;
+ UINT32 DescriptorVersion;
+ UINTN Pages;
+
+ MemoryMap = NULL;
+ MemoryMapSize = 0;
+ Pages = 0;
+
+ do {
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+
+ Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
+ MemoryMap = AllocatePages (Pages);
+
+ //
+ // Get System MemoryMap
+ //
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ }
+
+ // Don't do anything between the GetMemoryMap() and ExitBootServices()
+ if (!EFI_ERROR(Status)) {
+ Status = gBS->ExitBootServices (gImageHandle, MapKey);
+ if (EFI_ERROR(Status)) {
+ FreePages (MemoryMap, Pages);
+ MemoryMap = NULL;
+ MemoryMapSize = 0;
+ }
+ }
+ } while (EFI_ERROR(Status));
+
+ return Status;
+}
+
+/**
+ Connect all DXE drivers
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsConnectAllDrivers (
+ VOID
+ )
+{
+ UINTN HandleCount, Index;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+
+ do {
+ // Locate all the driver handles
+ Status = gBS->LocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ // Connect every handles
+ for (Index = 0; Index < HandleCount; Index++) {
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ // Check if new handles have been created after the start of the previous handles
+ Status = gDS->Dispatch ();
+ } while (!EFI_ERROR(Status));
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+InsertSystemMemoryResources (
+ LIST_ENTRY *ResourceList,
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResHob
+ )
+{
+ BDS_SYSTEM_MEMORY_RESOURCE *NewResource;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NextLink;
+ LIST_ENTRY AttachedResources;
+ BDS_SYSTEM_MEMORY_RESOURCE *Resource;
+ EFI_PHYSICAL_ADDRESS NewResourceEnd;
+
+ if (IsListEmpty (ResourceList)) {
+ NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
+ NewResource->PhysicalStart = ResHob->PhysicalStart;
+ NewResource->ResourceLength = ResHob->ResourceLength;
+ InsertTailList (ResourceList, &NewResource->Link);
+ return EFI_SUCCESS;
+ }
+
+ InitializeListHead (&AttachedResources);
+
+ Link = ResourceList->ForwardLink;
+ ASSERT (Link != NULL);
+ while (Link != ResourceList) {
+ Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
+
+ // Sanity Check. The resources should not overlapped.
+ ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));
+ ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) &&
+ ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength))));
+
+ // The new resource is attached after this resource descriptor
+ if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {
+ Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
+
+ NextLink = RemoveEntryList (&Resource->Link);
+ InsertTailList (&AttachedResources, &Resource->Link);
+ Link = NextLink;
+ }
+ // The new resource is attached before this resource descriptor
+ else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {
+ Resource->PhysicalStart = ResHob->PhysicalStart;
+ Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
+
+ NextLink = RemoveEntryList (&Resource->Link);
+ InsertTailList (&AttachedResources, &Resource->Link);
+ Link = NextLink;
+ } else {
+ Link = Link->ForwardLink;
+ }
+ }
+
+ if (!IsListEmpty (&AttachedResources)) {
+ // See if we can merge the attached resource with other resources
+
+ NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);
+ Link = RemoveEntryList (&NewResource->Link);
+ while (!IsListEmpty (&AttachedResources)) {
+ // Merge resources
+ Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
+
+ // Ensure they overlap each other
+ ASSERT(
+ ((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) ||
+ (((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength)))
+ );
+
+ NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength);
+ NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart);
+ NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart;
+
+ Link = RemoveEntryList (Link);
+ }
+ } else {
+ // None of the Resource of the list is attached to this ResHob. Create a new entry for it
+ NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
+ NewResource->PhysicalStart = ResHob->PhysicalStart;
+ NewResource->ResourceLength = ResHob->ResourceLength;
+ }
+ InsertTailList (ResourceList, &NewResource->Link);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetSystemMemoryResources (
+ IN LIST_ENTRY *ResourceList
+ )
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
+
+ InitializeListHead (ResourceList);
+
+ // Find the first System Memory Resource Descriptor
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
+ }
+
+ // Did not find any
+ if (ResHob == NULL) {
+ return EFI_NOT_FOUND;
+ } else {
+ InsertSystemMemoryResources (ResourceList, ResHob);
+ }
+
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
+ while (ResHob != NULL) {
+ if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ InsertSystemMemoryResources (ResourceList, ResHob);
+ }
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID
+PrintPerformance (
+ VOID
+ )
+{
+ UINTN Key;
+ CONST VOID *Handle;
+ CONST CHAR8 *Token, *Module;
+ UINT64 Start, Stop, TimeStamp;
+ UINT64 Delta, TicksPerSecond, Milliseconds;
+ UINTN Index;
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+ BOOLEAN CountUp;
+
+ TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);
+ if (Start < Stop) {
+ CountUp = TRUE;
+ } else {
+ CountUp = FALSE;
+ }
+
+ TimeStamp = 0;
+ Key = 0;
+ do {
+ Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
+ if (Key != 0) {
+ for (Index = 0; mTokenList[Index] != NULL; Index++) {
+ if (AsciiStriCmp (mTokenList[Index], Token) == 0) {
+ Delta = CountUp?(Stop - Start):(Start - Stop);
+ TimeStamp += Delta;
+ Milliseconds = DivU64x64Remainder (MultU64x32 (Delta, 1000), TicksPerSecond, NULL);
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"%6a %6ld ms\n", Token, Milliseconds);
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);
+ break;
+ }
+ }
+ }
+ } while (Key != 0);
+
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);
+}
+
+EFI_STATUS
+GetGlobalEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ )
+{
+ return GetEnvironmentVariable (VariableName, &gEfiGlobalVariableGuid,
+ DefaultValue, Size, Value);
+}
+
+EFI_STATUS
+GetEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN EFI_GUID* VendorGuid,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableSize;
+
+ // Try to get the variable size.
+ *Value = NULL;
+ VariableSize = 0;
+ Status = gRT->GetVariable ((CHAR16 *) VariableName, VendorGuid, NULL, &VariableSize, *Value);
+ if (Status == EFI_NOT_FOUND) {
+ if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {
+ // If the environment variable does not exist yet then set it with the default value
+ Status = gRT->SetVariable (
+ (CHAR16*)VariableName,
+ VendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ *Size,
+ DefaultValue
+ );
+ *Value = AllocateCopyPool (*Size, DefaultValue);
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else if (Status == EFI_BUFFER_TOO_SMALL) {
+ // Get the environment variable value
+ *Value = AllocatePool (VariableSize);
+ if (*Value == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable ((CHAR16 *)VariableName, VendorGuid, NULL, &VariableSize, *Value);
+ if (EFI_ERROR (Status)) {
+ FreePool(*Value);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Size) {
+ *Size = VariableSize;
+ }
+ } else {
+ *Value = AllocateCopyPool (*Size, DefaultValue);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsInternal.h b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsInternal.h
new file mode 100644
index 0000000..602fd8d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsInternal.h
@@ -0,0 +1,104 @@
+/** @file
+*
+* Copyright (c) 2011-2012, 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 __BDS_INTERNAL_H__
+#define __BDS_INTERNAL_H__
+
+#include <PiDxe.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BdsLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Guid/ArmMpCoreInfo.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/FileInfo.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/PxeBaseCode.h>
+
+#include <Uefi.h>
+
+typedef BOOLEAN (*BDS_FILE_LOADER_SUPPORT) (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath
+ );
+
+typedef EFI_STATUS (*BDS_FILE_LOADER_LOAD_IMAGE) (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH *RemainingDevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *ImageSize
+ );
+
+typedef struct {
+ BDS_FILE_LOADER_SUPPORT Support;
+ BDS_FILE_LOADER_LOAD_IMAGE LoadImage;
+} BDS_FILE_LOADER;
+
+typedef struct _BDS_SYSTEM_MEMORY_RESOURCE {
+ LIST_ENTRY Link; // This attribute must be the first entry of this structure (to avoid pointer computation)
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ UINT64 ResourceLength;
+} BDS_SYSTEM_MEMORY_RESOURCE;
+
+typedef struct {
+ UINT64 FileSize;
+ UINT64 DownloadedNbOfBytes;
+ UINT64 LastReportedNbOfBytes;
+} BDS_TFTP_CONTEXT;
+
+// BdsHelper.c
+EFI_STATUS
+ShutdownUefiBootServices (
+ VOID
+ );
+
+EFI_STATUS
+GetSystemMemoryResources (
+ LIST_ENTRY *ResourceList
+ );
+
+VOID
+PrintPerformance (
+ VOID
+ );
+
+EFI_STATUS
+BdsLoadImage (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *FileSize
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLib.inf b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLib.inf
new file mode 100644
index 0000000..6d6a2df
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLib.inf
@@ -0,0 +1,107 @@
+#/* @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.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BdsLib
+ FILE_GUID = ddbf73a0-bb25-11df-8e4e-0002a5d5c51b
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BdsLib
+
+[Sources.common]
+ BdsFilePath.c
+ BdsAppLoader.c
+ BdsHelper.c
+ BdsLoadOption.c
+ BdsLinuxFdt.c
+
+[Sources.ARM]
+ Arm/BdsLinuxLoader.c
+ Arm/BdsLinuxAtag.c
+
+[Sources.AARCH64]
+ AArch64/BdsLinuxLoader.c
+ AArch64/BdsLinuxLoaderHelper.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ ArmSmcLib
+ BaseLib
+ DebugLib
+ DevicePathLib
+ HobLib
+ PcdLib
+ PerformanceLib
+ SerialPortLib
+ FdtLib
+ TimerLib
+ NetLib
+
+[LibraryClasses.AARCH64]
+ ArmGicLib
+
+[Guids]
+ gEfiFileInfoGuid
+ gArmMpCoreInfoGuid
+ gArmGlobalVariableGuid
+
+[Protocols]
+ gEfiBdsArchProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiDevicePathFromTextProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
+ gEfiFirmwareVolume2ProtocolGuid
+ gEfiLoadFileProtocolGuid
+ gEfiPxeBaseCodeProtocolGuid
+ gEfiDiskIoProtocolGuid
+ gEfiUsbIoProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiSimpleNetworkProtocolGuid
+ gEfiDhcp4ServiceBindingProtocolGuid
+ gEfiDhcp4ProtocolGuid
+ gEfiMtftp4ServiceBindingProtocolGuid
+ gEfiMtftp4ProtocolGuid
+
+[FeaturePcd]
+ gArmTokenSpaceGuid.PcdArmLinuxSpinTable
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmMachineType
+ gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset
+ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment
+ gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset
+
+ gArmTokenSpaceGuid.PcdMaxTftpFileSize
+
+[FixedPcd.ARM]
+ gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset
+
+[Pcd.AARCH64]
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicSgiIntId
+
+[Depex]
+ TRUE
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
new file mode 100644
index 0000000..e379552
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
@@ -0,0 +1,572 @@
+/** @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 <Library/ArmSmcLib.h>
+#include <Library/PcdLib.h>
+#include <libfdt.h>
+
+#include "BdsInternal.h"
+#include "BdsLinuxLoader.h"
+
+#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+#define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a))))
+#define GET_CELL(p) (p += 4, *((const UINT32 *)(p-4)))
+
+STATIC
+UINTN
+cpu_to_fdtn (UINTN x) {
+ if (sizeof (UINTN) == sizeof (UINT32)) {
+ return cpu_to_fdt32 (x);
+ } else {
+ return cpu_to_fdt64 (x);
+ }
+}
+
+typedef struct {
+ UINTN Base;
+ UINTN Size;
+} FdtRegion;
+
+
+STATIC
+UINTN
+IsPrintableString (
+ IN CONST VOID* data,
+ IN UINTN len
+ )
+{
+ CONST CHAR8 *s = data;
+ CONST CHAR8 *ss;
+
+ // Zero length is not
+ if (len == 0) {
+ return 0;
+ }
+
+ // Must terminate with zero
+ if (s[len - 1] != '\0') {
+ return 0;
+ }
+
+ ss = s;
+ while (*s/* && isprint(*s)*/) {
+ s++;
+ }
+
+ // Not zero, or not done yet
+ if (*s != '\0' || (s + 1 - ss) < len) {
+ return 0;
+ }
+
+ return 1;
+}
+
+STATIC
+VOID
+PrintData (
+ IN CONST CHAR8* data,
+ IN UINTN len
+ )
+{
+ UINTN i;
+ CONST CHAR8 *p = data;
+
+ // No data, don't print
+ if (len == 0)
+ return;
+
+ if (IsPrintableString (data, len)) {
+ Print(L" = \"%a\"", (const char *)data);
+ } else if ((len % 4) == 0) {
+ Print(L" = <");
+ for (i = 0; i < len; i += 4) {
+ Print(L"0x%08x%a", fdt32_to_cpu(GET_CELL(p)),i < (len - 4) ? " " : "");
+ }
+ Print(L">");
+ } else {
+ Print(L" = [");
+ for (i = 0; i < len; i++)
+ Print(L"%02x%a", *p++, i < len - 1 ? " " : "");
+ Print(L"]");
+ }
+}
+
+VOID
+DebugDumpFdt (
+ IN VOID* FdtBlob
+ )
+{
+ struct fdt_header *bph;
+ UINT32 off_dt;
+ UINT32 off_str;
+ CONST CHAR8* p_struct;
+ CONST CHAR8* p_strings;
+ CONST CHAR8* p;
+ CONST CHAR8* s;
+ CONST CHAR8* t;
+ UINT32 tag;
+ UINTN sz;
+ UINTN depth;
+ UINTN shift;
+ UINT32 version;
+
+ {
+ // Can 'memreserve' be printed by below code?
+ INTN num = fdt_num_mem_rsv(FdtBlob);
+ INTN i, err;
+ UINT64 addr = 0,size = 0;
+
+ for (i = 0; i < num; i++) {
+ err = fdt_get_mem_rsv(FdtBlob, i, &addr, &size);
+ if (err) {
+ DEBUG((EFI_D_ERROR, "Error (%d) : Cannot get memreserve section (%d)\n", err, i));
+ }
+ else {
+ Print(L"/memreserve/ \t0x%lx \t0x%lx;\n",addr,size);
+ }
+ }
+ }
+
+ depth = 0;
+ shift = 4;
+
+ bph = FdtBlob;
+ off_dt = fdt32_to_cpu(bph->off_dt_struct);
+ off_str = fdt32_to_cpu(bph->off_dt_strings);
+ p_struct = (CONST CHAR8*)FdtBlob + off_dt;
+ p_strings = (CONST CHAR8*)FdtBlob + off_str;
+ version = fdt32_to_cpu(bph->version);
+
+ p = p_struct;
+ while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
+ if (tag == FDT_BEGIN_NODE) {
+ s = p;
+ p = PALIGN(p + AsciiStrLen (s) + 1, 4);
+
+ if (*s == '\0')
+ s = "/";
+
+ Print(L"%*s%a {\n", depth * shift, L" ", s);
+
+ depth++;
+ continue;
+ }
+
+ if (tag == FDT_END_NODE) {
+ depth--;
+
+ Print(L"%*s};\n", depth * shift, L" ");
+ continue;
+ }
+
+ if (tag == FDT_NOP) {
+ Print(L"%*s// [NOP]\n", depth * shift, L" ");
+ continue;
+ }
+
+ if (tag != FDT_PROP) {
+ Print(L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag);
+ break;
+ }
+ sz = fdt32_to_cpu(GET_CELL(p));
+ s = p_strings + fdt32_to_cpu(GET_CELL(p));
+ if (version < 16 && sz >= 8)
+ p = PALIGN(p, 8);
+ t = p;
+
+ p = PALIGN(p + sz, 4);
+
+ Print(L"%*s%a", depth * shift, L" ", s);
+ PrintData(t, sz);
+ Print(L";\n");
+ }
+}
+
+STATIC
+BOOLEAN
+IsLinuxReservedRegion (
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+{
+ switch(MemoryType) {
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ case EfiUnusableMemory:
+ case EfiACPIReclaimMemory:
+ case EfiACPIMemoryNVS:
+ case EfiReservedMemoryType:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/**
+** Relocate the FDT blob to a more appropriate location for the Linux kernel.
+** This function will allocate memory for the relocated FDT blob.
+**
+** @retval EFI_SUCCESS on success.
+** @retval EFI_OUT_OF_RESOURCES or EFI_INVALID_PARAMETER on failure.
+*/
+STATIC
+EFI_STATUS
+RelocateFdt (
+ EFI_PHYSICAL_ADDRESS OriginalFdt,
+ UINTN OriginalFdtSize,
+ EFI_PHYSICAL_ADDRESS *RelocatedFdt,
+ UINTN *RelocatedFdtSize,
+ EFI_PHYSICAL_ADDRESS *RelocatedFdtAlloc
+ )
+{
+ EFI_STATUS Status;
+ INTN Error;
+ UINT64 FdtAlignment;
+
+ *RelocatedFdtSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE;
+
+ // If FDT load address needs to be aligned, allocate more space.
+ FdtAlignment = PcdGet32 (PcdArmLinuxFdtAlignment);
+ if (FdtAlignment != 0) {
+ *RelocatedFdtSize += FdtAlignment;
+ }
+
+ // Try below a watermark address.
+ Status = EFI_NOT_FOUND;
+ if (PcdGet32 (PcdArmLinuxFdtMaxOffset) != 0) {
+ *RelocatedFdt = LINUX_FDT_MAX_OFFSET;
+ Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_WARN, "Warning: Failed to load FDT below address 0x%lX (%r). Will try again at a random address anywhere.\n", *RelocatedFdt, Status));
+ }
+ }
+
+ // Try anywhere there is available space.
+ if (EFI_ERROR (Status)) {
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", *RelocatedFdt));
+ }
+ }
+
+ *RelocatedFdtAlloc = *RelocatedFdt;
+ if (FdtAlignment != 0) {
+ *RelocatedFdt = ALIGN (*RelocatedFdt, FdtAlignment);
+ }
+
+ // Load the Original FDT tree into the new region
+ Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt,
+ (VOID*)(UINTN)(*RelocatedFdt), *RelocatedFdtSize);
+ if (Error) {
+ DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Error)));
+ gBS->FreePages (*RelocatedFdtAlloc, EFI_SIZE_TO_PAGES (*RelocatedFdtSize));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG_CODE_BEGIN();
+ //DebugDumpFdt (fdt);
+ DEBUG_CODE_END();
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+PrepareFdt (
+ IN CONST CHAR8* CommandLineArguments,
+ IN EFI_PHYSICAL_ADDRESS InitrdImage,
+ IN UINTN InitrdImageSize,
+ IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase,
+ IN OUT UINTN *FdtBlobSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS NewFdtBlobBase;
+ EFI_PHYSICAL_ADDRESS NewFdtBlobAllocation;
+ UINTN NewFdtBlobSize;
+ VOID* fdt;
+ INTN err;
+ INTN node;
+ INTN cpu_node;
+ INT32 lenp;
+ CONST VOID* BootArg;
+ CONST VOID* Method;
+ EFI_PHYSICAL_ADDRESS InitrdImageStart;
+ EFI_PHYSICAL_ADDRESS InitrdImageEnd;
+ FdtRegion Region;
+ UINTN Index;
+ CHAR8 Name[10];
+ LIST_ENTRY ResourceList;
+ BDS_SYSTEM_MEMORY_RESOURCE *Resource;
+ ARM_PROCESSOR_TABLE *ArmProcessorTable;
+ ARM_CORE_INFO *ArmCoreInfoTable;
+ UINT32 MpId;
+ UINT32 ClusterId;
+ UINT32 CoreId;
+ UINT64 CpuReleaseAddr;
+ UINTN MemoryMapSize;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
+ UINTN MapKey;
+ UINTN DescriptorSize;
+ UINT32 DescriptorVersion;
+ UINTN Pages;
+ UINTN OriginalFdtSize;
+ BOOLEAN CpusNodeExist;
+ UINTN CoreMpId;
+
+ NewFdtBlobAllocation = 0;
+
+ //
+ // Sanity checks on the original FDT blob.
+ //
+ err = fdt_check_header ((VOID*)(UINTN)(*FdtBlobBase));
+ if (err != 0) {
+ Print (L"ERROR: Device Tree header not valid (err:%d)\n", err);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // The original FDT blob might have been loaded partially.
+ // Check that it is not the case.
+ OriginalFdtSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));
+ if (OriginalFdtSize > *FdtBlobSize) {
+ Print (L"ERROR: Incomplete FDT. Only %d/%d bytes have been loaded.\n",
+ *FdtBlobSize, OriginalFdtSize);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Relocate the FDT to its final location.
+ //
+ Status = RelocateFdt (*FdtBlobBase, OriginalFdtSize,
+ &NewFdtBlobBase, &NewFdtBlobSize, &NewFdtBlobAllocation);
+ if (EFI_ERROR (Status)) {
+ goto FAIL_RELOCATE_FDT;
+ }
+
+ fdt = (VOID*)(UINTN)NewFdtBlobBase;
+
+ node = fdt_subnode_offset (fdt, 0, "chosen");
+ if (node < 0) {
+ // The 'chosen' node does not exist, create it
+ node = fdt_add_subnode(fdt, 0, "chosen");
+ if (node < 0) {
+ DEBUG((EFI_D_ERROR,"Error on finding 'chosen' node\n"));
+ Status = EFI_INVALID_PARAMETER;
+ goto FAIL_COMPLETE_FDT;
+ }
+ }
+
+ DEBUG_CODE_BEGIN();
+ BootArg = fdt_getprop(fdt, node, "bootargs", &lenp);
+ if (BootArg != NULL) {
+ DEBUG((EFI_D_ERROR,"BootArg: %a\n",BootArg));
+ }
+ DEBUG_CODE_END();
+
+ //
+ // Set Linux CmdLine
+ //
+ if ((CommandLineArguments != NULL) && (AsciiStrLen (CommandLineArguments) > 0)) {
+ err = fdt_setprop(fdt, node, "bootargs", CommandLineArguments, AsciiStrSize(CommandLineArguments));
+ if (err) {
+ DEBUG((EFI_D_ERROR,"Fail to set new 'bootarg' (err:%d)\n",err));
+ }
+ }
+
+ //
+ // Set Linux Initrd
+ //
+ if (InitrdImageSize != 0) {
+ InitrdImageStart = cpu_to_fdt64 (InitrdImage);
+ err = fdt_setprop(fdt, node, "linux,initrd-start", &InitrdImageStart, sizeof(EFI_PHYSICAL_ADDRESS));
+ if (err) {
+ DEBUG((EFI_D_ERROR,"Fail to set new 'linux,initrd-start' (err:%d)\n",err));
+ }
+ InitrdImageEnd = cpu_to_fdt64 (InitrdImage + InitrdImageSize);
+ err = fdt_setprop(fdt, node, "linux,initrd-end", &InitrdImageEnd, sizeof(EFI_PHYSICAL_ADDRESS));
+ if (err) {
+ DEBUG((EFI_D_ERROR,"Fail to set new 'linux,initrd-start' (err:%d)\n",err));
+ }
+ }
+
+ //
+ // Set Physical memory setup if does not exist
+ //
+ node = fdt_subnode_offset(fdt, 0, "memory");
+ if (node < 0) {
+ // The 'memory' node does not exist, create it
+ node = fdt_add_subnode(fdt, 0, "memory");
+ if (node >= 0) {
+ fdt_setprop_string(fdt, node, "name", "memory");
+ fdt_setprop_string(fdt, node, "device_type", "memory");
+
+ GetSystemMemoryResources (&ResourceList);
+ Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink;
+
+ Region.Base = cpu_to_fdtn ((UINTN)Resource->PhysicalStart);
+ Region.Size = cpu_to_fdtn ((UINTN)Resource->ResourceLength);
+
+ err = fdt_setprop(fdt, node, "reg", &Region, sizeof(Region));
+ if (err) {
+ DEBUG((EFI_D_ERROR,"Fail to set new 'memory region' (err:%d)\n",err));
+ }
+ }
+ }
+
+ //
+ // Add the memory regions reserved by the UEFI Firmware
+ //
+
+ // Retrieve the UEFI Memory Map
+ MemoryMap = NULL;
+ MemoryMapSize = 0;
+ Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive
+ // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size.
+ Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
+ MemoryMap = AllocatePages (Pages);
+ if (MemoryMap == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FAIL_COMPLETE_FDT;
+ }
+ Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
+ }
+
+ // Go through the list and add the reserved region to the Device Tree
+ if (!EFI_ERROR(Status)) {
+ MemoryMapPtr = MemoryMap;
+ for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
+ if (IsLinuxReservedRegion ((EFI_MEMORY_TYPE)MemoryMapPtr->Type)) {
+ DEBUG((DEBUG_VERBOSE, "Reserved region of type %d [0x%lX, 0x%lX]\n",
+ MemoryMapPtr->Type,
+ (UINTN)MemoryMapPtr->PhysicalStart,
+ (UINTN)(MemoryMapPtr->PhysicalStart + MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE)));
+ err = fdt_add_mem_rsv(fdt, MemoryMapPtr->PhysicalStart, MemoryMapPtr->NumberOfPages * EFI_PAGE_SIZE);
+ if (err != 0) {
+ Print(L"Warning: Fail to add 'memreserve' (err:%d)\n", err);
+ }
+ }
+ MemoryMapPtr = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + DescriptorSize);
+ }
+ }
+
+ //
+ // Setup Arm Mpcore Info if it is a multi-core or multi-cluster platforms.
+ //
+ // For 'cpus' and 'cpu' device tree nodes bindings, refer to this file
+ // in the kernel documentation:
+ // Documentation/devicetree/bindings/arm/cpus.txt
+ //
+ for (Index=0; Index < gST->NumberOfTableEntries; Index++) {
+ // Check for correct GUID type
+ if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+ MpId = ArmReadMpidr ();
+ ClusterId = GET_CLUSTER_ID(MpId);
+ CoreId = GET_CORE_ID(MpId);
+
+ node = fdt_subnode_offset(fdt, 0, "cpus");
+ if (node < 0) {
+ // Create the /cpus node
+ node = fdt_add_subnode(fdt, 0, "cpus");
+ fdt_setprop_string(fdt, node, "name", "cpus");
+ fdt_setprop_cell (fdt, node, "#address-cells", sizeof (UINTN) / 4);
+ fdt_setprop_cell(fdt, node, "#size-cells", 0);
+ CpusNodeExist = FALSE;
+ } else {
+ CpusNodeExist = TRUE;
+ }
+
+ // Get pointer to ARM processor table
+ ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Index].VendorTable;
+ ArmCoreInfoTable = ArmProcessorTable->ArmCpus;
+
+ for (Index = 0; Index < ArmProcessorTable->NumberOfEntries; Index++) {
+ CoreMpId = (UINTN) GET_MPID (ArmCoreInfoTable[Index].ClusterId,
+ ArmCoreInfoTable[Index].CoreId);
+ AsciiSPrint (Name, 10, "cpu@%x", CoreMpId);
+
+ // If the 'cpus' node did not exist then create all the 'cpu' nodes.
+ // In case 'cpus' node is provided in the original FDT then we do not add
+ // any 'cpu' node.
+ if (!CpusNodeExist) {
+ cpu_node = fdt_add_subnode (fdt, node, Name);
+ if (cpu_node < 0) {
+ DEBUG ((EFI_D_ERROR, "Error on creating '%s' node\n", Name));
+ Status = EFI_INVALID_PARAMETER;
+ goto FAIL_COMPLETE_FDT;
+ }
+
+ fdt_setprop_string (fdt, cpu_node, "device_type", "cpu");
+
+ CoreMpId = cpu_to_fdtn (CoreMpId);
+ fdt_setprop (fdt, cpu_node, "reg", &CoreMpId, sizeof (CoreMpId));
+ } else {
+ cpu_node = fdt_subnode_offset(fdt, node, Name);
+ }
+
+ if (cpu_node >= 0) {
+ Method = fdt_getprop (fdt, cpu_node, "enable-method", &lenp);
+ // We only care when 'enable-method' == 'spin-table'. If the enable-method is not defined
+ // or defined as 'psci' then we ignore its properties.
+ if ((Method != NULL) && (AsciiStrCmp ((CHAR8 *)Method, "spin-table") == 0)) {
+ // There are two cases;
+ // - UEFI firmware parked the secondary cores and/or UEFI firmware is aware of the CPU
+ // release addresses (PcdArmLinuxSpinTable == TRUE)
+ // - the parking of the secondary cores has been managed before starting UEFI and/or UEFI
+ // does not anything about the CPU release addresses - in this case we do nothing
+ if (FeaturePcdGet (PcdArmLinuxSpinTable)) {
+ CpuReleaseAddr = cpu_to_fdt64 (ArmCoreInfoTable[Index].MailboxSetAddress);
+ fdt_setprop (fdt, cpu_node, "cpu-release-addr", &CpuReleaseAddr, sizeof(CpuReleaseAddr));
+
+ // If it is not the primary core than the cpu should be disabled
+ if (((ArmCoreInfoTable[Index].ClusterId != ClusterId) || (ArmCoreInfoTable[Index].CoreId != CoreId))) {
+ fdt_setprop_string(fdt, cpu_node, "status", "disabled");
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ DEBUG_CODE_BEGIN();
+ //DebugDumpFdt (fdt);
+ DEBUG_CODE_END();
+
+ // If we succeeded to generate the new Device Tree then free the old Device Tree
+ gBS->FreePages (*FdtBlobBase, EFI_SIZE_TO_PAGES (*FdtBlobSize));
+
+ // Update the real size of the Device Tree
+ fdt_pack ((VOID*)(UINTN)(NewFdtBlobBase));
+
+ *FdtBlobBase = NewFdtBlobBase;
+ *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase));
+ return EFI_SUCCESS;
+
+FAIL_COMPLETE_FDT:
+ gBS->FreePages (NewFdtBlobAllocation, EFI_SIZE_TO_PAGES (NewFdtBlobSize));
+
+FAIL_RELOCATE_FDT:
+ *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(*FdtBlobBase));
+ // Return success even if we failed to update the FDT blob.
+ // The original one is still valid.
+ return EFI_SUCCESS;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxLoader.h b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxLoader.h
new file mode 100644
index 0000000..b78f606
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLinuxLoader.h
@@ -0,0 +1,156 @@
+/** @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.
+*
+**/
+
+#ifndef __BDSLINUXLOADER_H
+#define __BDSLINUXLOADER_H
+
+#define LINUX_UIMAGE_SIGNATURE 0x56190527
+#define LINUX_KERNEL_MAX_OFFSET (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxKernelMaxOffset))
+#define LINUX_ATAG_MAX_OFFSET (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxAtagMaxOffset))
+#define LINUX_FDT_MAX_OFFSET (PcdGet64 (PcdSystemMemoryBase) + PcdGet32(PcdArmLinuxFdtMaxOffset))
+
+// Additional size that could be used for FDT entries added by the UEFI OS Loader
+// Estimation based on: EDID (300bytes) + bootargs (200bytes) + initrd region (20bytes)
+// + system memory region (20bytes) + mp_core entries (200 bytes)
+#define FDT_ADDITIONAL_ENTRIES_SIZE 0x300
+
+#define ARM_FDT_MACHINE_TYPE 0xFFFFFFFF
+
+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 next_tag_address(t) ((LINUX_ATAG*)((UINT32)(t) + (((t)->header.size) << 2) ))
+#define tag_size(type) ((UINT32)((sizeof(LINUX_ATAG_HEADER) + sizeof(type)) >> 2))
+
+typedef struct {
+ UINT32 size; /* length of tag in words including this header */
+ UINT32 type; /* tag type */
+} LINUX_ATAG_HEADER;
+
+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[1];
+} LINUX_ATAG_CMDLINE;
+
+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;
+ } body;
+} LINUX_ATAG;
+
+EFI_STATUS
+PrepareAtagList (
+ IN CONST CHAR8* CommandLineString,
+ IN EFI_PHYSICAL_ADDRESS InitrdImage,
+ IN UINTN InitrdImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *AtagBase,
+ OUT UINT32 *AtagSize
+ );
+
+EFI_STATUS
+PrepareFdt (
+ IN CONST CHAR8* CommandLineArguments,
+ IN EFI_PHYSICAL_ADDRESS InitrdImage,
+ IN UINTN InitrdImageSize,
+ IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase,
+ IN OUT UINTN *FdtBlobSize
+ );
+
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLoadOption.c b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLoadOption.c
new file mode 100644
index 0000000..be5ed41
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/BdsLib/BdsLoadOption.c
@@ -0,0 +1,270 @@
+/** @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 "BdsInternal.h"
+
+EFI_STATUS
+BootOptionParseLoadOption (
+ IN EFI_LOAD_OPTION EfiLoadOption,
+ IN UINTN EfiLoadOptionSize,
+ IN OUT BDS_LOAD_OPTION **BdsLoadOption
+ )
+{
+ BDS_LOAD_OPTION *LoadOption;
+ UINTN DescriptionLength;
+
+ if (EfiLoadOption == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (EfiLoadOptionSize < sizeof(UINT32) + sizeof(UINT16) + sizeof(CHAR16) + sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (*BdsLoadOption == NULL) {
+ LoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));
+ if (LoadOption == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ LoadOption = *BdsLoadOption;
+ }
+
+ LoadOption->LoadOption = EfiLoadOption;
+ LoadOption->LoadOptionSize = EfiLoadOptionSize;
+
+ 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 ((End of EfiLoadOptiony - Start of EfiLoadOption) == EfiLoadOptionSize) then No Optional Data
+ 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 (*BdsLoadOption == NULL) {
+ *BdsLoadOption = LoadOption;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BootOptionFromLoadOptionVariable (
+ IN CHAR16* BootVariableName,
+ OUT BDS_LOAD_OPTION** BdsLoadOption
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOAD_OPTION EfiLoadOption;
+ UINTN EfiLoadOptionSize;
+
+ Status = GetGlobalEnvironmentVariable (BootVariableName, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption);
+ if (!EFI_ERROR(Status)) {
+ *BdsLoadOption = NULL;
+ Status = BootOptionParseLoadOption (EfiLoadOption, EfiLoadOptionSize, BdsLoadOption);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+BootOptionFromLoadOptionIndex (
+ IN UINT16 LoadOptionIndex,
+ OUT BDS_LOAD_OPTION **BdsLoadOption
+ )
+{
+ CHAR16 BootVariableName[9];
+ EFI_STATUS Status;
+
+ UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", LoadOptionIndex);
+
+ Status = BootOptionFromLoadOptionVariable (BootVariableName, BdsLoadOption);
+ if (!EFI_ERROR(Status)) {
+ (*BdsLoadOption)->LoadOptionIndex = LoadOptionIndex;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+BootOptionToLoadOptionVariable (
+ IN BDS_LOAD_OPTION* BdsLoadOption
+ )
+{
+ EFI_STATUS Status;
+ UINTN DescriptionSize;
+ //UINT16 FilePathListLength;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePathNode;
+ UINTN NodeLength;
+ UINT8* EfiLoadOptionPtr;
+ VOID* OldLoadOption;
+ CHAR16 BootVariableName[9];
+ UINTN BootOrderSize;
+ UINT16* BootOrder;
+
+ // If we are overwriting an existent Boot Option then we have to free previously allocated memory
+ if (BdsLoadOption->LoadOptionSize > 0) {
+ OldLoadOption = BdsLoadOption->LoadOption;
+ } else {
+ OldLoadOption = NULL;
+
+ // 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
+ BdsLoadOption->LoadOptionIndex = BootOptionAllocateBootIndex ();
+
+ //TODO: Add to the the Boot Entry List
+ }
+
+ DescriptionSize = StrSize(BdsLoadOption->Description);
+
+ // Ensure the FilePathListLength information is correct
+ ASSERT (GetDevicePathSize (BdsLoadOption->FilePathList) == BdsLoadOption->FilePathListLength);
+
+ // Allocate the memory for the EFI Load Option
+ BdsLoadOption->LoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + DescriptionSize + BdsLoadOption->FilePathListLength + BdsLoadOption->OptionalDataSize;
+
+ BdsLoadOption->LoadOption = (EFI_LOAD_OPTION)AllocateZeroPool (BdsLoadOption->LoadOptionSize);
+ if (BdsLoadOption->LoadOption == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ 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);
+ }
+
+ // Case where the fields have been updated
+ if (OldLoadOption) {
+ // Now, the old data has been copied to the new allocated packed structure, we need to update the pointers of BdsLoadOption
+ BootOptionParseLoadOption (BdsLoadOption->LoadOption, BdsLoadOption->LoadOptionSize, &BdsLoadOption);
+ // Free the old packed structure
+ FreePool (OldLoadOption);
+ }
+
+ // Create/Update Boot#### environment variable
+ 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
+ );
+
+ // When it is a new entry we must add the entry to the BootOrder
+ if (OldLoadOption == NULL) {
+ // 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)] = BdsLoadOption->LoadOptionIndex;
+ BootOrderSize += sizeof(UINT16);
+ } else {
+ // BootOrder does not exist. Create it
+ BootOrderSize = sizeof(UINT16);
+ BootOrder = &(BdsLoadOption->LoadOptionIndex);
+ }
+
+ // Update (or Create) the BootOrder environment variable
+ gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ BootOrderSize,
+ BootOrder
+ );
+ DEBUG((EFI_D_ERROR,"Create %s\n",BootVariableName));
+
+ // Free memory allocated by GetGlobalEnvironmentVariable
+ if (!EFI_ERROR(Status)) {
+ FreePool (BootOrder);
+ }
+ } else {
+ DEBUG((EFI_D_ERROR,"Update %s\n",BootVariableName));
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINT16
+BootOptionAllocateBootIndex (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT32 BootIndex;
+ UINT16 *BootOrder;
+ UINTN BootOrderSize;
+ BOOLEAN Found;
+
+ // Get the Boot Option Order from the environment variable
+ Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);
+ if (!EFI_ERROR(Status)) {
+ for (BootIndex = 0; BootIndex <= 0xFFFF; BootIndex++) {
+ Found = FALSE;
+ for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
+ if (BootOrder[Index] == BootIndex) {
+ Found = TRUE;
+ break;
+ }
+ }
+ if (!Found) {
+ return BootIndex;
+ }
+ }
+ FreePool (BootOrder);
+ }
+ // Return the first index
+ return 0;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memcpy.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memcpy.S
new file mode 100644
index 0000000..66102da
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memcpy.S
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2011 - 2013, ARM Ltd
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
+ */
+
+
+.text
+.align 2
+
+
+GCC_ASM_EXPORT(memcpy)
+
+
+// Taken from Newlib BSD implementation.
+ASM_PFX(memcpy):
+ // Copy dst to x6, so we can preserve return value.
+ mov x6, x0
+
+ // NOTE: although size_t is unsigned, this code uses signed
+ // comparisons on x2 so relies on nb never having its top bit
+ // set. In practice this is not going to be a real problem.
+
+ // Require at least 64 bytes to be worth aligning.
+ cmp x2, #64
+ blt qwordcopy
+
+ // Compute offset to align destination to 16 bytes.
+ neg x3, x0
+ and x3, x3, 15
+
+ cbz x3, blockcopy // offset == 0 is likely
+
+ // We know there is at least 64 bytes to be done, so we
+ // do a 16 byte misaligned copy at first and then later do
+ // all 16-byte aligned copies. Some bytes will be copied
+ // twice, but there's no harm in that since memcpy does not
+ // guarantee correctness on overlap.
+
+ sub x2, x2, x3 // nb -= offset
+ ldp x4, x5, [x1]
+ add x1, x1, x3
+ stp x4, x5, [x6]
+ add x6, x6, x3
+
+ // The destination pointer is now qword (16 byte) aligned.
+ // (The src pointer might be.)
+
+blockcopy:
+ // Copy 64 bytes at a time.
+ subs x2, x2, #64
+ blt 3f
+2: subs x2, x2, #64
+ ldp x4, x5, [x1,#0]
+ ldp x8, x9, [x1,#16]
+ ldp x10,x11,[x1,#32]
+ ldp x12,x13,[x1,#48]
+ add x1, x1, #64
+ stp x4, x5, [x6,#0]
+ stp x8, x9, [x6,#16]
+ stp x10,x11,[x6,#32]
+ stp x12,x13,[x6,#48]
+ add x6, x6, #64
+ bge 2b
+
+ // Unwind pre-decrement
+3: add x2, x2, #64
+
+qwordcopy:
+ // Copy 0-48 bytes, 16 bytes at a time.
+ subs x2, x2, #16
+ blt tailcopy
+2: ldp x4, x5, [x1],#16
+ subs x2, x2, #16
+ stp x4, x5, [x6],#16
+ bge 2b
+
+ // No need to unwind the pre-decrement, it would not change
+ // the low 4 bits of the count. But how likely is it for the
+ // byte count to be multiple of 16? Is it worth the overhead
+ // of testing for x2 == -16?
+
+tailcopy:
+ // Copy trailing 0-15 bytes.
+ tbz x2, #3, 1f
+ ldr x4, [x1],#8 // copy 8 bytes
+ str x4, [x6],#8
+1:
+ tbz x2, #2, 1f
+ ldr w4, [x1],#4 // copy 4 bytes
+ str w4, [x6],#4
+1:
+ tbz x2, #1, 1f
+ ldrh w4, [x1],#2 // copy 2 bytes
+ strh w4, [x6],#2
+1:
+ tbz x2, #0, return
+ ldrb w4, [x1] // copy 1 byte
+ strb w4, [x6]
+
+return:
+ // This is the only return point of memcpy.
+ ret
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c
new file mode 100644
index 0000000..069c932
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c
@@ -0,0 +1,25 @@
+/** @file
+
+ Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+
+void *memset(void *Destination, int Value, int Count)
+{
+ CHAR8 *Ptr = Destination;
+
+ while (Count--)
+ *Ptr++ = Value;
+
+ return Destination;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h
new file mode 100644
index 0000000..78d3e21
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h
@@ -0,0 +1,99 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+
+#define CHAR_BIT 8
+
+typedef union {
+ INT64 all;
+ struct {
+ UINT32 low;
+ INT32 high;
+ };
+} dwords;
+
+typedef union {
+ UINT64 all;
+ struct {
+ UINT32 low;
+ UINT32 high;
+ };
+} udwords;
+
+// __aeabi_ return values
+typedef struct {
+ UINT64 Quotent;
+ UINT64 Remainder;
+} ulldiv_t;
+
+typedef struct {
+ INT64 Quotent;
+ INT64 Remainder;
+} lldiv_t;
+
+typedef struct {
+ UINT32 Quotent;
+ UINT32 Remainder;
+} uidiv_return;
+
+#if __GNUC__
+ #define COUNT_LEADING_ZEROS(_a) __builtin_clz((_a))
+ #define COUNT_TRAILING_ZEROS(_a) __builtin_ctz((_a))
+#else
+#error COUNT_LEADING_ZEROS() and COUNT_TRAILING_ZEROS() macros not ported to your compiler
+#endif
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
new file mode 100644
index 0000000..74960b1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__ashldi3)
+
+ASM_PFX(__ashldi3):
+ cmp r2, #31
+ bls L2
+ cmp r2, #63
+ subls r2, r2, #32
+ movls r2, r0, asl r2
+ movhi r2, #0
+ mov r1, r2
+ mov r0, #0
+ bx lr
+L2:
+ cmp r2, #0
+ rsbne r3, r2, #32
+ movne r3, r0, lsr r3
+ movne r0, r0, asl r2
+ orrne r1, r3, r1, asl r2
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c
new file mode 100644
index 0000000..e13ea01
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c
@@ -0,0 +1,83 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+#include "Llvm_int_lib.h"
+
+// Returns: a << b
+
+// Precondition: 0 <= b < bits_in_dword
+
+INT64
+__ashldi3(INT64 a, INT32 b)
+{
+ const int bits_in_word = (int)(sizeof(INT32) * CHAR_BIT);
+ dwords input;
+ dwords result;
+ input.all = a;
+ if (b & bits_in_word) // bits_in_word <= b < bits_in_dword
+ {
+ result.low = 0;
+ result.high = input.low << (b - bits_in_word);
+ }
+ else // 0 <= b < bits_in_word
+ {
+ if (b == 0)
+ return a;
+ result.low = input.low << b;
+ result.high = (input.high << b) | (input.low >> (bits_in_word - b));
+ }
+ return result.all;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
new file mode 100644
index 0000000..3cee2c1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__ashrdi3)
+
+ASM_PFX(__ashrdi3):
+ cmp r2, #31
+ bls L2
+ cmp r2, #63
+ subls r2, r2, #32
+ mov ip, r1, asr #31
+ movls r2, r1, asr r2
+ movhi r2, ip
+ mov r0, r2
+ mov r1, ip
+ bx lr
+L2:
+ cmp r2, #0
+ rsbne r3, r2, #32
+ movne r3, r1, asl r3
+ movne r1, r1, asr r2
+ orrne r0, r3, r0, lsr r2
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c
new file mode 100644
index 0000000..1617543
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c
@@ -0,0 +1,84 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+#include "Llvm_int_lib.h"
+
+// Returns: arithmetic a >> b
+
+// Precondition: 0 <= b < bits_in_dword
+
+INT64
+__ashrdi3(INT64 a, INT32 b)
+{
+ const int bits_in_word = (int)(sizeof(INT32) * CHAR_BIT);
+ dwords input;
+ dwords result;
+ input.all = a;
+ if (b & bits_in_word) // bits_in_word <= b < bits_in_dword
+ {
+ // result.high = input.high < 0 ? -1 : 0
+ result.high = input.high >> (bits_in_word - 1);
+ result.low = input.high >> (b - bits_in_word);
+ }
+ else // 0 <= b < bits_in_word
+ {
+ if (b == 0)
+ return a;
+ result.high = input.high >> b;
+ result.low = (input.high << (bits_in_word - b)) | (input.low >> b);
+ }
+ return result.all;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
new file mode 100644
index 0000000..4cef265
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__clzsi2)
+
+ASM_PFX(__clzsi2):
+ @ frame_needed = 1, uses_anonymous_args = 0
+ stmfd sp!, {r7, lr}
+ add r7, sp, #0
+ movs r3, r0, lsr #16
+ movne r3, #16
+ moveq r3, #0
+ movne r9, #0
+ moveq r9, #16
+ mov r3, r0, lsr r3
+ tst r3, #65280
+ movne r0, #8
+ moveq r0, #0
+ movne lr, #0
+ moveq lr, #8
+ mov r3, r3, lsr r0
+ tst r3, #240
+ movne r0, #4
+ moveq r0, #0
+ movne ip, #0
+ moveq ip, #4
+ mov r3, r3, lsr r0
+ tst r3, #12
+ movne r0, #2
+ moveq r0, #0
+ movne r1, #0
+ moveq r1, #2
+ mov r2, r3, lsr r0
+ add r3, lr, r9
+ add r0, r3, ip
+ add r1, r0, r1
+ mov r0, r2, lsr #1
+ eor r0, r0, #1
+ ands r0, r0, #1
+ mvnne r0, #0
+ rsb r3, r2, #2
+ and r0, r0, r3
+ add r0, r1, r0
+ ldmfd sp!, {r7, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c
new file mode 100644
index 0000000..5c2a3ea
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c
@@ -0,0 +1,96 @@
+/** @file
+ Compiler intrinsic to return the number of leading zeros, ported from LLVM code.
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+// Returns: the number of leading 0-bits
+
+// Precondition: a != 0
+
+INT32
+__clzsi2(INT32 a)
+{
+ UINT32 x = (UINT32)a;
+ INT32 t = ((x & 0xFFFF0000) == 0) << 4; // if (x is small) t = 16 else 0
+ x >>= 16 - t; // x = [0 - 0xFFFF]
+ UINT32 r = t; // r = [0, 16]
+ // return r + clz(x)
+ t = ((x & 0xFF00) == 0) << 3;
+ x >>= 8 - t; // x = [0 - 0xFF]
+ r += t; // r = [0, 8, 16, 24]
+ // return r + clz(x)
+ t = ((x & 0xF0) == 0) << 2;
+ x >>= 4 - t; // x = [0 - 0xF]
+ r += t; // r = [0, 4, 8, 12, 16, 20, 24, 28]
+ // return r + clz(x)
+ t = ((x & 0xC) == 0) << 1;
+ x >>= 2 - t; // x = [0 - 3]
+ r += t; // r = [0 - 30] and is even
+ // return r + clz(x)
+// switch (x)
+// {
+// case 0:
+// return r + 2;
+// case 1:
+// return r + 1;
+// case 2:
+// case 3:
+// return r;
+// }
+ return r + ((2 - x) & -((x & 2) == 0));
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
new file mode 100644
index 0000000..108072e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__ctzsi2)
+
+ASM_PFX(__ctzsi2):
+ uxth r3, r0
+ cmp r3, #0
+ moveq ip, #16
+ movne ip, #0
+ @ lr needed for prologue
+ mov r0, r0, lsr ip
+ tst r0, #255
+ movne r3, #0
+ moveq r3, #8
+ mov r0, r0, lsr r3
+ tst r0, #15
+ movne r1, #0
+ moveq r1, #4
+ add r3, r3, ip
+ mov r0, r0, lsr r1
+ tst r0, #3
+ movne r2, #0
+ moveq r2, #2
+ add r3, r3, r1
+ mov r0, r0, lsr r2
+ and r0, r0, #3
+ add r2, r3, r2
+ eor r3, r0, #1
+ mov r0, r0, lsr #1
+ ands r3, r3, #1
+ mvnne r3, #0
+ rsb r0, r0, #2
+ and r0, r3, r0
+ add r0, r2, r0
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c
new file mode 100644
index 0000000..12cad92
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c
@@ -0,0 +1,98 @@
+/** @file
+ Compiler intrinsic to return the number of trailing zeros, ported from LLVM code.
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+// Returns: the number of trailing 0-bits
+
+// Precondition: a != 0
+
+INT32
+__ctzsi2(INT32 a)
+{
+ UINT32 x = (UINT32)a;
+ INT32 t = ((x & 0x0000FFFF) == 0) << 4; // if (x has no small bits) t = 16 else 0
+ x >>= t; // x = [0 - 0xFFFF] + higher garbage bits
+ UINT32 r = t; // r = [0, 16]
+ // return r + ctz(x)
+ t = ((x & 0x00FF) == 0) << 3;
+ x >>= t; // x = [0 - 0xFF] + higher garbage bits
+ r += t; // r = [0, 8, 16, 24]
+ // return r + ctz(x)
+ t = ((x & 0x0F) == 0) << 2;
+ x >>= t; // x = [0 - 0xF] + higher garbage bits
+ r += t; // r = [0, 4, 8, 12, 16, 20, 24, 28]
+ // return r + ctz(x)
+ t = ((x & 0x3) == 0) << 1;
+ x >>= t;
+ x &= 3; // x = [0 - 3]
+ r += t; // r = [0 - 30] and is even
+ // return r + ctz(x)
+// The branch-less return statement below is equivalent
+// to the following switch statement:
+// switch (x)
+// {
+// case 0:
+// return r + 2;
+// case 2:
+// return r + 1;
+// case 1:
+// case 3:
+// return r;
+// }
+ return r + ((2 - (x >> 1)) & -((x & 1) == 0));
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S
new file mode 100644
index 0000000..faf70db
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S
@@ -0,0 +1,153 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2011, ARM. 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+GCC_ASM_EXPORT(__aeabi_uidiv)
+GCC_ASM_EXPORT(__aeabi_uidivmod)
+GCC_ASM_EXPORT(__aeabi_idiv)
+GCC_ASM_EXPORT(__aeabi_idivmod)
+
+# AREA Math, CODE, READONLY
+
+#
+#UINT32
+#EFIAPI
+#__aeabi_uidivmode (
+# IN UINT32 Dividen
+# IN UINT32 Divisor
+# );
+#
+
+ASM_PFX(__aeabi_uidiv):
+ASM_PFX(__aeabi_uidivmod):
+ rsbs r12, r1, r0, LSR #4
+ mov r2, #0
+ bcc ASM_PFX(__arm_div4)
+ rsbs r12, r1, r0, LSR #8
+ bcc ASM_PFX(__arm_div8)
+ mov r3, #0
+ b ASM_PFX(__arm_div_large)
+
+#
+#INT32
+#EFIAPI
+#__aeabi_idivmode (
+# IN INT32 Dividen
+# IN INT32 Divisor
+# );
+#
+ASM_PFX(__aeabi_idiv):
+ASM_PFX(__aeabi_idivmod):
+ orrs r12, r0, r1
+ bmi ASM_PFX(__arm_div_negative)
+ rsbs r12, r1, r0, LSR #1
+ mov r2, #0
+ bcc ASM_PFX(__arm_div1)
+ rsbs r12, r1, r0, LSR #4
+ bcc ASM_PFX(__arm_div4)
+ rsbs r12, r1, r0, LSR #8
+ bcc ASM_PFX(__arm_div8)
+ mov r3, #0
+ b ASM_PFX(__arm_div_large)
+ASM_PFX(__arm_div8):
+ rsbs r12, r1, r0, LSR #7
+ subcs r0, r0, r1, LSL #7
+ adc r2, r2, r2
+ rsbs r12, r1, r0,LSR #6
+ subcs r0, r0, r1, LSL #6
+ adc r2, r2, r2
+ rsbs r12, r1, r0, LSR #5
+ subcs r0, r0, r1, LSL #5
+ adc r2, r2, r2
+ rsbs r12, r1, r0, LSR #4
+ subcs r0, r0, r1, LSL #4
+ adc r2, r2, r2
+ASM_PFX(__arm_div4):
+ rsbs r12, r1, r0, LSR #3
+ subcs r0, r0, r1, LSL #3
+ adc r2, r2, r2
+ rsbs r12, r1, r0, LSR #2
+ subcs r0, r0, r1, LSL #2
+ adcs r2, r2, r2
+ rsbs r12, r1, r0, LSR #1
+ subcs r0, r0, r1, LSL #1
+ adc r2, r2, r2
+ASM_PFX(__arm_div1):
+ subs r1, r0, r1
+ movcc r1, r0
+ adc r0, r2, r2
+ bx r14
+ASM_PFX(__arm_div_negative):
+ ands r2, r1, #0x80000000
+ rsbmi r1, r1, #0
+ eors r3, r2, r0, ASR #32
+ rsbcs r0, r0, #0
+ rsbs r12, r1, r0, LSR #4
+ bcc label1
+ rsbs r12, r1, r0, LSR #8
+ bcc label2
+ASM_PFX(__arm_div_large):
+ lsl r1, r1, #6
+ rsbs r12, r1, r0, LSR #8
+ orr r2, r2, #0xfc000000
+ bcc label2
+ lsl r1, r1, #6
+ rsbs r12, r1, r0, LSR #8
+ orr r2, r2, #0x3f00000
+ bcc label2
+ lsl r1, r1, #6
+ rsbs r12, r1, r0, LSR #8
+ orr r2, r2, #0xfc000
+ orrcs r2, r2, #0x3f00
+ lslcs r1, r1, #6
+ rsbs r12, r1, #0
+ bcs ASM_PFX(__aeabi_idiv0)
+label3:
+ lsrcs r1, r1, #6
+label2:
+ rsbs r12, r1, r0, LSR #7
+ subcs r0, r0, r1, LSL #7
+ adc r2, r2, r2
+ rsbs r12, r1, r0, LSR #6
+ subcs r0, r0, r1, LSL #6
+ adc r2, r2, r2
+ rsbs r12, r1, r0, LSR #5
+ subcs r0, r0, r1, LSL #5
+ adc r2, r2, r2
+ rsbs r12, r1, r0, LSR #4
+ subcs r0, r0, r1, LSL #4
+ adc r2, r2, r2
+label1:
+ rsbs r12, r1, r0, LSR #3
+ subcs r0, r0, r1, LSL #3
+ adc r2, r2, r2
+ rsbs r12, r1, r0, LSR #2
+ subcs r0, r0, r1, LSL #2
+ adcs r2, r2, r2
+ bcs label3
+ rsbs r12, r1, r0, LSR #1
+ subcs r0, r0, r1, LSL #1
+ adc r2, r2, r2
+ subs r1, r0, r1
+ movcc r1, r0
+ adc r0, r2, r2
+ asrs r3, r3, #31
+ rsbmi r0, r0, #0
+ rsbcs r1, r1, #0
+ bx r14
+
+ @ What to do about division by zero? For now, just return.
+ASM_PFX(__aeabi_idiv0):
+ bx r14
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
new file mode 100644
index 0000000..b539e51
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
@@ -0,0 +1,155 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_uidiv
+ EXPORT __aeabi_uidivmod
+ EXPORT __aeabi_idiv
+ EXPORT __aeabi_idivmod
+
+ AREA Math, CODE, READONLY
+
+;
+;UINT32
+;EFIAPI
+;__aeabi_uidivmode (
+; IN UINT32 Dividen
+; IN UINT32 Divisor
+; );
+;
+
+__aeabi_uidiv
+__aeabi_uidivmod
+ RSBS r12, r1, r0, LSR #4
+ MOV r2, #0
+ BCC __arm_div4
+ RSBS r12, r1, r0, LSR #8
+ BCC __arm_div8
+ MOV r3, #0
+ B __arm_div_large
+
+;
+;INT32
+;EFIAPI
+;__aeabi_idivmode (
+; IN INT32 Dividen
+; IN INT32 Divisor
+; );
+;
+__aeabi_idiv
+__aeabi_idivmod
+ ORRS r12, r0, r1
+ BMI __arm_div_negative
+ RSBS r12, r1, r0, LSR #1
+ MOV r2, #0
+ BCC __arm_div1
+ RSBS r12, r1, r0, LSR #4
+ BCC __arm_div4
+ RSBS r12, r1, r0, LSR #8
+ BCC __arm_div8
+ MOV r3, #0
+ B __arm_div_large
+__arm_div8
+ RSBS r12, r1, r0, LSR #7
+ SUBCS r0, r0, r1, LSL #7
+ ADC r2, r2, r2
+ RSBS r12, r1, r0,LSR #6
+ SUBCS r0, r0, r1, LSL #6
+ ADC r2, r2, r2
+ RSBS r12, r1, r0, LSR #5
+ SUBCS r0, r0, r1, LSL #5
+ ADC r2, r2, r2
+ RSBS r12, r1, r0, LSR #4
+ SUBCS r0, r0, r1, LSL #4
+ ADC r2, r2, r2
+__arm_div4
+ RSBS r12, r1, r0, LSR #3
+ SUBCS r0, r0, r1, LSL #3
+ ADC r2, r2, r2
+ RSBS r12, r1, r0, LSR #2
+ SUBCS r0, r0, r1, LSL #2
+ ADCS r2, r2, r2
+ RSBS r12, r1, r0, LSR #1
+ SUBCS r0, r0, r1, LSL #1
+ ADC r2, r2, r2
+__arm_div1
+ SUBS r1, r0, r1
+ MOVCC r1, r0
+ ADC r0, r2, r2
+ BX r14
+__arm_div_negative
+ ANDS r2, r1, #0x80000000
+ RSBMI r1, r1, #0
+ EORS r3, r2, r0, ASR #32
+ RSBCS r0, r0, #0
+ RSBS r12, r1, r0, LSR #4
+ BCC label1
+ RSBS r12, r1, r0, LSR #8
+ BCC label2
+__arm_div_large
+ LSL r1, r1, #6
+ RSBS r12, r1, r0, LSR #8
+ ORR r2, r2, #0xfc000000
+ BCC label2
+ LSL r1, r1, #6
+ RSBS r12, r1, r0, LSR #8
+ ORR r2, r2, #0x3f00000
+ BCC label2
+ LSL r1, r1, #6
+ RSBS r12, r1, r0, LSR #8
+ ORR r2, r2, #0xfc000
+ ORRCS r2, r2, #0x3f00
+ LSLCS r1, r1, #6
+ RSBS r12, r1, #0
+ BCS __aeabi_idiv0
+label3
+ LSRCS r1, r1, #6
+label2
+ RSBS r12, r1, r0, LSR #7
+ SUBCS r0, r0, r1, LSL #7
+ ADC r2, r2, r2
+ RSBS r12, r1, r0, LSR #6
+ SUBCS r0, r0, r1, LSL #6
+ ADC r2, r2, r2
+ RSBS r12, r1, r0, LSR #5
+ SUBCS r0, r0, r1, LSL #5
+ ADC r2, r2, r2
+ RSBS r12, r1, r0, LSR #4
+ SUBCS r0, r0, r1, LSL #4
+ ADC r2, r2, r2
+label1
+ RSBS r12, r1, r0, LSR #3
+ SUBCS r0, r0, r1, LSL #3
+ ADC r2, r2, r2
+ RSBS r12, r1, r0, LSR #2
+ SUBCS r0, r0, r1, LSL #2
+ ADCS r2, r2, r2
+ BCS label3
+ RSBS r12, r1, r0, LSR #1
+ SUBCS r0, r0, r1, LSL #1
+ ADC r2, r2, r2
+ SUBS r1, r0, r1
+ MOVCC r1, r0
+ ADC r0, r2, r2
+ ASRS r3, r3, #31
+ RSBMI r0, r0, #0
+ RSBCS r1, r1, #0
+ BX r14
+
+ ; What to do about division by zero? For now, just return.
+__aeabi_idiv0
+ BX r14
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
new file mode 100644
index 0000000..23c8e8f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__divdi3)
+
+ASM_PFX(__divdi3):
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 1, uses_anonymous_args = 0
+ stmfd sp!, {r4, r5, r7, lr}
+ mov r4, r3, asr #31
+ add r7, sp, #8
+ stmfd sp!, {r10, r11}
+ mov r10, r1, asr #31
+ sub sp, sp, #8
+ mov r11, r10
+ mov r5, r4
+ eor r0, r0, r10
+ eor r1, r1, r10
+ eor r2, r2, r4
+ eor r3, r3, r4
+ subs r2, r2, r4
+ sbc r3, r3, r5
+ mov ip, #0
+ subs r0, r0, r10
+ sbc r1, r1, r11
+ str ip, [sp, #0]
+ bl ASM_PFX(__udivmoddi4)
+ eor r2, r10, r4
+ eor r3, r10, r4
+ eor r0, r0, r2
+ eor r1, r1, r3
+ subs r0, r0, r2
+ sbc r1, r1, r3
+ sub sp, r7, #16
+ ldmfd sp!, {r10, r11}
+ ldmfd sp!, {r4, r5, r7, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c
new file mode 100644
index 0000000..c7916b8
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c
@@ -0,0 +1,77 @@
+/** @file
+ Compiler intrinsic for 64-bit compare, ported from LLVM code.
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+UINT64 __udivmoddi4(UINT64 a, UINT64 b, UINT64* rem);
+
+// Returns: a / b
+
+INT64
+__divdi3(INT64 a, INT64 b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(INT64) * CHAR_BIT) - 1;
+ INT64 s_a = a >> bits_in_dword_m1; // s_a = a < 0 ? -1 : 0
+ INT64 s_b = b >> bits_in_dword_m1; // s_b = b < 0 ? -1 : 0
+ a = (a ^ s_a) - s_a; // negate if s_a == -1
+ b = (b ^ s_b) - s_b; // negate if s_b == -1
+ s_a ^= s_b; // sign of quotient
+ return (__udivmoddi4(a, b, (UINT64*)0) ^ s_a) - s_a; // negate if s_a == -1
+}
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
new file mode 100644
index 0000000..d585146
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__divsi3)
+
+ASM_PFX(__divsi3):
+ eor r3, r0, r0, asr #31
+ eor r2, r1, r1, asr #31
+ stmfd sp!, {r4, r5, r7, lr}
+ mov r5, r0, asr #31
+ add r7, sp, #8
+ mov r4, r1, asr #31
+ sub r0, r3, r0, asr #31
+ sub r1, r2, r1, asr #31
+ bl ASM_PFX(__udivsi3)
+ eor r1, r5, r4
+ eor r0, r0, r1
+ rsb r0, r1, r0
+ ldmfd sp!, {r4, r5, r7, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c
new file mode 100644
index 0000000..24e43dd
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c
@@ -0,0 +1,78 @@
+/** @file
+ Compiler intrinsic for 32--bit unsigned division, ported from LLVM code.
+
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+UINT32 __udivsi3(UINT32 n, UINT32 d);
+
+// Returns: a / b
+
+INT32
+__divsi3(INT32 a, INT32 b)
+{
+ const int bits_in_word_m1 = (int)(sizeof(INT32) * CHAR_BIT) - 1;
+ INT32 s_a = a >> bits_in_word_m1; // s_a = a < 0 ? -1 : 0
+ INT32 s_b = b >> bits_in_word_m1; // s_b = b < 0 ? -1 : 0
+ a = (a ^ s_a) - s_a; // negate if s_a == -1
+ b = (b ^ s_b) - s_b; // negate if s_b == -1
+ s_a ^= s_b; // sign of quotient
+ return (__udivsi3(a, b) ^ s_a) - s_a; // negate if s_a == -1
+}
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm
new file mode 100644
index 0000000..feb267a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm
@@ -0,0 +1,41 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_lasr
+
+ AREA Math, CODE, READONLY
+
+;
+;UINT32
+;EFIAPI
+;__aeabi_lasr (
+; IN UINT32 Dividen
+; IN UINT32 Divisor
+; );
+;
+__aeabi_lasr
+ SUBS r3,r2,#0x20
+ BPL {pc} + 0x18 ; 0x1c
+ RSB r3,r2,#0x20
+ LSR r0,r0,r2
+ ORR r0,r0,r1,LSL r3
+ ASR r1,r1,r2
+ BX lr
+ ASR r0,r1,r3
+ ASR r1,r1,#31
+ BX lr
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
new file mode 100755
index 0000000..e7a05de
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
@@ -0,0 +1,59 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__aeabi_ldivmod)
+
+//
+// A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}},
+// the quotient in {r0, r1}, and the remainder in {r2, r3}.
+//
+//__value_in_regs lldiv_t
+//EFIAPI
+//__aeabi_ldivmod (
+// IN UINT64 Dividen
+// IN UINT64 Divisor
+// )//
+//
+
+ASM_PFX(__aeabi_ldivmod):
+ push {r4,lr}
+ asrs r4,r1,#1
+ eor r4,r4,r3,LSR #1
+ bpl L_Test1
+ rsbs r0,r0,#0
+ rsc r1,r1,#0
+L_Test1:
+ tst r3,r3
+ bpl L_Test2
+ rsbs r2,r2,#0
+ rsc r3,r3,#0
+L_Test2:
+ bl ASM_PFX(__aeabi_uldivmod)
+ tst r4,#0x40000000
+ beq L_Test3
+ rsbs r0,r0,#0
+ rsc r1,r1,#0
+L_Test3:
+ tst r4,#0x80000000
+ beq L_Exit
+ rsbs r2,r2,#0
+ rsc r3,r3,#0
+L_Exit:
+ pop {r4,pc}
+
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
new file mode 100644
index 0000000..9c14e89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
@@ -0,0 +1,58 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_ldivmod
+ EXTERN __aeabi_uldivmod
+
+ AREA Math, CODE, READONLY
+
+;
+;UINT32
+;EFIAPI
+;__aeabi_uidivmode (
+; IN UINT32 Dividen
+; IN UINT32 Divisor
+; );
+;
+
+__aeabi_ldivmod
+ PUSH {r4,lr}
+ ASRS r4,r1,#1
+ EOR r4,r4,r3,LSR #1
+ BPL L_Test1
+ RSBS r0,r0,#0
+ RSC r1,r1,#0
+L_Test1
+ TST r3,r3
+ BPL L_Test2
+ RSBS r2,r2,#0
+ RSC r3,r3,#0
+L_Test2
+ BL __aeabi_uldivmod ;
+ TST r4,#0x40000000
+ BEQ L_Test3
+ RSBS r0,r0,#0
+ RSC r1,r1,#0
+L_Test3
+ TST r4,#0x80000000
+ BEQ L_Exit
+ RSBS r2,r2,#0
+ RSC r3,r3,#0
+L_Exit
+ POP {r4,pc}
+
+ END
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S
new file mode 100644
index 0000000..ba8ab1c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013, ARM. 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.
+#
+#------------------------------------------------------------------------------
+
+
+.text
+.align 2
+GCC_ASM_EXPORT(__aeabi_llsl)
+
+#
+#VOID
+#EFIAPI
+#__aeabi_llsl (
+# IN VOID *Destination,
+# IN VOID *Source,
+# IN UINT32 Size
+# );
+#
+ASM_PFX(__aeabi_llsl):
+ subs r3,r2,#0x20
+ bpl 1f
+ rsb r3,r2,#0x20
+ lsl r1,r1,r2
+ orr r1,r1,r0,lsr r3
+ lsl r0,r0,r2
+ bx lr
+1:
+ lsl r1,r0,r3
+ mov r0,#0
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm
new file mode 100644
index 0000000..f6fc208
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_llsl
+
+ AREA Math, CODE, READONLY
+
+;
+;VOID
+;EFIAPI
+;__aeabi_llsl (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINT32 Size
+; );
+;
+
+__aeabi_llsl
+ SUBS r3,r2,#0x20
+ BPL {pc} + 0x18 ; 0x1c
+ RSB r3,r2,#0x20
+ LSL r1,r1,r2
+ ORR r1,r1,r0,LSR r3
+ LSL r0,r0,r2
+ BX lr
+ LSL r1,r0,r3
+ MOV r0,#0
+ BX lr
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S
new file mode 100644
index 0000000..3d2c106
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013, ARM. 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.
+#
+#------------------------------------------------------------------------------
+
+
+.text
+.align 2
+GCC_ASM_EXPORT(__aeabi_llsr)
+
+#
+#VOID
+#EFIAPI
+#__aeabi_llsr (
+# IN VOID *Destination,
+# IN VOID *Source,
+# IN UINT32 Size
+# );
+#
+ASM_PFX(__aeabi_llsr):
+ subs r3,r2,#0x20
+ bpl 1f
+ rsb r3,r2,#0x20
+ lsr r0,r0,r2
+ orr r0,r0,r1,lsl r3
+ lsr r1,r1,r2
+ bx lr
+1:
+ lsr r0,r1,r3
+ mov r1,#0
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
new file mode 100644
index 0000000..829c871
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_llsr
+
+ AREA Math, CODE, READONLY
+
+;
+;VOID
+;EFIAPI
+;__aeabi_llsr (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINT32 Size
+; );
+;
+__aeabi_llsr
+ SUBS r3,r2,#0x20
+ BPL {pc} + 0x18 ; 0x1c
+ RSB r3,r2,#0x20
+ LSR r0,r0,r2
+ ORR r0,r0,r1,LSL r3
+ LSR r1,r1,r2
+ BX lr
+ LSR r0,r1,r3
+ MOV r1,#0
+ BX lr
+
+ END
+
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
new file mode 100644
index 0000000..a313320
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__lshrdi3)
+
+ASM_PFX(__lshrdi3):
+ cmp r2, #31
+ bls L2
+ cmp r2, #63
+ subls r2, r2, #32
+ movls r2, r1, lsr r2
+ movhi r2, #0
+ mov r0, r2
+ mov r1, #0
+ bx lr
+L2:
+ cmp r2, #0
+ rsbne r3, r2, #32
+ movne r3, r1, asl r3
+ movne r1, r1, lsr r2
+ orrne r0, r3, r0, lsr r2
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c
new file mode 100644
index 0000000..2175cd9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c
@@ -0,0 +1,83 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+#include "Llvm_int_lib.h"
+
+// Returns: logical a >> b
+
+// Precondition: 0 <= b < bits_in_dword
+
+INT64
+__lshrdi3(INT64 a, INT32 b)
+{
+ const int bits_in_word = (int)(sizeof(INT32) * CHAR_BIT);
+ udwords input;
+ udwords result;
+ input.all = a;
+ if (b & bits_in_word) // bits_in_word <= b < bits_in_dword
+ {
+ result.high = 0;
+ result.low = input.high >> (b - bits_in_word);
+ }
+ else // 0 <= b < bits_in_word
+ {
+ if (b == 0)
+ return a;
+ result.high = input.high >> b;
+ result.low = (input.high << (bits_in_word - b)) | (input.low >> b);
+ }
+ return result.all;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S
new file mode 100644
index 0000000..b68ed8a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__aeabi_memcpy)
+ GCC_ASM_EXPORT(memcpy)
+
+ASM_PFX(__aeabi_memcpy):
+ASM_PFX(memcpy):
+ cmp r2, #0
+ bxeq lr
+ push {lr}
+ mov lr, r0
+L5:
+ ldrb r3, [r1], #1 @ zero_extendqisi2
+ strb r3, [lr], #1
+ subs r2, r2, #1
+ bne L5
+ pop {pc}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm
new file mode 100644
index 0000000..60556b1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm
@@ -0,0 +1,41 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_memcpy
+
+ AREA Memcpy, CODE, READONLY
+
+;
+;VOID
+;EFIAPI
+;__aeabi_memcpy (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINT32 Size
+; );
+;
+__aeabi_memcpy
+ cmp r2, #0
+ bxeq lr
+ push {lr}
+ mov lr, r0
+L5
+ ldrb r3, [r1], #1
+ strb r3, [lr], #1
+ subs r2, r2, #1
+ bne L5
+ pop {pc}
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm
new file mode 100644
index 0000000..ecaa86f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_memcpy4
+
+ AREA Memcpy4, CODE, READONLY
+
+;
+;VOID
+;EFIAPI
+;__aeabi_memcpy (
+; IN VOID *Destination,
+; IN VOID *Source,
+; IN UINT32 Size
+; );
+;
+__aeabi_memcpy4
+ stmdb sp!, {r4, lr}
+ subs r2, r2, #32 ; 0x20
+ bcc memcpy4_label2
+memcpy4_label1
+ ldmcsia r1!, {r3, r4, ip, lr}
+ stmcsia r0!, {r3, r4, ip, lr}
+ ldmcsia r1!, {r3, r4, ip, lr}
+ stmcsia r0!, {r3, r4, ip, lr}
+ subcss r2, r2, #32 ; 0x20
+ bcs memcpy4_label1
+memcpy4_label2
+ movs ip, r2, lsl #28
+ ldmcsia r1!, {r3, r4, ip, lr}
+ stmcsia r0!, {r3, r4, ip, lr}
+ ldmmiia r1!, {r3, r4}
+ stmmiia r0!, {r3, r4}
+ ldmia sp!, {r4, lr}
+ movs ip, r2, lsl #30
+ ldrcs r3, [r1], #4
+ strcs r3, [r0], #4
+ bxeq lr
+
+_memcpy4_lastbytes_aligned
+ movs r2, r2, lsl #31
+ ldrcsh r3, [r1], #2
+ ldrmib r2, [r1], #1
+ strcsh r3, [r0], #2
+ strmib r2, [r0], #1
+ bx lr
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S
new file mode 100644
index 0000000..79f95b0
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S
@@ -0,0 +1,48 @@
+#------------------------------------------------------------------------------
+#
+# 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT (memmove)
+
+# VOID
+# EFIAPI
+# memmove (
+# IN VOID *Destination,
+# IN CONST VOID *Source,
+# IN UINT32 Size
+# );
+ASM_PFX(memmove):
+ CMP r2, #0
+ BXEQ lr
+ CMP r0, r1
+ BXEQ lr
+ BHI memmove_backward
+
+memmove_forward:
+ LDRB r3, [r1], #1
+ STRB r3, [r0], #1
+ SUBS r2, r2, #1
+ BXEQ lr
+ B memmove_forward
+
+memmove_backward:
+ add r0, r2
+ add r1, r2
+memmove_backward_loop:
+ LDRB r3, [r1, #-1]!
+ STRB r3, [r0, #-1]!
+ SUBS r2, r2, #1
+ BXEQ lr
+ B memmove_backward_loop
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.asm
new file mode 100755
index 0000000..2147e29
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.asm
@@ -0,0 +1,53 @@
+//------------------------------------------------------------------------------
+//
+// 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_memmove
+
+ AREA Memmove, CODE, READONLY
+
+;
+;VOID
+;EFIAPI
+;__aeabi_memmove (
+; IN VOID *Destination,
+; IN CONST VOID *Source,
+; IN UINT32 Size
+; );
+;
+__aeabi_memmove
+ CMP r2, #0
+ BXEQ lr
+ CMP r0, r1
+ BXEQ lr
+ BHI memmove_backward
+
+memmove_forward
+ LDRB r3, [r1], #1
+ STRB r3, [r0], #1
+ SUBS r2, r2, #1
+ BNE memmove_forward
+ BX lr
+
+memmove_backward
+ add r0, r2
+ add r1, r2
+memmove_backward_loop
+ LDRB r3, [r1, #-1]!
+ STRB r3, [r0, #-1]!
+ SUBS r2, r2, #1
+ BNE memmove_backward_loop
+ BX lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S
new file mode 100644
index 0000000..0c7789e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT (memset)
+
+# VOID
+# EFIAPI
+# memset (
+# IN VOID *Destination,
+# IN UINT32 Character,
+# IN UINT32 Size
+# );
+ASM_PFX(memset):
+ cmp r2, #0
+ bxeq lr
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 1, uses_anonymous_args = 0
+L10:
+ strb r1, [r0], #1
+ subs r2, r2, #1
+ @ While size is not 0
+ bne L10
+ bx lr
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.asm
new file mode 100755
index 0000000..bae3c1f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.asm
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+// Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_memset
+ EXPORT __aeabi_memclr
+ EXPORT __aeabi_memclr4
+
+ AREA Memset, CODE, READONLY
+
+; void __aeabi_memclr4(void *dest, size_t n);
+; void __aeabi_memclr(void *dest, size_t n);
+__aeabi_memclr
+__aeabi_memclr4
+ mov r2, #0
+
+;
+;VOID
+;EFIAPI
+;__aeabi_memset (
+; IN VOID *Destination,
+; IN UINT32 Size,
+; IN UINT32 Character
+; );
+;
+__aeabi_memset
+ cmp r1, #0
+ bxeq lr
+ ; args = 0, pretend = 0, frame = 0
+ ; frame_needed = 1, uses_anonymous_args = 0
+L10
+ strb r2, [r0], #1
+ subs r1, r1, #1
+ ; While size is not 0
+ bne L10
+ bx lr
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
new file mode 100644
index 0000000..7b618eb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__moddi3)
+
+ASM_PFX(__moddi3):
+ stmfd sp!, {r4, r5, r7, lr}
+ mov r4, r1, asr #31
+ add r7, sp, #8
+ stmfd sp!, {r10, r11}
+ mov r10, r3, asr #31
+ sub sp, sp, #16
+ mov r5, r4
+ mov r11, r10
+ eor r0, r0, r4
+ eor r1, r1, r4
+ eor r2, r2, r10
+ eor r3, r3, r10
+ add ip, sp, #8
+ subs r0, r0, r4
+ sbc r1, r1, r5
+ subs r2, r2, r10
+ sbc r3, r3, r11
+ str ip, [sp, #0]
+ bl ASM_PFX(__udivmoddi4)
+ ldrd r0, [sp, #8]
+ eor r0, r0, r4
+ eor r1, r1, r4
+ subs r0, r0, r4
+ sbc r1, r1, r5
+ sub sp, r7, #16
+ ldmfd sp!, {r10, r11}
+ ldmfd sp!, {r4, r5, r7, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c
new file mode 100644
index 0000000..04562de
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c
@@ -0,0 +1,77 @@
+/** @file
+ Compiler intrinsic for 64-bit mod, ported from LLVM code.
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+UINT64 __udivmoddi4(UINT64 a, UINT64 b, UINT64* rem);
+
+// Returns: a % b
+
+INT64
+__moddi3(INT64 a, INT64 b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(INT64) * CHAR_BIT) - 1;
+ INT64 s = b >> bits_in_dword_m1; // s = b < 0 ? -1 : 0
+ b = (b ^ s) - s; // negate if s == -1
+ s = a >> bits_in_dword_m1; // s = a < 0 ? -1 : 0
+ a = (a ^ s) - s; // negate if s == -1
+ INT64 r;
+ __udivmoddi4(a, b, (UINT64*)&r);
+ return (r ^ s) - s; // negate if s == -1
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
new file mode 100644
index 0000000..047501e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
@@ -0,0 +1,27 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__modsi3)
+
+ASM_PFX(__modsi3):
+ stmfd sp!, {r4, r5, r7, lr}
+ add r7, sp, #8
+ mov r5, r0
+ mov r4, r1
+ bl ___divsi3
+ mul r0, r4, r0
+ rsb r0, r0, r5
+ ldmfd sp!, {r4, r5, r7, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c
new file mode 100644
index 0000000..91ee6aa
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c
@@ -0,0 +1,70 @@
+/** @file
+ Compiler intrinsic for 32-bit mod, ported from LLVM code.
+
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+// Returns: a % b
+
+INT32
+__modsi3(INT32 a, INT32 b)
+{
+ return a - (a / b) * b;
+}
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
new file mode 100644
index 0000000..dff61ef
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
@@ -0,0 +1,58 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__muldi3)
+
+ASM_PFX(__muldi3):
+ stmfd sp!, {r4, r5, r6, r7, lr}
+ add r7, sp, #12
+ stmfd sp!, {r8, r10, r11}
+ ldr r11, L4
+ mov r4, r0, lsr #16
+ and r8, r0, r11
+ and ip, r2, r11
+ mul lr, ip, r8
+ mul ip, r4, ip
+ sub sp, sp, #8
+ add r10, ip, lr, lsr #16
+ and ip, r10, r11
+ and lr, lr, r11
+ mov r6, r2, lsr #16
+ str r4, [sp, #4]
+ add r4, lr, ip, asl #16
+ mul ip, r8, r6
+ mov r5, r10, lsr #16
+ add r10, ip, r4, lsr #16
+ and ip, r10, r11
+ and lr, r4, r11
+ add r4, lr, ip, asl #16
+ mul r0, r3, r0
+ add ip, r5, r10, lsr #16
+ ldr r5, [sp, #4]
+ mla r0, r2, r1, r0
+ mla r5, r6, r5, ip
+ mov r10, r4
+ add r11, r0, r5
+ mov r1, r11
+ mov r0, r4
+ sub sp, r7, #24
+ ldmfd sp!, {r8, r10, r11}
+ ldmfd sp!, {r4, r5, r6, r7, pc}
+ .p2align 2
+L5:
+ .align 2
+L4:
+ .long 65535
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c
new file mode 100644
index 0000000..dbdda86
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c
@@ -0,0 +1,98 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+#include <Base.h>
+#include "Llvm_int_lib.h"
+
+
+// Returns: a * b
+
+static
+INT64
+__muldsi3(UINT32 a, UINT32 b)
+{
+ dwords r;
+ const int bits_in_word_2 = (int)(sizeof(INT32) * CHAR_BIT) / 2;
+ const UINT32 lower_mask = (UINT32)~0 >> bits_in_word_2;
+ r.low = (a & lower_mask) * (b & lower_mask);
+ UINT32 t = r.low >> bits_in_word_2;
+ r.low &= lower_mask;
+ t += (a >> bits_in_word_2) * (b & lower_mask);
+ r.low += (t & lower_mask) << bits_in_word_2;
+ r.high = t >> bits_in_word_2;
+ t = r.low >> bits_in_word_2;
+ r.low &= lower_mask;
+ t += (b >> bits_in_word_2) * (a & lower_mask);
+ r.low += (t & lower_mask) << bits_in_word_2;
+ r.high += t >> bits_in_word_2;
+ r.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);
+ return r.all;
+}
+
+// Returns: a * b
+
+INT64
+__muldi3(INT64 a, INT64 b)
+{
+ dwords x;
+ x.all = a;
+ dwords y;
+ y.all = b;
+ dwords r;
+ r.all = __muldsi3(x.low, y.low);
+ r.high += x.high * y.low + x.low * y.high;
+ return r.all;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S
new file mode 100644
index 0000000..e653559
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+.text
+
+GCC_ASM_EXPORT(__ARM_ll_mullu)
+GCC_ASM_EXPORT(__aeabi_lmul)
+#
+#INT64
+#EFIAPI
+#__aeabi_lmul (
+# IN INT64 Multiplicand
+# IN INT32 Multiplier
+# );
+#
+ASM_PFX(__ARM_ll_mullu):
+ mov r3, #0
+# Make upper part of INT64 Multiplier 0 and use __aeabi_lmul
+
+#
+#INT64
+#EFIAPI
+#__aeabi_lmul (
+# IN INT64 Multiplicand
+# IN INT64 Multiplier
+# );
+#
+ASM_PFX(__aeabi_lmul):
+ stmdb sp!, {lr}
+ mov lr, r0
+ umull r0, ip, r2, lr
+ mla r1, r2, r1, ip
+ mla r1, r3, lr, r1
+ ldmia sp!, {pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm
new file mode 100644
index 0000000..3451c2c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __ARM_ll_mullu
+ EXPORT __aeabi_lmul
+
+ AREA Math, CODE, READONLY
+
+;
+;INT64
+;EFIAPI
+;__aeabi_lmul (
+; IN INT64 Multiplicand
+; IN INT32 Multiplier
+; );
+;
+__ARM_ll_mullu
+ mov r3, #0
+// Make upper part of INT64 Multiplier 0 and use __aeabi_lmul
+
+;
+;INT64
+;EFIAPI
+;__aeabi_lmul (
+; IN INT64 Multiplicand
+; IN INT64 Multiplier
+; );
+;
+__aeabi_lmul
+ stmdb sp!, {lr}
+ mov lr, r0
+ umull r0, ip, r2, lr
+ mla r1, r2, r1, ip
+ mla r1, r3, lr, r1
+ ldmia sp!, {pc}
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
new file mode 100755
index 0000000..1e0b524
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
@@ -0,0 +1,55 @@
+#------s------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__aeabi_ulcmp)
+
+ASM_PFX(__aeabi_ulcmp):
+ stmfd sp!, {r4, r5, r8}
+ cmp r3, r1
+ mov r8, r0
+ mov r9, r1
+ mov r4, r2
+ mov r5, r3
+ bls L16
+L2:
+ mvn r0, #0
+L1:
+ ldmfd sp!, {r4, r5, r8}
+ bx lr
+L16:
+ beq L17
+L4:
+ cmp r9, r5
+ bhi L7
+ beq L18
+ cmp r8, r4
+L14:
+ cmpeq r9, r5
+ moveq r0, #0
+ beq L1
+ b L1
+L18:
+ cmp r8, r4
+ bls L14
+L7:
+ mov r0, #1
+ b L1
+L17:
+ cmp r2, r0
+ bhi L2
+ b L4
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm
new file mode 100644
index 0000000..e09c90c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm
@@ -0,0 +1,29 @@
+///------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+
+ EXPORT __ARM_switch8
+
+ AREA ArmSwitch, CODE, READONLY
+
+__ARM_switch8
+ LDRB r12,[lr,#-1]
+ CMP r3,r12
+ LDRBCC r3,[lr,r3]
+ LDRBCS r3,[lr,r12]
+ ADD r12,lr,r3,LSL #1
+ BX r12
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
new file mode 100644
index 0000000..7f41353
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
@@ -0,0 +1,31 @@
+#/** @file
+# Compiler intrinsic for ARM compiler
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.;
+#
+#**/
+#
+
+.text
+.p2align 2
+
+GCC_ASM_EXPORT(__switch16)
+
+ASM_PFX(__switch16):
+ ldrh ip, [lr, #-1]
+ cmp r0, ip
+ add r0, lr, r0, lsl #1
+ ldrccsh r0, [r0, #1]
+ add ip, lr, ip, lsl #1
+ ldrcssh r0, [ip, #1]
+ add ip, lr, r0, lsl #1
+ bx ip
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
new file mode 100644
index 0000000..8675a4a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
@@ -0,0 +1,30 @@
+#/** @file
+# Compiler intrinsic for ARM compiler
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.;
+#
+#**/
+#
+
+.text
+.p2align 2
+
+GCC_ASM_EXPORT(__switch32)
+
+ASM_PFX(__switch32):
+ ldr ip, [lr, #-1]
+ cmp r0, ip
+ add r0, lr, r0, lsl #2
+ ldrcc r0, [r0, #3]
+ add ip, lr, ip, lsl #2
+ ldrcs r0, [ip, #3]
+ add ip, lr, r0
+ bx ip
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
new file mode 100644
index 0000000..27edccb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
@@ -0,0 +1,28 @@
+#/** @file
+# Compiler intrinsic for ARM compiler
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.;
+#
+#**/
+#
+
+.text
+.p2align 2
+
+GCC_ASM_EXPORT(__switch8)
+
+ASM_PFX(__switch8):
+ ldrb ip, [lr, #-1]
+ cmp r0, ip
+ ldrccsb r0, [lr, r0]
+ ldrcssb r0, [lr, ip]
+ add ip, lr, r0, lsl #1
+ bx ip
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
new file mode 100644
index 0000000..39c4a7f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
@@ -0,0 +1,29 @@
+#/** @file
+# Compiler intrinsic for ARM compiler
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.;
+#
+#**/
+#
+
+.text
+.p2align 2
+
+GCC_ASM_EXPORT(__switchu8)
+
+
+ASM_PFX(__switchu8):
+ ldrb ip,[lr,#-1]
+ cmp r0,ip
+ ldrccb r0,[lr,r0]
+ ldrcsb r0,[lr,ip]
+ add ip,lr,r0,LSL #1
+ bx ip
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
new file mode 100644
index 0000000..da57423
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__ucmpdi2)
+
+ASM_PFX(__ucmpdi2):
+ stmfd sp!, {r4, r5, r8, lr}
+ cmp r1, r3
+ mov r8, r0
+ mov r4, r2
+ mov r5, r3
+ bcc L2
+ bhi L4
+ cmp r0, r2
+ bcc L2
+ movls r0, #1
+ bls L8
+ b L4
+L2:
+ mov r0, #0
+ b L8
+L4:
+ mov r0, #2
+L8:
+ ldmfd sp!, {r4, r5, r8, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c
new file mode 100644
index 0000000..aa03a3d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c
@@ -0,0 +1,82 @@
+/** @file
+ Compiler intrinsic for 64-bit compare, ported from LLVM code.
+
+ Copyright (c) 2008-2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+
+// Returns: if (a < b) returns 0
+// if (a == b) returns 1
+// if (a > b) returns 2
+
+UINT32
+__ucmpdi2(UINT64 a, UINT64 b)
+{
+ udwords x;
+ x.all = a;
+ udwords y;
+ y.all = b;
+ if (x.high < y.high)
+ return 0;
+ if (x.high > y.high)
+ return 2;
+ if (x.low < y.low)
+ return 0;
+ if (x.low > y.low)
+ return 2;
+ return 1;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
new file mode 100644
index 0000000..cbfb127
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
@@ -0,0 +1,27 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__udivdi3)
+
+ASM_PFX(__udivdi3):
+ stmfd sp!, {r7, lr}
+ add r7, sp, #0
+ sub sp, sp, #8
+ mov ip, #0
+ str ip, [sp, #0]
+ bl ASM_PFX(__udivmoddi4)
+ sub sp, r7, #0
+ ldmfd sp!, {r7, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c
new file mode 100644
index 0000000..fc383b4
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c
@@ -0,0 +1,71 @@
+/** @file
+ Compiler intrinsic for 64-bit unisigned div, ported from LLVM code.
+
+ Copyright (c) 2008-2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+UINT64 __udivmoddi4 (UINT64 a, UINT64 b, UINT64 *rem);
+
+// Returns: a / b
+
+UINT64
+__udivdi3(UINT64 a, UINT64 b)
+{
+ return __udivmoddi4(a, b, 0);
+}
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
new file mode 100644
index 0000000..4c0ef5a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
@@ -0,0 +1,242 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__udivmoddi4)
+
+ASM_PFX(__udivmoddi4):
+ stmfd sp!, {r4, r5, r6, r7, lr}
+ add r7, sp, #12
+ stmfd sp!, {r10, r11}
+ sub sp, sp, #20
+ stmia sp, {r2-r3}
+ ldr r6, [sp, #48]
+ orrs r2, r2, r3
+ mov r10, r0
+ mov r11, r1
+ beq L2
+ subs ip, r1, #0
+ bne L4
+ cmp r3, #0
+ bne L6
+ cmp r6, #0
+ beq L8
+ mov r1, r2
+ bl ASM_PFX(__umodsi3)
+ mov r1, #0
+ stmia r6, {r0-r1}
+L8:
+ ldr r1, [sp, #0]
+ mov r0, r10
+ b L45
+L6:
+ cmp r6, #0
+ movne r1, #0
+ stmneia r6, {r0-r1}
+ b L2
+L4:
+ ldr r1, [sp, #0]
+ cmp r1, #0
+ bne L12
+ ldr r2, [sp, #4]
+ cmp r2, #0
+ bne L14
+ cmp r6, #0
+ beq L16
+ mov r1, r2
+ mov r0, r11
+ bl ASM_PFX(__umodsi3)
+ mov r1, #0
+ stmia r6, {r0-r1}
+L16:
+ ldr r1, [sp, #4]
+ mov r0, r11
+L45:
+ bl ASM_PFX(__udivsi3)
+L46:
+ mov r10, r0
+ mov r11, #0
+ b L10
+L14:
+ subs r1, r0, #0
+ bne L18
+ cmp r6, #0
+ beq L16
+ ldr r1, [sp, #4]
+ mov r0, r11
+ bl ASM_PFX(__umodsi3)
+ mov r4, r10
+ mov r5, r0
+ stmia r6, {r4-r5}
+ b L16
+L18:
+ sub r3, r2, #1
+ tst r2, r3
+ bne L22
+ cmp r6, #0
+ movne r4, r0
+ andne r5, ip, r3
+ stmneia r6, {r4-r5}
+L24:
+ rsb r3, r2, #0
+ and r3, r2, r3
+ clz r3, r3
+ rsb r3, r3, #31
+ mov r0, ip, lsr r3
+ b L46
+L22:
+ clz r2, r2
+ clz r3, ip
+ rsb r3, r3, r2
+ cmp r3, #30
+ bhi L48
+ rsb r2, r3, #31
+ add lr, r3, #1
+ mov r3, r1, asl r2
+ str r3, [sp, #12]
+ mov r3, r1, lsr lr
+ ldr r0, [sp, #0]
+ mov r5, ip, lsr lr
+ orr r4, r3, ip, asl r2
+ str r0, [sp, #8]
+ b L29
+L12:
+ ldr r3, [sp, #4]
+ cmp r3, #0
+ bne L30
+ sub r3, r1, #1
+ tst r1, r3
+ bne L32
+ cmp r6, #0
+ andne r3, r3, r0
+ movne r2, r3
+ movne r3, #0
+ stmneia r6, {r2-r3}
+L34:
+ cmp r1, #1
+ beq L10
+ rsb r3, r1, #0
+ and r3, r1, r3
+ clz r3, r3
+ rsb r0, r3, #31
+ mov r1, ip, lsr r0
+ rsb r3, r0, #32
+ mov r0, r10, lsr r0
+ orr ip, r0, ip, asl r3
+ str r1, [sp, #12]
+ str ip, [sp, #8]
+ ldrd r10, [sp, #8]
+ b L10
+L32:
+ clz r2, r1
+ clz r3, ip
+ rsb r3, r3, r2
+ rsb r4, r3, #31
+ mov r2, r0, asl r4
+ mvn r1, r3
+ and r2, r2, r1, asr #31
+ add lr, r3, #33
+ str r2, [sp, #8]
+ add r2, r3, #1
+ mov r3, r3, asr #31
+ and r0, r3, r0, asl r1
+ mov r3, r10, lsr r2
+ orr r3, r3, ip, asl r4
+ and r3, r3, r1, asr #31
+ orr r0, r0, r3
+ mov r3, ip, lsr lr
+ str r0, [sp, #12]
+ mov r0, r10, lsr lr
+ and r5, r3, r2, asr #31
+ rsb r3, lr, #31
+ mov r3, r3, asr #31
+ orr r0, r0, ip, asl r1
+ and r3, r3, ip, lsr r2
+ and r0, r0, r2, asr #31
+ orr r4, r3, r0
+ b L29
+L30:
+ clz r2, r3
+ clz r3, ip
+ rsb r3, r3, r2
+ cmp r3, #31
+ bls L37
+L48:
+ cmp r6, #0
+ stmneia r6, {r10-r11}
+ b L2
+L37:
+ rsb r1, r3, #31
+ mov r0, r0, asl r1
+ add lr, r3, #1
+ mov r2, #0
+ str r0, [sp, #12]
+ mov r0, r10, lsr lr
+ str r2, [sp, #8]
+ sub r2, r3, #31
+ and r0, r0, r2, asr #31
+ mov r3, ip, lsr lr
+ orr r4, r0, ip, asl r1
+ and r5, r3, r2, asr #31
+L29:
+ mov ip, #0
+ mov r10, ip
+ b L40
+L41:
+ ldr r1, [sp, #12]
+ ldr r2, [sp, #8]
+ mov r3, r4, lsr #31
+ orr r5, r3, r5, asl #1
+ mov r3, r1, lsr #31
+ orr r4, r3, r4, asl #1
+ mov r3, r2, lsr #31
+ orr r0, r3, r1, asl #1
+ orr r1, ip, r2, asl #1
+ ldmia sp, {r2-r3}
+ str r0, [sp, #12]
+ subs r2, r2, r4
+ sbc r3, r3, r5
+ str r1, [sp, #8]
+ subs r0, r2, #1
+ sbc r1, r3, #0
+ mov r2, r1, asr #31
+ ldmia sp, {r0-r1}
+ mov r3, r2
+ and ip, r2, #1
+ and r3, r3, r1
+ and r2, r2, r0
+ subs r4, r4, r2
+ sbc r5, r5, r3
+ add r10, r10, #1
+L40:
+ cmp r10, lr
+ bne L41
+ ldrd r0, [sp, #8]
+ adds r0, r0, r0
+ adc r1, r1, r1
+ cmp r6, #0
+ orr r10, r0, ip
+ mov r11, r1
+ stmneia r6, {r4-r5}
+ b L10
+L2:
+ mov r10, #0
+ mov r11, #0
+L10:
+ mov r0, r10
+ mov r1, r11
+ sub sp, r7, #20
+ ldmfd sp!, {r10, r11}
+ ldmfd sp!, {r4, r5, r6, r7, pc}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c
new file mode 100644
index 0000000..a268596
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c
@@ -0,0 +1,287 @@
+/** @file
+ Compiler intrinsic for 64-bit compare, ported from LLVM code.
+
+ Copyright (c) 2008-2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+// Effects: if rem != 0, *rem = a % b
+// Returns: a / b
+
+// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
+
+UINT64
+__udivmoddi4 (UINT64 a, UINT64 b, UINT64* rem)
+{
+ const unsigned n_uword_bits = sizeof(UINT32) * CHAR_BIT;
+ const unsigned n_udword_bits = sizeof(UINT64) * CHAR_BIT;
+ udwords n;
+ n.all = a;
+ udwords d;
+ d.all = b;
+ udwords q;
+ udwords r;
+ unsigned sr;
+
+ if (b == 0) {
+// ASSERT (FALSE);
+ return 0;
+ }
+
+ // special cases, X is unknown, K != 0
+ if (n.high == 0)
+ {
+ if (d.high == 0)
+ {
+ // 0 X
+ // ---
+ // 0 X
+ if (rem)
+ *rem = n.low % d.low;
+ return n.low / d.low;
+ }
+ // 0 X
+ // ---
+ // K X
+ if (rem)
+ *rem = n.low;
+ return 0;
+ }
+ // n.high != 0
+ if (d.low == 0)
+ {
+ if (d.high == 0)
+ {
+ // K X
+ // ---
+ // 0 0
+ if (rem)
+ *rem = n.high % d.low;
+ return n.high / d.low;
+ }
+ // d.high != 0
+ if (n.low == 0)
+ {
+ // K 0
+ // ---
+ // K 0
+ if (rem)
+ {
+ r.high = n.high % d.high;
+ r.low = 0;
+ *rem = r.all;
+ }
+ return n.high / d.high;
+ }
+ // K K
+ // ---
+ // K 0
+ if ((d.high & (d.high - 1)) == 0) // if d is a power of 2
+ {
+ if (rem)
+ {
+ r.low = n.low;
+ r.high = n.high & (d.high - 1);
+ *rem = r.all;
+ }
+ return n.high >> COUNT_TRAILING_ZEROS(d.high);
+ }
+ // K K
+ // ---
+ // K 0
+ sr = COUNT_LEADING_ZEROS(d.high) - COUNT_LEADING_ZEROS(n.high);
+ // 0 <= sr <= n_uword_bits - 2 or sr large
+ if (sr > n_uword_bits - 2)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ // 1 <= sr <= n_uword_bits - 1
+ // q.all = n.all << (n_udword_bits - sr);
+ q.low = 0;
+ q.high = n.low << (n_uword_bits - sr);
+ // r.all = n.all >> sr;
+ r.high = n.high >> sr;
+ r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ }
+ else // d.low != 0
+ {
+ if (d.high == 0)
+ {
+ // K X
+ // ---
+ // 0 K
+ if ((d.low & (d.low - 1)) == 0) // if d is a power of 2
+ {
+ if (rem)
+ *rem = n.low & (d.low - 1);
+ if (d.low == 1)
+ return n.all;
+ unsigned sr = COUNT_TRAILING_ZEROS(d.low);
+ q.high = n.high >> sr;
+ q.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ return q.all;
+ }
+ // K X
+ // ---
+ // 0 K
+ sr = 1 + n_uword_bits + COUNT_LEADING_ZEROS(d.low) - COUNT_LEADING_ZEROS(n.high);
+ // 2 <= sr <= n_udword_bits - 1
+ // q.all = n.all << (n_udword_bits - sr);
+ // r.all = n.all >> sr;
+ // if (sr == n_uword_bits)
+ // {
+ // q.low = 0;
+ // q.high = n.low;
+ // r.high = 0;
+ // r.low = n.high;
+ // }
+ // else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1
+ // {
+ // q.low = 0;
+ // q.high = n.low << (n_uword_bits - sr);
+ // r.high = n.high >> sr;
+ // r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ // }
+ // else // n_uword_bits + 1 <= sr <= n_udword_bits - 1
+ // {
+ // q.low = n.low << (n_udword_bits - sr);
+ // q.high = (n.high << (n_udword_bits - sr)) |
+ // (n.low >> (sr - n_uword_bits));
+ // r.high = 0;
+ // r.low = n.high >> (sr - n_uword_bits);
+ // }
+ q.low = (n.low << (n_udword_bits - sr)) &
+ ((INT32)(n_uword_bits - sr) >> (n_uword_bits-1));
+ q.high = ((n.low << ( n_uword_bits - sr)) &
+ ((INT32)(sr - n_uword_bits - 1) >> (n_uword_bits-1))) |
+ (((n.high << (n_udword_bits - sr)) |
+ (n.low >> (sr - n_uword_bits))) &
+ ((INT32)(n_uword_bits - sr) >> (n_uword_bits-1)));
+ r.high = (n.high >> sr) &
+ ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1));
+ r.low = ((n.high >> (sr - n_uword_bits)) &
+ ((INT32)(n_uword_bits - sr - 1) >> (n_uword_bits-1))) |
+ (((n.high << (n_uword_bits - sr)) |
+ (n.low >> sr)) &
+ ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1)));
+ }
+ else
+ {
+ // K X
+ // ---
+ // K K
+ sr = COUNT_LEADING_ZEROS(d.high) - COUNT_LEADING_ZEROS(n.high);
+ // 0 <= sr <= n_uword_bits - 1 or sr large
+ if (sr > n_uword_bits - 1)
+ {
+ if (rem)
+ *rem = n.all;
+ return 0;
+ }
+ ++sr;
+ // 1 <= sr <= n_uword_bits
+ // q.all = n.all << (n_udword_bits - sr);
+ q.low = 0;
+ q.high = n.low << (n_uword_bits - sr);
+ // r.all = n.all >> sr;
+ // if (sr < n_uword_bits)
+ // {
+ // r.high = n.high >> sr;
+ // r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
+ // }
+ // else
+ // {
+ // r.high = 0;
+ // r.low = n.high;
+ // }
+ r.high = (n.high >> sr) &
+ ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1));
+ r.low = (n.high << (n_uword_bits - sr)) |
+ ((n.low >> sr) &
+ ((INT32)(sr - n_uword_bits) >> (n_uword_bits-1)));
+ }
+ }
+ // Not a special case
+ // q and r are initialized with:
+ // q.all = n.all << (n_udword_bits - sr);
+ // r.all = n.all >> sr;
+ // 1 <= sr <= n_udword_bits - 1
+ UINT32 carry = 0;
+ for (; sr > 0; --sr)
+ {
+ // r:q = ((r:q) << 1) | carry
+ r.high = (r.high << 1) | (r.low >> (n_uword_bits - 1));
+ r.low = (r.low << 1) | (q.high >> (n_uword_bits - 1));
+ q.high = (q.high << 1) | (q.low >> (n_uword_bits - 1));
+ q.low = (q.low << 1) | carry;
+ // carry = 0;
+ // if (r.all >= d.all)
+ // {
+ // r.all -= d.all;
+ // carry = 1;
+ // }
+ const INT64 s = (INT64)(d.all - r.all - 1) >> (n_udword_bits - 1);
+ carry = s & 1;
+ r.all -= d.all & s;
+ }
+ q.all = (q.all << 1) | carry;
+ if (rem)
+ *rem = r.all;
+ return q.all;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
new file mode 100644
index 0000000..5e2d31c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__udivsi3)
+
+ASM_PFX(__udivsi3):
+ cmp r1, #0
+ cmpne r0, #0
+ stmfd sp!, {r4, r5, r7, lr}
+ add r7, sp, #8
+ beq L2
+ clz r2, r1
+ clz r3, r0
+ rsb r3, r3, r2
+ cmp r3, #31
+ bhi L2
+ ldmeqfd sp!, {r4, r5, r7, pc}
+ add r5, r3, #1
+ rsb r3, r3, #31
+ mov lr, #0
+ mov r2, r0, asl r3
+ mov ip, r0, lsr r5
+ mov r4, lr
+ b L8
+L9:
+ mov r0, r2, lsr #31
+ orr ip, r0, ip, asl #1
+ orr r2, r3, lr
+ rsb r3, ip, r1
+ sub r3, r3, #1
+ and r0, r1, r3, asr #31
+ mov lr, r3, lsr #31
+ rsb ip, r0, ip
+ add r4, r4, #1
+L8:
+ cmp r4, r5
+ mov r3, r2, asl #1
+ bne L9
+ orr r0, r3, lr
+ ldmfd sp!, {r4, r5, r7, pc}
+L2:
+ mov r0, #0
+ ldmfd sp!, {r4, r5, r7, pc}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c
new file mode 100644
index 0000000..8b9cb9f
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c
@@ -0,0 +1,111 @@
+/** @file
+ Compiler intrinsic for 32-bit unsigned div, ported from LLVM code.
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+
+// Returns: n / d
+
+// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
+
+UINT32
+__udivsi3(UINT32 n, UINT32 d)
+{
+ const unsigned n_uword_bits = sizeof(UINT32) * CHAR_BIT;
+ UINT32 q;
+ UINT32 r;
+ unsigned sr;
+
+ // special cases
+ if (d == 0) {
+// ASSERT (FALSE);
+ return 0; // ?!
+ }
+ if (n == 0)
+ return 0;
+
+ sr = COUNT_LEADING_ZEROS(d) - COUNT_LEADING_ZEROS(n);
+ // 0 <= sr <= n_uword_bits - 1 or sr large
+ if (sr > n_uword_bits - 1) // d > r
+ return 0;
+ if (sr == n_uword_bits - 1) // d == 1
+ return n;
+ ++sr;
+ // 1 <= sr <= n_uword_bits - 1
+ // Not a special case
+ q = n << (n_uword_bits - sr);
+ r = n >> sr;
+ UINT32 carry = 0;
+ for (; sr > 0; --sr)
+ {
+ // r:q = ((r:q) << 1) | carry
+ r = (r << 1) | (q >> (n_uword_bits - 1));
+ q = (q << 1) | carry;
+ // carry = 0;
+ // if (r.all >= d.all)
+ // {
+ // r.all -= d.all;
+ // carry = 1;
+ // }
+ const INT32 s = (INT32)(d - r - 1) >> (n_uword_bits - 1);
+ carry = s & 1;
+ r -= d & s;
+ }
+ q = (q << 1) | carry;
+ return q;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
new file mode 100755
index 0000000..4481c6d
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
@@ -0,0 +1,267 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__aeabi_uldivmod)
+
+//
+//UINT64
+//EFIAPI
+//__aeabi_uldivmod (
+// IN UINT64 Dividend
+// IN UINT64 Divisor
+// )
+//
+ASM_PFX(__aeabi_uldivmod):
+ stmdb sp!, {r4, r5, r6, lr}
+ mov r4, r1
+ mov r5, r0
+ mov r6, #0 // 0x0
+ orrs ip, r3, r2, lsr #31
+ bne ASM_PFX(__aeabi_uldivmod_label1)
+ tst r2, r2
+ beq ASM_PFX(_ll_div0)
+ movs ip, r2, lsr #15
+ addeq r6, r6, #16 // 0x10
+ mov ip, r2, lsl r6
+ movs lr, ip, lsr #23
+ moveq ip, ip, lsl #8
+ addeq r6, r6, #8 // 0x8
+ movs lr, ip, lsr #27
+ moveq ip, ip, lsl #4
+ addeq r6, r6, #4 // 0x4
+ movs lr, ip, lsr #29
+ moveq ip, ip, lsl #2
+ addeq r6, r6, #2 // 0x2
+ movs lr, ip, lsr #30
+ moveq ip, ip, lsl #1
+ addeq r6, r6, #1 // 0x1
+ b ASM_PFX(_ll_udiv_small)
+ASM_PFX(__aeabi_uldivmod_label1):
+ tst r3, #-2147483648 // 0x80000000
+ bne ASM_PFX(__aeabi_uldivmod_label2)
+ movs ip, r3, lsr #15
+ addeq r6, r6, #16 // 0x10
+ mov ip, r3, lsl r6
+ movs lr, ip, lsr #23
+ moveq ip, ip, lsl #8
+ addeq r6, r6, #8 // 0x8
+ movs lr, ip, lsr #27
+ moveq ip, ip, lsl #4
+ addeq r6, r6, #4 // 0x4
+ movs lr, ip, lsr #29
+ moveq ip, ip, lsl #2
+ addeq r6, r6, #2 // 0x2
+ movs lr, ip, lsr #30
+ addeq r6, r6, #1 // 0x1
+ rsb r3, r6, #32 // 0x20
+ moveq ip, ip, lsl #1
+ orr ip, ip, r2, lsr r3
+ mov lr, r2, lsl r6
+ b ASM_PFX(_ll_udiv_big)
+ASM_PFX(__aeabi_uldivmod_label2):
+ mov ip, r3
+ mov lr, r2
+ b ASM_PFX(_ll_udiv_ginormous)
+
+ASM_PFX(_ll_udiv_small):
+ cmp r4, ip, lsl #1
+ mov r3, #0 // 0x0
+ subcs r4, r4, ip, lsl #1
+ addcs r3, r3, #2 // 0x2
+ cmp r4, ip
+ subcs r4, r4, ip
+ adcs r3, r3, #0 // 0x0
+ add r2, r6, #32 // 0x20
+ cmp r2, #32 // 0x20
+ rsb ip, ip, #0 // 0x0
+ bcc ASM_PFX(_ll_udiv_small_label1)
+ orrs r0, r4, r5, lsr #30
+ moveq r4, r5
+ moveq r5, #0 // 0x0
+ subeq r2, r2, #32 // 0x20
+ASM_PFX(_ll_udiv_small_label1):
+ mov r1, #0 // 0x0
+ cmp r2, #16 // 0x10
+ bcc ASM_PFX(_ll_udiv_small_label2)
+ movs r0, r4, lsr #14
+ moveq r4, r4, lsl #16
+ addeq r1, r1, #16 // 0x10
+ASM_PFX(_ll_udiv_small_label2):
+ sub lr, r2, r1
+ cmp lr, #8 // 0x8
+ bcc ASM_PFX(_ll_udiv_small_label3)
+ movs r0, r4, lsr #22
+ moveq r4, r4, lsl #8
+ addeq r1, r1, #8 // 0x8
+ASM_PFX(_ll_udiv_small_label3):
+ rsb r0, r1, #32 // 0x20
+ sub r2, r2, r1
+ orr r4, r4, r5, lsr r0
+ mov r5, r5, lsl r1
+ cmp r2, #1 // 0x1
+ bcc ASM_PFX(_ll_udiv_small_label5)
+ sub r2, r2, #1 // 0x1
+ and r0, r2, #7 // 0x7
+ eor r0, r0, #7 // 0x7
+ adds r0, r0, r0, lsl #1
+ add pc, pc, r0, lsl #2
+ nop // (mov r0,r0)
+ASM_PFX(_ll_udiv_small_label4):
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ sub r2, r2, #8 // 0x8
+ tst r2, r2
+ rsbcc r4, ip, r4
+ bpl ASM_PFX(_ll_udiv_small_label4)
+ASM_PFX(_ll_udiv_small_label5):
+ mov r2, r4, lsr r6
+ bic r4, r4, r2, lsl r6
+ adcs r0, r5, r5
+ adc r1, r4, r4
+ add r1, r1, r3, lsl r6
+ mov r3, #0 // 0x0
+ ldmia sp!, {r4, r5, r6, pc}
+
+ASM_PFX(_ll_udiv_big):
+ subs r0, r5, lr
+ mov r3, #0 // 0x0
+ sbcs r1, r4, ip
+ movcs r5, r0
+ movcs r4, r1
+ adcs r3, r3, #0 // 0x0
+ subs r0, r5, lr
+ sbcs r1, r4, ip
+ movcs r5, r0
+ movcs r4, r1
+ adcs r3, r3, #0 // 0x0
+ subs r0, r5, lr
+ sbcs r1, r4, ip
+ movcs r5, r0
+ movcs r4, r1
+ adcs r3, r3, #0 // 0x0
+ mov r1, #0 // 0x0
+ rsbs lr, lr, #0 // 0x0
+ rsc ip, ip, #0 // 0x0
+ cmp r6, #16 // 0x10
+ bcc ASM_PFX(_ll_udiv_big_label1)
+ movs r0, r4, lsr #14
+ moveq r4, r4, lsl #16
+ addeq r1, r1, #16 // 0x10
+ASM_PFX(_ll_udiv_big_label1):
+ sub r2, r6, r1
+ cmp r2, #8 // 0x8
+ bcc ASM_PFX(_ll_udiv_big_label2)
+ movs r0, r4, lsr #22
+ moveq r4, r4, lsl #8
+ addeq r1, r1, #8 // 0x8
+ASM_PFX(_ll_udiv_big_label2):
+ rsb r0, r1, #32 // 0x20
+ sub r2, r6, r1
+ orr r4, r4, r5, lsr r0
+ mov r5, r5, lsl r1
+ cmp r2, #1 // 0x1
+ bcc ASM_PFX(_ll_udiv_big_label4)
+ sub r2, r2, #1 // 0x1
+ and r0, r2, #3 // 0x3
+ rsb r0, r0, #3 // 0x3
+ adds r0, r0, r0, lsl #1
+ add pc, pc, r0, lsl #3
+ nop // (mov r0,r0)
+ASM_PFX(_ll_udiv_big_label3):
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ movcs r5, r0
+ movcs r4, r1
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ movcs r5, r0
+ movcs r4, r1
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ movcs r5, r0
+ movcs r4, r1
+ sub r2, r2, #4 // 0x4
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ tst r2, r2
+ movcs r5, r0
+ movcs r4, r1
+ bpl ASM_PFX(_ll_udiv_big_label3)
+ASM_PFX(_ll_udiv_big_label4):
+ mov r1, #0 // 0x0
+ mov r2, r5, lsr r6
+ bic r5, r5, r2, lsl r6
+ adcs r0, r5, r5
+ adc r1, r1, #0 // 0x0
+ movs lr, r3, lsl r6
+ mov r3, r4, lsr r6
+ bic r4, r4, r3, lsl r6
+ adc r1, r1, #0 // 0x0
+ adds r0, r0, lr
+ orr r2, r2, r4, ror r6
+ adc r1, r1, #0 // 0x0
+ ldmia sp!, {r4, r5, r6, pc}
+
+ASM_PFX(_ll_udiv_ginormous):
+ subs r2, r5, lr
+ mov r1, #0 // 0x0
+ sbcs r3, r4, ip
+ adc r0, r1, r1
+ movcc r2, r5
+ movcc r3, r4
+ ldmia sp!, {r4, r5, r6, pc}
+
+ASM_PFX(_ll_div0):
+ ldmia sp!, {r4, r5, r6, lr}
+ mov r0, #0 // 0x0
+ mov r1, #0 // 0x0
+ b ASM_PFX(__aeabi_ldiv0)
+
+ASM_PFX(__aeabi_ldiv0):
+ bx r14
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
new file mode 100644
index 0000000..aed649b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
@@ -0,0 +1,268 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+
+ EXPORT __aeabi_uldivmod
+
+ AREA Uldivmod, CODE, READONLY
+
+;
+;UINT64
+;EFIAPI
+;__aeabi_uldivmod (
+; IN UINT64 Dividend
+; IN UINT64 Divisor
+; )
+;
+__aeabi_uldivmod
+ stmdb sp!, {r4, r5, r6, lr}
+ mov r4, r1
+ mov r5, r0
+ mov r6, #0 ; 0x0
+ orrs ip, r3, r2, lsr #31
+ bne __aeabi_uldivmod_label1
+ tst r2, r2
+ beq _ll_div0
+ movs ip, r2, lsr #15
+ addeq r6, r6, #16 ; 0x10
+ mov ip, r2, lsl r6
+ movs lr, ip, lsr #23
+ moveq ip, ip, lsl #8
+ addeq r6, r6, #8 ; 0x8
+ movs lr, ip, lsr #27
+ moveq ip, ip, lsl #4
+ addeq r6, r6, #4 ; 0x4
+ movs lr, ip, lsr #29
+ moveq ip, ip, lsl #2
+ addeq r6, r6, #2 ; 0x2
+ movs lr, ip, lsr #30
+ moveq ip, ip, lsl #1
+ addeq r6, r6, #1 ; 0x1
+ b _ll_udiv_small
+__aeabi_uldivmod_label1
+ tst r3, #-2147483648 ; 0x80000000
+ bne __aeabi_uldivmod_label2
+ movs ip, r3, lsr #15
+ addeq r6, r6, #16 ; 0x10
+ mov ip, r3, lsl r6
+ movs lr, ip, lsr #23
+ moveq ip, ip, lsl #8
+ addeq r6, r6, #8 ; 0x8
+ movs lr, ip, lsr #27
+ moveq ip, ip, lsl #4
+ addeq r6, r6, #4 ; 0x4
+ movs lr, ip, lsr #29
+ moveq ip, ip, lsl #2
+ addeq r6, r6, #2 ; 0x2
+ movs lr, ip, lsr #30
+ addeq r6, r6, #1 ; 0x1
+ rsb r3, r6, #32 ; 0x20
+ moveq ip, ip, lsl #1
+ orr ip, ip, r2, lsr r3
+ mov lr, r2, lsl r6
+ b _ll_udiv_big
+__aeabi_uldivmod_label2
+ mov ip, r3
+ mov lr, r2
+ b _ll_udiv_ginormous
+
+_ll_udiv_small
+ cmp r4, ip, lsl #1
+ mov r3, #0 ; 0x0
+ subcs r4, r4, ip, lsl #1
+ addcs r3, r3, #2 ; 0x2
+ cmp r4, ip
+ subcs r4, r4, ip
+ adcs r3, r3, #0 ; 0x0
+ add r2, r6, #32 ; 0x20
+ cmp r2, #32 ; 0x20
+ rsb ip, ip, #0 ; 0x0
+ bcc _ll_udiv_small_label1
+ orrs r0, r4, r5, lsr #30
+ moveq r4, r5
+ moveq r5, #0 ; 0x0
+ subeq r2, r2, #32 ; 0x20
+_ll_udiv_small_label1
+ mov r1, #0 ; 0x0
+ cmp r2, #16 ; 0x10
+ bcc _ll_udiv_small_label2
+ movs r0, r4, lsr #14
+ moveq r4, r4, lsl #16
+ addeq r1, r1, #16 ; 0x10
+_ll_udiv_small_label2
+ sub lr, r2, r1
+ cmp lr, #8 ; 0x8
+ bcc _ll_udiv_small_label3
+ movs r0, r4, lsr #22
+ moveq r4, r4, lsl #8
+ addeq r1, r1, #8 ; 0x8
+_ll_udiv_small_label3
+ rsb r0, r1, #32 ; 0x20
+ sub r2, r2, r1
+ orr r4, r4, r5, lsr r0
+ mov r5, r5, lsl r1
+ cmp r2, #1 ; 0x1
+ bcc _ll_udiv_small_label5
+ sub r2, r2, #1 ; 0x1
+ and r0, r2, #7 ; 0x7
+ eor r0, r0, #7 ; 0x7
+ adds r0, r0, r0, lsl #1
+ add pc, pc, r0, lsl #2
+ nop ; (mov r0,r0)
+_ll_udiv_small_label4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ rsbcc r4, ip, r4
+ adcs r5, r5, r5
+ adcs r4, ip, r4, lsl #1
+ sub r2, r2, #8 ; 0x8
+ tst r2, r2
+ rsbcc r4, ip, r4
+ bpl _ll_udiv_small_label4
+_ll_udiv_small_label5
+ mov r2, r4, lsr r6
+ bic r4, r4, r2, lsl r6
+ adcs r0, r5, r5
+ adc r1, r4, r4
+ add r1, r1, r3, lsl r6
+ mov r3, #0 ; 0x0
+ ldmia sp!, {r4, r5, r6, pc}
+
+_ll_udiv_big
+ subs r0, r5, lr
+ mov r3, #0 ; 0x0
+ sbcs r1, r4, ip
+ movcs r5, r0
+ movcs r4, r1
+ adcs r3, r3, #0 ; 0x0
+ subs r0, r5, lr
+ sbcs r1, r4, ip
+ movcs r5, r0
+ movcs r4, r1
+ adcs r3, r3, #0 ; 0x0
+ subs r0, r5, lr
+ sbcs r1, r4, ip
+ movcs r5, r0
+ movcs r4, r1
+ adcs r3, r3, #0 ; 0x0
+ mov r1, #0 ; 0x0
+ rsbs lr, lr, #0 ; 0x0
+ rsc ip, ip, #0 ; 0x0
+ cmp r6, #16 ; 0x10
+ bcc _ll_udiv_big_label1
+ movs r0, r4, lsr #14
+ moveq r4, r4, lsl #16
+ addeq r1, r1, #16 ; 0x10
+_ll_udiv_big_label1
+ sub r2, r6, r1
+ cmp r2, #8 ; 0x8
+ bcc _ll_udiv_big_label2
+ movs r0, r4, lsr #22
+ moveq r4, r4, lsl #8
+ addeq r1, r1, #8 ; 0x8
+_ll_udiv_big_label2
+ rsb r0, r1, #32 ; 0x20
+ sub r2, r6, r1
+ orr r4, r4, r5, lsr r0
+ mov r5, r5, lsl r1
+ cmp r2, #1 ; 0x1
+ bcc _ll_udiv_big_label4
+ sub r2, r2, #1 ; 0x1
+ and r0, r2, #3 ; 0x3
+ rsb r0, r0, #3 ; 0x3
+ adds r0, r0, r0, lsl #1
+ add pc, pc, r0, lsl #3
+ nop ; (mov r0,r0)
+_ll_udiv_big_label3
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ movcs r5, r0
+ movcs r4, r1
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ movcs r5, r0
+ movcs r4, r1
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ movcs r5, r0
+ movcs r4, r1
+ sub r2, r2, #4 ; 0x4
+ adcs r5, r5, r5
+ adcs r4, r4, r4
+ adcs r0, lr, r5
+ adcs r1, ip, r4
+ tst r2, r2
+ movcs r5, r0
+ movcs r4, r1
+ bpl _ll_udiv_big_label3
+_ll_udiv_big_label4
+ mov r1, #0 ; 0x0
+ mov r2, r5, lsr r6
+ bic r5, r5, r2, lsl r6
+ adcs r0, r5, r5
+ adc r1, r1, #0 ; 0x0
+ movs lr, r3, lsl r6
+ mov r3, r4, lsr r6
+ bic r4, r4, r3, lsl r6
+ adc r1, r1, #0 ; 0x0
+ adds r0, r0, lr
+ orr r2, r2, r4, ror r6
+ adc r1, r1, #0 ; 0x0
+ ldmia sp!, {r4, r5, r6, pc}
+
+_ll_udiv_ginormous
+ subs r2, r5, lr
+ mov r1, #0 ; 0x0
+ sbcs r3, r4, ip
+ adc r0, r1, r1
+ movcc r2, r5
+ movcc r3, r4
+ ldmia sp!, {r4, r5, r6, pc}
+
+_ll_div0
+ ldmia sp!, {r4, r5, r6, lr}
+ mov r0, #0 ; 0x0
+ mov r1, #0 ; 0x0
+ b __aeabi_ldiv0
+
+__aeabi_ldiv0
+ BX r14
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldivmod.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldivmod.c
new file mode 100755
index 0000000..8887938
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldivmod.c
@@ -0,0 +1,43 @@
+/** @file
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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 "Llvm_int_lib.h"
+#include <Library/BaseLib.h>
+
+
+UINT32 __udivsi3(UINT32 n, UINT32 d);
+UINT32 __umodsi3(UINT32 a, UINT32 b);
+
+
+UINT64
+__aeabi_uidivmod(unsigned numerator, unsigned denominator)
+{
+ UINT64 Return;
+
+ Return = __udivsi3 (numerator, denominator);
+ Return |= LShiftU64 (__umodsi3 (numerator, denominator), 32);
+
+ return Return;
+}
+
+unsigned
+__aeabi_uidiv (unsigned n, unsigned d)
+{
+ return __udivsi3 (n, d);
+}
+
+
+
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
new file mode 100644
index 0000000..6b718a6
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
@@ -0,0 +1,29 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__umoddi3)
+
+ASM_PFX(__umoddi3):
+ stmfd sp!, {r7, lr}
+ add r7, sp, #0
+ sub sp, sp, #16
+ add ip, sp, #8
+ str ip, [sp, #0]
+ bl ASM_PFX(__udivmoddi4)
+ ldrd r0, [sp, #8]
+ sub sp, r7, #0
+ ldmfd sp!, {r7, pc}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c
new file mode 100644
index 0000000..2a2ec61
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c
@@ -0,0 +1,72 @@
+/** @file
+ Compiler intrinsic for 64-bit unsigned mod, ported from LLVM code.
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+UINT64 __udivmoddi4(UINT64 a, UINT64 b, UINT64* rem);
+
+// Returns: a % b
+
+UINT64
+__umoddi3(UINT64 a, UINT64 b)
+{
+ UINT64 r;
+ __udivmoddi4(a, b, &r);
+ return r;
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
new file mode 100644
index 0000000..76c26be
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
@@ -0,0 +1,28 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2009, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+ .text
+ .align 2
+ GCC_ASM_EXPORT(__umodsi3)
+
+ASM_PFX(__umodsi3):
+ stmfd sp!, {r4, r5, r7, lr}
+ add r7, sp, #8
+ mov r5, r0
+ mov r4, r1
+ bl ASM_PFX(__udivsi3)
+ mul r0, r4, r0
+ rsb r0, r0, r5
+ ldmfd sp!, {r4, r5, r7, pc}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c
new file mode 100644
index 0000000..d0a5b76
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c
@@ -0,0 +1,68 @@
+/** @file
+ Compiler intrinsic for 32-bit unsigned mod, ported from LLVM code.
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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.
+
+**/
+/**
+ University of Illinois/NCSA
+ Open Source License
+
+ Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign.
+ All rights reserved.
+
+ Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
+ this software and associated documentation files (the "Software"), to deal with
+ the Software without restriction, including without limitation the rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is furnished to do
+ so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+ SOFTWARE.
+**/
+
+
+#include "Llvm_int_lib.h"
+
+
+// Returns: a % b
+
+UINT32
+__umodsi3(UINT32 a, UINT32 b)
+{
+ return a - (a / b) * b;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm
new file mode 100644
index 0000000..3d58965
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+
+ EXPORT __aeabi_uread4
+ EXPORT __aeabi_uread8
+
+ AREA Uread4, CODE, READONLY
+
+;
+;UINT32
+;EFIAPI
+;__aeabi_uread4 (
+; IN VOID *Pointer
+; );
+;
+__aeabi_uread4
+ ldrb r1, [r0]
+ ldrb r2, [r0, #1]
+ ldrb r3, [r0, #2]
+ ldrb r0, [r0, #3]
+ orr r1, r1, r2, lsl #8
+ orr r1, r1, r3, lsl #16
+ orr r0, r1, r0, lsl #24
+ bx lr
+
+;
+;UINT64
+;EFIAPI
+;__aeabi_uread8 (
+; IN VOID *Pointer
+; );
+;
+__aeabi_uread8
+ mov r3, r0
+
+ ldrb r1, [r3]
+ ldrb r2, [r3, #1]
+ orr r1, r1, r2, lsl #8
+ ldrb r2, [r3, #2]
+ orr r1, r1, r2, lsl #16
+ ldrb r0, [r3, #3]
+ orr r0, r1, r0, lsl #24
+
+ ldrb r1, [r3, #4]
+ ldrb r2, [r3, #5]
+ orr r1, r1, r2, lsl #8
+ ldrb r2, [r3, #6]
+ orr r1, r1, r2, lsl #16
+ ldrb r2, [r3, #7]
+ orr r1, r1, r2, lsl #24
+
+ bx lr
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm
new file mode 100644
index 0000000..85e1ba8
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2009, Apple Inc. 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.
+//
+//------------------------------------------------------------------------------
+
+
+ EXPORT __aeabi_uwrite4
+ EXPORT __aeabi_uwrite8
+
+ AREA Uwrite4, CODE, READONLY
+
+;
+;UINT32
+;EFIAPI
+;__aeabi_uwrite4 (
+; IN UINT32 Data,
+; IN VOID *Pointer
+; );
+;
+;
+__aeabi_uwrite4
+ mov r2, r0, lsr #8
+ strb r0, [r1]
+ strb r2, [r1, #1]
+ mov r2, r0, lsr #16
+ strb r2, [r1, #2]
+ mov r2, r0, lsr #24
+ strb r2, [r1, #3]
+ bx lr
+
+;
+;UINT64
+;EFIAPI
+;__aeabi_uwrite8 (
+; IN UINT64 Data, //r0-r1
+; IN VOID *Pointer //r2
+; );
+;
+;
+__aeabi_uwrite8
+ mov r3, r0, lsr #8
+ strb r0, [r2]
+ strb r3, [r2, #1]
+ mov r3, r0, lsr #16
+ strb r3, [r2, #2]
+ mov r3, r0, lsr #24
+ strb r3, [r2, #3]
+
+ mov r3, r1, lsr #8
+ strb r1, [r2, #4]
+ strb r3, [r2, #5]
+ mov r3, r1, lsr #16
+ strb r3, [r2, #6]
+ mov r3, r1, lsr #24
+ strb r3, [r2, #7]
+ bx lr
+
+ END
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
new file mode 100644
index 0000000..3487787
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@@ -0,0 +1,107 @@
+#/** @file
+# Base Library implementation.
+#
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+# 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CompilerIntrinsicsLib
+ FILE_GUID = 855274FA-3575-4C20-9709-C031DC5589FA
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CompilerIntrinsicsLib
+
+[Sources.AARCH64]
+ AArch64/memcpy.S
+ AArch64/memset.c
+
+[Sources.ARM]
+ Arm/mullu.asm | RVCT
+ Arm/switch.asm | RVCT
+ Arm/llsr.asm | RVCT
+ Arm/memcpy.asm | RVCT
+ Arm/memcpy4.asm | RVCT
+ Arm/memset.asm | RVCT
+ Arm/memmove.asm | RVCT
+ Arm/uread.asm | RVCT
+ Arm/uwrite.asm | RVCT
+ Arm/lasr.asm | RVCT
+ Arm/llsl.asm | RVCT
+ Arm/div.asm | RVCT
+ Arm/uldiv.asm | RVCT
+ Arm/ldivmod.asm | RVCT
+
+
+#
+# Move .c to .s to work around LLVM issues
+#
+# Arm/ashrdi3.c | GCC
+# Arm/ashldi3.c | GCC
+# Arm/divdi3.c | GCC
+# Arm/divsi3.c | GCC
+# Arm/lshrdi3.c | GCC
+ Arm/ashrdi3.S | GCC
+ Arm/ashldi3.S | GCC
+ Arm/div.S | GCC
+ Arm/divdi3.S | GCC
+ Arm/divsi3.S | GCC
+ Arm/lshrdi3.S | GCC
+
+ Arm/memcpy.S | GCC
+ Arm/memset.S | GCC
+ Arm/memmove.S | GCC
+
+# Arm/modsi3.c | GCC
+# Arm/moddi3.c | GCC
+# Arm/muldi3.c | GCC
+ Arm/modsi3.S | GCC
+ Arm/moddi3.S | GCC
+ Arm/muldi3.S | GCC
+ Arm/mullu.S | GCC
+
+# Arm/udivsi3.c | GCC
+# Arm/umodsi3.c | GCC
+# Arm/udivdi3.c | GCC
+# Arm/umoddi3.c | GCC
+# Arm/udivmoddi4.c | GCC
+ Arm/udivsi3.S | GCC
+ Arm/umodsi3.S | GCC
+ Arm/udivdi3.S | GCC
+ Arm/umoddi3.S | GCC
+ Arm/udivmoddi4.S | GCC
+
+# Arm/clzsi2.c | GCC
+# Arm/ctzsi2.c | GCC
+# Arm/ucmpdi2.c | GCC
+ Arm/clzsi2.S | GCC
+ Arm/ctzsi2.S | GCC
+ Arm/ucmpdi2.S | GCC
+ Arm/switch8.S | GCC
+ Arm/switchu8.S | GCC
+ Arm/switch16.S | GCC
+ Arm/switch32.S | GCC
+
+ Arm/sourcery.S | GCC
+ Arm/uldiv.S | GCC
+ Arm/ldivmod.S | GCC
+
+ Arm/llsr.S | GCC
+ Arm/llsl.S | GCC
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/AArch64/DebugAgentException.S b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/AArch64/DebugAgentException.S
new file mode 100644
index 0000000..022e279
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/AArch64/DebugAgentException.S
@@ -0,0 +1,93 @@
+#------------------------------------------------------------------------------
+#
+# 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.
+#
+#------------------------------------------------------------------------------
+
+GCC_ASM_EXPORT(DebugAgentVectorTable)
+GCC_ASM_IMPORT(DefaultExceptionHandler)
+
+.text
+ASM_PFX(DebugAgentVectorTable):
+
+//
+// Current EL with SP0 : 0x0 - 0x180
+//
+.align 11
+ASM_PFX(SynchronousExceptionSP0):
+ b ASM_PFX(SynchronousExceptionSP0)
+
+.align 7
+ASM_PFX(IrqSP0):
+ b ASM_PFX(IrqSP0)
+
+.align 7
+ASM_PFX(FiqSP0):
+ b ASM_PFX(FiqSP0)
+
+.align 7
+ASM_PFX(SErrorSP0):
+ b ASM_PFX(SErrorSP0)
+
+//
+// Current EL with SPx: 0x200 - 0x380
+//
+.align 7
+ASM_PFX(SynchronousExceptionSPx):
+ b ASM_PFX(SynchronousExceptionSPx)
+
+.align 7
+ASM_PFX(IrqSPx):
+ b ASM_PFX(IrqSPx)
+
+.align 7
+ASM_PFX(FiqSPx):
+ b ASM_PFX(FiqSPx)
+
+.align 7
+ASM_PFX(SErrorSPx):
+ b ASM_PFX(SErrorSPx)
+
+/* Lower EL using AArch64 : 0x400 - 0x580 */
+.align 7
+ASM_PFX(SynchronousExceptionA64):
+ b ASM_PFX(SynchronousExceptionA64)
+
+.align 7
+ASM_PFX(IrqA64):
+ b ASM_PFX(IrqA64)
+
+.align 7
+ASM_PFX(FiqA64):
+ b ASM_PFX(FiqA64)
+
+.align 7
+ASM_PFX(SErrorA64):
+ b ASM_PFX(SErrorA64)
+
+//
+// Lower EL using AArch32 : 0x0 - 0x180
+//
+.align 7
+ASM_PFX(SynchronousExceptionA32):
+ b ASM_PFX(SynchronousExceptionA32)
+
+.align 7
+ASM_PFX(IrqA32):
+ b ASM_PFX(IrqA32)
+
+.align 7
+ASM_PFX(FiqA32):
+ b ASM_PFX(FiqA32)
+
+.align 7
+ASM_PFX(SErrorA32):
+ b ASM_PFX(SErrorA32)
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S
new file mode 100644
index 0000000..0566a89
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S
@@ -0,0 +1,276 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2011 - 2012, 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 <Library/PcdLib.h>
+
+/*
+
+This is the stack constructed by the exception handler (low address to high address)
+ # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
+ Reg Offset
+ === ======
+ R0 0x00 # stmfd SP!,{R0-R12}
+ R1 0x04
+ R2 0x08
+ R3 0x0c
+ R4 0x10
+ R5 0x14
+ R6 0x18
+ R7 0x1c
+ R8 0x20
+ R9 0x24
+ R10 0x28
+ R11 0x2c
+ R12 0x30
+ SP 0x34 # reserved via adding 0x20 (32) to the SP
+ LR 0x38
+ PC 0x3c
+ CPSR 0x40
+ DFSR 0x44
+ DFAR 0x48
+ IFSR 0x4c
+ IFAR 0x50
+
+ LR 0x54 # SVC Link register (we need to restore it)
+
+ LR 0x58 # pushed by srsfd
+ CPSR 0x5c
+
+ */
+
+GCC_ASM_EXPORT(DebugAgentVectorTable)
+GCC_ASM_IMPORT(DefaultExceptionHandler)
+
+.text
+#if !defined(__APPLE__)
+.fpu neon @ makes vpush/vpop assemble
+#endif
+.align 5
+
+
+//
+// This code gets copied to the ARM vector table
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
+//
+ASM_PFX(DebugAgentVectorTable):
+ b ASM_PFX(ResetEntry)
+ b ASM_PFX(UndefinedInstructionEntry)
+ b ASM_PFX(SoftwareInterruptEntry)
+ b ASM_PFX(PrefetchAbortEntry)
+ b ASM_PFX(DataAbortEntry)
+ b ASM_PFX(ReservedExceptionEntry)
+ b ASM_PFX(IrqEntry)
+ b ASM_PFX(FiqEntry)
+
+ASM_PFX(ResetEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ @ We are already in SVC mode
+
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#0 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(UndefinedInstructionEntry):
+ sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#1 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(SoftwareInterruptEntry):
+ sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsdb #0x13! @ Store return state on SVC stack
+ @ We are already in SVC mode
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#2 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(PrefetchAbortEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#3 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(DataAbortEntry):
+ sub LR,LR,#8
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#4
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(ReservedExceptionEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#5
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(IrqEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#6 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(FiqEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+ @ Since we have already switch to SVC R8_fiq - R12_fiq
+ @ never get used or saved
+ mov R0,#7 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+//
+// This gets patched by the C code that patches in the vector table
+//
+ASM_PFX(CommonExceptionEntry):
+ .word ASM_PFX(AsmCommonExceptionEntry)
+
+ASM_PFX(ExceptionHandlersEnd):
+
+//
+// This code runs from CpuDxe driver loaded address. It is patched into
+// CommonExceptionEntry.
+//
+ASM_PFX(AsmCommonExceptionEntry):
+ mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
+ str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
+
+ mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
+ str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+
+ mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
+ str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+
+ mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
+ str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+
+ ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
+ str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+
+ add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R3, R1, #0x1f @ Check CPSR to see if User or System Mode
+ cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df))
+ cmpne R3, #0x10 @
+ stmeqed R2, {lr}^ @ save unbanked lr
+ @ else
+ stmneed R2, {lr} @ save SVC lr
+
+
+ ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
+ @ Check to see if we have to adjust for Thumb entry
+ sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) {
+ cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb
+ bhi NoAdjustNeeded
+
+ tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
+ addne R5, R5, #2 @ PC += 2@
+ str R5,[SP,#0x58] @ Update LR value pused by srsfd
+
+NoAdjustNeeded:
+
+ str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+ sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
+ str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+
+ @ R0 is ExceptionType
+ mov R1,SP @ R1 is SystemContext
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpush {d0-d15} @ save vstm registers in case they are used in optimizations
+#endif
+
+/*
+VOID
+EFIAPI
+DefaultExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType, R0
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
+ )
+
+*/
+ blx ASM_PFX(DefaultExceptionHandler) @ Call exception handler
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpop {d0-d15}
+#endif
+
+ ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
+ mcr p15, 0, R1, c5, c0, 1 @ Write IFSR
+
+ ldr R1, [SP, #0x44] @ sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR
+ mcr p15, 0, R1, c5, c0, 0 @ Write DFSR
+
+ ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
+ str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
+
+ ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
+ str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
+
+ add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
+ add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R1, R1, #0x1f @ Check to see if User or System Mode
+ cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R1, #0x10 @
+ ldmeqed R2, {lr}^ @ restore unbanked lr
+ @ else
+ ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
+
+ ldmfd SP!,{R0-R12} @ Restore general purpose registers
+ @ Exception handler can not change SP
+
+ add SP,SP,#0x20 @ Clear out the remaining stack space
+ ldmfd SP!,{LR} @ restore the link register for this context
+ rfefd SP! @ return from exception via srsfd stack slot
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm
new file mode 100644
index 0000000..b879142
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm
@@ -0,0 +1,273 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+// Copyright (c) 2011 - 2012, 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 <Library/PcdLib.h>
+
+/*
+
+This is the stack constructed by the exception handler (low address to high address)
+ # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
+ Reg Offset
+ === ======
+ R0 0x00 # stmfd SP!,{R0-R12}
+ R1 0x04
+ R2 0x08
+ R3 0x0c
+ R4 0x10
+ R5 0x14
+ R6 0x18
+ R7 0x1c
+ R8 0x20
+ R9 0x24
+ R10 0x28
+ R11 0x2c
+ R12 0x30
+ SP 0x34 # reserved via adding 0x20 (32) to the SP
+ LR 0x38
+ PC 0x3c
+ CPSR 0x40
+ DFSR 0x44
+ DFAR 0x48
+ IFSR 0x4c
+ IFAR 0x50
+
+ LR 0x54 # SVC Link register (we need to restore it)
+
+ LR 0x58 # pushed by srsfd
+ CPSR 0x5c
+
+ */
+
+ EXPORT DebugAgentVectorTable
+ IMPORT DefaultExceptionHandler
+
+ PRESERVE8
+ AREA DebugAgentException, CODE, READONLY, CODEALIGN, ALIGN=5
+
+//
+// This code gets copied to the ARM vector table
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
+//
+DebugAgentVectorTable FUNCTION
+ b ResetEntry
+ b UndefinedInstructionEntry
+ b SoftwareInterruptEntry
+ b PrefetchAbortEntry
+ b DataAbortEntry
+ b ReservedExceptionEntry
+ b IrqEntry
+ b FiqEntry
+ ENDFUNC
+
+ResetEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ ; We are already in SVC mode
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#0 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+UndefinedInstructionEntry
+ sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#1 ; ExceptionType
+ ldr R1,CommonExceptionEntry;
+ bx R1
+
+SoftwareInterruptEntry
+ sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ ; We are already in SVC mode
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#2 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+PrefetchAbortEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#3 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+DataAbortEntry
+ sub LR,LR,#8
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#4 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+ReservedExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#5 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+IrqEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#6 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+FiqEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+ ; Since we have already switch to SVC R8_fiq - R12_fiq
+ ; never get used or saved
+ mov R0,#7 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+//
+// This gets patched by the C code that patches in the vector table
+//
+CommonExceptionEntry
+ dcd AsmCommonExceptionEntry
+
+ExceptionHandlersEnd
+
+//
+// This code runs from CpuDxe driver loaded address. It is patched into
+// CommonExceptionEntry.
+//
+AsmCommonExceptionEntry
+ mrc p15, 0, R1, c6, c0, 2 ; Read IFAR
+ str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
+
+ mrc p15, 0, R1, c5, c0, 1 ; Read IFSR
+ str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+
+ mrc p15, 0, R1, c6, c0, 0 ; Read DFAR
+ str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+
+ mrc p15, 0, R1, c5, c0, 0 ; Read DFSR
+ str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+
+ ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack
+ str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+
+ add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R3, R1, #0x1f ; Check CPSR to see if User or System Mode
+ cmp R3, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1df))
+ cmpne R3, #0x10 ;
+ stmeqed R2, {lr}^ ; save unbanked lr
+ ; else
+ stmneed R2, {lr} ; save SVC lr
+
+
+ ldr R5, [SP, #0x58] ; PC is the LR pushed by srsfd
+ ; Check to see if we have to adjust for Thumb entry
+ sub r4, r0, #1 ; if (ExceptionType == 1 || ExceptionType ==2)) {
+ cmp r4, #1 ; // UND & SVC have differnt LR adjust for Thumb
+ bhi NoAdjustNeeded
+
+ tst r1, #0x20 ; if ((CPSR & T)) == T) { // Thumb Mode on entry
+ addne R5, R5, #2 ; PC += 2;
+ str R5,[SP,#0x58] ; Update LR value pused by srsfd
+
+NoAdjustNeeded
+
+ str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+ sub R1, SP, #0x60 ; We pused 0x60 bytes on the stack
+ str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+
+ ; R0 is ExceptionType
+ mov R1,SP ; R1 is SystemContext
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpush {d0-d15} ; save vstm registers in case they are used in optimizations
+#endif
+
+/*
+VOID
+EFIAPI
+DefaultExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType, R0
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
+ )
+
+*/
+ blx DefaultExceptionHandler ; Call exception handler
+
+#if (FixedPcdGet32(PcdVFPEnabled))
+ vpop {d0-d15}
+#endif
+
+ ldr R1, [SP, #0x4c] ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
+ mcr p15, 0, R1, c5, c0, 1 ; Write IFSR
+
+ ldr R1, [SP, #0x44] ; sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR
+ mcr p15, 0, R1, c5, c0, 0 ; Write DFSR
+
+ ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC
+ str R1,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored
+
+ ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR
+ str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored
+
+ add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry
+ add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R1, R1, #0x1f ; Check to see if User or System Mode
+ cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R1, #0x10 ;
+ ldmeqed R2, {lr}^ ; restore unbanked lr
+ ; else
+ ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR}
+
+ ldmfd SP!,{R0-R12} ; Restore general purpose registers
+ ; Exception handler can not change SP
+
+ add SP,SP,#0x20 ; Clear out the remaining stack space
+ ldmfd SP!,{LR} ; restore the link register for this context
+ rfefd SP! ; return from exception via srsfd stack slot
+
+ END
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c
new file mode 100644
index 0000000..fe5fd55
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c
@@ -0,0 +1,351 @@
+/** @file
+* Main file supporting the SEC Phase for Versatile Express
+*
+* 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 <Uefi.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/PeCoffLib.h>
+
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiFirmwareVolume.h>
+
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
+
+
+// Vector Table for Sec Phase
+VOID
+DebugAgentVectorTable (
+ VOID
+ );
+
+/**
+ Returns the highest bit set of the State field
+
+ @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
+ in the Attributes field.
+ @param FfsHeader Pointer to FFS File Header
+
+
+ @retval the highest bit in the State field
+
+**/
+STATIC
+EFI_FFS_FILE_STATE
+GetFileState (
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+{
+ EFI_FFS_FILE_STATE FileState;
+ EFI_FFS_FILE_STATE HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
+
+/**
+ Calculates the checksum of the header of a file.
+ The header is a zero byte checksum, so zero means header is good
+
+ @param FfsHeader Pointer to FFS File Header
+
+ @retval Checksum of the header
+
+**/
+STATIC
+UINT8
+CalculateHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FileHeader
+ )
+{
+ UINT8 Sum;
+
+ // Calculate the sum of the header
+ Sum = CalculateSum8 ((CONST VOID*)FileHeader,sizeof(EFI_FFS_FILE_HEADER));
+
+ // State field (since this indicates the different state of file).
+ Sum = (UINT8)(Sum - FileHeader->State);
+
+ // Checksum field of the file is not part of the header checksum.
+ Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
+
+ return Sum;
+}
+
+EFI_STATUS
+GetFfsFile (
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN EFI_FV_FILETYPE FileType,
+ OUT EFI_FFS_FILE_HEADER **FileHeader
+ )
+{
+ UINT64 FvLength;
+ UINTN FileOffset;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINT8 ErasePolarity;
+ UINT8 FileState;
+ UINT32 FileLength;
+ UINT32 FileOccupiedSize;
+
+ ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);
+
+ FvLength = FwVolHeader->FvLength;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
+ FileOffset = FwVolHeader->HeaderLength;
+
+ if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
+ // Get FileState which is the highest bit of the State
+ FileState = GetFileState (ErasePolarity, FfsFileHeader);
+
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_INVALID:
+ FileOffset += sizeof(EFI_FFS_FILE_HEADER);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
+ break;
+
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
+ ASSERT (FALSE);
+ return EFI_NOT_FOUND;
+ }
+
+ if (FfsFileHeader->Type == FileType) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ case EFI_FILE_DELETED:
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ default:
+ return EFI_NOT_FOUND;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+GetImageContext (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+ EFI_STATUS Status;
+ UINTN ParsedLength;
+ UINTN SectionSize;
+ UINTN SectionLength;
+ EFI_COMMON_SECTION_HEADER *Section;
+ VOID *EfiImage;
+ UINTN ImageAddress;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ VOID *CodeViewEntryPointer;
+
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
+ SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
+ SectionSize -= sizeof (EFI_FFS_FILE_HEADER);
+ ParsedLength = 0;
+ EfiImage = NULL;
+
+ while (ParsedLength < SectionSize) {
+ if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {
+ EfiImage = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(Section + 1);
+ break;
+ }
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+ SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ ASSERT (SectionLength != 0);
+ ParsedLength += SectionLength;
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ }
+
+ if (EfiImage == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ // Initialize the Image Context
+ ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+ ImageContext->Handle = EfiImage;
+ ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ Status = PeCoffLoaderGetImageInfo (ImageContext);
+ if (!EFI_ERROR(Status) && ((VOID*)(UINTN)ImageContext->DebugDirectoryEntryRva != NULL)) {
+ ImageAddress = ImageContext->ImageAddress;
+ if (ImageContext->IsTeImage) {
+ ImageAddress += sizeof (EFI_TE_IMAGE_HEADER) - ((EFI_TE_IMAGE_HEADER*)EfiImage)->StrippedSize;
+ }
+
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(ImageAddress + ImageContext->DebugDirectoryEntryRva);
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ CodeViewEntryPointer = (VOID *) (ImageAddress + (UINTN) DebugEntry->RVA);
+ switch (* (UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+ case CODEVIEW_SIGNATURE_RSDS:
+ ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+ case CODEVIEW_SIGNATURE_MTOC:
+ ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Initialize debug agent.
+
+ This function is used to set up debug environment to support source level debugging.
+ If certain Debug Agent Library instance has to save some private data in the stack,
+ this function must work on the mode that doesn't return to the caller, then
+ the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one
+ function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is
+ responsible to invoke the passing-in function at the end of InitializeDebugAgent().
+
+ If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by
+ passing in the Context to be its parameter.
+
+ If Function() is NULL, Debug Agent Library instance will return after setup debug
+ environment.
+
+ @param[in] InitFlag Init flag is used to decide the initialize process.
+ @param[in] Context Context needed according to InitFlag; it was optional.
+ @param[in] Function Continue function called by debug agent library; it was
+ optional.
+
+**/
+VOID
+EFIAPI
+InitializeDebugAgent (
+ IN UINT32 InitFlag,
+ IN VOID *Context, OPTIONAL
+ IN DEBUG_AGENT_CONTINUE Function OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ // Now we've got UART, check the Debug Agent Vector Table
+ // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure
+ // 'Align=4K' is defined into your FDF for this module.
+ ASSERT (((UINTN)DebugAgentVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
+ ArmWriteVBar ((UINTN)DebugAgentVectorTable);
+
+ // We use InitFlag to know if DebugAgent has been intialized from
+ // Sec (DEBUG_AGENT_INIT_PREMEM_SEC) or PrePi (DEBUG_AGENT_INIT_POSTMEM_SEC)
+ // modules
+ if (InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) {
+ //
+ // Get the Sec or PrePeiCore module (defined as SEC type module)
+ //
+ Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdSecureFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);
+ if (!EFI_ERROR(Status)) {
+ Status = GetImageContext (FfsHeader,&ImageContext);
+ if (!EFI_ERROR(Status)) {
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+ }
+ }
+ } else if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {
+ //
+ // Get the PrePi or PrePeiCore module (defined as SEC type module)
+ //
+ Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);
+ if (!EFI_ERROR(Status)) {
+ Status = GetImageContext (FfsHeader,&ImageContext);
+ if (!EFI_ERROR(Status)) {
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+ }
+ }
+
+ //
+ // Get the PeiCore module (defined as PEI_CORE type module)
+ //
+ Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_PEI_CORE, &FfsHeader);
+ if (!EFI_ERROR(Status)) {
+ Status = GetImageContext (FfsHeader,&ImageContext);
+ if (!EFI_ERROR(Status)) {
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+ }
+ }
+ }
+}
+
+/**
+ Enable/Disable the interrupt of debug timer and return the interrupt state
+ prior to the operation.
+
+ If EnableStatus is TRUE, enable the interrupt of debug timer.
+ If EnableStatus is FALSE, disable the interrupt of debug timer.
+
+ @param[in] EnableStatus Enable/Disable.
+
+ @return FALSE always.
+
+**/
+BOOLEAN
+EFIAPI
+SaveAndSetDebugTimerInterrupt (
+ IN BOOLEAN EnableStatus
+ )
+{
+ return FALSE;
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
new file mode 100644
index 0000000..6b784f7
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2011-2012, 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.
+#
+#
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DebugAgentSymbolsBaseLib
+ FILE_GUID = 9055e2e0-9b33-11e0-a7d7-0002a5d5c51b
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DebugAgentLib
+
+[Sources.common]
+ DebugAgentSymbolsBaseLib.c
+
+[Sources.ARM]
+ Arm/DebugAgentException.asm | RVCT
+ Arm/DebugAgentException.S | GCC
+
+[Sources.AARCH64]
+ AArch64/DebugAgentException.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ DebugLib
+ DefaultExceptionHandlerLib
+ PcdLib
+ PeCoffExtraActionLib
+ PeCoffLib
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSecureFvBaseAddress
+ gArmTokenSpaceGuid.PcdFvBaseAddress
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
new file mode 100755
index 0000000..41018de
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
@@ -0,0 +1,141 @@
+/**@file
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+Portions copyright (c) 2011 - 2012, 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 <PiDxe.h>
+#include <Library/PeCoffLib.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/PrintLib.h>
+
+
+/**
+ If the build is done on cygwin the paths are cygpaths.
+ /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert
+ them to work with RVD commands
+
+ @param Name Path to convert if needed
+
+**/
+CHAR8 *
+DeCygwinPathIfNeeded (
+ IN CHAR8 *Name,
+ IN CHAR8 *Temp,
+ IN UINTN Size
+ )
+{
+ CHAR8 *Ptr;
+ UINTN Index;
+ UINTN Index2;
+
+ Ptr = AsciiStrStr (Name, "/cygdrive/");
+ if (Ptr == NULL) {
+ return Name;
+ }
+
+ for (Index = 9, Index2 = 0; (Index < (Size + 9)) && (Ptr[Index] != '\0'); Index++, Index2++) {
+ Temp[Index2] = Ptr[Index];
+ if (Temp[Index2] == '/') {
+ Temp[Index2] = '\\' ;
+ }
+
+ if (Index2 == 1) {
+ Temp[Index2 - 1] = Ptr[Index];
+ Temp[Index2] = ':';
+ }
+ }
+
+ return Temp;
+}
+
+
+/**
+ Performs additional actions after a PE/COFF image has been loaded and relocated.
+
+ If ImageContext is NULL, then ASSERT().
+
+ @param ImageContext Pointer to the image context structure that describes the
+ PE/COFF image that has already been loaded and relocated.
+
+**/
+VOID
+EFIAPI
+PeCoffLoaderRelocateImageExtraAction (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+#if !defined(MDEPKG_NDEBUG)
+ CHAR8 Temp[512];
+#endif
+
+ if (ImageContext->PdbPointer) {
+#ifdef __CC_ARM
+#if (__ARMCC_VERSION < 500000)
+ // Print out the command for the RVD debugger to load symbols for this image
+ DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
+#else
+ // Print out the command for the DS-5 to load symbols for this image
+ DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
+#endif
+#elif __GNUC__
+ // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required
+ DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
+#else
+ DEBUG ((EFI_D_ERROR, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_POINT (ImageContext->EntryPoint)));
+#endif
+ } else {
+ DEBUG ((EFI_D_ERROR, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_POINT (ImageContext->EntryPoint)));
+ }
+}
+
+
+
+/**
+ Performs additional actions just before a PE/COFF image is unloaded. Any resources
+ that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
+
+ If ImageContext is NULL, then ASSERT().
+
+ @param ImageContext Pointer to the image context structure that describes the
+ PE/COFF image that is being unloaded.
+
+**/
+VOID
+EFIAPI
+PeCoffLoaderUnloadImageExtraAction (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+#if !defined(MDEPKG_NDEBUG)
+ CHAR8 Temp[512];
+#endif
+
+ if (ImageContext->PdbPointer) {
+#ifdef __CC_ARM
+ // Print out the command for the RVD debugger to load symbols for this image
+ DEBUG ((EFI_D_ERROR, "unload symbols_only %a\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp))));
+#elif __GNUC__
+ // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required
+ DEBUG ((EFI_D_ERROR, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
+#else
+ DEBUG ((EFI_D_ERROR, "Unloading %a\n", ImageContext->PdbPointer));
+#endif
+ } else {
+ DEBUG ((EFI_D_ERROR, "Unloading driver at 0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress));
+ }
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
new file mode 100755
index 0000000..c1f717e
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
@@ -0,0 +1,39 @@
+#/** @file
+# PeCoff extra action libary for DXE phase that run Unix emulator.
+#
+# Lib to provide memory journal status code reporting Routines
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Portions copyright (c) 2010, Apple Inc. 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 = DebugUnixPeCoffExtraActionLib
+ FILE_GUID = C3E9448E-1726-42fb-9368-41F75B038C0C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeCoffExtraActionLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM
+#
+
+[Sources.common]
+ DebugPeCoffExtraActionLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c
new file mode 100644
index 0000000..00e01a9
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.c
@@ -0,0 +1,656 @@
+/** @file
+ Debug version of the UncachedMemoryAllocation lib that uses the VirtualUncachedPages
+ protocol, produced by the DXE CPU driver, to produce debuggable uncached memory buffers.
+
+ The DMA rules for EFI contain the concept of a PCI (DMA master) address for memory and
+ a CPU (C code) address for the memory buffer that don't have to be the same. There seem to
+ be common errors out there with folks mixing up the two addresses. This library causes
+ the PCI (DMA master) address to not be mapped into system memory so if the CPU (C code)
+ uses the wrong pointer it will generate a page fault. The CPU (C code) version of the buffer
+ has a virtual address that does not match the physical address. The virtual address has
+ PcdArmUncachedMemoryMask ored into the physical address.
+
+ Copyright (c) 2008 - 2010, Apple Inc. 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 <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/VirtualUncachedPages.h>
+
+VOID *
+UncachedInternalAllocatePages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages
+ );
+
+VOID *
+UncachedInternalAllocateAlignedPages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN UINTN Alignment
+ );
+
+
+
+EFI_CPU_ARCH_PROTOCOL *gDebugUncachedCpu;
+VIRTUAL_UNCACHED_PAGES_PROTOCOL *gVirtualUncachedPages;
+
+//
+// Assume all of memory has the same cache attributes, unless we do our magic
+//
+UINT64 gAttributes;
+
+typedef struct {
+ VOID *Buffer;
+ VOID *Allocation;
+ UINTN Pages;
+ LIST_ENTRY Link;
+} FREE_PAGE_NODE;
+
+LIST_ENTRY mPageList = INITIALIZE_LIST_HEAD_VARIABLE (mPageList);
+
+VOID
+AddPagesToList (
+ IN VOID *Buffer,
+ IN VOID *Allocation,
+ UINTN Pages
+ )
+{
+ FREE_PAGE_NODE *NewNode;
+
+ NewNode = AllocatePool (sizeof (LIST_ENTRY));
+ if (NewNode == NULL) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ NewNode->Buffer = Buffer;
+ NewNode->Allocation = Allocation;
+ NewNode->Pages = Pages;
+
+ InsertTailList (&mPageList, &NewNode->Link);
+}
+
+
+VOID
+RemovePagesFromList (
+ IN VOID *Buffer,
+ OUT VOID **Allocation,
+ OUT UINTN *Pages
+ )
+{
+ LIST_ENTRY *Link;
+ FREE_PAGE_NODE *OldNode;
+
+ *Allocation = NULL;
+ *Pages = 0;
+
+ for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {
+ OldNode = BASE_CR (Link, FREE_PAGE_NODE, Link);
+ if (OldNode->Buffer == Buffer) {
+ *Allocation = OldNode->Allocation;
+ *Pages = OldNode->Pages;
+
+ RemoveEntryList (&OldNode->Link);
+ FreePool (OldNode);
+ return;
+ }
+ }
+
+ return;
+}
+
+
+
+EFI_PHYSICAL_ADDRESS
+ConvertToPhysicalAddress (
+ IN VOID *VirtualAddress
+ )
+{
+ UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);
+ UINTN PhysicalAddress;
+
+ PhysicalAddress = (UINTN)VirtualAddress & ~UncachedMemoryMask;
+
+ return (EFI_PHYSICAL_ADDRESS)PhysicalAddress;
+}
+
+
+VOID *
+ConvertToUncachedAddress (
+ IN VOID *Address
+ )
+{
+ UINTN UncachedMemoryMask = (UINTN)PcdGet64 (PcdArmUncachedMemoryMask);
+ UINTN UncachedAddress;
+
+ UncachedAddress = (UINTN)Address | UncachedMemoryMask;
+
+ return (VOID *)UncachedAddress;
+}
+
+
+
+VOID *
+UncachedInternalAllocatePages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocateAlignedPages (MemoryType, Pages, EFI_PAGE_SIZE);
+}
+
+
+VOID *
+EFIAPI
+UncachedAllocatePages (
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocatePages (EfiBootServicesData, Pages);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimePages (
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedPages (
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages);
+}
+
+
+
+VOID
+EFIAPI
+UncachedFreePages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ )
+{
+ UncachedFreeAlignedPages (Buffer, Pages);
+ return;
+}
+
+
+VOID *
+UncachedInternalAllocateAlignedPages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN UINTN Alignment
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory;
+ EFI_PHYSICAL_ADDRESS AlignedMemory;
+ UINTN AlignmentMask;
+ UINTN UnalignedPages;
+ UINTN RealPages;
+
+ //
+ // Alignment must be a power of two or zero.
+ //
+ ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+ if (Pages == 0) {
+ return NULL;
+ }
+ if (Alignment > EFI_PAGE_SIZE) {
+ //
+ // Caculate the total number of pages since alignment is larger than page size.
+ //
+ AlignmentMask = Alignment - 1;
+ RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
+ //
+ // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
+ //
+ ASSERT (RealPages > Pages);
+
+ Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
+ UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
+ if (UnalignedPages > 0) {
+ //
+ // Free first unaligned page(s).
+ //
+ Status = gBS->FreePages (Memory, UnalignedPages);
+ ASSERT_EFI_ERROR (Status);
+ }
+ Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
+ UnalignedPages = RealPages - Pages - UnalignedPages;
+ if (UnalignedPages > 0) {
+ //
+ // Free last unaligned page(s).
+ //
+ Status = gBS->FreePages (Memory, UnalignedPages);
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else {
+ //
+ // Do not over-allocate pages in this case.
+ //
+ Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ AlignedMemory = (UINTN) Memory;
+ }
+
+ Status = gVirtualUncachedPages->ConvertPages (gVirtualUncachedPages, AlignedMemory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), &gAttributes);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ AlignedMemory = (EFI_PHYSICAL_ADDRESS)(UINTN)ConvertToUncachedAddress ((VOID *)(UINTN)AlignedMemory);
+
+ return (VOID *)(UINTN)AlignedMemory;
+}
+
+
+VOID
+EFIAPI
+UncachedFreeAlignedPages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory;
+
+ ASSERT (Pages != 0);
+
+ Memory = ConvertToPhysicalAddress (Buffer);
+
+ Status = gVirtualUncachedPages->RevertPages (gVirtualUncachedPages, Memory, Pages * EFI_PAGE_SIZE, PcdGet64 (PcdArmUncachedMemoryMask), gAttributes);
+
+
+ Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Memory, Pages);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+
+
+VOID *
+UncachedInternalAllocateAlignedPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ VOID *AlignedAddress;
+
+ //
+ // Alignment must be a power of two or zero.
+ //
+ ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+ if (Alignment < EFI_PAGE_SIZE) {
+ Alignment = EFI_PAGE_SIZE;
+ }
+
+ AlignedAddress = UncachedInternalAllocateAlignedPages (PoolType, EFI_SIZE_TO_PAGES (AllocationSize), Alignment);
+ if (AlignedAddress == NULL) {
+ return NULL;
+ }
+
+ AddPagesToList ((VOID *)(UINTN)ConvertToPhysicalAddress (AlignedAddress), (VOID *)(UINTN)AlignedAddress, EFI_SIZE_TO_PAGES (AllocationSize));
+
+ return (VOID *) AlignedAddress;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimePool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
+}
+
+VOID *
+UncachedInternalAllocateAlignedZeroPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ VOID *Memory;
+ Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
+ if (Memory != NULL) {
+ Memory = ZeroMem (Memory, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimeZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
+}
+
+VOID *
+UncachedInternalAllocateAlignedCopyPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ VOID *Memory;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+ Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
+ if (Memory != NULL) {
+ Memory = CopyMem (Memory, Buffer, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
+}
+
+VOID
+EFIAPI
+UncachedFreeAlignedPool (
+ IN VOID *Buffer
+ )
+{
+ VOID *Allocation;
+ UINTN Pages;
+
+ RemovePagesFromList (Buffer, &Allocation, &Pages);
+
+ UncachedFreePages (Allocation, Pages);
+}
+
+VOID *
+UncachedInternalAllocatePool (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN AllocationSize
+ )
+{
+ UINTN CacheLineLength = ArmDataCacheLineLength ();
+ return UncachedInternalAllocateAlignedPool (MemoryType, AllocationSize, CacheLineLength);
+}
+
+VOID *
+EFIAPI
+UncachedAllocatePool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimePool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize);
+}
+
+VOID *
+UncachedInternalAllocateZeroPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize
+ )
+{
+ VOID *Memory;
+
+ Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
+ if (Memory != NULL) {
+ Memory = ZeroMem (Memory, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimeZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
+}
+
+VOID *
+UncachedInternalAllocateCopyPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ VOID *Memory;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+ Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
+ if (Memory != NULL) {
+ Memory = CopyMem (Memory, Buffer, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
+}
+
+VOID
+EFIAPI
+UncachedFreePool (
+ IN VOID *Buffer
+ )
+{
+ UncachedFreeAlignedPool (Buffer);
+}
+
+VOID
+EFIAPI
+UncachedSafeFreePool (
+ IN VOID *Buffer
+ )
+{
+ if (Buffer != NULL) {
+ UncachedFreePool (Buffer);
+ Buffer = NULL;
+ }
+}
+
+/**
+ The constructor function caches the pointer of DXE Services Table.
+
+ The constructor function caches the pointer of DXE Services Table.
+ It will ASSERT() if that operation fails.
+ It will ASSERT() if the pointer of DXE Services Table is NULL.
+ It will always return EFI_SUCCESS.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+DebugUncachedMemoryAllocationLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gDebugUncachedCpu);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBS->LocateProtocol (&gVirtualUncachedPagesProtocolGuid, NULL, (VOID **)&gVirtualUncachedPages);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
new file mode 100644
index 0000000..213188a
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
@@ -0,0 +1,47 @@
+#/** @file
+#
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = UncachedMemoryAllocationLib
+ FILE_GUID = 3C1EA826-696A-4E8A-B89D-3C5369B84F2A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UncachedMemoryAllocationLib
+ CONSTRUCTOR = DebugUncachedMemoryAllocationLibConstructor
+
+[Sources.common]
+ DebugUncachedMemoryAllocationLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ ArmLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+ gVirtualUncachedPagesProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdArmUncachedMemoryMask
+
+
+[Depex]
+ gEfiCpuArchProtocolGuid AND gVirtualUncachedPagesProtocolGuid
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
new file mode 100644
index 0000000..49d36ed
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
@@ -0,0 +1,187 @@
+/** @file
+ Default exception handler
+
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ArmDisassemblerLib.h>
+#include <Library/SerialPortLib.h>
+
+#include <Guid/DebugImageInfoTable.h>
+#include <Protocol/DebugSupport.h>
+#include <Protocol/LoadedImage.h>
+
+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
+
+STATIC CHAR8 *gExceptionTypeString[] = {
+ "Synchronous",
+ "IRQ",
+ "FIQ",
+ "SError"
+};
+
+CHAR8 *
+GetImageName (
+ IN UINTN FaultAddress,
+ OUT UINTN *ImageBase,
+ OUT UINTN *PeCoffSizeOfHeaders
+ );
+
+STATIC
+VOID
+DescribeInstructionOrDataAbort (
+ IN CHAR8 *AbortType,
+ IN UINTN Iss
+ )
+{
+ CHAR8 *AbortCause;
+
+ switch (Iss & 0x3f) {
+ case 0x0: AbortCause = "Address size fault, zeroth level of translation or translation table base register"; break;
+ case 0x1: AbortCause = "Address size fault, first level"; break;
+ case 0x2: AbortCause = "Address size fault, second level"; break;
+ case 0x3: AbortCause = "Address size fault, third level"; break;
+ case 0x4: AbortCause = "Translation fault, zeroth level"; break;
+ case 0x5: AbortCause = "Translation fault, first level"; break;
+ case 0x6: AbortCause = "Translation fault, second level"; break;
+ case 0x7: AbortCause = "Translation fault, third level"; break;
+ case 0x9: AbortCause = "Access flag fault, first level"; break;
+ case 0xa: AbortCause = "Access flag fault, second level"; break;
+ case 0xb: AbortCause = "Access flag fault, third level"; break;
+ case 0xd: AbortCause = "Permission fault, first level"; break;
+ case 0xe: AbortCause = "Permission fault, second level"; break;
+ case 0xf: AbortCause = "Permission fault, third level"; break;
+ case 0x10: AbortCause = "Synchronous external abort"; break;
+ case 0x18: AbortCause = "Synchronous parity error on memory access"; break;
+ case 0x11: AbortCause = "Asynchronous external abort"; break;
+ case 0x19: AbortCause = "Asynchronous parity error on memory access"; break;
+ case 0x14: AbortCause = "Synchronous external abort on translation table walk, zeroth level"; break;
+ case 0x15: AbortCause = "Synchronous external abort on translation table walk, first level"; break;
+ case 0x16: AbortCause = "Synchronous external abort on translation table walk, second level"; break;
+ case 0x17: AbortCause = "Synchronous external abort on translation table walk, third level"; break;
+ case 0x1c: AbortCause = "Synchronous parity error on memory access on translation table walk, zeroth level"; break;
+ case 0x1d: AbortCause = "Synchronous parity error on memory access on translation table walk, first level"; break;
+ case 0x1e: AbortCause = "Synchronous parity error on memory access on translation table walk, second level"; break;
+ case 0x1f: AbortCause = "Synchronous parity error on memory access on translation table walk, third level"; break;
+ case 0x21: AbortCause = "Alignment fault"; break;
+ case 0x22: AbortCause = "Debug event"; break;
+ case 0x30: AbortCause = "TLB conflict abort"; break;
+ case 0x33:
+ case 0x34: AbortCause = "IMPLEMENTATION DEFINED"; break;
+ case 0x35:
+ case 0x36: AbortCause = "Domain fault"; break;
+ default: AbortCause = ""; break;
+ }
+
+ DEBUG ((EFI_D_ERROR, "\n%a: %a\n", AbortType, AbortCause));
+}
+
+STATIC
+VOID
+DescribeExceptionSyndrome (
+ IN UINT32 Esr
+ )
+{
+ CHAR8 *Message;
+ UINTN Ec;
+ UINTN Iss;
+
+ Ec = Esr >> 26;
+ Iss = Esr & 0x00ffffff;
+
+ switch (Ec) {
+ case 0x15: Message = "SVC executed in AArch64"; break;
+ case 0x20:
+ case 0x21: DescribeInstructionOrDataAbort ("Instruction abort", Iss); return;
+ case 0x22: Message = "PC alignment fault"; break;
+ case 0x23: Message = "SP alignment fault"; break;
+ case 0x24:
+ case 0x25: DescribeInstructionOrDataAbort ("Data abort", Iss); return;
+ default: return;
+ }
+
+ DEBUG ((EFI_D_ERROR, "\n %a \n", Message));
+}
+
+/**
+ This is the default action to take on an unexpected exception
+
+ Since this is exception context don't do anything crazy like try to allcoate memory.
+
+ @param ExceptionType Type of the exception
+ @param SystemContext Register state at the time of the Exception
+
+**/
+VOID
+DefaultExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n\n%a Exception at 0x%016lx\n", gExceptionTypeString[ExceptionType], SystemContext.SystemContextAArch64->ELR);
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+ DEBUG_CODE_BEGIN ();
+ CHAR8 *Pdb;
+ UINTN ImageBase;
+ UINTN PeCoffSizeOfHeader;
+ Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader);
+ if (Pdb != NULL) {
+ DEBUG ((EFI_D_ERROR, "%a loaded at 0x%016lx \n", Pdb, ImageBase));
+ }
+ DEBUG_CODE_END ();
+
+ DEBUG ((EFI_D_ERROR, "\n X0 0x%016lx X1 0x%016lx X2 0x%016lx X3 0x%016lx\n", SystemContext.SystemContextAArch64->X0, SystemContext.SystemContextAArch64->X1, SystemContext.SystemContextAArch64->X2, SystemContext.SystemContextAArch64->X3));
+ DEBUG ((EFI_D_ERROR, " X4 0x%016lx X5 0x%016lx X6 0x%016lx X7 0x%016lx\n", SystemContext.SystemContextAArch64->X4, SystemContext.SystemContextAArch64->X5, SystemContext.SystemContextAArch64->X6, SystemContext.SystemContextAArch64->X7));
+ DEBUG ((EFI_D_ERROR, " X8 0x%016lx X9 0x%016lx X10 0x%016lx X11 0x%016lx\n", SystemContext.SystemContextAArch64->X8, SystemContext.SystemContextAArch64->X9, SystemContext.SystemContextAArch64->X10, SystemContext.SystemContextAArch64->X11));
+ DEBUG ((EFI_D_ERROR, " X12 0x%016lx X13 0x%016lx X14 0x%016lx X15 0x%016lx\n", SystemContext.SystemContextAArch64->X12, SystemContext.SystemContextAArch64->X13, SystemContext.SystemContextAArch64->X14, SystemContext.SystemContextAArch64->X15));
+ DEBUG ((EFI_D_ERROR, " X16 0x%016lx X17 0x%016lx X18 0x%016lx X19 0x%016lx\n", SystemContext.SystemContextAArch64->X16, SystemContext.SystemContextAArch64->X17, SystemContext.SystemContextAArch64->X18, SystemContext.SystemContextAArch64->X19));
+ DEBUG ((EFI_D_ERROR, " X20 0x%016lx X21 0x%016lx X22 0x%016lx X23 0x%016lx\n", SystemContext.SystemContextAArch64->X20, SystemContext.SystemContextAArch64->X21, SystemContext.SystemContextAArch64->X22, SystemContext.SystemContextAArch64->X23));
+ DEBUG ((EFI_D_ERROR, " X24 0x%016lx X25 0x%016lx X26 0x%016lx X27 0x%016lx\n", SystemContext.SystemContextAArch64->X24, SystemContext.SystemContextAArch64->X25, SystemContext.SystemContextAArch64->X26, SystemContext.SystemContextAArch64->X27));
+ DEBUG ((EFI_D_ERROR, " X28 0x%016lx FP 0x%016lx LR 0x%016lx \n", SystemContext.SystemContextAArch64->X28, SystemContext.SystemContextAArch64->FP, SystemContext.SystemContextAArch64->LR));
+
+ /* We save these as 128bit numbers, but have to print them as two 64bit numbers,
+ so swap the 64bit words to correctly represent a 128bit number. */
+ DEBUG ((EFI_D_ERROR, "\n V0 0x%016lx %016lx V1 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V0[1], SystemContext.SystemContextAArch64->V0[0], SystemContext.SystemContextAArch64->V1[1], SystemContext.SystemContextAArch64->V1[0]));
+ DEBUG ((EFI_D_ERROR, " V2 0x%016lx %016lx V3 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V2[1], SystemContext.SystemContextAArch64->V2[0], SystemContext.SystemContextAArch64->V3[1], SystemContext.SystemContextAArch64->V3[0]));
+ DEBUG ((EFI_D_ERROR, " V4 0x%016lx %016lx V5 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V4[1], SystemContext.SystemContextAArch64->V4[0], SystemContext.SystemContextAArch64->V5[1], SystemContext.SystemContextAArch64->V5[0]));
+ DEBUG ((EFI_D_ERROR, " V6 0x%016lx %016lx V7 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V6[1], SystemContext.SystemContextAArch64->V6[0], SystemContext.SystemContextAArch64->V7[1], SystemContext.SystemContextAArch64->V7[0]));
+ DEBUG ((EFI_D_ERROR, " V8 0x%016lx %016lx V9 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V8[1], SystemContext.SystemContextAArch64->V8[0], SystemContext.SystemContextAArch64->V9[1], SystemContext.SystemContextAArch64->V9[0]));
+ DEBUG ((EFI_D_ERROR, " V10 0x%016lx %016lx V11 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V10[1], SystemContext.SystemContextAArch64->V10[0], SystemContext.SystemContextAArch64->V11[1], SystemContext.SystemContextAArch64->V11[0]));
+ DEBUG ((EFI_D_ERROR, " V12 0x%016lx %016lx V13 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V12[1], SystemContext.SystemContextAArch64->V12[0], SystemContext.SystemContextAArch64->V13[1], SystemContext.SystemContextAArch64->V13[0]));
+ DEBUG ((EFI_D_ERROR, " V14 0x%016lx %016lx V15 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V14[1], SystemContext.SystemContextAArch64->V14[0], SystemContext.SystemContextAArch64->V15[1], SystemContext.SystemContextAArch64->V15[0]));
+ DEBUG ((EFI_D_ERROR, " V16 0x%016lx %016lx V17 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V16[1], SystemContext.SystemContextAArch64->V16[0], SystemContext.SystemContextAArch64->V17[1], SystemContext.SystemContextAArch64->V17[0]));
+ DEBUG ((EFI_D_ERROR, " V18 0x%016lx %016lx V19 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V18[1], SystemContext.SystemContextAArch64->V18[0], SystemContext.SystemContextAArch64->V19[1], SystemContext.SystemContextAArch64->V19[0]));
+ DEBUG ((EFI_D_ERROR, " V20 0x%016lx %016lx V21 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V20[1], SystemContext.SystemContextAArch64->V20[0], SystemContext.SystemContextAArch64->V21[1], SystemContext.SystemContextAArch64->V21[0]));
+ DEBUG ((EFI_D_ERROR, " V22 0x%016lx %016lx V23 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V22[1], SystemContext.SystemContextAArch64->V22[0], SystemContext.SystemContextAArch64->V23[1], SystemContext.SystemContextAArch64->V23[0]));
+ DEBUG ((EFI_D_ERROR, " V24 0x%016lx %016lx V25 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V24[1], SystemContext.SystemContextAArch64->V24[0], SystemContext.SystemContextAArch64->V25[1], SystemContext.SystemContextAArch64->V25[0]));
+ DEBUG ((EFI_D_ERROR, " V26 0x%016lx %016lx V27 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V26[1], SystemContext.SystemContextAArch64->V26[0], SystemContext.SystemContextAArch64->V27[1], SystemContext.SystemContextAArch64->V27[0]));
+ DEBUG ((EFI_D_ERROR, " V28 0x%016lx %016lx V29 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V28[1], SystemContext.SystemContextAArch64->V28[0], SystemContext.SystemContextAArch64->V29[1], SystemContext.SystemContextAArch64->V29[0]));
+ DEBUG ((EFI_D_ERROR, " V30 0x%016lx %016lx V31 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V30[1], SystemContext.SystemContextAArch64->V30[0], SystemContext.SystemContextAArch64->V31[1], SystemContext.SystemContextAArch64->V31[0]));
+
+ DEBUG ((EFI_D_ERROR, "\n SP 0x%016lx ELR 0x%016lx SPSR 0x%08lx FPSR 0x%08lx\n ESR 0x%08lx FAR 0x%016lx\n", SystemContext.SystemContextAArch64->SP, SystemContext.SystemContextAArch64->ELR, SystemContext.SystemContextAArch64->SPSR, SystemContext.SystemContextAArch64->FPSR, SystemContext.SystemContextAArch64->ESR, SystemContext.SystemContextAArch64->FAR));
+
+ DEBUG ((EFI_D_ERROR, "\n ESR : EC 0x%02x IL 0x%x ISS 0x%08x\n", (SystemContext.SystemContextAArch64->ESR & 0xFC000000) >> 26, (SystemContext.SystemContextAArch64->ESR >> 25) & 0x1, SystemContext.SystemContextAArch64->ESR & 0x1FFFFFF ));
+
+ DescribeExceptionSyndrome (SystemContext.SystemContextAArch64->ESR);
+ ASSERT (FALSE);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c
new file mode 100644
index 0000000..179fc22
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c
@@ -0,0 +1,268 @@
+/** @file
+ Default exception handler
+
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2012, 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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ArmDisassemblerLib.h>
+#include <Library/SerialPortLib.h>
+
+#include <Guid/DebugImageInfoTable.h>
+
+#include <Protocol/DebugSupport.h>
+#include <Library/DefaultExceptionHandlerLib.h>
+
+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
+
+typedef struct {
+ UINT32 BIT;
+ CHAR8 Char;
+} CPSR_CHAR;
+
+CHAR8 *
+GetImageName (
+ IN UINTN FaultAddress,
+ OUT UINTN *ImageBase,
+ OUT UINTN *PeCoffSizeOfHeaders
+ );
+
+/**
+ Convert the Current Program Status Register (CPSR) to a string. The string is
+ a defacto standard in the ARM world.
+
+ It is possible to add extra bits by adding them to CpsrChar array.
+
+ @param Cpsr ARM CPSR register value
+ @param ReturnStr 32 byte string that contains string version of CPSR
+
+**/
+VOID
+CpsrString (
+ IN UINT32 Cpsr,
+ OUT CHAR8 *ReturnStr
+ )
+{
+ UINTN Index;
+ CHAR8* Str;
+ CHAR8* ModeStr;
+ CPSR_CHAR CpsrChar[] = {
+ { 31, 'n' },
+ { 30, 'z' },
+ { 29, 'c' },
+ { 28, 'v' },
+
+ { 9, 'e' },
+ { 8, 'a' },
+ { 7, 'i' },
+ { 6, 'f' },
+ { 5, 't' },
+ { 0, '?' }
+ };
+
+ Str = ReturnStr;
+
+ for (Index = 0; CpsrChar[Index].BIT != 0; Index++, Str++) {
+ *Str = CpsrChar[Index].Char;
+ if ((Cpsr & (1 << CpsrChar[Index].BIT)) != 0) {
+ // Concert to upper case if bit is set
+ *Str &= ~0x20;
+ }
+ }
+
+ *Str++ = '_';
+ *Str = '\0';
+
+ switch (Cpsr & 0x1f) {
+ case 0x10:
+ ModeStr = "usr";
+ break;
+ case 0x011:
+ ModeStr = "fiq";
+ break;
+ case 0x12:
+ ModeStr = "irq";
+ break;
+ case 0x13:
+ ModeStr = "svc";
+ break;
+ case 0x16:
+ ModeStr = "mon";
+ break;
+ case 0x17:
+ ModeStr = "abt";
+ break;
+ case 0x1b:
+ ModeStr = "und";
+ break;
+ case 0x1f:
+ ModeStr = "sys";
+ break;
+
+ default:
+ ModeStr = "???";
+ break;
+ }
+
+ AsciiStrCat (Str, ModeStr);
+ return;
+}
+
+CHAR8 *
+FaultStatusToString (
+ IN UINT32 Status
+ )
+{
+ CHAR8 *FaultSource;
+
+ switch (Status) {
+ case 0x01: FaultSource = "Alignment fault"; break;
+ case 0x02: FaultSource = "Debug event fault"; break;
+ case 0x03: FaultSource = "Access Flag fault on Section"; break;
+ case 0x04: FaultSource = "Cache maintenance operation fault[2]"; break;
+ case 0x05: FaultSource = "Translation fault on Section"; break;
+ case 0x06: FaultSource = "Access Flag fault on Page"; break;
+ case 0x07: FaultSource = "Translation fault on Page"; break;
+ case 0x08: FaultSource = "Precise External Abort"; break;
+ case 0x09: FaultSource = "Domain fault on Section"; break;
+ case 0x0b: FaultSource = "Domain fault on Page"; break;
+ case 0x0c: FaultSource = "External abort on translation, first level"; break;
+ case 0x0d: FaultSource = "Permission fault on Section"; break;
+ case 0x0e: FaultSource = "External abort on translation, second level"; break;
+ case 0x0f: FaultSource = "Permission fault on Page"; break;
+ case 0x16: FaultSource = "Imprecise External Abort"; break;
+ default: FaultSource = "No function"; break;
+ }
+
+ return FaultSource;
+}
+
+STATIC CHAR8 *gExceptionTypeString[] = {
+ "Reset",
+ "Undefined OpCode",
+ "SVC",
+ "Prefetch Abort",
+ "Data Abort",
+ "Undefined",
+ "IRQ",
+ "FIQ"
+};
+
+/**
+ This is the default action to take on an unexpected exception
+
+ Since this is exception context don't do anything crazy like try to allcoate memory.
+
+ @param ExceptionType Type of the exception
+ @param SystemContext Register state at the time of the Exception
+
+
+**/
+VOID
+DefaultExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+ UINT32 DfsrStatus;
+ UINT32 IfsrStatus;
+ BOOLEAN DfsrWrite;
+ UINT32 PcAdjust = 0;
+
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n%a Exception PC at 0x%08x CPSR 0x%08x ",
+ gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+ DEBUG_CODE_BEGIN ();
+ CHAR8 *Pdb;
+ UINT32 ImageBase;
+ UINT32 PeCoffSizeOfHeader;
+ UINT32 Offset;
+ CHAR8 CpsrStr[32]; // char per bit. Lower 5-bits are mode that is a 3 char string
+ CHAR8 Buffer[80];
+ UINT8 *DisAsm;
+ UINT32 ItBlock;
+
+ CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);
+ DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));
+
+ Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);
+ Offset = SystemContext.SystemContextArm->PC - ImageBase;
+ if (Pdb != NULL) {
+ DEBUG ((EFI_D_ERROR, "%a\n", Pdb));
+
+ //
+ // A PE/COFF image loads its headers into memory so the headers are
+ // included in the linked addresses. ELF and Mach-O images do not
+ // include the headers so the first byte of the image is usually
+ // text (code). If you look at link maps from ELF or Mach-O images
+ // you need to subtract out the size of the PE/COFF header to get
+ // get the offset that matches the link map.
+ //
+ DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));
+
+ // If we come from an image it is safe to show the instruction. We know it should not fault
+ DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;
+ ItBlock = 0;
+ DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, TRUE, &ItBlock, Buffer, sizeof (Buffer));
+ DEBUG ((EFI_D_ERROR, "\n%a", Buffer));
+
+ switch (ExceptionType) {
+ case EXCEPT_ARM_UNDEFINED_INSTRUCTION:
+ case EXCEPT_ARM_SOFTWARE_INTERRUPT:
+ case EXCEPT_ARM_PREFETCH_ABORT:
+ case EXCEPT_ARM_DATA_ABORT:
+ // advance PC past the faulting instruction
+ PcAdjust = (UINTN)DisAsm - SystemContext.SystemContextArm->PC;
+ break;
+
+ default:
+ break;
+ }
+
+ }
+ DEBUG_CODE_END ();
+ DEBUG ((EFI_D_ERROR, "\n R0 0x%08x R1 0x%08x R2 0x%08x R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));
+ DEBUG ((EFI_D_ERROR, " R4 0x%08x R5 0x%08x R6 0x%08x R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));
+ DEBUG ((EFI_D_ERROR, " R8 0x%08x R9 0x%08x R10 0x%08x R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));
+ DEBUG ((EFI_D_ERROR, " R12 0x%08x SP 0x%08x LR 0x%08x PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));
+ DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));
+
+ // Bit10 is Status[4] Bit3:0 is Status[3:0]
+ DfsrStatus = (SystemContext.SystemContextArm->DFSR & 0xf) | ((SystemContext.SystemContextArm->DFSR >> 6) & 0x10);
+ DfsrWrite = (SystemContext.SystemContextArm->DFSR & BIT11) != 0;
+ if (DfsrStatus != 0x00) {
+ DEBUG ((EFI_D_ERROR, " %a: %a 0x%08x\n", FaultStatusToString (DfsrStatus), DfsrWrite ? "write to" : "read from", SystemContext.SystemContextArm->DFAR));
+ }
+
+ IfsrStatus = (SystemContext.SystemContextArm->IFSR & 0xf) | ((SystemContext.SystemContextArm->IFSR >> 6) & 0x10);
+ if (IfsrStatus != 0) {
+ DEBUG ((EFI_D_ERROR, " Instruction %a at 0x%08x\n", FaultStatusToString (SystemContext.SystemContextArm->IFSR & 0xf), SystemContext.SystemContextArm->IFAR));
+ }
+
+ DEBUG ((EFI_D_ERROR, "\n"));
+ ASSERT (FALSE);
+
+ // Clear the error registers that we have already displayed incase some one wants to keep going
+ SystemContext.SystemContextArm->DFSR = 0;
+ SystemContext.SystemContextArm->IFSR = 0;
+
+ // If some one is stepping past the exception handler adjust the PC to point to the next instruction
+ SystemContext.SystemContextArm->PC += PcAdjust;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerBase.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerBase.c
new file mode 100644
index 0000000..4a54298
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerBase.c
@@ -0,0 +1,35 @@
+/** @file
+
+ Copyright (c) 2012, 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 <Base.h>
+
+/**
+
+ @param FaultAddress Address to find PE/COFF image for.
+ @param ImageBase Return load address of found image
+ @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found
+
+ @retval NULL FaultAddress not in a loaded PE/COFF image.
+ @retval Path and file name of PE/COFF image.
+
+**/
+CHAR8 *
+GetImageName (
+ IN UINTN FaultAddress,
+ OUT UINTN *ImageBase,
+ OUT UINTN *PeCoffSizeOfHeaders
+ )
+{
+ return NULL;
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
new file mode 100644
index 0000000..da8190b
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
@@ -0,0 +1,45 @@
+#/** @file
+#
+# Copyright (c) 2008, 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DefaultExceptionHandlerLib
+ FILE_GUID = EACDB354-DF1A-4AF9-A171-499737ED818F
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DefaultExceptionHandlerLib
+ CONSTRUCTOR = DefaultExceptionHandlerConstructor
+
+[Sources.common]
+ DefaultExceptionHandlerUefi.c
+
+[Sources.ARM]
+ Arm/DefaultExceptionHandler.c
+
+[Sources.AARCH64]
+ AArch64/DefaultExceptionHandler.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ UefiLib
+ BaseLib
+ PrintLib
+ DebugLib
+ PeCoffGetEntryPointLib
+ ArmDisassemblerLib
+ SerialPortLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
new file mode 100644
index 0000000..8f5b3e1
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
@@ -0,0 +1,42 @@
+#/** @file
+#
+# Copyright (c) 2012, 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 = DefaultExceptionHandlerBaseLib
+ FILE_GUID = 3d5261d5-5eb7-4559-98e7-475aa9d0dc42
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DefaultExceptionHandlerLib
+
+[Sources.common]
+ DefaultExceptionHandlerBase.c
+
+[Sources.ARM]
+ Arm/DefaultExceptionHandler.c
+
+[Sources.AARCH64]
+ AArch64/DefaultExceptionHandler.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ PrintLib
+ DebugLib
+ PeCoffGetEntryPointLib
+ ArmDisassemblerLib
+ SerialPortLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c
new file mode 100644
index 0000000..b2d630c
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c
@@ -0,0 +1,96 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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 <Library/PeCoffGetEntryPointLib.h>
+#include <Library/UefiLib.h>
+
+#include <Guid/DebugImageInfoTable.h>
+
+extern EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader;
+
+/**
+ The constructor function caches EFI Debug table information for use in the exception handler.
+
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+DefaultExceptionHandlerConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
+ if (EFI_ERROR (Status)) {
+ gDebugImageTableHeader = NULL;
+ }
+ return Status;
+}
+
+/**
+ Use the EFI Debug Image Table to lookup the FaultAddress and find which PE/COFF image
+ it came from. As long as the PE/COFF image contains a debug directory entry a
+ string can be returned. For ELF and Mach-O images the string points to the Mach-O or ELF
+ image. Microsoft tools contain a pointer to the PDB file that contains the debug information.
+
+ @param FaultAddress Address to find PE/COFF image for.
+ @param ImageBase Return load address of found image
+ @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found
+
+ @retval NULL FaultAddress not in a loaded PE/COFF image.
+ @retval Path and file name of PE/COFF image.
+
+**/
+CHAR8 *
+GetImageName (
+ IN UINTN FaultAddress,
+ OUT UINTN *ImageBase,
+ OUT UINTN *PeCoffSizeOfHeaders
+ )
+{
+ EFI_DEBUG_IMAGE_INFO *DebugTable;
+ UINTN Entry;
+ CHAR8 *Address;
+
+ DebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
+ if (DebugTable == NULL) {
+ return NULL;
+ }
+
+ Address = (CHAR8 *)(UINTN)FaultAddress;
+ for (Entry = 0; Entry < gDebugImageTableHeader->TableSize; Entry++, DebugTable++) {
+ if (DebugTable->NormalImage != NULL) {
+ if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
+ (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
+ if ((Address >= (CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) &&
+ (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) {
+ *ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
+ *PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase);
+ return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
new file mode 100644
index 0000000..c2a4a35
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
@@ -0,0 +1,62 @@
+/** @file
+ PEI Services Table Pointer Library.
+
+ This library is used for PEIM which does executed from flash device directly but
+ executed in memory.
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011 Hewlett-Packard Corporation. 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 <PiPei.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Caches a pointer PEI Services Table.
+
+ Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer
+ in a platform specific manner.
+
+ If PeiServicesTablePointer is NULL, then ASSERT().
+
+ @param PeiServicesTablePointer The address of PeiServices pointer.
+**/
+VOID
+EFIAPI
+SetPeiServicesTablePointer (
+ IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer
+ )
+{
+ ArmWriteTpidrurw((UINTN)PeiServicesTablePointer);
+}
+
+/**
+ Retrieves the cached value of the PEI Services Table pointer.
+
+ Returns the cached value of the PEI Services Table pointer in a CPU specific manner
+ as specified in the CPU binding section of the Platform Initialization Pre-EFI
+ Initialization Core Interface Specification.
+
+ If the cached PEI Services Table pointer is NULL, then ASSERT().
+
+ @return The pointer to PeiServices.
+
+**/
+CONST EFI_PEI_SERVICES **
+EFIAPI
+GetPeiServicesTablePointer (
+ VOID
+ )
+{
+ return (CONST EFI_PEI_SERVICES **)ArmReadTpidrurw();
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
new file mode 100644
index 0000000..fd75977
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Instance of PEI Services Table Pointer Library using global variable for the table pointer.
+#
+# PEI Services Table Pointer Library implementation that retrieves a pointer to the
+# PEI Services Table from a global variable. Not available to modules that execute from
+# read-only memory.
+#
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 Hewlett-Packard Corporation. 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 = PeiServicesTablePointerLib
+ FILE_GUID = C3C9C4ED-EB8A-4548-BE1B-ABB0B6F35B1E
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM PEI_CORE SEC
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only)
+#
+
+[Sources]
+ PeiServicesTablePointer.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ ArmLib
+ DebugLib
+
+[Pcd]
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c
new file mode 100644
index 0000000..abe3c37
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c
@@ -0,0 +1,156 @@
+/**@file
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+Portions copyright (c) 2011 - 2012, 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 <PiDxe.h>
+#include <Library/PeCoffLib.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/SemihostLib.h>
+#include <Library/PrintLib.h>
+
+/**
+ Append string to debugger script file, create file if needed.
+
+ This library can show up in mulitple places so we need to append the file every time we write to it.
+ For example Sec can use this to load the DXE core, and the DXE core would use this to load all the
+ other modules. So we have two instances of the library in the system.
+
+ @param Buffer Buffer to write to file.
+ @param Length Length of Buffer in bytes.
+**/
+VOID
+WriteStringToFile (
+ IN VOID *Buffer,
+ IN UINT32 Length
+ )
+{
+ // Working around and issue with the code that is commented out. For now send it to the console.
+ // You can copy the console into a file and source the file as a script and you get symbols.
+ // This gets you all the symbols except for SEC. To get SEC symbols you need to copy the
+ // debug print in the SEC into the debugger manually
+ SemihostWriteString (Buffer);
+/*
+ I'm currently having issues with this code crashing the debugger. Seems like it should work.
+
+ UINT32 SemihostHandle;
+ UINT32 SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
+
+ SemihostFileOpen ("c:\rvi_symbols.inc", SemihostMode, &SemihostHandle);
+ SemihostFileWrite (SemihostHandle, &Length, Buffer);
+ SemihostFileClose (SemihostHandle);
+ */
+}
+
+
+/**
+ If the build is done on cygwin the paths are cygpaths.
+ /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert
+ them to work with RVD commands
+
+ @param Name Path to convert if needed
+
+**/
+CHAR8 *
+DeCygwinPathIfNeeded (
+ IN CHAR8 *Name
+ )
+{
+ CHAR8 *Ptr;
+ UINTN Index;
+ UINTN Len;
+
+ Ptr = AsciiStrStr (Name, "/cygdrive/");
+ if (Ptr == NULL) {
+ return Name;
+ }
+
+ Len = AsciiStrLen (Ptr);
+
+ // convert "/cygdrive" to spaces
+ for (Index = 0; Index < 9; Index++) {
+ Ptr[Index] = ' ';
+ }
+
+ // convert /c to c:
+ Ptr[9] = Ptr[10];
+ Ptr[10] = ':';
+
+ // switch path separators
+ for (Index = 11; Index < Len; Index++) {
+ if (Ptr[Index] == '/') {
+ Ptr[Index] = '\\' ;
+ }
+ }
+
+ return Name;
+}
+
+
+/**
+ Performs additional actions after a PE/COFF image has been loaded and relocated.
+
+ If ImageContext is NULL, then ASSERT().
+
+ @param ImageContext Pointer to the image context structure that describes the
+ PE/COFF image that has already been loaded and relocated.
+
+**/
+VOID
+EFIAPI
+PeCoffLoaderRelocateImageExtraAction (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+ CHAR8 Buffer[256];
+
+#if (__ARMCC_VERSION < 500000)
+ AsciiSPrint (Buffer, sizeof(Buffer), "load /a /ni /np \"%a\" &0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
+#else
+ AsciiSPrint (Buffer, sizeof(Buffer), "add-symbol-file %a 0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
+#endif
+ DeCygwinPathIfNeeded (&Buffer[16]);
+
+ WriteStringToFile (Buffer, AsciiStrSize (Buffer));
+}
+
+
+
+/**
+ Performs additional actions just before a PE/COFF image is unloaded. Any resources
+ that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
+
+ If ImageContext is NULL, then ASSERT().
+
+ @param ImageContext Pointer to the image context structure that describes the
+ PE/COFF image that is being unloaded.
+
+**/
+VOID
+EFIAPI
+PeCoffLoaderUnloadImageExtraAction (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+ CHAR8 Buffer[256];
+
+ AsciiSPrint (Buffer, sizeof(Buffer), "unload symbols_only \"%a\"\n", ImageContext->PdbPointer);
+ DeCygwinPathIfNeeded (Buffer);
+
+ WriteStringToFile (Buffer, AsciiStrSize (Buffer));
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
new file mode 100644
index 0000000..3be0237
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
@@ -0,0 +1,41 @@
+#/** @file
+# PeCoff extra action libary for DXE phase that run Unix emulator.
+#
+# Lib to provide memory journal status code reporting Routines
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Portions copyright (c) 2010, Apple Inc. 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 = RvdUnixPeCoffExtraActionLib
+ FILE_GUID = 5EDEB7E7-EA55-4E92-8216-335AC98A3B11
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeCoffExtraActionLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM
+#
+
+[Sources.common]
+ RvdPeCoffExtraActionLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ SemihostLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c
new file mode 100644
index 0000000..ec03edb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c
@@ -0,0 +1,246 @@
+/** @file
+ UEFI Debug Library that uses PrintLib to send messages to STDERR.
+
+ Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
+ Portions copyright (c) 2008 - 2009, Apple Inc. 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 <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SemihostLib.h>
+
+//
+// Define the maximum debug and assert message length that this library supports
+//
+#define MAX_DEBUG_MESSAGE_LENGTH 0x100
+
+/**
+
+ Prints a debug message to the debug output device if the specified error level is enabled.
+
+ If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print
+ the message specified by Format and the associated variable argument list to
+ the debug output device.
+
+ If Format is NULL, then ASSERT().
+
+ @param ErrorLevel The error level of the debug message.
+ @param Format Format string for the debug message to print.
+
+**/
+VOID
+EFIAPI
+DebugPrint (
+ IN UINTN ErrorLevel,
+ IN CONST CHAR8 *Format,
+ ...
+ )
+{
+ CHAR8 AsciiBuffer[MAX_DEBUG_MESSAGE_LENGTH];
+ VA_LIST Marker;
+
+ //
+ // If Format is NULL, then ASSERT().
+ //
+ ASSERT (Format != NULL);
+
+ //
+ // Check driver debug mask value and global mask
+ //
+ if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {
+ return;
+ }
+
+ //
+ // Convert the DEBUG() message to a Unicode String
+ //
+ VA_START (Marker, Format);
+ AsciiVSPrint (AsciiBuffer, sizeof (AsciiBuffer), Format, Marker);
+ VA_END (Marker);
+
+ SemihostWriteString (AsciiBuffer);
+}
+
+
+/**
+
+ Prints an assert message containing a filename, line number, and description.
+ This may be followed by a breakpoint or a dead loop.
+
+ Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
+ to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
+ PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
+ CpuDeadLoop() is called. If neither of these bits are set, then this function
+ returns immediately after the message is printed to the debug output device.
+ DebugAssert() must actively prevent recusrsion. If DebugAssert() is called while
+ processing another DebugAssert(), then DebugAssert() must return immediately.
+
+ If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
+
+ If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
+
+ @param FileName Pointer to the name of the source file that generated the assert condition.
+ @param LineNumber The line number in the source file that generated the assert condition
+ @param Description Pointer to the description of the assert condition.
+
+**/
+VOID
+EFIAPI
+DebugAssert (
+ IN CONST CHAR8 *FileName,
+ IN UINTN LineNumber,
+ IN CONST CHAR8 *Description
+ )
+{
+ CHAR8 AsciiBuffer[MAX_DEBUG_MESSAGE_LENGTH];
+
+ //
+ // Generate the ASSERT() message in Unicode format
+ //
+ AsciiSPrint (AsciiBuffer, sizeof (AsciiBuffer), "ASSERT %a(%d): %a\n", FileName, LineNumber, Description);
+
+ SemihostWriteString (AsciiBuffer);
+
+ //
+ // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
+ //
+ if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
+ CpuBreakpoint ();
+ } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
+ CpuDeadLoop ();
+ }
+}
+
+
+/**
+
+ Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the value specified by
+ PcdDebugClearMemoryValue, and returns Buffer.
+
+ If Buffer is NULL, then ASSERT().
+
+ If Length is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill with PcdDebugClearMemoryValue.
+ @param Length Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+DebugClearMemory (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ //
+ // If Buffer is NULL, then ASSERT().
+ //
+ ASSERT (Buffer != NULL);
+
+ //
+ // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
+ //
+ return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));
+}
+
+
+/**
+
+ Returns TRUE if ASSERT() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugAssertEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
+}
+
+
+/**
+
+ Returns TRUE if DEBUG()macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
+}
+
+
+/**
+
+ Returns TRUE if DEBUG_CODE()macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugCodeEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
+}
+
+
+/**
+
+ Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugClearMemoryEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
new file mode 100644
index 0000000..4c2c5ff
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
@@ -0,0 +1,47 @@
+
+#/** @file
+# Debug Library for UEFI drivers
+#
+# Library to abstract Framework extensions that conflict with UEFI 2.0 Specification
+# Copyright (c) 2007, Intel Corporation. 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 = SemiHostingDebugLib
+ FILE_GUID = 2A8D3FC4-8DB1-4D27-A3F3-780AF03CF848
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DebugLib|BASE SEC DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+
+[Sources.common]
+ DebugLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ BaseLib
+ PcdLib
+ PrintLib
+ SemihostLib
+ DebugLib
+
+[Pcd.common]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
new file mode 100644
index 0000000..fedf389
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
@@ -0,0 +1,34 @@
+#/** @file
+# Semihosting serail port lib
+#
+# Copyright (c) 2008, Apple Inc. 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 = SemiHostingSerialPortLib
+ FILE_GUID = E9FB2D1E-05D9-421C-8C35-6100BB0093B7
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SerialPortLib
+
+
+[Sources.common]
+ SerialPortLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ SemihostLib
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c
new file mode 100644
index 0000000..bc4d691
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c
@@ -0,0 +1,144 @@
+/** @file
+ Serial I/O Port library functions with no library constructor/destructor
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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 <Library/DebugLib.h>
+#include <Library/SemihostLib.h>
+#include <Library/SerialPortLib.h>
+
+
+/*
+
+ Programmed hardware of Serial port.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+ VOID
+ )
+{
+ if (SemihostConnectionSupported ()) {
+ return RETURN_SUCCESS;
+ } else {
+ return RETURN_UNSUPPORTED;
+ }
+}
+
+/**
+ Write data to serial device.
+
+ @param Buffer Point of data buffer which need to be writed.
+ @param NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Write data failed.
+ @retval !0 Actual number of bytes writed to serial device.
+
+**/
+
+#define PRINT_BUFFER_SIZE 512
+#define PRINT_BUFFER_THRESHOLD (PRINT_BUFFER_SIZE - 4)
+
+UINTN
+EFIAPI
+SerialPortWrite (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ UINT8 PrintBuffer[PRINT_BUFFER_SIZE];
+ UINTN SourceIndex = 0;
+ UINTN DestinationIndex = 0;
+ UINT8 CurrentCharacter;
+
+ while (SourceIndex < NumberOfBytes)
+ {
+ CurrentCharacter = Buffer[SourceIndex++];
+
+ switch (CurrentCharacter)
+ {
+ case '\r':
+ continue;
+
+ case '\n':
+ PrintBuffer[DestinationIndex++] = ' ';
+ // fall through
+
+ default:
+ PrintBuffer[DestinationIndex++] = CurrentCharacter;
+ break;
+ }
+
+ if (DestinationIndex > PRINT_BUFFER_THRESHOLD)
+ {
+ PrintBuffer[DestinationIndex] = '\0';
+ SemihostWriteString ((CHAR8 *) PrintBuffer);
+
+ DestinationIndex = 0;
+ }
+ }
+
+ if (DestinationIndex > 0)
+ {
+ PrintBuffer[DestinationIndex] = '\0';
+ SemihostWriteString ((CHAR8 *) PrintBuffer);
+ }
+
+ return NumberOfBytes;
+}
+
+
+/**
+ Read data from serial device and save the datas in buffer.
+
+ @param Buffer Point of data buffer which need to be writed.
+ @param NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Read data failed.
+ @retval !0 Aactual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ *Buffer = SemihostReadCharacter ();
+ return 1;
+}
+
+
+
+/**
+ Check to see if any data is avaiable to be read from the debug device.
+
+ @retval TRUE At least one byte of data is avaiable to be read
+ @retval FALSE No data is avaiable to be read
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+ VOID
+ )
+{
+ // Since SemiHosting read character is blocking always say we have a char ready?
+ return SemihostConnectionSupported ();
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S
new file mode 100644
index 0000000..42211cf
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S
@@ -0,0 +1,23 @@
+#------------------------------------------------------------------------------
+#
+# 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+
+.globl ASM_PFX(GccSemihostCall)
+
+ASM_PFX(GccSemihostCall):
+ hlt #0xf000
+ ret
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S
new file mode 100755
index 0000000..c9d1318
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+
+.globl ASM_PFX(GccSemihostCall)
+INTERWORK_FUNC(GccSemihostCall)
+
+/*
+ Semihosting operation request mechanism
+
+ SVC 0x123456 in ARM state (for all architectures)
+ SVC 0xAB in Thumb state (excluding ARMv7-M)
+ BKPT 0xAB for ARMv7-M (Thumb-2 only)
+
+ R0 - operation type
+ R1 - block containing all other parametes
+
+ lr - must be saved as svc instruction will cause an svc exception and write
+ the svc lr register. That happens to be the one we are using, so we must
+ save it or we will not be able to return.
+ */
+ASM_PFX(GccSemihostCall):
+ stmfd sp!, {lr}
+ svc #0x123456
+ ldmfd sp!, {lr}
+ bx lr
+
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.c b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.c
new file mode 100644
index 0000000..b1bbcbb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.c
@@ -0,0 +1,313 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/SemihostLib.h>
+
+#include "SemihostPrivate.h"
+
+BOOLEAN
+SemihostConnectionSupported (
+ VOID
+ )
+{
+ return SEMIHOST_SUPPORTED;
+}
+
+RETURN_STATUS
+SemihostFileOpen (
+ IN CHAR8 *FileName,
+ IN UINT32 Mode,
+ OUT UINTN *FileHandle
+ )
+{
+ SEMIHOST_FILE_OPEN_BLOCK OpenBlock;
+ INT32 Result;
+
+ if (FileHandle == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ // Remove any leading separator (e.g.: '\'). EFI Shell adds one.
+ if (*FileName == '\\') {
+ FileName++;
+ }
+
+ OpenBlock.FileName = FileName;
+ OpenBlock.Mode = Mode;
+ OpenBlock.NameLength = AsciiStrLen(FileName);
+
+ Result = Semihost_SYS_OPEN(&OpenBlock);
+
+ if (Result == -1) {
+ return RETURN_NOT_FOUND;
+ } else {
+ *FileHandle = Result;
+ return RETURN_SUCCESS;
+ }
+}
+
+RETURN_STATUS
+SemihostFileSeek (
+ IN UINTN FileHandle,
+ IN UINTN Offset
+ )
+{
+ SEMIHOST_FILE_SEEK_BLOCK SeekBlock;
+ INT32 Result;
+
+ SeekBlock.Handle = FileHandle;
+ SeekBlock.Location = Offset;
+
+ Result = Semihost_SYS_SEEK(&SeekBlock);
+
+ // Semihosting does not behave as documented. It returns the offset on
+ // success.
+ if (Result < 0) {
+ return RETURN_ABORTED;
+ } else {
+ return RETURN_SUCCESS;
+ }
+}
+
+RETURN_STATUS
+SemihostFileRead (
+ IN UINTN FileHandle,
+ IN OUT UINTN *Length,
+ OUT VOID *Buffer
+ )
+{
+ SEMIHOST_FILE_READ_WRITE_BLOCK ReadBlock;
+ UINT32 Result;
+
+ if ((Length == NULL) || (Buffer == NULL)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ ReadBlock.Handle = FileHandle;
+ ReadBlock.Buffer = Buffer;
+ ReadBlock.Length = *Length;
+
+ Result = Semihost_SYS_READ(&ReadBlock);
+
+ if ((*Length != 0) && (Result == *Length)) {
+ return RETURN_ABORTED;
+ } else {
+ *Length -= Result;
+ return RETURN_SUCCESS;
+ }
+}
+
+RETURN_STATUS
+SemihostFileWrite (
+ IN UINTN FileHandle,
+ IN OUT UINTN *Length,
+ IN VOID *Buffer
+ )
+{
+ SEMIHOST_FILE_READ_WRITE_BLOCK WriteBlock;
+
+ if ((Length == NULL) || (Buffer == NULL)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ WriteBlock.Handle = FileHandle;
+ WriteBlock.Buffer = Buffer;
+ WriteBlock.Length = *Length;
+
+ *Length = Semihost_SYS_WRITE(&WriteBlock);
+
+ if (*Length != 0)
+ return RETURN_ABORTED;
+ else
+ return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+SemihostFileClose (
+ IN UINTN FileHandle
+ )
+{
+ INT32 Result = Semihost_SYS_CLOSE(&FileHandle);
+
+ if (Result == -1) {
+ return RETURN_INVALID_PARAMETER;
+ } else {
+ return RETURN_SUCCESS;
+ }
+}
+
+RETURN_STATUS
+SemihostFileLength (
+ IN UINTN FileHandle,
+ OUT UINTN *Length
+ )
+{
+ INT32 Result;
+
+ if (Length == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ Result = Semihost_SYS_FLEN(&FileHandle);
+
+ if (Result == -1) {
+ return RETURN_ABORTED;
+ } else {
+ *Length = Result;
+ return RETURN_SUCCESS;
+ }
+}
+
+/**
+ Get a temporary name for a file from the host running the debug agent.
+
+ @param[out] Buffer Pointer to the buffer where the temporary name has to
+ be stored
+ @param[in] Identifier File name identifier (integer in the range 0 to 255)
+ @param[in] Length Length of the buffer to store the temporary name
+
+ @retval RETURN_SUCCESS Temporary name returned
+ @retval RETURN_INVALID_PARAMETER Invalid buffer address
+ @retval RETURN_ABORTED Temporary name not returned
+
+**/
+RETURN_STATUS
+SemihostFileTmpName(
+ OUT VOID *Buffer,
+ IN UINT8 Identifier,
+ IN UINTN Length
+ )
+{
+ SEMIHOST_FILE_TMPNAME_BLOCK TmpNameBlock;
+ INT32 Result;
+
+ if (Buffer == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ TmpNameBlock.Buffer = Buffer;
+ TmpNameBlock.Identifier = Identifier;
+ TmpNameBlock.Length = Length;
+
+ Result = Semihost_SYS_TMPNAME (&TmpNameBlock);
+
+ if (Result != 0) {
+ return RETURN_ABORTED;
+ } else {
+ return RETURN_SUCCESS;
+ }
+}
+
+RETURN_STATUS
+SemihostFileRemove (
+ IN CHAR8 *FileName
+ )
+{
+ SEMIHOST_FILE_REMOVE_BLOCK RemoveBlock;
+ UINT32 Result;
+
+ // Remove any leading separator (e.g.: '\'). EFI Shell adds one.
+ if (*FileName == '\\') {
+ FileName++;
+ }
+
+ RemoveBlock.FileName = FileName;
+ RemoveBlock.NameLength = AsciiStrLen(FileName);
+
+ Result = Semihost_SYS_REMOVE(&RemoveBlock);
+
+ if (Result == 0) {
+ return RETURN_SUCCESS;
+ } else {
+ return RETURN_ABORTED;
+ }
+}
+
+/**
+ Rename a specified file.
+
+ @param[in] FileName Name of the file to rename.
+ @param[in] NewFileName The new name of the file.
+
+ @retval RETURN_SUCCESS File Renamed
+ @retval RETURN_INVALID_PARAMETER Either the current or the new name is not specified
+ @retval RETURN_ABORTED Rename failed
+
+**/
+RETURN_STATUS
+SemihostFileRename(
+ IN CHAR8 *FileName,
+ IN CHAR8 *NewFileName
+ )
+{
+ SEMIHOST_FILE_RENAME_BLOCK RenameBlock;
+ INT32 Result;
+
+ if ((FileName == NULL) || (NewFileName == NULL)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ RenameBlock.FileName = FileName;
+ RenameBlock.FileNameLength = AsciiStrLen (FileName);
+ RenameBlock.NewFileName = NewFileName;
+ RenameBlock.NewFileNameLength = AsciiStrLen (NewFileName);
+
+ Result = Semihost_SYS_RENAME (&RenameBlock);
+
+ if (Result != 0) {
+ return RETURN_ABORTED;
+ } else {
+ return RETURN_SUCCESS;
+ }
+}
+
+CHAR8
+SemihostReadCharacter (
+ VOID
+ )
+{
+ return Semihost_SYS_READC();
+}
+
+VOID
+SemihostWriteCharacter (
+ IN CHAR8 Character
+ )
+{
+ Semihost_SYS_WRITEC(&Character);
+}
+
+VOID
+SemihostWriteString (
+ IN CHAR8 *String
+ )
+{
+ Semihost_SYS_WRITE0(String);
+}
+
+UINT32
+SemihostSystem (
+ IN CHAR8 *CommandLine
+ )
+{
+ SEMIHOST_SYSTEM_BLOCK SystemBlock;
+
+ SystemBlock.CommandLine = CommandLine;
+ SystemBlock.CommandLength = AsciiStrLen(CommandLine);
+
+ return Semihost_SYS_SYSTEM(&SystemBlock);
+}
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.inf b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.inf
new file mode 100644
index 0000000..460f4cd
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostLib.inf
@@ -0,0 +1,46 @@
+#/** @file
+# Semihosting JTAG lib
+#
+# 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.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SemihostLib
+ FILE_GUID = C40D08BA-DB7B-4F07-905A-C5FE4B5AF987
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SemihostLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM AARCH64
+#
+[Sources.common]
+ SemihostLib.c
+
+[Sources.ARM]
+ Arm/GccSemihost.S | GCC
+
+[Sources.AARCH64]
+ AArch64/GccSemihost.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostPrivate.h b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostPrivate.h
new file mode 100644
index 0000000..afc5327
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/SemihostLib/SemihostPrivate.h
@@ -0,0 +1,218 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SEMIHOST_PRIVATE_H__
+#define __SEMIHOST_PRIVATE_H__
+
+typedef struct {
+ CHAR8 *FileName;
+ UINTN Mode;
+ UINTN NameLength;
+} SEMIHOST_FILE_OPEN_BLOCK;
+
+typedef struct {
+ UINTN Handle;
+ VOID *Buffer;
+ UINTN Length;
+} SEMIHOST_FILE_READ_WRITE_BLOCK;
+
+typedef struct {
+ UINTN Handle;
+ UINTN Location;
+} SEMIHOST_FILE_SEEK_BLOCK;
+
+typedef struct {
+ VOID *Buffer;
+ UINTN Identifier;
+ UINTN Length;
+} SEMIHOST_FILE_TMPNAME_BLOCK;
+
+typedef struct {
+ CHAR8 *FileName;
+ UINTN NameLength;
+} SEMIHOST_FILE_REMOVE_BLOCK;
+
+typedef struct {
+ CHAR8 *FileName;
+ UINTN FileNameLength;
+ CHAR8 *NewFileName;
+ UINTN NewFileNameLength;
+} SEMIHOST_FILE_RENAME_BLOCK;
+
+typedef struct {
+ CHAR8 *CommandLine;
+ UINTN CommandLength;
+} SEMIHOST_SYSTEM_BLOCK;
+
+#if defined(__CC_ARM)
+
+#if defined(__thumb__)
+#define SWI 0xAB
+#else
+#define SWI 0x123456
+#endif
+
+#define SEMIHOST_SUPPORTED TRUE
+
+__swi(SWI)
+INT32
+_Semihost_SYS_OPEN(
+ IN UINTN SWI_0x01,
+ IN SEMIHOST_FILE_OPEN_BLOCK *OpenBlock
+ );
+
+__swi(SWI)
+INT32
+_Semihost_SYS_CLOSE(
+ IN UINTN SWI_0x02,
+ IN UINT32 *Handle
+ );
+
+__swi(SWI)
+VOID
+_Semihost_SYS_WRITEC(
+ IN UINTN SWI_0x03,
+ IN CHAR8 *Character
+ );
+
+__swi(SWI)
+VOID
+_Semihost_SYS_WRITE0(
+ IN UINTN SWI_0x04,
+ IN CHAR8 *String
+ );
+
+__swi(SWI)
+UINT32
+_Semihost_SYS_WRITE(
+ IN UINTN SWI_0x05,
+ IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *WriteBlock
+ );
+
+__swi(SWI)
+UINT32
+_Semihost_SYS_READ(
+ IN UINTN SWI_0x06,
+ IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *ReadBlock
+ );
+
+__swi(SWI)
+CHAR8
+_Semihost_SYS_READC(
+ IN UINTN SWI_0x07,
+ IN UINTN Zero
+ );
+
+__swi(SWI)
+INT32
+_Semihost_SYS_SEEK(
+ IN UINTN SWI_0x0A,
+ IN SEMIHOST_FILE_SEEK_BLOCK *SeekBlock
+ );
+
+__swi(SWI)
+INT32
+_Semihost_SYS_FLEN(
+ IN UINTN SWI_0x0C,
+ IN UINT32 *Handle
+ );
+
+__swi(SWI)
+UINT32
+_Semihost_SYS_TMPNAME(
+ IN UINTN SWI_0x0D,
+ IN SEMIHOST_FILE_TMPNAME_BLOCK *TmpNameBlock
+ );
+
+__swi(SWI)
+UINT32
+_Semihost_SYS_REMOVE(
+ IN UINTN SWI_0x0E,
+ IN SEMIHOST_FILE_REMOVE_BLOCK *RemoveBlock
+ );
+
+__swi(SWI)
+UINT32
+_Semihost_SYS_RENAME(
+ IN UINTN SWI_0x0F,
+ IN SEMIHOST_FILE_RENAME_BLOCK *RenameBlock
+ );
+
+__swi(SWI)
+UINT32
+_Semihost_SYS_SYSTEM(
+ IN UINTN SWI_0x12,
+ IN SEMIHOST_SYSTEM_BLOCK *SystemBlock
+ );
+
+#define Semihost_SYS_OPEN(OpenBlock) _Semihost_SYS_OPEN(0x01, OpenBlock)
+#define Semihost_SYS_CLOSE(Handle) _Semihost_SYS_CLOSE(0x02, Handle)
+#define Semihost_SYS_WRITE0(String) _Semihost_SYS_WRITE0(0x04, String)
+#define Semihost_SYS_WRITEC(Character) _Semihost_SYS_WRITEC(0x03, Character)
+#define Semihost_SYS_WRITE(WriteBlock) _Semihost_SYS_WRITE(0x05, WriteBlock)
+#define Semihost_SYS_READ(ReadBlock) _Semihost_SYS_READ(0x06, ReadBlock)
+#define Semihost_SYS_READC() _Semihost_SYS_READC(0x07, 0)
+#define Semihost_SYS_SEEK(SeekBlock) _Semihost_SYS_SEEK(0x0A, SeekBlock)
+#define Semihost_SYS_FLEN(Handle) _Semihost_SYS_FLEN(0x0C, Handle)
+#define Semihost_SYS_TMPNAME(TmpNameBlock) _Semihost_SYS_TMPNAME(0x0D, TmpNameBlock)
+#define Semihost_SYS_REMOVE(RemoveBlock) _Semihost_SYS_REMOVE(0x0E, RemoveBlock)
+#define Semihost_SYS_RENAME(RenameBlock) _Semihost_SYS_RENAME(0x0F, RenameBlock)
+#define Semihost_SYS_SYSTEM(SystemBlock) _Semihost_SYS_SYSTEM(0x12, SystemBlock)
+
+#elif defined(__GNUC__) // __CC_ARM
+
+#define SEMIHOST_SUPPORTED TRUE
+
+UINT32
+GccSemihostCall (
+ IN UINT32 Operation,
+ IN UINTN SystemBlockAddress
+ ); // __attribute__ ((interrupt ("SVC")));
+
+#define Semihost_SYS_OPEN(OpenBlock) GccSemihostCall(0x01, (UINTN)(OpenBlock))
+#define Semihost_SYS_CLOSE(Handle) GccSemihostCall(0x02, (UINTN)(Handle))
+#define Semihost_SYS_WRITE0(String) GccSemihostCall(0x04, (UINTN)(String))
+#define Semihost_SYS_WRITEC(Character) GccSemihostCall(0x03, (UINTN)(Character))
+#define Semihost_SYS_WRITE(WriteBlock) GccSemihostCall(0x05, (UINTN)(WriteBlock))
+#define Semihost_SYS_READ(ReadBlock) GccSemihostCall(0x06, (UINTN)(ReadBlock))
+#define Semihost_SYS_READC() GccSemihostCall(0x07, (UINTN)(0))
+#define Semihost_SYS_SEEK(SeekBlock) GccSemihostCall(0x0A, (UINTN)(SeekBlock))
+#define Semihost_SYS_FLEN(Handle) GccSemihostCall(0x0C, (UINTN)(Handle))
+#define Semihost_SYS_TMPNAME(TmpNameBlock) GccSemihostCall(0x0D, (UINTN)(TmpNameBlock))
+#define Semihost_SYS_REMOVE(RemoveBlock) GccSemihostCall(0x0E, (UINTN)(RemoveBlock))
+#define Semihost_SYS_RENAME(RenameBlock) GccSemihostCall(0x0F, (UINTN)(RenameBlock))
+#define Semihost_SYS_SYSTEM(SystemBlock) GccSemihostCall(0x12, (UINTN)(SystemBlock))
+
+#else // __CC_ARM
+
+#define SEMIHOST_SUPPORTED FALSE
+
+#define Semihost_SYS_OPEN(OpenBlock) (-1)
+#define Semihost_SYS_CLOSE(Handle) (-1)
+#define Semihost_SYS_WRITE0(String)
+#define Semihost_SYS_WRITEC(Character)
+#define Semihost_SYS_WRITE(WriteBlock) (0)
+#define Semihost_SYS_READ(ReadBlock) ((ReadBlock)->Length)
+#define Semihost_SYS_READC() ('x')
+#define Semihost_SYS_SEEK(SeekBlock) (-1)
+#define Semihost_SYS_FLEN(Handle) (-1)
+#define Semihost_SYS_TMPNAME(TmpNameBlock) (-1)
+#define Semihost_SYS_REMOVE(RemoveBlock) (-1)
+#define Semihost_SYS_RENAME(RenameBlock) (-1)
+#define Semihost_SYS_SYSTEM(SystemBlock) (-1)
+
+#endif // __CC_ARM
+
+#endif //__SEMIHOST_PRIVATE_H__
diff --git a/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c
new file mode 100644
index 0000000..e70d877
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c
@@ -0,0 +1,687 @@
+/** @file
+ UncachedMemoryAllocation lib that uses DXE Service to change cachability for
+ a buffer.
+
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2014, AMR 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 <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+#include <Library/DxeServicesTableLib.h>
+
+VOID *
+UncachedInternalAllocatePages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages
+ );
+
+VOID *
+UncachedInternalAllocateAlignedPages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN UINTN Alignment
+ );
+
+
+
+//
+// Assume all of memory has the same cache attributes, unless we do our magic
+//
+UINT64 gAttributes;
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS Base;
+ VOID *Allocation;
+ UINTN Pages;
+ EFI_MEMORY_TYPE MemoryType;
+ BOOLEAN Allocated;
+ LIST_ENTRY Link;
+} FREE_PAGE_NODE;
+
+STATIC LIST_ENTRY mPageList = INITIALIZE_LIST_HEAD_VARIABLE (mPageList);
+// Track the size of the non-allocated buffer in the linked-list
+STATIC UINTN mFreedBufferSize = 0;
+
+/**
+ * This function firstly checks if the requested allocation can fit into one
+ * of the previously allocated buffer.
+ * If the requested allocation does not fit in the existing pool then
+ * the function makes a new allocation.
+ *
+ * @param MemoryType Type of memory requested for the new allocation
+ * @param Pages Number of requested page
+ * @param Alignment Required alignment
+ * @param Allocation Address of the newly allocated buffer
+ *
+ * @return EFI_SUCCESS If the function manage to allocate a buffer
+ * @return !EFI_SUCCESS If the function did not manage to allocate a buffer
+ */
+STATIC
+EFI_STATUS
+AllocatePagesFromList (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN UINTN Alignment,
+ OUT VOID **Allocation
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Link;
+ FREE_PAGE_NODE *Node;
+ FREE_PAGE_NODE *NewNode;
+ UINTN AlignmentMask;
+ EFI_PHYSICAL_ADDRESS Memory;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+
+ // Alignment must be a power of two or zero.
+ ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+ //
+ // Look in our list for the smallest page that could satisfy the new allocation
+ //
+ NewNode = NULL;
+ for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {
+ Node = BASE_CR (Link, FREE_PAGE_NODE, Link);
+ if ((Node->Allocated == FALSE) && (Node->MemoryType == MemoryType)) {
+ // We have a node that fits our requirements
+ if (((UINTN)Node->Base & (Alignment - 1)) == 0) {
+ // We found a page that matches the page size
+ if (Node->Pages == Pages) {
+ Node->Allocated = TRUE;
+ Node->Allocation = (VOID*)(UINTN)Node->Base;
+ *Allocation = Node->Allocation;
+
+ // Update the size of the freed buffer
+ mFreedBufferSize -= Pages * EFI_PAGE_SIZE;
+ return EFI_SUCCESS;
+ } else if (Node->Pages > Pages) {
+ if (NewNode == NULL) {
+ // It is the first node that could contain our new allocation
+ NewNode = Node;
+ } else if (NewNode->Pages > Node->Pages) {
+ // This node offers a smaller number of page.
+ NewNode = Node;
+ }
+ }
+ }
+ }
+ }
+ // Check if we have found a node that could contain our new allocation
+ if (NewNode != NULL) {
+ NewNode->Allocated = TRUE;
+ Node->Allocation = (VOID*)(UINTN)Node->Base;
+ *Allocation = Node->Allocation;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Otherwise, we need to allocate a new buffer
+ //
+
+ // We do not want to over-allocate in case the alignment requirement does not
+ // require extra pages
+ if (Alignment > EFI_PAGE_SIZE) {
+ AlignmentMask = Alignment - 1;
+ Pages += EFI_SIZE_TO_PAGES (Alignment);
+ } else {
+ AlignmentMask = 0;
+ }
+
+ Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gDS->GetMemorySpaceDescriptor (Memory, &Descriptor);
+ if (!EFI_ERROR (Status)) {
+ // We are making an assumption that all of memory has the same default attributes
+ gAttributes = Descriptor.Attributes;
+ } else {
+ gBS->FreePages (Memory, Pages);
+ return Status;
+ }
+
+ Status = gDS->SetMemorySpaceAttributes (Memory, EFI_PAGES_TO_SIZE (Pages), EFI_MEMORY_WC);
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (Memory, Pages);
+ return Status;
+ }
+
+ NewNode = AllocatePool (sizeof (FREE_PAGE_NODE));
+ if (NewNode == NULL) {
+ ASSERT (FALSE);
+ gBS->FreePages (Memory, Pages);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewNode->Base = Memory;
+ NewNode->Allocation = (VOID*)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask);
+ NewNode->Pages = Pages;
+ NewNode->Allocated = TRUE;
+ NewNode->MemoryType = MemoryType;
+
+ InsertTailList (&mPageList, &NewNode->Link);
+
+ *Allocation = NewNode->Allocation;
+ return EFI_SUCCESS;
+}
+
+/**
+ * Free the memory allocation
+ *
+ * This function will actually try to find the allocation in the linked list.
+ * And it will then mark the entry as freed.
+ *
+ * @param Allocation Base address of the buffer to free
+ *
+ * @return EFI_SUCCESS The allocation has been freed
+ * @return EFI_NOT_FOUND The allocation was not found in the pool.
+ * @return EFI_INVALID_PARAMETER If Allocation is NULL
+ *
+ */
+STATIC
+EFI_STATUS
+FreePagesFromList (
+ IN VOID *Allocation
+ )
+{
+ LIST_ENTRY *Link;
+ FREE_PAGE_NODE *Node;
+
+ if (Allocation == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Link = mPageList.ForwardLink; Link != &mPageList; Link = Link->ForwardLink) {
+ Node = BASE_CR (Link, FREE_PAGE_NODE, Link);
+ if ((UINTN)Node->Allocation == (UINTN)Allocation) {
+ Node->Allocated = FALSE;
+
+ // Update the size of the freed buffer
+ mFreedBufferSize += Node->Pages * EFI_PAGE_SIZE;
+
+ // If the size of the non-allocated reaches the threshold we raise a warning.
+ // It might be an expected behaviour in some cases.
+ // We might device to free some of these buffers later on.
+ if (mFreedBufferSize > PcdGet64 (PcdArmFreeUncachedMemorySizeThreshold)) {
+ DEBUG ((EFI_D_WARN, "Warning: The list of non-allocated buffer has reach the threshold.\n"));
+ }
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ * This function is automatically invoked when the driver exits
+ * It frees all the non-allocated memory buffer.
+ * This function is not responsible to free allocated buffer (eg: case of memory leak,
+ * runtime allocation).
+ */
+EFI_STATUS
+EFIAPI
+UncachedMemoryAllocationLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ LIST_ENTRY *Link;
+ FREE_PAGE_NODE *OldNode;
+
+ // Test if the list is empty
+ Link = mPageList.ForwardLink;
+ if (Link == &mPageList) {
+ return EFI_SUCCESS;
+ }
+
+ // Free all the pages and nodes
+ do {
+ OldNode = BASE_CR (Link, FREE_PAGE_NODE, Link);
+ // Point to the next entry
+ Link = Link->ForwardLink;
+
+ // We only free the non-allocated buffer
+ if (OldNode->Allocated == FALSE) {
+ gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)OldNode->Base, OldNode->Pages);
+ RemoveEntryList (&OldNode->Link);
+ FreePool (OldNode);
+ }
+ } while (Link != &mPageList);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Converts a cached or uncached address to a physical address suitable for use in SoC registers.
+
+ @param VirtualAddress The pointer to convert.
+
+ @return The physical address of the supplied virtual pointer.
+
+**/
+EFI_PHYSICAL_ADDRESS
+ConvertToPhysicalAddress (
+ IN VOID *VirtualAddress
+ )
+{
+ return (EFI_PHYSICAL_ADDRESS)(UINTN)VirtualAddress;
+}
+
+
+VOID *
+UncachedInternalAllocatePages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocateAlignedPages (MemoryType, Pages, EFI_PAGE_SIZE);
+}
+
+
+VOID *
+EFIAPI
+UncachedAllocatePages (
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocatePages (EfiBootServicesData, Pages);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimePages (
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedPages (
+ IN UINTN Pages
+ )
+{
+ return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages);
+}
+
+
+
+VOID
+EFIAPI
+UncachedFreePages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ )
+{
+ UncachedFreeAlignedPages (Buffer, Pages);
+ return;
+}
+
+
+VOID *
+UncachedInternalAllocateAlignedPages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN UINTN Alignment
+ )
+{
+ EFI_STATUS Status;
+ VOID *Allocation;
+
+ if (Pages == 0) {
+ return NULL;
+ }
+
+ Allocation = NULL;
+ Status = AllocatePagesFromList (MemoryType, Pages, Alignment, &Allocation);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return NULL;
+ } else {
+ return Allocation;
+ }
+}
+
+
+VOID
+EFIAPI
+UncachedFreeAlignedPages (
+ IN VOID *Buffer,
+ IN UINTN Pages
+ )
+{
+ FreePagesFromList (Buffer);
+}
+
+
+VOID *
+UncachedInternalAllocateAlignedPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ VOID *AlignedAddress;
+
+ //
+ // Alignment must be a power of two or zero.
+ //
+ ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+ if (Alignment < EFI_PAGE_SIZE) {
+ Alignment = EFI_PAGE_SIZE;
+ }
+
+ AlignedAddress = UncachedInternalAllocateAlignedPages (PoolType, EFI_SIZE_TO_PAGES (AllocationSize), Alignment);
+ if (AlignedAddress == NULL) {
+ return NULL;
+ }
+
+ return (VOID *) AlignedAddress;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimePool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
+}
+
+VOID *
+UncachedInternalAllocateAlignedZeroPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ VOID *Memory;
+ Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
+ if (Memory != NULL) {
+ Memory = ZeroMem (Memory, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimeZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedZeroPool (
+ IN UINTN AllocationSize,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
+}
+
+VOID *
+UncachedInternalAllocateAlignedCopyPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ VOID *Memory;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+ Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
+ if (Memory != NULL) {
+ Memory = CopyMem (Memory, Buffer, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateAlignedReservedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer,
+ IN UINTN Alignment
+ )
+{
+ return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
+}
+
+VOID
+EFIAPI
+UncachedFreeAlignedPool (
+ IN VOID *Allocation
+ )
+{
+ UncachedFreePages (Allocation, 0);
+}
+
+VOID *
+UncachedInternalAllocatePool (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN AllocationSize
+ )
+{
+ UINTN CacheLineLength = ArmDataCacheLineLength ();
+ return UncachedInternalAllocateAlignedPool (MemoryType, AllocationSize, CacheLineLength);
+}
+
+VOID *
+EFIAPI
+UncachedAllocatePool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimePool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize);
+}
+
+VOID *
+UncachedInternalAllocateZeroPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize
+ )
+{
+ VOID *Memory;
+
+ Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
+ if (Memory != NULL) {
+ Memory = ZeroMem (Memory, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimeZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
+}
+
+VOID *
+UncachedInternalAllocateCopyPool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ VOID *Memory;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
+
+ Memory = UncachedInternalAllocatePool (PoolType, AllocationSize);
+ if (Memory != NULL) {
+ Memory = CopyMem (Memory, Buffer, AllocationSize);
+ }
+ return Memory;
+}
+
+VOID *
+EFIAPI
+UncachedAllocateCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
+}
+
+VOID *
+EFIAPI
+UncachedAllocateReservedCopyPool (
+ IN UINTN AllocationSize,
+ IN CONST VOID *Buffer
+ )
+{
+ return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
+}
+
+VOID
+EFIAPI
+UncachedFreePool (
+ IN VOID *Buffer
+ )
+{
+ UncachedFreeAlignedPool (Buffer);
+}
+
+VOID
+EFIAPI
+UncachedSafeFreePool (
+ IN VOID *Buffer
+ )
+{
+ if (Buffer != NULL) {
+ UncachedFreePool (Buffer);
+ Buffer = NULL;
+ }
+}
+
diff --git a/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
new file mode 100644
index 0000000..0a0b6cb
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
@@ -0,0 +1,43 @@
+#/** @file
+#
+# UncachedMemoryAllocation lib that uses DXE Service to change cachability for
+# a buffer.
+#
+# Copyright (c) 2008 - 2010, Apple Inc. 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 = UncachedMemoryAllocationLib
+ FILE_GUID = DC101A1A-7525-429B-84AF-EEAA630E576C
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UncachedMemoryAllocationLib
+
+ DESTRUCTOR = UncachedMemoryAllocationLibDestructor
+
+[Sources.common]
+ UncachedMemoryAllocationLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ ArmLib
+ MemoryAllocationLib
+ PcdLib
+ DxeServicesTableLib
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdArmFreeUncachedMemorySizeThreshold
diff --git a/uefi/linaro-edk2/ArmPkg/License.txt b/uefi/linaro-edk2/ArmPkg/License.txt
new file mode 100755
index 0000000..05dbd36
--- /dev/null
+++ b/uefi/linaro-edk2/ArmPkg/License.txt
@@ -0,0 +1,26 @@
+Copyright (c) 2009-2010, Apple Inc. All rights reserved.
+Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+* 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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE
+COPYRIGHT HOLDER 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.