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