Linux 2.6.17.7
[linux/fpc-iii.git] / arch / ppc / xmon / start.c
blobcfc2d6ad464ddcbdd31a59a59fb024a5a19cd83c
1 /*
2 * Copyright (C) 1996 Paul Mackerras.
3 */
4 #include <linux/config.h>
5 #include <linux/string.h>
6 #include <asm/machdep.h>
7 #include <asm/io.h>
8 #include <asm/page.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/sysrq.h>
12 #include <linux/bitops.h>
13 #include <asm/xmon.h>
14 #include <asm/machdep.h>
15 #include <asm/errno.h>
16 #include <asm/processor.h>
17 #include <asm/delay.h>
18 #include <asm/btext.h>
20 static volatile unsigned char *sccc, *sccd;
21 unsigned int TXRDY, RXRDY, DLAB;
22 static int xmon_expect(const char *str, unsigned int timeout);
24 static int via_modem;
26 #define TB_SPEED 25000000
28 static inline unsigned int readtb(void)
30 unsigned int ret;
32 asm volatile("mftb %0" : "=r" (ret) :);
33 return ret;
36 void buf_access(void)
38 if (DLAB)
39 sccd[3] &= ~DLAB; /* reset DLAB */
43 #ifdef CONFIG_MAGIC_SYSRQ
44 static void sysrq_handle_xmon(int key, struct pt_regs *regs,
45 struct tty_struct *tty)
47 xmon(regs);
50 static struct sysrq_key_op sysrq_xmon_op =
52 .handler = sysrq_handle_xmon,
53 .help_msg = "Xmon",
54 .action_msg = "Entering xmon",
56 #endif
58 void
59 xmon_map_scc(void)
61 #ifdef CONFIG_PPC_PREP
62 volatile unsigned char *base;
64 #elif defined(CONFIG_GEMINI)
65 /* should already be mapped by the kernel boot */
66 sccc = (volatile unsigned char *) 0xffeffb0d;
67 sccd = (volatile unsigned char *) 0xffeffb08;
68 TXRDY = 0x20;
69 RXRDY = 1;
70 DLAB = 0x80;
71 #elif defined(CONFIG_405GP)
72 sccc = (volatile unsigned char *)0xef600305;
73 sccd = (volatile unsigned char *)0xef600300;
74 TXRDY = 0x20;
75 RXRDY = 1;
76 DLAB = 0x80;
77 #endif /* platform */
79 register_sysrq_key('x', &sysrq_xmon_op);
82 static int scc_initialized;
84 void xmon_init_scc(void);
86 int
87 xmon_write(void *handle, void *ptr, int nb)
89 char *p = ptr;
90 int i, c, ct;
92 #ifdef CONFIG_SMP
93 static unsigned long xmon_write_lock;
94 int lock_wait = 1000000;
95 int locked;
97 while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
98 if (--lock_wait == 0)
99 break;
100 #endif
102 if (!scc_initialized)
103 xmon_init_scc();
104 ct = 0;
105 for (i = 0; i < nb; ++i) {
106 while ((*sccc & TXRDY) == 0)
108 c = p[i];
109 if (c == '\n' && !ct) {
110 c = '\r';
111 ct = 1;
112 --i;
113 } else {
114 ct = 0;
116 buf_access();
117 *sccd = c;
118 eieio();
121 #ifdef CONFIG_SMP
122 if (!locked)
123 clear_bit(0, &xmon_write_lock);
124 #endif
125 return nb;
128 int xmon_wants_key;
132 xmon_read(void *handle, void *ptr, int nb)
134 char *p = ptr;
135 int i;
137 if (!scc_initialized)
138 xmon_init_scc();
139 for (i = 0; i < nb; ++i) {
140 while ((*sccc & RXRDY) == 0)
142 buf_access();
143 *p++ = *sccd;
145 return i;
149 xmon_read_poll(void)
151 if ((*sccc & RXRDY) == 0) {
153 return -1;
155 buf_access();
156 return *sccd;
159 void
160 xmon_init_scc(void)
162 scc_initialized = 1;
163 if (via_modem) {
164 for (;;) {
165 xmon_write(NULL, "ATE1V1\r", 7);
166 if (xmon_expect("OK", 5)) {
167 xmon_write(NULL, "ATA\r", 4);
168 if (xmon_expect("CONNECT", 40))
169 break;
171 xmon_write(NULL, "+++", 3);
172 xmon_expect("OK", 3);
178 void *xmon_stdin;
179 void *xmon_stdout;
180 void *xmon_stderr;
182 void
183 xmon_init(int arg)
185 xmon_map_scc();
189 xmon_putc(int c, void *f)
191 char ch = c;
193 if (c == '\n')
194 xmon_putc('\r', f);
195 return xmon_write(f, &ch, 1) == 1? c: -1;
199 xmon_putchar(int c)
201 return xmon_putc(c, xmon_stdout);
205 xmon_fputs(char *str, void *f)
207 int n = strlen(str);
209 return xmon_write(f, str, n) == n? 0: -1;
213 xmon_readchar(void)
215 char ch;
217 for (;;) {
218 switch (xmon_read(xmon_stdin, &ch, 1)) {
219 case 1:
220 return ch;
221 case -1:
222 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
223 return -1;
228 static char line[256];
229 static char *lineptr;
230 static int lineleft;
232 int xmon_expect(const char *str, unsigned int timeout)
234 int c;
235 unsigned int t0;
237 timeout *= TB_SPEED;
238 t0 = readtb();
239 do {
240 lineptr = line;
241 for (;;) {
242 c = xmon_read_poll();
243 if (c == -1) {
244 if (readtb() - t0 > timeout)
245 return 0;
246 continue;
248 if (c == '\n')
249 break;
250 if (c != '\r' && lineptr < &line[sizeof(line) - 1])
251 *lineptr++ = c;
253 *lineptr = 0;
254 } while (strstr(line, str) == NULL);
255 return 1;
259 xmon_getchar(void)
261 int c;
263 if (lineleft == 0) {
264 lineptr = line;
265 for (;;) {
266 c = xmon_readchar();
267 if (c == -1 || c == 4)
268 break;
269 if (c == '\r' || c == '\n') {
270 *lineptr++ = '\n';
271 xmon_putchar('\n');
272 break;
274 switch (c) {
275 case 0177:
276 case '\b':
277 if (lineptr > line) {
278 xmon_putchar('\b');
279 xmon_putchar(' ');
280 xmon_putchar('\b');
281 --lineptr;
283 break;
284 case 'U' & 0x1F:
285 while (lineptr > line) {
286 xmon_putchar('\b');
287 xmon_putchar(' ');
288 xmon_putchar('\b');
289 --lineptr;
291 break;
292 default:
293 if (lineptr >= &line[sizeof(line) - 1])
294 xmon_putchar('\a');
295 else {
296 xmon_putchar(c);
297 *lineptr++ = c;
301 lineleft = lineptr - line;
302 lineptr = line;
304 if (lineleft == 0)
305 return -1;
306 --lineleft;
307 return *lineptr++;
310 char *
311 xmon_fgets(char *str, int nb, void *f)
313 char *p;
314 int c;
316 for (p = str; p < str + nb - 1; ) {
317 c = xmon_getchar();
318 if (c == -1) {
319 if (p == str)
320 return NULL;
321 break;
323 *p++ = c;
324 if (c == '\n')
325 break;
327 *p = 0;
328 return str;
331 void
332 xmon_enter(void)
336 void
337 xmon_leave(void)