Home | History | Annotate | Download | only in Ia32
      1 /** @file
      2   IA32 CPU Exception Handler functons.
      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 **/
     25 VOID
     26 ArchUpdateIdtEntry (
     27   IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry,
     28   IN UINTN                           InterruptHandler
     29   )
     30 {
     31   IdtEntry->Bits.OffsetLow   = (UINT16)(UINTN)InterruptHandler;
     32   IdtEntry->Bits.OffsetHigh  = (UINT16)((UINTN)InterruptHandler >> 16);
     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 (UINTN)IdtEntry->Bits.OffsetLow + (((UINTN)IdtEntry->Bits.OffsetHigh) << 16);
     48 }
     49 
     50 /**
     51   Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
     52 
     53   @param[in] ExceptionType        Exception type.
     54   @param[in] SystemContext        Pointer to EFI_SYSTEM_CONTEXT.
     55   @param[in] ExceptionHandlerData Pointer to exception handler data.
     56 **/
     57 VOID
     58 ArchSaveExceptionContext (
     59   IN UINTN                        ExceptionType,
     60   IN EFI_SYSTEM_CONTEXT           SystemContext,
     61   IN EXCEPTION_HANDLER_DATA       *ExceptionHandlerData
     62   )
     63 {
     64   IA32_EFLAGS32           Eflags;
     65   RESERVED_VECTORS_DATA   *ReservedVectors;
     66 
     67   ReservedVectors = ExceptionHandlerData->ReservedVectors;
     68   //
     69   // Save Exception context in global variable
     70   //
     71   ReservedVectors[ExceptionType].OldFlags      = SystemContext.SystemContextIa32->Eflags;
     72   ReservedVectors[ExceptionType].OldCs         = SystemContext.SystemContextIa32->Cs;
     73   ReservedVectors[ExceptionType].OldIp         = SystemContext.SystemContextIa32->Eip;
     74   ReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextIa32->ExceptionData;
     75   //
     76   // Clear IF flag to avoid old IDT handler enable interrupt by IRET
     77   //
     78   Eflags.UintN = SystemContext.SystemContextIa32->Eflags;
     79   Eflags.Bits.IF = 0;
     80   SystemContext.SystemContextIa32->Eflags = Eflags.UintN;
     81   //
     82   // Modify the EIP in stack, then old IDT handler will return to the stub code
     83   //
     84   SystemContext.SystemContextIa32->Eip    = (UINTN) ReservedVectors[ExceptionType].HookAfterStubHeaderCode;
     85 }
     86 
     87 /**
     88   Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
     89 
     90   @param[in] ExceptionType        Exception type.
     91   @param[in] SystemContext        Pointer to EFI_SYSTEM_CONTEXT.
     92   @param[in] ExceptionHandlerData Pointer to exception handler data.
     93 **/
     94 VOID
     95 ArchRestoreExceptionContext (
     96   IN UINTN                        ExceptionType,
     97   IN EFI_SYSTEM_CONTEXT           SystemContext,
     98   IN EXCEPTION_HANDLER_DATA       *ExceptionHandlerData
     99   )
    100 {
    101   RESERVED_VECTORS_DATA   *ReservedVectors;
    102 
    103   ReservedVectors = ExceptionHandlerData->ReservedVectors;
    104   SystemContext.SystemContextIa32->Eflags        = ReservedVectors[ExceptionType].OldFlags;
    105   SystemContext.SystemContextIa32->Cs            = ReservedVectors[ExceptionType].OldCs;
    106   SystemContext.SystemContextIa32->Eip           = ReservedVectors[ExceptionType].OldIp;
    107   SystemContext.SystemContextIa32->ExceptionData = ReservedVectors[ExceptionType].ExceptionData;
    108 }
    109 
    110 /**
    111   Display CPU information.
    112 
    113   @param ExceptionType  Exception type.
    114   @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
    115 **/
    116 VOID
    117 DumpCpuContent (
    118   IN EFI_EXCEPTION_TYPE   ExceptionType,
    119   IN EFI_SYSTEM_CONTEXT   SystemContext
    120   )
    121 {
    122   UINTN                   ImageBase;
    123   UINTN                   EntryPoint;
    124 
    125   InternalPrintMessage (
    126     "!!!! IA32 Exception Type - %02x(%a)  CPU Apic ID - %08x !!!!\n",
    127     ExceptionType,
    128     GetExceptionNameStr (ExceptionType),
    129     GetApicId ()
    130     );
    131 
    132   InternalPrintMessage (
    133     "EIP  - %08x, CS  - %08x, EFLAGS - %08x\n",
    134     SystemContext.SystemContextIa32->Eip,
    135     SystemContext.SystemContextIa32->Cs,
    136     SystemContext.SystemContextIa32->Eflags
    137     );
    138   if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) {
    139     InternalPrintMessage (
    140       "ExceptionData - %08x\n",
    141       SystemContext.SystemContextIa32->ExceptionData
    142       );
    143   }
    144   InternalPrintMessage (
    145     "EAX  - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",
    146     SystemContext.SystemContextIa32->Eax,
    147     SystemContext.SystemContextIa32->Ecx,
    148     SystemContext.SystemContextIa32->Edx,
    149     SystemContext.SystemContextIa32->Ebx
    150     );
    151   InternalPrintMessage (
    152     "ESP  - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
    153     SystemContext.SystemContextIa32->Esp,
    154     SystemContext.SystemContextIa32->Ebp,
    155     SystemContext.SystemContextIa32->Esi,
    156     SystemContext.SystemContextIa32->Edi
    157     );
    158   InternalPrintMessage (
    159     "DS   - %08x, ES  - %08x, FS  - %08x, GS  - %08x, SS - %08x\n",
    160     SystemContext.SystemContextIa32->Ds,
    161     SystemContext.SystemContextIa32->Es,
    162     SystemContext.SystemContextIa32->Fs,
    163     SystemContext.SystemContextIa32->Gs,
    164     SystemContext.SystemContextIa32->Ss
    165     );
    166   InternalPrintMessage (
    167     "CR0  - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
    168     SystemContext.SystemContextIa32->Cr0,
    169     SystemContext.SystemContextIa32->Cr2,
    170     SystemContext.SystemContextIa32->Cr3,
    171     SystemContext.SystemContextIa32->Cr4
    172     );
    173   InternalPrintMessage (
    174     "DR0  - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
    175     SystemContext.SystemContextIa32->Dr0,
    176     SystemContext.SystemContextIa32->Dr1,
    177     SystemContext.SystemContextIa32->Dr2,
    178     SystemContext.SystemContextIa32->Dr3
    179     );
    180   InternalPrintMessage (
    181     "DR6  - %08x, DR7 - %08x\n",
    182     SystemContext.SystemContextIa32->Dr6,
    183     SystemContext.SystemContextIa32->Dr7
    184     );
    185   InternalPrintMessage (
    186     "GDTR - %08x %08x, IDTR - %08x %08x\n",
    187     SystemContext.SystemContextIa32->Gdtr[0],
    188     SystemContext.SystemContextIa32->Gdtr[1],
    189     SystemContext.SystemContextIa32->Idtr[0],
    190     SystemContext.SystemContextIa32->Idtr[1]
    191     );
    192   InternalPrintMessage (
    193     "LDTR - %08x, TR - %08x\n",
    194     SystemContext.SystemContextIa32->Ldtr,
    195     SystemContext.SystemContextIa32->Tr
    196     );
    197   InternalPrintMessage (
    198     "FXSAVE_STATE - %08x\n",
    199     &SystemContext.SystemContextIa32->FxSaveState
    200     );
    201 
    202   //
    203   // Find module image base and module entry point by RIP
    204   //
    205   ImageBase = FindModuleImageBase (SystemContext.SystemContextIa32->Eip, &EntryPoint);
    206   if (ImageBase != 0) {
    207     InternalPrintMessage (
    208       " (ImageBase=%08x, EntryPoint=%08x) !!!!\n",
    209       ImageBase,
    210       EntryPoint
    211       );
    212   }
    213 }
    214