]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/kdp.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1993 NeXT Computer, Inc. All rights reserved.
25 * kdp.c -- Kernel Debugging Protocol.
29 #include <mach/mach_types.h>
30 #include <kern/debug.h>
32 #include <kdp/kdp_internal.h>
33 #include <kdp/kdp_private.h>
35 int kdp_vm_read( caddr_t
, caddr_t
, unsigned int);
36 int kdp_vm_write( caddr_t
, caddr_t
, unsigned int);
38 #define DO_ALIGN 1 /* align all packet data accesses */
40 #define KDP_TEST_HARNESS 0
42 #define dprintf(x) kprintf x
48 dispatch_table
[KDP_TERMINATION
- KDP_CONNECT
+ 1] =
51 /* 1 */ kdp_disconnect
,
58 /* 8 */ kdp_writeregs
,
62 /* C */ kdp_resumecpus
,
74 unsigned short *reply_port
77 static unsigned aligned_pkt
[1538/sizeof(unsigned)+1]; // max ether pkt
78 kdp_pkt_t
*rd
= (kdp_pkt_t
*)&aligned_pkt
;
84 bcopy((char *)pkt
, (char *)rd
, sizeof(aligned_pkt
));
86 rd
= (kdp_pkt_t
*)pkt
;
88 if (plen
< sizeof (rd
->hdr
) || rd
->hdr
.len
!= plen
) {
89 printf("kdp_packet bad len pkt %d hdr %d\n", plen
, rd
->hdr
.len
);
94 if (rd
->hdr
.is_reply
) {
95 printf("kdp_packet reply recvd req %x seq %x\n",
96 rd
->hdr
.request
, rd
->hdr
.seq
);
101 req
= rd
->hdr
.request
;
102 if (req
< KDP_CONNECT
|| req
> KDP_TERMINATION
) {
103 printf("kdp_packet bad request %x len %d seq %x key %x\n",
104 rd
->hdr
.request
, rd
->hdr
.len
, rd
->hdr
.seq
, rd
->hdr
.key
);
109 ret
= ((*dispatch_table
[req
- KDP_CONNECT
])(rd
, len
, reply_port
));
111 bcopy((char *)rd
, (char *) pkt
, *len
);
120 unsigned short *reply_port
123 kdp_pkt_t
*rd
= (kdp_pkt_t
*)pkt
;
125 printf("kdp_unknown request %x len %d seq %x key %x\n",
126 rd
->hdr
.request
, rd
->hdr
.len
, rd
->hdr
.seq
, rd
->hdr
.key
);
135 unsigned short *reply_port
138 kdp_connect_req_t
*rq
= &pkt
->connect_req
;
140 kdp_connect_reply_t
*rp
= &pkt
->connect_reply
;
142 if (plen
< sizeof (*rq
))
145 dprintf(("kdp_connect seq %x greeting %s\n", rq
->hdr
.seq
, rq
->greeting
));
148 if (rq
->hdr
.seq
== kdp
.conn_seq
) /* duplicate request */
149 rp
->error
= KDPERR_NO_ERROR
;
151 rp
->error
= KDPERR_ALREADY_CONNECTED
;
154 kdp
.reply_port
= rq
->req_reply_port
;
155 kdp
.exception_port
= rq
->exc_note_port
;
157 kdp
.conn_seq
= rq
->hdr
.seq
;
159 rp
->error
= KDPERR_NO_ERROR
;
162 rp
->hdr
.is_reply
= 1;
163 rp
->hdr
.len
= sizeof (*rp
);
165 *reply_port
= kdp
.reply_port
;
168 if (current_debugger
== KDP_CUR_DB
)
178 unsigned short *reply_port
181 kdp_disconnect_req_t
*rq
= &pkt
->disconnect_req
;
183 kdp_disconnect_reply_t
*rp
= &pkt
->disconnect_reply
;
185 if (plen
< sizeof (*rq
))
191 dprintf(("kdp_disconnect\n"));
193 *reply_port
= kdp
.reply_port
;
195 kdp
.reply_port
= kdp
.exception_port
= 0;
196 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
197 kdp
.exception_seq
= kdp
.conn_seq
= 0;
199 rp
->hdr
.is_reply
= 1;
200 rp
->hdr
.len
= sizeof (*rp
);
204 if (current_debugger
== KDP_CUR_DB
)
214 unsigned short *reply_port
217 kdp_hostinfo_req_t
*rq
= &pkt
->hostinfo_req
;
219 kdp_hostinfo_reply_t
*rp
= &pkt
->hostinfo_reply
;
221 if (plen
< sizeof (*rq
))
224 rp
->hdr
.is_reply
= 1;
225 rp
->hdr
.len
= sizeof (*rp
);
227 kdp_machine_hostinfo(&rp
->hostinfo
);
229 *reply_port
= kdp
.reply_port
;
239 unsigned short *reply_port
242 kdp_suspend_req_t
*rq
= &pkt
->suspend_req
;
244 kdp_suspend_reply_t
*rp
= &pkt
->suspend_reply
;
246 if (plen
< sizeof (*rq
))
249 rp
->hdr
.is_reply
= 1;
250 rp
->hdr
.len
= sizeof (*rp
);
252 dprintf(("kdp_suspend\n"));
254 kdp
.is_halted
= TRUE
;
256 *reply_port
= kdp
.reply_port
;
266 unsigned short *reply_port
269 kdp_resumecpus_req_t
*rq
= &pkt
->resumecpus_req
;
271 kdp_resumecpus_reply_t
*rp
= &pkt
->resumecpus_reply
;
273 if (plen
< sizeof (*rq
))
276 rp
->hdr
.is_reply
= 1;
277 rp
->hdr
.len
= sizeof (*rp
);
279 dprintf(("kdp_resumecpus %x\n", rq
->cpu_mask
));
281 kdp
.is_halted
= FALSE
;
283 *reply_port
= kdp
.reply_port
;
293 unsigned short *reply_port
296 kdp_writemem_req_t
*rq
= &pkt
->writemem_req
;
298 kdp_writemem_reply_t
*rp
= &pkt
->writemem_reply
;
301 if (plen
< sizeof (*rq
))
304 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
305 rp
->error
= KDPERR_BAD_NBYTES
;
307 dprintf(("kdp_writemem addr %x size %d\n", rq
->address
, rq
->nbytes
));
309 cnt
= kdp_vm_write((caddr_t
)rq
->data
, (caddr_t
)rq
->address
, rq
->nbytes
);
310 rp
->error
= KDPERR_NO_ERROR
;
313 rp
->hdr
.is_reply
= 1;
314 rp
->hdr
.len
= sizeof (*rp
);
316 *reply_port
= kdp
.reply_port
;
326 unsigned short *reply_port
329 kdp_readmem_req_t
*rq
= &pkt
->readmem_req
;
331 kdp_readmem_reply_t
*rp
= &pkt
->readmem_reply
;
334 if (plen
< sizeof (*rq
))
337 rp
->hdr
.is_reply
= 1;
338 rp
->hdr
.len
= sizeof (*rp
);
340 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
341 rp
->error
= KDPERR_BAD_NBYTES
;
343 unsigned int n
= rq
->nbytes
;
345 dprintf(("kdp_readmem addr %x size %d\n", rq
->address
, rq
->nbytes
));
347 cnt
= kdp_vm_read((caddr_t
)rq
->address
, (caddr_t
)rp
->data
, rq
->nbytes
);
348 rp
->error
= KDPERR_NO_ERROR
;
353 *reply_port
= kdp
.reply_port
;
363 unsigned short *reply_port
366 kdp_maxbytes_req_t
*rq
= &pkt
->maxbytes_req
;
368 kdp_maxbytes_reply_t
*rp
= &pkt
->maxbytes_reply
;
370 if (plen
< sizeof (*rq
))
373 rp
->hdr
.is_reply
= 1;
374 rp
->hdr
.len
= sizeof (*rp
);
376 dprintf(("kdp_maxbytes\n"));
378 rp
->max_bytes
= MAX_KDP_DATA_SIZE
;
380 *reply_port
= kdp
.reply_port
;
390 unsigned short *reply_port
393 kdp_regions_req_t
*rq
= &pkt
->regions_req
;
395 kdp_regions_reply_t
*rp
= &pkt
->regions_reply
;
398 if (plen
< sizeof (*rq
))
401 rp
->hdr
.is_reply
= 1;
402 rp
->hdr
.len
= sizeof (*rp
);
404 dprintf(("kdp_regions\n"));
409 (vm_offset_t
)r
->address
= 0;
410 r
->nbytes
= 0xffffffff;
412 r
->protection
= VM_PROT_ALL
; r
++; rp
->nregions
++;
414 rp
->hdr
.len
+= rp
->nregions
* sizeof (kdp_region_t
);
416 *reply_port
= kdp
.reply_port
;
426 unsigned short *reply_port
429 kdp_writeregs_req_t
*rq
= &pkt
->writeregs_req
;
432 kdp_writeregs_reply_t
*rp
= &pkt
->writeregs_reply
;
434 if (plen
< sizeof (*rq
))
437 size
= rq
->hdr
.len
- sizeof(kdp_hdr_t
) - sizeof(unsigned int);
438 rp
->error
= kdp_machine_write_regs(rq
->cpu
, rq
->flavor
, rq
->data
, &size
);
440 rp
->hdr
.is_reply
= 1;
441 rp
->hdr
.len
= sizeof (*rp
);
443 *reply_port
= kdp
.reply_port
;
453 unsigned short *reply_port
456 kdp_readregs_req_t
*rq
= &pkt
->readregs_req
;
458 kdp_readregs_reply_t
*rp
= &pkt
->readregs_reply
;
461 if (plen
< sizeof (*rq
))
464 rp
->hdr
.is_reply
= 1;
465 rp
->hdr
.len
= sizeof (*rp
);
467 rp
->error
= kdp_machine_read_regs(rq
->cpu
, rq
->flavor
, rp
->data
, &size
);
470 *reply_port
= kdp
.reply_port
;