diff options
author | Paul Mackerras <paulus@samba.org> | 2005-11-08 22:55:08 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-11-08 22:55:08 +1100 |
commit | fca5dcd4835ed09bb1a48a355344aff7a25c76e0 (patch) | |
tree | b596fad4509d3208ef974b9e22b2326ecfd85b83 /arch/powerpc | |
parent | 3825ac0ee66b50cb0208ee74796fe65f3040e67c (diff) |
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>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/kernel/setup-common.c | 21 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 20 | ||||
-rw-r--r-- | arch/powerpc/xmon/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/xmon/nonstdio.c | 134 | ||||
-rw-r--r-- | arch/powerpc/xmon/nonstdio.h | 28 | ||||
-rw-r--r-- | arch/powerpc/xmon/start_32.c | 235 | ||||
-rw-r--r-- | arch/powerpc/xmon/start_64.c | 167 | ||||
-rw-r--r-- | arch/powerpc/xmon/start_8xx.c | 255 | ||||
-rw-r--r-- | arch/powerpc/xmon/subr_prf.c | 54 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 37 |
11 files changed, 236 insertions, 728 deletions
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index e22856ecb5a..26bb1fe6384 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -51,6 +51,7 @@ #include <asm/page.h> #include <asm/mmu.h> #include <asm/lmb.h> +#include <asm/xmon.h> #undef DEBUG @@ -559,3 +560,23 @@ void __init smp_setup_cpu_maps(void) #endif /* CONFIG_PPC64 */ } #endif /* CONFIG_SMP */ + +#ifdef CONFIG_XMON +static int __init early_xmon(char *p) +{ + /* ensure xmon is enabled */ + if (p) { + if (strncmp(p, "on", 2) == 0) + xmon_init(1); + if (strncmp(p, "off", 3) == 0) + xmon_init(0); + if (strncmp(p, "early", 5) != 0) + return 0; + } + xmon_init(1); + debugger(NULL); + + return 0; +} +early_param("xmon", early_xmon); +#endif diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 3af2631e3fa..0fbc73f7f82 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -303,14 +303,9 @@ void __init setup_arch(char **cmdline_p) pmac_feature_init(); /* New cool way */ #endif -#ifdef CONFIG_XMON - xmon_map_scc(); - if (strstr(cmd_line, "xmon")) { - xmon_init(1); - debugger(NULL); - } -#endif /* CONFIG_XMON */ - if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); +#ifdef CONFIG_XMON_DEFAULT + xmon_init(1); +#endif #if defined(CONFIG_KGDB) if (ppc_md.kgdb_map_scc) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 0471e843b6c..54c606f680b 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -858,26 +858,6 @@ int check_legacy_ioport(unsigned long base_port) } EXPORT_SYMBOL(check_legacy_ioport); -#ifdef CONFIG_XMON -static int __init early_xmon(char *p) -{ - /* ensure xmon is enabled */ - if (p) { - if (strncmp(p, "on", 2) == 0) - xmon_init(1); - if (strncmp(p, "off", 3) == 0) - xmon_init(0); - if (strncmp(p, "early", 5) != 0) - return 0; - } - xmon_init(1); - debugger(NULL); - - return 0; -} -early_param("xmon", early_xmon); -#endif - void cpu_die(void) { if (ppc_md.cpu_die) diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 79a784f0e7a..b20312e5ed2 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -8,4 +8,4 @@ obj-$(CONFIG_8xx) += start_8xx.o obj-$(CONFIG_6xx) += start_32.o obj-$(CONFIG_4xx) += start_32.o obj-$(CONFIG_PPC64) += start_64.o -obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o +obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c new file mode 100644 index 00000000000..78765833f4c --- /dev/null +++ b/arch/powerpc/xmon/nonstdio.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 1996-2005 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <linux/string.h> +#include <asm/time.h> +#include "nonstdio.h" + +int xmon_putchar(int c) +{ + char ch = c; + + if (c == '\n') + xmon_putchar('\r'); + return xmon_write(&ch, 1) == 1? c: -1; +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +int xmon_expect(const char *str, unsigned long timeout) +{ + int c; + unsigned long t0; + + /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */ + timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000; + t0 = get_tbl(); + do { + lineptr = line; + for (;;) { + c = xmon_read_poll(); + if (c == -1) { + if (get_tbl() - t0 > timeout) + return 0; + continue; + } + if (c == '\n') + break; + if (c != '\r' && lineptr < &line[sizeof(line) - 1]) + *lineptr++ = c; + } + *lineptr = 0; + } while (strstr(line, str) == NULL); + return 1; +} + +int xmon_getchar(void) +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = xmon_readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + xmon_putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + xmon_putchar('\b'); + xmon_putchar(' '); + xmon_putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + xmon_putchar('\b'); + xmon_putchar(' '); + xmon_putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + xmon_putchar('\a'); + else { + xmon_putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +char *xmon_gets(char *str, int nb) +{ + char *p; + int c; + + for (p = str; p < str + nb - 1; ) { + c = xmon_getchar(); + if (c == -1) { + if (p == str) + return NULL; + break; + } + *p++ = c; + if (c == '\n') + break; + } + *p = 0; + return str; +} + +void xmon_printf(const char *format, ...) +{ + va_list args; + int n; + static char xmon_outbuf[1024]; + + va_start(args, format); + n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args); + va_end(args); + xmon_write(xmon_outbuf, n); +} diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h index 84211a21c6f..47cebbd2b1b 100644 --- a/arch/powerpc/xmon/nonstdio.h +++ b/arch/powerpc/xmon/nonstdio.h @@ -1,22 +1,14 @@ -typedef int FILE; -extern FILE *xmon_stdin, *xmon_stdout; #define EOF (-1) -#define stdin xmon_stdin -#define stdout xmon_stdout + #define printf xmon_printf -#define fprintf xmon_fprintf -#define fputs xmon_fputs -#define fgets xmon_fgets #define putchar xmon_putchar -#define getchar xmon_getchar -#define putc xmon_putc -#define getc xmon_getc -#define fopen(n, m) NULL -#define fflush(f) do {} while (0) -#define fclose(f) do {} while (0) -extern char *fgets(char *, int, void *); -extern void xmon_printf(const char *, ...); -extern void xmon_fprintf(void *, const char *, ...); -extern void xmon_sprintf(char *, const char *, ...); -#define perror(s) printf("%s: no files!\n", (s)) +extern int xmon_putchar(int c); +extern int xmon_getchar(void); +extern char *xmon_gets(char *, int); +extern void xmon_printf(const char *, ...); +extern void xmon_map_scc(void); +extern int xmon_expect(const char *str, unsigned long timeout); +extern int xmon_write(void *ptr, int nb); +extern int xmon_readchar(void); +extern int xmon_read_poll(void); diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c index 69b658c0f76..c2464df4217 100644 --- a/arch/powerpc/xmon/start_32.c +++ b/arch/powerpc/xmon/start_32.c @@ -11,7 +11,6 @@ #include <linux/cuda.h> #include <linux/kernel.h> #include <linux/errno.h> -#include <linux/sysrq.h> #include <linux/bitops.h> #include <asm/xmon.h> #include <asm/prom.h> @@ -22,10 +21,11 @@ #include <asm/processor.h> #include <asm/delay.h> #include <asm/btext.h> +#include <asm/time.h> +#include "nonstdio.h" static volatile unsigned char __iomem *sccc, *sccd; unsigned int TXRDY, RXRDY, DLAB; -static int xmon_expect(const char *str, unsigned int timeout); static int use_serial; static int use_screen; @@ -33,16 +33,6 @@ static int via_modem; static int xmon_use_sccb; static struct device_node *channel_node; -#define TB_SPEED 25000000 - -static inline unsigned int readtb(void) -{ - unsigned int ret; - - asm volatile("mftb %0" : "=r" (ret) :); - return ret; -} - void buf_access(void) { if (DLAB) @@ -91,23 +81,7 @@ static unsigned long chrp_find_phys_io_base(void) } #endif /* CONFIG_PPC_CHRP */ -#ifdef CONFIG_MAGIC_SYSRQ -static void sysrq_handle_xmon(int key, struct pt_regs *regs, - struct tty_struct *tty) -{ - xmon(regs); -} - -static struct sysrq_key_op sysrq_xmon_op = -{ - .handler = sysrq_handle_xmon, - .help_msg = "Xmon", - .action_msg = "Entering xmon", -}; -#endif - -void -xmon_map_scc(void) +void xmon_map_scc(void) { #ifdef CONFIG_PPC_MULTIPLATFORM volatile unsigned char __iomem *base; @@ -217,8 +191,6 @@ xmon_map_scc(void) RXRDY = 1; DLAB = 0x80; #endif /* platform */ - - register_sysrq_key('x', &sysrq_xmon_op); } static int scc_initialized = 0; @@ -238,8 +210,7 @@ static inline void do_poll_adb(void) #endif /* CONFIG_ADB_CUDA */ } -int -xmon_write(void *handle, void *ptr, int nb) +int xmon_write(void *ptr, int nb) { char *p = ptr; int i, c, ct; @@ -311,8 +282,7 @@ static unsigned char xmon_shift_keytab[128] = "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ -static int -xmon_get_adb_key(void) +static int xmon_get_adb_key(void) { int k, t, on; @@ -350,32 +320,21 @@ xmon_get_adb_key(void) } #endif /* CONFIG_BOOTX_TEXT */ -int -xmon_read(void *handle, void *ptr, int nb) +int xmon_readchar(void) { - char *p = ptr; - int i; - #ifdef CONFIG_BOOTX_TEXT - if (use_screen) { - for (i = 0; i < nb; ++i) - *p++ = xmon_get_adb_key(); - return i; - } + if (use_screen) + return xmon_get_adb_key(); #endif - if (!scc_initialized) - xmon_init_scc(); - for (i = 0; i < nb; ++i) { + if (!scc_initialized) + xmon_init_scc(); while ((*sccc & RXRDY) == 0) - do_poll_adb(); + do_poll_adb(); buf_access(); - *p++ = *sccd; - } - return i; + return *sccd; } -int -xmon_read_poll(void) +int xmon_read_poll(void) { if ((*sccc & RXRDY) == 0) { do_poll_adb(); @@ -395,8 +354,7 @@ static unsigned char scc_inittab[] = { 3, 0xc1, /* rx enable, 8 bits */ }; -void -xmon_init_scc(void) +void xmon_init_scc(void) { if ( _machine == _MACH_chrp ) { @@ -410,6 +368,7 @@ xmon_init_scc(void) else if ( _machine == _MACH_Pmac ) { int i, x; + unsigned long timeout; if (channel_node != 0) pmac_call_feature( @@ -424,8 +383,12 @@ xmon_init_scc(void) PMAC_FTR_MODEM_ENABLE, channel_node, 0, 1); printk(KERN_INFO "Modem powered up by debugger !\n"); - t0 = readtb(); - while (readtb() - t0 < 3*TB_SPEED) + t0 = get_tbl(); + timeout = 3 * tb_ticks_per_sec; + if (timeout == 0) + /* assume 25MHz if tb_ticks_per_sec not set */ + timeout = 75000000; + while (get_tbl() - t0 < timeout) eieio(); } /* use the B channel if requested */ @@ -447,164 +410,19 @@ xmon_init_scc(void) scc_initialized = 1; if (via_modem) { for (;;) { - xmon_write(NULL, "ATE1V1\r", 7); + xmon_write("ATE1V1\r", 7); if (xmon_expect("OK", 5)) { - xmon_write(NULL, "ATA\r", 4); + xmon_write("ATA\r", 4); if (xmon_expect("CONNECT", 40)) break; } - xmon_write(NULL, "+++", 3); + xmon_write("+++", 3); xmon_expect("OK", 3); } } } -void *xmon_stdin; -void *xmon_stdout; -void *xmon_stderr; - -int xmon_putc(int c, void *f) -{ - char ch = c; - - if (c == '\n') - xmon_putc('\r', f); - return xmon_write(f, &ch, 1) == 1? c: -1; -} - -int xmon_putchar(int c) -{ - return xmon_putc(c, xmon_stdout); -} - -int xmon_fputs(char *str, void *f) -{ - int n = strlen(str); - - return xmon_write(f, str, n) == n? 0: -1; -} - -int -xmon_readchar(void) -{ - char ch; - - for (;;) { - switch (xmon_read(xmon_stdin, &ch, 1)) { - case 1: - return ch; - case -1: - xmon_printf("read(stdin) returned -1\r\n", 0, 0); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -int xmon_expect(const char *str, unsigned int timeout) -{ - int c; - unsigned int t0; - - timeout *= TB_SPEED; - t0 = readtb(); - do { - lineptr = line; - for (;;) { - c = xmon_read_poll(); - if (c == -1) { - if (readtb() - t0 > timeout) - return 0; - continue; - } - if (c == '\n') - break; - if (c != '\r' && lineptr < &line[sizeof(line) - 1]) - *lineptr++ = c; - } - *lineptr = 0; - } while (strstr(line, str) == NULL); - return 1; -} - -int -xmon_getchar(void) -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = xmon_readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - xmon_putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - xmon_putchar('\b'); - xmon_putchar(' '); - xmon_putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - xmon_putchar('\b'); - xmon_putchar(' '); - xmon_putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - xmon_putchar('\a'); - else { - xmon_putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - -char * -xmon_fgets(char *str, int nb, void *f) -{ - char *p; - int c; - - for (p = str; p < str + nb - 1; ) { - c = xmon_getchar(); - if (c == -1) { - if (p == str) - return NULL; - break; - } - *p++ = c; - if (c == '\n') - break; - } - *p = 0; - return str; -} - -void -xmon_enter(void) +void xmon_enter(void) { #ifdef CONFIG_ADB_PMU if (_machine == _MACH_Pmac) { @@ -613,8 +431,7 @@ xmon_enter(void) #endif } -void -xmon_leave(void) +void xmon_leave(void) { #ifdef CONFIG_ADB_PMU if (_machine == _MACH_Pmac) { diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start_64.c index e50c158191e..712552c4f24 100644 --- a/arch/powerpc/xmon/start_64.c +++ b/arch/powerpc/xmon/start_64.c @@ -6,182 +6,29 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/sysrq.h> -#include <linux/init.h> #include <asm/machdep.h> -#include <asm/io.h> -#include <asm/page.h> -#include <asm/prom.h> -#include <asm/processor.h> #include <asm/udbg.h> -#include <asm/system.h> #include "nonstdio.h" -#ifdef CONFIG_MAGIC_SYSRQ - -static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, - struct tty_struct *tty) -{ - /* ensure xmon is enabled */ - xmon_init(1); - debugger(pt_regs); -} - -static struct sysrq_key_op sysrq_xmon_op = +void xmon_map_scc(void) { - .handler = sysrq_handle_xmon, - .help_msg = "Xmon", - .action_msg = "Entering xmon", -}; - -static int __init setup_xmon_sysrq(void) -{ - register_sysrq_key('x', &sysrq_xmon_op); - return 0; } -__initcall(setup_xmon_sysrq); -#endif /* CONFIG_MAGIC_SYSRQ */ -int -xmon_write(void *handle, void *ptr, int nb) +int xmon_write(void *ptr, int nb) { return udbg_write(ptr, nb); } -int -xmon_read(void *handle, void *ptr, int nb) +int xmon_readchar(void) { - return udbg_read(ptr, nb); + if (udbg_getc) + return udbg_getc(); + return -1; } -int -xmon_read_poll(void) +int xmon_read_poll(void) { if (udbg_getc_poll) return udbg_getc_poll(); return -1; } - -FILE *xmon_stdin; -FILE *xmon_stdout; - -int -xmon_putc(int c, void *f) -{ - char ch = c; - - if (c == '\n') - xmon_putc('\r', f); - return xmon_write(f, &ch, 1) == 1? c: -1; -} - -int -xmon_putchar(int c) -{ - return xmon_putc(c, xmon_stdout); -} - -int -xmon_fputs(char *str, void *f) -{ - int n = strlen(str); - - return xmon_write(f, str, n) == n? 0: -1; -} - -int -xmon_readchar(void) -{ - char ch; - - for (;;) { - switch (xmon_read(xmon_stdin, &ch, 1)) { - case 1: - return ch; - case -1: - xmon_printf("read(stdin) returned -1\r\n", 0, 0); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -int -xmon_getchar(void) -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = xmon_readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - xmon_putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - xmon_putchar('\b'); - xmon_putchar(' '); - xmon_putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - xmon_putchar('\b'); - xmon_putchar(' '); - xmon_putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - xmon_putchar('\a'); - else { - xmon_putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - -char * -xmon_fgets(char *str, int nb, void *f) -{ - char *p; - int c; - - for (p = str; p < str + nb - 1; ) { - c = xmon_getchar(); - if (c == -1) { - if (p == str) - return NULL; - break; - } - *p++ = c; - if (c == '\n') - break; - } - *p = 0; - return str; -} diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c index a48bd594cf6..4c17b0486ad 100644 --- a/arch/powerpc/xmon/start_8xx.c +++ b/arch/powerpc/xmon/start_8xx.c @@ -15,273 +15,30 @@ #include <asm/8xx_immap.h> #include <asm/mpc8xx.h> #include <asm/commproc.h> +#include "nonstdio.h" -extern void xmon_printf(const char *fmt, ...); extern int xmon_8xx_write(char *str, int nb); extern int xmon_8xx_read_poll(void); extern int xmon_8xx_read_char(void); -void prom_drawhex(uint); -void prom_drawstring(const char *str); -static int use_screen = 1; /* default */ - -#define TB_SPEED 25000000 - -static inline unsigned int readtb(void) -{ - unsigned int ret; - - asm volatile("mftb %0" : "=r" (ret) :); - return ret; -} - -void buf_access(void) -{ -} - -void -xmon_map_scc(void) +void xmon_map_scc(void) { - cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); - use_screen = 0; - - prom_drawstring("xmon uses serial port\n"); } -static int scc_initialized = 0; - void xmon_init_scc(void); -int -xmon_write(void *handle, void *ptr, int nb) +int xmon_write(void *ptr, int nb) { - char *p = ptr; - int i, c, ct; - - if (!scc_initialized) - xmon_init_scc(); - return(xmon_8xx_write(ptr, nb)); } -int xmon_wants_key; - -int -xmon_read(void *handle, void *ptr, int nb) +int xmon_readchar(void) { - char *p = ptr; - int i; - - if (!scc_initialized) - xmon_init_scc(); - - for (i = 0; i < nb; ++i) { - *p++ = xmon_8xx_read_char(); - } - return i; + return xmon_8xx_read_char(); } -int -xmon_read_poll(void) +int xmon_read_poll(void) { return(xmon_8xx_read_poll()); } - -void -xmon_init_scc() -{ - scc_initialized = 1; -} - -#if 0 -extern int (*prom_entry)(void *); - -int -xmon_exit(void) -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom_entry)(&args); - } -} -#endif - -void *xmon_stdin; -void *xmon_stdout; -void *xmon_stderr; - -void -xmon_init(void) -{ -} - -int -xmon_putc(int c, void *f) -{ - char ch = c; - - if (c == '\n') - xmon_putc('\r', f); - return xmon_write(f, &ch, 1) == 1? c: -1; -} - -int -xmon_putchar(int c) -{ - return xmon_putc(c, xmon_stdout); -} - -int -xmon_fputs(char *str, void *f) -{ - int n = strlen(str); - - return xmon_write(f, str, n) == n? 0: -1; -} - -int -xmon_readchar(void) -{ - char ch; - - for (;;) { - switch (xmon_read(xmon_stdin, &ch, 1)) { - case 1: - return ch; - case -1: - xmon_printf("read(stdin) returned -1\r\n", 0, 0); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -#if 0 -int xmon_expect(const char *str, unsigned int timeout) -{ - int c; - unsigned int t0; - - timeout *= TB_SPEED; - t0 = readtb(); - do { - lineptr = line; - for (;;) { - c = xmon_read_poll(); - if (c == -1) { - if (readtb() - t0 > timeout) - return 0; - continue; - } - if (c == '\n') - break; - if (c != '\r' && lineptr < &line[sizeof(line) - 1]) - *lineptr++ = c; - } - *lineptr = 0; - } while (strstr(line, str) == NULL); - return 1; -} -#endif - -int -xmon_getchar(void) -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = xmon_readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - xmon_putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - xmon_putchar('\b'); - xmon_putchar(' '); - xmon_putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - xmon_putchar('\b'); - xmon_putchar(' '); - xmon_putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - xmon_putchar('\a'); - else { - xmon_putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - -char * -xmon_fgets(char *str, int nb, void *f) -{ - char *p; - int c; - - for (p = str; p < str + nb - 1; ) { - c = xmon_getchar(); - if (c == -1) { - if (p == str) - return 0; - break; - } - *p++ = c; - if (c == '\n') - break; - } - *p = 0; - return str; -} - -void -prom_drawhex(uint val) -{ - unsigned char buf[10]; - - int i; - for (i = 7; i >= 0; i--) - { - buf[i] = "0123456789abcdef"[val & 0x0f]; - val >>= 4; - } - buf[8] = '\0'; - xmon_fputs(buf, xmon_stdout); -} - -void -prom_drawstring(const char *str) -{ - xmon_fputs(str, xmon_stdout); -} diff --git a/arch/powerpc/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c deleted file mode 100644 index b48738c6dd3..00000000000 --- a/arch/powerpc/xmon/subr_prf.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Written by Cort Dougan to replace the version originally used - * by Paul Mackerras, which came from NetBSD and thus had copyright - * conflicts with Linux. - * - * This file makes liberal use of the standard linux utility - * routines to reduce the size of the binary. We assume we can - * trust some parts of Linux inside the debugger. - * -- Cort (cort@cs.nmt.edu) - * - * Copyright (C) 1999 Cort Dougan. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/module.h> -#include <stdarg.h> -#include "nonstdio.h" - -extern int xmon_write(void *, void *, int); - -void xmon_vfprintf(void *f, const char *fmt, va_list ap) -{ - static char xmon_buf[2048]; - int n; - - n = vsprintf(xmon_buf, fmt, ap); - xmon_write(f, xmon_buf, n); -} - -void xmon_printf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - xmon_vfprintf(stdout, fmt, ap); - va_end(ap); -} -EXPORT_SYMBOL(xmon_printf); - -void xmon_fprintf(void *f, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - xmon_vfprintf(f, fmt, ap); - va_end(ap); -} - diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 1124f114620..b43a57425ea 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1,7 +1,7 @@ /* * Routines providing a simple monitor for use on the PowerMac. * - * Copyright (C) 1996 Paul Mackerras. + * Copyright (C) 1996-2005 Paul Mackerras. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,6 +18,7 @@ #include <linux/kallsyms.h> #include <linux/cpumask.h> #include <linux/module.h> +#include <linux/sysrq.h> #include <asm/ptrace.h> #include <asm/string.h> @@ -144,15 +145,10 @@ static void xmon_print_symbol(unsigned long address, const char *mid, static const char *getvecname(unsigned long vec); extern int print_insn_powerpc(unsigned long, unsigned long, int); -extern void printf(const char *fmt, ...); -extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); -extern int xmon_putc(int c, void *f); -extern int putchar(int ch); extern void xmon_enter(void); extern void xmon_leave(void); -extern int xmon_read_poll(void); extern long setjmp(long *); extern void longjmp(long *, long); extern void xmon_save_regs(struct pt_regs *); @@ -748,7 +744,6 @@ cmds(struct pt_regs *excp) printf("%x:", smp_processor_id()); #endif /* CONFIG_SMP */ printf("mon> "); - fflush(stdout); flush_input(); termch = 0; cmd = skipbl(); @@ -2151,7 +2146,6 @@ memzcan(void) ok = mread(a, &v, 1); if (ok && !ook) { printf("%.8x .. ", a); - fflush(stdout); } else if (!ok && ook) printf("%.8x\n", a - mskip); ook = ok; @@ -2372,7 +2366,7 @@ int inchar(void) { if (lineptr == NULL || *lineptr == 0) { - if (fgets(line, sizeof(line), stdin) == NULL) { + if (xmon_gets(line, sizeof(line)) == NULL) { lineptr = NULL; return EOF; } @@ -2526,4 +2520,29 @@ void xmon_init(int enable) __debugger_dabr_match = NULL; __debugger_fault_handler = NULL; } + xmon_map_scc(); } + +#ifdef CONFIG_MAGIC_SYSRQ +static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + /* ensure xmon is enabled */ + xmon_init(1); + debugger(pt_regs); +} + +static struct sysrq_key_op sysrq_xmon_op = +{ + .handler = sysrq_handle_xmon, + .help_msg = "Xmon", + .action_msg = "Entering xmon", +}; + +static int __init setup_xmon_sysrq(void) +{ + register_sysrq_key('x', &sysrq_xmon_op); + return 0; +} +__initcall(setup_xmon_sysrq); +#endif /* CONFIG_MAGIC_SYSRQ */ |