[xtensa-cvscommit] linux/arch/xtensa/platform-xt2000 gdb_hook.c,NONE,1.1 Makefile,1.1.1.1,1.2
Brought to you by:
zankel
|
From: <sfo...@us...> - 2002-09-19 07:06:15
|
Update of /cvsroot/xtensa/linux/arch/xtensa/platform-xt2000
In directory usw-pr-cvs1:/tmp/cvs-serv975/arch/xtensa/platform-xt2000
Modified Files:
Makefile
Added Files:
gdb_hook.c
Log Message:
First functional checkin of kgdb. Reading AR registers does not work yet. (Reading A registers works.)
Currently uses ttyS1 at 9600 8N1. Serial port and baud rate to become paramterized.
To use, must have CONFIGURE_KGDB. Must also pass the parameter "gdb" to the kernel to tell it to stop on boot and wait for a connection from gdb.
--- NEW FILE: gdb_hook.c ---
/*
* arch/platform-xt2000/gdb_hook.c
*
* Derived from MIPS.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001 Tensilica Inc.
* Authors: Scott Foehner <sfo...@te...>
*/
#include <linux/serialP.h>
#include <linux/serial_reg.h>
#include <asm/serial.h>
#include <asm/io.h>
static struct serial_state rs_table[RS_TABLE_SIZE] = {
SERIAL_PORT_DFNS /* Defined in serial.h */
};
static struct async_struct kdb_port_info = {0};
static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
{
#if 0
return inb(info->port + offset);
#else
return readb((unsigned long) info->iomem_base + (offset<<info->iomem_reg_shift));
#endif
}
static __inline__ void serial_out(struct async_struct *info, int offset,
int value)
{
#if 0
printk("serial_out: port: 0x%08lx iomem_base: %08lx iomem_reg_shift: %d\n", info->port, info->iomem_base, info->iomem_reg_shift);
#endif
#if 0
outb(value, info->port+offset);
#else
writeb(value, (unsigned long) info->iomem_base + (offset<<info->iomem_reg_shift));
#endif
}
void rs_kgdb_hook(int tty_no) {
int t;
struct serial_state *ser = &rs_table[tty_no];
kdb_port_info.state = ser;
kdb_port_info.magic = SERIAL_MAGIC;
kdb_port_info.port = ser->port;
kdb_port_info.flags = ser->flags;
kdb_port_info.iomem_base = ser->iomem_base;
kdb_port_info.iomem_reg_shift = ser->iomem_reg_shift;
/*
* Clear all interrupts
*/
serial_in(&kdb_port_info, UART_LSR);
serial_in(&kdb_port_info, UART_RX);
serial_in(&kdb_port_info, UART_IIR);
serial_in(&kdb_port_info, UART_MSR);
/*
* Now, initialize the UART
*/
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
if (kdb_port_info.flags & ASYNC_FOURPORT) {
kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
t = UART_MCR_DTR | UART_MCR_OUT1;
} else {
kdb_port_info.MCR
= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
t = UART_MCR_DTR | UART_MCR_RTS;
}
kdb_port_info.MCR = t; /* no interrupts, please */
serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
/*
* and set the speed of the serial port
* (currently hardwired to 9600 8N1
*/
/* baud rate is fixed to 9600 (is this sufficient?)*/
t = kdb_port_info.state->baud_base / 9600;
#if 0
printk("BAUD BASE: %d\n", kdb_port_info.state->baud_base);
#endif
/* set DLAB */
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */
/* reset DLAB */
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
}
int rs_putDebugChar(char c)
{
if (!kdb_port_info.state) { /* need to init device first */
return 0;
}
/* Compiler might not think this is volatile, so might want to
* re-code as in rs_getDebugChar below. */
#if 0
while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
;
#else
retry:
if ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
goto retry;
#endif
serial_out(&kdb_port_info, UART_TX, c);
#if 0
printk("putDebugChar: \'%c\'\n", c);
#endif
return 1;
}
char rs_getDebugChar(void)
{
char c;
if (!kdb_port_info.state) { /* need to init device first */
return 0;
}
#if 0
while (!((volatile)serial_in(&kdb_port_info, UART_LSR) & UART_LSR_DR))
;
#else
/* Compiler does not seem to think above is volatile, so it
* generates a never-ending loop, i.e., it only reads the
* memory value into the register once. The below code
* seems to generate machine code that re-reads the memory
* every time through the loop.
* Turns out this is not a compiler problem, but rather a problem with * the macro definitions, which "define out" the volatile cast. */
retry:
if ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_DR) == 0)
goto retry;
#endif
#if 1
return(serial_in(&kdb_port_info, UART_RX));
#else
c = serial_in(&kdb_port_info, UART_RX);
printk("getDebugChar: \'%c\'\n", c);
return c;
#endif
}
int putDebugChar(char c)
{
return rs_putDebugChar(c);
}
char getDebugChar(void)
{
return rs_getDebugChar();
}
Index: Makefile
===================================================================
RCS file: /cvsroot/xtensa/linux/arch/xtensa/platform-xt2000/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** Makefile 28 Aug 2002 16:10:14 -0000 1.1.1.1
--- Makefile 19 Sep 2002 07:06:12 -0000 1.2
***************
*** 13,16 ****
--- 13,17 ----
obj-y = time.o setup.o xt2000-i2cdev.o
obj-$(CONFIG_PCI) += pci.o pci_v320usc.o ../kernel/pci-auto.o
+ obj-$(CONFIG_KGDB) += gdb_hook.o
include $(TOPDIR)/Rules.make
|