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