File: /usr/src/linux/arch/ppc/xmon/start_8xx.c

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