2 * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <mach/mach_types.h>
30 #include <mach/vm_param.h>
31 #include <sys/appleapiopts.h>
32 #include <kern/debug.h>
33 #include <uuid/uuid.h>
35 #include <kdp/kdp_internal.h>
36 #include <kdp/kdp_private.h>
37 #include <kdp/kdp_core.h>
39 #include <libsa/types.h>
40 #include <libkern/section_keywords.h>
41 #include <libkern/version.h>
43 #include <string.h> /* bcopy */
45 #include <kern/processor.h>
46 #include <kern/thread.h>
47 #include <kern/clock.h>
48 #include <vm/vm_map.h>
49 #include <vm/vm_kern.h>
50 #include <vm/vm_pageout.h>
51 #include <vm/vm_shared_region.h>
52 #include <libkern/OSKextLibPrivate.h>
54 #define DO_ALIGN 1 /* align all packet data accesses */
56 #define KDP_TEST_HARNESS 0
58 #define dprintf(x) kprintf x
63 SECURITY_READ_ONLY_EARLY(static kdp_dispatch_t
)
64 dispatch_table
[KDP_INVALID_REQUEST
- KDP_CONNECT
] =
67 /* 1 */ kdp_disconnect
,
74 /* 8 */ kdp_writeregs
,
78 /* C */ kdp_resumecpus
,
81 /* F */ kdp_breakpoint_set
,
82 /*10 */ kdp_breakpoint_remove
,
86 /*14 */ kdp_readmem64
,
87 /*15 */ kdp_writemem64
,
88 /*16 */ kdp_breakpoint64_set
,
89 /*17 */ kdp_breakpoint64_remove
,
90 /*18 */ kdp_kernelversion
,
91 /*19 */ kdp_readphysmem64
,
92 /*1A */ kdp_writephysmem64
,
93 /*1B */ kdp_readioport
,
94 /*1C */ kdp_writeioport
,
95 /*1D */ kdp_readmsr64
,
96 /*1E */ kdp_writemsr64
,
102 #define MAX_BREAKPOINTS 100
105 * Version 11 of the KDP Protocol adds support for 64-bit wide memory
106 * addresses (read/write and breakpoints) as well as a dedicated
107 * kernelversion request. Version 12 adds read/writing of physical
108 * memory with 64-bit wide memory addresses.
110 #define KDP_VERSION 12
113 mach_vm_address_t address
;
115 uint8_t oldbytes
[MAX_BREAKINSN_BYTES
];
116 } kdp_breakpoint_record_t
;
118 static kdp_breakpoint_record_t breakpoint_list
[MAX_BREAKPOINTS
];
119 static unsigned int breakpoints_initialized
= 0;
121 int reattach_wait
= 0;
122 int noresume_on_disconnect
= 0;
125 kdp_set_breakpoint_internal(
126 mach_vm_address_t address
130 kdp_remove_breakpoint_internal(
131 mach_vm_address_t address
138 unsigned short *reply_port
141 static unsigned aligned_pkt
[1538 / sizeof(unsigned) + 1];// max ether pkt
142 kdp_pkt_t
*rd
= (kdp_pkt_t
*)&aligned_pkt
;
148 if (plen
> sizeof(aligned_pkt
)) {
149 printf("kdp_packet bad len %lu\n", plen
);
152 bcopy((char *)pkt
, (char *)rd
, plen
);
154 rd
= (kdp_pkt_t
*)pkt
;
156 if (plen
< sizeof(rd
->hdr
) || rd
->hdr
.len
!= plen
) {
157 printf("kdp_packet bad len pkt %lu hdr %d\n", plen
, rd
->hdr
.len
);
162 if (rd
->hdr
.is_reply
) {
163 printf("kdp_packet reply recvd req %x seq %x\n",
164 rd
->hdr
.request
, rd
->hdr
.seq
);
169 req
= rd
->hdr
.request
;
170 if (req
>= KDP_INVALID_REQUEST
) {
171 printf("kdp_packet bad request %x len %d seq %x key %x\n",
172 rd
->hdr
.request
, rd
->hdr
.len
, rd
->hdr
.seq
, rd
->hdr
.key
);
177 ret
= ((*dispatch_table
[req
- KDP_CONNECT
])(rd
, len
, reply_port
));
179 bcopy((char *)rd
, (char *) pkt
, *len
);
188 __unused
unsigned short *reply_port
191 kdp_pkt_t
*rd
= (kdp_pkt_t
*)pkt
;
193 printf("kdp_unknown request %x len %d seq %x key %x\n",
194 rd
->hdr
.request
, rd
->hdr
.len
, rd
->hdr
.seq
, rd
->hdr
.key
);
203 unsigned short *reply_port
206 kdp_connect_req_t
*rq
= &pkt
->connect_req
;
208 kdp_connect_reply_t
*rp
= &pkt
->connect_reply
;
209 uint16_t rport
, eport
;
213 if (plen
< sizeof(*rq
)) {
217 dprintf(("kdp_connect seq %x greeting %s\n", rq
->hdr
.seq
, rq
->greeting
));
219 rport
= rq
->req_reply_port
;
220 eport
= rq
->exc_note_port
;
224 if ((seq
== kdp
.conn_seq
) && /* duplicate request */
225 (rport
== kdp
.reply_port
) &&
226 (eport
== kdp
.exception_port
) &&
227 (key
== kdp
.session_key
)) {
228 rp
->error
= KDPERR_NO_ERROR
;
230 rp
->error
= KDPERR_ALREADY_CONNECTED
;
233 kdp
.reply_port
= rport
;
234 kdp
.exception_port
= eport
;
237 kdp
.session_key
= key
;
239 rp
->error
= KDPERR_NO_ERROR
;
242 rp
->hdr
.is_reply
= 1;
243 rp
->hdr
.len
= sizeof(*rp
);
248 if (current_debugger
== KDP_CUR_DB
) {
259 unsigned short *reply_port
262 kdp_disconnect_req_t
*rq
= &pkt
->disconnect_req
;
264 kdp_disconnect_reply_t
*rp
= &pkt
->disconnect_reply
;
266 if (plen
< sizeof(*rq
)) {
274 dprintf(("kdp_disconnect\n"));
276 *reply_port
= kdp
.reply_port
;
278 kdp
.reply_port
= kdp
.exception_port
= 0;
279 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
280 kdp
.exception_seq
= kdp
.conn_seq
= 0;
283 if (debugger_panic_str
!= NULL
) {
287 if (noresume_on_disconnect
== 1) {
289 noresume_on_disconnect
= 0;
292 rp
->hdr
.is_reply
= 1;
293 rp
->hdr
.len
= sizeof(*rp
);
297 if (current_debugger
== KDP_CUR_DB
) {
308 unsigned short *reply_port
311 kdp_reattach_req_t
*rq
= &pkt
->reattach_req
;
314 kdp_disconnect(pkt
, len
, reply_port
);
315 *reply_port
= rq
->req_reply_port
;
324 unsigned short *reply_port
327 kdp_hostinfo_req_t
*rq
= &pkt
->hostinfo_req
;
329 kdp_hostinfo_reply_t
*rp
= &pkt
->hostinfo_reply
;
331 if (plen
< sizeof(*rq
)) {
335 dprintf(("kdp_hostinfo\n"));
337 rp
->hdr
.is_reply
= 1;
338 rp
->hdr
.len
= sizeof(*rp
);
340 kdp_machine_hostinfo(&rp
->hostinfo
);
342 *reply_port
= kdp
.reply_port
;
352 unsigned short *reply_port
355 kdp_kernelversion_req_t
*rq
= &pkt
->kernelversion_req
;
357 kdp_kernelversion_reply_t
*rp
= &pkt
->kernelversion_reply
;
360 if (plen
< sizeof(*rq
)) {
364 rp
->hdr
.is_reply
= 1;
365 rp
->hdr
.len
= sizeof(*rp
);
367 dprintf(("kdp_kernelversion\n"));
368 slen
= strlcpy(rp
->version
, kdp_kernelversion_string
, MAX_KDP_DATA_SIZE
);
370 rp
->hdr
.len
+= slen
+ 1; /* strlcpy returns the amount copied with NUL */
372 *reply_port
= kdp
.reply_port
;
382 unsigned short *reply_port
385 kdp_suspend_req_t
*rq
= &pkt
->suspend_req
;
387 kdp_suspend_reply_t
*rp
= &pkt
->suspend_reply
;
389 if (plen
< sizeof(*rq
)) {
393 rp
->hdr
.is_reply
= 1;
394 rp
->hdr
.len
= sizeof(*rp
);
396 dprintf(("kdp_suspend\n"));
398 kdp
.is_halted
= TRUE
;
400 *reply_port
= kdp
.reply_port
;
410 unsigned short *reply_port
413 kdp_resumecpus_req_t
*rq
= &pkt
->resumecpus_req
;
415 kdp_resumecpus_reply_t
*rp
= &pkt
->resumecpus_reply
;
417 if (plen
< sizeof(*rq
)) {
421 rp
->hdr
.is_reply
= 1;
422 rp
->hdr
.len
= sizeof(*rp
);
424 dprintf(("kdp_resumecpus %x\n", rq
->cpu_mask
));
426 kdp
.is_halted
= FALSE
;
428 *reply_port
= kdp
.reply_port
;
438 unsigned short *reply_port
441 kdp_writemem_req_t
*rq
= &pkt
->writemem_req
;
443 kdp_writemem_reply_t
*rp
= &pkt
->writemem_reply
;
446 if (plen
< sizeof(*rq
)) {
450 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
) {
451 rp
->error
= KDPERR_BAD_NBYTES
;
453 dprintf(("kdp_writemem addr %x size %d\n", rq
->address
, rq
->nbytes
));
454 cnt
= kdp_machine_vm_write((caddr_t
)rq
->data
, (mach_vm_address_t
)rq
->address
, rq
->nbytes
);
455 rp
->error
= KDPERR_ACCESS(rq
->nbytes
, cnt
);
456 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
459 rp
->hdr
.is_reply
= 1;
460 rp
->hdr
.len
= sizeof(*rp
);
462 *reply_port
= kdp
.reply_port
;
472 unsigned short *reply_port
475 kdp_writemem64_req_t
*rq
= &pkt
->writemem64_req
;
477 kdp_writemem64_reply_t
*rp
= &pkt
->writemem64_reply
;
480 if (plen
< sizeof(*rq
)) {
484 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
) {
485 rp
->error
= KDPERR_BAD_NBYTES
;
487 dprintf(("kdp_writemem64 addr %llx size %d\n", rq
->address
, rq
->nbytes
));
488 cnt
= kdp_machine_vm_write((caddr_t
)rq
->data
, (mach_vm_address_t
)rq
->address
, (mach_vm_size_t
)rq
->nbytes
);
489 rp
->error
= KDPERR_ACCESS(rq
->nbytes
, cnt
);
490 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
493 rp
->hdr
.is_reply
= 1;
494 rp
->hdr
.len
= sizeof(*rp
);
496 *reply_port
= kdp
.reply_port
;
506 unsigned short *reply_port
509 kdp_writephysmem64_req_t
*rq
= &pkt
->writephysmem64_req
;
511 kdp_writephysmem64_reply_t
*rp
= &pkt
->writephysmem64_reply
;
515 if (plen
< sizeof(*rq
)) {
520 if (size
> MAX_KDP_DATA_SIZE
) {
521 rp
->error
= KDPERR_BAD_NBYTES
;
523 dprintf(("kdp_writephysmem64 addr %llx size %d\n", rq
->address
, size
));
524 cnt
= kdp_machine_phys_write(rq
, rq
->data
, rq
->lcpu
);
525 rp
->error
= KDPERR_ACCESS(size
, cnt
);
526 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
529 rp
->hdr
.is_reply
= 1;
530 rp
->hdr
.len
= sizeof(*rp
);
532 *reply_port
= kdp
.reply_port
;
542 unsigned short *reply_port
545 kdp_readmem_req_t
*rq
= &pkt
->readmem_req
;
547 kdp_readmem_reply_t
*rp
= &pkt
->readmem_reply
;
551 if (plen
< sizeof(*rq
)) {
555 rp
->hdr
.is_reply
= 1;
556 rp
->hdr
.len
= sizeof(*rp
);
559 if (size
> MAX_KDP_DATA_SIZE
) {
560 rp
->error
= KDPERR_BAD_NBYTES
;
562 dprintf(("kdp_readmem addr %x size %d\n", rq
->address
, size
));
563 cnt
= kdp_machine_vm_read((mach_vm_address_t
)rq
->address
, (caddr_t
)rp
->data
, rq
->nbytes
);
564 rp
->error
= KDPERR_ACCESS(size
, cnt
);
565 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
570 *reply_port
= kdp
.reply_port
;
580 unsigned short *reply_port
583 kdp_readmem64_req_t
*rq
= &pkt
->readmem64_req
;
585 kdp_readmem64_reply_t
*rp
= &pkt
->readmem64_reply
;
589 if (plen
< sizeof(*rq
)) {
593 rp
->hdr
.is_reply
= 1;
594 rp
->hdr
.len
= sizeof(*rp
);
597 if (size
> MAX_KDP_DATA_SIZE
) {
598 rp
->error
= KDPERR_BAD_NBYTES
;
600 dprintf(("kdp_readmem64 addr %llx size %d\n", rq
->address
, size
));
601 cnt
= kdp_machine_vm_read((mach_vm_address_t
)rq
->address
, (caddr_t
)rp
->data
, rq
->nbytes
);
602 rp
->error
= KDPERR_ACCESS(size
, cnt
);
603 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
608 *reply_port
= kdp
.reply_port
;
618 unsigned short *reply_port
621 kdp_readphysmem64_req_t
*rq
= &pkt
->readphysmem64_req
;
623 kdp_readphysmem64_reply_t
*rp
= &pkt
->readphysmem64_reply
;
627 if (plen
< sizeof(*rq
)) {
631 rp
->hdr
.is_reply
= 1;
632 rp
->hdr
.len
= sizeof(*rp
);
635 if (size
> MAX_KDP_DATA_SIZE
) {
636 rp
->error
= KDPERR_BAD_NBYTES
;
638 dprintf(("kdp_readphysmem64 addr %llx size %d\n", rq
->address
, size
));
639 cnt
= kdp_machine_phys_read(rq
, rp
->data
, rq
->lcpu
);
640 rp
->error
= KDPERR_ACCESS(size
, cnt
);
641 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
646 *reply_port
= kdp
.reply_port
;
656 unsigned short *reply_port
659 kdp_maxbytes_req_t
*rq
= &pkt
->maxbytes_req
;
661 kdp_maxbytes_reply_t
*rp
= &pkt
->maxbytes_reply
;
663 if (plen
< sizeof(*rq
)) {
667 rp
->hdr
.is_reply
= 1;
668 rp
->hdr
.len
= sizeof(*rp
);
670 dprintf(("kdp_maxbytes\n"));
672 rp
->max_bytes
= MAX_KDP_DATA_SIZE
;
674 *reply_port
= kdp
.reply_port
;
684 unsigned short *reply_port
687 kdp_version_req_t
*rq
= &pkt
->version_req
;
689 kdp_version_reply_t
*rp
= &pkt
->version_reply
;
691 if (plen
< sizeof(*rq
)) {
695 rp
->hdr
.is_reply
= 1;
696 rp
->hdr
.len
= sizeof(*rp
);
698 dprintf(("kdp_version\n"));
700 rp
->version
= KDP_VERSION
;
701 if (!(kdp_flag
& KDP_BP_DIS
)) {
702 rp
->feature
= KDP_FEATURE_BP
;
707 *reply_port
= kdp
.reply_port
;
717 unsigned short *reply_port
720 kdp_regions_req_t
*rq
= &pkt
->regions_req
;
722 kdp_regions_reply_t
*rp
= &pkt
->regions_reply
;
725 if (plen
< sizeof(*rq
)) {
729 rp
->hdr
.is_reply
= 1;
730 rp
->hdr
.len
= sizeof(*rp
);
732 dprintf(("kdp_regions\n"));
738 r
->nbytes
= 0xffffffff;
740 r
->protection
= VM_PROT_ALL
; r
++; rp
->nregions
++;
742 rp
->hdr
.len
+= rp
->nregions
* sizeof(kdp_region_t
);
744 *reply_port
= kdp
.reply_port
;
754 unsigned short *reply_port
757 kdp_writeregs_req_t
*rq
= &pkt
->writeregs_req
;
760 kdp_writeregs_reply_t
*rp
= &pkt
->writeregs_reply
;
762 if (plen
< sizeof(*rq
)) {
766 size
= rq
->hdr
.len
- (unsigned)sizeof(kdp_hdr_t
) - (unsigned)sizeof(unsigned int);
767 rp
->error
= kdp_machine_write_regs(rq
->cpu
, rq
->flavor
, rq
->data
, &size
);
769 rp
->hdr
.is_reply
= 1;
770 rp
->hdr
.len
= sizeof(*rp
);
772 *reply_port
= kdp
.reply_port
;
782 unsigned short *reply_port
785 kdp_readregs_req_t
*rq
= &pkt
->readregs_req
;
787 kdp_readregs_reply_t
*rp
= &pkt
->readregs_reply
;
790 if (plen
< sizeof(*rq
)) {
794 rp
->hdr
.is_reply
= 1;
795 rp
->hdr
.len
= sizeof(*rp
);
797 rp
->error
= kdp_machine_read_regs(rq
->cpu
, rq
->flavor
, rp
->data
, &size
);
800 *reply_port
= kdp
.reply_port
;
811 unsigned short *reply_port
814 kdp_breakpoint_req_t
*rq
= &pkt
->breakpoint_req
;
815 kdp_breakpoint_reply_t
*rp
= &pkt
->breakpoint_reply
;
819 if (plen
< sizeof(*rq
)) {
823 dprintf(("kdp_breakpoint_set %x\n", rq
->address
));
825 kerr
= kdp_set_breakpoint_internal((mach_vm_address_t
)rq
->address
);
829 rp
->hdr
.is_reply
= 1;
830 rp
->hdr
.len
= sizeof(*rp
);
831 *reply_port
= kdp
.reply_port
;
838 kdp_breakpoint64_set(
841 unsigned short *reply_port
844 kdp_breakpoint64_req_t
*rq
= &pkt
->breakpoint64_req
;
845 kdp_breakpoint64_reply_t
*rp
= &pkt
->breakpoint64_reply
;
849 if (plen
< sizeof(*rq
)) {
853 dprintf(("kdp_breakpoint64_set %llx\n", rq
->address
));
855 kerr
= kdp_set_breakpoint_internal((mach_vm_address_t
)rq
->address
);
859 rp
->hdr
.is_reply
= 1;
860 rp
->hdr
.len
= sizeof(*rp
);
861 *reply_port
= kdp
.reply_port
;
868 kdp_breakpoint_remove(
871 unsigned short *reply_port
874 kdp_breakpoint_req_t
*rq
= &pkt
->breakpoint_req
;
875 kdp_breakpoint_reply_t
*rp
= &pkt
->breakpoint_reply
;
878 if (plen
< sizeof(*rq
)) {
882 dprintf(("kdp_breakpoint_remove %x\n", rq
->address
));
884 kerr
= kdp_remove_breakpoint_internal((mach_vm_address_t
)rq
->address
);
888 rp
->hdr
.is_reply
= 1;
889 rp
->hdr
.len
= sizeof(*rp
);
890 *reply_port
= kdp
.reply_port
;
897 kdp_breakpoint64_remove(
900 unsigned short *reply_port
903 kdp_breakpoint64_req_t
*rq
= &pkt
->breakpoint64_req
;
904 kdp_breakpoint64_reply_t
*rp
= &pkt
->breakpoint64_reply
;
908 if (plen
< sizeof(*rq
)) {
912 dprintf(("kdp_breakpoint64_remove %llx\n", rq
->address
));
914 kerr
= kdp_remove_breakpoint_internal((mach_vm_address_t
)rq
->address
);
918 rp
->hdr
.is_reply
= 1;
919 rp
->hdr
.len
= sizeof(*rp
);
920 *reply_port
= kdp
.reply_port
;
928 kdp_set_breakpoint_internal(
929 mach_vm_address_t address
932 uint8_t breakinstr
[MAX_BREAKINSN_BYTES
], oldinstr
[MAX_BREAKINSN_BYTES
];
933 uint32_t breakinstrsize
= sizeof(breakinstr
);
937 kdp_machine_get_breakinsn(breakinstr
, &breakinstrsize
);
939 if (breakpoints_initialized
== 0) {
940 for (i
= 0; (i
< MAX_BREAKPOINTS
); breakpoint_list
[i
].address
= 0, i
++) {
943 breakpoints_initialized
++;
946 cnt
= kdp_machine_vm_read(address
, (caddr_t
)&oldinstr
, (mach_vm_size_t
)breakinstrsize
);
948 if (0 == memcmp(oldinstr
, breakinstr
, breakinstrsize
)) {
949 printf("A trap was already set at that address, not setting new breakpoint\n");
951 return KDPERR_BREAKPOINT_ALREADY_SET
;
954 for (i
= 0; (i
< MAX_BREAKPOINTS
) && (breakpoint_list
[i
].address
!= 0); i
++) {
958 if (i
== MAX_BREAKPOINTS
) {
959 return KDPERR_MAX_BREAKPOINTS
;
962 breakpoint_list
[i
].address
= address
;
963 memcpy(breakpoint_list
[i
].oldbytes
, oldinstr
, breakinstrsize
);
964 breakpoint_list
[i
].bytesused
= breakinstrsize
;
966 cnt
= kdp_machine_vm_write((caddr_t
)&breakinstr
, address
, breakinstrsize
);
968 return KDPERR_NO_ERROR
;
972 kdp_remove_breakpoint_internal(
973 mach_vm_address_t address
979 for (i
= 0; (i
< MAX_BREAKPOINTS
) && (breakpoint_list
[i
].address
!= address
); i
++) {
983 if (i
== MAX_BREAKPOINTS
) {
984 return KDPERR_BREAKPOINT_NOT_FOUND
;
987 breakpoint_list
[i
].address
= 0;
988 cnt
= kdp_machine_vm_write((caddr_t
)&breakpoint_list
[i
].oldbytes
, address
, breakpoint_list
[i
].bytesused
);
990 return KDPERR_NO_ERROR
;
994 kdp_remove_all_breakpoints(void)
997 boolean_t breakpoint_found
= FALSE
;
999 if (breakpoints_initialized
) {
1000 for (i
= 0; i
< MAX_BREAKPOINTS
; i
++) {
1001 if (breakpoint_list
[i
].address
) {
1002 kdp_machine_vm_write((caddr_t
)&(breakpoint_list
[i
].oldbytes
), (mach_vm_address_t
)breakpoint_list
[i
].address
, (mach_vm_size_t
)breakpoint_list
[i
].bytesused
);
1003 breakpoint_found
= TRUE
;
1004 breakpoint_list
[i
].address
= 0;
1008 if (breakpoint_found
) {
1009 printf("kdp_remove_all_breakpoints: found extant breakpoints, removing them.\n");
1012 return breakpoint_found
;
1017 __unused kdp_pkt_t
*pkt
,
1019 __unused
unsigned short *reply_port
1022 dprintf(("kdp_reboot\n"));
1024 kdp_machine_reboot();
1026 return TRUE
; // no, not really, we won't return
1033 unsigned short *reply_port
1036 kdp_readioport_req_t
*rq
= &pkt
->readioport_req
;
1037 kdp_readioport_reply_t
*rp
= &pkt
->readioport_reply
;
1040 if (plen
< sizeof(*rq
)) {
1044 rp
->hdr
.is_reply
= 1;
1045 rp
->hdr
.len
= sizeof(*rp
);
1047 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
) {
1048 rp
->error
= KDPERR_BAD_NBYTES
;
1050 #if KDP_TEST_HARNESS
1051 uint16_t addr
= rq
->address
;
1053 uint16_t size
= rq
->nbytes
;
1054 dprintf(("kdp_readioport addr %x size %d\n", addr
, size
));
1056 rp
->error
= kdp_machine_ioport_read(rq
, rp
->data
, rq
->lcpu
);
1057 if (rp
->error
== KDPERR_NO_ERROR
) {
1058 rp
->hdr
.len
+= size
;
1062 *reply_port
= kdp
.reply_port
;
1072 unsigned short *reply_port
1075 kdp_writeioport_req_t
*rq
= &pkt
->writeioport_req
;
1076 kdp_writeioport_reply_t
*rp
= &pkt
->writeioport_reply
;
1079 if (plen
< sizeof(*rq
)) {
1083 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
) {
1084 rp
->error
= KDPERR_BAD_NBYTES
;
1086 dprintf(("kdp_writeioport addr %x size %d\n", rq
->address
,
1089 rp
->error
= kdp_machine_ioport_write(rq
, rq
->data
, rq
->lcpu
);
1092 rp
->hdr
.is_reply
= 1;
1093 rp
->hdr
.len
= sizeof(*rp
);
1095 *reply_port
= kdp
.reply_port
;
1105 unsigned short *reply_port
1108 kdp_readmsr64_req_t
*rq
= &pkt
->readmsr64_req
;
1109 kdp_readmsr64_reply_t
*rp
= &pkt
->readmsr64_reply
;
1112 if (plen
< sizeof(*rq
)) {
1116 rp
->hdr
.is_reply
= 1;
1117 rp
->hdr
.len
= sizeof(*rp
);
1119 dprintf(("kdp_readmsr64 lcpu %x addr %x\n", rq
->lcpu
, rq
->address
));
1120 rp
->error
= kdp_machine_msr64_read(rq
, rp
->data
, rq
->lcpu
);
1121 if (rp
->error
== KDPERR_NO_ERROR
) {
1122 rp
->hdr
.len
+= sizeof(uint64_t);
1125 *reply_port
= kdp
.reply_port
;
1135 unsigned short *reply_port
1138 kdp_writemsr64_req_t
*rq
= &pkt
->writemsr64_req
;
1139 kdp_writemsr64_reply_t
*rp
= &pkt
->writemsr64_reply
;
1142 if (plen
< sizeof(*rq
)) {
1146 dprintf(("kdp_writemsr64 lcpu %x addr %x\n", rq
->lcpu
, rq
->address
));
1147 rp
->error
= kdp_machine_msr64_write(rq
, rq
->data
, rq
->lcpu
);
1149 rp
->hdr
.is_reply
= 1;
1150 rp
->hdr
.len
= sizeof(*rp
);
1152 *reply_port
= kdp
.reply_port
;
1162 unsigned short *reply_port
1165 kdp_dumpinfo_req_t
*rq
= &pkt
->dumpinfo_req
;
1166 kdp_dumpinfo_reply_t
*rp
= &pkt
->dumpinfo_reply
;
1169 if (plen
< sizeof(*rq
)) {
1173 dprintf(("kdp_dumpinfo file=%s destip=%s routerip=%s\n", rq
->name
, rq
->destip
, rq
->routerip
));
1174 rp
->hdr
.is_reply
= 1;
1175 rp
->hdr
.len
= sizeof(*rp
);
1177 if ((rq
->type
& KDP_DUMPINFO_MASK
) != KDP_DUMPINFO_GETINFO
) {
1178 kdp_set_dump_info(rq
->type
, rq
->name
, rq
->destip
, rq
->routerip
,
1182 /* gather some stats for reply */
1183 kdp_get_dump_info(rp
);
1185 *reply_port
= kdp
.reply_port
;