1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 * Copyright (C) 2000 Dan Malek.
4 * Quick hack of Paul's code to make XMON work on 8xx processors.  Lots
5 * of assumptions, like the SMC1 is used, it has been initialized by the
6 * loader at some point, and we can just stuff and suck bytes.
7 * We rely upon the 8xx uart driver to support us, as the interface
8 * changes between boot up and operational phases of the kernel.
9 */
10#include <linux/string.h>
11#include <asm/machdep.h>
12#include <asm/io.h>
13#include <asm/page.h>
14#include <linux/kernel.h>
15#include <asm/8xx_immap.h>
16#include <asm/mpc8xx.h>
17#include <asm/commproc.h>
18
19extern void xmon_printf(const char *fmt, ...);
20extern int xmon_8xx_write(char *str, int nb);
21extern int xmon_8xx_read_poll(void);
22extern int xmon_8xx_read_char(void);
23void prom_drawhex(uint);
24void prom_drawstring(const char *str);
25
26static int use_screen = 1; /* default */
27
28#define TB_SPEED	25000000
29
30static inline unsigned int readtb(void)
31{
32	unsigned int ret;
33
34	asm volatile("mftb %0" : "=r" (ret) :);
35	return ret;
36}
37
38void buf_access(void)
39{
40}
41
42void
43xmon_map_scc(void)
44{
45
46	cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
47	use_screen = 0;
48
49	prom_drawstring("xmon uses serial port\n");
50}
51
52static int scc_initialized = 0;
53
54void xmon_init_scc(void);
55
56int
57xmon_write(void *handle, void *ptr, int nb)
58{
59	char *p = ptr;
60	int i, c, ct;
61
62	if (!scc_initialized)
63		xmon_init_scc();
64
65	return(xmon_8xx_write(ptr, nb));
66}
67
68int xmon_wants_key;
69
70int
71xmon_read(void *handle, void *ptr, int nb)
72{
73	char *p = ptr;
74	int i;
75
76	if (!scc_initialized)
77		xmon_init_scc();
78
79	for (i = 0; i < nb; ++i) {
80		*p++ = xmon_8xx_read_char();
81	}
82	return i;
83}
84
85int
86xmon_read_poll(void)
87{
88	return(xmon_8xx_read_poll());
89}
90
91void
92xmon_init_scc()
93{
94	scc_initialized = 1;
95}
96
97
98void *xmon_stdin;
99void *xmon_stdout;
100void *xmon_stderr;
101
102void
103xmon_init(void)
104{
105}
106
107int
108xmon_putc(int c, void *f)
109{
110    char ch = c;
111
112    if (c == '\n')
113	xmon_putc('\r', f);
114    return xmon_write(f, &ch, 1) == 1? c: -1;
115}
116
117int
118xmon_putchar(int c)
119{
120    return xmon_putc(c, xmon_stdout);
121}
122
123int
124xmon_fputs(char *str, void *f)
125{
126    int n = strlen(str);
127
128    return xmon_write(f, str, n) == n? 0: -1;
129}
130
131int
132xmon_readchar(void)
133{
134    char ch;
135
136    for (;;) {
137	switch (xmon_read(xmon_stdin, &ch, 1)) {
138	case 1:
139	    return ch;
140	case -1:
141	    xmon_printf("read(stdin) returned -1\r\n", 0, 0);
142	    return -1;
143	}
144    }
145}
146
147static char line[256];
148static char *lineptr;
149static int lineleft;
150
151
152int
153xmon_getchar(void)
154{
155    int c;
156
157    if (lineleft == 0) {
158	lineptr = line;
159	for (;;) {
160	    c = xmon_readchar();
161	    if (c == -1 || c == 4)
162		break;
163	    if (c == '\r' || c == '\n') {
164		*lineptr++ = '\n';
165		xmon_putchar('\n');
166		break;
167	    }
168	    switch (c) {
169	    case 0177:
170	    case '\b':
171		if (lineptr > line) {
172		    xmon_putchar('\b');
173		    xmon_putchar(' ');
174		    xmon_putchar('\b');
175		    --lineptr;
176		}
177		break;
178	    case 'U' & 0x1F:
179		while (lineptr > line) {
180		    xmon_putchar('\b');
181		    xmon_putchar(' ');
182		    xmon_putchar('\b');
183		    --lineptr;
184		}
185		break;
186	    default:
187		if (lineptr >= &line[sizeof(line) - 1])
188		    xmon_putchar('\a');
189		else {
190		    xmon_putchar(c);
191		    *lineptr++ = c;
192		}
193	    }
194	}
195	lineleft = lineptr - line;
196	lineptr = line;
197    }
198    if (lineleft == 0)
199	return -1;
200    --lineleft;
201    return *lineptr++;
202}
203
204char *
205xmon_fgets(char *str, int nb, void *f)
206{
207    char *p;
208    int c;
209
210    for (p = str; p < str + nb - 1; ) {
211	c = xmon_getchar();
212	if (c == -1) {
213	    if (p == str)
214		return 0;
215	    break;
216	}
217	*p++ = c;
218	if (c == '\n')
219	    break;
220    }
221    *p = 0;
222    return str;
223}
224
225void
226prom_drawhex(uint val)
227{
228	unsigned char buf[10];
229
230	int i;
231	for (i = 7;  i >= 0;  i--)
232	{
233		buf[i] = "0123456789abcdef"[val & 0x0f];
234		val >>= 4;
235	}
236	buf[8] = '\0';
237	xmon_fputs(buf, xmon_stdout);
238}
239
240void
241prom_drawstring(const char *str)
242{
243	xmon_fputs(str, xmon_stdout);
244}
245