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