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