Merge linux-2.6 into linux-acpi-2.6 test
[linux-2.6] / arch / ppc64 / xmon / start.c
1 /*
2  * Copyright (C) 1996 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/config.h>
10 #include <linux/string.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/sysrq.h>
14 #include <linux/init.h>
15 #include <asm/machdep.h>
16 #include <asm/io.h>
17 #include <asm/page.h>
18 #include <asm/prom.h>
19 #include <asm/processor.h>
20 #include <asm/udbg.h>
21 #include <asm/system.h>
22 #include "nonstdio.h"
23
24 #ifdef CONFIG_MAGIC_SYSRQ
25
26 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
27                               struct tty_struct *tty) 
28 {
29         /* ensure xmon is enabled */
30         xmon_init(1);
31         debugger(pt_regs);
32 }
33
34 static struct sysrq_key_op sysrq_xmon_op = 
35 {
36         .handler =      sysrq_handle_xmon,
37         .help_msg =     "Xmon",
38         .action_msg =   "Entering xmon",
39 };
40
41 static int __init setup_xmon_sysrq(void)
42 {
43         register_sysrq_key('x', &sysrq_xmon_op);
44         return 0;
45 }
46 __initcall(setup_xmon_sysrq);
47 #endif /* CONFIG_MAGIC_SYSRQ */
48
49 int
50 xmon_write(void *handle, void *ptr, int nb)
51 {
52         return udbg_write(ptr, nb);
53 }
54
55 int
56 xmon_read(void *handle, void *ptr, int nb)
57 {
58         return udbg_read(ptr, nb);
59 }
60
61 int
62 xmon_read_poll(void)
63 {
64         return udbg_getc_poll();
65 }
66  
67 FILE *xmon_stdin;
68 FILE *xmon_stdout;
69
70 int
71 xmon_putc(int c, void *f)
72 {
73         char ch = c;
74
75         if (c == '\n')
76                 xmon_putc('\r', f);
77         return xmon_write(f, &ch, 1) == 1? c: -1;
78 }
79
80 int
81 xmon_putchar(int c)
82 {
83         return xmon_putc(c, xmon_stdout);
84 }
85
86 int
87 xmon_fputs(char *str, void *f)
88 {
89         int n = strlen(str);
90
91         return xmon_write(f, str, n) == n? 0: -1;
92 }
93
94 int
95 xmon_readchar(void)
96 {
97         char ch;
98
99         for (;;) {
100                 switch (xmon_read(xmon_stdin, &ch, 1)) {
101                 case 1:
102                         return ch;
103                 case -1:
104                         xmon_printf("read(stdin) returned -1\r\n", 0, 0);
105                         return -1;
106                 }
107         }
108 }
109
110 static char line[256];
111 static char *lineptr;
112 static int lineleft;
113
114 int
115 xmon_getchar(void)
116 {
117         int c;
118
119         if (lineleft == 0) {
120                 lineptr = line;
121                 for (;;) {
122                         c = xmon_readchar();
123                         if (c == -1 || c == 4)
124                                 break;
125                         if (c == '\r' || c == '\n') {
126                                 *lineptr++ = '\n';
127                                 xmon_putchar('\n');
128                                 break;
129                         }
130                         switch (c) {
131                         case 0177:
132                         case '\b':
133                                 if (lineptr > line) {
134                                         xmon_putchar('\b');
135                                         xmon_putchar(' ');
136                                         xmon_putchar('\b');
137                                         --lineptr;
138                                 }
139                                 break;
140                         case 'U' & 0x1F:
141                                 while (lineptr > line) {
142                                         xmon_putchar('\b');
143                                         xmon_putchar(' ');
144                                         xmon_putchar('\b');
145                                         --lineptr;
146                                 }
147                                 break;
148                         default:
149                                 if (lineptr >= &line[sizeof(line) - 1])
150                                         xmon_putchar('\a');
151                                 else {
152                                         xmon_putchar(c);
153                                         *lineptr++ = c;
154                                 }
155                         }
156                 }
157                 lineleft = lineptr - line;
158                 lineptr = line;
159         }
160         if (lineleft == 0)
161                 return -1;
162         --lineleft;
163         return *lineptr++;
164 }
165
166 char *
167 xmon_fgets(char *str, int nb, void *f)
168 {
169         char *p;
170         int c;
171
172         for (p = str; p < str + nb - 1; ) {
173                 c = xmon_getchar();
174                 if (c == -1) {
175                         if (p == str)
176                                 return NULL;
177                         break;
178                 }
179                 *p++ = c;
180                 if (c == '\n')
181                         break;
182         }
183         *p = 0;
184         return str;
185 }