summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/CpuInit/Dxe/x64/Exception.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/CpuInit/Dxe/x64/Exception.c')
-rw-r--r--ReferenceCode/Haswell/CpuInit/Dxe/x64/Exception.c372
1 files changed, 372 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/CpuInit/Dxe/x64/Exception.c b/ReferenceCode/Haswell/CpuInit/Dxe/x64/Exception.c
new file mode 100644
index 0000000..bcd306b
--- /dev/null
+++ b/ReferenceCode/Haswell/CpuInit/Dxe/x64/Exception.c
@@ -0,0 +1,372 @@
+/** @file
+ EM64T Exception Handler
+
+@copyright
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "CpuInitDxe.h"
+#include "MpCommon.h"
+#include "Exception.h"
+#endif
+
+typedef
+VOID
+(*EFI_INSTALL_EXCEPTION)(
+ IN UINT32 InterruptType,
+ IN VOID *SystemContext
+ );
+
+typedef struct {
+ UINT32 ErrorMessage;
+ UINT8 Interrupt;
+} EFI_EXCEPTION_HANDLER;
+
+///
+/// Error code flag indicating whether or not an error code will be
+/// pushed on the stack if an exception occurs.
+///
+/// 1 means an error code will be pushed, otherwise 0
+///
+/// bit 0 - exception 0
+/// bit 1 - exception 1
+/// etc.
+///
+UINT32 mErrorCodeFlag = 0x00027d00;
+
+///
+/// Local Table
+///
+EFI_EXCEPTION_HANDLER mExceptionTable[] = {
+ {
+ EFI_SW_EC_IA32_DIVIDE_ERROR,
+ INTERRUPT_HANDLER_DIVIDE_ZERO
+ },
+ {
+ EFI_SW_EC_IA32_DEBUG,
+ INTERRUPT_HANDLER_DEBUG
+ },
+ {
+ EFI_SW_EC_IA32_NMI,
+ INTERRUPT_HANDLER_NMI
+ },
+ {
+ EFI_SW_EC_IA32_BREAKPOINT,
+ INTERRUPT_HANDLER_BREAKPOINT
+ },
+ {
+ EFI_SW_EC_IA32_OVERFLOW,
+ INTERRUPT_HANDLER_OVERFLOW
+ },
+ {
+ EFI_SW_EC_IA32_BOUND,
+ INTERRUPT_HANDLER_BOUND
+ },
+ {
+ EFI_SW_EC_IA32_INVALID_OPCODE,
+ INTERRUPT_HANDLER_INVALID_OPCODE
+ },
+ ///
+ /// Interrupt 7, 9, 15 not defined in the debug support protocol. Hence no status codes for them!
+ ///
+ {
+ EFI_SW_EC_IA32_DOUBLE_FAULT,
+ INTERRUPT_HANDLER_DOUBLE_FAULT
+ },
+ {
+ EFI_SW_EC_IA32_INVALID_TSS,
+ INTERRUPT_HANDLER_INVALID_TSS
+ },
+ {
+ EFI_SW_EC_IA32_SEG_NOT_PRESENT,
+ INTERRUPT_HANDLER_SEGMENT_NOT_PRESENT
+ },
+ {
+ EFI_SW_EC_IA32_STACK_FAULT,
+ INTERRUPT_HANDLER_STACK_SEGMENT_FAULT
+ },
+ {
+ EFI_SW_EC_IA32_GP_FAULT,
+ INTERRUPT_HANDLER_GP_FAULT
+ },
+ {
+ EFI_SW_EC_IA32_PAGE_FAULT,
+ INTERRUPT_HANDLER_PAGE_FAULT
+ },
+ {
+ EFI_SW_EC_IA32_FP_ERROR,
+ INTERRUPT_HANDLER_MATH_FAULT
+ },
+ {
+ EFI_SW_EC_IA32_ALIGNMENT_CHECK,
+ INTERRUPT_HANDLER_ALIGNMENT_FAULT
+ },
+ {
+ EFI_SW_EC_IA32_MACHINE_CHECK,
+ INTERRUPT_HANDLER_MACHINE_CHECK
+ },
+ {
+ EFI_SW_EC_IA32_SIMD,
+ INTERRUPT_HANDLER_STREAMING_SIMD
+ }
+};
+
+UINTN mExceptionNumber = sizeof (mExceptionTable) / sizeof (EFI_EXCEPTION_HANDLER);
+
+CPU_STATUS_CODE_TEMPLATE mStatusCodeData = {
+ {
+ sizeof (EFI_STATUS_CODE_DATA),
+ sizeof (EFI_SYSTEM_CONTEXT_X64),
+ EFI_STATUS_CODE_DATA_TYPE_EXCEPTION_HANDLER_GUID
+ },
+ {
+ 0
+ }
+};
+
+UINT8 mExceptionLock = 0;
+
+/**
+ Report StatusCode for Exception
+
+ @param[in] InterruptType - Interrupt type
+ @param[in] SystemContext - EFI_SYSTEM_CONTEXT
+
+ @retval EFI_SUCCESS
+**/
+EFI_STATUS
+ReportData (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINT32 ErrorMessage;
+ UINT32 Index;
+
+ CopyMem (
+ &mStatusCodeData.SystemContext.SystemContextX64,
+ SystemContext.SystemContextX64,
+ sizeof (EFI_SYSTEM_CONTEXT_X64)
+ );
+
+ ErrorMessage = EFI_SOFTWARE_DXE_BS_DRIVER;
+ for (Index = 0; Index < mExceptionNumber; Index++) {
+ if (mExceptionTable[Index].Interrupt == InterruptType) {
+ ErrorMessage |= mExceptionTable[Index].ErrorMessage;
+ break;
+ }
+ }
+
+ ReportStatusCode (
+ (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+ EFI_SOFTWARE_UNSPECIFIED | ErrorMessage
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Common exception handler
+
+ @param[in] InterruptType - Exception type
+ @param[in] SystemContext - EFI_SYSTEM_CONTEXT
+**/
+VOID
+EFIAPI
+CommonExceptionHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ AsmAcquireMPLock (&mExceptionLock);
+
+ DEBUG (
+ (EFI_D_ERROR,
+ "!!!! X64 Exception Type - %016lx CPU Apic ID - %08x!!!!\n",
+ InterruptType,
+ GetApicID (NULL,
+ NULL))
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",
+ SystemContext.SystemContextX64->Rip,
+ SystemContext.SystemContextX64->Cs,
+ SystemContext.SystemContextX64->Rflags)
+ );
+ if (mErrorCodeFlag & (1 << InterruptType)) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "ExceptionData - %016lx\n",
+ SystemContext.SystemContextX64->ExceptionData)
+ );
+ }
+
+ DEBUG (
+ (EFI_D_ERROR,
+ "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
+ SystemContext.SystemContextX64->Rax,
+ SystemContext.SystemContextX64->Rcx,
+ SystemContext.SystemContextX64->Rdx)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
+ SystemContext.SystemContextX64->Rbx,
+ SystemContext.SystemContextX64->Rsp,
+ SystemContext.SystemContextX64->Rbp)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "RSI - %016lx, RDI - %016lx\n",
+ SystemContext.SystemContextX64->Rsi,
+ SystemContext.SystemContextX64->Rdi)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
+ SystemContext.SystemContextX64->R8,
+ SystemContext.SystemContextX64->R9,
+ SystemContext.SystemContextX64->R10)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
+ SystemContext.SystemContextX64->R11,
+ SystemContext.SystemContextX64->R12,
+ SystemContext.SystemContextX64->R13)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "R14 - %016lx, R15 - %016lx\n",
+ SystemContext.SystemContextX64->R14,
+ SystemContext.SystemContextX64->R15)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "DS - %016lx, ES - %016lx, FS - %016lx\n",
+ SystemContext.SystemContextX64->Ds,
+ SystemContext.SystemContextX64->Es,
+ SystemContext.SystemContextX64->Fs)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "GS - %016lx, SS - %016lx\n",
+ SystemContext.SystemContextX64->Gs,
+ SystemContext.SystemContextX64->Ss)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "GDTR - %016lx %016lx, LDTR - %016lx\n",
+ SystemContext.SystemContextX64->Gdtr[0],
+ SystemContext.SystemContextX64->Gdtr[1],
+ SystemContext.SystemContextX64->Ldtr)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "IDTR - %016lx %016lx, TR - %016lx\n",
+ SystemContext.SystemContextX64->Idtr[0],
+ SystemContext.SystemContextX64->Idtr[1],
+ SystemContext.SystemContextX64->Tr)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
+ SystemContext.SystemContextX64->Cr0,
+ SystemContext.SystemContextX64->Cr2,
+ SystemContext.SystemContextX64->Cr3)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "CR4 - %016lx, CR8 - %016lx\n",
+ SystemContext.SystemContextX64->Cr4,
+ SystemContext.SystemContextX64->Cr8)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
+ SystemContext.SystemContextX64->Dr0,
+ SystemContext.SystemContextX64->Dr1,
+ SystemContext.SystemContextX64->Dr2)
+ );
+ DEBUG (
+ (EFI_D_ERROR,
+ "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
+ SystemContext.SystemContextX64->Dr3,
+ SystemContext.SystemContextX64->Dr6,
+ SystemContext.SystemContextX64->Dr7)
+ );
+
+ ///
+ /// Report Status Code
+ ///
+ ReportData (InterruptType, SystemContext);
+ AsmReleaseMPLock (&mExceptionLock);
+
+ ///
+ /// Use this macro to hang so that the compiler does not optimize out
+ /// the following RET instructions. This allows us to return if we
+ /// have a debugger attached.
+ ///
+ EFI_DEADLOOP ();
+
+ return;
+}
+
+/**
+ Install the IA-32 EM64T Exception Handler.
+ The current operation (which likely will change) will uninstall all the
+ pertinent exception handlers (0-7, 10-14, 16-19) except for Int8 which the timer
+ is currently sitting on (or soon will be).
+
+ It then installs all the appropriate handlers for each exception.
+
+ The handler then calls gRT->ReportStatusCode with a specific progress code. The
+ progress codes for now start at 0x200 for IA-32 processors. See Status Code
+ Specification for details. The Status code Specification uses the enumeration from
+ the EFI 1.1 Debug Support Protocol.
+
+ @param[in] CpuProtocol - Instance of CPU Arch Protocol
+
+ @retval EFI_SUCCESS - This function always return success after registering handlers.
+**/
+EFI_STATUS
+InitializeException (
+ IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+
+ CpuProtocol->DisableInterrupt (CpuProtocol);
+
+ for (Index = 0; Index < mExceptionNumber; Index++) {
+ Status = CpuProtocol->RegisterInterruptHandler (CpuProtocol, mExceptionTable[Index].Interrupt, NULL);
+ ///
+ /// Add in our handler
+ ///
+ Status = CpuProtocol->RegisterInterruptHandler (
+ CpuProtocol,
+ mExceptionTable[Index].Interrupt,
+ CommonExceptionHandler
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}