net: Add rtnl_lock_killable()
[linux/fpc-iii.git] / arch / mn10300 / kernel / gdb-io-ttysm.c
blobcaae8cac9db100dd32a1d49cfe78d71a6129aee7
1 /* MN10300 On-chip serial driver for gdbstub I/O
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
11 #include <linux/string.h>
12 #include <linux/kernel.h>
13 #include <linux/signal.h>
14 #include <linux/sched.h>
15 #include <linux/mm.h>
16 #include <linux/console.h>
17 #include <linux/init.h>
18 #include <linux/tty.h>
19 #include <asm/pgtable.h>
20 #include <asm/gdb-stub.h>
21 #include <asm/exceptions.h>
22 #include <unit/clock.h>
23 #include "mn10300-serial.h"
25 #if defined(CONFIG_GDBSTUB_ON_TTYSM0)
26 struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif0;
27 #elif defined(CONFIG_GDBSTUB_ON_TTYSM1)
28 struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif1;
29 #else
30 struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif2;
31 #endif
35 * initialise the GDB stub I/O routines
37 void __init gdbstub_io_init(void)
39 uint16_t scxctr;
40 int tmp;
42 switch (gdbstub_port->clock_src) {
43 case MNSCx_CLOCK_SRC_IOCLK:
44 gdbstub_port->ioclk = MN10300_IOCLK;
45 break;
47 #ifdef MN10300_IOBCLK
48 case MNSCx_CLOCK_SRC_IOBCLK:
49 gdbstub_port->ioclk = MN10300_IOBCLK;
50 break;
51 #endif
52 default:
53 BUG();
56 /* set up the serial port */
57 gdbstub_io_set_baud(115200);
59 /* we want to get serial receive interrupts */
60 set_intr_level(gdbstub_port->rx_irq,
61 NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
62 set_intr_level(gdbstub_port->tx_irq,
63 NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
64 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL),
65 gdbstub_io_rx_handler);
67 *gdbstub_port->rx_icr |= GxICR_ENABLE;
68 tmp = *gdbstub_port->rx_icr;
70 /* enable the device */
71 scxctr = SC01CTR_CLN_8BIT; /* 1N8 */
72 switch (gdbstub_port->div_timer) {
73 case MNSCx_DIV_TIMER_16BIT:
74 scxctr |= SC0CTR_CK_TM8UFLOW_8; /* == SC1CTR_CK_TM9UFLOW_8
75 == SC2CTR_CK_TM10UFLOW_8 */
76 break;
78 case MNSCx_DIV_TIMER_8BIT:
79 scxctr |= SC0CTR_CK_TM2UFLOW_8;
80 break;
83 scxctr |= SC01CTR_TXE | SC01CTR_RXE;
85 *gdbstub_port->_control = scxctr;
86 tmp = *gdbstub_port->_control;
88 /* permit level 0 IRQs only */
89 arch_local_change_intr_mask_level(
90 NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
94 * set up the GDB stub serial port baud rate timers
96 void gdbstub_io_set_baud(unsigned baud)
98 const unsigned bits = 10; /* 1 [start] + 8 [data] + 0 [parity] +
99 * 1 [stop] */
100 unsigned long ioclk = gdbstub_port->ioclk;
101 unsigned xdiv, tmp;
102 uint16_t tmxbr;
103 uint8_t tmxmd;
105 if (!baud) {
106 baud = 9600;
107 } else if (baud == 134) {
108 baud = 269; /* 134 is really 134.5 */
109 xdiv = 2;
112 try_alternative:
113 xdiv = 1;
115 switch (gdbstub_port->div_timer) {
116 case MNSCx_DIV_TIMER_16BIT:
117 tmxmd = TM8MD_SRC_IOCLK;
118 tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
119 if (tmp > 0 && tmp <= 65535)
120 goto timer_okay;
122 tmxmd = TM8MD_SRC_IOCLK_8;
123 tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
124 if (tmp > 0 && tmp <= 65535)
125 goto timer_okay;
127 tmxmd = TM8MD_SRC_IOCLK_32;
128 tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
129 if (tmp > 0 && tmp <= 65535)
130 goto timer_okay;
132 break;
134 case MNSCx_DIV_TIMER_8BIT:
135 tmxmd = TM2MD_SRC_IOCLK;
136 tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
137 if (tmp > 0 && tmp <= 255)
138 goto timer_okay;
140 tmxmd = TM2MD_SRC_IOCLK_8;
141 tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
142 if (tmp > 0 && tmp <= 255)
143 goto timer_okay;
145 tmxmd = TM2MD_SRC_IOCLK_32;
146 tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
147 if (tmp > 0 && tmp <= 255)
148 goto timer_okay;
149 break;
152 /* as a last resort, if the quotient is zero, default to 9600 bps */
153 baud = 9600;
154 goto try_alternative;
156 timer_okay:
157 gdbstub_port->uart.timeout = (2 * bits * HZ) / baud;
158 gdbstub_port->uart.timeout += HZ / 50;
160 /* set the timer to produce the required baud rate */
161 switch (gdbstub_port->div_timer) {
162 case MNSCx_DIV_TIMER_16BIT:
163 *gdbstub_port->_tmxmd = 0;
164 *gdbstub_port->_tmxbr = tmxbr;
165 *gdbstub_port->_tmxmd = TM8MD_INIT_COUNTER;
166 *gdbstub_port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE;
167 break;
169 case MNSCx_DIV_TIMER_8BIT:
170 *gdbstub_port->_tmxmd = 0;
171 *(volatile u8 *) gdbstub_port->_tmxbr = (u8)tmxbr;
172 *gdbstub_port->_tmxmd = TM2MD_INIT_COUNTER;
173 *gdbstub_port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE;
174 break;
179 * wait for a character to come from the debugger
181 int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
183 unsigned ix;
184 u8 ch, st;
185 #if defined(CONFIG_MN10300_WD_TIMER)
186 int cpu;
187 #endif
189 *_ch = 0xff;
191 if (gdbstub_rx_unget) {
192 *_ch = gdbstub_rx_unget;
193 gdbstub_rx_unget = 0;
194 return 0;
197 try_again:
198 /* pull chars out of the buffer */
199 ix = gdbstub_rx_outp;
200 barrier();
201 if (ix == gdbstub_rx_inp) {
202 if (nonblock)
203 return -EAGAIN;
204 #ifdef CONFIG_MN10300_WD_TIMER
205 for (cpu = 0; cpu < NR_CPUS; cpu++)
206 watchdog_alert_counter[cpu] = 0;
207 #endif
208 goto try_again;
211 ch = gdbstub_rx_buffer[ix++];
212 st = gdbstub_rx_buffer[ix++];
213 barrier();
214 gdbstub_rx_outp = ix & (PAGE_SIZE - 1);
216 st &= SC01STR_RXF | SC01STR_RBF | SC01STR_FEF | SC01STR_PEF |
217 SC01STR_OEF;
219 /* deal with what we've got
220 * - note that the UART doesn't do BREAK-detection for us
222 if (st & SC01STR_FEF && ch == 0) {
223 switch (gdbstub_port->rx_brk) {
224 case 0: gdbstub_port->rx_brk = 1; goto try_again;
225 case 1: gdbstub_port->rx_brk = 2; goto try_again;
226 case 2:
227 gdbstub_port->rx_brk = 3;
228 gdbstub_proto("### GDB MNSERIAL Rx Break Detected"
229 " ###\n");
230 return -EINTR;
231 default:
232 goto try_again;
234 } else if (st & SC01STR_FEF) {
235 if (gdbstub_port->rx_brk)
236 goto try_again;
238 gdbstub_proto("### GDB MNSERIAL Framing Error ###\n");
239 return -EIO;
240 } else if (st & SC01STR_OEF) {
241 if (gdbstub_port->rx_brk)
242 goto try_again;
244 gdbstub_proto("### GDB MNSERIAL Overrun Error ###\n");
245 return -EIO;
246 } else if (st & SC01STR_PEF) {
247 if (gdbstub_port->rx_brk)
248 goto try_again;
250 gdbstub_proto("### GDB MNSERIAL Parity Error ###\n");
251 return -EIO;
252 } else {
253 /* look for the tail-end char on a break run */
254 if (gdbstub_port->rx_brk == 3) {
255 switch (ch) {
256 case 0xFF:
257 case 0xFE:
258 case 0xFC:
259 case 0xF8:
260 case 0xF0:
261 case 0xE0:
262 case 0xC0:
263 case 0x80:
264 case 0x00:
265 gdbstub_port->rx_brk = 0;
266 goto try_again;
267 default:
268 break;
272 gdbstub_port->rx_brk = 0;
273 gdbstub_io("### GDB Rx %02x (st=%02x) ###\n", ch, st);
274 *_ch = ch & 0x7f;
275 return 0;
280 * send a character to the debugger
282 void gdbstub_io_tx_char(unsigned char ch)
284 while (*gdbstub_port->_status & SC01STR_TBF)
285 continue;
287 if (ch == 0x0a) {
288 *(u8 *) gdbstub_port->_txb = 0x0d;
289 while (*gdbstub_port->_status & SC01STR_TBF)
290 continue;
293 *(u8 *) gdbstub_port->_txb = ch;
297 * flush the transmission buffers
299 void gdbstub_io_tx_flush(void)
301 while (*gdbstub_port->_status & (SC01STR_TBF | SC01STR_TXF))
302 continue;