]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Drivers/CpuDxe/Exception.c
Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib...
[mirror_edk2.git] / ArmPkg / Drivers / CpuDxe / Exception.c
index e0aca46cd79729672c4b93e521dd30ba08ffede2..21a4c035a9a00968052174bb87622f469ff7d984 100644 (file)
@@ -14,6 +14,8 @@
 \r
 #include "CpuDxe.h" \r
 \r
+//FIXME: Will not compile on non-ARMv7 builds\r
+#include <Chipset/ArmV7.h>\r
 \r
 VOID\r
 ExceptionHandlersStart (\r
@@ -127,6 +129,7 @@ InitializeExceptions (
   EFI_PHYSICAL_ADDRESS Base;\r
   UINT32               *VectorBase;\r
 \r
+  Status = EFI_SUCCESS;\r
   //\r
   // Disable interrupts\r
   //\r
@@ -140,54 +143,63 @@ InitializeExceptions (
   FiqEnabled = ArmGetFiqState ();\r
   ArmDisableFiq ();\r
 \r
-  //\r
-  // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.\r
-  //\r
-  Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;\r
-\r
-  //\r
-  // Reserve space for the exception handlers\r
-  //\r
-  Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);\r
-  VectorBase = (UINT32 *)(UINTN)Base;\r
-  Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);\r
-  // If the request was for memory that's not in the memory map (which is often the case for 0x00000000\r
-  // on embedded systems, for example, we don't want to hang up.  So we'll check here for a status of \r
-  // EFI_NOT_FOUND, and continue in that case.\r
-  if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
-\r
-  // Save existing vector table, in case debugger is already hooked in\r
-  CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));\r
-\r
-  // Copy our assembly code into the page that contains the exception vectors. \r
-  CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);\r
-\r
-  //\r
-  // Patch in the common Assembly exception handler\r
-  //\r
-  Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;\r
-  *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;\r
-\r
-  //\r
-  // Initialize the C entry points for interrupts\r
-  //\r
-  for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {\r
-    if ((gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {\r
-      // Exception handler contains branch to vector location (jmp $) so no handler\r
-      // NOTE: This code assumes vectors are ARM and not Thumb code\r
-      Status = RegisterInterruptHandler (Index, NULL);\r
-      ASSERT_EFI_ERROR (Status);\r
-    } else {\r
-      // If the debugger has alread hooked put its vector back\r
-      VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];\r
-    }\r
+  if (FeaturePcdGet(PcdRelocateVectorTable) == TRUE) {\r
+      //\r
+      // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress.\r
+      //\r
+      Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;\r
+    \r
+      //\r
+      // Reserve space for the exception handlers\r
+      //\r
+      Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress);\r
+      VectorBase = (UINT32 *)(UINTN)Base;\r
+      Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, EFI_SIZE_TO_PAGES (Length), &Base);\r
+      // If the request was for memory that's not in the memory map (which is often the case for 0x00000000\r
+      // on embedded systems, for example, we don't want to hang up.  So we'll check here for a status of \r
+      // EFI_NOT_FOUND, and continue in that case.\r
+      if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) {\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
+    \r
+      // Save existing vector table, in case debugger is already hooked in\r
+      CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, sizeof (gDebuggerExceptionHandlers));\r
+    \r
+      // Copy our assembly code into the page that contains the exception vectors. \r
+      CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length);\r
+    \r
+      //\r
+      // Patch in the common Assembly exception handler\r
+      //\r
+      Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;\r
+      *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;\r
+    \r
+      //\r
+      // Initialize the C entry points for interrupts\r
+      //\r
+      for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {\r
+        if ((gDebuggerExceptionHandlers[Index] == 0) || (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) {\r
+          // Exception handler contains branch to vector location (jmp $) so no handler\r
+          // NOTE: This code assumes vectors are ARM and not Thumb code\r
+          Status = RegisterInterruptHandler (Index, NULL);\r
+          ASSERT_EFI_ERROR (Status);\r
+        } else {\r
+          // If the debugger has alread hooked put its vector back\r
+          VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index];\r
+        }\r
+      }\r
+    \r
+      // Flush Caches since we updated executable stuff\r
+      InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);\r
+\r
+      //Note: On ARM processor with the Security Extension, the Vector Table can be located anywhere in the memory.\r
+      //      The Vector Base Address Register defines the location\r
+      ArmWriteVBar(PcdGet32(PcdCpuVectorBaseAddress));\r
+  } else {\r
+    // We do not copy the Exception Table at PcdGet32(PcdCpuVectorBaseAddress). We just set Vector Base Address to point into CpuDxe code.\r
+    ArmWriteVBar((UINT32)ExceptionHandlersStart);\r
   }\r
 \r
-  // Flush Caches since we updated executable stuff\r
-  InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);\r
-\r
   if (FiqEnabled) {\r
     ArmEnableFiq ();\r
   }\r