/** Save the volatile registers required to be restored following INIT IPI. @param VolatileRegisters Returns buffer saved the volatile resisters **/ VOID SaveVolatileRegisters ( OUT CPU_VOLATILE_REGISTERS *VolatileRegisters ) { UINT32 RegEdx; VolatileRegisters->Cr0 = AsmReadCr0 (); VolatileRegisters->Cr3 = AsmReadCr3 (); VolatileRegisters->Cr4 = AsmReadCr4 (); AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx); if ((RegEdx & BIT2) != 0) { // // If processor supports Debugging Extensions feature // by CPUID.[EAX=01H]:EDX.BIT2 // VolatileRegisters->Dr0 = AsmReadDr0 (); VolatileRegisters->Dr1 = AsmReadDr1 (); VolatileRegisters->Dr2 = AsmReadDr2 (); VolatileRegisters->Dr3 = AsmReadDr3 (); VolatileRegisters->Dr6 = AsmReadDr6 (); VolatileRegisters->Dr7 = AsmReadDr7 (); } }
/** 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); }
/** Store debug register when SMI exit. **/ VOID SaveDebugRegister ( VOID ) { mSavedDebugRegisters[0] = AsmReadDr0 (); mSavedDebugRegisters[1] = AsmReadDr1 (); mSavedDebugRegisters[2] = AsmReadDr2 (); mSavedDebugRegisters[3] = AsmReadDr3 (); mSavedDebugRegisters[4] = AsmReadDr6 (); mSavedDebugRegisters[5] = AsmReadDr7 (); }