]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Drivers/CpuDxe/Exception.c
ArmPlatformPkg: Remove PcdStandalone from Sec module and Introduce ArmPlatformSecExtr...
[mirror_edk2.git] / ArmPkg / Drivers / CpuDxe / Exception.c
index 21a4c035a9a00968052174bb87622f469ff7d984..55a71321935007376be89a792b6899a3a0ea8347 100644 (file)
@@ -92,7 +92,6 @@ CommonCExceptionHandler (
   IN OUT EFI_SYSTEM_CONTEXT           SystemContext\r
   )\r
 {\r
-\r
   if (ExceptionType <= MAX_ARM_EXCEPTION) {\r
     if (gExceptionHandlers[ExceptionType]) {\r
       gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);\r
@@ -130,6 +129,8 @@ InitializeExceptions (
   UINT32               *VectorBase;\r
 \r
   Status = EFI_SUCCESS;\r
+  ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers));\r
+\r
   //\r
   // Disable interrupts\r
   //\r
@@ -144,60 +145,74 @@ InitializeExceptions (
   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
-      //\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
+    //\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
-      // 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
+    // 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
-      // Flush Caches since we updated executable stuff\r
-      InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length);\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
+    //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
+    ArmWriteVBar ((UINT32)ExceptionHandlersStart);\r
   }\r
 \r
   if (FiqEnabled) {\r