2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
5 * ########################################################################
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
20 * ########################################################################
22 * This is the interface to the remote debugger stub.
25 #include <linux/config.h>
26 #include <linux/serialP.h>
27 #include <linux/serial_reg.h>
29 #include <asm/serial.h>
32 static struct serial_state rs_table[RS_TABLE_SIZE] = {
33 SERIAL_PORT_DFNS /* Defined in serial.h */
36 static struct async_struct kdb_port_info = {0};
38 int (*generic_putDebugChar)(char);
39 char (*generic_getDebugChar)(void);
41 static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
43 return inb(info->port + offset);
46 static __inline__ void serial_out(struct async_struct *info, int offset,
49 outb(value, info->port+offset);
52 void rs_kgdb_hook(int tty_no) {
54 struct serial_state *ser = &rs_table[tty_no];
56 kdb_port_info.state = ser;
57 kdb_port_info.magic = SERIAL_MAGIC;
58 kdb_port_info.port = ser->port;
59 kdb_port_info.flags = ser->flags;
62 * Clear all interrupts
64 serial_in(&kdb_port_info, UART_LSR);
65 serial_in(&kdb_port_info, UART_RX);
66 serial_in(&kdb_port_info, UART_IIR);
67 serial_in(&kdb_port_info, UART_MSR);
70 * Now, initialize the UART
72 serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
73 if (kdb_port_info.flags & ASYNC_FOURPORT) {
74 kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
75 t = UART_MCR_DTR | UART_MCR_OUT1;
78 = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
79 t = UART_MCR_DTR | UART_MCR_RTS;
82 kdb_port_info.MCR = t; /* no interrupts, please */
83 serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
86 * and set the speed of the serial port
87 * (currently hardwired to 9600 8N1
90 /* baud rate is fixed to 9600 (is this sufficient?)*/
91 t = kdb_port_info.state->baud_base / 9600;
93 serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
94 serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
95 serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */
97 serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
100 int putDebugChar(char c)
102 return generic_putDebugChar(c);
105 char getDebugChar(void)
107 return generic_getDebugChar();
110 int rs_putDebugChar(char c)
113 if (!kdb_port_info.state) { /* need to init device first */
117 while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
120 serial_out(&kdb_port_info, UART_TX, c);
125 char rs_getDebugChar(void)
127 if (!kdb_port_info.state) { /* need to init device first */
131 while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
134 return(serial_in(&kdb_port_info, UART_RX));
138 #ifdef CONFIG_MIPS_ATLAS
140 #include <asm/mips-boards/atlas.h>
141 #include <asm/mips-boards/saa9730_uart.h>
143 #define INB(a) inb((unsigned long)a)
144 #define OUTB(x,a) outb(x,(unsigned long)a)
147 * This is the interface to the remote debugger stub
148 * if the Philips part is used for the debug port,
149 * called from the platform setup code.
151 * PCI init will not have been done yet, we make a
152 * universal assumption about the way the bootloader (YAMON)
153 * have located and set up the chip.
155 static t_uart_saa9730_regmap *kgdb_uart = (void *)(ATLAS_SAA9730_REG + SAA9730_UART_REGS_ADDR);
157 static int saa9730_kgdb_active = 0;
159 void saa9730_kgdb_hook(void)
161 volatile unsigned char t;
164 * Clear all interrupts
166 t = INB(&kgdb_uart->Lsr);
167 t += INB(&kgdb_uart->Msr);
168 t += INB(&kgdb_uart->Thr_Rbr);
169 t += INB(&kgdb_uart->Iir_Fcr);
172 * Now, initialize the UART
174 /* 8 data bits, one stop bit, no parity */
175 OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr);
177 /* baud rate is fixed to 9600 (is this sufficient?)*/
178 OUTB(0, &kgdb_uart->BaudDivMsb); /* HACK - Assumes standard crystal */
179 OUTB(23, &kgdb_uart->BaudDivLsb); /* HACK - known for MIPS Atlas */
181 /* Set RTS/DTR active */
182 OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr);
183 saa9730_kgdb_active = 1;
186 int saa9730_putDebugChar(char c)
189 if (!saa9730_kgdb_active) { /* need to init device first */
193 while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE))
195 OUTB(c, &kgdb_uart->Thr_Rbr);
200 char saa9730_getDebugChar(void)
204 if (!saa9730_kgdb_active) { /* need to init device first */
207 while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR))
210 c = INB(&kgdb_uart->Thr_Rbr);