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