1 /** @file 2 Command header of for Debug Agent library instance. 3 4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> 5 SPDX-License-Identifier: BSD-2-Clause-Patent 6 7 **/ 8 9 #ifndef _DEBUG_AGENT_H_ 10 #define _DEBUG_AGENT_H_ 11 12 #include <Register/LocalApic.h> 13 #include <Guid/DebugAgentGuid.h> 14 #include <Guid/VectorHandoffTable.h> 15 #include <Ppi/VectorHandoffInfo.h> 16 #include <Library/BaseLib.h> 17 #include <Library/BaseMemoryLib.h> 18 #include <Library/ResetSystemLib.h> 19 #include <Library/IoLib.h> 20 #include <Library/HobLib.h> 21 #include <Library/DebugCommunicationLib.h> 22 #include <Library/DebugAgentLib.h> 23 #include <Library/PcdLib.h> 24 #include <Library/SynchronizationLib.h> 25 #include <Library/LocalApicLib.h> 26 #include <Library/DebugLib.h> 27 #include <Library/TimerLib.h> 28 #include <Library/PrintLib.h> 29 #include <Library/PeCoffGetEntryPointLib.h> 30 #include <Library/PeCoffExtraActionLib.h> 31 #include <Register/ArchitecturalMsr.h> 32 33 #include <TransferProtocol.h> 34 #include <ImageDebugSupport.h> 35 36 #include "DebugMp.h" 37 #include "DebugTimer.h" 38 #include "ArchDebugSupport.h" 39 #include "DebugException.h" 40 41 // 42 // These macros may be already defined in DebugAgentLib.h 43 // 44 #define DEBUG_AGENT_INIT_PEI 9 45 #define DEBUG_AGENT_INIT_DXE_LOAD 10 46 #define DEBUG_AGENT_INIT_DXE_UNLOAD 11 47 #define DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64 12 48 49 #define DEBUG_INT1_VECTOR DEBUG_EXCEPT_DEBUG 50 #define DEBUG_INT3_VECTOR DEBUG_EXCEPT_BREAKPOINT 51 #define DEBUG_TIMER_VECTOR 32 52 #define DEBUG_MAILBOX_VECTOR 33 53 54 // 55 // Timeout value for reading packet (unit is microsecond) 56 // 57 #define READ_PACKET_TIMEOUT (500 * 1000) 58 #define DEBUG_TIMER_INTERVAL (100 * 1000) 59 60 #define SOFT_INTERRUPT_SIGNATURE SIGNATURE_32('S','O','F','T') 61 #define SYSTEM_RESET_SIGNATURE SIGNATURE_32('S','Y','S','R') 62 #define MEMORY_READY_SIGNATURE SIGNATURE_32('M','E','M','R') 63 64 extern UINTN Exception0Handle; 65 extern UINTN TimerInterruptHandle; 66 extern UINT32 ExceptionStubHeaderSize; 67 extern BOOLEAN mSkipBreakpoint; 68 extern EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[]; 69 extern UINTN mVectorHandoffInfoCount; 70 71 // 72 // CPU exception information issued by debug agent 73 // 74 typedef struct { 75 // 76 // This field is used to save CPU content before executing HOST command 77 // 78 BASE_LIBRARY_JUMP_BUFFER JumpBuffer; 79 // 80 // This field returns the exception information issued by the HOST command 81 // 82 DEBUG_DATA_RESPONSE_GET_EXCEPTION ExceptionContent; 83 } DEBUG_AGENT_EXCEPTION_BUFFER; 84 85 #define DEBUG_AGENT_FLAG_HOST_ATTACHED BIT0 86 #define DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS BIT1 87 #define DEBUG_AGENT_FLAG_MEMORY_READY BIT2 88 #define DEBUG_AGENT_FLAG_STEPPING BIT3 89 #define DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB BIT4 90 #define DEBUG_AGENT_FLAG_INIT_ARCH BIT5|BIT6 91 #define DEBUG_AGENT_FLAG_INTERRUPT_FLAG BIT7 92 #define DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI BIT32 93 #define DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL (BIT33|BIT34|BIT35|BIT36) 94 #define DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT BIT37 95 96 #define DEBUG_MAILBOX_DEBUG_FLAG_INDEX 1 97 #define DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX 2 98 #define DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX 3 99 #define DEBUG_MAILBOX_LAST_ACK 4 100 #define DEBUG_MAILBOX_SEQUENCE_NO_INDEX 5 101 #define DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX 6 102 #define DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY 7 103 104 #pragma pack(1) 105 typedef union { 106 struct { 107 // 108 // Lower 32 bits to store the status of DebugAgent 109 // 110 UINT32 HostAttached : 1; // 1: HOST is attached 111 UINT32 AgentInProgress : 1; // 1: Debug Agent is communicating with HOST 112 UINT32 MemoryReady : 1; // 1: Memory is ready 113 UINT32 SteppingFlag : 1; // 1: Agent is running stepping command 114 UINT32 CheckMailboxInHob : 1; // 1: Need to check mailbox saved in HOB 115 UINT32 InitArch : 2; // value of DEBUG_DATA_RESPONSE_ARCH_MODE 116 UINT32 InterruptFlag : 1; // 1: EFLAGS.IF is set 117 UINT32 Reserved1 : 24; 118 // 119 // Higher 32bits to control the behavior of DebugAgent 120 // 121 UINT32 BreakOnNextSmi : 1; // 1: Break on next SMI 122 UINT32 PrintErrorLevel : 4; // Bitmask of print error level for debug message 123 UINT32 BreakOnBootScript : 1; // 1: Break before executing boot script 124 UINT32 Reserved2 : 26; 125 } Bits; 126 UINT64 Uint64; 127 } DEBUG_AGENT_FLAG; 128 129 typedef struct { 130 DEBUG_AGENT_FLAG DebugFlag; 131 UINT64 DebugPortHandle; 132 // 133 // Pointer to DEBUG_AGENT_EXCEPTION_BUFFER 134 // 135 UINT64 ExceptionBufferPointer; 136 UINT8 LastAck; // The last ack packet type 137 UINT8 SequenceNo; 138 UINT8 HostSequenceNo; 139 UINT32 DebugTimerFrequency; 140 UINT8 CheckSum; // Mailbox checksum 141 UINT8 ToBeCheckSum; // To be Mailbox checksum at the next 142 } DEBUG_AGENT_MAILBOX; 143 #pragma pack() 144 145 /// 146 /// Byte packed structure for an IA-32 Interrupt Gate Descriptor. 147 /// 148 typedef union { 149 struct { 150 UINT32 OffsetLow:16; ///< Offset bits 15..0. 151 UINT32 Selector:16; ///< Selector. 152 UINT32 Reserved_0:8; ///< Reserved. 153 UINT32 GateType:8; ///< Gate Type. See #defines above. 154 UINT32 OffsetHigh:16; ///< Offset bits 31..16. 155 } Bits; 156 UINT64 Uint64; 157 } IA32_IDT_ENTRY; 158 159 160 typedef union { 161 struct { 162 UINT32 LimitLow : 16; 163 UINT32 BaseLow : 16; 164 UINT32 BaseMid : 8; 165 UINT32 Type : 4; 166 UINT32 System : 1; 167 UINT32 Dpl : 2; 168 UINT32 Present : 1; 169 UINT32 LimitHigh : 4; 170 UINT32 Software : 1; 171 UINT32 Reserved : 1; 172 UINT32 DefaultSize : 1; 173 UINT32 Granularity : 1; 174 UINT32 BaseHigh : 8; 175 } Bits; 176 UINT64 Uint64; 177 } IA32_GDT; 178 179 /** 180 Initialize IDT entries to support source level debug. 181 182 **/ 183 VOID 184 InitializeDebugIdt ( 185 VOID 186 ); 187 188 /** 189 Read register value from saved CPU context. 190 191 @param[in] CpuContext Pointer to saved CPU context. 192 @param[in] Index Register index value. 193 @param[in] Width Data width to read. 194 195 @return The address of register value. 196 197 **/ 198 UINT8 * 199 ArchReadRegisterBuffer ( 200 IN DEBUG_CPU_CONTEXT *CpuContext, 201 IN UINT8 Index, 202 IN UINT8 *Width 203 ); 204 205 /** 206 Send packet with response data to HOST. 207 208 @param[in] Data Pointer to response data buffer. 209 @param[in] DataSize Size of response data in byte. 210 @param[in, out] DebugHeader Pointer to a buffer for creating response packet and receiving ACK packet, 211 to minimize the stack usage. 212 213 @retval RETURN_SUCCESS Response data was sent successfully. 214 @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST. 215 216 **/ 217 RETURN_STATUS 218 SendDataResponsePacket ( 219 IN UINT8 *Data, 220 IN UINT16 DataSize, 221 IN OUT DEBUG_PACKET_HEADER *DebugHeader 222 ); 223 224 /** 225 Check if HOST is attached based on Mailbox. 226 227 @retval TRUE HOST is attached. 228 @retval FALSE HOST is not attached. 229 230 **/ 231 BOOLEAN 232 IsHostAttached ( 233 VOID 234 ); 235 236 /** 237 Get Debug Agent Mailbox pointer. 238 239 @return Mailbox pointer. 240 241 **/ 242 DEBUG_AGENT_MAILBOX * 243 GetMailboxPointer ( 244 VOID 245 ); 246 247 /** 248 Get debug port handle. 249 250 @return Debug port handle. 251 252 **/ 253 DEBUG_PORT_HANDLE 254 GetDebugPortHandle ( 255 VOID 256 ); 257 258 /** 259 Read the Attach/Break-in symbols from the debug port. 260 261 @param[in] Handle Pointer to Debug Port handle. 262 @param[out] BreakSymbol Returned break symbol. 263 264 @retval EFI_SUCCESS Read the symbol in BreakSymbol. 265 @retval EFI_NOT_FOUND No read the break symbol. 266 267 **/ 268 EFI_STATUS 269 DebugReadBreakSymbol ( 270 IN DEBUG_PORT_HANDLE Handle, 271 OUT UINT8 *BreakSymbol 272 ); 273 274 /** 275 Prints a debug message to the debug port if the specified error level is enabled. 276 277 If any bit in ErrorLevel is also set in Mainbox, then print the message specified 278 by Format and the associated variable argument list to the debug port. 279 280 @param[in] ErrorLevel The error level of the debug message. 281 @param[in] Format Format string for the debug message to print. 282 @param[in] ... Variable argument list whose contents are accessed 283 based on the format string specified by Format. 284 285 **/ 286 VOID 287 EFIAPI 288 DebugAgentMsgPrint ( 289 IN UINT8 ErrorLevel, 290 IN CHAR8 *Format, 291 ... 292 ); 293 294 /** 295 Trigger one software interrupt to debug agent to handle it. 296 297 @param[in] Signature Software interrupt signature. 298 299 **/ 300 VOID 301 TriggerSoftInterrupt ( 302 IN UINT32 Signature 303 ); 304 305 /** 306 Check if debug agent support multi-processor. 307 308 @retval TRUE Multi-processor is supported. 309 @retval FALSE Multi-processor is not supported. 310 311 **/ 312 BOOLEAN 313 MultiProcessorDebugSupport ( 314 VOID 315 ); 316 317 /** 318 Find and report module image info to HOST. 319 320 @param[in] AlignSize Image aligned size. 321 322 **/ 323 VOID 324 FindAndReportModuleImageInfo ( 325 IN UINTN AlignSize 326 ); 327 328 /** 329 Read IDT entry to check if IDT entries are setup by Debug Agent. 330 331 @retval TRUE IDT entries were setup by Debug Agent. 332 @retval FALSE IDT entries were not setup by Debug Agent. 333 334 **/ 335 BOOLEAN 336 IsDebugAgentInitialzed ( 337 VOID 338 ); 339 340 /** 341 Calculate Mailbox checksum and update the checksum field. 342 343 @param[in] Mailbox Debug Agent Mailbox pointer. 344 345 **/ 346 VOID 347 UpdateMailboxChecksum ( 348 IN DEBUG_AGENT_MAILBOX *Mailbox 349 ); 350 351 /** 352 Verify Mailbox checksum. 353 354 If checksum error, print debug message and run init dead loop. 355 356 @param[in] Mailbox Debug Agent Mailbox pointer. 357 358 **/ 359 VOID 360 VerifyMailboxChecksum ( 361 IN DEBUG_AGENT_MAILBOX *Mailbox 362 ); 363 364 /** 365 Set debug flag in mailbox. 366 367 @param[in] FlagMask Debug flag mask value. 368 @param[in] FlagValue Debug flag value. 369 370 **/ 371 VOID 372 SetDebugFlag ( 373 IN UINT64 FlagMask, 374 IN UINT32 FlagValue 375 ); 376 377 /** 378 Get debug flag in mailbox. 379 380 @param[in] FlagMask Debug flag mask value. 381 382 @return Debug flag value. 383 384 **/ 385 UINT32 386 GetDebugFlag ( 387 IN UINT64 FlagMask 388 ); 389 390 /** 391 Update Mailbox content by index. 392 393 @param[in] Mailbox Debug Agent Mailbox pointer. 394 @param[in] Index Mailbox content index. 395 @param[in] Value Value to be set into mail box. 396 397 **/ 398 VOID 399 UpdateMailboxContent ( 400 IN DEBUG_AGENT_MAILBOX *Mailbox, 401 IN UINTN Index, 402 IN UINT64 Value 403 ); 404 405 /** 406 Retrieve exception handler from IDT table by ExceptionNum. 407 408 @param[in] ExceptionNum Exception number 409 410 @return Exception handler 411 412 **/ 413 VOID * 414 GetExceptionHandlerInIdtEntry ( 415 IN UINTN ExceptionNum 416 ); 417 418 /** 419 Set exception handler in IDT table by ExceptionNum. 420 421 @param[in] ExceptionNum Exception number 422 @param[in] ExceptionHandler Exception Handler to be set 423 424 **/ 425 VOID 426 SetExceptionHandlerInIdtEntry ( 427 IN UINTN ExceptionNum, 428 IN VOID *ExceptionHandler 429 ); 430 431 /** 432 Prints a debug message to the debug output device if the specified error level is enabled. 433 434 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 435 GetDebugPrintErrorLevel (), then print the message specified by Format and the 436 associated variable argument list to the debug output device. 437 438 If Format is NULL, then ASSERT(). 439 440 @param[in] ErrorLevel The error level of the debug message. 441 @param[in] IsSend Flag of debug message to declare that the data is being sent or being received. 442 @param[in] Data Variable argument list whose contents are accessed 443 @param[in] Length based on the format string specified by Format. 444 445 **/ 446 VOID 447 EFIAPI 448 DebugAgentDataMsgPrint ( 449 IN UINT8 ErrorLevel, 450 IN BOOLEAN IsSend, 451 IN UINT8 *Data, 452 IN UINT8 Length 453 ); 454 455 /** 456 Read remaing debug packet except for the start symbol 457 458 @param[in] Handle Pointer to Debug Port handle. 459 @param[in, out] DebugHeader Debug header buffer including start symbol. 460 461 @retval EFI_SUCCESS Read the symbol in BreakSymbol. 462 @retval EFI_CRC_ERROR CRC check fail. 463 @retval EFI_TIMEOUT Timeout occurs when reading debug packet. 464 465 **/ 466 EFI_STATUS 467 ReadRemainingBreakPacket ( 468 IN DEBUG_PORT_HANDLE Handle, 469 IN OUT DEBUG_PACKET_HEADER *DebugHeader 470 ); 471 472 /** 473 Read data from debug channel and save the data in buffer. 474 475 Reads NumberOfBytes data bytes from a debug device into the buffer 476 specified by Buffer. The number of bytes actually read is returned. 477 If the return value is less than NumberOfBytes, then the rest operation failed. 478 If NumberOfBytes is zero, then return 0. 479 480 @param Handle Debug port handle. 481 @param Buffer Pointer to the data buffer to store the data read from the debug device. 482 @param NumberOfBytes Number of bytes which will be read. 483 @param Timeout Timeout value for reading from debug device. It unit is Microsecond. 484 485 @retval 0 Read data failed, no data is to be read. 486 @retval >0 Actual number of bytes read from debug device. 487 488 **/ 489 UINTN 490 DebugAgentReadBuffer ( 491 IN DEBUG_PORT_HANDLE Handle, 492 IN OUT UINT8 *Buffer, 493 IN UINTN NumberOfBytes, 494 IN UINTN Timeout 495 ); 496 497 #endif 498 499