1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29/*
30 * Definition of remote debugger protocol.
31 */
32
33#include	<mach/vm_prot.h>
34
35/*
36 * Retransmit parameters
37 */
38#if	DDEBUG_DEBUG || DEBUG_DEBUG
39#define	KDP_REXMIT_SECS		20	/* rexmit if no ack in 3 secs */
40#else	/* DDEBUG_DEBUG || DEBUG_DEBUG */
41#define	KDP_REXMIT_SECS		3	/* rexmit if no ack in 3 secs */
42#endif	/* DDEBUG_DEBUG || DEBUG_DEBUG */
43#define	KDP_REXMIT_TRIES	8	/* xmit 8 times, then give up */
44
45/*
46 * (NMI) Attention Max Wait Time
47 * Remote will resume unless KDP requests is received within this
48 * many seconds after an attention (nmi) packet is sent.
49 */
50#define	KDP_MAX_ATTN_WAIT	30	/* wait max of 30 seconds */
51
52/*
53 * Well-known UDP port, debugger side.
54 * FIXME: This is what the 68K guys use, but beats me how they chose it...
55 */
56#define	KDP_REMOTE_PORT		41139	/* pick one and register it */
57
58/*
59 * UDP ports, KDB side. 5 port numbers are reserved for each port (request
60 * and exception). This allows multiple KDBs to run on one host.
61 */
62#define UDP_HOST_COMM_BASE	41140
63#define UDP_HOST_EXCEP_BASE	41145
64#define NUM_UDP_HOST_PORTS	5
65
66/*
67 * Requests
68 */
69typedef enum {
70	/* connection oriented requests */
71	KDP_CONNECT,	KDP_DISCONNECT,
72
73	/* obtaining client info */
74	KDP_HOSTINFO,	KDP_VERSION,	KDP_MAXBYTES,
75
76	/* memory access */
77	KDP_READMEM,	KDP_WRITEMEM,
78
79	/* register access */
80	KDP_READREGS,	KDP_WRITEREGS,
81
82	/* executable image info */
83	KDP_LOAD,	KDP_IMAGEPATH,
84
85	/* execution control */
86	KDP_SUSPEND,	KDP_RESUMECPUS,
87
88	/* exception and termination notification, NOT true requests */
89	KDP_EXCEPTION,	KDP_TERMINATION,
90
91	/* breakpoint control */
92	KDP_BREAKPOINT_SET, KDP_BREAKPOINT_REMOVE,
93
94	/* vm regions */
95	KDP_REGIONS,
96
97	/* reattach to a connected host */
98	KDP_REATTACH,
99
100	/* remote reboot request */
101	KDP_HOSTREBOOT
102} kdp_req_t;
103
104/*
105 * Common KDP packet header
106 */
107typedef struct {
108	kdp_req_t	request:7;	/* request type */
109	unsigned	is_reply:1;	/* 0 => request, 1 => reply */
110	unsigned	seq:8;		/* sequence number within session */
111	unsigned	len:16;		/* length of entire pkt including hdr */
112	unsigned	key;		/* session key */
113} kdp_hdr_t;
114
115/*
116 * KDP errors
117 */
118typedef enum {
119	KDPERR_NO_ERROR = 0,
120	KDPERR_ALREADY_CONNECTED,
121	KDPERR_BAD_NBYTES,
122	KDPERR_BADFLAVOR		/* bad flavor in w/r regs */
123} kdp_error_t;
124
125/*
126 * KDP requests and reply packet formats
127 */
128
129/*
130 * KDP_CONNECT
131 */
132typedef struct {			/* KDP_CONNECT request */
133	kdp_hdr_t	hdr;
134	unsigned short	req_reply_port;	/* udp port which to send replies */
135	unsigned short	exc_note_port;	/* udp port which to send exc notes */
136	char		greeting[0];	/* "greetings", null-terminated */
137} kdp_connect_req_t;
138
139typedef struct {			/* KDP_CONNECT reply */
140	kdp_hdr_t	hdr;
141	kdp_error_t	error;
142} kdp_connect_reply_t;
143
144/*
145 * KDP_DISCONNECT
146 */
147typedef struct {			/* KDP_DISCONNECT request */
148	kdp_hdr_t	hdr;
149} kdp_disconnect_req_t;
150
151typedef struct {			/* KDP_DISCONNECT reply */
152	kdp_hdr_t	hdr;
153} kdp_disconnect_reply_t;
154
155/*
156 * KDP_REATTACH
157 */
158typedef struct {
159  kdp_hdr_t hdr;
160  unsigned short req_reply_port; /* udp port which to send replies */
161} kdp_reattach_req_t;
162
163/*
164 * KDP_HOSTINFO
165 */
166typedef struct {			/* KDP_HOSTINFO request */
167	kdp_hdr_t	hdr;
168} kdp_hostinfo_req_t;
169
170typedef struct {
171	unsigned	cpus_mask;	/* bit is 1 if cpu present */
172	int		cpu_type;
173	int		cpu_subtype;
174} kdp_hostinfo_t;
175
176typedef struct {			/* KDP_HOSTINFO reply */
177	kdp_hdr_t	hdr;
178	kdp_hostinfo_t	hostinfo;
179} kdp_hostinfo_reply_t;
180
181/*
182 * KDP_VERSION
183 */
184typedef struct {			/* KDP_VERSION request */
185	kdp_hdr_t	hdr;
186} kdp_version_req_t;
187
188#define	KDP_FEATURE_BP	0x1	/* local breakpoint support */
189
190typedef struct {			/* KDP_REGIONS reply */
191	kdp_hdr_t	hdr;
192	unsigned	version;
193	unsigned	feature;
194	unsigned	pad0;
195	unsigned	pad1;
196} kdp_version_reply_t;
197
198/*
199 * KDP_REGIONS
200 */
201typedef struct {			/* KDP_REGIONS request */
202	kdp_hdr_t	hdr;
203} kdp_regions_req_t;
204
205#define	VM_PROT_VOLATILE	((vm_prot_t) 0x08)	/* not cacheable */
206#define	VM_PROT_SPARSE		((vm_prot_t) 0x10)	/* sparse addr space */
207
208typedef struct {
209	void		*address;
210	unsigned	nbytes;
211	vm_prot_t	protection;
212} kdp_region_t;
213
214typedef struct {			/* KDP_REGIONS reply */
215	kdp_hdr_t	hdr;
216	unsigned	nregions;
217	kdp_region_t	regions[0];
218} kdp_regions_reply_t;
219
220/*
221 * KDP_MAXBYTES
222 */
223typedef struct {			/* KDP_MAXBYTES request */
224	kdp_hdr_t	hdr;
225} kdp_maxbytes_req_t;
226
227typedef struct {			/* KDP_MAXBYTES reply */
228	kdp_hdr_t	hdr;
229	unsigned	max_bytes;
230} kdp_maxbytes_reply_t;
231
232/*
233 * KDP_READMEM
234 */
235typedef struct {			/* KDP_READMEM request */
236	kdp_hdr_t	hdr;
237	void		*address;
238	unsigned	nbytes;
239} kdp_readmem_req_t;
240
241typedef struct {			/* KDP_READMEM reply */
242	kdp_hdr_t	hdr;
243	kdp_error_t	error;
244	char		data[0];
245} kdp_readmem_reply_t;
246
247/*
248 * KDP_WRITEMEM
249 */
250typedef struct {			/* KDP_WRITEMEM request */
251	kdp_hdr_t	hdr;
252	void		*address;
253	unsigned	nbytes;
254	char		data[0];
255} kdp_writemem_req_t;
256
257typedef struct {			/* KDP_WRITEMEM reply */
258	kdp_hdr_t	hdr;
259	kdp_error_t	error;
260} kdp_writemem_reply_t;
261
262/*
263 * KDP_READREGS
264 */
265typedef struct {			/* KDP_READREGS request */
266	kdp_hdr_t	hdr;
267	unsigned	cpu;
268	unsigned	flavor;
269} kdp_readregs_req_t;
270
271typedef struct {			/* KDP_READREGS reply */
272	kdp_hdr_t	hdr;
273	kdp_error_t	error;		/* could be KDPERR_BADFLAVOR */
274	char		data[0];
275} kdp_readregs_reply_t;
276
277/*
278 * KDP_WRITEREGS
279 */
280typedef struct {			/* KDP_WRITEREGS request */
281	kdp_hdr_t	hdr;
282	unsigned	cpu;
283	unsigned	flavor;
284	char		data[0];
285} kdp_writeregs_req_t;
286
287typedef struct {			/* KDP_WRITEREGS reply */
288	kdp_hdr_t	hdr;
289	kdp_error_t	error;
290} kdp_writeregs_reply_t;
291
292/*
293 * KDP_LOAD
294 */
295typedef struct {			/* KDP_LOAD request */
296	kdp_hdr_t	hdr;
297	char		file_args[0];
298} kdp_load_req_t;
299
300typedef struct {			/* KDP_LOAD reply */
301	kdp_hdr_t	hdr;
302	kdp_error_t	error;
303} kdp_load_reply_t;
304
305/*
306 * KDP_IMAGEPATH
307 */
308typedef struct {			/* KDP_IMAGEPATH request */
309	kdp_hdr_t	hdr;
310} kdp_imagepath_req_t;
311
312typedef struct {			/* KDP_IMAGEPATH reply */
313	kdp_hdr_t	hdr;
314	char		path[0];
315} kdp_imagepath_reply_t;
316
317/*
318 * KDP_SUSPEND
319 */
320typedef struct {			/* KDP_SUSPEND request */
321	kdp_hdr_t	hdr;
322} kdp_suspend_req_t;
323
324typedef struct {			/* KDP_SUSPEND reply */
325	kdp_hdr_t	hdr;
326} kdp_suspend_reply_t;
327
328/*
329 * KDP_RESUMECPUS
330 */
331typedef struct {			/* KDP_RESUMECPUS request */
332	kdp_hdr_t	hdr;
333	unsigned	cpu_mask;
334} kdp_resumecpus_req_t;
335
336typedef struct {			/* KDP_RESUMECPUS reply */
337	kdp_hdr_t	hdr;
338} kdp_resumecpus_reply_t;
339
340typedef struct {
341  kdp_hdr_t hdr;
342  unsigned long address;
343} kdp_breakpoint_req_t;
344
345typedef struct {
346  kdp_hdr_t hdr;
347  kdp_error_t error;
348} kdp_breakpoint_reply_t;
349
350/*
351 * Exception notifications
352 * (Exception notifications are not requests, and in fact travel from
353 * the remote debugger to the gdb agent KDB.)
354 */
355typedef struct {			/* exc. info for one cpu */
356	unsigned	cpu;
357	/*
358	 * Following info is defined as
359	 * per <mach/exception.h>
360	 */
361	unsigned	exception;
362	unsigned	code;
363	unsigned	subcode;
364} kdp_exc_info_t;
365
366typedef struct {			/* KDP_EXCEPTION notification */
367	kdp_hdr_t	hdr;
368	unsigned	n_exc_info;
369	kdp_exc_info_t	exc_info[0];
370} kdp_exception_t;
371
372typedef struct {			/* KDP_EXCEPTION acknowledgement */
373	kdp_hdr_t	hdr;
374} kdp_exception_ack_t;
375
376/*
377 * Child termination messages
378 */
379typedef enum {
380	KDP_FAULT = 0,		/* child took fault (internal use) */
381	KDP_EXIT,		/* child exited */
382	KDP_POWEROFF,		/* child power-off */
383	KDP_REBOOT,		/* child reboot */
384	KDP_COMMAND_MODE	/* child exit to mon command_mode */
385} kdp_termination_code_t;
386
387typedef struct {			/* KDP_TERMINATION notification */
388	kdp_hdr_t		hdr;
389	kdp_termination_code_t	term_code;
390	unsigned		exit_code;
391} kdp_termination_t;
392
393typedef struct {
394	kdp_hdr_t	hdr;
395} kdp_termination_ack_t;
396
397typedef union {
398	kdp_hdr_t		hdr;
399	kdp_connect_req_t	connect_req;
400	kdp_connect_reply_t	connect_reply;
401	kdp_disconnect_req_t	disconnect_req;
402	kdp_disconnect_reply_t	disconnect_reply;
403	kdp_hostinfo_req_t	hostinfo_req;
404	kdp_hostinfo_reply_t	hostinfo_reply;
405	kdp_version_req_t	version_req;
406	kdp_version_reply_t	version_reply;
407	kdp_maxbytes_req_t	maxbytes_req;
408	kdp_maxbytes_reply_t	maxbytes_reply;
409	kdp_readmem_req_t	readmem_req;
410	kdp_readmem_reply_t	readmem_reply;
411	kdp_writemem_req_t	writemem_req;
412	kdp_writemem_reply_t	writemem_reply;
413	kdp_readregs_req_t	readregs_req;
414	kdp_readregs_reply_t	readregs_reply;
415	kdp_writeregs_req_t	writeregs_req;
416	kdp_writeregs_reply_t	writeregs_reply;
417	kdp_load_req_t		load_req;
418	kdp_load_reply_t	load_reply;
419	kdp_imagepath_req_t	imagepath_req;
420	kdp_imagepath_reply_t	imagepath_reply;
421	kdp_suspend_req_t	suspend_req;
422	kdp_suspend_reply_t	suspend_reply;
423	kdp_resumecpus_req_t	resumecpus_req;
424	kdp_resumecpus_reply_t	resumecpus_reply;
425	kdp_exception_t		exception;
426	kdp_exception_ack_t	exception_ack;
427	kdp_termination_t	termination;
428	kdp_termination_ack_t	termination_ack;
429	kdp_breakpoint_req_t	breakpoint_req;
430	kdp_breakpoint_reply_t	breakpoint_reply;
431	kdp_reattach_req_t	reattach_req;
432	kdp_regions_req_t	regions_req;
433	kdp_regions_reply_t	regions_reply;
434} kdp_pkt_t;
435
436#define MAX_KDP_PKT_SIZE	1200	/* max packet size */
437#define MAX_KDP_DATA_SIZE	1024	/* max r/w data per packet */
438