1269f91e066c5991a4d4aa2945ea2c285f8589b12Greg Clayton//===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===//
2363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//
3363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//                     The LLVM Compiler Infrastructure
4363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//
5363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// This file is distributed under the University of Illinois Open Source
6363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// License. See LICENSE.TXT for details.
7363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//
8363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//===----------------------------------------------------------------------===//
9363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
10363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
11363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "CommunicationKDP.h"
12363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
13363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// C Includes
14fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda#include <errno.h>
15363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include <limits.h>
16363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include <string.h>
17363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
18363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// C++ Includes
190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton#include "llvm/Support/MachO.h"
200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
21363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// Other libraries and framework includes
22d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton#include "lldb/Core/DataBufferHeap.h"
231e5b02176d6952d0679479926fa557534313472bGreg Clayton#include "lldb/Core/DataExtractor.h"
24363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "lldb/Core/Log.h"
250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton#include "lldb/Core/State.h"
26fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda#include "lldb/Core/UUID.h"
27363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "lldb/Host/FileSpec.h"
28363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "lldb/Host/Host.h"
29363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "lldb/Host/TimeValue.h"
30363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "lldb/Target/Process.h"
31363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
32363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// Project includes
33363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton#include "ProcessKDPLog.h"
34363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
35363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonusing namespace lldb;
36363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonusing namespace lldb_private;
37363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
38363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//----------------------------------------------------------------------
39363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// CommunicationKDP constructor
40363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//----------------------------------------------------------------------
41363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg ClaytonCommunicationKDP::CommunicationKDP (const char *comm_name) :
42363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    Communication(comm_name),
430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    m_addr_byte_size (4),
44d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_byte_order (eByteOrderLittle),
4552fbbd224d4ba741d5f717e1683c5daa21fe8710Jason Molenda    m_packet_timeout (5),
46363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    m_sequence_mutex (Mutex::eMutexTypeRecursive),
473acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    m_is_running (false),
48d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_session_key (0u),
49d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_request_sequence_id (0u),
50d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_exception_sequence_id (0u),
51d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_version_version (0u),
52d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_version_feature (0u),
53d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_hostinfo_cpu_mask (0u),
54d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_hostinfo_cpu_type (0u),
55d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_hostinfo_cpu_subtype (0u)
56363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
57363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
58363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
59363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//----------------------------------------------------------------------
60363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton// Destructor
61363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton//----------------------------------------------------------------------
62363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg ClaytonCommunicationKDP::~CommunicationKDP()
63363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
64363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    if (IsConnected())
65363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    {
66363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        Disconnect();
67363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    }
68363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
69363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
701e5b02176d6952d0679479926fa557534313472bGreg Claytonbool
71d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet)
72363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
73363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    Mutex::Locker locker(m_sequence_mutex);
741e5b02176d6952d0679479926fa557534313472bGreg Clayton    return SendRequestPacketNoLock (request_packet);
75363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
76363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
77d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton#if 0
78d52d00f4edb746ba458a3e659699160952dc925eGreg Claytontypedef struct {
79d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton	uint8_t     request;	// Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply
80d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton	uint8_t     sequence;
81d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton	uint16_t    length;		// Length of entire packet including this header
82d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton	uint32_t	key;		// Session key
83d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton} kdp_hdr_t;
84d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton#endif
85d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
861e5b02176d6952d0679479926fa557534313472bGreg Claytonvoid
87307c7fdc58d19f734991a176db972cc61d9ada16Greg ClaytonCommunicationKDP::MakeRequestPacketHeader (CommandType request_type,
88d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                                           PacketStreamType &request_packet,
89d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                                           uint16_t request_length)
90363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
911e5b02176d6952d0679479926fa557534313472bGreg Clayton    request_packet.Clear();
92d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type
93d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    request_packet.PutHex8 (m_request_sequence_id++);           // Sequence number
94d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    request_packet.PutHex16 (request_length);                   // Length of the packet including this header
95d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    request_packet.PutHex32 (m_session_key);                    // Session key
96363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
97363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
98d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonbool
99d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::SendRequestAndGetReply (const CommandType command,
100d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton                                          const PacketStreamType &request_packet,
101d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                                          DataExtractor &reply_packet)
102d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
1033acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    if (IsRunning())
1043acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    {
105952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
1063acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton        if (log)
1073acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton        {
1083acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton            PacketStreamType log_strm;
1093acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton            DumpPacket (log_strm, request_packet.GetData(), request_packet.GetSize());
1103acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton            log->Printf("error: kdp running, not sending packet: %.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
1113acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton        }
1123acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton        return false;
1133acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    }
114d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
1153acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    Mutex::Locker locker(m_sequence_mutex);
1163acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton#ifdef LLDB_CONFIGURATION_DEBUG
1173acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    // NOTE: this only works for packets that are in native endian byte order
1183acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
1193acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton#endif
120d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    lldb::offset_t offset = 1;
121d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    const uint32_t num_retries = 3;
122d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    for (uint32_t i=0; i<num_retries; ++i)
123d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    {
124d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton        if (SendRequestPacketNoLock(request_packet))
125d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        {
126d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton            const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
1277efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton            while (1)
128d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            {
1297efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
1303acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                {
1317efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    offset = 0;
132ea4626053e22d06f145ccbf3b154cc04eea8e770Greg Clayton                    const uint8_t reply_command = reply_packet.GetU8 (&offset);
1337efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
134d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton                    if (request_sequence_id == reply_sequence_id)
135d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton                    {
1367efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        // The sequent ID was correct, now verify we got the response we were looking for
1377efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        if ((reply_command & eCommandTypeMask) == command)
1387efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        {
1397efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                            // Success
1407efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                            if (command == KDP_RESUMECPUS)
1417efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                                m_is_running.SetValue(true, eBroadcastAlways);
1427efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                            return true;
1437efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        }
1447efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        else
1457efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        {
1467efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                            // Failed to get the correct response, bail
1477efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                            reply_packet.Clear();
1487efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                            return false;
1497efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        }
150d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton                    }
1517efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    else if (reply_sequence_id > request_sequence_id)
1527efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    {
1537efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        // Sequence ID was greater than the sequence ID of the packet we sent, something
1547efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        // is really wrong...
1557efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        reply_packet.Clear();
1567efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        return false;
1577efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    }
1587efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    else
1597efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    {
1607efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        // The reply sequence ID was less than our current packet's sequence ID
1617efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        // so we should keep trying to get a response because this was a response
1627efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                        // for a previous packet that we must have retried.
1637efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    }
1647efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                }
1657efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                else
1667efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                {
1677efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    // Break and retry sending the packet as we didn't get a response due to timeout
1687efa0885bbb5c2cc57d30242f63c154f6a25d372Greg Clayton                    break;
1693acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                }
170d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            }
171d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        }
172d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    }
173d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    reply_packet.Clear();
174d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return false;
175d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
176363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
1771e5b02176d6952d0679479926fa557534313472bGreg Claytonbool
178d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet)
179363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
180363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    if (IsConnected())
181363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    {
1821e5b02176d6952d0679479926fa557534313472bGreg Clayton        const char *packet_data = request_packet.GetData();
1831e5b02176d6952d0679479926fa557534313472bGreg Clayton        const size_t packet_size = request_packet.GetSize();
184363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
185952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
186363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        if (log)
187363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        {
1880fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            PacketStreamType log_strm;
1890fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            DumpPacket (log_strm, packet_data, packet_size);
1900fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
191363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        }
1921e5b02176d6952d0679479926fa557534313472bGreg Clayton        ConnectionStatus status = eConnectionStatusSuccess;
193363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
1941e5b02176d6952d0679479926fa557534313472bGreg Clayton        size_t bytes_written = Write (packet_data,
1951e5b02176d6952d0679479926fa557534313472bGreg Clayton                                      packet_size,
1961e5b02176d6952d0679479926fa557534313472bGreg Clayton                                      status,
1971e5b02176d6952d0679479926fa557534313472bGreg Clayton                                      NULL);
1981e5b02176d6952d0679479926fa557534313472bGreg Clayton
1991e5b02176d6952d0679479926fa557534313472bGreg Clayton        if (bytes_written == packet_size)
2001e5b02176d6952d0679479926fa557534313472bGreg Clayton            return true;
2011e5b02176d6952d0679479926fa557534313472bGreg Clayton
2021e5b02176d6952d0679479926fa557534313472bGreg Clayton        if (log)
2035f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("error: failed to send packet entire packet %" PRIu64 " of %" PRIu64 " bytes sent", (uint64_t)bytes_written, (uint64_t)packet_size);
2041e5b02176d6952d0679479926fa557534313472bGreg Clayton    }
2051e5b02176d6952d0679479926fa557534313472bGreg Clayton    return false;
206363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
207363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
208363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonbool
209516f0849819d094d4eab39a1f27b770259103ff8Greg ClaytonCommunicationKDP::GetSequenceMutex (Mutex::Locker& locker)
210363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
2111b584ebc1de8b50fe375cffb5fb33ad13be10046Jim Ingham    return locker.TryLock (m_sequence_mutex);
212363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
213363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
214363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
215363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonbool
216363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg ClaytonCommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
217363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
2183acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    return m_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
219363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
220363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
221363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonsize_t
222d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec)
223363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
224363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    Mutex::Locker locker(m_sequence_mutex);
225363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
226363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
227363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
228363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonsize_t
229d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec)
230363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
231363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    uint8_t buffer[8192];
232363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    Error error;
233363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
234952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
235363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
236363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    // Check for a packet from our cache first without trying any reading...
237363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    if (CheckForPacket (NULL, 0, packet))
238d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        return packet.GetByteSize();
239363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
240363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    bool timed_out = false;
241363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    while (IsConnected() && !timed_out)
242363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    {
2431e3a522380565640ec900979b8532500bd3004c5Johnny Chen        lldb::ConnectionStatus status = eConnectionStatusNoConnection;
244363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
245363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
246363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        if (log)
2475f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
248363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                         __PRETTY_FUNCTION__,
249363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                         timeout_usec,
250363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                         Communication::ConnectionStatusAsCString (status),
251363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                         error.AsCString(),
252851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton                         (uint64_t)bytes_read);
253363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
254363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        if (bytes_read > 0)
255363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        {
256363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            if (CheckForPacket (buffer, bytes_read, packet))
257d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                return packet.GetByteSize();
258363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        }
259363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        else
260363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        {
261363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            switch (status)
262363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            {
263363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            case eConnectionStatusTimedOut:
264363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                timed_out = true;
265363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                break;
266363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            case eConnectionStatusSuccess:
267363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
268363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                break;
269363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
270363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            case eConnectionStatusEndOfFile:
271363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            case eConnectionStatusNoConnection:
272363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            case eConnectionStatusLostConnection:
273363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            case eConnectionStatusError:
274363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                Disconnect();
275363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                break;
276363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton            }
277363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        }
278363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    }
279363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    packet.Clear ();
280363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    return 0;
281363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
282363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
283363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Claytonbool
284d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
285363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton{
286363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    // Put the packet data into the buffer in a thread safe fashion
287363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    Mutex::Locker locker(m_bytes_mutex);
288363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
289952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
290363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
291363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    if (src && src_len > 0)
292363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    {
293363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        if (log && log->GetVerbose())
294363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        {
295d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            PacketStreamType log_strm;
2968d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton            DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
297d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
298363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                         __FUNCTION__,
299363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton                         (uint32_t)src_len,
300d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                         log_strm.GetData());
301363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        }
302363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton        m_bytes.append ((const char *)src, src_len);
303363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    }
304363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
305d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    // Make sure we at least have enough bytes for a packet header
306d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    const size_t bytes_available = m_bytes.size();
307d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    if (bytes_available >= 8)
308363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    {
309d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
31036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 0;
311d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        uint8_t reply_command = packet.GetU8(&offset);
312d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        switch (reply_command)
313d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        {
314ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton        case ePacketTypeRequest | KDP_EXCEPTION:
315ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton        case ePacketTypeRequest | KDP_TERMINATION:
316ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton            // We got an exception request, so be sure to send an ACK
317ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton            {
318ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                PacketStreamType request_ack_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
319ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                // Set the reply but and make the ACK packet
320ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                request_ack_packet.PutHex8 (reply_command | ePacketTypeReply);
321ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                request_ack_packet.PutHex8 (packet.GetU8(&offset));
322ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                request_ack_packet.PutHex16 (packet.GetU16(&offset));
323ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                request_ack_packet.PutHex32 (packet.GetU32(&offset));
3243acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                m_is_running.SetValue(false, eBroadcastAlways);
325ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                // Ack to the exception or termination
326ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                SendRequestPacketNoLock (request_ack_packet);
327ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton            }
328ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton            // Fall through to case below to get packet contents
3297b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_CONNECT:
3307b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_DISCONNECT:
3317b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_HOSTINFO:
3327b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_VERSION:
3337b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_MAXBYTES:
3347b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_READMEM:
3357b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_WRITEMEM:
3367b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_READREGS:
3377b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_WRITEREGS:
3387b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_LOAD:
3397b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_IMAGEPATH:
3407b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_SUSPEND:
3417b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_RESUMECPUS:
3427b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_BREAKPOINT_SET:
3437b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
3447b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_REGIONS:
3457b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_REATTACH:
3467b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_HOSTREBOOT:
3477b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_READMEM64:
3487b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_WRITEMEM64:
3497b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_BREAKPOINT_SET64:
3507b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
3517b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        case ePacketTypeReply | KDP_KERNELVERSION:
352cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        case ePacketTypeReply | KDP_READPHYSMEM64:
353cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        case ePacketTypeReply | KDP_WRITEPHYSMEM64:
354cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        case ePacketTypeReply | KDP_READIOPORT:
355cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        case ePacketTypeReply | KDP_WRITEIOPORT:
356cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        case ePacketTypeReply | KDP_READMSR64:
357cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        case ePacketTypeReply | KDP_WRITEMSR64:
358cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        case ePacketTypeReply | KDP_DUMPINFO:
359d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            {
360d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                offset = 2;
361d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                const uint16_t length = packet.GetU16 (&offset);
362d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                if (length <= bytes_available)
363d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                {
364d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                    // We have an entire packet ready, we need to copy the data
365d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                    // bytes into a buffer that will be owned by the packet and
366d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                    // erase the bytes from our communcation buffer "m_bytes"
367d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                    packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
368d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                    m_bytes.erase (0, length);
3698d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton
3708d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton                    if (log)
3718d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton                    {
3728d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton                        PacketStreamType log_strm;
3730fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        DumpPacket (log_strm, packet);
3748d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton
3750fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
3768d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton                    }
377d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                    return true;
378d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                }
379d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            }
380d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            break;
381d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
382d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        default:
383d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            // Unrecognized reply command byte, erase this byte and try to get back on track
384d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            if (log)
385d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
386d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                             __FUNCTION__,
387d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton                             (uint8_t)m_bytes[0]);
388d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            m_bytes.erase(0, 1);
389d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton            break;
390d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        }
391363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    }
392363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    packet.Clear();
393363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton    return false;
394363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton}
395363be3fc515bea8baf2c5031f3c62f6326d9e1b8Greg Clayton
3961e5b02176d6952d0679479926fa557534313472bGreg Clayton
397d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonbool
3988d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg ClaytonCommunicationKDP::SendRequestConnect (uint16_t reply_port,
3998d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton                                      uint16_t exc_port,
4008d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton                                      const char *greeting)
4011e5b02176d6952d0679479926fa557534313472bGreg Clayton{
4020fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
403d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    if (greeting == NULL)
404d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        greeting = "";
405d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
4067b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_CONNECT;
4078d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
4088d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
409d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
4108d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    // Always send connect ports as little endian
4118d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    request_packet.SetByteOrder (eByteOrderLittle);
4128d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    request_packet.PutHex16 (reply_port);
4138d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    request_packet.PutHex16 (exc_port);
4148d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    request_packet.SetByteOrder (m_byte_order);
4158d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    request_packet.PutCString (greeting);
416d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    DataExtractor reply_packet;
417d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    return SendRequestAndGetReply (command, request_packet, reply_packet);
418d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
419d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
420d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonvoid
421d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::ClearKDPSettings ()
422d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
423d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_request_sequence_id = 0;
424d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_version_version = 0;
425d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_version_feature = 0;
426d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_hostinfo_cpu_mask = 0;
427d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_hostinfo_cpu_type = 0;
428d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    m_kdp_hostinfo_cpu_subtype = 0;
429d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
430d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
431d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonbool
4328d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg ClaytonCommunicationKDP::SendRequestReattach (uint16_t reply_port)
433d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
4340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
4357b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_REATTACH;
436d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
437d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    const uint32_t command_length = 8 + 2;
438d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
4398d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    // Always send connect ports as little endian
4408d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    request_packet.SetByteOrder (eByteOrderLittle);
441d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    request_packet.PutHex16(reply_port);
4428d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg Clayton    request_packet.SetByteOrder (m_byte_order);
443d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    DataExtractor reply_packet;
444d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
445d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    {
446d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        // Reset the sequence ID to zero for reattach
447d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        ClearKDPSettings ();
44836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 4;
449d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        m_session_key = reply_packet.GetU32 (&offset);
450d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        return true;
451d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    }
452d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return false;
4531e5b02176d6952d0679479926fa557534313472bGreg Clayton}
4541e5b02176d6952d0679479926fa557534313472bGreg Clayton
455d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonuint32_t
456d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::GetVersion ()
457d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
458d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    if (!VersionIsValid())
459d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        SendRequestVersion();
460d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return m_kdp_version_version;
461d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
462d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
463d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonuint32_t
464d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::GetFeatureFlags ()
465d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
466d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    if (!VersionIsValid())
467d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        SendRequestVersion();
468d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return m_kdp_version_feature;
469d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
470d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
471d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonbool
472d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::SendRequestVersion ()
473d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
4740fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
4757b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_VERSION;
476d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    const uint32_t command_length = 8;
477d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
478d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    DataExtractor reply_packet;
479d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
480d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    {
48136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
482d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        m_kdp_version_version = reply_packet.GetU32 (&offset);
483d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        m_kdp_version_feature = reply_packet.GetU32 (&offset);
484d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        return true;
485d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    }
486d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return false;
487d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
488d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
4897b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton#if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
4907b13922c3c6b55225fa8403762c0399e9692b730Greg Claytonconst char *
4917b13922c3c6b55225fa8403762c0399e9692b730Greg ClaytonCommunicationKDP::GetImagePath ()
4927b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton{
4937b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    if (m_image_path.empty())
4947b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        SendRequestImagePath();
4957b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    return m_image_path.c_str();
4967b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton}
4977b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton
4987b13922c3c6b55225fa8403762c0399e9692b730Greg Claytonbool
4997b13922c3c6b55225fa8403762c0399e9692b730Greg ClaytonCommunicationKDP::SendRequestImagePath ()
5007b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton{
5017b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
5027b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_IMAGEPATH;
5037b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const uint32_t command_length = 8;
5047b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
5057b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    DataExtractor reply_packet;
506d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
5077b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    {
5087b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        const char *path = reply_packet.PeekCStr(8);
5097b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        if (path && path[0])
5107b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton            m_kernel_version.assign (path);
5117b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton        return true;
5127b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    }
5137b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    return false;
5147b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton}
5157b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton#endif
5167b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton
517d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonuint32_t
518d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::GetCPUMask ()
519d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
520d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    if (!HostInfoIsValid())
521d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        SendRequestHostInfo();
522d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return m_kdp_hostinfo_cpu_mask;
523d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
524d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
525d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonuint32_t
526d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::GetCPUType ()
527d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
528d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    if (!HostInfoIsValid())
529d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        SendRequestHostInfo();
530d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return m_kdp_hostinfo_cpu_type;
531d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
532d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
533d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonuint32_t
534d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::GetCPUSubtype ()
535d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
536d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    if (!HostInfoIsValid())
537d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        SendRequestHostInfo();
538d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return m_kdp_hostinfo_cpu_subtype;
539d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
540d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
541fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molendalldb_private::UUID
542fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason MolendaCommunicationKDP::GetUUID ()
543fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda{
544fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    UUID uuid;
545fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (GetKernelVersion() == NULL)
546fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return uuid;
547fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
548fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (m_kernel_version.find("UUID=") == std::string::npos)
549fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return uuid;
550fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
551fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    size_t p = m_kernel_version.find("UUID=") + strlen ("UUID=");
552fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    std::string uuid_str = m_kernel_version.substr(p, 36);
553fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (uuid_str.size() < 32)
554fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return uuid;
555fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
556fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (uuid.SetFromCString (uuid_str.c_str()) == 0)
557fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    {
558fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        UUID invalid_uuid;
559fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return invalid_uuid;
560fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    }
561fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
562fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    return uuid;
563fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda}
564fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
565d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molendabool
566d06bb5007b310b5498f7c47006022561ce1ceb4dJason MolendaCommunicationKDP::RemoteIsEFI ()
567d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda{
568d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda    if (GetKernelVersion() == NULL)
569d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda        return false;
570d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda    if (strncmp (m_kernel_version.c_str(), "EFI", 3) == 0)
571d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda        return true;
572d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda    else
573d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda        return false;
574d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda}
575d06bb5007b310b5498f7c47006022561ce1ceb4dJason Molenda
5766c32437e2255db9089ee00cd70b474676d09ab6eJason Molendabool
5776c32437e2255db9089ee00cd70b474676d09ab6eJason MolendaCommunicationKDP::RemoteIsDarwinKernel ()
5786c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda{
5796c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda    if (GetKernelVersion() == NULL)
5806c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda        return false;
5816c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda    if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
5826c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda        return true;
5836c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda    else
5846c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda        return false;
5856c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda}
5866c32437e2255db9089ee00cd70b474676d09ab6eJason Molenda
587fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molendalldb::addr_t
588fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason MolendaCommunicationKDP::GetLoadAddress ()
589fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda{
590fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (GetKernelVersion() == NULL)
591fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return LLDB_INVALID_ADDRESS;
592fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
593fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (m_kernel_version.find("stext=") == std::string::npos)
594fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return LLDB_INVALID_ADDRESS;
595fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    size_t p = m_kernel_version.find("stext=") + strlen ("stext=");
596fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
597fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return LLDB_INVALID_ADDRESS;
598fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
599fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    addr_t kernel_load_address;
600fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    errno = 0;
601fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    kernel_load_address = ::strtoul (m_kernel_version.c_str() + p, NULL, 16);
602fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    if (errno != 0 || kernel_load_address == 0)
603fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda        return LLDB_INVALID_ADDRESS;
604fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
605fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda    return kernel_load_address;
606fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda}
607fac2e62f08719ba800a440b7ad0d5a55a26dc620Jason Molenda
608d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonbool
609d52d00f4edb746ba458a3e659699160952dc925eGreg ClaytonCommunicationKDP::SendRequestHostInfo ()
610d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton{
6110fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
6127b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_HOSTINFO;
613d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    const uint32_t command_length = 8;
614d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
615d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    DataExtractor reply_packet;
616d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
617d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    {
61836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
6190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        m_kdp_hostinfo_cpu_mask     = reply_packet.GetU32 (&offset);
6200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        m_kdp_hostinfo_cpu_type     = reply_packet.GetU32 (&offset);
6210fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        m_kdp_hostinfo_cpu_subtype  = reply_packet.GetU32 (&offset);
6220fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
6230fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        ArchSpec kernel_arch;
6240fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        kernel_arch.SetArchitecture (eArchTypeMachO,
6250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                     m_kdp_hostinfo_cpu_type,
6260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                     m_kdp_hostinfo_cpu_subtype);
6270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
6280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        m_addr_byte_size = kernel_arch.GetAddressByteSize();
6290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        m_byte_order = kernel_arch.GetByteOrder();
630d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        return true;
631d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    }
632d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return false;
633d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton}
634d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton
635234981a4559db084f9c90612660e40f19915b89cGreg Claytonconst char *
636234981a4559db084f9c90612660e40f19915b89cGreg ClaytonCommunicationKDP::GetKernelVersion ()
637234981a4559db084f9c90612660e40f19915b89cGreg Clayton{
638234981a4559db084f9c90612660e40f19915b89cGreg Clayton    if (m_kernel_version.empty())
639234981a4559db084f9c90612660e40f19915b89cGreg Clayton        SendRequestKernelVersion ();
640234981a4559db084f9c90612660e40f19915b89cGreg Clayton    return m_kernel_version.c_str();
641234981a4559db084f9c90612660e40f19915b89cGreg Clayton}
642234981a4559db084f9c90612660e40f19915b89cGreg Clayton
643234981a4559db084f9c90612660e40f19915b89cGreg Claytonbool
644234981a4559db084f9c90612660e40f19915b89cGreg ClaytonCommunicationKDP::SendRequestKernelVersion ()
645234981a4559db084f9c90612660e40f19915b89cGreg Clayton{
646234981a4559db084f9c90612660e40f19915b89cGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
6477b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_KERNELVERSION;
648234981a4559db084f9c90612660e40f19915b89cGreg Clayton    const uint32_t command_length = 8;
649234981a4559db084f9c90612660e40f19915b89cGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
650234981a4559db084f9c90612660e40f19915b89cGreg Clayton    DataExtractor reply_packet;
651d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
652234981a4559db084f9c90612660e40f19915b89cGreg Clayton    {
653234981a4559db084f9c90612660e40f19915b89cGreg Clayton        const char *kernel_version_cstr = reply_packet.PeekCStr(8);
654234981a4559db084f9c90612660e40f19915b89cGreg Clayton        if (kernel_version_cstr && kernel_version_cstr[0])
655234981a4559db084f9c90612660e40f19915b89cGreg Clayton            m_kernel_version.assign (kernel_version_cstr);
656234981a4559db084f9c90612660e40f19915b89cGreg Clayton        return true;
657234981a4559db084f9c90612660e40f19915b89cGreg Clayton    }
658234981a4559db084f9c90612660e40f19915b89cGreg Clayton    return false;
659234981a4559db084f9c90612660e40f19915b89cGreg Clayton}
660234981a4559db084f9c90612660e40f19915b89cGreg Clayton
661d52d00f4edb746ba458a3e659699160952dc925eGreg Claytonbool
6628d2ea2888a4acb7f140f9af64ddd2b16b2dee870Greg ClaytonCommunicationKDP::SendRequestDisconnect ()
6631e5b02176d6952d0679479926fa557534313472bGreg Clayton{
6640fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
6657b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_DISCONNECT;
666d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    const uint32_t command_length = 8;
667d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
668d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    DataExtractor reply_packet;
669d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
670d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    {
671d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton        // Are we supposed to get a reply for disconnect?
672d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    }
673d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    ClearKDPSettings ();
674d52d00f4edb746ba458a3e659699160952dc925eGreg Clayton    return true;
6751e5b02176d6952d0679479926fa557534313472bGreg Clayton}
6761e5b02176d6952d0679479926fa557534313472bGreg Clayton
6770fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Claytonuint32_t
6780fa512447e00da09d300fbabd18b5ce94f52fdaaGreg ClaytonCommunicationKDP::SendRequestReadMemory (lldb::addr_t addr,
6790fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                         void *dst,
6800fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                         uint32_t dst_len,
6810fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                         Error &error)
6820fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton{
6830fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
6840fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    bool use_64 = (GetVersion() >= 11);
6850fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    uint32_t command_addr_byte_size = use_64 ? 8 : 4;
6867b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
6870fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    // Size is header + address size + uint32_t length
6880fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    const uint32_t command_length = 8 + command_addr_byte_size + 4;
6890fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
6900fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    request_packet.PutMaxHex64 (addr, command_addr_byte_size);
6910fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    request_packet.PutHex32 (dst_len);
6920fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    DataExtractor reply_packet;
693d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
6940fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    {
69536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
6960fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        uint32_t kdp_error = reply_packet.GetU32 (&offset);
6970fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        uint32_t src_len = reply_packet.GetByteSize() - 12;
6980fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
6990fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        if (src_len > 0)
7000fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        {
7010fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            const void *src = reply_packet.GetData(&offset, src_len);
7020fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            if (src)
7030fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            {
7040fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                ::memcpy (dst, src, src_len);
7050fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                error.Clear();
7060fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                return src_len;
7070fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            }
7080fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        }
7090fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        if (kdp_error)
7100fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            error.SetErrorStringWithFormat ("kdp read memory failed (error %u)", kdp_error);
7110fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        else
7120fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            error.SetErrorString ("kdp read memory failed");
7130fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    }
714307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    else
715307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    {
716307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        error.SetErrorString ("failed to send packet");
717307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    }
7180fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    return 0;
7190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton}
7200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
721ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
722ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Claytonuint32_t
723ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg ClaytonCommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr,
724ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                          const void *src,
725ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                          uint32_t src_len,
726ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                          Error &error)
727ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton{
728ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
729ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    bool use_64 = (GetVersion() >= 11);
730ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    uint32_t command_addr_byte_size = use_64 ? 8 : 4;
7317b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
732ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    // Size is header + address size + uint32_t length
733fe3150f2d6f2dc0ae81ed5f59acc10197024be2dGreg Clayton    const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
734ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
735ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    request_packet.PutMaxHex64 (addr, command_addr_byte_size);
736ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    request_packet.PutHex32 (src_len);
73762377463542bd94bbec63bd374233fab0b9d7c0cJason Molenda    request_packet.PutRawBytes(src, src_len);
738ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
739ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    DataExtractor reply_packet;
740d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
741ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    {
74236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
743ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton        uint32_t kdp_error = reply_packet.GetU32 (&offset);
744ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton        if (kdp_error)
745ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton            error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error);
746ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton        else
747ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton        {
748ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton            error.Clear();
749ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton            return src_len;
750ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton        }
751ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    }
752307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    else
753307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    {
754307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        error.SetErrorString ("failed to send packet");
755307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    }
756ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton    return 0;
757ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton}
758ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
759307c7fdc58d19f734991a176db972cc61d9ada16Greg Claytonbool
760307c7fdc58d19f734991a176db972cc61d9ada16Greg ClaytonCommunicationKDP::SendRawRequest (uint8_t command_byte,
761307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton                                  const void *src,  // Raw packet payload bytes
762307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton                                  uint32_t src_len, // Raw packet payload length
763307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton                                  DataExtractor &reply_packet,
764307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton                                  Error &error)
765307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton{
766307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
767307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    // Size is header + address size + uint32_t length
768307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    const uint32_t command_length = 8 + src_len;
769307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    const CommandType command = (CommandType)command_byte;
770307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
771307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    request_packet.PutRawBytes(src, src_len);
772307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton
773d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
774307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    {
77536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
776307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        uint32_t kdp_error = reply_packet.GetU32 (&offset);
777cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda        if (kdp_error  && (command_byte != KDP_DUMPINFO))
778307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton            error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error);
779307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        else
780307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        {
781307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton            error.Clear();
782307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton            return true;
783307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        }
784307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    }
785307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    else
786307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    {
787307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        error.SetErrorString ("failed to send packet");
788307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    }
789307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    return false;
790307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton}
791307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton
792307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton
7930fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Claytonconst char *
7940fa512447e00da09d300fbabd18b5ce94f52fdaaGreg ClaytonCommunicationKDP::GetCommandAsCString (uint8_t command)
7950fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton{
7960fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    switch (command)
7970fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    {
7987b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_CONNECT:               return "KDP_CONNECT";
7997b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_DISCONNECT:            return "KDP_DISCONNECT";
8007b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_HOSTINFO:              return "KDP_HOSTINFO";
8017b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_VERSION:               return "KDP_VERSION";
8027b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_MAXBYTES:              return "KDP_MAXBYTES";
8037b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_READMEM:               return "KDP_READMEM";
8047b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_WRITEMEM:              return "KDP_WRITEMEM";
8057b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_READREGS:              return "KDP_READREGS";
8067b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_WRITEREGS:             return "KDP_WRITEREGS";
8077b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_LOAD:                  return "KDP_LOAD";
8087b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_IMAGEPATH:             return "KDP_IMAGEPATH";
8097b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_SUSPEND:               return "KDP_SUSPEND";
8107b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_RESUMECPUS:            return "KDP_RESUMECPUS";
8117b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_EXCEPTION:             return "KDP_EXCEPTION";
8127b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_TERMINATION:           return "KDP_TERMINATION";
8137b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_BREAKPOINT_SET:        return "KDP_BREAKPOINT_SET";
8147b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_BREAKPOINT_REMOVE:     return "KDP_BREAKPOINT_REMOVE";
8157b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_REGIONS:               return "KDP_REGIONS";
8167b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_REATTACH:              return "KDP_REATTACH";
8177b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_HOSTREBOOT:            return "KDP_HOSTREBOOT";
8187b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_READMEM64:             return "KDP_READMEM64";
8197b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_WRITEMEM64:            return "KDP_WRITEMEM64";
8207b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_BREAKPOINT_SET64:      return "KDP_BREAKPOINT64_SET";
8217b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_BREAKPOINT_REMOVE64:   return "KDP_BREAKPOINT64_REMOVE";
8227b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    case KDP_KERNELVERSION:         return "KDP_KERNELVERSION";
823cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda    case KDP_READPHYSMEM64:         return "KDP_READPHYSMEM64";
824cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda    case KDP_WRITEPHYSMEM64:        return "KDP_WRITEPHYSMEM64";
825cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda    case KDP_READIOPORT:            return "KDP_READIOPORT";
826cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda    case KDP_WRITEIOPORT:           return "KDP_WRITEIOPORT";
827cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda    case KDP_READMSR64:             return "KDP_READMSR64";
828cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda    case KDP_WRITEMSR64:            return "KDP_WRITEMSR64";
829cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda    case KDP_DUMPINFO:              return "KDP_DUMPINFO";
8300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    }
8310fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    return NULL;
8320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton}
8330fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
8340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Claytonvoid
8350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg ClaytonCommunicationKDP::DumpPacket (Stream &s, const void *data, uint32_t data_len)
8360fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton{
8370fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    DataExtractor extractor (data, data_len, m_byte_order, m_addr_byte_size);
8380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    DumpPacket (s, extractor);
8390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton}
8400fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
8410fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Claytonvoid
8420fa512447e00da09d300fbabd18b5ce94f52fdaaGreg ClaytonCommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet)
8430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton{
8440fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    const char *error_desc = NULL;
8450fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    if (packet.GetByteSize() < 8)
8460fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    {
8470fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        error_desc = "error: invalid packet (too short): ";
8480fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    }
8490fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    else
8500fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    {
85136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 0;
8520fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        const uint8_t first_packet_byte = packet.GetU8 (&offset);
8530fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        const uint8_t sequence_id = packet.GetU8 (&offset);
8540fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        const uint16_t length = packet.GetU16 (&offset);
8550fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        const uint32_t key = packet.GetU32 (&offset);
8560fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        const CommandType command = ExtractCommand (first_packet_byte);
8570fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        const char *command_name = GetCommandAsCString (command);
8580fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        if (command_name)
8590fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        {
8600fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            const bool is_reply = ExtractIsReply(first_packet_byte);
8613acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton            s.Printf ("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
8623acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                      IsRunning(),
8633acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                      is_reply ? "<--" : "-->",
8643acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                      command_name,
8653acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                      first_packet_byte,
8660fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                      sequence_id,
8670fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                      length,
8683acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                      key);
8690fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
8700fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            if (is_reply)
8710fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            {
8720fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                // Dump request reply packets
8730fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                switch (command)
8740fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                {
875ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                    // Commands that return a single 32 bit error
8767b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_CONNECT:
8777b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_WRITEMEM:
8787b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_WRITEMEM64:
8797b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_SET:
8807b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_REMOVE:
8817b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_SET64:
8827b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_REMOVE64:
8837b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_WRITEREGS:
8847b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_LOAD:
885cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_WRITEIOPORT:
886cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_WRITEMSR64:
8870fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
8880fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t error = packet.GetU32 (&offset);
8890fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            s.Printf(" (error=0x%8.8x)", error);
8900fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
8910fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
8920fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
8937b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_DISCONNECT:
8947b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_REATTACH:
8957b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_HOSTREBOOT:
8967b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_SUSPEND:
8977b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_RESUMECPUS:
8987b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_EXCEPTION:
8997b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_TERMINATION:
9000fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        // No return value for the reply, just the header to ack
901ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        s.PutCString(" ()");
9020fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
9030fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
9047b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_HOSTINFO:
9050fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
9060fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t cpu_mask = packet.GetU32 (&offset);
9070fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t cpu_type = packet.GetU32 (&offset);
9080fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t cpu_subtype = packet.GetU32 (&offset);
9090fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype);
9100fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
9110fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
9120fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
9137b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_VERSION:
9140fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
9150fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t version = packet.GetU32 (&offset);
9160fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t feature = packet.GetU32 (&offset);
9170fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
9180fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
9190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
9200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
9217b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_REGIONS:
9220fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
9230fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t region_count = packet.GetU32 (&offset);
9240fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            s.Printf(" (count = %u", region_count);
9250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            for (uint32_t i=0; i<region_count; ++i)
9260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            {
9270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                const addr_t region_addr = packet.GetPointer (&offset);
9280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                const uint32_t region_size = packet.GetU32 (&offset);
9290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                const uint32_t region_prot = packet.GetU32 (&offset);
9305f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                                s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
9310fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            }
9320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
9330fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
9340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
9357b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_READMEM:
9367b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_READMEM64:
937cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_READPHYSMEM64:
9380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
9390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t error = packet.GetU32 (&offset);
940ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t count = packet.GetByteSize() - offset;
9411bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (error = 0x%8.8x:\n", error);
9420fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            if (count > 0)
943234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                packet.Dump (&s,                        // Stream to dump to
944234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                             offset,                    // Offset within "packet"
945234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                             eFormatBytesWithASCII,     // Format to use
946234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                             1,                         // Size of each item in bytes
947234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                             count,                     // Number of items
948234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                             16,                        // Number per line
949234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                             m_last_read_memory_addr,   // Don't show addresses before each line
950234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                             0, 0);                     // No bitfields
9510fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
9520fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
9530fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
9547b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_READREGS:
955ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        {
956ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t error = packet.GetU32 (&offset);
957ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t count = packet.GetByteSize() - offset;
9581bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (error = 0x%8.8x regs:\n", error);
959ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            if (count > 0)
960ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                packet.Dump (&s,                        // Stream to dump to
961ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             offset,                    // Offset within "packet"
962ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             eFormatHex,                // Format to use
963ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             m_addr_byte_size,          // Size of each item in bytes
964ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             count / m_addr_byte_size,  // Number of items
965ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             16 / m_addr_byte_size,     // Number per line
966ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
967ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             0, 0);                     // No bitfields
968ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        }
969ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        break;
970ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
9717b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_KERNELVERSION:
972234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
973234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const char *kernel_version = packet.PeekCStr(8);
974234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            s.Printf(" (version = \"%s\")", kernel_version);
975234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
976234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
977234981a4559db084f9c90612660e40f19915b89cGreg Clayton
9787b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_MAXBYTES:
979234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
980234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const uint32_t max_bytes = packet.GetU32 (&offset);
981234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
982234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
983234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
9847b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_IMAGEPATH:
985234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
986234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const char *path = packet.GetCStr(&offset);
987234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            s.Printf(" (path = \"%s\")", path);
988234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
989234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
990cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
991cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_READIOPORT:
992cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_READMSR64:
993cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
994cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t error = packet.GetU32 (&offset);
995cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t count = packet.GetByteSize() - offset;
996cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (error = 0x%8.8x io:\n", error);
997cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            if (count > 0)
998cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                packet.Dump (&s,                        // Stream to dump to
999cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             offset,                    // Offset within "packet"
1000cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             eFormatHex,                // Format to use
1001cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             1,                         // Size of each item in bytes
1002cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             count,                     // Number of items
1003cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             16,                        // Number per line
1004cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1005cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             0, 0);                     // No bitfields
1006cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1007cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1008cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_DUMPINFO:
1009cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
1010cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t count = packet.GetByteSize() - offset;
1011cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (count = %u, bytes = \n", count);
1012cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            if (count > 0)
1013cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                packet.Dump (&s,                        // Stream to dump to
1014cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             offset,                    // Offset within "packet"
1015cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             eFormatHex,                // Format to use
1016cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             1,                         // Size of each item in bytes
1017cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             count,                     // Number of items
1018cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             16,                        // Number per line
1019cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1020cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             0, 0);                     // No bitfields
1021cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1022cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1023cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1024cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1025234981a4559db084f9c90612660e40f19915b89cGreg Clayton                    default:
1026ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        s.Printf(" (add support for dumping this packet reply!!!");
10270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
10280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
10290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                }
10300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            }
10310fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            else
10320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            {
10330fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                // Dump request packets
10340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                switch (command)
10350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                {
10367b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_CONNECT:
10370fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
10380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint16_t reply_port = packet.GetU16 (&offset);
10390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint16_t exc_port = packet.GetU16 (&offset);
10401bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset));
10410fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
10420fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
10430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
10447b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_DISCONNECT:
10457b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_HOSTREBOOT:
10467b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_HOSTINFO:
10477b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_VERSION:
10487b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_REGIONS:
10497b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_KERNELVERSION:
10507b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_MAXBYTES:
10517b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_IMAGEPATH:
10527b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_SUSPEND:
10530fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        // No args, just the header in the request...
1054234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        s.PutCString(" ()");
1055234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
1056234981a4559db084f9c90612660e40f19915b89cGreg Clayton
10577b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_RESUMECPUS:
1058234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
1059234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const uint32_t cpu_mask = packet.GetU32 (&offset);
1060234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
1061234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
10620fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
10630fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
10647b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_READMEM:
10650fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
10660fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t addr = packet.GetU32 (&offset);
10670fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t size = packet.GetU32 (&offset);
10681bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
1069234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            m_last_read_memory_addr = addr;
10700fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
10710fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
10720fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
10737b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_WRITEMEM:
1074ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        {
1075ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t addr = packet.GetU32 (&offset);
1076ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t size = packet.GetU32 (&offset);
10771bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
1078ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            if (size > 0)
1079ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
1080ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        }
1081ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        break;
1082ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
10837b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_READMEM64:
10840fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
10850fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint64_t addr = packet.GetU64 (&offset);
10860fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t size = packet.GetU32 (&offset);
10875f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                            s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
1088234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            m_last_read_memory_addr = addr;
10890fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
10900fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
10910fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
1092cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_READPHYSMEM64:
1093cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
1094cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint64_t addr = packet.GetU64 (&offset);
1095cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t size = packet.GetU32 (&offset);
1096cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t lcpu = packet.GetU16 (&offset);
1097cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu);
1098cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            m_last_read_memory_addr = addr;
1099cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1100cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1101cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
11027b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_WRITEMEM64:
1103ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        {
1104ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint64_t addr = packet.GetU64 (&offset);
1105ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t size = packet.GetU32 (&offset);
11065f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                            s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, size);
1107ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            if (size > 0)
1108ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
1109ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        }
1110ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        break;
1111ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
1112cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_WRITEPHYSMEM64:
1113cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
1114cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint64_t addr = packet.GetU64 (&offset);
1115cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t size = packet.GetU32 (&offset);
1116cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t lcpu = packet.GetU16 (&offset);
1117cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu);
1118cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            if (size > 0)
1119cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
1120cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1121cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1122cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
11237b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_READREGS:
11240fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
11250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t cpu = packet.GetU32 (&offset);
11260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint32_t flavor = packet.GetU32 (&offset);
11271bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
11280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
11290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
11300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
11317b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_WRITEREGS:
1132ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        {
1133ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t cpu = packet.GetU32 (&offset);
1134ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t flavor = packet.GetU32 (&offset);
1135ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            const uint32_t nbytes = packet.GetByteSize() - offset;
11361bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
1137ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                            if (nbytes > 0)
1138ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                packet.Dump (&s,                        // Stream to dump to
1139ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             offset,                    // Offset within "packet"
1140ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             eFormatHex,                // Format to use
1141ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             m_addr_byte_size,          // Size of each item in bytes
1142ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             nbytes / m_addr_byte_size, // Number of items
1143ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             16 / m_addr_byte_size,     // Number per line
1144ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1145ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                                             0, 0);                     // No bitfields
1146ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        }
1147ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton                        break;
1148ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
1149234981a4559db084f9c90612660e40f19915b89cGreg Clayton
11507b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_SET:
11517b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_REMOVE:
1152234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
1153234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const uint32_t addr = packet.GetU32 (&offset);
1154234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            s.Printf(" (addr = 0x%8.8x)", addr);
1155234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
1156234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
1157234981a4559db084f9c90612660e40f19915b89cGreg Clayton
11587b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_SET64:
11597b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_BREAKPOINT_REMOVE64:
1160234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
1161234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const uint64_t addr = packet.GetU64 (&offset);
11625f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                            s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
1163234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
1164234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
1165234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1166ec15f50fdd7011fc155ab4fe71d4887ffe31df4eGreg Clayton
11677b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_LOAD:
1168234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
1169234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const char *path = packet.GetCStr(&offset);
1170234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            s.Printf(" (path = \"%s\")", path);
1171234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
1172234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
1173234981a4559db084f9c90612660e40f19915b89cGreg Clayton
11747b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_EXCEPTION:
1175234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
1176234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const uint32_t count = packet.GetU32 (&offset);
1177234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1178234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            for (uint32_t i=0; i<count; ++i)
1179234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            {
1180234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                const uint32_t cpu = packet.GetU32 (&offset);
1181234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                const uint32_t exc = packet.GetU32 (&offset);
1182234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                const uint32_t code = packet.GetU32 (&offset);
1183234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                const uint32_t subcode = packet.GetU32 (&offset);
1184234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                const char *exc_cstr = NULL;
1185234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                switch (exc)
1186234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                {
1187234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 1:  exc_cstr = "EXC_BAD_ACCESS"; break;
1188234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 2:  exc_cstr = "EXC_BAD_INSTRUCTION"; break;
1189234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 3:  exc_cstr = "EXC_ARITHMETIC"; break;
1190234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 4:  exc_cstr = "EXC_EMULATION"; break;
1191234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 5:  exc_cstr = "EXC_SOFTWARE"; break;
1192234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 6:  exc_cstr = "EXC_BREAKPOINT"; break;
1193234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 7:  exc_cstr = "EXC_SYSCALL"; break;
1194234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 8:  exc_cstr = "EXC_MACH_SYSCALL"; break;
1195234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 9:  exc_cstr = "EXC_RPC_ALERT"; break;
1196234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    case 10: exc_cstr = "EXC_CRASH"; break;
1197234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                    default:
1198234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                        break;
1199234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                }
1200234981a4559db084f9c90612660e40f19915b89cGreg Clayton
12013acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton                                s.Printf ("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)} ",
1202234981a4559db084f9c90612660e40f19915b89cGreg Clayton                                          cpu, exc_cstr, exc, code, code, subcode, subcode);
1203234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            }
1204234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
1205234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        break;
1206234981a4559db084f9c90612660e40f19915b89cGreg Clayton
12077b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_TERMINATION:
1208234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        {
1209234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const uint32_t term_code = packet.GetU32 (&offset);
1210234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            const uint32_t exit_code = packet.GetU32 (&offset);
1211234981a4559db084f9c90612660e40f19915b89cGreg Clayton                            s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code);
1212234981a4559db084f9c90612660e40f19915b89cGreg Clayton                        }
12130fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
12140fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
12157b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                    case KDP_REATTACH:
12160fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        {
12170fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                            const uint16_t reply_port = packet.GetU16 (&offset);
12181bc04edcd75cc676823428499878ecac2215a00bGreg Clayton                            s.Printf(" (reply_port = %u)", reply_port);
12190fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        }
12200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                        break;
1221cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1222cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_READMSR64:
1223cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
1224cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t address = packet.GetU32 (&offset);
1225cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t lcpu = packet.GetU16 (&offset);
1226cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
1227cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1228cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1229cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1230cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_WRITEMSR64:
1231cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
1232cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t address = packet.GetU32 (&offset);
1233cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t lcpu = packet.GetU16 (&offset);
1234cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t nbytes = packet.GetByteSize() - offset;
1235cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes);
1236cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            if (nbytes > 0)
1237cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                packet.Dump (&s,                        // Stream to dump to
1238cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             offset,                    // Offset within "packet"
1239cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             eFormatHex,                // Format to use
1240cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             1,                         // Size of each item in bytes
1241cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             nbytes,                    // Number of items
1242cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             16,                        // Number per line
1243cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1244cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             0, 0);                     // No bitfields
1245cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1246cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1247cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1248cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_READIOPORT:
1249cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
1250cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t lcpu = packet.GetU16 (&offset);
1251cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t address = packet.GetU16 (&offset);
1252cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t nbytes = packet.GetU16 (&offset);
1253cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes);
1254cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1255cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1256cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1257cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_WRITEIOPORT:
1258cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                         {
1259cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t lcpu = packet.GetU16 (&offset);
1260cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t address = packet.GetU16 (&offset);
1261cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint16_t nbytes = packet.GetU16 (&offset);
1262cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes);
1263cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            if (nbytes > 0)
1264cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                packet.Dump (&s,                        // Stream to dump to
1265cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             offset,                    // Offset within "packet"
1266cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             eFormatHex,                // Format to use
1267cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             1,                         // Size of each item in bytes
1268cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             nbytes,                    // Number of items
1269cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             16,                        // Number per line
1270cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1271cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             0, 0);                     // No bitfields
1272cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1273cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1274cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1275cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                    case KDP_DUMPINFO:
1276cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        {
1277cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            const uint32_t count = packet.GetByteSize() - offset;
1278cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            s.Printf(" (count = %u, bytes = \n", count);
1279cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                            if (count > 0)
1280cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                packet.Dump (&s,                        // Stream to dump to
1281cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             offset,                    // Offset within "packet"
1282cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             eFormatHex,                // Format to use
1283cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             1,                         // Size of each item in bytes
1284cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             count,                     // Number of items
1285cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             16,                        // Number per line
1286cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
1287cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                                             0, 0);                     // No bitfields
1288cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1289cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        }
1290cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda                        break;
1291cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda
1292cc2cffeda2a1a2c56d33459d6c36be08032b8613Jason Molenda               }
12930fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            }
12940fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        }
12950fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        else
12960fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        {
12970fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            error_desc = "error: invalid packet command: ";
12980fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        }
12990fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    }
13000fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
13010fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    if (error_desc)
13020fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    {
13030fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        s.PutCString (error_desc);
13040fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
13050fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        packet.Dump (&s,                    // Stream to dump to
13060fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                     0,                     // Offset into "packet"
13070fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                     eFormatBytes,          // Dump as hex bytes
13080fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                     1,                     // Size of each item is 1 for single bytes
13090fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                     packet.GetByteSize(),  // Number of bytes
13100fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                     UINT32_MAX,            // Num bytes per line
13110fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                     LLDB_INVALID_ADDRESS,  // Base address
13120fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                     0, 0);                 // Bitfield info set to not do anything bitfield related
13130fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    }
13140fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton}
13150fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
13160fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Claytonuint32_t
13170fa512447e00da09d300fbabd18b5ce94f52fdaaGreg ClaytonCommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
13180fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            uint32_t flavor,
1319ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                                            void *dst,
13200fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            uint32_t dst_len,
13210fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                                            Error &error)
13220fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton{
13230fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
13247b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_READREGS;
13250fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    // Size is header + 4 byte cpu and 4 byte flavor
13260fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    const uint32_t command_length = 8 + 4 + 4;
13270fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
13280fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    request_packet.PutHex32 (cpu);
13290fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    request_packet.PutHex32 (flavor);
13300fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    DataExtractor reply_packet;
1331d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
13320fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    {
133336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
13340fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        uint32_t kdp_error = reply_packet.GetU32 (&offset);
13350fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        uint32_t src_len = reply_packet.GetByteSize() - 12;
13360fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
13370fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        if (src_len > 0)
13380fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        {
13390fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
13400fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            const void *src = reply_packet.GetData(&offset, bytes_to_copy);
13410fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            if (src)
13420fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            {
13430fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                ::memcpy (dst, src, bytes_to_copy);
13440fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                error.Clear();
13450fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                // Return the number of bytes we could have returned regardless if
13460fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton                // we copied them or not, just so we know when things don't match up
1347ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                return src_len;
13480fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            }
13490fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        }
13500fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        if (kdp_error)
13510fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
13520fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton        else
13530fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton            error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
13540fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    }
1355307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    else
1356307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    {
1357307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        error.SetErrorString ("failed to send packet");
1358307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    }
13590fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton    return 0;
13600fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton}
13610fa512447e00da09d300fbabd18b5ce94f52fdaaGreg Clayton
1362ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Claytonuint32_t
1363ea63601b1d4a21e46e477563f27d1b1c516136d8Greg ClaytonCommunicationKDP::SendRequestWriteRegisters (uint32_t cpu,
1364ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                                             uint32_t flavor,
1365ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                                             const void *src,
1366ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                                             uint32_t src_len,
1367ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton                                             Error &error)
1368ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton{
1369ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1370ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    const CommandType command = KDP_WRITEREGS;
1371ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    // Size is header + 4 byte cpu and 4 byte flavor
13723acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    const uint32_t command_length = 8 + 4 + 4 + src_len;
1373ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
1374ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    request_packet.PutHex32 (cpu);
1375ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    request_packet.PutHex32 (flavor);
1376ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    request_packet.Write(src, src_len);
1377ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    DataExtractor reply_packet;
1378d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1379ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    {
138036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
1381ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton        uint32_t kdp_error = reply_packet.GetU32 (&offset);
1382ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton        if (kdp_error == 0)
1383ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton            return src_len;
1384ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton        error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
1385ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    }
1386307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    else
1387307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    {
1388307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton        error.SetErrorString ("failed to send packet");
1389307c7fdc58d19f734991a176db972cc61d9ada16Greg Clayton    }
1390ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton    return 0;
1391ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton}
1392ea63601b1d4a21e46e477563f27d1b1c516136d8Greg Clayton
1393234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1394234981a4559db084f9c90612660e40f19915b89cGreg Claytonbool
13953acaa926c8f0d32da48db61a5fcb95276e6a4006Greg ClaytonCommunicationKDP::SendRequestResume ()
1396234981a4559db084f9c90612660e40f19915b89cGreg Clayton{
1397234981a4559db084f9c90612660e40f19915b89cGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
13987b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_RESUMECPUS;
1399234981a4559db084f9c90612660e40f19915b89cGreg Clayton    const uint32_t command_length = 12;
1400234981a4559db084f9c90612660e40f19915b89cGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
14013acaa926c8f0d32da48db61a5fcb95276e6a4006Greg Clayton    request_packet.PutHex32(GetCPUMask());
1402234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1403234981a4559db084f9c90612660e40f19915b89cGreg Clayton    DataExtractor reply_packet;
1404d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1405234981a4559db084f9c90612660e40f19915b89cGreg Clayton        return true;
1406234981a4559db084f9c90612660e40f19915b89cGreg Clayton    return false;
1407234981a4559db084f9c90612660e40f19915b89cGreg Clayton}
1408234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1409234981a4559db084f9c90612660e40f19915b89cGreg Claytonbool
1410234981a4559db084f9c90612660e40f19915b89cGreg ClaytonCommunicationKDP::SendRequestBreakpoint (bool set, addr_t addr)
1411234981a4559db084f9c90612660e40f19915b89cGreg Clayton{
1412234981a4559db084f9c90612660e40f19915b89cGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1413234981a4559db084f9c90612660e40f19915b89cGreg Clayton    bool use_64 = (GetVersion() >= 11);
1414234981a4559db084f9c90612660e40f19915b89cGreg Clayton    uint32_t command_addr_byte_size = use_64 ? 8 : 4;
14157b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = set ? (use_64 ? KDP_BREAKPOINT_SET64    : KDP_BREAKPOINT_SET   ):
14167b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton                                      (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
1417234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1418234981a4559db084f9c90612660e40f19915b89cGreg Clayton    const uint32_t command_length = 8 + command_addr_byte_size;
1419234981a4559db084f9c90612660e40f19915b89cGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
1420234981a4559db084f9c90612660e40f19915b89cGreg Clayton    request_packet.PutMaxHex64 (addr, command_addr_byte_size);
1421234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1422234981a4559db084f9c90612660e40f19915b89cGreg Clayton    DataExtractor reply_packet;
1423d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
14241bc04edcd75cc676823428499878ecac2215a00bGreg Clayton    {
142536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 8;
14261bc04edcd75cc676823428499878ecac2215a00bGreg Clayton        uint32_t kdp_error = reply_packet.GetU32 (&offset);
14271bc04edcd75cc676823428499878ecac2215a00bGreg Clayton        if (kdp_error == 0)
14281bc04edcd75cc676823428499878ecac2215a00bGreg Clayton            return true;
14291bc04edcd75cc676823428499878ecac2215a00bGreg Clayton    }
1430234981a4559db084f9c90612660e40f19915b89cGreg Clayton    return false;
1431234981a4559db084f9c90612660e40f19915b89cGreg Clayton}
1432234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1433234981a4559db084f9c90612660e40f19915b89cGreg Claytonbool
1434234981a4559db084f9c90612660e40f19915b89cGreg ClaytonCommunicationKDP::SendRequestSuspend ()
1435234981a4559db084f9c90612660e40f19915b89cGreg Clayton{
1436234981a4559db084f9c90612660e40f19915b89cGreg Clayton    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
14377b13922c3c6b55225fa8403762c0399e9692b730Greg Clayton    const CommandType command = KDP_SUSPEND;
1438234981a4559db084f9c90612660e40f19915b89cGreg Clayton    const uint32_t command_length = 8;
1439234981a4559db084f9c90612660e40f19915b89cGreg Clayton    MakeRequestPacketHeader (command, request_packet, command_length);
1440234981a4559db084f9c90612660e40f19915b89cGreg Clayton    DataExtractor reply_packet;
1441d2f3b42f70f309f548c2b618c5991a905a00ec3aGreg Clayton    if (SendRequestAndGetReply (command, request_packet, reply_packet))
1442234981a4559db084f9c90612660e40f19915b89cGreg Clayton        return true;
1443234981a4559db084f9c90612660e40f19915b89cGreg Clayton    return false;
1444234981a4559db084f9c90612660e40f19915b89cGreg Clayton}
1445234981a4559db084f9c90612660e40f19915b89cGreg Clayton
1446