Преглед изворни кода

Adding support for BeagleBoard.
ArmPkg - Supoprt for ARM specific things that can change as the architecture changes. Plus semihosting JTAG drivers.
EmbeddedPkg - Generic support for an embeddded platform. Including a light weight command line shell.
BeagleBoardPkg - Platform specifics for BeagleBoard. SD Card works, but USB has issues. Looks like a bug in the open source USB stack (Our internal stack works fine).


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9518 6f19259b-4bc3-4df7-8a09-765794883524

AJFISH пре 14 година
родитељ
комит
2ef2b01e07
100 измењених фајлова са 10035 додато и 0 уклоњено
  1. 36 0
      ArmPkg/ArmPkg.dec
  2. 61 0
      ArmPkg/ArmPkg.dsc
  3. 154 0
      ArmPkg/Drivers/CpuDxe/CpuDxe.c
  4. 91 0
      ArmPkg/Drivers/CpuDxe/CpuDxe.h
  5. 56 0
      ArmPkg/Drivers/CpuDxe/CpuDxe.inf
  6. 247 0
      ArmPkg/Drivers/CpuDxe/DebugSupport.c
  7. 238 0
      ArmPkg/Drivers/CpuDxe/Exception.c
  8. 152 0
      ArmPkg/Drivers/CpuDxe/ExceptionSupport.S
  9. 152 0
      ArmPkg/Drivers/CpuDxe/ExceptionSupport.asm
  10. 119 0
      ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c
  11. 30 0
      ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf
  12. 526 0
      ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
  13. 114 0
      ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h
  14. 48 0
      ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
  15. 236 0
      ArmPkg/Include/AsmMacroIoLib.h
  16. 74 0
      ArmPkg/Include/AsmMacroIoLib.inc
  17. 111 0
      ArmPkg/Include/Chipset/ARM1176JZ-S.h
  18. 71 0
      ArmPkg/Include/Chipset/ARM926EJ-S.h
  19. 104 0
      ArmPkg/Include/Chipset/Cortex-A8.h
  20. 294 0
      ArmPkg/Include/Library/ArmLib.h
  21. 100 0
      ArmPkg/Include/Library/SemihostLib.h
  22. 665 0
      ArmPkg/Include/Library/UncachedMemoryAllocationLib.h
  23. 59 0
      ArmPkg/Include/Protocol/TimerDebugSupport.h
  24. 129 0
      ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c
  25. 23 0
      ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
  26. 32 0
      ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf
  27. 32 0
      ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf
  28. 118 0
      ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c
  29. 129 0
      ArmPkg/Library/ArmLib/Arm11/Arm11Support.S
  30. 133 0
      ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm
  31. 32 0
      ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
  32. 32 0
      ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
  33. 164 0
      ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
  34. 118 0
      ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c
  35. 128 0
      ArmPkg/Library/ArmLib/Arm9/Arm9Support.S
  36. 129 0
      ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm
  37. 288 0
      ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.c
  38. 45 0
      ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.h
  39. 140 0
      ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.S
  40. 141 0
      ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.asm
  41. 31 0
      ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
  42. 31 0
      ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLibPrePi.inf
  43. 60 0
      ArmPkg/Library/ArmLib/Common/ArmLib.c
  44. 70 0
      ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h
  45. 89 0
      ArmPkg/Library/ArmLib/Common/ArmLibSupport.S
  46. 90 0
      ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm
  47. 106 0
      ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c
  48. 117 0
      ArmPkg/Library/ArmLib/Null/NullArmLib.c
  49. 26 0
      ArmPkg/Library/ArmLib/Null/NullArmLib.inf
  50. 83 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h
  51. 38 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
  52. 83 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c
  53. 39 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
  54. 84 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c
  55. 96 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c
  56. 111 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c
  57. 155 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
  58. 48 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
  59. 77 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c
  60. 33 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
  61. 78 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c
  62. 41 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm
  63. 54 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
  64. 43 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm
  65. 44 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
  66. 38 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
  67. 83 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c
  68. 35 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S
  69. 40 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm
  70. 61 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm
  71. 35 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S
  72. 47 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
  73. 77 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c
  74. 28 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
  75. 70 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c
  76. 59 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
  77. 98 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c
  78. 49 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm
  79. 29 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm
  80. 46 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
  81. 45 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
  82. 43 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
  83. 43 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
  84. 82 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c
  85. 28 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
  86. 71 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c
  87. 243 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
  88. 287 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c
  89. 57 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
  90. 111 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c
  91. 268 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
  92. 30 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
  93. 72 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c
  94. 40 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
  95. 68 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c
  96. 38 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm
  97. 40 0
      ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm
  98. 92 0
      ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
  99. 258 0
      ArmPkg/Library/SemiHostingDebugLib/DebugLib.c
  100. 46 0
      ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf

+ 36 - 0
ArmPkg/ArmPkg.dec

@@ -0,0 +1,36 @@
+#%HEADER%
+[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]
+  SemihostLib|Include/Library/Semihosting.h
+
+[Guids.common]
+  gArmTokenSpaceGuid       = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }
+
+[Protocols.common]
+  gTimerDebugSupportProtocolGuid = { 0x68300561, 0x0197, 0x465d, { 0xb5, 0xa1, 0x28, 0xeb, 0xa1, 0x98, 0xdd, 0x0b } }
+
+[PcdsFeatureFlag.common]
+  gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE|BOOLEAN|0x00000001
+
+[PcdsFixedAtBuild.common]
+  gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000080000000|UINT64|0x00000002
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003
+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xfff00000|UINT32|0x00000004
+  gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005

+ 61 - 0
ArmPkg/ArmPkg.dsc

@@ -0,0 +1,61 @@
+#%HEADER%
+#/** @file
+#
+# ARM Package
+#
+#**/
+
+################################################################################
+#
+# 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
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+
+
+[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
+  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
+
+  ArmLib|ArmPkg/Library/ArmLib/Null/NullArmLib.inf
+  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
+  UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+
+
+[Components.common]
+  ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.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/ArmCortexA/ArmCortexArmLib.inf
+  ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLibPrePi.inf
+  ArmPkg/Library/ArmLib/Null/NullArmLib.inf
+  ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+  ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
+  ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
+  ArmPkg/Library/SemihostLib/SemihostLib.inf
+  ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf
+  ArmPkg/Filesystem/SemihostFs/SemihostFs.inf

+ 154 - 0
ArmPkg/Drivers/CpuDxe/CpuDxe.c

@@ -0,0 +1,154 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CpuDxe.h"
+
+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;
+}
+
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL          *This
+  )
+{
+  if (ArmProcessorMode() != ARM_PROCESSOR_MODE_IRQ) {
+    ArmEnableInterrupts(); 
+  }
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+  IN EFI_CPU_ARCH_PROTOCOL          *This
+  )
+{
+  if (ArmProcessorMode() != ARM_PROCESSOR_MODE_IRQ) {
+    ArmDisableInterrupts();
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+  IN  EFI_CPU_ARCH_PROTOCOL         *This,
+  OUT BOOLEAN                       *State
+  )
+{
+  if (State == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *State = ArmGetInterruptState();
+  return EFI_SUCCESS;
+}
+
+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;
+}
+
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+  IN EFI_CPU_ARCH_PROTOCOL     *This,
+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,
+  IN UINT64                    Length,
+  IN UINT64                    Attributes
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+//
+// 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
+  )
+{
+  InitializeExceptions(&mCpu);  
+  return gBS->InstallMultipleProtocolInterfaces(&mCpuHandle, &gEfiCpuArchProtocolGuid, &mCpu, NULL);
+}
+

+ 91 - 0
ArmPkg/Drivers/CpuDxe/CpuDxe.h

@@ -0,0 +1,91 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/DebugSupport.h>
+#include <Protocol/DebugSupportPeriodicCallback.h>
+
+
+/**
+  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
+InitializeExceptions (
+	IN EFI_CPU_ARCH_PROTOCOL    *Cpu
+	);
+
+#endif // __CPU_DXE_ARM_EXCEPTION_H__

+ 56 - 0
ArmPkg/Drivers/CpuDxe/CpuDxe.inf

@@ -0,0 +1,56 @@
+#%HEADER%
+#/** @file
+#  
+#  DXE CPU driver
+#  
+#  Copyright (c) 2009, Apple Inc. <BR>
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  
+#  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.ARM]
+  CpuDxe.c
+  CpuDxe.h
+  DebugSupport.c
+  Exception.c
+  ExceptionSupport.asm | RVCT
+  ExceptionSupport.S   | GCC
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  CacheMaintenanceLib
+  UefiDriverEntryPoint
+  ArmLib
+
+[Protocols]
+  gEfiCpuArchProtocolGuid
+  gEfiDebugSupportPeriodicCallbackProtocolGuid
+
+[Pcd.common]
+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
+  
+[FeaturePcd.common]
+  gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport
+
+[depex]
+  gHardwareInterruptProtocolGuid

+ 247 - 0
ArmPkg/Drivers/CpuDxe/DebugSupport.c

@@ -0,0 +1,247 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/** @file
+  DXE Cpu Driver.
+  
+  May need some porting work for platform specifics.
+
+  Copyright (c) 2008, Apple Inc                                                        
+  All rights reserved. This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  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"
+
+EFI_PERIODIC_CALLBACK   gPeriodicCallBack = (EFI_PERIODIC_CALLBACK)NULL;
+
+EFI_DEBUG_SUPPORT_PERIODIC_CALLBACK_PROTOCOL *gDebugSupportCallback = NULL;
+
+
+EFI_STATUS
+EFIAPI
+DebugSupportGetMaximumProcessorIndex (
+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,
+  OUT UINTN                           *MaxProcessorIndex
+  )
+/*++
+
+Routine Description: This is a DebugSupport protocol member function.
+
+Arguments:
+  This              - The DebugSupport instance
+  MaxProcessorIndex - The maximuim supported processor index
+
+Returns:
+  Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0
+
+--*/
+{
+  *MaxProcessorIndex = 0;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DebugSupportRegisterPeriodicCallback (
+  IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+  IN UINTN                      ProcessorIndex,
+  IN EFI_PERIODIC_CALLBACK      PeriodicCallback
+  )
+/*++
+
+Routine Description: This is a DebugSupport protocol member function.
+
+Arguments:
+  This             - The DebugSupport instance
+  ProcessorIndex   - Which processor the callback applies to.
+  PeriodicCallback - Callback function
+
+Returns:
+
+  EFI_SUCCESS
+  EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has
+                          no handler registered for it
+  EFI_ALREADY_STARTED   - requested install to a vector that already has a handler registered.
+
+  Other possible return values are passed through from UnHookEntry and HookEntry.
+
+--*/
+{
+  if (ProcessorIndex != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  
+  if ((gPeriodicCallBack != (EFI_PERIODIC_CALLBACK)NULL) && (PeriodicCallback != (EFI_PERIODIC_CALLBACK)NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+  
+  gPeriodicCallBack = PeriodicCallback;
+  
+  if (gDebugSupportCallback != NULL) {
+    //
+    // We can only update this protocol if the Register Protocol Notify has fired. If it fires 
+    // after this call it will update with gPeriodicCallBack value.
+    //
+    gDebugSupportCallback->PeriodicCallback = gPeriodicCallBack;
+  }
+  
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+DebugSupportRegisterExceptionCallback (
+  IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+  IN UINTN                      ProcessorIndex,
+  IN EFI_EXCEPTION_CALLBACK     NewCallback,
+  IN EFI_EXCEPTION_TYPE         ExceptionType
+  )
+/*++
+
+Routine Description:
+  This is a DebugSupport protocol member function.
+
+  This code executes in boot services context.
+
+Arguments:
+  This             - The DebugSupport instance
+  ProcessorIndex   - Which processor the callback applies to.
+  NewCallback      - Callback function
+  ExceptionType    - Which exception to hook
+
+Returns:
+
+  EFI_SUCCESS
+  EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has
+                          no handler registered for it
+  EFI_ALREADY_STARTED   - requested install to a vector that already has a handler registered.
+
+  Other possible return values are passed through from UnHookEntry and HookEntry.
+
+--*/
+{
+  if (ProcessorIndex != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return RegisterDebuggerInterruptHandler (ExceptionType, NewCallback);
+}
+
+
+EFI_STATUS
+EFIAPI
+DebugSupportInvalidateInstructionCache (
+  IN EFI_DEBUG_SUPPORT_PROTOCOL       *This,
+  IN UINTN                            ProcessorIndex,
+  IN VOID                             *Start,
+  IN UINT64                           Length
+  )
+/*++
+
+Routine Description:
+  This is a DebugSupport protocol member function.
+  Calls assembly routine to flush cache.
+
+Arguments:
+  This             - The DebugSupport instance
+  ProcessorIndex   - Which processor the callback applies to.
+  Start            - Physical base of the memory range to be invalidated
+  Length           - mininum number of bytes in instruction cache to invalidate
+
+Returns:
+
+  EFI_SUCCESS - always return success
+
+--*/
+{
+  if (ProcessorIndex != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  InvalidateInstructionCache();
+
+  return EFI_SUCCESS;
+}
+
+//
+// This is a global that is the actual interface
+//
+EFI_DEBUG_SUPPORT_PROTOCOL  gDebugSupportProtocolInterface = {
+  IsaArm, // Fixme to be more generic
+  DebugSupportGetMaximumProcessorIndex,
+  DebugSupportRegisterPeriodicCallback,
+  DebugSupportRegisterExceptionCallback,
+  DebugSupportInvalidateInstructionCache
+};
+
+
+VOID
+EFIAPI
+DebugSupportPeriodicCallbackEventProtocolNotify (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_STATUS    Status;
+  
+  Status = gBS->LocateProtocol (&gEfiDebugSupportPeriodicCallbackProtocolGuid, NULL, (VOID **)&gDebugSupportCallback);
+  if (!EFI_ERROR (Status)) {
+    gDebugSupportCallback->PeriodicCallback = gPeriodicCallBack;
+  }
+}
+
+VOID *gRegistration = NULL;
+
+
+EFI_DEBUG_SUPPORT_PROTOCOL *
+InitilaizeDebugSupport (
+  VOID
+  )
+{
+  // RPN gEfiDebugSupportPeriodicCallbackProtocolGuid
+  EFI_STATUS    Status;
+  EFI_EVENT     Event;
+
+  if (!FeaturePcdGet (PcdCpuDxeProduceDebugSupport)) {
+    // Don't include this code unless Feature Flag is set
+    return NULL;
+  }
+  
+
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL, 
+                  TPL_CALLBACK, 
+                  DebugSupportPeriodicCallbackEventProtocolNotify, 
+                  NULL, 
+                  &Event
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->RegisterProtocolNotify (&gEfiDebugSupportPeriodicCallbackProtocolGuid, Event, &gRegistration);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // We assume the Timer must depend on our driver to register interrupts so we don't need to do
+  // a gBS->SignalEvent (Event) here to check to see if the protocol allready exists
+  //
+
+  return &gDebugSupportProtocolInterface;
+}

+ 238 - 0
ArmPkg/Drivers/CpuDxe/Exception.c

@@ -0,0 +1,238 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "CpuDxe.h" 
+#include <Library/CacheMaintenanceLib.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;
+}
+
+
+/**
+  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
+  )
+{
+  if (InterruptType > MAX_ARM_EXCEPTION) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((InterruptHandler != NULL) && (gDebuggerExceptionHandlers[InterruptType] != NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  gDebuggerExceptionHandlers[InterruptType] = InterruptHandler;
+
+  return EFI_SUCCESS;
+}
+
+
+
+VOID
+EFIAPI
+CommonCExceptionHandler (
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext
+  )
+{
+  BOOLEAN Dispatched = FALSE;
+  
+  if (ExceptionType <= MAX_ARM_EXCEPTION) {
+    if (gDebuggerExceptionHandlers[ExceptionType]) {
+      //
+      // If DebugSupport hooked the interrupt call the handler. This does not disable 
+      // the normal handler.
+      //
+      gDebuggerExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);
+      Dispatched = TRUE;
+    }
+    if (gExceptionHandlers[ExceptionType]) {
+      gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);
+      Dispatched = TRUE;
+    }
+  }
+
+  if (Dispatched) {
+    //
+    // We did work so this was an expected ExceptionType
+    //
+    return;
+  }
+  
+  if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {
+    //
+    // ARM JTAG debuggers some times use this vector, so it is not an error to get one
+    //
+    return;
+  }
+
+  //
+  // Code after here is the default exception handler...
+  //
+  DEBUG ((EFI_D_ERROR, "Exception %d from %08x\n", ExceptionType, SystemContext.SystemContextArm->PC));
+  ASSERT (FALSE);
+
+}
+
+
+
+EFI_STATUS
+InitializeExceptions (
+  IN EFI_CPU_ARCH_PROTOCOL    *Cpu
+  )
+{
+  EFI_STATUS           Status;
+  UINTN                Offset;
+  UINTN                Length;
+  UINTN                Index;
+  BOOLEAN              Enabled;
+  EFI_PHYSICAL_ADDRESS Base;
+
+  //
+  // Disable interrupts
+  //
+  Cpu->GetInterruptState (Cpu, &Enabled);
+  Cpu->DisableInterrupt (Cpu);
+
+  //
+  // Initialize the C entry points for interrupts
+  //
+  for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {
+    Status = RegisterInterruptHandler (Index, NULL);
+    ASSERT_EFI_ERROR (Status);
+    
+    Status = RegisterDebuggerInterruptHandler (Index, NULL);
+    ASSERT_EFI_ERROR (Status);
+  }
+  
+  //
+  // Copy an implementation of the ARM exception vectors to 0x0.
+  //
+  Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
+
+  //
+  // Reserve space for the exception handlers
+  //
+  Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);
+  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);
+  }
+
+  CopyMem ((VOID *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress), (VOID *)ExceptionHandlersStart, Length);
+
+  //
+  // Patch in the common Assembly exception handler
+  //
+  Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;
+  *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;
+
+  // Flush Caches since we updated executable stuff
+  InvalidateInstructionCacheRange((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);
+
+  if (Enabled) {
+    // 
+    // Restore interrupt state
+    //
+    Status = Cpu->EnableInterrupt (Cpu);
+  }
+
+  return Status;
+}

+ 152 - 0
ArmPkg/Drivers/CpuDxe/ExceptionSupport.S

@@ -0,0 +1,152 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 3
+
+.globl ASM_PFX(ExceptionHandlersStart)
+.globl ASM_PFX(ExceptionHandlersEnd)
+.globl ASM_PFX(CommonExceptionEntry)
+.globl ASM_PFX(AsmCommonExceptionEntry)
+.globl ASM_PFX(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):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#0
+  ldr       r1,ASM_PFX(CommonExceptionEntry)
+  bx        r1
+
+ASM_PFX(UndefinedInstructionEntry):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#1
+  ldr       r1,ASM_PFX(CommonExceptionEntry)
+  bx        r1
+
+ASM_PFX(SoftwareInterruptEntry):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#2
+  ldr       r1,ASM_PFX(CommonExceptionEntry)
+  bx        r1
+
+ASM_PFX(PrefetchAbortEntry):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#3
+  sub       lr,lr,#4
+  ldr       r1,ASM_PFX(CommonExceptionEntry)
+  bx        r1
+
+ASM_PFX(DataAbortEntry):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#4
+  sub       lr,lr,#8
+  ldr       r1,ASM_PFX(CommonExceptionEntry)
+  bx        r1
+
+ASM_PFX(ReservedExceptionEntry):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#5
+  ldr       r1,ASM_PFX(CommonExceptionEntry)
+  bx        r1
+
+ASM_PFX(IrqEntry):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#6
+  sub       lr,lr,#4
+  ldr       r1,ASM_PFX(CommonExceptionEntry)
+  bx        r1
+
+ASM_PFX(FiqEntry):
+  stmfd     sp!,{r0-r1}
+  mov       r0,#7
+  sub       lr,lr,#4
+  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
+  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
+  bl        ASM_PFX(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
+  ldmia     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
+  

+ 152 - 0
ArmPkg/Drivers/CpuDxe/ExceptionSupport.asm

@@ -0,0 +1,152 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+  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
+
+

+ 119 - 0
ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c

@@ -0,0 +1,119 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/DebugSupport.h>
+#include <Protocol/TimerDebugSupport.h>
+
+EFI_STATUS
+EFIAPI
+DebugSupportGetMaximumProcessorIndex (
+  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,
+  OUT UINTN                       *MaxProcessorIndex
+  )
+{
+  if (MaxProcessorIndex == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *MaxProcessorIndex = 0;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DebugSupportRegisterPeriodicCallback (
+  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,
+  IN  UINTN                       ProcessorIndex,
+  IN  EFI_PERIODIC_CALLBACK       PeriodicCallback
+  )
+{
+  TIMER_DEBUG_SUPPORT_PROTOCOL  *Timer;
+  EFI_STATUS                    Status;
+
+  Status = gBS->LocateProtocol(&gTimerDebugSupportProtocolGuid, NULL, (VOID **)&Timer);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  Status = Timer->RegisterPeriodicCallback(Timer, PeriodicCallback);
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DebugSupportRegisterExceptionCallback (
+  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,
+  IN  UINTN                       ProcessorIndex,
+  IN  EFI_EXCEPTION_CALLBACK      ExceptionCallback,
+  IN  EFI_EXCEPTION_TYPE          ExceptionType
+  )
+{
+  EFI_CPU_ARCH_PROTOCOL *Cpu;
+  EFI_STATUS            Status;
+
+  Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  Status = Cpu->RegisterInterruptHandler(Cpu, ExceptionType, (EFI_CPU_INTERRUPT_HANDLER)ExceptionCallback);
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DebugSupportInvalidateInstructionCache (
+  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,
+  IN  UINTN                       ProcessorIndex,
+  IN  VOID                        *Start,
+  IN  UINT64                      Length
+  )
+{
+  InvalidateInstructionCacheRange(Start, Length);
+  return EFI_SUCCESS;
+}
+
+EFI_DEBUG_SUPPORT_PROTOCOL  mDebugSupport = {
+  IsaArm,
+  DebugSupportGetMaximumProcessorIndex,
+  DebugSupportRegisterPeriodicCallback,
+  DebugSupportRegisterExceptionCallback,
+  DebugSupportInvalidateInstructionCache
+};
+
+EFI_STATUS
+DebugSupportDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  Handle = NULL;
+
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiDebugSupportProtocolGuid);
+  Status = gBS->InstallMultipleProtocolInterfaces(&Handle, &gEfiDebugSupportProtocolGuid, &mDebugSupport, NULL);
+
+  return Status;
+}
+

+ 30 - 0
ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf

@@ -0,0 +1,30 @@
+#%HEADER%
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmDebugSupportDxe
+  FILE_GUID                      = 2e7c151b-cbd8-4df6-a0e3-cde660067c6a
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = DebugSupportDxeInitialize
+
+[Sources.common]
+  DebugSupport.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  CacheMaintenanceLib
+  UefiDriverEntryPoint
+  ArmLib
+
+[Protocols]
+  gEfiCpuArchProtocolGuid
+  gEfiDebugSupportProtocolGuid
+  gTimerDebugSupportProtocolGuid
+  
+[Depex]
+  TRUE

+ 526 - 0
ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c

@@ -0,0 +1,526 @@
+/** @file
+  Support a Semi Host file system over a debuggers JTAG
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.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"
+
+
+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 SemiHosting. 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;
+  UINT32      Position;
+  UINT32      SemihostHandle;
+  BOOLEAN     IsRoot;
+} 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;
+
+  InsertTailList (&gFileList, &RootFcb->Link);
+
+  *Root = &RootFcb->File;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FileOpen (
+  IN  EFI_FILE    *File,
+  OUT EFI_FILE    **NewHandle,
+  IN  CHAR16      *FileName,
+  IN  UINT64      OpenMode,
+  IN  UINT64      Attributes
+  )
+{
+  SEMIHOST_FCB  *FileFcb = NULL;
+  EFI_STATUS    Status   = EFI_SUCCESS;
+  UINT32        SemihostHandle;
+  CHAR8         *AsciiFileName;
+  CHAR8         *AsciiPtr;
+  UINTN         Length;
+  UINT32        SemihostMode;
+  BOOLEAN       IsRoot;
+
+  if ((FileName == NULL) || (NewHandle == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Semihost interface requires ASCII filesnames
+  Length = StrSize (FileName);
+
+  AsciiFileName = AllocatePool (Length);
+  if (AsciiFileName == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  AsciiPtr = AsciiFileName;
+
+  while (Length--) {
+    *AsciiPtr++ = *FileName++ & 0xFF;
+  }
+
+  if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0)) {
+    // Opening '/', '\', or the NULL pathname is trying to open the root directory
+    IsRoot = TRUE;
+
+    // Root directory node doesn't have a name.
+    FreePool (AsciiFileName);
+    AsciiFileName = NULL;
+  } else {
+    // Translate EFI_FILE_MODE into Semihosting mode
+    if (OpenMode & EFI_FILE_MODE_WRITE) {
+      SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY;
+    } else if (OpenMode & EFI_FILE_MODE_READ) {
+      SemihostMode = SEMIHOST_FILE_MODE_READ  | SEMIHOST_FILE_MODE_BINARY;
+    } else {
+      return EFI_UNSUPPORTED;
+    }
+
+    // Add the creation flag if necessary
+    if (OpenMode & EFI_FILE_MODE_CREATE) {
+      SemihostMode |= SEMIHOST_FILE_MODE_CREATE;
+    }
+
+    // Call the semihosting interface to open the file.
+    Status = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+    
+    IsRoot = FALSE;
+  }
+
+  // Allocate a control block and fill it
+  FileFcb = AllocateFCB ();
+  if (FileFcb == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  FileFcb->FileName       = AsciiFileName;
+  FileFcb->SemihostHandle = SemihostHandle;
+  FileFcb->Position       = 0;
+  FileFcb->IsRoot         = IsRoot;
+
+  InsertTailList (&gFileList, &FileFcb->Link);
+
+  *NewHandle = &FileFcb->File;
+
+  return Status;
+}
+
+
+EFI_STATUS
+FileClose (
+  IN EFI_FILE *File
+  )
+{
+  SEMIHOST_FCB *Fcb    = NULL;
+  EFI_STATUS   Status  = EFI_SUCCESS;
+
+  Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+  if (Fcb->IsRoot == TRUE) {
+    FreeFCB (Fcb);
+    Status = EFI_SUCCESS;
+  } else {
+    Status = SemihostFileClose (Fcb->SemihostHandle);
+    if (!EFI_ERROR(Status)) {
+      FreePool (Fcb->FileName);
+      FreeFCB (Fcb);
+    }
+  }
+  
+  return Status;
+}
+
+EFI_STATUS
+FileDelete (
+  IN EFI_FILE *File
+  )
+{
+  SEMIHOST_FCB *Fcb = NULL;
+  EFI_STATUS   Status;
+  CHAR8        *FileName;
+  UINTN        NameSize;
+
+  Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+  // 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.
+  File->Close (File);
+    
+  // Call the semihost interface to delete the file.
+  Status = SemihostFileRemove (FileName);
+
+  return Status;
+}
+
+EFI_STATUS
+FileRead (
+  IN     EFI_FILE *File,
+  IN OUT UINTN    *BufferSize,
+  OUT    VOID     *Buffer
+  )
+{
+  SEMIHOST_FCB *Fcb = NULL;
+  EFI_STATUS   Status;
+
+  Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+  if (Fcb->IsRoot == TRUE) {
+    Status = EFI_UNSUPPORTED;
+  } else {
+    Status = SemihostFileRead (Fcb->SemihostHandle, BufferSize, Buffer);
+    if (!EFI_ERROR (Status)) {
+      Fcb->Position += *BufferSize;
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+FileWrite (
+  IN     EFI_FILE *File,
+  IN OUT UINTN    *BufferSize,
+  IN     VOID     *Buffer
+  )
+{
+  SEMIHOST_FCB *Fcb    = NULL;
+  EFI_STATUS   Status;
+  UINTN        WriteSize = *BufferSize;
+
+  Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+  Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
+
+  if (!EFI_ERROR(Status)) {
+    // Semihost write return the number of bytes *NOT* written.
+    *BufferSize -= WriteSize;
+    Fcb->Position += *BufferSize;
+  }
+  
+  return Status;
+}
+
+EFI_STATUS
+FileGetPosition (
+  IN  EFI_FILE    *File,
+  OUT UINT64      *Position
+  )
+{
+  SEMIHOST_FCB *Fcb = NULL;
+    
+  if (Position == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+  *Position = Fcb->Position;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FileSetPosition (
+  IN EFI_FILE *File,
+  IN UINT64   Position
+  )
+{
+  SEMIHOST_FCB *Fcb    = NULL;
+  UINT32       Length;
+  EFI_STATUS   Status;
+
+  Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+  Status = SemihostFileLength (Fcb->SemihostHandle, &Length);
+  if (!EFI_ERROR(Status) && (Length < Position)) {
+    Position = Length;
+  }
+
+  Status = SemihostFileSeek (Fcb->SemihostHandle, (UINT32)Position);
+  if (!EFI_ERROR(Status)) {
+    Fcb->Position = Position;
+  }
+
+  return Status;
+}
+
+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;
+  UINT32          Length;
+  EFI_STATUS      Status;
+
+  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;
+
+  // Zero out the structure
+  ZeroMem (Info, SIZE_OF_EFI_FILE_INFO);
+
+  // Fill in the structure
+  Info->Size = ResultSize;
+
+  if (Fcb->IsRoot == TRUE) {
+    Info->Attribute    = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
+    Info->FileName[0]  = L'\0';
+  } else {
+    Status = SemihostFileLength (Fcb->SemihostHandle, &Length);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+
+    Info->FileSize     = Length;
+    Info->PhysicalSize = Length;
+
+    for (Index = 0; Index < NameSize; Index++) {
+      Info->FileName[Index] = Fcb->FileName[Index];            
+    }
+  }
+
+
+  *BufferSize = ResultSize;    
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetFilesystemInfo (
+  IN     SEMIHOST_FCB *Fcb,
+  IN OUT UINTN        *BufferSize,
+  OUT    VOID         *Buffer
+  )
+{
+  EFI_FILE_SYSTEM_INFO    *Info = NULL;
+  EFI_STATUS              Status;
+  STATIC CHAR16           Label[] = L"SemihostFs";
+  UINTN                   ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(Label);
+    
+  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, Label);
+  } else {
+    Status = EFI_BUFFER_TOO_SMALL;
+  }
+
+  *BufferSize = ResultSize;    
+  return Status;
+}
+
+EFI_STATUS
+FileGetInfo (
+  IN     EFI_FILE *File,
+  IN     EFI_GUID *InformationType,
+  IN OUT UINTN    *BufferSize,
+  OUT    VOID     *Buffer
+  )
+{
+  SEMIHOST_FCB *Fcb = NULL;
+  EFI_STATUS   Status = EFI_UNSUPPORTED;
+  
+  Fcb = SEMIHOST_FCB_FROM_THIS(File);
+  
+  if (CompareGuid(InformationType, &gEfiFileSystemInfoGuid) != 0) {
+    Status = GetFilesystemInfo(Fcb, BufferSize, Buffer);  
+  } else if (CompareGuid(InformationType, &gEfiFileInfoGuid) != 0) {
+    Status = GetFileInfo(Fcb, BufferSize, Buffer);  
+  }
+    
+  return Status;
+}
+
+EFI_STATUS
+FileSetInfo (
+  IN EFI_FILE *File,
+  IN EFI_GUID *InformationType,
+  IN UINTN    BufferSize,
+  IN VOID     *Buffer
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+FileFlush (
+  IN EFI_FILE *File
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SemihostFsEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS    Status = EFI_NOT_FOUND;
+
+  if (SemihostConnectionSupported ()) {
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &gInstallHandle, 
+                    &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs, 
+                    &gEfiDevicePathProtocolGuid,       &gDevicePath,
+                    NULL
+                    );
+  }
+ 
+  return Status;
+}
+

+ 114 - 0
ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h

@@ -0,0 +1,114 @@
+/** @file
+  Support a Semi Host file system over a debuggers JTAG
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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
+SemihostFsSupported(
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+EFI_STATUS
+SemihostFsStart(
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+EFI_STATUS
+SemihostFsStop(
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  );
+
+EFI_STATUS
+VolumeOpen(
+  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+  OUT EFI_FILE                        **Root
+  );
+
+EFI_STATUS
+FileOpen(
+  IN  EFI_FILE  *File,
+  OUT EFI_FILE  **NewHandle,
+  IN  CHAR16    *FileName,
+  IN  UINT64    OpenMode,
+  IN  UINT64    Attributes
+  );
+
+EFI_STATUS
+FileClose(
+  IN EFI_FILE *File
+  );
+
+EFI_STATUS
+FileDelete(
+  IN EFI_FILE *File
+  );
+
+EFI_STATUS
+FileRead(
+  IN     EFI_FILE *File,
+  IN OUT UINTN    *BufferSize,
+  OUT    VOID     *Buffer
+  );
+
+EFI_STATUS
+FileWrite(
+  IN     EFI_FILE *File,
+  IN OUT UINTN    *BufferSize,
+  IN     VOID     *Buffer
+  );
+
+EFI_STATUS
+FileGetPosition(
+  IN  EFI_FILE  *File,
+  OUT UINT64    *Position
+  );
+
+EFI_STATUS
+FileSetPosition(
+  IN EFI_FILE *File,
+  IN UINT64   Position
+  );
+
+EFI_STATUS
+FileGetInfo(
+  IN     EFI_FILE *File,
+  IN     EFI_GUID *InformationType,
+  IN OUT UINTN    *BufferSize,
+  OUT    VOID     *Buffer
+  );
+
+EFI_STATUS
+FileSetInfo(
+  IN EFI_FILE *File,
+  IN EFI_GUID *InformationType,
+  IN UINTN    BufferSize,
+  IN VOID     *Buffer
+  );
+
+EFI_STATUS
+FileFlush(
+  IN EFI_FILE *File
+  );
+
+#endif // __SEMIHOST_FS_H__
+

+ 48 - 0
ArmPkg/Filesystem/SemihostFs/SemihostFs.inf

@@ -0,0 +1,48 @@
+#%HEADER%
+#/** @file
+#  Support a Semi Host file system over a debuggers JTAG
+#
+#  Copyright (c) 2009, Apple, Inc.                                                         
+#  All rights reserved. This program and the accompanying materials                          
+#  are licensed and made available under the terms and conditions of the BSD License         
+#  which accompanies this distribution.  The full text of the license may be found at        
+#  http://opensource.org/licenses/bsd-license.php                                            
+#
+#  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]
+  Arm/SemihostFs.c
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  MemoryAllocationLib
+  SemihostLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Guids]
+  gEfiFileSystemInfoGuid
+  gEfiFileInfoGuid
+  gEfiFileSystemVolumeLabelInfoIdGuid
+
+[Protocols]
+  gEfiSimpleFileSystemProtocolGuid
+  gEfiDevicePathProtocolGuid
+  

+ 236 - 0
ArmPkg/Include/AsmMacroIoLib.h

@@ -0,0 +1,236 @@
+/** @file
+  Macros to work around lack of Apple support for LDR register, =expr
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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:
+
+
+#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
+  
+#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
+
+
+#endif
+
+
+#endif

+ 74 - 0
ArmPkg/Include/AsmMacroIoLib.inc

@@ -0,0 +1,74 @@
+;%HEADER%
+;/** @file
+;  Macros to work around lack of Apple support for LDR register, =expr
+;
+;  Copyright (c) 2009, Apple, Inc.  All rights reserved.
+;
+;**/
+
+
+  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 
+
+  END

+ 111 - 0
ArmPkg/Include/Chipset/ARM1176JZ-S.h

@@ -0,0 +1,111 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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_SECURE                         (0UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS_NON_SECURE                     (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          (TT_DESCRIPTOR_TYPE_SECTION                              | \
+                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \
+                                                   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       (TT_DESCRIPTOR_TYPE_SECTION                              | \
+                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \
+                                                   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            (TT_DESCRIPTOR_TYPE_SECTION                              | \
+                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \
+                                                   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)
+
+#endif // __ARM1176JZ_S_H__

+ 71 - 0
ArmPkg/Include/Chipset/ARM926EJ-S.h

@@ -0,0 +1,71 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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__

+ 104 - 0
ArmPkg/Include/Chipset/Cortex-A8.h

@@ -0,0 +1,104 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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 __CORTEX_A8_H__
+#define __CORTEX_A8_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_SECURE                         (0UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS_NON_SECURE                     (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_SECTION_CACHE_POLICY_MASK                   ((3UL << 12) | (0UL << 3) | (0UL << 2))
+#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_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          (TT_DESCRIPTOR_TYPE_SECTION                              | \
+                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \
+                                                   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       (TT_DESCRIPTOR_TYPE_SECTION                              | \
+                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                     | \
+                                                   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              (TT_DESCRIPTOR_TYPE_SECTION                              | \
+                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \
+                                                   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            (TT_DESCRIPTOR_TYPE_SECTION                              | \
+                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \
+                                                   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)
+
+#endif // __CORTEX_A8_H__

+ 294 - 0
ArmPkg/Include/Library/ArmLib.h

@@ -0,0 +1,294 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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__
+
+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;
+
+typedef enum {
+  ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED,
+  ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK,
+  ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH,
+  ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+} ARM_MEMORY_REGION_ATTRIBUTES;
+
+typedef struct {
+  UINT32                        PhysicalBase;
+  UINT32                        VirtualBase;
+  UINT32                        Length;
+  ARM_MEMORY_REGION_ATTRIBUTES  Attributes;
+} ARM_MEMORY_REGION_DESCRIPTOR;
+
+typedef VOID (*CACHE_OPERATION)(VOID);
+typedef VOID (*LINE_OPERATION)(UINTN);
+
+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_UNDEFINED  = 0x1B,
+  ARM_PROCESSOR_MODE_SYSTEM     = 0x1F,
+  ARM_PROCESSOR_MODE_MASK       = 0x1F
+} ARM_PROCESSOR_MODE;
+
+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
+  );
+  
+UINT32
+EFIAPI
+Cp15IdCode (
+  VOID
+  );
+  
+UINT32
+EFIAPI
+Cp15CacheInfo (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmInvalidateDataCache (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+  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
+ArmEnableDataCache (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmDisableDataCache (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmEnableInstructionCache (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmDisableInstructionCache (
+  VOID
+  );
+  
+VOID
+EFIAPI
+ArmEnableMmu (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmDisableMmu (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmEnableInterrupts (
+  VOID
+  );
+
+UINTN
+EFIAPI
+ArmDisableInterrupts (
+  VOID
+  );
+  
+BOOLEAN
+EFIAPI
+ArmGetInterruptState (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmInvalidateTlb (
+  VOID
+  );
+  
+VOID
+EFIAPI
+ArmSetDomainAccessControl (
+  IN  UINT32  Domain
+  );
+
+VOID
+EFIAPI
+ArmSetTranslationTableBaseAddress (
+  IN  VOID  *TranslationTableBase
+  );
+
+VOID
+EFIAPI
+ArmConfigureMmu (
+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,
+  OUT VOID                          **TranslationTableBase OPTIONAL,
+  OUT UINTN                         *TranslationTableSize  OPTIONAL
+  );
+  
+VOID
+EFIAPI
+ArmSwitchProcessorMode (
+  IN ARM_PROCESSOR_MODE Mode
+  );
+
+ARM_PROCESSOR_MODE
+EFIAPI
+ArmProcessorMode (
+  VOID
+  );
+  
+VOID
+EFIAPI
+ArmEnableBranchPrediction (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmDisableBranchPrediction (
+  VOID
+  );
+
+#endif // __ARM_LIB__

+ 100 - 0
ArmPkg/Include/Library/SemihostLib.h

@@ -0,0 +1,100 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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_CREATE   (1 << 1)
+#define SEMIHOST_FILE_MODE_BINARY   (1 << 0)
+#define SEMIHOST_FILE_MODE_ASCII    (0 << 0)
+
+BOOLEAN
+SemihostConnectionSupported (
+  VOID
+  );
+
+EFI_STATUS
+SemihostFileOpen (
+  IN  CHAR8  *FileName,
+  IN  UINT32 Mode,
+  OUT UINT32 *FileHandle
+  );
+
+EFI_STATUS
+SemihostFileSeek (
+  IN UINT32 FileHandle,
+  IN UINT32 Offset
+  );
+
+EFI_STATUS
+SemihostFileRead (
+  IN     UINT32 FileHandle,
+  IN OUT UINT32 *Length,
+  OUT    VOID   *Buffer
+  );
+
+EFI_STATUS
+SemihostFileWrite (
+  IN     UINT32 FileHandle,
+  IN OUT UINT32 *Length,
+  IN     VOID   *Buffer
+  );
+
+EFI_STATUS
+SemihostFileClose (
+  IN UINT32 FileHandle
+  );
+
+EFI_STATUS
+SemihostFileLength (
+  IN  UINT32 FileHandle,
+  OUT UINT32 *Length
+  );
+
+EFI_STATUS
+SemihostFileRemove (
+  IN CHAR8 *FileName
+  );
+
+CHAR8
+SemihostReadCharacter (
+  VOID
+  );
+
+VOID
+SemihostWriteCharacter (
+  IN CHAR8 Character
+  );
+
+VOID
+SemihostWriteString (
+  IN CHAR8 *String
+  );
+  
+UINT32
+SemihostSystem (
+  IN CHAR8 *CommandLine
+  );
+  
+#endif // __SEMIHOSTING_H__

+ 665 - 0
ArmPkg/Include/Library/UncachedMemoryAllocationLib.h

@@ -0,0 +1,665 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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__

+ 59 - 0
ArmPkg/Include/Protocol/TimerDebugSupport.h

@@ -0,0 +1,59 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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 __TIMERDEBUGSUPPORTPROTOCOL_H__
+#define __TIMERDEBUGSUPPORTPROTOCOL_H__
+
+//
+// Protocol GUID
+//
+#define TIMER_DEBUG_PROTOCOL_GUID { 0x68300561, 0x0197, 0x465d, { 0xb5, 0xa1, 0x28, 0xeb, 0xa1, 0x98, 0xdd, 0x0b } }
+
+
+
+//
+// Protocol interface structure
+//
+typedef struct _TIMER_DEBUG_SUPPORT_PROTOCOL  TIMER_DEBUG_SUPPORT_PROTOCOL;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *TIMER_DEBUG_SUPPORT_REGISTER_PERIODIC_CALLBACK) (
+  IN  TIMER_DEBUG_SUPPORT_PROTOCOL  *This,
+  IN  EFI_PERIODIC_CALLBACK         PeriodicCallback
+  )
+/*++
+
+Routine Description:
+  Register a periodic callback for debug support.
+
+Arguments:
+  This              - pointer to protocol
+  PeriodicCallback  - callback to be registered
+  
+Returns:
+  EFI_SUCCESS - callback registered
+
+--*/
+;
+
+struct _TIMER_DEBUG_SUPPORT_PROTOCOL {
+  TIMER_DEBUG_SUPPORT_REGISTER_PERIODIC_CALLBACK  RegisterPeriodicCallback;
+};
+
+extern EFI_GUID gTimerDebugSupportProtocolGuid;
+
+#endif	// __TIMERDEBUGSUPPORTPROTOCOL_H__
+

+ 129 - 0
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c

@@ -0,0 +1,129 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#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))
+  {
+    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, ArmCleanDataCache, 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;
+}

+ 23 - 0
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf

@@ -0,0 +1,23 @@
+#%HEADER%
+[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
+  

+ 32 - 0
ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf

@@ -0,0 +1,32 @@
+#%HEADER%
+[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/ArmLibSupport.S    | GCC
+  ../Common/ArmLibSupport.asm  | RVCT
+  ../Common/ArmLib.c
+  
+  Arm11Support.S    | GCC
+  Arm11Support.asm  | RVCT
+  
+  Arm11Lib.c
+  ../Arm9/Arm9CacheInformation.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  
+[Protocols]
+  gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+ 32 - 0
ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf

@@ -0,0 +1,32 @@
+#%HEADER%
+[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/ArmLibSupport.S    | GCC
+  ../Common/ArmLibSupport.asm  | RVCT
+  ../Common/ArmLib.c
+  
+  Arm11Support.S    | GCC
+  Arm11Support.asm  | RVCT
+  
+  Arm11Lib.c
+  ../Arm9/Arm9CacheInformation.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  PrePiLib
+  
+[Protocols]
+  gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+ 118 - 0
ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c

@@ -0,0 +1,118 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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;
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+    default:
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
+      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;
+  }
+}
+
+VOID
+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));
+  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++;
+  }
+
+  ArmSetTranslationTableBaseAddress(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();  
+}

+ 129 - 0
ArmPkg/Library/ArmLib/Arm11/Arm11Support.S

@@ -0,0 +1,129 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+.globl ASM_PFX(ArmCleanInvalidateDataCache)
+.globl ASM_PFX(ArmCleanDataCache)
+.globl ASM_PFX(ArmInvalidateDataCache)
+.globl ASM_PFX(ArmInvalidateInstructionCache)
+.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
+.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
+.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
+.globl ASM_PFX(ArmEnableMmu)
+.globl ASM_PFX(ArmDisableMmu)
+.globl ASM_PFX(ArmEnableDataCache)
+.globl ASM_PFX(ArmDisableDataCache)
+.globl ASM_PFX(ArmEnableInstructionCache)
+.globl ASM_PFX(ArmDisableInstructionCache)
+.globl ASM_PFX(ArmEnableBranchPrediction)
+.globl ASM_PFX(ArmDisableBranchPrediction)
+
+.set DC_ON, (0x1<<2)
+.set IC_ON, (0x1<<12)
+.set XP_ON, (0x1<<23)
+
+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(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):
+  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(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_FUNCTION_REMOVE_IF_UNREFERENCED

+ 133 - 0
ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm

@@ -0,0 +1,133 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+    EXPORT  ArmCleanInvalidateDataCache
+    EXPORT  ArmCleanDataCache
+    EXPORT  ArmInvalidateDataCache
+    EXPORT  ArmInvalidateInstructionCache
+    EXPORT  ArmInvalidateDataCacheEntryByMVA
+    EXPORT  ArmCleanDataCacheEntryByMVA
+    EXPORT  ArmCleanInvalidateDataCacheEntryByMVA
+    EXPORT  ArmEnableMmu
+    EXPORT  ArmDisableMmu
+    EXPORT  ArmEnableDataCache
+    EXPORT  ArmDisableDataCache
+    EXPORT  ArmEnableInstructionCache
+    EXPORT  ArmDisableInstructionCache
+    EXPORT  ArmEnableBranchPrediction
+    EXPORT  ArmDisableBranchPrediction
+
+
+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
+
+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
+
+    END

+ 32 - 0
ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf

@@ -0,0 +1,32 @@
+#%HEADER%
+[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/ArmLibSupport.S    | GCC
+  ../Common/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

+ 32 - 0
ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf

@@ -0,0 +1,32 @@
+#%HEADER%
+[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/ArmLibSupport.S    | GCC
+  ../Common/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

+ 164 - 0
ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c

@@ -0,0 +1,164 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/ArmLib.h>
+#include "ArmLibPrivate.h"
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+  VOID
+  )
+{
+  switch (CACHE_TYPE(Cp15CacheInfo()))
+  {
+    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(Cp15CacheInfo()))
+  {
+    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(Cp15CacheInfo()))
+  {
+    case CACHE_PRESENT:     return TRUE;
+    case CACHE_NOT_PRESENT: return FALSE;
+    default:                return FALSE;
+  }
+}
+  
+UINTN
+EFIAPI
+ArmDataCacheSize (
+  VOID
+  )
+{
+  switch (DATA_CACHE_SIZE(Cp15CacheInfo()))
+  {
+    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(Cp15CacheInfo()))
+  {
+    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(Cp15CacheInfo()))
+  {
+    case CACHE_LINE_LENGTH_32_BYTES: return 32;
+    default:                         return  0;
+  }
+}
+  
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+  VOID
+  )
+{
+  switch (INSTRUCTION_CACHE_PRESENT(Cp15CacheInfo()))
+  {
+    case CACHE_PRESENT:     return TRUE;
+    case CACHE_NOT_PRESENT: return FALSE;
+    default:                return FALSE;
+  }
+}
+  
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+  VOID
+  )
+{
+  switch (INSTRUCTION_CACHE_SIZE(Cp15CacheInfo()))
+  {
+    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(Cp15CacheInfo()))
+  {
+    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(Cp15CacheInfo()))
+  {
+    case CACHE_LINE_LENGTH_32_BYTES: return 32;
+    default:                         return  0;
+  }
+}
+
+

+ 118 - 0
ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c

@@ -0,0 +1,118 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Chipset/ARM926EJ-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;
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+    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;
+  
+  for (Index = 0; Index < Sections; Index++)
+  {
+    *Entry++     =  TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
+    PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
+  }
+}
+
+VOID
+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));
+  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++;
+  }
+
+  ArmSetTranslationTableBaseAddress(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();
+}

+ 128 - 0
ArmPkg/Library/ArmLib/Arm9/Arm9Support.S

@@ -0,0 +1,128 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+.globl ASM_PFX(ArmCleanInvalidateDataCache)
+.globl ASM_PFX(ArmCleanDataCache)
+.globl ASM_PFX(ArmInvalidateDataCache)
+.globl ASM_PFX(ArmInvalidateInstructionCache)
+.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
+.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
+.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
+.globl ASM_PFX(ArmEnableMmu)
+.globl ASM_PFX(ArmDisableMmu)
+.globl ASM_PFX(ArmEnableDataCache)
+.globl ASM_PFX(ArmDisableDataCache)
+.globl ASM_PFX(ArmEnableInstructionCache)
+.globl ASM_PFX(ArmDisableInstructionCache)
+.globl ASM_PFX(ArmEnableBranchPrediction)
+.globl ASM_PFX(ArmDisableBranchPrediction)
+
+.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(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_FUNCTION_REMOVE_IF_UNREFERENCED
+

+ 129 - 0
ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm

@@ -0,0 +1,129 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+    EXPORT  ArmCleanInvalidateDataCache
+    EXPORT  ArmCleanDataCache
+    EXPORT  ArmInvalidateDataCache
+    EXPORT  ArmInvalidateInstructionCache
+    EXPORT  ArmInvalidateDataCacheEntryByMVA
+    EXPORT  ArmCleanDataCacheEntryByMVA
+    EXPORT  ArmCleanInvalidateDataCacheEntryByMVA
+    EXPORT  ArmEnableMmu
+    EXPORT  ArmDisableMmu
+    EXPORT  ArmEnableDataCache
+    EXPORT  ArmDisableDataCache
+    EXPORT  ArmEnableInstructionCache
+    EXPORT  ArmDisableInstructionCache
+    EXPORT  ArmEnableBranchPrediction
+    EXPORT  ArmDisableBranchPrediction
+
+
+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
+
+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.
+
+    END

+ 288 - 0
ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.c

@@ -0,0 +1,288 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Chipset/Cortex-A8.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "ArmCortexALib.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_DEVICE:
+      Attributes = TT_DESCRIPTOR_SECTION_DEVICE;
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+    default:
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
+      break;
+  }
+  
+  Entry    = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
+  Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;
+  
+  for (Index = 0; Index < Sections; Index++)
+  {
+    *Entry++     =  TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
+    PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
+  }
+}
+
+VOID
+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));
+  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++;
+  }
+
+  ArmSetTranslationTableBaseAddress(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();
+}
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+  VOID
+  )
+{
+  return ARM_CACHE_TYPE_WRITE_BACK;
+}
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+  VOID
+  )
+{
+  return ARM_CACHE_ARCHITECTURE_SEPARATE;
+}
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+  VOID
+  )
+{
+  return TRUE;
+}
+  
+UINTN
+EFIAPI
+ArmDataCacheSize (
+  VOID
+  )
+{
+  return  16 * 1024;      
+}
+  
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+  VOID
+  )
+{
+  return 4;
+}
+  
+UINTN
+ArmDataCacheSets (
+  VOID
+  )
+{
+  return 64;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+  VOID
+  )
+{
+  return 64;
+}
+  
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+  VOID
+  )
+{
+  return TRUE;
+}
+  
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+  VOID
+  )
+{
+  return  16 * 1024;      
+}
+  
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+  VOID
+  )
+{
+  return 4;
+}
+  
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+  VOID
+  )
+{
+  return 64;
+}
+
+VOID
+ArmCortexADataCacheOperation (
+  IN  ARM_CORTEX_A_CACHE_OPERATION  DataCacheOperation
+  )
+{
+  UINTN     Set;
+  UINTN     SetCount;
+  UINTN     SetShift;
+  UINTN     Way;
+  UINTN     WayCount;
+  UINTN     WayShift;
+  UINT32    SetWayFormat;
+  UINTN     SavedInterruptState;
+
+  SetCount = ArmDataCacheSets();
+  WayCount = ArmDataCacheAssociativity();
+
+  // Cortex-A8 Manual, System Control Coprocessor chapter
+  SetShift = 6;
+  WayShift = 32 - LowBitSet32 ((UINT32)WayCount);
+  
+  SavedInterruptState = ArmDisableInterrupts();
+      
+  for (Way = 0; Way < WayCount; Way++) {
+    for (Set = 0; Set < SetCount; Set++) {      
+      // Build the format that the CP15 instruction can understand
+      SetWayFormat = (Way << WayShift) | (Set << SetShift);
+
+      // Pass it through
+      (*DataCacheOperation)(SetWayFormat);
+    }
+  }
+  
+  ArmDrainWriteBuffer();
+  
+  if (SavedInterruptState) {
+    ArmEnableInterrupts();
+  }
+}
+
+VOID
+EFIAPI
+ArmInvalidateDataCache (
+  VOID
+  )
+{
+  ArmCortexADataCacheOperation(ArmInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+  VOID
+  )
+{
+  ArmCortexADataCacheOperation(ArmCleanInvalidateDataCacheEntryBySetWay);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+  VOID
+  )
+{
+  ArmCortexADataCacheOperation(ArmCleanDataCacheEntryBySetWay);
+}

+ 45 - 0
ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.h

@@ -0,0 +1,45 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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 __ARMCORTEXALIB_H__
+#define __ARMCORTEXALIB_H__
+
+typedef VOID (*ARM_CORTEX_A_CACHE_OPERATION)(UINT32);
+
+VOID
+EFIAPI
+ArmDrainWriteBuffer (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmInvalidateDataCacheEntryBySetWay (
+  IN  UINT32  SetWayFormat
+  );
+
+VOID
+EFIAPI
+ArmCleanDataCacheEntryBySetWay (
+  IN  UINT32  SetWayFormat
+  );
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCacheEntryBySetWay (
+  IN  UINT32   SetWayFormat
+  );
+
+#endif // __ARMCORTEXALIB_H__
+

+ 140 - 0
ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.S

@@ -0,0 +1,140 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+.globl ASM_PFX(ArmInvalidateInstructionCache)
+.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
+.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
+.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
+.globl ASM_PFX(ArmInvalidateDataCacheEntryBySetWay)
+.globl ASM_PFX(ArmCleanDataCacheEntryBySetWay)
+.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay)
+.globl ASM_PFX(ArmDrainWriteBuffer)
+.globl ASM_PFX(ArmEnableMmu)
+.globl ASM_PFX(ArmDisableMmu)
+.globl ASM_PFX(ArmEnableDataCache)
+.globl ASM_PFX(ArmDisableDataCache)
+.globl ASM_PFX(ArmEnableInstructionCache)
+.globl ASM_PFX(ArmDisableInstructionCache)
+.globl ASM_PFX(ArmEnableExtendPTConfig)
+.globl ASM_PFX(ArmDisableExtendPTConfig)
+.globl ASM_PFX(ArmEnableBranchPrediction)
+.globl ASM_PFX(ArmDisableBranchPrediction)
+
+.set DC_ON, (0x1<<2)
+.set IC_ON, (0x1<<12)
+.set XP_ON, (0x1<<23)
+
+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(ArmInvalidateDataCacheEntryBySetWay):
+  mcr     p15, 0, r0, c7, c6, 2        @ Invalidate this line		
+  bx      lr
+
+
+ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay):
+  mcr     p15, 0, r0, c7, c14, 2       @ Clean and Invalidate this line		
+  bx      lr
+
+
+ASM_PFX(ArmCleanDataCacheEntryBySetWay):
+  mcr     p15, 0, r0, c7, c10, 2       @ Clean this line		
+  bx      lr
+
+
+ASM_PFX(ArmDrainWriteBuffer):
+  mcr     p15, 0, r0, c7, c10, 4       @ Drain write buffer for sync
+  bx      lr
+  
+
+ASM_PFX(ArmInvalidateInstructionCache):
+  mov     R0,#0
+  mcr     p15,0,R0,c7,c5,0      @Invalidate entire instruction cache
+  mov     R0,#0
+  mcr     p15,0,R0,c7,c5,4      @Instruction synchronization barrier
+  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(ArmDisableMmu):
+  mov     R0,#0
+  mcr     p15,0,R0,c13,c0,0     @FCSE PID register must be cleared before disabling MMU
+  mrc     p15,0,R0,c1,c0,0
+  bic     R0,R0,#1
+  mcr     p15,0,R0,c1,c0,0      @Disable MMU
+  mov     R0,#0
+  mcr     p15,0,R0,c7,c10,4     @Data synchronization barrier
+  mov     R0,#0
+  mcr     p15,0,R0,c7,c5,4      @Instruction synchronization barrier
+  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(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_FUNCTION_REMOVE_IF_UNREFERENCED

+ 141 - 0
ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.asm

@@ -0,0 +1,141 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+    EXPORT  ArmInvalidateInstructionCache
+    EXPORT  ArmInvalidateDataCacheEntryByMVA
+    EXPORT  ArmCleanDataCacheEntryByMVA
+    EXPORT  ArmCleanInvalidateDataCacheEntryByMVA
+    EXPORT  ArmInvalidateDataCacheEntryBySetWay
+    EXPORT  ArmCleanDataCacheEntryBySetWay
+    EXPORT  ArmCleanInvalidateDataCacheEntryBySetWay
+    EXPORT  ArmDrainWriteBuffer
+    EXPORT  ArmEnableMmu
+    EXPORT  ArmDisableMmu
+    EXPORT  ArmEnableDataCache
+    EXPORT  ArmDisableDataCache
+    EXPORT  ArmEnableInstructionCache
+    EXPORT  ArmDisableInstructionCache
+    EXPORT  ArmEnableBranchPrediction
+    EXPORT  ArmDisableBranchPrediction
+
+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
+
+
+ArmInvalidateDataCacheEntryBySetWay
+  mcr     p15, 0, r0, c7, c6, 2        ; Invalidate this line		
+  bx      lr
+
+
+ArmCleanInvalidateDataCacheEntryBySetWay
+  mcr     p15, 0, r0, c7, c14, 2       ; Clean and Invalidate this line		
+  bx      lr
+
+
+ArmCleanDataCacheEntryBySetWay
+  mcr     p15, 0, r0, c7, c10, 2       ; Clean this line		
+  bx      lr
+
+
+ArmDrainWriteBuffer
+  mcr     p15, 0, r0, c7, c10, 4       ; Drain write buffer for sync
+  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,c5,4      ;Instruction synchronization barrier
+  BX      LR
+
+ArmEnableMmu
+  mrc     p15,0,R0,c1,c0,0
+  orr     R0,R0,#1
+  mcr     p15,0,R0,c1,c0,0
+  bx      LR
+
+ArmDisableMmu
+  mov     R0,#0
+  mcr     p15,0,R0,c13,c0,0     ;FCSE PID register must be cleared before disabling MMU
+  mrc     p15,0,R0,c1,c0,0
+  bic     R0,R0,#1
+  mcr     p15,0,R0,c1,c0,0      ;Disable MMU
+  mov     R0,#0
+  mcr     p15,0,R0,c7,c10,4     ;Data synchronization barrier
+  mov     R0,#0
+  mcr     p15,0,R0,c7,c5,4      ;Instruction synchronization barrier
+  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
+
+    END

+ 31 - 0
ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf

@@ -0,0 +1,31 @@
+#%HEADER%
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmCortexArmLib
+  FILE_GUID                      = 411cdfd8-f964-4b9d-a3e3-1719a9c15559
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmLib
+
+[Sources.common]
+  ../Common/ArmLibSupport.S    | GCC
+  ../Common/ArmLibSupport.asm  | RVCT
+  ../Common/ArmLib.c
+  
+  ArmCortexASupport.S    | GCC
+  ArmCortexASupport.asm  | RVCT
+
+  ArmCortexALib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  
+[Protocols]
+  gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+ 31 - 0
ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLibPrePi.inf

@@ -0,0 +1,31 @@
+#%HEADER%
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ArmCortexArmLibPrePi
+  FILE_GUID                      = A150FA0C-F4E8-4207-9BEB-CD6DFB430D73
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmLib
+
+[Sources.common]
+  ../Common/ArmLibSupport.S    | GCC
+  ../Common/ArmLibSupport.asm  | RVCT
+  ../Common/ArmLib.c
+  
+  ArmCortexASupport.S    | GCC
+  ArmCortexASupport.asm  | RVCT
+
+  ArmCortexALib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  PrePiLib
+  
+[Protocols]
+  gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+ 60 - 0
ArmPkg/Library/ArmLib/Common/ArmLib.c

@@ -0,0 +1,60 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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
+ArmSwitchProcessorMode (
+  IN ARM_PROCESSOR_MODE Mode
+  )
+{
+  CPSRMaskInsert(ARM_PROCESSOR_MODE_MASK, Mode);
+}
+
+
+ARM_PROCESSOR_MODE
+EFIAPI
+ArmProcessorMode (
+  VOID
+  )
+{
+  return (ARM_PROCESSOR_MODE)(CPSRRead() & (UINT32)ARM_PROCESSOR_MODE_MASK);
+}

+ 70 - 0
ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h

@@ -0,0 +1,70 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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
+  );
+
+#endif // __ARM_LIB_PRIVATE_H__

+ 89 - 0
ArmPkg/Library/ArmLib/Common/ArmLibSupport.S

@@ -0,0 +1,89 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+.text
+.align 2
+.globl ASM_PFX(Cp15IdCode)
+.globl ASM_PFX(Cp15CacheInfo)
+.globl ASM_PFX(ArmEnableInterrupts)
+.globl ASM_PFX(ArmDisableInterrupts)
+.globl ASM_PFX(ArmGetInterruptState)
+.globl ASM_PFX(ArmInvalidateTlb)
+.globl ASM_PFX(ArmSetTranslationTableBaseAddress)
+.globl ASM_PFX(ArmSetDomainAccessControl)
+.globl ASM_PFX(CPSRMaskInsert)
+.globl ASM_PFX(CPSRRead)
+
+#------------------------------------------------------------------------------
+
+ASM_PFX(Cp15IdCode):
+  mrc     p15,0,R0,c0,c0,0
+  bx      LR
+
+ASM_PFX(Cp15CacheInfo):
+  mrc     p15,0,R0,c0,c0,1
+  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(ArmGetInterruptState):
+	mrs     R0,CPSR
+	tst     R0,#0x80	    @Check if IRQ is enabled.
+	moveq   R0,#1
+	movne   R0,#0
+	bx      LR
+
+ASM_PFX(ArmInvalidateTlb):
+  mov     r0,#0
+  mcr     p15,0,r0,c8,c7,0
+  bx      lr
+
+ASM_PFX(ArmSetTranslationTableBaseAddress):
+  mcr     p15,0,r0,c2,c0,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)
+  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_FUNCTION_REMOVE_IF_UNREFERENCED

+ 90 - 0
ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm

@@ -0,0 +1,90 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    EXPORT  Cp15IdCode
+    EXPORT  Cp15CacheInfo
+    EXPORT  ArmEnableInterrupts
+    EXPORT  ArmDisableInterrupts
+    EXPORT  ArmGetInterruptState
+    EXPORT  ArmInvalidateTlb
+    EXPORT  ArmSetTranslationTableBaseAddress
+    EXPORT  ArmSetDomainAccessControl
+    EXPORT  CPSRMaskInsert
+    EXPORT  CPSRRead
+
+    AREA ArmLibSupport, CODE, READONLY
+
+Cp15IdCode
+  mrc     p15,0,R0,c0,c0,0
+  bx      LR
+
+Cp15CacheInfo
+  mrc     p15,0,R0,c0,c0,1
+  bx      LR
+
+ArmEnableInterrupts
+	mrs     R0,CPSR
+	bic     R0,R0,#0x80		;Enable IRQ interrupts
+	msr     CPSR_c,R0
+	bx      LR
+
+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
+
+ArmGetInterruptState
+	mrs     R0,CPSR
+	tst     R0,#0x80	    ;Check if IRQ is enabled.
+	moveq   R0,#1
+	movne   R0,#0
+	bx      LR
+  
+ArmInvalidateTlb
+  mov     r0,#0
+  mcr     p15,0,r0,c8,c7,0
+  bx      lr
+
+ArmSetTranslationTableBaseAddress
+  mcr     p15,0,r0,c2,c0,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)
+  mov     sp, r3            ; restore stack pointer
+  ldmfd   sp!, {r4-r12, lr} ; restore registers
+  bx      lr                ; return (hopefully thumb-safe!)
+
+CPSRRead
+  mrs     r0, cpsr
+  bx      lr
+  
+  END
+
+

+ 106 - 0
ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c

@@ -0,0 +1,106 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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;
+}

+ 117 - 0
ArmPkg/Library/ArmLib/Null/NullArmLib.c

@@ -0,0 +1,117 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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);
+}

+ 26 - 0
ArmPkg/Library/ArmLib/Null/NullArmLib.inf

@@ -0,0 +1,26 @@
+#%HEADER%
+[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/ArmLibSupport.S    | GCC
+  ../Common/ArmLibSupport.asm  | RVCT
+  ../Common/ArmLib.c
+
+  NullArmLib.c
+  NullArmCacheInformation.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[Protocols]
+  gEfiCpuArchProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold

+ 83 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h

@@ -0,0 +1,83 @@
+/** @file
+
+  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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;
+
+#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

+ 38 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S

@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___ashldi3
+___ashldi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 0, uses_anonymous_args = 0
+	@ link register save eliminated.
+	cmp	r2, #31
+	@ lr needed for prologue
+	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

+ 83 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c

@@ -0,0 +1,83 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/**
+  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;
+}

+ 39 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S

@@ -0,0 +1,39 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___ashrdi3
+___ashrdi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 0, uses_anonymous_args = 0
+	@ link register save eliminated.
+	cmp	r2, #31
+	@ lr needed for prologue
+	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

+ 84 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c

@@ -0,0 +1,84 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/**
+  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;
+}

+ 96 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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));
+}

+ 111 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c

@@ -0,0 +1,111 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/** @file
+  Compiler intrinsic to return the number of trailing zeros, ported from LLVM code.
+
+  Copyright (c) 2008, Apple, Inc.
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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));
+}

+ 155 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm

@@ -0,0 +1,155 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    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
+

+ 48 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S

@@ -0,0 +1,48 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___divdi3
+___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	___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}

+ 77 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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
+}
+
+

+ 33 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S

@@ -0,0 +1,33 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___divsi3
+___divsi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 1, uses_anonymous_args = 0
+	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	___udivsi3
+	eor	r1, r5, r4
+	eor	r0, r0, r1
+	rsb	r0, r1, r0
+	ldmfd	sp!, {r4, r5, r7, pc}

+ 78 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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
+}
+
+

+ 41 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm

@@ -0,0 +1,41 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    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
+

+ 54 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm

@@ -0,0 +1,54 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    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      {pc} + 0xc  ; 0x18
+    RSBS     r0,r0,#0
+    RSC      r1,r1,#0
+    TST      r3,r3
+    BPL      {pc} + 0xc  ; 0x28
+    RSBS     r2,r2,#0
+    RSC      r3,r3,#0
+    BL       __aeabi_uldivmod  ;
+    TST      r4,#0x40000000
+    BEQ      {pc} + 0xc  ; 0x3c
+    RSBS     r0,r0,#0
+    RSC      r1,r1,#0
+    TST      r4,#0x80000000
+    BEQ      {pc} + 0xc  ; 0x4c
+    RSBS     r2,r2,#0
+    RSC      r3,r3,#0
+    POP      {r4,pc}
+ 
+    END
+
+

+ 43 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm

@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    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
+

+ 44 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm

@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    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
+
+
+

+ 38 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S

@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___lshrdi3
+___lshrdi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 0, uses_anonymous_args = 0
+	@ link register save eliminated.
+	cmp	r2, #31
+	@ lr needed for prologue
+	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

+ 83 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c

@@ -0,0 +1,83 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/**
+  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;
+}

+ 35 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S

@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl _memcpy
+_memcpy:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 1, uses_anonymous_args = 0
+	stmfd	sp!, {r7, lr}
+	mov	ip, #0
+	add	r7, sp, #0
+	mov	lr, r0
+	b	L4
+L5:
+	ldrb	r3, [r1], #1	@ zero_extendqisi2
+	add	ip, ip, #1
+	and	r3, r3, #255
+	strb	r3, [lr], #1
+L4:
+	cmp	ip, r2
+	bne	L5
+	ldmfd	sp!, {r7, pc}
+

+ 40 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm

@@ -0,0 +1,40 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    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    r14
+loop
+    LDRB    r3, [r1], #1
+    STRB    r3, [r0], #1
+    SUBS    r2, r2, #1
+    BXEQ    r14
+    B       loop
+        
+    END
+

+ 61 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm

@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    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
+

+ 35 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S

@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+
+  .text
+	.align 2
+	.globl _memset
+_memset:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 1, uses_anonymous_args = 0
+	stmfd	sp!, {r7, lr}
+	mov	ip, #0
+	add	r7, sp, #0
+	mov	lr, r0
+	b	L9
+L10:
+	and	r3, r1, #255
+	add	ip, ip, #1
+	strb	r3, [lr], #1
+L9:
+	cmp	ip, r2
+	bne	L10
+	ldmfd	sp!, {r7, pc}
+

+ 47 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S

@@ -0,0 +1,47 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___moddi3
+___moddi3:
+	@ args = 0, pretend = 0, frame = 8
+	@ frame_needed = 1, uses_anonymous_args = 0
+	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	___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}

+ 77 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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
+}
+

+ 28 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S

@@ -0,0 +1,28 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___modsi3
+___modsi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 1, uses_anonymous_args = 0
+	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}

+ 70 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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;
+}
+
+

+ 59 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S

@@ -0,0 +1,59 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___muldi3
+___muldi3:
+	@ args = 0, pretend = 0, frame = 8
+	@ frame_needed = 1, uses_anonymous_args = 0
+	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

+ 98 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c

@@ -0,0 +1,98 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/**
+  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;
+}

+ 49 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm

@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+  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

+ 29 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm

@@ -0,0 +1,29 @@
+///------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+
+    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

+ 46 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S

@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+#/** @file
+#  Compiler intrinsic for ARM compiler
+#
+#  Copyright (c) 2008, Apple, Inc.
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http)://opensource.org/licenses/bsd-license.php
+#
+#  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
+
+.globl ASM_PFX(__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
+
+

+ 45 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S

@@ -0,0 +1,45 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+#/** @file
+#  Compiler intrinsic for ARM compiler
+#
+#  Copyright (c) 2008, Apple, Inc.
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http)://opensource.org/licenses/bsd-license.php
+#
+#  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
+
+.globl ASM_PFX(__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
+

+ 43 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S

@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+#/** @file
+#  Compiler intrinsic for ARM compiler
+#
+#  Copyright (c) 2008, Apple, Inc.
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http)://opensource.org/licenses/bsd-license.php
+#
+#  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
+
+.globl ASM_PFX(__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
+

+ 43 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S

@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+#/** @file
+#  Compiler intrinsic for ARM compiler
+#
+#  Copyright (c) 2008, Apple, Inc.
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http)://opensource.org/licenses/bsd-license.php
+#
+#  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
+
+.globl ASM_PFX(__switchu8)
+
+
+ASM_PFX(__switchu8):
+    ldrb      ip,[lr,#-1]
+    cmp       r3,ip
+    ldrccb    r3,[lr,r3]
+    ldrcsb    r3,[lr,ip]
+    add       ip,lr,r3,LSL #1
+    bx        ip
+

+ 82 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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;
+}

+ 28 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S

@@ -0,0 +1,28 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___udivdi3
+___udivdi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 1, uses_anonymous_args = 0
+	stmfd	sp!, {r7, lr}
+	add	r7, sp, #0
+	sub	sp, sp, #8
+	mov	ip, #0
+	str	ip, [sp, #0]
+	bl	___udivmoddi4
+	sub	sp, r7, #0
+	ldmfd	sp!, {r7, pc}

+ 71 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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);
+}
+
+

+ 243 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S

@@ -0,0 +1,243 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___udivmoddi4
+___udivmoddi4:
+	@ args = 8, pretend = 0, frame = 16
+	@ frame_needed = 1, uses_anonymous_args = 0
+	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	___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	___umodsi3
+	mov	r1, #0
+	stmia	r6, {r0-r1}
+L16:
+	ldr	r1, [sp, #4]
+	mov	r0, r11
+L45:
+	bl	___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	___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}

+ 287 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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;
+}

+ 57 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S

@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___udivsi3
+___udivsi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 1, uses_anonymous_args = 0
+	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}

+ 111 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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;
+}

+ 268 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm

@@ -0,0 +1,268 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+
+    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
+

+ 30 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S

@@ -0,0 +1,30 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___umoddi3
+___umoddi3:
+	@ args = 0, pretend = 0, frame = 8
+	@ frame_needed = 1, uses_anonymous_args = 0
+	stmfd	sp!, {r7, lr}
+	add	r7, sp, #0
+	sub	sp, sp, #16
+	add	ip, sp, #8
+	str	ip, [sp, #0]
+	bl	___udivmoddi4
+	ldrd	r0, [sp, #8]
+	sub	sp, r7, #0
+	ldmfd	sp!, {r7, pc}
+

+ 72 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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;
+}
+

+ 40 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S

@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------ 
+#
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#------------------------------------------------------------------------------
+
+	.text
+	.align 2
+	.globl ___umodsi3
+___umodsi3:
+	@ args = 0, pretend = 0, frame = 0
+	@ frame_needed = 1, uses_anonymous_args = 0
+	stmfd	sp!, {r4, r5, r7, lr}
+	add	r7, sp, #8
+	mov	r5, r0
+	mov	r4, r1
+	bl	L___udivsi3$stub
+	mul	r0, r4, r0
+	rsb	r0, r0, r5
+	ldmfd	sp!, {r4, r5, r7, pc}
+	.section __TEXT,__symbol_stub4,symbol_stubs,none,12
+	.align 2
+L___udivsi3$stub:
+	.indirect_symbol ___udivsi3
+	ldr	ip, L___udivsi3$slp
+	ldr	pc, [ip, #0]
+L___udivsi3$slp:
+	.long	L___udivsi3$lazy_ptr
+	.lazy_symbol_pointer
+L___udivsi3$lazy_ptr:
+	.indirect_symbol	___udivsi3
+	.long	dyld_stub_binding_helper

+ 68 - 0
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.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  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;
+}

+ 38 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm

@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+
+    EXPORT  __aeabi_uread4
+
+    AREA  Uread4, CODE, READONLY
+
+;
+;UINT32
+;EFIAPI
+;__aeabi_uread4 (
+;  IN VOID   *Pointer
+;  );
+;
+__aeabi_uread4
+    ldrb    r2, [r0, #1]
+    ldrb    r1, [r0]
+    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
+
+    END

+ 40 - 0
ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm

@@ -0,0 +1,40 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+    EXPORT  __aeabi_uwrite4
+
+    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
+ 
+    END
+

+ 92 - 0
ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

@@ -0,0 +1,92 @@
+#%HEADER%
+#/** @file
+#  Base Library implementation.
+#
+#  Copyright (c) 2009, Apple, Inc.
+#
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  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.common]
+
+
+[Sources.ARM]
+  Arm/mullu.asm        | RVCT
+  Arm/switch.asm       | RVCT
+  Arm/llsr.asm         | RVCT
+  Arm/memcpy.asm       | RVCT
+  Arm/memcpy4.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/divdi3.S     | GCC
+  Arm/divsi3.S     | GCC
+  Arm/lshrdi3.S    | GCC
+
+  Arm/memcpy.S     | GCC
+  Arm/memset.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/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/switch8.S    | GCC
+  Arm/switchu8.S   | GCC
+  Arm/switch16.S   | GCC
+  Arm/switch32.S   | GCC
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+

+ 258 - 0
ArmPkg/Library/SemiHostingDebugLib/DebugLib.c

@@ -0,0 +1,258 @@
+/** @file
+
+  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
+  
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+/** @file
+  UEFI Debug Library that uses PrintLib to send messages to STDERR.
+
+  Copyright (c) 2006 - 2007, Intel Corporation<BR>
+  All rights reserved. This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  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);
+}

+ 46 - 0
ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf

@@ -0,0 +1,46 @@
+#%HEADER%
+#/** @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. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  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
+
+[Pcd.common]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
+

Неке датотеке нису приказане због велике количине промена