xref: /openbmc/linux/arch/powerpc/xmon/nonstdio.c (revision 1ab142d4)
1 /*
2  * Copyright (C) 1996-2005 Paul Mackerras.
3  *
4  *      This program is free software; you can redistribute it and/or
5  *      modify it under the terms of the GNU General Public License
6  *      as published by the Free Software Foundation; either version
7  *      2 of the License, or (at your option) any later version.
8  */
9 #include <linux/string.h>
10 #include <asm/time.h>
11 #include "nonstdio.h"
12 
13 int xmon_putchar(int c)
14 {
15 	char ch = c;
16 
17 	if (c == '\n')
18 		xmon_putchar('\r');
19 	return xmon_write(&ch, 1) == 1? c: -1;
20 }
21 
22 static char line[256];
23 static char *lineptr;
24 static int lineleft;
25 
26 int xmon_expect(const char *str, unsigned long timeout)
27 {
28 	int c;
29 	unsigned long t0;
30 
31 	/* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
32 	timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
33 	t0 = get_tbl();
34 	do {
35 		lineptr = line;
36 		for (;;) {
37 			c = xmon_read_poll();
38 			if (c == -1) {
39 				if (get_tbl() - t0 > timeout)
40 					return 0;
41 				continue;
42 			}
43 			if (c == '\n')
44 				break;
45 			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
46 				*lineptr++ = c;
47 		}
48 		*lineptr = 0;
49 	} while (strstr(line, str) == NULL);
50 	return 1;
51 }
52 
53 int xmon_getchar(void)
54 {
55 	int c;
56 
57 	if (lineleft == 0) {
58 		lineptr = line;
59 		for (;;) {
60 			c = xmon_readchar();
61 			if (c == -1 || c == 4)
62 				break;
63 			if (c == '\r' || c == '\n') {
64 				*lineptr++ = '\n';
65 				xmon_putchar('\n');
66 				break;
67 			}
68 			switch (c) {
69 			case 0177:
70 			case '\b':
71 				if (lineptr > line) {
72 					xmon_putchar('\b');
73 					xmon_putchar(' ');
74 					xmon_putchar('\b');
75 					--lineptr;
76 				}
77 				break;
78 			case 'U' & 0x1F:
79 				while (lineptr > line) {
80 					xmon_putchar('\b');
81 					xmon_putchar(' ');
82 					xmon_putchar('\b');
83 					--lineptr;
84 				}
85 				break;
86 			default:
87 				if (lineptr >= &line[sizeof(line) - 1])
88 					xmon_putchar('\a');
89 				else {
90 					xmon_putchar(c);
91 					*lineptr++ = c;
92 				}
93 			}
94 		}
95 		lineleft = lineptr - line;
96 		lineptr = line;
97 	}
98 	if (lineleft == 0)
99 		return -1;
100 	--lineleft;
101 	return *lineptr++;
102 }
103 
104 char *xmon_gets(char *str, int nb)
105 {
106 	char *p;
107 	int c;
108 
109 	for (p = str; p < str + nb - 1; ) {
110 		c = xmon_getchar();
111 		if (c == -1) {
112 			if (p == str)
113 				return NULL;
114 			break;
115 		}
116 		*p++ = c;
117 		if (c == '\n')
118 			break;
119 	}
120 	*p = 0;
121 	return str;
122 }
123 
124 void xmon_printf(const char *format, ...)
125 {
126 	va_list args;
127 	int n;
128 	static char xmon_outbuf[1024];
129 
130 	va_start(args, format);
131 	n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
132 	va_end(args);
133 	xmon_write(xmon_outbuf, n);
134 }
135 
136 void xmon_puts(const char *str)
137 {
138 	xmon_write(str, strlen(str));
139 }
140