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