]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib...
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 2 Feb 2011 22:35:30 +0000 (22:35 +0000)
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 2 Feb 2011 22:35:30 +0000 (22:35 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11293 6f19259b-4bc3-4df7-8a09-765794883524

114 files changed:
ArmPkg/ArmPkg.dec
ArmPkg/ArmPkg.dsc
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
ArmPkg/Drivers/CpuDxe/Exception.c
ArmPkg/Drivers/CpuDxe/ExceptionSupport.ARMv6.S
ArmPkg/Drivers/CpuDxe/ExceptionSupport.ARMv6.asm
ArmPkg/Drivers/CpuDxe/ExceptionSupport.S
ArmPkg/Drivers/CpuDxe/Mmu.c
ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c [deleted file]
ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf [deleted file]
ArmPkg/Drivers/PL180MciDxe/PL180Mci.c [new file with mode: 0644]
ArmPkg/Drivers/PL180MciDxe/PL180Mci.h [new file with mode: 0644]
ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf [new file with mode: 0644]
ArmPkg/Drivers/PL301Axi/PL301Axi.c [new file with mode: 0644]
ArmPkg/Drivers/PL301Axi/PL301Axi.inf [new file with mode: 0644]
ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c [new file with mode: 0644]
ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf [new file with mode: 0644]
ArmPkg/Drivers/PL34xDmc/PL341Dmc.c [new file with mode: 0644]
ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf [new file with mode: 0644]
ArmPkg/Drivers/PL35xSmc/InitializeSMC.S [new file with mode: 0644]
ArmPkg/Drivers/PL35xSmc/InitializeSMC.asm [new file with mode: 0644]
ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf [new file with mode: 0644]
ArmPkg/Drivers/PL390Gic/PL390GicDxe.c [new file with mode: 0644]
ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf [new file with mode: 0644]
ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c [new file with mode: 0644]
ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf [new file with mode: 0644]
ArmPkg/Drivers/PL390Gic/PL390GicSec.c [new file with mode: 0644]
ArmPkg/Drivers/PL390Gic/PL390GicSec.inf [new file with mode: 0644]
ArmPkg/Include/Chipset/ARM1176JZ-S.h
ArmPkg/Include/Chipset/ArmV7.h
ArmPkg/Include/Drivers/PL341Dmc.h [new file with mode: 0644]
ArmPkg/Include/Drivers/PL390Gic.h [new file with mode: 0644]
ArmPkg/Include/Library/ArmLib.h
ArmPkg/Include/Library/ArmMPCoreMailBoxLib.h [new file with mode: 0644]
ArmPkg/Include/Library/ArmTrustZoneLib.h [new file with mode: 0644]
ArmPkg/Include/Library/BdsUnixLib.h [new file with mode: 0644]
ArmPkg/Include/Library/L2X0CacheLib.h [new file with mode: 0644]
ArmPkg/Include/Protocol/MmcHost.h [new file with mode: 0644]
ArmPkg/Library/ArmDmaLib/ArmDmaLib.c
ArmPkg/Library/ArmLib/Arm11/Arm11Lib.c
ArmPkg/Library/ArmLib/Arm11/Arm11Support.S
ArmPkg/Library/ArmLib/Arm9/Arm9Lib.c
ArmPkg/Library/ArmLib/Arm9/Arm9Support.S
ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.S
ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.asm
ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c
ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCore.c [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.S [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.asm [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibPrePi.inf [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c [new file with mode: 0644]
ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
ArmPkg/Library/ArmLib/Common/ArmLibSupport.S
ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm
ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBox.c [new file with mode: 0644]
ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf [new file with mode: 0644]
ArmPkg/Library/ArmTrustZoneLib/ArmTrustZone.c [new file with mode: 0644]
ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf [new file with mode: 0644]
ArmPkg/Library/BaseMemoryLibStm/Arm/CopyMem.S
ArmPkg/Library/BaseMemoryLibStm/Arm/SetMem.S
ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S
ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S
ArmPkg/Library/BasePeCoffLib/BasePeCoff.c
ArmPkg/Library/BdsLib/BdsAppLoader.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsFilePath.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsFilePathFs.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsFilePathFv.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsFilePathMem.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsHelper.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsInternal.h [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsLib.inf [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsLinuxLoader.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsLinuxLoader.h [new file with mode: 0644]
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/memcpy.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/memset.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
ArmPkg/Library/L2X0CacheLibNull/L2X0Cache.c [new file with mode: 0644]
ArmPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf [new file with mode: 0644]
ArmPkg/Universal/MmcDxe/ComponentName.c [new file with mode: 0644]
ArmPkg/Universal/MmcDxe/Diagnostics.c [new file with mode: 0644]
ArmPkg/Universal/MmcDxe/Mmc.c [new file with mode: 0644]
ArmPkg/Universal/MmcDxe/Mmc.h [new file with mode: 0644]
ArmPkg/Universal/MmcDxe/MmcBlockIo.c [new file with mode: 0644]
ArmPkg/Universal/MmcDxe/MmcDxe.inf [new file with mode: 0644]

index 0b8c101c821b7c27a45687edf513d720d5db217e..63445756d916d19ded4417c890ea8e8cde2f3286 100644 (file)
 [Protocols.common]\r
   gVirtualUncachedPagesProtocolGuid = { 0xAD651C7D, 0x3C22, 0x4DBF, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } }\r
 \r
+  ## Include/Protocol/MmcHost.h\r
+  gEfiMmcHostProtocolGuid              = { 0x3e591c00, 0x9e4a, 0x11df, {0x92, 0x44, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B }}\r
+\r
 [PcdsFeatureFlag.common]\r
   gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport|FALSE|BOOLEAN|0x00000001\r
 \r
+  # On ARM Architecture with the Security Extension, the address for the\r
+  # Vector Table can be mapped anywhere in the memory map. It means we can\r
+  # point the Exception Vector Table to its location in CpuDxe.\r
+  # By default we copy the Vector Table at  PcdGet32(PcdCpuVectorBaseAddress)\r
+  gArmTokenSpaceGuid.PcdRelocateVectorTable|TRUE|BOOLEAN|0x00000022\r
+  \r
+  gArmTokenSpaceGuid.PcdEfiUncachedMemoryToStronglyOrdered|FALSE|BOOLEAN|0x00000025\r
+  gArmTokenSpaceGuid.PcdSkipPeiCore|FALSE|BOOLEAN|0x00000026\r
+\r
 [PcdsFixedAtBuild.common]\r
+  # This PCD should be a FeaturePcd. But we used this PCD as an '#if' in an ASM file.\r
+  # Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.\r
+  gArmTokenSpaceGuid.PcdVFPEnabled|0|UINT32|0x00000024\r
+\r
   gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000080000000|UINT64|0x00000002\r
   gArmTokenSpaceGuid.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003\r
   gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xfff00000|UINT32|0x00000004\r
   gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005\r
+  \r
+  #\r
+  # ARM PL180 MCI\r
+  #\r
+  gArmTokenSpaceGuid.PcdPL180SysMciRegAddress|0x00000000|UINT32|0x00000006\r
+  gArmTokenSpaceGuid.PcdPL180MciBaseAddress|0x00000000|UINT32|0x00000007\r
+\r
+  #\r
+  # ARM PL390 General Interrupt Controller\r
+  #\r
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C\r
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D\r
+  gArmTokenSpaceGuid.PcdGicNumInterrupts|96|UINT32|0x00000023\r
+\r
+  #\r
+  # ARM Secure SEC PCDs\r
+  #\r
+  gArmTokenSpaceGuid.PcdSecureFdBaseAddress|0|UINT32|0x00000015\r
+  gArmTokenSpaceGuid.PcdSecureFdSize|0|UINT32|0x00000016\r
+\r
+  #\r
+  # ARM MPCore MailBox PCDs\r
+  #\r
+  # Address to Set/Get to Mailbox in Multicore system\r
+  gArmTokenSpaceGuid.PcdMPCoreMailboxSetAddress|0|UINT32|0x00000017\r
+  gArmTokenSpaceGuid.PcdMPCoreMailboxGetAddress|0|UINT32|0x00000018\r
+  # Address/Value to clear Mailbox in Multicore system\r
+  gArmTokenSpaceGuid.PcdMPCoreMailboxClearAddress|0|UINT32|0x00000019\r
+  gArmTokenSpaceGuid.PcdMPCoreMailboxClearValue|0|UINT32|0x0000001A\r
+\r
+  #\r
+  # ARM L2x0 PCDs\r
+  #\r
+  gArmTokenSpaceGuid.PcdL2x0ControllerBase|0|UINT32|0x0000001B\r
+  \r
+  #\r
+  # ARM PL390 General Interrupt Controller\r
+  #\r
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000001C\r
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000001D\r
+  \r
+  # \r
+  # BdsLib\r
+  #\r
+  gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E\r
+  gArmTokenSpaceGuid.PcdLinuxKernelDP|L""|VOID*|0x0000001F\r
+  gArmTokenSpaceGuid.PcdLinuxAtag|""|VOID*|0x00000020\r
+  gArmTokenSpaceGuid.PcdFdtDP|L""|VOID*|0x00000021\r
+\r
index 4185a112598d7f5d9cae5623af9058e117009c78..8cc748c849127987b06b5081385173a0edf37db1 100644 (file)
   CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
   ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
   DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
+  ArmTrustZoneLib|ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
+  ArmMPCoreMailBoxLib|ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
+  
+  PL354SmcSecLib|ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
+  PL341DmcLib|ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
+  PL301AxiLib|ArmPkg/Drivers/PL301Axi/PL301Axi.inf
+  PL310L2CacheSecLib|ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
+  
+  BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+  
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+
+[LibraryClasses.common.PEIM]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
 
 [LibraryClasses.ARM]
   NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.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/ArmDisassemblerLib/ArmDisassemblerLib.inf
+  ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
+  ArmPkg/Library/ArmLib/Arm11/Arm11ArmLib.inf
+  ArmPkg/Library/ArmLib/Arm11/Arm11ArmLibPrePi.inf
+  ArmPkg/Library/ArmLib/Arm9/Arm9ArmLib.inf
+  ArmPkg/Library/ArmLib/Arm9/Arm9ArmLibPrePi.inf
   ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
   ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
+  ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
+  ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf
+  ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibPrePi.inf
+  ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf
   ArmPkg/Library/ArmLib/Null/NullArmLib.inf
+  ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
+  ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
+  ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
+  ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
+  ArmPkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  ArmPkg/Library/BdsLib/BdsLib.inf
   ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+  ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+  ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
+  ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  ArmPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf
+  ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
   ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
   ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
   ArmPkg/Library/SemihostLib/SemihostLib.inf
   ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
-  ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
-  ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
-  ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
-  ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
 
   ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  ArmPkg/Drivers/CpuPei/CpuPei.inf
+  ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
+  ArmPkg/Drivers/PL301Axi/PL301Axi.inf
+  ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
+  ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
+  ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
+  ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+  ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf
+  ArmPkg/Drivers/PL390Gic/PL390GicSec.inf
   ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+  ArmPkg/Universal/MmcDxe/MmcDxe.inf
+
+
index 2fc5fda69156fe2375e08d715ab3876c7313dd88..25c0b880b2e5eda329e12ff6c48a12fd438505e0 100644 (file)
   gEfiDebugImageInfoTableGuid\r
 \r
 [Pcd.common]\r
+  gArmTokenSpaceGuid.PcdVFPEnabled\r
   gArmTokenSpaceGuid.PcdCpuVectorBaseAddress\r
   \r
 [FeaturePcd.common]\r
   gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport\r
+  gArmTokenSpaceGuid.PcdRelocateVectorTable\r
+  gArmTokenSpaceGuid.PcdEfiUncachedMemoryToStronglyOrdered\r
 \r
 [depex]\r
   gHardwareInterruptProtocolGuid\r
index e0aca46cd79729672c4b93e521dd30ba08ffede2..21a4c035a9a00968052174bb87622f469ff7d984 100644 (file)
@@ -14,6 +14,8 @@
 \r
 #include "CpuDxe.h" \r
 \r
+//FIXME: Will not compile on non-ARMv7 builds\r
+#include <Chipset/ArmV7.h>\r
 \r
 VOID\r
 ExceptionHandlersStart (\r
@@ -127,6 +129,7 @@ InitializeExceptions (
   EFI_PHYSICAL_ADDRESS Base;\r
   UINT32               *VectorBase;\r
 \r
+  Status = EFI_SUCCESS;\r
   //\r
   // Disable interrupts\r
   //\r
@@ -140,54 +143,63 @@ InitializeExceptions (
   FiqEnabled = ArmGetFiqState ();\r
   ArmDisableFiq ();\r
 \r
-  //\r
-  // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.\r
-  //\r
-  Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;\r
-\r
-  //\r
-  // Reserve space for the exception handlers\r
-  //\r
-  Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);\r
-  VectorBase = (UINT32 *)(UINTN)Base;\r
-  Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);\r
-  // If the request was for memory that's not in the memory map (which is often the case for 0x00000000\r
-  // on embedded systems, for example, we don't want to hang up.  So we'll check here for a status of \r
-  // EFI_NOT_FOUND, and continue in that case.\r
-  if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
-\r
-  // Save existing vector table, in case debugger is already hooked in\r
-  CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));\r
-\r
-  // Copy our assembly code into the page that contains the exception vectors. \r
-  CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);\r
-\r
-  //\r
-  // Patch in the common Assembly exception handler\r
-  //\r
-  Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;\r
-  *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;\r
-\r
-  //\r
-  // Initialize the C entry points for interrupts\r
-  //\r
-  for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {\r
-    if ((gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {\r
-      // Exception handler contains branch to vector location (jmp $) so no handler\r
-      // NOTE: This code assumes vectors are ARM and not Thumb code\r
-      Status = RegisterInterruptHandler (Index, NULL);\r
-      ASSERT_EFI_ERROR (Status);\r
-    } else {\r
-      // If the debugger has alread hooked put its vector back\r
-      VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];\r
-    }\r
+  if (FeaturePcdGet(PcdRelocateVectorTable) == TRUE) {\r
+      //\r
+      // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.\r
+      //\r
+      Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;\r
+    \r
+      //\r
+      // Reserve space for the exception handlers\r
+      //\r
+      Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);\r
+      VectorBase = (UINT32 *)(UINTN)Base;\r
+      Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);\r
+      // If the request was for memory that's not in the memory map (which is often the case for 0x00000000\r
+      // on embedded systems, for example, we don't want to hang up.  So we'll check here for a status of \r
+      // EFI_NOT_FOUND, and continue in that case.\r
+      if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
+    \r
+      // Save existing vector table, in case debugger is already hooked in\r
+      CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));\r
+    \r
+      // Copy our assembly code into the page that contains the exception vectors. \r
+      CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);\r
+    \r
+      //\r
+      // Patch in the common Assembly exception handler\r
+      //\r
+      Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;\r
+      *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;\r
+    \r
+      //\r
+      // Initialize the C entry points for interrupts\r
+      //\r
+      for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {\r
+        if ((gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {\r
+          // Exception handler contains branch to vector location (jmp $) so no handler\r
+          // NOTE: This code assumes vectors are ARM and not Thumb code\r
+          Status = RegisterInterruptHandler (Index, NULL);\r
+          ASSERT_EFI_ERROR (Status);\r
+        } else {\r
+          // If the debugger has alread hooked put its vector back\r
+          VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];\r
+        }\r
+      }\r
+    \r
+      // Flush Caches since we updated executable stuff\r
+      InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);\r
+\r
+      //Note: On ARM processor with the Security Extension, the Vector Table can be located anywhere in the memory.\r
+      //      The Vector Base Address Register defines the location\r
+      ArmWriteVBar(PcdGet32(PcdCpuVectorBaseAddress));\r
+  } else {\r
+    // We do not copy the Exception Table at PcdGet32(PcdCpuVectorBaseAddress). We just set Vector Base Address to point into CpuDxe code.\r
+    ArmWriteVBar((UINT32)ExceptionHandlersStart);\r
   }\r
 \r
-  // Flush Caches since we updated executable stuff\r
-  InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);\r
-\r
   if (FiqEnabled) {\r
     ArmEnableFiq ();\r
   }\r
index 1c2bb62605f297053d7956f7867c47938a91ed58..86d2a7135fce84a62b8c90bc01ead955effa2f47 100644 (file)
@@ -14,6 +14,8 @@
 #
 #------------------------------------------------------------------------------
 
+#include <Library/PcdLib.h>
+
 /*
 
 This is the stack constructed by the exception handler (low address to high address)
@@ -50,22 +52,17 @@ This is the stack constructed by the exception handler (low address to high addr
  */
  
 
-.globl ASM_PFX(ExceptionHandlersStart)
-INTERWORK_FUNC(ExceptionHandlersStart)
-.globl ASM_PFX(ExceptionHandlersEnd)
-INTERWORK_FUNC(ExceptionHandlersEnd)
-.globl ASM_PFX(CommonExceptionEntry)
-INTERWORK_FUNC(CommonExceptionEntry)
-.globl ASM_PFX(AsmCommonExceptionEntry)
-INTERWORK_FUNC(AsmCommonExceptionEntry)
-.globl ASM_PFX(CommonCExceptionHandler)
-INTERWORK_FUNC(CommonCExceptionHandler)
+GCC_ASM_EXPORT(ExceptionHandlersStart)
+GCC_ASM_EXPORT(ExceptionHandlersEnd)
+GCC_ASM_EXPORT(CommonExceptionEntry)
+GCC_ASM_EXPORT(AsmCommonExceptionEntry)
+GCC_ASM_EXPORT(CommonCExceptionHandler)
 
 .text
 #if !defined(__APPLE__)
 .fpu neon    @ makes vpush/vpop assemble
 #endif
-.align 3
+.align 5
 
 
 //
@@ -198,10 +195,7 @@ ASM_PFX(FiqEntry):
 // This gets patched by the C code that patches in the vector table
 //
 ASM_PFX(CommonExceptionEntry):
-  .byte       0x12
-  .byte       0x34
-  .byte       0x56
-  .byte       0x78
+  .word       ASM_PFX(AsmCommonExceptionEntry)
 
 ASM_PFX(ExceptionHandlersEnd):
 
@@ -254,8 +248,9 @@ NoAdjustNeeded:
                                     @ R0 is ExceptionType 
   mov       R1,SP                   @ R1 is SystemContext 
 
+#if (FixedPcdGet32(PcdVFPEnabled))
   vpush     {d0-d15}                @ save vstm registers in case they are used in optimizations
-
+#endif
 
 /* 
 VOID
@@ -268,7 +263,9 @@ CommonCExceptionHandler (
 */  
   blx       ASM_PFX(CommonCExceptionHandler)  @ Call exception handler
 
+#if (FixedPcdGet32(PcdVFPEnabled))
   vpop      {d0-d15}  
+#endif
 
   ldr       R1, [SP, #0x4c]         @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
   mcr       p15, 0, R1, c5, c0, 1   @ Write IFSR
index a8a477026eeb1636bd949f1ee8a2e72b13fefd58..240e1e38ae7d788331c1a57a067fbd50acb582b4 100644 (file)
@@ -14,7 +14,7 @@
 //
 //------------------------------------------------------------------------------
 
-
+#include <Library/PcdLib.h>
 
 /*
 
@@ -61,6 +61,8 @@ This is the stack constructed by the exception handler (low address to high addr
   PRESERVE8
   AREA  DxeExceptionHandlers, CODE, READONLY
   
+  ALIGN   32
+  
 //
 // This code gets copied to the ARM vector table
 // ExceptionHandlersStart - ExceptionHandlersEnd gets copied
@@ -190,7 +192,7 @@ FiqEntry
 // This gets patched by the C code that patches in the vector table
 //
 CommonExceptionEntry
-  dcd       0x12345678
+  dcd       AsmCommonExceptionEntry
 
 ExceptionHandlersEnd
 
@@ -243,7 +245,9 @@ NoAdjustNeeded
                                     ; R0 is ExceptionType 
   mov       R1,SP                   ; R1 is SystemContext 
 
+#if (FixedPcdGet32(PcdVFPEnabled))
   vpush    {d0-d15}                  ; save vstm registers in case they are used in optimizations\r
+#endif
 
 /* 
 VOID
@@ -256,7 +260,9 @@ CommonCExceptionHandler (
 */
   blx       CommonCExceptionHandler ; Call exception handler
 \r
+#if (FixedPcdGet32(PcdVFPEnabled))
   vpop      {d0-d15}\r
+#endif
   
   ldr       R1, [SP, #0x4c]         ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
   mcr       p15, 0, R1, c5, c0, 1   ; Write IFSR
index 223a383d3608916b35d2b1dfedeed381c8a7610b..96bd68246f91a65fd0eb66e01df2c354ad654549 100644 (file)
 .text
 .align 3
 
-.globl ASM_PFX(ExceptionHandlersStart)
-.globl ASM_PFX(ExceptionHandlersEnd)
-.globl ASM_PFX(CommonExceptionEntry)
-.globl ASM_PFX(AsmCommonExceptionEntry)
-.globl ASM_PFX(CommonCExceptionHandler)
+GCC_ASM_EXPORT(ExceptionHandlersStart)
+GCC_ASM_EXPORT(ExceptionHandlersEnd)
+GCC_ASM_EXPORT(CommonExceptionEntry)
+GCC_ASM_EXPORT(AsmCommonExceptionEntry)
+GCC_ASM_EXPORT(CommonCExceptionHandler)
 
 ASM_PFX(ExceptionHandlersStart):
 
index 3662e739e34500d93f5da192a36792e680a527b9..d7ea0eb551fb17165ff084964837166f218605c5 100644 (file)
@@ -15,129 +15,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 --*/\r
 \r
 #include "CpuDxe.h"\r
-\r
-\r
-//\r
-// Translation/page table definitions\r
-//\r
+//FIXME: Remove this ARMv7 specific header\r
+#include <Chipset/ArmV7.h>\r
 \r
 // First Level Descriptors\r
 typedef UINT32    ARM_FIRST_LEVEL_DESCRIPTOR;\r
 \r
-// memory space covered by a first level descriptor\r
-#define ARM_PAGE_DESC_ENTRY_MVA_SIZE  0x00100000  // 1MB\r
-\r
-// number of first level descriptors to cover entire 32-bit memory space\r
-#define FIRST_LEVEL_ENTRY_COUNT       (0xFFFFFFFF / ARM_PAGE_DESC_ENTRY_MVA_SIZE + 1)\r
-\r
-\r
-// page table 1st level descriptor entries\r
-#define ARM_PAGE_DESC_BASE_MASK       0xFFFFFC00\r
-#define ARM_PAGE_DESC_BASE_SHFIT      10\r
-#define ARM_PAGE_DESC_DOMAIN_MASK     0x000001E0\r
-#define ARM_PAGE_DESC_DOMAIN_SHIFT    5\r
-#define ARM_PAGE_DESC_NS              0x00000008\r
-\r
-#define ARM_FIRST_LEVEL_DESC_ALIGN    0x00004000  // 16KB\r
-\r
-// section 1st level desriptor entries\r
-#define ARM_SECTION_BASE_MASK         0xFFF00000\r
-#define ARM_SECTION_BASE_SHIFT        20\r
-#define ARM_SECTION_NS                0x00080000\r
-#define ARM_SECTION_nG                0x00020000\r
-#define ARM_SECTION_S                 0x00010000\r
-#define ARM_SECTION_AP2               0x00008000\r
-#define ARM_SECTION_TEX_MASK          0x00007000\r
-#define ARM_SECTION_TEX_SHIFT         12\r
-#define ARM_SECTION_AP10_MASK         0x00000C00\r
-#define ARM_SECTION_AP10_SHIFT        10\r
-#define ARM_SECTION_DOMAIN_MASK       0x000001E0\r
-#define ARM_SECTION_DOMAIN_SHIFT      5\r
-#define ARM_SECTION_XN                0x00000010\r
-#define ARM_SECTION_C                 0x00000008\r
-#define ARM_SECTION_B                 0x00000004\r
-\r
-// section level AP[2:0] definitions\r
-#define ARM_SECTION_AP_NO_ACCESS      0   // AP[2:0] = 0\r
-#define ARM_SECTION_AP_READ_WRITE     ARM_SECTION_AP10_MASK // AP[2:0] = 011\r
-#define ARM_SECTION_AP_READ_ONLY      (ARM_SECTION_AP2 | ARM_SECTION_AP10_MASK) // AP[2:0] = 111\r
-\r
-// common 1st level descriptor fields\r
-#define ARM_DESC_TYPE_MASK            0x00000003\r
-\r
-// descriptor type values\r
-#define ARM_DESC_TYPE_FAULT           0x0\r
-#define ARM_DESC_TYPE_PAGE_TABLE      0x1\r
-#define ARM_DESC_TYPE_SECTION         0x2\r
-\r
-\r
 // Second Level Descriptors\r
 typedef UINT32    ARM_PAGE_TABLE_ENTRY;\r
 \r
-// small page 2nd level descriptor entries\r
-#define ARM_SMALL_PAGE_BASE_MASK      0xFFFFF000\r
-#define ARM_SMALL_PAGE_INDEX_MASK     0x000FF000\r
-#define ARM_SMALL_PAGE_BASE_SHIFT     12\r
-#define ARM_SMALL_PAGE_TEX_MASK       0x000001C0\r
-#define ARM_SMALL_PAGE_TEX_SHIFT      6\r
-#define ARM_SMALL_PAGE_XN             0x00000001\r
-\r
-// large page 2nd level descriptor entries\r
-#define ARM_LARGE_PAGE_BASE_MASK      0xFFFF0000\r
-#define ARM_LARGE_PAGE_BASE_SHIFT     16\r
-#define ARM_LARGE_PAGE_TEX_MASK       0x00007000\r
-#define ARM_LARGE_PAGE_TEX_SHIFT      12\r
-#define ARM_LARGE_PAGE_XN             0x00008000\r
-\r
-// common 2nd level desriptor fields\r
-#define ARM_PAGE_nG                   0x00000800\r
-#define ARM_PAGE_S                    0x00000400\r
-#define ARM_PAGE_AP2                  0x00000200\r
-#define ARM_PAGE_AP10_MASK            0x00000030\r
-#define ARM_PAGE_AP10_SHIFT           4\r
-#define ARM_PAGE_C                    0x00000008\r
-#define ARM_PAGE_B                    0x00000004\r
-#define ARM_PAGE_DESC_TYPE_MASK       0x00000003\r
-\r
-// descriptor type values\r
-#define ARM_PAGE_TYPE_FAULT           0x0\r
-#define ARM_PAGE_TYPE_LARGE           0x1\r
-#define ARM_PAGE_TYPE_SMALL           0x2\r
-#define ARM_PAGE_TYPE_SMALL_XN        0x3\r
-\r
-#define SMALL_PAGE_TABLE_ENTRY_COUNT  (ARM_PAGE_DESC_ENTRY_MVA_SIZE / SIZE_4KB)\r
-\r
-\r
-// Translation Table Base 0 fields\r
-#define ARM_TTBR0_BASE_MASK           0xFFFFC000\r
-#define ARM_TTBR0_BASE_SHIFT          14\r
-#define ARM_TTRB0_NOS                 0x00000020\r
-\r
-// define the combination of interesting attributes: cacheability and access permissions\r
-#define ARM_SECTION_CACHEABILITY_MASK   ( ARM_SECTION_TEX_MASK | ARM_SECTION_C | ARM_SECTION_B )\r
-#define ARM_SECTION_RW_PERMISSIONS_MASK ( ARM_SECTION_AP2 | ARM_SECTION_AP10_MASK )\r
-#define ARM_DESCRIPTOR_ATTRIBUTES       ( ARM_SECTION_CACHEABILITY_MASK | ARM_SECTION_RW_PERMISSIONS_MASK | ARM_SECTION_XN )\r
-\r
-// cacheability values for section entries\r
-#define ARM_SECTION_STRONGLY_ORDERED    0\r
-#define ARM_SECTION_SHAREABLE_DEVICE    ARM_SECTION_B\r
-#define ARM_SECTION_WRITE_THROUGH       ARM_SECTION_C\r
-#define ARM_SECTION_WRITE_BACK_NWA      ( ARM_SECTION_C| ARM_SECTION_B )\r
-#define ARM_SECTION_NORMAL_UNCACHEABLE  ( 0x1 << ARM_SECTION_TEX_SHIFT )\r
-#define ARM_SECTION_WRITE_BACK          ( ( 0x1 << ARM_SECTION_TEX_SHIFT ) | ARM_SECTION_C | ARM_SECTION_B )\r
-#define ARM_SECTION_NONSHAREABLE_DEVICE ( 0x2 << ARM_SECTION_TEX_SHIFT )\r
-\r
-// permissions values for section entries\r
-#define ARM_SECTION_NO_ACCESS           0\r
-#define ARM_SECTION_PRIV_ACCESS_ONLY    ( 0x1 << ARM_SECTION_AP10_SHIFT)\r
-#define ARM_SECTION_USER_READ_ONLY      ( 0x2 << ARM_SECTION_AP10_SHIFT)\r
-#define ARM_SECTION_FULL_ACCESS         ( 0x3 << ARM_SECTION_AP10_SHIFT)\r
-#define ARM_SECTION_PRIV_READ_ONLY      ( ARM_SECTION_AP2 | (0x1 << ARM_SECTION_AP10_SHIFT) )\r
-#define ARM_SECTION_READ_ONLY_DEP       ( ARM_SECTION_AP2 | (0x2 << ARM_SECTION_AP10_SHIFT) )\r
-#define ARM_SECTION_READ_ONLY           ( ARM_SECTION_AP2 | (0x3 << ARM_SECTION_AP10_SHIFT) )\r
-\r
-\r
-\r
 EFI_STATUS \r
 SectionToGcdAttributes (\r
   IN  UINT32  SectionAttributes,\r
@@ -147,47 +33,46 @@ SectionToGcdAttributes (
   *GcdAttributes = 0;\r
 \r
   // determine cacheability attributes\r
-  switch(SectionAttributes & ARM_SECTION_CACHEABILITY_MASK) {\r
-    case ARM_SECTION_STRONGLY_ORDERED:\r
+  switch(SectionAttributes & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) {\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED:\r
       *GcdAttributes |= EFI_MEMORY_UC;\r
       break;\r
-    case ARM_SECTION_SHAREABLE_DEVICE:\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE:\r
       *GcdAttributes |= EFI_MEMORY_UC;\r
       break;\r
-    case ARM_SECTION_WRITE_THROUGH:\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:\r
       *GcdAttributes |= EFI_MEMORY_WT;\r
       break;\r
-    case ARM_SECTION_WRITE_BACK_NWA:\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC:\r
       *GcdAttributes |= EFI_MEMORY_WB;\r
       break;\r
-    case ARM_SECTION_NORMAL_UNCACHEABLE:\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE:\r
       *GcdAttributes |= EFI_MEMORY_WC;\r
       break;\r
-    case ARM_SECTION_WRITE_BACK:\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC:\r
       *GcdAttributes |= EFI_MEMORY_WB;\r
       break;\r
-    case ARM_SECTION_NONSHAREABLE_DEVICE:\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE:\r
       *GcdAttributes |= EFI_MEMORY_UC;\r
       break;\r
     default:\r
       return EFI_UNSUPPORTED;\r
   }\r
-    \r
+\r
   // determine protection attributes\r
-  switch(SectionAttributes & ARM_SECTION_RW_PERMISSIONS_MASK) {\r
-    case ARM_SECTION_NO_ACCESS: // no read, no write\r
+  switch(SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) {\r
+    case TT_DESCRIPTOR_SECTION_AP_NO_NO: // no read, no write\r
       //*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;\r
       break;\r
 \r
-    case ARM_SECTION_PRIV_ACCESS_ONLY:\r
-    case ARM_SECTION_FULL_ACCESS:\r
+    case TT_DESCRIPTOR_SECTION_AP_RW_NO:\r
+    case TT_DESCRIPTOR_SECTION_AP_RW_RW:\r
       // normal read/write access, do not add additional attributes\r
       break;\r
 \r
     // read only cases map to write-protect\r
-    case ARM_SECTION_PRIV_READ_ONLY:\r
-    case ARM_SECTION_READ_ONLY_DEP:\r
-    case ARM_SECTION_READ_ONLY:\r
+    case TT_DESCRIPTOR_SECTION_AP_RO_NO:\r
+    case TT_DESCRIPTOR_SECTION_AP_RO_RO:\r
       *GcdAttributes |= EFI_MEMORY_WP;\r
       break;\r
 \r
@@ -196,7 +81,7 @@ SectionToGcdAttributes (
   }\r
 \r
   // now process eXectue Never attribute\r
-  if ((SectionAttributes & ARM_SECTION_XN) != 0 ) {\r
+  if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {\r
     *GcdAttributes |= EFI_MEMORY_XP;\r
   }\r
 \r
@@ -369,22 +254,22 @@ SyncCacheConfig (
   // with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead.\r
 \r
   // obtain page table base\r
-  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTranslationTableBaseAddress ());\r
+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());\r
 \r
 \r
   // iterate through each 1MB descriptor\r
   NextRegionBase = NextRegionLength = 0;\r
-  for (i=0; i< FIRST_LEVEL_ENTRY_COUNT; i++) {\r
+  for (i=0; i< TRANSLATION_TABLE_SECTION_COUNT; i++) {\r
 \r
     // obtain existing descriptor and make sure it contains a valid Base Address even if it is a fault section\r
-    Descriptor = FirstLevelTable[i] | (ARM_SECTION_BASE_MASK & (i << ARM_SECTION_BASE_SHIFT));\r
+    Descriptor = FirstLevelTable[i] | TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
 \r
     // extract attributes (cacheability and permissions)\r
-    SectionAttributes = Descriptor & 0xDEC;\r
+    SectionAttributes = Descriptor & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);\r
 \r
     // do we already have an existing region (or are we about to finish)?\r
     // Skip the first entry, and make sure we close on the last entry\r
-    if ( (NextRegionLength > 0) || (i == (FIRST_LEVEL_ENTRY_COUNT-1)) ) {\r
+    if ( (NextRegionLength > 0) || (i == (TRANSLATION_TABLE_SECTION_COUNT-1)) ) {\r
       // attributes are changing, update attributes in GCD\r
       if (SectionAttributes != NextRegionAttributes) {\r
         \r
@@ -398,7 +283,7 @@ SyncCacheConfig (
 \r
         // start on a new region\r
         NextRegionLength = 0;\r
-        NextRegionBase = Descriptor & ARM_SECTION_BASE_MASK;\r
+        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(Descriptor);\r
       }\r
     }\r
 \r
@@ -407,7 +292,7 @@ SyncCacheConfig (
       NextRegionAttributes = SectionAttributes;\r
     }\r
 \r
-    NextRegionLength += ARM_PAGE_DESC_ENTRY_MVA_SIZE;\r
+    NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;\r
 \r
   } // section entry loop\r
 \r
@@ -444,37 +329,42 @@ UpdatePageEntries (
 \r
   // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)\r
   // EntryValue: values at bit positions specified by EntryMask\r
-  EntryMask = ARM_PAGE_DESC_TYPE_MASK;\r
-  EntryValue = ARM_PAGE_TYPE_SMALL;\r
+  EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK;\r
+  EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;\r
   // Although the PI spec is unclear on this the GCD guarantees that only\r
   // one Attribute bit is set at a time, so we can safely use a switch statement\r
   switch (Attributes) {\r
     case EFI_MEMORY_UC:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;\r
-      // map to strongly ordered\r
-      EntryValue |= 0; // TEX[2:0] = 0, C=0, B=0\r
+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
+      if (FeaturePcdGet(PcdEfiUncachedMemoryToStronglyOrdered)) {\r
+                   // map to strongly ordered\r
+                   EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
+      } else {\r
+         // map to normal non-cachable\r
+         EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0\r
+      }\r
       break;\r
 \r
     case EFI_MEMORY_WC:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;\r
+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
       // map to normal non-cachable\r
-      EntryValue |= (0x1 << ARM_SMALL_PAGE_TEX_SHIFT); // TEX [2:0]= 001 = 0x2, B=0, C=0\r
+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0\r
       break;\r
 \r
     case EFI_MEMORY_WT:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;\r
+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
       // write through with no-allocate\r
-      EntryValue |= ARM_PAGE_C; // TEX [2:0] = 0, C=1, B=0\r
+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0\r
       break;\r
 \r
     case EFI_MEMORY_WB:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SMALL_PAGE_TEX_MASK | ARM_PAGE_C | ARM_PAGE_B;\r
+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
       // write back (with allocate)\r
-      EntryValue |= (0x1 << ARM_SMALL_PAGE_TEX_SHIFT) | ARM_PAGE_C | ARM_PAGE_B; // TEX [2:0] = 001, C=1, B=1\r
+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1\r
       break;\r
 \r
     case EFI_MEMORY_WP:\r
@@ -482,7 +372,7 @@ UpdatePageEntries (
     case EFI_MEMORY_UCE:\r
       // cannot be implemented UEFI definition unclear for ARM\r
       // Cause a page fault if these ranges are accessed.\r
-      EntryValue = ARM_PAGE_TYPE_FAULT;\r
+      EntryValue = TT_DESCRIPTOR_PAGE_TYPE_FAULT;\r
       DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));\r
       break;\r
 \r
@@ -491,7 +381,7 @@ UpdatePageEntries (
   }\r
 \r
   // obtain page table base\r
-  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();\r
+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
 \r
   // calculate number of 4KB page table entries to change\r
   NumPageEntries = Length/SIZE_4KB;\r
@@ -501,15 +391,15 @@ UpdatePageEntries (
   for(p=0; p<NumPageEntries; p++) {\r
     // calculate index into first level translation table for page table value\r
     \r
-    FirstLevelIdx = ((BaseAddress + Offset) & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;\r
-    ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);\r
+    FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;\r
+    ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);\r
 \r
     // read the descriptor from the first level page table\r
     Descriptor = FirstLevelTable[FirstLevelIdx];\r
 \r
     // does this descriptor need to be converted from section entry to 4K pages?\r
-    if ((Descriptor & ARM_DESC_TYPE_MASK) != ARM_DESC_TYPE_PAGE_TABLE ) {\r
-      Status = ConvertSectionToPages (FirstLevelIdx << ARM_SECTION_BASE_SHIFT);\r
+    if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {\r
+      Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
       if (EFI_ERROR(Status)) {\r
         // exit for loop\r
         break; \r
@@ -520,11 +410,11 @@ UpdatePageEntries (
     }\r
 \r
     // obtain page table base address\r
-    PageTable = (ARM_PAGE_TABLE_ENTRY *)(Descriptor & ARM_SMALL_PAGE_BASE_MASK);\r
+    PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);\r
 \r
     // calculate index into the page table\r
-    PageTableIndex = ((BaseAddress + Offset) & ARM_SMALL_PAGE_INDEX_MASK) >> ARM_SMALL_PAGE_BASE_SHIFT;\r
-    ASSERT (PageTableIndex < SMALL_PAGE_TABLE_ENTRY_COUNT);\r
+    PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;\r
+    ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);\r
 \r
     // get the entry\r
     CurrentPageTableEntry = PageTable[PageTableIndex];\r
@@ -541,8 +431,8 @@ UpdatePageEntries (
     }\r
    \r
     if (CurrentPageTableEntry  != PageTableEntry) {\r
-      Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << ARM_SECTION_BASE_SHIFT) + (PageTableIndex << ARM_SMALL_PAGE_BASE_SHIFT));\r
-      if ((CurrentPageTableEntry & ARM_PAGE_C) == ARM_PAGE_C) {\r
+      Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));\r
+      if ((CurrentPageTableEntry & TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) == TT_DESCRIPTOR_PAGE_CACHEABLE_MASK) {\r
         // The current section mapping is cacheable so Clean/Invalidate the MVA of the page\r
         // Note assumes switch(Attributes), not ARMv7 possibilities\r
         WriteBackInvalidateDataCacheRange (Mva, SIZE_4KB);\r
@@ -586,38 +476,43 @@ UpdateSectionEntries (
   // EntryValue: values at bit positions specified by EntryMask\r
 \r
   // Make sure we handle a section range that is unmapped \r
-  EntryMask = ARM_DESC_TYPE_MASK;\r
-  EntryValue = ARM_DESC_TYPE_SECTION;\r
+  EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK;\r
+  EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;\r
 \r
   // Although the PI spec is unclear on this the GCD guarantees that only\r
   // one Attribute bit is set at a time, so we can safely use a switch statement\r
   switch(Attributes) {\r
     case EFI_MEMORY_UC:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SECTION_CACHEABILITY_MASK;\r
-      // map to strongly ordered\r
-      EntryValue |= 0; // TEX[2:0] = 0, C=0, B=0\r
+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
+      if (FeaturePcdGet(PcdEfiUncachedMemoryToStronglyOrdered)) {\r
+                   // map to strongly ordered\r
+                   EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
+      } else {\r
+         // map to normal non-cachable\r
+         EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0\r
+      }\r
       break;\r
 \r
     case EFI_MEMORY_WC:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SECTION_CACHEABILITY_MASK;\r
+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
       // map to normal non-cachable\r
-      EntryValue |= (0x1 << ARM_SECTION_TEX_SHIFT); // TEX [2:0]= 001 = 0x2, B=0, C=0\r
+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0\r
       break;\r
 \r
     case EFI_MEMORY_WT:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SECTION_CACHEABILITY_MASK;\r
+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
       // write through with no-allocate\r
-      EntryValue |= ARM_SECTION_C; // TEX [2:0] = 0, C=1, B=0\r
+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0\r
       break;\r
 \r
     case EFI_MEMORY_WB:\r
       // modify cacheability attributes\r
-      EntryMask |= ARM_SECTION_CACHEABILITY_MASK;\r
+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
       // write back (with allocate)\r
-      EntryValue |= (0x1 << ARM_SECTION_TEX_SHIFT) | ARM_SECTION_C | ARM_SECTION_B; // TEX [2:0] = 001, C=1, B=1\r
+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1\r
       break;\r
 \r
     case EFI_MEMORY_WP:\r
@@ -626,7 +521,7 @@ UpdateSectionEntries (
     case EFI_MEMORY_UCE:\r
       // cannot be implemented UEFI definition unclear for ARM\r
       // Cause a page fault if these ranges are accessed.\r
-      EntryValue = ARM_DESC_TYPE_FAULT;\r
+      EntryValue = TT_DESCRIPTOR_SECTION_TYPE_FAULT;\r
       DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes));\r
       break;\r
 \r
@@ -636,23 +531,23 @@ UpdateSectionEntries (
   }\r
 \r
   // obtain page table base\r
-  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();\r
+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
 \r
   // calculate index into first level translation table for start of modification\r
-  FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;\r
-  ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);\r
+  FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;\r
+  ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);\r
 \r
   // calculate number of 1MB first level entries this applies to\r
-  NumSections = Length / ARM_PAGE_DESC_ENTRY_MVA_SIZE;\r
+  NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;\r
   \r
   // iterate through each descriptor\r
   for(i=0; i<NumSections; i++) {\r
     CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];\r
 \r
     // has this descriptor already been coverted to pages?\r
-    if ((CurrentDescriptor & ARM_DESC_TYPE_MASK) != ARM_DESC_TYPE_PAGE_TABLE ) {\r
+    if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {\r
       // forward this 1MB range to page table function instead\r
-      Status = UpdatePageEntries ((FirstLevelIdx + i) << ARM_SECTION_BASE_SHIFT, ARM_PAGE_DESC_ENTRY_MVA_SIZE, Attributes, VirtualMask);\r
+      Status = UpdatePageEntries ((FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, TT_DESCRIPTOR_SECTION_SIZE, Attributes, VirtualMask);\r
     } else {\r
       // still a section entry\r
       \r
@@ -666,8 +561,8 @@ UpdateSectionEntries (
       }\r
 \r
       if (CurrentDescriptor  != Descriptor) {\r
-        Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << ARM_SECTION_BASE_SHIFT);\r
-        if ((CurrentDescriptor & ARM_SECTION_C) == ARM_SECTION_C) {\r
+        Mva = (VOID *)(UINTN)(((UINTN)FirstLevelTable) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
+        if ((CurrentDescriptor & TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) == TT_DESCRIPTOR_SECTION_CACHEABLE_MASK) {\r
           // The current section mapping is cacheable so Clean/Invalidate the MVA of the section\r
           // Note assumes switch(Attributes), not ARMv7 possabilities\r
           WriteBackInvalidateDataCacheRange (Mva, SIZE_1MB);\r
@@ -704,35 +599,20 @@ ConvertSectionToPages (
   DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));\r
 \r
   // obtain page table base\r
-  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress ();\r
+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
 \r
   // calculate index into first level translation table for start of modification\r
-  FirstLevelIdx = (BaseAddress & ARM_SECTION_BASE_MASK) >> ARM_SECTION_BASE_SHIFT;\r
-  ASSERT (FirstLevelIdx < FIRST_LEVEL_ENTRY_COUNT);\r
+  FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;\r
+  ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);\r
 \r
   // get section attributes and convert to page attributes\r
   SectionDescriptor = FirstLevelTable[FirstLevelIdx];\r
-  PageDescriptor = ARM_PAGE_TYPE_SMALL;\r
-  PageDescriptor |= ((SectionDescriptor & ARM_SECTION_TEX_MASK) >> ARM_SECTION_TEX_SHIFT) << ARM_SMALL_PAGE_TEX_SHIFT;\r
-  if ((SectionDescriptor & ARM_SECTION_B) != 0) {\r
-    PageDescriptor |= ARM_PAGE_B;\r
-  }\r
-  if ((SectionDescriptor & ARM_SECTION_C) != 0) {\r
-    PageDescriptor |= ARM_PAGE_C;\r
-  }\r
-  PageDescriptor |= ((SectionDescriptor & ARM_SECTION_AP10_MASK) >> ARM_SECTION_AP10_SHIFT) << ARM_PAGE_AP10_SHIFT;\r
-  if ((SectionDescriptor & ARM_SECTION_AP2) != 0) {\r
-    PageDescriptor |= ARM_PAGE_AP2;\r
-  }\r
-  if ((SectionDescriptor & ARM_SECTION_XN) != 0) {\r
-    PageDescriptor |= ARM_PAGE_TYPE_SMALL_XN;\r
-  }\r
-  if ((SectionDescriptor & ARM_SECTION_nG) != 0) {\r
-    PageDescriptor |= ARM_PAGE_nG;\r
-  }\r
-  if ((SectionDescriptor & ARM_SECTION_S) != 0) {\r
-    PageDescriptor |= ARM_PAGE_S;\r
-  }\r
+  PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE;\r
+  PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(SectionDescriptor,0);\r
+  PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(SectionDescriptor);\r
+  PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(SectionDescriptor,0);\r
+  PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(SectionDescriptor);\r
+  PageDescriptor |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S(SectionDescriptor);\r
 \r
   // allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)\r
   Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, 1, &PageTableAddr);\r
@@ -743,15 +623,15 @@ ConvertSectionToPages (
   PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;\r
 \r
   // write the page table entries out\r
-  for (i=0; i<(ARM_PAGE_DESC_ENTRY_MVA_SIZE/SIZE_4KB); i++) {\r
-    PageTable[i] = ((BaseAddress + (i << 12)) & ARM_SMALL_PAGE_BASE_MASK) | PageDescriptor;\r
+  for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {\r
+    PageTable[i] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (i << 12)) | PageDescriptor;\r
   }\r
 \r
   // flush d-cache so descriptors make it back to uncached memory for subsequent table walks\r
   WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, SIZE_4KB);\r
 \r
   // formulate page table entry, Domain=0, NS=0\r
-  PageTableDescriptor = (((UINTN)PageTableAddr) & ARM_PAGE_DESC_BASE_MASK) | ARM_DESC_TYPE_PAGE_TABLE;\r
+  PageTableDescriptor = (((UINTN)PageTableAddr) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;\r
 \r
   // write the page table entry out, repalcing section entry\r
   FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;\r
@@ -910,7 +790,3 @@ VIRTUAL_UNCACHED_PAGES_PROTOCOL  gVirtualUncachedPages = {
   CpuConvertPagesToUncachedVirtualAddress,\r
   CpuReconvertPages\r
 };\r
-\r
-\r
-\r
-\r
diff --git a/ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c b/ArmPkg/Drivers/DebugSupportDxe/DebugSupport.c
deleted file mode 100644 (file)
index 5498aab..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/** @file\r
-\r
-  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-  \r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Uefi.h>\r
-\r
-#include <Library/CacheMaintenanceLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-\r
-#include <Protocol/Cpu.h>\r
-#include <Protocol/DebugSupport.h>\r
-#include <Protocol/TimerDebugSupport.h>\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-DebugSupportGetMaximumProcessorIndex (\r
-  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,\r
-  OUT UINTN                       *MaxProcessorIndex\r
-  )\r
-{\r
-  if (MaxProcessorIndex == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  *MaxProcessorIndex = 0;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-DebugSupportRegisterPeriodicCallback (\r
-  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,\r
-  IN  UINTN                       ProcessorIndex,\r
-  IN  EFI_PERIODIC_CALLBACK       PeriodicCallback\r
-  )\r
-{\r
-  TIMER_DEBUG_SUPPORT_PROTOCOL  *Timer;\r
-  EFI_STATUS                    Status;\r
-\r
-  Status = gBS->LocateProtocol(&gTimerDebugSupportProtocolGuid, NULL, (VOID **)&Timer);\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = Timer->RegisterPeriodicCallback(Timer, PeriodicCallback);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-DebugSupportRegisterExceptionCallback (\r
-  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,\r
-  IN  UINTN                       ProcessorIndex,\r
-  IN  EFI_EXCEPTION_CALLBACK      ExceptionCallback,\r
-  IN  EFI_EXCEPTION_TYPE          ExceptionType\r
-  )\r
-{\r
-  EFI_CPU_ARCH_PROTOCOL *Cpu;\r
-  EFI_STATUS            Status;\r
-\r
-  Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = Cpu->RegisterInterruptHandler(Cpu, ExceptionType, (EFI_CPU_INTERRUPT_HANDLER)ExceptionCallback);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-DebugSupportInvalidateInstructionCache (\r
-  IN  EFI_DEBUG_SUPPORT_PROTOCOL  *This,\r
-  IN  UINTN                       ProcessorIndex,\r
-  IN  VOID                        *Start,\r
-  IN  UINT64                      Length\r
-  )\r
-{\r
-  InvalidateInstructionCacheRange(Start, Length);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_DEBUG_SUPPORT_PROTOCOL  mDebugSupport = {\r
-  IsaArm,\r
-  DebugSupportGetMaximumProcessorIndex,\r
-  DebugSupportRegisterPeriodicCallback,\r
-  DebugSupportRegisterExceptionCallback,\r
-  DebugSupportInvalidateInstructionCache\r
-};\r
-\r
-EFI_STATUS\r
-DebugSupportDxeInitialize (\r
-  IN EFI_HANDLE         ImageHandle,\r
-  IN EFI_SYSTEM_TABLE   *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_HANDLE  Handle = NULL;\r
-\r
-  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiDebugSupportProtocolGuid);\r
-  Status = gBS->InstallMultipleProtocolInterfaces(&Handle, &gEfiDebugSupportProtocolGuid, &mDebugSupport, NULL);\r
-\r
-  return Status;\r
-}\r
-\r
diff --git a/ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf b/ArmPkg/Drivers/DebugSupportDxe/DebugSupportDxe.inf
deleted file mode 100644 (file)
index 31310fc..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#/** @file\r
-#  \r
-#  DXE CPU driver\r
-#  \r
-#  Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>\r
-#  This program and the accompanying materials\r
-#  are licensed and made available under the terms and conditions of the BSD License\r
-#  which accompanies this distribution.  The full text of the license may be found at\r
-#  http://opensource.org/licenses/bsd-license.php\r
-#  \r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#  \r
-#**/\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = ArmDebugSupportDxe\r
-  FILE_GUID                      = 2e7c151b-cbd8-4df6-a0e3-cde660067c6a\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-\r
-  ENTRY_POINT                    = DebugSupportDxeInitialize\r
-\r
-[Sources.common]\r
-  DebugSupport.c\r
-\r
-[Packages]\r
-  ArmPkg/ArmPkg.dec\r
-  MdePkg/MdePkg.dec\r
-\r
-[LibraryClasses]\r
-  BaseMemoryLib\r
-  CacheMaintenanceLib\r
-  UefiDriverEntryPoint\r
-  ArmLib\r
-\r
-[Protocols]\r
-  gEfiCpuArchProtocolGuid\r
-  gEfiDebugSupportProtocolGuid\r
-  gTimerDebugSupportProtocolGuid\r
-  \r
-[Depex]\r
-  TRUE
\ No newline at end of file
diff --git a/ArmPkg/Drivers/PL180MciDxe/PL180Mci.c b/ArmPkg/Drivers/PL180MciDxe/PL180Mci.c
new file mode 100644 (file)
index 0000000..fe6c904
--- /dev/null
@@ -0,0 +1,387 @@
+/** @file\r
+  This file implement the MMC Host Protocol for the ARM PrimeCell PL180.\r
+\r
+  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+  \r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#include "PL180Mci.h"\r
+\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+EFI_MMC_HOST_PROTOCOL     *gpMmcHost;\r
+\r
+// Untested ...\r
+//#define USE_STREAM\r
+\r
+#define MMCI0_BLOCKLEN 512\r
+#define MMCI0_POW2_BLOCKLEN     9\r
+#define MMCI0_TIMEOUT           1000\r
+\r
+BOOLEAN MciIsPowerOn() {\r
+    return ((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);\r
+}\r
+\r
+EFI_STATUS MciInitialize() {\r
+    MCI_TRACE("MciInitialize()");\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN MciIsCardPresent() {\r
+    return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 1);\r
+}\r
+\r
+BOOLEAN MciIsReadOnly() {\r
+    return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 2);\r
+}\r
+\r
+// Convert block size to 2^n\r
+UINT32 GetPow2BlockLen(UINT32 BlockLen) {\r
+    UINTN Loop;\r
+    UINTN Pow2BlockLen;\r
+    \r
+    Loop    = 0x8000;\r
+    Pow2BlockLen = 15;\r
+    do {\r
+        Loop = (Loop >> 1) & 0xFFFF;\r
+        Pow2BlockLen--;\r
+    } while (Pow2BlockLen && (!(Loop & BlockLen)));\r
+\r
+    return Pow2BlockLen;\r
+}\r
+\r
+VOID MciPrepareDataPath(UINTN TransferDirection) {\r
+    // Set Data Length & Data Timer\r
+    MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFFFF);\r
+    MmioWrite32(MCI_DATA_LENGTH_REG,MMCI0_BLOCKLEN);\r
+\r
+#ifndef USE_STREAM\r
+    //Note: we are using a hardcoded BlockLen (=512). If we decide to use a variable size, we could\r
+    // compute the pow2 of BlockLen with the above function GetPow2BlockLen()\r
+    MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4));\r
+#else\r
+    MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS);\r
+#endif\r
+}\r
+\r
+EFI_STATUS MciSendCommand(MMC_CMD MmcCmd, UINT32 Argument) {\r
+    UINT32 Status;\r
+    UINT32  Timer;\r
+    UINT32 Cmd;\r
+\r
+    if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) {\r
+        MciPrepareDataPath(MCI_DATACTL_CARD_TO_CONT);\r
+    } else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {\r
+        MciPrepareDataPath(MCI_DATACTL_CONT_TO_CARD);\r
+    }\r
+\r
+    // Create Command for PL180\r
+    Cmd = INDX(MmcCmd);\r
+    if (MmcCmd & MMC_CMD_WAIT_RESPONSE)\r
+        Cmd |= MCI_CPSM_WAIT_RESPONSE;\r
+    if (MmcCmd & MMC_CMD_LONG_RESPONSE)\r
+        Cmd |= MCI_CPSM_LONG_RESPONSE;\r
+\r
+    MmioWrite32(MCI_CLEAR_STATUS_REG,0x5FFF);\r
+    MmioWrite32(MCI_ARGUMENT_REG,Argument);\r
+    MmioWrite32(MCI_COMMAND_REG,Cmd);\r
+\r
+    Timer = 1000;\r
+    if (Cmd & MCI_CPSM_WAIT_RESPONSE) {\r
+        Status = MmioRead32(MCI_STATUS_REG);\r
+        while (!(Status & (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT)) && Timer) {\r
+            //NanoSecondDelay(10);\r
+            Status = MmioRead32(MCI_STATUS_REG);\r
+            Timer--;\r
+        }\r
+\r
+        if ((Timer == 0) || (Status == MCI_STATUS_CMD_CMDTIMEOUT)) {\r
+            //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%X\n",Cmd & 0x3F,MmioRead32(MCI_RESPONSE0_REG),Status));\r
+            return EFI_TIMEOUT;\r
+        } else if (!((Cmd & 0x3F) == INDX(1)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {\r
+            // The CMD1 does not contain CRC. We should ignore the CRC failed Status.\r
+            return EFI_CRC_ERROR;\r
+        } else {\r
+            return EFI_SUCCESS;\r
+        }\r
+    } else {\r
+        Status = MmioRead32(MCI_STATUS_REG);\r
+        while (!(Status & MCI_STATUS_CMD_SENT) && Timer) {\r
+            //NanoSecondDelay(10);\r
+            Status = MmioRead32(MCI_STATUS_REG);\r
+            Timer--;\r
+        }\r
+\r
+        if (Timer == 0) {\r
+            //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT2! 0x%X\n",Cmd & 0x3F,MmioRead32(MCI_RESPONSE0_REG)));\r
+            return EFI_TIMEOUT;\r
+        } else {\r
+            return EFI_SUCCESS;\r
+        }\r
+    }\r
+}\r
+\r
+EFI_STATUS MciReceiveResponse(MMC_RESPONSE_TYPE Type, UINT32* Buffer) {\r
+    if (Buffer == NULL) {\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((Type == MMC_RESPONSE_TYPE_R1) || (Type == MMC_RESPONSE_TYPE_R1b) ||\r
+        (Type == MMC_RESPONSE_TYPE_R3) || (Type == MMC_RESPONSE_TYPE_R6) ||\r
+        (Type == MMC_RESPONSE_TYPE_R7)) {\r
+        Buffer[0] = MmioRead32(MCI_RESPONSE0_REG);\r
+        Buffer[1] = MmioRead32(MCI_RESPONSE1_REG);\r
+    } else if (Type == MMC_RESPONSE_TYPE_R2) {\r
+        Buffer[0] = MmioRead32(MCI_RESPONSE0_REG);\r
+        Buffer[1] = MmioRead32(MCI_RESPONSE1_REG);\r
+        Buffer[2] = MmioRead32(MCI_RESPONSE2_REG);\r
+        Buffer[3] = MmioRead32(MCI_RESPONSE3_REG);\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS MciReadBlockData(EFI_LBA Lba, UINTN Length, UINT32* Buffer) {\r
+    UINTN Loop;\r
+    UINTN Finish;\r
+    UINTN Timer;\r
+    UINTN Status;\r
+\r
+    // Read data from the RX FIFO\r
+    Loop   = 0;\r
+    Finish = MMCI0_BLOCKLEN / 4;\r
+    Timer  = MMCI0_TIMEOUT * 10;\r
+    do {\r
+        // Read the Status flags\r
+        Status = MmioRead32(MCI_STATUS_REG);\r
+        // Do eight reads if possible else a single read\r
+        if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+        }\r
+        else if (!(Status & MCI_STATUS_CMD_RXFIFOEMPTY)) {\r
+            Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
+            Loop++;\r
+        } else\r
+            Timer--;\r
+    } while ((Loop < Finish) && Timer);\r
+\r
+    if (Timer == 0) {\r
+        DEBUG ((EFI_D_ERROR, "MciReadBlockData: Timeout Status:0x%X Loop:%d // Finish:%d\n",MmioRead32(MCI_STATUS_REG),Loop,Finish));\r
+        return EFI_TIMEOUT;\r
+    } else\r
+        return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS MciWriteBlockData(EFI_LBA Lba, UINTN Length, UINT32* Buffer) {\r
+    UINTN Loop;\r
+    UINTN Finish;\r
+    UINTN Timer;\r
+    UINTN Status;\r
+\r
+    // Write the data to the TX FIFO\r
+    Loop   = 0;\r
+    Finish = MMCI0_BLOCKLEN / 4;\r
+    Timer  = MMCI0_TIMEOUT * 100;\r
+    do {\r
+        // Read the Status flags\r
+        Status = MmioRead32(MCI_STATUS_REG);\r
+\r
+        // Do eight writes if possible else a single write\r
+        if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) {\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+        }\r
+        else if (!(Status & MCI_STATUS_CMD_TXFIFOFULL)) {\r
+            MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
+            Loop++;\r
+        }\r
+        else\r
+            Timer--;\r
+    } while ((Loop < Finish) && Timer);\r
+\r
+    ASSERT(Timer > 0);\r
+\r
+    // Wait for FIFO to drain\r
+    Timer = MMCI0_TIMEOUT;\r
+    Status = MmioRead32(MCI_STATUS_REG);\r
+/*#ifndef USE_STREAM\r
+    // Single block\r
+    while (((Status & MCI_STATUS_CMD_TXDONE) != MCI_STATUS_CMD_TXDONE) && Timer) {\r
+#else*/\r
+    // Stream\r
+    while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) {\r
+//#endif\r
+        NanoSecondDelay(10);\r
+        Status = MmioRead32(MCI_STATUS_REG);\r
+        Timer--;\r
+    }\r
+\r
+    ASSERT(Timer > 0);\r
+\r
+    if (Timer == 0)\r
+        return EFI_TIMEOUT;\r
+    else\r
+        return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS MciNotifyState(MMC_STATE State) {\r
+    UINT32      Data32;\r
+\r
+    switch(State) {\r
+    case MmcInvalidState:\r
+        ASSERT(0);\r
+        break;\r
+    case MmcHwInitializationState:\r
+        // If device already turn on then restart it\r
+        Data32 = MmioRead32(MCI_POWER_CONTROL_REG);\r
+        if ((Data32 & 0x2) == MCI_POWER_UP) {\r
+            MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOff MCI");\r
+\r
+            // Turn off\r
+            MmioWrite32(MCI_CLOCK_CONTROL_REG, 0);\r
+            MmioWrite32(MCI_POWER_CONTROL_REG, 0);\r
+            MicroSecondDelay(100);\r
+        }\r
+        \r
+        MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOn MCI");\r
+        // Setup clock\r
+        //  - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz\r
+        MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);\r
+        //MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE);\r
+\r
+        // Set the voltage\r
+        MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_OPENDRAIN | (15<<2));\r
+        MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP);\r
+        MicroSecondDelay(10);\r
+        MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON);\r
+        MicroSecondDelay(100);\r
+\r
+        // Set Data Length & Data Timer\r
+        MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFF);\r
+        MmioWrite32(MCI_DATA_LENGTH_REG,8);\r
+\r
+        ASSERT((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);\r
+        break;\r
+    case MmcIdleState:\r
+        MCI_TRACE("MciNotifyState(MmcIdleState)");\r
+        break;\r
+    case MmcReadyState:\r
+        MCI_TRACE("MciNotifyState(MmcReadyState)");\r
+        break;\r
+    case MmcIdentificationState:\r
+        MCI_TRACE("MciNotifyState(MmcIdentificationState)");\r
+        break;\r
+    case MmcStandByState:\r
+        MCI_TRACE("MciNotifyState(MmcStandByState)");\r
\r
+        // Enable MCICMD push-pull drive\r
+        MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | (15<<2) | MCI_POWER_ON);\r
+\r
+        /*// Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled)\r
+        MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);*/\r
+        // Set MMCI0 clock to 24MHz (by bypassing the divider)\r
+        MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE);\r
+        break;\r
+    case MmcTransferState:\r
+        //MCI_TRACE("MciNotifyState(MmcTransferState)");\r
+        break;\r
+    case MmcSendingDataState:\r
+        MCI_TRACE("MciNotifyState(MmcSendingDataState)");\r
+        break;\r
+    case MmcReceiveDataState:\r
+        MCI_TRACE("MciNotifyState(MmcReceiveDataState)");\r
+        break;\r
+    case MmcProgrammingState:\r
+        MCI_TRACE("MciNotifyState(MmcProgrammingState)");\r
+        break;\r
+    case MmcDisconnectState:\r
+        MCI_TRACE("MciNotifyState(MmcDisconnectState)");\r
+        break;\r
+    default:\r
+        ASSERT(0);\r
+    }\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_GUID mPL180MciDevicePathGuid = { 0x621b6fa5, 0x4dc1, 0x476f, 0xb9, 0xd8, 0x52, 0xc5, 0x57, 0xd8, 0x10, 0x70 };\r
+\r
+EFI_STATUS MciBuildDevicePath(EFI_DEVICE_PATH_PROTOCOL **DevicePath) {\r
+    EFI_DEVICE_PATH_PROTOCOL    *NewDevicePathNode;\r
+\r
+    NewDevicePathNode = CreateDeviceNode(HARDWARE_DEVICE_PATH,HW_VENDOR_DP,sizeof(VENDOR_DEVICE_PATH));\r
+    CopyGuid(&((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid,&mPL180MciDevicePathGuid);\r
+    \r
+    *DevicePath = NewDevicePathNode;\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_MMC_HOST_PROTOCOL gMciHost = {\r
+    MciIsCardPresent,\r
+    MciIsReadOnly,\r
+    MciBuildDevicePath,\r
+    MciNotifyState,\r
+    MciSendCommand,\r
+    MciReceiveResponse,\r
+    MciReadBlockData,\r
+    MciWriteBlockData\r
+};\r
+\r
+EFI_STATUS\r
+PL180MciDxeInitialize (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  EFI_HANDLE    Handle = NULL;\r
+\r
+  MCI_TRACE("PL180MciDxeInitialize()");\r
+\r
+  //Publish Component Name, BlockIO protocol interfaces\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Handle, \r
+                  &gEfiMmcHostProtocolGuid,         &gMciHost,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/ArmPkg/Drivers/PL180MciDxe/PL180Mci.h b/ArmPkg/Drivers/PL180MciDxe/PL180Mci.h
new file mode 100644 (file)
index 0000000..2120716
--- /dev/null
@@ -0,0 +1,117 @@
+/** @file\r
+  Header for the MMC Host Protocol implementation for the ARM PrimeCell PL180.\r
+\r
+  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+  \r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#ifndef __PL180_MCI_H\r
+#define __PL180_MCI_H\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/MmcHost.h>\r
+\r
+#include <Library/UefiLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#define PL180_MCI_DXE_VERSION   0x10\r
+\r
+#define MCI_SYSCTL  FixedPcdGet32(PcdPL180MciBaseAddress)\r
+\r
+#define MCI_POWER_CONTROL_REG           (MCI_SYSCTL+0x000)\r
+#define MCI_CLOCK_CONTROL_REG           (MCI_SYSCTL+0x004)\r
+#define MCI_ARGUMENT_REG                (MCI_SYSCTL+0x008)\r
+#define MCI_COMMAND_REG                 (MCI_SYSCTL+0x00C)\r
+#define MCI_RESPCMD_REG                 (MCI_SYSCTL+0x010)\r
+#define MCI_RESPONSE0_REG               (MCI_SYSCTL+0x014)\r
+#define MCI_RESPONSE1_REG               (MCI_SYSCTL+0x018)\r
+#define MCI_RESPONSE2_REG               (MCI_SYSCTL+0x01C)\r
+#define MCI_RESPONSE3_REG               (MCI_SYSCTL+0x020)\r
+#define MCI_DATA_TIMER_REG              (MCI_SYSCTL+0x024)\r
+#define MCI_DATA_LENGTH_REG             (MCI_SYSCTL+0x028)\r
+#define MCI_DATA_CTL_REG                (MCI_SYSCTL+0x02C)\r
+#define MCI_DATA_COUNTER                (MCI_SYSCTL+0x030)\r
+#define MCI_STATUS_REG                  (MCI_SYSCTL+0x034)\r
+#define MCI_CLEAR_STATUS_REG            (MCI_SYSCTL+0x038)\r
+#define MCI_INT0_MASK_REG               (MCI_SYSCTL+0x03C)\r
+#define MCI_INT1_MASK_REG               (MCI_SYSCTL+0x040)\r
+#define MCI_FIFOCOUNT_REG               (MCI_SYSCTL+0x048)\r
+#define MCI_FIFO_REG                    (MCI_SYSCTL+0x080)\r
+\r
+#define MCI_POWER_UP                    0x2\r
+#define MCI_POWER_ON                    0x3\r
+#define MCI_POWER_OPENDRAIN             (1 << 6)\r
+#define MCI_POWER_ROD                   (1 << 7)\r
+\r
+#define MCI_CLOCK_ENABLE                0x100\r
+#define MCI_CLOCK_POWERSAVE             0x200\r
+#define MCI_CLOCK_BYPASS                0x400\r
+\r
+#define MCI_STATUS_CMD_CMDCRCFAIL       0x1\r
+#define MCI_STATUS_CMD_DATACRCFAIL      0x2\r
+#define MCI_STATUS_CMD_CMDTIMEOUT       0x4\r
+#define MCI_STATUS_CMD_DATATIMEOUT      0x8\r
+#define MCI_STATUS_CMD_RXOVERRUN        0x20\r
+#define MCI_STATUS_CMD_RESPEND          0x40\r
+#define MCI_STATUS_CMD_SENT             0x80\r
+#define MCI_STATUS_CMD_TXDONE           (MCI_STATUS_CMD_DATAEND | MCI_STATUS_CMD_DATABLOCKEND)\r
+#define MCI_STATUS_CMD_DATAEND          0x000100    // Command Status - Data end\r
+#define MCI_STATUS_CMD_DATABLOCKEND     0x000400    // Command Status - Data end\r
+#define MCI_STATUS_CMD_ACTIVE           0x800\r
+#define MCI_STATUS_CMD_RXACTIVE         (1 << 13)\r
+#define MCI_STATUS_CMD_RXFIFOHALFFULL   0x008000\r
+#define MCI_STATUS_CMD_RXFIFOEMPTY      0x080000\r
+#define MCI_STATUS_CMD_RXDATAAVAILBL    (1 << 21)\r
+#define MCI_STATUS_CMD_TXACTIVE         (1 << 12)\r
+#define MCI_STATUS_CMD_TXFIFOFULL       (1 << 16)\r
+#define MCI_STATUS_CMD_TXFIFOHALFEMPTY  (1 << 14)\r
+#define MCI_STATUS_CMD_TXFIFOEMPTY      (1 << 18)\r
+#define MCI_STATUS_CMD_TXDATAAVAILBL    (1 << 20)\r
+\r
+#define MCI_DATACTL_ENABLE              1\r
+#define MCI_DATACTL_CONT_TO_CARD        0\r
+#define MCI_DATACTL_CARD_TO_CONT        2\r
+#define MCI_DATACTL_BLOCK_TRANS         0\r
+#define MCI_DATACTL_STREAM_TRANS        4\r
+#define MCI_DATACTL_DMA_ENABLE          8\r
+\r
+#define INDX(CMD_INDX)    ((CMD_INDX & 0x3F) | MCI_CPSM_ENABLED)\r
+\r
+#define MCI_CPSM_ENABLED            (1 << 10)\r
+#define MCI_CPSM_WAIT_RESPONSE      (1 << 6)\r
+#define MCI_CPSM_LONG_RESPONSE      (1 << 7)\r
+\r
+#define MCI_TRACE(txt)  DEBUG((EFI_D_BLKIO, "ARM_MCI: " txt "\n"))\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MciGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MciGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  );\r
+\r
+#endif\r
diff --git a/ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf b/ArmPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
new file mode 100644 (file)
index 0000000..7ce555b
--- /dev/null
@@ -0,0 +1,51 @@
+#/** @file\r
+#  INF file for the MMC Host Protocol implementation for the ARM PrimeCell PL180.\r
+#\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PL180MciDxe\r
+  FILE_GUID                      = 09831032-6fa3-4484-af4f-0a000a8d3a82\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = PL180MciDxeInitialize\r
+\r
+[Sources.common]\r
+  PL180Mci.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  BaseMemoryLib\r
+  ArmLib\r
+  IoLib\r
+  TimerLib\r
+\r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid\r
+  gEfiDevicePathProtocolGuid\r
+  gEfiMmcHostProtocolGuid\r
+  \r
+[Pcd]\r
+  gArmTokenSpaceGuid.PcdPL180SysMciRegAddress\r
+  gArmTokenSpaceGuid.PcdPL180MciBaseAddress\r
+  \r
+[Depex]\r
+  TRUE\r
diff --git a/ArmPkg/Drivers/PL301Axi/PL301Axi.c b/ArmPkg/Drivers/PL301Axi/PL301Axi.c
new file mode 100644 (file)
index 0000000..7241f5c
--- /dev/null
@@ -0,0 +1,108 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#define PL301_QOS_TIDEMARK_MI_0                  0x400\r
+#define PL301_QOS_ACCESSCONTROL_MI_0             0x404\r
+\r
+#define PL301_QOS_TIDEMARK_MI_1                  0x420\r
+#define PL301_QOS_ACCESSCONTROL_MI_1             0x424\r
+\r
+#define PL301_QOS_TIDEMARK_MI_2                  0x440\r
+#define PL301_QOS_ACCESSCONTROL_MI_2             0x444\r
+\r
+#define PL301_AR_ARB_MI_0                        0x408\r
+#define PL301_AW_ARB_MI_0                        0x40C\r
+\r
+#define PL301_AR_ARB_MI_1                        0x428\r
+#define PL301_AW_ARB_MI_1                        0x42C\r
+\r
+#define PL301_AR_ARB_MI_2                        0x448\r
+#define PL301_AW_ARB_MI_2                        0x44C\r
+\r
+#define PL301_MI_1_OFFSET                        0x20\r
+#define PL301_MI_2_OFFSET                        0x40\r
+#define PL301_MI_3_OFFSET                        0x60\r
+#define PL301_MI_4_OFFSET                        0x80\r
+#define PL301_MI_5_OFFSET                        0xa0\r
+\r
+#define V2P_CA9_FAXI_MI0_TIDEMARK_VAL            0x6\r
+#define V2P_CA9_FAXI_MI0_ACCESSCNTRL_VAL         0x1\r
+\r
+#define V2P_CA9_FAXI_MI1_TIDEMARK_VAL            0x6\r
+#define V2P_CA9_FAXI_MI1_ACCESSCNTRL_VAL         0x1\r
+\r
+#define V2P_CA9_FAXI_MI2_TIDEMARK_VAL            0x6\r
+#define V2P_CA9_FAXI_MI2_ACCESSCNTRL_VAL         0x1\r
+\r
+\r
+#define FAxiWriteReg(reg,val)                    MmioWrite32(FAxiBase + reg, val)\r
+#define FAxiReadReg(reg)                         MmioRead32(FAxiBase + reg)\r
+\r
+// IN FAxiBase\r
+// Initialize PL301 Dynamic Memory Controller\r
+VOID PL301AxiInit(UINTN FAxiBase) {\r
+    // Configure Tidemark Register for Master Port 0 (MI 0)\r
+    FAxiWriteReg(PL301_QOS_TIDEMARK_MI_0, V2P_CA9_FAXI_MI0_TIDEMARK_VAL);\r
+\r
+    // Configure the Access Control Register (MI 0)\r
+    FAxiWriteReg(PL301_QOS_ACCESSCONTROL_MI_0, V2P_CA9_FAXI_MI0_ACCESSCNTRL_VAL);\r
+\r
+    // MP0 \r
+    // Set priority for Read\r
+    FAxiWriteReg(PL301_AR_ARB_MI_0, 0x00000100);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_0, 0x01000200);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_0, 0x02000200);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_0, 0x03000200);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_0, 0x04000200);\r
+  \r
+    // Set priority for Write\r
+    FAxiWriteReg(PL301_AW_ARB_MI_0, 0x00000100);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_0, 0x01000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_0, 0x02000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_0, 0x03000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_0, 0x04000200);\r
+\r
+    // MP1\r
+    // Set priority for Read\r
+    FAxiWriteReg(PL301_AR_ARB_MI_1, 0x00000100);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_1, 0x01000200);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_1, 0x02000200);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_1, 0x03000200);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_1, 0x04000200);\r
+\r
+    // Set priority for Write\r
+    FAxiWriteReg(PL301_AW_ARB_MI_1, 0x00000100);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_1, 0x01000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_1, 0x02000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_1, 0x03000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_1, 0x04000200);\r
+\r
+    // MP2\r
+    // Set priority for Read\r
+    FAxiWriteReg(PL301_AR_ARB_MI_2, 0x00000100);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_2, 0x01000100);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_2, 0x02000100);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_2, 0x03000100);\r
+    FAxiWriteReg(PL301_AR_ARB_MI_2, 0x04000100);\r
+  \r
+    // Set priority for Write\r
+    FAxiWriteReg(PL301_AW_ARB_MI_2, 0x00000100);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_2, 0x01000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_2, 0x02000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_2, 0x03000200);\r
+    FAxiWriteReg(PL301_AW_ARB_MI_2, 0x04000200);\r
+}\r
diff --git a/ArmPkg/Drivers/PL301Axi/PL301Axi.inf b/ArmPkg/Drivers/PL301Axi/PL301Axi.inf
new file mode 100644 (file)
index 0000000..2358124
--- /dev/null
@@ -0,0 +1,29 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PL301AxiSec\r
+  FILE_GUID                      = 2ea84160-aba0-11df-9896-0002a5d5c51b\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PL301AxiLib\r
+\r
+[Sources]\r
+  PL301Axi.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[FixedPcd]\r
diff --git a/ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c b/ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c
new file mode 100644 (file)
index 0000000..6cc6cc6
--- /dev/null
@@ -0,0 +1,130 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ArmLib.h>\r
+#include <Library/L2X0CacheLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#define L2x0WriteReg(reg,val)               MmioWrite32(PcdGet32(PcdL2x0ControllerBase) + reg, val)\r
+#define L2x0ReadReg(reg)                    MmioRead32(PcdGet32(PcdL2x0ControllerBase) + reg)\r
+\r
+// Initialize PL320 L2 Cache Controller\r
+VOID L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled) {\r
+    UINT32 Data;\r
+    UINT32 Revision;\r
+    UINT32 Aux;\r
+    UINT32 PfCtl;\r
+    UINT32 PwrCtl;\r
+\r
+    // Check if L2x0 is present and is an ARM implementation\r
+    Data = L2x0ReadReg(L2X0_CACHEID);\r
+    if ((Data >> 24) != L2X0_CACHEID_IMPLEMENTER_ARM) {\r
+        ASSERT(0);\r
+        return;\r
+    }\r
+\r
+    // Check if L2x0 is PL310\r
+    if (((Data >> 6) & 0xF) != L2X0_CACHEID_PARTNUM_PL310) {\r
+        ASSERT(0);\r
+        return;\r
+    }\r
+\r
+    // RTL release\r
+    Revision = Data & 0x3F;\r
+\r
+    // Check if L2x0 is already enabled then we disable it\r
+    Data = L2x0ReadReg(L2X0_CTRL);\r
+    if (Data & L2X0_CTRL_ENABLED) {\r
+        L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_DISABLED);\r
+    }\r
+\r
+    //\r
+    // Set up global configurations\r
+    //\r
+\r
+    // Auxiliary register: Non-secure interrupt access Control + Event monitor bus enable + SBO\r
+    Aux = L2X0_AUXCTRL_NSAC | L2X0_AUXCTRL_EM | L2X0_AUXCTRL_SBO;\r
+    // Use AWCACHE attributes for WA\r
+    Aux |= L2x0_AUXCTRL_AW_AWCACHE;\r
+    // Use default Size\r
+    Data = L2x0ReadReg(L2X0_AUXCTRL);\r
+    Aux |= Data & (0x7 << 17);\r
+    // Use default associativity\r
+    Aux |= Data & (0x1 << 16);\r
+    // Enabled I & D Prefetch\r
+    Aux |= L2x0_AUXCTRL_IPREFETCH | L2x0_AUXCTRL_DPREFETCH;\r
+    \r
+    if (Revision >= 5) {\r
+        // Prefetch Offset Register\r
+        PfCtl = L2x0ReadReg(L2X0_PFCTRL);\r
+        // - Prefetch increment set to 0\r
+        // - Prefetch dropping off\r
+        // - Double linefills off\r
+        L2x0WriteReg(L2X0_PFCTRL, PfCtl);\r
+\r
+        // Power Control Register - L2X0_PWRCTRL\r
+        PwrCtl = L2x0ReadReg(L2X0_PWRCTRL);\r
+        // - Standby when idle off\r
+        // - Dynamic clock gating off\r
+        // - Nc,NC-shared dropping off\r
+        L2x0WriteReg(L2X0_PWRCTRL, PwrCtl);\r
+    }\r
+\r
+    if (Revision >= 4) {\r
+        // Tag RAM Latency register\r
+        // - Use default latency\r
+    \r
+        // Data RAM Latency Control register\r
+        // - Use default latency\r
+    } else if (Revision >= 2) {\r
+        L2x0WriteReg(L230_TAG_LATENCY,\r
+            (L2_TAG_ACCESS_LATENCY << 8)\r
+            | (L2_TAG_ACCESS_LATENCY << 4)\r
+            | L2_TAG_SETUP_LATENCY\r
+        );\r
+        \r
+        L2x0WriteReg(L230_DATA_LATENCY,\r
+            (L2_DATA_ACCESS_LATENCY << 8)\r
+            | (L2_DATA_ACCESS_LATENCY << 4)\r
+            | L2_DATA_SETUP_LATENCY\r
+        );\r
+    } else {\r
+        Aux |= (L2_TAG_ACCESS_LATENCY << 6)\r
+               | (L2_DATA_ACCESS_LATENCY << 3)\r
+               | L2_DATA_ACCESS_LATENCY;\r
+    }\r
+\r
+    // Write Auxiliary value\r
+    L2x0WriteReg(L2X0_AUXCTRL, Aux);\r
+\r
+    //\r
+    // Invalidate all entries in cache\r
+    //\r
+    L2x0WriteReg(L2X0_INVWAY, 0xffff);\r
+    // Poll cache maintenance register until invalidate operation is complete\r
+    while(L2x0ReadReg(L2X0_INVWAY) & 0xffff);\r
+\r
+    // Write to the Lockdown D and Lockdown I Register 9 if required\r
+    // - Not required\r
+\r
+    // Clear any residual raw interrupts\r
+    L2x0WriteReg(L2X0_INTCLEAR, 0x1FF);\r
+\r
+    // Enable the cache\r
+    if (CacheEnabled) {\r
+        L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_ENABLED);\r
+    }\r
+}\r
diff --git a/ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf b/ArmPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf
new file mode 100644 (file)
index 0000000..73c9689
--- /dev/null
@@ -0,0 +1,30 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PL310L2Cache\r
+  FILE_GUID                      = 16ad4fe0-b5b1-11df-8cbf-0002a5d5c51b\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = L2X0CacheLib\r
+\r
+[Sources]\r
+  PL310L2Cache.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[FixedPcd]\r
+  gArmTokenSpaceGuid.PcdL2x0ControllerBase\r
diff --git a/ArmPkg/Drivers/PL34xDmc/PL341Dmc.c b/ArmPkg/Drivers/PL34xDmc/PL341Dmc.c
new file mode 100644 (file)
index 0000000..9c62a1a
--- /dev/null
@@ -0,0 +1,373 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Drivers/PL341Dmc.h>\r
+\r
+//\r
+// DMC Configuration Register Map\r
+//\r
+#define DMC_STATUS_REG              0x00\r
+#define DMC_COMMAND_REG             0x04\r
+#define DMC_DIRECT_CMD_REG          0x08\r
+#define DMC_MEMORY_CONFIG_REG       0x0C\r
+#define DMC_REFRESH_PRD_REG         0x10\r
+#define DMC_CAS_LATENCY_REG         0x14\r
+#define DMC_WRITE_LATENCY_REG       0x18\r
+#define DMC_T_MRD_REG               0x1C\r
+#define DMC_T_RAS_REG               0x20\r
+#define DMC_T_RC_REG                0x24\r
+#define DMC_T_RCD_REG               0x28\r
+#define DMC_T_RFC_REG               0x2C\r
+#define DMC_T_RP_REG                0x30\r
+#define DMC_T_RRD_REG               0x34\r
+#define DMC_T_WR_REG                0x38\r
+#define DMC_T_WTR_REG               0x3C\r
+#define DMC_T_XP_REG                0x40\r
+#define DMC_T_XSR_REG               0x44\r
+#define DMC_T_ESR_REG               0x48\r
+#define DMC_MEMORY_CFG2_REG         0x4C\r
+#define DMC_MEMORY_CFG3_REG         0x50\r
+#define DMC_T_FAW_REG               0x54\r
+\r
+// Returns the state of the memory controller:\r
+#define DMC_STATUS_CONFIG       0x0\r
+#define DMC_STATUS_READY        0x1\r
+#define DMC_STATUS_PAUSED       0x2\r
+#define DMC_STATUS_LOWPOWER     0x3\r
+\r
+// Changes the state of the memory controller:\r
+#define DMC_COMMAND_GO              0x0\r
+#define DMC_COMMAND_SLEEP           0x1\r
+#define DMC_COMMAND_WAKEUP          0x2\r
+#define DMC_COMMAND_PAUSE           0x3\r
+#define DMC_COMMAND_CONFIGURE       0x4\r
+#define DMC_COMMAND_ACTIVEPAUSE     0x7\r
+\r
+// Determines the command required\r
+#define DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL      0x0\r
+#define DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH       (0x1 << 18)\r
+#define DMC_DIRECT_CMD_MEMCMD_MODEREG           (0x2 << 18)\r
+#define DMC_DIRECT_CMD_MEMCMD_EXTMODEREG        (0x2 << 18)\r
+#define DMC_DIRECT_CMD_MEMCMD_NOP               (0x3 << 18)\r
+#define DMC_DIRECT_CMD_MEMCMD_DPD               (0x1 << 22)\r
+#define DMC_DIRECT_CMD_BANKADDR(n)              ((n & 0x3) << 16)\r
+#define DMC_DIRECT_CMD_CHIP_ADDR(n)            ((n & 0x3) << 20)\r
+\r
+\r
+//\r
+// AXI ID configuration register map\r
+//\r
+#define DMC_ID_0_CFG_REG            0x100\r
+#define DMC_ID_1_CFG_REG            0x104\r
+#define DMC_ID_2_CFG_REG            0x108\r
+#define DMC_ID_3_CFG_REG            0x10C\r
+#define DMC_ID_4_CFG_REG            0x110\r
+#define DMC_ID_5_CFG_REG            0x114\r
+#define DMC_ID_6_CFG_REG            0x118\r
+#define DMC_ID_7_CFG_REG            0x11C\r
+#define DMC_ID_8_CFG_REG            0x120\r
+#define DMC_ID_9_CFG_REG            0x124\r
+#define DMC_ID_10_CFG_REG           0x128\r
+#define DMC_ID_11_CFG_REG           0x12C\r
+#define DMC_ID_12_CFG_REG           0x130\r
+#define DMC_ID_13_CFG_REG           0x134\r
+#define DMC_ID_14_CFG_REG           0x138\r
+#define DMC_ID_15_CFG_REG           0x13C\r
+\r
+// Set the QoS\r
+#define DMC_ID_CFG_QOS_DISABLE      0\r
+#define DMC_ID_CFG_QOS_ENABLE       1\r
+#define DMC_ID_CFG_QOS_MIN          2\r
+\r
+\r
+//\r
+// Chip configuration register map\r
+//\r
+#define DMC_CHIP_0_CFG_REG          0x200\r
+#define DMC_CHIP_1_CFG_REG          0x204\r
+#define DMC_CHIP_2_CFG_REG          0x208\r
+#define DMC_CHIP_3_CFG_REG          0x20C\r
+\r
+//\r
+// User Defined Pins\r
+//\r
+#define DMC_USER_STATUS_REG         0x300\r
+#define DMC_USER_0_CFG_REG          0x304\r
+#define DMC_USER_1_CFG_REG          0x308\r
+#define DMC_FEATURE_CRTL_REG        0x30C\r
+#define DMC_USER_2_CFG_REG          0x310\r
+\r
+\r
+//\r
+// PHY Register Settings\r
+//\r
+#define TC_UIOLHNC_MASK                         0x000003C0\r
+#define TC_UIOLHNC_SHIFT                        0x6\r
+#define TC_UIOLHPC_MASK                         0x0000003F\r
+#define TC_UIOLHPC_SHIFT                        0x2\r
+#define TC_UIOHOCT_MASK                         0x2\r
+#define TC_UIOHOCT_SHIFT                        0x1\r
+#define TC_UIOHSTOP_SHIFT                       0x0\r
+#define TC_UIOLHXC_VALUE                        0x4                     \r
+\r
+//\r
+// Extended Mode Register settings\r
+//\r
+#define DDR_EMR_OCD_MASK                        0x0000380\r
+#define DDR_EMR_OCD_SHIFT                       0x7\r
+#define DDR_EMR_RTT_MASK                        0x00000044                  // DDR2 Device RTT (ODT) settings\r
+#define DDR_EMR_RTT_SHIFT                       0x2     \r
+#define DDR_EMR_ODS_MASK                        0x00000002                  // DDR2 Output Drive Strength\r
+#define DDR_EMR_ODS_SHIFT                       0x0001\r
+// Termination Values:\r
+#define DDR_EMR_RTT_50                          0x00000044                  // DDR2 50 Ohm termination\r
+#define DDR_EMR_RTT_75R                         0x00000004                  // DDR2 75 Ohm termination\r
+#define DDR_EMR_RTT_150                         0x00000040                  // DDR2 150 Ohm termination\r
+// Output Drive Strength Values:\r
+#define DDR_EMR_ODS_FULL                        0x0                         // DDR2 Full Drive Strength\r
+#define DDR_EMR_ODS_HALF                        0x1                         // DDR2 Half Drive Strength\r
+// OCD values\r
+#define DDR_EMR_OCD_DEFAULT                     0x7\r
+#define DDR_EMR_OCD_NS                          0x0\r
+\r
+#define DDR_EMR_ODS_VAL                         DDR_EMR_ODS_FULL\r
+\r
+\r
+\r
+#define DmcWriteReg(reg,val)                    MmioWrite32(DmcBase + reg, val)\r
+#define DmcReadReg(reg)                         MmioRead32(DmcBase + reg)\r
+\r
+// Initialize PL341 Dynamic Memory Controller\r
+VOID PL341DmcInit(struct pl341_dmc_config *config) {\r
+    UINTN   DmcBase = config->base;\r
+    UINT32  i, chip, val32;\r
+\r
+    // Set config mode\r
+    DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_CONFIGURE);\r
+\r
+    //\r
+    // Setup the QoS AXI ID bits    \r
+    //\r
+\r
+    if (config->has_qos) {\r
+       // CLCD AXIID = 000\r
+       DmcWriteReg(DMC_ID_0_CFG_REG, DMC_ID_CFG_QOS_ENABLE | DMC_ID_CFG_QOS_MIN);\r
+\r
+       // Default disable QoS\r
+       DmcWriteReg(DMC_ID_1_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_2_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_3_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_4_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_5_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_6_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_7_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_8_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_9_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_10_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_11_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_12_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_13_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_14_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+       DmcWriteReg(DMC_ID_15_CFG_REG, DMC_ID_CFG_QOS_DISABLE);\r
+    }\r
+\r
+    //\r
+    // Initialise memory controlller\r
+    //\r
+    DmcWriteReg(DMC_REFRESH_PRD_REG, config->refresh_prd);\r
+    DmcWriteReg(DMC_CAS_LATENCY_REG, config->cas_latency);\r
+    DmcWriteReg(DMC_WRITE_LATENCY_REG, config->write_latency);\r
+    DmcWriteReg(DMC_T_MRD_REG, config->t_mrd);\r
+    DmcWriteReg(DMC_T_RAS_REG, config->t_ras);\r
+    DmcWriteReg(DMC_T_RC_REG, config->t_rc);\r
+    DmcWriteReg(DMC_T_RCD_REG, config->t_rcd);\r
+    DmcWriteReg(DMC_T_RFC_REG, config->t_rfc);\r
+    DmcWriteReg(DMC_T_RP_REG, config->t_rp);\r
+    DmcWriteReg(DMC_T_RRD_REG, config->t_rrd);\r
+    DmcWriteReg(DMC_T_WR_REG, config->t_wr);\r
+    DmcWriteReg(DMC_T_WTR_REG, config->t_wtr);\r
+    DmcWriteReg(DMC_T_XP_REG, config->t_xp);\r
+    DmcWriteReg(DMC_T_XSR_REG, config->t_xsr);\r
+    DmcWriteReg(DMC_T_ESR_REG, config->t_esr);\r
+    DmcWriteReg(DMC_T_FAW_REG, config->t_faw);\r
+\r
+    // =======================================================================\r
+    // Initialise PL341 Mem Config Registers\r
+    // =======================================================================\r
+\r
+    // |======================================\r
+    // | Set PL341 Memory Config\r
+    // |======================================\r
+    DmcWriteReg(DMC_MEMORY_CONFIG_REG, config->memory_cfg);\r
+\r
+    // |======================================\r
+    // | Set PL341 Memory Config 2\r
+    // |======================================\r
+    DmcWriteReg(DMC_MEMORY_CFG2_REG, config->memory_cfg2);\r
+\r
+    // |======================================\r
+    // | Set PL341 Chip Select <n>\r
+    // |======================================\r
+    DmcWriteReg(DMC_CHIP_0_CFG_REG, config->chip_cfg0);\r
+    DmcWriteReg(DMC_CHIP_1_CFG_REG, config->chip_cfg1);\r
+    DmcWriteReg(DMC_CHIP_2_CFG_REG, config->chip_cfg2);\r
+    DmcWriteReg(DMC_CHIP_3_CFG_REG, config->chip_cfg3);\r
+\r
+    // |======================================\r
+    // | Set PL341 Memory Config 3 \r
+    // |======================================\r
+    DmcWriteReg(DMC_MEMORY_CFG3_REG, config->memory_cfg3);\r
+\r
+       // |========================================================\r
+       // |Set Test Chip PHY Registers via PL341 User Config Reg\r
+       // |Note that user_cfgX registers are Write Only\r
+       // |\r
+       // |DLL Freq set = 250MHz - 266MHz\r
+       // |======================================================== \r
+       DmcWriteReg(DMC_USER_0_CFG_REG, 0x7C924924);\r
\r
+       // user_config2\r
+       // ------------\r
+       // Set defaults before calibrating the DDR2 buffer impendence\r
+       // -Disable ODT\r
+       // -Default drive strengths\r
+       DmcWriteReg(DMC_USER_2_CFG_REG, 0x40000198);\r
\r
+       // |=======================================================\r
+       // |Auto calibrate the DDR2 buffers impendence \r
+       // |=======================================================\r
+       val32 = DmcReadReg(DMC_USER_STATUS_REG);\r
+       while (!(val32 & 0x100)) {\r
+           val32 = DmcReadReg(DMC_USER_STATUS_REG);\r
+       }\r
+\r
+       // Set the output driven strength\r
+       DmcWriteReg(DMC_USER_2_CFG_REG, 0x40800000 | \r
+                   (TC_UIOLHXC_VALUE << TC_UIOLHNC_SHIFT) | \r
+                   (TC_UIOLHXC_VALUE << TC_UIOLHPC_SHIFT) |\r
+                   (0x1 << TC_UIOHOCT_SHIFT) | \r
+                   (0x1 << TC_UIOHSTOP_SHIFT));\r
+\r
+       // |======================================\r
+       // | Set PL341 Feature Control Register \r
+       // |======================================\r
+       // | Disable early BRESP - use to optimise CLCD performance\r
+       DmcWriteReg(DMC_FEATURE_CRTL_REG, 0x00000001);\r
\r
+    //=================\r
+    // Config memories\r
+    //=================\r
+\r
+    for (chip = 0; chip <= config-> max_chip; chip++) {\r
+       // send nop\r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_NOP);\r
+       // pre-charge all\r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL);\r
+\r
+       // delay\r
+       for (i = 0; i < 10; i++) {\r
+           val32 = DmcReadReg(DMC_STATUS_REG);\r
+       }\r
+\r
+       // set (EMR2) extended mode register 2\r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, \r
+                   DMC_DIRECT_CMD_CHIP_ADDR(chip) | \r
+                   DMC_DIRECT_CMD_BANKADDR(2) | \r
+                   DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);\r
+       // set (EMR3) extended mode register 3\r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, \r
+                   DMC_DIRECT_CMD_CHIP_ADDR(chip) | \r
+                   DMC_DIRECT_CMD_BANKADDR(3) | \r
+                   DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);\r
+\r
+       // =================================\r
+       //  set (EMR) Extended Mode Register\r
+       // ==================================\r
+       // Put into OCD default state\r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, \r
+                   DMC_DIRECT_CMD_CHIP_ADDR(chip) | \r
+                   DMC_DIRECT_CMD_BANKADDR(1) | \r
+                   DMC_DIRECT_CMD_MEMCMD_EXTMODEREG);\r
+\r
+       // ===========================================================        \r
+       // set (MR) mode register - With DLL reset\r
+       // ===========================================================\r
+       // Burst Length = 4 (010)\r
+       // Burst Type   = Seq (0)\r
+       // Latency      = 4 (100)\r
+       // Test mode    = Off (0)\r
+       // DLL reset    = Yes (1)\r
+       // Wr Recovery  = 4  (011)      \r
+       // PD           = Normal (0)\r
+  DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00080742);\r
+        \r
+       // pre-charge all \r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL);\r
+       // auto-refresh \r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);\r
+       // auto-refresh \r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);\r
+\r
+       // delay\r
+       for (i = 0; i < 10; i++) {\r
+           val32 = DmcReadReg(DMC_STATUS_REG);\r
+       }\r
+\r
+       // ===========================================================        \r
+       // set (MR) mode register - Without DLL reset\r
+       // ===========================================================\r
+  // auto-refresh\r
+  DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH);\r
+  DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00080642);\r
+\r
+  // delay\r
+  for (i = 0; i < 10; i++) {\r
+    val32 = DmcReadReg(DMC_STATUS_REG);\r
+  }\r
+\r
+       // ======================================================        \r
+       // set (EMR) extended mode register - Enable OCD defaults\r
+       // ====================================================== \r
+       val32 = 0; //NOP\r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00090000 |\r
+                   (DDR_EMR_OCD_DEFAULT << DDR_EMR_OCD_SHIFT) | \r
+                   DDR_EMR_RTT_75R | \r
+                   (DDR_EMR_ODS_VAL << DDR_EMR_ODS_MASK));\r
+\r
+       // delay\r
+       for (i = 0; i < 10; i++) {\r
+           val32 = DmcReadReg(DMC_STATUS_REG);\r
+       }\r
+\r
+       // Set (EMR) extended mode register - OCD Exit\r
+       val32 = 0; //NOP\r
+       DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(chip) | 0x00090000 | \r
+                   (DDR_EMR_OCD_NS << DDR_EMR_OCD_SHIFT) | \r
+                   DDR_EMR_RTT_75R |\r
+                   (DDR_EMR_ODS_VAL << DDR_EMR_ODS_MASK));\r
+\r
+    }\r
+\r
+    //----------------------------------------    \r
+    // go command\r
+    DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_GO);\r
+\r
+    // wait for ready\r
+    val32 = DmcReadReg(DMC_STATUS_REG);\r
+    while (!(val32 & DMC_STATUS_READY)) {\r
+        val32 = DmcReadReg(DMC_STATUS_REG);\r
+    }\r
+}\r
diff --git a/ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf b/ArmPkg/Drivers/PL34xDmc/PL341Dmc.inf
new file mode 100644 (file)
index 0000000..1000058
--- /dev/null
@@ -0,0 +1,29 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PL341Dmc\r
+  FILE_GUID                      = edf8da40-aad1-11df-a1f4-0002a5d5c51b\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PL341DmcLib\r
+\r
+[Sources]\r
+  PL341Dmc.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[FixedPcd]\r
diff --git a/ArmPkg/Drivers/PL35xSmc/InitializeSMC.S b/ArmPkg/Drivers/PL35xSmc/InitializeSMC.S
new file mode 100644 (file)
index 0000000..b3b597a
--- /dev/null
@@ -0,0 +1,189 @@
+#\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http:#opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#\r
+\r
+#include <AsmMacroIoLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <AutoGen.h>\r
+#include <AsmMacroIoLib.h>\r
+\r
+#Start of the code section\r
+.text\r
+\r
+#Maintain 8 byte alignment\r
+.align 3\r
+\r
+#Export Initialize SMC symbol\r
+GCC_ASM_EXPORT(InitializeSMC)\r
+\r
+# Static memory configuation definitions for SMC\r
+.set        SmcDirectCmd,              0x10\r
+.set        SmcSetCycles,              0x14\r
+.set        SmcSetOpMode,              0x18\r
+\r
+# CS0  CS0-Interf0     NOR1 flash on the motherboard\r
+# CS1  CS1-Interf0     Reserved for the motherboard\r
+# CS2  CS2-Interf0     SRAM on the motherboard\r
+# CS3  CS3-Interf0     memory-mapped Ethernet and USB controllers on the motherboard\r
+# CS4  CS0-Interf1     NOR2 flash on the motherboard\r
+# CS5  CS1-Interf1     memory-mapped peripherals\r
+# CS6  CS2-Interf1     memory-mapped peripherals\r
+# CS7  CS3-Interf1     system memory-mapped peripherals on the motherboard.\r
+\r
+# IN r1 SmcBase\r
+# IN r2 VideoSRamBase\r
+# NOTE: This code is been called before any stack has been setup. It means some registers\r
+#       could be overwritten (case of 'r0')\r
+\r
+\r
+ASM_PFX(InitializeSMC):\r
+#\r
+# Setup NOR1 (CS0-Interface0)\r
+#\r
+\r
+  #Write to set_cycle register(holding register for NOR 1 cycle register or NAND cycle register)\r
+     #Read cycle timeout = 0xA (0:3)\r
+     #Write cycle timeout = 0x3(7:4)\r
+     #OE Assertion Delay = 0x9(11:8)\r
+     #WE Assertion delay = 0x3(15:12)\r
+     #Page cycle timeout = 0x2(19:16)  \r
+  LoadConstantToReg (0x0002393A,r0)       @ldr     r0, = 0x0002393A\r
+  str     r0, [r1, #SmcSetCycles]\r
+  \r
+  #Write to set_opmode register(holding register for NOR 1 opomode register or NAND opmode register)\r
+     # 0x00000002 = MemoryWidth: 32bit\r
+     # 0x00000028 = ReadMemoryBurstLength:continuous\r
+     # 0x00000280 = WriteMemoryBurstLength:continuous\r
+     # 0x00000800 = Set Address Valid\r
+  LoadConstantToReg (0x00000AAA,r0)       @ldr     r0, = 0x00000AAA\r
+  str     r0, [r1, #SmcSetOpMode]    \r
+\r
+ #Write to direct_cmd register so that the NOR 1 registers(set-cycles and opmode) are updated with holding registers\r
+     # 0x00000000 = ChipSelect0-Interface 0\r
+     # 0x00400000 = CmdTypes: UpdateRegs\r
+  LoadConstantToReg (0x00400000,r0)       @ldr     r0, = 0x00400000\r
+  str     r0, [r1, #SmcDirectCmd]                              \r
+  \r
+  \r
+#\r
+# Setup SRAM (CS2-Interface0)\r
+#\r
+  LoadConstantToReg (0x00027158,r0)       @ldr     r0, = 0x00027158\r
+  str     r0, [r1, #SmcSetCycles]\r
+\r
+  # 0x00000002 = MemoryWidth: 32bit\r
+  # 0x00000800 = Set Address Valid\r
+  LoadConstantToReg (0x00000802,r0)       @ldr     r0, = 0x00000802\r
+  str     r0, [r1, #SmcSetOpMode]\r
+  \r
+  # 0x01000000 = ChipSelect2-Interface 0\r
+  # 0x00400000 = CmdTypes: UpdateRegs\r
+  LoadConstantToReg (0x01400000,r0)       @ldr     r0, = 0x01400000\r
+  str     r0, [r1, #SmcDirectCmd]\r
+\r
+#\r
+# USB/Eth/VRAM (CS3-Interface0)\r
+#\r
+  LoadConstantToReg (0x000CD2AA,r0)      @ldr     r0, = 0x000CD2AA\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  # 0x00000002 = MemoryWidth: 32bit\r
+  # 0x00000004 = Memory reads are synchronous\r
+  # 0x00000040 = Memory writes are synchronous\r
+  LoadConstantToReg (0x00000046,r0)      @ldr     r0, = 0x00000046\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  # 0x01800000 = ChipSelect3-Interface 0\r
+  # 0x00400000 = CmdTypes: UpdateRegs\r
+  LoadConstantToReg (0x01C00000,r0)      @ldr     r0, = 0x01C00000\r
+  str     r0, [r1, #SmcDirectCmd]  \r
+\r
+#\r
+# Setup NOR3 (CS0-Interface1)\r
+#\r
+  LoadConstantToReg (0x0002393A,r0)      @ldr     r0, = 0x0002393A\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  # 0x00000002 = MemoryWidth: 32bit\r
+  # 0x00000028 = ReadMemoryBurstLength:continuous\r
+  # 0x00000280 = WriteMemoryBurstLength:continuous\r
+  # 0x00000800 = Set Address Valid\r
+  LoadConstantToReg (0x00000AAA,r0)      @ldr     r0, = 0x00000AAA\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  # 0x02000000 = ChipSelect0-Interface 1\r
+  # 0x00400000 = CmdTypes: UpdateRegs\r
+  LoadConstantToReg (0x02400000,r0)      @ldr     r0, = 0x02400000\r
+  str     r0, [r1, #SmcDirectCmd]  \r
\r
+#\r
+# Setup Peripherals (CS3-Interface1)\r
+#\r
+  LoadConstantToReg (0x00025156,r0)      @ldr     r0, = 0x00025156\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  # 0x00000002 = MemoryWidth: 32bit\r
+  # 0x00000004 = Memory reads are synchronous\r
+  # 0x00000040 = Memory writes are synchronous\r
+  LoadConstantToReg (0x00000046,r0)      @ldr     r0, = 0x00000046\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  # 0x03800000 = ChipSelect3-Interface 1\r
+  # 0x00400000 = CmdTypes: UpdateRegs\r
+  LoadConstantToReg (0x03C00000,r0)      @ldr     r0, = 0x03C00000\r
+  str     r0, [r1, #SmcDirectCmd] \r
+\r
+#\r
+# Setup VRAM (CS1-Interface0)\r
+#\r
+  LoadConstantToReg (0x00049249,r0)      @ldr     r0, =  0x00049249\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  # 0x00000002 = MemoryWidth: 32bit\r
+  # 0x00000004 = Memory reads are synchronous\r
+  # 0x00000040 = Memory writes are synchronous\r
+  LoadConstantToReg (0x00000046,r0)      @ldr     r0, = 0x00000046\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  # 0x00800000 = ChipSelect1-Interface 0\r
+  # 0x00400000 = CmdTypes: UpdateRegs\r
+  LoadConstantToReg (0x00C00000,r0)      @ldr     r0, = 0x00C00000\r
+  str     r0, [r1, #SmcDirectCmd]  \r
+  \r
+#\r
+# Page mode setup for VRAM\r
+#\r
+  #read current state \r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, [r2, #0]  \r
+  LoadConstantToReg (0x00000000,r0)      @ldr     r0, = 0x00000000\r
+  str     r0, [r2, #0] \r
+  ldr     r0, [r2, #0]  \r
+\r
+  #enable page mode \r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, [r2, #0]  \r
+  LoadConstantToReg (0x00000000,r0)      @ldr     r0, = 0x00000000\r
+  str     r0, [r2, #0] \r
+  LoadConstantToReg (0x00900090,r0)      @ldr     r0, = 0x00900090\r
+  str     r0, [r2, #0] \r
+\r
+  #confirm page mode enabled\r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, [r2, #0]  \r
+  LoadConstantToReg (0x00000000,r0)      @ldr     r0, = 0x00000000\r
+  str     r0, [r2, #0] \r
+  ldr     r0, [r2, #0]  \r
+  \r
+  bx    lr\r
+  \r
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
\ No newline at end of file
diff --git a/ArmPkg/Drivers/PL35xSmc/InitializeSMC.asm b/ArmPkg/Drivers/PL35xSmc/InitializeSMC.asm
new file mode 100644 (file)
index 0000000..ebf6a79
--- /dev/null
@@ -0,0 +1,183 @@
+//\r
+//  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+//  \r
+//  This program and the accompanying materials                          \r
+//  are licensed and made available under the terms and conditions of the BSD License         \r
+//  which accompanies this distribution.  The full text of the license may be found at        \r
+//  http://opensource.org/licenses/bsd-license.php                                            \r
+//\r
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+//\r
+//\r
+\r
+#include <AsmMacroIoLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <AutoGen.h>\r
+\r
+  INCLUDE AsmMacroIoLib.inc\r
+  \r
+  EXPORT  InitializeSMC\r
+\r
+  PRESERVE8\r
+  AREA    ModuleInitializeSMC, CODE, READONLY\r
+  \r
+// Static memory configuation definitions for SMC\r
+SmcDirectCmd              EQU 0x10\r
+SmcSetCycles              EQU 0x14\r
+SmcSetOpMode              EQU 0x18\r
+\r
+// CS0  CS0-Interf0     NOR1 flash on the motherboard\r
+// CS1  CS1-Interf0     Reserved for the motherboard\r
+// CS2  CS2-Interf0     SRAM on the motherboard\r
+// CS3  CS3-Interf0     memory-mapped Ethernet and USB controllers on the motherboard\r
+// CS4  CS0-Interf1     NOR2 flash on the motherboard\r
+// CS5  CS1-Interf1     memory-mapped peripherals\r
+// CS6  CS2-Interf1     memory-mapped peripherals\r
+// CS7  CS3-Interf1     system memory-mapped peripherals on the motherboard.\r
+\r
+// IN r1 SmcBase\r
+// IN r2 VideoSRamBase\r
+// NOTE: This code is been called before any stack has been setup. It means some registers\r
+//       could be overwritten (case of 'r0')\r
+InitializeSMC\r
+//\r
+// Setup NOR1 (CS0-Interface0)\r
+//\r
+\r
+  //Write to set_cycle register(holding register for NOR 1 cycle register or NAND cycle register)\r
+     //Read cycle timeout = 0xA (0:3)\r
+     //Write cycle timeout = 0x3(7:4)\r
+     //OE Assertion Delay = 0x9(11:8)\r
+     //WE Assertion delay = 0x3(15:12)\r
+     //Page cycle timeout = 0x2(19:16)  \r
+  ldr     r0, = 0x0002393A\r
+  str     r0, [r1, #SmcSetCycles]\r
+  \r
+  //Write to set_opmode register(holding register for NOR 1 opomode register or NAND opmode register)\r
+     // 0x00000002 = MemoryWidth: 32bit\r
+     // 0x00000028 = ReadMemoryBurstLength:continuous\r
+     // 0x00000280 = WriteMemoryBurstLength:continuous\r
+     // 0x00000800 = Set Address Valid\r
+  ldr     r0, = 0x00000AAA\r
+  str     r0, [r1, #SmcSetOpMode]    \r
+\r
+ //Write to direct_cmd register so that the NOR 1 registers(set-cycles and opmode) are updated with holding registers\r
+     // 0x00000000 = ChipSelect0-Interface 0\r
+     // 0x00400000 = CmdTypes: UpdateRegs\r
+  ldr     r0, = 0x00400000\r
+  str     r0, [r1, #SmcDirectCmd]                              \r
+  \r
+//\r
+// Setup SRAM (CS2-Interface0)\r
+//\r
+  ldr     r0, = 0x00027158\r
+  str     r0, [r1, #SmcSetCycles]\r
+\r
+  // 0x00000002 = MemoryWidth: 32bit\r
+  // 0x00000800 = Set Address Valid\r
+  ldr     r0, = 0x00000802\r
+  str     r0, [r1, #SmcSetOpMode]\r
+  \r
+  // 0x01000000 = ChipSelect2-Interface 0\r
+  // 0x00400000 = CmdTypes: UpdateRegs\r
+  ldr     r0, = 0x01400000\r
+  str     r0, [r1, #SmcDirectCmd]\r
+\r
+//\r
+// USB/Eth/VRAM (CS3-Interface0)\r
+//\r
+  ldr     r0, = 0x000CD2AA\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  // 0x00000002 = MemoryWidth: 32bit\r
+  // 0x00000004 = Memory reads are synchronous\r
+  // 0x00000040 = Memory writes are synchronous\r
+  ldr     r0, = 0x00000046\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  // 0x01800000 = ChipSelect3-Interface 0\r
+  // 0x00400000 = CmdTypes: UpdateRegs\r
+  ldr     r0, = 0x01C00000\r
+  str     r0, [r1, #SmcDirectCmd]  \r
+\r
+//\r
+// Setup NOR3 (CS0-Interface1)\r
+//\r
+  ldr     r0, = 0x0002393A\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  // 0x00000002 = MemoryWidth: 32bit\r
+  // 0x00000028 = ReadMemoryBurstLength:continuous\r
+  // 0x00000280 = WriteMemoryBurstLength:continuous\r
+  // 0x00000800 = Set Address Valid\r
+  ldr     r0, = 0x00000AAA\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  // 0x02000000 = ChipSelect0-Interface 1\r
+  // 0x00400000 = CmdTypes: UpdateRegs\r
+  ldr     r0, = 0x02400000\r
+  str     r0, [r1, #SmcDirectCmd]  \r
\r
+//\r
+// Setup Peripherals (CS3-Interface1)\r
+//\r
+  ldr     r0, = 0x00025156\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  // 0x00000002 = MemoryWidth: 32bit\r
+  // 0x00000004 = Memory reads are synchronous\r
+  // 0x00000040 = Memory writes are synchronous\r
+  ldr     r0, = 0x00000046\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  // 0x03800000 = ChipSelect3-Interface 1\r
+  // 0x00400000 = CmdTypes: UpdateRegs\r
+  ldr     r0, = 0x03C00000\r
+  str     r0, [r1, #SmcDirectCmd] \r
+\r
+//\r
+// Setup VRAM (CS1-Interface0)\r
+//\r
+  ldr     r0, =  0x00049249\r
+  str     r0, [r1, #SmcSetCycles]\r
\r
+  // 0x00000002 = MemoryWidth: 32bit\r
+  // 0x00000004 = Memory reads are synchronous\r
+  // 0x00000040 = Memory writes are synchronous\r
+  ldr     r0, = 0x00000046\r
+  str     r0, [r1, #SmcSetOpMode]  \r
+        \r
+  // 0x00800000 = ChipSelect1-Interface 0\r
+  // 0x00400000 = CmdTypes: UpdateRegs\r
+  ldr     r0, = 0x00C00000\r
+  str     r0, [r1, #SmcDirectCmd]  \r
+  \r
+//\r
+// Page mode setup for VRAM\r
+//\r
+  //read current state \r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, = 0x00000000\r
+  str     r0, [r2, #0] \r
+  ldr     r0, [r2, #0]  \r
+\r
+  //enable page mode \r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, = 0x00000000\r
+  str     r0, [r2, #0] \r
+  ldr     r0, = 0x00900090\r
+  str     r0, [r2, #0] \r
+\r
+  //confirm page mode enabled\r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, [r2, #0]  \r
+  ldr     r0, = 0x00000000\r
+  str     r0, [r2, #0] \r
+  ldr     r0, [r2, #0]  \r
+  \r
+  bx    lr\r
+  \r
+  END\r
diff --git a/ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf b/ArmPkg/Drivers/PL35xSmc/PL354SmcSec.inf
new file mode 100644 (file)
index 0000000..188f080
--- /dev/null
@@ -0,0 +1,30 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PL354SmcSec\r
+  FILE_GUID                      = 10952220-aa32-11df-a438-0002a5d5c51b\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PL354SmcSecLib\r
+\r
+[Sources.common]\r
+  InitializeSMC.asm  | RVCT\r
+  InitializeSMC.S    | GCC\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[FixedPcd]\r
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicDxe.c b/ArmPkg/Drivers/PL390Gic/PL390GicDxe.c
new file mode 100644 (file)
index 0000000..da86bbc
--- /dev/null
@@ -0,0 +1,435 @@
+/*++
+
+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>                                                         
+This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.   
+
+Module Name:
+
+  Gic.c
+
+Abstract:
+
+  Driver implementing the GIC interrupt controller protocol
+
+--*/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include <Drivers/PL390Gic.h>
+
+// number of 32-bit registers needed to represent those interrupts as a bit
+// (used for enable set, enable clear, pending set, pending clear, and active regs)
+#define GIC_NUM_REG_PER_INT_BITS   (PcdGet32(PcdGicNumInterrupts) / 32)
+
+// number of 32-bit registers needed to represent those interrupts as two bits
+// (used for configuration reg)
+#define GIC_NUM_REG_PER_INT_CFG    (PcdGet32(PcdGicNumInterrupts) / 16)
+
+// number of 32-bit registers needed to represent interrupts as 8-bit priority field
+// (used for priority regs)
+#define GIC_NUM_REG_PER_INT_BYTES  (PcdGet32(PcdGicNumInterrupts) / 4)
+
+#define GIC_DEFAULT_PRIORITY  0x80
+
+extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol;
+
+//
+// Notifications
+//
+VOID      *CpuProtocolNotificationToken = NULL;
+EFI_EVENT CpuProtocolNotificationEvent  = (EFI_EVENT)NULL;
+EFI_EVENT EfiExitBootServicesEvent      = (EFI_EVENT)NULL;
+
+HARDWARE_INTERRUPT_HANDLER  gRegisteredInterruptHandlers[FixedPcdGet32(PcdGicNumInterrupts)];
+
+/**
+  Register Handler for the specified interrupt source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+  @param Handler  Callback for interrupt. NULL to unregister
+
+  @retval EFI_SUCCESS Source was updated to support Handler.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source,
+  IN HARDWARE_INTERRUPT_HANDLER         Handler
+  )
+{
+  if (Source > PcdGet32(PcdGicNumInterrupts)) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  } 
+  
+  if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  gRegisteredInterruptHandlers[Source] = Handler;
+  return This->EnableInterruptSource(This, Source);
+}
+
+/**
+  Enable interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt enabled.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  UINT32    RegOffset;
+  UINTN     RegShift;
+  
+  if (Source > PcdGet32(PcdGicNumInterrupts)) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  
+  // calculate enable register offset and bit position
+  RegOffset = Source / 32;
+  RegShift = Source % 32;
+
+  // write set-enable register
+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDISER+(4*RegOffset), 1 << RegShift);
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Disable interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt disabled.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  UINT32    RegOffset;
+  UINTN     RegShift;
+  
+  if (Source > PcdGet32(PcdGicNumInterrupts)) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  
+  // calculate enable register offset and bit position
+  RegOffset = Source / 32;
+  RegShift = Source % 32;
+
+  // write set-enable register
+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDICER+(4*RegOffset), 1 << RegShift);
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Return current state of interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+  @param InterruptState  TRUE: source enabled, FALSE: source disabled.
+
+  @retval EFI_SUCCESS       InterruptState is valid
+  @retval EFI_DEVICE_ERROR  InterruptState is not valid
+
+**/
+EFI_STATUS
+EFIAPI
+GetInterruptSourceState (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source,
+  IN BOOLEAN                            *InterruptState
+  )
+{
+  UINT32    RegOffset;
+  UINTN     RegShift;
+  
+  if (Source > PcdGet32(PcdGicNumInterrupts)) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  
+  // calculate enable register offset and bit position
+  RegOffset = Source / 32;
+  RegShift = Source % 32;
+    
+  if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDISER+(4*RegOffset)) & (1<<RegShift)) == 0) {
+    *InterruptState = FALSE;
+  } else {
+    *InterruptState = TRUE;
+  }
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Signal to the hardware that the End Of Intrrupt state 
+  has been reached.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt EOI'ed.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EndOfInterrupt (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  if (Source > PcdGet32(PcdGicNumInterrupts)) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCEIOR, Source);
+  return EFI_SUCCESS;
+}
+
+/**
+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
+
+  @param  InterruptType    Defines the type of interrupt or exception that
+                           occurred on the processor.This parameter is processor architecture specific.
+  @param  SystemContext    A pointer to the processor context when
+                           the interrupt occurred on the processor.
+
+  @return None
+
+**/
+VOID
+EFIAPI
+IrqInterruptHandler (
+  IN EFI_EXCEPTION_TYPE           InterruptType,
+  IN EFI_SYSTEM_CONTEXT           SystemContext
+  )
+{
+  UINT32                      GicInterrupt;
+  HARDWARE_INTERRUPT_HANDLER  InterruptHandler;
+
+  GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCIAR);
+  if (GicInterrupt >= PcdGet32(PcdGicNumInterrupts)) {
+    MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCEIOR, GicInterrupt);
+  }
+  
+  InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
+  if (InterruptHandler != NULL) {
+    // Call the registered interrupt handler.
+    InterruptHandler (GicInterrupt, SystemContext);
+  } else {
+    DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
+  }
+
+  EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt);
+}
+
+//
+// Making this global saves a few bytes in image size
+//
+EFI_HANDLE  gHardwareInterruptHandle = NULL;
+
+//
+// The protocol instance produced by this driver
+//
+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
+  RegisterInterruptSource,
+  EnableInterruptSource,
+  DisableInterruptSource,
+  GetInterruptSourceState,
+  EndOfInterrupt
+};
+
+/**
+  Shutdown our hardware
+  
+  DXE Core will disable interrupts and turn off the timer and disable interrupts
+  after all the event handlers have run.
+
+  @param[in]  Event   The Event that is being processed
+  @param[in]  Context Event Context
+**/
+VOID
+EFIAPI
+ExitBootServicesEvent (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  UINTN    i;
+  
+  for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
+    DisableInterruptSource (&gHardwareInterruptProtocol, i);
+  }
+
+  // Acknowledge all pending interrupts
+  for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
+    DisableInterruptSource (&gHardwareInterruptProtocol, i);
+  }
+
+  for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
+    EndOfInterrupt (&gHardwareInterruptProtocol, i);
+  }
+
+  // Disable Gic Interface
+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCICR, 0x0);
+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCPMR, 0x0);
+
+  // Disable Gic Distributor
+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDDCR, 0x0);
+}
+
+//
+// Notification routines
+//
+VOID
+CpuProtocolInstalledNotification (
+  IN EFI_EVENT   Event,
+  IN VOID        *Context
+  )
+{
+  EFI_STATUS              Status;
+  EFI_CPU_ARCH_PROTOCOL   *Cpu;
+  
+  //
+  // Get the cpu protocol that this driver requires.
+  //
+  Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Unregister the default exception handler.
+  //
+  Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Register to receive interrupts
+  //
+  Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler);
+  ASSERT_EFI_ERROR(Status);
+}
+
+/**
+  Initialize the state information for the CPU Architectural Protocol
+
+  @param  ImageHandle   of the loaded driver
+  @param  SystemTable   Pointer to the System Table
+
+  @retval EFI_SUCCESS           Protocol registered
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Hardware problems
+
+**/
+EFI_STATUS
+InterruptDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  UINTN      i;
+  UINT32      RegOffset;
+  UINTN       RegShift;
+  
+  // Make sure the Interrupt Controller Protocol is not already installed in the system.
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
+
+  for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
+    DisableInterruptSource (&gHardwareInterruptProtocol, i);
+    
+    // Set Priority 
+    RegOffset = i / 4;
+    RegShift = (i % 4) * 8;
+    MmioAndThenOr32 (
+      PcdGet32(PcdGicDistributorBase) + GIC_ICDIPR+(4*RegOffset), 
+      ~(0xff << RegShift), 
+      GIC_DEFAULT_PRIORITY << RegShift
+      );
+  }
+
+  // configure interrupts for cpu 0
+  for (i = 0; i < GIC_NUM_REG_PER_INT_BYTES; i++) {
+    MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDIPTR + (i*4), 0x01010101);
+  }
+
+  // set binary point reg to 0x7 (no preemption)
+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCBPR, 0x7);
+
+  // set priority mask reg to 0xff to allow all priorities through
+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCPMR, 0xff);
+  
+  // enable gic cpu interface
+  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + GIC_ICCICR, 0x1);
+
+  // enable gic distributor
+  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDDCR, 0x1);
+  
+  ZeroMem (&gRegisteredInterruptHandlers, sizeof (gRegisteredInterruptHandlers));
+  
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &gHardwareInterruptHandle,
+                  &gHardwareInterruptProtocolGuid,   &gHardwareInterruptProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  
+  // Set up to be notified when the Cpu protocol is installed.
+  Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, CpuProtocolInstalledNotification, NULL, &CpuProtocolNotificationEvent);    
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->RegisterProtocolNotify (&gEfiCpuArchProtocolGuid, CpuProtocolNotificationEvent, (VOID *)&CpuProtocolNotificationToken);
+  ASSERT_EFI_ERROR (Status);
+
+  // Register for an ExitBootServicesEvent
+  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf b/ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
new file mode 100644 (file)
index 0000000..9077565
--- /dev/null
@@ -0,0 +1,55 @@
+#/** @file
+#  
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#  
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PL390GicDxe
+  FILE_GUID                      = DE371F7C-DEC4-4D21-ADF1-593ABCC15882 
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InterruptDxeInitialize
+
+
+[Sources.common]
+  PL390GicDxe.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiLib
+  UefiBootServicesTableLib
+  DebugLib
+  PrintLib
+  UefiDriverEntryPoint
+  IoLib
+
+[Guids]
+  
+
+[Protocols]
+  gHardwareInterruptProtocolGuid
+  gEfiCpuArchProtocolGuid
+  
+[FixedPcd.common]
+  gArmTokenSpaceGuid.PcdGicDistributorBase
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+  gArmTokenSpaceGuid.PcdGicNumInterrupts
+
+[depex]
+  TRUE
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c b/ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c
new file mode 100644 (file)
index 0000000..e5faa40
--- /dev/null
@@ -0,0 +1,97 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Drivers/PL390Gic.h>\r
+\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicEnableInterruptInterface (\r
+  IN  INTN          GicInterruptInterfaceBase\r
+  )\r
+{      \r
+       /*\r
+        * Enable the CPU interface in Non-Secure world\r
+        * Note: The ICCICR register is banked when Security extensions are implemented  \r
+        */\r
+    MmioWrite32(GicInterruptInterfaceBase + GIC_ICCICR,0x00000001);\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicEnableDistributor (\r
+  IN  INTN          GicDistributorBase\r
+  )\r
+{\r
+    /*\r
+     * Enable GIC distributor in Non-Secure world.\r
+     * Note: The ICDDCR register is banked when Security extensions are implemented\r
+     */\r
+    MmioWrite32(GicDistributorBase + GIC_ICDDCR, 0x00000001);\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicSendSgiTo (\r
+  IN  INTN          GicDistributorBase,\r
+  IN  INTN          TargetListFilter,\r
+  IN  INTN          CPUTargetList\r
+  )\r
+{\r
+       MmioWrite32(GicDistributorBase + GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16));\r
+}\r
+\r
+UINT32\r
+EFIAPI\r
+PL390GicAcknowledgeSgiFrom (\r
+  IN  INTN          GicInterruptInterfaceBase,\r
+  IN  INTN          CoreId\r
+  )\r
+{\r
+    INTN            InterruptId;\r
+\r
+    InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);\r
+\r
+    //Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID\r
+       if (((CoreId & 0x7) << 10) == (InterruptId & 0x1C00)) {\r
+           //Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR\r
+               MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);\r
+        return 1;\r
+    } else {\r
+        return 0;\r
+    }\r
+}\r
+\r
+UINT32\r
+EFIAPI\r
+PL390GicAcknowledgeSgi2From (\r
+  IN  INTN          GicInterruptInterfaceBase,\r
+  IN  INTN          CoreId,\r
+  IN  INTN          SgiId\r
+  )\r
+{\r
+    INTN            InterruptId;\r
+\r
+    InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);\r
+\r
+    //Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID\r
+       if((((CoreId & 0x7) << 10) | (SgiId & 0x3FF)) == (InterruptId & 0x1FFF)) {\r
+           //Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR\r
+               MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);\r
+        return 1;\r
+    } else {\r
+        return 0;\r
+    }\r
+}\r
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf b/ArmPkg/Drivers/PL390Gic/PL390GicNonSec.inf
new file mode 100644 (file)
index 0000000..f5ffd7f
--- /dev/null
@@ -0,0 +1,29 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PL390GicNonSec\r
+  FILE_GUID                      = 03d05ee4-cdeb-458c-9dfc-993f09bdf405\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PL390GicNonSecLib\r
+\r
+[Sources]\r
+  PL390GicNonSec.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[FixedPcd]\r
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c b/ArmPkg/Drivers/PL390Gic/PL390GicSec.c
new file mode 100644 (file)
index 0000000..46b14e0
--- /dev/null
@@ -0,0 +1,135 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Drivers/PL390Gic.h>\r
+\r
+/*\r
+ * This function configures the all interrupts to be Non-secure.\r
+ *\r
+ */\r
+VOID\r
+EFIAPI\r
+PL390GicSetupNonSecure (\r
+  IN  INTN          GicDistributorBase,\r
+  IN  INTN          GicInterruptInterfaceBase\r
+  )\r
+{\r
+   UINTN CachedPriorityMask = MmioRead32(GicInterruptInterfaceBase + GIC_ICCPMR);\r
+\r
+   //Set priority Mask so that no interrupts get through to CPU\r
+   MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, 0);\r
+\r
+   //Check if there are any pending interrupts\r
+   while(0 != (MmioRead32(GicDistributorBase + GIC_ICDICPR) & 0xF))\r
+   {\r
+          //Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal\r
+          UINTN InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);\r
+\r
+          //Write to End of interrupt signal\r
+          MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);\r
+   }\r
+\r
+  // Ensure all GIC interrupts are Non-Secure\r
+   MmioWrite32(GicDistributorBase + GIC_ICDISR, 0xffffffff);     // IRQs  0-31 are Non-Secure : Private Peripheral Interrupt[31:16] & Software Generated Interrupt[15:0]\r
+   MmioWrite32(GicDistributorBase + GIC_ICDISR + 4, 0xffffffff); // IRQs 32-63 are Non-Secure : Shared Peripheral Interrupt\r
+   MmioWrite32(GicDistributorBase + GIC_ICDISR + 8, 0xffffffff); // And another 32 in case we're on the testchip : Shared Peripheral Interrupt (2)\r
+\r
+  // Ensure all interrupts can get through the priority mask\r
+   MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, CachedPriorityMask);\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicEnableInterruptInterface (\r
+  IN  INTN          GicInterruptInterfaceBase\r
+  )\r
+{\r
+       MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, 0x000000FF);  /* Set Priority Mask to allow interrupts */\r
+\r
+       /*\r
+        * Enable CPU interface in Secure world\r
+     * Enable CPU inteface in Non-secure World\r
+        * Signal Secure Interrupts to CPU using FIQ line *\r
+        */\r
+    MmioWrite32(GicInterruptInterfaceBase + GIC_ICCICR,\r
+               GIC_ICCICR_ENABLE_SECURE(1) |\r
+               GIC_ICCICR_ENABLE_NS(1) |\r
+               GIC_ICCICR_ACK_CTL(0) |\r
+               GIC_ICCICR_SIGNAL_SECURE_TO_FIQ(1) |\r
+               GIC_ICCICR_USE_SBPR(0));\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicEnableDistributor (\r
+  IN  INTN          GicDistributorBase\r
+  )\r
+{\r
+    MmioWrite32(GicDistributorBase + GIC_ICDDCR, 1);               // turn on the GIC distributor\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicSendSgiTo (\r
+  IN  INTN          GicDistributorBase,\r
+  IN  INTN          TargetListFilter,\r
+  IN  INTN          CPUTargetList\r
+  )\r
+{\r
+       MmioWrite32(GicDistributorBase + GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16));\r
+}\r
+\r
+UINT32\r
+EFIAPI\r
+PL390GicAcknowledgeSgiFrom (\r
+  IN  INTN          GicInterruptInterfaceBase,\r
+  IN  INTN          CoreId\r
+  )\r
+{\r
+    INTN            InterruptId;\r
+\r
+    InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);\r
+\r
+    //Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID\r
+       if (((CoreId & 0x7) << 10) == (InterruptId & 0x1C00)) {\r
+           //Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR\r
+               MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);\r
+        return 1;\r
+    } else {\r
+        return 0;\r
+    }\r
+}\r
+\r
+UINT32\r
+EFIAPI\r
+PL390GicAcknowledgeSgi2From (\r
+  IN  INTN          GicInterruptInterfaceBase,\r
+  IN  INTN          CoreId,\r
+  IN  INTN          SgiId\r
+  )\r
+{\r
+    INTN            InterruptId;\r
+\r
+    InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR);\r
+\r
+    //Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID\r
+       if((((CoreId & 0x7) << 10) | (SgiId & 0x3FF)) == (InterruptId & 0x1FFF)) {\r
+           //Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR\r
+               MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId);\r
+        return 1;\r
+    } else {\r
+        return 0;\r
+    }\r
+}\r
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSec.inf b/ArmPkg/Drivers/PL390Gic/PL390GicSec.inf
new file mode 100644 (file)
index 0000000..9cbdb6e
--- /dev/null
@@ -0,0 +1,29 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PL390GicSec\r
+  FILE_GUID                      = 85f3cf80-b5f4-11df-9855-0002a5d5c51b\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PL390GicSecLib\r
+\r
+[Sources]\r
+  PL390GicSec.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[FixedPcd]\r
index 5bf679458d65ed123a706bc89fc057257ef4f1fa..68e120abcd86c23ccacb37da69ba1dcf02252e25 100644 (file)
 #define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK                 (0xFFF00000)\r
 #define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a)                   (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)\r
 \r
-#define TT_DESCRIPTOR_SECTION_WRITE_BACK          (TT_DESCRIPTOR_TYPE_SECTION                              | \\r
-                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \\r
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK(Secure)       (TT_DESCRIPTOR_TYPE_SECTION                                                          | \\r
+                                                        (Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE )   | \\r
                                                    TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
                                                    TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
                                                    TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
                                                    TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
                                                    TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)\r
-#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH       (TT_DESCRIPTOR_TYPE_SECTION                              | \\r
-                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \\r
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(Secure)    (TT_DESCRIPTOR_TYPE_SECTION                                                          | \\r
+                                                        (Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE )   | \\r
                                                    TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
                                                    TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
                                                    TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
                                                    TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
                                                    TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)\r
-#define TT_DESCRIPTOR_SECTION_UNCACHED            (TT_DESCRIPTOR_TYPE_SECTION                              | \\r
-                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \\r
+#define TT_DESCRIPTOR_SECTION_UNCACHED(Secure)         (TT_DESCRIPTOR_TYPE_SECTION                                                          | \\r
+                                                        (Secure ? TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE )   | \\r
                                                    TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
                                                    TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
                                                    TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
index 1f7aa46f7050701b74c85ecb8e51c36d1ae7aae1..b9d74305801a09f75c42eb54b2d271e18051aa4f 100644 (file)
 #define DOMAIN_ACCESS_CONTROL_RESERVED(a) (2UL << (2 * (a)))\r
 #define DOMAIN_ACCESS_CONTROL_MANAGER(a)  (3UL << (2 * (a)))\r
 \r
-#define TRANSLATION_TABLE_SIZE            (16 * 1024)\r
-#define TRANSLATION_TABLE_ALIGNMENT       (16 * 1024)\r
-#define TRANSLATION_TABLE_ALIGNMENT_MASK  (TRANSLATION_TABLE_ALIGNMENT - 1)\r
+#define TTBR_NOT_OUTER_SHAREABLE             BIT5\r
+#define TTBR_RGN_OUTER_NON_CACHEABLE         0\r
+#define TTBR_RGN_OUTER_WRITE_BACK_ALLOC      BIT3\r
+#define TTBR_RGN_OUTER_WRITE_THROUGH         BIT4\r
+#define TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC   (BIT3|BIT4)\r
+#define TTBR_SHAREABLE                       BIT1\r
+#define TTBR_NON_SHAREABLE                   0\r
+#define TTBR_INNER_CACHEABLE                 BIT0\r
+#define TTBR_NON_INNER_CACHEABLE             BIT0\r
+#define TTBR_RGN_INNER_NON_CACHEABLE         0\r
+#define TTBR_RGN_INNER_WRITE_BACK_ALLOC      BIT6\r
+#define TTBR_RGN_INNER_WRITE_THROUGH         BIT0\r
+#define TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC   (BIT0|BIT6)\r
+\r
+#define TTBR_WRITE_THROUGH_NO_ALLOC     ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )\r
+#define TTBR_WRITE_BACK_NO_ALLOC        ( TTBR_RGN_OUTER_WRITE_BACK_NO_ALLOC | TTBR_RGN_INNER_WRITE_BACK_NO_ALLOC )\r
+#define TTBR_NON_CACHEABLE              ( TTBR_RGN_OUTER_NON_CACHEABLE | TTBR_RGN_INNER_NON_CACHEABLE )\r
+#define TTBR_WRITE_BACK_ALLOC           ( TTBR_RGN_OUTER_WRITE_BACK_ALLOC | TTBR_RGN_INNER_WRITE_BACK_ALLOC )\r
+\r
+\r
+#define TRANSLATION_TABLE_SECTION_COUNT                 4096\r
+#define TRANSLATION_TABLE_SECTION_SIZE                  (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)\r
+#define TRANSLATION_TABLE_SECTION_ALIGNMENT             (sizeof(UINT32) * TRANSLATION_TABLE_SECTION_COUNT)\r
+#define TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK        (TRANSLATION_TABLE_SECTION_ALIGNMENT - 1)\r
+\r
+#define TRANSLATION_TABLE_PAGE_COUNT                 256\r
+#define TRANSLATION_TABLE_PAGE_SIZE                  (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)\r
+#define TRANSLATION_TABLE_PAGE_ALIGNMENT             (sizeof(UINT32) * TRANSLATION_TABLE_PAGE_COUNT)\r
+#define TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK        (TRANSLATION_TABLE_PAGE_ALIGNMENT - 1)\r
 \r
 #define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20))\r
 \r
 // Translation table descriptor types\r
-#define TT_DESCRIPTOR_TYPE_MASK         ((1UL << 18) | (3UL << 0))\r
-#define TT_DESCRIPTOR_TYPE_PAGE_TABLE   ((0UL << 18) | (1UL << 0))\r
-#define TT_DESCRIPTOR_TYPE_SECTION      ((0UL << 18) | (2UL << 0))\r
-#define TT_DESCRIPTOR_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))\r
+#define TT_DESCRIPTOR_SECTION_TYPE_MASK         ((1UL << 18) | (3UL << 0))\r
+#define TT_DESCRIPTOR_SECTION_TYPE_FAULT        (0UL << 0)\r
+#define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE   (1UL << 0)\r
+#define TT_DESCRIPTOR_SECTION_TYPE_SECTION      ((0UL << 18) | (2UL << 0))\r
+#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0))\r
+#define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE)\r
+\r
+// Translation table descriptor types\r
+#define TT_DESCRIPTOR_PAGE_TYPE_MASK         (3UL << 0)\r
+#define TT_DESCRIPTOR_PAGE_TYPE_FAULT        (0UL << 0)\r
+#define TT_DESCRIPTOR_PAGE_TYPE_PAGE         (2UL << 0)\r
+#define TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN      (3UL << 0)\r
+#define TT_DESCRIPTOR_PAGE_TYPE_LARGEPAGE    (1UL << 0)\r
 \r
 // Section descriptor definitions\r
 #define TT_DESCRIPTOR_SECTION_SIZE                              (0x00100000)\r
 #define TT_DESCRIPTOR_SECTION_NG_GLOBAL                         (0UL << 17)\r
 #define TT_DESCRIPTOR_SECTION_NG_LOCAL                          (1UL << 17)\r
 \r
+#define TT_DESCRIPTOR_PAGE_NG_MASK                              (1UL << 11)\r
+#define TT_DESCRIPTOR_PAGE_NG_GLOBAL                            (0UL << 11)\r
+#define TT_DESCRIPTOR_PAGE_NG_LOCAL                             (1UL << 11)\r
+\r
 #define TT_DESCRIPTOR_SECTION_S_MASK                            (1UL << 16)\r
 #define TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      (0UL << 16)\r
 #define TT_DESCRIPTOR_SECTION_S_SHARED                          (1UL << 16)\r
 \r
+#define TT_DESCRIPTOR_PAGE_S_MASK                               (1UL << 10)\r
+#define TT_DESCRIPTOR_PAGE_S_NOT_SHARED                         (0UL << 10)\r
+#define TT_DESCRIPTOR_PAGE_S_SHARED                             (1UL << 10)\r
+\r
 #define TT_DESCRIPTOR_SECTION_AP_MASK                           ((1UL << 15) | (3UL << 10))\r
 #define TT_DESCRIPTOR_SECTION_AP_NO_NO                          ((0UL << 15) | (0UL << 10))\r
 #define TT_DESCRIPTOR_SECTION_AP_RW_NO                          ((0UL << 15) | (1UL << 10))\r
 #define TT_DESCRIPTOR_SECTION_AP_RO_NO                          ((1UL << 15) | (1UL << 10))\r
 #define TT_DESCRIPTOR_SECTION_AP_RO_RO                          ((1UL << 15) | (3UL << 10))\r
 \r
-#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK                   ((3UL << 12) | (0UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_AP_MASK                              ((1UL << 9) | (3UL << 4))\r
+#define TT_DESCRIPTOR_PAGE_AP_NO_NO                             ((0UL << 9) | (0UL << 4))\r
+#define TT_DESCRIPTOR_PAGE_AP_RW_NO                             ((0UL << 9) | (1UL << 4))\r
+#define TT_DESCRIPTOR_PAGE_AP_RW_RO                             ((0UL << 9) | (2UL << 4))\r
+#define TT_DESCRIPTOR_PAGE_AP_RW_RW                             ((0UL << 9) | (3UL << 4))\r
+#define TT_DESCRIPTOR_PAGE_AP_RO_NO                             ((1UL << 9) | (1UL << 4))\r
+#define TT_DESCRIPTOR_PAGE_AP_RO_RO                             ((1UL << 9) | (3UL << 4))\r
+\r
+#define TT_DESCRIPTOR_SECTION_XN_MASK                           (0x1UL << 4)\r
+#define TT_DESCRIPTOR_PAGE_XN_MASK                              (0x1UL << 0)\r
+#define TT_DESCRIPTOR_LARGEPAGE_XN_MASK                         (0x1UL << 15)\r
+\r
+#define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK                   ((3UL << 12) | (1UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_SECTION_CACHEABLE_MASK                       (1UL << 3)\r
 #define TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED       ((0UL << 12) | (0UL << 3) | (0UL << 2))\r
 #define TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE       ((0UL << 12) | (0UL << 3) | (1UL << 2))\r
 #define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))\r
 #define TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 12) | (1UL << 3) | (1UL << 2))\r
 #define TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 12) | (0UL << 3) | (0UL << 2))\r
 \r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK                   ((3UL << 6) | (1UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_CACHEABLE_MASK                       (1UL << 3)\r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED       ((0UL << 6) | (0UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE       ((0UL << 6) | (0UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 6) | (1UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC    ((0UL << 6) | (1UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE          ((1UL << 6) | (0UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 6) | (1UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 6) | (0UL << 3) | (0UL << 2))\r
+\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK                   ((3UL << 12) | (0UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_STRONGLY_ORDERED       ((0UL << 12) | (0UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_SHAREABLE_DEVICE       ((0UL << 12) | (0UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC ((0UL << 12) | (1UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC    ((0UL << 12) | (1UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_CACHEABLE          ((1UL << 12) | (0UL << 3) | (0UL << 2))\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_WRITE_BACK_ALLOC       ((1UL << 12) | (1UL << 3) | (1UL << 2))\r
+#define TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE   ((2UL << 12) | (0UL << 3) | (0UL << 2))\r
+\r
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_AP_MASK) >> 6) & TT_DESCRIPTOR_PAGE_AP_MASK)\r
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_NG_MASK) >> 6) & TT_DESCRIPTOR_PAGE_NG_MASK)\r
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_S(Desc)                  ((((Desc) & TT_DESCRIPTOR_SECTION_S_MASK) >> 6) & TT_DESCRIPTOR_PAGE_S_MASK)\r
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(Desc,IsLargePage)      ((IsLargePage)? \\r
+                                                                    ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) >> 4) & TT_DESCRIPTOR_LARGEPAGE_XN_MASK):    \\r
+                                                                    ((((Desc) & TT_DESCRIPTOR_SECTION_XN_MASK) << 11) & TT_DESCRIPTOR_PAGE_XN_MASK))\r
+#define TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(Desc,IsLargePage)      (IsLargePage? \\r
+                                                                    (((Desc) & TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) & TT_DESCRIPTOR_LARGEPAGE_CACHE_POLICY_MASK): \\r
+                                                                    (((((Desc) & (0x3 << 12)) >> 6) | (Desc & (0x3 << 2)))))\r
+\r
 #define TT_DESCRIPTOR_SECTION_DOMAIN_MASK                       (0x0FUL << 5)\r
 #define TT_DESCRIPTOR_SECTION_DOMAIN(a)                         (((a) & 0x0FUL) << 5)\r
 \r
 #define TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK                 (0xFFF00000)\r
-#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a)                   (a & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)\r
-\r
-#define TT_DESCRIPTOR_SECTION_WRITE_BACK          (TT_DESCRIPTOR_TYPE_SECTION                              | \\r
-                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
-                                                   TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
-                                                   TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)\r
-#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH       (TT_DESCRIPTOR_TYPE_SECTION                              | \\r
-                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                     | \\r
-                                                   TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
-                                                   TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
-                                                   TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)\r
-#define TT_DESCRIPTOR_SECTION_DEVICE              (TT_DESCRIPTOR_TYPE_SECTION                              | \\r
-                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
-                                                   TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
-                                                   TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)\r
-#define TT_DESCRIPTOR_SECTION_UNCACHED            (TT_DESCRIPTOR_TYPE_SECTION                              | \\r
-                                                   TT_DESCRIPTOR_SECTION_NS_NON_SECURE                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
-                                                   TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
-                                                   TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
-                                                   TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)\r
+#define TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK            (0xFFFFFC00)\r
+#define TT_DESCRIPTOR_SECTION_BASE_ADDRESS(a)                   ((a) & TT_DESCRIPTOR_SECTION_BASE_ADDRESS_MASK)\r
+#define TT_DESCRIPTOR_SECTION_BASE_SHIFT                        20\r
+\r
+#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK                 (0xFFFFF000)\r
+#define TT_DESCRIPTOR_PAGE_INDEX_MASK                        (0x000FF000)\r
+#define TT_DESCRIPTOR_PAGE_BASE_ADDRESS(a)                   ((a) & TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK)\r
+#define TT_DESCRIPTOR_PAGE_BASE_SHIFT                        12\r
+\r
+#define TT_DESCRIPTOR_SECTION_WRITE_BACK(Secure)       (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \\r
+                                                        ((Secure) ?  TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE )    | \\r
+                                                                     TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
+                                                                     TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
+                                                                     TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC)\r
+#define TT_DESCRIPTOR_SECTION_WRITE_THROUGH(Secure)    (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \\r
+                                                        ((Secure) ?  TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE )    | \\r
+                                                                     TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
+                                                                     TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
+                                                                     TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC)\r
+#define TT_DESCRIPTOR_SECTION_DEVICE(Secure)           (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \\r
+                                                        ((Secure) ?  TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE )    | \\r
+                                                                     TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
+                                                                     TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
+                                                                     TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE)\r
+#define TT_DESCRIPTOR_SECTION_UNCACHED(Secure)         (TT_DESCRIPTOR_SECTION_TYPE_SECTION                                                           | \\r
+                                                        ((Secure) ?  TT_DESCRIPTOR_SECTION_NS_SECURE : TT_DESCRIPTOR_SECTION_NS_NON_SECURE )    | \\r
+                                                                     TT_DESCRIPTOR_SECTION_NG_GLOBAL                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_S_NOT_SHARED                      | \\r
+                                                                     TT_DESCRIPTOR_SECTION_DOMAIN(0)                         | \\r
+                                                                     TT_DESCRIPTOR_SECTION_AP_RW_RW                          | \\r
+                                                                     TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE)\r
+\r
+// Cortex A9 feature bit definitions\r
+#define A9_FEATURE_PARITY  (1<<9)\r
+#define A9_FEATURE_AOW     (1<<8)\r
+#define A9_FEATURE_EXCL    (1<<7)\r
+#define A9_FEATURE_SMP     (1<<6)\r
+#define A9_FEATURE_FOZ     (1<<3)\r
+#define A9_FEATURE_DPREF   (1<<2)\r
+#define A9_FEATURE_HINT    (1<<1)\r
+#define A9_FEATURE_FWD     (1<<0)\r
+\r
+// SCU register offsets & masks\r
+#define SCU_CONTROL_OFFSET       0x0\r
+#define SCU_CONFIG_OFFSET        0x4\r
+#define SCU_INVALL_OFFSET        0xC\r
+#define SCU_FILT_START_OFFSET    0x40\r
+#define SCU_FILT_END_OFFSET      0x44\r
+#define SCU_SACR_OFFSET          0x50\r
+#define SCU_SSACR_OFFSET         0x54\r
+\r
+#define SMP_GIC_CPUIF_BASE       0x100\r
+#define SMP_GIC_DIST_BASE        0x1000\r
+\r
+// CPACR - Coprocessor Access Control Register defintions\r
+#define CPACR_CP_DENIED(cp)     0x00\r
+#define CPACR_CP_PRIV(cp)       ((0x1 << ((cp) << 1)) & 0x0FFFFFFF)\r
+#define CPACR_CP_FULL(cp)       ((0x3 << ((cp) << 1)) & 0x0FFFFFFF)\r
+#define CPACR_ASEDIS            (1 << 31)\r
+#define CPACR_D32DIS            (1 << 30)\r
+#define CPACR_CP_FULL_ACCESS    0x0FFFFFFF\r
+\r
+// NSACR - Non-Secure Access Control Register defintions\r
+#define NSACR_CP(cp)            ((1 << (cp)) & 0x3FFF)\r
+#define NSACR_NSD32DIS          (1 << 14)\r
+#define NSACR_NSASEDIS          (1 << 15)\r
+#define NSACR_PLE               (1 << 16)\r
+#define NSACR_TL                (1 << 17)\r
+#define NSACR_NS_SMP            (1 << 18)\r
+#define NSACR_RFR               (1 << 19)\r
+\r
+// SCR - Secure Configuration Register defintions\r
+#define SCR_NS                  (1 << 0)\r
+#define SCR_IRQ                 (1 << 1)\r
+#define SCR_FIQ                 (1 << 2)\r
+#define SCR_EA                  (1 << 3)\r
+#define SCR_FW                  (1 << 4)\r
+#define SCR_AW                  (1 << 5)\r
+\r
+VOID\r
+EFIAPI\r
+ArmEnableSWPInstruction (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmWriteNsacr (\r
+  IN  UINT32   SetWayFormat\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmWriteScr (\r
+  IN  UINT32   SetWayFormat\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmWriteVMBar (\r
+  IN  UINT32   SetWayFormat\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmWriteVBar (\r
+  IN  UINT32   SetWayFormat\r
+  );\r
+\r
+UINT32\r
+EFIAPI\r
+ArmReadVBar (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmWriteCPACR (\r
+  IN  UINT32   SetWayFormat\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmEnableVFP (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmCallWFI (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmInvalidScu (\r
+  VOID\r
+  );\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+ArmGetScuBaseAddress (\r
+  VOID\r
+  );\r
+\r
+UINT32\r
+EFIAPI\r
+ArmIsScuEnable(\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmWriteAuxCr (\r
+  IN  UINT32    Bit\r
+  );\r
+\r
+UINT32\r
+EFIAPI\r
+ArmReadAuxCr (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmSetAuxCrBit (\r
+  IN  UINT32    Bits\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ArmSetupSmpNonSecure (\r
+  IN  UINTN                     CoreId\r
+  );\r
+\r
+\r
+UINTN \r
+EFIAPI\r
+ArmReadCbar(\r
+VOID\r
+);\r
+\r
+VOID\r
+EFIAPI\r
+ArmInvalidateInstructionAndDataTlb(\r
+VOID\r
+);\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+ArmReadMpidr(\r
+VOID\r
+);\r
+\r
 \r
 #endif // __ARM_V7_H__\r
diff --git a/ArmPkg/Include/Drivers/PL341Dmc.h b/ArmPkg/Include/Drivers/PL341Dmc.h
new file mode 100644 (file)
index 0000000..68b8be4
--- /dev/null
@@ -0,0 +1,84 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef PL341DMC_H_
+#define PL341DMC_H_
+
+
+struct pl341_dmc_config {
+    UINTN      base;           // base address for the controller
+    UINTN      has_qos;        // has QoS registers
+    UINTN      max_chip;       // number of memory chips accessible
+    UINT32     refresh_prd;
+    UINT32     cas_latency;
+    UINT32     write_latency;
+    UINT32     t_mrd;
+    UINT32     t_ras;
+    UINT32     t_rc;
+    UINT32     t_rcd;
+    UINT32     t_rfc;
+    UINT32     t_rp;
+    UINT32     t_rrd;
+    UINT32     t_wr;
+    UINT32     t_wtr;
+    UINT32     t_xp;
+    UINT32     t_xsr;
+    UINT32     t_esr;
+    UINT32     memory_cfg;
+    UINT32     memory_cfg2;
+    UINT32     memory_cfg3;
+    UINT32     chip_cfg0;
+    UINT32     chip_cfg1;
+    UINT32     chip_cfg2;
+    UINT32     chip_cfg3;
+    UINT32     t_faw;
+};
+
+/* Memory config bit fields */
+#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_9      0x1
+#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_10     0x2
+#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_11     0x3
+#define DMC_MEMORY_CONFIG_COLUMN_ADDRESS_12     0x4
+#define DMC_MEMORY_CONFIG_ROW_ADDRESS_11        (0x0 << 3)
+#define DMC_MEMORY_CONFIG_ROW_ADDRESS_12        (0x1 << 3)
+#define DMC_MEMORY_CONFIG_ROW_ADDRESS_13        (0x2 << 3)
+#define DMC_MEMORY_CONFIG_ROW_ADDRESS_14        (0x3 << 3)
+#define DMC_MEMORY_CONFIG_ROW_ADDRESS_15        (0x4 << 3)
+#define DMC_MEMORY_CONFIG_ROW_ADDRESS_16        (0x5 << 3)
+#define DMC_MEMORY_CONFIG_BURST_2               (0x1 << 15)
+#define DMC_MEMORY_CONFIG_BURST_4               (0x2 << 15)
+#define DMC_MEMORY_CONFIG_BURST_8               (0x3 << 15)
+#define DMC_MEMORY_CONFIG_BURST_16              (0x4 << 15)
+#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_1                (0x0 << 21)
+#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_2                (0x1 << 21)
+#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_3                (0x2 << 21)
+#define DMC_MEMORY_CONFIG_ACTIVE_CHIP_4                (0x3 << 21)
+
+#define DMC_MEMORY_CFG2_CLK_ASYNC              (0x0 << 0)
+#define DMC_MEMORY_CFG2_CLK_SYNC               (0x1 << 0)
+#define DMC_MEMORY_CFG2_DQM_INIT               (0x1 << 2)
+#define DMC_MEMORY_CFG2_CKE_INIT               (0x1 << 3)
+#define DMC_MEMORY_CFG2_BANK_BITS_2            (0x0 << 4)
+#define DMC_MEMORY_CFG2_BANK_BITS_3            (0x3 << 4)
+#define DMC_MEMORY_CFG2_MEM_WIDTH_16           (0x0 << 6)
+#define DMC_MEMORY_CFG2_MEM_WIDTH_32           (0x1 << 6)
+#define DMC_MEMORY_CFG2_MEM_WIDTH_64           (0x2 << 6)
+#define DMC_MEMORY_CFG2_MEM_WIDTH_RESERVED     (0x3 << 6)
+
+
+
+VOID PL341DmcInit(struct pl341_dmc_config *config);
+
+
+#endif /* PL341DMC_H_ */
diff --git a/ArmPkg/Include/Drivers/PL390Gic.h b/ArmPkg/Include/Drivers/PL390Gic.h
new file mode 100644 (file)
index 0000000..823e6c0
--- /dev/null
@@ -0,0 +1,120 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#ifndef __PL390GIC_H\r
+#define __PL390GIC_H\r
+\r
+//\r
+// GIC definitions\r
+//\r
+\r
+// Distributor\r
+#define GIC_ICDDCR          0x000 // Distributor Control Register\r
+#define GIC_ICDICTR         0x004 // Interrupt Controller Type Register\r
+#define GIC_ICDIIDR         0x008 // Implementer Identification Register\r
+\r
+// each reg base below repeats for VE_NUM_GIC_REG_PER_INT_BITS (see GIC spec)\r
+#define GIC_ICDISR          0x080 // Interrupt Security Registers\r
+#define GIC_ICDISER         0x100 // Interrupt Set-Enable Registers\r
+#define GIC_ICDICER         0x180 // Interrupt Clear-Enable Registers\r
+#define GIC_ICDSPR          0x200 // Interrupt Set-Pending Registers\r
+#define GIC_ICDICPR         0x280 // Interrupt Clear-Pending Registers\r
+#define GIC_ICDABR          0x300 // Active Bit Registers\r
+\r
+// each reg base below repeats for VE_NUM_GIC_REG_PER_INT_BYTES\r
+#define GIC_ICDIPR          0x400 // Interrupt Priority Registers\r
+\r
+// each reg base below repeats for VE_NUM_GIC_INTERRUPTS\r
+#define GIC_ICDIPTR         0x800 // Interrupt Processor Target Registers\r
+#define GIC_ICDICFR         0xC00 // Interrupt Configuration Registers\r
+\r
+// just one of these\r
+#define GIC_ICDSGIR         0xF00 // Software Generated Interrupt Register\r
+\r
+// Cpu interface\r
+#define GIC_ICCICR          0x00  // CPU Interface Control Register\r
+#define GIC_ICCPMR          0x04  // Interrupt Priority Mask Register\r
+#define GIC_ICCBPR          0x08  // Binary Point Register\r
+#define GIC_ICCIAR          0x0C  // Interrupt Acknowledge Register\r
+#define GIC_ICCEIOR         0x10  // End Of Interrupt Register\r
+#define GIC_ICCRPR          0x14  // Running Priority Register\r
+#define GIC_ICCPIR          0x18  // Highest Pending Interrupt Register\r
+#define GIC_ICCABPR         0x1C  // Aliased Binary Point Register\r
+#define GIC_ICCIDR          0xFC  // Identification Register\r
+\r
+#define GIC_ICDSGIR_FILTER_TARGETLIST       0x0\r
+#define GIC_ICDSGIR_FILTER_EVERYONEELSE     0x1\r
+#define GIC_ICDSGIR_FILTER_ITSELF           0x2\r
+\r
+//Bit-masks to configure the CPU Interface Control register\r
+#define GIC_ICCICR_ENABLE_SECURE(a)       ((a << 0) & 0x01)\r
+#define GIC_ICCICR_ENABLE_NS(a)           ((a << 1) & 0x02)\r
+#define GIC_ICCICR_ACK_CTL(a)             ((a << 2) & 0x04)\r
+#define GIC_ICCICR_SIGNAL_SECURE_TO_FIQ(a)((a << 3) & 0x08)\r
+#define GIC_ICCICR_USE_SBPR(a)            ((a << 4) & 0x10)\r
+\r
+\r
+//\r
+// GIC SEC interfaces\r
+//\r
+VOID\r
+EFIAPI\r
+PL390GicSetupNonSecure (\r
+  IN  INTN          GicDistributorBase,\r
+  IN  INTN          GicInterruptInterfaceBase\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicEnableInterruptInterface (\r
+  IN  INTN          GicInterruptInterfaceBase\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicEnableDistributor (\r
+  IN  INTN          GicDistributorBase\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+PL390GicSendSgiTo (\r
+  IN  INTN          GicDistributorBase,\r
+  IN  INTN          TargetListFilter,\r
+  IN  INTN          CPUTargetList\r
+  );\r
+\r
+UINT32\r
+EFIAPI\r
+PL390GicAcknowledgeSgiFrom (\r
+  IN  INTN          GicInterruptInterfaceBase,\r
+  IN  INTN          CoreId\r
+  );\r
+\r
+UINT32\r
+EFIAPI\r
+PL390GicAcknowledgeSgi2From (\r
+  IN  INTN          GicInterruptInterfaceBase,\r
+  IN  INTN          CoreId,\r
+  IN  INTN          SgiId\r
+  );\r
+\r
+UINTN\r
+EFIAPI\r
+PL390GicSetPriorityMask (\r
+  IN  INTN          GicInterruptInterfaceBase,\r
+  IN  INTN          PriorityMask\r
+  );\r
+\r
+#endif\r
index a7920a02042f901861525d4c749310ffc4140232..de3cddf66cdde95dde09f90752c6d86e73d96263 100644 (file)
@@ -43,7 +43,11 @@ 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_ATTRIBUTE_DEVICE,
+  ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED,
+  ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK,
+  ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH,
+  ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE
 } ARM_MEMORY_REGION_ATTRIBUTES;
 
 typedef struct {
@@ -145,6 +149,12 @@ Cp15CacheInfo (
   VOID
   );
 
+BOOLEAN
+EFIAPI
+ArmIsMPCore (
+  VOID
+  );
+
 VOID
 EFIAPI
 ArmInvalidateDataCache (
@@ -224,6 +234,12 @@ ArmDisableMmu (
   VOID
   );
 
+VOID
+EFIAPI
+ArmDisableCachesAndMmu (
+  VOID
+  );
+
 VOID
 EFIAPI
 ArmEnableInterrupts (
@@ -241,6 +257,7 @@ EFIAPI
 ArmGetInterruptState (
   VOID
   );
+
 VOID
 EFIAPI
 ArmEnableFiq (
@@ -280,13 +297,13 @@ ArmSetDomainAccessControl (
 
 VOID
 EFIAPI
-ArmSetTranslationTableBaseAddress (
+ArmSetTTBR0 (
   IN  VOID  *TranslationTableBase
   );
 
 VOID *
 EFIAPI
-ArmGetTranslationTableBaseAddress (
+ArmGetTTBR0BaseAddress (
   VOID
   );
 
diff --git a/ArmPkg/Include/Library/ArmMPCoreMailBoxLib.h b/ArmPkg/Include/Library/ArmMPCoreMailBoxLib.h
new file mode 100644 (file)
index 0000000..1588c31
--- /dev/null
@@ -0,0 +1,22 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#ifndef _ARM_MPCORE_MAILBOX_LIB_H_\r
+#define _ARM_MPCORE_MAILBOX_LIB_H_\r
+\r
+VOID ArmClearMPCoreMailbox(VOID);\r
+\r
+UINTN ArmGetMPCoreMailbox(VOID);\r
+\r
+#endif\r
diff --git a/ArmPkg/Include/Library/ArmTrustZoneLib.h b/ArmPkg/Include/Library/ArmTrustZoneLib.h
new file mode 100644 (file)
index 0000000..8eeb6a2
--- /dev/null
@@ -0,0 +1,69 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#ifndef __ARM_TRUSTZONE_LIB_H__\r
+#define __ARM_TRUSTZONE_LIB_H__\r
+\r
+#include <Uefi.h>\r
+\r
+// Setup TZ Protection Controller\r
+#define TZPC_DECPROT_0  0\r
+#define TZPC_DECPROT_1  1\r
+#define TZPC_DECPROT_2  2\r
+#define TZPC_DECPROT_MAX  2\r
+\r
+/**\r
+    FIXME: Need documentation\r
+**/\r
+EFI_STATUS TZPCSetDecProtBits(UINTN tzpc_base, UINTN tzpc_id, UINTN bits);\r
+\r
+/**\r
+    FIXME: Need documentation\r
+**/\r
+EFI_STATUS TZPCClearDecProtBits(UINTN tzpc_base, UINTN tzpc_id, UINTN bits);\r
+\r
+// Setup TZ Address Space Controller\r
+#define TZASC_REGION_ENABLED        1\r
+#define TZASC_REGION_DISABLED       0\r
+#define TZASC_REGION_SIZE_32KB      0xE\r
+#define TZASC_REGION_SIZE_64KB      0xF\r
+#define TZASC_REGION_SIZE_128KB     0x10\r
+#define TZASC_REGION_SIZE_256KB     0x11\r
+#define TZASC_REGION_SIZE_512KB     0x12\r
+#define TZASC_REGION_SIZE_1MB       0x13\r
+#define TZASC_REGION_SIZE_2MB       0x14\r
+#define TZASC_REGION_SIZE_4MB       0x15\r
+#define TZASC_REGION_SIZE_8MB       0x16\r
+#define TZASC_REGION_SIZE_16MB      0x17\r
+#define TZASC_REGION_SIZE_32MB      0x18\r
+#define TZASC_REGION_SIZE_64MB      0x19\r
+#define TZASC_REGION_SIZE_128MB     0x1A\r
+#define TZASC_REGION_SIZE_256MB     0x1B\r
+#define TZASC_REGION_SIZE_512MB     0x1C\r
+#define TZASC_REGION_SIZE_1GB       0x1D\r
+#define TZASC_REGION_SIZE_2GB       0x1E\r
+#define TZASC_REGION_SIZE_4GB       0x1F\r
+#define TZASC_REGION_SECURITY_SR    (1 << 3)\r
+#define TZASC_REGION_SECURITY_SW    (1 << 2)\r
+#define TZASC_REGION_SECURITY_SRW   (TZASC_REGION_SECURITY_SR|TZASC_REGION_SECURITY_SW)\r
+#define TZASC_REGION_SECURITY_NSR   (1 << 1)\r
+#define TZASC_REGION_SECURITY_NSW   1\r
+#define TZASC_REGION_SECURITY_NSRW  (TZASC_REGION_SECURITY_NSR|TZASC_REGION_SECURITY_NSW)\r
+\r
+/**\r
+    FIXME: Need documentation\r
+**/\r
+EFI_STATUS TZASCSetRegion(UINTN tzasc_base, UINTN region_id, UINTN enabled, UINTN low_address, UINTN high_address, UINTN size, UINTN security);\r
+\r
+#endif\r
diff --git a/ArmPkg/Include/Library/BdsUnixLib.h b/ArmPkg/Include/Library/BdsUnixLib.h
new file mode 100644 (file)
index 0000000..969f951
--- /dev/null
@@ -0,0 +1,38 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#ifndef __BDS_ENTRY_H__\r
+#define __BDS_ENTRY_H__\r
+\r
+EFI_STATUS\r
+BdsConnectAllDrivers ( VOID );\r
+\r
+EFI_STATUS\r
+BdsBootLinux (\r
+    IN  CONST CHAR16* LinuxKernel,\r
+    IN  CONST CHAR8*  ATag,\r
+    IN  CONST CHAR16* Fdt\r
+);\r
+\r
+EFI_STATUS\r
+BdsLoadApplication (\r
+    IN  CHAR16* EfiApp\r
+);\r
+\r
+EFI_STATUS\r
+BdsLoadApplicationFromPath (\r
+    IN  CHAR16* EfiAppPath\r
+);\r
+\r
+#endif\r
diff --git a/ArmPkg/Include/Library/L2X0CacheLib.h b/ArmPkg/Include/Library/L2X0CacheLib.h
new file mode 100644 (file)
index 0000000..4f95b99
--- /dev/null
@@ -0,0 +1,62 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*\r
+*  This program and the accompanying materials\r
+*  are licensed and made available under the terms and conditions of the BSD License\r
+*  which accompanies this distribution.  The full text of the license may be found at\r
+*  http://opensource.org/licenses/bsd-license.php\r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#ifndef L2CACHELIB_H_\r
+#define L2CACHELIB_H_\r
+\r
+#define L2_LATENCY                          7\r
+\r
+#define L2_TAG_ACCESS_LATENCY               L2_LATENCY\r
+#define L2_TAG_SETUP_LATENCY                L2_LATENCY\r
+#define L2_DATA_ACCESS_LATENCY              L2_LATENCY\r
+#define L2_DATA_SETUP_LATENCY               L2_LATENCY\r
+\r
+\r
+#define L2X0_CACHEID            0x000\r
+#define L2X0_CTRL               0x100\r
+#define L2X0_AUXCTRL            0x104\r
+#define L230_TAG_LATENCY        0x108\r
+#define L230_DATA_LATENCY       0x10C\r
+#define L2X0_INTCLEAR           0x220\r
+#define L2X0_CACHE_SYNC                        0x730\r
+#define L2X0_INVWAY             0x77C\r
+#define L2X0_CLEAN_WAY          0x7BC\r
+#define L2X0_PFCTRL             0xF60\r
+#define L2X0_PWRCTRL            0xF80\r
+\r
+#define L2X0_CACHEID_IMPLEMENTER_ARM        0x41\r
+#define L2X0_CACHEID_PARTNUM_PL310          0x03\r
+\r
+#define L2X0_CTRL_ENABLED                   0x1\r
+#define L2X0_CTRL_DISABLED                  0x0\r
+\r
+#define L2X0_AUXCTRL_EXCLUSIVE              (1<<12)\r
+#define L2X0_AUXCTRL_WAYSIZE_16KB           (0x001 << 17)\r
+#define L2X0_AUXCTRL_WAYSIZE_32KB           (0x010 << 17)\r
+#define L2X0_AUXCTRL_WAYSIZE_64KB           (0x011 << 17)\r
+#define L2X0_AUXCTRL_WAYSIZE_128KB          (0x100 << 17)\r
+#define L2X0_AUXCTRL_WAYSIZE_256KB          (0x101 << 17)\r
+#define L2X0_AUXCTRL_WAYSIZE_512KB          (0x110 << 17)\r
+#define L2X0_AUXCTRL_EM                     (1 << 20)\r
+#define L2x0_AUXCTRL_AW_AWCACHE             (0x00 << 23)\r
+#define L2x0_AUXCTRL_AW_NOALLOC             (0x01 << 23)\r
+#define L2x0_AUXCTRL_AW_OVERRIDE            (0x10 << 23)\r
+#define L2X0_AUXCTRL_SBO                    (1 << 25)\r
+#define L2X0_AUXCTRL_NSAC                   (1 << 27)\r
+#define L2x0_AUXCTRL_DPREFETCH              (1 << 28)\r
+#define L2x0_AUXCTRL_IPREFETCH              (1 << 29)\r
+\r
+VOID L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled);\r
+\r
+#endif /* L2CACHELIB_H_ */\r
diff --git a/ArmPkg/Include/Protocol/MmcHost.h b/ArmPkg/Include/Protocol/MmcHost.h
new file mode 100644 (file)
index 0000000..096b479
--- /dev/null
@@ -0,0 +1,112 @@
+/** @file\r
+  Definition of the MMC Host Protocol\r
+\r
+  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+  \r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#ifndef __MMC_HOST_H__\r
+#define __MMC_HOST_H__\r
+\r
+///\r
+/// Global ID for the MMC Host Protocol\r
+///\r
+#define EFI_MMC_HOST_PROTOCOL_GUID \\r
+  { 0x3e591c00, 0x9e4a, 0x11df, {0x92, 0x44, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B } }\r
+\r
+#define MMC_RESPONSE_TYPE_R1        0\r
+#define MMC_RESPONSE_TYPE_R1b       0\r
+#define MMC_RESPONSE_TYPE_R2        1\r
+#define MMC_RESPONSE_TYPE_R3        0\r
+#define MMC_RESPONSE_TYPE_R6        0\r
+#define MMC_RESPONSE_TYPE_R7        0\r
+#define MMC_RESPONSE_TYPE_OCR       0\r
+#define MMC_RESPONSE_TYPE_CID       1\r
+#define MMC_RESPONSE_TYPE_CSD       1\r
+#define MMC_RESPONSE_TYPE_RCA       0\r
+\r
+typedef UINT32  MMC_RESPONSE_TYPE;\r
+\r
+typedef UINT32 MMC_CMD;\r
+\r
+#define MMC_CMD_WAIT_RESPONSE      (1 << 16)\r
+#define MMC_CMD_LONG_RESPONSE      (1 << 17)\r
+\r
+#define MMC_INDX(CMD_INDX)    (CMD_INDX & 0xFFFF)\r
+\r
+#define MMC_CMD0              MMC_INDX(0)\r
+#define MMC_CMD1              (MMC_INDX(1) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD2              (MMC_INDX(2) | MMC_CMD_WAIT_RESPONSE | MMC_CMD_LONG_RESPONSE)\r
+#define MMC_CMD3              (MMC_INDX(3) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD5              (MMC_INDX(5) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD7              (MMC_INDX(7) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD8              (MMC_INDX(8) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD9              (MMC_INDX(9) | MMC_CMD_WAIT_RESPONSE | MMC_CMD_LONG_RESPONSE)\r
+#define MMC_CMD11             (MMC_INDX(11) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD12             (MMC_INDX(12) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD13             (MMC_INDX(13) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD16             (MMC_INDX(16) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD17             (MMC_INDX(17) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD18             (MMC_INDX(18) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD20             (MMC_INDX(20) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD23             (MMC_INDX(23) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD24             (MMC_INDX(24) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_CMD55             (MMC_INDX(55) | MMC_CMD_WAIT_RESPONSE)\r
+#define MMC_ACMD41            (MMC_INDX(41) | MMC_CMD_WAIT_RESPONSE)\r
+\r
+typedef enum _MMC_STATE {\r
+    MmcInvalidState = 0,\r
+    MmcHwInitializationState,\r
+    MmcIdleState,\r
+    MmcReadyState,\r
+    MmcIdentificationState,\r
+    MmcStandByState,\r
+    MmcTransferState,\r
+    MmcSendingDataState,\r
+    MmcReceiveDataState,\r
+    MmcProgrammingState,\r
+    MmcDisconnectState,\r
+} MMC_STATE;\r
+\r
+typedef BOOLEAN (*MMC_ISCARDPRESENT)();\r
+\r
+typedef BOOLEAN (*MMC_ISREADONLY)();\r
+\r
+typedef EFI_STATUS (*MMC_BUILDDEVICEPATH)(EFI_DEVICE_PATH_PROTOCOL **DevicePath);\r
+\r
+typedef EFI_STATUS (*MMC_NOTIFYSTATE)(MMC_STATE State);\r
+\r
+typedef EFI_STATUS (*MMC_SENDCOMMAND)(MMC_CMD Cmd, UINT32 Argument);\r
+\r
+typedef EFI_STATUS (*MMC_RECEIVERESPONSE)(MMC_RESPONSE_TYPE Type, UINT32* Buffer);\r
+\r
+typedef EFI_STATUS (*MMC_READBLOCKDATA)(EFI_LBA Lba, UINTN Length, UINT32* Buffer);\r
+\r
+typedef EFI_STATUS (*MMC_WRITEBLOCKDATA)(EFI_LBA Lba, UINTN Length, UINT32* Buffer);\r
+\r
+typedef struct _EFI_MMC_HOST_PROTOCOL {\r
+    MMC_ISCARDPRESENT       IsCardPresent;\r
+    MMC_ISREADONLY          IsReadOnly;\r
+    MMC_BUILDDEVICEPATH     BuildDevicePath;\r
+\r
+    MMC_NOTIFYSTATE         NotifyState;\r
+\r
+    MMC_SENDCOMMAND         SendCommand;\r
+    MMC_RECEIVERESPONSE     ReceiveResponse;\r
+\r
+    MMC_READBLOCKDATA       ReadBlockData;\r
+    MMC_WRITEBLOCKDATA      WriteBlockData;\r
+} EFI_MMC_HOST_PROTOCOL;\r
+\r
+extern EFI_GUID gEfiMmcHostProtocolGuid;\r
+\r
+#endif\r
+\r
index 7fef208c78c1867122275960bb912c4c7d011503..adea97ff296ffc7ab553c2beb26284b7f4159e83 100755 (executable)
@@ -215,7 +215,7 @@ DmaAllocateBuffer (
   //\r
   if (MemoryType == EfiBootServicesData) {\r
     *HostAddress = UncachedAllocatePages (Pages);\r
-  } else if (MemoryType != EfiRuntimeServicesData) {\r
+  } else if (MemoryType == EfiRuntimeServicesData) {\r
     *HostAddress = UncachedAllocateRuntimePages (Pages);\r
   } else {\r
     return EFI_INVALID_PARAMETER;\r
index 710b838073ce214c40f03d67e516be0234a0efae..1257be8cf60a67f6e274904e7d6cc2c092cbccd0 100644 (file)
@@ -31,14 +31,25 @@ FillTranslationTable (
   
   switch (MemoryRegion->Attributes) {
     case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
-      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
       break;
     case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
-      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
       break;
     case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
+      break;
     default:
-      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
       break;
   }
   
@@ -93,7 +104,7 @@ ArmConfigureMmu (
     MemoryTable++;
   }
 
-  ArmSetTranslationTableBaseAddress(TranslationTable);
+  ArmSetTTBR0(TranslationTable);
     
   ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
                             DOMAIN_ACCESS_CONTROL_NONE(14) |
index 8c2ce60f5a6a08e56c9b1a289782d85dd09f0976..35774a8e626b8435af3a5deaff346a2b35b2add8 100644 (file)
 #
 #------------------------------------------------------------------------------
 
+#include <AsmMacroIoLib.h>
+
 .text
 .align 2
-.globl ASM_PFX(ArmCleanInvalidateDataCache)
-INTERWORK_FUNC(ArmCleanInvalidateDataCache)
-.globl ASM_PFX(ArmCleanDataCache)
-INTERWORK_FUNC(ArmCleanDataCache)
-.globl ASM_PFX(ArmInvalidateDataCache)
-INTERWORK_FUNC(ArmInvalidateDataCache)
-.globl ASM_PFX(ArmInvalidateInstructionCache)
-INTERWORK_FUNC(ArmInvalidateInstructionCache)
-.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmInvalidateDataCacheEntryByMVA)
-.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmCleanDataCacheEntryByMVA)
-.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
-.globl ASM_PFX(ArmEnableMmu)
-INTERWORK_FUNC(ArmEnableMmu)
-.globl ASM_PFX(ArmDisableMmu)
-INTERWORK_FUNC(ArmDisableMmu)
-.globl ASM_PFX(ArmMmuEnabled)
-INTERWORK_FUNC(ArmMmuEnabled)
-.globl ASM_PFX(ArmEnableDataCache)
-INTERWORK_FUNC(ArmEnableDataCache)
-.globl ASM_PFX(ArmDisableDataCache)
-INTERWORK_FUNC(ArmDisableDataCache)
-.globl ASM_PFX(ArmEnableInstructionCache)
-INTERWORK_FUNC(ArmEnableInstructionCache)
-.globl ASM_PFX(ArmDisableInstructionCache)
-INTERWORK_FUNC(ArmDisableInstructionCache)
-.globl ASM_PFX(ArmEnableBranchPrediction)
-INTERWORK_FUNC(ArmEnableBranchPrediction)
-.globl ASM_PFX(ArmDisableBranchPrediction)
-INTERWORK_FUNC(ArmDisableBranchPrediction)
-.globl ASM_PFX(ArmDataMemoryBarrier)
-INTERWORK_FUNC(ArmDataMemoryBarrier)
-.globl ASM_PFX(ArmDataSyncronizationBarrier) 
-INTERWORK_FUNC(ArmDataSyncronizationBarrier)
-.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
-INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
+GCC_ASM_EXPORT(ArmCleanDataCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCache)
+GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmEnableMmu)
+GCC_ASM_EXPORT(ArmDisableMmu)
+GCC_ASM_EXPORT(ArmMmuEnabled)
+GCC_ASM_EXPORT(ArmEnableDataCache)
+GCC_ASM_EXPORT(ArmDisableDataCache)
+GCC_ASM_EXPORT(ArmEnableInstructionCache)
+GCC_ASM_EXPORT(ArmDisableInstructionCache)
+GCC_ASM_EXPORT(ArmEnableBranchPrediction)
+GCC_ASM_EXPORT(ArmDisableBranchPrediction)
+GCC_ASM_EXPORT(ArmDataMemoryBarrier)
+GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
+GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
 
 
 .set DC_ON, (0x1<<2)
@@ -116,14 +99,14 @@ ASM_PFX(ArmDisableMmu):
   bx      LR
 
 ASM_PFX(ArmEnableDataCache):
-  ldr     R1,=DC_ON
+  LoadConstantToReg(DC_ON, R1)  @ldr     R1,=DC_ON
   mrc     p15,0,R0,c1,c0,0      @Read control register configuration data
   orr     R0,R0,R1              @Set C bit
   mcr     p15,0,r0,c1,c0,0      @Write control register configuration data
   bx      LR
     
 ASM_PFX(ArmDisableDataCache):
-  ldr     R1,=DC_ON
+  LoadConstantToReg(DC_ON, R1)  @ldr     R1,=DC_ON
   mrc     p15,0,R0,c1,c0,0      @Read control register configuration data
   bic     R0,R0,R1              @Clear C bit
   mcr     p15,0,r0,c1,c0,0      @Write control register configuration data
index e8834ef47d6fb4773b83a1b8adb8b391372b2203..1bdc439258a78bfea3c8448a547934e34fc64bf3 100644 (file)
@@ -16,6 +16,7 @@
 #include <Library/ArmLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
 
 VOID
 FillTranslationTable (
@@ -37,6 +38,12 @@ FillTranslationTable (
       Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
       break;
     case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
+      break;
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:
+      ASSERT(0); // Trustzone is not supported on ARMv5
     default:
       Attributes = TT_DESCRIPTOR_SECTION_UNCACHED_UNBUFFERED;
       break;
@@ -93,7 +100,7 @@ ArmConfigureMmu (
     MemoryTable++;
   }
 
-  ArmSetTranslationTableBaseAddress(TranslationTable);
+  ArmSetTTBR0(TranslationTable);
     
   ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
                             DOMAIN_ACCESS_CONTROL_NONE(14) |
index f570f750594b4eac9bd9d0e40d5d5a5fd6b286ac..8e75a3d79e8694b58ff5e5f502ca13c460388c85 100644 (file)
 
 .text
 .align 2
-.globl ASM_PFX(ArmCleanInvalidateDataCache)
-INTERWORK_FUNC(ArmCleanInvalidateDataCache)
-.globl ASM_PFX(ArmCleanDataCache)
-INTERWORK_FUNC(ArmCleanDataCache)
-.globl ASM_PFX(ArmInvalidateDataCache)
-INTERWORK_FUNC(ArmInvalidateDataCache)
-.globl ASM_PFX(ArmInvalidateInstructionCache)
-INTERWORK_FUNC(ArmInvalidateInstructionCache)
-.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmInvalidateDataCacheEntryByMVA)
-.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmCleanDataCacheEntryByMVA)
-.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
-.globl ASM_PFX(ArmEnableMmu)
-INTERWORK_FUNC(ArmEnableMmu)
-.globl ASM_PFX(ArmDisableMmu)
-INTERWORK_FUNC(ArmDisableMmu)
-.globl ASM_PFX(ArmMmuEnabled)
-INTERWORK_FUNC(ArmMmuEnabled)
-.globl ASM_PFX(ArmEnableDataCache)
-INTERWORK_FUNC(ArmEnableDataCache)
-.globl ASM_PFX(ArmDisableDataCache)
-INTERWORK_FUNC(ArmDisableDataCache)
-.globl ASM_PFX(ArmEnableInstructionCache)
-INTERWORK_FUNC(ArmEnableInstructionCache)
-.globl ASM_PFX(ArmDisableInstructionCache)
-INTERWORK_FUNC(ArmDisableInstructionCache)
-.globl ASM_PFX(ArmEnableBranchPrediction)
-INTERWORK_FUNC(ArmEnableBranchPrediction)
-.globl ASM_PFX(ArmDisableBranchPrediction)
-INTERWORK_FUNC(ArmDisableBranchPrediction)
-.globl ASM_PFX(ArmDataMemoryBarrier)
-INTERWORK_FUNC(ArmDataMemoryBarrier)
-.globl ASM_PFX(ArmDataSyncronizationBarrier) 
-INTERWORK_FUNC(ArmDataSyncronizationBarrier)
-.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
-INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCache)
+GCC_ASM_EXPORT(ArmCleanDataCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCache)
+GCC_ASM_EXPORT(ArmInvalidateInstructionCache)
+GCC_ASM_EXPORT(ArmInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmCleanInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT(ArmEnableMmu)
+GCC_ASM_EXPORT(ArmDisableMmu)
+GCC_ASM_EXPORT(ArmMmuEnabled)
+GCC_ASM_EXPORT(ArmEnableDataCache)
+GCC_ASM_EXPORT(ArmDisableDataCache)
+GCC_ASM_EXPORT(ArmEnableInstructionCache)
+GCC_ASM_EXPORT(ArmDisableInstructionCache)
+GCC_ASM_EXPORT(ArmEnableBranchPrediction)
+GCC_ASM_EXPORT(ArmDisableBranchPrediction)
+GCC_ASM_EXPORT(ArmDataMemoryBarrier)
+GCC_ASM_EXPORT(ArmDataSyncronizationBarrier)
+GCC_ASM_EXPORT(ArmInstructionSynchronizationBarrier)
 
 
 .set DC_ON, (1<<2)
index 8ca37f0be0441540ffc9f01a60bf816e073eec65..54f36174bb2fd469ce02a4aa4f8432e29dbff0b1 100644 (file)
 #
 #------------------------------------------------------------------------------
 
-.globl ASM_PFX(Cp15IdCode)
-INTERWORK_FUNC(Cp15IdCode)
-.globl ASM_PFX(Cp15CacheInfo)
-INTERWORK_FUNC(Cp15CacheInfo)
-.globl ASM_PFX(ArmEnableInterrupts)
-INTERWORK_FUNC(ArmEnableInterrupts)
-.globl ASM_PFX(ArmDisableInterrupts)
-INTERWORK_FUNC(ArmDisableInterrupts)
-.globl ASM_PFX(ArmGetInterruptState)
-INTERWORK_FUNC(ArmGetInterruptState)
-.globl ASM_PFX(ArmEnableFiq)
-INTERWORK_FUNC(ArmEnableFiq)
-.globl ASM_PFX(ArmDisableFiq)
-INTERWORK_FUNC(ArmDisableFiq)
-.globl ASM_PFX(ArmGetFiqState)
-INTERWORK_FUNC(ArmGetFiqState)
-.globl ASM_PFX(ArmInvalidateTlb)
-INTERWORK_FUNC(ArmInvalidateTlb)
-.globl ASM_PFX(ArmSetTranslationTableBaseAddress)
-INTERWORK_FUNC(ArmSetTranslationTableBaseAddress)
-.globl ASM_PFX(ArmGetTranslationTableBaseAddress)
-INTERWORK_FUNC(ArmGetTranslationTableBaseAddress)
-.globl ASM_PFX(ArmSetDomainAccessControl)
-INTERWORK_FUNC(ArmSetDomainAccessControl)
-.globl ASM_PFX(ArmUpdateTranslationTableEntry)
-INTERWORK_FUNC(ArmUpdateTranslationTableEntry)
-.globl ASM_PFX(CPSRMaskInsert)
-INTERWORK_FUNC(CPSRMaskInsert)
-.globl ASM_PFX(CPSRRead)
-INTERWORK_FUNC(CPSRRead)
-.globl ASM_PFX(ReadCCSIDR)
-INTERWORK_FUNC(ReadCCSIDR)
-.globl ASM_PFX(ReadCLIDR)
-INTERWORK_FUNC(ReadCLIDR)
+#include <AsmMacroIoLib.h>
 
 .text
 .align 2
 
+GCC_ASM_EXPORT(Cp15IdCode)
+GCC_ASM_EXPORT(Cp15CacheInfo)
+GCC_ASM_EXPORT(ArmIsMPCore)
+GCC_ASM_EXPORT(ArmEnableAsynchronousAbort)
+GCC_ASM_EXPORT(ArmDisableAsynchronousAbort)
+GCC_ASM_EXPORT(ArmEnableIrq)
+GCC_ASM_EXPORT(ArmDisableIrq)
+GCC_ASM_EXPORT(ArmGetInterruptState)
+GCC_ASM_EXPORT(ArmEnableFiq)
+GCC_ASM_EXPORT(ArmDisableFiq)
+GCC_ASM_EXPORT(ArmEnableInterrupts)
+GCC_ASM_EXPORT(ArmDisableInterrupts)
+GCC_ASM_EXPORT(ArmGetFiqState)
+GCC_ASM_EXPORT(ArmInvalidateTlb)
+GCC_ASM_EXPORT(ArmSetTTBR0)
+GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)
+GCC_ASM_EXPORT(ArmSetDomainAccessControl)
+GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)
+GCC_ASM_EXPORT(CPSRMaskInsert)
+GCC_ASM_EXPORT(CPSRRead)
+GCC_ASM_EXPORT(ReadCCSIDR)
+GCC_ASM_EXPORT(ReadCLIDR)
+
+
+
 #------------------------------------------------------------------------------
 
 ASM_PFX(Cp15IdCode):
@@ -60,35 +52,67 @@ ASM_PFX(Cp15CacheInfo):
   mrc     p15,0,R0,c0,c0,1
   bx      LR
 
-ASM_PFX(ArmEnableInterrupts):
+ASM_PFX(ArmIsMPCore):
+  mrc     p15,0,R0,c0,c0,5
+  // Get Multiprocessing extension (bit31) & U bit (bit30)
+  and     R0, R0, #0xC0000000
+  // if bit30 == 0 then the processor is part of a multiprocessor system)
+  and     R0, R0, #0x80000000
+  bx      LR
+
+ASM_PFX(ArmEnableAsynchronousAbort):
+  cpsie   a
+  isb
+  bx      LR
+
+ASM_PFX(ArmDisableAsynchronousAbort):
+  cpsid   a
+  isb
+  bx      LR
+
+ASM_PFX(ArmEnableIrq):
   cpsie   i
-       bx      LR
+  isb
+  bx      LR
 
-ASM_PFX(ArmDisableInterrupts):
+ASM_PFX(ArmDisableIrq):
   cpsid   i
-       bx      LR
+  isb
+  bx      LR
 
 ASM_PFX(ArmGetInterruptState):
-       mrs     R0,CPSR
-       tst     R0,#0x80            @Check if IRQ is enabled.
-       moveq   R0,#1
-       movne   R0,#0
-       bx      LR
+  mrs     R0,CPSR
+  tst     R0,#0x80      @Check if IRQ is enabled.
+  moveq   R0,#1
+  movne   R0,#0
+  bx      LR
 
 ASM_PFX(ArmEnableFiq):
   cpsie   f
-       bx      LR
+  isb
+  bx      LR
 
 ASM_PFX(ArmDisableFiq):
   cpsid   f
-       bx      LR
+  isb
+  bx      LR
+
+ASM_PFX(ArmEnableInterrupts):
+  cpsie   if
+  isb
+  bx      LR
+
+ASM_PFX(ArmDisableInterrupts):
+  cpsid   if
+  isb
+  bx      LR
 
 ASM_PFX(ArmGetFiqState):
-       mrs     R0,CPSR
-       tst     R0,#0x40            @Check if FIQ is enabled.
-       moveq   R0,#1
-       movne   R0,#0
-       bx      LR
+  mrs     R0,CPSR
+  tst     R0,#0x40      @Check if FIQ is enabled.
+  moveq   R0,#1
+  movne   R0,#0
+  bx      LR
 
 ASM_PFX(ArmInvalidateTlb):
   mov     r0,#0
@@ -98,13 +122,15 @@ ASM_PFX(ArmInvalidateTlb):
   isb
   bx      lr
 
-ASM_PFX(ArmSetTranslationTableBaseAddress):
+ASM_PFX(ArmSetTTBR0):
   mcr     p15,0,r0,c2,c0,0
   isb
   bx      lr
 
-ASM_PFX(ArmGetTranslationTableBaseAddress):
+ASM_PFX(ArmGetTTBR0BaseAddress):
   mrc     p15,0,r0,c2,c0,0
+  LoadConstantToReg(0xFFFFC000, r1)
+  and     r0, r0, r1
   isb
   bx      lr
 
index 08a2d900fd40f74926d6b985b97664f32f9c5697..7099ced8f4dc04db3b077314b536ce2f25ae3281 100644 (file)
 
     EXPORT  Cp15IdCode
     EXPORT  Cp15CacheInfo
-    EXPORT  ArmEnableInterrupts
-    EXPORT  ArmDisableInterrupts
+    EXPORT  ArmIsMPCore
+    EXPORT  ArmEnableAsynchronousAbort
+    EXPORT  ArmDisableAsynchronousAbort
+    EXPORT  ArmEnableIrq
+    EXPORT  ArmDisableIrq
     EXPORT  ArmGetInterruptState
     EXPORT  ArmEnableFiq
     EXPORT  ArmDisableFiq
+    EXPORT  ArmEnableInterrupts
+    EXPORT  ArmDisableInterrupts
     EXPORT  ArmGetFiqState
     EXPORT  ArmInvalidateTlb
-    EXPORT  ArmSetTranslationTableBaseAddress
-    EXPORT  ArmGetTranslationTableBaseAddress
+    EXPORT  ArmSetTTBR0
+    EXPORT  ArmGetTTBR0BaseAddress
     EXPORT  ArmSetDomainAccessControl
     EXPORT  ArmUpdateTranslationTableEntry
     EXPORT  CPSRMaskInsert
@@ -44,27 +49,59 @@ Cp15CacheInfo
   mrc     p15,0,R0,c0,c0,1
   bx      LR
 
-ArmEnableInterrupts
+ArmIsMPCore
+  mrc     p15,0,R0,c0,c0,5
+  // Get Multiprocessing extension (bit31) & U bit (bit30)
+  and     R0, R0, #0xC0000000
+  // if bit30 == 0 then the processor is part of a multiprocessor system)
+  and     R0, R0, #0x80000000
+  bx      LR
+
+ArmEnableAsynchronousAbort
+  cpsie   a
+  isb
+  bx      LR
+
+ArmDisableAsynchronousAbort
+  cpsid   a
+  isb
+  bx      LR
+
+ArmEnableIrq
   cpsie   i
+  isb
        bx      LR
 
-ArmDisableInterrupts
+ArmDisableIrq
   cpsid   i
-       bx      LR
-
-ArmGetInterruptState
-       mrs     R0,CPSR
-       tst     R0,#0x80            ;Check if IRQ is enabled.
-       moveq   R0,#1
-       movne   R0,#0
+  isb
        bx      LR
 
 ArmEnableFiq
   cpsie   f
+  isb
        bx      LR
 
 ArmDisableFiq
   cpsid   f
+  isb
+  bx      LR
+
+ArmEnableInterrupts
+  cpsie   if
+  isb
+  bx      LR
+
+ArmDisableInterrupts
+  cpsid   if
+  isb
+  bx      LR
+
+ArmGetInterruptState
+  mrs     R0,CPSR
+  tst     R0,#0x80         ;Check if IRQ is enabled.
+  moveq   R0,#1
+  movne   R0,#0
        bx      LR
 
 ArmGetFiqState
@@ -82,13 +119,15 @@ ArmInvalidateTlb
   isb
   bx      lr
 
-ArmSetTranslationTableBaseAddress
+ArmSetTTBR0
   mcr     p15,0,r0,c2,c0,0
   isb
   bx      lr
 
-ArmGetTranslationTableBaseAddress
+ArmGetTTBR0BaseAddress
   mrc     p15,0,r0,c2,c0,0
+  ldr    r1, = 0xFFFFC000
+  and     r0, r0, r1
   isb
   bx      lr
 
@@ -150,7 +189,4 @@ ReadCLIDR
   mrc p15,1,r0,c0,c0,1 ; Read CP15 Cache Level ID Register
   bx  lr
   
-
 END
-
-
index cad3c13ba4c04fad54f8684445d63c0e41c7ddc2..4329bd72391b5a3369854a26c5160f0bd07bcd48 100644 (file)
 #include <Chipset/ArmV7.h>
 #include <Library/ArmLib.h>
 #include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
 #include "ArmV7Lib.h"
 #include "ArmLibPrivate.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 (
@@ -139,7 +36,7 @@ ArmCacheArchitecture (
 {
   UINT32 CLIDR = ReadCLIDR ();
 
-  return CLIDR; // BugBug Fix Me
+  return (ARM_CACHE_ARCHITECTURE)CLIDR; // BugBug Fix Me
 }
 
 BOOLEAN
@@ -173,7 +70,7 @@ ArmDataCacheSize (
   UINT32 LineSize;
   UINT32 CCSIDR = ReadCCSIDR (0);
   
-  LineSize      = (1 << (CCSIDR + 2));
+  LineSize      = (1 << ((CCSIDR & 0x7) + 2));
   Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
   NumSets       = ((CCSIDR >> 13) & 0x7fff) + 1;
 
@@ -245,7 +142,7 @@ ArmInstructionCacheSize (
   UINT32 LineSize;
   UINT32 CCSIDR = ReadCCSIDR (1);
   
-  LineSize      = (1 << (CCSIDR + 2));
+  LineSize      = (1 << ((CCSIDR & 0x7) + 2));
   Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
   NumSets       = ((CCSIDR >> 13) & 0x7fff) + 1;
 
@@ -299,6 +196,8 @@ ArmV7DataCacheOperation (
   UINTN     SavedInterruptState;
 
   SavedInterruptState = ArmGetInterruptState ();
+  ArmDisableInterrupts();
+  
 
   ArmV7AllDataCachesOperation (DataCacheOperation);
   
@@ -335,3 +234,14 @@ ArmCleanDataCache (
 {
   ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
 }
+
+VOID
+EFIAPI
+ArmSetAuxCrBit (
+  IN  UINT32    Bits
+  )
+{
+  UINT32 val = ArmReadAuxCr();
+  val |= Bits;
+  ArmWriteAuxCr(val);
+}
index 2e8c39b3b35515c64065d4679200dfc02fdded5c..7eaeb156613d7026bebd3636d9cd2bd2b5557686 100644 (file)
@@ -40,5 +40,41 @@ ArmCleanInvalidateDataCacheEntryBySetWay (
   IN  UINT32   SetWayFormat
   );
 
+VOID
+EFIAPI
+ArmEnableAsynchronousAbort (
+  VOID
+  );
+
+UINTN
+EFIAPI
+ArmDisableAsynchronousAbort (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmEnableIrq (
+  VOID
+  );
+
+UINTN
+EFIAPI
+ArmDisableIrq (
+  VOID
+  );
+
+VOID
+EFIAPI
+ArmEnableFiq (
+  VOID
+  );
+
+UINTN
+EFIAPI
+ArmDisableFiq (
+  VOID
+  );
+
 #endif // __ARM_V7_LIB_H__
 
index bbd257646066d87a20383725698d6df0dbb9533e..2452c287343c410de34e6bfb324f175846e4b0fd 100644 (file)
@@ -30,6 +30,7 @@
   ArmV7Support.asm  | RVCT\r
 \r
   ArmV7Lib.c\r
+  ArmV7Mmu.c\r
 \r
 [Packages]\r
   ArmPkg/ArmPkg.dec\r
index cbdef6cfb9eaedd631fc64ed2a5c3f79ccad7bb0..f97b5a4cee58c49e8574a5171823a9d3c0494adf 100644 (file)
@@ -30,6 +30,7 @@
   ArmV7Support.asm  | RVCT\r
 \r
   ArmV7Lib.c\r
+  ArmV7Mmu.c\r
 \r
 [Packages]\r
   ArmPkg/ArmPkg.dec\r
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
new file mode 100644 (file)
index 0000000..73bf09a
--- /dev/null
@@ -0,0 +1,40 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ArmV7Lib\r
+  FILE_GUID                      = 411cdfd8-f964-4b9d-a3e3-1719a9c15559\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ArmLib\r
+\r
+[Sources.common]\r
+  ArmLibSupport.S    | GCC\r
+  ArmLibSupport.asm  | RVCT\r
+  ../Common/ArmLib.c\r
+  \r
+  ArmV7Support.S    | GCC\r
+  ArmV7Support.asm  | RVCT\r
+\r
+  ArmV7Lib.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid\r
+\r
+[FixedPcd]\r
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold\r
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCore.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCore.c
new file mode 100644 (file)
index 0000000..65c09a1
--- /dev/null
@@ -0,0 +1,57 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#include <Uefi.h>
+#include <Chipset/ArmV7.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include "ArmV7Lib.h"
+#include "ArmLibPrivate.h"
+
+VOID
+EFIAPI
+ArmSetupSmpNonSecure (
+  IN  UINTN         CoreId
+  )
+{
+    INTN          scu_base;
+
+    ArmSetAuxCrBit (A9_FEATURE_SMP);
+
+    if (CoreId == 0) {
+        scu_base = ArmGetScuBaseAddress();
+
+        // Allow NS access to SCU register
+        MmioOr32(scu_base + SCU_SACR_OFFSET, 0xf);  
+        // Allow NS access to Private Peripherals
+        MmioOr32(scu_base + SCU_SSACR_OFFSET, 0xfff);
+    }
+}
+
+VOID
+EFIAPI
+ArmInvalidScu (
+  VOID
+  )
+{
+    INTN          scu_base;
+
+    scu_base = ArmGetScuBaseAddress();
+
+    /* Invalidate all: write -1 to SCU Invalidate All register */
+    MmioWrite32(scu_base + SCU_INVALL_OFFSET, 0xffffffff);
+    /* Enable SCU */
+    MmioWrite32(scu_base + SCU_CONTROL_OFFSET, 0x1);
+}
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.S b/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.S
new file mode 100644 (file)
index 0000000..0636897
--- /dev/null
@@ -0,0 +1,48 @@
+#\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http:#opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#\r
+\r
+#include <AsmMacroIoLib.h>\r
+#include <Base.h>\r
+#include <Library/PcdLib.h>\r
+#include <Chipset/ArmV7.h>\r
+#include <AutoGen.h>\r
+#.include AsmMacroIoLib.inc\r
+\r
+.text\r
+.align 2\r
+\r
+GCC_ASM_EXPORT(ArmIsScuEnable)\r
+GCC_ASM_EXPORT(ArmGetScuBaseAddress)\r
+\r
+# IN None\r
+# OUT r0 = SCU Base Address\r
+ASM_PFX(ArmGetScuBaseAddress):\r
+  # Read Configuration Base Address Register. ArmCBar cannot be called to get\r
+  # the Configuration BAR as a stack is not necessary setup. The SCU is at the\r
+  # offset 0x0000 from the Private Memory Region.\r
+  mrc   p15, 4, r0, c15, c0, 0\r
+  bx   lr\r
+\r
+# IN  None\r
+# OUT r1 = SCU enabled (boolean)\r
+ASM_PFX(ArmIsScuEnable):\r
+  # Read Configuration Base Address Register. ArmCBar cannot be called to get\r
+  # the Configuration BAR as a stack is not necessary setup. The SCU is at the\r
+  # offset 0x0000 from the Private Memory Region.\r
+  mrc   p15, 4, r0, c15, c0, 0\r
+  add   r1, r0, #SCU_CONTROL_OFFSET\r
+  ldr   r1, [r1]\r
+  and   r1, r1, #1\r
+  bx    lr\r
+\r
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED \r
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.asm b/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreHelper.asm
new file mode 100644 (file)
index 0000000..08528fc
--- /dev/null
@@ -0,0 +1,48 @@
+//\r
+//  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+//  \r
+//  This program and the accompanying materials                          \r
+//  are licensed and made available under the terms and conditions of the BSD License         \r
+//  which accompanies this distribution.  The full text of the license may be found at        \r
+//  http://opensource.org/licenses/bsd-license.php                                            \r
+//\r
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+//\r
+//\r
+\r
+#include <AsmMacroIoLib.h>\r
+#include <Base.h>\r
+#include <Library/PcdLib.h>\r
+#include <Chipset/ArmV7.h>\r
+#include <AutoGen.h>\r
+\r
+  INCLUDE AsmMacroIoLib.inc\r
+\r
+  EXPORT    ArmIsScuEnable\r
+  EXPORT    ArmGetScuBaseAddress\r
+    \r
+  AREA ArmV7MPCore, CODE, READONLY\r
+\r
+// IN None\r
+// OUT r0 = SCU Base Address\r
+ArmGetScuBaseAddress\r
+  // Read Configuration Base Address Register. ArmCBar cannot be called to get\r
+  // the Configuration BAR as a stack is not necessary setup. The SCU is at the\r
+  // offset 0x0000 from the Private Memory Region.\r
+  mrc   p15, 4, r0, c15, c0, 0\r
+  bx   lr\r
+\r
+// IN  None\r
+// OUT r1 = SCU enabled (boolean)\r
+ArmIsScuEnable\r
+  // Read Configuration Base Address Register. ArmCBar cannot be called to get\r
+  // the Configuration BAR as a stack is not necessary setup. The SCU is at the\r
+  // offset 0x0000 from the Private Memory Region.\r
+  mrc   p15, 4, r0, c15, c0, 0\r
+  add   r1, r0, #SCU_CONTROL_OFFSET\r
+  ldr   r1, [r1]\r
+  and   r1, r1, #1\r
+  bx    lr\r
+\r
+  END\r
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLib.inf
new file mode 100644 (file)
index 0000000..c847d89
--- /dev/null
@@ -0,0 +1,51 @@
+#/** @file\r
+# Helper Library for ARMv7 MPCore architecture\r
+\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ArmV7Lib\r
+  FILE_GUID                      = 411cdfd8-f964-4b9d-a3e3-1719a9c15559\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ArmLib\r
+\r
+[Sources.common]\r
+  ArmLibSupport.S    | GCC\r
+  ArmLibSupport.asm  | RVCT\r
+  ../Common/ArmLib.c\r
+  \r
+  ArmV7Support.S    | GCC\r
+  ArmV7Support.asm  | RVCT\r
+\r
+  ArmV7Lib.c\r
+  ArmV7Mmu.c\r
+\r
+  ArmV7MPCore.c\r
+  ArmV7MPCoreHelper.S   | GCC\r
+  ArmV7MPCoreHelper.asm   | RVCT\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+\r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid\r
+\r
+[FixedPcd]\r
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold\r
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibPrePi.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibPrePi.inf
new file mode 100644 (file)
index 0000000..e1de26f
--- /dev/null
@@ -0,0 +1,49 @@
+#/** @file\r
+#\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ArmV7LibPrePi\r
+  FILE_GUID                      = A150FA0C-F4E8-4207-9BEB-CD6DFB430D73\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ArmLib\r
+\r
+[Sources.common]\r
+  ArmLibSupport.S    | GCC\r
+  ArmLibSupport.asm  | RVCT\r
+  ../Common/ArmLib.c\r
+  \r
+  ArmV7Support.S    | GCC\r
+  ArmV7Support.asm  | RVCT\r
+\r
+  ArmV7Lib.c\r
+  ArmV7Mmu.c\r
+\r
+  ArmV7MPCore.c\r
+  ArmV7MPCoreHelper.S     | GCC\r
+  ArmV7MPCoreHelper.asm   | RVCT\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  PrePiLib\r
+  \r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid\r
+\r
+[FixedPcd]\r
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold\r
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7MPCoreLibSec.inf
new file mode 100644 (file)
index 0000000..05c8d36
--- /dev/null
@@ -0,0 +1,43 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ArmV7Lib\r
+  FILE_GUID                      = 411cdfd8-f964-4b9d-a3e3-1719a9c15559\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ArmLib\r
+\r
+[Sources.common]\r
+  ArmLibSupport.S    | GCC\r
+  ArmLibSupport.asm  | RVCT\r
+  ../Common/ArmLib.c\r
+  \r
+  ArmV7Support.S    | GCC\r
+  ArmV7Support.asm  | RVCT\r
+\r
+  ArmV7Lib.c\r
+  ArmV7MPCore.c\r
+  ArmV7MPCoreHelper.S   | GCC\r
+  ArmV7MPCoreHelper.asm   | RVCT\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid\r
+\r
+[FixedPcd]\r
+  gArmTokenSpaceGuid.PcdArmCacheOperationThreshold\r
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
new file mode 100644 (file)
index 0000000..9bb3c26
--- /dev/null
@@ -0,0 +1,162 @@
+/** @file\r
+*  File managing the MMU for ARMv7 architecture\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Uefi.h> \r
+#include <Chipset/ArmV7.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/ArmLib.h>\r
+#include <Library/BaseLib.h>\r
+#include "ArmV7Lib.h"\r
+#include "ArmLibPrivate.h"\r
+\r
+VOID\r
+FillTranslationTable (\r
+  IN  UINT32                        *TranslationTable,\r
+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion\r
+  )\r
+{\r
+  UINT32  *Entry;\r
+  UINTN   Sections;\r
+  UINTN   Index;\r
+  UINT32  Attributes;\r
+  UINT32  PhysicalBase = MemoryRegion->PhysicalBase;\r
+  \r
+  switch (MemoryRegion->Attributes) {\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:\r
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);\r
+      break;\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:\r
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);\r
+      break;\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:\r
+      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);\r
+      break;\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:\r
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);\r
+      break;\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:\r
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);\r
+      break;\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:\r
+      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);\r
+      break;\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE:\r
+      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);\r
+      break;\r
+    case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:\r
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);\r
+      break;\r
+    default:\r
+      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);\r
+      break;\r
+  }\r
+  \r
+  Entry    = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);\r
+  Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;\r
+  \r
+  for (Index = 0; Index < Sections; Index++) {\r
+    *Entry++     =  TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;\r
+    PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;\r
+  }\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+ArmConfigureMmu (\r
+  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,\r
+  OUT VOID                          **TranslationTableBase OPTIONAL,\r
+  OUT UINTN                         *TranslationTableSize  OPTIONAL\r
+  )\r
+{\r
+  UINTN                         TranslationTable;\r
+  ARM_MEMORY_REGION_ATTRIBUTES  TranslationTableAttribute;\r
+  UINT32                        TTBRAttributes;\r
+\r
+  // Allocate pages for translation table.\r
+  TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));\r
+  TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK;\r
+\r
+  if (TranslationTableBase != NULL) {\r
+    *TranslationTableBase = (VOID *)TranslationTable;\r
+  }\r
+  \r
+  if (TranslationTableBase != NULL) {\r
+    *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;\r
+  }\r
+\r
+  ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);\r
+\r
+  ArmCleanInvalidateDataCache();\r
+  ArmInvalidateInstructionCache();\r
+  ArmInvalidateTlb();\r
+\r
+  ArmDisableDataCache();\r
+  ArmDisableInstructionCache();\r
+  ArmDisableMmu();\r
+\r
+  // Make sure nothing sneaked into the cache\r
+  ArmCleanInvalidateDataCache();\r
+  ArmInvalidateInstructionCache();\r
+\r
+  TranslationTableAttribute = 0;\r
+  while (MemoryTable->Length != 0) {\r
+    // Find the memory attribute for the Translation Table\r
+    if ((TranslationTable >= MemoryTable->PhysicalBase) && (TranslationTable < MemoryTable->PhysicalBase + MemoryTable->Length)) {\r
+      TranslationTableAttribute = MemoryTable->Attributes;\r
+    }\r
+\r
+    FillTranslationTable ((VOID *)TranslationTable, MemoryTable);\r
+    MemoryTable++;\r
+  }\r
+\r
+  // Translate the Memory Attributes into Translation Table Register Attributes\r
+  if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) || \r
+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED)) {\r
+    TTBRAttributes = TTBR_NON_CACHEABLE;\r
+  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) || \r
+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK)) {\r
+    TTBRAttributes = TTBR_WRITE_BACK_ALLOC;\r
+  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) || \r
+      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH)) {\r
+    TTBRAttributes = TTBR_WRITE_THROUGH_NO_ALLOC;\r
+  } else {\r
+    //TODO: We should raise an error here\r
+    TTBRAttributes = TTBR_NON_CACHEABLE;\r
+  }\r
+\r
+  ArmSetTTBR0 ((VOID *)(UINTN)((TranslationTable & 0xFFFFC000) | (TTBRAttributes & 0x7F)));\r
+    \r
+  ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE(14) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE(13) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE(12) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE(11) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE(10) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 9) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 8) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 7) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 6) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 5) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 4) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 3) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 2) |\r
+                             DOMAIN_ACCESS_CONTROL_NONE( 1) |\r
+                             DOMAIN_ACCESS_CONTROL_MANAGER(0));\r
+    \r
+  ArmEnableInstructionCache();\r
+  ArmEnableDataCache();\r
+  ArmEnableMmu();\r
+}\r
index 991de89a9606699a0755634c19ff7be0cda43687..cfbb8f545c726605675ffc07933c661200ac0a2b 100644 (file)
 #
 #------------------------------------------------------------------------------
 
-.globl ASM_PFX(ArmInvalidateInstructionCache)
-INTERWORK_FUNC(ArmInvalidateInstructionCache)
-.globl ASM_PFX(ArmInvalidateDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmInvalidateDataCacheEntryByMVA)
-.globl ASM_PFX(ArmCleanDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmCleanDataCacheEntryByMVA)
-.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryByMVA)
-INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
-.globl ASM_PFX(ArmInvalidateDataCacheEntryBySetWay)
-INTERWORK_FUNC(ArmInvalidateDataCacheEntryBySetWay)
-.globl ASM_PFX(ArmCleanDataCacheEntryBySetWay)
-INTERWORK_FUNC(ArmCleanDataCacheEntryBySetWay)
-.globl ASM_PFX(ArmCleanInvalidateDataCacheEntryBySetWay)
-INTERWORK_FUNC(ArmCleanInvalidateDataCacheEntryBySetWay)
-.globl ASM_PFX(ArmDrainWriteBuffer)
-INTERWORK_FUNC(ArmDrainWriteBuffer)
-.globl ASM_PFX(ArmEnableMmu)
-INTERWORK_FUNC(ArmEnableMmu)
-.globl ASM_PFX(ArmDisableMmu)
-INTERWORK_FUNC(ArmDisableMmu)
-.globl ASM_PFX(ArmMmuEnabled)
-INTERWORK_FUNC(ArmMmuEnabled)
-.globl ASM_PFX(ArmEnableDataCache)
-INTERWORK_FUNC(ArmEnableDataCache)
-.globl ASM_PFX(ArmDisableDataCache)
-INTERWORK_FUNC(ArmDisableDataCache)
-.globl ASM_PFX(ArmEnableInstructionCache)
-INTERWORK_FUNC(ArmEnableInstructionCache)
-.globl ASM_PFX(ArmDisableInstructionCache)
-INTERWORK_FUNC(ArmDisableInstructionCache)
-.globl ASM_PFX(ArmEnableBranchPrediction)
-INTERWORK_FUNC(ArmEnableBranchPrediction)
-.globl ASM_PFX(ArmDisableBranchPrediction)
-INTERWORK_FUNC(ArmDisableBranchPrediction)
-.globl ASM_PFX(ArmV7AllDataCachesOperation)
-INTERWORK_FUNC(ArmV7AllDataCachesOperation)
-.globl ASM_PFX(ArmDataMemoryBarrier)
-INTERWORK_FUNC(ArmDataMemoryBarrier)
-.globl ASM_PFX(ArmDataSyncronizationBarrier) 
-INTERWORK_FUNC(ArmDataSyncronizationBarrier)
-.globl ASM_PFX(ArmInstructionSynchronizationBarrier)
-INTERWORK_FUNC(ArmInstructionSynchronizationBarrier)
-
 .text
 .align 2
 
+GCC_ASM_EXPORT (ArmInvalidateInstructionCache)
+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmCleanDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryByMVA)
+GCC_ASM_EXPORT (ArmInvalidateDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmCleanDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmCleanInvalidateDataCacheEntryBySetWay)
+GCC_ASM_EXPORT (ArmDrainWriteBuffer)
+GCC_ASM_EXPORT (ArmEnableMmu)
+GCC_ASM_EXPORT (ArmDisableMmu)
+GCC_ASM_EXPORT (ArmDisableCachesAndMmu)
+GCC_ASM_EXPORT (ArmMmuEnabled)
+GCC_ASM_EXPORT (ArmEnableDataCache)
+GCC_ASM_EXPORT (ArmDisableDataCache)
+GCC_ASM_EXPORT (ArmEnableInstructionCache)
+GCC_ASM_EXPORT (ArmDisableInstructionCache)
+GCC_ASM_EXPORT (ArmEnableSWPInstruction)
+GCC_ASM_EXPORT (ArmEnableBranchPrediction)
+GCC_ASM_EXPORT (ArmDisableBranchPrediction)
+GCC_ASM_EXPORT (ArmV7AllDataCachesOperation)
+GCC_ASM_EXPORT (ArmDataMemoryBarrier)
+GCC_ASM_EXPORT (ArmDataSyncronizationBarrier)
+GCC_ASM_EXPORT (ArmInstructionSynchronizationBarrier)
+GCC_ASM_EXPORT (ArmWriteNsacr)
+GCC_ASM_EXPORT (ArmWriteScr)
+GCC_ASM_EXPORT (ArmWriteVMBar)
+GCC_ASM_EXPORT (ArmWriteVBar)
+GCC_ASM_EXPORT (ArmWriteCPACR)
+GCC_ASM_EXPORT (ArmEnableVFP)
+GCC_ASM_EXPORT (ArmCallWFI)
+GCC_ASM_EXPORT (ArmWriteAuxCr)
+GCC_ASM_EXPORT (ArmReadAuxCr)
+GCC_ASM_EXPORT (ArmReadCbar)
+GCC_ASM_EXPORT (ArmInvalidateInstructionAndDataTlb)
+GCC_ASM_EXPORT (ArmReadMpidr)
+
 .set DC_ON, (0x1<<2)
 .set IC_ON, (0x1<<12)
-
+.set CTRL_M_BIT,  (1 << 0)
+.set CTRL_C_BIT,  (1 << 2)
+.set CTRL_B_BIT,  (1 << 7)
+.set CTRL_I_BIT,  (1 << 12)
 
 
 ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
@@ -69,7 +65,6 @@ ASM_PFX(ArmInvalidateDataCacheEntryByMVA):
   isb
   bx      lr
 
-
 ASM_PFX(ArmCleanDataCacheEntryByMVA):
   mcr     p15, 0, r0, c7, c10, 1  @clean single data cache line     
   dsb
@@ -104,7 +99,6 @@ ASM_PFX(ArmCleanDataCacheEntryBySetWay):
   isb
   bx      lr
 
-
 ASM_PFX(ArmInvalidateInstructionCache):
   mcr     p15,0,R0,c7,c5,0      @Invalidate entire instruction cache
   dsb
@@ -119,10 +113,6 @@ ASM_PFX(ArmEnableMmu):
   isb
   bx      LR
 
-ASM_PFX(ArmMmuEnabled):
-  mrc     p15,0,R0,c1,c0,0
-  and     R0,R0,#1
-  bx      LR
 
 ASM_PFX(ArmDisableMmu):
   mrc     p15,0,R0,c1,c0,0
@@ -135,6 +125,21 @@ ASM_PFX(ArmDisableMmu):
   isb
   bx      LR
 
+ASM_PFX(ArmDisableCachesAndMmu):
+  mrc   p15, 0, r0, c1, c0, 0           @ Get control register
+  bic   r0, r0, #CTRL_M_BIT             @ Disable MMU
+  bic   r0, r0, #CTRL_C_BIT             @ Disable D Cache
+  bic   r0, r0, #CTRL_I_BIT             @ Disable I Cache
+  mcr   p15, 0, r0, c1, c0, 0           @ Write control register
+  dsb
+  isb
+  bx      LR
+
+ASM_PFX(ArmMmuEnabled):
+  mrc     p15,0,R0,c1,c0,0
+  and     R0,R0,#1
+  bx      LR  
+
 ASM_PFX(ArmEnableDataCache):
   ldr     R1,=DC_ON
   mrc     p15,0,R0,c1,c0,0      @Read control register configuration data
@@ -171,6 +176,13 @@ ASM_PFX(ArmDisableInstructionCache):
   isb
   bx      LR
 
+ASM_PFX(ArmEnableSWPInstruction):
+  mrc     p15, 0, r0, c1, c0, 0
+  orr     r0, r0, #0x00000400
+  mcr     p15, 0, r0, c1, c0, 0
+  isb
+  bx      LR
+
 ASM_PFX(ArmEnableBranchPrediction):
   mrc     p15, 0, r0, c1, c0, 0
   orr     r0, r0, #0x00000800
@@ -254,5 +266,59 @@ ASM_PFX(ArmInstructionSynchronizationBarrier):
   isb
   bx      LR
  
+ASM_PFX(ArmWriteNsacr):
+  mcr     p15, 0, r0, c1, c1, 2
+  bx      lr
+
+ASM_PFX(ArmWriteScr):
+  mcr     p15, 0, r0, c1, c1, 0
+  bx      lr
+
+ASM_PFX(ArmWriteAuxCr):
+  mcr     p15, 0, r0, c1, c0, 1
+  bx      lr
+
+ASM_PFX(ArmReadAuxCr):
+  mrc     p15, 0, r0, c1, c0, 1
+  bx      lr  
+
+ASM_PFX(ArmWriteVMBar):
+  mcr     p15, 0, r0, c12, c0, 1
+  bx      lr
+
+ASM_PFX(ArmWriteVBar):
+  mcr     p15, 0, r0, c12, c0, 0 
+  bx      lr
+
+ASM_PFX(ArmWriteCPACR):
+  mcr     p15, 0, r0, c1, c0, 2
+  bx      lr
+
+ASM_PFX(ArmEnableVFP):
+  // Enable VFP registers
+  mrc     p15, 0, r0, c1, c0, 2
+  orr     r0, r0, #0x00f00000   // Enable VPF access (V* instructions)
+  mcr     p15, 0, r0, c1, c0, 2
+  mov     r0, #0x40000000       // Set EN bit in FPEXC
+  mcr     p10,#0x7,r0,c8,c0,#0  // msr     FPEXC,r0 in ARM assembly
+  bx      lr
+
+ASM_PFX(ArmCallWFI):
+  wfi
+  bx      lr
+
+//Note: Return 0 in Uniprocessor implementation
+ASM_PFX(ArmReadCbar):
+  mrc     p15, 4, r0, c15, c0, 0       //Read Configuration Base Address Register
+  bx      lr
+
+ASM_PFX(ArmInvalidateInstructionAndDataTlb):
+  mcr     p15, 0, r0, c8, c7, 0      @ Invalidate Inst TLB and Data TLB
+  dsb
+  bx lr
+
+ASM_PFX(ArmReadMpidr):
+  mrc     p15, 0, r0, c0, c0, 5             @ read MPIDR
+  bx      lr
 
 ASM_FUNCTION_REMOVE_IF_UNREFERENCED
index 8758b80ba5491f714ee083d56c0cf5c8630a7343..7b4ca425bd3d71cd488afc2d847648029e2096f2 100644 (file)
     EXPORT  ArmDrainWriteBuffer
     EXPORT  ArmEnableMmu
     EXPORT  ArmDisableMmu
+    EXPORT  ArmDisableCachesAndMmu
     EXPORT  ArmMmuEnabled
     EXPORT  ArmEnableDataCache
     EXPORT  ArmDisableDataCache
     EXPORT  ArmEnableInstructionCache
     EXPORT  ArmDisableInstructionCache
+    EXPORT  ArmEnableSWPInstruction
     EXPORT  ArmEnableBranchPrediction
     EXPORT  ArmDisableBranchPrediction
     EXPORT  ArmV7AllDataCachesOperation
     EXPORT  ArmDataMemoryBarrier
     EXPORT  ArmDataSyncronizationBarrier
     EXPORT  ArmInstructionSynchronizationBarrier
+    EXPORT  ArmWriteNsacr
+    EXPORT  ArmWriteScr
+    EXPORT  ArmWriteVMBar
+    EXPORT  ArmWriteVBar
+    EXPORT  ArmReadVBar
+    EXPORT  ArmWriteCPACR
+    EXPORT  ArmEnableVFP
+    EXPORT  ArmCallWFI
+    EXPORT  ArmWriteAuxCr
+    EXPORT  ArmReadAuxCr
+    EXPORT  ArmReadCbar
+    EXPORT  ArmInvalidateInstructionAndDataTlb
+    EXPORT  ArmReadMpidr
 
     AREA    ArmCacheLib, CODE, READONLY
     PRESERVE8
 
-DC_ON       EQU     ( 0x1:SHL:2 )
-IC_ON       EQU     ( 0x1:SHL:12 )
-
+DC_ON           EQU     ( 0x1:SHL:2 )
+IC_ON           EQU     ( 0x1:SHL:12 )
+CTRL_M_BIT      EQU     (1 << 0)
+CTRL_C_BIT      EQU     (1 << 2)
+CTRL_B_BIT      EQU     (1 << 7)
+CTRL_I_BIT      EQU     (1 << 12)
 
 
 ArmInvalidateDataCacheEntryByMVA
@@ -90,75 +108,91 @@ ArmInvalidateInstructionCache
   bx      LR
 
 ArmEnableMmu
-  mrc     p15,0,R0,c1,c0,0
-  orr     R0,R0,#1
-  mcr     p15,0,R0,c1,c0,0
+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)
+  orr     R0,R0,#1              ; Set SCTLR.M bit : Enable MMU
+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)
   dsb
   isb
   bx      LR
 
 ArmMmuEnabled
-  mrc     p15,0,R0,c1,c0,0
+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)
   and     R0,R0,#1
   bx      LR
 
 ArmDisableMmu
-  mrc     p15,0,R0,c1,c0,0
-  bic     R0,R0,#1
-  mcr     p15,0,R0,c1,c0,0      ;Disable MMU
+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)
+  bic     R0,R0,#1              ; Clear SCTLR.M bit : Disable MMU
+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)
 
-       mcr             p15,0,R0,c8,c7,0      ;Invalidate TLB
-  mcr     p15,0,R0,c7,c5,6      ;Invalidate Branch predictor array
+  mcr    p15,0,R0,c8,c7,0      ; TLBIALL : Invalidate unified TLB
+  mcr     p15,0,R0,c7,c5,6      ; BPIALL  : Invalidate entire branch predictor array
   dsb
   isb
   bx      LR
 
+ArmDisableCachesAndMmu
+  mrc   p15, 0, r0, c1, c0, 0           ; Get control register
+  bic   r0, r0, #CTRL_M_BIT             ; Disable MMU
+  bic   r0, r0, #CTRL_C_BIT             ; Disable D Cache
+  bic   r0, r0, #CTRL_I_BIT             ; Disable I Cache
+  mcr   p15, 0, r0, c1, c0, 0           ; Write control register
+  dsb
+  isb
+  bx      LR
 
 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
+  ldr     R1,=DC_ON             ; Specify SCTLR.C bit : (Data) Cache enable bit
+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)
+  orr     R0,R0,R1              ; Set SCTLR.C bit : Data and unified caches enabled
+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)
   dsb
   isb
   bx      LR
     
 ArmDisableDataCache
-  ldr     R1,=DC_ON
-  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
+  ldr     R1,=DC_ON             ; Specify SCTLR.C bit : (Data) Cache enable bit
+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)
+  bic     R0,R0,R1              ; Clear SCTLR.C bit : Data and unified caches disabled
+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)
   isb
   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
+  ldr     R1,=IC_ON             ; Specify SCTLR.I bit : Instruction cache enable bit
+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)
+  orr     R0,R0,R1              ; Set SCTLR.I bit : Instruction caches enabled
+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)
   dsb
   isb
   bx      LR
   
 ArmDisableInstructionCache
-  ldr     R1,=IC_ON
-  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
+  ldr     R1,=IC_ON             ; Specify SCTLR.I bit : Instruction cache enable bit
+  mrc     p15,0,R0,c1,c0,0      ; Read SCTLR into R0 (Read control register configuration data)
+  BIC     R0,R0,R1              ; Clear SCTLR.I bit : Instruction caches disabled
+  mcr     p15,0,R0,c1,c0,0      ; Write R0 into SCTLR (Write control register configuration data)
   isb
   bx      LR
 
-ArmEnableBranchPrediction
+ArmEnableSWPInstruction
   mrc     p15, 0, r0, c1, c0, 0
-  orr     r0, r0, #0x00000800
+  orr     r0, r0, #0x00000400
   mcr     p15, 0, r0, c1, c0, 0
   isb
   bx      LR
 
+ArmEnableBranchPrediction
+  mrc     p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+  orr     r0, r0, #0x00000800   ;
+  mcr     p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
+  isb
+  bx      LR
+
 ArmDisableBranchPrediction
-  mrc     p15, 0, r0, c1, c0, 0
-  bic     r0, r0, #0x00000800
-  mcr     p15, 0, r0, c1, c0, 0
+  mrc     p15, 0, r0, c1, c0, 0 ; Read SCTLR into R0 (Read control register configuration data)
+  bic     r0, r0, #0x00000800   ;
+  mcr     p15, 0, r0, c1, c0, 0 ; Write R0 into SCTLR (Write control register configuration data)
   isb
   bx      LR
 
@@ -173,9 +207,9 @@ ArmV7AllDataCachesOperation
   mov   R10, #0
 
 Loop1   
-  add   R2, R10, R10, LSR #1  ; Work out 3xcachelevel
-  mov   R12, R6, LSR R2       ; bottom 3 bits are the Cache type for this level
-  and   R12, R12, #7          ; get those 3 bits alone
+  add   R2, R10, R10, LSR #1    ; Work out 3xcachelevel
+  mov   R12, R6, LSR R2         ; bottom 3 bits are the Cache type for this level
+  and   R12, R12, #7            ; get those 3 bits alone
   cmp   R12, #2
   blt   Skip                    ; no cache or only instruction cache at this level
   mcr   p15, 2, R10, c0, c0, 0  ; write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
@@ -226,5 +260,64 @@ ArmInstructionSynchronizationBarrier
   isb
   bx      LR
 
-    END
+ArmWriteNsacr
+  mcr     p15, 0, r0, c1, c1, 2
+  bx      lr
+
+ArmWriteScr
+  mcr     p15, 0, r0, c1, c1, 0
+  bx      lr
+
+ArmWriteAuxCr
+  mcr     p15, 0, r0, c1, c0, 1
+  bx      lr
+
+ArmReadAuxCr
+  mrc     p15, 0, r0, c1, c0, 1
+  bx      lr  
+
+ArmWriteVMBar
+  mcr     p15, 0, r0, c12, c0, 1
+  bx      lr
+
+ArmWriteVBar
+  mcr     p15, 0, r0, c12, c0, 0 
+  bx      lr
+
+ArmReadVBar
+  mrc     p15, 0, r0, c12, c0, 0 
+  bx      lr
+
+ArmWriteCPACR
+  mcr     p15, 0, r0, c1, c0, 2
+  bx      lr
+
+ArmEnableVFP
+  // Enable VFP registers
+  mrc     p15, 0, r0, c1, c0, 2
+  orr     r0, r0, #0x00f00000   // Enable VPF access (V* instructions)
+  mcr     p15, 0, r0, c1, c0, 2
+  mov     r0, #0x40000000       // Set EN bit in FPEXC
+  mcr     p10,#0x7,r0,c8,c0,#0  // msr     FPEXC,r0 in ARM assembly
+  bx      lr
+
+ArmCallWFI
+  wfi
+  bx      lr
+
+//Note: Return 0 in Uniprocessor implementation
+ArmReadCbar
+  mrc     p15, 4, r0, c15, c0, 0       //Read Configuration Base Address Register
+  bx      lr
+
+ArmInvalidateInstructionAndDataTlb
+  mcr     p15, 0, r0, c8, c7, 0      ; Invalidate Inst TLB and Data TLB
+  dsb
+  bx lr
+
+ArmReadMpidr
+  mrc     p15, 0, r0, c0, c0, 5                ; read MPIDR
+  bx      lr
+
+  END
 
index a432acbb808bd15f0ccfd06c3a0f17089842229e..9b144c82c5918fb4d2ea720936d63f7f097f3812 100644 (file)
 #
 #------------------------------------------------------------------------------
 
+#include <AsmMacroIoLib.h>
+
 .text
 .align 2
-.globl ASM_PFX(Cp15IdCode)
-INTERWORK_FUNC(Cp15IdCode)
-.globl ASM_PFX(Cp15CacheInfo)
-INTERWORK_FUNC(Cp15CacheInfo)
-.globl ASM_PFX(ArmEnableInterrupts)
-INTERWORK_FUNC(ArmEnableInterrupts)
-.globl ASM_PFX(ArmDisableInterrupts)
-INTERWORK_FUNC(ArmDisableInterrupts)
-.globl ASM_PFX(ArmGetInterruptState)
-INTERWORK_FUNC(ArmGetInterruptState)
-.globl ASM_PFX(ArmEnableFiq)
-INTERWORK_FUNC(ArmEnableFiq)
-.globl ASM_PFX(ArmDisableFiq)
-INTERWORK_FUNC(ArmDisableFiq)
-.globl ASM_PFX(ArmGetFiqState)
-INTERWORK_FUNC(ArmGetFiqState)
-.globl ASM_PFX(ArmInvalidateTlb)
-INTERWORK_FUNC(ArmInvalidateTlb)
-.globl ASM_PFX(ArmSetTranslationTableBaseAddress)
-INTERWORK_FUNC(ArmSetTranslationTableBaseAddress)
-.globl ASM_PFX(ArmGetTranslationTableBaseAddress)
-INTERWORK_FUNC(ArmGetTranslationTableBaseAddress)
-.globl ASM_PFX(ArmSetDomainAccessControl)
-INTERWORK_FUNC(ArmSetDomainAccessControl)
-.globl ASM_PFX(CPSRMaskInsert)
-INTERWORK_FUNC(CPSRMaskInsert)
-.globl ASM_PFX(CPSRRead)
-INTERWORK_FUNC(CPSRRead)
-
+GCC_ASM_EXPORT(Cp15IdCode)
+GCC_ASM_EXPORT(Cp15CacheInfo)
+GCC_ASM_EXPORT(ArmEnableInterrupts)
+GCC_ASM_EXPORT(ArmDisableInterrupts)
+GCC_ASM_EXPORT(ArmGetInterruptState)
+GCC_ASM_EXPORT(ArmEnableFiq)
+GCC_ASM_EXPORT(ArmDisableFiq)
+GCC_ASM_EXPORT(ArmGetFiqState)
+GCC_ASM_EXPORT(ArmInvalidateTlb)
+GCC_ASM_EXPORT(ArmSetTTBR0)
+GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)
+GCC_ASM_EXPORT(ArmSetDomainAccessControl)
+GCC_ASM_EXPORT(CPSRMaskInsert)
+GCC_ASM_EXPORT(CPSRRead)
 
 #------------------------------------------------------------------------------
 
@@ -103,12 +90,14 @@ ASM_PFX(ArmInvalidateTlb):
   mcr     p15,0,r0,c8,c7,0
   bx      lr
 
-ASM_PFX(ArmSetTranslationTableBaseAddress):
+ASM_PFX(ArmSetTTBR0):
   mcr     p15,0,r0,c2,c0,0
   bx      lr
 
-ASM_PFX(ArmGetTranslationTableBaseAddress):
+ASM_PFX(ArmGetTTBR0BaseAddress):
   mrc     p15,0,r0,c2,c0,0
+  LoadConstantToReg(0xFFFFC000, r1)   @  and     r0, r0, #0xFFFFC000
+  and     r0, r0, r1
   bx      lr
 
 
index 459ebd44c887955c5cb3c5c59de765e8cf1e217a..cf7605f45aeee05c55b8bdd56f032fe94e28cf31 100644 (file)
@@ -15,6 +15,7 @@
 
     EXPORT  Cp15IdCode
     EXPORT  Cp15CacheInfo
+    EXPORT  ArmIsMPCore
     EXPORT  ArmEnableInterrupts
     EXPORT  ArmDisableInterrupts
     EXPORT  ArmGetInterruptState
@@ -22,8 +23,8 @@
     EXPORT  ArmDisableFiq
     EXPORT  ArmGetFiqState
     EXPORT  ArmInvalidateTlb
-    EXPORT  ArmSetTranslationTableBaseAddress
-    EXPORT  ArmGetTranslationTableBaseAddress
+    EXPORT  ArmSetTTBR0
+    EXPORT  ArmGetTTBR0BaseAddress
     EXPORT  ArmSetDomainAccessControl
     EXPORT  CPSRMaskInsert
     EXPORT  CPSRRead
@@ -38,6 +39,14 @@ Cp15CacheInfo
   mrc     p15,0,R0,c0,c0,1
   bx      LR
 
+ArmIsMPCore
+  mrc     p15,0,R0,c0,c0,5
+  # Get Multiprocessing extension (bit31) & U bit (bit30)
+  and     R0, R0, #0xC0000000
+  # if bit30 == 0 then the processor is part of a multiprocessor system)
+  and     R0, R0, #0x80000000
+  bx      LR
+
 ArmEnableInterrupts
        mrs     R0,CPSR
        bic     R0,R0,#0x80             ;Enable IRQ interrupts
@@ -87,12 +96,13 @@ ArmInvalidateTlb
   mcr     p15,0,r0,c8,c7,0
   bx      lr
 
-ArmSetTranslationTableBaseAddress
+ArmSetTTBR0
   mcr     p15,0,r0,c2,c0,0
   bx      lr
 
-ArmGetTranslationTableBaseAddress
+ArmGetTTBR0BaseAddress
   mrc     p15,0,r0,c2,c0,0
+  and     r0, r0, #0xFFFFC000
   bx      lr
 
 ArmSetDomainAccessControl
diff --git a/ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBox.c b/ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBox.c
new file mode 100644 (file)
index 0000000..7648780
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/ArmMPCoreMailBoxLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/IoLib.h>\r
+\r
+VOID ArmClearMPCoreMailbox() {\r
+       MmioWrite32(PcdGet32(PcdMPCoreMailboxClearAddress),PcdGet32(PcdMPCoreMailboxClearValue));\r
+}\r
+\r
+UINTN ArmGetMPCoreMailbox() {\r
+    return MmioRead32(PcdGet32(PcdMPCoreMailboxGetAddress));\r
+}\r
diff --git a/ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf b/ArmPkg/Library/ArmMPCoreMailBoxLib/ArmMPCoreMailBoxLib.inf
new file mode 100644 (file)
index 0000000..9003f1d
--- /dev/null
@@ -0,0 +1,37 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ArmMPCoreMailBoxLib\r
+  FILE_GUID                      = de76d780-f422-11df-967a-0002a5d5c51b\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ArmMPCoreMailBoxLib\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ArmPkg/ArmPkg.dec\r
+\r
+[LibraryClasses]\r
+  IoLib\r
+\r
+[Sources.common]\r
+  ArmMPCoreMailBox.c\r
+\r
+[Protocols]\r
+\r
+[FixedPcd]\r
+  gArmTokenSpaceGuid.PcdMPCoreMailboxGetAddress\r
+  gArmTokenSpaceGuid.PcdMPCoreMailboxClearAddress\r
+  gArmTokenSpaceGuid.PcdMPCoreMailboxClearValue\r
diff --git a/ArmPkg/Library/ArmTrustZoneLib/ArmTrustZone.c b/ArmPkg/Library/ArmTrustZoneLib/ArmTrustZone.c
new file mode 100644 (file)
index 0000000..ed9abe3
--- /dev/null
@@ -0,0 +1,79 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/ArmTrustZoneLib.h>\r
+\r
+#define TZPC_DECPROT0_STATUS_REG        0x800\r
+#define TZPC_DECPROT0_SET_REG           0x804\r
+#define TZPC_DECPROT0_CLEAR_REG         0x808\r
+\r
+#define TZASC_CONFIGURATION_REG         0x000\r
+#define TZASC_REGIONS_REG               0x100\r
+#define TZASC_REGION0_LOW_ADDRESS_REG   0x100\r
+#define TZASC_REGION0_HIGH_ADDRESS_REG  0x104\r
+#define TZASC_REGION0_ATTRIBUTES        0x108\r
+\r
+/**\r
+    FIXME: Need documentation\r
+**/\r
+EFI_STATUS TZPCSetDecProtBits(UINTN TzpcBase, UINTN TzpcId, UINTN Bits) {\r
+    if (TzpcId > TZPC_DECPROT_MAX) {\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    MmioWrite32((UINTN)TzpcBase + TZPC_DECPROT0_SET_REG + (TzpcId * 0x0C), Bits);\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+    FIXME: Need documentation\r
+**/\r
+EFI_STATUS TZPCClearDecProtBits(UINTN TzpcBase, UINTN TzpcId, UINTN Bits) {\r
+    if (TzpcId> TZPC_DECPROT_MAX) {\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    MmioWrite32((UINTN)TzpcBase + TZPC_DECPROT0_CLEAR_REG + (TzpcId * 0x0C), Bits);\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+    FIXME: Need documentation\r
+**/\r
+UINT32 TZASCGetNumRegions(UINTN TzascBase) {\r
+    return (MmioRead32((UINTN)TzascBase + TZASC_CONFIGURATION_REG) & 0xF);\r
+}\r
+\r
+/**\r
+    FIXME: Need documentation\r
+**/\r
+EFI_STATUS TZASCSetRegion(UINTN TzascBase, UINTN RegionId, UINTN Enabled, UINTN LowAddress, UINTN HighAddress, UINTN Size, UINTN Security) {\r
+    UINT32*     Region;\r
+\r
+    if (RegionId > TZASCGetNumRegions(TzascBase)) {\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Region = (UINT32*)((UINTN)TzascBase + TZASC_REGIONS_REG + (RegionId * 0x10));\r
+\r
+    MmioWrite32((UINTN)(Region), LowAddress&0xFFFF8000);\r
+       MmioWrite32((UINTN)(Region+1), HighAddress);\r
+       MmioWrite32((UINTN)(Region+2), ((Security & 0xF) <<28) | ((Size & 0x3F) << 1) | (Enabled & 0x1));\r
+\r
+    return EFI_SUCCESS;\r
+}\r
diff --git a/ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf b/ArmPkg/Library/ArmTrustZoneLib/ArmTrustZoneLib.inf
new file mode 100644 (file)
index 0000000..fae8206
--- /dev/null
@@ -0,0 +1,32 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ArmTrustZoneLib\r
+  FILE_GUID                      = 5962d040-8b8a-11df-9a71-0002a5d5c51b\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ArmTrustZoneLib\r
+\r
+\r
+[Sources.common]\r
+  ArmTrustZone.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ArmPkg/ArmPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  IoLib\r
index 1cd1dae54ffee051f2e8a4975c9b2cd2d1b3fb83..8339a101957d75e2aaee0f63de75b0a3091e9e14 100755 (executable)
@@ -39,8 +39,7 @@ InternalMemCopyMem (
 **/\r
 .text\r
 .align 2\r
-.globl ASM_PFX(InternalMemCopyMem)\r
-INTERWORK_FUNC(InternalMemCopyMem)\r
+GCC_ASM_EXPORT(InternalMemCopyMem)\r
 \r
 ASM_PFX(InternalMemCopyMem):\r
        stmfd   sp!, {r4-r11, lr}\r
index 29a50f5a49d5b6ad9e36c06afe97529815f766ec..c6dbc7f2c75c4caa8a86e839c46f6a6596793aae 100755 (executable)
@@ -37,8 +37,7 @@ InternalMemSetMem (
        \r
 .text\r
 .align 2\r
-.globl ASM_PFX(InternalMemSetMem)\r
-INTERWORK_FUNC(InternalMemSetMem)\r
+GCC_ASM_EXPORT(InternalMemSetMem)\r
 \r
 ASM_PFX(InternalMemSetMem):\r
        stmfd   sp!, {r4-r11, lr}\r
index 69db9365557f58dcb170a3fbeb4ba14569d50d28..239807c7321c9a63d833d880f06be76797b1e9ce 100755 (executable)
@@ -39,8 +39,7 @@ InternalMemCopyMem (
 **/\r
 .text\r
 .align 2\r
-.globl ASM_PFX(InternalMemCopyMem)\r
-INTERWORK_FUNC(InternalMemCopyMem)\r
+GCC_ASM_EXPORT(InternalMemCopyMem)\r
 \r
 ASM_PFX(InternalMemCopyMem):\r
        stmfd   sp!, {r4, r9, lr}\r
index 3eb901b58f8c040c79a7251f9959fde5797a27ea..8120cfc1c339156301950959427fde5279755c56 100755 (executable)
@@ -37,8 +37,7 @@ InternalMemSetMem (
        \r
 .text\r
 .align 2\r
-.globl ASM_PFX(InternalMemSetMem)\r
-INTERWORK_FUNC(InternalMemSetMem)\r
+GCC_ASM_EXPORT(InternalMemSetMem)\r
 \r
 ASM_PFX(InternalMemSetMem):\r
        stmfd   sp!, {r4-r7, lr}\r
index a4c80eaa8bafee1fb48582b2cdc9c0bcb60044e1..8e0ceb88109dd2fbcc05f1d54b395a72159f76dc 100755 (executable)
@@ -913,7 +913,7 @@ PeCoffLoaderLoadImage (
                             ImageContext->Handle,\r
                             0,\r
                             &ImageContext->SizeOfHeaders,\r
-                            (void *)(UINTN)ImageContext->ImageAddress\r
+                            (VOID*)(UINTN)ImageContext->ImageAddress\r
                             );\r
 \r
     Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
diff --git a/ArmPkg/Library/BdsLib/BdsAppLoader.c b/ArmPkg/Library/BdsLib/BdsAppLoader.c
new file mode 100644 (file)
index 0000000..1cc4fdd
--- /dev/null
@@ -0,0 +1,102 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include "BdsInternal.h"\r
+\r
+EFI_STATUS\r
+BdsLoadPeCoff (\r
+ IN  BDS_FILE     *EfiAppFile\r
+ )\r
+{\r
+    EFI_STATUS                          Status;\r
+    EFI_HANDLE                          ImageHandle;\r
+    MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   NewNode;\r
+    EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
+\r
+    // Only support loading from FV right now\r
+    ASSERT(EfiAppFile->Type == BDS_FILETYPE_FV);\r
+\r
+    // Generate the Device Path for the file\r
+    DevicePath = DuplicateDevicePath(EfiAppFile->DevicePath);\r
+    EfiInitializeFwVolDevicepathNode (&NewNode, &(EfiAppFile->File.Fv.Guid));\r
+    DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&NewNode);\r
+\r
+    Status = gBS->LoadImage (TRUE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);\r
+    if (!EFI_ERROR (Status)) {\r
+        Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+    }\r
+  \r
+    return Status;\r
+}\r
+\r
+EFI_STATUS BdsLoadApplicationFromPath(\r
+    IN  CHAR16* EfiAppPath\r
+) {\r
+    EFI_STATUS Status;\r
+    BDS_FILE   EfiAppFile;\r
+\r
+    // Need to connect every drivers to ensure no dependencies are missing for the application\r
+    Status = BdsConnectAllDrivers();\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));\r
+        return Status;\r
+    }\r
+\r
+    // Locate the application from a device path\r
+    Status = BdsLoadFilePath(EfiAppPath, &EfiAppFile);\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG ((EFI_D_ERROR, "ERROR: Do not find EFI application %s\n",EfiAppPath));\r
+        return Status;\r
+    }\r
+\r
+    // Start the application\r
+    Status = BdsLoadPeCoff(&EfiAppFile);\r
+\r
+    return Status;\r
+}\r
+\r
+EFI_STATUS BdsLoadApplication(\r
+    IN  CHAR16* EfiApp\r
+) {\r
+    EFI_STATUS                      Status;\r
+    UINTN                           NoHandles, HandleIndex;\r
+    EFI_HANDLE                      *Handles;\r
+    BDS_FILE                        EfiAppFile;\r
+\r
+    // Need to connect every drivers to ensure no dependencies are missing for the application\r
+    Status = BdsConnectAllDrivers();\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));\r
+        return Status;\r
+    }\r
+\r
+    // Search the application in any Firmware Volume\r
+    Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);\r
+    if (EFI_ERROR (Status) || (NoHandles == 0)) {\r
+        DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));\r
+        return Status;\r
+    }\r
+\r
+    // Search in all Firmware Volume for the EFI Application\r
+    for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {\r
+        Status = BdsLoadFileFromFirmwareVolume(Handles[HandleIndex],EfiApp,EFI_FV_FILETYPE_APPLICATION,&EfiAppFile);\r
+        if (!EFI_ERROR (Status)) {\r
+            // Start the application\r
+            Status = BdsLoadPeCoff(&EfiAppFile);\r
+            return Status;\r
+        }\r
+    }\r
+\r
+    return Status;\r
+}\r
diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c
new file mode 100644 (file)
index 0000000..b1460b9
--- /dev/null
@@ -0,0 +1,182 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#include "BdsInternal.h"
+
+// Count the number of DevicePath Node
+static UINTN NumberNodeFromDevicePath(
+    IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath
+) {
+    UINTN NumberDevicePathNode = 0;
+
+    while (!IsDevicePathEnd (DevicePath)) {
+        NumberDevicePathNode++;
+        DevicePath = NextDevicePathNode(DevicePath);
+    }
+    return NumberDevicePathNode;
+}
+
+// Extract the FilePath from the Device Path
+CHAR16* BdsExtractFilePathFromDevicePath(
+    IN  CONST CHAR16    *StrDevicePath,
+    IN  UINTN           NumberDevicePathNode
+) {
+    UINTN       Node;
+    CHAR16      *Str;
+
+    Str = (CHAR16*)StrDevicePath;
+    Node = 0;
+    while ((Str != NULL) && (*Str != L'\0') && (Node < NumberDevicePathNode)) {
+        if ((*Str == L'/') || (*Str == L'\\')) {
+            Node++;
+        }
+        Str++;
+    }
+
+    if (*Str == L'\0') {
+        return NULL;
+    } else {
+        return Str;
+    }
+}
+
+EFI_STATUS
+BdsLoadDevicePath(
+    IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,
+    OUT EFI_HANDLE                *Handle
+) {
+    EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath;
+    EFI_STATUS                  Status;
+
+    if ((DevicePath == NULL) || (Handle == NULL)) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    do {
+        RemainingDevicePath = DevicePath;
+        // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
+        // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
+        // to point to the remaining part of the device path
+        Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
+        if (!EFI_ERROR (Status)) {
+            // Recursive = FALSE: We do not want to start all the device tree
+            Status = gBS->ConnectController (*Handle, NULL, RemainingDevicePath, FALSE);
+        }
+
+        // We need to check if RemainingDevicePath does not point on the last node. Otherwise, calling
+        // NextDevicePathNode() will return an undetermined Device Path Node
+        if (!IsDevicePathEnd (RemainingDevicePath)) {
+            RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
+        }
+    } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
+
+    if (!EFI_ERROR (Status)) {
+        // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
+        // Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
+        RemainingDevicePath = DevicePath;
+        Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
+        if (!EFI_ERROR (Status)) {
+            Status = gBS->ConnectController (*Handle, NULL, RemainingDevicePath, FALSE);
+            if (EFI_ERROR (Status)) {
+                // If the last node is a Memory Map Device Path just return EFI_SUCCESS.
+                if ((RemainingDevicePath->Type == HARDWARE_DEVICE_PATH) && (RemainingDevicePath->SubType == HW_MEMMAP_DP)) {
+                    Status = EFI_SUCCESS;
+                }
+            }
+        }
+    } else if (IsDevicePathEnd (RemainingDevicePath)) {
+        // Case when the DevicePath contains a MemoryMap Device Path Node and all drivers are connected.
+        // Ensure the Device Path exists
+        RemainingDevicePath = DevicePath;
+        Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
+    }
+
+    return Status;
+}
+
+
+EFI_STATUS
+BdsLoadFilePath (
+    IN  CONST CHAR16        *DeviceFilePath,
+    OUT BDS_FILE            *File
+) {
+    EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
+    EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;
+    EFI_STATUS Status;
+    EFI_HANDLE Handle;
+    UINTN                               NumberDevicePathNode;
+    CHAR16                              *FilePath;
+
+    //Do a sanity check on the Device file path
+    if (DeviceFilePath == NULL) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    //  Convert the Device Path String into Device Path Protocol
+    Status = gBS->LocateProtocol(&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
+    ASSERT_EFI_ERROR(Status);
+    DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath(DeviceFilePath);
+
+    //Do a sanity check on the Device Path
+    if (DevicePath == NULL) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    // Count the number of DevicePath Node
+    NumberDevicePathNode = NumberNodeFromDevicePath(DevicePath);
+    // Extract the FilePath from the Device Path
+    FilePath = BdsExtractFilePathFromDevicePath(DeviceFilePath,NumberDevicePathNode);
+
+    Status = BdsLoadDevicePath(DevicePath,&Handle);
+    if (EFI_ERROR (Status)) {
+        return Status;
+    }
+
+    //If FilePath == NULL then let consider if a MemoryMap Device Path
+    if (FilePath == NULL) {
+        // Check if the Node is a MemoryMap Device Path
+        Status = BdsLoadFileFromMemMap(Handle,DevicePath,File);
+    } else {
+        Status = BdsLoadFileFromSimpleFileSystem(Handle,FilePath,File);
+        if (EFI_ERROR (Status)) {
+            Status = BdsLoadFileFromFirmwareVolume(Handle,FilePath,EFI_FV_FILETYPE_ALL,File);
+        }
+    }
+
+    if (!EFI_ERROR (Status)) {
+        File->DevicePath = DevicePath;
+    }
+
+    return Status;
+}
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemory(
+    IN  BDS_FILE            *File,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+) {
+    if (File == NULL) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    if (File->Type == BDS_FILETYPE_FS) {
+        return BdsCopyRawFileToRuntimeMemoryFS(File->File.Fs.Handle,FileImage,FileSize);
+    } else if (File->Type == BDS_FILETYPE_FV) {
+        return BdsCopyRawFileToRuntimeMemoryFV(&(File->File.Fv),FileImage,FileSize);
+    } else if (File->Type == BDS_FILETYPE_MEM) {
+        return BdsCopyRawFileToRuntimeMemoryMemMap(&(File->File.Mem),FileImage,FileSize);
+    } else {
+        return EFI_INVALID_PARAMETER;
+    }
+}
diff --git a/ArmPkg/Library/BdsLib/BdsFilePathFs.c b/ArmPkg/Library/BdsLib/BdsFilePathFs.c
new file mode 100644 (file)
index 0000000..c928247
--- /dev/null
@@ -0,0 +1,86 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#include "BdsInternal.h"
+
+EFI_STATUS BdsLoadFileFromSimpleFileSystem(
+    IN  EFI_HANDLE Handle,
+    IN  CHAR16                              *FilePath,
+    OUT BDS_FILE            *File
+) {
+    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *FsProtocol;
+    EFI_FILE_PROTOCOL                   *Fs;
+    EFI_STATUS Status;
+    EFI_FILE_PROTOCOL   *FileHandle = NULL;
+
+    if (File == NULL) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    Status = gBS->HandleProtocol(Handle,&gEfiSimpleFileSystemProtocolGuid, (VOID **)&FsProtocol);
+    if (EFI_ERROR(Status)) {
+        return Status;
+    }
+
+    //Try to Open the volume and get root directory
+       Status = FsProtocol->OpenVolume(FsProtocol, &Fs);
+       if (EFI_ERROR(Status)) {
+        return Status;
+    }
+
+    Status = Fs->Open(Fs, &FileHandle, FilePath, EFI_FILE_MODE_READ, 0);
+
+    File->Type = BDS_FILETYPE_FS;
+    File->FilePath = FilePath;
+    File->File.Fs.Handle = FileHandle;
+
+    return Status;
+}
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemoryFS(
+    IN  EFI_FILE_PROTOCOL   *File,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+) {
+    EFI_FILE_INFO   *FileInfo;
+    UINTN           Size;
+    VOID*           Image;
+    EFI_STATUS      Status;
+
+    Size = 0;
+    File->GetInfo(File, &gEfiFileInfoGuid, &Size, NULL);
+    FileInfo = AllocatePool (Size);
+    Status = File->GetInfo(File, &gEfiFileInfoGuid, &Size, FileInfo);
+    if (EFI_ERROR(Status)) {
+        return Status;
+    }
+
+    // Get the file size
+    Size = FileInfo->FileSize;
+    if (FileSize) {
+        *FileSize = Size;
+    }
+    FreePool(FileInfo);
+
+    Image = AllocateRuntimePool(Size);
+    if (Image == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+    Status = File->Read(File, &Size, Image);
+    if (!EFI_ERROR(Status)) {
+        *FileImage = Image;
+    }
+    return Status;
+}
diff --git a/ArmPkg/Library/BdsLib/BdsFilePathFv.c b/ArmPkg/Library/BdsLib/BdsFilePathFv.c
new file mode 100644 (file)
index 0000000..f5b4e57
--- /dev/null
@@ -0,0 +1,136 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#include "BdsInternal.h"
+
+EFI_STATUS BdsLoadFileFromFirmwareVolume(
+    IN  EFI_HANDLE      FvHandle,
+    IN  CHAR16    *FilePath,
+    IN  EFI_FV_FILETYPE FileTypeFilter,
+    OUT BDS_FILE        *File
+) {
+    EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+    VOID                          *Key;    
+    EFI_STATUS                    Status, FileStatus;
+    EFI_GUID                      NameGuid;
+    EFI_FV_FILETYPE               FileType;
+    EFI_FV_FILE_ATTRIBUTES        Attributes;
+    UINTN                         Size;
+    UINTN                         UiStringLen;
+    CHAR16                        *UiSection;
+    UINT32                        Authentication;
+
+    if (File == NULL) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    Status = gBS->HandleProtocol(FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
+    if (EFI_ERROR(Status)) {
+        return Status;
+    }
+
+    // Length of FilePath
+    UiStringLen = StrLen (FilePath);
+
+    // Allocate Key
+    Key = AllocatePool (FvProtocol->KeySize);
+    ASSERT (Key != NULL);
+    ZeroMem (Key, FvProtocol->KeySize);
+
+    do {
+        // Search in all files
+        FileType = FileTypeFilter;
+
+        Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
+        if (!EFI_ERROR (Status)) {
+            UiSection = NULL;
+            FileStatus = FvProtocol->ReadSection (
+                          FvProtocol, 
+                          &NameGuid, 
+                          EFI_SECTION_USER_INTERFACE, 
+                          0,
+                          (VOID **)&UiSection,
+                          &Size,
+                          &Authentication
+                          );
+            if (!EFI_ERROR (FileStatus)) {
+              if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
+                  
+                //
+                // We found a UiString match. 
+                //
+                //*FileGuid = NameGuid;
+                File->Type = BDS_FILETYPE_FV;
+                File->FilePath = FilePath;
+                CopyGuid (&(File->File.Fv.Guid),&NameGuid);
+                File->File.Fv.FvProtocol = FvProtocol;
+                File->File.Fv.FileType = FileType;
+
+                Status = gBS->HandleProtocol(FvHandle,&gEfiDevicePathProtocolGuid, (VOID **)&(File->DevicePath));
+
+                FreePool (Key);
+                FreePool (UiSection);
+                return FileStatus;
+              }
+              FreePool (UiSection);
+            }
+        }
+    } while (!EFI_ERROR (Status));
+
+    FreePool(Key);
+    return Status;
+}
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemoryFV(
+    IN  BDS_FV_FILE         *FvFile,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+) {
+    EFI_STATUS Status = EFI_INVALID_PARAMETER;
+    EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+    EFI_FV_FILETYPE               FileType;
+    EFI_GUID*    NameGuid;
+    EFI_FV_FILE_ATTRIBUTES        Attributes;
+    UINT32                        Authentication;
+
+    FvProtocol = FvFile->FvProtocol;
+    FileType = FvFile->FileType;
+    NameGuid = &(FvFile->Guid);
+
+    if (FileType == EFI_FV_FILETYPE_RAW) {
+        *FileImage = NULL;
+        *FileSize = 0;
+        Status = FvProtocol->ReadFile(
+            FvProtocol,NameGuid,                            // IN
+            FileImage,FileSize,                             // IN OUT
+            &FileType,&Attributes,&Authentication           // OUT
+        );
+        ASSERT_EFI_ERROR(Status);
+
+        // This raw file also contains a header
+        *FileSize = *FileSize - 4;
+        *FileImage = (UINT8*)FileImage + 4;
+    } else if (FileType == EFI_FV_FILETYPE_FREEFORM) {
+        Status = FvProtocol->ReadSection (
+            FvProtocol,NameGuid,EFI_SECTION_RAW,0,          // IN
+            FileImage,FileSize,                             // IN OUT
+            &Authentication                                 // OUT
+        );
+        ASSERT_EFI_ERROR(Status);
+    } else {
+        ASSERT(0); //Maybe support application as well ???
+    }
+
+    return Status;
+}
diff --git a/ArmPkg/Library/BdsLib/BdsFilePathMem.c b/ArmPkg/Library/BdsLib/BdsFilePathMem.c
new file mode 100644 (file)
index 0000000..dddaa3d
--- /dev/null
@@ -0,0 +1,73 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#include "BdsInternal.h"
+
+
+EFI_STATUS BdsLoadFileFromMemMap (
+    IN  EFI_HANDLE                  Handle,
+    IN  EFI_DEVICE_PATH_PROTOCOL    *DevicePath,
+    OUT BDS_FILE                    *File
+) {
+    EFI_DEVICE_PATH_PROTOCOL            *LastDevicePath;
+
+    if ((File == NULL) || (DevicePath == NULL) || (IsDevicePathEnd (DevicePath))) {
+        return EFI_INVALID_PARAMETER;
+    }
+
+    // Check if the last node of the device Path is a Memory Map Device Node
+    LastDevicePath = DevicePath;
+    DevicePath = NextDevicePathNode(DevicePath);
+    while (!IsDevicePathEnd (DevicePath)) {
+        LastDevicePath = DevicePath;
+        DevicePath = NextDevicePathNode(DevicePath);
+    }
+    if ((LastDevicePath->Type != HARDWARE_DEVICE_PATH) || (LastDevicePath->SubType != HW_MEMMAP_DP)) {
+        return EFI_UNSUPPORTED;
+    }
+
+    File->Type = BDS_FILETYPE_MEM;
+    File->File.Mem.MemoryType = ((MEMMAP_DEVICE_PATH*)LastDevicePath)->MemoryType;
+    File->File.Mem.StartingAddress = ((MEMMAP_DEVICE_PATH*)LastDevicePath)->StartingAddress;
+    File->File.Mem.EndingAddress = ((MEMMAP_DEVICE_PATH*)LastDevicePath)->EndingAddress;
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemoryMemMap(
+    IN  BDS_MEM_FILE        *MemFile,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+) {
+    UINTN           Size;
+    VOID*           Image;
+
+    Size = MemFile->EndingAddress - MemFile->StartingAddress;
+
+    if ((Size == 0) || (FileImage == NULL)) {
+        return EFI_INVALID_PARAMETER;
+    }
+    if (FileSize != NULL) {
+        *FileSize = Size;
+    }
+
+    Image = AllocateRuntimePool(Size);
+    if (Image == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+    }
+
+    *FileImage = CopyMem(Image,(CONST VOID*)(UINTN)MemFile->StartingAddress,Size);
+
+    return EFI_SUCCESS;
+}
diff --git a/ArmPkg/Library/BdsLib/BdsHelper.c b/ArmPkg/Library/BdsLib/BdsHelper.c
new file mode 100644 (file)
index 0000000..896ae73
--- /dev/null
@@ -0,0 +1,183 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include "BdsInternal.h"\r
+\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/HobLib.h>\r
+\r
+EFI_STATUS\r
+ShutdownUefiBootServices( VOID )\r
+{\r
+  EFI_STATUS              Status;\r
+  UINTN                   MemoryMapSize;\r
+  EFI_MEMORY_DESCRIPTOR   *MemoryMap;\r
+  UINTN                   MapKey;\r
+  UINTN                   DescriptorSize;\r
+  UINT32                  DescriptorVersion;\r
+  UINTN                   Pages;\r
+\r
+  MemoryMap = NULL;\r
+  MemoryMapSize = 0;\r
+  do {\r
+    Status = gBS->GetMemoryMap (\r
+                    &MemoryMapSize,\r
+                    MemoryMap,\r
+                    &MapKey,\r
+                    &DescriptorSize,\r
+                    &DescriptorVersion\r
+                    );\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+      Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;\r
+      MemoryMap = AllocatePages (Pages);\r
+\r
+      //\r
+      // Get System MemoryMap\r
+      //\r
+      Status = gBS->GetMemoryMap (\r
+                      &MemoryMapSize,\r
+                      MemoryMap,\r
+                      &MapKey,\r
+                      &DescriptorSize,\r
+                      &DescriptorVersion\r
+                      );\r
+      // Don't do anything between the GetMemoryMap() and ExitBootServices()\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = gBS->ExitBootServices (gImageHandle, MapKey);\r
+        if (EFI_ERROR (Status)) {\r
+          FreePages (MemoryMap, Pages);\r
+          MemoryMap = NULL;\r
+          MemoryMapSize = 0;\r
+        }\r
+      }\r
+    }\r
+  } while (EFI_ERROR (Status));\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+BdsConnectAllDrivers( VOID ) {\r
+    UINTN                     HandleCount, Index;\r
+    EFI_HANDLE                *HandleBuffer;\r
+    EFI_STATUS                Status;\r
+\r
+    do {\r
+        // Locate all the driver handles\r
+        Status = gBS->LocateHandleBuffer (\r
+                    AllHandles,\r
+                    NULL,\r
+                    NULL,\r
+                    &HandleCount,\r
+                    &HandleBuffer\r
+                    );\r
+        if (EFI_ERROR (Status)) {\r
+            break;\r
+        }\r
+\r
+        // Connect every handles\r
+        for (Index = 0; Index < HandleCount; Index++) {\r
+            gBS->ConnectController(HandleBuffer[Index], NULL, NULL, TRUE);\r
+        }\r
+\r
+        if (HandleBuffer != NULL) {\r
+            FreePool (HandleBuffer);\r
+        }\r
+        \r
+        // Check if new handles have been created after the start of the previous handles\r
+        Status = gDS->Dispatch ();\r
+    } while (!EFI_ERROR(Status));\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+STATIC EFI_STATUS InsertSystemMemoryResources(LIST_ENTRY *ResourceList, EFI_HOB_RESOURCE_DESCRIPTOR *ResHob) {\r
+    BDS_SYSTEM_MEMORY_RESOURCE  NewResource;\r
+    LIST_ENTRY                  *Link;\r
+    BDS_SYSTEM_MEMORY_RESOURCE  *Resource;\r
+\r
+    //DEBUG ((EFI_D_ERROR, "** InsertSystemMemoryResources(0x%X,0x%X)\n",(UINT32)ResHob->PhysicalStart,(UINT32)ResHob->ResourceLength));\r
+\r
+    if (IsListEmpty (ResourceList)) {\r
+        ZeroMem(&NewResource,sizeof(BDS_SYSTEM_MEMORY_RESOURCE));\r
+        NewResource.PhysicalStart = ResHob->PhysicalStart;\r
+        NewResource.ResourceLength = ResHob->ResourceLength;\r
+        InsertTailList (ResourceList, &NewResource.Link);\r
+        return EFI_SUCCESS;\r
+    }\r
+\r
+    //for (Link = GetFirstNode (ResourceList); !IsNull (ResourceList,Link); Link = GetNextNode (ResourceList,Link)) {\r
+    Link = ResourceList->ForwardLink;\r
+    while (Link != NULL && Link != ResourceList) {\r
+        Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;\r
+        //DEBUG ((EFI_D_ERROR, "   - (0x%X,0x%X)\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->ResourceLength));\r
+\r
+        // Sanity Check. The resources should not overlapped.\r
+        ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));\r
+        ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength >= Resource->PhysicalStart) &&\r
+            ((ResHob->PhysicalStart + ResHob->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength))));\r
+\r
+        // The new resource is attached after this resource descriptor\r
+        if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {\r
+            Resource->ResourceLength =  Resource->ResourceLength + ResHob->ResourceLength;\r
+            //DEBUG ((EFI_D_ERROR, "** Attached new Length:0x%X\n",(UINT32)Resource->ResourceLength));\r
+            return EFI_SUCCESS;\r
+        }\r
+        // The new resource is attached before this resource descriptor\r
+        else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {\r
+            Resource->PhysicalStart = ResHob->PhysicalStart;\r
+            Resource->ResourceLength =  Resource->ResourceLength + ResHob->ResourceLength;\r
+            //DEBUG ((EFI_D_ERROR, "** Attached2 new Length:0x%X\n",(UINT32)Resource->ResourceLength));\r
+            return EFI_SUCCESS;\r
+        }\r
+        Link = Link->ForwardLink;\r
+    }\r
+\r
+    // None of the Resource of the list is attached to this ResHob. Create a new entry for it\r
+    ZeroMem(&NewResource,sizeof(BDS_SYSTEM_MEMORY_RESOURCE));\r
+    NewResource.PhysicalStart = ResHob->PhysicalStart;\r
+    NewResource.ResourceLength = ResHob->ResourceLength;\r
+    InsertTailList (ResourceList, &NewResource.Link);\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS GetSystemMemoryResources(LIST_ENTRY *ResourceList) {\r
+    EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;\r
+\r
+    InitializeListHead (ResourceList);\r
+    \r
+    // Find the first System Memory Resource Descriptor\r
+    ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);\r
+    while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {\r
+        ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); \r
+    }\r
+\r
+    // Did not find any\r
+    if (ResHob == NULL) {\r
+        return EFI_NOT_FOUND;\r
+    } else {\r
+        InsertSystemMemoryResources(ResourceList, ResHob);\r
+    }\r
+\r
+    ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); \r
+    while (ResHob != NULL) {\r
+        if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {\r
+            InsertSystemMemoryResources(ResourceList, ResHob);\r
+        }\r
+        ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); \r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+}\r
diff --git a/ArmPkg/Library/BdsLib/BdsInternal.h b/ArmPkg/Library/BdsLib/BdsInternal.h
new file mode 100644 (file)
index 0000000..07f722e
--- /dev/null
@@ -0,0 +1,136 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#ifndef __BDS_INTERNAL_H__
+#define __BDS_INTERNAL_H__
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BdsUnixLib.h>
+
+#include <Guid/FileInfo.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/FirmwareVolume2.h>
+
+
+typedef enum { BDS_FILETYPE_MEM, BDS_FILETYPE_FS, BDS_FILETYPE_FV } BDS_FILE_TYPE;
+
+typedef struct {
+    UINT32                  MemoryType;
+    EFI_PHYSICAL_ADDRESS    StartingAddress;
+    EFI_PHYSICAL_ADDRESS    EndingAddress;
+} BDS_MEM_FILE;
+
+typedef struct {
+    EFI_FILE_PROTOCOL   *Handle;
+} BDS_FS_FILE;
+
+typedef struct {
+    EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+    EFI_FV_FILETYPE               FileType;
+    EFI_GUID            Guid;
+} BDS_FV_FILE;
+
+typedef struct _BDS_FILE {
+    CHAR16* FilePath;
+    EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
+    BDS_FILE_TYPE Type;
+    union {
+        BDS_MEM_FILE    Mem;
+        BDS_FS_FILE Fs;
+        BDS_FV_FILE Fv;
+    } File;
+} BDS_FILE;
+
+typedef struct _BDS_SYSTEM_MEMORY_RESOURCE {
+    LIST_ENTRY                  Link; // This attribute must be the first entry of this structure (to avoid pointer computation)
+    EFI_PHYSICAL_ADDRESS        PhysicalStart;
+    UINT64                      ResourceLength;
+} BDS_SYSTEM_MEMORY_RESOURCE;
+
+
+// BdsHelper.c
+EFI_STATUS
+ShutdownUefiBootServices( VOID );
+
+EFI_STATUS
+GetSystemMemoryResources (LIST_ENTRY *ResourceList);
+
+// BdsFilePath.c
+EFI_STATUS BdsLoadDevicePath(
+    IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,
+    OUT EFI_HANDLE                *Handle
+);
+
+EFI_STATUS BdsLoadFilePath(
+    IN  CONST CHAR16        *DeviceFilePath,
+    OUT BDS_FILE            *File
+);
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemory(
+    IN  BDS_FILE            *File,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+);
+
+// BdsFilePathFs.c
+EFI_STATUS BdsLoadFileFromSimpleFileSystem(
+    IN  EFI_HANDLE Handle,
+    IN  CHAR16                              *FilePath,
+    OUT BDS_FILE            *File
+);
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemoryFS(
+    IN  EFI_FILE_PROTOCOL   *File,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+);
+
+// BdsFilePathFv.c
+EFI_STATUS BdsLoadFileFromFirmwareVolume(
+    IN  EFI_HANDLE          FvHandle,
+    IN  CHAR16                              *FilePath,
+    IN  EFI_FV_FILETYPE     FileTypeFilter,
+    OUT BDS_FILE            *File
+);
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemoryFV(
+    IN  BDS_FV_FILE         *FvFile,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+);
+
+// BdsFilePathMem.c
+EFI_STATUS BdsLoadFileFromMemMap (
+    IN  EFI_HANDLE                  Handle,
+    IN  EFI_DEVICE_PATH_PROTOCOL    *DevicePath,
+    OUT BDS_FILE                    *File
+);
+
+EFI_STATUS BdsCopyRawFileToRuntimeMemoryMemMap(
+    IN  BDS_MEM_FILE        *MemFile,
+    OUT VOID                **FileImage,
+    OUT UINTN               *FileSize
+);
+
+#endif
diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf
new file mode 100644 (file)
index 0000000..223f47b
--- /dev/null
@@ -0,0 +1,63 @@
+#/* @file
+#  Copyright (c) 2011, ARM Limited. All rights reserved.
+#  
+#  This program and the accompanying materials                          
+#  are licensed and made available under the terms and conditions of the BSD License         
+#  which accompanies this distribution.  The full text of the license may be found at        
+#  http://opensource.org/licenses/bsd-license.php                                            
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+#
+#*/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BdsLib
+  FILE_GUID                      = ddbf73a0-bb25-11df-8e4e-0002a5d5c51b
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BdsLib
+
+[Sources.common]
+  BdsFilePath.c
+  BdsFilePathFs.c
+  BdsFilePathFv.c
+  BdsFilePathMem.c
+  BdsLinuxLoader.c
+  BdsAppLoader.c
+  BdsHelper.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+  DevicePathLib
+  BaseLib
+  HobLib
+  DebugLib
+  UefiDriverEntryPoint
+  DxeServicesTableLib
+  ArmLib
+
+[Guids]
+  gEfiFileInfoGuid
+
+[Protocols]
+  gEfiBdsArchProtocolGuid                       
+  gEfiDevicePathProtocolGuid
+  gEfiDevicePathFromTextProtocolGuid
+  gEfiSimpleFileSystemProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+    
+[FeaturePcd]  
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdArmMachineType
+  
+[Pcd]
+  
+[Depex]
+  TRUE
diff --git a/ArmPkg/Library/BdsLib/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/BdsLinuxLoader.c
new file mode 100644 (file)
index 0000000..6943593
--- /dev/null
@@ -0,0 +1,337 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#include "BdsInternal.h"
+#include "BdsLinuxLoader.h"
+
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+#include <Library/HobLib.h>
+
+STATIC
+EFI_STATUS
+GetARMLinuxMachineType (
+    IN  BOOLEAN FdtSupported,
+    OUT UINT32  *MachineType
+) {
+  if (FdtSupported)
+  {
+    // FDT requires that the machine type is set to the maximum 32-bit number.
+    *MachineType = 0xFFFFFFFF;
+  }
+  else
+  {
+    // Non-FDT requires a specific machine type.
+    // This OS Boot loader supports just one machine type,
+    // but that could change in the future.
+    *MachineType = PcdGet32(PcdArmMachineType);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+SetupCoreTag( IN UINT32 PageSize )
+{
+  Params->header.size = tag_size(atag_core);
+  Params->header.type = ATAG_CORE;
+
+  Params->body.core_tag.flags    = 1;            /* ensure read-only */
+  Params->body.core_tag.pagesize = PageSize;     /* systems PageSize (4k) */
+  Params->body.core_tag.rootdev  = 0;            /* zero root device (typically overridden from kernel command line )*/
+
+  Params = next_tag_address(Params);             /* move pointer to next tag */
+}
+
+STATIC
+VOID
+SetupMemTag( IN UINTN StartAddress, IN UINT32 Size )
+{
+  Params->header.size = tag_size(atag_mem);
+  Params->header.type = ATAG_MEM;
+
+  Params->body.mem_tag.start = StartAddress;    /* Start of memory chunk for AtagMem */
+  Params->body.mem_tag.size  = Size;             /* Size of memory chunk for AtagMem */
+
+  Params = next_tag_address(Params);             /* move pointer to next tag */
+}
+
+STATIC
+VOID
+SetupCmdlineTag( IN CONST CHAR8 *CmdLine )
+{
+  UINT32 LineLength;
+
+  // Increment the line length by 1 to account for the null string terminator character
+  LineLength = AsciiStrLen(CmdLine) + 1;
+
+  /* Check for NULL strings.
+   * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.
+   * Remember, you have at least one null string terminator character.
+   */
+  if( LineLength > 1 )
+  {
+    Params->header.size = ((UINT32)sizeof(struct atag_header) + LineLength + (UINT32)3) >> 2;
+    Params->header.type = ATAG_CMDLINE;
+
+    /* place CommandLine into tag */
+    AsciiStrCpy(Params->body.cmdline_tag.cmdline, CmdLine);
+
+    Params = next_tag_address(Params);             /* move pointer to next tag */
+  }
+}
+
+STATIC
+VOID
+SetupEndTag( VOID )
+{
+  // Empty tag ends list; this has zero length and no body
+  Params->header.type = ATAG_NONE;
+  Params->header.size = 0;
+
+  /* We can not calculate the next address by using the standard macro:
+   * Params = next_tag_address(Params);
+   * because it relies on the header.size, which here it is 0 (zero).
+   * The easiest way is to add the sizeof(Params->header).
+   */
+  Params = (struct atag *)((UINT32)Params + sizeof(Params->header));
+}
+
+STATIC
+EFI_STATUS
+PrepareAtagList(
+    IN OUT struct atag      **AtagStartAddress,
+    IN     CONST CHAR8*     CommandLineString,
+    OUT    UINT32           *AtagSize
+) {
+  LIST_ENTRY    *ResourceLink;
+  LIST_ENTRY ResourceList;
+  BDS_SYSTEM_MEMORY_RESOURCE  *Resource;
+
+  // If no address supplied then this function will decide where to put it
+  if( *AtagStartAddress == 0 )
+  {
+    /* WARNING: At the time of writing (2010-July-30) the linux kernel expects
+     * the atag list it in the first 1MB of memory and preferably at address 0x100.
+     * This has a very high risk of overwriting UEFI code, but as
+     * the linux kernel does not expect any runtime services from uefi
+     * and there is no afterlife section following the linux kernel termination,
+     * it does not matter if we stamp over that memory area.
+     *
+     * The proposed workaround is to create the atag list somewhere in boot services memory
+     * and then transfer it to address 0x100 (or to runtime services memory) immediately
+     * before starting the kernel.
+     * An additional benefit of this is that when we copy the ATAG list to it's final place,
+     * we can trim down the memory allocation size. Before we create the list we don't know
+     * how much space it is going to take, so we are over-allocating space.
+     */
+    *AtagStartAddress = (struct atag *) AllocatePool(ATAG_MAX_SIZE);
+  }
+
+  // Ensure the pointer is not NULL.
+  ASSERT( *AtagStartAddress != (struct atag *)NULL );
+
+  // Ready to setup the atag list
+  Params = *AtagStartAddress;
+
+  // Standard core tag 4k PageSize
+  SetupCoreTag( (UINT32)SIZE_4KB );
+
+  // Physical memory setup
+  GetSystemMemoryResources(&ResourceList);
+  ResourceLink = ResourceList.ForwardLink;
+  while (ResourceLink != NULL && ResourceLink != &ResourceList) {
+    Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceList.ForwardLink;
+    SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength );
+    ResourceLink = ResourceLink->ForwardLink;
+  }
+
+  // CommandLine setting root device
+  SetupCmdlineTag( CommandLineString );
+
+  // end of tags
+  SetupEndTag();
+
+  // Calculate atag list size
+  *AtagSize = (UINT32)Params - (UINT32)*AtagStartAddress + 1;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+PreparePlatformHardware( VOID )
+{
+  //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.
+
+  // clean, invalidate, disable data cache
+  ArmCleanInvalidateDataCache();
+  ArmDisableDataCache();
+
+  // Invalidate and disable the Instruction cache
+  ArmInvalidateInstructionCache ();
+  ArmDisableInstructionCache ();
+
+  // turn off MMU
+  ArmInvalidateTlb();
+  ArmDisableMmu();
+
+  return EFI_SUCCESS;
+}
+
+/*************************************************
+ * R0, R1, R2 correspond to registers R0, R1, R2
+ *************************************************/
+//STATIC
+EFI_STATUS
+StartLinuxKernel( IN VOID* KernelAddress, IN UINTN R0, IN UINTN R1, IN UINTN R2 )
+{
+  VOID     (*Kernel)(UINT32 Zero, UINT32 Arch, UINTN AtagListParams);
+
+  // set the kernel address
+  Kernel = (VOID (*)(UINT32, UINT32, UINTN)) KernelAddress;
+
+  // Outside BootServices, so can't use Print();
+  DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));
+
+  // jump to kernel with register set
+  Kernel( R0, R1, R2 );
+
+  // Kernel should never exit
+  // After Life services are not provided
+  ASSERT( FALSE );
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS BdsBootLinux(
+    IN  CONST CHAR16* LinuxKernel,
+    IN  CONST CHAR8*  ATag,
+    IN  CONST CHAR16* Fdt
+) {
+    BDS_FILE   LinuxKernelFile;
+    BDS_FILE   FdtFile;
+    EFI_STATUS          Status;
+    VOID*               LinuxImage;
+
+    UINT32              KernelParamsSize;
+    VOID*               KernelParamsAddress = NULL;
+    UINTN               KernelParamsNewAddress;
+    UINTN               *AtagAddress;
+    UINT32              MachineType;
+    BOOLEAN             FdtSupported = FALSE;
+    EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
+
+    // Load the Linux kernel from a device path
+    Status = BdsLoadFilePath(LinuxKernel, &LinuxKernelFile);
+    if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_ERROR, "ERROR: Do not find Linux kernel %s\n",LinuxKernel));
+        return Status;
+    }
+
+    // Copy the Linux Kernel from the raw file to Runtime memory
+    Status = BdsCopyRawFileToRuntimeMemory(&LinuxKernelFile,&LinuxImage,NULL);
+    if (EFI_ERROR(Status)) {
+        goto Exit;
+    }
+
+    // Load the FDT binary from a device path
+    Status = BdsLoadFilePath(Fdt, &FdtFile);
+    if (!EFI_ERROR(Status)) {
+        // Copy the FDT binary from the raw file to Runtime memory
+        Status = BdsCopyRawFileToRuntimeMemory(&FdtFile,&KernelParamsAddress,&KernelParamsSize);
+        if (EFI_ERROR(Status)) {
+            goto Exit;
+        } else {
+            FdtSupported = TRUE;
+        }
+    }
+
+    /**********************************************************
+    * Setup the platform type
+    **********************************************************/
+    Status = GetARMLinuxMachineType(FdtSupported, &MachineType);
+    if(EFI_ERROR(Status))
+    {
+        Print(L"ERROR  : Can not prepare ARM Linux machine type. Status=0x%X\n", Status);
+        goto Exit;
+    }
+
+    if (!FdtSupported) {
+        /**********************************************************
+         * Setup the ATAG list
+         **********************************************************/
+        // By setting address=0 we leave the memory allocation to the function
+        AtagAddress = 0;
+        Status = PrepareAtagList( (struct atag **)&AtagAddress, ATag, &KernelParamsSize );
+        KernelParamsAddress = (VOID*)AtagAddress;
+        if(EFI_ERROR(Status))
+        {
+            Print(L"ERROR  : Can not prepare ATAG list. Status=0x%X\n", Status);
+            goto Exit;
+        }
+    }
+
+    /**********************************************************
+    * Switch off interrupts, caches, mmu, etc
+    **********************************************************/
+    Status = PreparePlatformHardware();
+    if(EFI_ERROR(Status))
+    {
+        Print(L"ERROR  : Can not prepare platform hardware. Status=0x%X\n", Status);
+        goto Exit;
+    }
+
+    // Initialize the ATag destination
+    KernelParamsNewAddress = 0x100;
+
+    // Update the ATag destination by finding the start address of the first System Memory Resource Descriptor Hob
+    ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+    while (ResHob != NULL) {
+        if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+            KernelParamsNewAddress = (UINTN)ResHob->PhysicalStart + 0x100;
+            break;
+        }
+        ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); 
+    }
+
+    // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on
+    // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.
+    Status = ShutdownUefiBootServices();
+    if(EFI_ERROR(Status))
+    {
+        Print(L"ERROR  : Can not shutdown UEFI boot services. Status=0x%X\n", Status);
+        goto Exit;
+    }
+
+    // Move the kernel parameters to any address inside the first 1MB.
+    // This is necessary because the ARM Linux kernel requires
+    // the FTD / ATAG List to reside entirely inside the first 1MB of
+    // physical memory.
+    CopyMem((VOID*)KernelParamsNewAddress, KernelParamsAddress, KernelParamsSize);
+
+    //**********************************************************
+    // * Start the Linux Kernel
+    // **********************************************************
+    // Lift off ...
+    Status = StartLinuxKernel(LinuxImage, (UINTN)0, (UINTN)MachineType, KernelParamsNewAddress );
+
+    // Only be here if we fail to start Linux
+    DEBUG((EFI_D_ERROR, "ERROR  : Can not start the kernel. Status=0x%X\n", Status));
+
+Exit:
+    // Free Runtimee Memory (kernel and FDT)
+    return Status;
+}
diff --git a/ArmPkg/Library/BdsLib/BdsLinuxLoader.h b/ArmPkg/Library/BdsLib/BdsLinuxLoader.h
new file mode 100644 (file)
index 0000000..2869f65
--- /dev/null
@@ -0,0 +1,165 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*  
+*  This program and the accompanying materials                          
+*  are licensed and made available under the terms and conditions of the BSD License         
+*  which accompanies this distribution.  The full text of the license may be found at        
+*  http://opensource.org/licenses/bsd-license.php                                            
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+*
+**/
+
+#ifndef __BDSLINUXLOADER_H
+#define __BDSLINUXLOADER_H
+
+#define ATAG_MAX_SIZE       0x4000
+//PcdKernelParamsMaxMemorySize
+
+/* ATAG : list of possible tags */
+#define ATAG_NONE            0x00000000
+#define ATAG_CORE            0x54410001
+#define ATAG_MEM             0x54410002
+#define ATAG_VIDEOTEXT       0x54410003
+#define ATAG_RAMDISK         0x54410004
+#define ATAG_INITRD2         0x54420005
+#define ATAG_SERIAL          0x54410006
+#define ATAG_REVISION        0x54410007
+#define ATAG_VIDEOLFB        0x54410008
+#define ATAG_CMDLINE         0x54410009
+#define ATAG_ARM_MP_CORE     0x5441000A
+
+// Some system addresses
+// These should probably come from the platform header file or from pcd values
+#define DRAM_BASE            0x10000000
+#define ZIMAGE_LOAD_ADDRESS  (DRAM_BASE + 0x8000)
+#define INITRD_LOAD_ADDRESS  (DRAM_BASE + 0x800000)
+
+#define SIZE_1B              0x00000001
+#define SIZE_2B              0x00000002
+#define SIZE_4B              0x00000004
+#define SIZE_8B              0x00000008
+#define SIZE_16B             0x00000010
+#define SIZE_32B             0x00000020
+#define SIZE_64B             0x00000040
+#define SIZE_128B            0x00000080
+#define SIZE_256B            0x00000100
+#define SIZE_512B            0x00000200
+#define SIZE_1KB             0x00000400
+#define SIZE_2KB             0x00000800
+#define SIZE_4KB             0x00001000
+#define SIZE_8KB             0x00002000
+#define SIZE_16KB            0x00004000
+#define SIZE_32KB            0x00008000
+#define SIZE_64KB            0x00010000
+#define SIZE_128KB           0x00020000
+#define SIZE_256KB           0x00040000
+#define SIZE_512KB           0x00080000
+#define SIZE_1MB             0x00100000
+#define SIZE_2MB             0x00200000
+#define SIZE_4MB             0x00400000
+#define SIZE_8MB             0x00800000
+#define SIZE_16MB            0x01000000
+#define SIZE_32MB            0x02000000
+#define SIZE_64MB            0x04000000
+#define SIZE_100MB           0x06400000
+#define SIZE_128MB           0x08000000
+#define SIZE_256MB           0x10000000
+#define SIZE_512MB           0x20000000
+#define SIZE_1GB             0x40000000
+#define SIZE_2GB             0x80000000
+
+/* structures for each atag */
+struct atag_header {
+  UINT32  size; /* length of tag in words including this header */
+  UINT32  type;  /* tag type */
+};
+
+struct atag_core {
+  UINT32  flags;
+  UINT32  pagesize;
+  UINT32  rootdev;
+};
+
+struct atag_mem {
+  UINT32  size;
+  UINTN  start;
+};
+
+struct atag_videotext {
+  UINT8   x;
+  UINT8   y;
+  UINT16  video_page;
+  UINT8   video_mode;
+  UINT8   video_cols;
+  UINT16  video_ega_bx;
+  UINT8   video_lines;
+  UINT8   video_isvga;
+  UINT16  video_points;
+};
+
+struct atag_ramdisk {
+  UINT32  flags;
+  UINT32  size;
+  UINTN  start;
+};
+
+struct atag_initrd2 {
+  UINT32  start;
+  UINT32  size;
+};
+
+struct atag_serialnr {
+  UINT32  low;
+  UINT32  high;
+};
+
+struct atag_revision {
+  UINT32  rev;
+};
+
+struct atag_videolfb {
+  UINT16  lfb_width;
+  UINT16  lfb_height;
+  UINT16  lfb_depth;
+  UINT16  lfb_linelength;
+  UINT32  lfb_base;
+  UINT32  lfb_size;
+  UINT8   red_size;
+  UINT8   red_pos;
+  UINT8   green_size;
+  UINT8   green_pos;
+  UINT8   blue_size;
+  UINT8   blue_pos;
+  UINT8   rsvd_size;
+  UINT8   rsvd_pos;
+};
+
+struct atag_cmdline {
+  CHAR8   cmdline[1];
+};
+
+struct atag {
+  struct atag_header header;
+  union {
+    struct atag_core         core_tag;
+    struct atag_mem          mem_tag;
+    struct atag_videotext    videotext_tag;
+    struct atag_ramdisk      ramdisk_tag;
+    struct atag_initrd2      initrd2_tag;
+    struct atag_serialnr     serialnr_tag;
+    struct atag_revision     revision_tag;
+    struct atag_videolfb     videolfb_tag;
+    struct atag_cmdline      cmdline_tag;
+  } body;
+};
+
+#define next_tag_address(t)     ((struct atag *)((UINT32)(t) + (((t)->header.size) << 2) ))
+#define tag_size(type)  ((UINT32)((sizeof(struct atag_header) + sizeof(struct type)) >> 2))
+
+STATIC struct atag *Params; /* used to point at the current tag */
+
+#endif
+
index 64d0a33c267dc32215ffd0a6c9d094971e42bcee..101ec677e8741a2d56a7e33178a6c55b93725b35 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__ashldi3)
-  INTERWORK_FUNC(__ashldi3)\r
+       GCC_ASM_EXPORT(__ashldi3)
        
 ASM_PFX(__ashldi3):
        cmp     r2, #31
index 3cb0e68f62f339aa748aa2ba675cf74d808f6188..775e288856cf9d1f4b94ff839fe249c5677ca9c4 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__ashrdi3)
-  INTERWORK_FUNC(__ashrdi3)\r
+       GCC_ASM_EXPORT(__ashrdi3)
 
 ASM_PFX(__ashrdi3):
        cmp     r2, #31
index 2f9dcd42973b2e300090c5615fa18d7efb06624a..9fb6f2b3d9a56eca50ad2725224bba2ed9bbe475 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__clzsi2)
-  INTERWORK_FUNC(__clzsi2)\r
+       GCC_ASM_EXPORT(__clzsi2)
 
 ASM_PFX(__clzsi2):
        @ frame_needed = 1, uses_anonymous_args = 0
index b776ef43e1e2de75b01c6de562a220bf333f2f1a..287ecd3ad74ca247159139ec3cb642816f4663a0 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__ctzsi2)
-  INTERWORK_FUNC(__ctzsi2)\r
+       GCC_ASM_EXPORT(__ctzsi2)
        
 ASM_PFX(__ctzsi2):
        uxth    r3, r0
index c6a889a8b45187083f9c101e2d69f0ffb5842557..d5f05f7eaff9f858ebbc92fbc387171cb433b072 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__divdi3)
-  INTERWORK_FUNC(__divdi3)\r
+       GCC_ASM_EXPORT(__divdi3)
        
 ASM_PFX(__divdi3):
        @ args = 0, pretend = 0, frame = 0
index 3d9b78c6b12f0d665dc2ec13a230ac68b1aa8338..d1a7f0874764a648ba2f5490c688f12e260dd3e4 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__divsi3)
-  INTERWORK_FUNC(__divsi3)\r
+       GCC_ASM_EXPORT(__divsi3)
        
 ASM_PFX(__divsi3):
        eor     r3, r0, r0, asr #31
index f8cd1aa9e273b3c3b01d6a99c31bc23244e73c31..97f9c6ca7c081594485bba86140a6aca8bb7a503 100755 (executable)
@@ -15,8 +15,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__aeabi_ldivmod)
-  INTERWORK_FUNC(__aeabi_ldivmod)\r
+       GCC_ASM_EXPORT(__aeabi_ldivmod)
 
 //
 // A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}}, 
index 8d8c98b602203dc074e12f96d5c3d2dcec725c3b..5800ae12a1189c755ff25d5cb052f2916d9e8131 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__lshrdi3)
-  INTERWORK_FUNC(__lshrdi3)\r
+       GCC_ASM_EXPORT(__lshrdi3)
        
 ASM_PFX(__lshrdi3):
        cmp     r2, #31
index ae2059894331da6f158a3f35864a787b1694d72b..09c0e7a1c04ae87914b1e5e58b54d774f412a3c3 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(memcpy)
-  INTERWORK_FUNC(memcpy)\r
+       GCC_ASM_EXPORT(memcpy)
 
 ASM_PFX(memcpy):
        stmfd   sp!, {r7, lr}
index 040bbf1fdc888fa9d5b07694213fdeadd3b88df3..73cb1b2af387fd6e999185555f2837759d22c2dd 100644 (file)
@@ -15,8 +15,7 @@
 
   .text
        .align 2
-       .globl ASM_PFX(memset)
-  INTERWORK_FUNC(memset)\r
+       GCC_ASM_EXPORT (memset)
 \r
 ASM_PFX(memset):\r
        @ args = 0, pretend = 0, frame = 0
index c7eb4b5f0e93306f295e32c6f485456be0483258..4b86b83f0022f1ea8038c434f12b976fff1a0680 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__moddi3)
-  INTERWORK_FUNC(__moddi3)\r
+       GCC_ASM_EXPORT(__moddi3)
 
 ASM_PFX(__moddi3):
        stmfd   sp!, {r4, r5, r7, lr}
index 93ba234ccbdc743cd61f91013b97d5f59c68b3b5..039688f44cc09b7fd0410f0fd9a59a4f0932e9dd 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__modsi3)
-  INTERWORK_FUNC(__modsi3)\r
+       GCC_ASM_EXPORT(__modsi3)
 
 ASM_PFX(__modsi3):
        stmfd   sp!, {r4, r5, r7, lr}
index 5c9aeef4ab3aa2d1b9121fc73fe2311d19c3042e..919d6374e1c0c0ca871bb66c8b97c69d44ab95fa 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__muldi3)
-       INTERWORK_FUNC(__muldi3)\r
+       GCC_ASM_EXPORT(__muldi3)
 
 ASM_PFX(__muldi3):
        stmfd   sp!, {r4, r5, r6, r7, lr}
index 68cc974fd956e3430022d8c0e41d255ccddd9297..7938856a9b7a5b83ffd8cc1b0a434a4f267fa620 100755 (executable)
@@ -15,8 +15,7 @@
 
        .text\r
        .align 2\r
-       .globl ASM_PFX(__aeabi_ulcmp)\r
-            INTERWORK_FUNC(__aeabi_ulcmp)\r
+       GCC_ASM_EXPORT(__aeabi_ulcmp)\r
 \r
 ASM_PFX(__aeabi_ulcmp):\r
        stmfd   sp!, {r4, r5, r8}\r
index 8c38a7af47512955f1ec58f2aaafcf23c01a8eb7..97ebf79351baac9f3c9a44e6201c14cf2ad057b1 100644 (file)
@@ -16,8 +16,7 @@
 .text
 .p2align 2
 
-.globl ASM_PFX(__switch16)
-INTERWORK_FUNC(__switch16)\r
+GCC_ASM_EXPORT(__switch16)
 
 ASM_PFX(__switch16):
     ldrh      ip, [lr, #-1]
index d9bf800fd76f0945638eaef6a8d962fc9419bc28..e0fd100aa590e1840bad025af19c7fa1c8da92aa 100644 (file)
@@ -16,8 +16,7 @@
 .text
 .p2align 2
 
-.globl ASM_PFX(__switch32)
-INTERWORK_FUNC(__switch32)
+GCC_ASM_EXPORT(__switch32)
 
 ASM_PFX(__switch32):    
     ldr     ip, [lr, #-1]
index 1fbd48aa35c8bb8acbf35395c039fa56d1a23b3c..ea3340c9a5979c16991d99172858e58a1d1e0855 100644 (file)
@@ -16,9 +16,7 @@
 .text
 .p2align 2
 
-.globl ASM_PFX(__switch8)
-INTERWORK_FUNC(__switch8)
-
+GCC_ASM_EXPORT(__switch8)
 
 ASM_PFX(__switch8):
     ldrb      ip, [lr, #-1]
index 753d999b5f0b99c49f720954f2eea1fb2c8c0ea9..83636e1f5080b4f8be0e0d636878d9f7691984e8 100644 (file)
@@ -16,8 +16,7 @@
 .text
 .p2align 2
 
-.globl ASM_PFX(__switchu8)
-INTERWORK_FUNC(__switchu8)
+GCC_ASM_EXPORT(__switchu8)
 
 
 ASM_PFX(__switchu8):
index 5b7f5b70b76a8ba8c1c24b2e7197db75c973d982..ae9a70310620c14f52cdca1100095bc4110d1cfa 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__ucmpdi2)
-  INTERWORK_FUNC(__ucmpdi2)
+       GCC_ASM_EXPORT(__ucmpdi2)
        
 ASM_PFX(__ucmpdi2):
        stmfd   sp!, {r4, r5, r8, lr}
index fc9240e135d79059a943538108330fe36ee6557f..7b67aeeeabc84ec3c29e07874b8651e2e740a874 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__udivdi3)
-  INTERWORK_FUNC(__udivdi3)
+       GCC_ASM_EXPORT(__udivdi3)
 
 ASM_PFX(__udivdi3):
        stmfd   sp!, {r7, lr}
index 816e66a12ab9a813f32b071ff51f9c4fe4185387..c6b823986cddf20ba9aab7c6989dcacb22b7f0f1 100644 (file)
@@ -14,9 +14,8 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__udivmoddi4)
-       INTERWORK_FUNC(__udivmoddi4)
-
+       GCC_ASM_EXPORT(__udivmoddi4)
+       
 ASM_PFX(__udivmoddi4):
        stmfd   sp!, {r4, r5, r6, r7, lr}
        add     r7, sp, #12
index 77cfa726c0a163deaa82508b2e44d9ee423826dc..87509941f2f17b01d43ebcae601c12ae147a6a4e 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__udivsi3)
-       INTERWORK_FUNC(__udivsi3)
+       GCC_ASM_EXPORT(__udivsi3)
 
 ASM_PFX(__udivsi3):
        cmp     r1, #0
index 81e824cc83b6687516b1a25264b295d05783db57..4bde15f28df557282cfdf108f5d7963b9330d07f 100755 (executable)
@@ -16,8 +16,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__aeabi_uldivmod)
-       INTERWORK_FUNC(__aeabi_uldivmod)
+       GCC_ASM_EXPORT(__aeabi_uldivmod)
 
 //        
 //UINT64
index c801ba06dde5b2aedcd261ca8882f9d0fd839998..e4374b5789a7a9ac7bb572de68c259e090018f6b 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl ASM_PFX(__umoddi3)
-       INTERWORK_FUNC(__umoddi3)
+       GCC_ASM_EXPORT(__umoddi3)
        
 ASM_PFX(__umoddi3):
        stmfd   sp!, {r7, lr}
index 30dc55193bcd73534cf34bd8ce0138d32660a629..f571a56db62137daa21dd6491f48086cefcc878e 100644 (file)
@@ -14,8 +14,7 @@
 
        .text
        .align 2
-       .globl  ASM_PFX(__umodsi3)
-        INTERWORK_FUNC(__umodsi3)
+       GCC_ASM_EXPORT(__umodsi3)
        
 ASM_PFX(__umodsi3):
        stmfd   sp!, {r4, r5, r7, lr}
index 5bfa0adc2456a948242e7af8a864eba8bbf2a49b..5bd1a9d1883d058a83aedb74d37e8aa57859b903 100755 (executable)
@@ -32,37 +32,33 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 CHAR8 *\r
 DeCygwinPathIfNeeded (\r
-  IN  CHAR8   *Name\r
+  IN  CHAR8   *Name,\r
+  IN  CHAR8   *Temp,\r
+  IN  UINTN   Size\r
   )\r
 {\r
   CHAR8   *Ptr;\r
   UINTN   Index;\r
-  UINTN   Len;\r
+  UINTN   Index2;\r
   \r
   Ptr = AsciiStrStr (Name, "/cygdrive/");\r
   if (Ptr == NULL) {\r
     return Name;\r
   }\r
   \r
-  Len = AsciiStrLen (Ptr);\r
-  \r
-  // convert "/cygdrive" to spaces\r
-  for (Index = 0; Index < 9; Index++) {\r
-    Ptr[Index] = ' ';\r
+  for (Index = 9, Index2 = 0; (Index < (Size + 9)) && (Ptr[Index] != '\0'); Index++, Index2++) {\r
+    Temp[Index2] = Ptr[Index];\r
+    if (Temp[Index2] == '/') {\r
+      Temp[Index2] = '\\' ;\r
   }\r
 \r
-  // convert /c to c:\r
-  Ptr[9]  = Ptr[10];\r
-  Ptr[10] = ':';\r
-  \r
-  // switch path seperators\r
-  for (Index = 11; Index < Len; Index++) {\r
-    if (Ptr[Index] == '/') {\r
-      Ptr[Index] = '\\' ;\r
+    if (Index2 == 1) {\r
+      Temp[Index2 - 1] = Ptr[Index];\r
+      Temp[Index2] = ':';\r
     }\r
   }\r
 \r
-  return Name;\r
+  return Temp;\r
 }\r
 \r
 \r
@@ -81,12 +77,14 @@ PeCoffLoaderRelocateImageExtraAction (
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
   )\r
 {\r
+    CHAR8 Temp[512];\r
+\r
 #ifdef __CC_ARM\r
   // Print out the command for the RVD debugger to load symbols for this image\r
-  DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));\r
+  DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));\r
 #elif __GNUC__\r
   // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required\r
-  DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));\r
+  DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));\r
 #else\r
   DEBUG ((EFI_D_ERROR, "Loading driver at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_POINT (ImageContext->EntryPoint)));\r
 #endif\r
@@ -110,12 +108,16 @@ PeCoffLoaderUnloadImageExtraAction (
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
   )\r
 {\r
+  CHAR8 Temp[512];\r
+  \r
 #ifdef __CC_ARM\r
+  {  \r
   // Print out the command for the RVD debugger to load symbols for this image\r
-  DEBUG ((EFI_D_ERROR, "unload symbols_only %a", DeCygwinPathIfNeeded (ImageContext->PdbPointer)));\r
+    DEBUG ((EFI_D_ERROR, "unload symbols_only %a", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp))));\r
+  }\r
 #elif __GNUC__\r
   // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required\r
-  DEBUG ((EFI_D_ERROR, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));\r
+  DEBUG ((EFI_D_ERROR, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));\r
 #else\r
   DEBUG ((EFI_D_ERROR, "Unloading %a", ImageContext->PdbPointer));\r
 #endif\r
diff --git a/ArmPkg/Library/L2X0CacheLibNull/L2X0Cache.c b/ArmPkg/Library/L2X0CacheLibNull/L2X0Cache.c
new file mode 100644 (file)
index 0000000..b7d79c3
--- /dev/null
@@ -0,0 +1,20 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/L2X0CacheLib.h>\r
+\r
+// Initialize L2X0 Cache Controller\r
+VOID L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled) {\r
+    //No implementation\r
+}\r
diff --git a/ArmPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf b/ArmPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf
new file mode 100644 (file)
index 0000000..f6ff894
--- /dev/null
@@ -0,0 +1,27 @@
+#/* @file\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#*/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = L2X0CacheLibNull\r
+  FILE_GUID                      = 9c76c900-1e8c-11e0-8766-0002a5d5c51b\r
+  MODULE_TYPE                    = SEC\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = L2X0CacheLib\r
+\r
+[Sources]\r
+  L2X0Cache.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ArmPkg/ArmPkg.dec\r
diff --git a/ArmPkg/Universal/MmcDxe/ComponentName.c b/ArmPkg/Universal/MmcDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..030a54f
--- /dev/null
@@ -0,0 +1,162 @@
+/** @file\r
+  Component Name Protocol implementation for the MMC DXE driver\r
+\r
+  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+  \r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#include "Mmc.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gMmcComponentName = {\r
+  MmcGetDriverName,\r
+  MmcGetControllerName,\r
+  "eng"\r
+};\r
+\r
+//\r
+// EFI Component Name 2 Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gMmcComponentName2 = {\r
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) MmcGetDriverName,\r
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) MmcGetControllerName,\r
+  "en"\r
+};\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE\r
+mMmcDriverNameTable[] = {\r
+  {"eng;en", L"MMC/SD Card Interface Driver"},\r
+  {NULL,  NULL}\r
+};\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This                  A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+  @param  Language              A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+  @param  DriverName            A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+{\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mMmcDriverNameTable,\r
+           DriverName,\r
+           (BOOLEAN)(This == &gMmcComponentName)\r
+           );\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This                  A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+  @param  ControllerHandle      The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+  @param  ChildHandle           The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+  @param  Language              A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+  @param  ControllerName        A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
diff --git a/ArmPkg/Universal/MmcDxe/Diagnostics.c b/ArmPkg/Universal/MmcDxe/Diagnostics.c
new file mode 100644 (file)
index 0000000..a477135
--- /dev/null
@@ -0,0 +1,215 @@
+/** @file\r
+  Diagnostics Protocol implementation for the MMC DXE driver\r
+\r
+  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+  \r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "Mmc.h"\r
+\r
+#define DIAGNOSTIC_LOGBUFFER_MAXCHAR  1024\r
+\r
+CHAR16* mLogBuffer = NULL;\r
+UINTN   mLogRemainChar = 0;\r
+\r
+CHAR16* DiagnosticInitLog(UINTN MaxBufferChar) {\r
+    mLogRemainChar = MaxBufferChar;\r
+    mLogBuffer = AllocatePool ((UINTN)MaxBufferChar * sizeof(CHAR16));\r
+    return mLogBuffer;\r
+}\r
+\r
+UINTN DiagnosticLog(CONST CHAR16* Str) {\r
+    UINTN len = StrLen (Str);\r
+    if (len <= mLogRemainChar) {\r
+        mLogRemainChar -= len;\r
+        StrCpy (mLogBuffer, Str);\r
+        mLogBuffer += len;\r
+        return len;\r
+    } else {\r
+        return 0;\r
+    }\r
+}\r
+\r
+VOID GenerateRandomBuffer(VOID* Buffer, UINTN BufferSize) {\r
+    UINT64 i;\r
+    UINT64* Buffer64 = (UINT64*)Buffer;\r
+\r
+    for (i = 0; i < (BufferSize >> 3); i++) {\r
+        *Buffer64 = i | (~i << 32);\r
+        Buffer64++;\r
+    }\r
+}\r
+\r
+BOOLEAN CompareBuffer(VOID *BufferA, VOID *BufferB, UINTN BufferSize) {\r
+    UINTN i;\r
+    UINT64* BufferA64 = (UINT64*)BufferA;\r
+    UINT64* BufferB64 = (UINT64*)BufferB;\r
+\r
+    for (i = 0; i < (BufferSize >> 3); i++) {\r
+        if (*BufferA64 != *BufferB64) {\r
+            DEBUG((EFI_D_ERROR, "CompareBuffer: Error at %i", i));\r
+            DEBUG((EFI_D_ERROR, "(0x%lX) != (0x%lX)\n", *BufferA64, *BufferB64));\r
+            return FALSE;\r
+        }\r
+        BufferA64++;\r
+        BufferB64++;\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+EFI_STATUS MmcReadWriteDataTest(MMC_HOST_INSTANCE *MmcHostInstance, EFI_LBA Lba, UINTN BufferSize) {\r
+    VOID                        *BackBuffer;\r
+    VOID                        *WriteBuffer;\r
+    VOID                        *ReadBuffer;\r
+    EFI_STATUS                  Status;\r
+    \r
+    // Check if a Media is Present\r
+    if (!MmcHostInstance->BlockIo.Media->MediaPresent) {\r
+        DiagnosticLog(L"ERROR: No Media Present\n");\r
+        return EFI_NO_MEDIA;\r
+    }\r
+\r
+    if (MmcHostInstance->State != MmcTransferState) {\r
+        DiagnosticLog(L"ERROR: Not ready for Transfer state\n");\r
+        return EFI_NOT_READY;\r
+    }\r
+\r
+    BackBuffer = AllocatePool(BufferSize);\r
+    WriteBuffer = AllocatePool(BufferSize);\r
+    ReadBuffer = AllocatePool(BufferSize);\r
+\r
+    // Read (and save) buffer at a specific location\r
+    Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
+    if (Status != EFI_SUCCESS) {\r
+        DiagnosticLog(L"ERROR: Fail to Read Block (1)\n");\r
+        return Status;\r
+    }\r
+\r
+    // Write buffer at the same location\r
+    GenerateRandomBuffer(WriteBuffer,BufferSize);\r
+    Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,WriteBuffer);\r
+    if (Status != EFI_SUCCESS) {\r
+        DiagnosticLog(L"ERROR: Fail to Write Block (1)\n");\r
+        return Status;\r
+    }\r
+\r
+    // Read the buffer at the same location\r
+    Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
+    if (Status != EFI_SUCCESS) {\r
+        DiagnosticLog(L"ERROR: Fail to Read Block (2)\n");\r
+        return Status;\r
+    }\r
+\r
+    // Check that is conform\r
+    if (!CompareBuffer(ReadBuffer,WriteBuffer,BufferSize)) {\r
+        DiagnosticLog(L"ERROR: Fail to Read/Write Block (1)\n");\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    // Restore content at the original location\r
+    Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
+    if (Status != EFI_SUCCESS) {\r
+        DiagnosticLog(L"ERROR: Fail to Write Block (2)\n");\r
+        return Status;\r
+    }\r
+\r
+    // Read the restored content\r
+    Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
+    if (Status != EFI_SUCCESS) {\r
+        DiagnosticLog(L"ERROR: Fail to Read Block (3)\n");\r
+        return Status;\r
+    }\r
+\r
+    // Check the content is correct\r
+    if (!CompareBuffer(ReadBuffer,BackBuffer,BufferSize)) {\r
+        DiagnosticLog(L"ERROR: Fail to Read/Write Block (2)\n");\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcDriverDiagnosticsRunDiagnostics (\r
+  IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,\r
+  IN  EFI_HANDLE                                    ControllerHandle,\r
+  IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,\r
+  IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,\r
+  IN  CHAR8                                         *Language,\r
+  OUT EFI_GUID                                      **ErrorType,\r
+  OUT UINTN                                         *BufferSize,\r
+  OUT CHAR16                                        **Buffer\r
+  )\r
+{\r
+    LIST_ENTRY          *CurrentLink;\r
+    MMC_HOST_INSTANCE   *MmcHostInstance;\r
+    EFI_STATUS          Status;\r
+\r
+    if (Language         == NULL ||\r
+        ErrorType        == NULL ||\r
+        Buffer           == NULL ||\r
+        ControllerHandle == NULL ||\r
+        BufferSize       == NULL) {\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Status = EFI_SUCCESS;\r
+    *ErrorType  = NULL;\r
+    *BufferSize = DIAGNOSTIC_LOGBUFFER_MAXCHAR;\r
+    *Buffer = DiagnosticInitLog(DIAGNOSTIC_LOGBUFFER_MAXCHAR);\r
+\r
+    DiagnosticLog(L"MMC Driver Diagnostics\n");\r
+\r
+    // For each MMC instance\r
+    CurrentLink = mMmcHostPool.ForwardLink;\r
+    while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {\r
+        MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink);\r
+        ASSERT(MmcHostInstance != NULL);\r
+\r
+        // LBA=1 Size=BlockSize\r
+        DiagnosticLog(L"MMC Driver Diagnostics - Test: First Block\n");\r
+        Status = MmcReadWriteDataTest(MmcHostInstance, 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
+\r
+        // LBA=2 Size=BlockSize\r
+        DiagnosticLog(L"MMC Driver Diagnostics - Test: Second Block\n");\r
+        Status = MmcReadWriteDataTest(MmcHostInstance, 2, MmcHostInstance->BlockIo.Media->BlockSize);\r
+\r
+        // LBA=10 Size=BlockSize\r
+        DiagnosticLog(L"MMC Driver Diagnostics - Test: Any Block\n");\r
+        Status = MmcReadWriteDataTest(MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock >> 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
+\r
+        // LBA=LastBlock Size=BlockSize\r
+        DiagnosticLog(L"MMC Driver Diagnostics - Test: Last Block\n");\r
+        Status = MmcReadWriteDataTest(MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock, MmcHostInstance->BlockIo.Media->BlockSize);\r
+\r
+        // LBA=1 Size=2*BlockSize\r
+        DiagnosticLog(L"MMC Driver Diagnostics - Test: First Block / 2 BlockSSize\n");\r
+        Status = MmcReadWriteDataTest(MmcHostInstance, 1, 2*MmcHostInstance->BlockIo.Media->BlockSize);\r
+\r
+        CurrentLink = CurrentLink->ForwardLink;\r
+    }\r
+\r
+    return Status;\r
+}\r
+\r
+//\r
+// EFI Driver Diagnostics 2 Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gMmcDriverDiagnostics2 = {\r
+  (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS) MmcDriverDiagnosticsRunDiagnostics,\r
+  "en"\r
+};\r
diff --git a/ArmPkg/Universal/MmcDxe/Mmc.c b/ArmPkg/Universal/MmcDxe/Mmc.c
new file mode 100644 (file)
index 0000000..90d1172
--- /dev/null
@@ -0,0 +1,387 @@
+/** @file\r
+  Main file of the MMC Dxe driver. The driver entrypoint is defined into this file.\r
+\r
+  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+  \r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/MmcHost.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#include "Mmc.h"\r
+\r
+EFI_BLOCK_IO_MEDIA mMmcMediaTemplate = {\r
+  SIGNATURE_32('m','m','c','o'),            // MediaId\r
+  TRUE,                                     // RemovableMedia\r
+  FALSE,                                    // MediaPresent\r
+  FALSE,                                    // LogicalPartition\r
+  FALSE,                                    // ReadOnly\r
+  FALSE,                                    // WriteCaching\r
+  512,                                      // BlockSize\r
+  4,                                        // IoAlign\r
+  0,                                        // Pad\r
+  0                                         // LastBlock\r
+};\r
+\r
+//\r
+// This device structure is serviced as a header.\r
+// Its next field points to the first root bridge device node.\r
+//\r
+LIST_ENTRY  mMmcHostPool;\r
+\r
+/**\r
+  Initialize the MMC Host Pool to support multiple MMC devices\r
+**/\r
+VOID\r
+InitializeMmcHostPool (\r
+  VOID\r
+  )\r
+{\r
+    InitializeListHead (&mMmcHostPool);\r
+}\r
+\r
+/**\r
+  Insert a new Mmc Host controller to the pool\r
+**/\r
+VOID\r
+InsertMmcHost (\r
+  IN MMC_HOST_INSTANCE      *MmcHostInstance\r
+  )\r
+{\r
+    InsertTailList (&mMmcHostPool, &(MmcHostInstance->Link));\r
+}\r
+\r
+/*\r
+  Remove a new Mmc Host controller to the pool\r
+*/\r
+VOID\r
+RemoveMmcHost (\r
+  IN MMC_HOST_INSTANCE      *MmcHostInstance\r
+  )\r
+{\r
+    RemoveEntryList (&(MmcHostInstance->Link));\r
+}\r
+\r
+MMC_HOST_INSTANCE* CreateMmcHostInstance(\r
+  IN EFI_MMC_HOST_PROTOCOL* MmcHost\r
+  )\r
+{\r
+    EFI_STATUS          Status;\r
+    MMC_HOST_INSTANCE*  MmcHostInstance;\r
+    EFI_DEVICE_PATH_PROTOCOL    *NewDevicePathNode;\r
+    EFI_DEVICE_PATH_PROTOCOL    *DevicePath;\r
+\r
+    MmcHostInstance = AllocateZeroPool (sizeof (MMC_HOST_INSTANCE));\r
+    if (MmcHostInstance == NULL) {\r
+        return NULL;\r
+    }\r
+\r
+    MmcHostInstance->Signature = MMC_HOST_INSTANCE_SIGNATURE;\r
+\r
+    MmcHostInstance->State = MmcHwInitializationState;\r
+    \r
+    MmcHostInstance->BlockIo.Media = AllocateCopyPool (sizeof(EFI_BLOCK_IO_MEDIA), &mMmcMediaTemplate);\r
+    if (MmcHostInstance->BlockIo.Media == NULL) {\r
+        goto FREE_INSTANCE;\r
+    }\r
+\r
+    MmcHostInstance->BlockIo.Revision = EFI_BLOCK_IO_INTERFACE_REVISION;\r
+    MmcHostInstance->BlockIo.Reset = MmcReset;\r
+    MmcHostInstance->BlockIo.ReadBlocks = MmcReadBlocks;\r
+    MmcHostInstance->BlockIo.WriteBlocks = MmcWriteBlocks;\r
+    MmcHostInstance->BlockIo.FlushBlocks = MmcFlushBlocks;\r
+\r
+    MmcHostInstance->MmcHost = MmcHost;\r
+\r
+    // Create DevicePath for the new MMC Host\r
+    Status = MmcHost->BuildDevicePath(&NewDevicePathNode);\r
+    if (EFI_ERROR (Status)) {\r
+        goto FREE_MEDIA;\r
+    }\r
+\r
+    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);\r
+    if (DevicePath == NULL) {\r
+        goto FREE_MEDIA;\r
+    }\r
+    \r
+    SetDevicePathEndNode (DevicePath);\r
+    MmcHostInstance->DevicePath = AppendDevicePathNode (DevicePath, NewDevicePathNode);\r
+\r
+    // Publish BlockIO protocol interface\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &MmcHostInstance->MmcHandle,\r
+                  &gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo),\r
+                  &gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath,\r
+                  NULL\r
+                  );\r
+    if (EFI_ERROR(Status)) {\r
+        goto FREE_DEVICE_PATH;\r
+    }\r
+\r
+    return MmcHostInstance;\r
+\r
+FREE_DEVICE_PATH:\r
+    FreePool(DevicePath);\r
+\r
+FREE_MEDIA:\r
+    FreePool(MmcHostInstance->BlockIo.Media);\r
+\r
+FREE_INSTANCE:\r
+    FreePool(MmcHostInstance);\r
+\r
+    return NULL;\r
+}\r
+\r
+EFI_STATUS DestroyMmcHostInstance(\r
+  IN MMC_HOST_INSTANCE* MmcHostInstance\r
+  )\r
+{\r
+    EFI_STATUS Status;\r
+\r
+    // Uninstall Protocol Interfaces\r
+    Status = gBS->UninstallMultipleProtocolInterfaces(\r
+            &MmcHostInstance->MmcHandle,\r
+            &gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo),\r
+            &gEfiDevicePathProtocolGuid,&(MmcHostInstance->DevicePath),\r
+            NULL\r
+            );\r
+    ASSERT_EFI_ERROR (Status);\r
+    \r
+    // Free Memory allocated for the instance\r
+    if (MmcHostInstance->BlockIo.Media) {\r
+        FreePool(MmcHostInstance->BlockIo.Media);\r
+    }\r
+    FreePool (MmcHostInstance);\r
+\r
+    return Status;\r
+}\r
+\r
+/**\r
+  This function checks if the controller implement the Mmc Host and the Device Path Protocols\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN EFI_HANDLE                     Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  )\r
+{\r
+    EFI_STATUS                      Status;\r
+    //EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;\r
+    EFI_MMC_HOST_PROTOCOL           *MmcHost;\r
+    EFI_DEV_PATH_PTR                Node;\r
+\r
+    //\r
+    // Check RemainingDevicePath validation\r
+    //\r
+    if (RemainingDevicePath != NULL) {\r
+        //\r
+        // Check if RemainingDevicePath is the End of Device Path Node, \r
+        // if yes, go on checking other conditions\r
+        //\r
+        if (!IsDevicePathEnd (RemainingDevicePath)) {\r
+            //\r
+            // If RemainingDevicePath isn't the End of Device Path Node,\r
+            // check its validation\r
+            //\r
+            Node.DevPath = RemainingDevicePath;\r
+            if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||\r
+              Node.DevPath->SubType != HW_VENDOR_DP      ||\r
+              DevicePathNodeLength(Node.DevPath) != sizeof(VENDOR_DEVICE_PATH)) {\r
+                return EFI_UNSUPPORTED;\r
+            }\r
+        }\r
+    }\r
+\r
+    //\r
+    // Check if Mmc Host protocol is installed by platform\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiMmcHostProtocolGuid,\r
+                  (VOID **) &MmcHost,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+    if (Status == EFI_ALREADY_STARTED) {\r
+        return EFI_SUCCESS;\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+        return Status;\r
+    }\r
+\r
+    //\r
+    // Close the Mmc Host used to perform the supported test\r
+    //\r
+    gBS->CloseProtocol (\r
+        Controller,\r
+        &gEfiMmcHostProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  )\r
+{\r
+    EFI_STATUS              Status;\r
+    MMC_HOST_INSTANCE       *MmcHostInstance;\r
+    EFI_MMC_HOST_PROTOCOL   *MmcHost;\r
+\r
+    //\r
+    // Check RemainingDevicePath validation\r
+    //\r
+    if (RemainingDevicePath != NULL) {\r
+        //\r
+        // Check if RemainingDevicePath is the End of Device Path Node, \r
+        // if yes, return EFI_SUCCESS\r
+        //\r
+        if (IsDevicePathEnd (RemainingDevicePath)) {\r
+            return EFI_SUCCESS;\r
+        }\r
+    }\r
+\r
+    //\r
+    // Get the Mmc Host protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiMmcHostProtocolGuid,\r
+                  (VOID **) &MmcHost,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+    if (EFI_ERROR (Status)) {\r
+        if (Status == EFI_ALREADY_STARTED) {\r
+            return EFI_SUCCESS;\r
+        }\r
+        return Status;\r
+    }\r
+\r
+    MmcHostInstance = CreateMmcHostInstance(MmcHost);\r
+    if (MmcHostInstance != NULL) {\r
+        // Add the handle to the pool\r
+        InsertMmcHost (MmcHostInstance);\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
+  IN  EFI_HANDLE                    Controller,\r
+  IN  UINTN                         NumberOfChildren,\r
+  IN  EFI_HANDLE                    *ChildHandleBuffer\r
+  )\r
+{\r
+    EFI_STATUS          Status = EFI_SUCCESS;\r
+    LIST_ENTRY          *CurrentLink;\r
+    MMC_HOST_INSTANCE   *MmcHostInstance;\r
+\r
+    MMC_TRACE("MmcDriverBindingStop()");\r
+\r
+    // For each MMC instance\r
+    CurrentLink = mMmcHostPool.ForwardLink;\r
+    while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {\r
+        MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink);\r
+        ASSERT(MmcHostInstance != NULL);\r
+\r
+        // Close gEfiMmcHostProtocolGuid\r
+        Status = gBS->CloseProtocol (\r
+                    Controller,\r
+                    &gEfiMmcHostProtocolGuid,(VOID **) &MmcHostInstance->MmcHost,\r
+                    This->DriverBindingHandle\r
+                    );\r
+\r
+        // Remove MMC Host Instance from the pool\r
+        RemoveMmcHost (MmcHostInstance);\r
+\r
+        // Destroy MmcHostInstance\r
+        DestroyMmcHostInstance (MmcHostInstance);\r
+    }\r
+\r
+    return Status;\r
+}\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = {\r
+  MmcDriverBindingSupported,\r
+  MmcDriverBindingStart,\r
+  MmcDriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+/**\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcDxeInitialize (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+    EFI_STATUS  Status;\r
+\r
+    //\r
+    // Initializes MMC Host pool\r
+    //\r
+    InitializeMmcHostPool ();\r
+\r
+    //\r
+    // Install driver model protocol(s).\r
+    //\r
+    Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gMmcDriverBinding,\r
+             ImageHandle,\r
+             &gMmcComponentName,\r
+             &gMmcComponentName2\r
+             );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    // Install driver diagnostics\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &ImageHandle, \r
+                  &gEfiDriverDiagnostics2ProtocolGuid,&gMmcDriverDiagnostics2,\r
+                  NULL\r
+                  );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    return Status;\r
+}\r
diff --git a/ArmPkg/Universal/MmcDxe/Mmc.h b/ArmPkg/Universal/MmcDxe/Mmc.h
new file mode 100644 (file)
index 0000000..dbca991
--- /dev/null
@@ -0,0 +1,284 @@
+/** @file\r
+  Main Header file for the MMC DXE driver\r
+\r
+  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+  \r
+  This program and the accompanying materials                          \r
+  are licensed and made available under the terms and conditions of the BSD License         \r
+  which accompanies this distribution.  The full text of the license may be found at        \r
+  http://opensource.org/licenses/bsd-license.php                                            \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#ifndef __MMC_H\r
+#define __MMC_H\r
+\r
+#include <Protocol/DiskIo.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/MmcHost.h>\r
+\r
+#include <Library/UefiLib.h>\r
+\r
+#define MMC_TRACE(txt)  DEBUG((EFI_D_BLKIO, "MMC: " txt "\n"))\r
+\r
+#define MMC_IOBLOCKS_READ       0\r
+#define MMC_IOBLOCKS_WRITE      1\r
+\r
+#define MMC_OCR_POWERUP             0x80000000\r
+\r
+#define MMC_CSD_GET_CCC(Response)              (Response[1] >> 20)\r
+#define MMC_CSD_GET_TRANSPEED(Response)                (Response[0] & 0xFF)\r
+#define MMC_CSD_GET_READBLLEN(Response)                ((Response[1] >> 16) & 0xF)\r
+#define MMC_CSD_GET_WRITEBLLEN(Response)       ((Response[3] >> 22) & 0xF)\r
+#define MMC_CSD_GET_FILEFORMAT(Response)       ((Response[3] >> 10) & 0x3)\r
+#define MMC_CSD_GET_FILEFORMATGRP(Response)    ((Response[3] >> 15) & 0x1)\r
+#define MMC_CSD_GET_DEVICESIZE(csd)         (((Response[2] >> 30) & 0x3) | ((Response[1] & 0x3FF) << 2))\r
+#define MMC_CSD_GET_DEVICESIZEMULT(csd)     ((Response[2] >> 15) & 0x7)\r
+\r
+#define MMC_R0_CURRENTSTATE(Response)       ((Response[0] >> 9) & 0xF)\r
+\r
+#define MMC_R0_STATE_IDLE       0\r
+#define MMC_R0_STATE_READY      1\r
+#define MMC_R0_STATE_IDENT      2\r
+#define MMC_R0_STATE_STDBY      3\r
+#define MMC_R0_STATE_TRAN       4\r
+#define MMC_R0_STATE_DATA       5\r
+\r
+typedef enum {\r
+  UNKNOWN_CARD,\r
+  MMC_CARD,              //MMC card\r
+  MMC_CARD_HIGH,         //MMC Card with High capacity\r
+  SD_CARD,               //SD 1.1 card\r
+  SD_CARD_2,             //SD 2.0 or above standard card\r
+  SD_CARD_2_HIGH         //SD 2.0 or above high capacity card\r
+} CARD_TYPE;\r
+\r
+typedef struct {\r
+  UINT32  Reserved0:   7; // 0 \r
+  UINT32  V170_V195:   1; // 1.70V - 1.95V\r
+  UINT32  V200_V260:   7; // 2.00V - 2.60V\r
+  UINT32  V270_V360:   9; // 2.70V - 3.60V\r
+  UINT32  RESERVED_1:  5; // Reserved\r
+  UINT32  AccessMode:  2; // 00b (byte mode), 10b (sector mode) \r
+  UINT32  Busy:        1; // This bit is set to LOW if the card has not finished the power up routine\r
+} OCR;\r
+\r
+typedef struct {\r
+  UINT32  NOT_USED;   // 1 [0:0]\r
+  UINT32  CRC;        // CRC7 checksum [7:1]\r
+  UINT32  MDT;        // Manufacturing date [19:8]\r
+  UINT32  RESERVED_1; // Reserved [23:20]\r
+  UINT32  PSN;        // Product serial number [55:24]\r
+  UINT8   PRV;        // Product revision [63:56]\r
+  UINT8   PNM[5];     // Product name [64:103]\r
+  UINT16  OID;        // OEM/Application ID [119:104]\r
+  UINT8   MID;        // Manufacturer ID [127:120]\r
+} CID;\r
+\r
+typedef struct {\r
+  UINT8   NOT_USED:           1; // Not used, always 1 [0:0]\r
+  UINT8   CRC:                7; // CRC [7:1]\r
+\r
+  UINT8   RESERVED_1:         2; // Reserved [9:8]\r
+  UINT8   FILE_FORMAT:        2; // File format [11:10]\r
+  UINT8   TMP_WRITE_PROTECT:  1; // Temporary write protection [12:12]\r
+  UINT8   PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]\r
+  UINT8   COPY:               1; // Copy flag (OTP) [14:14]\r
+  UINT8   FILE_FORMAT_GRP:    1; // File format group [15:15]\r
+  \r
+  UINT16  RESERVED_2:         5; // Reserved [20:16]\r
+  UINT16  WRITE_BL_PARTIAL:   1; // Partial blocks for write allowed [21:21]\r
+  UINT16  WRITE_BL_LEN:       4; // Max. write data block length [25:22]\r
+  UINT16  R2W_FACTOR:         3; // Write speed factor [28:26]\r
+  UINT16  RESERVED_3:         2; // Reserved [30:29]\r
+  UINT16  WP_GRP_ENABLE:      1; // Write protect group enable [31:31]\r
+  \r
+  UINT32  WP_GRP_SIZE:        7; // Write protect group size [38:32]\r
+  UINT32  SECTOR_SIZE:        7; // Erase sector size [45:39]\r
+  UINT32  ERASE_BLK_EN:       1; // Erase single block enable [46:46]\r
+  UINT32  C_SIZE_MULT:        3; // Device size multiplier [49:47]\r
+  UINT32  VDD_W_CURR_MAX:     3; // Max. write current @ VDD max [52:50]\r
+  UINT32  VDD_W_CURR_MIN:     3; // Max. write current @ VDD min [55:53]\r
+  UINT32  VDD_R_CURR_MAX:     3; // Max. read current @ VDD max [58:56]\r
+  UINT32  VDD_R_CURR_MIN:     3; // Max. read current @ VDD min [61:59]\r
+  UINT32  C_SIZELow2:         2; // Device size [63:62]\r
+  \r
+  UINT32  C_SIZEHigh10:       10;// Device size [73:64]\r
+  UINT32  RESERVED_4:         2; // Reserved [75:74]\r
+  UINT32  DSR_IMP:            1; // DSR implemented [76:76]\r
+  UINT32  READ_BLK_MISALIGN:  1; // Read block misalignment [77:77]\r
+  UINT32  WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]\r
+  UINT32  READ_BL_PARTIAL:    1; // Partial blocks for read allowed [79:79]\r
+  UINT32  READ_BL_LEN:        4; // Max. read data block length [83:80]\r
+  UINT32  CCC:                12;// Card command classes [95:84]\r
+\r
+  UINT8   TRAN_SPEED          ;  // Max. bus clock frequency [103:96]\r
+  UINT8   NSAC                ;  // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]\r
+  UINT8   TAAC                ;  // Data read access-time 1 [119:112]\r
+  \r
+  UINT8   RESERVED_5:         6; // Reserved [125:120]\r
+  UINT8   CSD_STRUCTURE:      2; // CSD structure [127:126]\r
+} CSD;\r
+\r
+typedef struct  {\r
+  UINT16    RCA;\r
+  CARD_TYPE CardType;\r
+  OCR       OCRData;\r
+  CID       CIDData;\r
+  CSD       CSDData;\r
+} CARD_INFO;\r
+\r
+typedef struct _MMC_HOST_INSTANCE {\r
+  UINTN                     Signature;\r
+  LIST_ENTRY                Link;\r
+  EFI_HANDLE                MmcHandle;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+\r
+  MMC_STATE                 State;\r
+  EFI_BLOCK_IO_PROTOCOL     BlockIo;\r
+  CARD_INFO                 CardInfo;\r
+  EFI_MMC_HOST_PROTOCOL     *MmcHost;\r
+} MMC_HOST_INSTANCE;\r
+\r
+#define MMC_HOST_INSTANCE_SIGNATURE                 SIGNATURE_32('m', 'm', 'c', 'h')\r
+#define MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS(a)     CR (a, MMC_HOST_INSTANCE, BlockIo, MMC_HOST_INSTANCE_SIGNATURE)\r
+#define MMC_HOST_INSTANCE_FROM_LINK(a)              CR (a, MMC_HOST_INSTANCE, Link, MMC_HOST_INSTANCE_SIGNATURE)\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  );\r
+\r
+extern EFI_COMPONENT_NAME_PROTOCOL  gMmcComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gMmcComponentName2;\r
+\r
+extern EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gMmcDriverDiagnostics2;\r
+\r
+extern LIST_ENTRY mMmcHostPool;\r
+\r
+/**\r
+  Reset the block device.\r
+\r
+  This function implements EFI_BLOCK_IO_PROTOCOL.Reset(). \r
+  It resets the block device hardware.\r
+  ExtendedVerification is ignored in this implementation.\r
+\r
+  @param  This                   Indicates a pointer to the calling context.\r
+  @param  ExtendedVerification   Indicates that the driver may perform a more exhaustive\r
+                                 verification operation of the device during reset.\r
+\r
+  @retval EFI_SUCCESS            The block device was reset.\r
+  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly and could not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcReset (\r
+  IN EFI_BLOCK_IO_PROTOCOL    *This,\r
+  IN BOOLEAN                  ExtendedVerification\r
+  );\r
+\r
+/**\r
+  Reads the requested number of blocks from the device.\r
+\r
+  This function implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks(). \r
+  It reads the requested number of blocks from the device.\r
+  All the blocks are read, or an error is returned.\r
+\r
+  @param  This                   Indicates a pointer to the calling context.\r
+  @param  MediaId                The media ID that the read request is for.\r
+  @param  Lba                    The starting logical block address to read from on the device.\r
+  @param  BufferSize             The size of the Buffer in bytes.\r
+                                 This must be a multiple of the intrinsic block size of the device.\r
+  @param  Buffer                 A pointer to the destination buffer for the data. The caller is\r
+                                 responsible for either having implicit or explicit ownership of the buffer.\r
+\r
+  @retval EFI_SUCCESS            The data was read correctly from the device.\r
+  @retval EFI_DEVICE_ERROR       The device reported an error while attempting to perform the read operation.\r
+  @retval EFI_NO_MEDIA           There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED      The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER  The read request contains LBAs that are not valid,\r
+                                 or the buffer is not on proper alignment.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcReadBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL    *This,\r
+  IN UINT32                   MediaId,\r
+  IN EFI_LBA                  Lba,\r
+  IN UINTN                    BufferSize,\r
+  OUT VOID                    *Buffer\r
+  );\r
+\r
+/**\r
+  Writes a specified number of blocks to the device.\r
+\r
+  This function implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks(). \r
+  It writes a specified number of blocks to the device.\r
+  All blocks are written, or an error is returned.\r
+\r
+  @param  This                   Indicates a pointer to the calling context.\r
+  @param  MediaId                The media ID that the write request is for.\r
+  @param  Lba                    The starting logical block address to be written.\r
+  @param  BufferSize             The size of the Buffer in bytes.\r
+                                 This must be a multiple of the intrinsic block size of the device.\r
+  @param  Buffer                 Pointer to the source buffer for the data.\r
+\r
+  @retval EFI_SUCCESS            The data were written correctly to the device.\r
+  @retval EFI_WRITE_PROTECTED    The device cannot be written to.\r
+  @retval EFI_NO_MEDIA           There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED      The MediaId is not for the current media.\r
+  @retval EFI_DEVICE_ERROR       The device reported an error while attempting to perform the write operation.\r
+  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the intrinsic\r
+                                 block size of the device.\r
+  @retval EFI_INVALID_PARAMETER  The write request contains LBAs that are not valid,\r
+                                 or the buffer is not on proper alignment.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcWriteBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL    *This,\r
+  IN UINT32                   MediaId,\r
+  IN EFI_LBA                  Lba,\r
+  IN UINTN                    BufferSize,\r
+  IN VOID                     *Buffer\r
+  );\r
+\r
+/**\r
+  Flushes all modified data to a physical block device.\r
+\r
+  @param  This                   Indicates a pointer to the calling context.\r
+\r
+  @retval EFI_SUCCESS            All outstanding data were written correctly to the device.\r
+  @retval EFI_DEVICE_ERROR       The device reported an error while attempting to write data.\r
+  @retval EFI_NO_MEDIA           There is no media in the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmcFlushBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *This\r
+  );\r
+\r
+#endif\r
diff --git a/ArmPkg/Universal/MmcDxe/MmcBlockIo.c b/ArmPkg/Universal/MmcDxe/MmcBlockIo.c
new file mode 100644 (file)
index 0000000..d8bd2d1
--- /dev/null
@@ -0,0 +1,558 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Protocol/MmcHost.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/TimerLib.h>\r
+\r
+#include "Mmc.h"\r
+\r
+// Untested ...\r
+//#define USE_STREAM\r
+\r
+#define MAX_RETRY_COUNT  200\r
+\r
+EFI_STATUS\r
+MmcNotifyState (\r
+  MMC_HOST_INSTANCE *MmcHostInstance,\r
+  MMC_STATE State\r
+  ) {\r
+    MmcHostInstance->State = State;\r
+    return MmcHostInstance->MmcHost->NotifyState(State);\r
+}\r
+\r
+VOID PrintOCR(UINT32 ocr) {\r
+    float minv, maxv, volts;\r
+    int loop;\r
+\r
+    minv  = 3.6;\r
+    maxv  = 2.0;\r
+    volts = 2.0;\r
+\r
+    // The MMC register bits [23:8] indicate the working range of the card\r
+    for (loop = 8; loop < 24; loop++) {\r
+        if (ocr & (1 << loop)) {\r
+            if (minv > volts) minv = volts;\r
+            if (maxv < volts) maxv = volts + 0.1;\r
+        }\r
+        volts = volts + 0.1;\r
+    }\r
+\r
+    DEBUG((EFI_D_ERROR, "- PrintOCR ocr (0x%X)\n",ocr));\r
+    //DEBUG((EFI_D_ERROR, "\t- Card operating voltage: %fV to %fV\n", minv, maxv));\r
+    if (((ocr >> 29) & 3) == 0)\r
+        DEBUG((EFI_D_ERROR, "\t- AccessMode: Byte Mode\n"));\r
+    else\r
+        DEBUG((EFI_D_ERROR, "\t- AccessMode: Block Mode (0x%X)\n",((ocr >> 29) & 3)));\r
+\r
+    if (ocr & MMC_OCR_POWERUP)\r
+        DEBUG((EFI_D_ERROR, "\t- PowerUp\n"));\r
+    else\r
+        DEBUG((EFI_D_ERROR, "\t- Voltage Not Supported\n"));\r
+}\r
+\r
+VOID PrintCID(UINT32* cid) {\r
+    DEBUG((EFI_D_ERROR, "- PrintCID\n"));\r
+    DEBUG((EFI_D_ERROR, "\t- Manufacturing date: %d/%d\n",(cid[0] >> 8) & 0xF,(cid[0] >> 12) & 0xFF));\r
+    DEBUG((EFI_D_ERROR, "\t- Product serial number: 0x%X%X\n",cid[1] & 0xFFFFFF,(cid[0] >> 24) & 0xFF));\r
+    DEBUG((EFI_D_ERROR, "\t- Product revision: %d\n",cid[1] >> 24));\r
+    //DEBUG((EFI_D_ERROR, "\t- Product name: %s\n",(char*)(cid + 2)));\r
+    DEBUG((EFI_D_ERROR, "\t- OEM ID: %c%c\n",(cid[3] >> 8) & 0xFF,(cid[3] >> 16) & 0xFF));\r
+}\r
+\r
+VOID PrintCSD(UINT32* csd) {\r
+    UINTN val32;\r
+    CONST CHAR8* str_unit[] = { "100kbit/s","1Mbit/s","10Mbit/s","100MBit/s","Unkbown","Unkbown","Unkbown","Unkbown" };\r
+    CONST CHAR8* str_value[] = { "1.0","1.2","1.3","1.5","2.0","2.5","3.0","3.5","4.0","4.5","5.0","Unknown","Unknown","Unknown","Unknown" };\r
+\r
+    if (((csd[2] >> 30) & 0x3) == 0)\r
+        DEBUG((EFI_D_ERROR, "- PrintCSD Version 1.01-1.10/Version 2.00/Standard Capacity\n"));\r
+    else if (((csd[2] >> 30) & 0x3) == 1)\r
+        DEBUG((EFI_D_ERROR, "- PrintCSD Version 2.00/High Capacity\n"));\r
+    else\r
+        DEBUG((EFI_D_ERROR, "- PrintCSD Version Higher than v3.3\n"));\r
+\r
+    DEBUG((EFI_D_ERROR, "\t- Supported card command class: 0x%X\n",MMC_CSD_GET_CCC(csd)));\r
+    DEBUG((EFI_D_ERROR, "\t- Speed: %a %a\n",str_value[(MMC_CSD_GET_TRANSPEED(csd) >> 3) & 0xF],str_unit[MMC_CSD_GET_TRANSPEED(csd) & 7]));\r
+    DEBUG((EFI_D_ERROR, "\t- Maximum Read Data Block: %d\n",2 << (MMC_CSD_GET_READBLLEN(csd)-1)));\r
+    DEBUG((EFI_D_ERROR, "\t- Maximum Write Data Block: %d\n",2 << (MMC_CSD_GET_WRITEBLLEN(csd)-1)));\r
+    \r
+    if (!MMC_CSD_GET_FILEFORMATGRP(csd)) {\r
+        val32 = MMC_CSD_GET_FILEFORMAT(csd);\r
+        if (val32 == 0)         DEBUG((EFI_D_ERROR, "\t- Format(0): Hard disk-like file system with partition table\n"));\r
+        else if (val32 == 1)    DEBUG((EFI_D_ERROR, "\t- Format(1): DOS FAT (floppy-like) with boot sector only (no partition table)\n"));\r
+        else if (val32 == 2)    DEBUG((EFI_D_ERROR, "\t- Format(2): Universal File Format\n"));\r
+        else                    DEBUG((EFI_D_ERROR, "\t- Format(3): Others/Unknown\n"));\r
+    } else {\r
+        DEBUG((EFI_D_ERROR, "\t- Format: Reserved\n"));\r
+    }\r
+}\r
+\r
+VOID PrintRCA(UINT32 rca) {\r
+    DEBUG((EFI_D_ERROR, "- PrintRCA: 0x%X\n",rca));\r
+    DEBUG((EFI_D_ERROR, "\t- Status: 0x%X\n",rca & 0xFFFF));\r
+    DEBUG((EFI_D_ERROR, "\t- RCA: 0x%X\n",(rca >> 16) & 0xFFFF));\r
+}\r
+\r
+VOID PrintResponseR1(UINT32 response) {\r
+    DEBUG((EFI_D_ERROR, "Response: 0x%X\n",response));\r
+    if (response & (1 << 8))                 DEBUG((EFI_D_ERROR, "\t- READY_FOR_DATA\n"));\r
+\r
+    if (((response >> 9) & 0xF) == 0)         DEBUG((EFI_D_ERROR, "\t- State: Idle\n"));\r
+    else if (((response >> 9) & 0xF) == 1)    DEBUG((EFI_D_ERROR, "\t- State: Ready\n"));\r
+    else if (((response >> 9) & 0xF) == 2)    DEBUG((EFI_D_ERROR, "\t- State: Ident\n"));\r
+    else if (((response >> 9) & 0xF) == 3)    DEBUG((EFI_D_ERROR, "\t- State: StandBy\n"));\r
+    else if (((response >> 9) & 0xF) == 4)    DEBUG((EFI_D_ERROR, "\t- State: Tran\n"));\r
+    else if (((response >> 9) & 0xF) == 5)    DEBUG((EFI_D_ERROR, "\t- State: Data\n"));\r
+    else if (((response >> 9) & 0xF) == 6)    DEBUG((EFI_D_ERROR, "\t- State: Rcv\n"));\r
+    else if (((response >> 9) & 0xF) == 7)    DEBUG((EFI_D_ERROR, "\t- State: Prg\n"));\r
+    else if (((response >> 9) & 0xF) == 8)    DEBUG((EFI_D_ERROR, "\t- State: Dis\n"));\r
+    else                                     DEBUG((EFI_D_ERROR, "\t- State: Reserved\n"));\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcIdentificationMode (\r
+  MMC_HOST_INSTANCE     *MmcHostInstance\r
+  ) {\r
+    EFI_STATUS              Status;\r
+    UINT32                  Response[4];\r
+    UINTN                   timer;\r
+    UINTN                   CmdArg;\r
+    BOOLEAN                 bHCS;\r
+    EFI_MMC_HOST_PROTOCOL   *MmcHost;\r
+    \r
+    MmcHost = MmcHostInstance->MmcHost;\r
+    CmdArg = 0;\r
+    bHCS = FALSE;\r
+\r
+    if (MmcHost == NULL) {\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    // We can get into this function if we restart the identification mode\r
+    if (MmcHostInstance->State == MmcHwInitializationState) {\r
+        // Initialize the MMC Host HW\r
+        Status = MmcNotifyState (MmcHostInstance, MmcHwInitializationState);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcHwInitializationState\n"));\r
+            return Status;\r
+        }\r
+    } else {\r
+        //Note: Could even be used in all cases. But it looks this command could put the state machine into inactive for some cards\r
+        Status = MmcHost->SendCommand(MMC_CMD0, 0);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD0): Error\n"));\r
+            return Status;\r
+        }\r
+    }\r
+\r
+    Status = MmcNotifyState (MmcHostInstance, MmcIdleState);\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdleState\n"));\r
+        return Status;\r
+    }\r
+\r
+    // Are we using SDIO ?\r
+    Status = MmcHost->SendCommand(MMC_CMD5, 0);\r
+    if (Status == EFI_SUCCESS) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported.\n"));\r
+        return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)\r
+    CmdArg = (0x0UL << 12 | BIT8 | 0xCEUL << 0);\r
+    Status = MmcHost->SendCommand(MMC_CMD8, CmdArg);\r
+    if (Status == EFI_SUCCESS) {\r
+        DEBUG ((EFI_D_ERROR, "Card is SD2.0 => Supports high capacity\n"));\r
+        bHCS = TRUE;\r
+        MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R7,Response);\r
+        PrintResponseR1(Response[0]);\r
+    } else {\r
+        DEBUG ((EFI_D_ERROR, "Not a SD2.0 Card\n"));\r
+    }\r
+\r
+    // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.Busy == 1)\r
+    timer = MAX_RETRY_COUNT;\r
+    while (timer > 0) {\r
+        // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command\r
+        Status = MmcHost->SendCommand(MMC_CMD55, 0);\r
+        if (Status == EFI_SUCCESS) {\r
+            DEBUG ((EFI_D_INFO, "Card should be SD\n"));\r
+            if (bHCS) {\r
+                MmcHostInstance->CardInfo.CardType = SD_CARD_2;\r
+            } else {\r
+                MmcHostInstance->CardInfo.CardType = SD_CARD;\r
+            }\r
+\r
+            // Note: The first time CmdArg will be zero\r
+            CmdArg = ((UINTN *) &(MmcHostInstance->CardInfo.OCRData))[0];\r
+            if (bHCS) {\r
+                CmdArg |= BIT30;\r
+            }\r
+            Status = MmcHost->SendCommand(MMC_ACMD41, CmdArg);\r
+            if (EFI_ERROR(Status)) {\r
+                DEBUG((EFI_D_ERROR, "MmcIdentificationMode(ACMD41): Error\n"));\r
+                return Status;\r
+            }\r
+            MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_OCR,Response);\r
+            ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
+        } else {\r
+            DEBUG ((EFI_D_INFO, "Card should be MMC\n"));\r
+            MmcHostInstance->CardInfo.CardType = MMC_CARD;\r
+\r
+            Status = MmcHost->SendCommand(MMC_CMD1, 0x800000);\r
+            if (EFI_ERROR(Status)) {\r
+                DEBUG((EFI_D_ERROR, "MmcIdentificationMode(ACMD41): Error\n"));\r
+                return Status;\r
+            }\r
+            MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_OCR,Response);\r
+            ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
+        }\r
+\r
+        if (MmcHostInstance->CardInfo.OCRData.Busy == 0) {\r
+            MicroSecondDelay(10*1000);\r
+            timer--;\r
+        } else {\r
+            if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {\r
+                MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;\r
+                DEBUG ((EFI_D_ERROR, "High capacity card.\n"));\r
+            }\r
+            break;  // The MMC/SD card is ready. Continue the Identification Mode\r
+        }\r
+    }\r
+\r
+    if (timer == 0) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode(): No Card\n"));\r
+        ASSERT(0);\r
+        return EFI_NO_MEDIA;\r
+    } else {\r
+        PrintOCR(Response[0]);\r
+    }\r
+\r
+    Status = MmcNotifyState (MmcHostInstance, MmcReadyState);\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcReadyState\n"));\r
+        return Status;\r
+    }\r
+\r
+    Status = MmcHost->SendCommand(MMC_CMD2, 0);\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD2): Error\n"));\r
+        ASSERT(0);\r
+        return Status;\r
+    }\r
+    MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_CID,Response);\r
+    PrintCID(Response);\r
+\r
+    Status = MmcNotifyState (MmcHostInstance, MmcIdentificationState);\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdentificationState\n"));\r
+        return Status;\r
+    }\r
+\r
+    CmdArg = 0;\r
+    Status = MmcHost->SendCommand(MMC_CMD3, CmdArg);\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));\r
+        return Status;\r
+    }\r
+    MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_RCA,Response);\r
+    PrintRCA(Response[0]);\r
+\r
+    // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card\r
+    if (MmcHostInstance->CardInfo.CardType != MMC_CARD) {\r
+        MmcHostInstance->CardInfo.RCA = Response[0] >> 16;\r
+    } else {\r
+        MmcHostInstance->CardInfo.RCA = CmdArg;\r
+    }\r
+\r
+    Status = MmcNotifyState (MmcHostInstance, MmcStandByState);\r
+    if (EFI_ERROR(Status)) {\r
+        DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcStandByState\n"));\r
+        return Status;\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcReset (\r
+  IN EFI_BLOCK_IO_PROTOCOL    *This,\r
+  IN BOOLEAN                  ExtendedVerification\r
+  ) {\r
+    // Implement me. Either send a CMD0 (could not work for some MMC host) or just turn off/turn\r
+    //      on power and restart Identification mode\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+MmcDetectCard (\r
+  EFI_MMC_HOST_PROTOCOL     *MmcHost\r
+  )\r
+{\r
+    if (!MmcHost->IsCardPresent()) {\r
+        return EFI_NO_MEDIA;\r
+    } else {\r
+        return EFI_SUCCESS;\r
+    }\r
+}\r
+\r
+#define MMCI0_BLOCKLEN 512\r
+#define MMCI0_TIMEOUT  10000\r
+\r
+EFI_STATUS MmcIoBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL    *This,\r
+  IN UINTN                    Transfer,\r
+  IN UINT32                   MediaId,\r
+  IN EFI_LBA                  Lba,\r
+  IN UINTN                    BufferSize,\r
+  OUT VOID                    *Buffer\r
+  ) {\r
+    UINT32                  Response[4];\r
+    EFI_STATUS              Status;\r
+    UINTN                   CardSize, NumBlocks, BlockSize, CmdArg;\r
+    UINTN                   timer;\r
+    UINTN                   Cmd;\r
+    MMC_HOST_INSTANCE       *MmcHostInstance;\r
+    EFI_MMC_HOST_PROTOCOL   *MmcHost;\r
+    UINTN                   BytesRemainingToBeTransfered;\r
+    UINTN                   BlockCount = 1;\r
+\r
+    MmcHostInstance = MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS(This);\r
+    ASSERT(MmcHostInstance != 0);\r
+    MmcHost = MmcHostInstance->MmcHost;\r
+    ASSERT(MmcHost);\r
+\r
+    if (MmcHost == 0) {\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    // Check if a Card is Present\r
+    if (!MmcHost->IsCardPresent()) {\r
+        MmcHostInstance->BlockIo.Media->MediaPresent = FALSE;\r
+        MmcHostInstance->BlockIo.Media->LastBlock    = 0;\r
+        MmcHostInstance->BlockIo.Media->BlockSize    = 512;  // Should be zero but there is a bug in DiskIo\r
+        MmcHostInstance->BlockIo.Media->ReadOnly     = FALSE; \r
+        return EFI_NO_MEDIA;\r
+    }\r
+\r
+    // If the driver has not been initialized yet then go into Iddentification Mode\r
+    if (MmcHostInstance->State == MmcHwInitializationState) {\r
+        MmcIdentificationMode (MmcHostInstance);\r
+\r
+        CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
+        Status = MmcHost->SendCommand(MMC_CMD9, CmdArg);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD9): Error\n"));\r
+            ASSERT(0);\r
+            return Status;\r
+        }\r
+        MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_CSD,Response);\r
+        PrintCSD(Response);\r
+\r
+\r
+        if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {\r
+            ASSERT(0);  //TODO: Implementation needed\r
+            CardSize = MMC_CSD_GET_DEVICESIZE(Response);\r
+            NumBlocks = ((CardSize + 1) * 1024);;\r
+            BlockSize = 1 << MMC_CSD_GET_READBLLEN(Response);\r
+        } else {\r
+            CardSize = MMC_CSD_GET_DEVICESIZE(Response);\r
+            NumBlocks = (CardSize + 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT(Response) + 2));\r
+            BlockSize = 1 << MMC_CSD_GET_READBLLEN(Response);\r
+        }\r
+\r
+        //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.\r
+        if (BlockSize > 512) {\r
+            NumBlocks = MultU64x32(NumBlocks, BlockSize/512);\r
+            BlockSize = 512;        \r
+        }\r
+\r
+        MmcHostInstance->BlockIo.Media->LastBlock    = (NumBlocks - 1);\r
+        MmcHostInstance->BlockIo.Media->BlockSize    = BlockSize;\r
+        MmcHostInstance->BlockIo.Media->ReadOnly     = MmcHost->IsReadOnly();\r
+        MmcHostInstance->BlockIo.Media->MediaPresent = TRUE; \r
+        MmcHostInstance->BlockIo.Media->MediaId++; \r
+\r
+        CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
+        Status = MmcHost->SendCommand(MMC_CMD7, CmdArg);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD7): Error\n"));\r
+            ASSERT(0);\r
+            return Status;\r
+        }\r
+        \r
+        Status = MmcNotifyState (MmcHostInstance, MmcTransferState);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcTransferState\n"));\r
+            return Status;\r
+        }\r
+    } else {\r
+        // Maybe test if the card has changed to update gMmcMedia information\r
+        if (MmcHostInstance->State == MmcTransferState) {\r
+            //DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : MmcTransferState\n"));\r
+        } else if (MmcHostInstance->State == MmcStandByState) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : MmcStandByState\n"));\r
+        } else {\r
+            ASSERT(0);\r
+        }\r
+    }\r
+\r
+    if (Lba > This->Media->LastBlock) {\r
+        ASSERT(0);\r
+        return EFI_INVALID_PARAMETER;\r
+    }\r
+  \r
+    if ((BufferSize % This->Media->BlockSize) != 0) {\r
+        ASSERT(0);\r
+        return EFI_BAD_BUFFER_SIZE;\r
+    }\r
+\r
+    BytesRemainingToBeTransfered = BufferSize;\r
+    while (BytesRemainingToBeTransfered > 0) {\r
+        // Set Block Length\r
+        Status = MmcHost->SendCommand(MMC_CMD16, This->Media->BlockSize);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD16): Error This->Media->BlockSize:%d\n",This->Media->BlockSize));\r
+            ASSERT(0);\r
+            return Status;\r
+        }\r
+\r
+        // Block Count (not used). Could return an error for SD card\r
+        MmcHost->SendCommand(MMC_CMD23, BlockCount);\r
+\r
+        //Set command argument based on the card access mode (Byte mode or Block mode)\r
+        if (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1) {\r
+            CmdArg = Lba;\r
+        } else {\r
+            CmdArg = Lba * This->Media->BlockSize;\r
+        }\r
+\r
+        if (Transfer == MMC_IOBLOCKS_READ) {\r
+#ifndef USE_STREAM\r
+            // Read a single block\r
+            Cmd = MMC_CMD17;\r
+#else\r
+            //TODO: Should we support read stream (MMC_CMD11)\r
+#endif\r
+        } else {\r
+#ifndef USE_STREAM\r
+            // Write a single block\r
+            Cmd = MMC_CMD24;\r
+#else\r
+            //TODO: Should we support write stream (MMC_CMD20)\r
+#endif\r
+        }\r
+        Status = MmcHost->SendCommand(Cmd, CmdArg);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD%d): Error\n",Cmd));\r
+            ASSERT(0);\r
+            return Status;\r
+        }\r
+\r
+        if (Transfer == MMC_IOBLOCKS_READ) {\r
+#ifndef USE_STREAM\r
+            // Read one block of Data\r
+            Status = MmcHost->ReadBlockData(Lba,This->Media->BlockSize,Buffer);\r
+            if (EFI_ERROR(Status)) {\r
+                DEBUG((EFI_D_BLKIO, "MmcIdentificationMode(): Error Read Block Data"));\r
+                ASSERT(0);\r
+                return Status;\r
+            }\r
+#else\r
+            //TODO: Read a steam\r
+            ASSERT(0);\r
+#endif\r
+            Status = MmcNotifyState (MmcHostInstance, MmcProgrammingState);\r
+            if (EFI_ERROR(Status)) {\r
+                DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcProgrammingState\n"));\r
+                return Status;\r
+            }\r
+        } else {\r
+#ifndef USE_STREAM\r
+            // Write one block of Data\r
+            Status = MmcHost->WriteBlockData(Lba,This->Media->BlockSize,Buffer);\r
+            if (EFI_ERROR(Status)) {\r
+                DEBUG((EFI_D_BLKIO, "MmcIdentificationMode(): Error Write Block Data"));\r
+                ASSERT(0);\r
+                return Status;\r
+            }\r
+#else\r
+            //TODO: Write a steam\r
+            ASSERT(0);\r
+#endif\r
+        }\r
+\r
+        // Command 12 - Stop transmission (ends read)\r
+        Status = MmcHost->SendCommand(MMC_CMD12, 0);\r
+        MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1b,Response);\r
+\r
+        // Command 13 - Read status and wait for programming to complete (return to tran)\r
+        timer = MMCI0_TIMEOUT;\r
+        while ((MMC_R0_CURRENTSTATE(Response) != MMC_R0_STATE_TRAN) && timer) {\r
+            MmcHost->SendCommand(MMC_CMD13, 0);\r
+            MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1,Response);\r
+            NanoSecondDelay(100);\r
+            timer--;\r
+        }\r
+\r
+        Status = MmcNotifyState (MmcHostInstance, MmcTransferState);\r
+        if (EFI_ERROR(Status)) {\r
+            DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcTransferState\n"));\r
+            return Status;\r
+        }\r
+\r
+        BytesRemainingToBeTransfered -= This->Media->BlockSize;\r
+        Lba    += BlockCount;\r
+        Buffer = (UINT8 *)Buffer + This->Media->BlockSize;\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcReadBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL    *This,\r
+  IN UINT32                   MediaId,\r
+  IN EFI_LBA                  Lba,\r
+  IN UINTN                    BufferSize,\r
+  OUT VOID                    *Buffer\r
+  ) {\r
+    return MmcIoBlocks (This, MMC_IOBLOCKS_READ, MediaId, Lba, BufferSize, Buffer);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcWriteBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL    *This,\r
+  IN UINT32                   MediaId,\r
+  IN EFI_LBA                  Lba,\r
+  IN UINTN                    BufferSize,\r
+  IN VOID                     *Buffer\r
+  ) {\r
+    return MmcIoBlocks (This, MMC_IOBLOCKS_WRITE, MediaId, Lba, BufferSize, Buffer);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcFlushBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *This\r
+  ) {\r
+    return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/ArmPkg/Universal/MmcDxe/MmcDxe.inf b/ArmPkg/Universal/MmcDxe/MmcDxe.inf
new file mode 100644 (file)
index 0000000..dbdd1ef
--- /dev/null
@@ -0,0 +1,50 @@
+#/** @file\r
+#  Build file for the MMC DXE driver\r
+#\r
+#  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+#  \r
+#  This program and the accompanying materials                          \r
+#  are licensed and made available under the terms and conditions of the BSD License         \r
+#  which accompanies this distribution.  The full text of the license may be found at        \r
+#  http://opensource.org/licenses/bsd-license.php                                            \r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = MmcDxe\r
+  FILE_GUID                      = b6f44cc0-9e45-11df-be21-0002a5d5c51b\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = MmcDxeInitialize\r
+\r
+[Sources.common]\r
+  ComponentName.c\r
+  Mmc.c\r
+  MmcBlockIo.c\r
+  Diagnostics.c\r
+\r
+[Packages]\r
+  ArmPkg/ArmPkg.dec\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  BaseMemoryLib\r
+  TimerLib\r
+\r
+[Protocols]\r
+  gEfiDiskIoProtocolGuid\r
+  gEfiBlockIoProtocolGuid\r
+  gEfiDevicePathProtocolGuid\r
+  gEfiMmcHostProtocolGuid\r
+  gEfiDriverDiagnostics2ProtocolGuid\r
+  \r
+[Depex]\r
+  TRUE
\ No newline at end of file