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