summaryrefslogtreecommitdiff
path: root/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h
blob: 64e4c3eaf0dc4f46b33453cf85c6e64f03a51444 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
/** @file
  Command header of for Debug Agent library instance.

  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#ifndef _DEBUG_AGENT_H_
#define _DEBUG_AGENT_H_

#include <Register/LocalApic.h>
#include <Guid/DebugAgentGuid.h>
#include <Guid/VectorHandoffTable.h>
#include <Ppi/VectorHandoffInfo.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/ResetSystemLib.h>
#include <Library/IoLib.h>
#include <Library/HobLib.h>
#include <Library/DebugCommunicationLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/PcdLib.h>
#include <Library/SynchronizationLib.h>
#include <Library/LocalApicLib.h>
#include <Library/DebugLib.h>
#include <Library/TimerLib.h>
#include <Library/PrintLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PeCoffExtraActionLib.h>

#include <TransferProtocol.h>
#include <ImageDebugSupport.h>

#include "DebugMp.h"
#include "DebugTimer.h"
#include "ArchDebugSupport.h"
#include "DebugException.h"

//
// These macros may be already defined in DebugAgentLib.h
//
#define DEBUG_AGENT_INIT_PEI                     9
#define DEBUG_AGENT_INIT_DXE_LOAD               10
#define DEBUG_AGENT_INIT_DXE_UNLOAD             11
#define DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64    12

#define DEBUG_INT1_VECTOR               DEBUG_EXCEPT_DEBUG
#define DEBUG_INT3_VECTOR               DEBUG_EXCEPT_BREAKPOINT
#define DEBUG_TIMER_VECTOR              32
#define DEBUG_MAILBOX_VECTOR            33

//
//  Timeout value for reading packet (unit is microsecond)
//
#define READ_PACKET_TIMEOUT     (500 * 1000)
#define DEBUG_TIMER_INTERVAL    (100 * 1000)

#define SOFT_INTERRUPT_SIGNATURE    SIGNATURE_32('S','O','F','T')
#define SYSTEM_RESET_SIGNATURE      SIGNATURE_32('S','Y','S','R')
#define MEMORY_READY_SIGNATURE      SIGNATURE_32('M','E','M','R')

extern UINTN  Exception0Handle;
extern UINTN  TimerInterruptHandle;
extern UINT32 ExceptionStubHeaderSize;
extern BOOLEAN mSkipBreakpoint;
extern EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[];
extern UINTN                   mVectorHandoffInfoCount;

//
// CPU exception information issued by debug agent
//
typedef struct {
  //
  // This field is used to save CPU content before executing HOST command
  //
  BASE_LIBRARY_JUMP_BUFFER            JumpBuffer;
  //
  // This field returns the exception information issued by the HOST command
  //
  DEBUG_DATA_RESPONSE_GET_EXCEPTION   ExceptionContent;
} DEBUG_AGENT_EXCEPTION_BUFFER;

#define DEBUG_AGENT_FLAG_HOST_ATTACHED         BIT0
#define DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS     BIT1
#define DEBUG_AGENT_FLAG_MEMORY_READY          BIT2
#define DEBUG_AGENT_FLAG_STEPPING              BIT3
#define DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB  BIT4
#define DEBUG_AGENT_FLAG_INIT_ARCH             BIT5|BIT6
#define DEBUG_AGENT_FLAG_INTERRUPT_FLAG        BIT7
#define DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI     BIT32
#define DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL     (BIT33|BIT34|BIT35|BIT36)
#define DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT     BIT37

#define DEBUG_MAILBOX_DEBUG_FLAG_INDEX                1
#define DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX         2
#define DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX  3
#define DEBUG_MAILBOX_LAST_ACK                        4
#define DEBUG_MAILBOX_SEQUENCE_NO_INDEX               5
#define DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX          6
#define DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY           7

#pragma pack(1)
typedef union {
  struct {
    //
    // Lower 32 bits to store the status of DebugAgent
    //
    UINT32  HostAttached      : 1;   // 1: HOST is attached
    UINT32  AgentInProgress   : 1;   // 1: Debug Agent is communicating with HOST
    UINT32  MemoryReady       : 1;   // 1: Memory is ready
    UINT32  SteppingFlag      : 1;   // 1: Agent is running stepping command
    UINT32  CheckMailboxInHob : 1;   // 1: Need to check mailbox saved in HOB
    UINT32  InitArch          : 2;   // value of DEBUG_DATA_RESPONSE_ARCH_MODE
    UINT32  InterruptFlag     : 1;   // 1: EFLAGS.IF is set
    UINT32  Reserved1         : 24;
    //
    // Higher 32bits to control the behavior of DebugAgent
    //
    UINT32  BreakOnNextSmi    : 1;   // 1: Break on next SMI
    UINT32  PrintErrorLevel   : 4;   // Bitmask of print error level for debug message
    UINT32  BreakOnBootScript : 1;   // 1: Break before executing boot script 
    UINT32  Reserved2         : 26;
  } Bits;
  UINT64  Uint64;
} DEBUG_AGENT_FLAG;

typedef struct {
  DEBUG_AGENT_FLAG           DebugFlag;
  UINT64                     DebugPortHandle;
  //
  // Pointer to DEBUG_AGENT_EXCEPTION_BUFFER
  //
  UINT64                     ExceptionBufferPointer;
  UINT8                      LastAck;      // The last ack packet type
  UINT8                      SequenceNo;
  UINT8                      HostSequenceNo;
  UINT32                     DebugTimerFrequency;
  UINT8                      CheckSum;     // Mailbox checksum
  UINT8                      ToBeCheckSum; // To be Mailbox checksum at the next
} DEBUG_AGENT_MAILBOX;
#pragma pack()

///
/// Byte packed structure for an IA-32 Interrupt Gate Descriptor.
///
typedef union {
  struct {
    UINT32  OffsetLow:16;   ///< Offset bits 15..0.
    UINT32  Selector:16;    ///< Selector.
    UINT32  Reserved_0:8;   ///< Reserved.
    UINT32  GateType:8;     ///< Gate Type.  See #defines above.
    UINT32  OffsetHigh:16;  ///< Offset bits 31..16.
  } Bits;
  UINT64  Uint64;
} IA32_IDT_ENTRY;


typedef union {
  struct {
    UINT32  LimitLow    : 16;
    UINT32  BaseLow     : 16;
    UINT32  BaseMid     : 8;
    UINT32  Type        : 4;
    UINT32  System      : 1;
    UINT32  Dpl         : 2;
    UINT32  Present     : 1;
    UINT32  LimitHigh   : 4;
    UINT32  Software    : 1;
    UINT32  Reserved    : 1;
    UINT32  DefaultSize : 1;
    UINT32  Granularity : 1;
    UINT32  BaseHigh    : 8;
  } Bits;
  UINT64  Uint64;
} IA32_GDT;

/**
  Initialize IDT entries to support source level debug.

**/
VOID
InitializeDebugIdt (
  VOID
  );

/**
  Read register value from saved CPU context.

  @param[in] CpuContext         Pointer to saved CPU context.
  @param[in] Index              Register index value.
  @param[in] Width              Data width to read.

  @return The address of register value.

**/
UINT8 *
ArchReadRegisterBuffer (
  IN DEBUG_CPU_CONTEXT               *CpuContext,
  IN UINT8                           Index,
  IN UINT8                           *Width
  );

/**
  Send packet with response data to HOST.

  @param[in]      Data        Pointer to response data buffer.
  @param[in]      DataSize    Size of response data in byte.
  @param[in, out] DebugHeader Pointer to a buffer for creating response packet and receiving ACK packet,
                              to minimize the stack usage.

  @retval RETURN_SUCCESS      Response data was sent successfully.
  @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.

**/
RETURN_STATUS
SendDataResponsePacket (
  IN UINT8                   *Data,
  IN UINT16                  DataSize,
  IN OUT DEBUG_PACKET_HEADER *DebugHeader
  );

/**
  Check if HOST is attached based on Mailbox.

  @retval TRUE        HOST is attached.
  @retval FALSE       HOST is not attached.

**/
BOOLEAN
IsHostAttached (
  VOID
  );

/**
  Get Debug Agent Mailbox pointer.

  @return Mailbox pointer.

**/
DEBUG_AGENT_MAILBOX *
GetMailboxPointer (
  VOID
  );

/**
  Get debug port handle.

  @return Debug port handle.

**/
DEBUG_PORT_HANDLE
GetDebugPortHandle (
  VOID
  );

/**
  Read the Attach/Break-in symbols from the debug port.

  @param[in]  Handle         Pointer to Debug Port handle.
  @param[out] BreakSymbol    Returned break symbol.

  @retval EFI_SUCCESS        Read the symbol in BreakSymbol.
  @retval EFI_NOT_FOUND      No read the break symbol.

**/
EFI_STATUS
DebugReadBreakSymbol (
  IN  DEBUG_PORT_HANDLE      Handle,
  OUT UINT8                  *BreakSymbol
  );

/**
  Prints a debug message to the debug port if the specified error level is enabled.

  If any bit in ErrorLevel is also set in Mainbox, then print the message specified
  by Format and the associated variable argument list to the debug port.

  @param[in] ErrorLevel  The error level of the debug message.
  @param[in] Format      Format string for the debug message to print.
  @param[in] ...         Variable argument list whose contents are accessed 
                         based on the format string specified by Format.

**/
VOID
EFIAPI
DebugAgentMsgPrint (
  IN UINT8         ErrorLevel,
  IN CHAR8         *Format,
  ...
  );

/**
  Trigger one software interrupt to debug agent to handle it.

  @param[in] Signature       Software interrupt signature.

**/
VOID
TriggerSoftInterrupt (
  IN UINT32                 Signature
  );

/**
  Check if debug agent support multi-processor.

  @retval TRUE    Multi-processor is supported.
  @retval FALSE   Multi-processor is not supported.

**/
BOOLEAN
MultiProcessorDebugSupport (
  VOID
  );

/**
  Find and report module image info to HOST.
  
  @param[in] AlignSize      Image aligned size.
  
**/
VOID 
FindAndReportModuleImageInfo (
  IN UINTN          AlignSize                   
  );

/**
  Read IDT entry to check if IDT entries are setup by Debug Agent.

  @retval  TRUE     IDT entries were setup by Debug Agent.
  @retval  FALSE    IDT entries were not setup by Debug Agent.

**/
BOOLEAN 
IsDebugAgentInitialzed (
  VOID
  );

/**
  Calculate Mailbox checksum and update the checksum field.

  @param[in]  Mailbox  Debug Agent Mailbox pointer.

**/
VOID
UpdateMailboxChecksum (
  IN DEBUG_AGENT_MAILBOX    *Mailbox
  );

/**
  Verify Mailbox checksum.

  If checksum error, print debug message and run init dead loop.

  @param[in]  Mailbox  Debug Agent Mailbox pointer.

**/
VOID 
VerifyMailboxChecksum (
  IN DEBUG_AGENT_MAILBOX    *Mailbox
  );

/**
  Set debug flag in mailbox.

  @param[in]  FlagMask      Debug flag mask value.
  @param[in]  FlagValue     Debug flag value.

**/
VOID 
SetDebugFlag (
  IN UINT64                 FlagMask,
  IN UINT32                 FlagValue                          
  );

/**
  Get debug flag in mailbox.

  @param[in]  FlagMask      Debug flag mask value.
  
  @return Debug flag value.

**/
UINT32
GetDebugFlag (
  IN UINT64                 FlagMask
  );

/**
  Update Mailbox content by index.

  @param[in]  Mailbox  Debug Agent Mailbox pointer.
  @param[in]  Index    Mailbox content index.
  @param[in]  Value    Value to be set into mail box.
  
**/
VOID
UpdateMailboxContent ( 
  IN DEBUG_AGENT_MAILBOX    *Mailbox,
  IN UINTN                  Index,
  IN UINT64                 Value
  );

/**
  Retrieve exception handler from IDT table by ExceptionNum.

  @param[in]  ExceptionNum    Exception number
 
  @return Exception handler

**/
VOID *
GetExceptionHandlerInIdtEntry (
  IN UINTN             ExceptionNum
  );

/**
  Set exception handler in IDT table by ExceptionNum.

  @param[in]  ExceptionNum      Exception number
  @param[in]  ExceptionHandler  Exception Handler to be set 

**/
VOID
SetExceptionHandlerInIdtEntry (
  IN UINTN             ExceptionNum,
  IN VOID              *ExceptionHandler
  );

/**
  Prints a debug message to the debug output device if the specified error level is enabled.

  If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 
  GetDebugPrintErrorLevel (), then print the message specified by Format and the 
  associated variable argument list to the debug output device.

  If Format is NULL, then ASSERT().

  @param[in] ErrorLevel  The error level of the debug message.
  @param[in] IsSend      Flag of debug message to declare that the data is being sent or being received.
  @param[in] Data        Variable argument list whose contents are accessed 
  @param[in] Length      based on the format string specified by Format.

**/
VOID
EFIAPI
DebugAgentDataMsgPrint (
  IN UINT8             ErrorLevel,
  IN BOOLEAN           IsSend,
  IN UINT8             *Data,
  IN UINT8             Length  
  );

/**
  Read remaing debug packet except for the start symbol

  @param[in]      Handle        Pointer to Debug Port handle.
  @param[in, out] DebugHeader   Debug header buffer including start symbol.

  @retval EFI_SUCCESS        Read the symbol in BreakSymbol.
  @retval EFI_CRC_ERROR      CRC check fail.
  @retval EFI_TIMEOUT        Timeout occurs when reading debug packet.

**/
EFI_STATUS
ReadRemainingBreakPacket (
  IN     DEBUG_PORT_HANDLE      Handle,
  IN OUT DEBUG_PACKET_HEADER    *DebugHeader
  );

/**
  Read data from debug channel and save the data in buffer.

  Reads NumberOfBytes data bytes from a debug device into the buffer
  specified by Buffer. The number of bytes actually read is returned.
  If the return value is less than NumberOfBytes, then the rest operation failed.
  If NumberOfBytes is zero, then return 0.

  @param  Handle           Debug port handle.
  @param  Buffer           Pointer to the data buffer to store the data read from the debug device.
  @param  NumberOfBytes    Number of bytes which will be read.
  @param  Timeout          Timeout value for reading from debug device. It unit is Microsecond.

  @retval 0                Read data failed, no data is to be read.
  @retval >0               Actual number of bytes read from debug device.

**/
UINTN
DebugAgentReadBuffer (
  IN     DEBUG_PORT_HANDLE     Handle,
  IN OUT UINT8                 *Buffer,
  IN     UINTN                 NumberOfBytes,
  IN     UINTN                 Timeout
  );

#endif