diff options
-rw-r--r-- | arch/powerpc/xmon/nonstdio.c | 64 | ||||
-rw-r--r-- | arch/powerpc/xmon/nonstdio.h | 3 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 18 |
3 files changed, 83 insertions, 2 deletions
diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c index c98748617896..d00123421e00 100644 --- a/arch/powerpc/xmon/nonstdio.c +++ b/arch/powerpc/xmon/nonstdio.c @@ -11,10 +11,25 @@ #include <asm/time.h> #include "nonstdio.h" +static bool paginating, paginate_skipping; +static unsigned long paginate_lpp; /* Lines Per Page */ +static unsigned long paginate_pos; -static int xmon_write(const void *ptr, int nb) +void xmon_start_pagination(void) { - return udbg_write(ptr, nb); + paginating = true; + paginate_skipping = false; + paginate_pos = 0; +} + +void xmon_end_pagination(void) +{ + paginating = false; +} + +void xmon_set_pagination_lpp(unsigned long lpp) +{ + paginate_lpp = lpp; } static int xmon_readchar(void) @@ -24,6 +39,51 @@ static int xmon_readchar(void) return -1; } +static int xmon_write(const char *ptr, int nb) +{ + int rv = 0; + const char *p = ptr, *q; + const char msg[] = "[Hit a key (a:all, q:truncate, any:next page)]"; + + if (nb <= 0) + return rv; + + if (paginating && paginate_skipping) + return nb; + + if (paginate_lpp) { + while (paginating && (q = strchr(p, '\n'))) { + rv += udbg_write(p, q - p + 1); + p = q + 1; + paginate_pos++; + + if (paginate_pos >= paginate_lpp) { + udbg_write(msg, strlen(msg)); + + switch (xmon_readchar()) { + case 'a': + paginating = false; + break; + case 'q': + paginate_skipping = true; + break; + default: + /* nothing */ + break; + } + + paginate_pos = 0; + udbg_write("\r\n", 2); + + if (paginate_skipping) + return nb; + } + } + } + + return rv + udbg_write(p, nb - (p - ptr)); +} + int xmon_putchar(int c) { char ch = c; diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h index 18a51ded4ffd..f8653365667e 100644 --- a/arch/powerpc/xmon/nonstdio.h +++ b/arch/powerpc/xmon/nonstdio.h @@ -3,6 +3,9 @@ #define printf xmon_printf #define putchar xmon_putchar +extern void xmon_set_pagination_lpp(unsigned long lpp); +extern void xmon_start_pagination(void); +extern void xmon_end_pagination(void); extern int xmon_putchar(int c); extern void xmon_puts(const char *); extern char *xmon_gets(char *, int); diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 6ef1231c6e9c..f829baf45fd7 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -242,6 +242,9 @@ Commands:\n\ " u dump TLB\n" #endif " ? help\n" +#ifdef CONFIG_PPC64 +" # n limit output to n lines per page (dump paca only)\n" +#endif " zr reboot\n\ zh halt\n" ; @@ -833,6 +836,16 @@ static void remove_cpu_bpts(void) write_ciabr(0); } +static void set_lpp_cmd(void) +{ + unsigned long lpp; + + if (!scanhex(&lpp)) { + printf("Invalid number.\n"); + lpp = 0; + } + xmon_set_pagination_lpp(lpp); +} /* Command interpreting routine */ static char *last_cmd; @@ -924,6 +937,9 @@ cmds(struct pt_regs *excp) case '?': xmon_puts(help_string); break; + case '#': + set_lpp_cmd(); + break; case 'b': bpt_cmds(); break; @@ -2166,7 +2182,9 @@ dump(void) #ifdef CONFIG_PPC64 if (c == 'p') { + xmon_start_pagination(); dump_pacas(); + xmon_end_pagination(); return; } #endif |