Example #1
0
static DWORD WINAPI EmulateGetCurrentProcessorNumber(VOID)
{
	const ApicId apicId = GetApicId();
	const DWORD processor = (DWORD)ProcessorFromApicId(apicId);
	ASSERT(processor < os_cpu_MaxProcessors);
	return processor;
}
Example #2
0
/**
  This return the handle number for the calling processor.

  @param[in] This                 A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
  @param[out] ProcessorNumber      The handle number of currently executing processor.

  @retval EFI_SUCCESS             The current processor handle number was returned
                                  in ProcessorNumber.
  @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.

**/
EFI_STATUS
EFIAPI
SmmWhoAmI (
  IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
  OUT      UINTN                        *ProcessorNumber
  )
{
  UINTN  Index;
  UINT64 ApicId;

  //
  // Check parameter
  //
  if (ProcessorNumber == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ApicId = GetApicId ();

  for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
    if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) {
      *ProcessorNumber = Index;
      return EFI_SUCCESS;
    }
  }
  //
  // This should not happen
  //
  ASSERT (FALSE);
  return EFI_NOT_FOUND;
}
Example #3
0
/**
  Get the current processor's index.

  @return Processor index value.

**/
UINT32
GetProcessorIndex (
  VOID
  )
{
  UINT32                Index;
  UINT16                LocalApicID;

  LocalApicID = (UINT16) GetApicId ();

  AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);

  for (Index = 0; Index < mDebugCpuData.CpuCount; Index ++) {
    if (mDebugCpuData.ApicID[Index] == LocalApicID) {
      break;
    }
  }

  if (Index == mDebugCpuData.CpuCount) {
    mDebugCpuData.ApicID[Index] = LocalApicID;
    mDebugCpuData.CpuCount ++ ;
  }

  ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);

  return Index;
}
Example #4
0
/**
  Configures an I/O APIC interrupt.
  
  Configure an I/O APIC Redirection Table Entry to deliver an interrupt in physical
  mode to the Local APIC of the currntly executing CPU.  The default state of the 
  entry is for the interrupt to be disabled (masked).  IoApicEnableInterrupts() must
  be used to enable(unmask) the I/O APIC Interrupt.
 
  If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). 
  If Vector >= 0x100, then ASSERT().
  If DeliveryMode is not supported, then ASSERT().

  @param  Irq             Specifies the I/O APIC interrupt to initialize.
  @param  Vector          The 8-bit interrupt vector associated with the I/O APIC
                          Interrupt.  Must be in the range 0x10..0xFE.
  @param  DeliveryMode    A 3-bit value that specifies how the recept of the I/O APIC
                          interrupt is handled.  The only supported values are:
                            0: IO_APIC_DELIVERY_MODE_FIXED
                            1: IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY
                            2: IO_APIC_DELIVERY_MODE_SMI
                            4: IO_APIC_DELIVERY_MODE_NMI
                            5: IO_APIC_DELIVERY_MODE_INIT
                            7: IO_APIC_DELIVERY_MODE_EXTINT
  @param  LevelTriggered  TRUE specifies a level triggered interrupt.
                          FALSE specifies an edge triggered interrupt.
  @param  AssertionLevel  TRUE specified an active high interrupt.
                          FALSE specifies an active low interrupt.
**/
VOID
EFIAPI
IoApicConfigureInterrupt (
  IN UINTN    Irq,
  IN UINTN    Vector,
  IN UINTN    DeliveryMode,
  IN BOOLEAN  LevelTriggered,
  IN BOOLEAN  AssertionLevel
  )
{
  IO_APIC_VERSION_REGISTER         Version;
  IO_APIC_REDIRECTION_TABLE_ENTRY  Entry;

  Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX);
  ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0);
  ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry);
  ASSERT (Vector <= 0xFF);
  ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3);
  
  Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2);
  Entry.Bits.Vector          = (UINT8)Vector;
  Entry.Bits.DeliveryMode    = (UINT32)DeliveryMode;
  Entry.Bits.DestinationMode = 0; 
  Entry.Bits.Polarity        = AssertionLevel ? 0 : 1;
  Entry.Bits.TriggerMode     = LevelTriggered ? 1 : 0;
  Entry.Bits.Mask            = 1;
  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low);

  Entry.Uint32.High = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1);
  Entry.Bits.DestinationID = GetApicId ();
  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1, Entry.Uint32.High);
}
Example #5
0
/**
  C function for SMI handler. To change all processor's SMMBase Register.

**/
VOID
EFIAPI
SmmInitHandler (
  VOID
  )
{
  UINT32                            ApicId;
  UINTN                             Index;

  //
  // Update SMM IDT entries' code segment and load IDT
  //
  AsmWriteIdtr (&gcSmiIdtr);
  ApicId = GetApicId ();

  ASSERT (mNumberOfCpus <= mMaxNumberOfCpus);

  for (Index = 0; Index < mNumberOfCpus; Index++) {
    if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) {
      //
      // Initialize SMM specific features on the currently executing CPU
      //
      SmmCpuFeaturesInitializeProcessor (
        Index,
        mIsBsp,
        gSmmCpuPrivate->ProcessorInfo,
        &mCpuHotPlugData
        );

      if (!mSmmS3Flag) {
        //
        // Check XD and BTS features on each processor on normal boot
        //
        CheckFeatureSupported ();
      }

      if (mIsBsp) {
        //
        // BSP rebase is already done above.
        // Initialize private data during S3 resume
        //
        InitializeMpSyncData ();
      }

      //
      // Hook return after RSM to set SMM re-based flag
      //
      SemaphoreHook (Index, &mRebased[Index]);

      return;
    }
  }
  ASSERT (FALSE);
}
Example #6
0
/**
  Get CPU Index from APIC ID.

**/
UINTN
GetCpuIndex (
  VOID
  )
{
  UINTN     Index;
  UINT32    ApicId;

  ApicId = GetApicId ();

  for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
    if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) {
      return Index;
    }
  }
  ASSERT (FALSE);
  return 0;
}
Example #7
0
/**
  Get CPU Index from APIC ID.

**/
UINTN
GetCpuIndex (
  VOID
  )
{
  UINTN     Index;
  UINT32    ApicId;

  ApicId = GetApicId ();

  for (Index = 0; Index < PcdGet32 (PcdCpuMaxLogicalProcessorNumber); Index++) {
    if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) {
      return Index;
    }
  }
  ASSERT (FALSE);
  return 0;
}
Example #8
0
/**
 *
 * Run code on every AP in the system.
 *
 * @param[in] ApParams       AP task pointer.
 * @param[in] StdHeader      Handle to config for library and services
 *
 * @return    The most severe AGESA_STATUS returned by an AP.
 *
 */
AGESA_STATUS
RunLateApTaskOnAllAPs (
  IN       AP_EXE_PARAMS     *ApParams,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32                  NumberOfSockets;
  UINT32                  NumberOfCores;
  UINT8                   Socket;
  UINT8                   Core;
  UINT8                   ApicId;
  UINT32                  BscSocket;
  UINT32                  Ignored;
  UINT32                  BscCoreNum;
  AGESA_STATUS            CalledStatus;
  AGESA_STATUS            IgnoredStatus;
  AGESA_STATUS            AgesaStatus;

  ASSERT (IsBsp (StdHeader, &IgnoredStatus));

  AgesaStatus = AGESA_SUCCESS;

  IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredStatus);
  NumberOfSockets = GetPlatformNumberOfSockets ();

  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
      for (Core = 0; Core < NumberOfCores; Core++) {
        if ((Socket != BscSocket) || (Core != BscCoreNum)) {
          GetApicId (StdHeader, Socket, Core, &ApicId, &IgnoredStatus);
          AGESA_TESTPOINT (TpIfBeforeRunApFromAllAps, StdHeader);
          CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams);
          AGESA_TESTPOINT (TpIfAfterRunApFromAllAps, StdHeader);
          if (CalledStatus > AgesaStatus) {
            AgesaStatus = CalledStatus;
          }
        }
      }
    }
  }
  return AgesaStatus;
}
Example #9
0
/**
 *
 * Run code on core 0 of every socket in the system.
 *
 * @param[in] ApParams       AP task pointer.
 * @param[in] StdHeader      Handle to config for library and services
 *
 * @return    The most severe AGESA_STATUS returned by an AP.
 *
 */
AGESA_STATUS
RunLateApTaskOnAllCore0s (
  IN       AP_EXE_PARAMS     *ApParams,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32                  NumberOfSockets;
  UINT8                   Socket;
  UINT8                   ApicId;
  UINT32                  BscSocket;
  UINT32                  IgnoredModule;
  UINT32                  IgnoredCore;
  AGESA_STATUS            CalledStatus;
  AGESA_STATUS            IgnoredStatus;
  AGESA_STATUS            AgesaStatus;

  ASSERT (IsBsp (StdHeader, &IgnoredStatus));

  AgesaStatus = AGESA_SUCCESS;

  IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &IgnoredCore, &IgnoredStatus);
  NumberOfSockets = GetPlatformNumberOfSockets ();

  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {
      if (Socket != BscSocket) {
        GetApicId (StdHeader, Socket, 0, &ApicId, &IgnoredStatus);
        AGESA_TESTPOINT (TpIfBeforeRunApFromAllCore0s, StdHeader);
        CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams);
        AGESA_TESTPOINT (TpIfAfterRunApFromAllCore0s, StdHeader);
        if (CalledStatus > AgesaStatus) {
          AgesaStatus = CalledStatus;
        }
      }
    }
  }
  return AgesaStatus;
}
Example #10
0
/**
  Relocate SmmBases for each processor.

  Execute on first boot and all S3 resumes

**/
VOID
EFIAPI
SmmRelocateBases (
  VOID
  )
{
  UINT8                 BakBuf[BACK_BUF_SIZE];
  SMRAM_SAVE_STATE_MAP  BakBuf2;
  SMRAM_SAVE_STATE_MAP  *CpuStatePtr;
  UINT8                 *U8Ptr;
  UINT32                ApicId;
  UINTN                 Index;
  UINTN                 BspIndex;

  //
  // Make sure the reserved size is large enough for procedure SmmInitTemplate.
  //
  ASSERT (sizeof (BakBuf) >= gcSmmInitSize);

  //
  // Patch ASM code template with current CR0, CR3, and CR4 values
  //
  gSmmCr0 = (UINT32)AsmReadCr0 ();
  gSmmCr3 = (UINT32)AsmReadCr3 ();
  gSmmCr4 = (UINT32)AsmReadCr4 ();

  //
  // Patch GDTR for SMM base relocation
  //
  gcSmiInitGdtr.Base  = gcSmiGdtr.Base;
  gcSmiInitGdtr.Limit = gcSmiGdtr.Limit;

  U8Ptr = (UINT8*)(UINTN)(SMM_DEFAULT_SMBASE + SMM_HANDLER_OFFSET);
  CpuStatePtr = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);

  //
  // Backup original contents at address 0x38000
  //
  CopyMem (BakBuf, U8Ptr, sizeof (BakBuf));
  CopyMem (&BakBuf2, CpuStatePtr, sizeof (BakBuf2));

  //
  // Load image for relocation
  //
  CopyMem (U8Ptr, gcSmmInitTemplate, gcSmmInitSize);

  //
  // Retrieve the local APIC ID of current processor
  //
  ApicId = GetApicId ();

  //
  // Relocate SM bases for all APs
  // This is APs' 1st SMI - rebase will be done here, and APs' default SMI handler will be overridden by gcSmmInitTemplate
  //
  mIsBsp   = FALSE;
  BspIndex = (UINTN)-1;
  for (Index = 0; Index < mNumberOfCpus; Index++) {
    mRebased[Index] = FALSE;
    if (ApicId != (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) {
      SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId);
      //
      // Wait for this AP to finish its 1st SMI
      //
      while (!mRebased[Index]);
    } else {
      //
      // BSP will be Relocated later
      //
      BspIndex = Index;
    }
  }

  //
  // Relocate BSP's SMM base
  //
  ASSERT (BspIndex != (UINTN)-1);
  mIsBsp = TRUE;
  SendSmiIpi (ApicId);
  //
  // Wait for the BSP to finish its 1st SMI
  //
  while (!mRebased[BspIndex]);

  //
  // Restore contents at address 0x38000
  //
  CopyMem (CpuStatePtr, &BakBuf2, sizeof (BakBuf2));
  CopyMem (U8Ptr, BakBuf, sizeof (BakBuf));
}
Example #11
0
/**
  The Page fault handler to save SMM profile data.

  @param  Rip        The RIP when exception happens.
  @param  ErrorCode  The Error code of exception.

**/
VOID
SmmProfilePFHandler (
  UINTN Rip,
  UINTN ErrorCode
  )
{
  UINT64                *PageTable;
  UINT64                PFAddress;
  UINTN                 CpuIndex;
  UINTN                 Index;
  UINT64                InstructionAddress;
  UINTN                 MaxEntryNumber;
  UINTN                 CurrentEntryNumber;
  BOOLEAN               IsValidPFAddress;
  SMM_PROFILE_ENTRY     *SmmProfileEntry;
  UINT64                SmiCommand;
  EFI_STATUS            Status;
  UINT8                 SoftSmiValue;
  EFI_SMM_SAVE_STATE_IO_INFO    IoInfo;

  if (!mSmmProfileStart) {
    //
    // If SMM profile does not start, call original page fault handler.
    //
    SmiDefaultPFHandler ();
    return;
  }

  if (mBtsSupported) {
    DisableBTS ();
  }

  IsValidPFAddress  = FALSE;
  PageTable         = (UINT64 *)AsmReadCr3 ();
  PFAddress         = AsmReadCr2 ();
  CpuIndex          = GetCpuIndex ();

  if (PFAddress <= 0xFFFFFFFF) {
    RestorePageTableBelow4G (PageTable, PFAddress, CpuIndex, ErrorCode);
  } else {
    RestorePageTableAbove4G (PageTable, PFAddress, CpuIndex, ErrorCode, &IsValidPFAddress);
  }

  if (!IsValidPFAddress) {
    InstructionAddress = Rip;
    if ((ErrorCode & IA32_PF_EC_ID) != 0 && (mBtsSupported)) {
      //
      // If it is instruction fetch failure, get the correct IP from BTS.
      //
      InstructionAddress = GetSourceFromDestinationOnBts (CpuIndex, Rip);
      if (InstructionAddress == 0) {
        //
        // It indicates the instruction which caused page fault is not a jump instruction,
        // set instruction address same as the page fault address.
        //
        InstructionAddress = PFAddress;
      }
    }

    //
    // Indicate it is not software SMI
    //
    SmiCommand    = 0xFFFFFFFFFFFFFFFFULL;
    for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
      Status = SmmReadSaveState(&mSmmCpu, sizeof(IoInfo), EFI_SMM_SAVE_STATE_REGISTER_IO, Index, &IoInfo);
      if (EFI_ERROR (Status)) {
        continue;
      }
      if (IoInfo.IoPort == mSmiCommandPort) {
        //
        // A software SMI triggered by SMI command port has been found, get SmiCommand from SMI command port.
        //
        SoftSmiValue = IoRead8 (mSmiCommandPort);
        SmiCommand = (UINT64)SoftSmiValue;
        break;
      }
    }

    SmmProfileEntry = (SMM_PROFILE_ENTRY *)(UINTN)(mSmmProfileBase + 1);
    //
    // Check if there is already a same entry in profile data.
    //
    for (Index = 0; Index < (UINTN) mSmmProfileBase->CurDataEntries; Index++) {
      if ((SmmProfileEntry[Index].ErrorCode   == (UINT64)ErrorCode) &&
          (SmmProfileEntry[Index].Address     == PFAddress) &&
          (SmmProfileEntry[Index].CpuNum      == (UINT64)CpuIndex) &&
          (SmmProfileEntry[Index].Instruction == InstructionAddress) &&
          (SmmProfileEntry[Index].SmiCmd      == SmiCommand)) {
        //
        // Same record exist, need not save again.
        //
        break;
      }
    }
    if (Index == mSmmProfileBase->CurDataEntries) {
      CurrentEntryNumber = (UINTN) mSmmProfileBase->CurDataEntries;
      MaxEntryNumber     = (UINTN) mSmmProfileBase->MaxDataEntries;
      if (FeaturePcdGet (PcdCpuSmmProfileRingBuffer)) {
        CurrentEntryNumber = CurrentEntryNumber % MaxEntryNumber;
      }
      if (CurrentEntryNumber < MaxEntryNumber) {
        //
        // Log the new entry
        //
        SmmProfileEntry[CurrentEntryNumber].SmiNum      = mSmmProfileBase->NumSmis;
        SmmProfileEntry[CurrentEntryNumber].ErrorCode   = (UINT64)ErrorCode;
        SmmProfileEntry[CurrentEntryNumber].ApicId      = (UINT64)GetApicId ();
        SmmProfileEntry[CurrentEntryNumber].CpuNum      = (UINT64)CpuIndex;
        SmmProfileEntry[CurrentEntryNumber].Address     = PFAddress;
        SmmProfileEntry[CurrentEntryNumber].Instruction = InstructionAddress;
        SmmProfileEntry[CurrentEntryNumber].SmiCmd      = SmiCommand;
        //
        // Update current entry index and data size in the header.
        //
        mSmmProfileBase->CurDataEntries++;
        mSmmProfileBase->CurDataSize = MultU64x64 (mSmmProfileBase->CurDataEntries, sizeof (SMM_PROFILE_ENTRY));
      }
    }
  }
  //
  // Flush TLB
  //
  CpuFlushTlb ();

  if (mBtsSupported) {
    EnableBTS ();
  }
}
Example #12
0
/**
  Display CPU information.

  @param ExceptionType  Exception type.
  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
**/
VOID
DumpCpuContent (
  IN EFI_EXCEPTION_TYPE   ExceptionType,
  IN EFI_SYSTEM_CONTEXT   SystemContext
  )
{
  UINTN                   ImageBase;
  UINTN                   EntryPoint;

  InternalPrintMessage (
    "!!!! IA32 Exception Type - %08x    CPU Apic ID - %08x !!!!\n",
    ExceptionType,
    GetApicId ()
    );
  InternalPrintMessage (
    "EIP  - %08x, CS  - %08x, EFLAGS - %08x\n",
    SystemContext.SystemContextIa32->Eip,
    SystemContext.SystemContextIa32->Cs,
    SystemContext.SystemContextIa32->Eflags
    );
  if ((mErrorCodeFlag & (1 << ExceptionType)) != 0) {
    InternalPrintMessage (
      "ExceptionData - %08x\n",
      SystemContext.SystemContextIa32->ExceptionData
      );
  }
  InternalPrintMessage (
    "EAX  - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",
    SystemContext.SystemContextIa32->Eax,
    SystemContext.SystemContextIa32->Ecx,
    SystemContext.SystemContextIa32->Edx,
    SystemContext.SystemContextIa32->Ebx
    );
  InternalPrintMessage (
    "ESP  - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
    SystemContext.SystemContextIa32->Esp,
    SystemContext.SystemContextIa32->Ebp,
    SystemContext.SystemContextIa32->Esi,
    SystemContext.SystemContextIa32->Edi
    );
  InternalPrintMessage (
    "DS   - %08x, ES  - %08x, FS  - %08x, GS  - %08x, SS - %08x\n",
    SystemContext.SystemContextIa32->Ds,
    SystemContext.SystemContextIa32->Es,
    SystemContext.SystemContextIa32->Fs,
    SystemContext.SystemContextIa32->Gs,
    SystemContext.SystemContextIa32->Ss
    );
  InternalPrintMessage (
    "CR0  - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
    SystemContext.SystemContextIa32->Cr0,
    SystemContext.SystemContextIa32->Cr2,
    SystemContext.SystemContextIa32->Cr3,
    SystemContext.SystemContextIa32->Cr4
    );
  InternalPrintMessage (
    "DR0  - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
    SystemContext.SystemContextIa32->Dr0,
    SystemContext.SystemContextIa32->Dr1,
    SystemContext.SystemContextIa32->Dr2,
    SystemContext.SystemContextIa32->Dr3
    );
  InternalPrintMessage (
    "DR6  - %08x, DR7 - %08x\n",
    SystemContext.SystemContextIa32->Dr6,
    SystemContext.SystemContextIa32->Dr7
    );
  InternalPrintMessage (
    "GDTR - %08x %08x, IDTR - %08x %08x\n",
    SystemContext.SystemContextIa32->Gdtr[0],
    SystemContext.SystemContextIa32->Gdtr[1],
    SystemContext.SystemContextIa32->Idtr[0],
    SystemContext.SystemContextIa32->Idtr[1]
    );
  InternalPrintMessage (
    "LDTR - %08x, TR - %08x\n",
    SystemContext.SystemContextIa32->Ldtr,
    SystemContext.SystemContextIa32->Tr
    );
  InternalPrintMessage (
    "FXSAVE_STATE - %08x\n",
    &SystemContext.SystemContextIa32->FxSaveState
    );

  //
  // Find module image base and module entry point by RIP
  //
  ImageBase = FindModuleImageBase (SystemContext.SystemContextIa32->Eip, &EntryPoint);
  if (ImageBase != 0) {
    InternalPrintMessage (
      " (ImageBase=%08x, EntryPoint=%08x) !!!!\n",
      ImageBase,
      EntryPoint
      );
  }
}
/**
  Display CPU information.

  @param ExceptionType  Exception type.
  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
**/
VOID
DumpCpuContent (
  IN EFI_EXCEPTION_TYPE   ExceptionType,
  IN EFI_SYSTEM_CONTEXT   SystemContext
  )
{
  UINTN                   ImageBase;
  UINTN                   EntryPoint;

  InternalPrintMessage (
    "!!!! X64 Exception Type - %016lx     CPU Apic ID - %08x !!!!\n",
    ExceptionType,
    GetApicId ()
    );
  InternalPrintMessage (
    "RIP  - %016lx, CS  - %016lx, RFLAGS - %016lx\n",
    SystemContext.SystemContextX64->Rip,
    SystemContext.SystemContextX64->Cs,
    SystemContext.SystemContextX64->Rflags
    );
  if (mErrorCodeFlag & (1 << ExceptionType)) {
    InternalPrintMessage (
      "ExceptionData - %016lx\n",
      SystemContext.SystemContextX64->ExceptionData
      );
  }
  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
    );

  //
  // Find module image base and module entry point by RIP
  //
  ImageBase = FindModuleImageBase (SystemContext.SystemContextX64->Rip, &EntryPoint);
  if (ImageBase != 0) {
    InternalPrintMessage (
      " (ImageBase=%016lx, EntryPoint=%016lx) !!!!\n",
      ImageBase,
      EntryPoint
      );
  }
}
Example #14
0
/**
  Internal worker function for common exception handler.

  @param ExceptionType         Exception type.
  @param SystemContext         Pointer to EFI_SYSTEM_CONTEXT.
  @param ExceptionHandlerData  Pointer to exception handler data.
**/
VOID
CommonExceptionHandlerWorker (
  IN EFI_EXCEPTION_TYPE          ExceptionType, 
  IN EFI_SYSTEM_CONTEXT          SystemContext,
  IN EXCEPTION_HANDLER_DATA      *ExceptionHandlerData
  )
{
  EXCEPTION_HANDLER_CONTEXT      *ExceptionHandlerContext;
  RESERVED_VECTORS_DATA          *ReservedVectors;
  EFI_CPU_INTERRUPT_HANDLER      *ExternalInterruptHandler;

  ExceptionHandlerContext  = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32);
  ReservedVectors          = ExceptionHandlerData->ReservedVectors;
  ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler;

  switch (ReservedVectors[ExceptionType].Attribute) {
  case EFI_VECTOR_HANDOFF_HOOK_BEFORE:
    //
    // Need to jmp to old IDT handler after this exception handler
    //
    ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
    ExceptionHandlerContext->OldIdtHandler     = ReservedVectors[ExceptionType].ExceptonHandler;
    break;
  case EFI_VECTOR_HANDOFF_HOOK_AFTER:
    while (TRUE) {
      //
      // If if anyone has gotten SPIN_LOCK for owner running hook after
      //
      if (AcquireSpinLockOrFail (&ReservedVectors[ExceptionType].SpinLock)) {
        //
        // Need to execute old IDT handler before running this exception handler
        //
        ReservedVectors[ExceptionType].ApicId = GetApicId ();
        ArchSaveExceptionContext (ExceptionType, SystemContext, ExceptionHandlerData);
        ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
        ExceptionHandlerContext->OldIdtHandler     = ReservedVectors[ExceptionType].ExceptonHandler;
        return;
      }
      //
      // If failed to acquire SPIN_LOCK, check if it was locked by processor itself
      //
      if (ReservedVectors[ExceptionType].ApicId == GetApicId ()) {
        //
        // Old IDT handler has been executed, then restore CPU exception content to
        // run new exception handler.
        //
        ArchRestoreExceptionContext (ExceptionType, SystemContext, ExceptionHandlerData);
        //
        // Rlease spin lock for ApicId
        //
        ReleaseSpinLock (&ReservedVectors[ExceptionType].SpinLock);
        break;
      }
      CpuPause ();
    }
    break;
  case 0xffffffff:
    break;
  default:
    //
    // It should never reach here
    //
    CpuDeadLoop ();
    break;
  }
  
  if (ExternalInterruptHandler != NULL &&
      ExternalInterruptHandler[ExceptionType] != NULL) {
    (ExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext);
  } else if (ExceptionType < CPU_EXCEPTION_NUM) {
    //
    // Get Spinlock to display CPU information
    //
    while (!AcquireSpinLockOrFail (&ExceptionHandlerData->DisplayMessageSpinLock)) {
      CpuPause ();
    }
    //
    // Display ExceptionType, CPU information and Image information
    //  
    DumpCpuContent (ExceptionType, SystemContext);
    //
    // Release Spinlock of output message
    //
    ReleaseSpinLock (&ExceptionHandlerData->DisplayMessageSpinLock);
    //
    // Enter a dead loop if needn't to execute old IDT handler further
    //
    if (ReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) {
      CpuDeadLoop ();
    }
  }
}