mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 05:38:26 +00:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1521 Add information dump for Control Protection exception. Cc: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yao Jiewen <jiewen.yao@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
		
			
				
	
	
		
			434 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			434 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  x64 CPU Exception Handler.
 | 
						|
 | 
						|
  Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "CpuExceptionCommon.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Return address map of exception handler template so that C code can generate
 | 
						|
  exception tables.
 | 
						|
 | 
						|
  @param IdtEntry          Pointer to IDT entry to be updated.
 | 
						|
  @param InterruptHandler  IDT handler value.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
ArchUpdateIdtEntry (
 | 
						|
  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry,
 | 
						|
  IN UINTN                           InterruptHandler
 | 
						|
  )
 | 
						|
{
 | 
						|
  IdtEntry->Bits.OffsetLow   = (UINT16)(UINTN)InterruptHandler;
 | 
						|
  IdtEntry->Bits.OffsetHigh  = (UINT16)((UINTN)InterruptHandler >> 16);
 | 
						|
  IdtEntry->Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
 | 
						|
  IdtEntry->Bits.GateType    = IA32_IDT_GATE_TYPE_INTERRUPT_32;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Read IDT handler value from IDT entry.
 | 
						|
 | 
						|
  @param IdtEntry          Pointer to IDT entry to be read.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
ArchGetIdtHandler (
 | 
						|
  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry
 | 
						|
  )
 | 
						|
{
 | 
						|
  return IdtEntry->Bits.OffsetLow + (((UINTN) IdtEntry->Bits.OffsetHigh)  << 16) +
 | 
						|
                                    (((UINTN) IdtEntry->Bits.OffsetUpper) << 32);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
 | 
						|
 | 
						|
  @param[in] ExceptionType        Exception type.
 | 
						|
  @param[in] SystemContext        Pointer to EFI_SYSTEM_CONTEXT.
 | 
						|
  @param[in] ExceptionHandlerData Pointer to exception handler data.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
ArchSaveExceptionContext (
 | 
						|
  IN UINTN                        ExceptionType,
 | 
						|
  IN EFI_SYSTEM_CONTEXT           SystemContext,
 | 
						|
  IN EXCEPTION_HANDLER_DATA       *ExceptionHandlerData
 | 
						|
  )
 | 
						|
{
 | 
						|
  IA32_EFLAGS32           Eflags;
 | 
						|
  RESERVED_VECTORS_DATA   *ReservedVectors;
 | 
						|
 | 
						|
  ReservedVectors = ExceptionHandlerData->ReservedVectors;
 | 
						|
  //
 | 
						|
  // Save Exception context in global variable in first entry of the exception handler.
 | 
						|
  // So when original exception handler returns to the new exception handler (second entry),
 | 
						|
  // the Eflags/Cs/Eip/ExceptionData can be used.
 | 
						|
  //
 | 
						|
  ReservedVectors[ExceptionType].OldSs         = SystemContext.SystemContextX64->Ss;
 | 
						|
  ReservedVectors[ExceptionType].OldSp         = SystemContext.SystemContextX64->Rsp;
 | 
						|
  ReservedVectors[ExceptionType].OldFlags      = SystemContext.SystemContextX64->Rflags;
 | 
						|
  ReservedVectors[ExceptionType].OldCs         = SystemContext.SystemContextX64->Cs;
 | 
						|
  ReservedVectors[ExceptionType].OldIp         = SystemContext.SystemContextX64->Rip;
 | 
						|
  ReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData;
 | 
						|
  //
 | 
						|
  // Clear IF flag to avoid old IDT handler enable interrupt by IRET
 | 
						|
  //
 | 
						|
  Eflags.UintN = SystemContext.SystemContextX64->Rflags;
 | 
						|
  Eflags.Bits.IF = 0;
 | 
						|
  SystemContext.SystemContextX64->Rflags = Eflags.UintN;
 | 
						|
  //
 | 
						|
  // Modify the EIP in stack, then old IDT handler will return to HookAfterStubBegin.
 | 
						|
  //
 | 
						|
  SystemContext.SystemContextX64->Rip = (UINTN) ReservedVectors[ExceptionType].HookAfterStubHeaderCode;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
 | 
						|
 | 
						|
  @param[in] ExceptionType        Exception type.
 | 
						|
  @param[in] SystemContext        Pointer to EFI_SYSTEM_CONTEXT.
 | 
						|
  @param[in] ExceptionHandlerData Pointer to exception handler data.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
ArchRestoreExceptionContext (
 | 
						|
  IN UINTN                        ExceptionType,
 | 
						|
  IN EFI_SYSTEM_CONTEXT           SystemContext,
 | 
						|
  IN EXCEPTION_HANDLER_DATA       *ExceptionHandlerData
 | 
						|
  )
 | 
						|
{
 | 
						|
  RESERVED_VECTORS_DATA   *ReservedVectors;
 | 
						|
 | 
						|
  ReservedVectors = ExceptionHandlerData->ReservedVectors;
 | 
						|
  SystemContext.SystemContextX64->Ss            = ReservedVectors[ExceptionType].OldSs;
 | 
						|
  SystemContext.SystemContextX64->Rsp           = ReservedVectors[ExceptionType].OldSp;
 | 
						|
  SystemContext.SystemContextX64->Rflags        = ReservedVectors[ExceptionType].OldFlags;
 | 
						|
  SystemContext.SystemContextX64->Cs            = ReservedVectors[ExceptionType].OldCs;
 | 
						|
  SystemContext.SystemContextX64->Rip           = ReservedVectors[ExceptionType].OldIp;
 | 
						|
  SystemContext.SystemContextX64->ExceptionData = ReservedVectors[ExceptionType].ExceptionData;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Setup separate stack for given exceptions.
 | 
						|
 | 
						|
  @param[in] StackSwitchData      Pointer to data required for setuping up
 | 
						|
                                  stack switch.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The exceptions have been successfully
 | 
						|
                                  initialized with new stack.
 | 
						|
  @retval EFI_INVALID_PARAMETER   StackSwitchData contains invalid content.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
ArchSetupExceptionStack (
 | 
						|
  IN CPU_EXCEPTION_INIT_DATA          *StackSwitchData
 | 
						|
  )
 | 
						|
{
 | 
						|
  IA32_DESCRIPTOR                   Gdtr;
 | 
						|
  IA32_DESCRIPTOR                   Idtr;
 | 
						|
  IA32_IDT_GATE_DESCRIPTOR          *IdtTable;
 | 
						|
  IA32_TSS_DESCRIPTOR               *TssDesc;
 | 
						|
  IA32_TASK_STATE_SEGMENT           *Tss;
 | 
						|
  UINTN                             StackTop;
 | 
						|
  UINTN                             Index;
 | 
						|
  UINTN                             Vector;
 | 
						|
  UINTN                             TssBase;
 | 
						|
  UINTN                             GdtSize;
 | 
						|
 | 
						|
  if (StackSwitchData == NULL ||
 | 
						|
      StackSwitchData->Ia32.Revision != CPU_EXCEPTION_INIT_DATA_REV ||
 | 
						|
      StackSwitchData->X64.KnownGoodStackTop == 0 ||
 | 
						|
      StackSwitchData->X64.KnownGoodStackSize == 0 ||
 | 
						|
      StackSwitchData->X64.StackSwitchExceptions == NULL ||
 | 
						|
      StackSwitchData->X64.StackSwitchExceptionNumber == 0 ||
 | 
						|
      StackSwitchData->X64.StackSwitchExceptionNumber > CPU_EXCEPTION_NUM ||
 | 
						|
      StackSwitchData->X64.GdtTable == NULL ||
 | 
						|
      StackSwitchData->X64.IdtTable == NULL ||
 | 
						|
      StackSwitchData->X64.ExceptionTssDesc == NULL ||
 | 
						|
      StackSwitchData->X64.ExceptionTss == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // The caller is responsible for that the GDT table, no matter the existing
 | 
						|
  // one or newly allocated, has enough space to hold descriptors for exception
 | 
						|
  // task-state segments.
 | 
						|
  //
 | 
						|
  if (((UINTN)StackSwitchData->X64.GdtTable & (IA32_GDT_ALIGNMENT - 1)) != 0) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((UINTN)StackSwitchData->X64.ExceptionTssDesc < (UINTN)(StackSwitchData->X64.GdtTable)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (((UINTN)StackSwitchData->X64.ExceptionTssDesc + StackSwitchData->X64.ExceptionTssDescSize) >
 | 
						|
      ((UINTN)(StackSwitchData->X64.GdtTable) + StackSwitchData->X64.GdtTableSize)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // One task gate descriptor and one task-state segment are needed.
 | 
						|
  //
 | 
						|
  if (StackSwitchData->X64.ExceptionTssDescSize < sizeof (IA32_TSS_DESCRIPTOR)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  if (StackSwitchData->X64.ExceptionTssSize < sizeof (IA32_TASK_STATE_SEGMENT)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Interrupt stack table supports only 7 vectors.
 | 
						|
  //
 | 
						|
  TssDesc = StackSwitchData->X64.ExceptionTssDesc;
 | 
						|
  Tss     = StackSwitchData->X64.ExceptionTss;
 | 
						|
  if (StackSwitchData->X64.StackSwitchExceptionNumber > ARRAY_SIZE (Tss->IST)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize new GDT table and/or IDT table, if any
 | 
						|
  //
 | 
						|
  AsmReadIdtr (&Idtr);
 | 
						|
  AsmReadGdtr (&Gdtr);
 | 
						|
 | 
						|
  GdtSize = (UINTN)TssDesc + sizeof (IA32_TSS_DESCRIPTOR) -
 | 
						|
            (UINTN)(StackSwitchData->X64.GdtTable);
 | 
						|
  if ((UINTN)StackSwitchData->X64.GdtTable != Gdtr.Base) {
 | 
						|
    CopyMem (StackSwitchData->X64.GdtTable, (VOID *)Gdtr.Base, Gdtr.Limit + 1);
 | 
						|
    Gdtr.Base = (UINTN)StackSwitchData->X64.GdtTable;
 | 
						|
    Gdtr.Limit = (UINT16)GdtSize - 1;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((UINTN)StackSwitchData->X64.IdtTable != Idtr.Base) {
 | 
						|
    Idtr.Base = (UINTN)StackSwitchData->X64.IdtTable;
 | 
						|
  }
 | 
						|
  if (StackSwitchData->X64.IdtTableSize > 0) {
 | 
						|
    Idtr.Limit = (UINT16)(StackSwitchData->X64.IdtTableSize - 1);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Fixup current task descriptor. Task-state segment for current task will
 | 
						|
  // be filled by processor during task switching.
 | 
						|
  //
 | 
						|
  TssBase = (UINTN)Tss;
 | 
						|
 | 
						|
  TssDesc->Uint128.Uint64  = 0;
 | 
						|
  TssDesc->Uint128.Uint64_1= 0;
 | 
						|
  TssDesc->Bits.LimitLow   = sizeof(IA32_TASK_STATE_SEGMENT) - 1;
 | 
						|
  TssDesc->Bits.BaseLow    = (UINT16)TssBase;
 | 
						|
  TssDesc->Bits.BaseMidl   = (UINT8)(TssBase >> 16);
 | 
						|
  TssDesc->Bits.Type       = IA32_GDT_TYPE_TSS;
 | 
						|
  TssDesc->Bits.P          = 1;
 | 
						|
  TssDesc->Bits.LimitHigh  = 0;
 | 
						|
  TssDesc->Bits.BaseMidh   = (UINT8)(TssBase >> 24);
 | 
						|
  TssDesc->Bits.BaseHigh   = (UINT32)(TssBase >> 32);
 | 
						|
 | 
						|
  //
 | 
						|
  // Fixup exception task descriptor and task-state segment
 | 
						|
  //
 | 
						|
  ZeroMem (Tss, sizeof (*Tss));
 | 
						|
  StackTop = StackSwitchData->X64.KnownGoodStackTop - CPU_STACK_ALIGNMENT;
 | 
						|
  StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT);
 | 
						|
  IdtTable = StackSwitchData->X64.IdtTable;
 | 
						|
  for (Index = 0; Index < StackSwitchData->X64.StackSwitchExceptionNumber; ++Index) {
 | 
						|
    //
 | 
						|
    // Fixup IST
 | 
						|
    //
 | 
						|
    Tss->IST[Index] = StackTop;
 | 
						|
    StackTop -= StackSwitchData->X64.KnownGoodStackSize;
 | 
						|
 | 
						|
    //
 | 
						|
    // Set the IST field to enable corresponding IST
 | 
						|
    //
 | 
						|
    Vector = StackSwitchData->X64.StackSwitchExceptions[Index];
 | 
						|
    if (Vector >= CPU_EXCEPTION_NUM ||
 | 
						|
        Vector >= (Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    IdtTable[Vector].Bits.Reserved_0 = (UINT8)(Index + 1);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Publish GDT
 | 
						|
  //
 | 
						|
  AsmWriteGdtr (&Gdtr);
 | 
						|
 | 
						|
  //
 | 
						|
  // Load current task
 | 
						|
  //
 | 
						|
  AsmWriteTr ((UINT16)((UINTN)StackSwitchData->X64.ExceptionTssDesc - Gdtr.Base));
 | 
						|
 | 
						|
  //
 | 
						|
  // Publish IDT
 | 
						|
  //
 | 
						|
  AsmWriteIdtr (&Idtr);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Display CPU information.
 | 
						|
 | 
						|
  @param ExceptionType  Exception type.
 | 
						|
  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
DumpCpuContext (
 | 
						|
  IN EFI_EXCEPTION_TYPE   ExceptionType,
 | 
						|
  IN EFI_SYSTEM_CONTEXT   SystemContext
 | 
						|
  )
 | 
						|
{
 | 
						|
  InternalPrintMessage (
 | 
						|
    "!!!! X64 Exception Type - %02x(%a)  CPU Apic ID - %08x !!!!\n",
 | 
						|
    ExceptionType,
 | 
						|
    GetExceptionNameStr (ExceptionType),
 | 
						|
    GetApicId ()
 | 
						|
    );
 | 
						|
  if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) {
 | 
						|
    InternalPrintMessage (
 | 
						|
      "ExceptionData - %016lx",
 | 
						|
      SystemContext.SystemContextX64->ExceptionData
 | 
						|
      );
 | 
						|
    if (ExceptionType == EXCEPT_IA32_PAGE_FAULT) {
 | 
						|
      InternalPrintMessage (
 | 
						|
        "  I:%x R:%x U:%x W:%x P:%x PK:%x SS:%x SGX:%x",
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID)   != 0,
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_RSVD) != 0,
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_US)   != 0,
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_WR)   != 0,
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_P)    != 0,
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_PK)   != 0,
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_SS)   != 0,
 | 
						|
        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_SGX)  != 0
 | 
						|
        );
 | 
						|
    }
 | 
						|
    InternalPrintMessage ("\n");
 | 
						|
  }
 | 
						|
  InternalPrintMessage (
 | 
						|
    "RIP  - %016lx, CS  - %016lx, RFLAGS - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Rip,
 | 
						|
    SystemContext.SystemContextX64->Cs,
 | 
						|
    SystemContext.SystemContextX64->Rflags
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "RAX  - %016lx, RCX - %016lx, RDX - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Rax,
 | 
						|
    SystemContext.SystemContextX64->Rcx,
 | 
						|
    SystemContext.SystemContextX64->Rdx
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "RBX  - %016lx, RSP - %016lx, RBP - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Rbx,
 | 
						|
    SystemContext.SystemContextX64->Rsp,
 | 
						|
    SystemContext.SystemContextX64->Rbp
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "RSI  - %016lx, RDI - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Rsi,
 | 
						|
    SystemContext.SystemContextX64->Rdi
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "R8   - %016lx, R9  - %016lx, R10 - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->R8,
 | 
						|
    SystemContext.SystemContextX64->R9,
 | 
						|
    SystemContext.SystemContextX64->R10
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "R11  - %016lx, R12 - %016lx, R13 - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->R11,
 | 
						|
    SystemContext.SystemContextX64->R12,
 | 
						|
    SystemContext.SystemContextX64->R13
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "R14  - %016lx, R15 - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->R14,
 | 
						|
    SystemContext.SystemContextX64->R15
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "DS   - %016lx, ES  - %016lx, FS  - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Ds,
 | 
						|
    SystemContext.SystemContextX64->Es,
 | 
						|
    SystemContext.SystemContextX64->Fs
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "GS   - %016lx, SS  - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Gs,
 | 
						|
    SystemContext.SystemContextX64->Ss
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "CR0  - %016lx, CR2 - %016lx, CR3 - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Cr0,
 | 
						|
    SystemContext.SystemContextX64->Cr2,
 | 
						|
    SystemContext.SystemContextX64->Cr3
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "CR4  - %016lx, CR8 - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Cr4,
 | 
						|
    SystemContext.SystemContextX64->Cr8
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "DR0  - %016lx, DR1 - %016lx, DR2 - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Dr0,
 | 
						|
    SystemContext.SystemContextX64->Dr1,
 | 
						|
    SystemContext.SystemContextX64->Dr2
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "DR3  - %016lx, DR6 - %016lx, DR7 - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Dr3,
 | 
						|
    SystemContext.SystemContextX64->Dr6,
 | 
						|
    SystemContext.SystemContextX64->Dr7
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "GDTR - %016lx %016lx, LDTR - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Gdtr[0],
 | 
						|
    SystemContext.SystemContextX64->Gdtr[1],
 | 
						|
    SystemContext.SystemContextX64->Ldtr
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "IDTR - %016lx %016lx,   TR - %016lx\n",
 | 
						|
    SystemContext.SystemContextX64->Idtr[0],
 | 
						|
    SystemContext.SystemContextX64->Idtr[1],
 | 
						|
    SystemContext.SystemContextX64->Tr
 | 
						|
    );
 | 
						|
  InternalPrintMessage (
 | 
						|
    "FXSAVE_STATE - %016lx\n",
 | 
						|
    &SystemContext.SystemContextX64->FxSaveState
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Display CPU information.
 | 
						|
 | 
						|
  @param ExceptionType  Exception type.
 | 
						|
  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
DumpImageAndCpuContent (
 | 
						|
  IN EFI_EXCEPTION_TYPE   ExceptionType,
 | 
						|
  IN EFI_SYSTEM_CONTEXT   SystemContext
 | 
						|
  )
 | 
						|
{
 | 
						|
  DumpCpuContext (ExceptionType, SystemContext);
 | 
						|
  //
 | 
						|
  // Dump module image base and module entry point by RIP
 | 
						|
  //
 | 
						|
  if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) &&
 | 
						|
      ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0)) {
 | 
						|
    //
 | 
						|
    // The RIP in SystemContext could not be used
 | 
						|
    // if it is page fault with I/D set.
 | 
						|
    //
 | 
						|
    DumpModuleImageInfo ((*(UINTN *)(UINTN)SystemContext.SystemContextX64->Rsp));
 | 
						|
  } else {
 | 
						|
    DumpModuleImageInfo (SystemContext.SystemContextX64->Rip);
 | 
						|
  }
 | 
						|
}
 |