ArmPkg: Moved ARMv7 specific files to a 'Arm' subdirectory
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 12 Mar 2013 00:49:42 +0000 (00:49 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 12 Mar 2013 00:49:42 +0000 (00:49 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14180 6f19259b-4bc3-4df7-8a09-765794883524

37 files changed:
ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c [new file with mode: 0644]
ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c [new file with mode: 0644]
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
ArmPkg/Drivers/CpuDxe/Exception.c [deleted file]
ArmPkg/Drivers/CpuDxe/Mmu.c [deleted file]
ArmPkg/Library/ArmLib/Arm11/Arm11Lib.inf
ArmPkg/Library/ArmLib/Arm11/Arm11LibPrePi.inf
ArmPkg/Library/ArmLib/Arm11/Arm11LibSec.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/Common/Arm/ArmLibSupport.S [new file with mode: 0644]
ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm [new file with mode: 0644]
ArmPkg/Library/ArmLib/Common/ArmLibSupport.S [deleted file]
ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm [deleted file]
ArmPkg/Library/ArmLib/Null/NullArmLib.inf
ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c [new file with mode: 0644]
ArmPkg/Library/BdsLib/BdsLib.inf
ArmPkg/Library/BdsLib/BdsLinuxAtag.c [deleted file]
ArmPkg/Library/BdsLib/BdsLinuxLoader.c [deleted file]
ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S [new file with mode: 0644]
ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm [new file with mode: 0644]
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentException.S [deleted file]
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentException.asm [deleted file]
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c [new file with mode: 0644]
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c [deleted file]
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
ArmPkg/Library/SemihostLib/Arm/SemihostLib.c [deleted file]
ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h [deleted file]
ArmPkg/Library/SemihostLib/SemihostLib.c [new file with mode: 0644]
ArmPkg/Library/SemihostLib/SemihostLib.inf
ArmPkg/Library/SemihostLib/SemihostPrivate.h [new file with mode: 0644]

diff --git a/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c b/ArmPkg/Drivers/CpuDxe/ArmV6/Exception.c
new file mode 100644 (file)
index 0000000..55a7132
--- /dev/null
@@ -0,0 +1,230 @@
+/** @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 "CpuDxe.h" \r
+\r
+//FIXME: Will not compile on non-ARMv7 builds\r
+#include <Chipset/ArmV7.h>\r
+\r
+VOID\r
+ExceptionHandlersStart (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+ExceptionHandlersEnd (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+CommonExceptionEntry (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+AsmCommonExceptionEntry (\r
+  VOID\r
+  );\r
+\r
+\r
+EFI_EXCEPTION_CALLBACK  gExceptionHandlers[MAX_ARM_EXCEPTION + 1];\r
+EFI_EXCEPTION_CALLBACK  gDebuggerExceptionHandlers[MAX_ARM_EXCEPTION + 1];\r
+\r
+\r
+\r
+/**\r
+  This function registers and enables the handler specified by InterruptHandler for a processor \r
+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the \r
+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled. \r
+  The installed handler is called once for each processor interrupt or exception.\r
+\r
+  @param  InterruptType    A pointer to the processor's current interrupt state. Set to TRUE if interrupts\r
+                           are enabled and FALSE if interrupts are disabled.\r
+  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+                           when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+                           will be uninstalled.\r
+\r
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.\r
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was\r
+                                previously installed.\r
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+                                previously installed.\r
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+RegisterInterruptHandler (\r
+  IN EFI_EXCEPTION_TYPE             InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler\r
+  )\r
+{\r
+  if (InterruptType > MAX_ARM_EXCEPTION) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+\r
+  gExceptionHandlers[InterruptType] = InterruptHandler;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+CommonCExceptionHandler (\r
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,\r
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext\r
+  )\r
+{\r
+  if (ExceptionType <= MAX_ARM_EXCEPTION) {\r
+    if (gExceptionHandlers[ExceptionType]) {\r
+      gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);\r
+      return;\r
+    }\r
+  } else {\r
+    DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %08x\n", ExceptionType, SystemContext.SystemContextArm->PC));\r
+    ASSERT (FALSE);\r
+  }\r
+  \r
+  if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {\r
+    //\r
+    // ARM JTAG debuggers some times use this vector, so it is not an error to get one\r
+    //\r
+    return;\r
+  }\r
+\r
+  DefaultExceptionHandler (ExceptionType, SystemContext);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+InitializeExceptions (\r
+  IN EFI_CPU_ARCH_PROTOCOL    *Cpu\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+  UINTN                Offset;\r
+  UINTN                Length;\r
+  UINTN                Index;\r
+  BOOLEAN              IrqEnabled;\r
+  BOOLEAN              FiqEnabled;\r
+  EFI_PHYSICAL_ADDRESS Base;\r
+  UINT32               *VectorBase;\r
+\r
+  Status = EFI_SUCCESS;\r
+  ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers));\r
+\r
+  //\r
+  // Disable interrupts\r
+  //\r
+  Cpu->GetInterruptState (Cpu, &IrqEnabled);\r
+  Cpu->DisableInterrupt (Cpu);\r
+\r
+  //\r
+  // EFI does not use the FIQ, but a debugger might so we must disable \r
+  // as we take over the exception vectors. \r
+  //\r
+  FiqEnabled = ArmGetFiqState ();\r
+  ArmDisableFiq ();\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
+    // Check if the exception vector is in the low address\r
+    if (PcdGet32 (PcdCpuVectorBaseAddress) == 0x0) {\r
+      // Set SCTLR.V to 0 to enable VBAR to be used\r
+      ArmSetLowVectors ();\r
+    } else {\r
+      ArmSetHighVectors ();\r
+    }\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
+    if (FeaturePcdGet(PcdDebuggerExceptionSupport) == TRUE) {\r
+      // Save existing vector table, in case debugger is already hooked in\r
+      CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));\r
+    }\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 (!FeaturePcdGet(PcdDebuggerExceptionSupport) ||\r
+          (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 already 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
+    // The Vector table must be 32-byte aligned\r
+    ASSERT(((UINT32)ExceptionHandlersStart & ((1 << 5)-1)) == 0);\r
+\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
+  if (FiqEnabled) {\r
+    ArmEnableFiq ();\r
+  }\r
+\r
+  if (IrqEnabled) {\r
+    // \r
+    // Restore interrupt state\r
+    //\r
+    Status = Cpu->EnableInterrupt (Cpu);\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c b/ArmPkg/Drivers/CpuDxe/ArmV6/Mmu.c
new file mode 100644 (file)
index 0000000..dcc7b68
--- /dev/null
@@ -0,0 +1,944 @@
+/*++\r
+\r
+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>\r
+Portions copyright (c) 2010, 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
+\r
+#include "CpuDxe.h"\r
+\r
+// First Level Descriptors\r
+typedef UINT32    ARM_FIRST_LEVEL_DESCRIPTOR;\r
+\r
+// Second Level Descriptors\r
+typedef UINT32    ARM_PAGE_TABLE_ENTRY;\r
+\r
+EFI_STATUS \r
+SectionToGcdAttributes (\r
+  IN  UINT32  SectionAttributes,\r
+  OUT UINT64  *GcdAttributes\r
+  )\r
+{\r
+  *GcdAttributes = 0;\r
+\r
+  // determine cacheability attributes\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 TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE:\r
+      *GcdAttributes |= EFI_MEMORY_UC;\r
+      break;\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:\r
+      *GcdAttributes |= EFI_MEMORY_WT;\r
+      break;\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC:\r
+      *GcdAttributes |= EFI_MEMORY_WB;\r
+      break;\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE:\r
+      *GcdAttributes |= EFI_MEMORY_WC;\r
+      break;\r
+    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC:\r
+      *GcdAttributes |= EFI_MEMORY_WB;\r
+      break;\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
+  // determine protection attributes\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 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 TT_DESCRIPTOR_SECTION_AP_RO_NO:\r
+    case TT_DESCRIPTOR_SECTION_AP_RO_RO:\r
+      *GcdAttributes |= EFI_MEMORY_WP;\r
+      break;\r
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  // now process eXectue Never attribute\r
+  if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {\r
+    *GcdAttributes |= EFI_MEMORY_XP;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PageToGcdAttributes (\r
+  IN  UINT32  PageAttributes,\r
+  OUT UINT64  *GcdAttributes\r
+  )\r
+{\r
+  *GcdAttributes = 0;\r
+\r
+  // determine cacheability attributes\r
+  switch(PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {\r
+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:\r
+      *GcdAttributes |= EFI_MEMORY_UC;\r
+      break;\r
+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE:\r
+      *GcdAttributes |= EFI_MEMORY_UC;\r
+      break;\r
+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:\r
+      *GcdAttributes |= EFI_MEMORY_WT;\r
+      break;\r
+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC:\r
+      *GcdAttributes |= EFI_MEMORY_WB;\r
+      break;\r
+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE:\r
+      *GcdAttributes |= EFI_MEMORY_WC;\r
+      break;\r
+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC:\r
+      *GcdAttributes |= EFI_MEMORY_WB;\r
+      break;\r
+    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE:\r
+      *GcdAttributes |= EFI_MEMORY_UC;\r
+      break;\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  // determine protection attributes\r
+  switch(PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) {\r
+    case TT_DESCRIPTOR_PAGE_AP_NO_NO: // no read, no write\r
+      //*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;\r
+      break;\r
+\r
+    case TT_DESCRIPTOR_PAGE_AP_RW_NO:\r
+    case TT_DESCRIPTOR_PAGE_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 TT_DESCRIPTOR_PAGE_AP_RO_NO:\r
+    case TT_DESCRIPTOR_PAGE_AP_RO_RO:\r
+      *GcdAttributes |= EFI_MEMORY_WP;\r
+      break;\r
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  // now process eXectue Never attribute\r
+  if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {\r
+    *GcdAttributes |= EFI_MEMORY_XP;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Searches memory descriptors covered by given memory range.\r
+\r
+  This function searches into the Gcd Memory Space for descriptors\r
+  (from StartIndex to EndIndex) that contains the memory range\r
+  specified by BaseAddress and Length.\r
+\r
+  @param  MemorySpaceMap       Gcd Memory Space Map as array.\r
+  @param  NumberOfDescriptors  Number of descriptors in map.\r
+  @param  BaseAddress          BaseAddress for the requested range.\r
+  @param  Length               Length for the requested range.\r
+  @param  StartIndex           Start index into the Gcd Memory Space Map.\r
+  @param  EndIndex             End index into the Gcd Memory Space Map.\r
+\r
+  @retval EFI_SUCCESS          Search successfully.\r
+  @retval EFI_NOT_FOUND        The requested descriptors does not exist.\r
+\r
+**/\r
+EFI_STATUS\r
+SearchGcdMemorySpaces (\r
+  IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap,\r
+  IN UINTN                               NumberOfDescriptors,\r
+  IN EFI_PHYSICAL_ADDRESS                BaseAddress,\r
+  IN UINT64                              Length,\r
+  OUT UINTN                              *StartIndex,\r
+  OUT UINTN                              *EndIndex\r
+  )\r
+{\r
+  UINTN           Index;\r
+\r
+  *StartIndex = 0;\r
+  *EndIndex   = 0;\r
+  for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+    if (BaseAddress >= MemorySpaceMap[Index].BaseAddress &&\r
+        BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
+      *StartIndex = Index;\r
+    }\r
+    if (BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress &&\r
+        BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
+      *EndIndex = Index;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+  Sets the attributes for a specified range in Gcd Memory Space Map.\r
+\r
+  This function sets the attributes for a specified range in\r
+  Gcd Memory Space Map.\r
+\r
+  @param  MemorySpaceMap       Gcd Memory Space Map as array\r
+  @param  NumberOfDescriptors  Number of descriptors in map\r
+  @param  BaseAddress          BaseAddress for the range\r
+  @param  Length               Length for the range\r
+  @param  Attributes           Attributes to set\r
+\r
+  @retval EFI_SUCCESS          Memory attributes set successfully\r
+  @retval EFI_NOT_FOUND        The specified range does not exist in Gcd Memory Space\r
+\r
+**/\r
+EFI_STATUS\r
+SetGcdMemorySpaceAttributes (\r
+  IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap,\r
+  IN UINTN                               NumberOfDescriptors,\r
+  IN EFI_PHYSICAL_ADDRESS                BaseAddress,\r
+  IN UINT64                              Length,\r
+  IN UINT64                              Attributes\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINTN                 Index;\r
+  UINTN                 StartIndex;\r
+  UINTN                 EndIndex;\r
+  EFI_PHYSICAL_ADDRESS  RegionStart;\r
+  UINT64                RegionLength;\r
+\r
+  //\r
+  // Get all memory descriptors covered by the memory range\r
+  //\r
+  Status = SearchGcdMemorySpaces (\r
+             MemorySpaceMap,\r
+             NumberOfDescriptors,\r
+             BaseAddress,\r
+             Length,\r
+             &StartIndex,\r
+             &EndIndex\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Go through all related descriptors and set attributes accordingly\r
+  //\r
+  for (Index = StartIndex; Index <= EndIndex; Index++) {\r
+    if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {\r
+      continue;\r
+    }\r
+    //\r
+    // Calculate the start and end address of the overlapping range\r
+    //\r
+    if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {\r
+      RegionStart = BaseAddress;\r
+    } else {\r
+      RegionStart = MemorySpaceMap[Index].BaseAddress;\r
+    }\r
+    if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
+      RegionLength = BaseAddress + Length - RegionStart;\r
+    } else {\r
+      RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;\r
+    }\r
+    //\r
+    // Set memory attributes according to MTRR attribute and the original attribute of descriptor\r
+    //\r
+    gDS->SetMemorySpaceAttributes (\r
+           RegionStart,\r
+           RegionLength,\r
+           (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)\r
+           );\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+SyncCacheConfigPage (\r
+  IN     UINT32                             SectionIndex,\r
+  IN     UINT32                             FirstLevelDescriptor,\r
+  IN     UINTN                              NumberOfDescriptors,\r
+  IN     EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap,\r
+  IN OUT EFI_PHYSICAL_ADDRESS               *NextRegionBase,\r
+  IN OUT UINT64                             *NextRegionLength,\r
+  IN OUT UINT32                             *NextSectionAttributes\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  UINT32                              i;\r
+  volatile ARM_PAGE_TABLE_ENTRY       *SecondLevelTable;\r
+  UINT32                              NextPageAttributes = 0;\r
+  UINT32                              PageAttributes = 0;\r
+  UINT32                              BaseAddress;\r
+  UINT64                              GcdAttributes;\r
+\r
+  // Get the Base Address from FirstLevelDescriptor;\r
+  BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
+\r
+  // Convert SectionAttributes into PageAttributes\r
+  NextPageAttributes =\r
+      TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(*NextSectionAttributes,0) |\r
+      TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(*NextSectionAttributes);\r
+\r
+  // obtain page table base\r
+  SecondLevelTable = (ARM_PAGE_TABLE_ENTRY *)(FirstLevelDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);\r
+\r
+  for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {\r
+    if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {\r
+      // extract attributes (cacheability and permissions)\r
+      PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK);\r
+\r
+      if (NextPageAttributes == 0) {\r
+        // start on a new region\r
+        *NextRegionLength = 0;\r
+        *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);\r
+        NextPageAttributes = PageAttributes;\r
+      } else if (PageAttributes != NextPageAttributes) {\r
+        // Convert Section Attributes into GCD Attributes\r
+        Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);\r
+        ASSERT_EFI_ERROR (Status);\r
+\r
+        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
+        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);\r
+\r
+        // start on a new region\r
+        *NextRegionLength = 0;\r
+        *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);\r
+        NextPageAttributes = PageAttributes;\r
+      }\r
+    } else if (NextPageAttributes != 0) {\r
+      // Convert Page Attributes into GCD Attributes\r
+      Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
+      SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);\r
+\r
+      *NextRegionLength = 0;\r
+      *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);\r
+      NextPageAttributes = 0;\r
+    }\r
+    *NextRegionLength += TT_DESCRIPTOR_PAGE_SIZE;\r
+  }\r
+\r
+  // Convert back PageAttributes into SectionAttributes\r
+  *NextSectionAttributes =\r
+      TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(NextPageAttributes,0) |\r
+      TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(NextPageAttributes);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+SyncCacheConfig (\r
+  IN  EFI_CPU_ARCH_PROTOCOL *CpuProtocol\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  UINT32                              i;\r
+  EFI_PHYSICAL_ADDRESS                NextRegionBase;\r
+  UINT64                              NextRegionLength;\r
+  UINT32                              NextSectionAttributes = 0;\r
+  UINT32                              SectionAttributes = 0;\r
+  UINT64                              GcdAttributes;\r
+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
+  UINTN                               NumberOfDescriptors;\r
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap;\r
+\r
+\r
+  DEBUG ((EFI_D_PAGE, "SyncCacheConfig()\n"));\r
+\r
+  // This code assumes MMU is enabled and filed with section translations\r
+  ASSERT (ArmMmuEnabled ());\r
+\r
+  //\r
+  // Get the memory space map from GCD\r
+  //\r
+  MemorySpaceMap = NULL;\r
+  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  // The GCD implementation maintains its own copy of the state of memory space attributes.  GCD needs\r
+  // to know what the initial memory space attributes are.  The CPU Arch. Protocol does not provide a\r
+  // GetMemoryAttributes function for GCD to get this so we must resort to calling GCD (as if we were\r
+  // a client) to update its copy of the attributes.  This is bad architecture and should be replaced\r
+  // 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 *)(ArmGetTTBR0BaseAddress ());\r
+\r
+  // Get the first region\r
+  NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);\r
+\r
+  // iterate through each 1MB descriptor\r
+  NextRegionBase = NextRegionLength = 0;\r
+  for (i=0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {\r
+    if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {\r
+      // extract attributes (cacheability and permissions)\r
+      SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);\r
+\r
+      if (NextSectionAttributes == 0) {\r
+        // start on a new region\r
+        NextRegionLength = 0;\r
+        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
+        NextSectionAttributes = SectionAttributes;\r
+      } else if (SectionAttributes != NextSectionAttributes) {\r
+        // Convert Section Attributes into GCD Attributes\r
+        Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);\r
+        ASSERT_EFI_ERROR (Status);\r
+\r
+        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
+        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);\r
+\r
+        // start on a new region\r
+        NextRegionLength = 0;\r
+        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
+        NextSectionAttributes = SectionAttributes;\r
+      }\r
+      NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;\r
+    } else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(FirstLevelTable[i])) {\r
+      Status = SyncCacheConfigPage (\r
+          i,FirstLevelTable[i],\r
+          NumberOfDescriptors, MemorySpaceMap,\r
+          &NextRegionBase,&NextRegionLength,&NextSectionAttributes);\r
+      ASSERT_EFI_ERROR (Status);\r
+    } else {\r
+      // We do not support yet 16MB sections\r
+      ASSERT ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) != TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION);\r
+\r
+      // start on a new region\r
+      if (NextSectionAttributes != 0) {\r
+        // Convert Section Attributes into GCD Attributes\r
+        Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);\r
+        ASSERT_EFI_ERROR (Status);\r
+\r
+        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
+        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);\r
+\r
+        NextRegionLength = 0;\r
+        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
+        NextSectionAttributes = 0;\r
+      }\r
+      NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;\r
+    }\r
+  } // section entry loop\r
+\r
+  if (NextSectionAttributes != 0) {\r
+    // Convert Section Attributes into GCD Attributes\r
+    Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
+    SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+UpdatePageEntries (\r
+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN UINT64                    Length,\r
+  IN UINT64                    Attributes,\r
+  IN EFI_PHYSICAL_ADDRESS      VirtualMask\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINT32        EntryValue;\r
+  UINT32        EntryMask;\r
+  UINT32        FirstLevelIdx;\r
+  UINT32        Offset;\r
+  UINT32        NumPageEntries;\r
+  UINT32        Descriptor;\r
+  UINT32        p;\r
+  UINT32        PageTableIndex;\r
+  UINT32        PageTableEntry;\r
+  UINT32        CurrentPageTableEntry;\r
+  VOID          *Mva;\r
+\r
+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
+  volatile ARM_PAGE_TABLE_ENTRY         *PageTable;\r
+\r
+  Status = EFI_SUCCESS;\r
+\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 = 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 |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
+      // map to strongly ordered\r
+      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
+      break;\r
+\r
+    case EFI_MEMORY_WC:\r
+      // modify cacheability attributes\r
+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\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
+      break;\r
+\r
+    case EFI_MEMORY_WT:\r
+      // modify cacheability attributes\r
+      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
+      // write through with no-allocate\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 |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
+      // write back (with allocate)\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
+    case EFI_MEMORY_XP:\r
+    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 = 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
+    default:\r
+      return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  // Obtain page table base\r
+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
+\r
+  // Calculate number of 4KB page table entries to change\r
+  NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;\r
+  \r
+  // Iterate for the number of 4KB pages to change\r
+  Offset = 0;\r
+  for(p = 0; p < NumPageEntries; p++) {\r
+    // Calculate index into first level translation table for page table value\r
+    \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 (!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
+      } \r
+      \r
+      // Re-read descriptor\r
+      Descriptor = FirstLevelTable[FirstLevelIdx];\r
+    }\r
+\r
+    // Obtain page table base address\r
+    PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);\r
+\r
+    // Calculate index into the page table\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
+\r
+    // Mask off appropriate fields\r
+    PageTableEntry = CurrentPageTableEntry & ~EntryMask;\r
+\r
+    // Mask in new attributes and/or permissions\r
+    PageTableEntry |= EntryValue;\r
+\r
+    if (VirtualMask != 0) {\r
+      // Make this virtual address point at a physical page\r
+      PageTableEntry &= ~VirtualMask;\r
+    }\r
+   \r
+    if (CurrentPageTableEntry  != PageTableEntry) {\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, TT_DESCRIPTOR_PAGE_SIZE);\r
+      }\r
+\r
+      // Only need to update if we are changing the entry  \r
+      PageTable[PageTableIndex] = PageTableEntry; \r
+      ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);\r
+    }\r
+\r
+    Status = EFI_SUCCESS;\r
+    Offset += TT_DESCRIPTOR_PAGE_SIZE;\r
+    \r
+  } // End first level translation table loop\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+UpdateSectionEntries (\r
+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN UINT64                    Length,\r
+  IN UINT64                    Attributes,\r
+  IN EFI_PHYSICAL_ADDRESS      VirtualMask\r
+  )\r
+{\r
+  EFI_STATUS    Status = EFI_SUCCESS;\r
+  UINT32        EntryMask;\r
+  UINT32        EntryValue;\r
+  UINT32        FirstLevelIdx;\r
+  UINT32        NumSections;\r
+  UINT32        i;\r
+  UINT32        CurrentDescriptor;\r
+  UINT32        Descriptor;\r
+  VOID          *Mva;\r
+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
+\r
+  // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)\r
+  // EntryValue: values at bit positions specified by EntryMask\r
+\r
+  // Make sure we handle a section range that is unmapped \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 |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
+      // map to strongly ordered\r
+      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
+      break;\r
+\r
+    case EFI_MEMORY_WC:\r
+      // modify cacheability attributes\r
+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\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
+      break;\r
+\r
+    case EFI_MEMORY_WT:\r
+      // modify cacheability attributes\r
+      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
+      // write through with no-allocate\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 |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
+      // write back (with allocate)\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
+    case EFI_MEMORY_XP:\r
+    case EFI_MEMORY_RP:\r
+    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 = 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
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  // obtain page table base\r
+  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
+\r
+  // calculate index into first level translation table for start of modification\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 / 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 (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {\r
+      // forward this 1MB range to page table function instead\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
+      // mask off appropriate fields\r
+      Descriptor = CurrentDescriptor & ~EntryMask;\r
+\r
+      // mask in new attributes and/or permissions\r
+      Descriptor |= EntryValue;\r
+      if (VirtualMask != 0) {\r
+        Descriptor &= ~VirtualMask;\r
+      }\r
+\r
+      if (CurrentDescriptor  != Descriptor) {\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
+        }\r
+\r
+        // Only need to update if we are changing the descriptor  \r
+        FirstLevelTable[FirstLevelIdx + i] = Descriptor;\r
+        ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);\r
+      }\r
+\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS \r
+ConvertSectionToPages (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_PHYSICAL_ADDRESS    PageTableAddr;\r
+  UINT32                  FirstLevelIdx;\r
+  UINT32                  SectionDescriptor;\r
+  UINT32                  PageTableDescriptor;\r
+  UINT32                  PageDescriptor;\r
+  UINT32                  Index;\r
+\r
+  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
+  volatile ARM_PAGE_TABLE_ENTRY         *PageTable;\r
+\r
+  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 *)ArmGetTTBR0BaseAddress ();\r
+\r
+  // Calculate index into first level translation table for start of modification\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 = 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
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;\r
+\r
+  // Write the page table entries out\r
+  for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {\r
+    PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 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, TT_DESCRIPTOR_PAGE_SIZE);\r
+\r
+  // Formulate page table entry, Domain=0, NS=0\r
+  PageTableDescriptor = (((UINTN)PageTableAddr) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;\r
+\r
+  // Write the page table entry out, replacing section entry\r
+  FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+SetMemoryAttributes (\r
+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN UINT64                    Length,\r
+  IN UINT64                    Attributes,\r
+  IN EFI_PHYSICAL_ADDRESS      VirtualMask\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  \r
+  if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) {\r
+    // Is the base and length a multiple of 1 MB?\r
+    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));\r
+    Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask);\r
+  } else {\r
+    // Base and/or length is not a multiple of 1 MB\r
+    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));\r
+    Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask);\r
+  }\r
+\r
+  // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks\r
+  // flush and invalidate pages\r
+  //TODO: Do we really need to invalidate the caches everytime we change the memory attributes ?\r
+  ArmCleanInvalidateDataCache ();\r
+\r
+  ArmInvalidateInstructionCache ();\r
+\r
+  // Invalidate all TLB entries so changes are synced\r
+  ArmInvalidateTlb ();\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  This function modifies the attributes for the memory region specified by BaseAddress and\r
+  Length from their current attributes to the attributes specified by Attributes.\r
+\r
+  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.\r
+  @param  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param  Length           The size in bytes of the memory region.\r
+  @param  Attributes       The bit mask of attributes to set for the memory region.\r
+\r
+  @retval EFI_SUCCESS           The attributes were set for the memory region.\r
+  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by\r
+                                BaseAddress and Length cannot be modified.\r
+  @retval EFI_INVALID_PARAMETER Length is zero.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of\r
+                                the memory resource range.\r
+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory\r
+                                resource range specified by BaseAddress and Length.\r
+                                The bit mask of attributes is not support for the memory resource\r
+                                range specified by BaseAddress and Length.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CpuSetMemoryAttributes (\r
+  IN EFI_CPU_ARCH_PROTOCOL     *This,\r
+  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN UINT64                    Length,\r
+  IN UINT64                    Attributes\r
+  )\r
+{\r
+  DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes));\r
+  if ( ((BaseAddress & ~TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) != 0) || ((Length & ~TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) != 0)){\r
+    // minimum granularity is SIZE_4KB (4KB on ARM)\r
+    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx): minimum ganularity is SIZE_4KB\n", BaseAddress, Length, Attributes));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  return SetMemoryAttributes (BaseAddress, Length, Attributes, 0);\r
+}\r
+\r
+\r
+\r
+//\r
+// Add a new protocol to support \r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuConvertPagesToUncachedVirtualAddress (\r
+  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL   *This,\r
+  IN  EFI_PHYSICAL_ADDRESS              Address,\r
+  IN  UINTN                             Length,\r
+  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,\r
+  OUT UINT64                            *Attributes     OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
+  \r
+  \r
+  if (Attributes != NULL) {\r
+    Status = gDS->GetMemorySpaceDescriptor (Address, &GcdDescriptor);\r
+    if (!EFI_ERROR (Status)) {\r
+      *Attributes = GcdDescriptor.Attributes;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Make this address range page fault if accessed. If it is a DMA buffer than this would \r
+  // be the PCI address. Code should always use the CPU address, and we will or in VirtualMask\r
+  // to that address. \r
+  //\r
+  Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_WP, 0);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "ConvertPagesToUncachedVirtualAddress()\n    Unmapped 0x%08lx Mapped 0x%08lx 0x%x bytes\n", Address, Address | VirtualMask, Length));\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuReconvertPages (\r
+  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL   *This,\r
+  IN  EFI_PHYSICAL_ADDRESS              Address,\r
+  IN  UINTN                             Length,\r
+  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,\r
+  IN  UINT64                            Attributes\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+\r
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuReconvertPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));\r
+  \r
+  //\r
+  // Unmap the alaised Address\r
+  //\r
+  Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Restore atttributes\r
+    //\r
+    Status = SetMemoryAttributes (Address, Length, Attributes, 0);\r
+  }\r
+  \r
+  return Status;\r
+}\r
+\r
+\r
+VIRTUAL_UNCACHED_PAGES_PROTOCOL  gVirtualUncachedPages = {\r
+  CpuConvertPagesToUncachedVirtualAddress,\r
+  CpuReconvertPages\r
+};\r
index b471e4a..16afd04 100644 (file)
@@ -40,8 +40,8 @@
 #\r
 \r
 [Sources.ARM]\r
-  Mmu.c\r
-  Exception.c\r
+  ArmV6/Mmu.c\r
+  ArmV6/Exception.c\r
   ArmV6/ExceptionSupport.asm | RVCT\r
   ArmV6/ExceptionSupport.S   | GCC\r
 \r
diff --git a/ArmPkg/Drivers/CpuDxe/Exception.c b/ArmPkg/Drivers/CpuDxe/Exception.c
deleted file mode 100644 (file)
index 55a7132..0000000
+++ /dev/null
@@ -1,230 +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 "CpuDxe.h" \r
-\r
-//FIXME: Will not compile on non-ARMv7 builds\r
-#include <Chipset/ArmV7.h>\r
-\r
-VOID\r
-ExceptionHandlersStart (\r
-  VOID\r
-  );\r
-\r
-VOID\r
-ExceptionHandlersEnd (\r
-  VOID\r
-  );\r
-\r
-VOID\r
-CommonExceptionEntry (\r
-  VOID\r
-  );\r
-\r
-VOID\r
-AsmCommonExceptionEntry (\r
-  VOID\r
-  );\r
-\r
-\r
-EFI_EXCEPTION_CALLBACK  gExceptionHandlers[MAX_ARM_EXCEPTION + 1];\r
-EFI_EXCEPTION_CALLBACK  gDebuggerExceptionHandlers[MAX_ARM_EXCEPTION + 1];\r
-\r
-\r
-\r
-/**\r
-  This function registers and enables the handler specified by InterruptHandler for a processor \r
-  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the \r
-  handler for the processor interrupt or exception type specified by InterruptType is uninstalled. \r
-  The installed handler is called once for each processor interrupt or exception.\r
-\r
-  @param  InterruptType    A pointer to the processor's current interrupt state. Set to TRUE if interrupts\r
-                           are enabled and FALSE if interrupts are disabled.\r
-  @param  InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
-                           when a processor interrupt occurs. If this parameter is NULL, then the handler\r
-                           will be uninstalled.\r
-\r
-  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.\r
-  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was\r
-                                previously installed.\r
-  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
-                                previously installed.\r
-  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-RegisterInterruptHandler (\r
-  IN EFI_EXCEPTION_TYPE             InterruptType,\r
-  IN EFI_CPU_INTERRUPT_HANDLER      InterruptHandler\r
-  )\r
-{\r
-  if (InterruptType > MAX_ARM_EXCEPTION) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {\r
-    return EFI_ALREADY_STARTED;\r
-  }\r
-\r
-  gExceptionHandlers[InterruptType] = InterruptHandler;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-\r
-VOID\r
-EFIAPI\r
-CommonCExceptionHandler (\r
-  IN     EFI_EXCEPTION_TYPE           ExceptionType,\r
-  IN OUT EFI_SYSTEM_CONTEXT           SystemContext\r
-  )\r
-{\r
-  if (ExceptionType <= MAX_ARM_EXCEPTION) {\r
-    if (gExceptionHandlers[ExceptionType]) {\r
-      gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);\r
-      return;\r
-    }\r
-  } else {\r
-    DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %08x\n", ExceptionType, SystemContext.SystemContextArm->PC));\r
-    ASSERT (FALSE);\r
-  }\r
-  \r
-  if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) {\r
-    //\r
-    // ARM JTAG debuggers some times use this vector, so it is not an error to get one\r
-    //\r
-    return;\r
-  }\r
-\r
-  DefaultExceptionHandler (ExceptionType, SystemContext);\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-InitializeExceptions (\r
-  IN EFI_CPU_ARCH_PROTOCOL    *Cpu\r
-  )\r
-{\r
-  EFI_STATUS           Status;\r
-  UINTN                Offset;\r
-  UINTN                Length;\r
-  UINTN                Index;\r
-  BOOLEAN              IrqEnabled;\r
-  BOOLEAN              FiqEnabled;\r
-  EFI_PHYSICAL_ADDRESS Base;\r
-  UINT32               *VectorBase;\r
-\r
-  Status = EFI_SUCCESS;\r
-  ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers));\r
-\r
-  //\r
-  // Disable interrupts\r
-  //\r
-  Cpu->GetInterruptState (Cpu, &IrqEnabled);\r
-  Cpu->DisableInterrupt (Cpu);\r
-\r
-  //\r
-  // EFI does not use the FIQ, but a debugger might so we must disable \r
-  // as we take over the exception vectors. \r
-  //\r
-  FiqEnabled = ArmGetFiqState ();\r
-  ArmDisableFiq ();\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
-    // Check if the exception vector is in the low address\r
-    if (PcdGet32 (PcdCpuVectorBaseAddress) == 0x0) {\r
-      // Set SCTLR.V to 0 to enable VBAR to be used\r
-      ArmSetLowVectors ();\r
-    } else {\r
-      ArmSetHighVectors ();\r
-    }\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
-    if (FeaturePcdGet(PcdDebuggerExceptionSupport) == TRUE) {\r
-      // Save existing vector table, in case debugger is already hooked in\r
-      CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));\r
-    }\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 (!FeaturePcdGet(PcdDebuggerExceptionSupport) ||\r
-          (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 already 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
-    // The Vector table must be 32-byte aligned\r
-    ASSERT(((UINT32)ExceptionHandlersStart & ((1 << 5)-1)) == 0);\r
-\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
-  if (FiqEnabled) {\r
-    ArmEnableFiq ();\r
-  }\r
-\r
-  if (IrqEnabled) {\r
-    // \r
-    // Restore interrupt state\r
-    //\r
-    Status = Cpu->EnableInterrupt (Cpu);\r
-  }\r
-\r
-  return Status;\r
-}\r
diff --git a/ArmPkg/Drivers/CpuDxe/Mmu.c b/ArmPkg/Drivers/CpuDxe/Mmu.c
deleted file mode 100644 (file)
index dcc7b68..0000000
+++ /dev/null
@@ -1,944 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>\r
-Portions copyright (c) 2010, 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
-\r
-#include "CpuDxe.h"\r
-\r
-// First Level Descriptors\r
-typedef UINT32    ARM_FIRST_LEVEL_DESCRIPTOR;\r
-\r
-// Second Level Descriptors\r
-typedef UINT32    ARM_PAGE_TABLE_ENTRY;\r
-\r
-EFI_STATUS \r
-SectionToGcdAttributes (\r
-  IN  UINT32  SectionAttributes,\r
-  OUT UINT64  *GcdAttributes\r
-  )\r
-{\r
-  *GcdAttributes = 0;\r
-\r
-  // determine cacheability attributes\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 TT_DESCRIPTOR_SECTION_CACHE_POLICY_SHAREABLE_DEVICE:\r
-      *GcdAttributes |= EFI_MEMORY_UC;\r
-      break;\r
-    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:\r
-      *GcdAttributes |= EFI_MEMORY_WT;\r
-      break;\r
-    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_NO_ALLOC:\r
-      *GcdAttributes |= EFI_MEMORY_WB;\r
-      break;\r
-    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE:\r
-      *GcdAttributes |= EFI_MEMORY_WC;\r
-      break;\r
-    case TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC:\r
-      *GcdAttributes |= EFI_MEMORY_WB;\r
-      break;\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
-  // determine protection attributes\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 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 TT_DESCRIPTOR_SECTION_AP_RO_NO:\r
-    case TT_DESCRIPTOR_SECTION_AP_RO_RO:\r
-      *GcdAttributes |= EFI_MEMORY_WP;\r
-      break;\r
-\r
-    default:\r
-      return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  // now process eXectue Never attribute\r
-  if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0 ) {\r
-    *GcdAttributes |= EFI_MEMORY_XP;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PageToGcdAttributes (\r
-  IN  UINT32  PageAttributes,\r
-  OUT UINT64  *GcdAttributes\r
-  )\r
-{\r
-  *GcdAttributes = 0;\r
-\r
-  // determine cacheability attributes\r
-  switch(PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {\r
-    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:\r
-      *GcdAttributes |= EFI_MEMORY_UC;\r
-      break;\r
-    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE:\r
-      *GcdAttributes |= EFI_MEMORY_UC;\r
-      break;\r
-    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:\r
-      *GcdAttributes |= EFI_MEMORY_WT;\r
-      break;\r
-    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC:\r
-      *GcdAttributes |= EFI_MEMORY_WB;\r
-      break;\r
-    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE:\r
-      *GcdAttributes |= EFI_MEMORY_WC;\r
-      break;\r
-    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC:\r
-      *GcdAttributes |= EFI_MEMORY_WB;\r
-      break;\r
-    case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE:\r
-      *GcdAttributes |= EFI_MEMORY_UC;\r
-      break;\r
-    default:\r
-      return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  // determine protection attributes\r
-  switch(PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) {\r
-    case TT_DESCRIPTOR_PAGE_AP_NO_NO: // no read, no write\r
-      //*GcdAttributes |= EFI_MEMORY_WP | EFI_MEMORY_RP;\r
-      break;\r
-\r
-    case TT_DESCRIPTOR_PAGE_AP_RW_NO:\r
-    case TT_DESCRIPTOR_PAGE_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 TT_DESCRIPTOR_PAGE_AP_RO_NO:\r
-    case TT_DESCRIPTOR_PAGE_AP_RO_RO:\r
-      *GcdAttributes |= EFI_MEMORY_WP;\r
-      break;\r
-\r
-    default:\r
-      return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  // now process eXectue Never attribute\r
-  if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {\r
-    *GcdAttributes |= EFI_MEMORY_XP;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Searches memory descriptors covered by given memory range.\r
-\r
-  This function searches into the Gcd Memory Space for descriptors\r
-  (from StartIndex to EndIndex) that contains the memory range\r
-  specified by BaseAddress and Length.\r
-\r
-  @param  MemorySpaceMap       Gcd Memory Space Map as array.\r
-  @param  NumberOfDescriptors  Number of descriptors in map.\r
-  @param  BaseAddress          BaseAddress for the requested range.\r
-  @param  Length               Length for the requested range.\r
-  @param  StartIndex           Start index into the Gcd Memory Space Map.\r
-  @param  EndIndex             End index into the Gcd Memory Space Map.\r
-\r
-  @retval EFI_SUCCESS          Search successfully.\r
-  @retval EFI_NOT_FOUND        The requested descriptors does not exist.\r
-\r
-**/\r
-EFI_STATUS\r
-SearchGcdMemorySpaces (\r
-  IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap,\r
-  IN UINTN                               NumberOfDescriptors,\r
-  IN EFI_PHYSICAL_ADDRESS                BaseAddress,\r
-  IN UINT64                              Length,\r
-  OUT UINTN                              *StartIndex,\r
-  OUT UINTN                              *EndIndex\r
-  )\r
-{\r
-  UINTN           Index;\r
-\r
-  *StartIndex = 0;\r
-  *EndIndex   = 0;\r
-  for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
-    if (BaseAddress >= MemorySpaceMap[Index].BaseAddress &&\r
-        BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
-      *StartIndex = Index;\r
-    }\r
-    if (BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress &&\r
-        BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
-      *EndIndex = Index;\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
-  Sets the attributes for a specified range in Gcd Memory Space Map.\r
-\r
-  This function sets the attributes for a specified range in\r
-  Gcd Memory Space Map.\r
-\r
-  @param  MemorySpaceMap       Gcd Memory Space Map as array\r
-  @param  NumberOfDescriptors  Number of descriptors in map\r
-  @param  BaseAddress          BaseAddress for the range\r
-  @param  Length               Length for the range\r
-  @param  Attributes           Attributes to set\r
-\r
-  @retval EFI_SUCCESS          Memory attributes set successfully\r
-  @retval EFI_NOT_FOUND        The specified range does not exist in Gcd Memory Space\r
-\r
-**/\r
-EFI_STATUS\r
-SetGcdMemorySpaceAttributes (\r
-  IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap,\r
-  IN UINTN                               NumberOfDescriptors,\r
-  IN EFI_PHYSICAL_ADDRESS                BaseAddress,\r
-  IN UINT64                              Length,\r
-  IN UINT64                              Attributes\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  UINTN                 Index;\r
-  UINTN                 StartIndex;\r
-  UINTN                 EndIndex;\r
-  EFI_PHYSICAL_ADDRESS  RegionStart;\r
-  UINT64                RegionLength;\r
-\r
-  //\r
-  // Get all memory descriptors covered by the memory range\r
-  //\r
-  Status = SearchGcdMemorySpaces (\r
-             MemorySpaceMap,\r
-             NumberOfDescriptors,\r
-             BaseAddress,\r
-             Length,\r
-             &StartIndex,\r
-             &EndIndex\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Go through all related descriptors and set attributes accordingly\r
-  //\r
-  for (Index = StartIndex; Index <= EndIndex; Index++) {\r
-    if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {\r
-      continue;\r
-    }\r
-    //\r
-    // Calculate the start and end address of the overlapping range\r
-    //\r
-    if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {\r
-      RegionStart = BaseAddress;\r
-    } else {\r
-      RegionStart = MemorySpaceMap[Index].BaseAddress;\r
-    }\r
-    if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
-      RegionLength = BaseAddress + Length - RegionStart;\r
-    } else {\r
-      RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;\r
-    }\r
-    //\r
-    // Set memory attributes according to MTRR attribute and the original attribute of descriptor\r
-    //\r
-    gDS->SetMemorySpaceAttributes (\r
-           RegionStart,\r
-           RegionLength,\r
-           (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)\r
-           );\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-SyncCacheConfigPage (\r
-  IN     UINT32                             SectionIndex,\r
-  IN     UINT32                             FirstLevelDescriptor,\r
-  IN     UINTN                              NumberOfDescriptors,\r
-  IN     EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMap,\r
-  IN OUT EFI_PHYSICAL_ADDRESS               *NextRegionBase,\r
-  IN OUT UINT64                             *NextRegionLength,\r
-  IN OUT UINT32                             *NextSectionAttributes\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  UINT32                              i;\r
-  volatile ARM_PAGE_TABLE_ENTRY       *SecondLevelTable;\r
-  UINT32                              NextPageAttributes = 0;\r
-  UINT32                              PageAttributes = 0;\r
-  UINT32                              BaseAddress;\r
-  UINT64                              GcdAttributes;\r
-\r
-  // Get the Base Address from FirstLevelDescriptor;\r
-  BaseAddress = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(SectionIndex << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
-\r
-  // Convert SectionAttributes into PageAttributes\r
-  NextPageAttributes =\r
-      TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(*NextSectionAttributes,0) |\r
-      TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(*NextSectionAttributes);\r
-\r
-  // obtain page table base\r
-  SecondLevelTable = (ARM_PAGE_TABLE_ENTRY *)(FirstLevelDescriptor & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK);\r
-\r
-  for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {\r
-    if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {\r
-      // extract attributes (cacheability and permissions)\r
-      PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK);\r
-\r
-      if (NextPageAttributes == 0) {\r
-        // start on a new region\r
-        *NextRegionLength = 0;\r
-        *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);\r
-        NextPageAttributes = PageAttributes;\r
-      } else if (PageAttributes != NextPageAttributes) {\r
-        // Convert Section Attributes into GCD Attributes\r
-        Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);\r
-        ASSERT_EFI_ERROR (Status);\r
-\r
-        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
-        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);\r
-\r
-        // start on a new region\r
-        *NextRegionLength = 0;\r
-        *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);\r
-        NextPageAttributes = PageAttributes;\r
-      }\r
-    } else if (NextPageAttributes != 0) {\r
-      // Convert Page Attributes into GCD Attributes\r
-      Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);\r
-      ASSERT_EFI_ERROR (Status);\r
-\r
-      // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
-      SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);\r
-\r
-      *NextRegionLength = 0;\r
-      *NextRegionBase = BaseAddress | (i << TT_DESCRIPTOR_PAGE_BASE_SHIFT);\r
-      NextPageAttributes = 0;\r
-    }\r
-    *NextRegionLength += TT_DESCRIPTOR_PAGE_SIZE;\r
-  }\r
-\r
-  // Convert back PageAttributes into SectionAttributes\r
-  *NextSectionAttributes =\r
-      TT_DESCRIPTOR_CONVERT_TO_SECTION_CACHE_POLICY(NextPageAttributes,0) |\r
-      TT_DESCRIPTOR_CONVERT_TO_SECTION_AP(NextPageAttributes);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-SyncCacheConfig (\r
-  IN  EFI_CPU_ARCH_PROTOCOL *CpuProtocol\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  UINT32                              i;\r
-  EFI_PHYSICAL_ADDRESS                NextRegionBase;\r
-  UINT64                              NextRegionLength;\r
-  UINT32                              NextSectionAttributes = 0;\r
-  UINT32                              SectionAttributes = 0;\r
-  UINT64                              GcdAttributes;\r
-  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
-  UINTN                               NumberOfDescriptors;\r
-  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     *MemorySpaceMap;\r
-\r
-\r
-  DEBUG ((EFI_D_PAGE, "SyncCacheConfig()\n"));\r
-\r
-  // This code assumes MMU is enabled and filed with section translations\r
-  ASSERT (ArmMmuEnabled ());\r
-\r
-  //\r
-  // Get the memory space map from GCD\r
-  //\r
-  MemorySpaceMap = NULL;\r
-  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-\r
-  // The GCD implementation maintains its own copy of the state of memory space attributes.  GCD needs\r
-  // to know what the initial memory space attributes are.  The CPU Arch. Protocol does not provide a\r
-  // GetMemoryAttributes function for GCD to get this so we must resort to calling GCD (as if we were\r
-  // a client) to update its copy of the attributes.  This is bad architecture and should be replaced\r
-  // 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 *)(ArmGetTTBR0BaseAddress ());\r
-\r
-  // Get the first region\r
-  NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);\r
-\r
-  // iterate through each 1MB descriptor\r
-  NextRegionBase = NextRegionLength = 0;\r
-  for (i=0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {\r
-    if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {\r
-      // extract attributes (cacheability and permissions)\r
-      SectionAttributes = FirstLevelTable[i] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);\r
-\r
-      if (NextSectionAttributes == 0) {\r
-        // start on a new region\r
-        NextRegionLength = 0;\r
-        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
-        NextSectionAttributes = SectionAttributes;\r
-      } else if (SectionAttributes != NextSectionAttributes) {\r
-        // Convert Section Attributes into GCD Attributes\r
-        Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);\r
-        ASSERT_EFI_ERROR (Status);\r
-\r
-        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
-        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);\r
-\r
-        // start on a new region\r
-        NextRegionLength = 0;\r
-        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
-        NextSectionAttributes = SectionAttributes;\r
-      }\r
-      NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;\r
-    } else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(FirstLevelTable[i])) {\r
-      Status = SyncCacheConfigPage (\r
-          i,FirstLevelTable[i],\r
-          NumberOfDescriptors, MemorySpaceMap,\r
-          &NextRegionBase,&NextRegionLength,&NextSectionAttributes);\r
-      ASSERT_EFI_ERROR (Status);\r
-    } else {\r
-      // We do not support yet 16MB sections\r
-      ASSERT ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) != TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION);\r
-\r
-      // start on a new region\r
-      if (NextSectionAttributes != 0) {\r
-        // Convert Section Attributes into GCD Attributes\r
-        Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);\r
-        ASSERT_EFI_ERROR (Status);\r
-\r
-        // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
-        SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);\r
-\r
-        NextRegionLength = 0;\r
-        NextRegionBase = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(i << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
-        NextSectionAttributes = 0;\r
-      }\r
-      NextRegionLength += TT_DESCRIPTOR_SECTION_SIZE;\r
-    }\r
-  } // section entry loop\r
-\r
-  if (NextSectionAttributes != 0) {\r
-    // Convert Section Attributes into GCD Attributes\r
-    Status = SectionToGcdAttributes (NextSectionAttributes, &GcdAttributes);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)\r
-    SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, NextRegionBase, NextRegionLength, GcdAttributes);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-UpdatePageEntries (\r
-  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN UINT64                    Length,\r
-  IN UINT64                    Attributes,\r
-  IN EFI_PHYSICAL_ADDRESS      VirtualMask\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINT32        EntryValue;\r
-  UINT32        EntryMask;\r
-  UINT32        FirstLevelIdx;\r
-  UINT32        Offset;\r
-  UINT32        NumPageEntries;\r
-  UINT32        Descriptor;\r
-  UINT32        p;\r
-  UINT32        PageTableIndex;\r
-  UINT32        PageTableEntry;\r
-  UINT32        CurrentPageTableEntry;\r
-  VOID          *Mva;\r
-\r
-  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
-  volatile ARM_PAGE_TABLE_ENTRY         *PageTable;\r
-\r
-  Status = EFI_SUCCESS;\r
-\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 = 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 |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
-      // map to strongly ordered\r
-      EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
-      break;\r
-\r
-    case EFI_MEMORY_WC:\r
-      // modify cacheability attributes\r
-      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\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
-      break;\r
-\r
-    case EFI_MEMORY_WT:\r
-      // modify cacheability attributes\r
-      EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
-      // write through with no-allocate\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 |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
-      // write back (with allocate)\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
-    case EFI_MEMORY_XP:\r
-    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 = 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
-    default:\r
-      return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  // Obtain page table base\r
-  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
-\r
-  // Calculate number of 4KB page table entries to change\r
-  NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;\r
-  \r
-  // Iterate for the number of 4KB pages to change\r
-  Offset = 0;\r
-  for(p = 0; p < NumPageEntries; p++) {\r
-    // Calculate index into first level translation table for page table value\r
-    \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 (!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
-      } \r
-      \r
-      // Re-read descriptor\r
-      Descriptor = FirstLevelTable[FirstLevelIdx];\r
-    }\r
-\r
-    // Obtain page table base address\r
-    PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);\r
-\r
-    // Calculate index into the page table\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
-\r
-    // Mask off appropriate fields\r
-    PageTableEntry = CurrentPageTableEntry & ~EntryMask;\r
-\r
-    // Mask in new attributes and/or permissions\r
-    PageTableEntry |= EntryValue;\r
-\r
-    if (VirtualMask != 0) {\r
-      // Make this virtual address point at a physical page\r
-      PageTableEntry &= ~VirtualMask;\r
-    }\r
-   \r
-    if (CurrentPageTableEntry  != PageTableEntry) {\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, TT_DESCRIPTOR_PAGE_SIZE);\r
-      }\r
-\r
-      // Only need to update if we are changing the entry  \r
-      PageTable[PageTableIndex] = PageTableEntry; \r
-      ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);\r
-    }\r
-\r
-    Status = EFI_SUCCESS;\r
-    Offset += TT_DESCRIPTOR_PAGE_SIZE;\r
-    \r
-  } // End first level translation table loop\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-UpdateSectionEntries (\r
-  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN UINT64                    Length,\r
-  IN UINT64                    Attributes,\r
-  IN EFI_PHYSICAL_ADDRESS      VirtualMask\r
-  )\r
-{\r
-  EFI_STATUS    Status = EFI_SUCCESS;\r
-  UINT32        EntryMask;\r
-  UINT32        EntryValue;\r
-  UINT32        FirstLevelIdx;\r
-  UINT32        NumSections;\r
-  UINT32        i;\r
-  UINT32        CurrentDescriptor;\r
-  UINT32        Descriptor;\r
-  VOID          *Mva;\r
-  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
-\r
-  // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)\r
-  // EntryValue: values at bit positions specified by EntryMask\r
-\r
-  // Make sure we handle a section range that is unmapped \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 |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
-      // map to strongly ordered\r
-      EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
-      break;\r
-\r
-    case EFI_MEMORY_WC:\r
-      // modify cacheability attributes\r
-      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\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
-      break;\r
-\r
-    case EFI_MEMORY_WT:\r
-      // modify cacheability attributes\r
-      EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
-      // write through with no-allocate\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 |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
-      // write back (with allocate)\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
-    case EFI_MEMORY_XP:\r
-    case EFI_MEMORY_RP:\r
-    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 = 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
-\r
-    default:\r
-      return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  // obtain page table base\r
-  FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
-\r
-  // calculate index into first level translation table for start of modification\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 / 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 (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {\r
-      // forward this 1MB range to page table function instead\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
-      // mask off appropriate fields\r
-      Descriptor = CurrentDescriptor & ~EntryMask;\r
-\r
-      // mask in new attributes and/or permissions\r
-      Descriptor |= EntryValue;\r
-      if (VirtualMask != 0) {\r
-        Descriptor &= ~VirtualMask;\r
-      }\r
-\r
-      if (CurrentDescriptor  != Descriptor) {\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
-        }\r
-\r
-        // Only need to update if we are changing the descriptor  \r
-        FirstLevelTable[FirstLevelIdx + i] = Descriptor;\r
-        ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);\r
-      }\r
-\r
-      Status = EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS \r
-ConvertSectionToPages (\r
-  IN EFI_PHYSICAL_ADDRESS  BaseAddress\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_PHYSICAL_ADDRESS    PageTableAddr;\r
-  UINT32                  FirstLevelIdx;\r
-  UINT32                  SectionDescriptor;\r
-  UINT32                  PageTableDescriptor;\r
-  UINT32                  PageDescriptor;\r
-  UINT32                  Index;\r
-\r
-  volatile ARM_FIRST_LEVEL_DESCRIPTOR   *FirstLevelTable;\r
-  volatile ARM_PAGE_TABLE_ENTRY         *PageTable;\r
-\r
-  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 *)ArmGetTTBR0BaseAddress ();\r
-\r
-  // Calculate index into first level translation table for start of modification\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 = 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
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)(UINTN)PageTableAddr;\r
-\r
-  // Write the page table entries out\r
-  for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {\r
-    PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 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, TT_DESCRIPTOR_PAGE_SIZE);\r
-\r
-  // Formulate page table entry, Domain=0, NS=0\r
-  PageTableDescriptor = (((UINTN)PageTableAddr) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;\r
-\r
-  // Write the page table entry out, replacing section entry\r
-  FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-SetMemoryAttributes (\r
-  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN UINT64                    Length,\r
-  IN UINT64                    Attributes,\r
-  IN EFI_PHYSICAL_ADDRESS      VirtualMask\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  \r
-  if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) {\r
-    // Is the base and length a multiple of 1 MB?\r
-    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));\r
-    Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask);\r
-  } else {\r
-    // Base and/or length is not a multiple of 1 MB\r
-    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes));\r
-    Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask);\r
-  }\r
-\r
-  // Flush d-cache so descriptors make it back to uncached memory for subsequent table walks\r
-  // flush and invalidate pages\r
-  //TODO: Do we really need to invalidate the caches everytime we change the memory attributes ?\r
-  ArmCleanInvalidateDataCache ();\r
-\r
-  ArmInvalidateInstructionCache ();\r
-\r
-  // Invalidate all TLB entries so changes are synced\r
-  ArmInvalidateTlb ();\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  This function modifies the attributes for the memory region specified by BaseAddress and\r
-  Length from their current attributes to the attributes specified by Attributes.\r
-\r
-  @param  This             The EFI_CPU_ARCH_PROTOCOL instance.\r
-  @param  BaseAddress      The physical address that is the start address of a memory region.\r
-  @param  Length           The size in bytes of the memory region.\r
-  @param  Attributes       The bit mask of attributes to set for the memory region.\r
-\r
-  @retval EFI_SUCCESS           The attributes were set for the memory region.\r
-  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by\r
-                                BaseAddress and Length cannot be modified.\r
-  @retval EFI_INVALID_PARAMETER Length is zero.\r
-  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of\r
-                                the memory resource range.\r
-  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory\r
-                                resource range specified by BaseAddress and Length.\r
-                                The bit mask of attributes is not support for the memory resource\r
-                                range specified by BaseAddress and Length.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CpuSetMemoryAttributes (\r
-  IN EFI_CPU_ARCH_PROTOCOL     *This,\r
-  IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
-  IN UINT64                    Length,\r
-  IN UINT64                    Attributes\r
-  )\r
-{\r
-  DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes));\r
-  if ( ((BaseAddress & ~TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) != 0) || ((Length & ~TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) != 0)){\r
-    // minimum granularity is SIZE_4KB (4KB on ARM)\r
-    DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx): minimum ganularity is SIZE_4KB\n", BaseAddress, Length, Attributes));\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  \r
-  return SetMemoryAttributes (BaseAddress, Length, Attributes, 0);\r
-}\r
-\r
-\r
-\r
-//\r
-// Add a new protocol to support \r
-//\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuConvertPagesToUncachedVirtualAddress (\r
-  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL   *This,\r
-  IN  EFI_PHYSICAL_ADDRESS              Address,\r
-  IN  UINTN                             Length,\r
-  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,\r
-  OUT UINT64                            *Attributes     OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
-  \r
-  \r
-  if (Attributes != NULL) {\r
-    Status = gDS->GetMemorySpaceDescriptor (Address, &GcdDescriptor);\r
-    if (!EFI_ERROR (Status)) {\r
-      *Attributes = GcdDescriptor.Attributes;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Make this address range page fault if accessed. If it is a DMA buffer than this would \r
-  // be the PCI address. Code should always use the CPU address, and we will or in VirtualMask\r
-  // to that address. \r
-  //\r
-  Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_WP, 0);\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);\r
-  }\r
-\r
-  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "ConvertPagesToUncachedVirtualAddress()\n    Unmapped 0x%08lx Mapped 0x%08lx 0x%x bytes\n", Address, Address | VirtualMask, Length));\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuReconvertPages (\r
-  IN  VIRTUAL_UNCACHED_PAGES_PROTOCOL   *This,\r
-  IN  EFI_PHYSICAL_ADDRESS              Address,\r
-  IN  UINTN                             Length,\r
-  IN  EFI_PHYSICAL_ADDRESS              VirtualMask,\r
-  IN  UINT64                            Attributes\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-\r
-  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuReconvertPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));\r
-  \r
-  //\r
-  // Unmap the alaised Address\r
-  //\r
-  Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Restore atttributes\r
-    //\r
-    Status = SetMemoryAttributes (Address, Length, Attributes, 0);\r
-  }\r
-  \r
-  return Status;\r
-}\r
-\r
-\r
-VIRTUAL_UNCACHED_PAGES_PROTOCOL  gVirtualUncachedPages = {\r
-  CpuConvertPagesToUncachedVirtualAddress,\r
-  CpuReconvertPages\r
-};\r
index b28a457..5f24ffa 100644 (file)
@@ -22,8 +22,8 @@
   LIBRARY_CLASS                  = ArmLib\r
 \r
 [Sources.common]\r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
   \r
   Arm11Support.S    | GCC\r
index cd36d8b..7239ace 100644 (file)
@@ -22,8 +22,8 @@
   LIBRARY_CLASS                  = ArmLib\r
 \r
 [Sources.common]\r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
   \r
   Arm11Support.S    | GCC\r
index 4c3566e..e693c46 100644 (file)
@@ -22,8 +22,8 @@
   LIBRARY_CLASS                  = ArmLib\r
 \r
 [Sources.common]\r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
   \r
   Arm11Support.S    | GCC\r
index 4eebf76..e962ca4 100644 (file)
@@ -22,8 +22,8 @@
   LIBRARY_CLASS                  = ArmLib\r
 \r
 [Sources.common]\r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
 \r
   Arm9Support.S    | GCC\r
index e1900c5..4c57001 100644 (file)
@@ -22,8 +22,8 @@
   LIBRARY_CLASS                  = ArmLib\r
 \r
 [Sources.common]\r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
 \r
   Arm9Support.S    | GCC\r
index 2bc01a9..ec2a0ba 100644 (file)
@@ -25,8 +25,8 @@
   ArmLibSupportV7.S    | GCC\r
   ArmLibSupportV7.asm  | RVCT\r
 \r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
   \r
   ArmV7Support.S    | GCC\r
index 5fdb044..be5b8e4 100644 (file)
@@ -25,8 +25,8 @@
   ArmLibSupportV7.S    | GCC\r
   ArmLibSupportV7.asm  | RVCT\r
 \r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
   \r
   ArmV7Support.S    | GCC\r
index 9e6f17e..c1f97bb 100644 (file)
@@ -23,8 +23,8 @@
   ArmLibSupportV7.S    | GCC\r
   ArmLibSupportV7.asm  | RVCT\r
 \r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
   \r
   ArmV7Support.S    | GCC\r
diff --git a/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
new file mode 100644 (file)
index 0000000..b191854
--- /dev/null
@@ -0,0 +1,184 @@
+#------------------------------------------------------------------------------ \r
+#\r
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+# Copyright (c) 2011-2012, 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
+\r
+#ifdef ARM_CPU_ARMv6\r
+// No memory barriers for ARMv6\r
+#define isb\r
+#define dsb\r
+#endif\r
+\r
+.text\r
+.align 2\r
+GCC_ASM_EXPORT(Cp15IdCode)\r
+GCC_ASM_EXPORT(Cp15CacheInfo)\r
+GCC_ASM_EXPORT(ArmGetInterruptState)\r
+GCC_ASM_EXPORT(ArmGetFiqState)\r
+GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)\r
+GCC_ASM_EXPORT(ArmSetTTBR0)\r
+GCC_ASM_EXPORT(ArmSetDomainAccessControl)\r
+GCC_ASM_EXPORT(CPSRMaskInsert)\r
+GCC_ASM_EXPORT(CPSRRead)\r
+GCC_ASM_EXPORT(ArmReadCpacr)\r
+GCC_ASM_EXPORT(ArmWriteCpacr)\r
+GCC_ASM_EXPORT(ArmWriteAuxCr)\r
+GCC_ASM_EXPORT(ArmReadAuxCr)\r
+GCC_ASM_EXPORT(ArmInvalidateTlb)\r
+GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)\r
+GCC_ASM_EXPORT(ArmReadNsacr)\r
+GCC_ASM_EXPORT(ArmWriteNsacr)\r
+GCC_ASM_EXPORT(ArmReadScr)\r
+GCC_ASM_EXPORT(ArmWriteScr)\r
+GCC_ASM_EXPORT(ArmReadMVBar)\r
+GCC_ASM_EXPORT(ArmWriteMVBar)\r
+GCC_ASM_EXPORT(ArmCallWFE)\r
+GCC_ASM_EXPORT(ArmCallSEV)\r
+GCC_ASM_EXPORT(ArmReadSctlr)\r
+\r
+#------------------------------------------------------------------------------\r
+\r
+ASM_PFX(Cp15IdCode):\r
+  mrc     p15,0,R0,c0,c0,0\r
+  bx      LR\r
+\r
+ASM_PFX(Cp15CacheInfo):\r
+  mrc     p15,0,R0,c0,c0,1\r
+  bx      LR\r
+\r
+ASM_PFX(ArmGetInterruptState):\r
+  mrs     R0,CPSR\r
+  tst     R0,#0x80      @Check if IRQ is enabled.\r
+  moveq   R0,#1\r
+  movne   R0,#0\r
+  bx      LR\r
+\r
+ASM_PFX(ArmGetFiqState):\r
+  mrs     R0,CPSR\r
+  tst     R0,#0x40      @Check if FIQ is enabled.\r
+  moveq   R0,#1\r
+  movne   R0,#0\r
+  bx      LR\r
+\r
+ASM_PFX(ArmSetDomainAccessControl):\r
+  mcr     p15,0,r0,c3,c0,0\r
+  bx      lr\r
+\r
+ASM_PFX(CPSRMaskInsert):    @ on entry, r0 is the mask and r1 is the field to insert\r
+  stmfd   sp!, {r4-r12, lr} @ save all the banked registers\r
+  mov     r3, sp            @ copy the stack pointer into a non-banked register\r
+  mrs     r2, cpsr          @ read the cpsr\r
+  bic     r2, r2, r0        @ clear mask in the cpsr\r
+  and     r1, r1, r0        @ clear bits outside the mask in the input\r
+  orr     r2, r2, r1        @ set field\r
+  msr     cpsr_cxsf, r2     @ write back cpsr (may have caused a mode switch)\r
+  isb\r
+  mov     sp, r3            @ restore stack pointer\r
+  ldmfd   sp!, {r4-r12, lr} @ restore registers\r
+  bx      lr                @ return (hopefully thumb-safe!)             @ return (hopefully thumb-safe!)\r
+\r
+ASM_PFX(CPSRRead):\r
+  mrs     r0, cpsr\r
+  bx      lr\r
+\r
+ASM_PFX(ArmReadCpacr):\r
+  mrc     p15, 0, r0, c1, c0, 2\r
+  bx      lr\r
+\r
+ASM_PFX(ArmWriteCpacr):\r
+  mcr     p15, 0, r0, c1, c0, 2\r
+  isb\r
+  bx      lr\r
+\r
+ASM_PFX(ArmWriteAuxCr):\r
+  mcr     p15, 0, r0, c1, c0, 1\r
+  bx      lr\r
+\r
+ASM_PFX(ArmReadAuxCr):\r
+  mrc     p15, 0, r0, c1, c0, 1\r
+  bx      lr  \r
+\r
+ASM_PFX(ArmSetTTBR0):\r
+  mcr     p15,0,r0,c2,c0,0\r
+  isb\r
+  bx      lr\r
+\r
+ASM_PFX(ArmGetTTBR0BaseAddress):\r
+  mrc     p15,0,r0,c2,c0,0\r
+  LoadConstantToReg(0xFFFFC000, r1)\r
+  and     r0, r0, r1\r
+  isb\r
+  bx      lr\r
+\r
+//\r
+//VOID\r
+//ArmUpdateTranslationTableEntry (\r
+//  IN VOID  *TranslationTableEntry  // R0\r
+//  IN VOID  *MVA                    // R1\r
+//  );\r
+ASM_PFX(ArmUpdateTranslationTableEntry):\r
+  mcr     p15,0,R0,c7,c14,1     @ DCCIMVAC Clean data cache by MVA\r
+  dsb\r
+  mcr     p15,0,R1,c8,c7,1      @ TLBIMVA TLB Invalidate MVA  \r
+  mcr     p15,0,R9,c7,c5,6      @ BPIALL Invalidate Branch predictor array. R9 == NoOp\r
+  dsb\r
+  isb\r
+  bx      lr\r
+\r
+ASM_PFX(ArmInvalidateTlb):\r
+  mov     r0,#0\r
+  mcr     p15,0,r0,c8,c7,0\r
+  mcr     p15,0,R9,c7,c5,6      @ BPIALL Invalidate Branch predictor array. R9 == NoOp\r
+  dsb\r
+  isb\r
+  bx      lr\r
+\r
+ASM_PFX(ArmReadNsacr):\r
+  mrc     p15, 0, r0, c1, c1, 2\r
+  bx      lr\r
+\r
+ASM_PFX(ArmWriteNsacr):\r
+  mcr     p15, 0, r0, c1, c1, 2\r
+  bx      lr\r
+\r
+ASM_PFX(ArmReadScr):\r
+  mrc     p15, 0, r0, c1, c1, 0\r
+  bx      lr\r
+\r
+ASM_PFX(ArmWriteScr):\r
+  mcr     p15, 0, r0, c1, c1, 0\r
+  bx      lr\r
+\r
+ASM_PFX(ArmReadMVBar):\r
+  mrc     p15, 0, r0, c12, c0, 1\r
+  bx      lr\r
+\r
+ASM_PFX(ArmWriteMVBar):\r
+  mcr     p15, 0, r0, c12, c0, 1\r
+  bx      lr\r
+\r
+ASM_PFX(ArmCallWFE):\r
+  wfe\r
+  bx      lr\r
+\r
+ASM_PFX(ArmCallSEV):\r
+  sev\r
+  bx      lr\r
+\r
+ASM_PFX(ArmReadSctlr):\r
+  mrc     p15, 0, R0, c1, c0, 0      @ Read SCTLR into R0 (Read control register configuration data)\r
+  bx     lr\r
+\r
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED\r
diff --git a/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm b/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
new file mode 100644 (file)
index 0000000..fd0f332
--- /dev/null
@@ -0,0 +1,184 @@
+//------------------------------------------------------------------------------ \r
+//\r
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+// Copyright (c) 2011-2012, 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
+    \r
+    INCLUDE AsmMacroIoLib.inc\r
+\r
+#ifdef ARM_CPU_ARMv6\r
+// No memory barriers for ARMv6\r
+#define isb\r
+#define dsb\r
+#endif\r
+\r
+    EXPORT Cp15IdCode\r
+    EXPORT Cp15CacheInfo\r
+    EXPORT ArmGetInterruptState\r
+    EXPORT ArmGetFiqState\r
+    EXPORT ArmGetTTBR0BaseAddress\r
+    EXPORT ArmSetTTBR0\r
+    EXPORT ArmSetDomainAccessControl\r
+    EXPORT CPSRMaskInsert\r
+    EXPORT CPSRRead\r
+    EXPORT ArmReadCpacr\r
+    EXPORT ArmWriteCpacr\r
+    EXPORT ArmWriteAuxCr\r
+    EXPORT ArmReadAuxCr\r
+    EXPORT ArmInvalidateTlb\r
+    EXPORT ArmUpdateTranslationTableEntry\r
+    EXPORT ArmReadNsacr\r
+    EXPORT ArmWriteNsacr\r
+    EXPORT ArmReadScr\r
+    EXPORT ArmWriteScr\r
+    EXPORT ArmReadMVBar\r
+    EXPORT ArmWriteMVBar\r
+    EXPORT ArmCallWFE\r
+    EXPORT ArmCallSEV\r
+    EXPORT ArmReadSctlr\r
+\r
+    AREA ArmLibSupport, CODE, READONLY\r
+\r
+Cp15IdCode\r
+  mrc     p15,0,R0,c0,c0,0\r
+  bx      LR\r
+\r
+Cp15CacheInfo\r
+  mrc     p15,0,R0,c0,c0,1\r
+  bx      LR\r
+\r
+ArmGetInterruptState\r
+  mrs     R0,CPSR\r
+  tst     R0,#0x80      // Check if IRQ is enabled.\r
+  moveq   R0,#1\r
+  movne   R0,#0\r
+  bx      LR\r
+\r
+ArmGetFiqState\r
+  mrs     R0,CPSR\r
+  tst     R0,#0x40      // Check if FIQ is enabled.\r
+  moveq   R0,#1\r
+  movne   R0,#0\r
+  bx      LR\r
+\r
+ArmSetDomainAccessControl\r
+  mcr     p15,0,r0,c3,c0,0\r
+  bx      lr\r
+\r
+CPSRMaskInsert    // on entry, r0 is the mask and r1 is the field to insert\r
+  stmfd   sp!, {r4-r12, lr} // save all the banked registers\r
+  mov     r3, sp            // copy the stack pointer into a non-banked register\r
+  mrs     r2, cpsr          // read the cpsr\r
+  bic     r2, r2, r0        // clear mask in the cpsr\r
+  and     r1, r1, r0        // clear bits outside the mask in the input\r
+  orr     r2, r2, r1        // set field\r
+  msr     cpsr_cxsf, r2     // write back cpsr (may have caused a mode switch)\r
+  isb\r
+  mov     sp, r3            // restore stack pointer\r
+  ldmfd   sp!, {r4-r12, lr} // restore registers\r
+  bx      lr                // return (hopefully thumb-safe!)             // return (hopefully thumb-safe!)\r
+\r
+CPSRRead\r
+  mrs     r0, cpsr\r
+  bx      lr\r
+\r
+ArmReadCpacr\r
+  mrc     p15, 0, r0, c1, c0, 2\r
+  bx      lr\r
+\r
+ArmWriteCpacr\r
+  mcr     p15, 0, r0, c1, c0, 2\r
+  isb\r
+  bx      lr\r
+\r
+ArmWriteAuxCr\r
+  mcr     p15, 0, r0, c1, c0, 1\r
+  bx      lr\r
+\r
+ArmReadAuxCr\r
+  mrc     p15, 0, r0, c1, c0, 1\r
+  bx      lr  \r
+\r
+ArmSetTTBR0\r
+  mcr     p15,0,r0,c2,c0,0\r
+  isb\r
+  bx      lr\r
+\r
+ArmGetTTBR0BaseAddress\r
+  mrc     p15,0,r0,c2,c0,0\r
+  LoadConstantToReg(0xFFFFC000, r1)\r
+  and     r0, r0, r1\r
+  isb\r
+  bx      lr\r
+\r
+//\r
+//VOID\r
+//ArmUpdateTranslationTableEntry (\r
+//  IN VOID  *TranslationTableEntry  // R0\r
+//  IN VOID  *MVA                    // R1\r
+//  );\r
+ArmUpdateTranslationTableEntry\r
+  mcr     p15,0,R0,c7,c14,1     // DCCIMVAC Clean data cache by MVA\r
+  dsb\r
+  mcr     p15,0,R1,c8,c7,1      // TLBIMVA TLB Invalidate MVA\r
+  mcr     p15,0,R9,c7,c5,6      // BPIALL Invalidate Branch predictor array. R9 == NoOp\r
+  dsb\r
+  isb\r
+  bx      lr\r
+\r
+ArmInvalidateTlb\r
+  mov     r0,#0\r
+  mcr     p15,0,r0,c8,c7,0\r
+  mcr     p15,0,R9,c7,c5,6      // BPIALL Invalidate Branch predictor array. R9 == NoOp\r
+  dsb\r
+  isb\r
+  bx      lr\r
+\r
+ArmReadNsacr\r
+  mrc     p15, 0, r0, c1, c1, 2\r
+  bx      lr\r
+\r
+ArmWriteNsacr\r
+  mcr     p15, 0, r0, c1, c1, 2\r
+  bx      lr\r
+\r
+ArmReadScr\r
+  mrc     p15, 0, r0, c1, c1, 0\r
+  bx      lr\r
+\r
+ArmWriteScr\r
+  mcr     p15, 0, r0, c1, c1, 0\r
+  bx      lr\r
+\r
+ArmReadMVBar\r
+  mrc     p15, 0, r0, c12, c0, 1\r
+  bx      lr\r
+\r
+ArmWriteMVBar\r
+  mcr     p15, 0, r0, c12, c0, 1\r
+  bx      lr\r
+  \r
+ArmCallWFE\r
+  wfe\r
+  blx   lr\r
+\r
+ArmCallSEV\r
+  sev\r
+  blx   lr\r
+\r
+ArmReadSctlr\r
+  mrc     p15, 0, R0, c1, c0, 0      // Read SCTLR into R0 (Read control register configuration data)\r
+  bx     lr\r
+\r
+  END\r
diff --git a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S
deleted file mode 100644 (file)
index b191854..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-#------------------------------------------------------------------------------ \r
-#\r
-# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-# Copyright (c) 2011-2012, 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
-\r
-#ifdef ARM_CPU_ARMv6\r
-// No memory barriers for ARMv6\r
-#define isb\r
-#define dsb\r
-#endif\r
-\r
-.text\r
-.align 2\r
-GCC_ASM_EXPORT(Cp15IdCode)\r
-GCC_ASM_EXPORT(Cp15CacheInfo)\r
-GCC_ASM_EXPORT(ArmGetInterruptState)\r
-GCC_ASM_EXPORT(ArmGetFiqState)\r
-GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)\r
-GCC_ASM_EXPORT(ArmSetTTBR0)\r
-GCC_ASM_EXPORT(ArmSetDomainAccessControl)\r
-GCC_ASM_EXPORT(CPSRMaskInsert)\r
-GCC_ASM_EXPORT(CPSRRead)\r
-GCC_ASM_EXPORT(ArmReadCpacr)\r
-GCC_ASM_EXPORT(ArmWriteCpacr)\r
-GCC_ASM_EXPORT(ArmWriteAuxCr)\r
-GCC_ASM_EXPORT(ArmReadAuxCr)\r
-GCC_ASM_EXPORT(ArmInvalidateTlb)\r
-GCC_ASM_EXPORT(ArmUpdateTranslationTableEntry)\r
-GCC_ASM_EXPORT(ArmReadNsacr)\r
-GCC_ASM_EXPORT(ArmWriteNsacr)\r
-GCC_ASM_EXPORT(ArmReadScr)\r
-GCC_ASM_EXPORT(ArmWriteScr)\r
-GCC_ASM_EXPORT(ArmReadMVBar)\r
-GCC_ASM_EXPORT(ArmWriteMVBar)\r
-GCC_ASM_EXPORT(ArmCallWFE)\r
-GCC_ASM_EXPORT(ArmCallSEV)\r
-GCC_ASM_EXPORT(ArmReadSctlr)\r
-\r
-#------------------------------------------------------------------------------\r
-\r
-ASM_PFX(Cp15IdCode):\r
-  mrc     p15,0,R0,c0,c0,0\r
-  bx      LR\r
-\r
-ASM_PFX(Cp15CacheInfo):\r
-  mrc     p15,0,R0,c0,c0,1\r
-  bx      LR\r
-\r
-ASM_PFX(ArmGetInterruptState):\r
-  mrs     R0,CPSR\r
-  tst     R0,#0x80      @Check if IRQ is enabled.\r
-  moveq   R0,#1\r
-  movne   R0,#0\r
-  bx      LR\r
-\r
-ASM_PFX(ArmGetFiqState):\r
-  mrs     R0,CPSR\r
-  tst     R0,#0x40      @Check if FIQ is enabled.\r
-  moveq   R0,#1\r
-  movne   R0,#0\r
-  bx      LR\r
-\r
-ASM_PFX(ArmSetDomainAccessControl):\r
-  mcr     p15,0,r0,c3,c0,0\r
-  bx      lr\r
-\r
-ASM_PFX(CPSRMaskInsert):    @ on entry, r0 is the mask and r1 is the field to insert\r
-  stmfd   sp!, {r4-r12, lr} @ save all the banked registers\r
-  mov     r3, sp            @ copy the stack pointer into a non-banked register\r
-  mrs     r2, cpsr          @ read the cpsr\r
-  bic     r2, r2, r0        @ clear mask in the cpsr\r
-  and     r1, r1, r0        @ clear bits outside the mask in the input\r
-  orr     r2, r2, r1        @ set field\r
-  msr     cpsr_cxsf, r2     @ write back cpsr (may have caused a mode switch)\r
-  isb\r
-  mov     sp, r3            @ restore stack pointer\r
-  ldmfd   sp!, {r4-r12, lr} @ restore registers\r
-  bx      lr                @ return (hopefully thumb-safe!)             @ return (hopefully thumb-safe!)\r
-\r
-ASM_PFX(CPSRRead):\r
-  mrs     r0, cpsr\r
-  bx      lr\r
-\r
-ASM_PFX(ArmReadCpacr):\r
-  mrc     p15, 0, r0, c1, c0, 2\r
-  bx      lr\r
-\r
-ASM_PFX(ArmWriteCpacr):\r
-  mcr     p15, 0, r0, c1, c0, 2\r
-  isb\r
-  bx      lr\r
-\r
-ASM_PFX(ArmWriteAuxCr):\r
-  mcr     p15, 0, r0, c1, c0, 1\r
-  bx      lr\r
-\r
-ASM_PFX(ArmReadAuxCr):\r
-  mrc     p15, 0, r0, c1, c0, 1\r
-  bx      lr  \r
-\r
-ASM_PFX(ArmSetTTBR0):\r
-  mcr     p15,0,r0,c2,c0,0\r
-  isb\r
-  bx      lr\r
-\r
-ASM_PFX(ArmGetTTBR0BaseAddress):\r
-  mrc     p15,0,r0,c2,c0,0\r
-  LoadConstantToReg(0xFFFFC000, r1)\r
-  and     r0, r0, r1\r
-  isb\r
-  bx      lr\r
-\r
-//\r
-//VOID\r
-//ArmUpdateTranslationTableEntry (\r
-//  IN VOID  *TranslationTableEntry  // R0\r
-//  IN VOID  *MVA                    // R1\r
-//  );\r
-ASM_PFX(ArmUpdateTranslationTableEntry):\r
-  mcr     p15,0,R0,c7,c14,1     @ DCCIMVAC Clean data cache by MVA\r
-  dsb\r
-  mcr     p15,0,R1,c8,c7,1      @ TLBIMVA TLB Invalidate MVA  \r
-  mcr     p15,0,R9,c7,c5,6      @ BPIALL Invalidate Branch predictor array. R9 == NoOp\r
-  dsb\r
-  isb\r
-  bx      lr\r
-\r
-ASM_PFX(ArmInvalidateTlb):\r
-  mov     r0,#0\r
-  mcr     p15,0,r0,c8,c7,0\r
-  mcr     p15,0,R9,c7,c5,6      @ BPIALL Invalidate Branch predictor array. R9 == NoOp\r
-  dsb\r
-  isb\r
-  bx      lr\r
-\r
-ASM_PFX(ArmReadNsacr):\r
-  mrc     p15, 0, r0, c1, c1, 2\r
-  bx      lr\r
-\r
-ASM_PFX(ArmWriteNsacr):\r
-  mcr     p15, 0, r0, c1, c1, 2\r
-  bx      lr\r
-\r
-ASM_PFX(ArmReadScr):\r
-  mrc     p15, 0, r0, c1, c1, 0\r
-  bx      lr\r
-\r
-ASM_PFX(ArmWriteScr):\r
-  mcr     p15, 0, r0, c1, c1, 0\r
-  bx      lr\r
-\r
-ASM_PFX(ArmReadMVBar):\r
-  mrc     p15, 0, r0, c12, c0, 1\r
-  bx      lr\r
-\r
-ASM_PFX(ArmWriteMVBar):\r
-  mcr     p15, 0, r0, c12, c0, 1\r
-  bx      lr\r
-\r
-ASM_PFX(ArmCallWFE):\r
-  wfe\r
-  bx      lr\r
-\r
-ASM_PFX(ArmCallSEV):\r
-  sev\r
-  bx      lr\r
-\r
-ASM_PFX(ArmReadSctlr):\r
-  mrc     p15, 0, R0, c1, c0, 0      @ Read SCTLR into R0 (Read control register configuration data)\r
-  bx     lr\r
-\r
-ASM_FUNCTION_REMOVE_IF_UNREFERENCED\r
diff --git a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm
deleted file mode 100644 (file)
index fd0f332..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-//------------------------------------------------------------------------------ \r
-//\r
-// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-// Copyright (c) 2011-2012, 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
-    \r
-    INCLUDE AsmMacroIoLib.inc\r
-\r
-#ifdef ARM_CPU_ARMv6\r
-// No memory barriers for ARMv6\r
-#define isb\r
-#define dsb\r
-#endif\r
-\r
-    EXPORT Cp15IdCode\r
-    EXPORT Cp15CacheInfo\r
-    EXPORT ArmGetInterruptState\r
-    EXPORT ArmGetFiqState\r
-    EXPORT ArmGetTTBR0BaseAddress\r
-    EXPORT ArmSetTTBR0\r
-    EXPORT ArmSetDomainAccessControl\r
-    EXPORT CPSRMaskInsert\r
-    EXPORT CPSRRead\r
-    EXPORT ArmReadCpacr\r
-    EXPORT ArmWriteCpacr\r
-    EXPORT ArmWriteAuxCr\r
-    EXPORT ArmReadAuxCr\r
-    EXPORT ArmInvalidateTlb\r
-    EXPORT ArmUpdateTranslationTableEntry\r
-    EXPORT ArmReadNsacr\r
-    EXPORT ArmWriteNsacr\r
-    EXPORT ArmReadScr\r
-    EXPORT ArmWriteScr\r
-    EXPORT ArmReadMVBar\r
-    EXPORT ArmWriteMVBar\r
-    EXPORT ArmCallWFE\r
-    EXPORT ArmCallSEV\r
-    EXPORT ArmReadSctlr\r
-\r
-    AREA ArmLibSupport, CODE, READONLY\r
-\r
-Cp15IdCode\r
-  mrc     p15,0,R0,c0,c0,0\r
-  bx      LR\r
-\r
-Cp15CacheInfo\r
-  mrc     p15,0,R0,c0,c0,1\r
-  bx      LR\r
-\r
-ArmGetInterruptState\r
-  mrs     R0,CPSR\r
-  tst     R0,#0x80      // Check if IRQ is enabled.\r
-  moveq   R0,#1\r
-  movne   R0,#0\r
-  bx      LR\r
-\r
-ArmGetFiqState\r
-  mrs     R0,CPSR\r
-  tst     R0,#0x40      // Check if FIQ is enabled.\r
-  moveq   R0,#1\r
-  movne   R0,#0\r
-  bx      LR\r
-\r
-ArmSetDomainAccessControl\r
-  mcr     p15,0,r0,c3,c0,0\r
-  bx      lr\r
-\r
-CPSRMaskInsert    // on entry, r0 is the mask and r1 is the field to insert\r
-  stmfd   sp!, {r4-r12, lr} // save all the banked registers\r
-  mov     r3, sp            // copy the stack pointer into a non-banked register\r
-  mrs     r2, cpsr          // read the cpsr\r
-  bic     r2, r2, r0        // clear mask in the cpsr\r
-  and     r1, r1, r0        // clear bits outside the mask in the input\r
-  orr     r2, r2, r1        // set field\r
-  msr     cpsr_cxsf, r2     // write back cpsr (may have caused a mode switch)\r
-  isb\r
-  mov     sp, r3            // restore stack pointer\r
-  ldmfd   sp!, {r4-r12, lr} // restore registers\r
-  bx      lr                // return (hopefully thumb-safe!)             // return (hopefully thumb-safe!)\r
-\r
-CPSRRead\r
-  mrs     r0, cpsr\r
-  bx      lr\r
-\r
-ArmReadCpacr\r
-  mrc     p15, 0, r0, c1, c0, 2\r
-  bx      lr\r
-\r
-ArmWriteCpacr\r
-  mcr     p15, 0, r0, c1, c0, 2\r
-  isb\r
-  bx      lr\r
-\r
-ArmWriteAuxCr\r
-  mcr     p15, 0, r0, c1, c0, 1\r
-  bx      lr\r
-\r
-ArmReadAuxCr\r
-  mrc     p15, 0, r0, c1, c0, 1\r
-  bx      lr  \r
-\r
-ArmSetTTBR0\r
-  mcr     p15,0,r0,c2,c0,0\r
-  isb\r
-  bx      lr\r
-\r
-ArmGetTTBR0BaseAddress\r
-  mrc     p15,0,r0,c2,c0,0\r
-  LoadConstantToReg(0xFFFFC000, r1)\r
-  and     r0, r0, r1\r
-  isb\r
-  bx      lr\r
-\r
-//\r
-//VOID\r
-//ArmUpdateTranslationTableEntry (\r
-//  IN VOID  *TranslationTableEntry  // R0\r
-//  IN VOID  *MVA                    // R1\r
-//  );\r
-ArmUpdateTranslationTableEntry\r
-  mcr     p15,0,R0,c7,c14,1     // DCCIMVAC Clean data cache by MVA\r
-  dsb\r
-  mcr     p15,0,R1,c8,c7,1      // TLBIMVA TLB Invalidate MVA\r
-  mcr     p15,0,R9,c7,c5,6      // BPIALL Invalidate Branch predictor array. R9 == NoOp\r
-  dsb\r
-  isb\r
-  bx      lr\r
-\r
-ArmInvalidateTlb\r
-  mov     r0,#0\r
-  mcr     p15,0,r0,c8,c7,0\r
-  mcr     p15,0,R9,c7,c5,6      // BPIALL Invalidate Branch predictor array. R9 == NoOp\r
-  dsb\r
-  isb\r
-  bx      lr\r
-\r
-ArmReadNsacr\r
-  mrc     p15, 0, r0, c1, c1, 2\r
-  bx      lr\r
-\r
-ArmWriteNsacr\r
-  mcr     p15, 0, r0, c1, c1, 2\r
-  bx      lr\r
-\r
-ArmReadScr\r
-  mrc     p15, 0, r0, c1, c1, 0\r
-  bx      lr\r
-\r
-ArmWriteScr\r
-  mcr     p15, 0, r0, c1, c1, 0\r
-  bx      lr\r
-\r
-ArmReadMVBar\r
-  mrc     p15, 0, r0, c12, c0, 1\r
-  bx      lr\r
-\r
-ArmWriteMVBar\r
-  mcr     p15, 0, r0, c12, c0, 1\r
-  bx      lr\r
-  \r
-ArmCallWFE\r
-  wfe\r
-  blx   lr\r
-\r
-ArmCallSEV\r
-  sev\r
-  blx   lr\r
-\r
-ArmReadSctlr\r
-  mrc     p15, 0, R0, c1, c0, 0      // Read SCTLR into R0 (Read control register configuration data)\r
-  bx     lr\r
-\r
-  END\r
index 3329620..d437198 100644 (file)
   LIBRARY_CLASS                  = ArmLib\r
 \r
 [Sources.common]\r
-  ../Common/ArmLibSupport.S    | GCC\r
-  ../Common/ArmLibSupport.asm  | RVCT\r
   ../Common/ArmLib.c\r
 \r
   NullArmLib.c\r
   NullArmCacheInformation.c\r
 \r
+[Sources.ARM]\r
+  ../Common/Arm/ArmLibSupport.S    | GCC\r
+  ../Common/Arm/ArmLibSupport.asm  | RVCT\r
+\r
 [Packages]\r
   ArmPkg/ArmPkg.dec\r
   MdePkg/MdePkg.dec\r
diff --git a/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c b/ArmPkg/Library/BdsLib/Arm/BdsLinuxAtag.c
new file mode 100644 (file)
index 0000000..8946b14
--- /dev/null
@@ -0,0 +1,173 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011-2012, 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
+#include "BdsLinuxLoader.h"\r
+\r
+// Point to the current ATAG\r
+STATIC LINUX_ATAG *mLinuxKernelCurrentAtag;\r
+\r
+STATIC\r
+VOID\r
+SetupCoreTag (\r
+  IN UINT32 PageSize\r
+  )\r
+{\r
+  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_CORE);\r
+  mLinuxKernelCurrentAtag->header.type = ATAG_CORE;\r
+\r
+  mLinuxKernelCurrentAtag->body.core_tag.flags    = 1;            /* ensure read-only */\r
+  mLinuxKernelCurrentAtag->body.core_tag.pagesize = PageSize;     /* systems PageSize (4k) */\r
+  mLinuxKernelCurrentAtag->body.core_tag.rootdev  = 0;            /* zero root device (typically overridden from kernel command line )*/\r
+\r
+  // move pointer to next tag\r
+  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
+}\r
+\r
+STATIC\r
+VOID\r
+SetupMemTag (\r
+  IN UINTN StartAddress,\r
+  IN UINT32 Size\r
+  )\r
+{\r
+  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_MEM);\r
+  mLinuxKernelCurrentAtag->header.type = ATAG_MEM;\r
+\r
+  mLinuxKernelCurrentAtag->body.mem_tag.start = StartAddress;    /* Start of memory chunk for AtagMem */\r
+  mLinuxKernelCurrentAtag->body.mem_tag.size  = Size;             /* Size of memory chunk for AtagMem */\r
+\r
+  // move pointer to next tag\r
+  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
+}\r
+\r
+STATIC\r
+VOID\r
+SetupCmdlineTag (\r
+  IN CONST CHAR8 *CmdLine\r
+  )\r
+{\r
+  UINT32 LineLength;\r
+\r
+  // Increment the line length by 1 to account for the null string terminator character\r
+  LineLength = AsciiStrLen(CmdLine) + 1;\r
+\r
+  /* Check for NULL strings.\r
+   * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.\r
+   * Remember, you have at least one null string terminator character.\r
+   */\r
+  if(LineLength > 1) {\r
+    mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof(LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2;\r
+    mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE;\r
+\r
+    /* place CommandLine into tag */\r
+    AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine);\r
+\r
+    // move pointer to next tag\r
+    mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
+  }\r
+}\r
+\r
+STATIC\r
+VOID\r
+SetupInitrdTag (\r
+  IN UINT32 InitrdImage,\r
+  IN UINT32 InitrdImageSize\r
+  )\r
+{\r
+  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_INITRD2);\r
+  mLinuxKernelCurrentAtag->header.type = ATAG_INITRD2;\r
+\r
+  mLinuxKernelCurrentAtag->body.initrd2_tag.start = InitrdImage;\r
+  mLinuxKernelCurrentAtag->body.initrd2_tag.size = InitrdImageSize;\r
+\r
+  // Move pointer to next tag\r
+  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
+}\r
+STATIC\r
+VOID\r
+SetupEndTag (\r
+  VOID\r
+  )\r
+{\r
+  // Empty tag ends list; this has zero length and no body\r
+  mLinuxKernelCurrentAtag->header.type = ATAG_NONE;\r
+  mLinuxKernelCurrentAtag->header.size = 0;\r
+\r
+  /* We can not calculate the next address by using the standard macro:\r
+   * Params = next_tag_address(Params);\r
+   * because it relies on the header.size, which here it is 0 (zero).\r
+   * The easiest way is to add the sizeof(mLinuxKernelCurrentAtag->header).\r
+   */\r
+  mLinuxKernelCurrentAtag = (LINUX_ATAG*)((UINT32)mLinuxKernelCurrentAtag + sizeof(mLinuxKernelCurrentAtag->header));\r
+}\r
+\r
+EFI_STATUS\r
+PrepareAtagList (\r
+  IN  CONST CHAR8*          CommandLineString,\r
+  IN  EFI_PHYSICAL_ADDRESS  InitrdImage,\r
+  IN  UINTN                 InitrdImageSize,\r
+  OUT EFI_PHYSICAL_ADDRESS  *AtagBase,\r
+  OUT UINT32                *AtagSize\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  LIST_ENTRY                  *ResourceLink;\r
+  LIST_ENTRY                  ResourceList;\r
+  EFI_PHYSICAL_ADDRESS        AtagStartAddress;\r
+  BDS_SYSTEM_MEMORY_RESOURCE  *Resource;\r
+\r
+  AtagStartAddress = LINUX_ATAG_MAX_OFFSET;\r
+  Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);\r
+  if (EFI_ERROR(Status)) {\r
+    DEBUG ((EFI_D_WARN, "Warning: Failed to allocate Atag at 0x%lX (%r). The Atag will be allocated somewhere else in System Memory.\n", AtagStartAddress, Status));\r
+    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);\r
+    ASSERT_EFI_ERROR(Status);\r
+  }\r
+\r
+  // Ready to setup the atag list\r
+  mLinuxKernelCurrentAtag = (LINUX_ATAG*)(UINTN)AtagStartAddress;\r
+\r
+  // Standard core tag 4k PageSize\r
+  SetupCoreTag( (UINT32)SIZE_4KB );\r
+\r
+  // Physical memory setup\r
+  GetSystemMemoryResources (&ResourceList);\r
+  ResourceLink = ResourceList.ForwardLink;\r
+  while (ResourceLink != NULL && ResourceLink != &ResourceList) {\r
+    Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceLink;\r
+    DEBUG((EFI_D_INFO,"- [0x%08X,0x%08X]\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->PhysicalStart+(UINT32)Resource->ResourceLength));\r
+    SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength );\r
+    ResourceLink = ResourceLink->ForwardLink;\r
+  }\r
+\r
+  // CommandLine setting root device\r
+  if (CommandLineString) {\r
+    SetupCmdlineTag (CommandLineString);\r
+  }\r
+\r
+  if (InitrdImageSize > 0 && InitrdImage != 0) {\r
+    SetupInitrdTag ((UINT32)InitrdImage, (UINT32)InitrdImageSize);\r
+  }\r
+\r
+  // End of tags\r
+  SetupEndTag();\r
+\r
+  // Calculate atag list size\r
+  *AtagBase = AtagStartAddress;\r
+  *AtagSize = (UINT32)mLinuxKernelCurrentAtag - (UINT32)AtagStartAddress + 1;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/Arm/BdsLinuxLoader.c
new file mode 100644 (file)
index 0000000..e3249e1
--- /dev/null
@@ -0,0 +1,274 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011-2012, 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
+#include "BdsLinuxLoader.h"\r
+\r
+#define ALIGN32_BELOW(addr)   ALIGN_POINTER(addr - 32,32)\r
+\r
+STATIC\r
+EFI_STATUS\r
+PreparePlatformHardware (\r
+  VOID\r
+  )\r
+{\r
+  //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.\r
+\r
+  // Clean, invalidate, disable data cache\r
+  ArmDisableDataCache();\r
+  ArmCleanInvalidateDataCache();\r
+\r
+  // Invalidate and disable the Instruction cache\r
+  ArmDisableInstructionCache ();\r
+  ArmInvalidateInstructionCache ();\r
+\r
+  // Turn off MMU\r
+  ArmDisableMmu();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+StartLinux (\r
+  IN  EFI_PHYSICAL_ADDRESS  LinuxImage,\r
+  IN  UINTN                 LinuxImageSize,\r
+  IN  EFI_PHYSICAL_ADDRESS  KernelParamsAddress,\r
+  IN  UINTN                 KernelParamsSize,\r
+  IN  UINT32                MachineType\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  LINUX_KERNEL          LinuxKernel;\r
+\r
+  // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on\r
+  // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.\r
+  Status = ShutdownUefiBootServices ();\r
+  if(EFI_ERROR(Status)) {\r
+    DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));\r
+    goto Exit;\r
+  }\r
+\r
+  // Move the kernel parameters to any address inside the first 1MB.\r
+  // This is necessary because the ARM Linux kernel requires\r
+  // the FTD / ATAG List to reside entirely inside the first 1MB of\r
+  // physical memory.\r
+  //Note: There is no requirement on the alignment\r
+  if (MachineType != ARM_FDT_MACHINE_TYPE) {\r
+    if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) {\r
+      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);\r
+    }\r
+  } else {\r
+    if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) {\r
+      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);\r
+    }\r
+  }\r
+\r
+  if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) {\r
+    //Note: There is no requirement on the alignment\r
+    LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize);\r
+  } else {\r
+    LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;\r
+  }\r
+\r
+  // Check if the Linux Image is a uImage\r
+  if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {\r
+    // Assume the Image Entry Point is just after the uImage header (64-byte size)\r
+    LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64);\r
+    LinuxImageSize -= 64;\r
+  }\r
+\r
+  //TODO: Check there is no overlapping between kernel and Atag\r
+\r
+  //\r
+  // Switch off interrupts, caches, mmu, etc\r
+  //\r
+  Status = PreparePlatformHardware ();\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  // Register and print out performance information\r
+  PERF_END (NULL, "BDS", NULL, 0);\r
+  if (PerformanceMeasurementEnabled ()) {\r
+    PrintPerformance ();\r
+  }\r
+\r
+  //\r
+  // Start the Linux Kernel\r
+  //\r
+\r
+  // Outside BootServices, so can't use Print();\r
+  DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));\r
+\r
+  // Jump to kernel with register set\r
+  LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);\r
+\r
+  // Kernel should never exit\r
+  // After Life services are not provided\r
+  ASSERT(FALSE);\r
+\r
+Exit:\r
+  // Only be here if we fail to start Linux\r
+  Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);\r
+\r
+  // Free Runtimee Memory (kernel and FDT)\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Start a Linux kernel from a Device Path\r
+\r
+  @param  LinuxKernel           Device Path to the Linux Kernel\r
+  @param  Parameters            Linux kernel arguments\r
+  @param  Fdt                   Device Path to the Flat Device Tree\r
+\r
+  @retval EFI_SUCCESS           All drivers have been connected\r
+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsBootLinuxAtag (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
+  IN  CONST CHAR8*              CommandLineArguments\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT32                LinuxImageSize;\r
+  UINT32                InitrdImageSize = 0;\r
+  UINT32                AtagSize;\r
+  EFI_PHYSICAL_ADDRESS  AtagBase;\r
+  EFI_PHYSICAL_ADDRESS  LinuxImage;\r
+  EFI_PHYSICAL_ADDRESS  InitrdImage;\r
+\r
+  PERF_START (NULL, "BDS", NULL, 0);\r
+\r
+  // Load the Linux kernel from a device path\r
+  LinuxImage = LINUX_KERNEL_MAX_OFFSET;\r
+  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);\r
+  if (EFI_ERROR(Status)) {\r
+    Print (L"ERROR: Did not find Linux kernel.\n");\r
+    return Status;\r
+  }\r
+\r
+  if (InitrdDevicePath) {\r
+    // Load the initrd near to the Linux kernel\r
+    InitrdImage = LINUX_KERNEL_MAX_OFFSET;\r
+    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);\r
+    if (Status == EFI_OUT_OF_RESOURCES) {\r
+      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
+    }\r
+    if (EFI_ERROR(Status)) {\r
+      Print (L"ERROR: Did not find initrd image.\n");\r
+      return Status;\r
+    }\r
+    \r
+    // Check if the initrd is a uInitrd\r
+    if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {\r
+      // Skip the 64-byte image header\r
+      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);\r
+      InitrdImageSize -= 64;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Setup the Linux Kernel Parameters\r
+  //\r
\r
+  // By setting address=0 we leave the memory allocation to the function\r
+  Status = PrepareAtagList (CommandLineArguments, InitrdImage, InitrdImageSize, &AtagBase, &AtagSize);\r
+  if (EFI_ERROR(Status)) {\r
+    Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);\r
+    return Status;\r
+  }\r
+\r
+  return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));\r
+}\r
+\r
+/**\r
+  Start a Linux kernel from a Device Path\r
+\r
+  @param  LinuxKernel           Device Path to the Linux Kernel\r
+  @param  Parameters            Linux kernel arguments\r
+  @param  Fdt                   Device Path to the Flat Device Tree\r
+\r
+  @retval EFI_SUCCESS           All drivers have been connected\r
+  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
+  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
+\r
+**/\r
+EFI_STATUS\r
+BdsBootLinuxFdt (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
+  IN  CONST CHAR8*              CommandLineArguments,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT32                LinuxImageSize;\r
+  UINT32                InitrdImageSize = 0;\r
+  UINT32                FdtBlobSize;\r
+  EFI_PHYSICAL_ADDRESS  FdtBlobBase;\r
+  EFI_PHYSICAL_ADDRESS  LinuxImage;\r
+  EFI_PHYSICAL_ADDRESS  InitrdImage;\r
+\r
+  PERF_START (NULL, "BDS", NULL, 0);\r
+\r
+  // Load the Linux kernel from a device path\r
+  LinuxImage = LINUX_KERNEL_MAX_OFFSET;\r
+  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);\r
+  if (EFI_ERROR(Status)) {\r
+    Print (L"ERROR: Did not find Linux kernel.\n");\r
+    return Status;\r
+  }\r
+\r
+  if (InitrdDevicePath) {\r
+    InitrdImage = LINUX_KERNEL_MAX_OFFSET;\r
+    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);\r
+    if (Status == EFI_OUT_OF_RESOURCES) {\r
+      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
+    }\r
+    if (EFI_ERROR(Status)) {\r
+      Print (L"ERROR: Did not find initrd image.\n");\r
+      return Status;\r
+    }\r
+\r
+    // Check if the initrd is a uInitrd\r
+    if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {\r
+      // Skip the 64-byte image header\r
+      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);\r
+      InitrdImageSize -= 64;\r
+    }\r
+  }\r
+\r
+  // Load the FDT binary from a device path. The FDT will be reloaded later to a more appropriate location for the Linux kernel.\r
+  FdtBlobBase = 0;\r
+  Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);\r
+  if (EFI_ERROR(Status)) {\r
+    Print (L"ERROR: Did not find Device Tree blob.\n");\r
+    return Status;\r
+  }\r
+\r
+  // Update the Fdt with the Initrd information. The FDT will increase in size.\r
+  // By setting address=0 we leave the memory allocation to the function\r
+  Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);\r
+  if (EFI_ERROR(Status)) {\r
+    Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status);\r
+    return Status;\r
+  }\r
+\r
+  return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);\r
+}\r
+\r
index d9439d9..7f8b03e 100644 (file)
   BdsAppLoader.c\r
   BdsHelper.c\r
   BdsLoadOption.c\r
-\r
-  BdsLinuxLoader.c\r
-  BdsLinuxAtag.c\r
   BdsLinuxFdt.c\r
 \r
+[Sources.ARM]\r
+  Arm/BdsLinuxLoader.c\r
+  Arm/BdsLinuxAtag.c\r
+\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   EmbeddedPkg/EmbeddedPkg.dec\r
diff --git a/ArmPkg/Library/BdsLib/BdsLinuxAtag.c b/ArmPkg/Library/BdsLib/BdsLinuxAtag.c
deleted file mode 100644 (file)
index 8946b14..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/** @file\r
-*\r
-*  Copyright (c) 2011-2012, 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
-#include "BdsLinuxLoader.h"\r
-\r
-// Point to the current ATAG\r
-STATIC LINUX_ATAG *mLinuxKernelCurrentAtag;\r
-\r
-STATIC\r
-VOID\r
-SetupCoreTag (\r
-  IN UINT32 PageSize\r
-  )\r
-{\r
-  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_CORE);\r
-  mLinuxKernelCurrentAtag->header.type = ATAG_CORE;\r
-\r
-  mLinuxKernelCurrentAtag->body.core_tag.flags    = 1;            /* ensure read-only */\r
-  mLinuxKernelCurrentAtag->body.core_tag.pagesize = PageSize;     /* systems PageSize (4k) */\r
-  mLinuxKernelCurrentAtag->body.core_tag.rootdev  = 0;            /* zero root device (typically overridden from kernel command line )*/\r
-\r
-  // move pointer to next tag\r
-  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
-}\r
-\r
-STATIC\r
-VOID\r
-SetupMemTag (\r
-  IN UINTN StartAddress,\r
-  IN UINT32 Size\r
-  )\r
-{\r
-  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_MEM);\r
-  mLinuxKernelCurrentAtag->header.type = ATAG_MEM;\r
-\r
-  mLinuxKernelCurrentAtag->body.mem_tag.start = StartAddress;    /* Start of memory chunk for AtagMem */\r
-  mLinuxKernelCurrentAtag->body.mem_tag.size  = Size;             /* Size of memory chunk for AtagMem */\r
-\r
-  // move pointer to next tag\r
-  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
-}\r
-\r
-STATIC\r
-VOID\r
-SetupCmdlineTag (\r
-  IN CONST CHAR8 *CmdLine\r
-  )\r
-{\r
-  UINT32 LineLength;\r
-\r
-  // Increment the line length by 1 to account for the null string terminator character\r
-  LineLength = AsciiStrLen(CmdLine) + 1;\r
-\r
-  /* Check for NULL strings.\r
-   * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.\r
-   * Remember, you have at least one null string terminator character.\r
-   */\r
-  if(LineLength > 1) {\r
-    mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof(LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2;\r
-    mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE;\r
-\r
-    /* place CommandLine into tag */\r
-    AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine);\r
-\r
-    // move pointer to next tag\r
-    mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
-  }\r
-}\r
-\r
-STATIC\r
-VOID\r
-SetupInitrdTag (\r
-  IN UINT32 InitrdImage,\r
-  IN UINT32 InitrdImageSize\r
-  )\r
-{\r
-  mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_INITRD2);\r
-  mLinuxKernelCurrentAtag->header.type = ATAG_INITRD2;\r
-\r
-  mLinuxKernelCurrentAtag->body.initrd2_tag.start = InitrdImage;\r
-  mLinuxKernelCurrentAtag->body.initrd2_tag.size = InitrdImageSize;\r
-\r
-  // Move pointer to next tag\r
-  mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);\r
-}\r
-STATIC\r
-VOID\r
-SetupEndTag (\r
-  VOID\r
-  )\r
-{\r
-  // Empty tag ends list; this has zero length and no body\r
-  mLinuxKernelCurrentAtag->header.type = ATAG_NONE;\r
-  mLinuxKernelCurrentAtag->header.size = 0;\r
-\r
-  /* We can not calculate the next address by using the standard macro:\r
-   * Params = next_tag_address(Params);\r
-   * because it relies on the header.size, which here it is 0 (zero).\r
-   * The easiest way is to add the sizeof(mLinuxKernelCurrentAtag->header).\r
-   */\r
-  mLinuxKernelCurrentAtag = (LINUX_ATAG*)((UINT32)mLinuxKernelCurrentAtag + sizeof(mLinuxKernelCurrentAtag->header));\r
-}\r
-\r
-EFI_STATUS\r
-PrepareAtagList (\r
-  IN  CONST CHAR8*          CommandLineString,\r
-  IN  EFI_PHYSICAL_ADDRESS  InitrdImage,\r
-  IN  UINTN                 InitrdImageSize,\r
-  OUT EFI_PHYSICAL_ADDRESS  *AtagBase,\r
-  OUT UINT32                *AtagSize\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  LIST_ENTRY                  *ResourceLink;\r
-  LIST_ENTRY                  ResourceList;\r
-  EFI_PHYSICAL_ADDRESS        AtagStartAddress;\r
-  BDS_SYSTEM_MEMORY_RESOURCE  *Resource;\r
-\r
-  AtagStartAddress = LINUX_ATAG_MAX_OFFSET;\r
-  Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG ((EFI_D_WARN, "Warning: Failed to allocate Atag at 0x%lX (%r). The Atag will be allocated somewhere else in System Memory.\n", AtagStartAddress, Status));\r
-    Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);\r
-    ASSERT_EFI_ERROR(Status);\r
-  }\r
-\r
-  // Ready to setup the atag list\r
-  mLinuxKernelCurrentAtag = (LINUX_ATAG*)(UINTN)AtagStartAddress;\r
-\r
-  // Standard core tag 4k PageSize\r
-  SetupCoreTag( (UINT32)SIZE_4KB );\r
-\r
-  // Physical memory setup\r
-  GetSystemMemoryResources (&ResourceList);\r
-  ResourceLink = ResourceList.ForwardLink;\r
-  while (ResourceLink != NULL && ResourceLink != &ResourceList) {\r
-    Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceLink;\r
-    DEBUG((EFI_D_INFO,"- [0x%08X,0x%08X]\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->PhysicalStart+(UINT32)Resource->ResourceLength));\r
-    SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength );\r
-    ResourceLink = ResourceLink->ForwardLink;\r
-  }\r
-\r
-  // CommandLine setting root device\r
-  if (CommandLineString) {\r
-    SetupCmdlineTag (CommandLineString);\r
-  }\r
-\r
-  if (InitrdImageSize > 0 && InitrdImage != 0) {\r
-    SetupInitrdTag ((UINT32)InitrdImage, (UINT32)InitrdImageSize);\r
-  }\r
-\r
-  // End of tags\r
-  SetupEndTag();\r
-\r
-  // Calculate atag list size\r
-  *AtagBase = AtagStartAddress;\r
-  *AtagSize = (UINT32)mLinuxKernelCurrentAtag - (UINT32)AtagStartAddress + 1;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
diff --git a/ArmPkg/Library/BdsLib/BdsLinuxLoader.c b/ArmPkg/Library/BdsLib/BdsLinuxLoader.c
deleted file mode 100644 (file)
index e3249e1..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/** @file\r
-*\r
-*  Copyright (c) 2011-2012, 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
-#include "BdsLinuxLoader.h"\r
-\r
-#define ALIGN32_BELOW(addr)   ALIGN_POINTER(addr - 32,32)\r
-\r
-STATIC\r
-EFI_STATUS\r
-PreparePlatformHardware (\r
-  VOID\r
-  )\r
-{\r
-  //Note: Interrupts will be disabled by the GIC driver when ExitBootServices() will be called.\r
-\r
-  // Clean, invalidate, disable data cache\r
-  ArmDisableDataCache();\r
-  ArmCleanInvalidateDataCache();\r
-\r
-  // Invalidate and disable the Instruction cache\r
-  ArmDisableInstructionCache ();\r
-  ArmInvalidateInstructionCache ();\r
-\r
-  // Turn off MMU\r
-  ArmDisableMmu();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-StartLinux (\r
-  IN  EFI_PHYSICAL_ADDRESS  LinuxImage,\r
-  IN  UINTN                 LinuxImageSize,\r
-  IN  EFI_PHYSICAL_ADDRESS  KernelParamsAddress,\r
-  IN  UINTN                 KernelParamsSize,\r
-  IN  UINT32                MachineType\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  LINUX_KERNEL          LinuxKernel;\r
-\r
-  // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on\r
-  // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.\r
-  Status = ShutdownUefiBootServices ();\r
-  if(EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));\r
-    goto Exit;\r
-  }\r
-\r
-  // Move the kernel parameters to any address inside the first 1MB.\r
-  // This is necessary because the ARM Linux kernel requires\r
-  // the FTD / ATAG List to reside entirely inside the first 1MB of\r
-  // physical memory.\r
-  //Note: There is no requirement on the alignment\r
-  if (MachineType != ARM_FDT_MACHINE_TYPE) {\r
-    if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) {\r
-      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);\r
-    }\r
-  } else {\r
-    if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) {\r
-      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);\r
-    }\r
-  }\r
-\r
-  if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) {\r
-    //Note: There is no requirement on the alignment\r
-    LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize);\r
-  } else {\r
-    LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;\r
-  }\r
-\r
-  // Check if the Linux Image is a uImage\r
-  if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {\r
-    // Assume the Image Entry Point is just after the uImage header (64-byte size)\r
-    LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64);\r
-    LinuxImageSize -= 64;\r
-  }\r
-\r
-  //TODO: Check there is no overlapping between kernel and Atag\r
-\r
-  //\r
-  // Switch off interrupts, caches, mmu, etc\r
-  //\r
-  Status = PreparePlatformHardware ();\r
-  ASSERT_EFI_ERROR(Status);\r
-\r
-  // Register and print out performance information\r
-  PERF_END (NULL, "BDS", NULL, 0);\r
-  if (PerformanceMeasurementEnabled ()) {\r
-    PrintPerformance ();\r
-  }\r
-\r
-  //\r
-  // Start the Linux Kernel\r
-  //\r
-\r
-  // Outside BootServices, so can't use Print();\r
-  DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));\r
-\r
-  // Jump to kernel with register set\r
-  LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);\r
-\r
-  // Kernel should never exit\r
-  // After Life services are not provided\r
-  ASSERT(FALSE);\r
-\r
-Exit:\r
-  // Only be here if we fail to start Linux\r
-  Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);\r
-\r
-  // Free Runtimee Memory (kernel and FDT)\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Start a Linux kernel from a Device Path\r
-\r
-  @param  LinuxKernel           Device Path to the Linux Kernel\r
-  @param  Parameters            Linux kernel arguments\r
-  @param  Fdt                   Device Path to the Flat Device Tree\r
-\r
-  @retval EFI_SUCCESS           All drivers have been connected\r
-  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
-  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsBootLinuxAtag (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
-  IN  CONST CHAR8*              CommandLineArguments\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  UINT32                LinuxImageSize;\r
-  UINT32                InitrdImageSize = 0;\r
-  UINT32                AtagSize;\r
-  EFI_PHYSICAL_ADDRESS  AtagBase;\r
-  EFI_PHYSICAL_ADDRESS  LinuxImage;\r
-  EFI_PHYSICAL_ADDRESS  InitrdImage;\r
-\r
-  PERF_START (NULL, "BDS", NULL, 0);\r
-\r
-  // Load the Linux kernel from a device path\r
-  LinuxImage = LINUX_KERNEL_MAX_OFFSET;\r
-  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);\r
-  if (EFI_ERROR(Status)) {\r
-    Print (L"ERROR: Did not find Linux kernel.\n");\r
-    return Status;\r
-  }\r
-\r
-  if (InitrdDevicePath) {\r
-    // Load the initrd near to the Linux kernel\r
-    InitrdImage = LINUX_KERNEL_MAX_OFFSET;\r
-    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
-    }\r
-    if (EFI_ERROR(Status)) {\r
-      Print (L"ERROR: Did not find initrd image.\n");\r
-      return Status;\r
-    }\r
-    \r
-    // Check if the initrd is a uInitrd\r
-    if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {\r
-      // Skip the 64-byte image header\r
-      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);\r
-      InitrdImageSize -= 64;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Setup the Linux Kernel Parameters\r
-  //\r
\r
-  // By setting address=0 we leave the memory allocation to the function\r
-  Status = PrepareAtagList (CommandLineArguments, InitrdImage, InitrdImageSize, &AtagBase, &AtagSize);\r
-  if (EFI_ERROR(Status)) {\r
-    Print(L"ERROR: Can not prepare ATAG list. Status=0x%X\n", Status);\r
-    return Status;\r
-  }\r
-\r
-  return StartLinux (LinuxImage, LinuxImageSize, AtagBase, AtagSize, PcdGet32(PcdArmMachineType));\r
-}\r
-\r
-/**\r
-  Start a Linux kernel from a Device Path\r
-\r
-  @param  LinuxKernel           Device Path to the Linux Kernel\r
-  @param  Parameters            Linux kernel arguments\r
-  @param  Fdt                   Device Path to the Flat Device Tree\r
-\r
-  @retval EFI_SUCCESS           All drivers have been connected\r
-  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
-  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsBootLinuxFdt (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,\r
-  IN  CONST CHAR8*              CommandLineArguments,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  UINT32                LinuxImageSize;\r
-  UINT32                InitrdImageSize = 0;\r
-  UINT32                FdtBlobSize;\r
-  EFI_PHYSICAL_ADDRESS  FdtBlobBase;\r
-  EFI_PHYSICAL_ADDRESS  LinuxImage;\r
-  EFI_PHYSICAL_ADDRESS  InitrdImage;\r
-\r
-  PERF_START (NULL, "BDS", NULL, 0);\r
-\r
-  // Load the Linux kernel from a device path\r
-  LinuxImage = LINUX_KERNEL_MAX_OFFSET;\r
-  Status = BdsLoadImage (LinuxKernelDevicePath, AllocateMaxAddress, &LinuxImage, &LinuxImageSize);\r
-  if (EFI_ERROR(Status)) {\r
-    Print (L"ERROR: Did not find Linux kernel.\n");\r
-    return Status;\r
-  }\r
-\r
-  if (InitrdDevicePath) {\r
-    InitrdImage = LINUX_KERNEL_MAX_OFFSET;\r
-    Status = BdsLoadImage (InitrdDevicePath, AllocateMaxAddress, &InitrdImage, &InitrdImageSize);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      Status = BdsLoadImage (InitrdDevicePath, AllocateAnyPages, &InitrdImage, &InitrdImageSize);\r
-    }\r
-    if (EFI_ERROR(Status)) {\r
-      Print (L"ERROR: Did not find initrd image.\n");\r
-      return Status;\r
-    }\r
-\r
-    // Check if the initrd is a uInitrd\r
-    if (*(UINT32*)((UINTN)InitrdImage) == LINUX_UIMAGE_SIGNATURE) {\r
-      // Skip the 64-byte image header\r
-      InitrdImage = (EFI_PHYSICAL_ADDRESS)((UINTN)InitrdImage + 64);\r
-      InitrdImageSize -= 64;\r
-    }\r
-  }\r
-\r
-  // Load the FDT binary from a device path. The FDT will be reloaded later to a more appropriate location for the Linux kernel.\r
-  FdtBlobBase = 0;\r
-  Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);\r
-  if (EFI_ERROR(Status)) {\r
-    Print (L"ERROR: Did not find Device Tree blob.\n");\r
-    return Status;\r
-  }\r
-\r
-  // Update the Fdt with the Initrd information. The FDT will increase in size.\r
-  // By setting address=0 we leave the memory allocation to the function\r
-  Status = PrepareFdt (CommandLineArguments, InitrdImage, InitrdImageSize, &FdtBlobBase, &FdtBlobSize);\r
-  if (EFI_ERROR(Status)) {\r
-    Print(L"ERROR: Can not load kernel with FDT. Status=%r\n", Status);\r
-    return Status;\r
-  }\r
-\r
-  return StartLinux (LinuxImage, LinuxImageSize, FdtBlobBase, FdtBlobSize, ARM_FDT_MACHINE_TYPE);\r
-}\r
-\r
diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S b/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.S
new file mode 100644 (file)
index 0000000..d92acfe
--- /dev/null
@@ -0,0 +1,276 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2012, ARM Ltd. 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 <Library/PcdLib.h>\r
+\r
+/*\r
+\r
+This is the stack constructed by the exception handler (low address to high address)\r
+                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM\r
+  Reg   Offset\r
+  ===   ======\r
+  R0    0x00    # stmfd     SP!,{R0-R12}\r
+  R1    0x04\r
+  R2    0x08\r
+  R3    0x0c\r
+  R4    0x10\r
+  R5    0x14\r
+  R6    0x18\r
+  R7    0x1c\r
+  R8    0x20\r
+  R9    0x24\r
+  R10   0x28\r
+  R11   0x2c\r
+  R12   0x30\r
+  SP    0x34    # reserved via adding 0x20 (32) to the SP\r
+  LR    0x38\r
+  PC    0x3c\r
+  CPSR  0x40\r
+  DFSR  0x44\r
+  DFAR  0x48\r
+  IFSR  0x4c\r
+  IFAR  0x50\r
+\r
+  LR    0x54    # SVC Link register (we need to restore it)\r
+\r
+  LR    0x58    # pushed by srsfd\r
+  CPSR  0x5c\r
+\r
+ */\r
+\r
+GCC_ASM_EXPORT(DebugAgentVectorTable)\r
+GCC_ASM_IMPORT(DefaultExceptionHandler)\r
+\r
+.text\r
+#if !defined(__APPLE__)\r
+.fpu neon    @ makes vpush/vpop assemble\r
+#endif\r
+.align 5\r
+\r
+\r
+//\r
+// This code gets copied to the ARM vector table\r
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied\r
+//\r
+ASM_PFX(DebugAgentVectorTable):\r
+  b ASM_PFX(ResetEntry)\r
+  b ASM_PFX(UndefinedInstructionEntry)\r
+  b ASM_PFX(SoftwareInterruptEntry)\r
+  b ASM_PFX(PrefetchAbortEntry)\r
+  b ASM_PFX(DataAbortEntry)\r
+  b ASM_PFX(ReservedExceptionEntry)\r
+  b ASM_PFX(IrqEntry)\r
+  b ASM_PFX(FiqEntry)\r
+\r
+ASM_PFX(ResetEntry):\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+                                      @ We are already in SVC mode\r
+\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+  \r
+  mov       R0,#0                     @ ExceptionType\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+ASM_PFX(UndefinedInstructionEntry):\r
+  sub       LR, LR, #4                @ Only -2 for Thumb, adjust in CommonExceptionEntry\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+  cps       #0x13                     @ Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+\r
+  mov       R0,#1                     @ ExceptionType\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+ASM_PFX(SoftwareInterruptEntry):\r
+  sub       LR, LR, #4                @ Only -2 for Thumb, adjust in CommonExceptionEntry\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+                                      @ We are already in SVC mode\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+\r
+  mov       R0,#2                     @ ExceptionType\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+ASM_PFX(PrefetchAbortEntry):\r
+  sub       LR,LR,#4\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+  cps       #0x13                     @ Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+\r
+  mov       R0,#3                     @ ExceptionType\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+ASM_PFX(DataAbortEntry):\r
+  sub       LR,LR,#8\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+  cps       #0x13                     @ Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+\r
+  mov       R0,#4\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+ASM_PFX(ReservedExceptionEntry):\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+  cps       #0x13                     @ Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+\r
+  mov       R0,#5\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+ASM_PFX(IrqEntry):\r
+  sub       LR,LR,#4\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+  cps       #0x13                     @ Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+\r
+  mov       R0,#6                     @ ExceptionType\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+ASM_PFX(FiqEntry):\r
+  sub       LR,LR,#4\r
+  srsdb     #0x13!                    @ Store return state on SVC stack\r
+  cps       #0x13                     @ Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
+  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              @ Store the register state\r
+                                      @ Since we have already switch to SVC R8_fiq - R12_fiq\r
+                                      @ never get used or saved\r
+  mov       R0,#7                     @ ExceptionType\r
+  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
+  bx        R1\r
+\r
+//\r
+// This gets patched by the C code that patches in the vector table\r
+//\r
+ASM_PFX(CommonExceptionEntry):\r
+  .word       ASM_PFX(AsmCommonExceptionEntry)\r
+\r
+ASM_PFX(ExceptionHandlersEnd):\r
+\r
+//\r
+// This code runs from CpuDxe driver loaded address. It is patched into\r
+// CommonExceptionEntry.\r
+//\r
+ASM_PFX(AsmCommonExceptionEntry):\r
+  mrc       p15, 0, R1, c6, c0, 2   @ Read IFAR\r
+  str       R1, [SP, #0x50]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR\r
+\r
+  mrc       p15, 0, R1, c5, c0, 1   @ Read IFSR\r
+  str       R1, [SP, #0x4c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR\r
+\r
+  mrc       p15, 0, R1, c6, c0, 0   @ Read DFAR\r
+  str       R1, [SP, #0x48]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR\r
+\r
+  mrc       p15, 0, R1, c5, c0, 0   @ Read DFSR\r
+  str       R1, [SP, #0x44]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR\r
+\r
+  ldr       R1, [SP, #0x5c]         @ srsdb saved pre-exception CPSR on the stack\r
+  str       R1, [SP, #0x40]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR\r
+\r
+  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
+  and       R3, R1, #0x1f           @ Check CPSR to see if User or System Mode\r
+  cmp       R3, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1df))\r
+  cmpne     R3, #0x10               @\r
+  stmeqed   R2, {lr}^               @   save unbanked lr\r
+                                    @ else\r
+  stmneed   R2, {lr}                @   save SVC lr\r
+\r
+\r
+  ldr       R5, [SP, #0x58]         @ PC is the LR pushed by srsfd\r
+                                    @ Check to see if we have to adjust for Thumb entry\r
+  sub       r4, r0, #1              @ if (ExceptionType == 1 || ExceptionType ==2)) {\r
+  cmp       r4, #1                  @   // UND & SVC have differnt LR adjust for Thumb\r
+  bhi       NoAdjustNeeded\r
+\r
+  tst       r1, #0x20               @   if ((CPSR & T)) == T) {  // Thumb Mode on entry\r
+  addne     R5, R5, #2              @     PC += 2@\r
+  str       R5,[SP,#0x58]           @ Update LR value pused by srsfd\r
+\r
+NoAdjustNeeded:\r
+\r
+  str       R5, [SP, #0x3c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC\r
+\r
+  sub       R1, SP, #0x60           @ We pused 0x60 bytes on the stack\r
+  str       R1, [SP, #0x34]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP\r
+\r
+                                    @ R0 is ExceptionType\r
+  mov       R1,SP                   @ R1 is SystemContext\r
+\r
+#if (FixedPcdGet32(PcdVFPEnabled))\r
+  vpush     {d0-d15}                @ save vstm registers in case they are used in optimizations\r
+#endif\r
+\r
+/*\r
+VOID\r
+EFIAPI\r
+DefaultExceptionHandler (\r
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0\r
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1\r
+  )\r
+\r
+*/\r
+  blx       ASM_PFX(DefaultExceptionHandler)  @ Call exception handler\r
+\r
+#if (FixedPcdGet32(PcdVFPEnabled))\r
+  vpop      {d0-d15}\r
+#endif\r
+\r
+  ldr       R1, [SP, #0x4c]         @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR\r
+  mcr       p15, 0, R1, c5, c0, 1   @ Write IFSR\r
+\r
+  ldr       R1, [SP, #0x44]         @ sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR\r
+  mcr       p15, 0, R1, c5, c0, 0   @ Write DFSR\r
+\r
+  ldr       R1,[SP,#0x3c]           @ EFI_SYSTEM_CONTEXT_ARM.PC\r
+  str       R1,[SP,#0x58]           @ Store it back to srsfd stack slot so it can be restored\r
+\r
+  ldr       R1,[SP,#0x40]           @ EFI_SYSTEM_CONTEXT_ARM.CPSR\r
+  str       R1,[SP,#0x5c]           @ Store it back to srsfd stack slot so it can be restored\r
+\r
+  add       R3, SP, #0x54           @ Make R3 point to SVC LR saved on entry\r
+  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
+  and       R1, R1, #0x1f           @ Check to see if User or System Mode\r
+  cmp       R1, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1f))\r
+  cmpne     R1, #0x10               @\r
+  ldmeqed   R2, {lr}^               @   restore unbanked lr\r
+                                    @ else\r
+  ldmneed   R3, {lr}                @   restore SVC lr, via ldmfd SP!, {LR}\r
+\r
+  ldmfd     SP!,{R0-R12}            @ Restore general purpose registers\r
+                                    @ Exception handler can not change SP\r
+\r
+  add       SP,SP,#0x20             @ Clear out the remaining stack space\r
+  ldmfd     SP!,{LR}                @ restore the link register for this context\r
+  rfefd     SP!                     @ return from exception via srsfd stack slot\r
+\r
diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm b/ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm
new file mode 100644 (file)
index 0000000..f281c06
--- /dev/null
@@ -0,0 +1,273 @@
+//------------------------------------------------------------------------------\r
+//\r
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
+// Copyright (c) 2011 - 2012, ARM Ltd. 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 <Library/PcdLib.h>\r
+\r
+/*\r
+\r
+This is the stack constructed by the exception handler (low address to high address)\r
+                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM\r
+  Reg   Offset\r
+  ===   ======\r
+  R0    0x00    # stmfd     SP!,{R0-R12}\r
+  R1    0x04\r
+  R2    0x08\r
+  R3    0x0c\r
+  R4    0x10\r
+  R5    0x14\r
+  R6    0x18\r
+  R7    0x1c\r
+  R8    0x20\r
+  R9    0x24\r
+  R10   0x28\r
+  R11   0x2c\r
+  R12   0x30\r
+  SP    0x34    # reserved via adding 0x20 (32) to the SP\r
+  LR    0x38\r
+  PC    0x3c\r
+  CPSR  0x40\r
+  DFSR  0x44\r
+  DFAR  0x48\r
+  IFSR  0x4c\r
+  IFAR  0x50\r
+\r
+  LR    0x54    # SVC Link register (we need to restore it)\r
+  \r
+  LR    0x58    # pushed by srsfd\r
+  CPSR  0x5c\r
+\r
+ */\r
+\r
+  EXPORT  DebugAgentVectorTable\r
+  IMPORT  DefaultExceptionHandler\r
+\r
+  PRESERVE8\r
+  AREA  DebugAgentException, CODE, READONLY, CODEALIGN, ALIGN=5\r
+\r
+//\r
+// This code gets copied to the ARM vector table\r
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied\r
+//\r
+DebugAgentVectorTable FUNCTION\r
+  b   ResetEntry\r
+  b   UndefinedInstructionEntry\r
+  b   SoftwareInterruptEntry\r
+  b   PrefetchAbortEntry\r
+  b   DataAbortEntry\r
+  b   ReservedExceptionEntry\r
+  b   IrqEntry\r
+  b   FiqEntry\r
+  ENDFUNC\r
+\r
+ResetEntry\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+                                      ; We are already in SVC mode\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+  \r
+  mov       R0,#0                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry\r
+  bx        R1\r
+\r
+UndefinedInstructionEntry\r
+  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+  cps       #0x13                     ; Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+\r
+  mov       R0,#1                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry;\r
+  bx        R1\r
+\r
+SoftwareInterruptEntry\r
+  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+                                      ; We are already in SVC mode\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+\r
+  mov       R0,#2                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry\r
+  bx        R1\r
+\r
+PrefetchAbortEntry\r
+  sub       LR,LR,#4\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+  cps       #0x13                     ; Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+\r
+  mov       R0,#3                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry\r
+  bx        R1\r
+\r
+DataAbortEntry\r
+  sub       LR,LR,#8\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+  cps       #0x13                     ; Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+\r
+  mov       R0,#4                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry\r
+  bx        R1\r
+\r
+ReservedExceptionEntry\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+  cps       #0x13                     ; Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+\r
+  mov       R0,#5                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry\r
+  bx        R1\r
+\r
+IrqEntry\r
+  sub       LR,LR,#4\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+  cps       #0x13                     ; Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+\r
+  mov       R0,#6                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry\r
+  bx        R1\r
+\r
+FiqEntry\r
+  sub       LR,LR,#4\r
+  srsfd     #0x13!                    ; Store return state on SVC stack\r
+  cps       #0x13                     ; Switch to SVC for common stack\r
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
+  stmfd     SP!,{R0-R12}              ; Store the register state\r
+                                      ; Since we have already switch to SVC R8_fiq - R12_fiq\r
+                                      ; never get used or saved\r
+  mov       R0,#7                     ; ExceptionType\r
+  ldr       R1,CommonExceptionEntry\r
+  bx        R1\r
+\r
+//\r
+// This gets patched by the C code that patches in the vector table\r
+//\r
+CommonExceptionEntry\r
+  dcd       AsmCommonExceptionEntry\r
+\r
+ExceptionHandlersEnd\r
+\r
+//\r
+// This code runs from CpuDxe driver loaded address. It is patched into\r
+// CommonExceptionEntry.\r
+//\r
+AsmCommonExceptionEntry\r
+  mrc       p15, 0, R1, c6, c0, 2   ; Read IFAR\r
+  str       R1, [SP, #0x50]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR\r
+\r
+  mrc       p15, 0, R1, c5, c0, 1   ; Read IFSR\r
+  str       R1, [SP, #0x4c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR\r
+\r
+  mrc       p15, 0, R1, c6, c0, 0   ; Read DFAR\r
+  str       R1, [SP, #0x48]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR\r
+\r
+  mrc       p15, 0, R1, c5, c0, 0   ; Read DFSR\r
+  str       R1, [SP, #0x44]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR\r
+\r
+  ldr       R1, [SP, #0x5c]         ; srsfd saved pre-exception CPSR on the stack\r
+  str       R1, [SP, #0x40]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR\r
+\r
+  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
+  and       R3, R1, #0x1f           ; Check CPSR to see if User or System Mode\r
+  cmp       R3, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1df))\r
+  cmpne     R3, #0x10               ;\r
+  stmeqed   R2, {lr}^               ;   save unbanked lr\r
+                                    ; else\r
+  stmneed   R2, {lr}                ;   save SVC lr\r
+\r
+\r
+  ldr       R5, [SP, #0x58]         ; PC is the LR pushed by srsfd\r
+                                    ; Check to see if we have to adjust for Thumb entry\r
+  sub       r4, r0, #1              ; if (ExceptionType == 1 || ExceptionType ==2)) {\r
+  cmp       r4, #1                  ;   // UND & SVC have differnt LR adjust for Thumb\r
+  bhi       NoAdjustNeeded\r
+\r
+  tst       r1, #0x20               ;   if ((CPSR & T)) == T) {  // Thumb Mode on entry\r
+  addne     R5, R5, #2              ;     PC += 2;\r
+  str       R5,[SP,#0x58]           ; Update LR value pused by srsfd\r
+\r
+NoAdjustNeeded\r
+\r
+  str       R5, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC\r
+\r
+  sub       R1, SP, #0x60           ; We pused 0x60 bytes on the stack\r
+  str       R1, [SP, #0x34]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP\r
+\r
+                                    ; R0 is ExceptionType\r
+  mov       R1,SP                   ; R1 is SystemContext\r
+\r
+#if (FixedPcdGet32(PcdVFPEnabled))\r
+  vpush    {d0-d15}                  ; save vstm registers in case they are used in optimizations\r
+#endif\r
+\r
+/*\r
+VOID\r
+EFIAPI\r
+DefaultExceptionHandler (\r
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0\r
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1\r
+  )\r
+\r
+*/\r
+  blx       DefaultExceptionHandler ; Call exception handler\r
+\r
+#if (FixedPcdGet32(PcdVFPEnabled))\r
+  vpop      {d0-d15}\r
+#endif\r
+\r
+  ldr       R1, [SP, #0x4c]         ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR\r
+  mcr       p15, 0, R1, c5, c0, 1   ; Write IFSR\r
+\r
+  ldr       R1, [SP, #0x44]         ; sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR\r
+  mcr       p15, 0, R1, c5, c0, 0   ; Write DFSR\r
+\r
+  ldr       R1,[SP,#0x3c]           ; EFI_SYSTEM_CONTEXT_ARM.PC\r
+  str       R1,[SP,#0x58]           ; Store it back to srsfd stack slot so it can be restored\r
+\r
+  ldr       R1,[SP,#0x40]           ; EFI_SYSTEM_CONTEXT_ARM.CPSR\r
+  str       R1,[SP,#0x5c]           ; Store it back to srsfd stack slot so it can be restored\r
+\r
+  add       R3, SP, #0x54           ; Make R3 point to SVC LR saved on entry\r
+  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
+  and       R1, R1, #0x1f           ; Check to see if User or System Mode\r
+  cmp       R1, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1f))\r
+  cmpne     R1, #0x10               ;\r
+  ldmeqed   R2, {lr}^               ;   restore unbanked lr\r
+                                    ; else\r
+  ldmneed   R3, {lr}                ;   restore SVC lr, via ldmfd SP!, {LR}\r
+\r
+  ldmfd     SP!,{R0-R12}            ; Restore general purpose registers\r
+                                    ; Exception handler can not change SP\r
+\r
+  add       SP,SP,#0x20             ; Clear out the remaining stack space\r
+  ldmfd     SP!,{LR}                ; restore the link register for this context\r
+  rfefd     SP!                     ; return from exception via srsfd stack slot\r
+\r
+  END\r
diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentException.S b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentException.S
deleted file mode 100644 (file)
index d92acfe..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
-# Copyright (c) 2011 - 2012, ARM Ltd. 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 <Library/PcdLib.h>\r
-\r
-/*\r
-\r
-This is the stack constructed by the exception handler (low address to high address)\r
-                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM\r
-  Reg   Offset\r
-  ===   ======\r
-  R0    0x00    # stmfd     SP!,{R0-R12}\r
-  R1    0x04\r
-  R2    0x08\r
-  R3    0x0c\r
-  R4    0x10\r
-  R5    0x14\r
-  R6    0x18\r
-  R7    0x1c\r
-  R8    0x20\r
-  R9    0x24\r
-  R10   0x28\r
-  R11   0x2c\r
-  R12   0x30\r
-  SP    0x34    # reserved via adding 0x20 (32) to the SP\r
-  LR    0x38\r
-  PC    0x3c\r
-  CPSR  0x40\r
-  DFSR  0x44\r
-  DFAR  0x48\r
-  IFSR  0x4c\r
-  IFAR  0x50\r
-\r
-  LR    0x54    # SVC Link register (we need to restore it)\r
-\r
-  LR    0x58    # pushed by srsfd\r
-  CPSR  0x5c\r
-\r
- */\r
-\r
-GCC_ASM_EXPORT(DebugAgentVectorTable)\r
-GCC_ASM_IMPORT(DefaultExceptionHandler)\r
-\r
-.text\r
-#if !defined(__APPLE__)\r
-.fpu neon    @ makes vpush/vpop assemble\r
-#endif\r
-.align 5\r
-\r
-\r
-//\r
-// This code gets copied to the ARM vector table\r
-// ExceptionHandlersStart - ExceptionHandlersEnd gets copied\r
-//\r
-ASM_PFX(DebugAgentVectorTable):\r
-  b ASM_PFX(ResetEntry)\r
-  b ASM_PFX(UndefinedInstructionEntry)\r
-  b ASM_PFX(SoftwareInterruptEntry)\r
-  b ASM_PFX(PrefetchAbortEntry)\r
-  b ASM_PFX(DataAbortEntry)\r
-  b ASM_PFX(ReservedExceptionEntry)\r
-  b ASM_PFX(IrqEntry)\r
-  b ASM_PFX(FiqEntry)\r
-\r
-ASM_PFX(ResetEntry):\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-                                      @ We are already in SVC mode\r
-\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-  \r
-  mov       R0,#0                     @ ExceptionType\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-ASM_PFX(UndefinedInstructionEntry):\r
-  sub       LR, LR, #4                @ Only -2 for Thumb, adjust in CommonExceptionEntry\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-  cps       #0x13                     @ Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-\r
-  mov       R0,#1                     @ ExceptionType\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-ASM_PFX(SoftwareInterruptEntry):\r
-  sub       LR, LR, #4                @ Only -2 for Thumb, adjust in CommonExceptionEntry\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-                                      @ We are already in SVC mode\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-\r
-  mov       R0,#2                     @ ExceptionType\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-ASM_PFX(PrefetchAbortEntry):\r
-  sub       LR,LR,#4\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-  cps       #0x13                     @ Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-\r
-  mov       R0,#3                     @ ExceptionType\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-ASM_PFX(DataAbortEntry):\r
-  sub       LR,LR,#8\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-  cps       #0x13                     @ Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-\r
-  mov       R0,#4\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-ASM_PFX(ReservedExceptionEntry):\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-  cps       #0x13                     @ Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-\r
-  mov       R0,#5\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-ASM_PFX(IrqEntry):\r
-  sub       LR,LR,#4\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-  cps       #0x13                     @ Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-\r
-  mov       R0,#6                     @ ExceptionType\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-ASM_PFX(FiqEntry):\r
-  sub       LR,LR,#4\r
-  srsdb     #0x13!                    @ Store return state on SVC stack\r
-  cps       #0x13                     @ Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  @ Store the link register for the current mode\r
-  sub       SP,SP,#0x20               @ Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              @ Store the register state\r
-                                      @ Since we have already switch to SVC R8_fiq - R12_fiq\r
-                                      @ never get used or saved\r
-  mov       R0,#7                     @ ExceptionType\r
-  ldr       R1,ASM_PFX(CommonExceptionEntry)\r
-  bx        R1\r
-\r
-//\r
-// This gets patched by the C code that patches in the vector table\r
-//\r
-ASM_PFX(CommonExceptionEntry):\r
-  .word       ASM_PFX(AsmCommonExceptionEntry)\r
-\r
-ASM_PFX(ExceptionHandlersEnd):\r
-\r
-//\r
-// This code runs from CpuDxe driver loaded address. It is patched into\r
-// CommonExceptionEntry.\r
-//\r
-ASM_PFX(AsmCommonExceptionEntry):\r
-  mrc       p15, 0, R1, c6, c0, 2   @ Read IFAR\r
-  str       R1, [SP, #0x50]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR\r
-\r
-  mrc       p15, 0, R1, c5, c0, 1   @ Read IFSR\r
-  str       R1, [SP, #0x4c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR\r
-\r
-  mrc       p15, 0, R1, c6, c0, 0   @ Read DFAR\r
-  str       R1, [SP, #0x48]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR\r
-\r
-  mrc       p15, 0, R1, c5, c0, 0   @ Read DFSR\r
-  str       R1, [SP, #0x44]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR\r
-\r
-  ldr       R1, [SP, #0x5c]         @ srsdb saved pre-exception CPSR on the stack\r
-  str       R1, [SP, #0x40]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR\r
-\r
-  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
-  and       R3, R1, #0x1f           @ Check CPSR to see if User or System Mode\r
-  cmp       R3, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1df))\r
-  cmpne     R3, #0x10               @\r
-  stmeqed   R2, {lr}^               @   save unbanked lr\r
-                                    @ else\r
-  stmneed   R2, {lr}                @   save SVC lr\r
-\r
-\r
-  ldr       R5, [SP, #0x58]         @ PC is the LR pushed by srsfd\r
-                                    @ Check to see if we have to adjust for Thumb entry\r
-  sub       r4, r0, #1              @ if (ExceptionType == 1 || ExceptionType ==2)) {\r
-  cmp       r4, #1                  @   // UND & SVC have differnt LR adjust for Thumb\r
-  bhi       NoAdjustNeeded\r
-\r
-  tst       r1, #0x20               @   if ((CPSR & T)) == T) {  // Thumb Mode on entry\r
-  addne     R5, R5, #2              @     PC += 2@\r
-  str       R5,[SP,#0x58]           @ Update LR value pused by srsfd\r
-\r
-NoAdjustNeeded:\r
-\r
-  str       R5, [SP, #0x3c]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC\r
-\r
-  sub       R1, SP, #0x60           @ We pused 0x60 bytes on the stack\r
-  str       R1, [SP, #0x34]         @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP\r
-\r
-                                    @ R0 is ExceptionType\r
-  mov       R1,SP                   @ R1 is SystemContext\r
-\r
-#if (FixedPcdGet32(PcdVFPEnabled))\r
-  vpush     {d0-d15}                @ save vstm registers in case they are used in optimizations\r
-#endif\r
-\r
-/*\r
-VOID\r
-EFIAPI\r
-DefaultExceptionHandler (\r
-  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0\r
-  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1\r
-  )\r
-\r
-*/\r
-  blx       ASM_PFX(DefaultExceptionHandler)  @ Call exception handler\r
-\r
-#if (FixedPcdGet32(PcdVFPEnabled))\r
-  vpop      {d0-d15}\r
-#endif\r
-\r
-  ldr       R1, [SP, #0x4c]         @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR\r
-  mcr       p15, 0, R1, c5, c0, 1   @ Write IFSR\r
-\r
-  ldr       R1, [SP, #0x44]         @ sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR\r
-  mcr       p15, 0, R1, c5, c0, 0   @ Write DFSR\r
-\r
-  ldr       R1,[SP,#0x3c]           @ EFI_SYSTEM_CONTEXT_ARM.PC\r
-  str       R1,[SP,#0x58]           @ Store it back to srsfd stack slot so it can be restored\r
-\r
-  ldr       R1,[SP,#0x40]           @ EFI_SYSTEM_CONTEXT_ARM.CPSR\r
-  str       R1,[SP,#0x5c]           @ Store it back to srsfd stack slot so it can be restored\r
-\r
-  add       R3, SP, #0x54           @ Make R3 point to SVC LR saved on entry\r
-  add       R2, SP, #0x38           @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
-  and       R1, R1, #0x1f           @ Check to see if User or System Mode\r
-  cmp       R1, #0x1f               @ if ((CPSR == 0x10) || (CPSR == 0x1f))\r
-  cmpne     R1, #0x10               @\r
-  ldmeqed   R2, {lr}^               @   restore unbanked lr\r
-                                    @ else\r
-  ldmneed   R3, {lr}                @   restore SVC lr, via ldmfd SP!, {LR}\r
-\r
-  ldmfd     SP!,{R0-R12}            @ Restore general purpose registers\r
-                                    @ Exception handler can not change SP\r
-\r
-  add       SP,SP,#0x20             @ Clear out the remaining stack space\r
-  ldmfd     SP!,{LR}                @ restore the link register for this context\r
-  rfefd     SP!                     @ return from exception via srsfd stack slot\r
-\r
diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentException.asm b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentException.asm
deleted file mode 100644 (file)
index f281c06..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-//------------------------------------------------------------------------------\r
-//\r
-// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
-// Copyright (c) 2011 - 2012, ARM Ltd. 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 <Library/PcdLib.h>\r
-\r
-/*\r
-\r
-This is the stack constructed by the exception handler (low address to high address)\r
-                # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM\r
-  Reg   Offset\r
-  ===   ======\r
-  R0    0x00    # stmfd     SP!,{R0-R12}\r
-  R1    0x04\r
-  R2    0x08\r
-  R3    0x0c\r
-  R4    0x10\r
-  R5    0x14\r
-  R6    0x18\r
-  R7    0x1c\r
-  R8    0x20\r
-  R9    0x24\r
-  R10   0x28\r
-  R11   0x2c\r
-  R12   0x30\r
-  SP    0x34    # reserved via adding 0x20 (32) to the SP\r
-  LR    0x38\r
-  PC    0x3c\r
-  CPSR  0x40\r
-  DFSR  0x44\r
-  DFAR  0x48\r
-  IFSR  0x4c\r
-  IFAR  0x50\r
-\r
-  LR    0x54    # SVC Link register (we need to restore it)\r
-  \r
-  LR    0x58    # pushed by srsfd\r
-  CPSR  0x5c\r
-\r
- */\r
-\r
-  EXPORT  DebugAgentVectorTable\r
-  IMPORT  DefaultExceptionHandler\r
-\r
-  PRESERVE8\r
-  AREA  DebugAgentException, CODE, READONLY, CODEALIGN, ALIGN=5\r
-\r
-//\r
-// This code gets copied to the ARM vector table\r
-// ExceptionHandlersStart - ExceptionHandlersEnd gets copied\r
-//\r
-DebugAgentVectorTable FUNCTION\r
-  b   ResetEntry\r
-  b   UndefinedInstructionEntry\r
-  b   SoftwareInterruptEntry\r
-  b   PrefetchAbortEntry\r
-  b   DataAbortEntry\r
-  b   ReservedExceptionEntry\r
-  b   IrqEntry\r
-  b   FiqEntry\r
-  ENDFUNC\r
-\r
-ResetEntry\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-                                      ; We are already in SVC mode\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-  \r
-  mov       R0,#0                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry\r
-  bx        R1\r
-\r
-UndefinedInstructionEntry\r
-  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-  cps       #0x13                     ; Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-\r
-  mov       R0,#1                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry;\r
-  bx        R1\r
-\r
-SoftwareInterruptEntry\r
-  sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-                                      ; We are already in SVC mode\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-\r
-  mov       R0,#2                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry\r
-  bx        R1\r
-\r
-PrefetchAbortEntry\r
-  sub       LR,LR,#4\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-  cps       #0x13                     ; Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-\r
-  mov       R0,#3                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry\r
-  bx        R1\r
-\r
-DataAbortEntry\r
-  sub       LR,LR,#8\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-  cps       #0x13                     ; Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-\r
-  mov       R0,#4                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry\r
-  bx        R1\r
-\r
-ReservedExceptionEntry\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-  cps       #0x13                     ; Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-\r
-  mov       R0,#5                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry\r
-  bx        R1\r
-\r
-IrqEntry\r
-  sub       LR,LR,#4\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-  cps       #0x13                     ; Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-\r
-  mov       R0,#6                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry\r
-  bx        R1\r
-\r
-FiqEntry\r
-  sub       LR,LR,#4\r
-  srsfd     #0x13!                    ; Store return state on SVC stack\r
-  cps       #0x13                     ; Switch to SVC for common stack\r
-  stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
-  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
-  stmfd     SP!,{R0-R12}              ; Store the register state\r
-                                      ; Since we have already switch to SVC R8_fiq - R12_fiq\r
-                                      ; never get used or saved\r
-  mov       R0,#7                     ; ExceptionType\r
-  ldr       R1,CommonExceptionEntry\r
-  bx        R1\r
-\r
-//\r
-// This gets patched by the C code that patches in the vector table\r
-//\r
-CommonExceptionEntry\r
-  dcd       AsmCommonExceptionEntry\r
-\r
-ExceptionHandlersEnd\r
-\r
-//\r
-// This code runs from CpuDxe driver loaded address. It is patched into\r
-// CommonExceptionEntry.\r
-//\r
-AsmCommonExceptionEntry\r
-  mrc       p15, 0, R1, c6, c0, 2   ; Read IFAR\r
-  str       R1, [SP, #0x50]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR\r
-\r
-  mrc       p15, 0, R1, c5, c0, 1   ; Read IFSR\r
-  str       R1, [SP, #0x4c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR\r
-\r
-  mrc       p15, 0, R1, c6, c0, 0   ; Read DFAR\r
-  str       R1, [SP, #0x48]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR\r
-\r
-  mrc       p15, 0, R1, c5, c0, 0   ; Read DFSR\r
-  str       R1, [SP, #0x44]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR\r
-\r
-  ldr       R1, [SP, #0x5c]         ; srsfd saved pre-exception CPSR on the stack\r
-  str       R1, [SP, #0x40]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR\r
-\r
-  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
-  and       R3, R1, #0x1f           ; Check CPSR to see if User or System Mode\r
-  cmp       R3, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1df))\r
-  cmpne     R3, #0x10               ;\r
-  stmeqed   R2, {lr}^               ;   save unbanked lr\r
-                                    ; else\r
-  stmneed   R2, {lr}                ;   save SVC lr\r
-\r
-\r
-  ldr       R5, [SP, #0x58]         ; PC is the LR pushed by srsfd\r
-                                    ; Check to see if we have to adjust for Thumb entry\r
-  sub       r4, r0, #1              ; if (ExceptionType == 1 || ExceptionType ==2)) {\r
-  cmp       r4, #1                  ;   // UND & SVC have differnt LR adjust for Thumb\r
-  bhi       NoAdjustNeeded\r
-\r
-  tst       r1, #0x20               ;   if ((CPSR & T)) == T) {  // Thumb Mode on entry\r
-  addne     R5, R5, #2              ;     PC += 2;\r
-  str       R5,[SP,#0x58]           ; Update LR value pused by srsfd\r
-\r
-NoAdjustNeeded\r
-\r
-  str       R5, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC\r
-\r
-  sub       R1, SP, #0x60           ; We pused 0x60 bytes on the stack\r
-  str       R1, [SP, #0x34]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP\r
-\r
-                                    ; R0 is ExceptionType\r
-  mov       R1,SP                   ; R1 is SystemContext\r
-\r
-#if (FixedPcdGet32(PcdVFPEnabled))\r
-  vpush    {d0-d15}                  ; save vstm registers in case they are used in optimizations\r
-#endif\r
-\r
-/*\r
-VOID\r
-EFIAPI\r
-DefaultExceptionHandler (\r
-  IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0\r
-  IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1\r
-  )\r
-\r
-*/\r
-  blx       DefaultExceptionHandler ; Call exception handler\r
-\r
-#if (FixedPcdGet32(PcdVFPEnabled))\r
-  vpop      {d0-d15}\r
-#endif\r
-\r
-  ldr       R1, [SP, #0x4c]         ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR\r
-  mcr       p15, 0, R1, c5, c0, 1   ; Write IFSR\r
-\r
-  ldr       R1, [SP, #0x44]         ; sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR\r
-  mcr       p15, 0, R1, c5, c0, 0   ; Write DFSR\r
-\r
-  ldr       R1,[SP,#0x3c]           ; EFI_SYSTEM_CONTEXT_ARM.PC\r
-  str       R1,[SP,#0x58]           ; Store it back to srsfd stack slot so it can be restored\r
-\r
-  ldr       R1,[SP,#0x40]           ; EFI_SYSTEM_CONTEXT_ARM.CPSR\r
-  str       R1,[SP,#0x5c]           ; Store it back to srsfd stack slot so it can be restored\r
-\r
-  add       R3, SP, #0x54           ; Make R3 point to SVC LR saved on entry\r
-  add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
-  and       R1, R1, #0x1f           ; Check to see if User or System Mode\r
-  cmp       R1, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1f))\r
-  cmpne     R1, #0x10               ;\r
-  ldmeqed   R2, {lr}^               ;   restore unbanked lr\r
-                                    ; else\r
-  ldmneed   R3, {lr}                ;   restore SVC lr, via ldmfd SP!, {LR}\r
-\r
-  ldmfd     SP!,{R0-R12}            ; Restore general purpose registers\r
-                                    ; Exception handler can not change SP\r
-\r
-  add       SP,SP,#0x20             ; Clear out the remaining stack space\r
-  ldmfd     SP!,{LR}                ; restore the link register for this context\r
-  rfefd     SP!                     ; return from exception via srsfd stack slot\r
-\r
-  END\r
index 1cf0b33..f6a0ec2 100644 (file)
 \r
 [Sources.common]\r
   DebugAgentSymbolsBaseLib.c\r
-  DebugAgentException.asm        | RVCT\r
-  DebugAgentException.S          | GCC\r
-  \r
+\r
+[Sources.ARM]\r
+  Arm/DebugAgentException.asm        | RVCT\r
+  Arm/DebugAgentException.S          | GCC\r
+\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c
new file mode 100644 (file)
index 0000000..bb29b95
--- /dev/null
@@ -0,0 +1,268 @@
+/** @file\r
+  Default exception handler\r
+\r
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
+  Copyright (c) 2012, ARM Ltd. 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
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/ArmDisassemblerLib.h>\r
+#include <Library/SerialPortLib.h>\r
+\r
+#include <Guid/DebugImageInfoTable.h>\r
+\r
+#include <Protocol/DebugSupport.h>\r
+#include <Library/DefaultExceptionHandlerLib.h>\r
+\r
+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;\r
+\r
+typedef struct {\r
+  UINT32  BIT;\r
+  CHAR8   Char;\r
+} CPSR_CHAR;\r
+\r
+CHAR8 *\r
+GetImageName (\r
+  IN  UINT32  FaultAddress,\r
+  OUT UINT32  *ImageBase,\r
+  OUT UINT32  *PeCoffSizeOfHeaders\r
+  );\r
+\r
+/**\r
+  Convert the Current Program Status Register (CPSR) to a string. The string is \r
+  a defacto standard in the ARM world. \r
+  \r
+  It is possible to add extra bits by adding them to CpsrChar array.\r
+\r
+  @param  Cpsr         ARM CPSR register value\r
+  @param  ReturnStr    32 byte string that contains string version of CPSR\r
+\r
+**/\r
+VOID\r
+CpsrString (\r
+  IN  UINT32  Cpsr,\r
+  OUT CHAR8   *ReturnStr\r
+  )\r
+{\r
+  UINTN     Index;\r
+  CHAR8*    Str;\r
+  CHAR8*    ModeStr;\r
+  CPSR_CHAR CpsrChar[] = {\r
+    { 31, 'n' },\r
+    { 30, 'z' },\r
+    { 29, 'c' },\r
+    { 28, 'v' },\r
+\r
+    { 9,  'e' },\r
+    { 8,  'a' },\r
+    { 7,  'i' },\r
+    { 6,  'f' },\r
+    { 5,  't' },\r
+    { 0,  '?' }\r
+  };\r
+  \r
+  Str = ReturnStr;\r
+\r
+  for (Index = 0; CpsrChar[Index].BIT != 0; Index++, Str++) {\r
+    *Str = CpsrChar[Index].Char;\r
+    if ((Cpsr & (1 << CpsrChar[Index].BIT)) != 0) {\r
+      // Concert to upper case if bit is set\r
+      *Str &= ~0x20;\r
+    }\r
+  }\r
+  \r
+  *Str++ = '_';\r
+  *Str = '\0';\r
+  \r
+  switch (Cpsr & 0x1f) {\r
+  case 0x10:\r
+    ModeStr = "usr";\r
+    break;\r
+  case 0x011:\r
+    ModeStr = "fiq";\r
+    break;\r
+  case 0x12:\r
+    ModeStr = "irq";\r
+    break;\r
+  case 0x13:\r
+    ModeStr = "svc";\r
+    break;\r
+  case 0x16:\r
+    ModeStr = "mon";\r
+    break;\r
+  case 0x17:\r
+    ModeStr = "abt";\r
+    break;\r
+  case 0x1b:\r
+    ModeStr = "und";\r
+    break;\r
+  case 0x1f:\r
+    ModeStr = "sys";\r
+    break;\r
+  \r
+  default:\r
+    ModeStr = "???";\r
+    break;\r
+  }\r
+  \r
+  AsciiStrCat (Str, ModeStr);\r
+  return;\r
+}  \r
+\r
+CHAR8 *\r
+FaultStatusToString (\r
+  IN  UINT32  Status\r
+  )\r
+{\r
+  CHAR8 *FaultSource;\r
+\r
+  switch (Status) {\r
+    case 0x01: FaultSource = "Alignment fault"; break;\r
+    case 0x02: FaultSource = "Debug event fault"; break;\r
+    case 0x03: FaultSource = "Access Flag fault on Section"; break;\r
+    case 0x04: FaultSource = "Cache maintenance operation fault[2]"; break;\r
+    case 0x05: FaultSource = "Translation fault on Section"; break;\r
+    case 0x06: FaultSource = "Access Flag fault on Page"; break;\r
+    case 0x07: FaultSource = "Translation fault on Page"; break;\r
+    case 0x08: FaultSource = "Precise External Abort"; break;\r
+    case 0x09: FaultSource = "Domain fault on Section"; break;\r
+    case 0x0b: FaultSource = "Domain fault on Page"; break;\r
+    case 0x0c: FaultSource = "External abort on translation, first level"; break;\r
+    case 0x0d: FaultSource = "Permission fault on Section"; break;\r
+    case 0x0e: FaultSource = "External abort on translation, second level"; break;\r
+    case 0x0f: FaultSource = "Permission fault on Page"; break;\r
+    case 0x16: FaultSource = "Imprecise External Abort"; break;\r
+    default:   FaultSource = "No function"; break;\r
+    }\r
+\r
+  return FaultSource;\r
+}\r
+\r
+STATIC CHAR8 *gExceptionTypeString[] = {\r
+  "Reset",\r
+  "Undefined OpCode",\r
+  "SVC",\r
+  "Prefetch Abort",\r
+  "Data Abort",\r
+  "Undefined",\r
+  "IRQ",\r
+  "FIQ"\r
+};\r
+\r
+/**\r
+  This is the default action to take on an unexpected exception\r
+  \r
+  Since this is exception context don't do anything crazy like try to allcoate memory.\r
+\r
+  @param  ExceptionType    Type of the exception\r
+  @param  SystemContext    Register state at the time of the Exception\r
+\r
+\r
+**/\r
+VOID\r
+DefaultExceptionHandler (\r
+  IN     EFI_EXCEPTION_TYPE           ExceptionType,\r
+  IN OUT EFI_SYSTEM_CONTEXT           SystemContext\r
+  )\r
+{\r
+  CHAR8     Buffer[100];\r
+  UINTN     CharCount;\r
+  UINT32    DfsrStatus;\r
+  UINT32    IfsrStatus;\r
+  BOOLEAN   DfsrWrite;\r
+  UINT32    PcAdjust = 0;\r
+\r
+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n%a Exception PC at 0x%08x  CPSR 0x%08x ",\r
+         gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);\r
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
+\r
+  DEBUG_CODE_BEGIN ();\r
+    CHAR8   *Pdb;\r
+    UINT32  ImageBase;\r
+    UINT32  PeCoffSizeOfHeader;\r
+    UINT32  Offset;\r
+    CHAR8   CpsrStr[32];  // char per bit. Lower 5-bits are mode that is a 3 char string\r
+    CHAR8   Buffer[80];\r
+    UINT8   *DisAsm;\r
+    UINT32  ItBlock;\r
+    \r
+    CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);\r
+    DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));\r
+  \r
+    Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);\r
+    Offset = SystemContext.SystemContextArm->PC - ImageBase;\r
+    if (Pdb != NULL) {\r
+      DEBUG ((EFI_D_ERROR, "%a\n", Pdb));\r
+\r
+      //\r
+      // A PE/COFF image loads its headers into memory so the headers are \r
+      // included in the linked addresses. ELF and Mach-O images do not\r
+      // include the headers so the first byte of the image is usually\r
+      // text (code). If you look at link maps from ELF or Mach-O images\r
+      // you need to subtract out the size of the PE/COFF header to get\r
+      // get the offset that matches the link map. \r
+      //\r
+      DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));\r
+      \r
+      // If we come from an image it is safe to show the instruction. We know it should not fault\r
+      DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;\r
+      ItBlock = 0;\r
+      DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, TRUE, &ItBlock, Buffer, sizeof (Buffer));\r
+      DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
+      \r
+      switch (ExceptionType) {\r
+      case EXCEPT_ARM_UNDEFINED_INSTRUCTION:\r
+      case EXCEPT_ARM_SOFTWARE_INTERRUPT:\r
+      case EXCEPT_ARM_PREFETCH_ABORT:\r
+      case EXCEPT_ARM_DATA_ABORT:\r
+        // advance PC past the faulting instruction\r
+        PcAdjust = (UINTN)DisAsm - SystemContext.SystemContextArm->PC;\r
+        break;\r
+      \r
+      default:\r
+        break;\r
+      }\r
+\r
+    }\r
+  DEBUG_CODE_END ();\r
+  DEBUG ((EFI_D_ERROR, "\n  R0 0x%08x   R1 0x%08x   R2 0x%08x   R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));\r
+  DEBUG ((EFI_D_ERROR, "  R4 0x%08x   R5 0x%08x   R6 0x%08x   R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));\r
+  DEBUG ((EFI_D_ERROR, "  R8 0x%08x   R9 0x%08x  R10 0x%08x  R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));\r
+  DEBUG ((EFI_D_ERROR, " R12 0x%08x   SP 0x%08x   LR 0x%08x   PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));\r
+  DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));\r
+\r
+  // Bit10 is Status[4] Bit3:0 is Status[3:0]\r
+  DfsrStatus = (SystemContext.SystemContextArm->DFSR & 0xf) | ((SystemContext.SystemContextArm->DFSR >> 6) & 0x10);\r
+  DfsrWrite = (SystemContext.SystemContextArm->DFSR & BIT11) != 0;\r
+  if (DfsrStatus != 0x00) {\r
+    DEBUG ((EFI_D_ERROR, " %a: %a 0x%08x\n", FaultStatusToString (DfsrStatus), DfsrWrite ? "write to" : "read from", SystemContext.SystemContextArm->DFAR));\r
+  }\r
+\r
+  IfsrStatus = (SystemContext.SystemContextArm->IFSR & 0xf) | ((SystemContext.SystemContextArm->IFSR >> 6) & 0x10);\r
+  if (IfsrStatus != 0) {\r
+    DEBUG ((EFI_D_ERROR, " Instruction %a at 0x%08x\n", FaultStatusToString (SystemContext.SystemContextArm->IFSR & 0xf), SystemContext.SystemContextArm->IFAR));\r
+  }\r
+\r
+  DEBUG ((EFI_D_ERROR, "\n"));\r
+  ASSERT (FALSE);\r
+  \r
+  // Clear the error registers that we have already displayed incase some one wants to keep going\r
+  SystemContext.SystemContextArm->DFSR = 0;\r
+  SystemContext.SystemContextArm->IFSR = 0;\r
+\r
+  // If some one is stepping past the exception handler adjust the PC to point to the next instruction \r
+  SystemContext.SystemContextArm->PC += PcAdjust;\r
+}\r
diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c
deleted file mode 100644 (file)
index bb29b95..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/** @file\r
-  Default exception handler\r
-\r
-  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
-  Copyright (c) 2012, ARM Ltd. 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
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PeCoffGetEntryPointLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/ArmDisassemblerLib.h>\r
-#include <Library/SerialPortLib.h>\r
-\r
-#include <Guid/DebugImageInfoTable.h>\r
-\r
-#include <Protocol/DebugSupport.h>\r
-#include <Library/DefaultExceptionHandlerLib.h>\r
-\r
-EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;\r
-\r
-typedef struct {\r
-  UINT32  BIT;\r
-  CHAR8   Char;\r
-} CPSR_CHAR;\r
-\r
-CHAR8 *\r
-GetImageName (\r
-  IN  UINT32  FaultAddress,\r
-  OUT UINT32  *ImageBase,\r
-  OUT UINT32  *PeCoffSizeOfHeaders\r
-  );\r
-\r
-/**\r
-  Convert the Current Program Status Register (CPSR) to a string. The string is \r
-  a defacto standard in the ARM world. \r
-  \r
-  It is possible to add extra bits by adding them to CpsrChar array.\r
-\r
-  @param  Cpsr         ARM CPSR register value\r
-  @param  ReturnStr    32 byte string that contains string version of CPSR\r
-\r
-**/\r
-VOID\r
-CpsrString (\r
-  IN  UINT32  Cpsr,\r
-  OUT CHAR8   *ReturnStr\r
-  )\r
-{\r
-  UINTN     Index;\r
-  CHAR8*    Str;\r
-  CHAR8*    ModeStr;\r
-  CPSR_CHAR CpsrChar[] = {\r
-    { 31, 'n' },\r
-    { 30, 'z' },\r
-    { 29, 'c' },\r
-    { 28, 'v' },\r
-\r
-    { 9,  'e' },\r
-    { 8,  'a' },\r
-    { 7,  'i' },\r
-    { 6,  'f' },\r
-    { 5,  't' },\r
-    { 0,  '?' }\r
-  };\r
-  \r
-  Str = ReturnStr;\r
-\r
-  for (Index = 0; CpsrChar[Index].BIT != 0; Index++, Str++) {\r
-    *Str = CpsrChar[Index].Char;\r
-    if ((Cpsr & (1 << CpsrChar[Index].BIT)) != 0) {\r
-      // Concert to upper case if bit is set\r
-      *Str &= ~0x20;\r
-    }\r
-  }\r
-  \r
-  *Str++ = '_';\r
-  *Str = '\0';\r
-  \r
-  switch (Cpsr & 0x1f) {\r
-  case 0x10:\r
-    ModeStr = "usr";\r
-    break;\r
-  case 0x011:\r
-    ModeStr = "fiq";\r
-    break;\r
-  case 0x12:\r
-    ModeStr = "irq";\r
-    break;\r
-  case 0x13:\r
-    ModeStr = "svc";\r
-    break;\r
-  case 0x16:\r
-    ModeStr = "mon";\r
-    break;\r
-  case 0x17:\r
-    ModeStr = "abt";\r
-    break;\r
-  case 0x1b:\r
-    ModeStr = "und";\r
-    break;\r
-  case 0x1f:\r
-    ModeStr = "sys";\r
-    break;\r
-  \r
-  default:\r
-    ModeStr = "???";\r
-    break;\r
-  }\r
-  \r
-  AsciiStrCat (Str, ModeStr);\r
-  return;\r
-}  \r
-\r
-CHAR8 *\r
-FaultStatusToString (\r
-  IN  UINT32  Status\r
-  )\r
-{\r
-  CHAR8 *FaultSource;\r
-\r
-  switch (Status) {\r
-    case 0x01: FaultSource = "Alignment fault"; break;\r
-    case 0x02: FaultSource = "Debug event fault"; break;\r
-    case 0x03: FaultSource = "Access Flag fault on Section"; break;\r
-    case 0x04: FaultSource = "Cache maintenance operation fault[2]"; break;\r
-    case 0x05: FaultSource = "Translation fault on Section"; break;\r
-    case 0x06: FaultSource = "Access Flag fault on Page"; break;\r
-    case 0x07: FaultSource = "Translation fault on Page"; break;\r
-    case 0x08: FaultSource = "Precise External Abort"; break;\r
-    case 0x09: FaultSource = "Domain fault on Section"; break;\r
-    case 0x0b: FaultSource = "Domain fault on Page"; break;\r
-    case 0x0c: FaultSource = "External abort on translation, first level"; break;\r
-    case 0x0d: FaultSource = "Permission fault on Section"; break;\r
-    case 0x0e: FaultSource = "External abort on translation, second level"; break;\r
-    case 0x0f: FaultSource = "Permission fault on Page"; break;\r
-    case 0x16: FaultSource = "Imprecise External Abort"; break;\r
-    default:   FaultSource = "No function"; break;\r
-    }\r
-\r
-  return FaultSource;\r
-}\r
-\r
-STATIC CHAR8 *gExceptionTypeString[] = {\r
-  "Reset",\r
-  "Undefined OpCode",\r
-  "SVC",\r
-  "Prefetch Abort",\r
-  "Data Abort",\r
-  "Undefined",\r
-  "IRQ",\r
-  "FIQ"\r
-};\r
-\r
-/**\r
-  This is the default action to take on an unexpected exception\r
-  \r
-  Since this is exception context don't do anything crazy like try to allcoate memory.\r
-\r
-  @param  ExceptionType    Type of the exception\r
-  @param  SystemContext    Register state at the time of the Exception\r
-\r
-\r
-**/\r
-VOID\r
-DefaultExceptionHandler (\r
-  IN     EFI_EXCEPTION_TYPE           ExceptionType,\r
-  IN OUT EFI_SYSTEM_CONTEXT           SystemContext\r
-  )\r
-{\r
-  CHAR8     Buffer[100];\r
-  UINTN     CharCount;\r
-  UINT32    DfsrStatus;\r
-  UINT32    IfsrStatus;\r
-  BOOLEAN   DfsrWrite;\r
-  UINT32    PcAdjust = 0;\r
-\r
-  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n%a Exception PC at 0x%08x  CPSR 0x%08x ",\r
-         gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);\r
-  SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
-\r
-  DEBUG_CODE_BEGIN ();\r
-    CHAR8   *Pdb;\r
-    UINT32  ImageBase;\r
-    UINT32  PeCoffSizeOfHeader;\r
-    UINT32  Offset;\r
-    CHAR8   CpsrStr[32];  // char per bit. Lower 5-bits are mode that is a 3 char string\r
-    CHAR8   Buffer[80];\r
-    UINT8   *DisAsm;\r
-    UINT32  ItBlock;\r
-    \r
-    CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);\r
-    DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));\r
-  \r
-    Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);\r
-    Offset = SystemContext.SystemContextArm->PC - ImageBase;\r
-    if (Pdb != NULL) {\r
-      DEBUG ((EFI_D_ERROR, "%a\n", Pdb));\r
-\r
-      //\r
-      // A PE/COFF image loads its headers into memory so the headers are \r
-      // included in the linked addresses. ELF and Mach-O images do not\r
-      // include the headers so the first byte of the image is usually\r
-      // text (code). If you look at link maps from ELF or Mach-O images\r
-      // you need to subtract out the size of the PE/COFF header to get\r
-      // get the offset that matches the link map. \r
-      //\r
-      DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));\r
-      \r
-      // If we come from an image it is safe to show the instruction. We know it should not fault\r
-      DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;\r
-      ItBlock = 0;\r
-      DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, TRUE, &ItBlock, Buffer, sizeof (Buffer));\r
-      DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
-      \r
-      switch (ExceptionType) {\r
-      case EXCEPT_ARM_UNDEFINED_INSTRUCTION:\r
-      case EXCEPT_ARM_SOFTWARE_INTERRUPT:\r
-      case EXCEPT_ARM_PREFETCH_ABORT:\r
-      case EXCEPT_ARM_DATA_ABORT:\r
-        // advance PC past the faulting instruction\r
-        PcAdjust = (UINTN)DisAsm - SystemContext.SystemContextArm->PC;\r
-        break;\r
-      \r
-      default:\r
-        break;\r
-      }\r
-\r
-    }\r
-  DEBUG_CODE_END ();\r
-  DEBUG ((EFI_D_ERROR, "\n  R0 0x%08x   R1 0x%08x   R2 0x%08x   R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));\r
-  DEBUG ((EFI_D_ERROR, "  R4 0x%08x   R5 0x%08x   R6 0x%08x   R7 0x%08x\n", SystemContext.SystemContextArm->R4, SystemContext.SystemContextArm->R5, SystemContext.SystemContextArm->R6, SystemContext.SystemContextArm->R7));\r
-  DEBUG ((EFI_D_ERROR, "  R8 0x%08x   R9 0x%08x  R10 0x%08x  R11 0x%08x\n", SystemContext.SystemContextArm->R8, SystemContext.SystemContextArm->R9, SystemContext.SystemContextArm->R10, SystemContext.SystemContextArm->R11));\r
-  DEBUG ((EFI_D_ERROR, " R12 0x%08x   SP 0x%08x   LR 0x%08x   PC 0x%08x\n", SystemContext.SystemContextArm->R12, SystemContext.SystemContextArm->SP, SystemContext.SystemContextArm->LR, SystemContext.SystemContextArm->PC));\r
-  DEBUG ((EFI_D_ERROR, "DFSR 0x%08x DFAR 0x%08x IFSR 0x%08x IFAR 0x%08x\n", SystemContext.SystemContextArm->DFSR, SystemContext.SystemContextArm->DFAR, SystemContext.SystemContextArm->IFSR, SystemContext.SystemContextArm->IFAR));\r
-\r
-  // Bit10 is Status[4] Bit3:0 is Status[3:0]\r
-  DfsrStatus = (SystemContext.SystemContextArm->DFSR & 0xf) | ((SystemContext.SystemContextArm->DFSR >> 6) & 0x10);\r
-  DfsrWrite = (SystemContext.SystemContextArm->DFSR & BIT11) != 0;\r
-  if (DfsrStatus != 0x00) {\r
-    DEBUG ((EFI_D_ERROR, " %a: %a 0x%08x\n", FaultStatusToString (DfsrStatus), DfsrWrite ? "write to" : "read from", SystemContext.SystemContextArm->DFAR));\r
-  }\r
-\r
-  IfsrStatus = (SystemContext.SystemContextArm->IFSR & 0xf) | ((SystemContext.SystemContextArm->IFSR >> 6) & 0x10);\r
-  if (IfsrStatus != 0) {\r
-    DEBUG ((EFI_D_ERROR, " Instruction %a at 0x%08x\n", FaultStatusToString (SystemContext.SystemContextArm->IFSR & 0xf), SystemContext.SystemContextArm->IFAR));\r
-  }\r
-\r
-  DEBUG ((EFI_D_ERROR, "\n"));\r
-  ASSERT (FALSE);\r
-  \r
-  // Clear the error registers that we have already displayed incase some one wants to keep going\r
-  SystemContext.SystemContextArm->DFSR = 0;\r
-  SystemContext.SystemContextArm->IFSR = 0;\r
-\r
-  // If some one is stepping past the exception handler adjust the PC to point to the next instruction \r
-  SystemContext.SystemContextArm->PC += PcAdjust;\r
-}\r
index 120e2de..61dabf4 100644 (file)
   LIBRARY_CLASS                  = DefaultExceptionHandlerLib\r
   CONSTRUCTOR                    = DefaultExceptionHandlerConstructor\r
 \r
-\r
 [Sources.common]\r
-  DefaultExceptionHandler.c\r
   DefaultExceptionHandlerUefi.c\r
 \r
+[Sources.ARM]\r
+  Arm/DefaultExceptionHandler.c\r
+\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   ArmPkg/ArmPkg.dec\r
index f51d3a0..39b2775 100644 (file)
   LIBRARY_CLASS                  = DefaultExceptionHandlerLib\r
 \r
 [Sources.common]\r
-  DefaultExceptionHandler.c\r
   DefaultExceptionHandlerBase.c\r
 \r
+[Sources.ARM]\r
+  Arm/DefaultExceptionHandler.c\r
+\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   ArmPkg/ArmPkg.dec\r
diff --git a/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c b/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c
deleted file mode 100644 (file)
index 01b6dc3..0000000
+++ /dev/null
@@ -1,219 +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
-#include <Base.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/SemihostLib.h>\r
-\r
-#include "SemihostPrivate.h"\r
-\r
-BOOLEAN\r
-SemihostConnectionSupported (\r
-  VOID\r
-  )\r
-{\r
-  return SEMIHOST_SUPPORTED;\r
-}\r
-\r
-RETURN_STATUS\r
-SemihostFileOpen (\r
-  IN  CHAR8  *FileName,\r
-  IN  UINT32 Mode,\r
-  OUT UINT32 *FileHandle\r
-  )\r
-{\r
-  SEMIHOST_FILE_OPEN_BLOCK  OpenBlock;\r
-  INT32                     Result;\r
-\r
-  if (FileHandle == NULL) {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-  OpenBlock.FileName    = FileName;\r
-  OpenBlock.Mode        = Mode;\r
-  OpenBlock.NameLength  = AsciiStrLen(FileName);\r
-\r
-  Result = Semihost_SYS_OPEN(&OpenBlock);\r
-\r
-  if (Result == -1) {\r
-    return RETURN_NOT_FOUND;\r
-  } else {\r
-    *FileHandle = Result;\r
-    return RETURN_SUCCESS;\r
-  }\r
-}\r
-\r
-RETURN_STATUS\r
-SemihostFileSeek (\r
-  IN UINT32 FileHandle,\r
-  IN UINT32 Offset\r
-  )\r
-{\r
-  SEMIHOST_FILE_SEEK_BLOCK  SeekBlock;\r
-  INT32                     Result;\r
-\r
-  SeekBlock.Handle   = FileHandle;\r
-  SeekBlock.Location = Offset;\r
-\r
-  Result = Semihost_SYS_SEEK(&SeekBlock);\r
-\r
-  if (Result == 0) {\r
-    return RETURN_SUCCESS;\r
-  } else {\r
-    return RETURN_ABORTED;\r
-  }\r
-}\r
-\r
-RETURN_STATUS\r
-SemihostFileRead (\r
-  IN     UINT32 FileHandle,\r
-  IN OUT UINT32 *Length,\r
-  OUT    VOID   *Buffer\r
-  )\r
-{\r
-  SEMIHOST_FILE_READ_WRITE_BLOCK  ReadBlock;\r
-  UINT32                          Result;\r
-\r
-  if ((Length == NULL) || (Buffer == NULL)) {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-  ReadBlock.Handle = FileHandle;\r
-  ReadBlock.Buffer = Buffer;\r
-  ReadBlock.Length = *Length;\r
-\r
-  Result = Semihost_SYS_READ(&ReadBlock);\r
-\r
-  if (Result == *Length) {\r
-    return RETURN_ABORTED;\r
-  } else {\r
-    *Length -= Result;\r
-    return RETURN_SUCCESS;\r
-  }\r
-}\r
-\r
-RETURN_STATUS\r
-SemihostFileWrite (\r
-  IN     UINT32 FileHandle,\r
-  IN OUT UINT32 *Length,\r
-  IN     VOID   *Buffer\r
-  )\r
-{\r
-  SEMIHOST_FILE_READ_WRITE_BLOCK  WriteBlock;\r
-\r
-  if ((Length == NULL) || (Buffer == NULL)) {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-  WriteBlock.Handle = FileHandle;\r
-  WriteBlock.Buffer = Buffer;\r
-  WriteBlock.Length = *Length;\r
-\r
-  *Length = Semihost_SYS_WRITE(&WriteBlock);\r
-  \r
-  return RETURN_SUCCESS;\r
-}\r
-\r
-RETURN_STATUS\r
-SemihostFileClose (\r
-  IN UINT32 FileHandle\r
-  )\r
-{\r
-  INT32 Result = Semihost_SYS_CLOSE(&FileHandle);\r
-\r
-  if (Result == -1) {\r
-    return RETURN_INVALID_PARAMETER;\r
-  } else {\r
-    return RETURN_SUCCESS;\r
-  }\r
-}\r
-\r
-RETURN_STATUS\r
-SemihostFileLength (\r
-  IN  UINT32 FileHandle,\r
-  OUT UINT32 *Length\r
-  )\r
-{\r
-  INT32       Result;\r
-\r
-  if (Length == NULL) {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-  Result = Semihost_SYS_FLEN(&FileHandle);\r
-\r
-  if (Result == -1) {\r
-    return RETURN_ABORTED;\r
-  } else {\r
-    *Length = Result;\r
-    return RETURN_SUCCESS;\r
-  }\r
-}\r
-\r
-RETURN_STATUS\r
-SemihostFileRemove (\r
-  IN CHAR8 *FileName\r
-  )\r
-{\r
-  SEMIHOST_FILE_REMOVE_BLOCK  RemoveBlock;\r
-  UINT32                      Result;\r
-\r
-  RemoveBlock.FileName    = FileName;\r
-  RemoveBlock.NameLength  = AsciiStrLen(FileName);\r
-\r
-  Result = Semihost_SYS_REMOVE(&RemoveBlock);\r
-\r
-  if (Result == 0) {\r
-    return RETURN_SUCCESS;\r
-  } else {\r
-    return RETURN_ABORTED;\r
-  }\r
-}\r
-\r
-CHAR8\r
-SemihostReadCharacter (\r
-  VOID\r
-  )\r
-{\r
-  return Semihost_SYS_READC();\r
-}\r
-\r
-VOID\r
-SemihostWriteCharacter (\r
-  IN CHAR8 Character\r
-  )\r
-{\r
-  Semihost_SYS_WRITEC(&Character);\r
-}\r
-\r
-VOID\r
-SemihostWriteString (\r
-  IN CHAR8 *String\r
-  )\r
-{\r
-  Semihost_SYS_WRITE0(String);\r
-}\r
-  \r
-UINT32\r
-SemihostSystem (\r
-  IN CHAR8 *CommandLine\r
-  )\r
-{\r
-  SEMIHOST_SYSTEM_BLOCK SystemBlock;\r
-\r
-  SystemBlock.CommandLine   = CommandLine;\r
-  SystemBlock.CommandLength = AsciiStrLen(CommandLine);\r
-\r
-  return Semihost_SYS_SYSTEM(&SystemBlock);\r
-}\r
diff --git a/ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h b/ArmPkg/Library/SemihostLib/Arm/SemihostPrivate.h
deleted file mode 100644 (file)
index 02836ca..0000000
+++ /dev/null
@@ -1,184 +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
-#ifndef __SEMIHOST_PRIVATE_H__\r
-#define __SEMIHOST_PRIVATE_H__\r
-\r
-typedef struct {\r
-  CHAR8   *FileName;\r
-  UINT32  Mode;\r
-  UINT32  NameLength;\r
-} SEMIHOST_FILE_OPEN_BLOCK;\r
-\r
-typedef struct {\r
-  UINT32  Handle;\r
-  VOID    *Buffer;\r
-  UINT32  Length;\r
-} SEMIHOST_FILE_READ_WRITE_BLOCK;\r
-\r
-typedef struct {\r
-  UINT32  Handle;\r
-  UINT32  Location;\r
-} SEMIHOST_FILE_SEEK_BLOCK;\r
-\r
-typedef struct {\r
-  CHAR8   *FileName;\r
-  UINT32  NameLength;\r
-} SEMIHOST_FILE_REMOVE_BLOCK;\r
-\r
-typedef struct {\r
-  CHAR8   *CommandLine;\r
-  UINT32  CommandLength;\r
-} SEMIHOST_SYSTEM_BLOCK;\r
-\r
-#if defined(__CC_ARM) \r
-\r
-#if defined(__thumb__)\r
-#define SWI 0xAB\r
-#else\r
-#define SWI 0x123456\r
-#endif\r
-\r
-#define SEMIHOST_SUPPORTED  TRUE\r
-\r
-__swi(SWI)\r
-INT32\r
-_Semihost_SYS_OPEN(\r
-  IN UINTN                    SWI_0x01,\r
-  IN SEMIHOST_FILE_OPEN_BLOCK *OpenBlock\r
-  );\r
-\r
-__swi(SWI)\r
-INT32\r
-_Semihost_SYS_CLOSE(\r
-  IN UINTN  SWI_0x02,\r
-  IN UINT32 *Handle\r
-  );\r
-\r
-__swi(SWI)\r
-VOID\r
-_Semihost_SYS_WRITEC(\r
-  IN UINTN    SWI_0x03,\r
-  IN CHAR8    *Character\r
-  );\r
-\r
-__swi(SWI)\r
-VOID\r
-_Semihost_SYS_WRITE0(\r
-  IN UINTN SWI_0x04,\r
-  IN CHAR8 *String\r
-  );\r
-\r
-__swi(SWI)\r
-UINT32\r
-_Semihost_SYS_WRITE(\r
-  IN     UINTN                          SWI_0x05,\r
-  IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *WriteBlock\r
-  );\r
-\r
-__swi(SWI)\r
-UINT32\r
-_Semihost_SYS_READ(\r
-  IN     UINTN                          SWI_0x06,\r
-  IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *ReadBlock\r
-  );\r
-\r
-__swi(SWI)\r
-CHAR8\r
-_Semihost_SYS_READC(\r
-  IN     UINTN SWI_0x07,\r
-  IN     UINTN Zero\r
-  );\r
-\r
-__swi(SWI)\r
-INT32\r
-_Semihost_SYS_SEEK(\r
-  IN UINTN                    SWI_0x0A,\r
-  IN SEMIHOST_FILE_SEEK_BLOCK *SeekBlock\r
-  );\r
-\r
-__swi(SWI)\r
-INT32\r
-_Semihost_SYS_FLEN(\r
-  IN UINTN  SWI_0x0C,\r
-  IN UINT32 *Handle\r
-  );\r
-\r
-__swi(SWI)\r
-UINT32\r
-_Semihost_SYS_REMOVE(\r
-  IN UINTN                      SWI_0x0E,\r
-  IN SEMIHOST_FILE_REMOVE_BLOCK *RemoveBlock\r
-  );\r
-\r
-__swi(SWI)\r
-UINT32\r
-_Semihost_SYS_SYSTEM(\r
-  IN UINTN                 SWI_0x12,\r
-  IN SEMIHOST_SYSTEM_BLOCK *SystemBlock\r
-  );\r
-\r
-#define Semihost_SYS_OPEN(OpenBlock)        _Semihost_SYS_OPEN(0x01, OpenBlock)\r
-#define Semihost_SYS_CLOSE(Handle)          _Semihost_SYS_CLOSE(0x02, Handle)\r
-#define Semihost_SYS_WRITE0(String)         _Semihost_SYS_WRITE0(0x04, String)\r
-#define Semihost_SYS_WRITEC(Character)      _Semihost_SYS_WRITEC(0x03, Character)\r
-#define Semihost_SYS_WRITE(WriteBlock)      _Semihost_SYS_WRITE(0x05, WriteBlock)\r
-#define Semihost_SYS_READ(ReadBlock)        _Semihost_SYS_READ(0x06, ReadBlock)\r
-#define Semihost_SYS_READC()                _Semihost_SYS_READC(0x07, 0)\r
-#define Semihost_SYS_SEEK(SeekBlock)        _Semihost_SYS_SEEK(0x0A, SeekBlock)\r
-#define Semihost_SYS_FLEN(Handle)           _Semihost_SYS_FLEN(0x0C, Handle)\r
-#define Semihost_SYS_REMOVE(RemoveBlock)    _Semihost_SYS_REMOVE(0x0E, RemoveBlock)\r
-#define Semihost_SYS_SYSTEM(SystemBlock)    _Semihost_SYS_SYSTEM(0x12, SystemBlock)\r
-\r
-#elif defined(__GNUC__) // __CC_ARM\r
-\r
-#define SEMIHOST_SUPPORTED  TRUE\r
-\r
-UINT32\r
-GccSemihostCall (\r
-  IN UINT32   Operation,\r
-  IN UINTN    SystemBlockAddress\r
-  ); // __attribute__ ((interrupt ("SVC")));\r
-\r
-#define Semihost_SYS_OPEN(OpenBlock)        GccSemihostCall(0x01, (UINTN)(OpenBlock))\r
-#define Semihost_SYS_CLOSE(Handle)          GccSemihostCall(0x02, (UINTN)(Handle))\r
-#define Semihost_SYS_WRITE0(String)         GccSemihostCall(0x04, (UINTN)(String))\r
-#define Semihost_SYS_WRITEC(Character)      GccSemihostCall(0x03, (UINTN)(Character))\r
-#define Semihost_SYS_WRITE(WriteBlock)      GccSemihostCall(0x05, (UINTN)(WriteBlock))\r
-#define Semihost_SYS_READ(ReadBlock)        GccSemihostCall(0x06, (UINTN)(ReadBlock))\r
-#define Semihost_SYS_READC()                GccSemihostCall(0x07, (UINTN)(0))\r
-#define Semihost_SYS_SEEK(SeekBlock)        GccSemihostCall(0x0A, (UINTN)(SeekBlock))\r
-#define Semihost_SYS_FLEN(Handle)           GccSemihostCall(0x0C, (UINTN)(Handle))\r
-#define Semihost_SYS_REMOVE(RemoveBlock)    GccSemihostCall(0x0E, (UINTN)(RemoveBlock))\r
-#define Semihost_SYS_SYSTEM(SystemBlock)    GccSemihostCall(0x12, (UINTN)(SystemBlock))\r
-\r
-#else // __CC_ARM\r
-\r
-#define SEMIHOST_SUPPORTED  FALSE\r
-\r
-#define Semihost_SYS_OPEN(OpenBlock)        (-1)\r
-#define Semihost_SYS_CLOSE(Handle)          (-1)\r
-#define Semihost_SYS_WRITE0(String)\r
-#define Semihost_SYS_WRITEC(Character)\r
-#define Semihost_SYS_WRITE(WriteBlock)      (0)\r
-#define Semihost_SYS_READ(ReadBlock)        ((ReadBlock)->Length)\r
-#define Semihost_SYS_READC()                ('x')\r
-#define Semihost_SYS_SEEK(SeekBlock)        (-1)\r
-#define Semihost_SYS_FLEN(Handle)           (-1)\r
-#define Semihost_SYS_REMOVE(RemoveBlock)    (-1)\r
-#define Semihost_SYS_SYSTEM(SystemBlock)    (-1)\r
-\r
-#endif // __CC_ARM\r
-\r
-#endif //__SEMIHOST_PRIVATE_H__\r
diff --git a/ArmPkg/Library/SemihostLib/SemihostLib.c b/ArmPkg/Library/SemihostLib/SemihostLib.c
new file mode 100644 (file)
index 0000000..01b6dc3
--- /dev/null
@@ -0,0 +1,219 @@
+/** @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
+#include <Base.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/SemihostLib.h>\r
+\r
+#include "SemihostPrivate.h"\r
+\r
+BOOLEAN\r
+SemihostConnectionSupported (\r
+  VOID\r
+  )\r
+{\r
+  return SEMIHOST_SUPPORTED;\r
+}\r
+\r
+RETURN_STATUS\r
+SemihostFileOpen (\r
+  IN  CHAR8  *FileName,\r
+  IN  UINT32 Mode,\r
+  OUT UINT32 *FileHandle\r
+  )\r
+{\r
+  SEMIHOST_FILE_OPEN_BLOCK  OpenBlock;\r
+  INT32                     Result;\r
+\r
+  if (FileHandle == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  OpenBlock.FileName    = FileName;\r
+  OpenBlock.Mode        = Mode;\r
+  OpenBlock.NameLength  = AsciiStrLen(FileName);\r
+\r
+  Result = Semihost_SYS_OPEN(&OpenBlock);\r
+\r
+  if (Result == -1) {\r
+    return RETURN_NOT_FOUND;\r
+  } else {\r
+    *FileHandle = Result;\r
+    return RETURN_SUCCESS;\r
+  }\r
+}\r
+\r
+RETURN_STATUS\r
+SemihostFileSeek (\r
+  IN UINT32 FileHandle,\r
+  IN UINT32 Offset\r
+  )\r
+{\r
+  SEMIHOST_FILE_SEEK_BLOCK  SeekBlock;\r
+  INT32                     Result;\r
+\r
+  SeekBlock.Handle   = FileHandle;\r
+  SeekBlock.Location = Offset;\r
+\r
+  Result = Semihost_SYS_SEEK(&SeekBlock);\r
+\r
+  if (Result == 0) {\r
+    return RETURN_SUCCESS;\r
+  } else {\r
+    return RETURN_ABORTED;\r
+  }\r
+}\r
+\r
+RETURN_STATUS\r
+SemihostFileRead (\r
+  IN     UINT32 FileHandle,\r
+  IN OUT UINT32 *Length,\r
+  OUT    VOID   *Buffer\r
+  )\r
+{\r
+  SEMIHOST_FILE_READ_WRITE_BLOCK  ReadBlock;\r
+  UINT32                          Result;\r
+\r
+  if ((Length == NULL) || (Buffer == NULL)) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  ReadBlock.Handle = FileHandle;\r
+  ReadBlock.Buffer = Buffer;\r
+  ReadBlock.Length = *Length;\r
+\r
+  Result = Semihost_SYS_READ(&ReadBlock);\r
+\r
+  if (Result == *Length) {\r
+    return RETURN_ABORTED;\r
+  } else {\r
+    *Length -= Result;\r
+    return RETURN_SUCCESS;\r
+  }\r
+}\r
+\r
+RETURN_STATUS\r
+SemihostFileWrite (\r
+  IN     UINT32 FileHandle,\r
+  IN OUT UINT32 *Length,\r
+  IN     VOID   *Buffer\r
+  )\r
+{\r
+  SEMIHOST_FILE_READ_WRITE_BLOCK  WriteBlock;\r
+\r
+  if ((Length == NULL) || (Buffer == NULL)) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  WriteBlock.Handle = FileHandle;\r
+  WriteBlock.Buffer = Buffer;\r
+  WriteBlock.Length = *Length;\r
+\r
+  *Length = Semihost_SYS_WRITE(&WriteBlock);\r
+  \r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+RETURN_STATUS\r
+SemihostFileClose (\r
+  IN UINT32 FileHandle\r
+  )\r
+{\r
+  INT32 Result = Semihost_SYS_CLOSE(&FileHandle);\r
+\r
+  if (Result == -1) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  } else {\r
+    return RETURN_SUCCESS;\r
+  }\r
+}\r
+\r
+RETURN_STATUS\r
+SemihostFileLength (\r
+  IN  UINT32 FileHandle,\r
+  OUT UINT32 *Length\r
+  )\r
+{\r
+  INT32       Result;\r
+\r
+  if (Length == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  Result = Semihost_SYS_FLEN(&FileHandle);\r
+\r
+  if (Result == -1) {\r
+    return RETURN_ABORTED;\r
+  } else {\r
+    *Length = Result;\r
+    return RETURN_SUCCESS;\r
+  }\r
+}\r
+\r
+RETURN_STATUS\r
+SemihostFileRemove (\r
+  IN CHAR8 *FileName\r
+  )\r
+{\r
+  SEMIHOST_FILE_REMOVE_BLOCK  RemoveBlock;\r
+  UINT32                      Result;\r
+\r
+  RemoveBlock.FileName    = FileName;\r
+  RemoveBlock.NameLength  = AsciiStrLen(FileName);\r
+\r
+  Result = Semihost_SYS_REMOVE(&RemoveBlock);\r
+\r
+  if (Result == 0) {\r
+    return RETURN_SUCCESS;\r
+  } else {\r
+    return RETURN_ABORTED;\r
+  }\r
+}\r
+\r
+CHAR8\r
+SemihostReadCharacter (\r
+  VOID\r
+  )\r
+{\r
+  return Semihost_SYS_READC();\r
+}\r
+\r
+VOID\r
+SemihostWriteCharacter (\r
+  IN CHAR8 Character\r
+  )\r
+{\r
+  Semihost_SYS_WRITEC(&Character);\r
+}\r
+\r
+VOID\r
+SemihostWriteString (\r
+  IN CHAR8 *String\r
+  )\r
+{\r
+  Semihost_SYS_WRITE0(String);\r
+}\r
+  \r
+UINT32\r
+SemihostSystem (\r
+  IN CHAR8 *CommandLine\r
+  )\r
+{\r
+  SEMIHOST_SYSTEM_BLOCK SystemBlock;\r
+\r
+  SystemBlock.CommandLine   = CommandLine;\r
+  SystemBlock.CommandLength = AsciiStrLen(CommandLine);\r
+\r
+  return Semihost_SYS_SYSTEM(&SystemBlock);\r
+}\r
index 5ec7fef..a0a6871 100644 (file)
 #\r
 #  VALID_ARCHITECTURES           = ARM\r
 #\r
+[Sources.common]\r
+  SemihostLib.c\r
+\r
 [Sources.ARM]\r
   Arm/GccSemihost.S | GCC\r
-  Arm/SemihostLib.c\r
-\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
 \r
 [LibraryClasses]\r
   BaseLib\r
-  \r
-[Protocols]\r
-  \r
-[Guids]\r
\r
-[Pcd]\r
\r
\ No newline at end of file
\r\r
diff --git a/ArmPkg/Library/SemihostLib/SemihostPrivate.h b/ArmPkg/Library/SemihostLib/SemihostPrivate.h
new file mode 100644 (file)
index 0000000..02836ca
--- /dev/null
@@ -0,0 +1,184 @@
+/** @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
+#ifndef __SEMIHOST_PRIVATE_H__\r
+#define __SEMIHOST_PRIVATE_H__\r
+\r
+typedef struct {\r
+  CHAR8   *FileName;\r
+  UINT32  Mode;\r
+  UINT32  NameLength;\r
+} SEMIHOST_FILE_OPEN_BLOCK;\r
+\r
+typedef struct {\r
+  UINT32  Handle;\r
+  VOID    *Buffer;\r
+  UINT32  Length;\r
+} SEMIHOST_FILE_READ_WRITE_BLOCK;\r
+\r
+typedef struct {\r
+  UINT32  Handle;\r
+  UINT32  Location;\r
+} SEMIHOST_FILE_SEEK_BLOCK;\r
+\r
+typedef struct {\r
+  CHAR8   *FileName;\r
+  UINT32  NameLength;\r
+} SEMIHOST_FILE_REMOVE_BLOCK;\r
+\r
+typedef struct {\r
+  CHAR8   *CommandLine;\r
+  UINT32  CommandLength;\r
+} SEMIHOST_SYSTEM_BLOCK;\r
+\r
+#if defined(__CC_ARM) \r
+\r
+#if defined(__thumb__)\r
+#define SWI 0xAB\r
+#else\r
+#define SWI 0x123456\r
+#endif\r
+\r
+#define SEMIHOST_SUPPORTED  TRUE\r
+\r
+__swi(SWI)\r
+INT32\r
+_Semihost_SYS_OPEN(\r
+  IN UINTN                    SWI_0x01,\r
+  IN SEMIHOST_FILE_OPEN_BLOCK *OpenBlock\r
+  );\r
+\r
+__swi(SWI)\r
+INT32\r
+_Semihost_SYS_CLOSE(\r
+  IN UINTN  SWI_0x02,\r
+  IN UINT32 *Handle\r
+  );\r
+\r
+__swi(SWI)\r
+VOID\r
+_Semihost_SYS_WRITEC(\r
+  IN UINTN    SWI_0x03,\r
+  IN CHAR8    *Character\r
+  );\r
+\r
+__swi(SWI)\r
+VOID\r
+_Semihost_SYS_WRITE0(\r
+  IN UINTN SWI_0x04,\r
+  IN CHAR8 *String\r
+  );\r
+\r
+__swi(SWI)\r
+UINT32\r
+_Semihost_SYS_WRITE(\r
+  IN     UINTN                          SWI_0x05,\r
+  IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *WriteBlock\r
+  );\r
+\r
+__swi(SWI)\r
+UINT32\r
+_Semihost_SYS_READ(\r
+  IN     UINTN                          SWI_0x06,\r
+  IN OUT SEMIHOST_FILE_READ_WRITE_BLOCK *ReadBlock\r
+  );\r
+\r
+__swi(SWI)\r
+CHAR8\r
+_Semihost_SYS_READC(\r
+  IN     UINTN SWI_0x07,\r
+  IN     UINTN Zero\r
+  );\r
+\r
+__swi(SWI)\r
+INT32\r
+_Semihost_SYS_SEEK(\r
+  IN UINTN                    SWI_0x0A,\r
+  IN SEMIHOST_FILE_SEEK_BLOCK *SeekBlock\r
+  );\r
+\r
+__swi(SWI)\r
+INT32\r
+_Semihost_SYS_FLEN(\r
+  IN UINTN  SWI_0x0C,\r
+  IN UINT32 *Handle\r
+  );\r
+\r
+__swi(SWI)\r
+UINT32\r
+_Semihost_SYS_REMOVE(\r
+  IN UINTN                      SWI_0x0E,\r
+  IN SEMIHOST_FILE_REMOVE_BLOCK *RemoveBlock\r
+  );\r
+\r
+__swi(SWI)\r
+UINT32\r
+_Semihost_SYS_SYSTEM(\r
+  IN UINTN                 SWI_0x12,\r
+  IN SEMIHOST_SYSTEM_BLOCK *SystemBlock\r
+  );\r
+\r
+#define Semihost_SYS_OPEN(OpenBlock)        _Semihost_SYS_OPEN(0x01, OpenBlock)\r
+#define Semihost_SYS_CLOSE(Handle)          _Semihost_SYS_CLOSE(0x02, Handle)\r
+#define Semihost_SYS_WRITE0(String)         _Semihost_SYS_WRITE0(0x04, String)\r
+#define Semihost_SYS_WRITEC(Character)      _Semihost_SYS_WRITEC(0x03, Character)\r
+#define Semihost_SYS_WRITE(WriteBlock)      _Semihost_SYS_WRITE(0x05, WriteBlock)\r
+#define Semihost_SYS_READ(ReadBlock)        _Semihost_SYS_READ(0x06, ReadBlock)\r
+#define Semihost_SYS_READC()                _Semihost_SYS_READC(0x07, 0)\r
+#define Semihost_SYS_SEEK(SeekBlock)        _Semihost_SYS_SEEK(0x0A, SeekBlock)\r
+#define Semihost_SYS_FLEN(Handle)           _Semihost_SYS_FLEN(0x0C, Handle)\r
+#define Semihost_SYS_REMOVE(RemoveBlock)    _Semihost_SYS_REMOVE(0x0E, RemoveBlock)\r
+#define Semihost_SYS_SYSTEM(SystemBlock)    _Semihost_SYS_SYSTEM(0x12, SystemBlock)\r
+\r
+#elif defined(__GNUC__) // __CC_ARM\r
+\r
+#define SEMIHOST_SUPPORTED  TRUE\r
+\r
+UINT32\r
+GccSemihostCall (\r
+  IN UINT32   Operation,\r
+  IN UINTN    SystemBlockAddress\r
+  ); // __attribute__ ((interrupt ("SVC")));\r
+\r
+#define Semihost_SYS_OPEN(OpenBlock)        GccSemihostCall(0x01, (UINTN)(OpenBlock))\r
+#define Semihost_SYS_CLOSE(Handle)          GccSemihostCall(0x02, (UINTN)(Handle))\r
+#define Semihost_SYS_WRITE0(String)         GccSemihostCall(0x04, (UINTN)(String))\r
+#define Semihost_SYS_WRITEC(Character)      GccSemihostCall(0x03, (UINTN)(Character))\r
+#define Semihost_SYS_WRITE(WriteBlock)      GccSemihostCall(0x05, (UINTN)(WriteBlock))\r
+#define Semihost_SYS_READ(ReadBlock)        GccSemihostCall(0x06, (UINTN)(ReadBlock))\r
+#define Semihost_SYS_READC()                GccSemihostCall(0x07, (UINTN)(0))\r
+#define Semihost_SYS_SEEK(SeekBlock)        GccSemihostCall(0x0A, (UINTN)(SeekBlock))\r
+#define Semihost_SYS_FLEN(Handle)           GccSemihostCall(0x0C, (UINTN)(Handle))\r
+#define Semihost_SYS_REMOVE(RemoveBlock)    GccSemihostCall(0x0E, (UINTN)(RemoveBlock))\r
+#define Semihost_SYS_SYSTEM(SystemBlock)    GccSemihostCall(0x12, (UINTN)(SystemBlock))\r
+\r
+#else // __CC_ARM\r
+\r
+#define SEMIHOST_SUPPORTED  FALSE\r
+\r
+#define Semihost_SYS_OPEN(OpenBlock)        (-1)\r
+#define Semihost_SYS_CLOSE(Handle)          (-1)\r
+#define Semihost_SYS_WRITE0(String)\r
+#define Semihost_SYS_WRITEC(Character)\r
+#define Semihost_SYS_WRITE(WriteBlock)      (0)\r
+#define Semihost_SYS_READ(ReadBlock)        ((ReadBlock)->Length)\r
+#define Semihost_SYS_READC()                ('x')\r
+#define Semihost_SYS_SEEK(SeekBlock)        (-1)\r
+#define Semihost_SYS_FLEN(Handle)           (-1)\r
+#define Semihost_SYS_REMOVE(RemoveBlock)    (-1)\r
+#define Semihost_SYS_SYSTEM(SystemBlock)    (-1)\r
+\r
+#endif // __CC_ARM\r
+\r
+#endif //__SEMIHOST_PRIVATE_H__\r