| /** @file | |
| Command header of for Debug Agent library instance. | |
| Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #ifndef _DEBUG_AGENT_H_ | |
| #define _DEBUG_AGENT_H_ | |
| #include <Register/LocalApic.h> | |
| #include <Guid/DebugAgentGuid.h> | |
| #include <Guid/VectorHandoffTable.h> | |
| #include <Ppi/VectorHandoffInfo.h> | |
| #include <Library/BaseLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/ResetSystemLib.h> | |
| #include <Library/IoLib.h> | |
| #include <Library/HobLib.h> | |
| #include <Library/DebugCommunicationLib.h> | |
| #include <Library/DebugAgentLib.h> | |
| #include <Library/PcdLib.h> | |
| #include <Library/SynchronizationLib.h> | |
| #include <Library/LocalApicLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/TimerLib.h> | |
| #include <Library/PrintLib.h> | |
| #include <Library/PeCoffGetEntryPointLib.h> | |
| #include <Library/PeCoffExtraActionLib.h> | |
| #include <Register/ArchitecturalMsr.h> | |
| #include <TransferProtocol.h> | |
| #include <ImageDebugSupport.h> | |
| #include "DebugMp.h" | |
| #include "DebugTimer.h" | |
| #include "ArchDebugSupport.h" | |
| #include "DebugException.h" | |
| // | |
| // These macros may be already defined in DebugAgentLib.h | |
| // | |
| #define DEBUG_AGENT_INIT_PEI 9 | |
| #define DEBUG_AGENT_INIT_DXE_LOAD 10 | |
| #define DEBUG_AGENT_INIT_DXE_UNLOAD 11 | |
| #define DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64 12 | |
| #define DEBUG_INT1_VECTOR DEBUG_EXCEPT_DEBUG | |
| #define DEBUG_INT3_VECTOR DEBUG_EXCEPT_BREAKPOINT | |
| #define DEBUG_TIMER_VECTOR 32 | |
| #define DEBUG_MAILBOX_VECTOR 33 | |
| // | |
| // Timeout value for reading packet (unit is microsecond) | |
| // | |
| #define READ_PACKET_TIMEOUT (500 * 1000) | |
| #define DEBUG_TIMER_INTERVAL (100 * 1000) | |
| #define SOFT_INTERRUPT_SIGNATURE SIGNATURE_32('S','O','F','T') | |
| #define SYSTEM_RESET_SIGNATURE SIGNATURE_32('S','Y','S','R') | |
| #define MEMORY_READY_SIGNATURE SIGNATURE_32('M','E','M','R') | |
| extern UINTN Exception0Handle; | |
| extern UINTN TimerInterruptHandle; | |
| extern UINT32 ExceptionStubHeaderSize; | |
| extern BOOLEAN mSkipBreakpoint; | |
| extern EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[]; | |
| extern UINTN mVectorHandoffInfoCount; | |
| // | |
| // CPU exception information issued by debug agent | |
| // | |
| typedef struct { | |
| // | |
| // This field is used to save CPU content before executing HOST command | |
| // | |
| BASE_LIBRARY_JUMP_BUFFER JumpBuffer; | |
| // | |
| // This field returns the exception information issued by the HOST command | |
| // | |
| DEBUG_DATA_RESPONSE_GET_EXCEPTION ExceptionContent; | |
| } DEBUG_AGENT_EXCEPTION_BUFFER; | |
| #define DEBUG_AGENT_FLAG_HOST_ATTACHED BIT0 | |
| #define DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS BIT1 | |
| #define DEBUG_AGENT_FLAG_MEMORY_READY BIT2 | |
| #define DEBUG_AGENT_FLAG_STEPPING BIT3 | |
| #define DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB BIT4 | |
| #define DEBUG_AGENT_FLAG_INIT_ARCH BIT5|BIT6 | |
| #define DEBUG_AGENT_FLAG_INTERRUPT_FLAG BIT7 | |
| #define DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI BIT32 | |
| #define DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL (BIT33|BIT34|BIT35|BIT36) | |
| #define DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT BIT37 | |
| #define DEBUG_MAILBOX_DEBUG_FLAG_INDEX 1 | |
| #define DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX 2 | |
| #define DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX 3 | |
| #define DEBUG_MAILBOX_LAST_ACK 4 | |
| #define DEBUG_MAILBOX_SEQUENCE_NO_INDEX 5 | |
| #define DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX 6 | |
| #define DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY 7 | |
| #pragma pack(1) | |
| typedef union { | |
| struct { | |
| // | |
| // Lower 32 bits to store the status of DebugAgent | |
| // | |
| UINT32 HostAttached : 1; // 1: HOST is attached | |
| UINT32 AgentInProgress : 1; // 1: Debug Agent is communicating with HOST | |
| UINT32 MemoryReady : 1; // 1: Memory is ready | |
| UINT32 SteppingFlag : 1; // 1: Agent is running stepping command | |
| UINT32 CheckMailboxInHob : 1; // 1: Need to check mailbox saved in HOB | |
| UINT32 InitArch : 2; // value of DEBUG_DATA_RESPONSE_ARCH_MODE | |
| UINT32 InterruptFlag : 1; // 1: EFLAGS.IF is set | |
| UINT32 Reserved1 : 24; | |
| // | |
| // Higher 32bits to control the behavior of DebugAgent | |
| // | |
| UINT32 BreakOnNextSmi : 1; // 1: Break on next SMI | |
| UINT32 PrintErrorLevel : 4; // Bitmask of print error level for debug message | |
| UINT32 BreakOnBootScript : 1; // 1: Break before executing boot script | |
| UINT32 Reserved2 : 26; | |
| } Bits; | |
| UINT64 Uint64; | |
| } DEBUG_AGENT_FLAG; | |
| typedef struct { | |
| DEBUG_AGENT_FLAG DebugFlag; | |
| UINT64 DebugPortHandle; | |
| // | |
| // Pointer to DEBUG_AGENT_EXCEPTION_BUFFER | |
| // | |
| UINT64 ExceptionBufferPointer; | |
| UINT8 LastAck; // The last ack packet type | |
| UINT8 SequenceNo; | |
| UINT8 HostSequenceNo; | |
| UINT32 DebugTimerFrequency; | |
| UINT8 CheckSum; // Mailbox checksum | |
| UINT8 ToBeCheckSum; // To be Mailbox checksum at the next | |
| } DEBUG_AGENT_MAILBOX; | |
| #pragma pack() | |
| /// | |
| /// Byte packed structure for an IA-32 Interrupt Gate Descriptor. | |
| /// | |
| typedef union { | |
| struct { | |
| UINT32 OffsetLow : 16; ///< Offset bits 15..0. | |
| UINT32 Selector : 16; ///< Selector. | |
| UINT32 Reserved_0 : 8; ///< Reserved. | |
| UINT32 GateType : 8; ///< Gate Type. See #defines above. | |
| UINT32 OffsetHigh : 16; ///< Offset bits 31..16. | |
| } Bits; | |
| UINT64 Uint64; | |
| } IA32_IDT_ENTRY; | |
| typedef union { | |
| struct { | |
| UINT32 LimitLow : 16; | |
| UINT32 BaseLow : 16; | |
| UINT32 BaseMid : 8; | |
| UINT32 Type : 4; | |
| UINT32 System : 1; | |
| UINT32 Dpl : 2; | |
| UINT32 Present : 1; | |
| UINT32 LimitHigh : 4; | |
| UINT32 Software : 1; | |
| UINT32 Reserved : 1; | |
| UINT32 DefaultSize : 1; | |
| UINT32 Granularity : 1; | |
| UINT32 BaseHigh : 8; | |
| } Bits; | |
| UINT64 Uint64; | |
| } IA32_GDT; | |
| /** | |
| Initialize IDT entries to support source level debug. | |
| **/ | |
| VOID | |
| InitializeDebugIdt ( | |
| VOID | |
| ); | |
| /** | |
| Read register value from saved CPU context. | |
| @param[in] CpuContext Pointer to saved CPU context. | |
| @param[in] Index Register index value. | |
| @param[in] Width Data width to read. | |
| @return The address of register value. | |
| **/ | |
| UINT8 * | |
| ArchReadRegisterBuffer ( | |
| IN DEBUG_CPU_CONTEXT *CpuContext, | |
| IN UINT8 Index, | |
| IN UINT8 *Width | |
| ); | |
| /** | |
| Send packet with response data to HOST. | |
| @param[in] Data Pointer to response data buffer. | |
| @param[in] DataSize Size of response data in byte. | |
| @param[in, out] DebugHeader Pointer to a buffer for creating response packet and receiving ACK packet, | |
| to minimize the stack usage. | |
| @retval RETURN_SUCCESS Response data was sent successfully. | |
| @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST. | |
| **/ | |
| RETURN_STATUS | |
| SendDataResponsePacket ( | |
| IN UINT8 *Data, | |
| IN UINT16 DataSize, | |
| IN OUT DEBUG_PACKET_HEADER *DebugHeader | |
| ); | |
| /** | |
| Check if HOST is attached based on Mailbox. | |
| @retval TRUE HOST is attached. | |
| @retval FALSE HOST is not attached. | |
| **/ | |
| BOOLEAN | |
| IsHostAttached ( | |
| VOID | |
| ); | |
| /** | |
| Get Debug Agent Mailbox pointer. | |
| @return Mailbox pointer. | |
| **/ | |
| DEBUG_AGENT_MAILBOX * | |
| GetMailboxPointer ( | |
| VOID | |
| ); | |
| /** | |
| Get debug port handle. | |
| @return Debug port handle. | |
| **/ | |
| DEBUG_PORT_HANDLE | |
| GetDebugPortHandle ( | |
| VOID | |
| ); | |
| /** | |
| 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 | |
| ); | |
| /** | |
| Prints a debug message to the debug port if the specified error level is enabled. | |
| If any bit in ErrorLevel is also set in Mainbox, then print the message specified | |
| by Format and the associated variable argument list to the debug port. | |
| @param[in] ErrorLevel The error level of the debug message. | |
| @param[in] Format Format string for the debug message to print. | |
| @param[in] ... Variable argument list whose contents are accessed | |
| based on the format string specified by Format. | |
| **/ | |
| VOID | |
| EFIAPI | |
| DebugAgentMsgPrint ( | |
| IN UINT8 ErrorLevel, | |
| IN CHAR8 *Format, | |
| ... | |
| ); | |
| /** | |
| Trigger one software interrupt to debug agent to handle it. | |
| @param[in] Signature Software interrupt signature. | |
| **/ | |
| VOID | |
| TriggerSoftInterrupt ( | |
| IN UINT32 Signature | |
| ); | |
| /** | |
| Check if debug agent support multi-processor. | |
| @retval TRUE Multi-processor is supported. | |
| @retval FALSE Multi-processor is not supported. | |
| **/ | |
| BOOLEAN | |
| MultiProcessorDebugSupport ( | |
| VOID | |
| ); | |
| /** | |
| Find and report module image info to HOST. | |
| @param[in] AlignSize Image aligned size. | |
| **/ | |
| VOID | |
| FindAndReportModuleImageInfo ( | |
| IN UINTN AlignSize | |
| ); | |
| /** | |
| Read IDT entry to check if IDT entries are setup by Debug Agent. | |
| @retval TRUE IDT entries were setup by Debug Agent. | |
| @retval FALSE IDT entries were not setup by Debug Agent. | |
| **/ | |
| BOOLEAN | |
| IsDebugAgentInitialzed ( | |
| VOID | |
| ); | |
| /** | |
| Calculate Mailbox checksum and update the checksum field. | |
| @param[in] Mailbox Debug Agent Mailbox pointer. | |
| **/ | |
| VOID | |
| UpdateMailboxChecksum ( | |
| IN DEBUG_AGENT_MAILBOX *Mailbox | |
| ); | |
| /** | |
| Verify Mailbox checksum. | |
| If checksum error, print debug message and run init dead loop. | |
| @param[in] Mailbox Debug Agent Mailbox pointer. | |
| **/ | |
| VOID | |
| VerifyMailboxChecksum ( | |
| IN DEBUG_AGENT_MAILBOX *Mailbox | |
| ); | |
| /** | |
| Set debug flag in mailbox. | |
| @param[in] FlagMask Debug flag mask value. | |
| @param[in] FlagValue Debug flag value. | |
| **/ | |
| VOID | |
| SetDebugFlag ( | |
| IN UINT64 FlagMask, | |
| IN UINT32 FlagValue | |
| ); | |
| /** | |
| Get debug flag in mailbox. | |
| @param[in] FlagMask Debug flag mask value. | |
| @return Debug flag value. | |
| **/ | |
| UINT32 | |
| GetDebugFlag ( | |
| IN UINT64 FlagMask | |
| ); | |
| /** | |
| Update Mailbox content by index. | |
| @param[in] Mailbox Debug Agent Mailbox pointer. | |
| @param[in] Index Mailbox content index. | |
| @param[in] Value Value to be set into mail box. | |
| **/ | |
| VOID | |
| UpdateMailboxContent ( | |
| IN DEBUG_AGENT_MAILBOX *Mailbox, | |
| IN UINTN Index, | |
| IN UINT64 Value | |
| ); | |
| /** | |
| Retrieve exception handler from IDT table by ExceptionNum. | |
| @param[in] ExceptionNum Exception number | |
| @return Exception handler | |
| **/ | |
| VOID * | |
| GetExceptionHandlerInIdtEntry ( | |
| IN UINTN ExceptionNum | |
| ); | |
| /** | |
| Set exception handler in IDT table by ExceptionNum. | |
| @param[in] ExceptionNum Exception number | |
| @param[in] ExceptionHandler Exception Handler to be set | |
| **/ | |
| VOID | |
| SetExceptionHandlerInIdtEntry ( | |
| IN UINTN ExceptionNum, | |
| IN VOID *ExceptionHandler | |
| ); | |
| /** | |
| Prints a debug message to the debug output device if the specified error level is enabled. | |
| If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function | |
| GetDebugPrintErrorLevel (), then print the message specified by Format and the | |
| associated variable argument list to the debug output device. | |
| If Format is NULL, then ASSERT(). | |
| @param[in] ErrorLevel The error level of the debug message. | |
| @param[in] IsSend Flag of debug message to declare that the data is being sent or being received. | |
| @param[in] Data Variable argument list whose contents are accessed | |
| @param[in] Length based on the format string specified by Format. | |
| **/ | |
| VOID | |
| EFIAPI | |
| DebugAgentDataMsgPrint ( | |
| IN UINT8 ErrorLevel, | |
| IN BOOLEAN IsSend, | |
| IN UINT8 *Data, | |
| IN UINT8 Length | |
| ); | |
| /** | |
| Read remaing debug packet except for the start symbol | |
| @param[in] Handle Pointer to Debug Port handle. | |
| @param[in, out] DebugHeader Debug header buffer including start symbol. | |
| @retval EFI_SUCCESS Read the symbol in BreakSymbol. | |
| @retval EFI_CRC_ERROR CRC check fail. | |
| @retval EFI_TIMEOUT Timeout occurs when reading debug packet. | |
| **/ | |
| EFI_STATUS | |
| ReadRemainingBreakPacket ( | |
| IN DEBUG_PORT_HANDLE Handle, | |
| IN OUT DEBUG_PACKET_HEADER *DebugHeader | |
| ); | |
| /** | |
| Read data from debug channel and save the data in buffer. | |
| Reads NumberOfBytes data bytes from a debug device into the buffer | |
| specified by Buffer. The number of bytes actually read is returned. | |
| If the return value is less than NumberOfBytes, then the rest operation failed. | |
| If NumberOfBytes is zero, then return 0. | |
| @param Handle Debug port handle. | |
| @param Buffer Pointer to the data buffer to store the data read from the debug device. | |
| @param NumberOfBytes Number of bytes which will be read. | |
| @param Timeout Timeout value for reading from debug device. It unit is Microsecond. | |
| @retval 0 Read data failed, no data is to be read. | |
| @retval >0 Actual number of bytes read from debug device. | |
| **/ | |
| UINTN | |
| DebugAgentReadBuffer ( | |
| IN DEBUG_PORT_HANDLE Handle, | |
| IN OUT UINT8 *Buffer, | |
| IN UINTN NumberOfBytes, | |
| IN UINTN Timeout | |
| ); | |
| #endif |