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