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