1969eba7b0df70c9aa261eaf005085568b88de87candrewfish/** @file
2969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Debug Agent library implementition with empty functions.
3969eba7b0df70c9aa261eaf005085568b88de87candrewfish
460274ccab831d7874129a6b6c271969418296960hhtian  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
560274ccab831d7874129a6b6c271969418296960hhtian  This program and the accompanying materials
6969eba7b0df70c9aa261eaf005085568b88de87candrewfish  are licensed and made available under the terms and conditions of the BSD License
7969eba7b0df70c9aa261eaf005085568b88de87candrewfish  which accompanies this distribution.  The full text of the license may be found at
8969eba7b0df70c9aa261eaf005085568b88de87candrewfish  http://opensource.org/licenses/bsd-license.php
9969eba7b0df70c9aa261eaf005085568b88de87candrewfish
10969eba7b0df70c9aa261eaf005085568b88de87candrewfish  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11969eba7b0df70c9aa261eaf005085568b88de87candrewfish  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12969eba7b0df70c9aa261eaf005085568b88de87candrewfish
13969eba7b0df70c9aa261eaf005085568b88de87candrewfish**/
14969eba7b0df70c9aa261eaf005085568b88de87candrewfish
15969eba7b0df70c9aa261eaf005085568b88de87candrewfish#include "GdbDebugAgent.h"
16969eba7b0df70c9aa261eaf005085568b88de87candrewfish
17969eba7b0df70c9aa261eaf005085568b88de87candrewfish
18969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINTN     gMaxProcessorIndex = 0;
19969eba7b0df70c9aa261eaf005085568b88de87candrewfish
20969eba7b0df70c9aa261eaf005085568b88de87candrewfish//
21969eba7b0df70c9aa261eaf005085568b88de87candrewfish// Buffers for basic gdb communication
22969eba7b0df70c9aa261eaf005085568b88de87candrewfish//
23969eba7b0df70c9aa261eaf005085568b88de87candrewfishCHAR8 gInBuffer[MAX_BUF_SIZE];
24969eba7b0df70c9aa261eaf005085568b88de87candrewfishCHAR8 gOutBuffer[MAX_BUF_SIZE];
25969eba7b0df70c9aa261eaf005085568b88de87candrewfish
26969eba7b0df70c9aa261eaf005085568b88de87candrewfish
27969eba7b0df70c9aa261eaf005085568b88de87candrewfish//
28969eba7b0df70c9aa261eaf005085568b88de87candrewfish// Globals for returning XML from qXfer:libraries:read packet
29969eba7b0df70c9aa261eaf005085568b88de87candrewfish//
30969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINTN                             gPacketqXferLibraryOffset = 0;
31969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINTN                             gEfiDebugImageTableEntry = 0;
32969eba7b0df70c9aa261eaf005085568b88de87candrewfishCHAR8                             gXferLibraryBuffer[2000];
33969eba7b0df70c9aa261eaf005085568b88de87candrewfish
34969eba7b0df70c9aa261eaf005085568b88de87candrewfishGLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
35969eba7b0df70c9aa261eaf005085568b88de87candrewfish
36969eba7b0df70c9aa261eaf005085568b88de87candrewfish
37460616bdecc5c8f4fb6b482df60ce6c51d9c0e90Ard Biesheuvel// add-symbol-file c:/work/edk2/Build/BeagleBoard/DEBUG_GCC48/ARM/BeagleBoardPkg/Sec/Sec/DEBUG/BeagleBoardSec.dll 0x80008360
38460616bdecc5c8f4fb6b482df60ce6c51d9c0e90Ard BiesheuvelCHAR8  *qXferHack = "<library name=\"c:/work/edk2/Build/BeagleBoard/DEBUG_GCC48/ARM/BeagleBoardPkg/Sec/Sec/DEBUG/BeagleBoardSec.dll\"><segment address=\"0x80008360\"/></library>";
39969eba7b0df70c9aa261eaf005085568b88de87candrewfish
40969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINTN
41969eba7b0df70c9aa261eaf005085568b88de87candrewfishgXferObjectReadResponse (
42969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  CHAR8         Type,
43969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  CHAR8         *Str
44969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
45969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
46969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8   *OutBufPtr;             // pointer to the output buffer
47969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8   Char;
48969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN   Count;
49969eba7b0df70c9aa261eaf005085568b88de87candrewfish
50969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // responce starts with 'm' or 'l' if it is the end
51969eba7b0df70c9aa261eaf005085568b88de87candrewfish  OutBufPtr = gOutBuffer;
52969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *OutBufPtr++ = Type;
53969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Count = 1;
54969eba7b0df70c9aa261eaf005085568b88de87candrewfish
553402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  // Binary data encoding
56969eba7b0df70c9aa261eaf005085568b88de87candrewfish  OutBufPtr = gOutBuffer;
57969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (*Str != '\0') {
58969eba7b0df70c9aa261eaf005085568b88de87candrewfish    Char = *Str++;
59969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) {
60969eba7b0df70c9aa261eaf005085568b88de87candrewfish      // escape character
61969eba7b0df70c9aa261eaf005085568b88de87candrewfish      *OutBufPtr++ = 0x7d;
62969eba7b0df70c9aa261eaf005085568b88de87candrewfish
63969eba7b0df70c9aa261eaf005085568b88de87candrewfish      Char ^= 0x20;
64969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
65969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *OutBufPtr++ = Char;
66969eba7b0df70c9aa261eaf005085568b88de87candrewfish    Count++;
67969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
68969eba7b0df70c9aa261eaf005085568b88de87candrewfish
69969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *OutBufPtr = '\0' ;  // the end of the buffer
70969eba7b0df70c9aa261eaf005085568b88de87candrewfish  SendPacket (gOutBuffer);
713402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
72969eba7b0df70c9aa261eaf005085568b88de87candrewfish  return Count;
73969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
74969eba7b0df70c9aa261eaf005085568b88de87candrewfish
753402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron/**
76969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Process "qXfer:object:read:annex:offset,length" request.
773402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
783402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  Returns an XML document that contains loaded libraries. In our case it is
79969eba7b0df70c9aa261eaf005085568b88de87candrewfish  infomration in the EFI Debug Inmage Table converted into an XML document.
803402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
813402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  GDB will call with an arbitrary length (it can't know the real length and
823402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  will reply with chunks of XML that are easy for us to deal with. Gdb will
83969eba7b0df70c9aa261eaf005085568b88de87candrewfish  keep calling until we say we are done. XML doc looks like:
843402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
85969eba7b0df70c9aa261eaf005085568b88de87candrewfish  <library-list>
86969eba7b0df70c9aa261eaf005085568b88de87candrewfish    <library name="/a/a/c/d.dSYM"><segment address="0x10000000"/></library>
87969eba7b0df70c9aa261eaf005085568b88de87candrewfish    <library name="/a/m/e/e.pdb"><segment address="0x20000000"/></library>
88969eba7b0df70c9aa261eaf005085568b88de87candrewfish    <library name="/a/l/f/f.dll"><segment address="0x30000000"/></library>
89969eba7b0df70c9aa261eaf005085568b88de87candrewfish  </library-list>
903402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
913402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  Since we can not allocate memory in interupt context this module has
92969eba7b0df70c9aa261eaf005085568b88de87candrewfish  assumptions about how it will get called:
93969eba7b0df70c9aa261eaf005085568b88de87candrewfish  1) Length will generally be max remote packet size (big enough)
94969eba7b0df70c9aa261eaf005085568b88de87candrewfish  2) First Offset of an XML document read needs to be 0
95969eba7b0df70c9aa261eaf005085568b88de87candrewfish  3) This code will return back small chunks of the XML document on every read.
96969eba7b0df70c9aa261eaf005085568b88de87candrewfish     Each subseqent call will ask for the next availble part of the document.
973402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
98969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Note: The only variable size element in the XML is:
993402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  "  <library name=\"%s\"><segment address=\"%p\"/></library>\n" and it is
100969eba7b0df70c9aa261eaf005085568b88de87candrewfish  based on the file path and name of the symbol file. If the symbol file name
101969eba7b0df70c9aa261eaf005085568b88de87candrewfish  is bigger than the max gdb remote packet size we could update this code
102969eba7b0df70c9aa261eaf005085568b88de87candrewfish  to respond back in chunks.
103969eba7b0df70c9aa261eaf005085568b88de87candrewfish
104969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param Offset  offset into special data area
1053402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param Length  number of bytes to read starting at Offset
1063402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
107969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
108969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
109969eba7b0df70c9aa261eaf005085568b88de87candrewfishQxferLibrary (
110969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  UINTN   Offset,
111969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  UINTN   Length
112969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
113969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
114969eba7b0df70c9aa261eaf005085568b88de87candrewfish  gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', "<library-list>\n");
115969eba7b0df70c9aa261eaf005085568b88de87candrewfish  gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', qXferHack);
116969eba7b0df70c9aa261eaf005085568b88de87candrewfish  gXferObjectReadResponse ('l', "</library-list>\n");
117969eba7b0df70c9aa261eaf005085568b88de87candrewfish  gPacketqXferLibraryOffset = 0;
118969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
119969eba7b0df70c9aa261eaf005085568b88de87candrewfish
120969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
121969eba7b0df70c9aa261eaf005085568b88de87candrewfish Transfer length bytes of input buffer, starting at Address, to memory.
122969eba7b0df70c9aa261eaf005085568b88de87candrewfish
123969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param     length                  the number of the bytes to be transferred/written
124969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param     *address                the start address of the transferring/writing the memory
125969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param     *new_data               the new data to be written to memory
126969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
127969eba7b0df70c9aa261eaf005085568b88de87candrewfish
128969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
129969eba7b0df70c9aa261eaf005085568b88de87candrewfishTransferFromInBufToMem (
130969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN    UINTN                       Length,
131969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN    unsigned char               *Address,
132969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN    CHAR8                       *NewData
133969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
134969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
135969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 c1;
136969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 c2;
1373402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
138969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (Length-- > 0) {
139969eba7b0df70c9aa261eaf005085568b88de87candrewfish    c1 = (CHAR8)HexCharToInt (*NewData++);
140969eba7b0df70c9aa261eaf005085568b88de87candrewfish    c2 = (CHAR8)HexCharToInt (*NewData++);
141969eba7b0df70c9aa261eaf005085568b88de87candrewfish
142969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if ((c1 < 0) || (c2 < 0)) {
1433402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron      SendError (GDB_EBADMEMDATA);
144969eba7b0df70c9aa261eaf005085568b88de87candrewfish      return;
145969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
146969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *Address++ = (UINT8)((c1 << 4) + c2);
147969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
148969eba7b0df70c9aa261eaf005085568b88de87candrewfish
149969eba7b0df70c9aa261eaf005085568b88de87candrewfish  SendSuccess();
150969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
151969eba7b0df70c9aa261eaf005085568b88de87candrewfish
152969eba7b0df70c9aa261eaf005085568b88de87candrewfish
153969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
154969eba7b0df70c9aa261eaf005085568b88de87candrewfish Transfer Length bytes of memory starting at Address to an output buffer, OutBuffer. This function will finally send the buffer
155969eba7b0df70c9aa261eaf005085568b88de87candrewfish as a packet.
156969eba7b0df70c9aa261eaf005085568b88de87candrewfish
157969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param     Length                  the number of the bytes to be transferred/read
158969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param     *address                pointer to the start address of the transferring/reading the memory
159969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
160969eba7b0df70c9aa261eaf005085568b88de87candrewfish
161969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
162969eba7b0df70c9aa261eaf005085568b88de87candrewfishTransferFromMemToOutBufAndSend (
163969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN    UINTN                       Length,
164969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN    unsigned char               *Address
165969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
166969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
167969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // there are Length bytes and every byte is represented as 2 hex chars
168969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8   OutBuffer[MAX_BUF_SIZE];
169969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8   *OutBufPtr;             // pointer to the output buffer
170969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8   Char;
171969eba7b0df70c9aa261eaf005085568b88de87candrewfish
172969eba7b0df70c9aa261eaf005085568b88de87candrewfish  OutBufPtr = OutBuffer;
173969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (Length > 0) {
1743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
175969eba7b0df70c9aa261eaf005085568b88de87candrewfish    Char = mHexToStr[*Address >> 4];
176969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if ((Char >= 'A') && (Char <= 'F')) {
177969eba7b0df70c9aa261eaf005085568b88de87candrewfish      Char = Char - 'A' + 'a';
178969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
179969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *OutBufPtr++ = Char;
180969eba7b0df70c9aa261eaf005085568b88de87candrewfish
181969eba7b0df70c9aa261eaf005085568b88de87candrewfish    Char = mHexToStr[*Address & 0x0f];
182969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if ((Char >= 'A') && (Char <= 'F')) {
183969eba7b0df70c9aa261eaf005085568b88de87candrewfish      Char = Char - 'A' + 'a';
184969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
185969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *OutBufPtr++ = Char;
186969eba7b0df70c9aa261eaf005085568b88de87candrewfish
187969eba7b0df70c9aa261eaf005085568b88de87candrewfish    Address++;
188969eba7b0df70c9aa261eaf005085568b88de87candrewfish    Length--;
189969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
190969eba7b0df70c9aa261eaf005085568b88de87candrewfish
191969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *OutBufPtr = '\0' ;  // the end of the buffer
192969eba7b0df70c9aa261eaf005085568b88de87candrewfish  SendPacket (OutBuffer);
193969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
194969eba7b0df70c9aa261eaf005085568b88de87candrewfish
195969eba7b0df70c9aa261eaf005085568b88de87candrewfish
196969eba7b0df70c9aa261eaf005085568b88de87candrewfish
197969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
198969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Send a GDB Remote Serial Protocol Packet
1993402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
2003402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
201969eba7b0df70c9aa261eaf005085568b88de87candrewfish  the packet teminating character '#' and the two digit checksum.
2023402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
2033402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
204969eba7b0df70c9aa261eaf005085568b88de87candrewfish  in an infinit loop. This is so if you unplug the debugger code just keeps running
205969eba7b0df70c9aa261eaf005085568b88de87candrewfish
2063402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  @param PacketData   Payload data for the packet
2073402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
208969eba7b0df70c9aa261eaf005085568b88de87candrewfish
209969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @retval             Number of bytes of packet data sent.
210969eba7b0df70c9aa261eaf005085568b88de87candrewfish
211969eba7b0df70c9aa261eaf005085568b88de87candrewfish**/
212969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINTN
213969eba7b0df70c9aa261eaf005085568b88de87candrewfishSendPacket (
214969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  CHAR8 *PacketData
215969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
216969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
217969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINT8 CheckSum;
218969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Timeout;
219969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *Ptr;
220969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 TestChar;
221969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Count;
2223402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
223969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Timeout = PcdGet32 (PcdGdbMaxPacketRetryCount);
224969eba7b0df70c9aa261eaf005085568b88de87candrewfish
225969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Count = 0;
226969eba7b0df70c9aa261eaf005085568b88de87candrewfish  do {
227969eba7b0df70c9aa261eaf005085568b88de87candrewfish
228969eba7b0df70c9aa261eaf005085568b88de87candrewfish    Ptr = PacketData;
229969eba7b0df70c9aa261eaf005085568b88de87candrewfish
230969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if (Timeout-- == 0) {
231969eba7b0df70c9aa261eaf005085568b88de87candrewfish      // Only try a finite number of times so we don't get stuck in the loop
232969eba7b0df70c9aa261eaf005085568b88de87candrewfish      return Count;
233969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
2343402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
235969eba7b0df70c9aa261eaf005085568b88de87candrewfish    // Packet prefix
236969eba7b0df70c9aa261eaf005085568b88de87candrewfish    GdbPutChar ('$');
2373402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
238969eba7b0df70c9aa261eaf005085568b88de87candrewfish    for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {
239969eba7b0df70c9aa261eaf005085568b88de87candrewfish      GdbPutChar (*Ptr);
240969eba7b0df70c9aa261eaf005085568b88de87candrewfish      CheckSum = CheckSum + *Ptr;
241969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
2423402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
2433402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    // Packet terminating character and checksum
244969eba7b0df70c9aa261eaf005085568b88de87candrewfish    GdbPutChar ('#');
245969eba7b0df70c9aa261eaf005085568b88de87candrewfish    GdbPutChar (mHexToStr[CheckSum >> 4]);
246969eba7b0df70c9aa261eaf005085568b88de87candrewfish    GdbPutChar (mHexToStr[CheckSum & 0x0F]);
2473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
248969eba7b0df70c9aa261eaf005085568b88de87candrewfish    TestChar =  GdbGetChar ();
249969eba7b0df70c9aa261eaf005085568b88de87candrewfish  } while (TestChar != '+');
2503402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
251969eba7b0df70c9aa261eaf005085568b88de87candrewfish  return Count;
252969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
253969eba7b0df70c9aa261eaf005085568b88de87candrewfish
254969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
255969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Receive a GDB Remote Serial Protocol Packet
2563402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
2573402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
258969eba7b0df70c9aa261eaf005085568b88de87candrewfish  the packet teminating character '#' and the two digit checksum.
2593402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
260969eba7b0df70c9aa261eaf005085568b88de87candrewfish  If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
261969eba7b0df70c9aa261eaf005085568b88de87candrewfish  (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
2623402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
263969eba7b0df70c9aa261eaf005085568b88de87candrewfish  If an ack '+' is not sent resend the packet
264969eba7b0df70c9aa261eaf005085568b88de87candrewfish
2653402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  @param PacketData   Payload data for the packet
266969eba7b0df70c9aa261eaf005085568b88de87candrewfish
267969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @retval             Number of bytes of packet data received.
268969eba7b0df70c9aa261eaf005085568b88de87candrewfish
269969eba7b0df70c9aa261eaf005085568b88de87candrewfish**/
270969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINTN
271969eba7b0df70c9aa261eaf005085568b88de87candrewfishReceivePacket (
272969eba7b0df70c9aa261eaf005085568b88de87candrewfish  OUT  CHAR8 *PacketData,
273969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN   UINTN PacketDataSize
274969eba7b0df70c9aa261eaf005085568b88de87candrewfish )
275969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
276969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINT8 CheckSum;
277969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Index;
278969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 Char;
279969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 SumString[3];
280969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 TestChar;
2813402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
282969eba7b0df70c9aa261eaf005085568b88de87candrewfish  ZeroMem (PacketData, PacketDataSize);
2833402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
284969eba7b0df70c9aa261eaf005085568b88de87candrewfish  for (;;) {
285969eba7b0df70c9aa261eaf005085568b88de87candrewfish      // wait for the start of a packet
286969eba7b0df70c9aa261eaf005085568b88de87candrewfish    TestChar = GdbGetChar ();
287969eba7b0df70c9aa261eaf005085568b88de87candrewfish    while (TestChar != '$') {
288969eba7b0df70c9aa261eaf005085568b88de87candrewfish      TestChar = GdbGetChar ();
289969eba7b0df70c9aa261eaf005085568b88de87candrewfish    };
2903402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
291969eba7b0df70c9aa261eaf005085568b88de87candrewfish  retry:
292969eba7b0df70c9aa261eaf005085568b88de87candrewfish    for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) {
293969eba7b0df70c9aa261eaf005085568b88de87candrewfish      Char = GdbGetChar ();
294969eba7b0df70c9aa261eaf005085568b88de87candrewfish      if (Char == '$') {
295969eba7b0df70c9aa261eaf005085568b88de87candrewfish        goto retry;
296969eba7b0df70c9aa261eaf005085568b88de87candrewfish      }
297969eba7b0df70c9aa261eaf005085568b88de87candrewfish      if (Char == '#') {
298969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
299969eba7b0df70c9aa261eaf005085568b88de87candrewfish      }
300969eba7b0df70c9aa261eaf005085568b88de87candrewfish
301969eba7b0df70c9aa261eaf005085568b88de87candrewfish      PacketData[Index] = Char;
302969eba7b0df70c9aa261eaf005085568b88de87candrewfish      CheckSum = CheckSum + Char;
303969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
304969eba7b0df70c9aa261eaf005085568b88de87candrewfish    PacketData[Index] = '\0';
305969eba7b0df70c9aa261eaf005085568b88de87candrewfish
306969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if (Index == PacketDataSize) {
307969eba7b0df70c9aa261eaf005085568b88de87candrewfish      continue;
308969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
309969eba7b0df70c9aa261eaf005085568b88de87candrewfish
3103402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    SumString[0] = GdbGetChar ();
311969eba7b0df70c9aa261eaf005085568b88de87candrewfish    SumString[1] = GdbGetChar ();
312969eba7b0df70c9aa261eaf005085568b88de87candrewfish    SumString[2] = '\0';
3133402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
314969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if (AsciiStrHexToUintn (SumString) == CheckSum) {
315969eba7b0df70c9aa261eaf005085568b88de87candrewfish      // Ack: Success
316969eba7b0df70c9aa261eaf005085568b88de87candrewfish      GdbPutChar ('+');
3173402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
318969eba7b0df70c9aa261eaf005085568b88de87candrewfish      // Null terminate the callers string
319969eba7b0df70c9aa261eaf005085568b88de87candrewfish      PacketData[Index] = '\0';
320969eba7b0df70c9aa261eaf005085568b88de87candrewfish      return Index;
321969eba7b0df70c9aa261eaf005085568b88de87candrewfish    } else {
322969eba7b0df70c9aa261eaf005085568b88de87candrewfish      // Ack: Failure
323969eba7b0df70c9aa261eaf005085568b88de87candrewfish      GdbPutChar ('-');
324969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
325969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
3263402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
327969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //return 0;
328969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
329969eba7b0df70c9aa261eaf005085568b88de87candrewfish
330969eba7b0df70c9aa261eaf005085568b88de87candrewfish
331969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
3323402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Empties the given buffer
333969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param   Buf          pointer to the first element in buffer to be emptied
334969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
335969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
3363402aac7d985bf8a9f9d3c639f3fe93609380513Ronald CronEmptyBuffer (
337969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  CHAR8           *Buf
338969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
3393402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron{
340969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *Buf = '\0';
341969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
342969eba7b0df70c9aa261eaf005085568b88de87candrewfish
343969eba7b0df70c9aa261eaf005085568b88de87candrewfish
344969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
345969eba7b0df70c9aa261eaf005085568b88de87candrewfish Converts an 8-bit Hex Char into a INTN.
3463402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
347969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param   Char the hex character to be converted into UINTN
348969eba7b0df70c9aa261eaf005085568b88de87candrewfish @retval  a INTN, from 0 to 15, that corressponds to Char
349969eba7b0df70c9aa261eaf005085568b88de87candrewfish -1 if Char is not a hex character
350969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
351969eba7b0df70c9aa261eaf005085568b88de87candrewfishINTN
352969eba7b0df70c9aa261eaf005085568b88de87candrewfishHexCharToInt (
353969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  CHAR8           Char
354969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
355969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
356969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if ((Char >= 'A') && (Char <= 'F')) {
357969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return Char - 'A' + 10;
358969eba7b0df70c9aa261eaf005085568b88de87candrewfish  } else if ((Char >= 'a') && (Char <= 'f')) {
359969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return Char - 'a' + 10;
360969eba7b0df70c9aa261eaf005085568b88de87candrewfish  } else if ((Char >= '0') && (Char <= '9')) {
361969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return Char - '0';
362969eba7b0df70c9aa261eaf005085568b88de87candrewfish  } else { // if not a hex value, return a negative value
3633402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    return -1;
364969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
365969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
366969eba7b0df70c9aa261eaf005085568b88de87candrewfish
367969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // 'E' + the biggest error number is 255, so its 2 hex digits + buffer end
368969eba7b0df70c9aa261eaf005085568b88de87candrewfishCHAR8 *gError = "E__";
369969eba7b0df70c9aa261eaf005085568b88de87candrewfish
370969eba7b0df70c9aa261eaf005085568b88de87candrewfish/** 'E NN'
371969eba7b0df70c9aa261eaf005085568b88de87candrewfish Send an error with the given error number after converting to hex.
372969eba7b0df70c9aa261eaf005085568b88de87candrewfish The error number is put into the buffer in hex. '255' is the biggest errno we can send.
373969eba7b0df70c9aa261eaf005085568b88de87candrewfish ex: 162 will be sent as A2.
3743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
375969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param   errno           the error number that will be sent
376969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
377969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
378969eba7b0df70c9aa261eaf005085568b88de87candrewfishEFIAPI
379969eba7b0df70c9aa261eaf005085568b88de87candrewfishSendError (
380969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  UINT8              ErrorNum
381969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
382969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
383969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //
384969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // Replace _, or old data, with current errno
385969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //
386969eba7b0df70c9aa261eaf005085568b88de87candrewfish  gError[1] = mHexToStr [ErrorNum >> 4];
387969eba7b0df70c9aa261eaf005085568b88de87candrewfish  gError[2] = mHexToStr [ErrorNum & 0x0f];
3883402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
389969eba7b0df70c9aa261eaf005085568b88de87candrewfish  SendPacket (gError); // send buffer
390969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
391969eba7b0df70c9aa261eaf005085568b88de87candrewfish
392969eba7b0df70c9aa261eaf005085568b88de87candrewfish
393969eba7b0df70c9aa261eaf005085568b88de87candrewfish
394969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
395969eba7b0df70c9aa261eaf005085568b88de87candrewfish Send 'OK' when the function is done executing successfully.
396969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
397969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
398969eba7b0df70c9aa261eaf005085568b88de87candrewfishEFIAPI
399969eba7b0df70c9aa261eaf005085568b88de87candrewfishSendSuccess (
400969eba7b0df70c9aa261eaf005085568b88de87candrewfish  VOID
4013402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  )
402969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
403969eba7b0df70c9aa261eaf005085568b88de87candrewfish  SendPacket ("OK"); // send buffer
404969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
405969eba7b0df70c9aa261eaf005085568b88de87candrewfish
406969eba7b0df70c9aa261eaf005085568b88de87candrewfish
407969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
408969eba7b0df70c9aa261eaf005085568b88de87candrewfish Send empty packet to specify that particular command/functionality is not supported.
409969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
4103402aac7d985bf8a9f9d3c639f3fe93609380513Ronald CronVOID
4113402aac7d985bf8a9f9d3c639f3fe93609380513Ronald CronEFIAPI
412969eba7b0df70c9aa261eaf005085568b88de87candrewfishSendNotSupported (
4133402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  VOID
4143402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  )
4153402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron{
416969eba7b0df70c9aa261eaf005085568b88de87candrewfish  SendPacket ("");
417969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
418969eba7b0df70c9aa261eaf005085568b88de87candrewfish
419969eba7b0df70c9aa261eaf005085568b88de87candrewfish
420969eba7b0df70c9aa261eaf005085568b88de87candrewfish
421969eba7b0df70c9aa261eaf005085568b88de87candrewfish
422969eba7b0df70c9aa261eaf005085568b88de87candrewfish
423969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
424969eba7b0df70c9aa261eaf005085568b88de87candrewfish Translates the EFI mapping to GDB mapping
4253402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
426969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param   EFIExceptionType    EFI Exception that is being processed
427969eba7b0df70c9aa261eaf005085568b88de87candrewfish @retval  UINTN that corresponds to EFIExceptionType's GDB exception type number
428969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
429969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINT8
4303402aac7d985bf8a9f9d3c639f3fe93609380513Ronald CronConvertEFItoGDBtype (
431969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  EFI_EXCEPTION_TYPE      EFIExceptionType
432969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
4333402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron{
434969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN i;
4353402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
436969eba7b0df70c9aa261eaf005085568b88de87candrewfish  for (i=0; i < MaxEfiException() ; i++) {
437969eba7b0df70c9aa261eaf005085568b88de87candrewfish    if (gExceptionType[i].Exception == EFIExceptionType) {
438969eba7b0df70c9aa261eaf005085568b88de87candrewfish      return gExceptionType[i].SignalNo;
439969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
440969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
441969eba7b0df70c9aa261eaf005085568b88de87candrewfish  return GDB_SIGTRAP; // this is a GDB trap
442969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
443969eba7b0df70c9aa261eaf005085568b88de87candrewfish
444969eba7b0df70c9aa261eaf005085568b88de87candrewfish
445969eba7b0df70c9aa261eaf005085568b88de87candrewfish/** "m addr,length"
4463402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Find the Length of the area to read and the start addres. Finally, pass them to
4473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
448969eba7b0df70c9aa261eaf005085568b88de87candrewfish send it as a packet.
449969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
450969eba7b0df70c9aa261eaf005085568b88de87candrewfish
451969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
452969eba7b0df70c9aa261eaf005085568b88de87candrewfishEFIAPI
453969eba7b0df70c9aa261eaf005085568b88de87candrewfishReadFromMemory (
454969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *PacketData
455969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
456969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
457969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Address;
458969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Length;
459969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars
460969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *AddrBufPtr; // pointer to the address buffer
461969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *InBufPtr; /// pointer to the input buffer
4623402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
463969eba7b0df70c9aa261eaf005085568b88de87candrewfish  AddrBufPtr = AddressBuffer;
464969eba7b0df70c9aa261eaf005085568b88de87candrewfish  InBufPtr = &PacketData[1];
465969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (*InBufPtr != ',') {
466969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *AddrBufPtr++ = *InBufPtr++;
467969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
468969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *AddrBufPtr = '\0';
4693402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
470969eba7b0df70c9aa261eaf005085568b88de87candrewfish  InBufPtr++; // this skips ',' in the buffer
4713402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
472969eba7b0df70c9aa261eaf005085568b88de87candrewfish  /* Error checking */
473969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
4743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    SendError (GDB_EBADMEMADDRBUFSIZE);
475969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return;
476969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
4773402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
478969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // 2 = 'm' + ','
479969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - 2 >= MAX_LENGTH_SIZE) {
4803402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    SendError (GDB_EBADMEMLENGTH);
481969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return;
482969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
4833402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
484969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Address = AsciiStrHexToUintn (AddressBuffer);
485969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Length = AsciiStrHexToUintn (InBufPtr);
4863402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
487969eba7b0df70c9aa261eaf005085568b88de87candrewfish  TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);
488969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
489969eba7b0df70c9aa261eaf005085568b88de87candrewfish
490969eba7b0df70c9aa261eaf005085568b88de87candrewfish
491969eba7b0df70c9aa261eaf005085568b88de87candrewfish/** "M addr,length :XX..."
4923402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Find the Length of the area in bytes to write and the start addres. Finally, pass them to
493969eba7b0df70c9aa261eaf005085568b88de87candrewfish another function, TransferFromInBufToMem, that will write to that memory space the info in
494969eba7b0df70c9aa261eaf005085568b88de87candrewfish the input buffer.
495969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
496969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
497969eba7b0df70c9aa261eaf005085568b88de87candrewfishEFIAPI
498969eba7b0df70c9aa261eaf005085568b88de87candrewfishWriteToMemory (
499969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN CHAR8 *PacketData
500969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
501969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
502969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Address;
503969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Length;
504969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN MessageLength;
505969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the Address in hex chars
506969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 LengthBuffer[MAX_LENGTH_SIZE]; // the buffer that will hold the Length in hex chars
507969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *AddrBufPtr; // pointer to the Address buffer
508969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *LengthBufPtr; // pointer to the Length buffer
509969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *InBufPtr; /// pointer to the input buffer
5103402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
511969eba7b0df70c9aa261eaf005085568b88de87candrewfish  AddrBufPtr = AddressBuffer;
512969eba7b0df70c9aa261eaf005085568b88de87candrewfish  LengthBufPtr = LengthBuffer;
513969eba7b0df70c9aa261eaf005085568b88de87candrewfish  InBufPtr = &PacketData[1];
5143402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
515969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (*InBufPtr != ',') {
516969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *AddrBufPtr++ = *InBufPtr++;
517969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
518969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *AddrBufPtr = '\0';
5193402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
520969eba7b0df70c9aa261eaf005085568b88de87candrewfish  InBufPtr++; // this skips ',' in the buffer
5213402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
522969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (*InBufPtr != ':') {
523969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *LengthBufPtr++ = *InBufPtr++;
524969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
525969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *LengthBufPtr = '\0';
5263402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
527969eba7b0df70c9aa261eaf005085568b88de87candrewfish  InBufPtr++; // this skips ':' in the buffer
5283402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
529969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Address = AsciiStrHexToUintn (AddressBuffer);
530969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Length = AsciiStrHexToUintn (LengthBuffer);
5313402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
532969eba7b0df70c9aa261eaf005085568b88de87candrewfish  /* Error checking */
5333402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
534969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Check if Address is not too long.
535969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
5363402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    SendError (GDB_EBADMEMADDRBUFSIZE);
537969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return;
538969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
5393402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
540969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Check if message length is not too long
541969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (AsciiStrLen(LengthBuffer) >= MAX_LENGTH_SIZE) {
5423402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    SendError (GDB_EBADMEMLENGBUFSIZE);
543969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return;
544969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
5453402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
546969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // Check if Message is not too long/short.
547969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // 3 = 'M' + ',' + ':'
548969eba7b0df70c9aa261eaf005085568b88de87candrewfish  MessageLength = (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - AsciiStrLen(LengthBuffer) - 3);
549969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (MessageLength != (2*Length)) {
550969eba7b0df70c9aa261eaf005085568b88de87candrewfish    //Message too long/short. New data is not the right size.
5513402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron    SendError (GDB_EBADMEMDATASIZE);
552969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return;
553969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
554969eba7b0df70c9aa261eaf005085568b88de87candrewfish  TransferFromInBufToMem (Length, (unsigned char *)Address, InBufPtr);
555969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
556969eba7b0df70c9aa261eaf005085568b88de87candrewfish
557969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
558969eba7b0df70c9aa261eaf005085568b88de87candrewfish  Parses breakpoint packet data and captures Breakpoint type, Address and length.
559969eba7b0df70c9aa261eaf005085568b88de87candrewfish  In case of an error, function returns particular error code. Returning 0 meaning
560969eba7b0df70c9aa261eaf005085568b88de87candrewfish  no error.
561969eba7b0df70c9aa261eaf005085568b88de87candrewfish
562969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @param  PacketData  Pointer to the payload data for the packet.
563969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @param  Type        Breakpoint type
564969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @param  Address     Breakpoint address
565969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @param  Length      Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
566969eba7b0df70c9aa261eaf005085568b88de87candrewfish
567969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @retval 1           Success
568969eba7b0df70c9aa261eaf005085568b88de87candrewfish  @retval {other}     Particular error code
569969eba7b0df70c9aa261eaf005085568b88de87candrewfish
570969eba7b0df70c9aa261eaf005085568b88de87candrewfish**/
571969eba7b0df70c9aa261eaf005085568b88de87candrewfishUINTN
572969eba7b0df70c9aa261eaf005085568b88de87candrewfishParseBreakpointPacket (
573969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  CHAR8 *PacketData,
574969eba7b0df70c9aa261eaf005085568b88de87candrewfish  OUT UINTN *Type,
575969eba7b0df70c9aa261eaf005085568b88de87candrewfish  OUT UINTN *Address,
576969eba7b0df70c9aa261eaf005085568b88de87candrewfish  OUT UINTN *Length
577969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
578969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
579969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 AddressBuffer[MAX_ADDR_SIZE];
580969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *AddressBufferPtr;
581969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *PacketDataPtr;
582969eba7b0df70c9aa261eaf005085568b88de87candrewfish
583969eba7b0df70c9aa261eaf005085568b88de87candrewfish  PacketDataPtr = &PacketData[1];
584969eba7b0df70c9aa261eaf005085568b88de87candrewfish  AddressBufferPtr = AddressBuffer;
585969eba7b0df70c9aa261eaf005085568b88de87candrewfish
586969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *Type = AsciiStrHexToUintn (PacketDataPtr);
587969eba7b0df70c9aa261eaf005085568b88de87candrewfish
588969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Breakpoint/watchpoint type should be between 0 to 4
589969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (*Type > 4) {
590969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return 22; //EINVAL: Invalid argument.
591969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
592969eba7b0df70c9aa261eaf005085568b88de87candrewfish
593969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Skip ',' in the buffer.
594969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (*PacketDataPtr++ != ',');
595969eba7b0df70c9aa261eaf005085568b88de87candrewfish
596969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Parse Address information
597969eba7b0df70c9aa261eaf005085568b88de87candrewfish  while (*PacketDataPtr != ',') {
598969eba7b0df70c9aa261eaf005085568b88de87candrewfish    *AddressBufferPtr++ = *PacketDataPtr++;
599969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
600969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *AddressBufferPtr = '\0';
601969eba7b0df70c9aa261eaf005085568b88de87candrewfish
602969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Check if Address is not too long.
603969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
604969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return 40; //EMSGSIZE: Message size too long.
605969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
606969eba7b0df70c9aa261eaf005085568b88de87candrewfish
607969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *Address = AsciiStrHexToUintn (AddressBuffer);
608969eba7b0df70c9aa261eaf005085568b88de87candrewfish
609969eba7b0df70c9aa261eaf005085568b88de87candrewfish  PacketDataPtr++; //This skips , in the buffer
610969eba7b0df70c9aa261eaf005085568b88de87candrewfish
611969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Parse Length information
612969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *Length = AsciiStrHexToUintn (PacketDataPtr);
613969eba7b0df70c9aa261eaf005085568b88de87candrewfish
614969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Length should be 1, 2 or 4 bytes
615969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (*Length > 4) {
616969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return 22; //EINVAL: Invalid argument
617969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
618969eba7b0df70c9aa261eaf005085568b88de87candrewfish
619969eba7b0df70c9aa261eaf005085568b88de87candrewfish  return 0; //0 = No error
620969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
621969eba7b0df70c9aa261eaf005085568b88de87candrewfish
622969eba7b0df70c9aa261eaf005085568b88de87candrewfish
623969eba7b0df70c9aa261eaf005085568b88de87candrewfish
624969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
625969eba7b0df70c9aa261eaf005085568b88de87candrewfish Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
6263402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
627969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param  SystemContext        Register content at time of the exception
628969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param  GdbExceptionType     GDB exception type
629969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
630969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
631969eba7b0df70c9aa261eaf005085568b88de87candrewfishGdbSendTSignal (
632969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  EFI_SYSTEM_CONTEXT  SystemContext,
633969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  UINT8               GdbExceptionType
634969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
635969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
636969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 TSignalBuffer[128];
637969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 *TSignalPtr;
638969eba7b0df70c9aa261eaf005085568b88de87candrewfish
639969eba7b0df70c9aa261eaf005085568b88de87candrewfish  TSignalPtr = &TSignalBuffer[0];
640969eba7b0df70c9aa261eaf005085568b88de87candrewfish
641969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //Construct TSignal packet
642969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *TSignalPtr++ = 'T';
643969eba7b0df70c9aa261eaf005085568b88de87candrewfish
644969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //
645969eba7b0df70c9aa261eaf005085568b88de87candrewfish  // replace _, or previous value, with Exception type
646969eba7b0df70c9aa261eaf005085568b88de87candrewfish  //
6473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  *TSignalPtr++ = mHexToStr [GdbExceptionType >> 4];
648969eba7b0df70c9aa261eaf005085568b88de87candrewfish  *TSignalPtr++ = mHexToStr [GdbExceptionType & 0x0f];
6493402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
650969eba7b0df70c9aa261eaf005085568b88de87candrewfish  ProcessorSendTSignal (SystemContext, GdbExceptionType, TSignalPtr, sizeof (TSignalBuffer) - 2);
651969eba7b0df70c9aa261eaf005085568b88de87candrewfish
6523402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  SendPacket (TSignalBuffer);
653969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
654969eba7b0df70c9aa261eaf005085568b88de87candrewfish
655969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
656969eba7b0df70c9aa261eaf005085568b88de87candrewfishGdbFWrite (
657969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  UINTN Fd,
658969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  CHAR8 *Data,
659969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN  UINTN DataSize
660969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
661969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
662969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8 Buffer[128];
663969eba7b0df70c9aa261eaf005085568b88de87candrewfish
664969eba7b0df70c9aa261eaf005085568b88de87candrewfish  AsciiSPrint (Buffer, sizeof (Buffer), "Fwrite,%x,%x,%x", Fd, Data, DataSize);
665969eba7b0df70c9aa261eaf005085568b88de87candrewfish  SendPacket (Buffer);
666969eba7b0df70c9aa261eaf005085568b88de87candrewfish
667969eba7b0df70c9aa261eaf005085568b88de87candrewfish  for( ; ; ) {
668969eba7b0df70c9aa261eaf005085568b88de87candrewfish    ReceivePacket (gInBuffer, MAX_BUF_SIZE);
6693402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
670969eba7b0df70c9aa261eaf005085568b88de87candrewfish    switch (gInBuffer[0]) {
671969eba7b0df70c9aa261eaf005085568b88de87candrewfish    case 'm':
672969eba7b0df70c9aa261eaf005085568b88de87candrewfish      ReadFromMemory (gInBuffer);
673969eba7b0df70c9aa261eaf005085568b88de87candrewfish      break;
674969eba7b0df70c9aa261eaf005085568b88de87candrewfish
675969eba7b0df70c9aa261eaf005085568b88de87candrewfish    case 'M':
676969eba7b0df70c9aa261eaf005085568b88de87candrewfish      WriteToMemory (gInBuffer);
677969eba7b0df70c9aa261eaf005085568b88de87candrewfish      break;
678969eba7b0df70c9aa261eaf005085568b88de87candrewfish
679969eba7b0df70c9aa261eaf005085568b88de87candrewfish    case 'F':
680969eba7b0df70c9aa261eaf005085568b88de87candrewfish      return;
681969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
682969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
683969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
684969eba7b0df70c9aa261eaf005085568b88de87candrewfish
685969eba7b0df70c9aa261eaf005085568b88de87candrewfish
686969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
687969eba7b0df70c9aa261eaf005085568b88de87candrewfishGdbFPutString (
688969eba7b0df70c9aa261eaf005085568b88de87candrewfish  IN CHAR8  *String
689969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
690969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
691969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINTN Len = AsciiStrSize (String);
692969eba7b0df70c9aa261eaf005085568b88de87candrewfish
693969eba7b0df70c9aa261eaf005085568b88de87candrewfish  GdbFWrite (2, String, Len);
694969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
695969eba7b0df70c9aa261eaf005085568b88de87candrewfish
696969eba7b0df70c9aa261eaf005085568b88de87candrewfish
697969eba7b0df70c9aa261eaf005085568b88de87candrewfish/**
698969eba7b0df70c9aa261eaf005085568b88de87candrewfish Exception Hanldler for GDB. It will be called for all exceptions
699969eba7b0df70c9aa261eaf005085568b88de87candrewfish registered via the gExceptionType[] array.
7003402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
701969eba7b0df70c9aa261eaf005085568b88de87candrewfish @param ExceptionType     Exception that is being processed
7023402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param SystemContext     Register content at time of the exception
703969eba7b0df70c9aa261eaf005085568b88de87candrewfish **/
704969eba7b0df70c9aa261eaf005085568b88de87candrewfishVOID
705969eba7b0df70c9aa261eaf005085568b88de87candrewfishEFIAPI
7063402aac7d985bf8a9f9d3c639f3fe93609380513Ronald CronGdbExceptionHandler (
7073402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  IN  EFI_EXCEPTION_TYPE        ExceptionType,
7083402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  IN OUT EFI_SYSTEM_CONTEXT     SystemContext
709969eba7b0df70c9aa261eaf005085568b88de87candrewfish  )
710969eba7b0df70c9aa261eaf005085568b88de87candrewfish{
711969eba7b0df70c9aa261eaf005085568b88de87candrewfish  UINT8   GdbExceptionType;
712969eba7b0df70c9aa261eaf005085568b88de87candrewfish  CHAR8   *Ptr;
7133402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
714969eba7b0df70c9aa261eaf005085568b88de87candrewfish  if (ProcessorControlC (ExceptionType, SystemContext)) {
715969eba7b0df70c9aa261eaf005085568b88de87candrewfish    // We tried to process a control C handler and there is nothing to do
716969eba7b0df70c9aa261eaf005085568b88de87candrewfish    return;
717969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
718969eba7b0df70c9aa261eaf005085568b88de87candrewfish
719969eba7b0df70c9aa261eaf005085568b88de87candrewfish  GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);
720969eba7b0df70c9aa261eaf005085568b88de87candrewfish  GdbSendTSignal (SystemContext, GdbExceptionType);
7213402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
722969eba7b0df70c9aa261eaf005085568b88de87candrewfish  for( ; ; ) {
723969eba7b0df70c9aa261eaf005085568b88de87candrewfish    ReceivePacket (gInBuffer, MAX_BUF_SIZE);
7243402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
725969eba7b0df70c9aa261eaf005085568b88de87candrewfish    switch (gInBuffer[0]) {
726969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case '?':
727969eba7b0df70c9aa261eaf005085568b88de87candrewfish        GdbSendTSignal (SystemContext, GdbExceptionType);
728969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
7293402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
730969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'c':
7313402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron        ContinueAtAddress (SystemContext, gInBuffer);
732969eba7b0df70c9aa261eaf005085568b88de87candrewfish        return;
733969eba7b0df70c9aa261eaf005085568b88de87candrewfish
734969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'D':
7353402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron        // gdb wants to disconnect so return "OK" packet since.
736969eba7b0df70c9aa261eaf005085568b88de87candrewfish        SendSuccess ();
737969eba7b0df70c9aa261eaf005085568b88de87candrewfish        return;
738969eba7b0df70c9aa261eaf005085568b88de87candrewfish
739969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'g':
740969eba7b0df70c9aa261eaf005085568b88de87candrewfish        ReadGeneralRegisters (SystemContext);
741969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
7423402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
743969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'G':
744969eba7b0df70c9aa261eaf005085568b88de87candrewfish        WriteGeneralRegisters (SystemContext, gInBuffer);
745969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
7463402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
747969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'H':
7483402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron        //Return "OK" packet since we don't have more than one thread.
749969eba7b0df70c9aa261eaf005085568b88de87candrewfish        SendSuccess ();
750969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
7513402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
752969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'm':
753969eba7b0df70c9aa261eaf005085568b88de87candrewfish        ReadFromMemory (gInBuffer);
754969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
755969eba7b0df70c9aa261eaf005085568b88de87candrewfish
756969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'M':
757969eba7b0df70c9aa261eaf005085568b88de87candrewfish        WriteToMemory (gInBuffer);
758969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
759969eba7b0df70c9aa261eaf005085568b88de87candrewfish
760969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'P':
761969eba7b0df70c9aa261eaf005085568b88de87candrewfish        WriteNthRegister (SystemContext, gInBuffer);
762969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
763969eba7b0df70c9aa261eaf005085568b88de87candrewfish
764969eba7b0df70c9aa261eaf005085568b88de87candrewfish      //
765969eba7b0df70c9aa261eaf005085568b88de87candrewfish      // Still debugging this code. Not used in Darwin
766969eba7b0df70c9aa261eaf005085568b88de87candrewfish      //
7673402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron      case 'q':
768969eba7b0df70c9aa261eaf005085568b88de87candrewfish        // General Query Packets
769969eba7b0df70c9aa261eaf005085568b88de87candrewfish        if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) {
770969eba7b0df70c9aa261eaf005085568b88de87candrewfish          // return what we currently support, we don't parse what gdb suports
771969eba7b0df70c9aa261eaf005085568b88de87candrewfish          AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE);
772969eba7b0df70c9aa261eaf005085568b88de87candrewfish          SendPacket (gOutBuffer);
773969eba7b0df70c9aa261eaf005085568b88de87candrewfish        } else if (AsciiStrnCmp (gInBuffer, "qXfer:libraries:read::", 22) == 0) {
774969eba7b0df70c9aa261eaf005085568b88de87candrewfish          // �qXfer:libraries:read::offset,length
775969eba7b0df70c9aa261eaf005085568b88de87candrewfish          // gInBuffer[22] is offset string, ++Ptr is length string�
776969eba7b0df70c9aa261eaf005085568b88de87candrewfish          for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);
7773402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
778969eba7b0df70c9aa261eaf005085568b88de87candrewfish          // Not sure if multi-radix support is required. Currently only support decimal
779969eba7b0df70c9aa261eaf005085568b88de87candrewfish          QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));
780969eba7b0df70c9aa261eaf005085568b88de87candrewfish        } else if (AsciiStrnCmp (gInBuffer, "qOffsets", 8) == 0) {
781969eba7b0df70c9aa261eaf005085568b88de87candrewfish          AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "Text=1000;Data=f000;Bss=f000");
782969eba7b0df70c9aa261eaf005085568b88de87candrewfish          SendPacket (gOutBuffer);
783969eba7b0df70c9aa261eaf005085568b88de87candrewfish        } else if (AsciiStrnCmp (gInBuffer, "qAttached", 9) == 0) {
784969eba7b0df70c9aa261eaf005085568b88de87candrewfish          // remote server attached to an existing process
785969eba7b0df70c9aa261eaf005085568b88de87candrewfish          SendPacket ("1");
786969eba7b0df70c9aa261eaf005085568b88de87candrewfish        } else {
787969eba7b0df70c9aa261eaf005085568b88de87candrewfish          //Send empty packet
788969eba7b0df70c9aa261eaf005085568b88de87candrewfish          SendNotSupported ();
789969eba7b0df70c9aa261eaf005085568b88de87candrewfish        }
790969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
791969eba7b0df70c9aa261eaf005085568b88de87candrewfish
792969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 's':
7933402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron        SingleStep (SystemContext, gInBuffer);
794969eba7b0df70c9aa261eaf005085568b88de87candrewfish        return;
7953402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
796969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'z':
797969eba7b0df70c9aa261eaf005085568b88de87candrewfish        RemoveBreakPoint (SystemContext, gInBuffer);
798969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
7993402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
800969eba7b0df70c9aa261eaf005085568b88de87candrewfish      case 'Z':
801969eba7b0df70c9aa261eaf005085568b88de87candrewfish        InsertBreakPoint (SystemContext, gInBuffer);
802969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
8033402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
8043402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron      default:
805969eba7b0df70c9aa261eaf005085568b88de87candrewfish        //Send empty packet
806969eba7b0df70c9aa261eaf005085568b88de87candrewfish        SendNotSupported ();
807969eba7b0df70c9aa261eaf005085568b88de87candrewfish        break;
808969eba7b0df70c9aa261eaf005085568b88de87candrewfish    }
809969eba7b0df70c9aa261eaf005085568b88de87candrewfish  }
810969eba7b0df70c9aa261eaf005085568b88de87candrewfish}
811969eba7b0df70c9aa261eaf005085568b88de87candrewfish
812969eba7b0df70c9aa261eaf005085568b88de87candrewfish
813969eba7b0df70c9aa261eaf005085568b88de87candrewfish
814969eba7b0df70c9aa261eaf005085568b88de87candrewfish
815969eba7b0df70c9aa261eaf005085568b88de87candrewfish
816