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