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/udbg.h> 11 #include <asm/time.h> 12 #include "nonstdio.h" 13 14 15 static int xmon_write(const void *ptr, int nb) 16 { 17 return udbg_write(ptr, nb); 18 } 19 20 static int xmon_readchar(void) 21 { 22 if (udbg_getc) 23 return udbg_getc(); 24 return -1; 25 } 26 27 int xmon_putchar(int c) 28 { 29 char ch = c; 30 31 if (c == '\n') 32 xmon_putchar('\r'); 33 return xmon_write(&ch, 1) == 1? c: -1; 34 } 35 36 static char line[256]; 37 static char *lineptr; 38 static int lineleft; 39 40 static int xmon_getchar(void) 41 { 42 int c; 43 44 if (lineleft == 0) { 45 lineptr = line; 46 for (;;) { 47 c = xmon_readchar(); 48 if (c == -1 || c == 4) 49 break; 50 if (c == '\r' || c == '\n') { 51 *lineptr++ = '\n'; 52 xmon_putchar('\n'); 53 break; 54 } 55 switch (c) { 56 case 0177: 57 case '\b': 58 if (lineptr > line) { 59 xmon_putchar('\b'); 60 xmon_putchar(' '); 61 xmon_putchar('\b'); 62 --lineptr; 63 } 64 break; 65 case 'U' & 0x1F: 66 while (lineptr > line) { 67 xmon_putchar('\b'); 68 xmon_putchar(' '); 69 xmon_putchar('\b'); 70 --lineptr; 71 } 72 break; 73 default: 74 if (lineptr >= &line[sizeof(line) - 1]) 75 xmon_putchar('\a'); 76 else { 77 xmon_putchar(c); 78 *lineptr++ = c; 79 } 80 } 81 } 82 lineleft = lineptr - line; 83 lineptr = line; 84 } 85 if (lineleft == 0) 86 return -1; 87 --lineleft; 88 return *lineptr++; 89 } 90 91 char *xmon_gets(char *str, int nb) 92 { 93 char *p; 94 int c; 95 96 for (p = str; p < str + nb - 1; ) { 97 c = xmon_getchar(); 98 if (c == -1) { 99 if (p == str) 100 return NULL; 101 break; 102 } 103 *p++ = c; 104 if (c == '\n') 105 break; 106 } 107 *p = 0; 108 return str; 109 } 110 111 void xmon_printf(const char *format, ...) 112 { 113 va_list args; 114 static char xmon_outbuf[1024]; 115 int rc, n; 116 117 va_start(args, format); 118 n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args); 119 va_end(args); 120 121 rc = xmon_write(xmon_outbuf, n); 122 123 if (n && rc == 0) { 124 /* No udbg hooks, fallback to printk() - dangerous */ 125 printk("%s", xmon_outbuf); 126 } 127 } 128 129 void xmon_puts(const char *str) 130 { 131 xmon_write(str, strlen(str)); 132 } 133