diff options
author | AJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-12-06 01:57:05 +0000 |
---|---|---|
committer | AJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-12-06 01:57:05 +0000 |
commit | 2ef2b01e07c02db339f34004445734a2dbdd80e1 (patch) | |
tree | 19532a6be8d8bdb0aef04bd00c1efb582f6dc841 /ArmPkg | |
parent | f7753a96ba1653ddd31b01c198a352f6332ac404 (diff) | |
download | edk2-platforms-2ef2b01e07c02db339f34004445734a2dbdd80e1.tar.xz |
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
Diffstat (limited to 'ArmPkg')
107 files changed, 11280 insertions, 0 deletions
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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __CPU_DXE_ARM_EXCEPTION_H__
+#define __CPU_DXE_ARM_EXCEPTION_H__
+
+#include <Uefi.h>
+
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/DebugSupport.h>
+#include <Protocol/DebugSupportPeriodicCallback.h>
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterDebuggerInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+
+EFI_STATUS
+InitializeExceptions (
+ IN EFI_CPU_ARCH_PROTOCOL *Cpu
+ );
+
+#endif // __CPU_DXE_ARM_EXCEPTION_H__
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. <BR>
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmCpuDxe
+ FILE_GUID = B8D9777E-D72A-451F-9BDB-BAFB52A68415
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = CpuDxeInitialize
+
+[Sources.ARM]
+ CpuDxe.c
+ CpuDxe.h
+ DebugSupport.c
+ Exception.c
+ ExceptionSupport.asm | RVCT
+ ExceptionSupport.S | GCC
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ CacheMaintenanceLib
+ UefiDriverEntryPoint
+ ArmLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid
+ gEfiDebugSupportPeriodicCallbackProtocolGuid
+
+[Pcd.common]
+ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
+
+[FeaturePcd.common]
+ gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport
+
+[depex]
+ gHardwareInterruptProtocolGuid
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 <Library/CacheMaintenanceLib.h>
+
+VOID
+ExceptionHandlersStart (
+ VOID
+ );
+
+VOID
+ExceptionHandlersEnd (
+ VOID
+ );
+
+VOID
+CommonExceptionEntry (
+ VOID
+ );
+
+VOID
+AsmCommonExceptionEntry (
+ VOID
+ );
+
+
+EFI_EXCEPTION_CALLBACK gExceptionHandlers[MAX_ARM_EXCEPTION + 1];
+EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_ARM_EXCEPTION + 1];
+
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ if (InterruptType > MAX_ARM_EXCEPTION) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ gExceptionHandlers[InterruptType] = InterruptHandler;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
+ are enabled and FALSE if interrupts are disabled.
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
+
+**/
+EFI_STATUS
+RegisterDebuggerInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ if (InterruptType > MAX_ARM_EXCEPTION) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((InterruptHandler != NULL) && (gDebuggerExceptionHandlers[InterruptType] != NULL)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ gDebuggerExceptionHandlers[InterruptType] = InterruptHandler;
+
+ return EFI_SUCCESS;
+}
+
+
+
+VOID
+EFIAPI
+CommonCExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ BOOLEAN Dispatched = FALSE;
+
+ if (ExceptionType <= MAX_ARM_EXCEPTION) {
+ if (gDebuggerExceptionHandlers[ExceptionType]) {
+ //
+ // If DebugSupport hooked the interrupt call the handler. This does not disable
+ // the normal handler.
+ //
+ gDebuggerExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);
+ Dispatched = TRUE;
+ }
+ if (gExceptionHandlers[ExceptionType]) {
+ gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);
+ Dispatched = TRUE;
+ }
+ }
+
+ if (Dispatched) {
+ //
+ // We did work so this was an expected ExceptionType
+ //
+ return;
+ }
+
+ if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {
+ //
+ // ARM JTAG debuggers some times use this vector, so it is not an error to get one
+ //
+ return;
+ }
+
+ //
+ // Code after here is the default exception handler...
+ //
+ DEBUG ((EFI_D_ERROR, "Exception %d from %08x\n", ExceptionType, SystemContext.SystemContextArm->PC));
+ ASSERT (FALSE);
+
+}
+
+
+
+EFI_STATUS
+InitializeExceptions (
+ IN EFI_CPU_ARCH_PROTOCOL *Cpu
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINTN Length;
+ UINTN Index;
+ BOOLEAN Enabled;
+ EFI_PHYSICAL_ADDRESS Base;
+
+ //
+ // Disable interrupts
+ //
+ Cpu->GetInterruptState (Cpu, &Enabled);
+ Cpu->DisableInterrupt (Cpu);
+
+ //
+ // Initialize the C entry points for interrupts
+ //
+ for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {
+ Status = RegisterInterruptHandler (Index, NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = RegisterDebuggerInterruptHandler (Index, NULL);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Copy an implementation of the ARM exception vectors to 0x0.
+ //
+ Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
+
+ //
+ // Reserve space for the exception handlers
+ //
+ Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);
+ Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);
+ // If the request was for memory that's not in the memory map (which is often the case for 0x00000000
+ // on embedded systems, for example, we don't want to hang up. So we'll check here for a status of
+ // EFI_NOT_FOUND, and continue in that case.
+ if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ CopyMem ((VOID *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress), (VOID *)ExceptionHandlersStart, Length);
+
+ //
+ // Patch in the common Assembly exception handler
+ //
+ Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;
+ *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;
+
+ // Flush Caches since we updated executable stuff
+ InvalidateInstructionCacheRange((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);
+
+ if (Enabled) {
+ //
+ // Restore interrupt state
+ //
+ Status = Cpu->EnableInterrupt (Cpu);
+ }
+
+ return Status;
+}
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 <Uefi.h>
+
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/DebugSupport.h>
+#include <Protocol/TimerDebugSupport.h>
+
+EFI_STATUS
+EFIAPI
+DebugSupportGetMaximumProcessorIndex (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ OUT UINTN *MaxProcessorIndex
+ )
+{
+ if (MaxProcessorIndex == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *MaxProcessorIndex = 0;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DebugSupportRegisterPeriodicCallback (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ IN EFI_PERIODIC_CALLBACK PeriodicCallback
+ )
+{
+ TIMER_DEBUG_SUPPORT_PROTOCOL *Timer;
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol(&gTimerDebugSupportProtocolGuid, NULL, (VOID **)&Timer);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Timer->RegisterPeriodicCallback(Timer, PeriodicCallback);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DebugSupportRegisterExceptionCallback (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ IN EFI_EXCEPTION_CALLBACK ExceptionCallback,
+ IN EFI_EXCEPTION_TYPE ExceptionType
+ )
+{
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Cpu->RegisterInterruptHandler(Cpu, ExceptionType, (EFI_CPU_INTERRUPT_HANDLER)ExceptionCallback);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+DebugSupportInvalidateInstructionCache (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ IN VOID *Start,
+ IN UINT64 Length
+ )
+{
+ InvalidateInstructionCacheRange(Start, Length);
+ return EFI_SUCCESS;
+}
+
+EFI_DEBUG_SUPPORT_PROTOCOL mDebugSupport = {
+ IsaArm,
+ DebugSupportGetMaximumProcessorIndex,
+ DebugSupportRegisterPeriodicCallback,
+ DebugSupportRegisterExceptionCallback,
+ DebugSupportInvalidateInstructionCache
+};
+
+EFI_STATUS
+DebugSupportDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiDebugSupportProtocolGuid);
+ Status = gBS->InstallMultipleProtocolInterfaces(&Handle, &gEfiDebugSupportProtocolGuid, &mDebugSupport, NULL);
+
+ return Status;
+}
+
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 <Uefi.h>
+
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SemihostLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include "SemihostFs.h"
+
+
+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
+ VolumeOpen
+};
+
+EFI_FILE gSemihostFsFile = {
+ EFI_FILE_PROTOCOL_REVISION,
+ FileOpen,
+ FileClose,
+ FileDelete,
+ FileRead,
+ FileWrite,
+ FileGetPosition,
+ FileSetPosition,
+ FileGetInfo,
+ FileSetInfo,
+ FileFlush
+};
+
+//
+// Device path for SemiHosting. It contains our autogened Caller ID GUID.
+//
+typedef struct {
+ VENDOR_DEVICE_PATH Guid;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} SEMIHOST_DEVICE_PATH;
+
+SEMIHOST_DEVICE_PATH gDevicePath = {
+ {
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0 },
+ EFI_CALLER_ID_GUID
+ },
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
+};
+
+typedef struct {
+ LIST_ENTRY Link;
+ UINT64 Signature;
+ EFI_FILE File;
+ CHAR8 *FileName;
+ UINT32 Position;
+ UINT32 SemihostHandle;
+ BOOLEAN IsRoot;
+} SEMIHOST_FCB;
+
+#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
+#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE)
+#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE);
+
+EFI_HANDLE gInstallHandle = NULL;
+LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList);
+
+SEMIHOST_FCB *
+AllocateFCB (
+ VOID
+ )
+{
+ SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
+
+ if (Fcb != NULL) {
+ CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));
+ Fcb->Signature = SEMIHOST_FCB_SIGNATURE;
+ }
+
+ return Fcb;
+}
+
+VOID
+FreeFCB (
+ IN SEMIHOST_FCB *Fcb
+ )
+{
+ // Remove Fcb from gFileList.
+ RemoveEntryList (&Fcb->Link);
+
+ // To help debugging...
+ Fcb->Signature = 0;
+
+ FreePool (Fcb);
+}
+
+
+
+EFI_STATUS
+VolumeOpen (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE **Root
+ )
+{
+ SEMIHOST_FCB *RootFcb = NULL;
+
+ if (Root == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RootFcb = AllocateFCB ();
+ if (RootFcb == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RootFcb->IsRoot = TRUE;
+
+ InsertTailList (&gFileList, &RootFcb->Link);
+
+ *Root = &RootFcb->File;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FileOpen (
+ IN EFI_FILE *File,
+ OUT EFI_FILE **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ SEMIHOST_FCB *FileFcb = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 SemihostHandle;
+ CHAR8 *AsciiFileName;
+ CHAR8 *AsciiPtr;
+ UINTN Length;
+ UINT32 SemihostMode;
+ BOOLEAN IsRoot;
+
+ if ((FileName == NULL) || (NewHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Semihost interface requires ASCII filesnames
+ Length = StrSize (FileName);
+
+ AsciiFileName = AllocatePool (Length);
+ if (AsciiFileName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AsciiPtr = AsciiFileName;
+
+ while (Length--) {
+ *AsciiPtr++ = *FileName++ & 0xFF;
+ }
+
+ if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0)) {
+ // Opening '/', '\', or the NULL pathname is trying to open the root directory
+ IsRoot = TRUE;
+
+ // Root directory node doesn't have a name.
+ FreePool (AsciiFileName);
+ AsciiFileName = NULL;
+ } else {
+ // Translate EFI_FILE_MODE into Semihosting mode
+ if (OpenMode & EFI_FILE_MODE_WRITE) {
+ SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY;
+ } else if (OpenMode & EFI_FILE_MODE_READ) {
+ SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Add the creation flag if necessary
+ if (OpenMode & EFI_FILE_MODE_CREATE) {
+ SemihostMode |= SEMIHOST_FILE_MODE_CREATE;
+ }
+
+ // Call the semihosting interface to open the file.
+ Status = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ IsRoot = FALSE;
+ }
+
+ // Allocate a control block and fill it
+ FileFcb = AllocateFCB ();
+ if (FileFcb == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FileFcb->FileName = AsciiFileName;
+ FileFcb->SemihostHandle = SemihostHandle;
+ FileFcb->Position = 0;
+ FileFcb->IsRoot = IsRoot;
+
+ InsertTailList (&gFileList, &FileFcb->Link);
+
+ *NewHandle = &FileFcb->File;
+
+ return Status;
+}
+
+
+EFI_STATUS
+FileClose (
+ IN EFI_FILE *File
+ )
+{
+ SEMIHOST_FCB *Fcb = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ if (Fcb->IsRoot == TRUE) {
+ FreeFCB (Fcb);
+ Status = EFI_SUCCESS;
+ } else {
+ Status = SemihostFileClose (Fcb->SemihostHandle);
+ if (!EFI_ERROR(Status)) {
+ FreePool (Fcb->FileName);
+ FreeFCB (Fcb);
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+FileDelete (
+ IN EFI_FILE *File
+ )
+{
+ SEMIHOST_FCB *Fcb = NULL;
+ EFI_STATUS Status;
+ CHAR8 *FileName;
+ UINTN NameSize;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ // Get the filename from the Fcb
+ NameSize = AsciiStrLen (Fcb->FileName);
+ FileName = AllocatePool (NameSize + 1);
+
+ AsciiStrCpy (FileName, Fcb->FileName);
+
+ // Close the file if it's open. Disregard return status,
+ // since it might give an error if the file isn't open.
+ File->Close (File);
+
+ // Call the semihost interface to delete the file.
+ Status = SemihostFileRemove (FileName);
+
+ return Status;
+}
+
+EFI_STATUS
+FileRead (
+ IN EFI_FILE *File,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ SEMIHOST_FCB *Fcb = NULL;
+ EFI_STATUS Status;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ if (Fcb->IsRoot == TRUE) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = SemihostFileRead (Fcb->SemihostHandle, BufferSize, Buffer);
+ if (!EFI_ERROR (Status)) {
+ Fcb->Position += *BufferSize;
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+FileWrite (
+ IN EFI_FILE *File,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ SEMIHOST_FCB *Fcb = NULL;
+ EFI_STATUS Status;
+ UINTN WriteSize = *BufferSize;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
+
+ if (!EFI_ERROR(Status)) {
+ // Semihost write return the number of bytes *NOT* written.
+ *BufferSize -= WriteSize;
+ Fcb->Position += *BufferSize;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+FileGetPosition (
+ IN EFI_FILE *File,
+ OUT UINT64 *Position
+ )
+{
+ SEMIHOST_FCB *Fcb = NULL;
+
+ if (Position == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ *Position = Fcb->Position;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FileSetPosition (
+ IN EFI_FILE *File,
+ IN UINT64 Position
+ )
+{
+ SEMIHOST_FCB *Fcb = NULL;
+ UINT32 Length;
+ EFI_STATUS Status;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ Status = SemihostFileLength (Fcb->SemihostHandle, &Length);
+ if (!EFI_ERROR(Status) && (Length < Position)) {
+ Position = Length;
+ }
+
+ Status = SemihostFileSeek (Fcb->SemihostHandle, (UINT32)Position);
+ if (!EFI_ERROR(Status)) {
+ Fcb->Position = Position;
+ }
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+GetFileInfo (
+ IN SEMIHOST_FCB *Fcb,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_FILE_INFO *Info = NULL;
+ UINTN NameSize = 0;
+ UINTN ResultSize;
+ UINTN Index;
+ UINT32 Length;
+ EFI_STATUS Status;
+
+ if (Fcb->IsRoot == TRUE) {
+ ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
+ } else {
+ NameSize = AsciiStrLen (Fcb->FileName) + 1;
+ ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16);
+ }
+
+ if (*BufferSize < ResultSize) {
+ *BufferSize = ResultSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Info = Buffer;
+
+ // Zero out the structure
+ ZeroMem (Info, SIZE_OF_EFI_FILE_INFO);
+
+ // Fill in the structure
+ Info->Size = ResultSize;
+
+ if (Fcb->IsRoot == TRUE) {
+ Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
+ Info->FileName[0] = L'\0';
+ } else {
+ Status = SemihostFileLength (Fcb->SemihostHandle, &Length);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Info->FileSize = Length;
+ Info->PhysicalSize = Length;
+
+ for (Index = 0; Index < NameSize; Index++) {
+ Info->FileName[Index] = Fcb->FileName[Index];
+ }
+ }
+
+
+ *BufferSize = ResultSize;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetFilesystemInfo (
+ IN SEMIHOST_FCB *Fcb,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_FILE_SYSTEM_INFO *Info = NULL;
+ EFI_STATUS Status;
+ STATIC CHAR16 Label[] = L"SemihostFs";
+ UINTN ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(Label);
+
+ if(*BufferSize >= ResultSize) {
+ ZeroMem (Buffer, ResultSize);
+ Status = EFI_SUCCESS;
+
+ Info = Buffer;
+
+ Info->Size = ResultSize;
+ Info->ReadOnly = FALSE;
+ Info->VolumeSize = 0;
+ Info->FreeSpace = 0;
+ Info->BlockSize = 0;
+
+ StrCpy (Info->VolumeLabel, Label);
+ } else {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = ResultSize;
+ return Status;
+}
+
+EFI_STATUS
+FileGetInfo (
+ IN EFI_FILE *File,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ SEMIHOST_FCB *Fcb = NULL;
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+ Fcb = SEMIHOST_FCB_FROM_THIS(File);
+
+ if (CompareGuid(InformationType, &gEfiFileSystemInfoGuid) != 0) {
+ Status = GetFilesystemInfo(Fcb, BufferSize, Buffer);
+ } else if (CompareGuid(InformationType, &gEfiFileInfoGuid) != 0) {
+ Status = GetFileInfo(Fcb, BufferSize, Buffer);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+FileSetInfo (
+ IN EFI_FILE *File,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+FileFlush (
+ IN EFI_FILE *File
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SemihostFsEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+
+ if (SemihostConnectionSupported ()) {
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gInstallHandle,
+ &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,
+ &gEfiDevicePathProtocolGuid, &gDevicePath,
+ NULL
+ );
+ }
+
+ return Status;
+}
+
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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SEMIHOST_FS_H__
+#define __SEMIHOST_FS_H__
+
+EFI_STATUS
+SemihostFsSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+SemihostFsStart(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+SemihostFsStop(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+EFI_STATUS
+VolumeOpen(
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE **Root
+ );
+
+EFI_STATUS
+FileOpen(
+ IN EFI_FILE *File,
+ OUT EFI_FILE **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ );
+
+EFI_STATUS
+FileClose(
+ IN EFI_FILE *File
+ );
+
+EFI_STATUS
+FileDelete(
+ IN EFI_FILE *File
+ );
+
+EFI_STATUS
+FileRead(
+ IN EFI_FILE *File,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+FileWrite(
+ IN EFI_FILE *File,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+EFI_STATUS
+FileGetPosition(
+ IN EFI_FILE *File,
+ OUT UINT64 *Position
+ );
+
+EFI_STATUS
+FileSetPosition(
+ IN EFI_FILE *File,
+ IN UINT64 Position
+ );
+
+EFI_STATUS
+FileGetInfo(
+ IN EFI_FILE *File,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+FileSetInfo(
+ IN EFI_FILE *File,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+EFI_STATUS
+FileFlush(
+ IN EFI_FILE *File
+ );
+
+#endif // __SEMIHOST_FS_H__
+
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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __MACRO_IO_LIB_H__
+#define __MACRO_IO_LIB_H__
+
+#if defined(__APPLE__)
+
+//
+// ldr reg, =expr does not work with current Apple tool chain. So do the work our selves
+//
+
+// returns _Data in R0 and _Address in R1
+#define MmioWrite32(_Address, _Data) \
+ ldr r1, [pc, #8] ; \
+ ldr r0, [pc, #8] ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_Data) ; \
+1:
+
+// returns _Data in R0 and _Address in R1, and _OrData in r2
+#define MmioOr32(_Address, _OrData) \
+ ldr r1, [pc, #16] ; \
+ ldr r2, [pc, #16] ; \
+ ldr r0, [r1] ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_OrData) ; \
+1:
+
+// returns _Data in R0 and _Address in R1, and _OrData in r2
+#define MmioAnd32(_Address, _AndData) \
+ ldr r1, [pc, #16] ; \
+ ldr r2, [pc, #16] ; \
+ ldr r0, [r1] ; \
+ and r0, r0, r2 ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_AndData) ; \
+1:
+
+// returns result in R0, _Address in R1, and _OrData in r2
+#define MmioAndThenOr32(_Address, _AndData, _OrData) \
+ ldr r1, [pc, #24] ; \
+ ldr r0, [r1] ; \
+ ldr r2, [pc, #20] ; \
+ and r0, r0, r2 ; \
+ ldr r2, [pc, #16] ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+ .long (_AndData) ; \
+ .long (_OrData) ; \
+1:
+
+// returns _Data in _Reg and _Address in R1
+#define MmioWriteFromReg32(_Address, _Reg) \
+ ldr r1, [pc, #4] ; \
+ str _Reg, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+1:
+
+
+// returns _Data in R0 and _Address in R1
+#define MmioRead32(_Address) \
+ ldr r1, [pc, #4] ; \
+ ldr r0, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+1:
+
+// returns _Data in Reg and _Address in R1
+#define MmioReadToReg32(_Address, _Reg) \
+ ldr r1, [pc, #4] ; \
+ ldr _Reg, [r1] ; \
+ b 1f ; \
+ .long (_Address) ; \
+1:
+
+
+// load R0 with _Data
+#define LoadConstant(_Data) \
+ ldr r0, [pc, #0] ; \
+ b 1f ; \
+ .long (_Data) ; \
+1:
+
+// load _Reg with _Data
+#define LoadConstantToReg(_Data, _Reg) \
+ ldr _Reg, [pc, #0] ; \
+ b 1f ; \
+ .long (_Data) ; \
+1:
+
+// load _Reg with _Data if eq
+#define LoadConstantToRegIfEq(_Data, _Reg) \
+ ldreq _Reg, [pc, #0] ; \
+ b 1f ; \
+ .long (_Data) ; \
+1:
+
+
+#elif defined (__GNUC__)
+
+#define MmioWrite32(Address, Data) \
+ ldr r1, =Address ; \
+ ldr r0, =Data ; \
+ str r0, [r1]
+
+#define MmioOr32(Address, OrData) \
+ ldr r1, =Address ; \
+ ldr r2, =OrData ; \
+ ldr r0, [r1] ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1]
+
+#define MmioAnd32(Address, AndData) \
+ ldr r1, =Address ; \
+ ldr r2, =AndData ; \
+ ldr r0, [r1] ; \
+ and r0, r0, r2 ; \
+ str r0, [r1]
+
+#define MmioAndThenOr32(Address, AndData, OrData) \
+ ldr r1, =Address ; \
+ ldr r0, [r1] ; \
+ ldr r2, =AndData ; \
+ and r0, r0, r2 ; \
+ ldr r2, =OrData ; \
+ orr r0, r0, r2 ; \
+ str r0, [r1]
+
+#define MmioWriteFromReg32(Address, Reg) \
+ ldr r1, =Address ; \
+ str Reg, [r1]
+
+#define MmioRead32(Address) \
+ ldr r1, =Address ; \
+ ldr r0, [r1]
+
+#define MmioReadToReg32(Address, Reg) \
+ ldr r1, =Address ; \
+ ldr Reg, [r1]
+
+#define LoadConstant(Data) \
+ ldr r0, =Data
+
+#define LoadConstantToReg(Data, Reg) \
+ ldr Reg, =Data
+
+#else
+
+//
+// Use ARM assembly macros, form armasam
+//
+// Less magic in the macros if ldr reg, =expr works
+//
+
+// returns _Data in R0 and _Address in R1
+
+
+
+#define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data
+
+
+
+
+// returns Data in R0 and Address in R1, and OrData in r2
+#define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData
+
+
+// returns _Data in R0 and _Address in R1, and _OrData in r2
+
+
+#define MmioAnd32(Address, AndData) MmioAnd32Macro Address, AndData
+
+// returns result in R0, _Address in R1, and _OrData in r2
+
+
+#define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData
+
+
+// returns _Data in _Reg and _Address in R1
+
+
+#define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg
+
+// returns _Data in R0 and _Address in R1
+
+
+#define MmioRead32(Address) MmioRead32Macro Address
+
+// returns _Data in Reg and _Address in R1
+
+
+#define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg
+
+
+// load R0 with _Data
+
+
+#define LoadConstant(Data) LoadConstantMacro Data
+
+// load _Reg with _Data
+
+
+#define LoadConstantToReg(Data, Reg) LoadConstantToRegMacro Data, Reg
+
+// conditional load testing eq flag
+#define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg
+
+
+#endif
+
+
+#endif
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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARM1176JZ_S_H__
+#define __ARM1176JZ_S_H__
+
+// Domain Access Control Register
+#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
+
+#define TRANSLATION_TABLE_SIZE (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1)
+
+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
+
+// Translation table descriptor types
+#define TT_DESCRIPTOR_TYPE_MASK ((1UL << 18) | (3UL << 0))
+#define TT_DESCRIPTOR_TYPE_PAGE_TABLE ((0UL << 18) | (1UL << 0))
+#define TT_DESCRIPTOR_TYPE_SECTION ((0UL << 18) | (2UL << 0))
+#define TT_DESCRIPTOR_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))
+
+// Section descriptor definitions
+#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
+
+#define TT_DESCRIPTOR_SECTION_NS_MASK (1UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS_SECURE (0UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS_NON_SECURE (1UL << 19)
+
+#define TT_DESCRIPTOR_SECTION_NG_MASK (1UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17)
+
+#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16)
+
+#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_NO_NO ((0UL << 15) | (0UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_NO ((0UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RO ((0UL << 15) | (2UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_NO ((1UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (3UL << 10))
+
+#define TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE (0UL)
+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE (1UL)
+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE (2UL)
+#define TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE (3UL)
+
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_MASK ((1UL << 14) | (3UL << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_NON_CACHEABLE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_ALLOCATE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE << 12))
+#define TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE ((1UL << 14) | (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE << 12))
+
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_MASK (3UL << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_NON_CACHEABLE (TT_DESCRIPTOR_CACHE_POLICY_NON_CACHEABLE << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_ALLOCATE (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_ALLOCATE << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE (TT_DESCRIPTOR_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE << 2)
+#define TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE (TT_DESCRIPTOR_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE << 2)
+
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK (TT_DESCRIPTOR_OUTER_CACHE_POLICY_MASK | TT_DESCRIPTOR_INNER_CACHE_POLICY_MASK)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_THROUGH_NO_ALLOCATE)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_NO_ALLOCATE)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE (TT_DESCRIPTOR_OUTER_CACHE_POLICY_NON_CACHEABLE | TT_DESCRIPTOR_INNER_CACHE_POLICY_NON_CACHEABLE)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC (TT_DESCRIPTOR_OUTER_CACHE_POLICY_WRITE_BACK_ALLOCATE | TT_DESCRIPTOR_INNER_CACHE_POLICY_WRITE_BACK_ALLOCATE)
+
+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
+#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5)
+
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
+
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_TYPE_SECTION | \
+ TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_TYPE_SECTION | \
+ TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
+#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_TYPE_SECTION | \
+ TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
+
+#endif // __ARM1176JZ_S_H__
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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARM926EJ_S_H__
+#define __ARM926EJ_S_H__
+
+// Domain Access Control Register
+#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
+
+#define TRANSLATION_TABLE_SIZE (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1)
+
+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
+
+// Translation table descriptor types
+#define TT_DESCRIPTOR_TYPE_MASK (3UL << 0)
+#define TT_DESCRIPTOR_TYPE_FAULT (0UL << 0)
+#define TT_DESCRIPTOR_TYPE_COARSE ((1UL << 0) | (1UL << 4))
+#define TT_DESCRIPTOR_TYPE_SECTION ((2UL << 0) | (1UL << 4))
+#define TT_DESCRIPTOR_TYPE_FINE ((3UL << 0) | (1UL << 4))
+
+// Section descriptor definitions
+#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
+
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK (3UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED (0UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_BUFFERED (1UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH (2UL << 2)
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK (3UL << 2)
+
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_MASK (3UL << 10)
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_NONE (1UL << 10)
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_ONLY (2UL << 10)
+#define TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE (3UL << 10)
+
+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
+#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0xF) << 5)
+
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
+
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK | \
+ TT_DESCRIPTOR_TYPE_SECTION)
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH | \
+ TT_DESCRIPTOR_TYPE_SECTION)
+#define TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED (TT_DESCRIPTOR_SECTION_ACCESS_PERMISSION_READ_WRITE | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_UNCACHED_UNBUFFERED | \
+ TT_DESCRIPTOR_TYPE_SECTION)
+
+#endif // __ARM926EJ_S_H__
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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __CORTEX_A8_H__
+#define __CORTEX_A8_H__
+
+// Domain Access Control Register
+#define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_CLIENT(a) (1UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))
+#define DOMAIN_ACCESS_CONTROL_MANAGER(a) (3UL << (2 * (a)))
+
+#define TRANSLATION_TABLE_SIZE (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT (16 * 1024)
+#define TRANSLATION_TABLE_ALIGNMENT_MASK (TRANSLATION_TABLE_ALIGNMENT - 1)
+
+#define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))
+
+// Translation table descriptor types
+#define TT_DESCRIPTOR_TYPE_MASK ((1UL << 18) | (3UL << 0))
+#define TT_DESCRIPTOR_TYPE_PAGE_TABLE ((0UL << 18) | (1UL << 0))
+#define TT_DESCRIPTOR_TYPE_SECTION ((0UL << 18) | (2UL << 0))
+#define TT_DESCRIPTOR_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))
+
+// Section descriptor definitions
+#define TT_DESCRIPTOR_SECTION_SIZE (0x00100000)
+
+#define TT_DESCRIPTOR_SECTION_NS_MASK (1UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS_SECURE (0UL << 19)
+#define TT_DESCRIPTOR_SECTION_NS_NON_SECURE (1UL << 19)
+
+#define TT_DESCRIPTOR_SECTION_NG_MASK (1UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_GLOBAL (0UL << 17)
+#define TT_DESCRIPTOR_SECTION_NG_LOCAL (1UL << 17)
+
+#define TT_DESCRIPTOR_SECTION_S_MASK (1UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_NOT_SHARED (0UL << 16)
+#define TT_DESCRIPTOR_SECTION_S_SHARED (1UL << 16)
+
+#define TT_DESCRIPTOR_SECTION_AP_MASK ((1UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_NO_NO ((0UL << 15) | (0UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_NO ((0UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RO ((0UL << 15) | (2UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RW_RW ((0UL << 15) | (3UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_NO ((1UL << 15) | (1UL << 10))
+#define TT_DESCRIPTOR_SECTION_AP_RO_RO ((1UL << 15) | (3UL << 10))
+
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED ((0UL << 12) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE ((0UL << 12) | (0UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC ((0UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE ((1UL << 12) | (0UL << 3) | (0UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC ((1UL << 12) | (1UL << 3) | (1UL << 2))
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE ((2UL << 12) | (0UL << 3) | (0UL << 2))
+
+#define TT_DESCRIPTOR_SECTION_DOMAIN_MASK (0x0FUL << 5)
+#define TT_DESCRIPTOR_SECTION_DOMAIN(a) (((a) & 0x0FUL) << 5)
+
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK (0xFFF00000)
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a) (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)
+
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_TYPE_SECTION | \
+ TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH (TT_DESCRIPTOR_TYPE_SECTION | \
+ TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)
+#define TT_DESCRIPTOR_SECTION_DEVICE (TT_DESCRIPTOR_TYPE_SECTION | \
+ TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)
+#define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_TYPE_SECTION | \
+ TT_DESCRIPTOR_SECTION_NS_NON_SECURE | \
+ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \
+ TT_DESCRIPTOR_SECTION_S_NOT_SHARED | \
+ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \
+ TT_DESCRIPTOR_SECTION_AP_RW_RW | \
+ TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)
+
+#endif // __CORTEX_A8_H__
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.<BR> + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __ARM_LIB__ +#define __ARM_LIB__ + +typedef enum { + ARM_CACHE_TYPE_WRITE_BACK, + ARM_CACHE_TYPE_UNKNOWN +} ARM_CACHE_TYPE; + +typedef enum { + ARM_CACHE_ARCHITECTURE_UNIFIED, + ARM_CACHE_ARCHITECTURE_SEPARATE, + ARM_CACHE_ARCHITECTURE_UNKNOWN +} ARM_CACHE_ARCHITECTURE; + +typedef struct { + ARM_CACHE_TYPE Type; + ARM_CACHE_ARCHITECTURE Architecture; + BOOLEAN DataCachePresent; + UINTN DataCacheSize; + UINTN DataCacheAssociativity; + UINTN DataCacheLineLength; + BOOLEAN InstructionCachePresent; + UINTN InstructionCacheSize; + UINTN InstructionCacheAssociativity; + UINTN InstructionCacheLineLength; +} ARM_CACHE_INFO; + +typedef enum { + ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED, + ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, + ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH, + ARM_MEMORY_REGION_ATTRIBUTE_DEVICE +} ARM_MEMORY_REGION_ATTRIBUTES; + +typedef struct { + UINT32 PhysicalBase; + UINT32 VirtualBase; + UINT32 Length; + ARM_MEMORY_REGION_ATTRIBUTES Attributes; +} ARM_MEMORY_REGION_DESCRIPTOR; + +typedef VOID (*CACHE_OPERATION)(VOID); +typedef VOID (*LINE_OPERATION)(UINTN); + +typedef enum { + ARM_PROCESSOR_MODE_USER = 0x10, + ARM_PROCESSOR_MODE_FIQ = 0x11, + ARM_PROCESSOR_MODE_IRQ = 0x12, + ARM_PROCESSOR_MODE_SUPERVISOR = 0x13, + ARM_PROCESSOR_MODE_ABORT = 0x17, + ARM_PROCESSOR_MODE_UNDEFINED = 0x1B, + ARM_PROCESSOR_MODE_SYSTEM = 0x1F, + ARM_PROCESSOR_MODE_MASK = 0x1F +} ARM_PROCESSOR_MODE; + +ARM_CACHE_TYPE +EFIAPI +ArmCacheType ( + VOID + ); + +ARM_CACHE_ARCHITECTURE +EFIAPI +ArmCacheArchitecture ( + VOID + ); + +VOID +EFIAPI +ArmCacheInformation ( + OUT ARM_CACHE_INFO *CacheInfo + ); + +BOOLEAN +EFIAPI +ArmDataCachePresent ( + VOID + ); + +UINTN +EFIAPI +ArmDataCacheSize ( + VOID + ); + +UINTN +EFIAPI +ArmDataCacheAssociativity ( + VOID + ); + +UINTN +EFIAPI +ArmDataCacheLineLength ( + VOID + ); + +BOOLEAN +EFIAPI +ArmInstructionCachePresent ( + VOID + ); + +UINTN +EFIAPI +ArmInstructionCacheSize ( + VOID + ); + +UINTN +EFIAPI +ArmInstructionCacheAssociativity ( + VOID + ); + +UINTN +EFIAPI +ArmInstructionCacheLineLength ( + VOID + ); + +UINT32 +EFIAPI +Cp15IdCode ( + VOID + ); + +UINT32 +EFIAPI +Cp15CacheInfo ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateDataCache ( + VOID + ); + +VOID +EFIAPI +ArmCleanInvalidateDataCache ( + VOID + ); + +VOID +EFIAPI +ArmCleanDataCache ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateInstructionCache ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateDataCacheEntryByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmCleanDataCacheEntryByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmCleanInvalidateDataCacheEntryByMVA ( + IN UINTN Address + ); + +VOID +EFIAPI +ArmEnableDataCache ( + VOID + ); + +VOID +EFIAPI +ArmDisableDataCache ( + VOID + ); + +VOID +EFIAPI +ArmEnableInstructionCache ( + VOID + ); + +VOID +EFIAPI +ArmDisableInstructionCache ( + VOID + ); + +VOID +EFIAPI +ArmEnableMmu ( + VOID + ); + +VOID +EFIAPI +ArmDisableMmu ( + VOID + ); + +VOID +EFIAPI +ArmEnableInterrupts ( + VOID + ); + +UINTN +EFIAPI +ArmDisableInterrupts ( + VOID + ); + +BOOLEAN +EFIAPI +ArmGetInterruptState ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateTlb ( + VOID + ); + +VOID +EFIAPI +ArmSetDomainAccessControl ( + IN UINT32 Domain + ); + +VOID +EFIAPI +ArmSetTranslationTableBaseAddress ( + IN VOID *TranslationTableBase + ); + +VOID +EFIAPI +ArmConfigureMmu ( + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, + OUT VOID **TranslationTableBase OPTIONAL, + OUT UINTN *TranslationTableSize OPTIONAL + ); + +VOID +EFIAPI +ArmSwitchProcessorMode ( + IN ARM_PROCESSOR_MODE Mode + ); + +ARM_PROCESSOR_MODE +EFIAPI +ArmProcessorMode ( + VOID + ); + +VOID +EFIAPI +ArmEnableBranchPrediction ( + VOID + ); + +VOID +EFIAPI +ArmDisableBranchPrediction ( + VOID + ); + +#endif // __ARM_LIB__ 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.<BR> + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __SEMIHOSTING_H__ +#define __SEMIHOSTING_H__ + +/* + * + * Please refer to ARM RVDS 3.0 Compiler and Libraries Guide for more information + * about the semihosting interface. + * + */ + +#define SEMIHOST_FILE_MODE_READ (0 << 2) +#define SEMIHOST_FILE_MODE_WRITE (1 << 2) +#define SEMIHOST_FILE_MODE_APPEND (2 << 2) +#define SEMIHOST_FILE_MODE_CREATE (1 << 1) +#define SEMIHOST_FILE_MODE_BINARY (1 << 0) +#define SEMIHOST_FILE_MODE_ASCII (0 << 0) + +BOOLEAN +SemihostConnectionSupported ( + VOID + ); + +EFI_STATUS +SemihostFileOpen ( + IN CHAR8 *FileName, + IN UINT32 Mode, + OUT UINT32 *FileHandle + ); + +EFI_STATUS +SemihostFileSeek ( + IN UINT32 FileHandle, + IN UINT32 Offset + ); + +EFI_STATUS +SemihostFileRead ( + IN UINT32 FileHandle, + IN OUT UINT32 *Length, + OUT VOID *Buffer + ); + +EFI_STATUS +SemihostFileWrite ( + IN UINT32 FileHandle, + IN OUT UINT32 *Length, + IN VOID *Buffer + ); + +EFI_STATUS +SemihostFileClose ( + IN UINT32 FileHandle + ); + +EFI_STATUS +SemihostFileLength ( + IN UINT32 FileHandle, + OUT UINT32 *Length + ); + +EFI_STATUS +SemihostFileRemove ( + IN CHAR8 *FileName + ); + +CHAR8 +SemihostReadCharacter ( + VOID + ); + +VOID +SemihostWriteCharacter ( + IN CHAR8 Character + ); + +VOID +SemihostWriteString ( + IN CHAR8 *String + ); + +UINT32 +SemihostSystem ( + IN CHAR8 *CommandLine + ); + +#endif // __SEMIHOSTING_H__ 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.<BR> + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __UNCACHED_MEMORY_ALLOCATION_LIB_H__ +#define __UNCACHED_MEMORY_ALLOCATION_LIB_H__ + +/** + Converts a cached or uncached address to a physical address suitable for use in SoC registers. + + @param VirtualAddress The pointer to convert. + + @return The physical address of the supplied virtual pointer. + +**/ +EFI_PHYSICAL_ADDRESS +ConvertToPhysicalAddress ( + IN VOID *VirtualAddress + ); + +/** + Converts a cached or uncached address to a cached address. + + @param Address The pointer to convert. + + @return The address of the cached memory location corresponding to the input address. + +**/ +VOID * +ConvertToCachedAddress ( + IN VOID *Address + ); + +/** + Converts a cached or uncached address to an uncached address. + + @param Address The pointer to convert. + + @return The address of the uncached memory location corresponding to the input address. + +**/ +VOID * +ConvertToUncachedAddress ( + IN VOID *Address + ); + +/** + Allocates one or more 4KB pages of type EfiBootServicesData. + + Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocatePages ( + IN UINTN Pages + ); + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimePages ( + IN UINTN Pages + ); + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType. + + Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedPages ( + IN UINTN Pages + ); + +/** + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the page allocation services of the Memory + Allocation Library. + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, + then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +UncachedFreePages ( + IN VOID *Buffer, + IN UINTN Pages + ); + +/** + Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedPages ( + IN UINTN Pages, + IN UINTN Alignment + ); + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimePages ( + IN UINTN Pages, + IN UINTN Alignment + ); + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedPages ( + IN UINTN Pages, + IN UINTN Alignment + ); + +/** + Frees one or more 4KB pages that were previously allocated with one of the aligned page + allocation functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the aligned page allocation services of the Memory + Allocation Library. + If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +UncachedFreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ); + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocatePool ( + IN UINTN AllocationSize + ); + +/** + Allocates a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimePool ( + IN UINTN AllocationSize + ); + +/** + Allocates a buffer of type EfieservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedPool ( + IN UINTN AllocationSize + ); + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateZeroPool ( + IN UINTN AllocationSize + ); + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ); + +/** + Allocates and zeros a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedZeroPool ( + IN UINTN AllocationSize + ); + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +UncachedFreePool ( + IN VOID *Buffer + ); + +/** + Allocates a buffer of type EfiBootServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates a buffer of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimePool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates a buffer of type EfieservedMemoryType at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an + alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory at the specified alignment remaining to satisfy the request, then NULL is + returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an + alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory at the specified alignment remaining to satisfy the request, then NULL is + returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimeZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an + alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory at the specified alignment remaining to satisfy the request, then NULL is + returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedZeroPool ( + IN UINTN AllocationSize, + IN UINTN Alignment + ); + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Buffer The buffer to copy to the allocated buffer. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ); + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Buffer The buffer to copy to the allocated buffer. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ); + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an + alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, + then a valid buffer of 0 size is returned. If there is not enough memory at the specified + alignment remaining to satisfy the request, then NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param AllocationSize The number of bytes to allocate. + @param Buffer The buffer to copy to the allocated buffer. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +UncachedAllocateAlignedReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer, + IN UINTN Alignment + ); + +/** + Frees a buffer that was previously allocated with one of the aligned pool allocation functions + in the Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + aligned pool allocation services of the Memory Allocation Library. + If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation + Library, then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +UncachedFreeAlignedPool ( + IN VOID *Buffer + ); + +VOID +EFIAPI +UncachedSafeFreePool ( + IN VOID *Buffer + ); + +#endif // __UNCACHED_MEMORY_ALLOCATION_LIB_H__ 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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TIMERDEBUGSUPPORTPROTOCOL_H__
+#define __TIMERDEBUGSUPPORTPROTOCOL_H__
+
+//
+// Protocol GUID
+//
+#define TIMER_DEBUG_PROTOCOL_GUID { 0x68300561, 0x0197, 0x465d, { 0xb5, 0xa1, 0x28, 0xeb, 0xa1, 0x98, 0xdd, 0x0b } }
+
+
+
+//
+// Protocol interface structure
+//
+typedef struct _TIMER_DEBUG_SUPPORT_PROTOCOL TIMER_DEBUG_SUPPORT_PROTOCOL;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *TIMER_DEBUG_SUPPORT_REGISTER_PERIODIC_CALLBACK) (
+ IN TIMER_DEBUG_SUPPORT_PROTOCOL *This,
+ IN EFI_PERIODIC_CALLBACK PeriodicCallback
+ )
+/*++
+
+Routine Description:
+ Register a periodic callback for debug support.
+
+Arguments:
+ This - pointer to protocol
+ PeriodicCallback - callback to be registered
+
+Returns:
+ EFI_SUCCESS - callback registered
+
+--*/
+;
+
+struct _TIMER_DEBUG_SUPPORT_PROTOCOL {
+ TIMER_DEBUG_SUPPORT_REGISTER_PERIODIC_CALLBACK RegisterPeriodicCallback;
+};
+
+extern EFI_GUID gTimerDebugSupportProtocolGuid;
+
+#endif // __TIMERDEBUGSUPPORTPROTOCOL_H__
+
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 <Base.h> +#include <Library/ArmLib.h> +#include <Library/PcdLib.h> + +VOID +CacheRangeOperation ( + IN VOID *Start, + IN UINTN Length, + IN CACHE_OPERATION CacheOperation, + IN LINE_OPERATION LineOperation + ) +{ + UINTN ArmCacheLineLength = ArmDataCacheLineLength(); + UINTN ArmCacheLineAlignmentMask = ArmCacheLineLength - 1; + UINTN ArmCacheOperationThreshold = PcdGet32(PcdArmCacheOperationThreshold); + + if ((CacheOperation != NULL) && (Length >= ArmCacheOperationThreshold)) + { + CacheOperation(); + } + else + { + // Align address (rounding down) + UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask); + UINTN EndAddress = (UINTN)Start + Length; + + // Perform the line operation on an address in each cache line + while (AlignedAddress < EndAddress) + { + LineOperation(AlignedAddress); + AlignedAddress += ArmCacheLineLength; + } + } +} + +VOID +EFIAPI +InvalidateInstructionCache ( + VOID + ) +{ + ArmCleanDataCache(); + ArmInvalidateInstructionCache(); +} + +VOID +EFIAPI +InvalidateDataCache ( + VOID + ) +{ + ArmInvalidateDataCache(); +} + +VOID * +EFIAPI +InvalidateInstructionCacheRange ( + IN VOID *Address, + IN UINTN Length + ) +{ + CacheRangeOperation(Address, Length, ArmCleanDataCache, ArmCleanDataCacheEntryByMVA); + ArmInvalidateInstructionCache(); + return Address; +} + +VOID +EFIAPI +WriteBackInvalidateDataCache ( + VOID + ) +{ + ArmCleanInvalidateDataCache(); +} + +VOID * +EFIAPI +WriteBackInvalidateDataCacheRange ( + IN VOID *Address, + IN UINTN Length + ) +{ + CacheRangeOperation(Address, Length, ArmCleanInvalidateDataCache, ArmCleanInvalidateDataCacheEntryByMVA); + return Address; +} + +VOID +EFIAPI +WriteBackDataCache ( + VOID + ) +{ + ArmCleanDataCache(); +} + +VOID * +EFIAPI +WriteBackDataCacheRange ( + IN VOID *Address, + IN UINTN Length + ) +{ + CacheRangeOperation(Address, Length, ArmCleanDataCache, ArmCleanDataCacheEntryByMVA); + return Address; +} + +VOID * +EFIAPI +InvalidateDataCacheRange ( + IN VOID *Address, + IN UINTN Length + ) +{ + CacheRangeOperation(Address, Length, NULL, ArmInvalidateDataCacheEntryByMVA); + return Address; +} 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 <Chipset/ARM1176JZ-S.h> +#include <Library/ArmLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> + +VOID +FillTranslationTable ( + IN UINT32 *TranslationTable, + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion + ) +{ + UINT32 *Entry; + UINTN Sections; + UINTN Index; + UINT32 Attributes; + UINT32 PhysicalBase = MemoryRegion->PhysicalBase; + + switch (MemoryRegion->Attributes) { + case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK: + Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; + break; + case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH: + Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH; + break; + case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED: + default: + Attributes = TT_DESCRIPTOR_SECTION_UNCACHED; + break; + } + + Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase); + Sections = ((( MemoryRegion->Length - 1 ) / TT_DESCRIPTOR_SECTION_SIZE ) + 1 ); + + for (Index = 0; Index < Sections; Index++) + { + *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes; + PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE; + } +} + +VOID +EFIAPI +ArmConfigureMmu ( + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, + OUT VOID **TranslationTableBase OPTIONAL, + OUT UINTN *TranslationTableSize OPTIONAL + ) +{ + VOID *TranslationTable; + + // Allocate pages for translation table. + TranslationTable = AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT)); + TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK); + + if (TranslationTableBase != NULL) { + *TranslationTableBase = TranslationTable; + } + + if (TranslationTableBase != NULL) { + *TranslationTableSize = TRANSLATION_TABLE_SIZE; + } + + ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE); + + ArmCleanInvalidateDataCache(); + ArmInvalidateInstructionCache(); + ArmInvalidateTlb(); + + ArmDisableDataCache(); + ArmDisableInstructionCache(); + ArmDisableMmu(); + + // Make sure nothing sneaked into the cache + ArmCleanInvalidateDataCache(); + ArmInvalidateInstructionCache(); + + while (MemoryTable->Length != 0) { + FillTranslationTable(TranslationTable, MemoryTable); + MemoryTable++; + } + + ArmSetTranslationTableBaseAddress(TranslationTable); + + ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) | + DOMAIN_ACCESS_CONTROL_NONE(14) | + DOMAIN_ACCESS_CONTROL_NONE(13) | + DOMAIN_ACCESS_CONTROL_NONE(12) | + DOMAIN_ACCESS_CONTROL_NONE(11) | + DOMAIN_ACCESS_CONTROL_NONE(10) | + DOMAIN_ACCESS_CONTROL_NONE( 9) | + DOMAIN_ACCESS_CONTROL_NONE( 8) | + DOMAIN_ACCESS_CONTROL_NONE( 7) | + DOMAIN_ACCESS_CONTROL_NONE( 6) | + DOMAIN_ACCESS_CONTROL_NONE( 5) | + DOMAIN_ACCESS_CONTROL_NONE( 4) | + DOMAIN_ACCESS_CONTROL_NONE( 3) | + DOMAIN_ACCESS_CONTROL_NONE( 2) | + DOMAIN_ACCESS_CONTROL_NONE( 1) | + DOMAIN_ACCESS_CONTROL_MANAGER(0)); + + ArmEnableInstructionCache(); + ArmEnableDataCache(); + ArmEnableMmu(); +} 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 <Library/ArmLib.h>
+#include "ArmLibPrivate.h"
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+ VOID
+ )
+{
+ switch (CACHE_TYPE(Cp15CacheInfo()))
+ {
+ case CACHE_TYPE_WRITE_BACK: return ARM_CACHE_TYPE_WRITE_BACK;
+ default: return ARM_CACHE_TYPE_UNKNOWN;
+ }
+}
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+ VOID
+ )
+{
+ switch (CACHE_ARCHITECTURE(Cp15CacheInfo()))
+ {
+ case CACHE_ARCHITECTURE_UNIFIED: return ARM_CACHE_ARCHITECTURE_UNIFIED;
+ case CACHE_ARCHITECTURE_SEPARATE: return ARM_CACHE_ARCHITECTURE_SEPARATE;
+ default: return ARM_CACHE_ARCHITECTURE_UNKNOWN;
+ }
+}
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+ VOID
+ )
+{
+ switch (DATA_CACHE_PRESENT(Cp15CacheInfo()))
+ {
+ case CACHE_PRESENT: return TRUE;
+ case CACHE_NOT_PRESENT: return FALSE;
+ default: return FALSE;
+ }
+}
+
+UINTN
+EFIAPI
+ArmDataCacheSize (
+ VOID
+ )
+{
+ switch (DATA_CACHE_SIZE(Cp15CacheInfo()))
+ {
+ case CACHE_SIZE_4_KB: return 4 * 1024;
+ case CACHE_SIZE_8_KB: return 8 * 1024;
+ case CACHE_SIZE_16_KB: return 16 * 1024;
+ case CACHE_SIZE_32_KB: return 32 * 1024;
+ case CACHE_SIZE_64_KB: return 64 * 1024;
+ case CACHE_SIZE_128_KB: return 128 * 1024;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+ VOID
+ )
+{
+ switch (DATA_CACHE_ASSOCIATIVITY(Cp15CacheInfo()))
+ {
+ case CACHE_ASSOCIATIVITY_4_WAY: return 4;
+ case CACHE_ASSOCIATIVITY_DIRECT: return 1;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+ VOID
+ )
+{
+ switch (DATA_CACHE_LINE_LENGTH(Cp15CacheInfo()))
+ {
+ case CACHE_LINE_LENGTH_32_BYTES: return 32;
+ default: return 0;
+ }
+}
+
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_PRESENT(Cp15CacheInfo()))
+ {
+ case CACHE_PRESENT: return TRUE;
+ case CACHE_NOT_PRESENT: return FALSE;
+ default: return FALSE;
+ }
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_SIZE(Cp15CacheInfo()))
+ {
+ case CACHE_SIZE_4_KB: return 4 * 1024;
+ case CACHE_SIZE_8_KB: return 8 * 1024;
+ case CACHE_SIZE_16_KB: return 16 * 1024;
+ case CACHE_SIZE_32_KB: return 32 * 1024;
+ case CACHE_SIZE_64_KB: return 64 * 1024;
+ case CACHE_SIZE_128_KB: return 128 * 1024;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_ASSOCIATIVITY(Cp15CacheInfo()))
+ {
+ case CACHE_ASSOCIATIVITY_8_WAY: return 8;
+ case CACHE_ASSOCIATIVITY_4_WAY: return 4;
+ case CACHE_ASSOCIATIVITY_DIRECT: return 1;
+ default: return 0;
+ }
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+ VOID
+ )
+{
+ switch (INSTRUCTION_CACHE_LINE_LENGTH(Cp15CacheInfo()))
+ {
+ case CACHE_LINE_LENGTH_32_BYTES: return 32;
+ default: return 0;
+ }
+}
+
+
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 <Chipset/ARM926EJ-S.h> +#include <Library/ArmLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> + +VOID +FillTranslationTable ( + IN UINT32 *TranslationTable, + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion + ) +{ + UINT32 *Entry; + UINTN Sections; + UINTN Index; + UINT32 Attributes; + UINT32 PhysicalBase = MemoryRegion->PhysicalBase; + + switch (MemoryRegion->Attributes) { + case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK: + Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; + break; + case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH: + Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH; + break; + case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED: + default: + Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED; + break; + } + + Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase); + Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE; + + for (Index = 0; Index < Sections; Index++) + { + *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes; + PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE; + } +} + +VOID +EFIAPI +ArmConfigureMmu ( + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, + OUT VOID **TranslationTableBase OPTIONAL, + OUT UINTN *TranslationTableSize OPTIONAL + ) +{ + VOID *TranslationTable; + + // Allocate pages for translation table. + TranslationTable = AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT)); + TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK); + + if (TranslationTableBase != NULL) { + *TranslationTableBase = TranslationTable; + } + + if (TranslationTableBase != NULL) { + *TranslationTableSize = TRANSLATION_TABLE_SIZE; + } + + ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE); + + ArmCleanInvalidateDataCache(); + ArmInvalidateInstructionCache(); + ArmInvalidateTlb(); + + ArmDisableDataCache(); + ArmDisableInstructionCache(); + ArmDisableMmu(); + + // Make sure nothing sneaked into the cache + ArmCleanInvalidateDataCache(); + ArmInvalidateInstructionCache(); + + while (MemoryTable->Length != 0) { + FillTranslationTable(TranslationTable, MemoryTable); + MemoryTable++; + } + + ArmSetTranslationTableBaseAddress(TranslationTable); + + ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) | + DOMAIN_ACCESS_CONTROL_NONE(14) | + DOMAIN_ACCESS_CONTROL_NONE(13) | + DOMAIN_ACCESS_CONTROL_NONE(12) | + DOMAIN_ACCESS_CONTROL_NONE(11) | + DOMAIN_ACCESS_CONTROL_NONE(10) | + DOMAIN_ACCESS_CONTROL_NONE( 9) | + DOMAIN_ACCESS_CONTROL_NONE( 8) | + DOMAIN_ACCESS_CONTROL_NONE( 7) | + DOMAIN_ACCESS_CONTROL_NONE( 6) | + DOMAIN_ACCESS_CONTROL_NONE( 5) | + DOMAIN_ACCESS_CONTROL_NONE( 4) | + DOMAIN_ACCESS_CONTROL_NONE( 3) | + DOMAIN_ACCESS_CONTROL_NONE( 2) | + DOMAIN_ACCESS_CONTROL_NONE( 1) | + DOMAIN_ACCESS_CONTROL_MANAGER(0)); + + ArmEnableInstructionCache(); + ArmEnableDataCache(); + ArmEnableMmu(); +} 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 <Chipset/Cortex-A8.h> +#include <Library/ArmLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include "ArmCortexALib.h" + +VOID +FillTranslationTable ( + IN UINT32 *TranslationTable, + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion + ) +{ + UINT32 *Entry; + UINTN Sections; + UINTN Index; + UINT32 Attributes; + UINT32 PhysicalBase = MemoryRegion->PhysicalBase; + + switch (MemoryRegion->Attributes) { + case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK: + Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; + break; + case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH: + Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH; + break; + case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE: + Attributes = TT_DESCRIPTOR_SECTION_DEVICE; + break; + case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED: + default: + Attributes = TT_DESCRIPTOR_SECTION_UNCACHED; + break; + } + + Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase); + Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE; + + for (Index = 0; Index < Sections; Index++) + { + *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes; + PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE; + } +} + +VOID +EFIAPI +ArmConfigureMmu ( + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, + OUT VOID **TranslationTableBase OPTIONAL, + OUT UINTN *TranslationTableSize OPTIONAL + ) +{ + VOID *TranslationTable; + + // Allocate pages for translation table. + TranslationTable = AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT)); + TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK); + + if (TranslationTableBase != NULL) { + *TranslationTableBase = TranslationTable; + } + + if (TranslationTableBase != NULL) { + *TranslationTableSize = TRANSLATION_TABLE_SIZE; + } + + ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE); + + ArmCleanInvalidateDataCache(); + ArmInvalidateInstructionCache(); + ArmInvalidateTlb(); + + ArmDisableDataCache(); + ArmDisableInstructionCache(); + ArmDisableMmu(); + + // Make sure nothing sneaked into the cache + ArmCleanInvalidateDataCache(); + ArmInvalidateInstructionCache(); + + while (MemoryTable->Length != 0) { + FillTranslationTable(TranslationTable, MemoryTable); + MemoryTable++; + } + + ArmSetTranslationTableBaseAddress(TranslationTable); + + ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) | + DOMAIN_ACCESS_CONTROL_NONE(14) | + DOMAIN_ACCESS_CONTROL_NONE(13) | + DOMAIN_ACCESS_CONTROL_NONE(12) | + DOMAIN_ACCESS_CONTROL_NONE(11) | + DOMAIN_ACCESS_CONTROL_NONE(10) | + DOMAIN_ACCESS_CONTROL_NONE( 9) | + DOMAIN_ACCESS_CONTROL_NONE( 8) | + DOMAIN_ACCESS_CONTROL_NONE( 7) | + DOMAIN_ACCESS_CONTROL_NONE( 6) | + DOMAIN_ACCESS_CONTROL_NONE( 5) | + DOMAIN_ACCESS_CONTROL_NONE( 4) | + DOMAIN_ACCESS_CONTROL_NONE( 3) | + DOMAIN_ACCESS_CONTROL_NONE( 2) | + DOMAIN_ACCESS_CONTROL_NONE( 1) | + DOMAIN_ACCESS_CONTROL_MANAGER(0)); + + ArmEnableInstructionCache(); + ArmEnableDataCache(); + ArmEnableMmu(); +} + +ARM_CACHE_TYPE +EFIAPI +ArmCacheType ( + VOID + ) +{ + return ARM_CACHE_TYPE_WRITE_BACK; +} + +ARM_CACHE_ARCHITECTURE +EFIAPI +ArmCacheArchitecture ( + VOID + ) +{ + return ARM_CACHE_ARCHITECTURE_SEPARATE; +} + +BOOLEAN +EFIAPI +ArmDataCachePresent ( + VOID + ) +{ + return TRUE; +} + +UINTN +EFIAPI +ArmDataCacheSize ( + VOID + ) +{ + return 16 * 1024; +} + +UINTN +EFIAPI +ArmDataCacheAssociativity ( + VOID + ) +{ + return 4; +} + +UINTN +ArmDataCacheSets ( + VOID + ) +{ + return 64; +} + +UINTN +EFIAPI +ArmDataCacheLineLength ( + VOID + ) +{ + return 64; +} + +BOOLEAN +EFIAPI +ArmInstructionCachePresent ( + VOID + ) +{ + return TRUE; +} + +UINTN +EFIAPI +ArmInstructionCacheSize ( + VOID + ) +{ + return 16 * 1024; +} + +UINTN +EFIAPI +ArmInstructionCacheAssociativity ( + VOID + ) +{ + return 4; +} + +UINTN +EFIAPI +ArmInstructionCacheLineLength ( + VOID + ) +{ + return 64; +} + +VOID +ArmCortexADataCacheOperation ( + IN ARM_CORTEX_A_CACHE_OPERATION DataCacheOperation + ) +{ + UINTN Set; + UINTN SetCount; + UINTN SetShift; + UINTN Way; + UINTN WayCount; + UINTN WayShift; + UINT32 SetWayFormat; + UINTN SavedInterruptState; + + SetCount = ArmDataCacheSets(); + WayCount = ArmDataCacheAssociativity(); + + // Cortex-A8 Manual, System Control Coprocessor chapter + SetShift = 6; + WayShift = 32 - LowBitSet32 ((UINT32)WayCount); + + SavedInterruptState = ArmDisableInterrupts(); + + for (Way = 0; Way < WayCount; Way++) { + for (Set = 0; Set < SetCount; Set++) { + // Build the format that the CP15 instruction can understand + SetWayFormat = (Way << WayShift) | (Set << SetShift); + + // Pass it through + (*DataCacheOperation)(SetWayFormat); + } + } + + ArmDrainWriteBuffer(); + + if (SavedInterruptState) { + ArmEnableInterrupts(); + } +} + +VOID +EFIAPI +ArmInvalidateDataCache ( + VOID + ) +{ + ArmCortexADataCacheOperation(ArmInvalidateDataCacheEntryBySetWay); +} + +VOID +EFIAPI +ArmCleanInvalidateDataCache ( + VOID + ) +{ + ArmCortexADataCacheOperation(ArmCleanInvalidateDataCacheEntryBySetWay); +} + +VOID +EFIAPI +ArmCleanDataCache ( + VOID + ) +{ + ArmCortexADataCacheOperation(ArmCleanDataCacheEntryBySetWay); +} 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.<BR> + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __ARMCORTEXALIB_H__ +#define __ARMCORTEXALIB_H__ + +typedef VOID (*ARM_CORTEX_A_CACHE_OPERATION)(UINT32); + +VOID +EFIAPI +ArmDrainWriteBuffer ( + VOID + ); + +VOID +EFIAPI +ArmInvalidateDataCacheEntryBySetWay ( + IN UINT32 SetWayFormat + ); + +VOID +EFIAPI +ArmCleanDataCacheEntryBySetWay ( + IN UINT32 SetWayFormat + ); + +VOID +EFIAPI +ArmCleanInvalidateDataCacheEntryBySetWay ( + IN UINT32 SetWayFormat + ); + +#endif // __ARMCORTEXALIB_H__ + 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 <Base.h>
+
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include "ArmLibPrivate.h"
+
+VOID
+EFIAPI
+ArmCacheInformation (
+ OUT ARM_CACHE_INFO *CacheInfo
+ )
+{
+ if (CacheInfo != NULL) {
+ CacheInfo->Type = ArmCacheType();
+ CacheInfo->Architecture = ArmCacheArchitecture();
+ CacheInfo->DataCachePresent = ArmDataCachePresent();
+ CacheInfo->DataCacheSize = ArmDataCacheSize();
+ CacheInfo->DataCacheAssociativity = ArmDataCacheAssociativity();
+ CacheInfo->DataCacheLineLength = ArmDataCacheLineLength();
+ CacheInfo->InstructionCachePresent = ArmInstructionCachePresent();
+ CacheInfo->InstructionCacheSize = ArmInstructionCacheSize();
+ CacheInfo->InstructionCacheAssociativity = ArmInstructionCacheAssociativity();
+ CacheInfo->InstructionCacheLineLength = ArmInstructionCacheLineLength();
+ }
+}
+
+VOID
+EFIAPI
+ArmSwitchProcessorMode (
+ IN ARM_PROCESSOR_MODE Mode
+ )
+{
+ CPSRMaskInsert(ARM_PROCESSOR_MODE_MASK, Mode);
+}
+
+
+ARM_PROCESSOR_MODE
+EFIAPI
+ArmProcessorMode (
+ VOID
+ )
+{
+ return (ARM_PROCESSOR_MODE)(CPSRRead() & (UINT32)ARM_PROCESSOR_MODE_MASK);
+}
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.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARM_LIB_PRIVATE_H__
+#define __ARM_LIB_PRIVATE_H__
+
+#define CACHE_SIZE_4_KB (3UL)
+#define CACHE_SIZE_8_KB (4UL)
+#define CACHE_SIZE_16_KB (5UL)
+#define CACHE_SIZE_32_KB (6UL)
+#define CACHE_SIZE_64_KB (7UL)
+#define CACHE_SIZE_128_KB (8UL)
+
+#define CACHE_ASSOCIATIVITY_DIRECT (0UL)
+#define CACHE_ASSOCIATIVITY_4_WAY (2UL)
+#define CACHE_ASSOCIATIVITY_8_WAY (3UL)
+
+#define CACHE_PRESENT (0UL)
+#define CACHE_NOT_PRESENT (1UL)
+
+#define CACHE_LINE_LENGTH_32_BYTES (2UL)
+
+#define SIZE_FIELD_TO_CACHE_SIZE(x) (((x) >> 6) & 0x0F)
+#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x) (((x) >> 3) & 0x07)
+#define SIZE_FIELD_TO_CACHE_PRESENCE(x) (((x) >> 2) & 0x01)
+#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x) (((x) >> 0) & 0x03)
+
+#define DATA_CACHE_SIZE_FIELD(x) (((x) >> 12) & 0x0FFF)
+#define INSTRUCTION_CACHE_SIZE_FIELD(x) (((x) >> 0) & 0x0FFF)
+
+#define DATA_CACHE_SIZE(x) (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
+#define DATA_CACHE_ASSOCIATIVITY(x) (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
+#define DATA_CACHE_PRESENT(x) (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
+#define DATA_CACHE_LINE_LENGTH(x) (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))
+
+#define INSTRUCTION_CACHE_SIZE(x) (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+#define INSTRUCTION_CACHE_ASSOCIATIVITY(x) (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+#define INSTRUCTION_CACHE_PRESENT(x) (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+#define INSTRUCTION_CACHE_LINE_LENGTH(x) (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))
+
+#define CACHE_TYPE(x) (((x) >> 25) & 0x0F)
+#define CACHE_TYPE_WRITE_BACK (0x0EUL)
+
+#define CACHE_ARCHITECTURE(x) (((x) >> 24) & 0x01)
+#define CACHE_ARCHITECTURE_UNIFIED (0UL)
+#define CACHE_ARCHITECTURE_SEPARATE (1UL)
+
+VOID
+CPSRMaskInsert (
+ IN UINT32 Mask,
+ IN UINT32 Value
+ );
+
+UINT32
+CPSRRead (
+ VOID
+ );
+
+#endif // __ARM_LIB_PRIVATE_H__
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 <Library/ArmLib.h>
+#include "ArmLibPrivate.h"
+
+ARM_CACHE_TYPE
+EFIAPI
+ArmCacheType (
+ VOID
+ )
+{
+ return ARM_CACHE_TYPE_UNKNOWN;
+}
+
+ARM_CACHE_ARCHITECTURE
+EFIAPI
+ArmCacheArchitecture (
+ VOID
+ )
+{
+ return ARM_CACHE_ARCHITECTURE_UNKNOWN;
+}
+
+BOOLEAN
+EFIAPI
+ArmDataCachePresent (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheSize (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheAssociativity (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmDataCacheLineLength (
+ VOID
+ )
+{
+ return 0;
+}
+
+BOOLEAN
+EFIAPI
+ArmInstructionCachePresent (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheSize (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheAssociativity (
+ VOID
+ )
+{
+ return 0;
+}
+
+UINTN
+EFIAPI
+ArmInstructionCacheLineLength (
+ VOID
+ )
+{
+ return 0;
+}
diff --git a/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 <Uefi.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmInvalidateInstructionCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmInvalidateDataCacheEntryByMVA (
+ IN UINTN Address
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmCleanDataCacheEntryByMVA (
+ IN UINTN Address
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmCleanInvalidateDataCacheEntryByMVA (
+ IN UINTN Address
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmEnableDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmDisableDataCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmEnableInstructionCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
+
+VOID
+EFIAPI
+ArmDisableInstructionCache (
+ VOID
+ )
+{
+ // Do not run code using the Null cache library.
+ ASSERT(FALSE);
+}
diff --git a/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.<BR> + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +/** + University of Illinois/NCSA + Open Source License + + Copyright (c) 2003-2008 University of Illinois at Urbana-Champaign. + All rights reserved. + + Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal with + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. +**/ + +#include <Base.h> +#include <Library/DebugLib.h> + +#define CHAR_BIT 8 + +typedef union { + INT64 all; + struct { + UINT32 low; + INT32 high; + }; +} dwords; + +typedef union { + UINT64 all; + struct { + UINT32 low; + UINT32 high; + }; +} udwords; + +#if __GNUC__ + #define COUNT_LEADING_ZEROS(_a) __builtin_clz((_a)) + #define COUNT_TRAILING_ZEROS(_a) __builtin_ctz((_a)) +#else +#error COUNT_LEADING_ZEROS() and COUNT_TRAILING_ZEROS() macros not ported to your compiler +#endif 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 <Base.h> +#include "Llvm_int_lib.h" + + +// Returns: a * b + +static +INT64 +__muldsi3(UINT32 a, UINT32 b) +{ + dwords r; + const int bits_in_word_2 = (int)(sizeof(INT32) * CHAR_BIT) / 2; + const UINT32 lower_mask = (UINT32)~0 >> bits_in_word_2; + r.low = (a & lower_mask) * (b & lower_mask); + UINT32 t = r.low >> bits_in_word_2; + r.low &= lower_mask; + t += (a >> bits_in_word_2) * (b & lower_mask); + r.low += (t & lower_mask) << bits_in_word_2; + r.high = t >> bits_in_word_2; + t = r.low >> bits_in_word_2; + r.low &= lower_mask; + t += (b >> bits_in_word_2) * (a & lower_mask); + r.low += (t & lower_mask) << bits_in_word_2; + r.high += t >> bits_in_word_2; + r.high += (a >> bits_in_word_2) * (b >> bits_in_word_2); + return r.all; +} + +// Returns: a * b + +INT64 +__muldi3(INT64 a, INT64 b) +{ + dwords x; + x.all = a; + dwords y; + y.all = b; + dwords r; + r.all = __muldsi3(x.low, y.low); + r.high += x.high * y.low + x.low * y.high; + return r.all; +} diff --git a/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<BR>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SemihostLib.h>
+
+//
+// Define the maximum debug and assert message length that this library supports
+//
+#define MAX_DEBUG_MESSAGE_LENGTH 0x100
+
+/**
+
+ Prints a debug message to the debug output device if the specified error level is enabled.
+
+ If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print
+ the message specified by Format and the associated variable argument list to
+ the debug output device.
+
+ If Format is NULL, then ASSERT().
+
+ @param ErrorLevel The error level of the debug message.
+ @param Format Format string for the debug message to print.
+
+**/
+VOID
+EFIAPI
+DebugPrint (
+ IN UINTN ErrorLevel,
+ IN CONST CHAR8 *Format,
+ ...
+ )
+{
+ CHAR8 AsciiBuffer[MAX_DEBUG_MESSAGE_LENGTH];
+ VA_LIST Marker;
+
+ //
+ // If Format is NULL, then ASSERT().
+ //
+ ASSERT (Format != NULL);
+
+ //
+ // Check driver debug mask value and global mask
+ //
+ if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {
+ return;
+ }
+
+ //
+ // Convert the DEBUG() message to a Unicode String
+ //
+ VA_START (Marker, Format);
+ AsciiVSPrint (AsciiBuffer, sizeof (AsciiBuffer), Format, Marker);
+ VA_END (Marker);
+
+ SemihostWriteString (AsciiBuffer);
+}
+
+
+/**
+
+ Prints an assert message containing a filename, line number, and description.
+ This may be followed by a breakpoint or a dead loop.
+
+ Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
+ to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
+ PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
+ CpuDeadLoop() is called. If neither of these bits are set, then this function
+ returns immediately after the message is printed to the debug output device.
+ DebugAssert() must actively prevent recusrsion. If DebugAssert() is called while
+ processing another DebugAssert(), then DebugAssert() must return immediately.
+
+ If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
+
+ If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
+
+ @param FileName Pointer to the name of the source file that generated the assert condition.
+ @param LineNumber The line number in the source file that generated the assert condition
+ @param Description Pointer to the description of the assert condition.
+
+**/
+VOID
+EFIAPI
+DebugAssert (
+ IN CONST CHAR8 *FileName,
+ IN UINTN LineNumber,
+ IN CONST CHAR8 *Description
+ )
+{
+ CHAR8 AsciiBuffer[MAX_DEBUG_MESSAGE_LENGTH];
+
+ //
+ // Generate the ASSERT() message in Unicode format
+ //
+ AsciiSPrint (AsciiBuffer, sizeof (AsciiBuffer), "ASSERT %a(%d): %a\n", FileName, LineNumber, Description);
+
+ SemihostWriteString (AsciiBuffer);
+
+ //
+ // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
+ //
+ if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
+ CpuBreakpoint ();
+ } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
+ CpuDeadLoop ();
+ }
+}
+
+
+/**
+
+ Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the value specified by
+ PcdDebugClearMemoryValue, and returns Buffer.
+
+ If Buffer is NULL, then ASSERT().
+
+ If Length is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
+
+ @param Buffer Pointer to the target buffer to fill with PcdDebugClearMemoryValue.
+ @param Length Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
+
+ @return Buffer
+
+**/
+VOID *
+EFIAPI
+DebugClearMemory (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ //
+ // If Buffer is NULL, then ASSERT().
+ //
+ ASSERT (Buffer != NULL);
+
+ //
+ // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
+ //
+ return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));
+}
+
+
+/**
+
+ Returns TRUE if ASSERT() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugAssertEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
+}
+
+
+/**
+
+ Returns TRUE if DEBUG()macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
+}
+
+
+/**
+
+ Returns TRUE if DEBUG_CODE()macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugCodeEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
+}
+
+
+/**
+
+ Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugClearMemoryEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
+}
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 <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/SemihostLib.h>
+#include <Library/SerialPortLib.h>
+
+
+/*
+
+ Programmed hardware of Serial port.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+ VOID
+ )
+{
+ if (SemihostConnectionSupported ()) {
+ return RETURN_SUCCESS;
+ } else {
+ return RETURN_UNSUPPORTED;
+ }
+}
+
+/**
+ Write data to serial device.
+
+ @param Buffer Point of data buffer which need to be writed.
+ @param NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Write data failed.
+ @retval !0 Actual number of bytes writed to serial device.
+
+**/
+
+#define PRINT_BUFFER_SIZE 512
+#define PRINT_BUFFER_THRESHOLD (PRINT_BUFFER_SIZE - 4)
+
+UINTN
+EFIAPI
+SerialPortWrite (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ UINT8 PrintBuffer[PRINT_BUFFER_SIZE];
+ UINTN SourceIndex = 0;
+ UINTN DestinationIndex = 0;
+ UINT8 CurrentCharacter;
+
+ while (SourceIndex < NumberOfBytes)
+ {
+ CurrentCharacter = Buffer[SourceIndex++];
+
+ switch (CurrentCharacter)
+ {
+ case '\r':
+ continue;
+
+ case '\n':
+ PrintBuffer[DestinationIndex++] = ' ';
+ // fall through
+
+ default:
+ PrintBuffer[DestinationIndex++] = CurrentCharacter;
+ break;
+ }
+
+ if (DestinationIndex > PRINT_BUFFER_THRESHOLD)
+ {
+ PrintBuffer[DestinationIndex] = '\0';
+ SemihostWriteString ((CHAR8 *) PrintBuffer);
+
+ DestinationIndex = 0;
+ }
+ }
+
+ if (DestinationIndex > 0)
+ {
+ PrintBuffer[DestinationIndex] = '\0';
+ SemihostWriteString ((CHAR8 *) PrintBuffer);
+ }
+
+ return 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 <Uefi.h> + +#include <Library/BaseLib.h> +#include <Library/SemihostLib.h> + +#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.<BR> + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __SEMIHOST_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 <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+#include <Protocol/Cpu.h>
+
+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 |