Home | History | Annotate | Download | only in X64
      1 /** @file
      2   x64 CPU Exception Handler.
      3 
      4   Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "CpuExceptionCommon.h"
     16 
     17 /**
     18   Return address map of exception handler template so that C code can generate
     19   exception tables.
     20 
     21   @param IdtEntry          Pointer to IDT entry to be updated.
     22   @param InterruptHandler  IDT handler value.
     23 **/
     24 VOID
     25 ArchUpdateIdtEntry (
     26   IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry,
     27   IN UINTN                           InterruptHandler
     28   )
     29 {
     30   IdtEntry->Bits.OffsetLow   = (UINT16)(UINTN)InterruptHandler;
     31   IdtEntry->Bits.OffsetHigh  = (UINT16)((UINTN)InterruptHandler >> 16);
     32   IdtEntry->Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
     33   IdtEntry->Bits.GateType    = IA32_IDT_GATE_TYPE_INTERRUPT_32;
     34 }
     35 
     36 /**
     37   Read IDT handler value from IDT entry.
     38 
     39   @param IdtEntry          Pointer to IDT entry to be read.
     40 
     41 **/
     42 UINTN
     43 ArchGetIdtHandler (
     44   IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry
     45   )
     46 {
     47   return IdtEntry->Bits.OffsetLow + (((UINTN) IdtEntry->Bits.OffsetHigh)  << 16) +
     48                                     (((UINTN) IdtEntry->Bits.OffsetUpper) << 32);
     49 }
     50 
     51 /**
     52   Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
     53 
     54   @param[in] ExceptionType        Exception type.
     55   @param[in] SystemContext        Pointer to EFI_SYSTEM_CONTEXT.
     56   @param[in] ExceptionHandlerData Pointer to exception handler data.
     57 **/
     58 VOID
     59 ArchSaveExceptionContext (
     60   IN UINTN                        ExceptionType,
     61   IN EFI_SYSTEM_CONTEXT           SystemContext,
     62   IN EXCEPTION_HANDLER_DATA       *ExceptionHandlerData
     63   )
     64 {
     65   IA32_EFLAGS32           Eflags;
     66   RESERVED_VECTORS_DATA   *ReservedVectors;
     67 
     68   ReservedVectors = ExceptionHandlerData->ReservedVectors;
     69   //
     70   // Save Exception context in global variable
     71   //
     72   ReservedVectors[ExceptionType].OldSs         = SystemContext.SystemContextX64->Ss;
     73   ReservedVectors[ExceptionType].OldSp         = SystemContext.SystemContextX64->Rsp;
     74   ReservedVectors[ExceptionType].OldFlags      = SystemContext.SystemContextX64->Rflags;
     75   ReservedVectors[ExceptionType].OldCs         = SystemContext.SystemContextX64->Cs;
     76   ReservedVectors[ExceptionType].OldIp         = SystemContext.SystemContextX64->Rip;
     77   ReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData;
     78   //
     79   // Clear IF flag to avoid old IDT handler enable interrupt by IRET
     80   //
     81   Eflags.UintN = SystemContext.SystemContextX64->Rflags;
     82   Eflags.Bits.IF = 0;
     83   SystemContext.SystemContextX64->Rflags = Eflags.UintN;
     84   //
     85   // Modify the EIP in stack, then old IDT handler will return to the stub code
     86   //
     87   SystemContext.SystemContextX64->Rip = (UINTN) ReservedVectors[ExceptionType].HookAfterStubHeaderCode;
     88 }
     89 
     90 /**
     91   Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
     92 
     93   @param[in] ExceptionType        Exception type.
     94   @param[in] SystemContext        Pointer to EFI_SYSTEM_CONTEXT.
     95   @param[in] ExceptionHandlerData Pointer to exception handler data.
     96 **/
     97 VOID
     98 ArchRestoreExceptionContext (
     99   IN UINTN                        ExceptionType,
    100   IN EFI_SYSTEM_CONTEXT           SystemContext,
    101   IN EXCEPTION_HANDLER_DATA       *ExceptionHandlerData
    102   )
    103 {
    104   RESERVED_VECTORS_DATA   *ReservedVectors;
    105 
    106   ReservedVectors = ExceptionHandlerData->ReservedVectors;
    107   SystemContext.SystemContextX64->Ss            = ReservedVectors[ExceptionType].OldSs;
    108   SystemContext.SystemContextX64->Rsp           = ReservedVectors[ExceptionType].OldSp;
    109   SystemContext.SystemContextX64->Rflags        = ReservedVectors[ExceptionType].OldFlags;
    110   SystemContext.SystemContextX64->Cs            = ReservedVectors[ExceptionType].OldCs;
    111   SystemContext.SystemContextX64->Rip           = ReservedVectors[ExceptionType].OldIp;
    112   SystemContext.SystemContextX64->ExceptionData = ReservedVectors[ExceptionType].ExceptionData;
    113 }
    114 
    115 /**
    116   Display CPU information.
    117 
    118   @param ExceptionType  Exception type.
    119   @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
    120 **/
    121 VOID
    122 DumpCpuContent (
    123   IN EFI_EXCEPTION_TYPE   ExceptionType,
    124   IN EFI_SYSTEM_CONTEXT   SystemContext
    125   )
    126 {
    127   UINTN                   ImageBase;
    128   UINTN                   EntryPoint;
    129 
    130   InternalPrintMessage (
    131     "!!!! X64 Exception Type - %02x(%a)  CPU Apic ID - %08x !!!!\n",
    132     ExceptionType,
    133     GetExceptionNameStr (ExceptionType),
    134     GetApicId ()
    135     );
    136 
    137   InternalPrintMessage (
    138     "RIP  - %016lx, CS  - %016lx, RFLAGS - %016lx\n",
    139     SystemContext.SystemContextX64->Rip,
    140     SystemContext.SystemContextX64->Cs,
    141     SystemContext.SystemContextX64->Rflags
    142     );
    143   if (mErrorCodeFlag & (1 << ExceptionType)) {
    144     InternalPrintMessage (
    145       "ExceptionData - %016lx\n",
    146       SystemContext.SystemContextX64->ExceptionData
    147       );
    148   }
    149   InternalPrintMessage (
    150     "RAX  - %016lx, RCX - %016lx, RDX - %016lx\n",
    151     SystemContext.SystemContextX64->Rax,
    152     SystemContext.SystemContextX64->Rcx,
    153     SystemContext.SystemContextX64->Rdx
    154     );
    155   InternalPrintMessage (
    156     "RBX  - %016lx, RSP - %016lx, RBP - %016lx\n",
    157     SystemContext.SystemContextX64->Rbx,
    158     SystemContext.SystemContextX64->Rsp,
    159     SystemContext.SystemContextX64->Rbp
    160     );
    161   InternalPrintMessage (
    162     "RSI  - %016lx, RDI - %016lx\n",
    163     SystemContext.SystemContextX64->Rsi,
    164     SystemContext.SystemContextX64->Rdi
    165     );
    166   InternalPrintMessage (
    167     "R8   - %016lx, R9  - %016lx, R10 - %016lx\n",
    168     SystemContext.SystemContextX64->R8,
    169     SystemContext.SystemContextX64->R9,
    170     SystemContext.SystemContextX64->R10
    171     );
    172   InternalPrintMessage (
    173     "R11  - %016lx, R12 - %016lx, R13 - %016lx\n",
    174     SystemContext.SystemContextX64->R11,
    175     SystemContext.SystemContextX64->R12,
    176     SystemContext.SystemContextX64->R13
    177     );
    178   InternalPrintMessage (
    179     "R14  - %016lx, R15 - %016lx\n",
    180     SystemContext.SystemContextX64->R14,
    181     SystemContext.SystemContextX64->R15
    182     );
    183   InternalPrintMessage (
    184     "DS   - %016lx, ES  - %016lx, FS  - %016lx\n",
    185     SystemContext.SystemContextX64->Ds,
    186     SystemContext.SystemContextX64->Es,
    187     SystemContext.SystemContextX64->Fs
    188     );
    189   InternalPrintMessage (
    190     "GS   - %016lx, SS  - %016lx\n",
    191     SystemContext.SystemContextX64->Gs,
    192     SystemContext.SystemContextX64->Ss
    193     );
    194   InternalPrintMessage (
    195     "CR0  - %016lx, CR2 - %016lx, CR3 - %016lx\n",
    196     SystemContext.SystemContextX64->Cr0,
    197     SystemContext.SystemContextX64->Cr2,
    198     SystemContext.SystemContextX64->Cr3
    199     );
    200   InternalPrintMessage (
    201     "CR4  - %016lx, CR8 - %016lx\n",
    202     SystemContext.SystemContextX64->Cr4,
    203     SystemContext.SystemContextX64->Cr8
    204     );
    205   InternalPrintMessage (
    206     "DR0  - %016lx, DR1 - %016lx, DR2 - %016lx\n",
    207     SystemContext.SystemContextX64->Dr0,
    208     SystemContext.SystemContextX64->Dr1,
    209     SystemContext.SystemContextX64->Dr2
    210     );
    211   InternalPrintMessage (
    212     "DR3  - %016lx, DR6 - %016lx, DR7 - %016lx\n",
    213     SystemContext.SystemContextX64->Dr3,
    214     SystemContext.SystemContextX64->Dr6,
    215     SystemContext.SystemContextX64->Dr7
    216     );
    217   InternalPrintMessage (
    218     "GDTR - %016lx %016lx, LDTR - %016lx\n",
    219     SystemContext.SystemContextX64->Gdtr[0],
    220     SystemContext.SystemContextX64->Gdtr[1],
    221     SystemContext.SystemContextX64->Ldtr
    222     );
    223   InternalPrintMessage (
    224     "IDTR - %016lx %016lx,   TR - %016lx\n",
    225     SystemContext.SystemContextX64->Idtr[0],
    226     SystemContext.SystemContextX64->Idtr[1],
    227     SystemContext.SystemContextX64->Tr
    228     );
    229 	InternalPrintMessage (
    230     "FXSAVE_STATE - %016lx\n",
    231     &SystemContext.SystemContextX64->FxSaveState
    232     );
    233 
    234   //
    235   // Find module image base and module entry point by RIP
    236   //
    237   ImageBase = FindModuleImageBase (SystemContext.SystemContextX64->Rip, &EntryPoint);
    238   if (ImageBase != 0) {
    239     InternalPrintMessage (
    240       " (ImageBase=%016lx, EntryPoint=%016lx) !!!!\n",
    241       ImageBase,
    242       EntryPoint
    243       );
    244   }
    245 }
    246