/** Trigger one software interrupt to debug agent to handle it. @param Signature Software interrupt signature. **/ VOID TriggerSoftInterrupt ( UINT32 Signature ) { UINTN Dr0; UINTN Dr1; // // Save Debug Register State // Dr0 = AsmReadDr0 (); Dr1 = AsmReadDr1 (); // // DR0 = Signature // AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE); AsmWriteDr1 (Signature); // // Do INT3 to communicate with HOST side // CpuBreakpoint (); // // Restore Debug Register State only when Host didn't change it inside exception handler. // Dr registers can only be changed by setting the HW breakpoint. // AsmWriteDr0 (Dr0); AsmWriteDr1 (Dr1); }
/** Restore the volatile registers following INIT IPI. @param VolatileRegisters Pointer to volatile resisters @param IsRestoreDr TRUE: Restore DRx if supported FALSE: Do not restore DRx **/ VOID RestoreVolatileRegisters ( IN CPU_VOLATILE_REGISTERS *VolatileRegisters, IN BOOLEAN IsRestoreDr ) { UINT32 RegEdx; AsmWriteCr0 (VolatileRegisters->Cr0); AsmWriteCr3 (VolatileRegisters->Cr3); AsmWriteCr4 (VolatileRegisters->Cr4); if (IsRestoreDr) { AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx); if ((RegEdx & BIT2) != 0) { // // If processor supports Debugging Extensions feature // by CPUID.[EAX=01H]:EDX.BIT2 // AsmWriteDr0 (VolatileRegisters->Dr0); AsmWriteDr1 (VolatileRegisters->Dr1); AsmWriteDr2 (VolatileRegisters->Dr2); AsmWriteDr3 (VolatileRegisters->Dr3); AsmWriteDr6 (VolatileRegisters->Dr6); AsmWriteDr7 (VolatileRegisters->Dr7); } } }
/** Restore debug register when SMI exit. **/ VOID RestoreDebugRegister ( VOID ) { AsmWriteDr7 (0); AsmWriteDr0 (mSavedDebugRegisters[0]); AsmWriteDr1 (mSavedDebugRegisters[1]); AsmWriteDr2 (mSavedDebugRegisters[2]); AsmWriteDr3 (mSavedDebugRegisters[3]); AsmWriteDr6 (mSavedDebugRegisters[4]); AsmWriteDr7 (mSavedDebugRegisters[5]); }