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