]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kdp/kdp_udp.c
xnu-1699.24.23.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;
7e4a7d39 1408 kdp.session_key = 0;
1c79356b
A
1409}
1410
55e303ae
A
1411struct corehdr *
1412create_panic_header(unsigned int request, const char *corename,
0c530ab8 1413 unsigned length, unsigned int block)
55e303ae 1414{
0c530ab8
A
1415 struct udpiphdr aligned_ui, *ui = &aligned_ui;
1416 struct ip aligned_ip, *ip = &aligned_ip;
1417 struct ether_header *eh;
1418 struct corehdr *coreh;
1419 const char *mode = "octet";
1420 char modelen = strlen(mode);
6d2010ae 1421
b0d623f7 1422 size_t fmask_size = sizeof(KDP_FEATURE_MASK_STRING) + sizeof(kdp_crashdump_feature_mask);
6d2010ae 1423
0c530ab8 1424 pkt.off = sizeof (struct ether_header);
b0d623f7
A
1425 pkt.len = (unsigned int)(length + ((request == KDP_WRQ) ? modelen + fmask_size : 0) +
1426 (corename ? strlen(corename): 0) + sizeof(struct corehdr));
55e303ae
A
1427
1428#if DO_ALIGN
0c530ab8 1429 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
55e303ae 1430#else
0c530ab8 1431 ui = (struct udpiphdr *)&pkt.data[pkt.off];
55e303ae 1432#endif
b0d623f7 1433 ui->ui_next = ui->ui_prev = 0;
0c530ab8
A
1434 ui->ui_x1 = 0;
1435 ui->ui_pr = IPPROTO_UDP;
1436 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
b0d623f7 1437 ui->ui_src.s_addr = (uint32_t)kdp_current_ip_address;
0c530ab8
A
1438 /* Already in network byte order via inet_aton() */
1439 ui->ui_dst.s_addr = panic_server_ip;
1440 ui->ui_sport = htons(panicd_port);
1441 ui->ui_dport = ((request == KDP_WRQ) ? htons(panicd_port) : last_panic_port);
1442 ui->ui_ulen = ui->ui_len;
1443 ui->ui_sum = 0;
55e303ae 1444#if DO_ALIGN
0c530ab8
A
1445 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
1446 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
55e303ae 1447#else
0c530ab8 1448 ip = (struct ip *)&pkt.data[pkt.off];
55e303ae 1449#endif
0c530ab8
A
1450 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
1451 ip->ip_v = IPVERSION;
1452 ip->ip_id = htons(ip_id++);
1453 ip->ip_hl = sizeof (struct ip) >> 2;
1454 ip->ip_ttl = udp_ttl;
1455 ip->ip_sum = 0;
1456 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
55e303ae 1457#if DO_ALIGN
0c530ab8 1458 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
55e303ae
A
1459#endif
1460
b0d623f7 1461 pkt.len += (unsigned int)sizeof (struct udpiphdr);
55e303ae 1462
b0d623f7 1463 pkt.off += (unsigned int)sizeof (struct udpiphdr);
55e303ae 1464
0c530ab8
A
1465 coreh = (struct corehdr *) &pkt.data[pkt.off];
1466 coreh->th_opcode = htons((u_short)request);
55e303ae 1467
0c530ab8
A
1468 if (request == KDP_WRQ)
1469 {
2d21ac55 1470 char *cp;
0c530ab8
A
1471
1472 cp = coreh->th_u.tu_rpl;
2d21ac55 1473 cp += strlcpy (cp, corename, KDP_MAXPACKET);
0c530ab8 1474 *cp++ = '\0';
2d21ac55 1475 cp += strlcpy (cp, mode, KDP_MAXPACKET - strlen(corename));
0c530ab8 1476 *cp++ = '\0';
b0d623f7
A
1477 cp += strlcpy(cp, KDP_FEATURE_MASK_STRING, sizeof(KDP_FEATURE_MASK_STRING));
1478 *cp++ = '\0'; /* Redundant */
1479 bcopy(&kdp_crashdump_feature_mask, cp, sizeof(kdp_crashdump_feature_mask));
6d2010ae
A
1480 kdp_crashdump_pkt_size = KDP_LARGE_CRASHDUMP_PKT_SIZE;
1481 PE_parse_boot_argn("kdp_crashdump_pkt_size", &kdp_crashdump_pkt_size, sizeof(kdp_crashdump_pkt_size));
1482 cp += sizeof(kdp_crashdump_feature_mask);
1483 *(uint32_t *)cp = htonl(kdp_crashdump_pkt_size);
0c530ab8
A
1484 }
1485 else
1486 {
1487 coreh->th_block = htonl((unsigned int) block);
1488 }
55e303ae 1489
b0d623f7
A
1490 pkt.off -= (unsigned int)sizeof (struct udpiphdr);
1491 pkt.off -= (unsigned int)sizeof (struct ether_header);
55e303ae 1492
0c530ab8
A
1493 eh = (struct ether_header *)&pkt.data[pkt.off];
1494 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
1495 enaddr_copy(&destination_mac, eh->ether_dhost);
1496 eh->ether_type = htons(ETHERTYPE_IP);
55e303ae 1497
b0d623f7 1498 pkt.len += (unsigned int)sizeof (struct ether_header);
0c530ab8 1499 return coreh;
55e303ae
A
1500}
1501
7e4a7d39
A
1502static int kdp_send_crashdump_seek(char *corename, uint64_t seek_off)
1503{
1504 int panic_error;
1505
7e4a7d39
A
1506 if (kdp_feature_large_crashdumps) {
1507 panic_error = kdp_send_crashdump_pkt(KDP_SEEK, corename,
1508 sizeof(seek_off),
1509 &seek_off);
6d2010ae 1510 } else {
7e4a7d39
A
1511 uint32_t off = (uint32_t) seek_off;
1512 panic_error = kdp_send_crashdump_pkt(KDP_SEEK, corename,
1513 sizeof(off), &off);
1514 }
1515
1516 if (panic_error < 0) {
1517 printf ("kdp_send_crashdump_pkt failed with error %d\n",
1518 panic_error);
1519 return panic_error;
1520 }
1521
1522 return 0;
1523}
1524
0c530ab8 1525int kdp_send_crashdump_data(unsigned int request, char *corename,
6d2010ae 1526 int64_t length, caddr_t txstart)
55e303ae 1527{
0c530ab8 1528 int panic_error = 0;
55e303ae 1529
7e4a7d39 1530 while (length > 0) {
6d2010ae
A
1531 uint64_t chunk = MIN(kdp_crashdump_pkt_size, length);
1532
7e4a7d39 1533 panic_error = kdp_send_crashdump_pkt(request, corename, chunk,
6d2010ae 1534 txstart);
7e4a7d39 1535 if (panic_error < 0) {
0c530ab8 1536 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
7e4a7d39 1537 return panic_error;
0c530ab8 1538 }
7e4a7d39 1539
7e4a7d39
A
1540 txstart += chunk;
1541 length -= chunk;
0c530ab8
A
1542 }
1543 return 0;
55e303ae
A
1544}
1545
6d2010ae
A
1546uint32_t kdp_crashdump_short_pkt;
1547
0c530ab8
A
1548int
1549kdp_send_crashdump_pkt(unsigned int request, char *corename,
b0d623f7 1550 uint64_t length, void *panic_data)
55e303ae 1551{
6d2010ae 1552 int poll_count;
0c530ab8 1553 struct corehdr *th = NULL;
6d2010ae
A
1554 char rretries, tretries;
1555
1556 if (kdp_dump_start_time == 0) {
1557 kdp_dump_start_time = mach_absolute_time();
1558 kdp_superblock_dump_start_time = kdp_dump_start_time;
1559 }
0c530ab8 1560
6d2010ae
A
1561 tretries = rretries = 0;
1562 poll_count = KDP_CRASHDUMP_POLL_COUNT;
0c530ab8 1563 pkt.off = pkt.len = 0;
0c530ab8
A
1564 if (request == KDP_WRQ) /* longer timeout for initial request */
1565 poll_count += 1000;
55e303ae
A
1566
1567TRANSMIT_RETRY:
0c530ab8 1568 tretries++;
8f6c56a5 1569
0c530ab8
A
1570 if (tretries >=15) {
1571/* The crashdump server is unreachable for some reason. This could be a network
1572 * issue or, if we've been especially unfortunate, we've hit Radar 2760413,
1573 * which is a long standing problem with the IOKit polled mode network driver
1574 * shim which can prevent transmits/receives completely.
1575 */
1576 printf ("Cannot contact panic server, timing out.\n");
1577 return (-3);
1578 }
8f6c56a5 1579
0c530ab8
A
1580 if (tretries > 2)
1581 printf("TX retry #%d ", tretries );
1582
b0d623f7 1583 th = create_panic_header(request, corename, (unsigned)length, panic_block);
21362eb3 1584
0c530ab8 1585 if (request == KDP_DATA) {
6d2010ae 1586 /* as all packets are kdp_crashdump_pkt_size in length, the last packet
7e4a7d39
A
1587 * may end up with trailing bits. make sure that those
1588 * bits aren't confusing. */
6d2010ae
A
1589 if (length < kdp_crashdump_pkt_size) {
1590 kdp_crashdump_short_pkt++;
1591 memset(th->th_data + length, 'Y',
1592 kdp_crashdump_pkt_size - (uint32_t) length);
1593 }
7e4a7d39 1594
6d2010ae
A
1595 if (!kdp_machine_vm_read((mach_vm_address_t)(uintptr_t)panic_data, (caddr_t) th->th_data, length)) {
1596 uintptr_t next_page = round_page((uintptr_t)panic_data);
1597 memset((caddr_t) th->th_data, 'X', (size_t)length);
1598 if ((next_page - ((uintptr_t) panic_data)) < length) {
1599 uint64_t resid = length - (next_page - (intptr_t) panic_data);
1600 if (!kdp_machine_vm_read((mach_vm_address_t)(uintptr_t)next_page, (caddr_t) th->th_data + (length - resid), resid)) {
1601 memset((caddr_t) th->th_data + (length - resid), 'X', (size_t)resid);
1602 }
1603 }
0c530ab8
A
1604 }
1605 }
1606 else if (request == KDP_SEEK) {
b0d623f7
A
1607 if (kdp_feature_large_crashdumps)
1608 *(uint64_t *) th->th_data = OSSwapHostToBigInt64((*(uint64_t *) panic_data));
1609 else
6d2010ae 1610 *(unsigned int *) th->th_data = htonl(*(unsigned int *) panic_data);
0c530ab8 1611 }
21362eb3 1612
6d2010ae 1613 kdp_send_data(&pkt.data[pkt.off], pkt.len);
6601e61a 1614
0c530ab8
A
1615 /* Listen for the ACK */
1616RECEIVE_RETRY:
1617 while (!pkt.input && flag_panic_dump_in_progress && poll_count) {
1618 kdp_poll();
1619 poll_count--;
1620 }
6601e61a 1621
0c530ab8 1622 if (pkt.input) {
55e303ae 1623
0c530ab8 1624 pkt.input = FALSE;
55e303ae 1625
0c530ab8 1626 th = (struct corehdr *) &pkt.data[pkt.off];
b0d623f7
A
1627 if (request == KDP_WRQ) {
1628 uint16_t opcode64 = ntohs(th->th_opcode);
1629 uint16_t features64 = (opcode64 & 0xFF00)>>8;
1630 if ((opcode64 & 0xFF) == KDP_ACK) {
1631 kdp_feature_large_crashdumps = features64 & KDP_FEATURE_LARGE_CRASHDUMPS;
6d2010ae
A
1632 if (features64 & KDP_FEATURE_LARGE_PKT_SIZE) {
1633 kdp_feature_large_pkt_size = 1;
1634 }
1635 else {
1636 kdp_feature_large_pkt_size = 0;
1637 kdp_crashdump_pkt_size = 512;
1638 }
b0d623f7
A
1639 printf("Protocol features: 0x%x\n", (uint32_t) features64);
1640 th->th_opcode = htons(KDP_ACK);
1641 }
1642 }
0c530ab8
A
1643 if (ntohs(th->th_opcode) == KDP_ACK && ntohl(th->th_block) == panic_block) {
1644 }
1645 else
1646 if (ntohs(th->th_opcode) == KDP_ERROR) {
1647 printf("Panic server returned error %d, retrying\n", ntohl(th->th_code));
1648 poll_count = 1000;
1649 goto TRANSMIT_RETRY;
1650 }
1651 else
1652 if (ntohl(th->th_block) == (panic_block - 1)) {
1653 printf("RX retry ");
1654 if (++rretries > 1)
1655 goto TRANSMIT_RETRY;
1656 else
1657 goto RECEIVE_RETRY;
1658 }
55e303ae 1659 }
0c530ab8
A
1660 else
1661 if (!flag_panic_dump_in_progress) /* we received a debugging packet, bail*/
1662 {
1663 printf("Received a debugger packet,transferring control to debugger\n");
1664 /* Configure that if not set ..*/
1665 kdp_flag |= DBG_POST_CORE;
1666 return (-2);
1667 }
1668 else /* We timed out */
1669 if (0 == poll_count) {
1670 poll_count = 1000;
1671 kdp_us_spin ((tretries%4) * panic_timeout); /* capped linear backoff */
1672 goto TRANSMIT_RETRY;
1673 }
6d2010ae
A
1674
1675 if (!(++panic_block % SBLOCKSZ)) {
1676 uint64_t ctime;
1677 kdb_printf_unbuffered(".");
1678 ctime = mach_absolute_time();
1679 kdp_superblock_dump_time = ctime - kdp_superblock_dump_start_time;
1680 kdp_superblock_dump_start_time = ctime;
1681 if (kdp_superblock_dump_time > kdp_max_superblock_dump_time)
1682 kdp_max_superblock_dump_time = kdp_superblock_dump_time;
1683 if (kdp_superblock_dump_time < kdp_min_superblock_dump_time)
1684 kdp_min_superblock_dump_time = kdp_superblock_dump_time;
1685 }
1686
1687 if (request == KDP_EOF) {
0c530ab8 1688 printf("\nTotal number of packets transmitted: %d\n", panic_block);
6d2010ae
A
1689 printf("Avg. superblock transfer abstime 0x%llx\n", ((mach_absolute_time() - kdp_dump_start_time) / panic_block) * SBLOCKSZ);
1690 printf("Minimum superblock transfer abstime: 0x%llx\n", kdp_min_superblock_dump_time);
1691 printf("Maximum superblock transfer abstime: 0x%llx\n", kdp_max_superblock_dump_time);
1692 }
0c530ab8 1693 return 1;
55e303ae
A
1694}
1695
55e303ae
A
1696static int
1697isdigit (char c)
1698{
1699 return ((c > 47) && (c < 58));
1700}
1701/* From user mode Libc - this ought to be in a library */
1702static char *
0c530ab8 1703strnstr(char *s, const char *find, size_t slen)
55e303ae
A
1704{
1705 char c, sc;
1706 size_t len;
1707
1708 if ((c = *find++) != '\0') {
1709 len = strlen(find);
1710 do {
1711 do {
1712 if ((sc = *s++) == '\0' || slen-- < 1)
1713 return (NULL);
1714 } while (sc != c);
1715 if (len > slen)
1716 return (NULL);
1717 } while (strncmp(s, find, len) != 0);
1718 s--;
1719 }
2d21ac55 1720 return (s);
55e303ae
A
1721}
1722
1723/* Horrid hack to extract xnu version if possible - a much cleaner approach
1724 * would be to have the integrator run a script which would copy the
1725 * xnu version into a string or an int somewhere at project submission
1726 * time - makes assumptions about sizeof(version), but will not fail if
1727 * it changes, but may be incorrect.
1728 */
0c530ab8
A
1729/* 2006: Incorporated a change from Darwin user P. Lovell to extract
1730 * the minor kernel version numbers from the version string.
1731 */
55e303ae
A
1732static int
1733kdp_get_xnu_version(char *versionbuf)
1734{
0c530ab8
A
1735 char *versionpos;
1736 char vstr[20];
1737 int retval = -1;
1738 char *vptr;
1739
2d21ac55 1740 strlcpy(vstr, "custom", 10);
060df5ea 1741 if (kdp_machine_vm_read((mach_vm_address_t)(uintptr_t)version, versionbuf, 128)) {
6d2010ae
A
1742 versionbuf[127] = '\0';
1743 versionpos = strnstr(versionbuf, "xnu-", 115);
cf7d32b8
A
1744 if (versionpos) {
1745 strncpy(vstr, versionpos, sizeof(vstr));
1746 vstr[sizeof(vstr)-1] = '\0';
1747 vptr = vstr + 4; /* Begin after "xnu-" */
1748 while (*vptr && (isdigit(*vptr) || *vptr == '.'))
1749 vptr++;
1750 *vptr = '\0';
1751 /* Remove trailing period, if any */
1752 if (*(--vptr) == '.')
0c530ab8 1753 *vptr = '\0';
cf7d32b8 1754 retval = 0;
0c530ab8
A
1755 }
1756 }
2d21ac55 1757 strlcpy(versionbuf, vstr, KDP_MAXPACKET);
0c530ab8 1758 return retval;
55e303ae 1759}
91447636 1760
7e4a7d39
A
1761void
1762kdp_set_dump_info(const uint32_t flags, const char *filename,
1763 const char *destipstr, const char *routeripstr,
1764 const uint32_t port)
1765{
1766 uint32_t cmd;
1767
1768 if (destipstr && (destipstr[0] != '\0')) {
1769 strlcpy(panicd_ip_str, destipstr, sizeof(panicd_ip_str));
1770 panicd_specified = 1;
1771 }
1772
1773 if (routeripstr && (routeripstr[0] != '\0')) {
1774 strlcpy(router_ip_str, routeripstr, sizeof(router_ip_str));
1775 router_specified = 1;
1776 }
1777
1778 if (filename && (filename[0] != '\0')) {
1779 strlcpy(corename_str, filename, sizeof(corename_str));
1780 corename_specified = TRUE;
1781 } else {
1782 corename_specified = FALSE;
1783 }
1784
1785 if (port)
1786 panicd_port = port;
1787
1788 /* on a disconnect, should we stay in KDP or not? */
1789 noresume_on_disconnect = (flags & KDP_DUMPINFO_NORESUME) ? 1 : 0;
1790
1791 if ((flags & KDP_DUMPINFO_DUMP) == 0)
1792 return;
1793
1794 /* the rest of the commands can modify kdp_flags */
1795 cmd = flags & KDP_DUMPINFO_MASK;
1796 if (cmd == KDP_DUMPINFO_DISABLE) {
1797 kdp_flag &= ~KDP_PANIC_DUMP_ENABLED;
1798 panicd_specified = 0;
1799 kdp_trigger_core_dump = 0;
1800 return;
1801 }
1802
1803 kdp_flag &= ~REBOOT_POST_CORE;
1804 if (flags & KDP_DUMPINFO_REBOOT)
1805 kdp_flag |= REBOOT_POST_CORE;
1806
1807 kdp_flag &= ~PANIC_LOG_DUMP;
1808 if (cmd == KDP_DUMPINFO_PANICLOG)
1809 kdp_flag |= PANIC_LOG_DUMP;
1810
1811 kdp_flag &= ~SYSTEM_LOG_DUMP;
1812 if (cmd == KDP_DUMPINFO_SYSTEMLOG)
1813 kdp_flag |= SYSTEM_LOG_DUMP;
1814
1815 /* trigger a dump */
1816 kdp_flag |= DBG_POST_CORE;
1817
1818 flag_dont_abort_panic_dump = (flags & KDP_DUMPINFO_NOINTR) ?
1819 TRUE : FALSE;
1820
1821 reattach_wait = 1;
1822 logPanicDataToScreen = 1;
1823 disableConsoleOutput = 0;
1824 disable_debug_output = 0;
1825 kdp_trigger_core_dump = 1;
1826}
1827
1828void
1829kdp_get_dump_info(uint32_t *flags, char *filename, char *destipstr,
1830 char *routeripstr, uint32_t *port)
1831{
1832 if (destipstr) {
1833 if (panicd_specified)
1834 strlcpy(destipstr, panicd_ip_str,
1835 sizeof(panicd_ip_str));
1836 else
1837 destipstr[0] = '\0';
1838 }
1839
1840 if (routeripstr) {
1841 if (router_specified)
1842 strlcpy(routeripstr, router_ip_str,
1843 sizeof(router_ip_str));
1844 else
1845 routeripstr[0] = '\0';
1846 }
1847
1848 if (filename) {
1849 if (corename_specified)
1850 strlcpy(filename, corename_str,
1851 sizeof(corename_str));
1852 else
1853 filename[0] = '\0';
1854
1855 }
1856
1857 if (port)
1858 *port = panicd_port;
1859
1860 if (flags) {
1861 *flags = 0;
1862 if (!panicd_specified)
1863 *flags |= KDP_DUMPINFO_DISABLE;
1864 else if (kdp_flag & PANIC_LOG_DUMP)
1865 *flags |= KDP_DUMPINFO_PANICLOG;
1866 else
1867 *flags |= KDP_DUMPINFO_CORE;
1868
1869 if (noresume_on_disconnect)
1870 *flags |= KDP_DUMPINFO_NORESUME;
1871 }
1872}
1873
1874
55e303ae
A
1875/* Primary dispatch routine for the system dump */
1876void
2d21ac55 1877kdp_panic_dump(void)
55e303ae 1878{
0c530ab8
A
1879 char coreprefix[10];
1880 int panic_error;
55e303ae 1881
6d2010ae 1882 uint64_t abstime;
b0d623f7 1883 uint32_t current_ip = ntohl((uint32_t)kdp_current_ip_address);
c0fea474 1884
0c530ab8 1885 if (flag_panic_dump_in_progress) {
6d2010ae 1886 kdb_printf("System dump aborted.\n");
0c530ab8
A
1887 goto panic_dump_exit;
1888 }
1889
1890 printf("Entering system dump routine\n");
060df5ea
A
1891
1892 if (!kdp_en_recv_pkt || !kdp_en_send_pkt) {
6d2010ae
A
1893 kdb_printf("Error: No transport device registered for kernel crashdump\n");
1894 return;
060df5ea
A
1895 }
1896
0c530ab8 1897 if (!panicd_specified) {
6d2010ae 1898 kdb_printf("A dump server was not specified in the boot-args, terminating kernel core dump.\n");
0c530ab8
A
1899 goto panic_dump_exit;
1900 }
8f6c56a5 1901
0c530ab8
A
1902 flag_panic_dump_in_progress = TRUE;
1903 not_in_kdp = 0;
55e303ae 1904
0c530ab8
A
1905 if (pkt.input)
1906 kdp_panic("kdp_panic_dump: unexpected pending input packet");
55e303ae 1907
0c530ab8 1908 kdp_get_xnu_version((char *) &pkt.data[0]);
55e303ae 1909
7e4a7d39
A
1910 if (!corename_specified) {
1911 /* Panic log bit takes precedence over core dump bit */
1912 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP))
1913 strlcpy(coreprefix, "paniclog", sizeof(coreprefix));
1914 else if (kdp_flag & SYSTEM_LOG_DUMP)
1915 strlcpy(coreprefix, "systemlog", sizeof(coreprefix));
1916 else
1917 strlcpy(coreprefix, "core", sizeof(coreprefix));
55e303ae 1918
7e4a7d39
A
1919 abstime = mach_absolute_time();
1920 pkt.data[20] = '\0';
1921 snprintf (corename_str, sizeof(corename_str), "%s-%s-%d.%d.%d.%d-%x",
1922 coreprefix, &pkt.data[0],
1923 (current_ip & 0xff000000) >> 24,
1924 (current_ip & 0xff0000) >> 16,
1925 (current_ip & 0xff00) >> 8,
1926 (current_ip & 0xff),
1927 (unsigned int) (abstime & 0xffffffff));
1928 }
0c530ab8
A
1929
1930 if (0 == inet_aton(panicd_ip_str, (struct in_addr *) &panic_server_ip)) {
6d2010ae 1931 kdb_printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str);
0c530ab8
A
1932 }
1933 else
6d2010ae 1934 kdb_printf("Attempting connection to panic server configured at IP %s, port %d\n", panicd_ip_str, panicd_port);
4452a7af 1935
0c530ab8
A
1936 destination_mac = router_mac;
1937
1938 if (kdp_arp_resolve(panic_server_ip, &temp_mac)) {
6d2010ae 1939 kdb_printf("Resolved %s's (or proxy's) link level address\n", panicd_ip_str);
0c530ab8 1940 destination_mac = temp_mac;
55e303ae 1941 }
0c530ab8
A
1942 else {
1943 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
1944 if (router_specified) {
1945 if (0 == inet_aton(router_ip_str, (struct in_addr *) &parsed_router_ip))
6d2010ae 1946 kdb_printf("inet_aton() failed interpreting %s as an IP\n", router_ip_str);
0c530ab8
A
1947 else {
1948 router_ip = parsed_router_ip;
1949 if (kdp_arp_resolve(router_ip, &temp_mac)) {
1950 destination_mac = temp_mac;
6d2010ae 1951 kdb_printf("Routing through specified router IP %s (%d)\n", router_ip_str, router_ip);
0c530ab8
A
1952 }
1953 }
1954 }
55e303ae 1955 }
91447636 1956
0c530ab8 1957 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
5d5c5d0d 1958
6d2010ae 1959 kdb_printf("Transmitting packets to link level address: %02x:%02x:%02x:%02x:%02x:%02x\n",
0c530ab8
A
1960 destination_mac.ether_addr_octet[0] & 0xff,
1961 destination_mac.ether_addr_octet[1] & 0xff,
1962 destination_mac.ether_addr_octet[2] & 0xff,
1963 destination_mac.ether_addr_octet[3] & 0xff,
1964 destination_mac.ether_addr_octet[4] & 0xff,
1965 destination_mac.ether_addr_octet[5] & 0xff);
89b3af67 1966
6d2010ae
A
1967 kdb_printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map));
1968 kdb_printf("Sending write request for %s\n", corename_str);
4452a7af 1969
7e4a7d39 1970 if ((panic_error = kdp_send_crashdump_pkt(KDP_WRQ, corename_str, 0 , NULL)) < 0) {
6d2010ae 1971 kdb_printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
0c530ab8
A
1972 goto panic_dump_exit;
1973 }
1974
1975 /* Just the panic log requested */
1976 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP)) {
6d2010ae 1977 kdb_printf_unbuffered("Transmitting panic log, please wait: ");
7e4a7d39
A
1978 kdp_send_crashdump_data(KDP_DATA, corename_str,
1979 debug_buf_ptr - debug_buf,
1980 debug_buf);
0c530ab8
A
1981 kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
1982 printf("Please file a bug report on this panic, if possible.\n");
1983 goto panic_dump_exit;
1984 }
55e303ae 1985
7e4a7d39
A
1986 /* maybe we wanted the systemlog */
1987 if (kdp_flag & SYSTEM_LOG_DUMP) {
1988 long start_off = msgbufp->msg_bufx;
1989 long len;
1990
6d2010ae 1991 kdb_printf_unbuffered("Transmitting system log, please wait: ");
7e4a7d39
A
1992 if (start_off >= msgbufp->msg_bufr) {
1993 len = msgbufp->msg_size - start_off;
1994 kdp_send_crashdump_data(KDP_DATA, corename_str, len,
1995 msgbufp->msg_bufc + start_off);
7e4a7d39 1996 /* seek to remove trailing bytes */
6d2010ae 1997 kdp_send_crashdump_seek(corename_str, len);
7e4a7d39
A
1998 start_off = 0;
1999 }
2000
2001 if (start_off != msgbufp->msg_bufr) {
2002 len = msgbufp->msg_bufr - start_off;
2003 kdp_send_crashdump_data(KDP_DATA, corename_str, len,
2004 msgbufp->msg_bufc + start_off);
2005 }
2006
2007 kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
2008 goto panic_dump_exit;
2009 }
2010
0c530ab8
A
2011 /* We want a core dump if we're here */
2012 kern_dump();
7e4a7d39 2013
55e303ae 2014panic_dump_exit:
0c530ab8
A
2015 abort_panic_transfer();
2016 pkt.input = FALSE;
2017 pkt.len = 0;
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;
593a1d5f
A
2125#if CONFIG_SERIAL_KDP
2126 char kdpname[80];
2127 struct in_addr ipaddr;
2128 struct ether_addr macaddr;
2129
b0d623f7 2130
593a1d5f
A
2131#if CONFIG_EMBEDDED
2132 //serial will be the debugger, unless match name is explicitly provided, and it's not "serial"
2133 if(PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname)) && strncmp(kdpname, "serial", sizeof(kdpname)) != 0)
2134 return;
2135#else
2136 // serial must be explicitly requested
2137 if(!PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname)) || strncmp(kdpname, "serial", sizeof(kdpname)) != 0)
2138 return;
2139#endif
2140
6d2010ae 2141 kprintf("Initializing serial KDP\n");
593a1d5f
A
2142
2143 kdp_register_callout(kdp_serial_callout, NULL);
6d2010ae 2144 kdp_register_link(NULL, kdp_serial_setmode);
593a1d5f
A
2145 kdp_register_send_receive(kdp_serial_send, kdp_serial_receive);
2146
2147 /* fake up an ip and mac for early serial debugging */
2148 macaddr.ether_addr_octet[0] = 's';
2149 macaddr.ether_addr_octet[1] = 'e';
2150 macaddr.ether_addr_octet[2] = 'r';
2151 macaddr.ether_addr_octet[3] = 'i';
2152 macaddr.ether_addr_octet[4] = 'a';
2153 macaddr.ether_addr_octet[5] = 'l';
6d2010ae 2154 ipaddr.s_addr = KDP_SERIAL_IPADDR;
593a1d5f 2155 kdp_set_ip_and_mac_addresses(&ipaddr, &macaddr);
6d2010ae 2156
593a1d5f
A
2157#endif /* CONFIG_SERIAL_KDP */
2158}