1. Define the transfer protocol revision mechanism. Increase the revision number to 0.2 and inform user to use the latest one when the HOST software is too old. New HOST software will implement logic to handle all other revision mismatch cases. 2. Define new debug message packet to print the debug agent trace information by debug port channel. 3. Add check sum mechanism in the communication protocol between TARGET/HOST. 4. Introduced one "try" mechanism to avoid Debug Agent crashed by some invalid HOST command. 5. Enable the late-attach feature: Change the break in from "!" to "\xFC". Add a new short symbol "\xFA" for attach and a new debug command for detach. 6. Support Terminal work on debug port by install EFI Serial IO protocol upon Debug Communication Library. 7. Enable CPUID feature. 8. Enable the hardware data breakpoint. 9. add handshake to improve usb debug cable identify stability issue. 10.Refine all the communication protocol packet to improve extensibility and debugging performance. a. Use 64bit for IO port address. b. Add additional Width field to READ_MEMORY/WRITE_MEMORY. c. Add SEARCH_SIGNATURE support to speed the symbol finding for late attach. d. Remove READ_GROUP register. e. Add READ_ALL_REGISTERS support (WinDbg always requests to read all registers). 11.Move AcquireDebugPortControl () in advance to fix resource collision on IpiSentByApFlag. 12.Fix IO break point does not work issue in PEI phase. 13.Avoid BSP/APs collision when they met break point at the same time. 14.Solve a bug of calculating debug handle in sec phase. 15.Use mailbox content at Dxe phase but not clear it and reinitialize again. 16.Fix FP/MMX/XMM/IO/MSR access issue in both Gdb and WinDbg. Signed-off-by: Jeff Fan <jeff.fan@intel.com> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Signed-off-by: Feng Tian <feng.tian@intel.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13437 6f19259b-4bc3-4df7-8a09-765794883524
176 lines
4.6 KiB
C
176 lines
4.6 KiB
C
/** @file
|
|
Debug Agent library implementition.
|
|
|
|
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php.
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include "SmmDebugAgentLib.h"
|
|
|
|
DEBUG_AGENT_MAILBOX *mMailboxPointer = NULL;
|
|
DEBUG_AGENT_MAILBOX mLocalMailbox;
|
|
UINTN mSavedDebugRegisters[6];
|
|
CONST BOOLEAN MultiProcessorDebugSupport = FALSE;
|
|
|
|
/**
|
|
Read the Attach/Break-in symbols from the debug port.
|
|
|
|
@param[in] Handle Pointer to Debug Port handle.
|
|
@param[out] BreakSymbol Returned break symbol.
|
|
|
|
@retval EFI_SUCCESS Read the symbol in BreakSymbol.
|
|
@retval EFI_NOT_FOUND No read the break symbol.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
DebugReadBreakSymbol (
|
|
IN DEBUG_PORT_HANDLE Handle,
|
|
OUT UINT8 *BreakSymbol
|
|
)
|
|
{
|
|
//
|
|
// Smm instance has no debug timer to poll break symbol.
|
|
//
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
/**
|
|
Get Debug Agent Mailbox pointer.
|
|
|
|
@return Mailbox pointer.
|
|
|
|
**/
|
|
DEBUG_AGENT_MAILBOX *
|
|
GetMailboxPointer (
|
|
VOID
|
|
)
|
|
{
|
|
return mMailboxPointer;
|
|
}
|
|
|
|
/**
|
|
Get debug port handle.
|
|
|
|
@return Debug port handle.
|
|
|
|
**/
|
|
DEBUG_PORT_HANDLE
|
|
GetDebugPortHandle (
|
|
VOID
|
|
)
|
|
{
|
|
return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
|
|
}
|
|
|
|
/**
|
|
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 ();
|
|
}
|
|
|
|
/**
|
|
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]);
|
|
}
|
|
|
|
/**
|
|
Initialize debug agent.
|
|
|
|
This function is used to set up debug enviroment for source level debug
|
|
in SMM code.
|
|
|
|
If InitFlag is DEBUG_AGENT_INIT_SMM, it will overirde IDT table entries
|
|
and initialize debug port. It will get debug agent Mailbox from GUIDed HOB,
|
|
it it exists, debug agent wiil copied it into the local Mailbox in SMM space.
|
|
it will overirde IDT table entries and initialize debug port. Context will be
|
|
NULL.
|
|
If InitFlag is DEBUG_AGENT_INIT_ENTER_SMI, debug agent will save Debug
|
|
Registers and get local Mailbox in SMM space. Context will be NULL.
|
|
If InitFlag is DEBUG_AGENT_INIT_EXIT_SMI, debug agent will restore Debug
|
|
Registers. Context will be NULL.
|
|
|
|
@param[in] InitFlag Init flag is used to decide initialize process.
|
|
@param[in] Context Context needed according to InitFlag.
|
|
@param[in] Function Continue function called by debug agent library; it was
|
|
optional.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
InitializeDebugAgent (
|
|
IN UINT32 InitFlag,
|
|
IN VOID *Context, OPTIONAL
|
|
IN DEBUG_AGENT_CONTINUE Function OPTIONAL
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT64 DebugPortHandle;
|
|
|
|
switch (InitFlag) {
|
|
case DEBUG_AGENT_INIT_SMM:
|
|
Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &mMailboxPointer);
|
|
if (EFI_ERROR (Status) || mMailboxPointer == NULL) {
|
|
ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
|
mMailboxPointer = &mLocalMailbox;
|
|
}
|
|
|
|
break;
|
|
|
|
case DEBUG_AGENT_INIT_ENTER_SMI:
|
|
SaveDebugRegister ();
|
|
InitializeDebugIdt ();
|
|
|
|
if (mMailboxPointer != NULL) {
|
|
//
|
|
// Initialize debug communication port
|
|
//
|
|
DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)mMailboxPointer->DebugPortHandle, NULL);
|
|
mMailboxPointer->DebugPortHandle = DebugPortHandle;
|
|
|
|
if (mMailboxPointer->DebugFlag.BreakOnNextSmi == 1) {
|
|
//
|
|
// If SMM entry break is set, SMM code will be break at here.
|
|
//
|
|
CpuBreakpoint ();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DEBUG_AGENT_INIT_EXIT_SMI:
|
|
RestoreDebugRegister ();
|
|
break;
|
|
}
|
|
}
|
|
|