]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/GdbStub/GdbStubInternal.h
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmbeddedPkg / GdbStub / GdbStubInternal.h
index 20231cff8236eced85e4a09a72659eaf3812a34e..9c3929c812b30cbb0527fd7cd34ef1c79ecc13e4 100644 (file)
-/** @file
-  Private include file for GDB stub
-
-  Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
-
-  All rights reserved. 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 __GDB_STUB_INTERNAL__
-#define __GDB_STUB_INTERNAL__
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/PcdLib.h>
-#include <Library/GdbSerialLib.h>
-#include <Library/PrintLib.h>
-
-#include <Protocol/DebugSupport.h>
-#include <Protocol/SerialIo.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/LoadedImage.h>
-#include <Guid/DebugImageInfoTable.h>
-#include <IndustryStandard/PeImage.h>
-
-extern CONST CHAR8 mHexToStr[];
-
-// maximum size of input and output buffers
-// This value came from the show remote command of the gdb we tested against 
-#define MAX_BUF_SIZE 2000
-
-// maximum size of address buffer
-#define MAX_ADDR_SIZE 32
-
-// maximum size of register number buffer
-#define MAX_REG_NUM_BUF_SIZE 32
-
-// maximum size of length buffer
-#define MAX_LENGTH_SIZE 32
-
-// maximum size of T signal members
-#define MAX_T_SIGNAL_SIZE 64
-
-// the mask used to clear all the cache
-#define TF_BIT 0x00000100
-
-
-//
-// GDB Signal definitions - generic names for interrupts
-//
-#define GDB_SIGILL      4  // Illegal instruction       
-#define GDB_SIGTRAP     5  // Trace Trap (Breakpoint and SingleStep)
-#define GDB_SIGEMT      7  // Emulator Trap
-#define GDB_SIGFPE      8  // Floating point exception
-#define GDB_SIGSEGV     11 // Setgment violation, page fault 
-
-
-//
-// GDB File I/O Error values, zero means no error
-// Includes all general GDB Unix like error values
-//
-#define GDB_EBADMEMADDRBUFSIZE   11  // the buffer that stores memory Address to be read from/written to is not the right size
-#define GDB_EBADMEMLENGBUFSIZE   12  // the buffer that stores Length is not the right size 
-#define GDB_EBADMEMLENGTH        13  // Length, the given number of bytes to read or write, is not the right size
-#define GDB_EBADMEMDATA          14  // one of the bytes or nibbles of the memory is leess than 0 
-#define GDB_EBADMEMDATASIZE      15  // the memory data, 'XX..', is too short or too long
-#define GDB_EBADBUFSIZE          21  // the buffer created is not the correct size
-#define GDB_EINVALIDARG          31  // argument is invalid
-#define GDB_ENOSPACE             41  //
-#define GDB_EINVALIDBRKPOINTTYPE 51  // the breakpoint type is not recognized
-#define GDB_EINVALIDREGNUM       61  // given register number is not valid: either <0 or >=Number of Registers
-#define GDB_EUNKNOWN             255 // unknown
-
-
-//
-// These devices are open by GDB so we can just read and write to them
-//
-#define GDB_STDIN   0x00
-#define GDB_STDOUT  0x01
-#define GDB_STDERR  0x02
-
-//
-//Define Register size for different architectures
-//
-#if defined (MDE_CPU_IA32) 
-#define REG_SIZE  32
-#elif defined (MDE_CPU_X64)
-#define REG_SIZE  64
-#elif defined (MDE_CPU_ARM)
-#define REG_SIZE  32
-#endif
-
-#define GDB_SERIAL_DEV_SIGNATURE    SIGNATURE_32 ('g', 'd', 'b', 's')
-
-typedef struct {
-  VENDOR_DEVICE_PATH                     VendorDevice;
-  UINT32                                 Index;         // Suport more than one
-  EFI_DEVICE_PATH_PROTOCOL               End;
-} GDB_SERIAL_DEVICE_PATH;
-
-//
-//  Name:   SERIAL_DEV
-//  Purpose:  To provide device specific information
-//  Fields:
-//      Signature UINTN: The identity of the serial device
-//      SerialIo  SERIAL_IO_PROTOCOL: Serial I/O protocol interface
-//      SerialMode  SERIAL_IO_MODE:
-//      DevicePath  EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device
-//
-typedef struct {
-  UINTN                                  Signature;
-  EFI_HANDLE                             Handle;
-  EFI_SERIAL_IO_PROTOCOL                 SerialIo;
-  EFI_SERIAL_IO_MODE                     SerialMode;
-  GDB_SERIAL_DEVICE_PATH                 DevicePath;
-  INTN                                   InFileDescriptor;
-  INTN                                   OutFileDescriptor;
-} GDB_SERIAL_DEV;
-
-
-#define GDB_SERIAL_DEV_FROM_THIS(a) CR (a, GDB_SERIAL_DEV, SerialIo, GDB_SERIAL_DEV_SIGNATURE)
-
-
-typedef struct {
-    EFI_EXCEPTION_TYPE  Exception;
-    UINT8               SignalNo;
-} EFI_EXCEPTION_TYPE_ENTRY;
-
-
-#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
-
-//
-// Byte packed structure for DR6
-// 32-bits on IA-32
-// 64-bits on X64.  The upper 32-bits on X64 are reserved
-//
-typedef union {
-  struct {
-    UINT32  B0:1;           // Breakpoint condition detected
-    UINT32  B1:1;           // Breakpoint condition detected
-    UINT32  B2:1;           // Breakpoint condition detected
-    UINT32  B3:1;           // Breakpoint condition detected
-    UINT32  Reserved_1:9;   // Reserved 
-    UINT32  BD:1;           // Debug register access detected
-    UINT32  BS:1;           // Single step
-    UINT32  BT:1;           // Task switch
-    UINT32  Reserved_2:16;  // Reserved
-  } Bits;
-  UINTN     UintN;
-} IA32_DR6;
-
-//
-// Byte packed structure for DR7
-// 32-bits on IA-32
-// 64-bits on X64.  The upper 32-bits on X64 are reserved
-//
-typedef union {
-  struct {
-    UINT32  L0:1;           // Local breakpoint enable
-    UINT32  G0:1;           // Global breakpoint enable
-    UINT32  L1:1;           // Local breakpoint enable
-    UINT32  G1:1;           // Global breakpoint enable
-    UINT32  L2:1;           // Local breakpoint enable
-    UINT32  G2:1;           // Global breakpoint enable
-    UINT32  L3:1;           // Local breakpoint enable
-    UINT32  G3:1;           // Global breakpoint enable
-    UINT32  LE:1;           // Local exact breakpoint enable
-    UINT32  GE:1;           // Global exact breakpoint enable
-    UINT32  Reserved_1:3;   // Reserved
-    UINT32  GD:1;           // Global detect enable
-    UINT32  Reserved_2:2;   // Reserved
-    UINT32  RW0:2;          // Read/Write field
-    UINT32  LEN0:2;         // Length field
-    UINT32  RW1:2;          // Read/Write field
-    UINT32  LEN1:2;         // Length field
-    UINT32  RW2:2;          // Read/Write field
-    UINT32  LEN2:2;         // Length field
-    UINT32  RW3:2;          // Read/Write field
-    UINT32  LEN3:2;         // Length field
-  } Bits;
-  UINTN     UintN;
-} IA32_DR7;
-
-#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */
-
-typedef enum {
-  InstructionExecution,   //Hardware breakpoint
-  DataWrite,              //watch
-  DataRead,               //rwatch
-  DataReadWrite,          //awatch
-  SoftwareBreakpoint,     //Software breakpoint
-  NotSupported
-} BREAK_TYPE;
-
-//
-// Array of exception types that need to be hooked by the debugger
-//
-extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[];
-
-//
-// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
-// here we need to wait for the periodic callback to do this. 
-//
-extern BOOLEAN gCtrlCBreakFlag;
-
-//
-// If the periodic callback is called while we are processing an F packet we need
-// to let the callback know to not read from the serail stream as it could steal
-// characters from the F reponse packet
-//
-extern BOOLEAN gProcessingFPacket;
-
-
-// The offsets of registers SystemContext.
-// The fields in the array are in the gdb ordering.
-//
-extern UINTN    gRegisterOffsets[];
-
-/**
- Return the number of entries in the gExceptionType[]
- @retval    UINTN, the number of entries in the gExceptionType[] array.    
- **/
-UINTN
-MaxEfiException (
-  VOID
-  );
-
-
-/**
- Return the number of entries in the gRegisters[]
- @retval    UINTN, the number of entries (registers) in the gRegisters[] array.    
- **/
-UINTN
-MaxRegisterCount (
-  VOID
-  );
-
-
-/**
- Check to see if the ISA is supported. 
- ISA = Instruction Set Architecture
- @retval    TRUE if Isa is supported,
- FALSE otherwise.
- **/
-BOOLEAN
-CheckIsa (
-  IN    EFI_INSTRUCTION_SET_ARCHITECTURE    Isa
-  );
-
-
-/**
- Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
- @param  SystemContext        Register content at time of the exception
- @param  GdbExceptionType     GDB exception type
- **/
-
-VOID
-GdbSendTSignal (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINT8                  GdbExceptionType
-  );
-
-
-/**
- Translates the EFI mapping to GDB mapping
- @param     EFIExceptionType        EFI Exception that is being processed
- @retval    UINTN that corresponds to EFIExceptionType's GDB exception type number
- **/
-UINT8
-ConvertEFItoGDBtype ( 
-  IN  EFI_EXCEPTION_TYPE EFIExceptionType
-  );
-
-
-/**
- Empties the given buffer 
- @param *Buf pointer to the first element in buffer to be emptied
- **/
-VOID
-EmptyBuffer ( 
-  IN CHAR8  *Buf
-  );
-
-
-/**
- Converts an 8-bit Hex Char into a INTN.
- @param     Char  - the hex character to be converted into UINTN
- @retval    a INTN, from 0 to 15, that corressponds to Char
- -1 if Char is not a hex character
- **/
-INTN
-HexCharToInt (
-  IN  CHAR8 Char
-  );
-
-
-/** 'E NN'
- Send an error with the given error number after converting to hex.
- The error number is put into the buffer in hex. '255' is the biggest errno we can send.
- ex: 162 will be sent as A2.
- @param   errno    the error number that will be sent
- **/
-VOID
-EFIAPI
-SendError (
-  IN  UINT8     ErrorNum
-  );
-
-
-/**
- Send 'OK' when the function is done executing successfully.
- **/
-VOID
-SendSuccess (
-  VOID
-  );
-
-
-/**
- Send empty packet to specify that particular command/functionality is not supported.
- **/
-VOID
-SendNotSupported (
-  VOID
-  );
-
-/** ‘p n’ 
- Reads the n-th register's value into an output buffer and sends it as a packet 
- @param     SystemContext       Register content at time of the exception
- @param     InBuffer            This is the input buffer received from gdb server
- **/
-VOID
-ReadNthRegister (
-  IN    EFI_SYSTEM_CONTEXT  SystemContext,
-  IN    CHAR8               *InBuffer
-  );
-
-
-/** ‘g’ 
- Reads the general registers into an output buffer  and sends it as a packet 
- @param     SystemContext           Register content at time of the exception
- **/
-VOID
-ReadGeneralRegisters (  
-  IN    EFI_SYSTEM_CONTEXT  SystemContext
-  );
-
-
-/** ‘P n...=r...’
- Writes the new value of n-th register received into the input buffer to the n-th register
- @param     SystemContext       Register content at time of the exception
- @param     InBuffer            This is the input buffer received from gdb server
- **/
-VOID
-WriteNthRegister (
-  IN    EFI_SYSTEM_CONTEXT  SystemContext,
-  IN    CHAR8               *InBuffer
-  );
-
-
-/** ‘G XX...’
- Writes the new values received into the input buffer to the general registers
- @param     SystemContext               Register content at time of the exception
- @param     InBuffer                    Pointer to the input buffer received from gdb server
- **/
-
-VOID
-WriteGeneralRegisters (
-  IN    EFI_SYSTEM_CONTEXT  SystemContext,
-  IN    CHAR8               *InBuffer
-  );
-
-
-/** ‘m addr,length ’
- Find the Length of the area to read and the start addres. Finally, pass them to 
- another function, TransferFromMemToOutBufAndSend, that will read from that memory space and 
- send it as a packet.
- @param  *PacketData  Pointer to Payload data for the packet
- **/
-VOID
-ReadFromMemory (
-  IN  CHAR8  *PacketData
-  );
-
-
-/** ‘M addr,length :XX...’
- Find the Length of the area in bytes to write and the start addres. Finally, pass them to 
- another function, TransferFromInBufToMem, that will write to that memory space the info in
- the input buffer.
- @param   PacketData     Pointer to Payload data for the packet
- **/
-VOID
-WriteToMemory (
-  IN CHAR8 *PacketData
-  );
-
-
-/** ‘c [addr ]’ 
- Continue. addr is Address to resume. If addr is omitted, resume at current 
- Address.
- @param SystemContext Register content at time of the exception  
- @param *PacketData   Pointer to PacketData
- **/
-
-VOID
-ContinueAtAddress (
-  IN  EFI_SYSTEM_CONTEXT   SystemContext,
-  IN  CHAR8                *PacketData
-  );
-
-
-/** ‘s [addr ]’
- Single step. addr is the Address at which to resume. If addr is omitted, resume 
- at same Address.
- @param SystemContext   Register content at time of the exception
- @param PacketData      Pointer to Payload data for the packet
- **/
-VOID
-SingleStep (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  CHAR8               *PacketData
-  );
-
-/** 
- Insert Single Step in the SystemContext
- @param SystemContext   Register content at time of the exception
- **/
-VOID
-AddSingleStep (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext
-  );
-  
-/** 
- Remove Single Step in the SystemContext
- @param SystemContext   Register content at time of the exception
- **/
-VOID
-RemoveSingleStep (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext
-  );
-  
-  
-/**
-  ‘Z1, [addr], [length]’
-  ‘Z2, [addr], [length]’
-  ‘Z3, [addr], [length]’
-  ‘Z4, [addr], [length]’
-
-  Insert hardware breakpoint/watchpoint at address addr of size length
-
-  @param SystemContext  Register content at time of the exception
-  @param *PacketData    Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-InsertBreakPoint(
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  CHAR8               *PacketData
-  );
-
-
-/**
-  ‘z1, [addr], [length]’
-  ‘z2, [addr], [length]’
-  ‘z3, [addr], [length]’
-  ‘z4, [addr], [length]’
-
-  Remove hardware breakpoint/watchpoint at address addr of size length
-
-  @param SystemContext  Register content at time of the exception
-  @param *PacketData    Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-RemoveBreakPoint(
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  CHAR8               *PacketData
-  );
-
-
-/**
- Exception Hanldler for GDB. It will be called for all exceptions
- registered via the gExceptionType[] array.
- @param ExceptionType   Exception that is being processed
- @param SystemContext   Register content at time of the exception  
- **/
-VOID
-EFIAPI
-GdbExceptionHandler ( 
-  IN     EFI_EXCEPTION_TYPE  ExceptionType, 
-  IN OUT EFI_SYSTEM_CONTEXT  SystemContext 
-  );
-
-
-/**
- Periodic callback for GDB. This function is used to catch a ctrl-c or other 
- break in type command from GDB.
- @param SystemContext           Register content at time of the call
- **/
-VOID
-EFIAPI
-GdbPeriodicCallBack ( 
-  IN OUT EFI_SYSTEM_CONTEXT  SystemContext 
-  );
-
-
-/**
-  Make two serail consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
-  
-  These console show up on the remote system running GDB
-
-**/
-
-VOID
-GdbInitializeSerialConsole (
-  VOID
-  );
-
-
-/**
-  Send a GDB Remote Serial Protocol Packet
-  
-  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$', 
-  the packet teminating character '#' and the two digit checksum.
-  
-  If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up 
-  in an infinit loop. This is so if you unplug the debugger code just keeps running
-
-  @param PacketData   Payload data for the packet  
-  
-  @retval             Number of bytes of packet data sent.
-
-**/
-UINTN
-SendPacket (
-  IN  CHAR8 *PacketData
-  );
-  
-
-/**
- Receive a GDB Remote Serial Protocol Packet
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$', 
- the packet teminating character '#' and the two digit checksum.
- If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
- (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
- If an ack '+' is not sent resend the packet
- @param PacketData   Payload data for the packet  
- @retval             Number of bytes of packet data received.
-
- **/
-UINTN
-ReceivePacket (
- OUT  CHAR8 *PacketData,
- IN   UINTN PacketDataSize
- );
-  
-
-/**
-  Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates 
-  the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
-
-  @param  FileDescriptor   Device to talk to.
-  @param  Buffer           Buffer to hold Count bytes that were read
-  @param  Count            Number of bytes to transfer. 
-
-  @retval -1               Error
-  @retval {other}          Number of bytes read.
-
-**/
-INTN
-GdbRead (
-  IN  INTN    FileDescriptor,
-  OUT VOID    *Buffer,
-  IN  UINTN   Count
-  );
-  
-
-/**
-  Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates 
-  nothing was written. On error -1 is returned. 
-
-  @param  FileDescriptor   Device to talk to.
-  @param  Buffer           Buffer to hold Count bytes that are to be written
-  @param  Count            Number of bytes to transfer. 
-
-  @retval -1               Error
-  @retval {other}          Number of bytes written.
-
-**/
-INTN
-GdbWrite (
-  IN  INTN          FileDescriptor,
-  OUT CONST VOID    *Buffer,
-  IN  UINTN         Count
-  );
-
-UINTN *  
-FindPointerToRegister (
-  IN  EFI_SYSTEM_CONTEXT    SystemContext,
-  IN  UINTN                 RegNumber  
-  );
-
-CHAR8 * 
-BasicReadRegister (
-  IN  EFI_SYSTEM_CONTEXT      SystemContext,
-  IN  UINTN                   RegNumber,
-  IN  CHAR8                   *OutBufPtr
-  );
-
-VOID
-TransferFromInBufToMem (
-  IN  UINTN   Length,
-  IN  UINT8   *Address,
-  IN  CHAR8   *NewData
-  );
-
-VOID
-TransferFromMemToOutBufAndSend (
-  IN  UINTN  Length,
-  IN  UINT8  *Address
-  );
-
-CHAR8 *
-BasicWriteRegister (
-  IN  EFI_SYSTEM_CONTEXT    SystemContext,
-  IN  UINTN                 RegNumber,
-  IN  CHAR8                 *InBufPtr
-  );
-
-VOID  
-PrintReg (
-  EFI_SYSTEM_CONTEXT SystemContext
-  );
-
-UINTN
-ParseBreakpointPacket (
-  IN  CHAR8 *PacketData,
-  OUT UINTN *Type,
-  OUT UINTN *Address,
-  OUT UINTN *Length
-  );
-
-UINTN
-GetBreakpointDataAddress (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINTN               BreakpointNumber 
-  );
-
-UINTN
-GetBreakpointDetected (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext
-  );
-
-BREAK_TYPE
-GetBreakpointType (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINTN               BreakpointNumber  
-  );
-
-UINTN
-ConvertLengthData (
-  IN  UINTN  Length
-  );
-
-EFI_STATUS
-FindNextFreeDebugRegister (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  OUT UINTN               *Register
-  );
-
-EFI_STATUS
-EnableDebugRegister (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINTN               Register,
-  IN  UINTN               Address,
-  IN  UINTN               Length,
-  IN  UINTN               Type
-  );
-
-EFI_STATUS
-FindMatchingDebugRegister (
- IN  EFI_SYSTEM_CONTEXT  SystemContext,
- IN  UINTN               Address,
- IN  UINTN               Length,
- IN  UINTN               Type,
- OUT UINTN               *Register
- );
-
-EFI_STATUS
-DisableDebugRegister (
- IN  EFI_SYSTEM_CONTEXT  SystemContext,
- IN  UINTN               Register
- );
-
-VOID
-InitializeProcessor (
-  VOID
-  );
-
-BOOLEAN
-ValidateAddress (
-  IN  VOID  *Address
-  );
-
-BOOLEAN
-ValidateException (
-  IN  EFI_EXCEPTION_TYPE    ExceptionType, 
-  IN OUT EFI_SYSTEM_CONTEXT SystemContext 
-  );
-
-#endif
+/** @file\r
+  Private include file for GDB stub\r
+\r
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __GDB_STUB_INTERNAL__\r
+#define __GDB_STUB_INTERNAL__\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/GdbSerialLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+#include <Protocol/DebugSupport.h>\r
+#include <Protocol/SerialIo.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Guid/DebugImageInfoTable.h>\r
+#include <IndustryStandard/PeImage.h>\r
+\r
+extern CONST CHAR8  mHexToStr[];\r
+\r
+// maximum size of input and output buffers\r
+// This value came from the show remote command of the gdb we tested against\r
+#define MAX_BUF_SIZE  2000\r
+\r
+// maximum size of address buffer\r
+#define MAX_ADDR_SIZE  32\r
+\r
+// maximum size of register number buffer\r
+#define MAX_REG_NUM_BUF_SIZE  32\r
+\r
+// maximum size of length buffer\r
+#define MAX_LENGTH_SIZE  32\r
+\r
+// maximum size of T signal members\r
+#define MAX_T_SIGNAL_SIZE  64\r
+\r
+// the mask used to clear all the cache\r
+#define TF_BIT  0x00000100\r
+\r
+//\r
+// GDB Signal definitions - generic names for interrupts\r
+//\r
+#define GDB_SIGILL   4     // Illegal instruction\r
+#define GDB_SIGTRAP  5     // Trace Trap (Breakpoint and SingleStep)\r
+#define GDB_SIGEMT   7     // Emulator Trap\r
+#define GDB_SIGFPE   8     // Floating point exception\r
+#define GDB_SIGSEGV  11    // Segment violation, page fault\r
+\r
+//\r
+// GDB File I/O Error values, zero means no error\r
+// Includes all general GDB Unix like error values\r
+//\r
+#define GDB_EBADMEMADDRBUFSIZE    11  // the buffer that stores memory Address to be read from/written to is not the right size\r
+#define GDB_EBADMEMLENGBUFSIZE    12  // the buffer that stores Length is not the right size\r
+#define GDB_EBADMEMLENGTH         13  // Length, the given number of bytes to read or write, is not the right size\r
+#define GDB_EBADMEMDATA           14  // one of the bytes or nibbles of the memory is less than 0\r
+#define GDB_EBADMEMDATASIZE       15  // the memory data, 'XX..', is too short or too long\r
+#define GDB_EBADBUFSIZE           21  // the buffer created is not the correct size\r
+#define GDB_EINVALIDARG           31  // argument is invalid\r
+#define GDB_ENOSPACE              41  //\r
+#define GDB_EINVALIDBRKPOINTTYPE  51  // the breakpoint type is not recognized\r
+#define GDB_EINVALIDREGNUM        61  // given register number is not valid: either <0 or >=Number of Registers\r
+#define GDB_EUNKNOWN              255 // unknown\r
+\r
+//\r
+// These devices are open by GDB so we can just read and write to them\r
+//\r
+#define GDB_STDIN   0x00\r
+#define GDB_STDOUT  0x01\r
+#define GDB_STDERR  0x02\r
+\r
+//\r
+// Define Register size for different architectures\r
+//\r
+#if defined (MDE_CPU_IA32)\r
+#define REG_SIZE  32\r
+#elif defined (MDE_CPU_X64)\r
+#define REG_SIZE  64\r
+#elif defined (MDE_CPU_ARM)\r
+#define REG_SIZE  32\r
+#endif\r
+\r
+#define GDB_SERIAL_DEV_SIGNATURE  SIGNATURE_32 ('g', 'd', 'b', 's')\r
+\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH          VendorDevice;\r
+  UINT32                      Index;                    // Support more than one\r
+  EFI_DEVICE_PATH_PROTOCOL    End;\r
+} GDB_SERIAL_DEVICE_PATH;\r
+\r
+//\r
+//  Name:   SERIAL_DEV\r
+//  Purpose:  To provide device specific information\r
+//  Fields:\r
+//      Signature UINTN: The identity of the serial device\r
+//      SerialIo  SERIAL_IO_PROTOCOL: Serial I/O protocol interface\r
+//      SerialMode  SERIAL_IO_MODE:\r
+//      DevicePath  EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device\r
+//\r
+typedef struct {\r
+  UINTN                     Signature;\r
+  EFI_HANDLE                Handle;\r
+  EFI_SERIAL_IO_PROTOCOL    SerialIo;\r
+  EFI_SERIAL_IO_MODE        SerialMode;\r
+  GDB_SERIAL_DEVICE_PATH    DevicePath;\r
+  INTN                      InFileDescriptor;\r
+  INTN                      OutFileDescriptor;\r
+} GDB_SERIAL_DEV;\r
+\r
+#define GDB_SERIAL_DEV_FROM_THIS(a)  CR (a, GDB_SERIAL_DEV, SerialIo, GDB_SERIAL_DEV_SIGNATURE)\r
+\r
+typedef struct {\r
+  EFI_EXCEPTION_TYPE    Exception;\r
+  UINT8                 SignalNo;\r
+} EFI_EXCEPTION_TYPE_ENTRY;\r
+\r
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)\r
+\r
+//\r
+// Byte packed structure for DR6\r
+// 32-bits on IA-32\r
+// 64-bits on X64.  The upper 32-bits on X64 are reserved\r
+//\r
+typedef union {\r
+  struct {\r
+    UINT32    B0         : 1;  // Breakpoint condition detected\r
+    UINT32    B1         : 1;  // Breakpoint condition detected\r
+    UINT32    B2         : 1;  // Breakpoint condition detected\r
+    UINT32    B3         : 1;  // Breakpoint condition detected\r
+    UINT32    Reserved_1 : 9;  // Reserved\r
+    UINT32    BD         : 1;  // Debug register access detected\r
+    UINT32    BS         : 1;  // Single step\r
+    UINT32    BT         : 1;  // Task switch\r
+    UINT32    Reserved_2 : 16; // Reserved\r
+  } Bits;\r
+  UINTN    UintN;\r
+} IA32_DR6;\r
+\r
+//\r
+// Byte packed structure for DR7\r
+// 32-bits on IA-32\r
+// 64-bits on X64.  The upper 32-bits on X64 are reserved\r
+//\r
+typedef union {\r
+  struct {\r
+    UINT32    L0         : 1; // Local breakpoint enable\r
+    UINT32    G0         : 1; // Global breakpoint enable\r
+    UINT32    L1         : 1; // Local breakpoint enable\r
+    UINT32    G1         : 1; // Global breakpoint enable\r
+    UINT32    L2         : 1; // Local breakpoint enable\r
+    UINT32    G2         : 1; // Global breakpoint enable\r
+    UINT32    L3         : 1; // Local breakpoint enable\r
+    UINT32    G3         : 1; // Global breakpoint enable\r
+    UINT32    LE         : 1; // Local exact breakpoint enable\r
+    UINT32    GE         : 1; // Global exact breakpoint enable\r
+    UINT32    Reserved_1 : 3; // Reserved\r
+    UINT32    GD         : 1; // Global detect enable\r
+    UINT32    Reserved_2 : 2; // Reserved\r
+    UINT32    RW0        : 2; // Read/Write field\r
+    UINT32    LEN0       : 2; // Length field\r
+    UINT32    RW1        : 2; // Read/Write field\r
+    UINT32    LEN1       : 2; // Length field\r
+    UINT32    RW2        : 2; // Read/Write field\r
+    UINT32    LEN2       : 2; // Length field\r
+    UINT32    RW3        : 2; // Read/Write field\r
+    UINT32    LEN3       : 2; // Length field\r
+  } Bits;\r
+  UINTN    UintN;\r
+} IA32_DR7;\r
+\r
+#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */\r
+\r
+typedef enum {\r
+  InstructionExecution,   // Hardware breakpoint\r
+  DataWrite,              // watch\r
+  DataRead,               // rwatch\r
+  DataReadWrite,          // awatch\r
+  SoftwareBreakpoint,     // Software breakpoint\r
+  NotSupported\r
+} BREAK_TYPE;\r
+\r
+//\r
+// Array of exception types that need to be hooked by the debugger\r
+//\r
+extern EFI_EXCEPTION_TYPE_ENTRY  gExceptionType[];\r
+\r
+//\r
+// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c\r
+// here we need to wait for the periodic callback to do this.\r
+//\r
+extern BOOLEAN  gCtrlCBreakFlag;\r
+\r
+//\r
+// If the periodic callback is called while we are processing an F packet we need\r
+// to let the callback know to not read from the serial stream as it could steal\r
+// characters from the F response packet\r
+//\r
+extern BOOLEAN  gProcessingFPacket;\r
+\r
+// The offsets of registers SystemContext.\r
+// The fields in the array are in the gdb ordering.\r
+//\r
+extern UINTN  gRegisterOffsets[];\r
+\r
+/**\r
+ Return the number of entries in the gExceptionType[]\r
+\r
+ @retval    UINTN, the number of entries in the gExceptionType[] array.\r
+ **/\r
+UINTN\r
+MaxEfiException (\r
+  VOID\r
+  );\r
+\r
+/**\r
+ Return the number of entries in the gRegisters[]\r
+\r
+ @retval    UINTN, the number of entries (registers) in the gRegisters[] array.\r
+ **/\r
+UINTN\r
+MaxRegisterCount (\r
+  VOID\r
+  );\r
+\r
+/**\r
+ Check to see if the ISA is supported.\r
+ ISA = Instruction Set Architecture\r
+\r
+ @retval    TRUE if Isa is supported,\r
+ FALSE otherwise.\r
+ **/\r
+BOOLEAN\r
+CheckIsa (\r
+  IN    EFI_INSTRUCTION_SET_ARCHITECTURE  Isa\r
+  );\r
+\r
+/**\r
+ Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints\r
+\r
+ @param  SystemContext        Register content at time of the exception\r
+ @param  GdbExceptionType     GDB exception type\r
+ **/\r
+\r
+VOID\r
+GdbSendTSignal (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINT8               GdbExceptionType\r
+  );\r
+\r
+/**\r
+ Translates the EFI mapping to GDB mapping\r
+\r
+ @param     EFIExceptionType        EFI Exception that is being processed\r
+ @retval    UINTN that corresponds to EFIExceptionType's GDB exception type number\r
+ **/\r
+UINT8\r
+ConvertEFItoGDBtype (\r
+  IN  EFI_EXCEPTION_TYPE  EFIExceptionType\r
+  );\r
+\r
+/**\r
+ Empties the given buffer\r
+ @param *Buf pointer to the first element in buffer to be emptied\r
+ **/\r
+VOID\r
+EmptyBuffer (\r
+  IN CHAR8  *Buf\r
+  );\r
+\r
+/**\r
+ Converts an 8-bit Hex Char into a INTN.\r
+\r
+ @param     Char  - the hex character to be converted into UINTN\r
+ @retval    a INTN, from 0 to 15, that corresponds to Char\r
+ -1 if Char is not a hex character\r
+ **/\r
+INTN\r
+HexCharToInt (\r
+  IN  CHAR8  Char\r
+  );\r
+\r
+/** 'E NN'\r
+ Send an error with the given error number after converting to hex.\r
+ The error number is put into the buffer in hex. '255' is the biggest errno we can send.\r
+ ex: 162 will be sent as A2.\r
+\r
+ @param   errno    the error number that will be sent\r
+ **/\r
+VOID\r
+EFIAPI\r
+SendError (\r
+  IN  UINT8  ErrorNum\r
+  );\r
+\r
+/**\r
+ Send 'OK' when the function is done executing successfully.\r
+ **/\r
+VOID\r
+EFIAPI\r
+SendSuccess (\r
+  VOID\r
+  );\r
+\r
+/**\r
+ Send empty packet to specify that particular command/functionality is not supported.\r
+ **/\r
+VOID\r
+EFIAPI\r
+SendNotSupported (\r
+  VOID\r
+  );\r
+\r
+/** ‘p n’\r
+ Reads the n-th register's value into an output buffer and sends it as a packet\r
+ @param     SystemContext       Register content at time of the exception\r
+ @param     InBuffer            This is the input buffer received from gdb server\r
+ **/\r
+VOID\r
+ReadNthRegister (\r
+  IN    EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN    CHAR8               *InBuffer\r
+  );\r
+\r
+/** ‘g’\r
+ Reads the general registers into an output buffer  and sends it as a packet\r
+ @param     SystemContext           Register content at time of the exception\r
+ **/\r
+VOID\r
+EFIAPI\r
+ReadGeneralRegisters (\r
+  IN    EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+/** ‘P n...=r...’\r
+ Writes the new value of n-th register received into the input buffer to the n-th register\r
+ @param     SystemContext       Register content at time of the exception\r
+ @param     InBuffer            This is the input buffer received from gdb server\r
+ **/\r
+VOID\r
+EFIAPI\r
+WriteNthRegister (\r
+  IN    EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN    CHAR8               *InBuffer\r
+  );\r
+\r
+/** ‘G XX...’\r
+ Writes the new values received into the input buffer to the general registers\r
+ @param     SystemContext               Register content at time of the exception\r
+ @param     InBuffer                    Pointer to the input buffer received from gdb server\r
+ **/\r
+\r
+VOID\r
+EFIAPI\r
+WriteGeneralRegisters (\r
+  IN    EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN    CHAR8               *InBuffer\r
+  );\r
+\r
+/** ‘m addr,length ’\r
+ Find the Length of the area to read and the start address. Finally, pass them to\r
+ another function, TransferFromMemToOutBufAndSend, that will read from that memory space and\r
+ send it as a packet.\r
+\r
+ @param  *PacketData  Pointer to Payload data for the packet\r
+ **/\r
+VOID\r
+EFIAPI\r
+ReadFromMemory (\r
+  IN  CHAR8  *PacketData\r
+  );\r
+\r
+/** ‘M addr,length :XX...’\r
+ Find the Length of the area in bytes to write and the start address. Finally, pass them to\r
+ another function, TransferFromInBufToMem, that will write to that memory space the info in\r
+ the input buffer.\r
+\r
+ @param   PacketData     Pointer to Payload data for the packet\r
+ **/\r
+VOID\r
+EFIAPI\r
+WriteToMemory (\r
+  IN CHAR8  *PacketData\r
+  );\r
+\r
+/** ‘c [addr ]’\r
+ Continue. addr is Address to resume. If addr is omitted, resume at current\r
+ Address.\r
+\r
+ @param SystemContext Register content at time of the exception\r
+ @param *PacketData   Pointer to PacketData\r
+ **/\r
+\r
+VOID\r
+EFIAPI\r
+ContinueAtAddress (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  CHAR8               *PacketData\r
+  );\r
+\r
+/** ‘s [addr ]’\r
+ Single step. addr is the Address at which to resume. If addr is omitted, resume\r
+ at same Address.\r
+\r
+ @param SystemContext   Register content at time of the exception\r
+ @param PacketData      Pointer to Payload data for the packet\r
+ **/\r
+VOID\r
+EFIAPI\r
+SingleStep (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  CHAR8               *PacketData\r
+  );\r
+\r
+/**\r
+ Insert Single Step in the SystemContext\r
+\r
+ @param SystemContext   Register content at time of the exception\r
+ **/\r
+VOID\r
+AddSingleStep (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+/**\r
+ Remove Single Step in the SystemContext\r
+\r
+ @param SystemContext   Register content at time of the exception\r
+ **/\r
+VOID\r
+RemoveSingleStep (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+/**\r
+  ‘Z1, [addr], [length]’\r
+  ‘Z2, [addr], [length]’\r
+  ‘Z3, [addr], [length]’\r
+  ‘Z4, [addr], [length]’\r
+\r
+  Insert hardware breakpoint/watchpoint at address addr of size length\r
+\r
+  @param SystemContext  Register content at time of the exception\r
+  @param *PacketData    Pointer to the Payload data for the packet\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InsertBreakPoint (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  CHAR8               *PacketData\r
+  );\r
+\r
+/**\r
+  ‘z1, [addr], [length]’\r
+  ‘z2, [addr], [length]’\r
+  ‘z3, [addr], [length]’\r
+  ‘z4, [addr], [length]’\r
+\r
+  Remove hardware breakpoint/watchpoint at address addr of size length\r
+\r
+  @param SystemContext  Register content at time of the exception\r
+  @param *PacketData    Pointer to the Payload data for the packet\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RemoveBreakPoint (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  CHAR8               *PacketData\r
+  );\r
+\r
+/**\r
+ Exception Handler for GDB. It will be called for all exceptions\r
+ registered via the gExceptionType[] array.\r
+\r
+ @param ExceptionType   Exception that is being processed\r
+ @param SystemContext   Register content at time of the exception\r
+\r
+ **/\r
+VOID\r
+EFIAPI\r
+GdbExceptionHandler (\r
+  IN     EFI_EXCEPTION_TYPE  ExceptionType,\r
+  IN OUT EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+/**\r
+ Periodic callback for GDB. This function is used to catch a ctrl-c or other\r
+ break in type command from GDB.\r
+\r
+ @param SystemContext           Register content at time of the call\r
+\r
+ **/\r
+VOID\r
+EFIAPI\r
+GdbPeriodicCallBack (\r
+  IN OUT EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+/**\r
+  Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.\r
+\r
+  These console show up on the remote system running GDB\r
+\r
+**/\r
+\r
+VOID\r
+GdbInitializeSerialConsole (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Send a GDB Remote Serial Protocol Packet\r
+\r
+  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',\r
+  the packet terminating character '#' and the two digit checksum.\r
+\r
+  If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up\r
+  in an infinite loop. This is so if you unplug the debugger code just keeps running\r
+\r
+  @param PacketData   Payload data for the packet\r
+\r
+  @retval             Number of bytes of packet data sent.\r
+\r
+**/\r
+UINTN\r
+SendPacket (\r
+  IN  CHAR8  *PacketData\r
+  );\r
+\r
+/**\r
+ Receive a GDB Remote Serial Protocol Packet\r
+\r
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',\r
+ the packet terminating character '#' and the two digit checksum.\r
+\r
+ If host re-starts sending a packet without ending the previous packet, only the last valid packet is processed.\r
+ (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)\r
+\r
+ If an ack '+' is not sent resend the packet\r
+\r
+ @param PacketData   Payload data for the packet\r
+\r
+ @retval             Number of bytes of packet data received.\r
+\r
+ **/\r
+UINTN\r
+ReceivePacket (\r
+  OUT  CHAR8  *PacketData,\r
+  IN   UINTN  PacketDataSize\r
+  );\r
+\r
+/**\r
+  Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates\r
+  the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.\r
+\r
+  @param  FileDescriptor   Device to talk to.\r
+  @param  Buffer           Buffer to hold Count bytes that were read\r
+  @param  Count            Number of bytes to transfer.\r
+\r
+  @retval -1               Error\r
+  @retval {other}          Number of bytes read.\r
+\r
+**/\r
+INTN\r
+GdbRead (\r
+  IN  INTN   FileDescriptor,\r
+  OUT VOID   *Buffer,\r
+  IN  UINTN  Count\r
+  );\r
+\r
+/**\r
+  Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates\r
+  nothing was written. On error -1 is returned.\r
+\r
+  @param  FileDescriptor   Device to talk to.\r
+  @param  Buffer           Buffer to hold Count bytes that are to be written\r
+  @param  Count            Number of bytes to transfer.\r
+\r
+  @retval -1               Error\r
+  @retval {other}          Number of bytes written.\r
+\r
+**/\r
+INTN\r
+GdbWrite (\r
+  IN  INTN        FileDescriptor,\r
+  OUT CONST VOID  *Buffer,\r
+  IN  UINTN       Count\r
+  );\r
+\r
+UINTN *\r
+FindPointerToRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               RegNumber\r
+  );\r
+\r
+CHAR8 *\r
+BasicReadRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               RegNumber,\r
+  IN  CHAR8               *OutBufPtr\r
+  );\r
+\r
+VOID\r
+TransferFromInBufToMem (\r
+  IN  UINTN  Length,\r
+  IN  UINT8  *Address,\r
+  IN  CHAR8  *NewData\r
+  );\r
+\r
+VOID\r
+TransferFromMemToOutBufAndSend (\r
+  IN  UINTN  Length,\r
+  IN  UINT8  *Address\r
+  );\r
+\r
+CHAR8 *\r
+BasicWriteRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               RegNumber,\r
+  IN  CHAR8               *InBufPtr\r
+  );\r
+\r
+VOID\r
+PrintReg (\r
+  EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+UINTN\r
+ParseBreakpointPacket (\r
+  IN  CHAR8  *PacketData,\r
+  OUT UINTN  *Type,\r
+  OUT UINTN  *Address,\r
+  OUT UINTN  *Length\r
+  );\r
+\r
+UINTN\r
+GetBreakpointDataAddress (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               BreakpointNumber\r
+  );\r
+\r
+UINTN\r
+GetBreakpointDetected (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+BREAK_TYPE\r
+GetBreakpointType (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               BreakpointNumber\r
+  );\r
+\r
+UINTN\r
+ConvertLengthData (\r
+  IN  UINTN  Length\r
+  );\r
+\r
+EFI_STATUS\r
+FindNextFreeDebugRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  OUT UINTN               *Register\r
+  );\r
+\r
+EFI_STATUS\r
+EnableDebugRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               Register,\r
+  IN  UINTN               Address,\r
+  IN  UINTN               Length,\r
+  IN  UINTN               Type\r
+  );\r
+\r
+EFI_STATUS\r
+FindMatchingDebugRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               Address,\r
+  IN  UINTN               Length,\r
+  IN  UINTN               Type,\r
+  OUT UINTN               *Register\r
+  );\r
+\r
+EFI_STATUS\r
+DisableDebugRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               Register\r
+  );\r
+\r
+VOID\r
+InitializeProcessor (\r
+  VOID\r
+  );\r
+\r
+BOOLEAN\r
+ValidateAddress (\r
+  IN  VOID  *Address\r
+  );\r
+\r
+BOOLEAN\r
+ValidateException (\r
+  IN  EFI_EXCEPTION_TYPE     ExceptionType,\r
+  IN OUT EFI_SYSTEM_CONTEXT  SystemContext\r
+  );\r
+\r
+#endif\r