From 2ef2b01e07c02db339f34004445734a2dbdd80e1 Mon Sep 17 00:00:00 2001 From: AJFISH Date: Sun, 6 Dec 2009 01:57:05 +0000 Subject: 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 --- ArmPkg/ArmPkg.dec | 36 ++ ArmPkg/ArmPkg.dsc | 61 ++ ArmPkg/Drivers/CpuDxe/CpuDxe.c | 154 +++++ ArmPkg/Drivers/CpuDxe/CpuDxe.h | 91 +++ ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 56 ++ ArmPkg/Drivers/CpuDxe/DebugSupport.c | 247 ++++++++ ArmPkg/Drivers/CpuDxe/Exception.c | 238 ++++++++ ArmPkg/Drivers/CpuDxe/ExceptionSupport.S | 152 +++++ ArmPkg/Drivers/CpuDxe/ExceptionSupport.asm | 152 +++++ ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c | 119 ++++ ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf | 30 + ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c | 526 ++++++++++++++++ ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h | 114 ++++ ArmPkg/Filesystem/SemihostFs/SemihostFs.inf | 48 ++ ArmPkg/Include/AsmMacroIoLib.h | 236 ++++++++ ArmPkg/Include/AsmMacroIoLib.inc | 74 +++ ArmPkg/Include/Chipset/ARM1176JZ-S.h | 111 ++++ ArmPkg/Include/Chipset/ARM926EJ-S.h | 71 +++ ArmPkg/Include/Chipset/Cortex-A8.h | 104 ++++ ArmPkg/Include/Library/ArmLib.h | 294 +++++++++ ArmPkg/Include/Library/SemihostLib.h | 100 ++++ .../Include/Library/UncachedMemoryAllocationLib.h | 665 +++++++++++++++++++++ ArmPkg/Include/Protocol/TimerDebugSupport.h | 59 ++ .../ArmCacheMaintenanceLib.c | 129 ++++ .../ArmCacheMaintenanceLib.inf | 23 + ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf | 32 + ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf | 32 + ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c | 118 ++++ ArmPkg/Library/ArmLib/Arm11/Arm11Support.S | 129 ++++ ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm | 133 +++++ ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf | 32 + ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf | 32 + ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c | 164 +++++ ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c | 118 ++++ ArmPkg/Library/ArmLib/Arm9/Arm9Support.S | 128 ++++ ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm | 129 ++++ ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.c | 288 +++++++++ ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.h | 45 ++ .../Library/ArmLib/ArmCortexA/ArmCortexASupport.S | 140 +++++ .../ArmLib/ArmCortexA/ArmCortexASupport.asm | 141 +++++ .../Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf | 31 + .../ArmLib/ArmCortexA/ArmCortexArmLibPrePi.inf | 31 + ArmPkg/Library/ArmLib/Common/ArmLib.c | 60 ++ ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h | 70 +++ ArmPkg/Library/ArmLib/Common/ArmLibSupport.S | 89 +++ ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm | 90 +++ .../Library/ArmLib/Null/NullArmCacheInformation.c | 106 ++++ ArmPkg/Library/ArmLib/Null/NullArmLib.c | 117 ++++ ArmPkg/Library/ArmLib/Null/NullArmLib.inf | 26 + .../CompilerIntrinsicsLib/Arm/Llvm_int_lib.h | 83 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S | 38 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c | 83 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S | 39 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c | 84 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c | 96 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c | 111 ++++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm | 155 +++++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S | 48 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c | 77 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S | 33 + ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c | 78 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm | 41 ++ .../Library/CompilerIntrinsicsLib/Arm/ldivmod.asm | 54 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm | 43 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm | 44 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S | 38 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c | 83 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S | 35 ++ .../Library/CompilerIntrinsicsLib/Arm/memcpy.asm | 40 ++ .../Library/CompilerIntrinsicsLib/Arm/memcpy4.asm | 61 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S | 35 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S | 47 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c | 77 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S | 28 + ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c | 70 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S | 59 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c | 98 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm | 49 ++ .../Library/CompilerIntrinsicsLib/Arm/switch.asm | 29 + .../Library/CompilerIntrinsicsLib/Arm/switch16.S | 46 ++ .../Library/CompilerIntrinsicsLib/Arm/switch32.S | 45 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S | 43 ++ .../Library/CompilerIntrinsicsLib/Arm/switchu8.S | 43 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c | 82 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S | 28 + ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c | 71 +++ .../Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S | 243 ++++++++ .../Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c | 287 +++++++++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S | 57 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c | 111 ++++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm | 268 +++++++++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S | 30 + ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c | 72 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S | 40 ++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c | 68 +++ ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm | 38 ++ .../Library/CompilerIntrinsicsLib/Arm/uwrite.asm | 40 ++ .../CompilerIntrinsicsLib.inf | 92 +++ ArmPkg/Library/SemiHostingDebugLib/DebugLib.c | 258 ++++++++ .../SemiHostingDebugLib/SemiHostingDebugLib.inf | 46 ++ .../SemiHostingSerialPortLib.inf | 35 ++ .../SemiHostingSerialPortLib/SerialPortLib.c | 144 +++++ ArmPkg/Library/SemihostLib/Arm/SemihostLib.c | 221 +++++++ ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h | 162 +++++ ArmPkg/Library/SemihostLib/SemihostLib.inf | 32 + .../UncachedMemoryAllocationLib.c | 626 +++++++++++++++++++ .../UncachedMemoryAllocationLib.inf | 25 + 107 files changed, 11280 insertions(+) create mode 100644 ArmPkg/ArmPkg.dec create mode 100644 ArmPkg/ArmPkg.dsc create mode 100644 ArmPkg/Drivers/CpuDxe/CpuDxe.c create mode 100644 ArmPkg/Drivers/CpuDxe/CpuDxe.h create mode 100644 ArmPkg/Drivers/CpuDxe/CpuDxe.inf create mode 100644 ArmPkg/Drivers/CpuDxe/DebugSupport.c create mode 100644 ArmPkg/Drivers/CpuDxe/Exception.c create mode 100755 ArmPkg/Drivers/CpuDxe/ExceptionSupport.S create mode 100755 ArmPkg/Drivers/CpuDxe/ExceptionSupport.asm create mode 100644 ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c create mode 100644 ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf create mode 100644 ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c create mode 100644 ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h create mode 100644 ArmPkg/Filesystem/SemihostFs/SemihostFs.inf create mode 100644 ArmPkg/Include/AsmMacroIoLib.h create mode 100644 ArmPkg/Include/AsmMacroIoLib.inc create mode 100644 ArmPkg/Include/Chipset/ARM1176JZ-S.h create mode 100644 ArmPkg/Include/Chipset/ARM926EJ-S.h create mode 100644 ArmPkg/Include/Chipset/Cortex-A8.h create mode 100644 ArmPkg/Include/Library/ArmLib.h create mode 100644 ArmPkg/Include/Library/SemihostLib.h create mode 100644 ArmPkg/Include/Library/UncachedMemoryAllocationLib.h create mode 100644 ArmPkg/Include/Protocol/TimerDebugSupport.h create mode 100644 ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c create mode 100644 ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf create mode 100644 ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf create mode 100644 ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf create mode 100644 ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c create mode 100644 ArmPkg/Library/ArmLib/Arm11/Arm11Support.S create mode 100644 ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm create mode 100644 ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf create mode 100755 ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf create mode 100644 ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c create mode 100644 ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c create mode 100644 ArmPkg/Library/ArmLib/Arm9/Arm9Support.S create mode 100644 ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm create mode 100644 ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.c create mode 100644 ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.h create mode 100644 ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.S create mode 100644 ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.asm create mode 100644 ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf create mode 100644 ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLibPrePi.inf create mode 100644 ArmPkg/Library/ArmLib/Common/ArmLib.c create mode 100644 ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h create mode 100644 ArmPkg/Library/ArmLib/Common/ArmLibSupport.S create mode 100644 ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm create mode 100644 ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c create mode 100644 ArmPkg/Library/ArmLib/Null/NullArmLib.c create mode 100644 ArmPkg/Library/ArmLib/Null/NullArmLib.inf create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf create mode 100644 ArmPkg/Library/SemiHostingDebugLib/DebugLib.c create mode 100644 ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf create mode 100644 ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf create mode 100644 ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c create mode 100644 ArmPkg/Library/SemihostLib/Arm/SemihostLib.c create mode 100644 ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h create mode 100644 ArmPkg/Library/SemihostLib/SemihostLib.inf create mode 100644 ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c create mode 100644 ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf (limited to 'ArmPkg') diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec new file mode 100644 index 0000000000..9773f450e3 --- /dev/null +++ b/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 diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc new file mode 100644 index 0000000000..ca4f4fa555 --- /dev/null +++ b/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 diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/ArmPkg/Drivers/CpuDxe/CpuDxe.c new file mode 100644 index 0000000000..c57dac2f74 --- /dev/null +++ b/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); +} + diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h new file mode 100644 index 0000000000..36133e11c3 --- /dev/null +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h @@ -0,0 +1,91 @@ +/** @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. + +**/ + +#ifndef __CPU_DXE_ARM_EXCEPTION_H__ +#define __CPU_DXE_ARM_EXCEPTION_H__ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/** + 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__ diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf new file mode 100644 index 0000000000..314965ca4a --- /dev/null +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf @@ -0,0 +1,56 @@ +#%HEADER% +#/** @file +# +# DXE CPU driver +# +# 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 = 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 diff --git a/ArmPkg/Drivers/CpuDxe/DebugSupport.c b/ArmPkg/Drivers/CpuDxe/DebugSupport.c new file mode 100644 index 0000000000..b8a5584939 --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Drivers/CpuDxe/Exception.c b/ArmPkg/Drivers/CpuDxe/Exception.c new file mode 100644 index 0000000000..fa256e60f8 --- /dev/null +++ b/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 + +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; +} diff --git a/ArmPkg/Drivers/CpuDxe/ExceptionSupport.S b/ArmPkg/Drivers/CpuDxe/ExceptionSupport.S new file mode 100755 index 0000000000..8574af6d71 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Drivers/CpuDxe/ExceptionSupport.asm b/ArmPkg/Drivers/CpuDxe/ExceptionSupport.asm new file mode 100755 index 0000000000..d91720cff3 --- /dev/null +++ b/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 + + diff --git a/ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c b/ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c new file mode 100644 index 0000000000..26f4c387dc --- /dev/null +++ b/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 + +#include +#include +#include + +#include +#include +#include + +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; +} + diff --git a/ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf b/ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf new file mode 100644 index 0000000000..59f44879c4 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c new file mode 100644 index 0000000000..0f1da65ba0 --- /dev/null +++ b/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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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; +} + diff --git a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h new file mode 100644 index 0000000000..f058d92e29 --- /dev/null +++ b/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.
+ + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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__ + diff --git a/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf b/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf new file mode 100644 index 0000000000..7fca293d6f --- /dev/null +++ b/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 + diff --git a/ArmPkg/Include/AsmMacroIoLib.h b/ArmPkg/Include/AsmMacroIoLib.h new file mode 100644 index 0000000000..aa3ed61632 --- /dev/null +++ b/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.
+ + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 diff --git a/ArmPkg/Include/AsmMacroIoLib.inc b/ArmPkg/Include/AsmMacroIoLib.inc new file mode 100644 index 0000000000..23f3c44d6b --- /dev/null +++ b/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 diff --git a/ArmPkg/Include/Chipset/ARM1176JZ-S.h b/ArmPkg/Include/Chipset/ARM1176JZ-S.h new file mode 100644 index 0000000000..2331f8effc --- /dev/null +++ b/ArmPkg/Include/Chipset/ARM1176JZ-S.h @@ -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. + +**/ + +#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__ diff --git a/ArmPkg/Include/Chipset/ARM926EJ-S.h b/ArmPkg/Include/Chipset/ARM926EJ-S.h new file mode 100644 index 0000000000..799d60c392 --- /dev/null +++ b/ArmPkg/Include/Chipset/ARM926EJ-S.h @@ -0,0 +1,71 @@ +/** @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. + +**/ + +#ifndef __ARM926EJ_S_H__ +#define __ARM926EJ_S_H__ + +// Domain Access Control Register +#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a))) +#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a))) + +#define TRANSLATION_TABLE_SIZE (16 * 1024) +#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024) +#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1) + +#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20)) + +// Translation table descriptor types +#define TT_DESCRIPTOR_TYPE_MASK (3UL << 0) +#define TT_DESCRIPTOR_TYPE_FAULT (0UL << 0) +#define TT_DESCRIPTOR_TYPE_COARSE ((1UL << 0) | (1UL << 4)) +#define TT_DESCRIPTOR_TYPE_SECTION ((2UL << 0) | (1UL << 4)) +#define TT_DESCRIPTOR_TYPE_FINE ((3UL << 0) | (1UL << 4)) + +// Section descriptor definitions +#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000) + +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK (3UL << 2) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED (0UL << 2) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_BUFFERED (1UL << 2) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH (2UL << 2) +#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK (3UL << 2) + +#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_MASK (3UL << 10) +#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_NONE (1UL << 10) +#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_ONLY (2UL << 10) +#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE (3UL << 10) + +#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5) +#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0xF) << 5) + +#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000) +#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK) + +#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \ + TT_DESCRIPTOR_SECTION_DOMAIN(0) | \ + TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK | \ + TT_DESCRIPTOR_TYPE_SECTION) +#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \ + TT_DESCRIPTOR_SECTION_DOMAIN(0) | \ + TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH | \ + TT_DESCRIPTOR_TYPE_SECTION) +#define TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \ + TT_DESCRIPTOR_SECTION_DOMAIN(0) | \ + TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED | \ + TT_DESCRIPTOR_TYPE_SECTION) + +#endif // __ARM926EJ_S_H__ diff --git a/ArmPkg/Include/Chipset/Cortex-A8.h b/ArmPkg/Include/Chipset/Cortex-A8.h new file mode 100644 index 0000000000..75ce397a79 --- /dev/null +++ b/ArmPkg/Include/Chipset/Cortex-A8.h @@ -0,0 +1,104 @@ +/** @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. + +**/ + +#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__ diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h new file mode 100644 index 0000000000..d68b334e2a --- /dev/null +++ b/ArmPkg/Include/Library/ArmLib.h @@ -0,0 +1,294 @@ +/** @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. + +**/ + +#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__ diff --git a/ArmPkg/Include/Library/SemihostLib.h b/ArmPkg/Include/Library/SemihostLib.h new file mode 100644 index 0000000000..2c8b6ac7d8 --- /dev/null +++ b/ArmPkg/Include/Library/SemihostLib.h @@ -0,0 +1,100 @@ +/** @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. + +**/ + +#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__ diff --git a/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h b/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h new file mode 100644 index 0000000000..8a65fcc586 --- /dev/null +++ b/ArmPkg/Include/Library/UncachedMemoryAllocationLib.h @@ -0,0 +1,665 @@ +/** @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. + +**/ + +#ifndef __UNCACHED_MEMORY_ALLOCATION_LIB_H__ +#define __UNCACHED_MEMORY_ALLOCATION_LIB_H__ + +/** + Converts a cached or uncached address to a physical address suitable for use in SoC registers. + + @param VirtualAddress The pointer to convert. + + @return The physical address of the supplied virtual pointer. + +**/ +EFI_PHYSICAL_ADDRESS +ConvertToPhysicalAddress ( + IN VOID *VirtualAddress + ); + +/** + Converts a cached or uncached address to a cached address. + + @param Address The pointer to convert. + + @return The address of the cached memory location corresponding to the input address. + +**/ +VOID * +ConvertToCachedAddress ( + IN VOID *Address + ); + +/** + Converts a cached or uncached address to an uncached address. + + @param Address The pointer to convert. + + @return The address of the uncached memory location corresponding to the input address. + +**/ +VOID * +ConvertToUncachedAddress ( + IN VOID *Address + ); + +/** + Allocates one or more 4KB pages of type EfiBootServicesData. + + Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocatePages ( + IN UINTN Pages + ); + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimePages ( + IN UINTN Pages + ); + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType. + + Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedPages ( + IN UINTN Pages + ); + +/** + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the page allocation services of the Memory + Allocation Library. + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, + then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +UncachedFreePages ( + IN VOID *Buffer, + IN UINTN Pages + ); + +/** + Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedPages ( + IN UINTN Pages, + IN UINTN Alignment + ); + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimePages ( + IN UINTN Pages, + IN UINTN Alignment + ); + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedPages ( + IN UINTN Pages, + IN UINTN Alignment + ); + +/** + Frees one or more 4KB pages that were previously allocated with one of the aligned page + allocation functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the aligned page allocation services of the Memory + Allocation Library. + If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +UncachedFreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ); + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocatePool ( + IN UINTN AllocationSize + ); + +/** + Allocates a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimePool ( + IN UINTN AllocationSize + ); + +/** + Allocates a buffer of type EfieservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedPool ( + IN UINTN AllocationSize + ); + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateZeroPool ( + IN UINTN AllocationSize + ); + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ); + +/** + Allocates and zeros a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedZeroPool ( + IN UINTN AllocationSize + ); + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +UncachedFreePool ( + IN VOID *Buffer + ); + +/** + Allocates a buffer of type EfiBootServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates a buffer of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimePool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates a buffer of type EfieservedMemoryType at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an + alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory at the specified alignment remaining to satisfy the request, then NULL is + returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an + alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory at the specified alignment remaining to satisfy the request, then NULL is + returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimeZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an + alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory at the specified alignment remaining to satisfy the request, then NULL is + returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Buffer The buffer to copy to the allocated buffer. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ); + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Buffer The buffer to copy to the allocated buffer. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ); + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Buffer The buffer to copy to the allocated buffer. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ); + +/** + Frees a buffer that was previously allocated with one of the aligned pool allocation functions + in the Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + aligned pool allocation services of the Memory Allocation Library. + If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation + Library, then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +UncachedFreeAlignedPool ( + IN VOID *Buffer + ); + +VOID +EFIAPI +UncachedSafeFreePool ( + IN VOID *Buffer + ); + +#endif // __UNCACHED_MEMORY_ALLOCATION_LIB_H__ diff --git a/ArmPkg/Include/Protocol/TimerDebugSupport.h b/ArmPkg/Include/Protocol/TimerDebugSupport.h new file mode 100644 index 0000000000..8ed9254176 --- /dev/null +++ b/ArmPkg/Include/Protocol/TimerDebugSupport.h @@ -0,0 +1,59 @@ +/** @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. + +**/ + +#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__ + diff --git a/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c b/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.c new file mode 100644 index 0000000000..7da6b42a92 --- /dev/null +++ b/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 +#include +#include + +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; +} diff --git a/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf b/ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf new file mode 100644 index 0000000000..93b88f4ef0 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf b/ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf new file mode 100644 index 0000000000..8042e4dd31 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf b/ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf new file mode 100644 index 0000000000..040179e445 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c b/ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c new file mode 100644 index 0000000000..3736904954 --- /dev/null +++ b/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 +#include +#include +#include + +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(); +} diff --git a/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S b/ArmPkg/Library/ArmLib/Arm11/Arm11Support.S new file mode 100644 index 0000000000..eec8f20b4e --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm b/ArmPkg/Library/ArmLib/Arm11/Arm11Support.asm new file mode 100644 index 0000000000..e0be8f0c07 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf b/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf new file mode 100644 index 0000000000..9a940394e2 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf b/ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf new file mode 100755 index 0000000000..909ce27616 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c b/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c new file mode 100644 index 0000000000..a8207b905f --- /dev/null +++ b/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 +#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; + } +} + + diff --git a/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c b/ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c new file mode 100644 index 0000000000..0ba2237d29 --- /dev/null +++ b/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 +#include +#include +#include + +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(); +} diff --git a/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S b/ArmPkg/Library/ArmLib/Arm9/Arm9Support.S new file mode 100644 index 0000000000..5c9afe9347 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm b/ArmPkg/Library/ArmLib/Arm9/Arm9Support.asm new file mode 100644 index 0000000000..3204d6607f --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.c b/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.c new file mode 100644 index 0000000000..4dfa18db58 --- /dev/null +++ b/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 +#include +#include +#include +#include +#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); +} diff --git a/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.h b/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.h new file mode 100644 index 0000000000..afe98bdfa2 --- /dev/null +++ b/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.h @@ -0,0 +1,45 @@ +/** @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. + +**/ + +#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__ + diff --git a/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.S b/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.S new file mode 100644 index 0000000000..0e24f6341c --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.asm b/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexASupport.asm new file mode 100644 index 0000000000..dbd8bd246a --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf b/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf new file mode 100644 index 0000000000..54b77e31b4 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLibPrePi.inf b/ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLibPrePi.inf new file mode 100644 index 0000000000..450dfe5936 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Common/ArmLib.c b/ArmPkg/Library/ArmLib/Common/ArmLib.c new file mode 100644 index 0000000000..b015dc4aa1 --- /dev/null +++ b/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 + +#include +#include +#include + +#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); +} diff --git a/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h b/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h new file mode 100644 index 0000000000..d1d2523947 --- /dev/null +++ b/ArmPkg/Library/ArmLib/Common/ArmLibPrivate.h @@ -0,0 +1,70 @@ +/** @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. + +**/ + +#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__ diff --git a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S new file mode 100644 index 0000000000..d80100c788 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm new file mode 100644 index 0000000000..ec7db638af --- /dev/null +++ b/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 + + diff --git a/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c b/ArmPkg/Library/ArmLib/Null/NullArmCacheInformation.c new file mode 100644 index 0000000000..08a1ad0c5f --- /dev/null +++ b/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 +#include "ArmLibPrivate.h" + +ARM_CACHE_TYPE +EFIAPI +ArmCacheType ( + VOID + ) +{ + return ARM_CACHE_TYPE_UNKNOWN; +} + +ARM_CACHE_ARCHITECTURE +EFIAPI +ArmCacheArchitecture ( + VOID + ) +{ + return ARM_CACHE_ARCHITECTURE_UNKNOWN; +} + +BOOLEAN +EFIAPI +ArmDataCachePresent ( + VOID + ) +{ + return FALSE; +} + +UINTN +EFIAPI +ArmDataCacheSize ( + VOID + ) +{ + return 0; +} + +UINTN +EFIAPI +ArmDataCacheAssociativity ( + VOID + ) +{ + return 0; +} + +UINTN +EFIAPI +ArmDataCacheLineLength ( + VOID + ) +{ + return 0; +} + +BOOLEAN +EFIAPI +ArmInstructionCachePresent ( + VOID + ) +{ + return FALSE; +} + +UINTN +EFIAPI +ArmInstructionCacheSize ( + VOID + ) +{ + return 0; +} + +UINTN +EFIAPI +ArmInstructionCacheAssociativity ( + VOID + ) +{ + return 0; +} + +UINTN +EFIAPI +ArmInstructionCacheLineLength ( + VOID + ) +{ + return 0; +} diff --git a/ArmPkg/Library/ArmLib/Null/NullArmLib.c b/ArmPkg/Library/ArmLib/Null/NullArmLib.c new file mode 100644 index 0000000000..6e95cba706 --- /dev/null +++ b/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 +#include +#include + +VOID +EFIAPI +ArmCleanInvalidateDataCache ( + VOID + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmCleanDataCache ( + VOID + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmInvalidateInstructionCache ( + VOID + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmInvalidateDataCacheEntryByMVA ( + IN UINTN Address + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmCleanDataCacheEntryByMVA ( + IN UINTN Address + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmCleanInvalidateDataCacheEntryByMVA ( + IN UINTN Address + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmEnableDataCache ( + VOID + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmDisableDataCache ( + VOID + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmEnableInstructionCache ( + VOID + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} + +VOID +EFIAPI +ArmDisableInstructionCache ( + VOID + ) +{ + // Do not run code using the Null cache library. + ASSERT(FALSE); +} diff --git a/ArmPkg/Library/ArmLib/Null/NullArmLib.inf b/ArmPkg/Library/ArmLib/Null/NullArmLib.inf new file mode 100644 index 0000000000..ff31b9cecb --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h new file mode 100644 index 0000000000..e2c00a2033 --- /dev/null +++ b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/Llvm_int_lib.h @@ -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 +#include + +#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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S new file mode 100644 index 0000000000..ac2bdbafd0 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.c new file mode 100644 index 0000000000..f708737035 --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S new file mode 100644 index 0000000000..fb87c88a09 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.c new file mode 100644 index 0000000000..ce5134eb64 --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.c new file mode 100644 index 0000000000..c7b4607ca4 --- /dev/null +++ b/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)); +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.c new file mode 100644 index 0000000000..c0e18977ec --- /dev/null +++ b/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)); +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm new file mode 100644 index 0000000000..f6f9bc2d56 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S new file mode 100644 index 0000000000..b7d946ecc7 --- /dev/null +++ b/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} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.c new file mode 100644 index 0000000000..286a504b49 --- /dev/null +++ b/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 +} + + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S new file mode 100644 index 0000000000..2651572222 --- /dev/null +++ b/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} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.c new file mode 100644 index 0000000000..56d731ca8e --- /dev/null +++ b/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 +} + + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.asm new file mode 100644 index 0000000000..9956d064c2 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm new file mode 100644 index 0000000000..cb81608b01 --- /dev/null +++ b/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 + + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.asm new file mode 100644 index 0000000000..745b984085 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm new file mode 100644 index 0000000000..630b542c70 --- /dev/null +++ b/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 + + + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S new file mode 100644 index 0000000000..2257deef97 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.c new file mode 100644 index 0000000000..14b3c8f00a --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S new file mode 100644 index 0000000000..2582a81f90 --- /dev/null +++ b/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} + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.asm new file mode 100644 index 0000000000..60dbcf2ab5 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy4.asm new file mode 100644 index 0000000000..fb251c1eaa --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S new file mode 100644 index 0000000000..f88464483b --- /dev/null +++ b/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} + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S new file mode 100644 index 0000000000..7af8d21683 --- /dev/null +++ b/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} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.c new file mode 100644 index 0000000000..796b179dd3 --- /dev/null +++ b/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 +} + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S new file mode 100644 index 0000000000..14d8542198 --- /dev/null +++ b/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} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.c new file mode 100644 index 0000000000..45e0afd0d1 --- /dev/null +++ b/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; +} + + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S new file mode 100644 index 0000000000..a36dbff8c3 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.c new file mode 100644 index 0000000000..88c88cec2d --- /dev/null +++ b/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 +#include "Llvm_int_lib.h" + + +// Returns: a * b + +static +INT64 +__muldsi3(UINT32 a, UINT32 b) +{ + dwords r; + const int bits_in_word_2 = (int)(sizeof(INT32) * CHAR_BIT) / 2; + const UINT32 lower_mask = (UINT32)~0 >> bits_in_word_2; + r.low = (a & lower_mask) * (b & lower_mask); + UINT32 t = r.low >> bits_in_word_2; + r.low &= lower_mask; + t += (a >> bits_in_word_2) * (b & lower_mask); + r.low += (t & lower_mask) << bits_in_word_2; + r.high = t >> bits_in_word_2; + t = r.low >> bits_in_word_2; + r.low &= lower_mask; + t += (b >> bits_in_word_2) * (a & lower_mask); + r.low += (t & lower_mask) << bits_in_word_2; + r.high += t >> bits_in_word_2; + r.high += (a >> bits_in_word_2) * (b >> bits_in_word_2); + return r.all; +} + +// Returns: a * b + +INT64 +__muldi3(INT64 a, INT64 b) +{ + dwords x; + x.all = a; + dwords y; + y.all = b; + dwords r; + r.all = __muldsi3(x.low, y.low); + r.high += x.high * y.low + x.low * y.high; + return r.all; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.asm new file mode 100644 index 0000000000..baf7caa006 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch.asm new file mode 100644 index 0000000000..2e26160363 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S new file mode 100644 index 0000000000..48e2ab74df --- /dev/null +++ b/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 + + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S new file mode 100644 index 0000000000..5ecffa6fee --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S new file mode 100644 index 0000000000..947156ee57 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S new file mode 100644 index 0000000000..e49204fdd4 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.c new file mode 100644 index 0000000000..0cf1404b32 --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S new file mode 100644 index 0000000000..fd7715da66 --- /dev/null +++ b/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} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.c new file mode 100644 index 0000000000..1a04ea7dd1 --- /dev/null +++ b/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); +} + + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S new file mode 100644 index 0000000000..1e54baec24 --- /dev/null +++ b/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} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.c new file mode 100644 index 0000000000..58f7554cc3 --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S new file mode 100644 index 0000000000..e5a0afa053 --- /dev/null +++ b/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} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.c new file mode 100644 index 0000000000..59d5b23643 --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm new file mode 100644 index 0000000000..a26ac762a4 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S new file mode 100644 index 0000000000..6396036c04 --- /dev/null +++ b/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} + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.c new file mode 100644 index 0000000000..73d796e499 --- /dev/null +++ b/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; +} + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S new file mode 100644 index 0000000000..4cde76beb5 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.c new file mode 100644 index 0000000000..09d4008e78 --- /dev/null +++ b/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; +} diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.asm new file mode 100644 index 0000000000..1d3d192821 --- /dev/null +++ b/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 diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm b/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.asm new file mode 100644 index 0000000000..d6a1e2fb00 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf new file mode 100644 index 0000000000..b1429737c7 --- /dev/null +++ b/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] + diff --git a/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c b/ArmPkg/Library/SemiHostingDebugLib/DebugLib.c new file mode 100644 index 0000000000..61e3aac3c2 --- /dev/null +++ b/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
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 +#include +#include +#include +#include +#include +#include + +// +// 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 (): \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 string of "(NULL) Filename" is printed. + + If Description is NULL, then a string of "(NULL) Description" is printed. + + @param FileName Pointer to the name of the source file that generated the assert condition. + @param LineNumber The line number in the source file that generated the assert condition + @param Description Pointer to the description of the assert condition. + +**/ +VOID +EFIAPI +DebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) +{ + CHAR8 AsciiBuffer[MAX_DEBUG_MESSAGE_LENGTH]; + + // + // Generate the ASSERT() message in Unicode format + // + AsciiSPrint (AsciiBuffer, sizeof (AsciiBuffer), "ASSERT %a(%d): %a\n", FileName, LineNumber, Description); + + SemihostWriteString (AsciiBuffer); + + // + // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings + // + if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { + CpuBreakpoint (); + } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { + CpuDeadLoop (); + } +} + + +/** + + Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. + + This function fills Length bytes of Buffer with the value specified by + PcdDebugClearMemoryValue, and returns Buffer. + + If Buffer is NULL, then ASSERT(). + + If Length is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param Buffer Pointer to the target buffer to fill with PcdDebugClearMemoryValue. + @param Length Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. + + @return Buffer + +**/ +VOID * +EFIAPI +DebugClearMemory ( + OUT VOID *Buffer, + IN UINTN Length + ) +{ + // + // If Buffer is NULL, then ASSERT(). + // + ASSERT (Buffer != NULL); + + // + // SetMem() checks for the the ASSERT() condition on Length and returns Buffer + // + return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue)); +} + + +/** + + Returns TRUE if ASSERT() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugAssertEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0); +} + + +/** + + Returns TRUE if DEBUG()macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugPrintEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0); +} + + +/** + + Returns TRUE if DEBUG_CODE()macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugCodeEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0); +} + + +/** + + Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugClearMemoryEnabled ( + VOID + ) +{ + return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0); +} diff --git a/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf b/ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf new file mode 100644 index 0000000000..683f03f2f3 --- /dev/null +++ b/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 + diff --git a/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf b/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf new file mode 100644 index 0000000000..c0a540342a --- /dev/null +++ b/ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf @@ -0,0 +1,35 @@ +#%HEADER% +#/** @file +# Semihosting serail port lib +# +# 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SemiHostingSerialPortLib + FILE_GUID = E9FB2D1E-05D9-421C-8C35-6100BB0093B7 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerialPortLib + + +[Sources.common] + SerialPortLib.c + + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + +[LibraryClasses] + SemihostLib diff --git a/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c b/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c new file mode 100644 index 0000000000..df43f31413 --- /dev/null +++ b/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c @@ -0,0 +1,144 @@ +/** @file + Serial I/O Port library functions with no library constructor/destructor + + Copyright (c) 2008-2009, Apple Inc. All rights reserved. + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 +#include +#include +#include + + +/* + + Programmed hardware of Serial port. + + @return Always return EFI_UNSUPPORTED. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + if (SemihostConnectionSupported ()) { + return RETURN_SUCCESS; + } else { + return RETURN_UNSUPPORTED; + } +} + +/** + Write data to serial device. + + @param Buffer Point of data buffer which need to be writed. + @param NumberOfBytes Number of output bytes which are cached in Buffer. + + @retval 0 Write data failed. + @retval !0 Actual number of bytes writed to serial device. + +**/ + +#define PRINT_BUFFER_SIZE 512 +#define PRINT_BUFFER_THRESHOLD (PRINT_BUFFER_SIZE - 4) + +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes +) +{ + UINT8 PrintBuffer[PRINT_BUFFER_SIZE]; + UINTN SourceIndex = 0; + UINTN DestinationIndex = 0; + UINT8 CurrentCharacter; + + while (SourceIndex < NumberOfBytes) + { + CurrentCharacter = Buffer[SourceIndex++]; + + switch (CurrentCharacter) + { + case '\r': + continue; + + case '\n': + PrintBuffer[DestinationIndex++] = ' '; + // fall through + + default: + PrintBuffer[DestinationIndex++] = CurrentCharacter; + break; + } + + if (DestinationIndex > PRINT_BUFFER_THRESHOLD) + { + PrintBuffer[DestinationIndex] = '\0'; + SemihostWriteString ((CHAR8 *) PrintBuffer); + + DestinationIndex = 0; + } + } + + if (DestinationIndex > 0) + { + PrintBuffer[DestinationIndex] = '\0'; + SemihostWriteString ((CHAR8 *) PrintBuffer); + } + + return 0; +} + + +/** + Read data from serial device and save the datas in buffer. + + @param Buffer Point of data buffer which need to be writed. + @param NumberOfBytes Number of output bytes which are cached in Buffer. + + @retval 0 Read data failed. + @retval !0 Aactual number of bytes read from serial device. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes +) +{ + *Buffer = SemihostReadCharacter (); + return 1; +} + + + +/** + Check to see if any data is avaiable to be read from the debug device. + + @retval TRUE At least one byte of data is avaiable to be read + @retval FALS No data is avaiable to be read + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + // Since SemiHosting read character is blocking always say we have a char ready? + return SemihostConnectionSupported (); +} + diff --git a/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c b/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c new file mode 100644 index 0000000000..e1a515ef21 --- /dev/null +++ b/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c @@ -0,0 +1,221 @@ +/** @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 + +#include +#include + +#include "SemihostPrivate.h" + +BOOLEAN +SemihostConnectionSupported ( + VOID + ) +{ + return SEMIHOST_SUPPORTED; +} + +EFI_STATUS +SemihostFileOpen ( + IN CHAR8 *FileName, + IN UINT32 Mode, + OUT UINT32 *FileHandle + ) +{ + SEMIHOST_FILE_OPEN_BLOCK OpenBlock; + INT32 Result; + + if (FileHandle == NULL) + return EFI_INVALID_PARAMETER; + + OpenBlock.FileName = FileName; + OpenBlock.Mode = Mode; + OpenBlock.NameLength = AsciiStrLen(FileName); + + Result = Semihost_SYS_OPEN(&OpenBlock); + + if (Result == -1) + { + return EFI_NOT_FOUND; + } + else + { + *FileHandle = Result; + return EFI_SUCCESS; + } +} + +EFI_STATUS +SemihostFileSeek ( + IN UINT32 FileHandle, + IN UINT32 Offset + ) +{ + SEMIHOST_FILE_SEEK_BLOCK SeekBlock; + INT32 Result; + + SeekBlock.Handle = FileHandle; + SeekBlock.Location = Offset; + + Result = Semihost_SYS_SEEK(&SeekBlock); + + if (Result == 0) + return EFI_SUCCESS; + else + return EFI_ABORTED; +} + +EFI_STATUS +SemihostFileRead ( + IN UINT32 FileHandle, + IN OUT UINT32 *Length, + OUT VOID *Buffer + ) +{ + SEMIHOST_FILE_READ_WRITE_BLOCK ReadBlock; + UINT32 Result; + + if ((Length == NULL) || (Buffer == NULL)) + return EFI_INVALID_PARAMETER; + + ReadBlock.Handle = FileHandle; + ReadBlock.Buffer = Buffer; + ReadBlock.Length = *Length; + + Result = Semihost_SYS_READ(&ReadBlock); + + if (Result == *Length) + { + return EFI_ABORTED; + } + else + { + *Length -= Result; + return EFI_SUCCESS; + } +} + +EFI_STATUS +SemihostFileWrite ( + IN UINT32 FileHandle, + IN OUT UINT32 *Length, + IN VOID *Buffer + ) +{ + SEMIHOST_FILE_READ_WRITE_BLOCK WriteBlock; + + if ((Length == NULL) || (Buffer == NULL)) + return EFI_INVALID_PARAMETER; + + WriteBlock.Handle = FileHandle; + WriteBlock.Buffer = Buffer; + WriteBlock.Length = *Length; + + *Length = Semihost_SYS_WRITE(&WriteBlock); + + return EFI_SUCCESS; +} + +EFI_STATUS +SemihostFileClose ( + IN UINT32 FileHandle + ) +{ + INT32 Result = Semihost_SYS_CLOSE(&FileHandle); + + if (Result == -1) + return EFI_INVALID_PARAMETER; + else + return EFI_SUCCESS; +} + +EFI_STATUS +SemihostFileLength ( + IN UINT32 FileHandle, + OUT UINT32 *Length + ) +{ + INT32 Result; + + if (Length == NULL) + return EFI_INVALID_PARAMETER; + + Result = Semihost_SYS_FLEN(&FileHandle); + + if (Result == -1) + { + return EFI_ABORTED; + } + else + { + *Length = Result; + return EFI_SUCCESS; + } +} + +EFI_STATUS +SemihostFileRemove ( + IN CHAR8 *FileName + ) +{ + SEMIHOST_FILE_REMOVE_BLOCK RemoveBlock; + UINT32 Result; + + RemoveBlock.FileName = FileName; + RemoveBlock.NameLength = AsciiStrLen(FileName); + + Result = Semihost_SYS_REMOVE(&RemoveBlock); + + if (Result == 0) + return EFI_SUCCESS; + else + return EFI_ABORTED; +} + +CHAR8 +SemihostReadCharacter ( + VOID + ) +{ + return Semihost_SYS_READC(); +} + +VOID +SemihostWriteCharacter ( + IN CHAR8 Character + ) +{ + Semihost_SYS_WRITEC(&Character); +} + +VOID +SemihostWriteString ( + IN CHAR8 *String + ) +{ + Semihost_SYS_WRITE0(String); +} + +UINT32 +SemihostSystem ( + IN CHAR8 *CommandLine + ) +{ + SEMIHOST_SYSTEM_BLOCK SystemBlock; + + SystemBlock.CommandLine = CommandLine; + SystemBlock.CommandLength = AsciiStrLen(CommandLine); + + return Semihost_SYS_SYSTEM(&SystemBlock); +} diff --git a/ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h b/ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h new file mode 100644 index 0000000000..e82111430a --- /dev/null +++ b/ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h @@ -0,0 +1,162 @@ +/** @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. + +**/ + +#ifndef __SEMIHOST_PRIVATE_H__ +#define __SEMIHOST_PRIVATE_H__ + +typedef struct { + CHAR8 *FileName; + UINT32 Mode; + UINT32 NameLength; +} SEMIHOST_FILE_OPEN_BLOCK; + +typedef struct { + UINT32 Handle; + VOID *Buffer; + UINT32 Length; +} SEMIHOST_FILE_READ_WRITE_BLOCK; + +typedef struct { + UINT32 Handle; + UINT32 Location; +} SEMIHOST_FILE_SEEK_BLOCK; + +typedef struct { + CHAR8 *FileName; + UINT32 NameLength; +} SEMIHOST_FILE_REMOVE_BLOCK; + +typedef struct { + CHAR8 *CommandLine; + UINT32 CommandLength; +} SEMIHOST_SYSTEM_BLOCK; + +#ifdef __CC_ARM + +#if defined(__thumb__) +#define SWI 0xAB +#else +#define SWI 0x123456 +#endif + +#define SEMIHOST_SUPPORTED TRUE + +__swi(SWI) +INT32 +_Semihost_SYS_OPEN( + IN UINTN SWI_0x01, + IN SEMIHOST_FILE_OPEN_BLOCK *OpenBlock + ); + +__swi(SWI) +INT32 +_Semihost_SYS_CLOSE( + IN UINTN SWI_0x02, + IN UINT32 *Handle + ); + +__swi(SWI) +VOID +_Semihost_SYS_WRITEC( + IN UINTN SWI_0x03, + IN CHAR8 *Character + ); + +__swi(SWI) +VOID +_Semihost_SYS_WRITE0( + IN UINTN SWI_0x04, + IN CHAR8 *String + ); + +__swi(SWI) +UINT32 +_Semihost_SYS_WRITE( + IN UINTN SWI_0x05, + IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *WriteBlock + ); + +__swi(SWI) +UINT32 +_Semihost_SYS_READ( + IN UINTN SWI_0x06, + IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *ReadBlock + ); + +__swi(SWI) +CHAR8 +_Semihost_SYS_READC( + IN UINTN SWI_0x07, + IN UINTN Zero + ); + +__swi(SWI) +INT32 +_Semihost_SYS_SEEK( + IN UINTN SWI_0x0A, + IN SEMIHOST_FILE_SEEK_BLOCK *SeekBlock + ); + +__swi(SWI) +INT32 +_Semihost_SYS_FLEN( + IN UINTN SWI_0x0C, + IN UINT32 *Handle + ); + +__swi(SWI) +UINT32 +_Semihost_SYS_REMOVE( + IN UINTN SWI_0x0E, + IN SEMIHOST_FILE_REMOVE_BLOCK *RemoveBlock + ); + +__swi(SWI) +UINT32 +_Semihost_SYS_SYSTEM( + IN UINTN SWI_0x12, + IN SEMIHOST_SYSTEM_BLOCK *SystemBlock + ); + +#define Semihost_SYS_OPEN(OpenBlock) _Semihost_SYS_OPEN(0x01, OpenBlock) +#define Semihost_SYS_CLOSE(Handle) _Semihost_SYS_CLOSE(0x02, Handle) +#define Semihost_SYS_WRITE0(String) _Semihost_SYS_WRITE0(0x04, String) +#define Semihost_SYS_WRITEC(Character) _Semihost_SYS_WRITEC(0x03, Character) +#define Semihost_SYS_WRITE(WriteBlock) _Semihost_SYS_WRITE(0x05, WriteBlock) +#define Semihost_SYS_READ(ReadBlock) _Semihost_SYS_READ(0x06, ReadBlock) +#define Semihost_SYS_READC() _Semihost_SYS_READC(0x07, 0) +#define Semihost_SYS_SEEK(SeekBlock) _Semihost_SYS_SEEK(0x0A, SeekBlock) +#define Semihost_SYS_FLEN(Handle) _Semihost_SYS_FLEN(0x0C, Handle) +#define Semihost_SYS_REMOVE(RemoveBlock) _Semihost_SYS_REMOVE(0x0E, RemoveBlock) +#define Semihost_SYS_SYSTEM(SystemBlock) _Semihost_SYS_SYSTEM(0x12, SystemBlock) + +#else // __CC_ARM + +#define SEMIHOST_SUPPORTED FALSE + +#define Semihost_SYS_OPEN(OpenBlock) (-1) +#define Semihost_SYS_CLOSE(Handle) (-1) +#define Semihost_SYS_WRITE0(String) +#define Semihost_SYS_WRITEC(Character) +#define Semihost_SYS_WRITE(WriteBlock) (0) +#define Semihost_SYS_READ(ReadBlock) ((ReadBlock)->Length) +#define Semihost_SYS_READC() ('x') +#define Semihost_SYS_SEEK(SeekBlock) (-1) +#define Semihost_SYS_FLEN(Handle) (-1) +#define Semihost_SYS_REMOVE(RemoveBlock) (-1) +#define Semihost_SYS_SYSTEM(SystemBlock) (-1) + +#endif // __CC_ARM + +#endif //__SEMIHOST_PRIVATE_H__ diff --git a/ArmPkg/Library/SemihostLib/SemihostLib.inf b/ArmPkg/Library/SemihostLib/SemihostLib.inf new file mode 100644 index 0000000000..cb278083c0 --- /dev/null +++ b/ArmPkg/Library/SemihostLib/SemihostLib.inf @@ -0,0 +1,32 @@ +#%HEADER% +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SemihostLib + FILE_GUID = C40D08BA-DB7B-4F07-905A-C5FE4B5AF987 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SemihostLib + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = ARM +# +[Sources.ARM] + Arm/SemihostLib.c + + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + +[LibraryClasses] + BaseLib + +[Protocols] + +[Guids] + +[Pcd] + \ No newline at end of file diff --git a/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c b/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c new file mode 100644 index 0000000000..060ba6bf98 --- /dev/null +++ b/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c @@ -0,0 +1,626 @@ +/** @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 +#include +#include +#include +#include +#include +#include + +EFI_PHYSICAL_ADDRESS +ConvertToPhysicalAddress ( + IN VOID *VirtualAddress + ) +{ + UINTN UncachedMemoryMask = (UINTN)PcdGet64(PcdArmUncachedMemoryMask); + UINTN PhysicalAddress; + + PhysicalAddress = (UINTN)VirtualAddress & ~UncachedMemoryMask; + + return (EFI_PHYSICAL_ADDRESS)PhysicalAddress; +} + +VOID * +ConvertToCachedAddress ( + IN VOID *Address + ) +{ + return (VOID *)(UINTN)ConvertToPhysicalAddress(Address); +} + +VOID * +ConvertToUncachedAddress ( + IN VOID *Address + ) +{ + UINTN UncachedMemoryMask = (UINTN)PcdGet64(PcdArmUncachedMemoryMask); + UINTN UncachedAddress; + + UncachedAddress = (UINTN)Address | UncachedMemoryMask; + + return (VOID *)UncachedAddress; +} + +VOID +FlushCache ( + IN EFI_PHYSICAL_ADDRESS Address, + IN UINTN Size + ) +{ + EFI_CPU_ARCH_PROTOCOL *Cpu; + EFI_STATUS Status; + + Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); + ASSERT_EFI_ERROR(Status); + + Status = Cpu->FlushDataCache(Cpu, Address, Size, EfiCpuFlushTypeWriteBackInvalidate); + ASSERT_EFI_ERROR(Status); +} + +VOID * +UncachedInternalAllocatePages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + + if (Pages == 0) { + return NULL; + } + + Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); + if (EFI_ERROR (Status)) { + Memory = 0; + } + + if (Memory != 0) { + FlushCache(Memory, EFI_PAGES_TO_SIZE(Pages)); + Memory = (EFI_PHYSICAL_ADDRESS)(UINTN)ConvertToUncachedAddress((VOID *)(UINTN)Memory); + } + + return (VOID *) (UINTN) Memory; +} + +VOID * +EFIAPI +UncachedAllocatePages ( + IN UINTN Pages + ) +{ + return UncachedInternalAllocatePages (EfiBootServicesData, Pages); +} + +VOID * +EFIAPI +UncachedAllocateRuntimePages ( + IN UINTN Pages + ) +{ + return UncachedInternalAllocatePages (EfiRuntimeServicesData, Pages); +} + +VOID * +EFIAPI +UncachedAllocateReservedPages ( + IN UINTN Pages + ) +{ + return UncachedInternalAllocatePages (EfiReservedMemoryType, Pages); +} + +VOID +EFIAPI +UncachedFreePages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + + ASSERT (Pages != 0); + + Buffer = ConvertToCachedAddress(Buffer); + + Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages); + ASSERT_EFI_ERROR (Status); +} + +VOID * +UncachedInternalAllocateAlignedPages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + UINTN AlignedMemory; + UINTN AlignmentMask; + UINTN UnalignedPages; + UINTN RealPages; + + // + // Alignment must be a power of two or zero. + // + ASSERT ((Alignment & (Alignment - 1)) == 0); + + if (Pages == 0) { + return NULL; + } + if (Alignment > EFI_PAGE_SIZE) { + // + // Caculate the total number of pages since alignment is larger than page size. + // + AlignmentMask = Alignment - 1; + RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); + // + // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. + // + ASSERT (RealPages > Pages); + + Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; + UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory); + if (UnalignedPages > 0) { + // + // Free first unaligned page(s). + // + Status = gBS->FreePages (Memory, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); + UnalignedPages = RealPages - Pages - UnalignedPages; + if (UnalignedPages > 0) { + // + // Free last unaligned page(s). + // + Status = gBS->FreePages (Memory, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + } else { + // + // Do not over-allocate pages in this case. + // + Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + AlignedMemory = (UINTN) Memory; + } + + if (AlignedMemory != 0) { + FlushCache(AlignedMemory, EFI_PAGES_TO_SIZE(Pages)); + AlignedMemory = (UINTN)ConvertToUncachedAddress((VOID *)AlignedMemory); + } + + return (VOID *) AlignedMemory; +} + +VOID * +EFIAPI +UncachedAllocateAlignedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedRuntimePages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedReservedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); +} + +VOID +EFIAPI +UncachedFreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + + ASSERT (Pages != 0); + + Buffer = ConvertToCachedAddress(Buffer); + + Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages); + ASSERT_EFI_ERROR (Status); +} + +VOID * +UncachedInternalAllocateAlignedPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + VOID *RawAddress; + UINTN AlignedAddress; + UINTN AlignmentMask; + UINTN OverAllocationSize; + UINTN RealAllocationSize; + VOID **FreePointer; + UINTN DataCacheLineLength; + EFI_STATUS Status; + + // + // Alignment must be a power of two or zero. + // + ASSERT ((Alignment & (Alignment - 1)) == 0); + + DataCacheLineLength = ArmDataCacheLineLength(); + + // Alignment must be at least cache-line aligned + if (Alignment < DataCacheLineLength) { + Alignment = DataCacheLineLength; + } + + if (Alignment == 0) { + AlignmentMask = Alignment; + } else { + AlignmentMask = Alignment - 1; + } + + // + // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address. + // + OverAllocationSize = sizeof (RawAddress) + AlignmentMask; + RealAllocationSize = AllocationSize + OverAllocationSize; + // + // Make sure that AllocationSize plus OverAllocationSize does not overflow. + // + ASSERT (RealAllocationSize > AllocationSize); + + Status = gBS->AllocatePool (PoolType, RealAllocationSize, &RawAddress); + if (EFI_ERROR (Status)) { + return NULL; + } + + AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask; + // + // Save the original memory address just before the aligned address. + // + FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress)); + *FreePointer = RawAddress; + + if (AlignedAddress != 0) { + FlushCache(AlignedAddress, AllocationSize); + AlignedAddress = (UINTN)ConvertToUncachedAddress((VOID *)AlignedAddress); + } + + return (VOID *) AlignedAddress; +} + +VOID * +EFIAPI +UncachedAllocateAlignedPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedRuntimePool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedReservedPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment); +} + +VOID * +UncachedInternalAllocateAlignedZeroPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + VOID *Memory; + Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment); + if (Memory != NULL) { + Memory = ZeroMem (Memory, AllocationSize); + } + return Memory; +} + +VOID * +EFIAPI +UncachedAllocateAlignedZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedRuntimeZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedReservedZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment); +} + +VOID * +UncachedInternalAllocateAlignedCopyPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ) +{ + VOID *Memory; + + ASSERT (Buffer != NULL); + ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1)); + + Memory = UncachedInternalAllocateAlignedPool (PoolType, AllocationSize, Alignment); + if (Memory != NULL) { + Memory = CopyMem (Memory, Buffer, AllocationSize); + } + return Memory; +} + +VOID * +EFIAPI +UncachedAllocateAlignedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment); +} + +VOID * +EFIAPI +UncachedAllocateAlignedReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ) +{ + return UncachedInternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment); +} + +VOID +EFIAPI +UncachedFreeAlignedPool ( + IN VOID *Buffer + ) +{ + VOID *RawAddress; + VOID **FreePointer; + EFI_STATUS Status; + + Buffer = ConvertToCachedAddress(Buffer); + + // + // Get the pre-saved original address in the over-allocate pool. + // + FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress)); + RawAddress = *FreePointer; + + Status = gBS->FreePool (RawAddress); + ASSERT_EFI_ERROR (Status); +} + +VOID * +UncachedInternalAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize + ) +{ + UINTN CacheLineLength = ArmDataCacheLineLength(); + return UncachedInternalAllocateAlignedPool(MemoryType, AllocationSize, CacheLineLength); +} + +VOID * +EFIAPI +UncachedAllocatePool ( + IN UINTN AllocationSize + ) +{ + return UncachedInternalAllocatePool (EfiBootServicesData, AllocationSize); +} + +VOID * +EFIAPI +UncachedAllocateRuntimePool ( + IN UINTN AllocationSize + ) +{ + return UncachedInternalAllocatePool (EfiRuntimeServicesData, AllocationSize); +} + +VOID * +EFIAPI +UncachedAllocateReservedPool ( + IN UINTN AllocationSize + ) +{ + return UncachedInternalAllocatePool (EfiReservedMemoryType, AllocationSize); +} + +VOID * +UncachedInternalAllocateZeroPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize + ) +{ + VOID *Memory; + + Memory = UncachedInternalAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = ZeroMem (Memory, AllocationSize); + } + return Memory; +} + +VOID * +EFIAPI +UncachedAllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + return UncachedInternalAllocateZeroPool (EfiBootServicesData, AllocationSize); +} + +VOID * +EFIAPI +UncachedAllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ) +{ + return UncachedInternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); +} + +VOID * +EFIAPI +UncachedAllocateReservedZeroPool ( + IN UINTN AllocationSize + ) +{ + return UncachedInternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); +} + +VOID * +UncachedInternalAllocateCopyPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *Memory; + + ASSERT (Buffer != NULL); + ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1)); + + Memory = UncachedInternalAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = CopyMem (Memory, Buffer, AllocationSize); + } + return Memory; +} + +VOID * +EFIAPI +UncachedAllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return UncachedInternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); +} + +VOID * +EFIAPI +UncachedAllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return UncachedInternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); +} + +VOID * +EFIAPI +UncachedAllocateReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return UncachedInternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); +} + +VOID +EFIAPI +UncachedFreePool ( + IN VOID *Buffer + ) +{ + UncachedFreeAlignedPool(Buffer); +} + +VOID +EFIAPI +UncachedSafeFreePool ( + IN VOID *Buffer + ) +{ + if (Buffer != NULL) { + UncachedFreePool (Buffer); + Buffer = NULL; + } +} + diff --git a/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf b/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf new file mode 100644 index 0000000000..1a62eb4231 --- /dev/null +++ b/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf @@ -0,0 +1,25 @@ +#%HEADER% +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UncachedMemoryAllocationLib + FILE_GUID = DC101A1A-7525-429B-84AF-EEAA630E576C + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = UncachedMemoryAllocationLib + +[Sources.common] + UncachedMemoryAllocationLib.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + +[Protocols] + gEfiCpuArchProtocolGuid + +[LibraryClasses] + ArmLib + +[FixedPcd] + gArmTokenSpaceGuid.PcdArmUncachedMemoryMask + \ No newline at end of file -- cgit v1.2.3