xref: /illumos-gate/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c (revision 17a5fa85fe0c34b1146222e40a80b42f2aae8500)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/termios.h>
29 #include <sys/promif.h>
30 #ifdef sun4v
31 #include <sys/promif_impl.h>
32 #endif
33 #include <unistd.h>
34 #include <string.h>
35 #include <stdlib.h>
36 
37 #include <kmdb/kmdb_promif_impl.h>
38 #include <kmdb/kmdb_kdi.h>
39 #include <kmdb/kmdb_dpi.h>
40 #include <mdb/mdb_debug.h>
41 #include <mdb/mdb_err.h>
42 #include <mdb/mdb_frame.h>
43 #include <mdb/mdb_string.h>
44 #include <mdb/mdb.h>
45 
46 #define	KMDB_PROM_DEF_CONS_MODE	"9600,n,1,-,-"
47 
48 #define	KMDB_PROM_READBUF_SIZE	1024
49 
50 static char kmdb_prom_readbuf[KMDB_PROM_READBUF_SIZE];
51 static int kmdb_prom_readbuf_head;
52 static int kmdb_prom_readbuf_tail;
53 
54 static int
55 kmdb_prom_getchar(int wait)
56 {
57 	struct cons_polledio *pio = mdb.m_pio;
58 	uintptr_t ischar;
59 	uintptr_t getchar;
60 	uintptr_t arg;
61 
62 	if (pio == NULL || pio->cons_polledio_getchar == NULL) {
63 		int c;
64 		while ((c = prom_mayget()) == -1) {
65 			if (!wait)
66 				return (-1);
67 		}
68 		return (c);
69 	}
70 
71 	ischar = (uintptr_t)pio->cons_polledio_ischar;
72 	getchar = (uintptr_t)pio->cons_polledio_getchar;
73 	arg = (uintptr_t)pio->cons_polledio_argument;
74 
75 	if (!wait && ischar != 0 && !kmdb_dpi_call(ischar, 1, &arg))
76 		return (-1);
77 
78 	return ((int)kmdb_dpi_call(getchar, 1, &arg));
79 }
80 
81 static ssize_t
82 kmdb_prom_polled_write(caddr_t buf, size_t len)
83 {
84 	uintptr_t args[2];
85 	int i;
86 
87 	args[0] = (uintptr_t)mdb.m_pio->cons_polledio_argument;
88 
89 	for (i = 0; i < len; i++) {
90 		args[1] = *buf++;
91 		(void) kmdb_dpi_call(
92 		    (uintptr_t)mdb.m_pio->cons_polledio_putchar, 2, args);
93 	}
94 
95 	return (len);
96 }
97 
98 static ssize_t
99 kmdb_prom_reader(caddr_t buf, size_t len, int wait)
100 {
101 	int nread = 0;
102 	int c;
103 
104 	while (nread < len) {
105 		if ((c = kmdb_prom_getchar(wait)) == -1)
106 			break;
107 
108 		*buf++ = (char)c;
109 		nread++;
110 		wait = 0;
111 	}
112 
113 	return (nread);
114 }
115 
116 static ssize_t
117 kmdb_prom_writer(caddr_t buf, size_t len)
118 {
119 	if (mdb.m_pio != NULL && mdb.m_pio->cons_polledio_putchar != NULL)
120 		return (kmdb_prom_polled_write(buf, len));
121 
122 	return (kmdb_prom_obp_writer(buf, len));
123 }
124 
125 /*
126  * Due to the nature of kmdb, we don't have signals.  This prevents us from
127  * receiving asynchronous notification when the user would like to abort active
128  * dcmds.  Whereas mdb can simply declare a SIGINT handler, we must
129  * occasionally poll the input stream, looking for pending ^C characters.  To
130  * give the illusion of asynchronous interrupt delivery, this polling is
131  * triggered from several commonly-used functions, such as kmdb_prom_write and
132  * the *read and *write target ops.  When an interrupt check is triggered, we
133  * read through pending input, looking for interrupt characters.  If we find
134  * one, we deliver an interrupt immediately.
135  *
136  * In a read context, we can deliver the interrupt character directly back to
137  * the termio handler rather than raising an interrupt.
138  *
139  * OBP doesn't have an "unget" facility.  Any character read for interrupt
140  * checking is gone forever, unless we save it.  Loss of these characters
141  * would prevent us from supporting typeahead.  We like typeahead, so we're
142  * going to save characters gathered during interrupt checking.  As with
143  * ungetc(3c), however, we can only store a finite number of characters in
144  * our typeahead buffer.  Characters read beyond that will be silently dropped
145  * after they undergo interrupt processing.
146  *
147  * The typeahead facility is implemented as a ring buffer, stored in
148  * kmdb_prom_readbuf.
149  */
150 static size_t
151 kmdb_prom_drain_readbuf(void *buf, size_t len)
152 {
153 	size_t n, tailread;
154 
155 	/*
156 	 * If head > tail, life is easy - we can simply read as much as we need
157 	 * in one gulp.
158 	 */
159 	if (kmdb_prom_readbuf_head > kmdb_prom_readbuf_tail) {
160 		n = MIN(kmdb_prom_readbuf_head - kmdb_prom_readbuf_tail, len);
161 		bcopy(kmdb_prom_readbuf + kmdb_prom_readbuf_tail, buf, n);
162 		kmdb_prom_readbuf_tail += n;
163 		return (n);
164 
165 	} else if (kmdb_prom_readbuf_head == kmdb_prom_readbuf_tail) {
166 		return (0);
167 	}
168 
169 	/*
170 	 * The consumable slots wrap around zero (there are slots from tail to
171 	 * zero, and from zero to head).  We have to read them in two parts.
172 	 */
173 	n = MIN(KMDB_PROM_READBUF_SIZE - kmdb_prom_readbuf_tail, len);
174 	bcopy(kmdb_prom_readbuf + kmdb_prom_readbuf_tail, buf, n);
175 	kmdb_prom_readbuf_tail = (kmdb_prom_readbuf_tail + n) %
176 	    KMDB_PROM_READBUF_SIZE;
177 
178 	if (n == len) {
179 		/*
180 		 * We filled the passed buffer from the first part, so there's
181 		 * no need to read the second.
182 		 */
183 		return (n);
184 	} else {
185 		tailread = n;
186 	}
187 
188 	n = MIN(kmdb_prom_readbuf_head, len - tailread);
189 	buf = (void *)((uintptr_t)buf + tailread);
190 	bcopy(kmdb_prom_readbuf, buf, n);
191 
192 	kmdb_prom_readbuf_tail = (kmdb_prom_readbuf_tail + n) %
193 	    KMDB_PROM_READBUF_SIZE;
194 
195 	return (tailread + n);
196 }
197 
198 static void
199 check_int(char *buf, size_t len)
200 {
201 	int i;
202 
203 	for (i = 0; i < len; i++) {
204 		if (buf[i] == CTRL('c')) {
205 			kmdb_prom_readbuf_tail = kmdb_prom_readbuf_head;
206 			if (mdb.m_intr == 0)
207 				longjmp(mdb.m_frame->f_pcb, MDB_ERR_SIGINT);
208 			else
209 				mdb.m_pend++;
210 		}
211 	}
212 }
213 
214 /*
215  * Attempt to refill the ring buffer from the input stream.  This called from
216  * two contexts:
217  *
218  * Direct read: read the input into our buffer until input is exhausted, or the
219  * buffer is full.
220  *
221  * Interrupt check: called 'asynchronously' from the normal read routines; read
222  * the input into our buffer until it is exhausted, discarding input if the
223  * buffer is full.  In this case we look ahead for any interrupt characters,
224  * delivering an interrupt directly if we find one.
225  */
226 static void
227 kmdb_prom_fill_readbuf(int check_for_int, int wait)
228 {
229 	int oldhead, left, n;
230 
231 	/*
232 	 * Calculate the number of slots left before we wrap around to the
233 	 * beginning again.
234 	 */
235 	left = KMDB_PROM_READBUF_SIZE - kmdb_prom_readbuf_head;
236 	if (kmdb_prom_readbuf_tail == 0)
237 		left--;
238 
239 	if (kmdb_prom_readbuf_head == kmdb_prom_readbuf_tail ||
240 	    (kmdb_prom_readbuf_head > kmdb_prom_readbuf_tail && left > 0)) {
241 		/*
242 		 * head > tail, so we have to read in two parts - the slots
243 		 * from head until we wrap back around to zero, and the ones
244 		 * from zero to tail.  We handle the first part here, and let
245 		 * the common code handle the second.
246 		 */
247 		if ((n = kmdb_prom_reader(kmdb_prom_readbuf +
248 		    kmdb_prom_readbuf_head, left, wait)) <= 0)
249 			return;
250 
251 		oldhead = kmdb_prom_readbuf_head;
252 		kmdb_prom_readbuf_head = (kmdb_prom_readbuf_head + n) %
253 		    KMDB_PROM_READBUF_SIZE;
254 
255 		if (check_for_int)
256 			check_int(kmdb_prom_readbuf + oldhead, n);
257 
258 		if (n != left)
259 			return;
260 	}
261 
262 	left = kmdb_prom_readbuf_tail - kmdb_prom_readbuf_head - 1;
263 	if (left > 0) {
264 		if ((n = kmdb_prom_reader(kmdb_prom_readbuf +
265 		    kmdb_prom_readbuf_head, left, wait)) <= 0)
266 			return;
267 
268 		oldhead = kmdb_prom_readbuf_head;
269 		kmdb_prom_readbuf_head = (kmdb_prom_readbuf_head + n) %
270 		    KMDB_PROM_READBUF_SIZE;
271 
272 		if (check_for_int)
273 			check_int(kmdb_prom_readbuf + oldhead, n);
274 
275 		if (n != left)
276 			return;
277 	}
278 
279 	if (check_for_int) {
280 		char c;
281 
282 		while (kmdb_prom_reader(&c, 1, 0) == 1)
283 			check_int(&c, 1);
284 	}
285 }
286 
287 void
288 kmdb_prom_check_interrupt(void)
289 {
290 	kmdb_prom_fill_readbuf(1, 0);
291 }
292 
293 /*
294  * OBP reads are always non-blocking.  If there are characters available,
295  * we'll return as many as we can.  If nothing is available, we'll spin
296  * until one shows up.
297  */
298 ssize_t
299 kmdb_prom_read(void *buf, size_t len, struct termios *tio)
300 {
301 	size_t totread = 0;
302 	size_t thisread;
303 	char *c = (char *)buf;
304 	int wait = 1;
305 
306 	for (;;) {
307 		kmdb_prom_fill_readbuf(0, wait);
308 		thisread = kmdb_prom_drain_readbuf(c, len);
309 		len -= thisread;
310 		totread += thisread;
311 		c += thisread;
312 
313 		/* wait until something shows up */
314 		if (totread == 0)
315 			continue;
316 
317 		wait = 0;
318 
319 		/*
320 		 * We're done if we've exhausted available input or if we've
321 		 * filled the provided buffer.
322 		 */
323 		if (len == 0 || thisread == 0)
324 			break;
325 	}
326 
327 	if (tio->c_iflag & ICRNL) {
328 		char *cbuf = buf;
329 		int i;
330 
331 		for (i = 0; i < totread; i++) {
332 			if (cbuf[i] == '\r')
333 				cbuf[i] = '\n';
334 		}
335 	}
336 
337 	if (tio->c_lflag & ECHO)
338 		(void) kmdb_prom_write(buf, totread, tio);
339 
340 	return (totread);
341 }
342 
343 /*ARGSUSED*/
344 ssize_t
345 kmdb_prom_write(const void *bufp, size_t len, struct termios *tio)
346 {
347 	caddr_t buf = (caddr_t)bufp;
348 	size_t left = len;
349 	char *nl = "\r\n";
350 	char *c;
351 
352 	kmdb_prom_check_interrupt();
353 
354 	if (!(tio->c_oflag & ONLCR))
355 		return (kmdb_prom_writer(buf, left));
356 
357 	/* translate every \n into \r\n */
358 	while ((c = strnchr(buf, '\n', left)) != NULL) {
359 		if (c != buf) {
360 			size_t sz = (size_t)(c - buf);
361 			(void) kmdb_prom_writer(buf, sz);
362 			left -= sz;
363 		}
364 
365 		buf = c + 1;
366 		left--;
367 
368 		(void) kmdb_prom_writer(nl, 2);
369 	}
370 
371 	if (*buf != '\0')
372 		(void) kmdb_prom_writer(buf, left);
373 
374 	return (len);
375 }
376 
377 static char *
378 kmdb_get_ttyio_mode(kmdb_auxv_t *kav, char *devname)
379 {
380 	char *modepname, *modepval;
381 
382 	modepname = mdb_alloc(strlen(devname) + 5 + 1, UM_SLEEP);
383 	(void) strcpy(modepname, devname);
384 	(void) strcat(modepname, "-mode");
385 
386 	modepval = kmdb_prom_get_ddi_prop(kav, modepname);
387 
388 	strfree(modepname);
389 
390 	return (modepval);
391 }
392 
393 static int
394 termios_setispeed(struct termios *tip, speed_t s)
395 {
396 	if (s > (2 * CBAUD + 1))
397 		return (-1);
398 
399 	if ((s << IBSHIFT) > CIBAUD) {
400 		tip->c_cflag |= CIBAUDEXT;
401 		s -= ((CIBAUD >> IBSHIFT) + 1);
402 	} else
403 		tip->c_cflag &= ~CIBAUDEXT;
404 
405 	tip->c_cflag = (tip->c_cflag & ~CIBAUD) | ((s << IBSHIFT) & CIBAUD);
406 
407 	return (0);
408 }
409 
410 static int
411 termios_setospeed(struct termios *tip, speed_t s)
412 {
413 	if (s > (2 * CBAUD + 1))
414 		return (-1);
415 
416 	if (s > CBAUD) {
417 		tip->c_cflag |= CBAUDEXT;
418 		s -= (CBAUD + 1);
419 	} else
420 		tip->c_cflag &= ~CBAUDEXT;
421 
422 	tip->c_cflag = (tip->c_cflag & ~CBAUD) | (s & CBAUD);
423 
424 	return (0);
425 }
426 
427 static int
428 kmdb_parse_mode(const char *mode, struct termios *tip, int in)
429 {
430 	static const uint_t baudmap[] = {
431 		0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
432 		1800, 2400, 4800, 9600, 19200, 38400, 57600,
433 		76800, 115200, 153600, 230400, 307200, 460800, 921600
434 	};
435 	static const uint_t bitsmap[] = { CS6, CS6, CS7, CS8 };
436 	char *m = strdup(mode);
437 	char *w;
438 	int rc = -1;
439 	speed_t speed;
440 	int baud, i;
441 
442 	/*
443 	 * termios supports different baud rates and flow control types for
444 	 * input and output, but it requires character width, parity, and stop
445 	 * bits to be equal in input and output.  obp allows them to be
446 	 * different, but we're going to (silently) assume that nobody will use
447 	 * it that way.
448 	 */
449 
450 	/* baud rate - see baudmap above */
451 	if ((w = strtok(m, ",")) == NULL)
452 		goto parse_mode_bail;
453 
454 	baud = strtol(w, NULL, 10);
455 	speed = 0;
456 	for (i = 0; i < sizeof (baudmap) / sizeof (baudmap[0]); i++) {
457 		if (baudmap[i] == baud) {
458 			speed = i;
459 			break;
460 		}
461 	}
462 	if (speed == 0)
463 		goto parse_mode_bail;
464 
465 	if (in == 1)
466 		(void) termios_setispeed(tip, speed);
467 	else
468 		(void) termios_setospeed(tip, speed);
469 
470 	/* character width (bits) - 5, 6, 7, or 8 */
471 	if ((w = strtok(NULL, ",")) == NULL || strlen(w) != 1 || *w < '5' ||
472 	    *w > '8')
473 		goto parse_mode_bail;
474 	tip->c_cflag = (tip->c_cflag & ~CSIZE) | bitsmap[*w - '5'];
475 
476 	/* parity - `n' (none), `e' (even), or `o' (odd) */
477 	if ((w = strtok(NULL, ",")) == NULL || strlen(w) != 1 ||
478 	    strchr("neo", *w) == NULL)
479 		goto parse_mode_bail;
480 
481 	tip->c_cflag = (tip->c_cflag & ~(PARENB|PARODD));
482 	switch (*w) {
483 	case 'n':
484 		/* nothing */
485 		break;
486 	case 'e':
487 		tip->c_cflag |= PARENB;
488 		break;
489 	case 'o':
490 		tip->c_cflag |= PARENB|PARODD;
491 		break;
492 	}
493 
494 	/*
495 	 * stop bits - 1, or 2.  obp can, in theory, support 1.5 bits,
496 	 * but we can't.  how many angels can dance on half of a bit?
497 	 */
498 	if ((w = strtok(NULL, ",")) == NULL || strlen(w) != 1 || *w < '1' ||
499 	    *w > '2')
500 		goto parse_mode_bail;
501 
502 	if (*w == '1')
503 		tip->c_cflag &= ~CSTOPB;
504 	else
505 		tip->c_cflag |= CSTOPB;
506 
507 	/* flow control - `-' (none), `h' (h/w), or `s' (s/w - XON/XOFF) */
508 	if ((w = strtok(NULL, ",")) == NULL || strlen(w) != 1 ||
509 	    strchr("-hs", *w) == NULL)
510 		goto parse_mode_bail;
511 
512 	tip->c_cflag &= ~(CRTSXOFF|CRTSCTS);
513 	tip->c_iflag &= ~(IXON|IXANY|IXOFF);
514 
515 	switch (*w) {
516 	case 'h':
517 		tip->c_cflag |= (in == 1 ? CRTSXOFF : CRTSCTS);
518 		break;
519 
520 	case 's':
521 		tip->c_iflag |= (in == 1 ? IXOFF : IXON);
522 		break;
523 	}
524 
525 	rc = 0;
526 
527 parse_mode_bail:
528 	strfree(m);
529 
530 	return (rc);
531 }
532 
533 #ifdef __sparc
534 #define	ATTACHED_TERM_TYPE	"sun"
535 #else
536 #define	ATTACHED_TERM_TYPE	"sun-color"
537 #endif
538 
539 static void
540 kmdb_prom_term_init(kmdb_auxv_t *kav, kmdb_promif_t *pif)
541 {
542 	const char ccs[NCCS] = { 0x03, 0x1c, 0x08, 0x15, 0x04, 0x00, 0x00,
543 	    0x00, 0x11, 0x13, 0x1a, 0x19, 0x12, 0x0f, 0x17, 0x16 };
544 	char *conin = NULL, *conout = NULL;
545 
546 	if (kmdb_prom_stdout_is_framebuffer(kav)) {
547 		struct winsize *wsz = &pif->pif_wsz;
548 
549 		/* Set default dimensions. */
550 		wsz->ws_row = KMDB_PIF_WINSIZE_ROWS;
551 		wsz->ws_col = KMDB_PIF_WINSIZE_COLS;
552 
553 		kmdb_prom_get_tem_size(kav, &wsz->ws_row, &wsz->ws_col);
554 		pif->pif_oterm = ATTACHED_TERM_TYPE;
555 	}
556 
557 	bzero(&pif->pif_tios, sizeof (struct termios));
558 
559 	/* output device characteristics */
560 	if ((conout = kmdb_prom_get_ddi_prop(kav, "output-device")) ==
561 	    NULL || strcmp(conout, "screen") == 0) {
562 		(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
563 		    &pif->pif_tios, 0);
564 	} else if (*conout == '/') {
565 		/*
566 		 * We're not going to be able to get characteristics for a
567 		 * device that's specified as a path, so don't even try.
568 		 * Conveniently, this allows us to avoid chattering on
569 		 * Serengetis.
570 		 */
571 		(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
572 		    &pif->pif_tios, 0);
573 	} else {
574 		char *mode = kmdb_get_ttyio_mode(kav, conout);
575 
576 #ifdef __sparc
577 		/*
578 		 * Some platforms (Starfire) define a value of `ttya' for
579 		 * output-device, but neglect to provide a specific property
580 		 * with the characteristics.  We'll provide a default value.
581 		 */
582 		if (mode == NULL && strcmp(conout, "ttya") == 0) {
583 			(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
584 			    &pif->pif_tios, 0);
585 		} else
586 #endif
587 		{
588 			if (mode == NULL || kmdb_parse_mode(mode,
589 			    &pif->pif_tios, 0) < 0) {
590 				/*
591 				 * Either we couldn't retrieve the
592 				 * characteristics for this console, or they
593 				 * weren't parseable.  The console hasn't been
594 				 * set up yet, so we can't warn.  We'll have to
595 				 * silently fall back to the default
596 				 * characteristics.
597 				 */
598 				(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
599 				    &pif->pif_tios, 0);
600 			}
601 		}
602 
603 		if (mode != NULL)
604 			kmdb_prom_free_ddi_prop(mode);
605 	}
606 
607 	/* input device characteristics */
608 	if ((conin = kmdb_prom_get_ddi_prop(kav, "input-device")) == NULL ||
609 	    strcmp(conin, "keyboard") == 0) {
610 		(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
611 		    &pif->pif_tios, 1);
612 	} else if (*conin == '/') {
613 		/* See similar case in output-device above */
614 		(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
615 		    &pif->pif_tios, 1);
616 	} else {
617 		char *mode = kmdb_get_ttyio_mode(kav, conin);
618 
619 #ifdef __sparc
620 		/*
621 		 * Some platforms (Starfire) define a value of `ttya' for
622 		 * input-device, but neglect to provide a specific property
623 		 * with the characteristics.  We'll provide a default value.
624 		 */
625 		if (mode == NULL && strcmp(conin, "ttya") == 0) {
626 			(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
627 			    &pif->pif_tios, 1);
628 		} else
629 #endif
630 		{
631 			if (mode == NULL || kmdb_parse_mode(mode,
632 			    &pif->pif_tios, 1) < 0) {
633 				/*
634 				 * Either we couldn't retrieve the
635 				 * characteristics for this console, or they
636 				 * weren't parseable.  The console hasn't been
637 				 * set up yet, so we can't warn.  We'll have to
638 				 * silently fall back to the default
639 				 * characteristics.
640 				 */
641 				(void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
642 				    &pif->pif_tios, 1);
643 			}
644 		}
645 
646 		if (mode != NULL)
647 			kmdb_prom_free_ddi_prop(mode);
648 	}
649 
650 	/* various characteristics of the prom read/write interface */
651 	pif->pif_tios.c_iflag |= ICRNL;
652 	pif->pif_tios.c_lflag |= ECHO;
653 	bcopy(ccs, &pif->pif_tios.c_cc, sizeof (ccs));
654 
655 	if (conin != NULL)
656 		kmdb_prom_free_ddi_prop(conin);
657 	if (conout != NULL)
658 		kmdb_prom_free_ddi_prop(conout);
659 }
660 
661 char *
662 kmdb_prom_term_type(void)
663 {
664 	return (mdb.m_promif->pif_oterm);
665 }
666 
667 int
668 kmdb_prom_term_ctl(int req, void *arg)
669 {
670 	switch (req) {
671 	case TCGETS: {
672 		struct termios *ti = arg;
673 		bcopy(&mdb.m_promif->pif_tios, ti, sizeof (struct termios));
674 		return (0);
675 	}
676 	case TIOCGWINSZ:
677 		/*
678 		 * When kmdb is used over a serial console, we have no idea how
679 		 * large the terminal window is.  When we're invoked on a local
680 		 * console, however, we do, and need to share that information
681 		 * with the debugger in order to contradict potentially
682 		 * incorrect sizing information retrieved from the terminfo
683 		 * database.  One specific case where this happens is with the
684 		 * Intel console, which is 80x25.  The terminfo entry for
685 		 * sun-color -- the default terminal type for local Intel
686 		 * consoles -- was cloned from sun, which has a height of 34
687 		 * rows.
688 		 */
689 		if (mdb.m_promif->pif_oterm != NULL) {
690 			struct winsize *wsz = arg;
691 
692 			wsz->ws_row = mdb.m_promif->pif_wsz.ws_row;
693 			wsz->ws_col = mdb.m_promif->pif_wsz.ws_col;
694 			wsz->ws_xpixel = wsz->ws_ypixel = 0;
695 			return (0);
696 		}
697 
698 		return (set_errno(ENOTSUP));
699 	default:
700 		return (set_errno(EINVAL));
701 	}
702 }
703 
704 int
705 kmdb_prom_vtop(uintptr_t virt, physaddr_t *pap)
706 {
707 	physaddr_t pa;
708 	int rc = kmdb_kdi_vtop(virt, &pa);
709 
710 #ifdef	__sparc
711 	if (rc < 0 && errno == EAGAIN)
712 		rc = kmdb_prom_translate_virt(virt, &pa);
713 #endif
714 
715 	if (rc == 0 && pap != NULL)
716 		*pap = pa;
717 
718 	return (rc);
719 }
720 
721 void
722 kmdb_prom_debugger_entry(void)
723 {
724 	/*
725 	 * While kmdb_prom_debugger_entry and kmdb_prom_debugger_exit are not
726 	 * guaranteed to be called an identical number of times (an intentional
727 	 * debugger fault will cause an additional entry call without a matching
728 	 * exit call), we must ensure that the polled I/O entry and exit calls
729 	 * match.
730 	 */
731 	if (mdb.m_pio == NULL) {
732 		mdb.m_pio = kmdb_kdi_get_polled_io();
733 
734 		if (mdb.m_pio != NULL &&
735 		    mdb.m_pio->cons_polledio_enter != NULL) {
736 			(void) kmdb_dpi_call(
737 			    (uintptr_t)mdb.m_pio->cons_polledio_enter, 1,
738 			    (uintptr_t *)&mdb.m_pio->cons_polledio_argument);
739 		}
740 	}
741 }
742 
743 void
744 kmdb_prom_debugger_exit(void)
745 {
746 	if (mdb.m_pio != NULL && mdb.m_pio->cons_polledio_exit != NULL) {
747 		(void) kmdb_dpi_call((uintptr_t)mdb.m_pio->cons_polledio_exit,
748 		    1, (uintptr_t *)&mdb.m_pio->cons_polledio_argument);
749 	}
750 
751 	mdb.m_pio = NULL;
752 }
753 
754 /*
755  * The prom_* files use ASSERT, which is #defined as assfail().  We need to
756  * redirect that to our assert function. This is also used by the various STAND
757  * libraries.
758  */
759 int
760 kmdb_prom_assfail(const char *assertion, const char *file, int line)
761 {
762 	(void) mdb_dassert(assertion, file, line);
763 	/*NOTREACHED*/
764 	return (0);
765 }
766 
767 /*
768  * Begin the initialization of the debugger/PROM interface.  Initialization is
769  * performed in two steps due to interlocking dependencies between promif and
770  * both the memory allocator and mdb_create.  The first phase is performed
771  * before either of the others have been initialized, and thus must neither
772  * attempt to allocate memory nor access/write to `mdb'.
773  */
774 void
775 kmdb_prom_init_begin(char *pgmname, kmdb_auxv_t *kav)
776 {
777 #ifdef sun4v
778 	if (kav->kav_domaining)
779 		kmdb_prom_init_promif(pgmname, kav);
780 	else
781 		prom_init(pgmname, kav->kav_romp);
782 #else
783 	prom_init(pgmname, kav->kav_romp);
784 #endif
785 
786 	/* Initialize the interrupt ring buffer */
787 	kmdb_prom_readbuf_head = kmdb_prom_readbuf_tail;
788 
789 #if defined(__i386) || defined(__amd64)
790 	kmdb_sysp = kav->kav_romp;
791 #endif
792 }
793 
794 #ifdef sun4v
795 void
796 kmdb_prom_init_promif(char *pgmname, kmdb_auxv_t *kav)
797 {
798 	ASSERT(kav->kav_domaining);
799 	cif_init(pgmname, kav->kav_promif_root,
800 	    kav->kav_promif_in, kav->kav_promif_out,
801 	    kav->kav_promif_pin, kav->kav_promif_pout,
802 	    kav->kav_promif_chosennode, kav->kav_promif_optionsnode);
803 }
804 #endif
805 
806 /*
807  * Conclude the initialization of the debugger/PROM interface.  Memory
808  * allocation and the global `mdb' object are now available.
809  */
810 void
811 kmdb_prom_init_finish(kmdb_auxv_t *kav)
812 {
813 	mdb.m_promif = mdb_zalloc(sizeof (kmdb_promif_t), UM_SLEEP);
814 	kmdb_prom_term_init(kav, mdb.m_promif);
815 }
816