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 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
))
216 dprintf(("kdp_connect seq %x greeting %s\n", rq
->hdr
.seq
, rq
->greeting
));
218 rport
= rq
->req_reply_port
;
219 eport
= rq
->exc_note_port
;
223 if ((seq
== kdp
.conn_seq
) && /* duplicate request */
224 (rport
== kdp
.reply_port
) &&
225 (eport
== kdp
.exception_port
) &&
226 (key
== kdp
.session_key
))
227 rp
->error
= KDPERR_NO_ERROR
;
229 rp
->error
= KDPERR_ALREADY_CONNECTED
;
232 kdp
.reply_port
= rport
;
233 kdp
.exception_port
= eport
;
236 kdp
.session_key
= key
;
238 rp
->error
= KDPERR_NO_ERROR
;
241 rp
->hdr
.is_reply
= 1;
242 rp
->hdr
.len
= sizeof (*rp
);
247 if (current_debugger
== KDP_CUR_DB
)
257 unsigned short *reply_port
260 kdp_disconnect_req_t
*rq
= &pkt
->disconnect_req
;
262 kdp_disconnect_reply_t
*rp
= &pkt
->disconnect_reply
;
264 if (plen
< sizeof (*rq
))
270 dprintf(("kdp_disconnect\n"));
272 *reply_port
= kdp
.reply_port
;
274 kdp
.reply_port
= kdp
.exception_port
= 0;
275 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
276 kdp
.exception_seq
= kdp
.conn_seq
= 0;
279 if ((panicstr
!= NULL
) && (return_on_panic
== 0))
282 if (noresume_on_disconnect
== 1) {
284 noresume_on_disconnect
= 0;
287 rp
->hdr
.is_reply
= 1;
288 rp
->hdr
.len
= sizeof (*rp
);
292 if (current_debugger
== KDP_CUR_DB
)
302 unsigned short *reply_port
305 kdp_reattach_req_t
*rq
= &pkt
->reattach_req
;
308 kdp_disconnect(pkt
, len
, reply_port
);
309 *reply_port
= rq
->req_reply_port
;
318 unsigned short *reply_port
321 kdp_hostinfo_req_t
*rq
= &pkt
->hostinfo_req
;
323 kdp_hostinfo_reply_t
*rp
= &pkt
->hostinfo_reply
;
325 if (plen
< sizeof (*rq
))
328 dprintf(("kdp_hostinfo\n"));
330 rp
->hdr
.is_reply
= 1;
331 rp
->hdr
.len
= sizeof (*rp
);
333 kdp_machine_hostinfo(&rp
->hostinfo
);
335 *reply_port
= kdp
.reply_port
;
345 unsigned short *reply_port
348 kdp_kernelversion_req_t
*rq
= &pkt
->kernelversion_req
;
350 kdp_kernelversion_reply_t
*rp
= &pkt
->kernelversion_reply
;
353 if (plen
< sizeof (*rq
))
356 rp
->hdr
.is_reply
= 1;
357 rp
->hdr
.len
= sizeof (*rp
);
359 dprintf(("kdp_kernelversion\n"));
360 slen
= strlcpy(rp
->version
, kdp_kernelversion_string
, MAX_KDP_DATA_SIZE
);
362 rp
->hdr
.len
+= slen
+ 1; /* strlcpy returns the amount copied with NUL */
364 *reply_port
= kdp
.reply_port
;
374 unsigned short *reply_port
377 kdp_suspend_req_t
*rq
= &pkt
->suspend_req
;
379 kdp_suspend_reply_t
*rp
= &pkt
->suspend_reply
;
381 if (plen
< sizeof (*rq
))
384 rp
->hdr
.is_reply
= 1;
385 rp
->hdr
.len
= sizeof (*rp
);
387 dprintf(("kdp_suspend\n"));
389 kdp
.is_halted
= TRUE
;
391 *reply_port
= kdp
.reply_port
;
401 unsigned short *reply_port
404 kdp_resumecpus_req_t
*rq
= &pkt
->resumecpus_req
;
406 kdp_resumecpus_reply_t
*rp
= &pkt
->resumecpus_reply
;
408 if (plen
< sizeof (*rq
))
411 rp
->hdr
.is_reply
= 1;
412 rp
->hdr
.len
= sizeof (*rp
);
414 dprintf(("kdp_resumecpus %x\n", rq
->cpu_mask
));
416 kdp
.is_halted
= FALSE
;
418 *reply_port
= kdp
.reply_port
;
428 unsigned short *reply_port
431 kdp_writemem_req_t
*rq
= &pkt
->writemem_req
;
433 kdp_writemem_reply_t
*rp
= &pkt
->writemem_reply
;
436 if (plen
< sizeof (*rq
))
439 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
440 rp
->error
= KDPERR_BAD_NBYTES
;
442 dprintf(("kdp_writemem addr %x size %d\n", rq
->address
, rq
->nbytes
));
443 cnt
= kdp_machine_vm_write((caddr_t
)rq
->data
, (mach_vm_address_t
)rq
->address
, rq
->nbytes
);
444 rp
->error
= KDPERR_ACCESS(rq
->nbytes
, cnt
);
445 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
448 rp
->hdr
.is_reply
= 1;
449 rp
->hdr
.len
= sizeof (*rp
);
451 *reply_port
= kdp
.reply_port
;
461 unsigned short *reply_port
464 kdp_writemem64_req_t
*rq
= &pkt
->writemem64_req
;
466 kdp_writemem64_reply_t
*rp
= &pkt
->writemem64_reply
;
469 if (plen
< sizeof (*rq
))
472 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
473 rp
->error
= KDPERR_BAD_NBYTES
;
475 dprintf(("kdp_writemem64 addr %llx size %d\n", rq
->address
, rq
->nbytes
));
476 cnt
= kdp_machine_vm_write((caddr_t
)rq
->data
, (mach_vm_address_t
)rq
->address
, (mach_vm_size_t
)rq
->nbytes
);
477 rp
->error
= KDPERR_ACCESS(rq
->nbytes
, cnt
);
478 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
481 rp
->hdr
.is_reply
= 1;
482 rp
->hdr
.len
= sizeof (*rp
);
484 *reply_port
= kdp
.reply_port
;
494 unsigned short *reply_port
497 kdp_writephysmem64_req_t
*rq
= &pkt
->writephysmem64_req
;
499 kdp_writephysmem64_reply_t
*rp
= &pkt
->writephysmem64_reply
;
503 if (plen
< sizeof (*rq
))
507 if (size
> MAX_KDP_DATA_SIZE
)
508 rp
->error
= KDPERR_BAD_NBYTES
;
510 dprintf(("kdp_writephysmem64 addr %llx size %d\n", rq
->address
, size
));
511 cnt
= kdp_machine_phys_write(rq
, rq
->data
, rq
->lcpu
);
512 rp
->error
= KDPERR_ACCESS(size
, cnt
);
513 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
516 rp
->hdr
.is_reply
= 1;
517 rp
->hdr
.len
= sizeof (*rp
);
519 *reply_port
= kdp
.reply_port
;
529 unsigned short *reply_port
532 kdp_readmem_req_t
*rq
= &pkt
->readmem_req
;
534 kdp_readmem_reply_t
*rp
= &pkt
->readmem_reply
;
538 if (plen
< sizeof (*rq
))
541 rp
->hdr
.is_reply
= 1;
542 rp
->hdr
.len
= sizeof (*rp
);
545 if (size
> MAX_KDP_DATA_SIZE
)
546 rp
->error
= KDPERR_BAD_NBYTES
;
548 dprintf(("kdp_readmem addr %x size %d\n", rq
->address
, size
));
549 cnt
= kdp_machine_vm_read((mach_vm_address_t
)rq
->address
, (caddr_t
)rp
->data
, rq
->nbytes
);
550 rp
->error
= KDPERR_ACCESS(size
, cnt
);
551 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
556 *reply_port
= kdp
.reply_port
;
566 unsigned short *reply_port
569 kdp_readmem64_req_t
*rq
= &pkt
->readmem64_req
;
571 kdp_readmem64_reply_t
*rp
= &pkt
->readmem64_reply
;
575 if (plen
< sizeof (*rq
))
578 rp
->hdr
.is_reply
= 1;
579 rp
->hdr
.len
= sizeof (*rp
);
582 if (size
> MAX_KDP_DATA_SIZE
)
583 rp
->error
= KDPERR_BAD_NBYTES
;
585 dprintf(("kdp_readmem64 addr %llx size %d\n", rq
->address
, size
));
586 cnt
= kdp_machine_vm_read((mach_vm_address_t
)rq
->address
, (caddr_t
)rp
->data
, rq
->nbytes
);
587 rp
->error
= KDPERR_ACCESS(size
, cnt
);
588 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
593 *reply_port
= kdp
.reply_port
;
603 unsigned short *reply_port
606 kdp_readphysmem64_req_t
*rq
= &pkt
->readphysmem64_req
;
608 kdp_readphysmem64_reply_t
*rp
= &pkt
->readphysmem64_reply
;
612 if (plen
< sizeof (*rq
))
615 rp
->hdr
.is_reply
= 1;
616 rp
->hdr
.len
= sizeof (*rp
);
619 if (size
> MAX_KDP_DATA_SIZE
)
620 rp
->error
= KDPERR_BAD_NBYTES
;
622 dprintf(("kdp_readphysmem64 addr %llx size %d\n", rq
->address
, size
));
623 cnt
= kdp_machine_phys_read(rq
, rp
->data
, rq
->lcpu
);
624 rp
->error
= KDPERR_ACCESS(size
, cnt
);
625 dprintf((" cnt %lld error %d\n", cnt
, rp
->error
));
630 *reply_port
= kdp
.reply_port
;
640 unsigned short *reply_port
643 kdp_maxbytes_req_t
*rq
= &pkt
->maxbytes_req
;
645 kdp_maxbytes_reply_t
*rp
= &pkt
->maxbytes_reply
;
647 if (plen
< sizeof (*rq
))
650 rp
->hdr
.is_reply
= 1;
651 rp
->hdr
.len
= sizeof (*rp
);
653 dprintf(("kdp_maxbytes\n"));
655 rp
->max_bytes
= MAX_KDP_DATA_SIZE
;
657 *reply_port
= kdp
.reply_port
;
667 unsigned short *reply_port
670 kdp_version_req_t
*rq
= &pkt
->version_req
;
672 kdp_version_reply_t
*rp
= &pkt
->version_reply
;
674 if (plen
< sizeof (*rq
))
677 rp
->hdr
.is_reply
= 1;
678 rp
->hdr
.len
= sizeof (*rp
);
680 dprintf(("kdp_version\n"));
682 rp
->version
= KDP_VERSION
;
683 if (!(kdp_flag
& KDP_BP_DIS
))
684 rp
->feature
= KDP_FEATURE_BP
;
688 *reply_port
= kdp
.reply_port
;
698 unsigned short *reply_port
701 kdp_regions_req_t
*rq
= &pkt
->regions_req
;
703 kdp_regions_reply_t
*rp
= &pkt
->regions_reply
;
706 if (plen
< sizeof (*rq
))
709 rp
->hdr
.is_reply
= 1;
710 rp
->hdr
.len
= sizeof (*rp
);
712 dprintf(("kdp_regions\n"));
718 r
->nbytes
= 0xffffffff;
720 r
->protection
= VM_PROT_ALL
; r
++; rp
->nregions
++;
722 rp
->hdr
.len
+= rp
->nregions
* sizeof (kdp_region_t
);
724 *reply_port
= kdp
.reply_port
;
734 unsigned short *reply_port
737 kdp_writeregs_req_t
*rq
= &pkt
->writeregs_req
;
740 kdp_writeregs_reply_t
*rp
= &pkt
->writeregs_reply
;
742 if (plen
< sizeof (*rq
))
745 size
= rq
->hdr
.len
- (unsigned)sizeof(kdp_hdr_t
) - (unsigned)sizeof(unsigned int);
746 rp
->error
= kdp_machine_write_regs(rq
->cpu
, rq
->flavor
, rq
->data
, &size
);
748 rp
->hdr
.is_reply
= 1;
749 rp
->hdr
.len
= sizeof (*rp
);
751 *reply_port
= kdp
.reply_port
;
761 unsigned short *reply_port
764 kdp_readregs_req_t
*rq
= &pkt
->readregs_req
;
766 kdp_readregs_reply_t
*rp
= &pkt
->readregs_reply
;
769 if (plen
< sizeof (*rq
))
772 rp
->hdr
.is_reply
= 1;
773 rp
->hdr
.len
= sizeof (*rp
);
775 rp
->error
= kdp_machine_read_regs(rq
->cpu
, rq
->flavor
, rp
->data
, &size
);
778 *reply_port
= kdp
.reply_port
;
789 unsigned short *reply_port
792 kdp_breakpoint_req_t
*rq
= &pkt
->breakpoint_req
;
793 kdp_breakpoint_reply_t
*rp
= &pkt
->breakpoint_reply
;
797 if (plen
< sizeof (*rq
))
800 dprintf(("kdp_breakpoint_set %x\n", rq
->address
));
802 kerr
= kdp_set_breakpoint_internal((mach_vm_address_t
)rq
->address
);
806 rp
->hdr
.is_reply
= 1;
807 rp
->hdr
.len
= sizeof (*rp
);
808 *reply_port
= kdp
.reply_port
;
815 kdp_breakpoint64_set(
818 unsigned short *reply_port
821 kdp_breakpoint64_req_t
*rq
= &pkt
->breakpoint64_req
;
822 kdp_breakpoint64_reply_t
*rp
= &pkt
->breakpoint64_reply
;
826 if (plen
< sizeof (*rq
))
829 dprintf(("kdp_breakpoint64_set %llx\n", rq
->address
));
831 kerr
= kdp_set_breakpoint_internal((mach_vm_address_t
)rq
->address
);
835 rp
->hdr
.is_reply
= 1;
836 rp
->hdr
.len
= sizeof (*rp
);
837 *reply_port
= kdp
.reply_port
;
844 kdp_breakpoint_remove(
847 unsigned short *reply_port
850 kdp_breakpoint_req_t
*rq
= &pkt
->breakpoint_req
;
851 kdp_breakpoint_reply_t
*rp
= &pkt
->breakpoint_reply
;
854 if (plen
< sizeof (*rq
))
857 dprintf(("kdp_breakpoint_remove %x\n", rq
->address
));
859 kerr
= kdp_remove_breakpoint_internal((mach_vm_address_t
)rq
->address
);
863 rp
->hdr
.is_reply
= 1;
864 rp
->hdr
.len
= sizeof (*rp
);
865 *reply_port
= kdp
.reply_port
;
872 kdp_breakpoint64_remove(
875 unsigned short *reply_port
878 kdp_breakpoint64_req_t
*rq
= &pkt
->breakpoint64_req
;
879 kdp_breakpoint64_reply_t
*rp
= &pkt
->breakpoint64_reply
;
883 if (plen
< sizeof (*rq
))
886 dprintf(("kdp_breakpoint64_remove %llx\n", rq
->address
));
888 kerr
= kdp_remove_breakpoint_internal((mach_vm_address_t
)rq
->address
);
892 rp
->hdr
.is_reply
= 1;
893 rp
->hdr
.len
= sizeof (*rp
);
894 *reply_port
= kdp
.reply_port
;
902 kdp_set_breakpoint_internal(
903 mach_vm_address_t address
907 uint8_t breakinstr
[MAX_BREAKINSN_BYTES
], oldinstr
[MAX_BREAKINSN_BYTES
];
908 uint32_t breakinstrsize
= sizeof(breakinstr
);
912 kdp_machine_get_breakinsn(breakinstr
, &breakinstrsize
);
914 if(breakpoints_initialized
== 0)
916 for(i
=0;(i
< MAX_BREAKPOINTS
); breakpoint_list
[i
].address
=0, i
++);
917 breakpoints_initialized
++;
920 cnt
= kdp_machine_vm_read(address
, (caddr_t
)&oldinstr
, (mach_vm_size_t
)breakinstrsize
);
922 if (0 == memcmp(oldinstr
, breakinstr
, breakinstrsize
)) {
923 printf("A trap was already set at that address, not setting new breakpoint\n");
925 return KDPERR_BREAKPOINT_ALREADY_SET
;
928 for(i
=0;(i
< MAX_BREAKPOINTS
) && (breakpoint_list
[i
].address
!= 0); i
++);
930 if (i
== MAX_BREAKPOINTS
) {
931 return KDPERR_MAX_BREAKPOINTS
;
934 breakpoint_list
[i
].address
= address
;
935 memcpy(breakpoint_list
[i
].oldbytes
, oldinstr
, breakinstrsize
);
936 breakpoint_list
[i
].bytesused
= breakinstrsize
;
938 cnt
= kdp_machine_vm_write((caddr_t
)&breakinstr
, address
, breakinstrsize
);
940 return KDPERR_NO_ERROR
;
944 kdp_remove_breakpoint_internal(
945 mach_vm_address_t address
951 for(i
=0;(i
< MAX_BREAKPOINTS
) && (breakpoint_list
[i
].address
!= address
); i
++);
953 if (i
== MAX_BREAKPOINTS
)
955 return KDPERR_BREAKPOINT_NOT_FOUND
;
958 breakpoint_list
[i
].address
= 0;
959 cnt
= kdp_machine_vm_write((caddr_t
)&breakpoint_list
[i
].oldbytes
, address
, breakpoint_list
[i
].bytesused
);
961 return KDPERR_NO_ERROR
;
965 kdp_remove_all_breakpoints(void)
968 boolean_t breakpoint_found
= FALSE
;
970 if (breakpoints_initialized
)
972 for(i
=0;i
< MAX_BREAKPOINTS
; i
++)
974 if (breakpoint_list
[i
].address
)
976 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
);
977 breakpoint_found
= TRUE
;
978 breakpoint_list
[i
].address
= 0;
982 if (breakpoint_found
)
983 printf("kdp_remove_all_breakpoints: found extant breakpoints, removing them.\n");
985 return breakpoint_found
;
990 __unused kdp_pkt_t
*pkt
,
992 __unused
unsigned short *reply_port
995 dprintf(("kdp_reboot\n"));
997 kdp_machine_reboot();
999 return (TRUE
); // no, not really, we won't return
1006 unsigned short *reply_port
1009 kdp_readioport_req_t
*rq
= &pkt
->readioport_req
;
1010 kdp_readioport_reply_t
*rp
= &pkt
->readioport_reply
;
1013 if (plen
< sizeof (*rq
))
1016 rp
->hdr
.is_reply
= 1;
1017 rp
->hdr
.len
= sizeof (*rp
);
1019 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
1020 rp
->error
= KDPERR_BAD_NBYTES
;
1022 #if KDP_TEST_HARNESS
1023 uint16_t addr
= rq
->address
;
1025 uint16_t size
= rq
->nbytes
;
1026 dprintf(("kdp_readioport addr %x size %d\n", addr
, size
));
1028 rp
->error
= kdp_machine_ioport_read(rq
, rp
->data
, rq
->lcpu
);
1029 if (rp
->error
== KDPERR_NO_ERROR
)
1030 rp
->hdr
.len
+= size
;
1033 *reply_port
= kdp
.reply_port
;
1043 unsigned short *reply_port
1046 kdp_writeioport_req_t
*rq
= &pkt
->writeioport_req
;
1047 kdp_writeioport_reply_t
*rp
= &pkt
->writeioport_reply
;
1050 if (plen
< sizeof (*rq
))
1053 if (rq
->nbytes
> MAX_KDP_DATA_SIZE
)
1054 rp
->error
= KDPERR_BAD_NBYTES
;
1056 dprintf(("kdp_writeioport addr %x size %d\n", rq
->address
,
1059 rp
->error
= kdp_machine_ioport_write(rq
, rq
->data
, rq
->lcpu
);
1062 rp
->hdr
.is_reply
= 1;
1063 rp
->hdr
.len
= sizeof (*rp
);
1065 *reply_port
= kdp
.reply_port
;
1075 unsigned short *reply_port
1078 kdp_readmsr64_req_t
*rq
= &pkt
->readmsr64_req
;
1079 kdp_readmsr64_reply_t
*rp
= &pkt
->readmsr64_reply
;
1082 if (plen
< sizeof (*rq
))
1085 rp
->hdr
.is_reply
= 1;
1086 rp
->hdr
.len
= sizeof (*rp
);
1088 dprintf(("kdp_readmsr64 lcpu %x addr %x\n", rq
->lcpu
, rq
->address
));
1089 rp
->error
= kdp_machine_msr64_read(rq
, rp
->data
, rq
->lcpu
);
1090 if (rp
->error
== KDPERR_NO_ERROR
)
1091 rp
->hdr
.len
+= sizeof(uint64_t);
1093 *reply_port
= kdp
.reply_port
;
1103 unsigned short *reply_port
1106 kdp_writemsr64_req_t
*rq
= &pkt
->writemsr64_req
;
1107 kdp_writemsr64_reply_t
*rp
= &pkt
->writemsr64_reply
;
1110 if (plen
< sizeof (*rq
))
1113 dprintf(("kdp_writemsr64 lcpu %x addr %x\n", rq
->lcpu
, rq
->address
));
1114 rp
->error
= kdp_machine_msr64_write(rq
, rq
->data
, rq
->lcpu
);
1116 rp
->hdr
.is_reply
= 1;
1117 rp
->hdr
.len
= sizeof (*rp
);
1119 *reply_port
= kdp
.reply_port
;
1129 unsigned short *reply_port
1132 kdp_dumpinfo_req_t
*rq
= &pkt
->dumpinfo_req
;
1133 kdp_dumpinfo_reply_t
*rp
= &pkt
->dumpinfo_reply
;
1136 if (plen
< sizeof (*rq
))
1139 dprintf(("kdp_dumpinfo file=%s destip=%s routerip=%s\n", rq
->name
, rq
->destip
, rq
->routerip
));
1140 rp
->hdr
.is_reply
= 1;
1141 rp
->hdr
.len
= sizeof (*rp
);
1143 if ((rq
->type
& KDP_DUMPINFO_MASK
) != KDP_DUMPINFO_GETINFO
) {
1144 kdp_set_dump_info(rq
->type
, rq
->name
, rq
->destip
, rq
->routerip
,
1148 /* gather some stats for reply */
1149 kdp_get_dump_info(rp
);
1151 *reply_port
= kdp
.reply_port
;