linux/arch/powerpc/xmon/nonstdio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 1996-2005 Paul Mackerras.
   4 */
   5#include <linux/string.h>
   6#include <asm/udbg.h>
   7#include <asm/time.h>
   8#include "nonstdio.h"
   9
  10static bool paginating, paginate_skipping;
  11static unsigned long paginate_lpp; /* Lines Per Page */
  12static unsigned long paginate_pos;
  13
  14void xmon_start_pagination(void)
  15{
  16        paginating = true;
  17        paginate_skipping = false;
  18        paginate_pos = 0;
  19}
  20
  21void xmon_end_pagination(void)
  22{
  23        paginating = false;
  24}
  25
  26void xmon_set_pagination_lpp(unsigned long lpp)
  27{
  28        paginate_lpp = lpp;
  29}
  30
  31static int xmon_readchar(void)
  32{
  33        if (udbg_getc)
  34                return udbg_getc();
  35        return -1;
  36}
  37
  38static int xmon_write(const char *ptr, int nb)
  39{
  40        int rv = 0;
  41        const char *p = ptr, *q;
  42        const char msg[] = "[Hit a key (a:all, q:truncate, any:next page)]";
  43
  44        if (nb <= 0)
  45                return rv;
  46
  47        if (paginating && paginate_skipping)
  48                return nb;
  49
  50        if (paginate_lpp) {
  51                while (paginating && (q = strchr(p, '\n'))) {
  52                        rv += udbg_write(p, q - p + 1);
  53                        p = q + 1;
  54                        paginate_pos++;
  55
  56                        if (paginate_pos >= paginate_lpp) {
  57                                udbg_write(msg, strlen(msg));
  58
  59                                switch (xmon_readchar()) {
  60                                case 'a':
  61                                        paginating = false;
  62                                        break;
  63                                case 'q':
  64                                        paginate_skipping = true;
  65                                        break;
  66                                default:
  67                                        /* nothing */
  68                                        break;
  69                                }
  70
  71                                paginate_pos = 0;
  72                                udbg_write("\r\n", 2);
  73
  74                                if (paginate_skipping)
  75                                        return nb;
  76                        }
  77                }
  78        }
  79
  80        return rv + udbg_write(p, nb - (p - ptr));
  81}
  82
  83int xmon_putchar(int c)
  84{
  85        char ch = c;
  86
  87        if (c == '\n')
  88                xmon_putchar('\r');
  89        return xmon_write(&ch, 1) == 1? c: -1;
  90}
  91
  92static char line[256];
  93static char *lineptr;
  94static int lineleft;
  95
  96static int xmon_getchar(void)
  97{
  98        int c;
  99
 100        if (lineleft == 0) {
 101                lineptr = line;
 102                for (;;) {
 103                        c = xmon_readchar();
 104                        if (c == -1 || c == 4)
 105                                break;
 106                        if (c == '\r' || c == '\n') {
 107                                *lineptr++ = '\n';
 108                                xmon_putchar('\n');
 109                                break;
 110                        }
 111                        switch (c) {
 112                        case 0177:
 113                        case '\b':
 114                                if (lineptr > line) {
 115                                        xmon_putchar('\b');
 116                                        xmon_putchar(' ');
 117                                        xmon_putchar('\b');
 118                                        --lineptr;
 119                                }
 120                                break;
 121                        case 'U' & 0x1F:
 122                                while (lineptr > line) {
 123                                        xmon_putchar('\b');
 124                                        xmon_putchar(' ');
 125                                        xmon_putchar('\b');
 126                                        --lineptr;
 127                                }
 128                                break;
 129                        default:
 130                                if (lineptr >= &line[sizeof(line) - 1])
 131                                        xmon_putchar('\a');
 132                                else {
 133                                        xmon_putchar(c);
 134                                        *lineptr++ = c;
 135                                }
 136                        }
 137                }
 138                lineleft = lineptr - line;
 139                lineptr = line;
 140        }
 141        if (lineleft == 0)
 142                return -1;
 143        --lineleft;
 144        return *lineptr++;
 145}
 146
 147char *xmon_gets(char *str, int nb)
 148{
 149        char *p;
 150        int c;
 151
 152        for (p = str; p < str + nb - 1; ) {
 153                c = xmon_getchar();
 154                if (c == -1) {
 155                        if (p == str)
 156                                return NULL;
 157                        break;
 158                }
 159                *p++ = c;
 160                if (c == '\n')
 161                        break;
 162        }
 163        *p = 0;
 164        return str;
 165}
 166
 167void xmon_printf(const char *format, ...)
 168{
 169        va_list args;
 170        static char xmon_outbuf[1024];
 171        int rc, n;
 172
 173        va_start(args, format);
 174        n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
 175        va_end(args);
 176
 177        rc = xmon_write(xmon_outbuf, n);
 178
 179        if (n && rc == 0) {
 180                /* No udbg hooks, fallback to printk() - dangerous */
 181                pr_cont("%s", xmon_outbuf);
 182        }
 183}
 184
 185void xmon_puts(const char *str)
 186{
 187        xmon_write(str, strlen(str));
 188}
 189