3 Copyright 2003 Broadcom Corp. All Rights Reserved.
5 This program is free software; you can distribute it and/or modify it
6 under the terms of the GNU General Public License (Version 2) as
7 published by the Free Software Foundation.
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
20 #include <linux/config.h>
21 #include <linux/tty.h>
22 #include <linux/major.h>
23 #include <linux/init.h>
24 #include <linux/console.h>
26 #include <linux/interrupt.h>
27 #include <linux/kernel.h>
28 #include <linux/types.h>
29 #include <linux/sched.h>
31 #include <bcm_map_part.h>
33 #undef PRNT /* define for debug printing */
35 #define UART16550_BAUD_2400 2400
36 #define UART16550_BAUD_4800 4800
37 #define UART16550_BAUD_9600 9600
38 #define UART16550_BAUD_19200 19200
39 #define UART16550_BAUD_38400 38400
40 #define UART16550_BAUD_57600 57600
41 #define UART16550_BAUD_115200 115200
43 #define UART16550_PARITY_NONE 0
44 #define UART16550_PARITY_ODD 0x08
45 #define UART16550_PARITY_EVEN 0x18
46 #define UART16550_PARITY_MARK 0x28
47 #define UART16550_PARITY_SPACE 0x38
49 #define UART16550_DATA_5BIT 0x0
50 #define UART16550_DATA_6BIT 0x1
51 #define UART16550_DATA_7BIT 0x2
52 #define UART16550_DATA_8BIT 0x3
54 #define UART16550_STOP_1BIT 0x0
55 #define UART16550_STOP_2BIT 0x4
57 volatile Uart * stUart = UART_BASE;
59 #define WRITE16(addr, value) ((*(volatile UINT16 *)((ULONG)&addr)) = value)
61 /* Low level UART routines from promcon.c */
62 extern void prom_putc(char c);
63 extern char prom_getc(void);
64 extern int prom_getc_nowait(void);
65 extern int prom_testc(void);
67 extern void set_debug_traps(void);
68 extern void breakpoint(void);
69 extern void enable_brcm_irq(unsigned int);
70 extern void set_async_breakpoint(unsigned int epc);
72 #ifdef CONFIG_GDB_CONSOLE
73 extern void register_gdb_console(void);
76 int gdb_initialized = 0;
78 #define GDB_BUF_SIZE 512 /* power of 2, please */
80 static char gdb_buf[GDB_BUF_SIZE] ;
81 static int gdb_buf_in_inx ;
82 static atomic_t gdb_buf_in_cnt ;
83 static int gdb_buf_out_inx ;
85 void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
87 /* Do nothing, assume boot loader has already set up serial port */
88 printk("debugInit called\n");
92 * Get a char if available, return -1 if nothing available.
93 * Empty the receive buffer first, then look at the interface hardware.
95 static int read_char(void)
97 if (atomic_read(&gdb_buf_in_cnt) != 0) /* intr routine has q'd chars */
101 chr = gdb_buf[gdb_buf_out_inx++] ;
102 gdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ;
103 atomic_dec(&gdb_buf_in_cnt) ;
106 return(prom_getc_nowait()) ; /* read from hardware */
110 * This is the receiver interrupt routine for the GDB stub.
111 * It will receive a limited number of characters of input
112 * from the gdb host machine and save them up in a buffer.
114 * When the gdb stub routine getDebugChar() is called it
115 * draws characters out of the buffer until it is empty and
116 * then reads directly from the serial port.
118 * We do not attempt to write chars from the interrupt routine
119 * since the stubs do all of that via putDebugChar() which
120 * writes one byte after waiting for the interface to become
123 * The debug stubs like to run with interrupts disabled since,
124 * after all, they run as a consequence of a breakpoint in
127 * Perhaps someone who knows more about the tty driver than I
128 * care to learn can make this work for any low level serial
131 static void gdb_interrupt(int irq, void *dev_id, struct pt_regs * regs)
137 chr = prom_getc_nowait() ;
139 if (chr < 0) continue ;
141 /* If we receive a Ctrl-C then this is GDB trying to break in */
144 /* Replace current instruction with breakpoint */
145 set_async_breakpoint(regs->cp0_epc);
150 printk("gdb_interrupt: chr=%02x '%c', more = %x\n",
151 chr, chr > ' ' && chr < 0x7F ? chr : ' ', more) ;
154 if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE)
155 { /* buffer overflow, clear it */
157 atomic_set(&gdb_buf_in_cnt, 0) ;
158 gdb_buf_out_inx = 0 ;
162 gdb_buf[gdb_buf_in_inx++] = chr ;
163 gdb_buf_in_inx &= (GDB_BUF_SIZE - 1) ;
164 atomic_inc(&gdb_buf_in_cnt) ;
168 } /* gdb_interrupt */
173 * This is a GDB stub routine. It waits for a character from the
174 * serial interface and then returns it. If there is no serial
175 * interface connection then it returns a bogus value which will
176 * almost certainly cause the system to hang.
178 int getDebugChar(void)
183 printk("getDebugChar: ") ;
186 while ( (chr = read_char()) < 0 ) ;
189 printk("%c\n", chr > ' ' && chr < 0x7F ? chr : ' ') ;
198 * This is a GDB stub routine. It waits until the interface is ready
199 * to transmit a char and then sends it. If there is no serial
200 * interface connection then it simply returns to its caller, having
201 * pretended to send the char.
203 int putDebugChar(unsigned char chr)
206 printk("putDebugChar: chr=%02x '%c'\n", chr,
207 chr > ' ' && chr < 0x7F ? chr : ' ') ;
210 prom_putc(chr) ; /* this routine will wait */
215 /* Just a NULL routine for testing. */
220 void rs_kgdb_hook(int tty_no)
222 printk("rs_kgdb_hook: tty %d\n", tty_no);
224 /* Call GDB routine to setup the exception vectors for the debugger */
227 printk("Breaking into debugger...\n");
230 printk("Connected.\n");
234 #ifdef CONFIG_GDB_CONSOLE
235 register_gdb_console();
244 printk("GDB: Hooking UART interrupt\n");
246 retval = request_irq(INTERRUPT_ID_UART,
252 printk("gdb_hook: request_irq(irq=%d) failed: %d\n", INTERRUPT_ID_UART, retval);
254 // Enable UART config Rx not empty IRQ
255 uMask = READ16(stUart->intMask) ;
256 // printk("intMask: 0x%x\n", uMask);
257 WRITE16(stUart->intMask, uMask | RXFIFONE);