Commit fca5dcd4835ed09bb1a48a355344aff7a25c76e0
1 parent
3825ac0ee6
Exists in
master
and in
7 other branches
powerpc: Simplify and clean up the xmon terminal I/O
This factors out the common bits of arch/powerpc/xmon/start_*.c into a new nonstdio.c, and removes some stuff that was supposed to make xmon's I/O routines somewhat stdio-like but was never used. It also makes the parsing of the xmon= command line option common, so that ppc32 can now use xmon={off,on,early} also. Signed-off-by: Paul Mackerras <paulus@samba.org>
Showing 12 changed files with 236 additions and 729 deletions Side-by-side Diff
- arch/powerpc/kernel/setup-common.c
- arch/powerpc/kernel/setup_32.c
- arch/powerpc/kernel/setup_64.c
- arch/powerpc/xmon/Makefile
- arch/powerpc/xmon/nonstdio.c
- arch/powerpc/xmon/nonstdio.h
- arch/powerpc/xmon/start_32.c
- arch/powerpc/xmon/start_64.c
- arch/powerpc/xmon/start_8xx.c
- arch/powerpc/xmon/subr_prf.c
- arch/powerpc/xmon/xmon.c
- include/asm-powerpc/xmon.h
arch/powerpc/kernel/setup-common.c
... | ... | @@ -51,6 +51,7 @@ |
51 | 51 | #include <asm/page.h> |
52 | 52 | #include <asm/mmu.h> |
53 | 53 | #include <asm/lmb.h> |
54 | +#include <asm/xmon.h> | |
54 | 55 | |
55 | 56 | #undef DEBUG |
56 | 57 | |
... | ... | @@ -559,4 +560,24 @@ |
559 | 560 | #endif /* CONFIG_PPC64 */ |
560 | 561 | } |
561 | 562 | #endif /* CONFIG_SMP */ |
563 | + | |
564 | +#ifdef CONFIG_XMON | |
565 | +static int __init early_xmon(char *p) | |
566 | +{ | |
567 | + /* ensure xmon is enabled */ | |
568 | + if (p) { | |
569 | + if (strncmp(p, "on", 2) == 0) | |
570 | + xmon_init(1); | |
571 | + if (strncmp(p, "off", 3) == 0) | |
572 | + xmon_init(0); | |
573 | + if (strncmp(p, "early", 5) != 0) | |
574 | + return 0; | |
575 | + } | |
576 | + xmon_init(1); | |
577 | + debugger(NULL); | |
578 | + | |
579 | + return 0; | |
580 | +} | |
581 | +early_param("xmon", early_xmon); | |
582 | +#endif |
arch/powerpc/kernel/setup_32.c
... | ... | @@ -303,14 +303,9 @@ |
303 | 303 | pmac_feature_init(); /* New cool way */ |
304 | 304 | #endif |
305 | 305 | |
306 | -#ifdef CONFIG_XMON | |
307 | - xmon_map_scc(); | |
308 | - if (strstr(cmd_line, "xmon")) { | |
309 | - xmon_init(1); | |
310 | - debugger(NULL); | |
311 | - } | |
312 | -#endif /* CONFIG_XMON */ | |
313 | - if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); | |
306 | +#ifdef CONFIG_XMON_DEFAULT | |
307 | + xmon_init(1); | |
308 | +#endif | |
314 | 309 | |
315 | 310 | #if defined(CONFIG_KGDB) |
316 | 311 | if (ppc_md.kgdb_map_scc) |
arch/powerpc/kernel/setup_64.c
... | ... | @@ -858,26 +858,6 @@ |
858 | 858 | } |
859 | 859 | EXPORT_SYMBOL(check_legacy_ioport); |
860 | 860 | |
861 | -#ifdef CONFIG_XMON | |
862 | -static int __init early_xmon(char *p) | |
863 | -{ | |
864 | - /* ensure xmon is enabled */ | |
865 | - if (p) { | |
866 | - if (strncmp(p, "on", 2) == 0) | |
867 | - xmon_init(1); | |
868 | - if (strncmp(p, "off", 3) == 0) | |
869 | - xmon_init(0); | |
870 | - if (strncmp(p, "early", 5) != 0) | |
871 | - return 0; | |
872 | - } | |
873 | - xmon_init(1); | |
874 | - debugger(NULL); | |
875 | - | |
876 | - return 0; | |
877 | -} | |
878 | -early_param("xmon", early_xmon); | |
879 | -#endif | |
880 | - | |
881 | 861 | void cpu_die(void) |
882 | 862 | { |
883 | 863 | if (ppc_md.cpu_die) |
arch/powerpc/xmon/Makefile
arch/powerpc/xmon/nonstdio.c
1 | +/* | |
2 | + * Copyright (C) 1996-2005 Paul Mackerras. | |
3 | + * | |
4 | + * This program is free software; you can redistribute it and/or | |
5 | + * modify it under the terms of the GNU General Public License | |
6 | + * as published by the Free Software Foundation; either version | |
7 | + * 2 of the License, or (at your option) any later version. | |
8 | + */ | |
9 | +#include <linux/string.h> | |
10 | +#include <asm/time.h> | |
11 | +#include "nonstdio.h" | |
12 | + | |
13 | +int xmon_putchar(int c) | |
14 | +{ | |
15 | + char ch = c; | |
16 | + | |
17 | + if (c == '\n') | |
18 | + xmon_putchar('\r'); | |
19 | + return xmon_write(&ch, 1) == 1? c: -1; | |
20 | +} | |
21 | + | |
22 | +static char line[256]; | |
23 | +static char *lineptr; | |
24 | +static int lineleft; | |
25 | + | |
26 | +int xmon_expect(const char *str, unsigned long timeout) | |
27 | +{ | |
28 | + int c; | |
29 | + unsigned long t0; | |
30 | + | |
31 | + /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */ | |
32 | + timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000; | |
33 | + t0 = get_tbl(); | |
34 | + do { | |
35 | + lineptr = line; | |
36 | + for (;;) { | |
37 | + c = xmon_read_poll(); | |
38 | + if (c == -1) { | |
39 | + if (get_tbl() - t0 > timeout) | |
40 | + return 0; | |
41 | + continue; | |
42 | + } | |
43 | + if (c == '\n') | |
44 | + break; | |
45 | + if (c != '\r' && lineptr < &line[sizeof(line) - 1]) | |
46 | + *lineptr++ = c; | |
47 | + } | |
48 | + *lineptr = 0; | |
49 | + } while (strstr(line, str) == NULL); | |
50 | + return 1; | |
51 | +} | |
52 | + | |
53 | +int xmon_getchar(void) | |
54 | +{ | |
55 | + int c; | |
56 | + | |
57 | + if (lineleft == 0) { | |
58 | + lineptr = line; | |
59 | + for (;;) { | |
60 | + c = xmon_readchar(); | |
61 | + if (c == -1 || c == 4) | |
62 | + break; | |
63 | + if (c == '\r' || c == '\n') { | |
64 | + *lineptr++ = '\n'; | |
65 | + xmon_putchar('\n'); | |
66 | + break; | |
67 | + } | |
68 | + switch (c) { | |
69 | + case 0177: | |
70 | + case '\b': | |
71 | + if (lineptr > line) { | |
72 | + xmon_putchar('\b'); | |
73 | + xmon_putchar(' '); | |
74 | + xmon_putchar('\b'); | |
75 | + --lineptr; | |
76 | + } | |
77 | + break; | |
78 | + case 'U' & 0x1F: | |
79 | + while (lineptr > line) { | |
80 | + xmon_putchar('\b'); | |
81 | + xmon_putchar(' '); | |
82 | + xmon_putchar('\b'); | |
83 | + --lineptr; | |
84 | + } | |
85 | + break; | |
86 | + default: | |
87 | + if (lineptr >= &line[sizeof(line) - 1]) | |
88 | + xmon_putchar('\a'); | |
89 | + else { | |
90 | + xmon_putchar(c); | |
91 | + *lineptr++ = c; | |
92 | + } | |
93 | + } | |
94 | + } | |
95 | + lineleft = lineptr - line; | |
96 | + lineptr = line; | |
97 | + } | |
98 | + if (lineleft == 0) | |
99 | + return -1; | |
100 | + --lineleft; | |
101 | + return *lineptr++; | |
102 | +} | |
103 | + | |
104 | +char *xmon_gets(char *str, int nb) | |
105 | +{ | |
106 | + char *p; | |
107 | + int c; | |
108 | + | |
109 | + for (p = str; p < str + nb - 1; ) { | |
110 | + c = xmon_getchar(); | |
111 | + if (c == -1) { | |
112 | + if (p == str) | |
113 | + return NULL; | |
114 | + break; | |
115 | + } | |
116 | + *p++ = c; | |
117 | + if (c == '\n') | |
118 | + break; | |
119 | + } | |
120 | + *p = 0; | |
121 | + return str; | |
122 | +} | |
123 | + | |
124 | +void xmon_printf(const char *format, ...) | |
125 | +{ | |
126 | + va_list args; | |
127 | + int n; | |
128 | + static char xmon_outbuf[1024]; | |
129 | + | |
130 | + va_start(args, format); | |
131 | + n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args); | |
132 | + va_end(args); | |
133 | + xmon_write(xmon_outbuf, n); | |
134 | +} |
arch/powerpc/xmon/nonstdio.h
1 | -typedef int FILE; | |
2 | -extern FILE *xmon_stdin, *xmon_stdout; | |
3 | 1 | #define EOF (-1) |
4 | -#define stdin xmon_stdin | |
5 | -#define stdout xmon_stdout | |
2 | + | |
6 | 3 | #define printf xmon_printf |
7 | -#define fprintf xmon_fprintf | |
8 | -#define fputs xmon_fputs | |
9 | -#define fgets xmon_fgets | |
10 | 4 | #define putchar xmon_putchar |
11 | -#define getchar xmon_getchar | |
12 | -#define putc xmon_putc | |
13 | -#define getc xmon_getc | |
14 | -#define fopen(n, m) NULL | |
15 | -#define fflush(f) do {} while (0) | |
16 | -#define fclose(f) do {} while (0) | |
17 | -extern char *fgets(char *, int, void *); | |
18 | -extern void xmon_printf(const char *, ...); | |
19 | -extern void xmon_fprintf(void *, const char *, ...); | |
20 | -extern void xmon_sprintf(char *, const char *, ...); | |
21 | 5 | |
22 | -#define perror(s) printf("%s: no files!\n", (s)) | |
6 | +extern int xmon_putchar(int c); | |
7 | +extern int xmon_getchar(void); | |
8 | +extern char *xmon_gets(char *, int); | |
9 | +extern void xmon_printf(const char *, ...); | |
10 | +extern void xmon_map_scc(void); | |
11 | +extern int xmon_expect(const char *str, unsigned long timeout); | |
12 | +extern int xmon_write(void *ptr, int nb); | |
13 | +extern int xmon_readchar(void); | |
14 | +extern int xmon_read_poll(void); |
arch/powerpc/xmon/start_32.c
... | ... | @@ -11,7 +11,6 @@ |
11 | 11 | #include <linux/cuda.h> |
12 | 12 | #include <linux/kernel.h> |
13 | 13 | #include <linux/errno.h> |
14 | -#include <linux/sysrq.h> | |
15 | 14 | #include <linux/bitops.h> |
16 | 15 | #include <asm/xmon.h> |
17 | 16 | #include <asm/prom.h> |
18 | 17 | |
... | ... | @@ -22,10 +21,11 @@ |
22 | 21 | #include <asm/processor.h> |
23 | 22 | #include <asm/delay.h> |
24 | 23 | #include <asm/btext.h> |
24 | +#include <asm/time.h> | |
25 | +#include "nonstdio.h" | |
25 | 26 | |
26 | 27 | static volatile unsigned char __iomem *sccc, *sccd; |
27 | 28 | unsigned int TXRDY, RXRDY, DLAB; |
28 | -static int xmon_expect(const char *str, unsigned int timeout); | |
29 | 29 | |
30 | 30 | static int use_serial; |
31 | 31 | static int use_screen; |
... | ... | @@ -33,16 +33,6 @@ |
33 | 33 | static int xmon_use_sccb; |
34 | 34 | static struct device_node *channel_node; |
35 | 35 | |
36 | -#define TB_SPEED 25000000 | |
37 | - | |
38 | -static inline unsigned int readtb(void) | |
39 | -{ | |
40 | - unsigned int ret; | |
41 | - | |
42 | - asm volatile("mftb %0" : "=r" (ret) :); | |
43 | - return ret; | |
44 | -} | |
45 | - | |
46 | 36 | void buf_access(void) |
47 | 37 | { |
48 | 38 | if (DLAB) |
49 | 39 | |
... | ... | @@ -91,24 +81,8 @@ |
91 | 81 | } |
92 | 82 | #endif /* CONFIG_PPC_CHRP */ |
93 | 83 | |
94 | -#ifdef CONFIG_MAGIC_SYSRQ | |
95 | -static void sysrq_handle_xmon(int key, struct pt_regs *regs, | |
96 | - struct tty_struct *tty) | |
84 | +void xmon_map_scc(void) | |
97 | 85 | { |
98 | - xmon(regs); | |
99 | -} | |
100 | - | |
101 | -static struct sysrq_key_op sysrq_xmon_op = | |
102 | -{ | |
103 | - .handler = sysrq_handle_xmon, | |
104 | - .help_msg = "Xmon", | |
105 | - .action_msg = "Entering xmon", | |
106 | -}; | |
107 | -#endif | |
108 | - | |
109 | -void | |
110 | -xmon_map_scc(void) | |
111 | -{ | |
112 | 86 | #ifdef CONFIG_PPC_MULTIPLATFORM |
113 | 87 | volatile unsigned char __iomem *base; |
114 | 88 | |
... | ... | @@ -217,8 +191,6 @@ |
217 | 191 | RXRDY = 1; |
218 | 192 | DLAB = 0x80; |
219 | 193 | #endif /* platform */ |
220 | - | |
221 | - register_sysrq_key('x', &sysrq_xmon_op); | |
222 | 194 | } |
223 | 195 | |
224 | 196 | static int scc_initialized = 0; |
... | ... | @@ -238,8 +210,7 @@ |
238 | 210 | #endif /* CONFIG_ADB_CUDA */ |
239 | 211 | } |
240 | 212 | |
241 | -int | |
242 | -xmon_write(void *handle, void *ptr, int nb) | |
213 | +int xmon_write(void *ptr, int nb) | |
243 | 214 | { |
244 | 215 | char *p = ptr; |
245 | 216 | int i, c, ct; |
... | ... | @@ -311,8 +282,7 @@ |
311 | 282 | "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ |
312 | 283 | "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ |
313 | 284 | |
314 | -static int | |
315 | -xmon_get_adb_key(void) | |
285 | +static int xmon_get_adb_key(void) | |
316 | 286 | { |
317 | 287 | int k, t, on; |
318 | 288 | |
319 | 289 | |
320 | 290 | |
321 | 291 | |
322 | 292 | |
323 | 293 | |
324 | 294 | |
... | ... | @@ -350,32 +320,21 @@ |
350 | 320 | } |
351 | 321 | #endif /* CONFIG_BOOTX_TEXT */ |
352 | 322 | |
353 | -int | |
354 | -xmon_read(void *handle, void *ptr, int nb) | |
323 | +int xmon_readchar(void) | |
355 | 324 | { |
356 | - char *p = ptr; | |
357 | - int i; | |
358 | - | |
359 | 325 | #ifdef CONFIG_BOOTX_TEXT |
360 | - if (use_screen) { | |
361 | - for (i = 0; i < nb; ++i) | |
362 | - *p++ = xmon_get_adb_key(); | |
363 | - return i; | |
364 | - } | |
326 | + if (use_screen) | |
327 | + return xmon_get_adb_key(); | |
365 | 328 | #endif |
366 | - if (!scc_initialized) | |
367 | - xmon_init_scc(); | |
368 | - for (i = 0; i < nb; ++i) { | |
329 | + if (!scc_initialized) | |
330 | + xmon_init_scc(); | |
369 | 331 | while ((*sccc & RXRDY) == 0) |
370 | - do_poll_adb(); | |
332 | + do_poll_adb(); | |
371 | 333 | buf_access(); |
372 | - *p++ = *sccd; | |
373 | - } | |
374 | - return i; | |
334 | + return *sccd; | |
375 | 335 | } |
376 | 336 | |
377 | -int | |
378 | -xmon_read_poll(void) | |
337 | +int xmon_read_poll(void) | |
379 | 338 | { |
380 | 339 | if ((*sccc & RXRDY) == 0) { |
381 | 340 | do_poll_adb(); |
... | ... | @@ -395,8 +354,7 @@ |
395 | 354 | 3, 0xc1, /* rx enable, 8 bits */ |
396 | 355 | }; |
397 | 356 | |
398 | -void | |
399 | -xmon_init_scc(void) | |
357 | +void xmon_init_scc(void) | |
400 | 358 | { |
401 | 359 | if ( _machine == _MACH_chrp ) |
402 | 360 | { |
... | ... | @@ -410,6 +368,7 @@ |
410 | 368 | else if ( _machine == _MACH_Pmac ) |
411 | 369 | { |
412 | 370 | int i, x; |
371 | + unsigned long timeout; | |
413 | 372 | |
414 | 373 | if (channel_node != 0) |
415 | 374 | pmac_call_feature( |
... | ... | @@ -424,8 +383,12 @@ |
424 | 383 | PMAC_FTR_MODEM_ENABLE, |
425 | 384 | channel_node, 0, 1); |
426 | 385 | printk(KERN_INFO "Modem powered up by debugger !\n"); |
427 | - t0 = readtb(); | |
428 | - while (readtb() - t0 < 3*TB_SPEED) | |
386 | + t0 = get_tbl(); | |
387 | + timeout = 3 * tb_ticks_per_sec; | |
388 | + if (timeout == 0) | |
389 | + /* assume 25MHz if tb_ticks_per_sec not set */ | |
390 | + timeout = 75000000; | |
391 | + while (get_tbl() - t0 < timeout) | |
429 | 392 | eieio(); |
430 | 393 | } |
431 | 394 | /* use the B channel if requested */ |
432 | 395 | |
433 | 396 | |
434 | 397 | |
435 | 398 | |
... | ... | @@ -447,165 +410,20 @@ |
447 | 410 | scc_initialized = 1; |
448 | 411 | if (via_modem) { |
449 | 412 | for (;;) { |
450 | - xmon_write(NULL, "ATE1V1\r", 7); | |
413 | + xmon_write("ATE1V1\r", 7); | |
451 | 414 | if (xmon_expect("OK", 5)) { |
452 | - xmon_write(NULL, "ATA\r", 4); | |
415 | + xmon_write("ATA\r", 4); | |
453 | 416 | if (xmon_expect("CONNECT", 40)) |
454 | 417 | break; |
455 | 418 | } |
456 | - xmon_write(NULL, "+++", 3); | |
419 | + xmon_write("+++", 3); | |
457 | 420 | xmon_expect("OK", 3); |
458 | 421 | } |
459 | 422 | } |
460 | 423 | } |
461 | 424 | |
462 | -void *xmon_stdin; | |
463 | -void *xmon_stdout; | |
464 | -void *xmon_stderr; | |
465 | - | |
466 | -int xmon_putc(int c, void *f) | |
425 | +void xmon_enter(void) | |
467 | 426 | { |
468 | - char ch = c; | |
469 | - | |
470 | - if (c == '\n') | |
471 | - xmon_putc('\r', f); | |
472 | - return xmon_write(f, &ch, 1) == 1? c: -1; | |
473 | -} | |
474 | - | |
475 | -int xmon_putchar(int c) | |
476 | -{ | |
477 | - return xmon_putc(c, xmon_stdout); | |
478 | -} | |
479 | - | |
480 | -int xmon_fputs(char *str, void *f) | |
481 | -{ | |
482 | - int n = strlen(str); | |
483 | - | |
484 | - return xmon_write(f, str, n) == n? 0: -1; | |
485 | -} | |
486 | - | |
487 | -int | |
488 | -xmon_readchar(void) | |
489 | -{ | |
490 | - char ch; | |
491 | - | |
492 | - for (;;) { | |
493 | - switch (xmon_read(xmon_stdin, &ch, 1)) { | |
494 | - case 1: | |
495 | - return ch; | |
496 | - case -1: | |
497 | - xmon_printf("read(stdin) returned -1\r\n", 0, 0); | |
498 | - return -1; | |
499 | - } | |
500 | - } | |
501 | -} | |
502 | - | |
503 | -static char line[256]; | |
504 | -static char *lineptr; | |
505 | -static int lineleft; | |
506 | - | |
507 | -int xmon_expect(const char *str, unsigned int timeout) | |
508 | -{ | |
509 | - int c; | |
510 | - unsigned int t0; | |
511 | - | |
512 | - timeout *= TB_SPEED; | |
513 | - t0 = readtb(); | |
514 | - do { | |
515 | - lineptr = line; | |
516 | - for (;;) { | |
517 | - c = xmon_read_poll(); | |
518 | - if (c == -1) { | |
519 | - if (readtb() - t0 > timeout) | |
520 | - return 0; | |
521 | - continue; | |
522 | - } | |
523 | - if (c == '\n') | |
524 | - break; | |
525 | - if (c != '\r' && lineptr < &line[sizeof(line) - 1]) | |
526 | - *lineptr++ = c; | |
527 | - } | |
528 | - *lineptr = 0; | |
529 | - } while (strstr(line, str) == NULL); | |
530 | - return 1; | |
531 | -} | |
532 | - | |
533 | -int | |
534 | -xmon_getchar(void) | |
535 | -{ | |
536 | - int c; | |
537 | - | |
538 | - if (lineleft == 0) { | |
539 | - lineptr = line; | |
540 | - for (;;) { | |
541 | - c = xmon_readchar(); | |
542 | - if (c == -1 || c == 4) | |
543 | - break; | |
544 | - if (c == '\r' || c == '\n') { | |
545 | - *lineptr++ = '\n'; | |
546 | - xmon_putchar('\n'); | |
547 | - break; | |
548 | - } | |
549 | - switch (c) { | |
550 | - case 0177: | |
551 | - case '\b': | |
552 | - if (lineptr > line) { | |
553 | - xmon_putchar('\b'); | |
554 | - xmon_putchar(' '); | |
555 | - xmon_putchar('\b'); | |
556 | - --lineptr; | |
557 | - } | |
558 | - break; | |
559 | - case 'U' & 0x1F: | |
560 | - while (lineptr > line) { | |
561 | - xmon_putchar('\b'); | |
562 | - xmon_putchar(' '); | |
563 | - xmon_putchar('\b'); | |
564 | - --lineptr; | |
565 | - } | |
566 | - break; | |
567 | - default: | |
568 | - if (lineptr >= &line[sizeof(line) - 1]) | |
569 | - xmon_putchar('\a'); | |
570 | - else { | |
571 | - xmon_putchar(c); | |
572 | - *lineptr++ = c; | |
573 | - } | |
574 | - } | |
575 | - } | |
576 | - lineleft = lineptr - line; | |
577 | - lineptr = line; | |
578 | - } | |
579 | - if (lineleft == 0) | |
580 | - return -1; | |
581 | - --lineleft; | |
582 | - return *lineptr++; | |
583 | -} | |
584 | - | |
585 | -char * | |
586 | -xmon_fgets(char *str, int nb, void *f) | |
587 | -{ | |
588 | - char *p; | |
589 | - int c; | |
590 | - | |
591 | - for (p = str; p < str + nb - 1; ) { | |
592 | - c = xmon_getchar(); | |
593 | - if (c == -1) { | |
594 | - if (p == str) | |
595 | - return NULL; | |
596 | - break; | |
597 | - } | |
598 | - *p++ = c; | |
599 | - if (c == '\n') | |
600 | - break; | |
601 | - } | |
602 | - *p = 0; | |
603 | - return str; | |
604 | -} | |
605 | - | |
606 | -void | |
607 | -xmon_enter(void) | |
608 | -{ | |
609 | 427 | #ifdef CONFIG_ADB_PMU |
610 | 428 | if (_machine == _MACH_Pmac) { |
611 | 429 | pmu_suspend(); |
... | ... | @@ -613,8 +431,7 @@ |
613 | 431 | #endif |
614 | 432 | } |
615 | 433 | |
616 | -void | |
617 | -xmon_leave(void) | |
434 | +void xmon_leave(void) | |
618 | 435 | { |
619 | 436 | #ifdef CONFIG_ADB_PMU |
620 | 437 | if (_machine == _MACH_Pmac) { |
arch/powerpc/xmon/start_64.c
... | ... | @@ -6,183 +6,30 @@ |
6 | 6 | * as published by the Free Software Foundation; either version |
7 | 7 | * 2 of the License, or (at your option) any later version. |
8 | 8 | */ |
9 | -#include <linux/config.h> | |
10 | -#include <linux/string.h> | |
11 | -#include <linux/kernel.h> | |
12 | -#include <linux/errno.h> | |
13 | -#include <linux/sysrq.h> | |
14 | -#include <linux/init.h> | |
15 | 9 | #include <asm/machdep.h> |
16 | -#include <asm/io.h> | |
17 | -#include <asm/page.h> | |
18 | -#include <asm/prom.h> | |
19 | -#include <asm/processor.h> | |
20 | 10 | #include <asm/udbg.h> |
21 | -#include <asm/system.h> | |
22 | 11 | #include "nonstdio.h" |
23 | 12 | |
24 | -#ifdef CONFIG_MAGIC_SYSRQ | |
25 | - | |
26 | -static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, | |
27 | - struct tty_struct *tty) | |
13 | +void xmon_map_scc(void) | |
28 | 14 | { |
29 | - /* ensure xmon is enabled */ | |
30 | - xmon_init(1); | |
31 | - debugger(pt_regs); | |
32 | 15 | } |
33 | 16 | |
34 | -static struct sysrq_key_op sysrq_xmon_op = | |
17 | +int xmon_write(void *ptr, int nb) | |
35 | 18 | { |
36 | - .handler = sysrq_handle_xmon, | |
37 | - .help_msg = "Xmon", | |
38 | - .action_msg = "Entering xmon", | |
39 | -}; | |
40 | - | |
41 | -static int __init setup_xmon_sysrq(void) | |
42 | -{ | |
43 | - register_sysrq_key('x', &sysrq_xmon_op); | |
44 | - return 0; | |
45 | -} | |
46 | -__initcall(setup_xmon_sysrq); | |
47 | -#endif /* CONFIG_MAGIC_SYSRQ */ | |
48 | - | |
49 | -int | |
50 | -xmon_write(void *handle, void *ptr, int nb) | |
51 | -{ | |
52 | 19 | return udbg_write(ptr, nb); |
53 | 20 | } |
54 | 21 | |
55 | -int | |
56 | -xmon_read(void *handle, void *ptr, int nb) | |
22 | +int xmon_readchar(void) | |
57 | 23 | { |
58 | - return udbg_read(ptr, nb); | |
24 | + if (udbg_getc) | |
25 | + return udbg_getc(); | |
26 | + return -1; | |
59 | 27 | } |
60 | 28 | |
61 | -int | |
62 | -xmon_read_poll(void) | |
29 | +int xmon_read_poll(void) | |
63 | 30 | { |
64 | 31 | if (udbg_getc_poll) |
65 | 32 | return udbg_getc_poll(); |
66 | 33 | return -1; |
67 | -} | |
68 | - | |
69 | -FILE *xmon_stdin; | |
70 | -FILE *xmon_stdout; | |
71 | - | |
72 | -int | |
73 | -xmon_putc(int c, void *f) | |
74 | -{ | |
75 | - char ch = c; | |
76 | - | |
77 | - if (c == '\n') | |
78 | - xmon_putc('\r', f); | |
79 | - return xmon_write(f, &ch, 1) == 1? c: -1; | |
80 | -} | |
81 | - | |
82 | -int | |
83 | -xmon_putchar(int c) | |
84 | -{ | |
85 | - return xmon_putc(c, xmon_stdout); | |
86 | -} | |
87 | - | |
88 | -int | |
89 | -xmon_fputs(char *str, void *f) | |
90 | -{ | |
91 | - int n = strlen(str); | |
92 | - | |
93 | - return xmon_write(f, str, n) == n? 0: -1; | |
94 | -} | |
95 | - | |
96 | -int | |
97 | -xmon_readchar(void) | |
98 | -{ | |
99 | - char ch; | |
100 | - | |
101 | - for (;;) { | |
102 | - switch (xmon_read(xmon_stdin, &ch, 1)) { | |
103 | - case 1: | |
104 | - return ch; | |
105 | - case -1: | |
106 | - xmon_printf("read(stdin) returned -1\r\n", 0, 0); | |
107 | - return -1; | |
108 | - } | |
109 | - } | |
110 | -} | |
111 | - | |
112 | -static char line[256]; | |
113 | -static char *lineptr; | |
114 | -static int lineleft; | |
115 | - | |
116 | -int | |
117 | -xmon_getchar(void) | |
118 | -{ | |
119 | - int c; | |
120 | - | |
121 | - if (lineleft == 0) { | |
122 | - lineptr = line; | |
123 | - for (;;) { | |
124 | - c = xmon_readchar(); | |
125 | - if (c == -1 || c == 4) | |
126 | - break; | |
127 | - if (c == '\r' || c == '\n') { | |
128 | - *lineptr++ = '\n'; | |
129 | - xmon_putchar('\n'); | |
130 | - break; | |
131 | - } | |
132 | - switch (c) { | |
133 | - case 0177: | |
134 | - case '\b': | |
135 | - if (lineptr > line) { | |
136 | - xmon_putchar('\b'); | |
137 | - xmon_putchar(' '); | |
138 | - xmon_putchar('\b'); | |
139 | - --lineptr; | |
140 | - } | |
141 | - break; | |
142 | - case 'U' & 0x1F: | |
143 | - while (lineptr > line) { | |
144 | - xmon_putchar('\b'); | |
145 | - xmon_putchar(' '); | |
146 | - xmon_putchar('\b'); | |
147 | - --lineptr; | |
148 | - } | |
149 | - break; | |
150 | - default: | |
151 | - if (lineptr >= &line[sizeof(line) - 1]) | |
152 | - xmon_putchar('\a'); | |
153 | - else { | |
154 | - xmon_putchar(c); | |
155 | - *lineptr++ = c; | |
156 | - } | |
157 | - } | |
158 | - } | |
159 | - lineleft = lineptr - line; | |
160 | - lineptr = line; | |
161 | - } | |
162 | - if (lineleft == 0) | |
163 | - return -1; | |
164 | - --lineleft; | |
165 | - return *lineptr++; | |
166 | -} | |
167 | - | |
168 | -char * | |
169 | -xmon_fgets(char *str, int nb, void *f) | |
170 | -{ | |
171 | - char *p; | |
172 | - int c; | |
173 | - | |
174 | - for (p = str; p < str + nb - 1; ) { | |
175 | - c = xmon_getchar(); | |
176 | - if (c == -1) { | |
177 | - if (p == str) | |
178 | - return NULL; | |
179 | - break; | |
180 | - } | |
181 | - *p++ = c; | |
182 | - if (c == '\n') | |
183 | - break; | |
184 | - } | |
185 | - *p = 0; | |
186 | - return str; | |
187 | 34 | } |
arch/powerpc/xmon/start_8xx.c
... | ... | @@ -15,274 +15,31 @@ |
15 | 15 | #include <asm/8xx_immap.h> |
16 | 16 | #include <asm/mpc8xx.h> |
17 | 17 | #include <asm/commproc.h> |
18 | +#include "nonstdio.h" | |
18 | 19 | |
19 | -extern void xmon_printf(const char *fmt, ...); | |
20 | 20 | extern int xmon_8xx_write(char *str, int nb); |
21 | 21 | extern int xmon_8xx_read_poll(void); |
22 | 22 | extern int xmon_8xx_read_char(void); |
23 | -void prom_drawhex(uint); | |
24 | -void prom_drawstring(const char *str); | |
25 | 23 | |
26 | -static int use_screen = 1; /* default */ | |
27 | - | |
28 | -#define TB_SPEED 25000000 | |
29 | - | |
30 | -static inline unsigned int readtb(void) | |
24 | +void xmon_map_scc(void) | |
31 | 25 | { |
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 | 26 | cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); |
47 | - use_screen = 0; | |
48 | - | |
49 | - prom_drawstring("xmon uses serial port\n"); | |
50 | 27 | } |
51 | 28 | |
52 | -static int scc_initialized = 0; | |
53 | - | |
54 | 29 | void xmon_init_scc(void); |
55 | 30 | |
56 | -int | |
57 | -xmon_write(void *handle, void *ptr, int nb) | |
31 | +int xmon_write(void *ptr, int nb) | |
58 | 32 | { |
59 | - char *p = ptr; | |
60 | - int i, c, ct; | |
61 | - | |
62 | - if (!scc_initialized) | |
63 | - xmon_init_scc(); | |
64 | - | |
65 | 33 | return(xmon_8xx_write(ptr, nb)); |
66 | 34 | } |
67 | 35 | |
68 | -int xmon_wants_key; | |
69 | - | |
70 | -int | |
71 | -xmon_read(void *handle, void *ptr, int nb) | |
36 | +int xmon_readchar(void) | |
72 | 37 | { |
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; | |
38 | + return xmon_8xx_read_char(); | |
83 | 39 | } |
84 | 40 | |
85 | -int | |
86 | -xmon_read_poll(void) | |
41 | +int xmon_read_poll(void) | |
87 | 42 | { |
88 | 43 | 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 | 44 | } |
arch/powerpc/xmon/subr_prf.c
1 | -/* | |
2 | - * Written by Cort Dougan to replace the version originally used | |
3 | - * by Paul Mackerras, which came from NetBSD and thus had copyright | |
4 | - * conflicts with Linux. | |
5 | - * | |
6 | - * This file makes liberal use of the standard linux utility | |
7 | - * routines to reduce the size of the binary. We assume we can | |
8 | - * trust some parts of Linux inside the debugger. | |
9 | - * -- Cort (cort@cs.nmt.edu) | |
10 | - * | |
11 | - * Copyright (C) 1999 Cort Dougan. | |
12 | - * | |
13 | - * This program is free software; you can redistribute it and/or | |
14 | - * modify it under the terms of the GNU General Public License | |
15 | - * as published by the Free Software Foundation; either version | |
16 | - * 2 of the License, or (at your option) any later version. | |
17 | - */ | |
18 | - | |
19 | -#include <linux/kernel.h> | |
20 | -#include <linux/string.h> | |
21 | -#include <linux/module.h> | |
22 | -#include <stdarg.h> | |
23 | -#include "nonstdio.h" | |
24 | - | |
25 | -extern int xmon_write(void *, void *, int); | |
26 | - | |
27 | -void xmon_vfprintf(void *f, const char *fmt, va_list ap) | |
28 | -{ | |
29 | - static char xmon_buf[2048]; | |
30 | - int n; | |
31 | - | |
32 | - n = vsprintf(xmon_buf, fmt, ap); | |
33 | - xmon_write(f, xmon_buf, n); | |
34 | -} | |
35 | - | |
36 | -void xmon_printf(const char *fmt, ...) | |
37 | -{ | |
38 | - va_list ap; | |
39 | - | |
40 | - va_start(ap, fmt); | |
41 | - xmon_vfprintf(stdout, fmt, ap); | |
42 | - va_end(ap); | |
43 | -} | |
44 | -EXPORT_SYMBOL(xmon_printf); | |
45 | - | |
46 | -void xmon_fprintf(void *f, const char *fmt, ...) | |
47 | -{ | |
48 | - va_list ap; | |
49 | - | |
50 | - va_start(ap, fmt); | |
51 | - xmon_vfprintf(f, fmt, ap); | |
52 | - va_end(ap); | |
53 | -} |
arch/powerpc/xmon/xmon.c
1 | 1 | /* |
2 | 2 | * Routines providing a simple monitor for use on the PowerMac. |
3 | 3 | * |
4 | - * Copyright (C) 1996 Paul Mackerras. | |
4 | + * Copyright (C) 1996-2005 Paul Mackerras. | |
5 | 5 | * |
6 | 6 | * This program is free software; you can redistribute it and/or |
7 | 7 | * modify it under the terms of the GNU General Public License |
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | #include <linux/kallsyms.h> |
19 | 19 | #include <linux/cpumask.h> |
20 | 20 | #include <linux/module.h> |
21 | +#include <linux/sysrq.h> | |
21 | 22 | |
22 | 23 | #include <asm/ptrace.h> |
23 | 24 | #include <asm/string.h> |
24 | 25 | |
... | ... | @@ -144,15 +145,10 @@ |
144 | 145 | static const char *getvecname(unsigned long vec); |
145 | 146 | |
146 | 147 | extern int print_insn_powerpc(unsigned long, unsigned long, int); |
147 | -extern void printf(const char *fmt, ...); | |
148 | -extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); | |
149 | -extern int xmon_putc(int c, void *f); | |
150 | -extern int putchar(int ch); | |
151 | 148 | |
152 | 149 | extern void xmon_enter(void); |
153 | 150 | extern void xmon_leave(void); |
154 | 151 | |
155 | -extern int xmon_read_poll(void); | |
156 | 152 | extern long setjmp(long *); |
157 | 153 | extern void longjmp(long *, long); |
158 | 154 | extern void xmon_save_regs(struct pt_regs *); |
... | ... | @@ -748,7 +744,6 @@ |
748 | 744 | printf("%x:", smp_processor_id()); |
749 | 745 | #endif /* CONFIG_SMP */ |
750 | 746 | printf("mon> "); |
751 | - fflush(stdout); | |
752 | 747 | flush_input(); |
753 | 748 | termch = 0; |
754 | 749 | cmd = skipbl(); |
... | ... | @@ -2151,7 +2146,6 @@ |
2151 | 2146 | ok = mread(a, &v, 1); |
2152 | 2147 | if (ok && !ook) { |
2153 | 2148 | printf("%.8x .. ", a); |
2154 | - fflush(stdout); | |
2155 | 2149 | } else if (!ok && ook) |
2156 | 2150 | printf("%.8x\n", a - mskip); |
2157 | 2151 | ook = ok; |
... | ... | @@ -2372,7 +2366,7 @@ |
2372 | 2366 | inchar(void) |
2373 | 2367 | { |
2374 | 2368 | if (lineptr == NULL || *lineptr == 0) { |
2375 | - if (fgets(line, sizeof(line), stdin) == NULL) { | |
2369 | + if (xmon_gets(line, sizeof(line)) == NULL) { | |
2376 | 2370 | lineptr = NULL; |
2377 | 2371 | return EOF; |
2378 | 2372 | } |
2379 | 2373 | |
... | ... | @@ -2526,5 +2520,30 @@ |
2526 | 2520 | __debugger_dabr_match = NULL; |
2527 | 2521 | __debugger_fault_handler = NULL; |
2528 | 2522 | } |
2523 | + xmon_map_scc(); | |
2529 | 2524 | } |
2525 | + | |
2526 | +#ifdef CONFIG_MAGIC_SYSRQ | |
2527 | +static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, | |
2528 | + struct tty_struct *tty) | |
2529 | +{ | |
2530 | + /* ensure xmon is enabled */ | |
2531 | + xmon_init(1); | |
2532 | + debugger(pt_regs); | |
2533 | +} | |
2534 | + | |
2535 | +static struct sysrq_key_op sysrq_xmon_op = | |
2536 | +{ | |
2537 | + .handler = sysrq_handle_xmon, | |
2538 | + .help_msg = "Xmon", | |
2539 | + .action_msg = "Entering xmon", | |
2540 | +}; | |
2541 | + | |
2542 | +static int __init setup_xmon_sysrq(void) | |
2543 | +{ | |
2544 | + register_sysrq_key('x', &sysrq_xmon_op); | |
2545 | + return 0; | |
2546 | +} | |
2547 | +__initcall(setup_xmon_sysrq); | |
2548 | +#endif /* CONFIG_MAGIC_SYSRQ */ |