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/version.h>
42 #include <string.h> /* bcopy */
44 #include <kern/processor.h>
45 #include <kern/thread.h>
46 #include <kern/clock.h>
47 #include <vm/vm_map.h>
48 #include <vm/vm_kern.h>
49 #include <vm/vm_pageout.h>
50 #include <vm/vm_shared_region.h>
51 #include <libkern/OSKextLibPrivate.h>
53 #define DO_ALIGN 1 /* align all packet data accesses */
55 #define KDP_TEST_HARNESS 0
57 #define dprintf(x) kprintf x
63 dispatch_table
[KDP_INVALID_REQUEST
-KDP_CONNECT
] =
66 /* 1 */ kdp_disconnect
,
73 /* 8 */ kdp_writeregs
,
77 /* C */ kdp_resumecpus
,
80 /* F */ kdp_breakpoint_set
,
81 /*10 */ kdp_breakpoint_remove
,
85 /*14 */ kdp_readmem64
,
86 /*15 */ kdp_writemem64
,
87 /*16 */ kdp_breakpoint64_set
,
88 /*17 */ kdp_breakpoint64_remove
,
89 /*18 */ kdp_kernelversion
,
90 /*19 */ kdp_readphysmem64
,
91 /*1A */ kdp_writephysmem64
,
92 /*1B */ kdp_readioport
,
93 /*1C */ kdp_writeioport
,
94 /*1D */ kdp_readmsr64
,
95 /*1E */ kdp_writemsr64
,
101 #define MAX_BREAKPOINTS 100
104 * Version 11 of the KDP Protocol adds support for 64-bit wide memory
105 * addresses (read/write and breakpoints) as well as a dedicated
106 * kernelversion request. Version 12 adds read/writing of physical
107 * memory with 64-bit wide memory addresses.
109 #define KDP_VERSION 12
112 mach_vm_address_t address
;
114 uint8_t oldbytes
[MAX_BREAKINSN_BYTES
];
115 } kdp_breakpoint_record_t
;
117 static kdp_breakpoint_record_t breakpoint_list
[MAX_BREAKPOINTS
];
118 static unsigned int breakpoints_initialized
= 0;
120 int reattach_wait
= 0;
121 int noresume_on_disconnect
= 0;
122 extern unsigned int return_on_panic
;
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 bcopy((char *)pkt
, (char *)rd
, sizeof(aligned_pkt
));
150 rd
= (kdp_pkt_t
*)pkt
;
152 if (plen
< sizeof (rd
->hdr
) || rd
->hdr
.len
!= plen
) {
153 printf("kdp_packet bad len pkt %lu hdr %d\n", plen
, rd
->hdr
.len
);
158 if (rd
->hdr
.is_reply
) {
159 printf("kdp_packet reply recvd req %x seq %x\n",
160 rd
->hdr
.request
, rd
->hdr
.seq
);
165 req
= rd
->hdr
.request
;
166 if (req
>= KDP_INVALID_REQUEST
) {
167 printf("kdp_packet bad request %x len %d seq %x key %x\n",
168 rd
->hdr
.request
, rd
->hdr
.len
, rd
->hdr
.seq
, rd
->hdr
.key
);
173 ret
= ((*dispatch_table
[req
- KDP_CONNECT
])(rd
, len
, reply_port
));
175 bcopy((char *)rd
, (char *) pkt
, *len
);
184 __unused
unsigned short *reply_port
187 kdp_pkt_t
*rd
= (kdp_pkt_t
*)pkt
;
189 printf("kdp_unknown request %x len %d seq %x key %x\n",
190 rd
->hdr
.request
, rd
->hdr
.len
, rd
->hdr
.seq
, rd
->hdr
.key
);
199 unsigned short *reply_port
202 kdp_connect_req_t
*rq
= &pkt
->connect_req
;
204 kdp_connect_reply_t
*rp
= &pkt
->connect_reply
;
205 uint16_t rport
, eport
;
209 if (plen
< sizeof (*rq
))
212 dprintf(("kdp_connect seq %x greeting %s\n", rq
->hdr
.seq
, rq
->greeting
));
214 rport
= rq
->req_reply_port
;
215 eport
= rq
->exc_note_port
;
219 if ((seq
== kdp
.conn_seq
) && /* duplicate request */
220 (rport
== kdp
.reply_port
) &&
221 (eport
== kdp
.exception_port
) &&
222 (key
== kdp
.session_key
))
223 rp
->error
= KDPERR_NO_ERROR
;
225 rp
->error
= KDPERR_ALREADY_CONNECTED
;
228 kdp
.reply_port
= rport
;
229 kdp
.exception_port
= eport
;
232 kdp
.session_key
= key
;
234 rp
->error
= KDPERR_NO_ERROR
;
237 rp
->hdr
.is_reply
= 1;
238 rp
->hdr
.len
= sizeof (*rp
);
243 if (current_debugger
== KDP_CUR_DB
)
253 unsigned short *reply_port
256 kdp_disconnect_req_t
*rq
= &pkt
->disconnect_req
;
258 kdp_disconnect_reply_t
*rp
= &pkt
->disconnect_reply
;
260 if (plen
< sizeof (*rq
))
266 dprintf(("kdp_disconnect\n"));
268 *reply_port
= kdp
.reply_port
;
270 kdp
.reply_port
= kdp
.exception_port
= 0;
271 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
272 kdp
.exception_seq
= kdp
.conn_seq
= 0;
275 if ((panicstr
!= NULL
) && (return_on_panic
== 0))
278 if (noresume_on_disconnect
== 1) {
280 noresume_on_disconnect
= 0;
283 rp
->hdr
.is_reply
= 1;
284 rp
->hdr
.len
= sizeof (*rp
);
288 if (current_debugger
== KDP_CUR_DB
)
298 unsigned short *reply_port
301 kdp_reattach_req_t
*rq
= &pkt
->reattach_req
;
304 kdp_disconnect(pkt
, len
, reply_port
);
305 *reply_port
= rq
->req_reply_port
;
314 unsigned short *reply_port
317 kdp_hostinfo_req_t
*rq
= &pkt
->hostinfo_req
;
319 kdp_hostinfo_reply_t
*rp
= &pkt
->hostinfo_reply
;
321 if (plen
< sizeof (*rq
))
324 dprintf(("kdp_hostinfo\n"));
326 rp
->hdr
.is_reply
= 1;
327 rp
->hdr
.len
= sizeof (*rp
);
329 kdp_machine_hostinfo(&rp
->hostinfo
);
331 *reply_port
= kdp
.reply_port
;
341 unsigned short *reply_port
344 kdp_kernelversion_req_t
*rq
= &pkt
->kernelversion_req
;
346 kdp_kernelversion_reply_t
*rp
= &pkt
->kernelversion_reply
;
349 if (plen
< sizeof (*rq
))
352 rp
->hdr
.is_reply
= 1;
353 rp
->hdr
.len
= sizeof (*rp
);
355 dprintf(("kdp_kernelversion\n"));
356 slen
= strlcpy(rp
->version
, kdp_kernelversion_string
, MAX_KDP_DATA_SIZE
);
358 rp
->hdr
.len
+= slen
+ 1; /* strlcpy returns the amount copied with NUL */
360 *reply_port
= kdp
.reply_port
;
370 unsigned short *reply_port
373 kdp_suspend_req_t
*rq
= &pkt
->suspend_req
;
375 kdp_suspend_reply_t
*rp
= &pkt
->suspend_reply
;
377 if (plen
< sizeof (*rq
))
380 rp
->hdr
.is_reply
= 1;
381 rp
->hdr
.len
= sizeof (*rp
);
383 dprintf(("kdp_suspend\n"));
385 kdp
.is_halted
= TRUE
;
387 *reply_port
= kdp
.reply_port
;
397 unsigned short *reply_port
400 kdp_resumecpus_req_t
*rq
= &pkt
->resumecpus_req
;
402 kdp_resumecpus_reply_t
*rp
= &pkt
->resumecpus_reply
;
404 if (plen
< sizeof (*rq
))
407 rp
->hdr
.is_reply
= 1;
408 rp
->hdr
.len
= sizeof (*rp
);
410 dprintf(("kdp_resumecpus %x\n", rq
->cpu_mask
));
412 kdp
.is_halted
= FALSE
;
414 *reply_port
= kdp
.reply_port
;
424 unsigned short *reply_port
427 kdp_writemem_req_t
*rq
= &pkt
->writemem_req
;
429 kdp_writemem_reply_t
*rp
= &pkt
->writemem_reply
;
432 if (plen
< sizeof (*rq
))
435 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
436 rp
->error
= KDPERR_BAD_NBYTES
;
438 dprintf(("kdp_writemem addr %x size %d\n", rq
->address
, rq
->nbytes
));
439 cnt
= kdp_machine_vm_write((caddr_t
)rq
->data
, (mach_vm_address_t
)rq
->address
, rq
->nbytes
);
440 rp
->error
= KDPERR_ACCESS(rq
->nbytes
, cnt
);
441 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
444 rp
->hdr
.is_reply
= 1;
445 rp
->hdr
.len
= sizeof (*rp
);
447 *reply_port
= kdp
.reply_port
;
457 unsigned short *reply_port
460 kdp_writemem64_req_t
*rq
= &pkt
->writemem64_req
;
462 kdp_writemem64_reply_t
*rp
= &pkt
->writemem64_reply
;
465 if (plen
< sizeof (*rq
))
468 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
469 rp
->error
= KDPERR_BAD_NBYTES
;
471 dprintf(("kdp_writemem64 addr %llx size %d\n", rq
->address
, rq
->nbytes
));
472 cnt
= kdp_machine_vm_write((caddr_t
)rq
->data
, (mach_vm_address_t
)rq
->address
, (mach_vm_size_t
)rq
->nbytes
);
473 rp
->error
= KDPERR_ACCESS(rq
->nbytes
, cnt
);
474 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
477 rp
->hdr
.is_reply
= 1;
478 rp
->hdr
.len
= sizeof (*rp
);
480 *reply_port
= kdp
.reply_port
;
490 unsigned short *reply_port
493 kdp_writephysmem64_req_t
*rq
= &pkt
->writephysmem64_req
;
495 kdp_writephysmem64_reply_t
*rp
= &pkt
->writephysmem64_reply
;
499 if (plen
< sizeof (*rq
))
503 if (size
> MAX_KDP_DATA_SIZE
)
504 rp
->error
= KDPERR_BAD_NBYTES
;
506 dprintf(("kdp_writephysmem64 addr %llx size %d\n", rq
->address
, size
));
507 cnt
= kdp_machine_phys_write(rq
, rq
->data
, rq
->lcpu
);
508 rp
->error
= KDPERR_ACCESS(size
, cnt
);
509 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
512 rp
->hdr
.is_reply
= 1;
513 rp
->hdr
.len
= sizeof (*rp
);
515 *reply_port
= kdp
.reply_port
;
525 unsigned short *reply_port
528 kdp_readmem_req_t
*rq
= &pkt
->readmem_req
;
530 kdp_readmem_reply_t
*rp
= &pkt
->readmem_reply
;
534 if (plen
< sizeof (*rq
))
537 rp
->hdr
.is_reply
= 1;
538 rp
->hdr
.len
= sizeof (*rp
);
541 if (size
> MAX_KDP_DATA_SIZE
)
542 rp
->error
= KDPERR_BAD_NBYTES
;
544 dprintf(("kdp_readmem addr %x size %d\n", rq
->address
, size
));
545 cnt
= kdp_machine_vm_read((mach_vm_address_t
)rq
->address
, (caddr_t
)rp
->data
, rq
->nbytes
);
546 rp
->error
= KDPERR_ACCESS(size
, cnt
);
547 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
552 *reply_port
= kdp
.reply_port
;
562 unsigned short *reply_port
565 kdp_readmem64_req_t
*rq
= &pkt
->readmem64_req
;
567 kdp_readmem64_reply_t
*rp
= &pkt
->readmem64_reply
;
571 if (plen
< sizeof (*rq
))
574 rp
->hdr
.is_reply
= 1;
575 rp
->hdr
.len
= sizeof (*rp
);
578 if (size
> MAX_KDP_DATA_SIZE
)
579 rp
->error
= KDPERR_BAD_NBYTES
;
581 dprintf(("kdp_readmem64 addr %llx size %d\n", rq
->address
, size
));
582 cnt
= kdp_machine_vm_read((mach_vm_address_t
)rq
->address
, (caddr_t
)rp
->data
, rq
->nbytes
);
583 rp
->error
= KDPERR_ACCESS(size
, cnt
);
584 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
589 *reply_port
= kdp
.reply_port
;
599 unsigned short *reply_port
602 kdp_readphysmem64_req_t
*rq
= &pkt
->readphysmem64_req
;
604 kdp_readphysmem64_reply_t
*rp
= &pkt
->readphysmem64_reply
;
608 if (plen
< sizeof (*rq
))
611 rp
->hdr
.is_reply
= 1;
612 rp
->hdr
.len
= sizeof (*rp
);
615 if (size
> MAX_KDP_DATA_SIZE
)
616 rp
->error
= KDPERR_BAD_NBYTES
;
618 dprintf(("kdp_readphysmem64 addr %llx size %d\n", rq
->address
, size
));
619 cnt
= kdp_machine_phys_read(rq
, rp
->data
, rq
->lcpu
);
620 rp
->error
= KDPERR_ACCESS(size
, cnt
);
621 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
626 *reply_port
= kdp
.reply_port
;
636 unsigned short *reply_port
639 kdp_maxbytes_req_t
*rq
= &pkt
->maxbytes_req
;
641 kdp_maxbytes_reply_t
*rp
= &pkt
->maxbytes_reply
;
643 if (plen
< sizeof (*rq
))
646 rp
->hdr
.is_reply
= 1;
647 rp
->hdr
.len
= sizeof (*rp
);
649 dprintf(("kdp_maxbytes\n"));
651 rp
->max_bytes
= MAX_KDP_DATA_SIZE
;
653 *reply_port
= kdp
.reply_port
;
663 unsigned short *reply_port
666 kdp_version_req_t
*rq
= &pkt
->version_req
;
668 kdp_version_reply_t
*rp
= &pkt
->version_reply
;
670 if (plen
< sizeof (*rq
))
673 rp
->hdr
.is_reply
= 1;
674 rp
->hdr
.len
= sizeof (*rp
);
676 dprintf(("kdp_version\n"));
678 rp
->version
= KDP_VERSION
;
679 if (!(kdp_flag
& KDP_BP_DIS
))
680 rp
->feature
= KDP_FEATURE_BP
;
684 *reply_port
= kdp
.reply_port
;
694 unsigned short *reply_port
697 kdp_regions_req_t
*rq
= &pkt
->regions_req
;
699 kdp_regions_reply_t
*rp
= &pkt
->regions_reply
;
702 if (plen
< sizeof (*rq
))
705 rp
->hdr
.is_reply
= 1;
706 rp
->hdr
.len
= sizeof (*rp
);
708 dprintf(("kdp_regions\n"));
714 r
->nbytes
= 0xffffffff;
716 r
->protection
= VM_PROT_ALL
; r
++; rp
->nregions
++;
718 rp
->hdr
.len
+= rp
->nregions
* sizeof (kdp_region_t
);
720 *reply_port
= kdp
.reply_port
;
730 unsigned short *reply_port
733 kdp_writeregs_req_t
*rq
= &pkt
->writeregs_req
;
736 kdp_writeregs_reply_t
*rp
= &pkt
->writeregs_reply
;
738 if (plen
< sizeof (*rq
))
741 size
= rq
->hdr
.len
- (unsigned)sizeof(kdp_hdr_t
) - (unsigned)sizeof(unsigned int);
742 rp
->error
= kdp_machine_write_regs(rq
->cpu
, rq
->flavor
, rq
->data
, &size
);
744 rp
->hdr
.is_reply
= 1;
745 rp
->hdr
.len
= sizeof (*rp
);
747 *reply_port
= kdp
.reply_port
;
757 unsigned short *reply_port
760 kdp_readregs_req_t
*rq
= &pkt
->readregs_req
;
762 kdp_readregs_reply_t
*rp
= &pkt
->readregs_reply
;
765 if (plen
< sizeof (*rq
))
768 rp
->hdr
.is_reply
= 1;
769 rp
->hdr
.len
= sizeof (*rp
);
771 rp
->error
= kdp_machine_read_regs(rq
->cpu
, rq
->flavor
, rp
->data
, &size
);
774 *reply_port
= kdp
.reply_port
;
785 unsigned short *reply_port
788 kdp_breakpoint_req_t
*rq
= &pkt
->breakpoint_req
;
789 kdp_breakpoint_reply_t
*rp
= &pkt
->breakpoint_reply
;
793 if (plen
< sizeof (*rq
))
796 dprintf(("kdp_breakpoint_set %x\n", rq
->address
));
798 kerr
= kdp_set_breakpoint_internal((mach_vm_address_t
)rq
->address
);
802 rp
->hdr
.is_reply
= 1;
803 rp
->hdr
.len
= sizeof (*rp
);
804 *reply_port
= kdp
.reply_port
;
811 kdp_breakpoint64_set(
814 unsigned short *reply_port
817 kdp_breakpoint64_req_t
*rq
= &pkt
->breakpoint64_req
;
818 kdp_breakpoint64_reply_t
*rp
= &pkt
->breakpoint64_reply
;
822 if (plen
< sizeof (*rq
))
825 dprintf(("kdp_breakpoint64_set %llx\n", rq
->address
));
827 kerr
= kdp_set_breakpoint_internal((mach_vm_address_t
)rq
->address
);
831 rp
->hdr
.is_reply
= 1;
832 rp
->hdr
.len
= sizeof (*rp
);
833 *reply_port
= kdp
.reply_port
;
840 kdp_breakpoint_remove(
843 unsigned short *reply_port
846 kdp_breakpoint_req_t
*rq
= &pkt
->breakpoint_req
;
847 kdp_breakpoint_reply_t
*rp
= &pkt
->breakpoint_reply
;
850 if (plen
< sizeof (*rq
))
853 dprintf(("kdp_breakpoint_remove %x\n", rq
->address
));
855 kerr
= kdp_remove_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_breakpoint64_remove(
871 unsigned short *reply_port
874 kdp_breakpoint64_req_t
*rq
= &pkt
->breakpoint64_req
;
875 kdp_breakpoint64_reply_t
*rp
= &pkt
->breakpoint64_reply
;
879 if (plen
< sizeof (*rq
))
882 dprintf(("kdp_breakpoint64_remove %llx\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
;
898 kdp_set_breakpoint_internal(
899 mach_vm_address_t address
903 uint8_t breakinstr
[MAX_BREAKINSN_BYTES
], oldinstr
[MAX_BREAKINSN_BYTES
];
904 uint32_t breakinstrsize
= sizeof(breakinstr
);
908 kdp_machine_get_breakinsn(breakinstr
, &breakinstrsize
);
910 if(breakpoints_initialized
== 0)
912 for(i
=0;(i
< MAX_BREAKPOINTS
); breakpoint_list
[i
].address
=0, i
++);
913 breakpoints_initialized
++;
916 cnt
= kdp_machine_vm_read(address
, (caddr_t
)&oldinstr
, (mach_vm_size_t
)breakinstrsize
);
918 if (0 == memcmp(oldinstr
, breakinstr
, breakinstrsize
)) {
919 printf("A trap was already set at that address, not setting new breakpoint\n");
921 return KDPERR_BREAKPOINT_ALREADY_SET
;
924 for(i
=0;(i
< MAX_BREAKPOINTS
) && (breakpoint_list
[i
].address
!= 0); i
++);
926 if (i
== MAX_BREAKPOINTS
) {
927 return KDPERR_MAX_BREAKPOINTS
;
930 breakpoint_list
[i
].address
= address
;
931 memcpy(breakpoint_list
[i
].oldbytes
, oldinstr
, breakinstrsize
);
932 breakpoint_list
[i
].bytesused
= breakinstrsize
;
934 cnt
= kdp_machine_vm_write((caddr_t
)&breakinstr
, address
, breakinstrsize
);
936 return KDPERR_NO_ERROR
;
940 kdp_remove_breakpoint_internal(
941 mach_vm_address_t address
947 for(i
=0;(i
< MAX_BREAKPOINTS
) && (breakpoint_list
[i
].address
!= address
); i
++);
949 if (i
== MAX_BREAKPOINTS
)
951 return KDPERR_BREAKPOINT_NOT_FOUND
;
954 breakpoint_list
[i
].address
= 0;
955 cnt
= kdp_machine_vm_write((caddr_t
)&breakpoint_list
[i
].oldbytes
, address
, breakpoint_list
[i
].bytesused
);
957 return KDPERR_NO_ERROR
;
961 kdp_remove_all_breakpoints(void)
964 boolean_t breakpoint_found
= FALSE
;
966 if (breakpoints_initialized
)
968 for(i
=0;i
< MAX_BREAKPOINTS
; i
++)
970 if (breakpoint_list
[i
].address
)
972 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
);
973 breakpoint_found
= TRUE
;
974 breakpoint_list
[i
].address
= 0;
978 if (breakpoint_found
)
979 printf("kdp_remove_all_breakpoints: found extant breakpoints, removing them.\n");
981 return breakpoint_found
;
986 __unused kdp_pkt_t
*pkt
,
988 __unused
unsigned short *reply_port
991 dprintf(("kdp_reboot\n"));
993 kdp_machine_reboot();
995 return (TRUE
); // no, not really, we won't return
1002 unsigned short *reply_port
1005 kdp_readioport_req_t
*rq
= &pkt
->readioport_req
;
1006 kdp_readioport_reply_t
*rp
= &pkt
->readioport_reply
;
1009 if (plen
< sizeof (*rq
))
1012 rp
->hdr
.is_reply
= 1;
1013 rp
->hdr
.len
= sizeof (*rp
);
1015 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
1016 rp
->error
= KDPERR_BAD_NBYTES
;
1018 #if KDP_TEST_HARNESS
1019 uint16_t addr
= rq
->address
;
1021 uint16_t size
= rq
->nbytes
;
1022 dprintf(("kdp_readioport addr %x size %d\n", addr
, size
));
1024 rp
->error
= kdp_machine_ioport_read(rq
, rp
->data
, rq
->lcpu
);
1025 if (rp
->error
== KDPERR_NO_ERROR
)
1026 rp
->hdr
.len
+= size
;
1029 *reply_port
= kdp
.reply_port
;
1039 unsigned short *reply_port
1042 kdp_writeioport_req_t
*rq
= &pkt
->writeioport_req
;
1043 kdp_writeioport_reply_t
*rp
= &pkt
->writeioport_reply
;
1046 if (plen
< sizeof (*rq
))
1049 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
1050 rp
->error
= KDPERR_BAD_NBYTES
;
1052 dprintf(("kdp_writeioport addr %x size %d\n", rq
->address
,
1055 rp
->error
= kdp_machine_ioport_write(rq
, rq
->data
, rq
->lcpu
);
1058 rp
->hdr
.is_reply
= 1;
1059 rp
->hdr
.len
= sizeof (*rp
);
1061 *reply_port
= kdp
.reply_port
;
1071 unsigned short *reply_port
1074 kdp_readmsr64_req_t
*rq
= &pkt
->readmsr64_req
;
1075 kdp_readmsr64_reply_t
*rp
= &pkt
->readmsr64_reply
;
1078 if (plen
< sizeof (*rq
))
1081 rp
->hdr
.is_reply
= 1;
1082 rp
->hdr
.len
= sizeof (*rp
);
1084 dprintf(("kdp_readmsr64 lcpu %x addr %x\n", rq
->lcpu
, rq
->address
));
1085 rp
->error
= kdp_machine_msr64_read(rq
, rp
->data
, rq
->lcpu
);
1086 if (rp
->error
== KDPERR_NO_ERROR
)
1087 rp
->hdr
.len
+= sizeof(uint64_t);
1089 *reply_port
= kdp
.reply_port
;
1099 unsigned short *reply_port
1102 kdp_writemsr64_req_t
*rq
= &pkt
->writemsr64_req
;
1103 kdp_writemsr64_reply_t
*rp
= &pkt
->writemsr64_reply
;
1106 if (plen
< sizeof (*rq
))
1109 dprintf(("kdp_writemsr64 lcpu %x addr %x\n", rq
->lcpu
, rq
->address
));
1110 rp
->error
= kdp_machine_msr64_write(rq
, rq
->data
, rq
->lcpu
);
1112 rp
->hdr
.is_reply
= 1;
1113 rp
->hdr
.len
= sizeof (*rp
);
1115 *reply_port
= kdp
.reply_port
;
1125 unsigned short *reply_port
1128 kdp_dumpinfo_req_t
*rq
= &pkt
->dumpinfo_req
;
1129 kdp_dumpinfo_reply_t
*rp
= &pkt
->dumpinfo_reply
;
1132 if (plen
< sizeof (*rq
))
1135 dprintf(("kdp_dumpinfo file=%s destip=%s routerip=%s\n", rq
->name
, rq
->destip
, rq
->routerip
));
1136 rp
->hdr
.is_reply
= 1;
1137 rp
->hdr
.len
= sizeof (*rp
);
1139 if ((rq
->type
& KDP_DUMPINFO_MASK
) != KDP_DUMPINFO_GETINFO
) {
1140 kdp_set_dump_info(rq
->type
, rq
->name
, rq
->destip
, rq
->routerip
,
1144 /* gather some stats for reply */
1145 kdp_get_dump_info(&rp
->type
, rp
->name
, rp
->destip
, rp
->routerip
,
1148 *reply_port
= kdp
.reply_port
;