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