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