]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kdp/kdp_udp.c
xnu-4570.61.1.tar.gz
[apple/xnu.git] / osfmk / kdp / kdp_udp.c
CommitLineData
1c79356b 1/*
39037602 2 * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
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.
8f6c56a5 14 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b 27 */
2d21ac55 28
1c79356b 29/*
9bccf70c
A
30 * Copyright (c) 1982, 1986, 1993
31 * The Regents of the University of California. All rights reserved.
32 */
33
34/*
35 * Kernel Debugging Protocol UDP implementation.
1c79356b
A
36 */
37
1c79356b 38#include <mach/boolean.h>
de355530 39#include <mach/mach_types.h>
55e303ae 40#include <mach/exception_types.h>
9bccf70c 41#include <kern/cpu_data.h>
1c79356b 42#include <kern/debug.h>
593a1d5f 43#include <kern/clock.h>
1c79356b 44
0c530ab8 45#include <kdp/kdp_core.h>
1c79356b 46#include <kdp/kdp_internal.h>
5ba3f43e 47#if (MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING)
1c79356b 48#include <kdp/kdp_en_debugger.h>
5ba3f43e 49#endif
593a1d5f 50#include <kdp/kdp_callout.h>
1c79356b 51#include <kdp/kdp_udp.h>
3e170ce0 52#include <kdp/kdp_core.h>
593a1d5f
A
53#if CONFIG_SERIAL_KDP
54#include <kdp/kdp_serial.h>
55#endif
1c79356b 56
55e303ae 57#include <vm/vm_map.h>
91447636 58#include <vm/vm_protos.h>
0c530ab8 59#include <vm/vm_kern.h> /* kernel_map */
91447636 60
55e303ae 61#include <mach/memory_object_types.h>
6d2010ae 62#include <machine/pal_routines.h>
55e303ae 63
7e4a7d39
A
64#include <sys/msgbuf.h>
65
6d2010ae
A
66/* we just want the link status flags, so undef KERNEL_PRIVATE for this
67 * header file. */
68#undef KERNEL_PRIVATE
69#include <net/if_media.h>
70#define KERNEL_PRIVATE
71
55e303ae
A
72#include <string.h>
73
6d2010ae
A
74#include <IOKit/IOPlatformExpert.h>
75#include <libkern/version.h>
76
39037602
A
77#include <sys/pgo.h>
78
fe8ab488
A
79extern unsigned int not_in_kdp;
80extern int kdp_snapshot;
fe8ab488
A
81
82#ifdef CONFIG_KDP_INTERACTIVE_DEBUGGING
83
39236c6e
A
84extern int inet_aton(const char *, struct kdp_in_addr *); /* in libkern */
85extern char *inet_ntoa_r(struct kdp_in_addr ina, char *buf,
86 size_t buflen); /* in libkern */
87
6d2010ae
A
88#define DO_ALIGN 1 /* align all packet data accesses */
89#define KDP_SERIAL_IPADDR 0xABADBABE /* IP address used for serial KDP */
90#define LINK_UP_STATUS (IFM_AVALID | IFM_ACTIVE)
1c79356b
A
91
92extern int kdp_getc(void);
9bccf70c 93extern int reattach_wait;
1c79356b 94
9bccf70c 95static u_short ip_id; /* ip packet ctr, for ids */
1c79356b
A
96
97/* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
98
99/*
100 * UDP protocol implementation.
101 * Per RFC 768, August, 1980.
102 */
103#define UDP_TTL 60 /* deflt time to live for UDP packets */
39236c6e 104static int udp_ttl = UDP_TTL;
1c79356b
A
105static unsigned char exception_seq;
106
39236c6e
A
107struct kdp_ipovly {
108 uint32_t ih_next, ih_prev; /* for protocol sequence q's */
109 u_char ih_x1; /* (unused) */
110 u_char ih_pr; /* protocol */
111 short ih_len; /* protocol length */
112 struct kdp_in_addr ih_src; /* source internet address */
113 struct kdp_in_addr ih_dst; /* destination internet address */
114};
115
116struct kdp_udphdr {
117 u_short uh_sport; /* source port */
118 u_short uh_dport; /* destination port */
119 short uh_ulen; /* udp length */
120 u_short uh_sum; /* udp checksum */
121};
122
123struct kdp_udpiphdr {
124 struct kdp_ipovly ui_i; /* overlaid ip structure */
125 struct kdp_udphdr ui_u; /* udp header */
126};
127#define ui_next ui_i.ih_next
128#define ui_prev ui_i.ih_prev
129#define ui_x1 ui_i.ih_x1
130#define ui_pr ui_i.ih_pr
131#define ui_len ui_i.ih_len
132#define ui_src ui_i.ih_src
133#define ui_dst ui_i.ih_dst
134#define ui_sport ui_u.uh_sport
135#define ui_dport ui_u.uh_dport
136#define ui_ulen ui_u.uh_ulen
137#define ui_sum ui_u.uh_sum
138
139struct kdp_ip {
140 union {
141 uint32_t ip_w;
142 struct {
143 unsigned int
144#ifdef __LITTLE_ENDIAN__
145 ip_xhl:4, /* header length */
146 ip_xv:4, /* version */
147 ip_xtos:8, /* type of service */
148 ip_xlen:16; /* total length */
149#endif
150#ifdef __BIG_ENDIAN__
151 ip_xv:4, /* version */
152 ip_xhl:4, /* header length */
153 ip_xtos:8, /* type of service */
154 ip_xlen:16; /* total length */
155#endif
156 } ip_x;
157 } ip_vhltl;
158 u_short ip_id; /* identification */
159 short ip_off; /* fragment offset field */
160#define IP_DF 0x4000 /* dont fragment flag */
161#define IP_MF 0x2000 /* more fragments flag */
162#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
163 u_char ip_ttl; /* time to live */
164 u_char ip_p; /* protocol */
165 u_short ip_sum; /* checksum */
166 struct kdp_in_addr ip_src,ip_dst; /* source and dest address */
167};
168#define ip_v ip_vhltl.ip_x.ip_xv
169#define ip_hl ip_vhltl.ip_x.ip_xhl
170#define ip_tos ip_vhltl.ip_x.ip_xtos
171#define ip_len ip_vhltl.ip_x.ip_xlen
172
173#define IPPROTO_UDP 17
174#define IPVERSION 4
175
176#define ETHERTYPE_IP 0x0800 /* IP protocol */
177
178/*
179 * Ethernet Address Resolution Protocol.
180 *
181 * See RFC 826 for protocol description. Structure below is adapted
182 * to resolving internet addresses. Field names used correspond to
183 * RFC 826.
184 */
185
186#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
187
188struct kdp_arphdr {
189 u_short ar_hrd; /* format of hardware address */
190#define ARPHRD_ETHER 1 /* ethernet hardware format */
191#define ARPHRD_FRELAY 15 /* frame relay hardware format */
192 u_short ar_pro; /* format of protocol address */
193 u_char ar_hln; /* length of hardware address */
194 u_char ar_pln; /* length of protocol address */
195 u_short ar_op; /* one of: */
196#define ARPOP_REQUEST 1 /* request to resolve address */
197#define ARPOP_REPLY 2 /* response to previous request */
198#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
199#define ARPOP_REVREPLY 4 /* response giving protocol address */
200#define ARPOP_INVREQUEST 8 /* request to identify peer */
201#define ARPOP_INVREPLY 9 /* response identifying peer */
202};
203
204struct kdp_ether_arp {
205 struct kdp_arphdr ea_hdr; /* fixed-size header */
206 u_char arp_sha[ETHER_ADDR_LEN]; /* sender hardware address */
207 u_char arp_spa[4]; /* sender protocol address */
208 u_char arp_tha[ETHER_ADDR_LEN]; /* target hardware address */
209 u_char arp_tpa[4]; /* target protocol address */
210};
211#define arp_hrd ea_hdr.ar_hrd
212#define arp_pro ea_hdr.ar_pro
213#define arp_hln ea_hdr.ar_hln
214#define arp_pln ea_hdr.ar_pln
215#define arp_op ea_hdr.ar_op
216
217#define ETHERMTU 1500
218#define ETHERHDRSIZE 14
219#define ETHERCRC 4
220#define KDP_MAXPACKET (ETHERHDRSIZE + ETHERMTU + ETHERCRC)
221
1c79356b 222static struct {
39037602
A
223 unsigned char data[KDP_MAXPACKET];
224 unsigned int off, len;
225 boolean_t input;
1c79356b
A
226} pkt, saved_reply;
227
7e4a7d39 228struct kdp_manual_pkt manual_pkt;
b0d623f7 229
1c79356b 230struct {
39037602
A
231 struct {
232 struct kdp_in_addr in;
233 struct kdp_ether_addr ea;
234 } loc;
235 struct {
236 struct kdp_in_addr in;
237 struct kdp_ether_addr ea;
238 } rmt;
1c79356b
A
239} adr;
240
0c530ab8 241static const char
1c79356b 242*exception_message[] = {
39037602
A
243 "Unknown",
244 "Memory access", /* EXC_BAD_ACCESS */
245 "Failed instruction", /* EXC_BAD_INSTRUCTION */
246 "Arithmetic", /* EXC_ARITHMETIC */
247 "Emulation", /* EXC_EMULATION */
248 "Software", /* EXC_SOFTWARE */
249 "Breakpoint" /* EXC_BREAKPOINT */
1c79356b
A
250};
251
0c530ab8 252volatile int kdp_flag = 0;
39037602 253boolean_t kdp_corezip_disabled = 0;
9bccf70c 254
fe8ab488 255kdp_send_t kdp_en_send_pkt;
2d21ac55 256static kdp_receive_t kdp_en_recv_pkt;
6d2010ae
A
257static kdp_link_t kdp_en_linkstatus;
258static kdp_mode_t kdp_en_setmode;
1c79356b 259
6d2010ae
A
260#if CONFIG_SERIAL_KDP
261static void kdp_serial_send(void *rpkt, unsigned int rpkt_len);
262#define KDP_SERIAL_ENABLED() (kdp_en_send_pkt == kdp_serial_send)
263#else
264#define KDP_SERIAL_ENABLED() (0)
265#endif
9bccf70c 266
b0d623f7 267static uint32_t kdp_current_ip_address = 0;
39236c6e 268static struct kdp_ether_addr kdp_current_mac_address = {{0, 0, 0, 0, 0, 0}};
2d21ac55 269static void *kdp_current_ifp;
9bccf70c 270
55e303ae
A
271static void kdp_handler( void *);
272
0c530ab8
A
273static uint32_t panic_server_ip = 0;
274static uint32_t parsed_router_ip = 0;
275static uint32_t router_ip = 0;
276static uint32_t target_ip = 0;
277
6d2010ae
A
278static boolean_t save_ip_in_nvram = FALSE;
279
0c530ab8
A
280static volatile boolean_t panicd_specified = FALSE;
281static boolean_t router_specified = FALSE;
7e4a7d39 282static boolean_t corename_specified = FALSE;
0c530ab8
A
283static unsigned int panicd_port = CORE_REMOTE_PORT;
284
39236c6e 285static struct kdp_ether_addr etherbroadcastaddr = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
55e303ae 286
39236c6e
A
287static struct kdp_ether_addr router_mac = {{0, 0, 0 , 0, 0, 0}};
288static struct kdp_ether_addr destination_mac = {{0, 0, 0 , 0, 0, 0}};
289static struct kdp_ether_addr temp_mac = {{0, 0, 0 , 0, 0, 0}};
290static struct kdp_ether_addr current_resolved_MAC = {{0, 0, 0 , 0, 0, 0}};
4452a7af 291
0c530ab8
A
292static boolean_t flag_panic_dump_in_progress = FALSE;
293static boolean_t flag_router_mac_initialized = FALSE;
7e4a7d39 294static boolean_t flag_dont_abort_panic_dump = FALSE;
0c530ab8
A
295
296static boolean_t flag_arp_resolved = FALSE;
55e303ae
A
297
298static unsigned int panic_timeout = 100000;
299static unsigned int last_panic_port = CORE_REMOTE_PORT;
300
6d2010ae 301#define KDP_THROTTLE_VALUE (10ULL * NSEC_PER_SEC)
55e303ae 302
6d2010ae 303uint32_t kdp_crashdump_pkt_size = 512;
39236c6e 304#define KDP_LARGE_CRASHDUMP_PKT_SIZE (1440 - 6 - sizeof(struct kdp_udpiphdr))
55e303ae
A
305static char panicd_ip_str[20];
306static char router_ip_str[20];
39037602 307static char corename_str[100];
55e303ae
A
308
309static unsigned int panic_block = 0;
2d21ac55
A
310volatile unsigned int kdp_trigger_core_dump = 0;
311__private_extern__ volatile unsigned int flag_kdp_trigger_reboot = 0;
55e303ae 312
1c79356b 313
0c530ab8
A
314extern unsigned int disableConsoleOutput;
315
0c530ab8 316extern void kdp_call(void);
0c530ab8
A
317
318void * kdp_get_interface(void);
6d2010ae 319void kdp_set_gateway_mac(void *gatewaymac);
39236c6e
A
320void kdp_set_ip_and_mac_addresses(struct kdp_in_addr *ipaddr, struct kdp_ether_addr *);
321void kdp_set_interface(void *interface, const struct kdp_ether_addr *macaddr);
0c530ab8
A
322
323void kdp_disable_arp(void);
39236c6e
A
324static void kdp_arp_reply(struct kdp_ether_arp *);
325static void kdp_process_arp_reply(struct kdp_ether_arp *);
326static boolean_t kdp_arp_resolve(uint32_t, struct kdp_ether_addr *);
0c530ab8 327
2d21ac55 328static volatile unsigned kdp_reentry_deadline;
6d2010ae
A
329
330static uint32_t kdp_crashdump_feature_mask = KDP_FEATURE_LARGE_CRASHDUMPS | KDP_FEATURE_LARGE_PKT_SIZE;
331uint32_t kdp_feature_large_crashdumps, kdp_feature_large_pkt_size;
332
333char kdp_kernelversion_string[256];
2d21ac55 334
0c530ab8 335static boolean_t gKDPDebug = FALSE;
39037602 336
0c530ab8
A
337#define KDP_DEBUG(...) if (gKDPDebug) printf(__VA_ARGS__);
338
6d2010ae
A
339#define SBLOCKSZ (2048)
340uint64_t kdp_dump_start_time = 0;
341uint64_t kdp_min_superblock_dump_time = ~1ULL;
342uint64_t kdp_max_superblock_dump_time = 0;
343uint64_t kdp_superblock_dump_time = 0;
344uint64_t kdp_superblock_dump_start_time = 0;
2d21ac55
A
345static thread_call_t
346kdp_timer_call;
347
348static void
349kdp_ml_enter_debugger_wrapper(__unused void *param0, __unused void *param1) {
350 kdp_ml_enter_debugger();
351}
352
353static void
354kdp_timer_callout_init(void) {
355 kdp_timer_call = thread_call_allocate(kdp_ml_enter_debugger_wrapper, NULL);
356}
357
358
6d2010ae 359/* only send/receive data if the link is up */
39037602
A
360inline static void
361wait_for_link(void)
6d2010ae 362{
39037602 363 static int first = 0;
6d2010ae 364
39037602
A
365 if (!kdp_en_linkstatus)
366 return;
6d2010ae 367
39037602
A
368 while (((*kdp_en_linkstatus)() & LINK_UP_STATUS) != LINK_UP_STATUS) {
369 if (first)
370 continue;
6d2010ae 371
39037602
A
372 first = 1;
373 printf("Waiting for link to become available.\n");
374 kprintf("Waiting for link to become available.\n");
375 }
6d2010ae
A
376}
377
378
39037602
A
379inline static void
380kdp_send_data(void *packet, unsigned int len)
6d2010ae 381{
39037602
A
382 wait_for_link();
383 (*kdp_en_send_pkt)(packet, len);
6d2010ae
A
384}
385
386
39037602
A
387inline static void
388kdp_receive_data(void *packet, unsigned int *len, unsigned int timeout)
6d2010ae 389{
39037602
A
390 wait_for_link();
391 (*kdp_en_recv_pkt)(packet, len, timeout);
6d2010ae
A
392}
393
394
39037602
A
395void
396kdp_register_link(kdp_link_t link, kdp_mode_t mode)
6d2010ae 397{
39037602
A
398 kdp_en_linkstatus = link;
399 kdp_en_setmode = mode;
6d2010ae
A
400}
401
39037602
A
402void
403kdp_unregister_link(__unused kdp_link_t link, __unused kdp_mode_t mode)
6d2010ae 404{
39037602
A
405 kdp_en_linkstatus = NULL;
406 kdp_en_setmode = NULL;
6d2010ae
A
407}
408
1c79356b 409void
9bccf70c 410kdp_register_send_receive(
55e303ae 411 kdp_send_t send,
9bccf70c 412 kdp_receive_t receive)
1c79356b 413{
2d21ac55 414 unsigned int debug = 0;
1c79356b 415
593a1d5f 416 PE_parse_boot_argn("debug", &debug, sizeof (debug));
6d2010ae 417
5ba3f43e
A
418#if defined(__arm__) || defined(__arm64__)
419 {
420 uint32_t debug_flags;
421
422 if (!PE_i_can_has_debugger(&debug_flags))
423 debug = 0;
424 }
425#endif
2d21ac55
A
426
427 if (!debug)
428 return;
429
6d2010ae
A
430 kdp_en_send_pkt = send;
431 kdp_en_recv_pkt = receive;
593a1d5f 432
9bccf70c
A
433 if (debug & DB_KDP_BP_DIS)
434 kdp_flag |= KDP_BP_DIS;
55e303ae
A
435 if (debug & DB_KDP_GETC_ENA)
436 kdp_flag |= KDP_GETC_ENA;
437 if (debug & DB_ARP)
2d21ac55 438 kdp_flag |= KDP_ARP;
55e303ae
A
439
440 if (debug & DB_KERN_DUMP_ON_PANIC)
2d21ac55 441 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
55e303ae 442 if (debug & DB_KERN_DUMP_ON_NMI)
2d21ac55
A
443 kdp_flag |= PANIC_CORE_ON_NMI;
444
55e303ae 445 if (debug & DB_DBG_POST_CORE)
2d21ac55
A
446 kdp_flag |= DBG_POST_CORE;
447
55e303ae 448 if (debug & DB_PANICLOG_DUMP)
2d21ac55
A
449 kdp_flag |= PANIC_LOG_DUMP;
450
39037602
A
451 kdp_corezip_disabled = (0 != (debug & DB_DISABLE_GZIP_CORE));
452
593a1d5f 453 if (PE_parse_boot_argn("_panicd_ip", panicd_ip_str, sizeof (panicd_ip_str)))
2d21ac55 454 panicd_specified = TRUE;
0c530ab8 455
b0d623f7
A
456 if ((debug & DB_REBOOT_POST_CORE) && (panicd_specified == TRUE))
457 kdp_flag |= REBOOT_POST_CORE;
458
593a1d5f 459 if (PE_parse_boot_argn("_router_ip", router_ip_str, sizeof (router_ip_str)))
2d21ac55 460 router_specified = TRUE;
0c530ab8 461
593a1d5f 462 if (!PE_parse_boot_argn("panicd_port", &panicd_port, sizeof (panicd_port)))
0c530ab8 463 panicd_port = CORE_REMOTE_PORT;
9bccf70c 464
7e4a7d39
A
465 if (PE_parse_boot_argn("_panicd_corename", &corename_str, sizeof (corename_str)))
466 corename_specified = TRUE;
467
1c79356b 468 kdp_flag |= KDP_READY;
3e170ce0 469
39037602 470 current_debugger = KDP_CUR_DB;
2d21ac55 471 if ((kdp_current_ip_address != 0) && halt_in_debugger) {
1c79356b
A
472 kdp_call();
473 halt_in_debugger=0;
474 }
475}
476
1c79356b 477void
9bccf70c 478kdp_unregister_send_receive(
0c530ab8
A
479 __unused kdp_send_t send,
480 __unused kdp_receive_t receive)
9bccf70c
A
481{
482 if (current_debugger == KDP_CUR_DB)
483 current_debugger = NO_CUR_DB;
484 kdp_flag &= ~KDP_READY;
6d2010ae
A
485 kdp_en_send_pkt = NULL;
486 kdp_en_recv_pkt = NULL;
9bccf70c
A
487}
488
2d21ac55
A
489static void
490kdp_schedule_debugger_reentry(unsigned interval) {
491 uint64_t deadline;;
492
493 clock_interval_to_deadline(interval, 1000 * 1000, &deadline);
494 thread_call_enter_delayed(kdp_timer_call, deadline);
495}
496
9bccf70c 497static void
1c79356b 498enaddr_copy(
9bccf70c
A
499 void *src,
500 void *dst
1c79356b
A
501)
502{
39236c6e 503 bcopy((char *)src, (char *)dst, sizeof (struct kdp_ether_addr));
1c79356b
A
504}
505
9bccf70c 506static unsigned short
1c79356b 507ip_sum(
9bccf70c
A
508 unsigned char *c,
509 unsigned int hlen
0c530ab8 510 )
1c79356b 511{
0c530ab8 512 unsigned int high, low, sum;
1c79356b 513
0c530ab8
A
514 high = low = 0;
515 while (hlen-- > 0) {
516 low += c[1] + c[3];
517 high += c[0] + c[2];
1c79356b 518
0c530ab8
A
519 c += sizeof (int);
520 }
1c79356b 521
0c530ab8
A
522 sum = (high << 8) + low;
523 sum = (sum >> 16) + (sum & 65535);
1c79356b 524
0c530ab8 525 return (sum > 65535 ? sum - 65535 : sum);
1c79356b
A
526}
527
9bccf70c 528static void
1c79356b 529kdp_reply(
7e4a7d39
A
530 unsigned short reply_port,
531 const boolean_t sideband
532 )
1c79356b 533{
39236c6e
A
534 struct kdp_udpiphdr aligned_ui, *ui = &aligned_ui;
535 struct kdp_ip aligned_ip, *ip = &aligned_ip;
536 struct kdp_in_addr tmp_ipaddr;
537 struct kdp_ether_addr tmp_enaddr;
538 struct kdp_ether_header *eh = NULL;
1c79356b 539
0c530ab8
A
540 if (!pkt.input)
541 kdp_panic("kdp_reply");
1c79356b 542
39236c6e 543 pkt.off -= (unsigned int)sizeof (struct kdp_udpiphdr);
1c79356b
A
544
545#if DO_ALIGN
0c530ab8 546 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
1c79356b 547#else
39236c6e 548 ui = (struct kdp_udpiphdr *)&pkt.data[pkt.off];
1c79356b 549#endif
b0d623f7 550 ui->ui_next = ui->ui_prev = 0;
0c530ab8
A
551 ui->ui_x1 = 0;
552 ui->ui_pr = IPPROTO_UDP;
39236c6e 553 ui->ui_len = htons((u_short)pkt.len + sizeof (struct kdp_udphdr));
0c530ab8
A
554 tmp_ipaddr = ui->ui_src;
555 ui->ui_src = ui->ui_dst;
556 ui->ui_dst = tmp_ipaddr;
557 ui->ui_sport = htons(KDP_REMOTE_PORT);
558 ui->ui_dport = reply_port;
559 ui->ui_ulen = ui->ui_len;
560 ui->ui_sum = 0;
1c79356b 561#if DO_ALIGN
0c530ab8
A
562 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
563 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
1c79356b 564#else
39236c6e 565 ip = (struct kdp_ip *)&pkt.data[pkt.off];
1c79356b 566#endif
39236c6e 567 ip->ip_len = htons(sizeof (struct kdp_udpiphdr) + pkt.len);
0c530ab8
A
568 ip->ip_v = IPVERSION;
569 ip->ip_id = htons(ip_id++);
39236c6e 570 ip->ip_hl = sizeof (struct kdp_ip) >> 2;
0c530ab8
A
571 ip->ip_ttl = udp_ttl;
572 ip->ip_sum = 0;
573 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
1c79356b 574#if DO_ALIGN
0c530ab8 575 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
1c79356b
A
576#endif
577
39236c6e 578 pkt.len += (unsigned int)sizeof (struct kdp_udpiphdr);
1c79356b 579
39236c6e 580 pkt.off -= (unsigned int)sizeof (struct kdp_ether_header);
1c79356b 581
39236c6e 582 eh = (struct kdp_ether_header *)&pkt.data[pkt.off];
0c530ab8
A
583 enaddr_copy(eh->ether_shost, &tmp_enaddr);
584 enaddr_copy(eh->ether_dhost, eh->ether_shost);
585 enaddr_copy(&tmp_enaddr, eh->ether_dhost);
586 eh->ether_type = htons(ETHERTYPE_IP);
1c79356b 587
39236c6e 588 pkt.len += (unsigned int)sizeof (struct kdp_ether_header);
1c79356b 589
0c530ab8 590 // save reply for possible retransmission
6d2010ae 591 assert(pkt.len <= KDP_MAXPACKET);
7e4a7d39 592 if (!sideband)
6d2010ae 593 bcopy((char *)&pkt, (char *)&saved_reply, sizeof(saved_reply));
1c79356b 594
6d2010ae 595 kdp_send_data(&pkt.data[pkt.off], pkt.len);
1c79356b 596
0c530ab8 597 // increment expected sequence number
7e4a7d39
A
598 if (!sideband)
599 exception_seq++;
1c79356b
A
600}
601
9bccf70c 602static void
1c79356b
A
603kdp_send(
604 unsigned short remote_port
605)
606{
39037602
A
607 struct kdp_udpiphdr aligned_ui, *ui = &aligned_ui;
608 struct kdp_ip aligned_ip, *ip = &aligned_ip;
609 struct kdp_ether_header *eh;
1c79356b 610
39037602
A
611 if (pkt.input)
612 kdp_panic("kdp_send");
613
614 pkt.off -= (unsigned int)sizeof (struct kdp_udpiphdr);
1c79356b
A
615
616#if DO_ALIGN
39037602 617 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
1c79356b 618#else
39037602 619 ui = (struct kdp_udpiphdr *)&pkt.data[pkt.off];
1c79356b 620#endif
39037602
A
621 ui->ui_next = ui->ui_prev = 0;
622 ui->ui_x1 = 0;
623 ui->ui_pr = IPPROTO_UDP;
624 ui->ui_len = htons((u_short)pkt.len + sizeof (struct kdp_udphdr));
625 ui->ui_src = adr.loc.in;
626 ui->ui_dst = adr.rmt.in;
627 ui->ui_sport = htons(KDP_REMOTE_PORT);
628 ui->ui_dport = remote_port;
629 ui->ui_ulen = ui->ui_len;
630 ui->ui_sum = 0;
1c79356b 631#if DO_ALIGN
39037602
A
632 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
633 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
1c79356b 634#else
39037602 635 ip = (struct kdp_ip *)&pkt.data[pkt.off];
1c79356b 636#endif
39037602
A
637 ip->ip_len = htons(sizeof (struct kdp_udpiphdr) + pkt.len);
638 ip->ip_v = IPVERSION;
639 ip->ip_id = htons(ip_id++);
640 ip->ip_hl = sizeof (struct kdp_ip) >> 2;
641 ip->ip_ttl = udp_ttl;
642 ip->ip_sum = 0;
643 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
1c79356b 644#if DO_ALIGN
39037602 645 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
1c79356b 646#endif
39037602
A
647
648 pkt.len += (unsigned int)sizeof (struct kdp_udpiphdr);
649
650 pkt.off -= (unsigned int)sizeof (struct kdp_ether_header);
651
652 eh = (struct kdp_ether_header *)&pkt.data[pkt.off];
653 enaddr_copy(&adr.loc.ea, eh->ether_shost);
654 enaddr_copy(&adr.rmt.ea, eh->ether_dhost);
655 eh->ether_type = htons(ETHERTYPE_IP);
656
657 pkt.len += (unsigned int)sizeof (struct kdp_ether_header);
658 kdp_send_data(&pkt.data[pkt.off], pkt.len);
1c79356b
A
659}
660
6d2010ae 661
39037602
A
662inline static void
663debugger_if_necessary(void)
6d2010ae 664{
39037602
A
665 if ((current_debugger == KDP_CUR_DB) && halt_in_debugger) {
666 kdp_call();
667 halt_in_debugger=0;
668 }
6d2010ae
A
669}
670
671
672/* We don't interpret this pointer, we just give it to the bsd stack
673 so it can decide when to set the MAC and IP info. We'll
674 early initialize the MAC/IP info if we can so that we can use
675 KDP early in boot. These values may subsequently get over-written
676 when the interface gets initialized for real.
677*/
4a249263 678void
39236c6e 679kdp_set_interface(void *ifp, const struct kdp_ether_addr *macaddr)
4a249263 680{
6d2010ae 681 char kdpstr[80];
39236c6e 682 struct kdp_in_addr addr = { 0 };
6d2010ae
A
683 unsigned int len;
684
4a249263 685 kdp_current_ifp = ifp;
6d2010ae
A
686
687 if (PE_parse_boot_argn("kdp_ip_addr", kdpstr, sizeof(kdpstr))) {
688 /* look for a static ip address */
689 if (inet_aton(kdpstr, &addr) == FALSE)
690 goto done;
691
692 goto config_network;
693 }
694
695 /* use saved ip address */
696 save_ip_in_nvram = TRUE;
697
698 len = sizeof(kdpstr);
699 if (PEReadNVRAMProperty("_kdp_ipstr", kdpstr, &len) == FALSE)
700 goto done;
701
702 kdpstr[len < sizeof(kdpstr) ? len : sizeof(kdpstr) - 1] = '\0';
703 if (inet_aton(kdpstr, &addr) == FALSE)
704 goto done;
705
706config_network:
707 kdp_current_ip_address = addr.s_addr;
708 if (macaddr)
709 kdp_current_mac_address = *macaddr;
710
711 /* we can't drop into the debugger at this point because the
712 link will likely not be up. when getDebuggerLinkStatus() support gets
713 added to the appropriate network drivers, adding the
714 following will enable this capability:
715 debugger_if_necessary();
716 */
717done:
718 return;
4a249263
A
719}
720
721void *
2d21ac55 722kdp_get_interface(void)
4a249263
A
723{
724 return kdp_current_ifp;
725}
9bccf70c
A
726
727void
728kdp_set_ip_and_mac_addresses(
39236c6e
A
729 struct kdp_in_addr *ipaddr,
730 struct kdp_ether_addr *macaddr)
1c79356b 731{
39037602
A
732 static uint64_t last_time = (uint64_t) -1;
733 static uint64_t throttle_val = 0;
734 uint64_t cur_time;
735 char addr[16];
736
737 if (kdp_current_ip_address == ipaddr->s_addr)
738 goto done;
739
740 /* don't replace if serial debugging is configured */
741 if (!KDP_SERIAL_ENABLED() ||
742 (kdp_current_ip_address != KDP_SERIAL_IPADDR)) {
743 kdp_current_mac_address = *macaddr;
744 kdp_current_ip_address = ipaddr->s_addr;
745 }
6d2010ae 746
39037602
A
747 if (save_ip_in_nvram == FALSE)
748 goto done;
6d2010ae 749
39037602
A
750 if (inet_ntoa_r(*ipaddr, addr, sizeof(addr)) == NULL)
751 goto done;
6d2010ae 752
39037602
A
753 /* throttle writes if needed */
754 if (!throttle_val)
755 nanoseconds_to_absolutetime(KDP_THROTTLE_VALUE, &throttle_val);
6d2010ae 756
39037602
A
757 cur_time = mach_absolute_time();
758 if (last_time == (uint64_t) -1 ||
759 ((cur_time - last_time) > throttle_val)) {
760 PEWriteNVRAMProperty("_kdp_ipstr", addr,
761 (const unsigned int) strlen(addr));
762 }
763 last_time = cur_time;
6d2010ae
A
764
765done:
39037602 766 debugger_if_necessary();
9bccf70c
A
767}
768
55e303ae
A
769void
770kdp_set_gateway_mac(void *gatewaymac)
771{
39037602
A
772 router_mac = *(struct kdp_ether_addr *)gatewaymac;
773 flag_router_mac_initialized = TRUE;
55e303ae
A
774}
775
39236c6e 776struct kdp_ether_addr
9bccf70c
A
777kdp_get_mac_addr(void)
778{
39037602 779 return kdp_current_mac_address;
9bccf70c
A
780}
781
782unsigned int
783kdp_get_ip_address(void)
784{
39037602 785 return (unsigned int)kdp_current_ip_address;
9bccf70c
A
786}
787
0c530ab8
A
788void
789kdp_disable_arp(void)
790{
791 kdp_flag &= ~(DB_ARP);
792}
793
794static void
795kdp_arp_dispatch(void)
796{
39236c6e 797 struct kdp_ether_arp aligned_ea, *ea = &aligned_ea;
0c530ab8
A
798 unsigned arp_header_offset;
799
39236c6e 800 arp_header_offset = (unsigned)sizeof(struct kdp_ether_header) + pkt.off;
0c530ab8
A
801 memcpy((void *)ea, (void *)&pkt.data[arp_header_offset], sizeof(*ea));
802
803 switch(ntohs(ea->arp_op)) {
804 case ARPOP_REQUEST:
805 kdp_arp_reply(ea);
806 break;
807 case ARPOP_REPLY:
808 kdp_process_arp_reply(ea);
809 break;
810 default:
811 return;
812 }
813}
814
815static void
39236c6e 816kdp_process_arp_reply(struct kdp_ether_arp *ea)
0c530ab8
A
817{
818 /* Are we interested in ARP replies? */
819 if (flag_arp_resolved == TRUE)
820 return;
821
822 /* Did we receive a reply from the right source? */
39236c6e 823 if (((struct kdp_in_addr *)(ea->arp_spa))->s_addr != target_ip)
0c530ab8
A
824 return;
825
826 flag_arp_resolved = TRUE;
39236c6e 827 current_resolved_MAC = *(struct kdp_ether_addr *) (ea->arp_sha);
0c530ab8
A
828
829 return;
830}
831
9bccf70c 832/* ARP responses are enabled when the DB_ARP bit of the debug boot arg
0c530ab8
A
833 * is set.
834 */
835
9bccf70c 836static void
39236c6e 837kdp_arp_reply(struct kdp_ether_arp *ea)
9bccf70c 838{
39236c6e 839 struct kdp_ether_header *eh;
9bccf70c 840
39236c6e
A
841 struct kdp_in_addr isaddr, itaddr, myaddr;
842 struct kdp_ether_addr my_enaddr;
9bccf70c 843
39236c6e
A
844 eh = (struct kdp_ether_header *)&pkt.data[pkt.off];
845 pkt.off += (unsigned int)sizeof(struct kdp_ether_header);
9bccf70c 846
55e303ae
A
847 if(ntohs(ea->arp_op) != ARPOP_REQUEST)
848 return;
9bccf70c
A
849
850 myaddr.s_addr = kdp_get_ip_address();
851 my_enaddr = kdp_get_mac_addr();
852
0c530ab8
A
853 if ((ntohl(myaddr.s_addr) == 0) ||
854 ((my_enaddr.ether_addr_octet[0] & 0xff) == 0
855 && (my_enaddr.ether_addr_octet[1] & 0xff) == 0
856 && (my_enaddr.ether_addr_octet[2] & 0xff) == 0
857 && (my_enaddr.ether_addr_octet[3] & 0xff) == 0
858 && (my_enaddr.ether_addr_octet[4] & 0xff) == 0
859 && (my_enaddr.ether_addr_octet[5] & 0xff) == 0
860 ))
9bccf70c
A
861 return;
862
863 (void)memcpy((void *)&isaddr, (void *)ea->arp_spa, sizeof (isaddr));
864 (void)memcpy((void *)&itaddr, (void *)ea->arp_tpa, sizeof (itaddr));
0c530ab8 865
9bccf70c
A
866 if (itaddr.s_addr == myaddr.s_addr) {
867 (void)memcpy((void *)ea->arp_tha, (void *)ea->arp_sha, sizeof(ea->arp_sha));
868 (void)memcpy((void *)ea->arp_sha, (void *)&my_enaddr, sizeof(ea->arp_sha));
869
870 (void)memcpy((void *)ea->arp_tpa, (void *) ea->arp_spa, sizeof(ea->arp_spa));
871 (void)memcpy((void *)ea->arp_spa, (void *) &itaddr, sizeof(ea->arp_spa));
872
873 ea->arp_op = htons(ARPOP_REPLY);
874 ea->arp_pro = htons(ETHERTYPE_IP);
875 (void)memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
876 (void)memcpy(eh->ether_shost, &my_enaddr, sizeof(eh->ether_shost));
877 eh->ether_type = htons(ETHERTYPE_ARP);
878 (void)memcpy(&pkt.data[pkt.off], ea, sizeof(*ea));
39236c6e 879 pkt.off -= (unsigned int)sizeof (struct kdp_ether_header);
9bccf70c 880 /* pkt.len is still the length we want, ether_header+ether_arp */
6d2010ae 881 kdp_send_data(&pkt.data[pkt.off], pkt.len);
9bccf70c
A
882 }
883}
884
885static void
886kdp_poll(void)
887{
39236c6e
A
888 struct kdp_ether_header *eh = NULL;
889 struct kdp_udpiphdr aligned_ui, *ui = &aligned_ui;
890 struct kdp_ip aligned_ip, *ip = &aligned_ip;
0c530ab8 891 static int msg_printed;
8f6c56a5 892
0c530ab8
A
893 if (pkt.input)
894 kdp_panic("kdp_poll");
1c79356b 895
0c530ab8
A
896 if (!kdp_en_recv_pkt || !kdp_en_send_pkt) {
897 if( msg_printed == 0) {
898 msg_printed = 1;
899 printf("kdp_poll: no debugger device\n");
900 }
901 return;
1c79356b 902 }
1c79356b 903
0c530ab8 904 pkt.off = pkt.len = 0;
6d2010ae 905 kdp_receive_data(pkt.data, &pkt.len, 3/* ms */);
8f6c56a5 906
0c530ab8 907 if (pkt.len == 0)
4452a7af 908 return;
21362eb3 909
39037602 910 if (pkt.len >= sizeof(struct kdp_ether_header)) {
39236c6e 911 eh = (struct kdp_ether_header *)&pkt.data[pkt.off];
0c530ab8 912
39037602
A
913 if (kdp_flag & KDP_ARP) {
914 if (ntohs(eh->ether_type) == ETHERTYPE_ARP) {
0c530ab8
A
915 kdp_arp_dispatch();
916 return;
917 }
918 }
919 }
920
39236c6e 921 if (pkt.len < (sizeof (struct kdp_ether_header) + sizeof (struct kdp_udpiphdr)))
0c530ab8 922 return;
6601e61a 923
39236c6e 924 pkt.off += (unsigned int)sizeof (struct kdp_ether_header);
0c530ab8
A
925 if (ntohs(eh->ether_type) != ETHERTYPE_IP) {
926 return;
927 }
1c79356b
A
928
929#if DO_ALIGN
0c530ab8
A
930 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
931 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
1c79356b 932#else
39236c6e
A
933 ui = (struct kdp_udpiphdr *)&pkt.data[pkt.off];
934 ip = (struct kdp_ip *)&pkt.data[pkt.off];
1c79356b
A
935#endif
936
39236c6e 937 pkt.off += (unsigned int)sizeof (struct kdp_udpiphdr);
0c530ab8
A
938 if (ui->ui_pr != IPPROTO_UDP) {
939 return;
940 }
1c79356b 941
39236c6e 942 if (ip->ip_hl > (sizeof (struct kdp_ip) >> 2)) {
0c530ab8
A
943 return;
944 }
4452a7af 945
0c530ab8
A
946 if (ntohs(ui->ui_dport) != KDP_REMOTE_PORT) {
947 if (panicd_port == (ntohs(ui->ui_dport)) &&
948 flag_panic_dump_in_progress) {
949 last_panic_port = ui->ui_sport;
950 }
951 else
952 return;
89b3af67 953 }
0c530ab8
A
954 /* If we receive a kernel debugging packet whilst a
955 * core dump is in progress, abort the transfer and
7e4a7d39 956 * enter the debugger if not told otherwise.
0c530ab8
A
957 */
958 else
39037602 959 if (flag_panic_dump_in_progress) {
7e4a7d39
A
960 if (!flag_dont_abort_panic_dump) {
961 abort_panic_transfer();
962 }
0c530ab8
A
963 return;
964 }
965
966 if (!kdp.is_conn && !flag_panic_dump_in_progress) {
967 enaddr_copy(eh->ether_dhost, &adr.loc.ea);
968 adr.loc.in = ui->ui_dst;
969
970 enaddr_copy(eh->ether_shost, &adr.rmt.ea);
971 adr.rmt.in = ui->ui_src;
4452a7af
A
972 }
973
0c530ab8
A
974 /*
975 * Calculate kdp packet length.
976 */
39236c6e 977 pkt.len = ntohs((u_short)ui->ui_ulen) - (unsigned int)sizeof (struct kdp_udphdr);
0c530ab8
A
978 pkt.input = TRUE;
979}
4452a7af 980
39037602 981
0c530ab8
A
982/* Create and transmit an ARP resolution request for the target IP address.
983 * This is modeled on ether_inet_arp()/RFC 826.
984 */
4452a7af 985
0c530ab8
A
986static void
987transmit_ARP_request(uint32_t ip_addr)
988{
39236c6e
A
989 struct kdp_ether_header *eh = (struct kdp_ether_header *) &pkt.data[0];
990 struct kdp_ether_arp *ea = (struct kdp_ether_arp *) &pkt.data[sizeof(struct kdp_ether_header)];
0c530ab8
A
991
992 KDP_DEBUG("Transmitting ARP request\n");
993 /* Populate the ether_header */
994 eh->ether_type = htons(ETHERTYPE_ARP);
995 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
996 enaddr_copy(&etherbroadcastaddr, eh->ether_dhost);
997
998 /* Populate the ARP header */
999 ea->arp_pro = htons(ETHERTYPE_IP);
1000 ea->arp_hln = sizeof(ea->arp_sha);
1001 ea->arp_pln = sizeof(ea->arp_spa);
1002 ea->arp_hrd = htons(ARPHRD_ETHER);
1003 ea->arp_op = htons(ARPOP_REQUEST);
1004
1005 /* Target fields */
1006 enaddr_copy(&etherbroadcastaddr, ea->arp_tha);
1007 memcpy(ea->arp_tpa, (void *) &ip_addr, sizeof(ip_addr));
1008
1009 /* Source fields */
1010 enaddr_copy(&kdp_current_mac_address, ea->arp_sha);
1011 memcpy(ea->arp_spa, (void *) &kdp_current_ip_address, sizeof(kdp_current_ip_address));
1012
1013 pkt.off = 0;
39236c6e 1014 pkt.len = sizeof(struct kdp_ether_header) + sizeof(struct kdp_ether_arp);
0c530ab8 1015 /* Transmit */
6d2010ae 1016 kdp_send_data(&pkt.data[pkt.off], pkt.len);
0c530ab8
A
1017}
1018
1019static boolean_t
39236c6e 1020kdp_arp_resolve(uint32_t arp_target_ip, struct kdp_ether_addr *resolved_MAC)
0c530ab8
A
1021{
1022 int poll_count = 256; /* ~770 ms modulo broadcast/delayed traffic? */
1023 char tretries = 0;
1024
1025#define NUM_ARP_TX_RETRIES 5
1026
1027 target_ip = arp_target_ip;
1028 flag_arp_resolved = FALSE;
1029
1030TRANSMIT_RETRY:
1031 pkt.off = pkt.len = 0;
1032
1033 tretries++;
1034
1035 if (tretries >= NUM_ARP_TX_RETRIES) {
1036 return FALSE;
1037 }
1038
1039 KDP_DEBUG("ARP TX attempt #%d \n", tretries);
1040
1041 transmit_ARP_request(arp_target_ip);
1042
1043 while (!pkt.input && !flag_arp_resolved && flag_panic_dump_in_progress && --poll_count) {
1044 kdp_poll();
1045 }
1046
1047 if (flag_arp_resolved) {
1048 *resolved_MAC = current_resolved_MAC;
1049 return TRUE;
1050 }
1051
39037602 1052 if (!flag_panic_dump_in_progress || pkt.input) { /* we received a debugging packet, bail*/
0c530ab8
A
1053 printf("Received a debugger packet,transferring control to debugger\n");
1054 /* Indicate that we should wait in the debugger when we return */
1055 kdp_flag |= DBG_POST_CORE;
1056 pkt.input = FALSE;
1057 return FALSE;
39037602 1058 } else { /* We timed out */
0c530ab8
A
1059 if (0 == poll_count) {
1060 poll_count = 256;
1061 goto TRANSMIT_RETRY;
1062 }
39037602 1063 }
0c530ab8 1064 return FALSE;
1c79356b
A
1065}
1066
9bccf70c 1067static void
1c79356b 1068kdp_handler(
39037602 1069 void *saved_state
1c79356b
A
1070)
1071{
39037602
A
1072 unsigned short reply_port;
1073 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
1c79356b 1074
39037602
A
1075 kdp.saved_state = saved_state; // see comment in kdp_raise_exception
1076
1077 do {
1078 while (!pkt.input)
1079 kdp_poll();
1c79356b 1080
1c79356b 1081#if DO_ALIGN
39037602 1082 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
1c79356b 1083#else
39037602 1084 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
1c79356b
A
1085#endif
1086
39037602
A
1087 // ignore replies -- we're not expecting them anyway.
1088 if (hdr->is_reply) {
1089 goto again;
1090 }
7e4a7d39 1091
39037602
A
1092 if (hdr->request == KDP_REATTACH)
1093 exception_seq = hdr->seq;
1094
1095 // check for retransmitted request
1096 if (hdr->seq == (exception_seq - 1)) {
1097 /* retransmit last reply */
1098 kdp_send_data(&saved_reply.data[saved_reply.off],
1099 saved_reply.len);
1100 goto again;
1101 } else if ((hdr->seq != exception_seq) &&
1102 (hdr->request != KDP_CONNECT)) {
1103 printf("kdp: bad sequence %d (want %d)\n",
1104 hdr->seq, exception_seq);
1105 goto again;
1106 }
1107
1108 /* This is a manual side-channel to the main KDP protocol.
1109 * A client like GDB/kgmacros can manually construct
1110 * a request, set the input flag, issue a dummy KDP request,
1111 * and then manually collect the result
1112 */
1113 if (manual_pkt.input) {
1114 kdp_hdr_t *manual_hdr = (kdp_hdr_t *)&manual_pkt.data;
1115 unsigned short manual_port_unused = 0;
1116 if (!manual_hdr->is_reply) {
1117 /* process */
813fb2f6 1118 int packet_length = manual_pkt.len;
39037602 1119 kdp_packet((unsigned char *)&manual_pkt.data,
813fb2f6 1120 &packet_length,
39037602 1121 &manual_port_unused);
813fb2f6 1122 manual_pkt.len = packet_length;
39037602
A
1123 }
1124 manual_pkt.input = 0;
1125 }
1126
1127 if (kdp_packet((unsigned char*)&pkt.data[pkt.off],
1128 (int *)&pkt.len,
1129 (unsigned short *)&reply_port)) {
1130 boolean_t sideband = FALSE;
1131
1132 /* if it's an already connected error message,
1133 * send a sideband reply for that. for successful connects,
1134 * make sure the sequence number is correct. */
1135 if (hdr->request == KDP_CONNECT) {
1136 kdp_connect_reply_t *rp =
1137 (kdp_connect_reply_t *) &pkt.data[pkt.off];
1138 kdp_error_t err = rp->error;
1139
1140 if (err == KDPERR_NO_ERROR) {
1141 exception_seq = hdr->seq;
1142 } else if (err == KDPERR_ALREADY_CONNECTED) {
1143 sideband = TRUE;
1144 }
1145 }
1146
1147 kdp_reply(reply_port, sideband);
1148 }
1c79356b
A
1149
1150again:
39037602
A
1151 pkt.input = FALSE;
1152 } while (kdp.is_halted);
1c79356b
A
1153}
1154
9bccf70c
A
1155static void
1156kdp_connection_wait(void)
1c79356b 1157{
55e303ae 1158 unsigned short reply_port;
39236c6e 1159 struct kdp_ether_addr kdp_mac_addr = kdp_get_mac_addr();
55e303ae 1160 unsigned int ip_addr = ntohl(kdp_get_ip_address());
9bccf70c 1161
0c530ab8
A
1162 /*
1163 * Do both a printf() and a kprintf() of the MAC and IP so that
1164 * they will print out on headless machines but not be added to
1165 * the panic.log
1166 */
1167
39037602
A
1168 if (KDP_SERIAL_ENABLED()) {
1169 printf("Using serial KDP.\n");
1170 kprintf("Using serial KDP.\n");
1171 } else {
1172 printf("ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1173 kdp_mac_addr.ether_addr_octet[0] & 0xff,
1174 kdp_mac_addr.ether_addr_octet[1] & 0xff,
1175 kdp_mac_addr.ether_addr_octet[2] & 0xff,
1176 kdp_mac_addr.ether_addr_octet[3] & 0xff,
1177 kdp_mac_addr.ether_addr_octet[4] & 0xff,
1178 kdp_mac_addr.ether_addr_octet[5] & 0xff);
1179
1180 kprintf("ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1181 kdp_mac_addr.ether_addr_octet[0] & 0xff,
1182 kdp_mac_addr.ether_addr_octet[1] & 0xff,
1183 kdp_mac_addr.ether_addr_octet[2] & 0xff,
1184 kdp_mac_addr.ether_addr_octet[3] & 0xff,
1185 kdp_mac_addr.ether_addr_octet[4] & 0xff,
1186 kdp_mac_addr.ether_addr_octet[5] & 0xff);
1187
1188 printf("ip address: %d.%d.%d.%d\n",
1189 (ip_addr & 0xff000000) >> 24,
1190 (ip_addr & 0xff0000) >> 16,
1191 (ip_addr & 0xff00) >> 8,
1192 (ip_addr & 0xff));
1193
1194 kprintf("ip address: %d.%d.%d.%d\n",
1195 (ip_addr & 0xff000000) >> 24,
1196 (ip_addr & 0xff0000) >> 16,
1197 (ip_addr & 0xff00) >> 8,
1198 (ip_addr & 0xff));
1199 }
0c530ab8 1200
55e303ae 1201 printf("\nWaiting for remote debugger connection.\n");
316670eb 1202 kprintf("\nWaiting for remote debugger connection.\n");
55e303ae 1203
5ba3f43e
A
1204#ifdef ARM
1205 printf("\nPlease go to https://panic.apple.com to report this panic\n");
1206#endif
2d21ac55 1207
55e303ae 1208 if (reattach_wait == 0) {
39037602 1209 if((kdp_flag & KDP_GETC_ENA) && (0 != kdp_getc())) {
55e303ae
A
1210 printf("Options..... Type\n");
1211 printf("------------ ----\n");
1212 printf("continue.... 'c'\n");
1213 printf("reboot...... 'r'\n");
55e303ae 1214 }
39037602 1215 } else {
55e303ae 1216 reattach_wait = 0;
39037602 1217 }
9bccf70c 1218
55e303ae
A
1219 exception_seq = 0;
1220
1221 do {
1222 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
1c79356b 1223
55e303ae
A
1224 while (!pkt.input) {
1225 if (kdp_flag & KDP_GETC_ENA) {
1226 switch(kdp_getc()) {
1227 case 'c':
1228 printf("Continuing...\n");
1229 return;
1230 case 'r':
1231 printf("Rebooting...\n");
b0d623f7 1232 kdp_machine_reboot();
55e303ae 1233 break;
316670eb 1234 default:
55e303ae
A
1235 break;
1236 }
1237 }
1238 kdp_poll();
1239 }
1c79356b 1240
1c79356b 1241#if DO_ALIGN
55e303ae 1242 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
1c79356b 1243#else
55e303ae 1244 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
1c79356b 1245#endif
55e303ae 1246 if (hdr->request == KDP_HOSTREBOOT) {
b0d623f7 1247 kdp_machine_reboot();
55e303ae
A
1248 /* should not return! */
1249 }
1250 if (((hdr->request == KDP_CONNECT) || (hdr->request == KDP_REATTACH)) &&
1251 !hdr->is_reply && (hdr->seq == exception_seq)) {
39037602
A
1252 if (kdp_packet((unsigned char *)&pkt.data[pkt.off],
1253 (int *)&pkt.len,
55e303ae 1254 (unsigned short *)&reply_port))
7e4a7d39 1255 kdp_reply(reply_port, FALSE);
55e303ae
A
1256 if (hdr->request == KDP_REATTACH) {
1257 reattach_wait = 0;
1258 hdr->request=KDP_DISCONNECT;
1259 exception_seq = 0;
1260 }
1261 }
1262
1263 pkt.input = FALSE;
1264 } while (!kdp.is_conn);
1c79356b 1265
55e303ae
A
1266 if (current_debugger == KDP_CUR_DB)
1267 active_debugger=1;
1268 printf("Connected to remote debugger.\n");
316670eb 1269 kprintf("Connected to remote debugger.\n");
1c79356b
A
1270}
1271
9bccf70c 1272static void
1c79356b 1273kdp_send_exception(
39037602
A
1274 unsigned int exception,
1275 unsigned int code,
1276 unsigned int subcode
1c79356b
A
1277)
1278{
39037602
A
1279 unsigned short remote_port;
1280 unsigned int timeout_count = 100;
1281 unsigned int poll_timeout;
1282
1283 do {
1284 pkt.off = sizeof (struct kdp_ether_header) + sizeof (struct kdp_udpiphdr);
1285 kdp_exception((unsigned char *)&pkt.data[pkt.off],
1286 (int *)&pkt.len,
1287 (unsigned short *)&remote_port,
1288 (unsigned int)exception,
1289 (unsigned int)code,
1290 (unsigned int)subcode);
1291
1292 kdp_send(remote_port);
1293
1294 poll_timeout = 50;
1295 while (!pkt.input && poll_timeout) {
1296 kdp_poll();
1297 poll_timeout--;
1298 }
1299
1300 if (pkt.input) {
1301 if (!kdp_exception_ack(&pkt.data[pkt.off], pkt.len)) {
1302 pkt.input = FALSE;
1303 }
1304 }
9bccf70c 1305
1c79356b 1306 pkt.input = FALSE;
9bccf70c 1307
39037602
A
1308 if (kdp.exception_ack_needed)
1309 kdp_us_spin(250000);
9bccf70c 1310
39037602 1311 } while (kdp.exception_ack_needed && timeout_count--);
1c79356b 1312
39037602
A
1313 if (kdp.exception_ack_needed) {
1314 // give up & disconnect
1315 printf("kdp: exception ack timeout\n");
1316 if (current_debugger == KDP_CUR_DB)
1317 active_debugger=0;
1318 kdp_reset();
1319 }
1c79356b
A
1320}
1321
fe8ab488
A
1322static void
1323kdp_debugger_loop(
39037602
A
1324 unsigned int exception,
1325 unsigned int code,
1326 unsigned int subcode,
1327 void *saved_state)
1c79356b 1328{
39037602 1329 int index;
1c79356b 1330
39037602
A
1331 if (saved_state == 0)
1332 printf("kdp_raise_exception with NULL state\n");
2d21ac55 1333
39037602
A
1334 index = exception;
1335 if (exception != EXC_BREAKPOINT) {
1336 if (exception > EXC_BREAKPOINT || exception < EXC_BAD_ACCESS) {
1337 index = 0;
1338 }
1339 printf("%s exception (%x,%x,%x)\n",
1340 exception_message[index],
1341 exception, code, subcode);
1342 }
1343
1344 kdp_sync_cache();
1345
1346 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
1347 * do this. I think the client and the host can get out of sync.
1348 */
1349 kdp.saved_state = saved_state;
1350 kdp.kdp_cpu = cpu_number();
1351 kdp.kdp_thread = current_thread();
2d21ac55 1352
39037602
A
1353 if (kdp_en_setmode)
1354 (*kdp_en_setmode)(TRUE); /* enabling link mode */
9bccf70c 1355
39037602
A
1356 if (pkt.input)
1357 kdp_panic("kdp_raise_exception");
1358
1359 if (((kdp_flag & KDP_PANIC_DUMP_ENABLED)
5ba3f43e
A
1360 || (kdp_flag & PANIC_LOG_DUMP))
1361 && panic_active()) {
39037602 1362 kdp_panic_dump();
5ba3f43e 1363 if (kdp_flag & REBOOT_POST_CORE && dumped_kernel_core())
39037602
A
1364 kdp_machine_reboot();
1365 } else {
9d749ea3 1366 if ((kdp_flag & PANIC_CORE_ON_NMI) && !panic_active()
39037602
A
1367 && !kdp.is_conn) {
1368
5ba3f43e 1369 disableConsoleOutput = FALSE;
39037602 1370 kdp_panic_dump();
5ba3f43e 1371 if (kdp_flag & REBOOT_POST_CORE && dumped_kernel_core())
39037602
A
1372 kdp_machine_reboot();
1373
1374 if (!(kdp_flag & DBG_POST_CORE))
1375 goto exit_debugger_loop;
1376 }
1377 }
1378
1379again:
1380 if (!kdp.is_conn) {
1381 kdp_connection_wait();
1382 } else {
1383 kdp_send_exception(exception, code, subcode);
1384 if (kdp.exception_ack_needed) {
1385 kdp.exception_ack_needed = FALSE;
1386 kdp_remove_all_breakpoints();
1387 printf("Remote debugger disconnected.\n");
1388 }
1389 }
1390
1391 if (kdp.is_conn) {
1392 kdp.is_halted = TRUE; /* XXX */
1393 kdp_handler(saved_state);
1394 if (!kdp.is_conn)
1395 {
1396 kdp_remove_all_breakpoints();
1397 printf("Remote debugger disconnected.\n");
1398 }
1399 }
1400 /* Allow triggering a panic core dump when connected to the machine
1401 * Continuing after setting kdp_trigger_core_dump should do the
1402 * trick.
1403 */
1404
1405 if (1 == kdp_trigger_core_dump) {
1406 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
1407 kdp_panic_dump();
5ba3f43e 1408 if (kdp_flag & REBOOT_POST_CORE && dumped_kernel_core())
39037602
A
1409 kdp_machine_reboot();
1410 kdp_trigger_core_dump = 0;
1411 }
1412
1413 /* Trigger a reboot if the user has set this flag through the
1414 * debugger.Ideally, this would be done through the HOSTREBOOT packet
1415 * in the protocol,but that will need gdb support,and when it's
1416 * available, it should work automatically.
1417 */
1418 if (1 == flag_kdp_trigger_reboot) {
1419 kdp_machine_reboot();
1420 /* If we're still around, reset the flag */
1421 flag_kdp_trigger_reboot = 0;
1422 }
1423
1424 if (kdp_reentry_deadline) {
1425 kdp_schedule_debugger_reentry(kdp_reentry_deadline);
1426 printf("Debugger re-entry scheduled in %d milliseconds\n", kdp_reentry_deadline);
1427 kdp_reentry_deadline = 0;
1428 }
1429
1430 kdp_sync_cache();
1431
1432 if (reattach_wait == 1)
1433 goto again;
91447636 1434
fe8ab488 1435exit_debugger_loop:
39037602
A
1436 if (kdp_en_setmode)
1437 (*kdp_en_setmode)(FALSE); /* link cleanup */
1c79356b
A
1438}
1439
1440void
1441kdp_reset(void)
1442{
9bccf70c
A
1443 kdp.reply_port = kdp.exception_port = 0;
1444 kdp.is_halted = kdp.is_conn = FALSE;
1445 kdp.exception_seq = kdp.conn_seq = 0;
7ddcb079
A
1446 kdp.session_key = 0;
1447 pkt.input = manual_pkt.input = FALSE;
1448 pkt.len = pkt.off = manual_pkt.len = 0;
1c79356b
A
1449}
1450
55e303ae
A
1451struct corehdr *
1452create_panic_header(unsigned int request, const char *corename,
39037602 1453 unsigned length, unsigned int block)
55e303ae 1454{
39236c6e
A
1455 struct kdp_udpiphdr aligned_ui, *ui = &aligned_ui;
1456 struct kdp_ip aligned_ip, *ip = &aligned_ip;
1457 struct kdp_ether_header *eh;
0c530ab8
A
1458 struct corehdr *coreh;
1459 const char *mode = "octet";
316670eb 1460 char modelen = strlen(mode) + 1;
6d2010ae 1461
b0d623f7 1462 size_t fmask_size = sizeof(KDP_FEATURE_MASK_STRING) + sizeof(kdp_crashdump_feature_mask);
6d2010ae 1463
39236c6e 1464 pkt.off = sizeof (struct kdp_ether_header);
b0d623f7 1465 pkt.len = (unsigned int)(length + ((request == KDP_WRQ) ? modelen + fmask_size : 0) +
316670eb 1466 (corename ? (strlen(corename) + 1 ): 0) + sizeof(struct corehdr));
55e303ae
A
1467
1468#if DO_ALIGN
0c530ab8 1469 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
55e303ae 1470#else
39236c6e 1471 ui = (struct kdp_udpiphdr *)&pkt.data[pkt.off];
55e303ae 1472#endif
b0d623f7 1473 ui->ui_next = ui->ui_prev = 0;
0c530ab8
A
1474 ui->ui_x1 = 0;
1475 ui->ui_pr = IPPROTO_UDP;
39236c6e 1476 ui->ui_len = htons((u_short)pkt.len + sizeof (struct kdp_udphdr));
b0d623f7 1477 ui->ui_src.s_addr = (uint32_t)kdp_current_ip_address;
0c530ab8
A
1478 /* Already in network byte order via inet_aton() */
1479 ui->ui_dst.s_addr = panic_server_ip;
1480 ui->ui_sport = htons(panicd_port);
1481 ui->ui_dport = ((request == KDP_WRQ) ? htons(panicd_port) : last_panic_port);
1482 ui->ui_ulen = ui->ui_len;
1483 ui->ui_sum = 0;
55e303ae 1484#if DO_ALIGN
0c530ab8
A
1485 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
1486 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
55e303ae 1487#else
39236c6e 1488 ip = (struct kdp_ip *)&pkt.data[pkt.off];
55e303ae 1489#endif
39236c6e 1490 ip->ip_len = htons(sizeof (struct kdp_udpiphdr) + pkt.len);
0c530ab8
A
1491 ip->ip_v = IPVERSION;
1492 ip->ip_id = htons(ip_id++);
39236c6e 1493 ip->ip_hl = sizeof (struct kdp_ip) >> 2;
0c530ab8
A
1494 ip->ip_ttl = udp_ttl;
1495 ip->ip_sum = 0;
1496 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
55e303ae 1497#if DO_ALIGN
0c530ab8 1498 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
55e303ae
A
1499#endif
1500
39236c6e 1501 pkt.len += (unsigned int)sizeof (struct kdp_udpiphdr);
55e303ae 1502
39236c6e 1503 pkt.off += (unsigned int)sizeof (struct kdp_udpiphdr);
55e303ae 1504
0c530ab8
A
1505 coreh = (struct corehdr *) &pkt.data[pkt.off];
1506 coreh->th_opcode = htons((u_short)request);
55e303ae 1507
39037602 1508 if (request == KDP_WRQ) {
2d21ac55 1509 char *cp;
0c530ab8
A
1510
1511 cp = coreh->th_u.tu_rpl;
2d21ac55 1512 cp += strlcpy (cp, corename, KDP_MAXPACKET);
0c530ab8 1513 *cp++ = '\0';
2d21ac55 1514 cp += strlcpy (cp, mode, KDP_MAXPACKET - strlen(corename));
0c530ab8 1515 *cp++ = '\0';
b0d623f7
A
1516 cp += strlcpy(cp, KDP_FEATURE_MASK_STRING, sizeof(KDP_FEATURE_MASK_STRING));
1517 *cp++ = '\0'; /* Redundant */
1518 bcopy(&kdp_crashdump_feature_mask, cp, sizeof(kdp_crashdump_feature_mask));
6d2010ae
A
1519 kdp_crashdump_pkt_size = KDP_LARGE_CRASHDUMP_PKT_SIZE;
1520 PE_parse_boot_argn("kdp_crashdump_pkt_size", &kdp_crashdump_pkt_size, sizeof(kdp_crashdump_pkt_size));
1521 cp += sizeof(kdp_crashdump_feature_mask);
1522 *(uint32_t *)cp = htonl(kdp_crashdump_pkt_size);
39037602 1523 } else {
0c530ab8
A
1524 coreh->th_block = htonl((unsigned int) block);
1525 }
55e303ae 1526
39236c6e
A
1527 pkt.off -= (unsigned int)sizeof (struct kdp_udpiphdr);
1528 pkt.off -= (unsigned int)sizeof (struct kdp_ether_header);
55e303ae 1529
39236c6e 1530 eh = (struct kdp_ether_header *)&pkt.data[pkt.off];
0c530ab8
A
1531 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
1532 enaddr_copy(&destination_mac, eh->ether_dhost);
1533 eh->ether_type = htons(ETHERTYPE_IP);
55e303ae 1534
39236c6e 1535 pkt.len += (unsigned int)sizeof (struct kdp_ether_header);
0c530ab8 1536 return coreh;
55e303ae
A
1537}
1538
39037602
A
1539static int
1540kdp_send_crashdump_seek(char *corename, uint64_t seek_off)
7e4a7d39
A
1541{
1542 int panic_error;
1543
7e4a7d39
A
1544 if (kdp_feature_large_crashdumps) {
1545 panic_error = kdp_send_crashdump_pkt(KDP_SEEK, corename,
1546 sizeof(seek_off),
1547 &seek_off);
6d2010ae 1548 } else {
7e4a7d39
A
1549 uint32_t off = (uint32_t) seek_off;
1550 panic_error = kdp_send_crashdump_pkt(KDP_SEEK, corename,
1551 sizeof(off), &off);
1552 }
1553
1554 if (panic_error < 0) {
1555 printf ("kdp_send_crashdump_pkt failed with error %d\n",
1556 panic_error);
1557 return panic_error;
1558 }
1559
3e170ce0 1560 return KERN_SUCCESS;
7e4a7d39
A
1561}
1562
39037602
A
1563int
1564kdp_send_crashdump_data(unsigned int request, char *corename,
3e170ce0 1565 uint64_t length, void * txstart)
55e303ae 1566{
0c530ab8 1567 int panic_error = 0;
55e303ae 1568
3e170ce0 1569 while ((length > 0) || !txstart) {
6d2010ae
A
1570 uint64_t chunk = MIN(kdp_crashdump_pkt_size, length);
1571
7e4a7d39 1572 panic_error = kdp_send_crashdump_pkt(request, corename, chunk,
6d2010ae 1573 txstart);
7e4a7d39 1574 if (panic_error < 0) {
0c530ab8 1575 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
7e4a7d39 1576 return panic_error;
0c530ab8 1577 }
3e170ce0
A
1578 if (!txstart) break;
1579 txstart = (void *)(((uintptr_t) txstart) + chunk);
7e4a7d39 1580 length -= chunk;
0c530ab8 1581 }
3e170ce0 1582 return KERN_SUCCESS;
55e303ae
A
1583}
1584
6d2010ae
A
1585uint32_t kdp_crashdump_short_pkt;
1586
0c530ab8
A
1587int
1588kdp_send_crashdump_pkt(unsigned int request, char *corename,
39037602 1589 uint64_t length, void *panic_data)
55e303ae 1590{
6d2010ae 1591 int poll_count;
0c530ab8 1592 struct corehdr *th = NULL;
6d2010ae
A
1593 char rretries, tretries;
1594
1595 if (kdp_dump_start_time == 0) {
1596 kdp_dump_start_time = mach_absolute_time();
1597 kdp_superblock_dump_start_time = kdp_dump_start_time;
1598 }
0c530ab8 1599
6d2010ae
A
1600 tretries = rretries = 0;
1601 poll_count = KDP_CRASHDUMP_POLL_COUNT;
0c530ab8 1602 pkt.off = pkt.len = 0;
0c530ab8
A
1603 if (request == KDP_WRQ) /* longer timeout for initial request */
1604 poll_count += 1000;
55e303ae
A
1605
1606TRANSMIT_RETRY:
0c530ab8 1607 tretries++;
8f6c56a5 1608
0c530ab8
A
1609 if (tretries >=15) {
1610/* The crashdump server is unreachable for some reason. This could be a network
1611 * issue or, if we've been especially unfortunate, we've hit Radar 2760413,
1612 * which is a long standing problem with the IOKit polled mode network driver
1613 * shim which can prevent transmits/receives completely.
1614 */
1615 printf ("Cannot contact panic server, timing out.\n");
1616 return (-3);
1617 }
8f6c56a5 1618
0c530ab8
A
1619 if (tretries > 2)
1620 printf("TX retry #%d ", tretries );
1621
b0d623f7 1622 th = create_panic_header(request, corename, (unsigned)length, panic_block);
21362eb3 1623
0c530ab8 1624 if (request == KDP_DATA) {
6d2010ae 1625 /* as all packets are kdp_crashdump_pkt_size in length, the last packet
7e4a7d39
A
1626 * may end up with trailing bits. make sure that those
1627 * bits aren't confusing. */
6d2010ae
A
1628 if (length < kdp_crashdump_pkt_size) {
1629 kdp_crashdump_short_pkt++;
1630 memset(th->th_data + length, 'Y',
1631 kdp_crashdump_pkt_size - (uint32_t) length);
1632 }
7e4a7d39 1633
6d2010ae
A
1634 if (!kdp_machine_vm_read((mach_vm_address_t)(uintptr_t)panic_data, (caddr_t) th->th_data, length)) {
1635 uintptr_t next_page = round_page((uintptr_t)panic_data);
1636 memset((caddr_t) th->th_data, 'X', (size_t)length);
1637 if ((next_page - ((uintptr_t) panic_data)) < length) {
1638 uint64_t resid = length - (next_page - (intptr_t) panic_data);
1639 if (!kdp_machine_vm_read((mach_vm_address_t)(uintptr_t)next_page, (caddr_t) th->th_data + (length - resid), resid)) {
1640 memset((caddr_t) th->th_data + (length - resid), 'X', (size_t)resid);
1641 }
1642 }
0c530ab8
A
1643 }
1644 }
1645 else if (request == KDP_SEEK) {
b0d623f7
A
1646 if (kdp_feature_large_crashdumps)
1647 *(uint64_t *) th->th_data = OSSwapHostToBigInt64((*(uint64_t *) panic_data));
1648 else
6d2010ae 1649 *(unsigned int *) th->th_data = htonl(*(unsigned int *) panic_data);
0c530ab8 1650 }
21362eb3 1651
6d2010ae 1652 kdp_send_data(&pkt.data[pkt.off], pkt.len);
6601e61a 1653
0c530ab8
A
1654 /* Listen for the ACK */
1655RECEIVE_RETRY:
1656 while (!pkt.input && flag_panic_dump_in_progress && poll_count) {
1657 kdp_poll();
1658 poll_count--;
1659 }
6601e61a 1660
0c530ab8 1661 if (pkt.input) {
0c530ab8 1662 pkt.input = FALSE;
55e303ae 1663
0c530ab8 1664 th = (struct corehdr *) &pkt.data[pkt.off];
b0d623f7
A
1665 if (request == KDP_WRQ) {
1666 uint16_t opcode64 = ntohs(th->th_opcode);
1667 uint16_t features64 = (opcode64 & 0xFF00)>>8;
1668 if ((opcode64 & 0xFF) == KDP_ACK) {
1669 kdp_feature_large_crashdumps = features64 & KDP_FEATURE_LARGE_CRASHDUMPS;
6d2010ae
A
1670 if (features64 & KDP_FEATURE_LARGE_PKT_SIZE) {
1671 kdp_feature_large_pkt_size = 1;
1672 }
1673 else {
1674 kdp_feature_large_pkt_size = 0;
1675 kdp_crashdump_pkt_size = 512;
1676 }
b0d623f7
A
1677 printf("Protocol features: 0x%x\n", (uint32_t) features64);
1678 th->th_opcode = htons(KDP_ACK);
1679 }
1680 }
0c530ab8 1681 if (ntohs(th->th_opcode) == KDP_ACK && ntohl(th->th_block) == panic_block) {
39037602 1682 } else {
0c530ab8
A
1683 if (ntohs(th->th_opcode) == KDP_ERROR) {
1684 printf("Panic server returned error %d, retrying\n", ntohl(th->th_code));
1685 poll_count = 1000;
1686 goto TRANSMIT_RETRY;
39037602
A
1687 } else if (ntohl(th->th_block) == (panic_block - 1)) {
1688 printf("RX retry ");
1689 if (++rretries > 1)
1690 goto TRANSMIT_RETRY;
1691 else
1692 goto RECEIVE_RETRY;
0c530ab8 1693 }
39037602
A
1694 }
1695 } else if (!flag_panic_dump_in_progress) { /* we received a debugging packet, bail*/
0c530ab8
A
1696 printf("Received a debugger packet,transferring control to debugger\n");
1697 /* Configure that if not set ..*/
1698 kdp_flag |= DBG_POST_CORE;
1699 return (-2);
39037602 1700 } else { /* We timed out */
0c530ab8
A
1701 if (0 == poll_count) {
1702 poll_count = 1000;
1703 kdp_us_spin ((tretries%4) * panic_timeout); /* capped linear backoff */
1704 goto TRANSMIT_RETRY;
1705 }
39037602 1706 }
6d2010ae
A
1707
1708 if (!(++panic_block % SBLOCKSZ)) {
1709 uint64_t ctime;
1710 kdb_printf_unbuffered(".");
1711 ctime = mach_absolute_time();
1712 kdp_superblock_dump_time = ctime - kdp_superblock_dump_start_time;
1713 kdp_superblock_dump_start_time = ctime;
1714 if (kdp_superblock_dump_time > kdp_max_superblock_dump_time)
1715 kdp_max_superblock_dump_time = kdp_superblock_dump_time;
1716 if (kdp_superblock_dump_time < kdp_min_superblock_dump_time)
1717 kdp_min_superblock_dump_time = kdp_superblock_dump_time;
1718 }
1719
1720 if (request == KDP_EOF) {
0c530ab8 1721 printf("\nTotal number of packets transmitted: %d\n", panic_block);
6d2010ae
A
1722 printf("Avg. superblock transfer abstime 0x%llx\n", ((mach_absolute_time() - kdp_dump_start_time) / panic_block) * SBLOCKSZ);
1723 printf("Minimum superblock transfer abstime: 0x%llx\n", kdp_min_superblock_dump_time);
1724 printf("Maximum superblock transfer abstime: 0x%llx\n", kdp_max_superblock_dump_time);
1725 }
3e170ce0 1726 return KERN_SUCCESS;
55e303ae
A
1727}
1728
55e303ae
A
1729static int
1730isdigit (char c)
1731{
39037602 1732 return ((c > 47) && (c < 58));
55e303ae 1733}
55e303ae
A
1734
1735/* Horrid hack to extract xnu version if possible - a much cleaner approach
1736 * would be to have the integrator run a script which would copy the
1737 * xnu version into a string or an int somewhere at project submission
1738 * time - makes assumptions about sizeof(version), but will not fail if
1739 * it changes, but may be incorrect.
1740 */
0c530ab8
A
1741/* 2006: Incorporated a change from Darwin user P. Lovell to extract
1742 * the minor kernel version numbers from the version string.
1743 */
55e303ae
A
1744static int
1745kdp_get_xnu_version(char *versionbuf)
1746{
0c530ab8
A
1747 char *versionpos;
1748 char vstr[20];
1749 int retval = -1;
1750 char *vptr;
1751
2d21ac55 1752 strlcpy(vstr, "custom", 10);
060df5ea 1753 if (kdp_machine_vm_read((mach_vm_address_t)(uintptr_t)version, versionbuf, 128)) {
6d2010ae
A
1754 versionbuf[127] = '\0';
1755 versionpos = strnstr(versionbuf, "xnu-", 115);
cf7d32b8
A
1756 if (versionpos) {
1757 strncpy(vstr, versionpos, sizeof(vstr));
1758 vstr[sizeof(vstr)-1] = '\0';
1759 vptr = vstr + 4; /* Begin after "xnu-" */
1760 while (*vptr && (isdigit(*vptr) || *vptr == '.'))
1761 vptr++;
1762 *vptr = '\0';
1763 /* Remove trailing period, if any */
1764 if (*(--vptr) == '.')
0c530ab8 1765 *vptr = '\0';
cf7d32b8 1766 retval = 0;
0c530ab8
A
1767 }
1768 }
2d21ac55 1769 strlcpy(versionbuf, vstr, KDP_MAXPACKET);
0c530ab8 1770 return retval;
55e303ae 1771}
91447636 1772
7e4a7d39
A
1773void
1774kdp_set_dump_info(const uint32_t flags, const char *filename,
1775 const char *destipstr, const char *routeripstr,
1776 const uint32_t port)
1777{
1778 uint32_t cmd;
1779
1780 if (destipstr && (destipstr[0] != '\0')) {
1781 strlcpy(panicd_ip_str, destipstr, sizeof(panicd_ip_str));
1782 panicd_specified = 1;
1783 }
1784
1785 if (routeripstr && (routeripstr[0] != '\0')) {
1786 strlcpy(router_ip_str, routeripstr, sizeof(router_ip_str));
1787 router_specified = 1;
1788 }
1789
1790 if (filename && (filename[0] != '\0')) {
1791 strlcpy(corename_str, filename, sizeof(corename_str));
1792 corename_specified = TRUE;
1793 } else {
1794 corename_specified = FALSE;
1795 }
1796
1797 if (port)
1798 panicd_port = port;
1799
1800 /* on a disconnect, should we stay in KDP or not? */
1801 noresume_on_disconnect = (flags & KDP_DUMPINFO_NORESUME) ? 1 : 0;
1802
1803 if ((flags & KDP_DUMPINFO_DUMP) == 0)
1804 return;
1805
1806 /* the rest of the commands can modify kdp_flags */
1807 cmd = flags & KDP_DUMPINFO_MASK;
1808 if (cmd == KDP_DUMPINFO_DISABLE) {
1809 kdp_flag &= ~KDP_PANIC_DUMP_ENABLED;
1810 panicd_specified = 0;
1811 kdp_trigger_core_dump = 0;
1812 return;
1813 }
1814
1815 kdp_flag &= ~REBOOT_POST_CORE;
1816 if (flags & KDP_DUMPINFO_REBOOT)
1817 kdp_flag |= REBOOT_POST_CORE;
1818
1819 kdp_flag &= ~PANIC_LOG_DUMP;
1820 if (cmd == KDP_DUMPINFO_PANICLOG)
1821 kdp_flag |= PANIC_LOG_DUMP;
1822
1823 kdp_flag &= ~SYSTEM_LOG_DUMP;
1824 if (cmd == KDP_DUMPINFO_SYSTEMLOG)
1825 kdp_flag |= SYSTEM_LOG_DUMP;
1826
1827 /* trigger a dump */
1828 kdp_flag |= DBG_POST_CORE;
1829
1830 flag_dont_abort_panic_dump = (flags & KDP_DUMPINFO_NOINTR) ?
1831 TRUE : FALSE;
1832
1833 reattach_wait = 1;
7e4a7d39 1834 disableConsoleOutput = 0;
7e4a7d39
A
1835 kdp_trigger_core_dump = 1;
1836}
1837
1838void
813fb2f6 1839kdp_get_dump_info(kdp_dumpinfo_reply_t *rp)
7e4a7d39 1840{
5ba3f43e
A
1841 if (panicd_specified)
1842 strlcpy(rp->destip, panicd_ip_str,
1843 sizeof(rp->destip));
1844 else
1845 rp->destip[0] = '\0';
7e4a7d39 1846
5ba3f43e
A
1847 if (router_specified)
1848 strlcpy(rp->routerip, router_ip_str,
1849 sizeof(rp->routerip));
1850 else
1851 rp->routerip[0] = '\0';
7e4a7d39 1852
5ba3f43e
A
1853 if (corename_specified)
1854 strlcpy(rp->name, corename_str,
1855 sizeof(rp->name));
1856 else
1857 rp->name[0] = '\0';
7e4a7d39 1858
813fb2f6 1859 rp->port = panicd_port;
7e4a7d39 1860
813fb2f6
A
1861 rp->type = 0;
1862 if (!panicd_specified)
1863 rp->type |= KDP_DUMPINFO_DISABLE;
1864 else if (kdp_flag & PANIC_LOG_DUMP)
1865 rp->type |= KDP_DUMPINFO_PANICLOG;
1866 else
1867 rp->type |= KDP_DUMPINFO_CORE;
1868
1869 if (noresume_on_disconnect)
1870 rp->type |= KDP_DUMPINFO_NORESUME;
7e4a7d39
A
1871}
1872
1873
55e303ae
A
1874/* Primary dispatch routine for the system dump */
1875void
2d21ac55 1876kdp_panic_dump(void)
55e303ae 1877{
0c530ab8 1878 char coreprefix[10];
3e170ce0 1879 char coresuffix[4];
0c530ab8 1880 int panic_error;
55e303ae 1881
6d2010ae 1882 uint64_t abstime;
b0d623f7 1883 uint32_t current_ip = ntohl((uint32_t)kdp_current_ip_address);
c0fea474 1884
0c530ab8 1885 if (flag_panic_dump_in_progress) {
6d2010ae 1886 kdb_printf("System dump aborted.\n");
0c530ab8
A
1887 goto panic_dump_exit;
1888 }
1889
1890 printf("Entering system dump routine\n");
060df5ea
A
1891
1892 if (!kdp_en_recv_pkt || !kdp_en_send_pkt) {
5ba3f43e 1893 kdb_printf("Error: No transport device registered for kernel crashdump\n");
3e170ce0 1894 return;
060df5ea
A
1895 }
1896
0c530ab8 1897 if (!panicd_specified) {
5ba3f43e 1898 kdb_printf("A dump server was not specified in the boot-args, terminating kernel core dump.\n");
0c530ab8
A
1899 goto panic_dump_exit;
1900 }
8f6c56a5 1901
0c530ab8 1902 flag_panic_dump_in_progress = TRUE;
55e303ae 1903
0c530ab8
A
1904 if (pkt.input)
1905 kdp_panic("kdp_panic_dump: unexpected pending input packet");
55e303ae 1906
0c530ab8 1907 kdp_get_xnu_version((char *) &pkt.data[0]);
55e303ae 1908
39037602
A
1909 if (!corename_specified) {
1910 coresuffix[0] = 0;
1911 /* Panic log bit takes precedence over core dump bit */
5ba3f43e 1912 if ((debugger_panic_str != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP))
39037602
A
1913 strlcpy(coreprefix, "paniclog", sizeof(coreprefix));
1914 else if (kdp_flag & SYSTEM_LOG_DUMP)
1915 strlcpy(coreprefix, "systemlog", sizeof(coreprefix));
1916 else {
1917 strlcpy(coreprefix, "core", sizeof(coreprefix));
1918 if (!kdp_corezip_disabled) strlcpy(coresuffix, ".gz", sizeof(coresuffix));
1919 }
1920
1921 abstime = mach_absolute_time();
1922 pkt.data[20] = '\0';
1923 snprintf (corename_str,
1924 sizeof(corename_str),
1925 "%s-%s-%d.%d.%d.%d-%x%s",
1926 coreprefix, &pkt.data[0],
1927 (current_ip & 0xff000000) >> 24,
1928 (current_ip & 0xff0000) >> 16,
1929 (current_ip & 0xff00) >> 8,
1930 (current_ip & 0xff),
1931 (unsigned int) (abstime & 0xffffffff),
1932 coresuffix);
1933 }
0c530ab8 1934
39236c6e 1935 if (0 == inet_aton(panicd_ip_str, (struct kdp_in_addr *) &panic_server_ip)) {
6d2010ae 1936 kdb_printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str);
39037602 1937 } else {
6d2010ae 1938 kdb_printf("Attempting connection to panic server configured at IP %s, port %d\n", panicd_ip_str, panicd_port);
39037602 1939 }
4452a7af 1940
0c530ab8
A
1941 destination_mac = router_mac;
1942
1943 if (kdp_arp_resolve(panic_server_ip, &temp_mac)) {
6d2010ae 1944 kdb_printf("Resolved %s's (or proxy's) link level address\n", panicd_ip_str);
0c530ab8 1945 destination_mac = temp_mac;
39037602 1946 } else {
0c530ab8
A
1947 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
1948 if (router_specified) {
39037602 1949 if (0 == inet_aton(router_ip_str, (struct kdp_in_addr *) &parsed_router_ip)) {
6d2010ae 1950 kdb_printf("inet_aton() failed interpreting %s as an IP\n", router_ip_str);
39037602 1951 } else {
0c530ab8
A
1952 router_ip = parsed_router_ip;
1953 if (kdp_arp_resolve(router_ip, &temp_mac)) {
1954 destination_mac = temp_mac;
6d2010ae 1955 kdb_printf("Routing through specified router IP %s (%d)\n", router_ip_str, router_ip);
0c530ab8
A
1956 }
1957 }
1958 }
55e303ae 1959 }
91447636 1960
0c530ab8 1961 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
5d5c5d0d 1962
6d2010ae 1963 kdb_printf("Transmitting packets to link level address: %02x:%02x:%02x:%02x:%02x:%02x\n",
0c530ab8
A
1964 destination_mac.ether_addr_octet[0] & 0xff,
1965 destination_mac.ether_addr_octet[1] & 0xff,
1966 destination_mac.ether_addr_octet[2] & 0xff,
1967 destination_mac.ether_addr_octet[3] & 0xff,
1968 destination_mac.ether_addr_octet[4] & 0xff,
1969 destination_mac.ether_addr_octet[5] & 0xff);
89b3af67 1970
6d2010ae
A
1971 kdb_printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map));
1972 kdb_printf("Sending write request for %s\n", corename_str);
4452a7af 1973
7e4a7d39 1974 if ((panic_error = kdp_send_crashdump_pkt(KDP_WRQ, corename_str, 0 , NULL)) < 0) {
6d2010ae 1975 kdb_printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
0c530ab8
A
1976 goto panic_dump_exit;
1977 }
1978
1979 /* Just the panic log requested */
5ba3f43e 1980 if ((debugger_panic_str != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP)) {
6d2010ae 1981 kdb_printf_unbuffered("Transmitting panic log, please wait: ");
7e4a7d39 1982 kdp_send_crashdump_data(KDP_DATA, corename_str,
5ba3f43e
A
1983 debug_buf_ptr - debug_buf_base,
1984 debug_buf_base);
0c530ab8
A
1985 kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
1986 printf("Please file a bug report on this panic, if possible.\n");
1987 goto panic_dump_exit;
1988 }
55e303ae 1989
7e4a7d39
A
1990 /* maybe we wanted the systemlog */
1991 if (kdp_flag & SYSTEM_LOG_DUMP) {
1992 long start_off = msgbufp->msg_bufx;
1993 long len;
1994
6d2010ae 1995 kdb_printf_unbuffered("Transmitting system log, please wait: ");
7e4a7d39
A
1996 if (start_off >= msgbufp->msg_bufr) {
1997 len = msgbufp->msg_size - start_off;
1998 kdp_send_crashdump_data(KDP_DATA, corename_str, len,
1999 msgbufp->msg_bufc + start_off);
7e4a7d39 2000 /* seek to remove trailing bytes */
6d2010ae 2001 kdp_send_crashdump_seek(corename_str, len);
7e4a7d39
A
2002 start_off = 0;
2003 }
2004
2005 if (start_off != msgbufp->msg_bufr) {
2006 len = msgbufp->msg_bufr - start_off;
2007 kdp_send_crashdump_data(KDP_DATA, corename_str, len,
2008 msgbufp->msg_bufc + start_off);
2009 }
2010
2011 kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
2012 goto panic_dump_exit;
2013 }
2014
0c530ab8 2015 /* We want a core dump if we're here */
39037602 2016 kern_dump(KERN_DUMP_NET);
7e4a7d39 2017
55e303ae 2018panic_dump_exit:
0c530ab8 2019 abort_panic_transfer();
0c530ab8
A
2020 kdp_reset();
2021 return;
55e303ae
A
2022}
2023
5ba3f43e
A
2024void
2025begin_panic_transfer(void)
2026{
2027 flag_panic_dump_in_progress = TRUE;
2028}
2029
55e303ae 2030void
0c530ab8 2031abort_panic_transfer(void)
55e303ae 2032{
0c530ab8 2033 flag_panic_dump_in_progress = FALSE;
7e4a7d39 2034 flag_dont_abort_panic_dump = FALSE;
0c530ab8 2035 panic_block = 0;
55e303ae 2036}
593a1d5f
A
2037
2038#if CONFIG_SERIAL_KDP
2039
2040static boolean_t needs_serial_init = TRUE;
2041
2042static void
2043kdp_serial_send(void *rpkt, unsigned int rpkt_len)
2044{
593a1d5f 2045 // printf("tx\n");
39037602 2046 kdp_serialize_packet((unsigned char *)rpkt, rpkt_len, pal_serial_putc_nocr);
593a1d5f
A
2047}
2048
2049static void
2050kdp_serial_receive(void *rpkt, unsigned int *rpkt_len, unsigned int timeout)
2051{
2052 int readkar;
2053 uint64_t now, deadline;
2054
593a1d5f
A
2055 clock_interval_to_deadline(timeout, 1000 * 1000 /* milliseconds */, &deadline);
2056
2057// printf("rx\n");
39037602 2058 for(clock_get_uptime(&now); now < deadline; clock_get_uptime(&now)) {
6d2010ae 2059 readkar = pal_serial_getc();
39037602 2060 if(readkar >= 0) {
593a1d5f
A
2061 unsigned char *packet;
2062 // printf("got char %02x\n", readkar);
39037602 2063 if((packet = kdp_unserialize_packet(readkar,rpkt_len))) {
593a1d5f
A
2064 memcpy(rpkt, packet, *rpkt_len);
2065 return;
2066 }
2067 }
2068 }
2069 *rpkt_len = 0;
2070}
2071
6d2010ae
A
2072static boolean_t
2073kdp_serial_setmode(boolean_t active)
2074{
39037602
A
2075 if (active == FALSE) /* leaving KDP */
2076 return TRUE;
6d2010ae
A
2077
2078 if (!needs_serial_init)
39037602 2079 return TRUE;
6d2010ae 2080
39037602
A
2081 pal_serial_init();
2082 needs_serial_init = FALSE;
2083 return TRUE;
6d2010ae
A
2084}
2085
2086
fe8ab488
A
2087static void
2088kdp_serial_callout(__unused void *arg, kdp_event_t event)
593a1d5f 2089{
39037602
A
2090 /*
2091 * When we stop KDP, set the bit to re-initialize the console serial
2092 * port the next time we send/receive a KDP packet. We don't do it on
2093 * KDP_EVENT_ENTER directly because it also gets called when we trap to
2094 * KDP for non-external debugging, i.e., stackshot or core dumps.
2095 *
2096 * Set needs_serial_init on exit (and initialization, see above) and not
2097 * enter because enter is sent multiple times and causes excess
2098 * reinitialization.
2099 */
2100
2101 switch (event)
2102 {
593a1d5f
A
2103 case KDP_EVENT_PANICLOG:
2104 case KDP_EVENT_ENTER:
2105 break;
2106 case KDP_EVENT_EXIT:
2107 needs_serial_init = TRUE;
2108 break;
39037602 2109 }
593a1d5f
A
2110}
2111
2112#endif /* CONFIG_SERIAL_KDP */
2113
2114void
2115kdp_init(void)
2116{
6d2010ae
A
2117 strlcpy(kdp_kernelversion_string, version, sizeof(kdp_kernelversion_string));
2118
2119 /* Relies on platform layer calling panic_init() before kdp_init() */
39236c6e 2120 if (kernel_uuid_string[0] != '\0') {
6d2010ae
A
2121 /*
2122 * Update kdp_kernelversion_string with our UUID
2123 * generated at link time.
2124 */
2125
2126 strlcat(kdp_kernelversion_string, "; UUID=", sizeof(kdp_kernelversion_string));
39236c6e 2127 strlcat(kdp_kernelversion_string, kernel_uuid_string, sizeof(kdp_kernelversion_string));
6d2010ae
A
2128 }
2129
316670eb
A
2130 debug_log_init();
2131
fe8ab488 2132#if defined(__x86_64__) || defined(__arm__) || defined(__arm64__)
316670eb
A
2133 if (vm_kernel_slide) {
2134 char KASLR_stext[19];
2135 strlcat(kdp_kernelversion_string, "; stext=", sizeof(kdp_kernelversion_string));
2136 snprintf(KASLR_stext, sizeof(KASLR_stext), "%p", (void *) vm_kernel_stext);
2137 strlcat(kdp_kernelversion_string, KASLR_stext, sizeof(kdp_kernelversion_string));
2138 }
2139#endif
2140
6d2010ae
A
2141 if (debug_boot_arg & DB_REBOOT_POST_CORE)
2142 kdp_flag |= REBOOT_POST_CORE;
7ddcb079
A
2143#if defined(__x86_64__)
2144 kdp_machine_init();
2145#endif
316670eb
A
2146
2147 kdp_timer_callout_init();
2148 kdp_crashdump_feature_mask = htonl(kdp_crashdump_feature_mask);
3e170ce0 2149 kdp_core_init();
316670eb 2150
593a1d5f
A
2151#if CONFIG_SERIAL_KDP
2152 char kdpname[80];
39236c6e
A
2153 struct kdp_in_addr ipaddr;
2154 struct kdp_ether_addr macaddr;
593a1d5f 2155
d190cdc3
A
2156 boolean_t kdp_match_name_found = PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname));
2157 boolean_t kdp_not_serial = kdp_match_name_found ? (strncmp(kdpname, "serial", sizeof(kdpname))) : TRUE;
2158
5ba3f43e
A
2159#if CONFIG_EMBEDDED
2160 //respect any custom debugger boot-args
2161 if(kdp_match_name_found && kdp_not_serial)
2162 return;
2163#else /* CONFIG_EMBEDDED */
39037602 2164 // serial must be explicitly requested
d190cdc3 2165 if(!kdp_match_name_found || kdp_not_serial)
39037602 2166 return;
5ba3f43e 2167#endif /* CONFIG_EMBEDDED */
b0d623f7 2168
5ba3f43e 2169#if CONFIG_EMBEDDED
d190cdc3 2170 if (kdp_not_serial && PE_consistent_debug_enabled() && debug_boot_arg) {
593a1d5f 2171 return;
39037602 2172 } else {
d190cdc3 2173 printf("Serial requested, consistent debug disabled or debug boot arg not present, configuring debugging over serial\n");
39037602 2174 }
5ba3f43e 2175#endif /* CONFIG_EMBEDDED */
39037602 2176
6d2010ae 2177 kprintf("Initializing serial KDP\n");
593a1d5f
A
2178
2179 kdp_register_callout(kdp_serial_callout, NULL);
6d2010ae 2180 kdp_register_link(NULL, kdp_serial_setmode);
593a1d5f
A
2181 kdp_register_send_receive(kdp_serial_send, kdp_serial_receive);
2182
2183 /* fake up an ip and mac for early serial debugging */
2184 macaddr.ether_addr_octet[0] = 's';
2185 macaddr.ether_addr_octet[1] = 'e';
2186 macaddr.ether_addr_octet[2] = 'r';
2187 macaddr.ether_addr_octet[3] = 'i';
2188 macaddr.ether_addr_octet[4] = 'a';
2189 macaddr.ether_addr_octet[5] = 'l';
6d2010ae 2190 ipaddr.s_addr = KDP_SERIAL_IPADDR;
593a1d5f 2191 kdp_set_ip_and_mac_addresses(&ipaddr, &macaddr);
6d2010ae 2192
593a1d5f
A
2193#endif /* CONFIG_SERIAL_KDP */
2194}
fe8ab488
A
2195
2196#else /* CONFIG_KDP_INTERACTIVE_DEBUGGING */
2197void
2198kdp_init(void)
2199{
2200}
2201#endif /* CONFIG_KDP_INTERACTIVE_DEBUGGING */
2202
5ba3f43e
A
2203#if !(MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING)
2204static struct kdp_ether_addr kdp_current_mac_address = {{0, 0, 0, 0, 0, 0}};
39037602 2205
5ba3f43e
A
2206/* XXX ugly forward declares to stop warnings */
2207void *kdp_get_interface(void);
2208void kdp_set_ip_and_mac_addresses(struct kdp_in_addr *, struct kdp_ether_addr *);
2209void kdp_set_gateway_mac(void *);
2210void kdp_set_interface(void *);
2211void kdp_register_send_receive(void *, void *);
2212void kdp_unregister_send_receive(void *, void *);
fe8ab488 2213
5ba3f43e
A
2214uint32_t kdp_stack_snapshot_bytes_traced(void);
2215
2216void
2217kdp_register_send_receive(__unused void *send, __unused void *receive)
2218{}
2219
2220void
2221kdp_unregister_send_receive(__unused void *send, __unused void *receive)
2222{}
2223
2224void *
2225kdp_get_interface( void)
39037602 2226{
5ba3f43e
A
2227 return(void *)0;
2228}
39037602 2229
5ba3f43e
A
2230unsigned int
2231kdp_get_ip_address(void )
2232{ return 0; }
2233
2234struct kdp_ether_addr
2235kdp_get_mac_addr(void)
2236{
2237 return kdp_current_mac_address;
39037602 2238}
5ba3f43e
A
2239
2240void
2241kdp_set_ip_and_mac_addresses(
2242 __unused struct kdp_in_addr *ipaddr,
2243 __unused struct kdp_ether_addr *macaddr)
2244{}
2245
2246void
2247kdp_set_gateway_mac(__unused void *gatewaymac)
2248{}
2249
2250void
2251kdp_set_interface(__unused void *ifp)
2252{}
2253
2254void kdp_register_link(__unused kdp_link_t link, __unused kdp_mode_t mode)
2255{}
2256
2257void kdp_unregister_link(__unused kdp_link_t link, __unused kdp_mode_t mode)
2258{}
2259
2260#endif /* !(MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING) */
39037602
A
2261
2262#if !CONFIG_KDP_INTERACTIVE_DEBUGGING
5ba3f43e
A
2263extern __attribute__((noreturn)) void panic_spin_forever(void);
2264
39037602 2265__attribute__((noreturn))
fe8ab488
A
2266void
2267kdp_raise_exception(
39037602
A
2268 __unused unsigned int exception,
2269 __unused unsigned int code,
2270 __unused unsigned int subcode,
2271 __unused void *saved_state
2272 )
2273#else
2274void
2275kdp_raise_exception(
2276 unsigned int exception,
2277 unsigned int code,
2278 unsigned int subcode,
2279 void *saved_state
2280 )
2281#endif
fe8ab488 2282{
5ba3f43e
A
2283#if CONFIG_EMBEDDED
2284 assert(PE_i_can_has_debugger(NULL));
2285#endif
fe8ab488 2286
39037602 2287#if CONFIG_KDP_INTERACTIVE_DEBUGGING
fe8ab488 2288
39037602 2289 kdp_debugger_loop(exception, code, subcode, saved_state);
fe8ab488 2290#else /* CONFIG_KDP_INTERACTIVE_DEBUGGING */
39037602
A
2291 assert(current_debugger != KDP_CUR_DB);
2292
39037602 2293 panic_spin_forever();
fe8ab488
A
2294#endif /* CONFIG_KDP_INTERACTIVE_DEBUGGING */
2295}