diff options
Diffstat (limited to 'arch/powerpc/kernel/udbg.c')
-rw-r--r-- | arch/powerpc/kernel/udbg.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c new file mode 100644 index 000000000000..0d878e72fc44 --- /dev/null +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -0,0 +1,125 @@ | |||
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)(unsigned char c); | ||
20 | unsigned char (*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 c, *p = buf; | ||
61 | int i; | ||
62 | |||
63 | if (!udbg_getc) | ||
64 | return 0; | ||
65 | |||
66 | for (i = 0; i < buflen; ++i) { | ||
67 | do { | ||
68 | c = udbg_getc(); | ||
69 | } while (c == 0x11 || c == 0x13); | ||
70 | if (c == 0) | ||
71 | break; | ||
72 | *p++ = c; | ||
73 | } | ||
74 | |||
75 | return i; | ||
76 | } | ||
77 | |||
78 | #define UDBG_BUFSIZE 256 | ||
79 | void udbg_printf(const char *fmt, ...) | ||
80 | { | ||
81 | unsigned char buf[UDBG_BUFSIZE]; | ||
82 | va_list args; | ||
83 | |||
84 | va_start(args, fmt); | ||
85 | vsnprintf(buf, UDBG_BUFSIZE, fmt, args); | ||
86 | udbg_puts(buf); | ||
87 | va_end(args); | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Early boot console based on udbg | ||
92 | */ | ||
93 | static void udbg_console_write(struct console *con, const char *s, | ||
94 | unsigned int n) | ||
95 | { | ||
96 | udbg_write(s, n); | ||
97 | } | ||
98 | |||
99 | static struct console udbg_console = { | ||
100 | .name = "udbg", | ||
101 | .write = udbg_console_write, | ||
102 | .flags = CON_PRINTBUFFER, | ||
103 | .index = -1, | ||
104 | }; | ||
105 | |||
106 | static int early_console_initialized; | ||
107 | |||
108 | void __init disable_early_printk(void) | ||
109 | { | ||
110 | if (!early_console_initialized) | ||
111 | return; | ||
112 | unregister_console(&udbg_console); | ||
113 | early_console_initialized = 0; | ||
114 | } | ||
115 | |||
116 | /* called by setup_system */ | ||
117 | void register_early_udbg_console(void) | ||
118 | { | ||
119 | early_console_initialized = 1; | ||
120 | register_console(&udbg_console); | ||
121 | } | ||
122 | |||
123 | #if 0 /* if you want to use this as a regular output console */ | ||
124 | console_initcall(register_udbg_console); | ||
125 | #endif | ||