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