\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
EFI_PHYSICAL_ADDRESS Base;\r
UINT32 *VectorBase;\r
\r
+ Status = EFI_SUCCESS;\r
//\r
// Disable interrupts\r
//\r
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