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
kmdb_prom_getchar(int wait)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 != NULL && !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
kmdb_prom_polled_write(caddr_t buf,size_t len)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
kmdb_prom_reader(caddr_t buf,size_t len,int wait)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
kmdb_prom_writer(caddr_t buf,size_t len)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
kmdb_prom_drain_readbuf(void * buf,size_t len)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
check_int(char * buf,size_t len)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
kmdb_prom_fill_readbuf(int check_for_int,int wait)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
kmdb_prom_check_interrupt(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
kmdb_prom_read(void * buf,size_t len,struct termios * tio)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
kmdb_prom_write(const void * bufp,size_t len,struct termios * tio)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 *
kmdb_get_ttyio_mode(kmdb_auxv_t * kav,char * devname)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
termios_setispeed(struct termios * tip,speed_t s)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
termios_setospeed(struct termios * tip,speed_t s)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
kmdb_parse_mode(const char * mode,struct termios * tip,int in)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
kmdb_prom_term_init(kmdb_auxv_t * kav,kmdb_promif_t * pif)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 pif->pif_oterm = ATTACHED_TERM_TYPE;
548
549 bzero(&pif->pif_tios, sizeof (struct termios));
550
551 /* output device characteristics */
552 if ((conout = kmdb_prom_get_ddi_prop(kav, "output-device")) ==
553 NULL || strcmp(conout, "screen") == 0) {
554 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
555 &pif->pif_tios, 0);
556 } else if (*conout == '/') {
557 /*
558 * We're not going to be able to get characteristics for a
559 * device that's specified as a path, so don't even try.
560 * Conveniently, this allows us to avoid chattering on
561 * Serengetis.
562 */
563 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
564 &pif->pif_tios, 0);
565 } else {
566 char *mode = kmdb_get_ttyio_mode(kav, conout);
567
568 #ifdef __sparc
569 /*
570 * Some platforms (Starfire) define a value of `ttya' for
571 * output-device, but neglect to provide a specific property
572 * with the characteristics. We'll provide a default value.
573 */
574 if (mode == NULL && strcmp(conout, "ttya") == 0) {
575 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
576 &pif->pif_tios, 0);
577 } else
578 #endif
579 {
580 if (mode == NULL || kmdb_parse_mode(mode,
581 &pif->pif_tios, 0) < 0) {
582 /*
583 * Either we couldn't retrieve the
584 * characteristics for this console, or they
585 * weren't parseable. The console hasn't been
586 * set up yet, so we can't warn. We'll have to
587 * silently fall back to the default
588 * characteristics.
589 */
590 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
591 &pif->pif_tios, 0);
592 }
593 }
594
595 if (mode != NULL)
596 kmdb_prom_free_ddi_prop(mode);
597 }
598
599 /* input device characteristics */
600 if ((conin = kmdb_prom_get_ddi_prop(kav, "input-device")) == NULL ||
601 strcmp(conin, "keyboard") == 0) {
602 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
603 &pif->pif_tios, 1);
604 } else if (*conin == '/') {
605 /* See similar case in output-device above */
606 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
607 &pif->pif_tios, 1);
608 } else {
609 char *mode = kmdb_get_ttyio_mode(kav, conin);
610
611 #ifdef __sparc
612 /*
613 * Some platforms (Starfire) define a value of `ttya' for
614 * input-device, but neglect to provide a specific property
615 * with the characteristics. We'll provide a default value.
616 */
617 if (mode == NULL && strcmp(conin, "ttya") == 0) {
618 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
619 &pif->pif_tios, 1);
620 } else
621 #endif
622 {
623 if (mode == NULL || kmdb_parse_mode(mode,
624 &pif->pif_tios, 1) < 0) {
625 /*
626 * Either we couldn't retrieve the
627 * characteristics for this console, or they
628 * weren't parseable. The console hasn't been
629 * set up yet, so we can't warn. We'll have to
630 * silently fall back to the default
631 * characteristics.
632 */
633 (void) kmdb_parse_mode(KMDB_PROM_DEF_CONS_MODE,
634 &pif->pif_tios, 1);
635 }
636 }
637
638 if (mode != NULL)
639 kmdb_prom_free_ddi_prop(mode);
640 }
641
642 /* various characteristics of the prom read/write interface */
643 pif->pif_tios.c_iflag |= ICRNL;
644 pif->pif_tios.c_lflag |= ECHO;
645 bcopy(ccs, &pif->pif_tios.c_cc, sizeof (ccs));
646
647 if (conin != NULL)
648 kmdb_prom_free_ddi_prop(conin);
649 if (conout != NULL)
650 kmdb_prom_free_ddi_prop(conout);
651 }
652
653 char *
kmdb_prom_term_type(void)654 kmdb_prom_term_type(void)
655 {
656 return (mdb.m_promif->pif_oterm);
657 }
658
659 int
kmdb_prom_term_ctl(int req,void * arg)660 kmdb_prom_term_ctl(int req, void *arg)
661 {
662 switch (req) {
663 case TCGETS: {
664 struct termios *ti = arg;
665 bcopy(&mdb.m_promif->pif_tios, ti, sizeof (struct termios));
666 return (0);
667 }
668 case TIOCGWINSZ:
669 /*
670 * When kmdb is used over a serial console, we have no idea how
671 * large the terminal window is. When we're invoked on a local
672 * console, however, we do, and need to share that information
673 * with the debugger in order to contradict potentially
674 * incorrect sizing information retrieved from the terminfo
675 * database. One specific case where this happens is with the
676 * Intel console, which is 80x25. The terminfo entry for
677 * sun-color -- the default terminal type for local Intel
678 * consoles -- was cloned from sun, which has a height of 34
679 * rows.
680 */
681 if (mdb.m_promif->pif_oterm != NULL) {
682 struct winsize *wsz = arg;
683 wsz->ws_row = KMDB_PIF_WINSIZE_ROWS;
684 wsz->ws_col = KMDB_PIF_WINSIZE_COLS;
685 wsz->ws_xpixel = wsz->ws_ypixel = 0;
686 return (0);
687 }
688
689 return (set_errno(ENOTSUP));
690 default:
691 return (set_errno(EINVAL));
692 }
693 }
694
695 int
kmdb_prom_vtop(uintptr_t virt,physaddr_t * pap)696 kmdb_prom_vtop(uintptr_t virt, physaddr_t *pap)
697 {
698 physaddr_t pa;
699 int rc = kmdb_kdi_vtop(virt, &pa);
700
701 #ifdef __sparc
702 if (rc < 0 && errno == EAGAIN)
703 rc = kmdb_prom_translate_virt(virt, &pa);
704 #endif
705
706 if (rc == 0 && pap != NULL)
707 *pap = pa;
708
709 return (rc);
710 }
711
712 void
kmdb_prom_debugger_entry(void)713 kmdb_prom_debugger_entry(void)
714 {
715 /*
716 * While kmdb_prom_debugger_entry and kmdb_prom_debugger_exit are not
717 * guaranteed to be called an identical number of times (an intentional
718 * debugger fault will cause an additional entry call without a matching
719 * exit call), we must ensure that the polled I/O entry and exit calls
720 * match.
721 */
722 if (mdb.m_pio == NULL) {
723 mdb.m_pio = kmdb_kdi_get_polled_io();
724
725 if (mdb.m_pio != NULL &&
726 mdb.m_pio->cons_polledio_enter != NULL) {
727 (void) kmdb_dpi_call(
728 (uintptr_t)mdb.m_pio->cons_polledio_enter, 1,
729 (uintptr_t *)&mdb.m_pio->cons_polledio_argument);
730 }
731 }
732 }
733
734 void
kmdb_prom_debugger_exit(void)735 kmdb_prom_debugger_exit(void)
736 {
737 if (mdb.m_pio != NULL && mdb.m_pio->cons_polledio_exit != NULL) {
738 (void) kmdb_dpi_call((uintptr_t)mdb.m_pio->cons_polledio_exit,
739 1, (uintptr_t *)&mdb.m_pio->cons_polledio_argument);
740 }
741
742 mdb.m_pio = NULL;
743 }
744
745 /*
746 * The prom_* files use ASSERT, which is #defined as assfail(). We need to
747 * redirect that to our assert function. This is also used by the various STAND
748 * libraries.
749 */
750 int
kmdb_prom_assfail(const char * assertion,const char * file,int line)751 kmdb_prom_assfail(const char *assertion, const char *file, int line)
752 {
753 (void) mdb_dassert(assertion, file, line);
754 /*NOTREACHED*/
755 return (0);
756 }
757
758 /*
759 * Begin the initialization of the debugger/PROM interface. Initialization is
760 * performed in two steps due to interlocking dependencies between promif and
761 * both the memory allocator and mdb_create. The first phase is performed
762 * before either of the others have been initialized, and thus must neither
763 * attempt to allocate memory nor access/write to `mdb'.
764 */
765 void
kmdb_prom_init_begin(char * pgmname,kmdb_auxv_t * kav)766 kmdb_prom_init_begin(char *pgmname, kmdb_auxv_t *kav)
767 {
768 #ifdef sun4v
769 if (kav->kav_domaining)
770 kmdb_prom_init_promif(pgmname, kav);
771 else
772 prom_init(pgmname, kav->kav_romp);
773 #else
774 prom_init(pgmname, kav->kav_romp);
775 #endif
776
777 /* Initialize the interrupt ring buffer */
778 kmdb_prom_readbuf_head = kmdb_prom_readbuf_tail;
779
780 #if defined(__i386) || defined(__amd64)
781 kmdb_sysp = kav->kav_romp;
782 #endif
783 }
784
785 #ifdef sun4v
786 void
kmdb_prom_init_promif(char * pgmname,kmdb_auxv_t * kav)787 kmdb_prom_init_promif(char *pgmname, kmdb_auxv_t *kav)
788 {
789 ASSERT(kav->kav_domaining);
790 cif_init(pgmname, kav->kav_promif_root,
791 kav->kav_promif_in, kav->kav_promif_out,
792 kav->kav_promif_pin, kav->kav_promif_pout,
793 kav->kav_promif_chosennode, kav->kav_promif_optionsnode);
794 }
795 #endif
796
797 /*
798 * Conclude the initialization of the debugger/PROM interface. Memory
799 * allocation and the global `mdb' object are now available.
800 */
801 void
kmdb_prom_init_finish(kmdb_auxv_t * kav)802 kmdb_prom_init_finish(kmdb_auxv_t *kav)
803 {
804 mdb.m_promif = mdb_zalloc(sizeof (kmdb_promif_t), UM_SLEEP);
805 kmdb_prom_term_init(kav, mdb.m_promif);
806 }
807