1 /* 2 * polling mode stateless debugging stuff, originally for NS16550 Serial Ports 3 * 4 * c 2001 PPC 64 Team, IBM Corp 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <stdarg.h> 13 #include <linux/config.h> 14 #include <linux/types.h> 15 #include <linux/sched.h> 16 #include <linux/console.h> 17 #include <asm/processor.h> 18 19 void (*udbg_putc)(char c); 20 int (*udbg_getc)(void); 21 int (*udbg_getc_poll)(void); 22 23 /* udbg library, used by xmon et al */ 24 void udbg_puts(const char *s) 25 { 26 if (udbg_putc) { 27 char c; 28 29 if (s && *s != '\0') { 30 while ((c = *s++) != '\0') 31 udbg_putc(c); 32 } 33 } 34 #if 0 35 else { 36 printk("%s", s); 37 } 38 #endif 39 } 40 41 int udbg_write(const char *s, int n) 42 { 43 int remain = n; 44 char c; 45 46 if (!udbg_putc) 47 return 0; 48 49 if (s && *s != '\0') { 50 while (((c = *s++) != '\0') && (remain-- > 0)) { 51 udbg_putc(c); 52 } 53 } 54 55 return n - remain; 56 } 57 58 int udbg_read(char *buf, int buflen) 59 { 60 char *p = buf; 61 int i, c; 62 63 if (!udbg_getc) 64 return 0; 65 66 for (i = 0; i < buflen; ++i) { 67 do { 68 c = udbg_getc(); 69 if (c == -1 && i == 0) 70 return -1; 71 72 } while (c == 0x11 || c == 0x13); 73 if (c == 0 || c == -1) 74 break; 75 *p++ = c; 76 } 77 78 return i; 79 } 80 81 #define UDBG_BUFSIZE 256 82 void udbg_printf(const char *fmt, ...) 83 { 84 char buf[UDBG_BUFSIZE]; 85 va_list args; 86 87 va_start(args, fmt); 88 vsnprintf(buf, UDBG_BUFSIZE, fmt, args); 89 udbg_puts(buf); 90 va_end(args); 91 } 92 93 void __init udbg_progress(char *s, unsigned short hex) 94 { 95 udbg_puts(s); 96 udbg_puts("\n"); 97 } 98 99 /* 100 * Early boot console based on udbg 101 */ 102 static void udbg_console_write(struct console *con, const char *s, 103 unsigned int n) 104 { 105 udbg_write(s, n); 106 } 107 108 static struct console udbg_console = { 109 .name = "udbg", 110 .write = udbg_console_write, 111 .flags = CON_PRINTBUFFER | CON_ENABLED, 112 .index = -1, 113 }; 114 115 static int early_console_initialized; 116 117 void __init disable_early_printk(void) 118 { 119 #if 1 120 if (!early_console_initialized) 121 return; 122 unregister_console(&udbg_console); 123 early_console_initialized = 0; 124 #endif 125 } 126 127 /* called by setup_system */ 128 void register_early_udbg_console(void) 129 { 130 if (early_console_initialized) 131 return; 132 early_console_initialized = 1; 133 register_console(&udbg_console); 134 } 135 136 #if 0 /* if you want to use this as a regular output console */ 137 console_initcall(register_udbg_console); 138 #endif 139