blob: a9265bcc79b24d1e3750efdb3ec86e7ee3d1cd61 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
26static 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();
31 debugger(pt_regs);
32}
33
34static struct sysrq_key_op sysrq_xmon_op =
35{
36 .handler = sysrq_handle_xmon,
37 .help_msg = "Xmon",
38 .action_msg = "Entering xmon",
39};
40
41static 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
49int
50xmon_write(void *handle, void *ptr, int nb)
51{
52 return udbg_write(ptr, nb);
53}
54
55int
56xmon_read(void *handle, void *ptr, int nb)
57{
58 return udbg_read(ptr, nb);
59}
60
61int
62xmon_read_poll(void)
63{
64 return udbg_getc_poll();
65}
66
67FILE *xmon_stdin;
68FILE *xmon_stdout;
69
70int
71xmon_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
80int
81xmon_putchar(int c)
82{
83 return xmon_putc(c, xmon_stdout);
84}
85
86int
87xmon_fputs(char *str, void *f)
88{
89 int n = strlen(str);
90
91 return xmon_write(f, str, n) == n? 0: -1;
92}
93
94int
95xmon_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
110static char line[256];
111static char *lineptr;
112static int lineleft;
113
114int
115xmon_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
166char *
167xmon_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}