提交 fa5da2f7 编写于 作者: P Paul Mundt 提交者: Paul Mundt

sh: Bring kgdb back from the dead.

This code has suffered quite a bit of bitrot, do some basic
tidying to get it to a reasonably functional state again.
This gets the basic support and the console working again.
Signed-off-by: NPaul Mundt <lethal@linux-sh.org>
上级 15700770
......@@ -77,16 +77,17 @@ config 4KSTACKS
on the VM subsystem for higher order allocations. This option
will also use IRQ stacks to compensate for the reduced stackspace.
config KGDB
config SH_KGDB
bool "Include KGDB kernel debugger"
select FRAME_POINTER
select DEBUG_INFO
help
Include in-kernel hooks for kgdb, the Linux kernel source level
debugger. See <http://kgdb.sourceforge.net/> for more information.
Unless you are intending to debug the kernel, say N here.
menu "KGDB configuration options"
depends on KGDB
depends on SH_KGDB
config MORE_COMPILE_OPTIONS
bool "Add any additional compile options"
......@@ -109,16 +110,14 @@ config KGDB_THREAD
config SH_KGDB_CONSOLE
bool "Console messages through GDB"
depends on !SERIAL_SH_SCI_CONSOLE
select SERIAL_CORE_CONSOLE
default n
config KGDB_SYSRQ
bool "Allow SysRq 'G' to enter KGDB"
default y
config KGDB_KERNEL_ASSERTS
bool "Include KGDB kernel assertions"
default n
comment "Serial port setup"
config KGDB_DEFPORT
......@@ -131,7 +130,7 @@ config KGDB_DEFBAUD
choice
prompt "Parity"
depends on KGDB
depends on SH_KGDB
default KGDB_DEFPARITY_N
config KGDB_DEFPARITY_N
......@@ -147,7 +146,7 @@ endchoice
choice
prompt "Data bits"
depends on KGDB
depends on SH_KGDB
default KGDB_DEFBITS_8
config KGDB_DEFBITS_8
......
......@@ -47,7 +47,6 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
cflags-$(CONFIG_SH_DSP) += -Wa,-dsp
cflags-$(CONFIG_SH_KGDB) += -g
cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
$(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
......
......@@ -14,153 +14,6 @@
#include <asm/se7751.h>
#include <asm/io.h>
void init_7751se_IRQ(void);
#ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h>
static int kgdb_uart_setup(void);
static struct kgdb_sermap kgdb_uart_sermap =
{ "ttyS", 0, kgdb_uart_setup, NULL };
#endif
/*
* Initialize the board
*/
static void __init sh7751se_setup(char **cmdline_p)
{
/* Call init_smsc() replacement to set up SuperIO. */
/* XXX: RTC setting comes here */
#ifdef CONFIG_SH_KGDB
kgdb_register_sermap(&kgdb_uart_sermap);
#endif
}
/*********************************************************************
* Currently a hack (e.g. does not interact well w/serial.c, lots of *
* hardcoded stuff) but may be useful if SCI/F needs debugging. *
* Mostly copied from x86 code (see files asm-i386/kgdb_local.h and *
* arch/i386/lib/kgdb_serial.c). *
*********************************************************************/
#ifdef CONFIG_SH_KGDB
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/serial_reg.h>
#define COM1_PORT 0x3f8 /* Base I/O address */
#define COM1_IRQ 4 /* IRQ not used yet */
#define COM2_PORT 0x2f8 /* Base I/O address */
#define COM2_IRQ 3 /* IRQ not used yet */
#define SB_CLOCK 1843200 /* Serial baud clock */
#define SB_BASE (SB_CLOCK/16)
#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
struct uart_port {
int base;
};
#define UART_NPORTS 2
struct uart_port uart_ports[] = {
{ COM1_PORT },
{ COM2_PORT },
};
struct uart_port *kgdb_uart_port;
#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg)
#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
/* Basic read/write functions for the UART */
#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
static int kgdb_uart_getchar(void)
{
int lsr;
int c = -1;
while (c == -1) {
lsr = UART_IN(UART_LSR);
if (lsr & UART_LSR_DR)
c = UART_IN(UART_RX);
if ((lsr & UART_LSR_RXCERR))
c = -1;
}
return c;
}
static void kgdb_uart_putchar(int c)
{
while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
;
UART_OUT(UART_TX, c);
}
/*
* Initialize UART to configured/requested values.
* (But we don't interrupts yet, or interact w/serial.c)
*/
static int kgdb_uart_setup(void)
{
int port;
int lcr = 0;
int bdiv = 0;
if (kgdb_portnum >= UART_NPORTS) {
KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
return -1;
}
kgdb_uart_port = &uart_ports[kgdb_portnum];
/* Init sequence from gdb_hook_interrupt */
UART_IN(UART_RX);
UART_OUT(UART_IER, 0);
UART_IN(UART_RX); /* Serial driver comments say */
UART_IN(UART_IIR); /* this clears interrupt regs */
UART_IN(UART_MSR);
/* Figure basic LCR values */
switch (kgdb_bits) {
case '7':
lcr |= UART_LCR_WLEN7;
break;
default: case '8':
lcr |= UART_LCR_WLEN8;
break;
}
switch (kgdb_parity) {
case 'O':
lcr |= UART_LCR_PARITY;
break;
case 'E':
lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
break;
default: break;
}
/* Figure the baud rate divisor */
bdiv = (SB_BASE/kgdb_baud);
/* Set the baud rate and LCR values */
UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
UART_OUT(UART_DLL, (bdiv & 0xff));
UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
UART_OUT(UART_LCR, lcr);
/* Set the MCR */
UART_OUT(UART_MCR, SB_MCR);
/* Turn off FIFOs for now */
UART_OUT(UART_FCR, 0);
/* Setup complete: initialize function pointers */
kgdb_getchar = kgdb_uart_getchar;
kgdb_putchar = kgdb_uart_putchar;
return 0;
}
#endif /* CONFIG_SH_KGDB */
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
......@@ -197,7 +50,6 @@ __initcall(se7751_devices_setup);
*/
struct sh_machine_vector mv_7751se __initmv = {
.mv_name = "7751 SolutionEngine",
.mv_setup = sh7751se_setup,
.mv_nr_irqs = 72,
.mv_inb = sh7751se_inb,
......
......@@ -6,11 +6,11 @@
* David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
* Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
* Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
*
*
* This version by Henry Bell <henry.bell@st.com>
* Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
*
* Contains low-level support for remote debug using GDB.
*
* Contains low-level support for remote debug using GDB.
*
* To enable debugger support, two things need to happen. A call to
* set_debug_traps() is necessary in order to allow any breakpoints
......@@ -48,7 +48,7 @@
* k kill (Detach GDB)
*
* d Toggle debug flag
* D Detach GDB
* D Detach GDB
*
* Hct Set thread t for operations, OK or ENN
* c = 'c' (step, cont), c = 'g' (other
......@@ -58,7 +58,7 @@
* qfThreadInfo Get list of current threads (first) m<id>
* qsThreadInfo " " " " " (subsequent)
* qOffsets Get section offsets Text=x;Data=y;Bss=z
*
*
* TXX Find if thread XX is alive OK or ENN
* ? What was the last sigval ? SNN (signal NN)
* O Output to GDB console
......@@ -74,7 +74,7 @@
* '$' or '#'. If <data> starts with two characters followed by
* ':', then the existing stubs interpret this as a sequence number.
*
* CSUM1 and CSUM2 are ascii hex representation of an 8-bit
* CSUM1 and CSUM2 are ascii hex representation of an 8-bit
* checksum of <data>, the most significant nibble is sent first.
* the hex digits 0-9,a-f are used.
*
......@@ -86,8 +86,8 @@
* Responses can be run-length encoded to save space. A '*' means that
* the next character is an ASCII encoding giving a repeat count which
* stands for that many repititions of the character preceding the '*'.
* The encoding is n+29, yielding a printable character where n >=3
* (which is where RLE starts to win). Don't use an n > 126.
* The encoding is n+29, yielding a printable character where n >=3
* (which is where RLE starts to win). Don't use an n > 126.
*
* So "0* " means the same as "0000".
*/
......@@ -100,12 +100,10 @@
#include <linux/delay.h>
#include <linux/linkage.h>
#include <linux/init.h>
#ifdef CONFIG_SH_KGDB_CONSOLE
#include <linux/console.h>
#endif
#include <linux/sysrq.h>
#include <asm/system.h>
#include <asm/cacheflush.h>
#include <asm/current.h>
#include <asm/signal.h>
#include <asm/pgtable.h>
......@@ -153,7 +151,6 @@ char kgdb_in_gdb_mode;
char in_nmi; /* Set during NMI to prevent reentry */
int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */
int kgdb_halt;
/* Exposed for user access */
struct task_struct *kgdb_current;
......@@ -328,7 +325,7 @@ static int hex_to_int(char **ptr, int *int_value)
}
/* Copy the binary array pointed to by buf into mem. Fix $, #,
and 0x7d escaped with 0x7d. Return a pointer to the character
and 0x7d escaped with 0x7d. Return a pointer to the character
after the last byte written. */
static char *ebin_to_mem(const char *buf, char *mem, int count)
{
......@@ -452,7 +449,7 @@ static void get_packet(char *buffer, int buflen)
/* Ack successful transfer */
put_debug_char('+');
/* If a sequence char is present, reply
/* If a sequence char is present, reply
the sequence ID */
if (buffer[2] == ':') {
put_debug_char(buffer[0]);
......@@ -759,7 +756,7 @@ static short *get_step_address(void)
return (short *) addr;
}
/* Set up a single-step. Replace the instruction immediately after the
/* Set up a single-step. Replace the instruction immediately after the
current instruction (i.e. next in the expected flow of control) with a
trap instruction, so that returning will cause only a single instruction
to be executed. Note that this model is slightly broken for instructions
......@@ -1002,10 +999,8 @@ void set_thread_msg(void)
char *ptr;
switch (in_buffer[1]) {
/* To select which thread for gG etc messages, i.e. supported */
/* To select which thread for gG etc messages, i.e. supported */
case 'g':
ptr = &in_buffer[2];
hex_to_int(&ptr, &threadid);
thread = get_thread(threadid);
......@@ -1173,6 +1168,7 @@ static void query_msg(void)
}
#endif /* CONFIG_KGDB_THREAD */
#ifdef CONFIG_SH_KGDB_CONSOLE
/*
* Bring up the ports..
*/
......@@ -1185,6 +1181,9 @@ static int kgdb_serial_setup(void)
return 0;
}
#else
#define kgdb_serial_setup() 0
#endif
/* The command loop, read and act on requests */
static void kgdb_command_loop(const int excep_code, const int trapa_value)
......@@ -1193,7 +1192,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
if (excep_code == NMI_VEC) {
#ifndef CONFIG_KGDB_NMI
KGDB_PRINTK("Ignoring unexpected NMI?\n");
printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n");
return;
#else /* CONFIG_KGDB_NMI */
if (!kgdb_enabled) {
......@@ -1216,10 +1215,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
/* Enter GDB mode (e.g. after detach) */
if (!kgdb_in_gdb_mode) {
/* Do serial setup, notify user, issue preemptive ack */
kgdb_serial_setup();
KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",
(kgdb_porttype ? kgdb_porttype->name : ""),
kgdb_portnum, kgdb_baud);
printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
kgdb_in_gdb_mode = 1;
put_debug_char('+');
}
......@@ -1233,21 +1229,18 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
will later be replaced by its original one. Do NOT do this for
trap 0xff, since that indicates a compiled-in breakpoint which
will not be replaced (and we would retake the trap forever) */
if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) {
if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
trap_registers.pc -= 2;
}
/* Undo any stepping we may have done */
undo_single_step();
while (1) {
out_buffer[0] = 0;
get_packet(in_buffer, BUFMAX);
/* Examine first char of buffer to see what we need to do */
switch (in_buffer[0]) {
case '?': /* Send which signal we've received */
send_signal_msg(sigval);
break;
......@@ -1323,11 +1316,8 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
}
/* There has been an exception, most likely a breakpoint. */
asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs)
static void handle_exception(struct pt_regs *regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int excep_code, vbr_val;
int count;
int trapa_value = ctrl_inl(TRA);
......@@ -1355,7 +1345,7 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
kgdb_trapa_val = trapa_value;
/* Act on the exception */
kgdb_command_loop(excep_code >> 5, trapa_value);
kgdb_command_loop(excep_code, trapa_value);
kgdb_current = NULL;
......@@ -1373,14 +1363,12 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
asm("ldc %0, vbr": :"r"(vbr_val));
}
/* Trigger a breakpoint by function */
void breakpoint(void)
asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs)
{
if (!kgdb_enabled) {
kgdb_enabled = 1;
kgdb_init();
}
BREAKPOINT();
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
handle_exception(regs);
}
/* Initialise the KGDB data structures and serial configuration */
......@@ -1395,24 +1383,16 @@ int kgdb_init(void)
kgdb_in_gdb_mode = 0;
if (kgdb_serial_setup() != 0) {
KGDB_PRINTK("serial setup error\n");
printk(KERN_NOTICE "KGDB: serial setup error\n");
return -1;
}
/* Init ptr to exception handler */
kgdb_debug_hook = kgdb_handle_exception;
kgdb_debug_hook = handle_exception;
kgdb_bus_err_hook = kgdb_handle_bus_error;
/* Enter kgdb now if requested, or just report init done */
if (kgdb_halt) {
kgdb_in_gdb_mode = 1;
put_debug_char('+');
breakpoint();
}
else
{
KGDB_PRINTK("stub is initialized.\n");
}
printk(KERN_NOTICE "KGDB: stub is initialized.\n");
return 0;
}
......@@ -1437,7 +1417,7 @@ static void kgdb_msg_write(const char *s, unsigned count)
/* Calculate how many this time */
wcount = (count > MAXOUT) ? MAXOUT : count;
/* Pack in hex chars */
for (i = 0; i < wcount; i++)
bufptr = pack_hex_byte(bufptr, s[i]);
......@@ -1467,3 +1447,25 @@ void kgdb_console_write(struct console *co, const char *s, unsigned count)
kgdb_msg_write(s, count);
}
#endif
#ifdef CONFIG_KGDB_SYSRQ
static void sysrq_handle_gdb(int key, struct tty_struct *tty)
{
printk("Entering GDB stub\n");
breakpoint();
}
static struct sysrq_key_op sysrq_gdb_op = {
.handler = sysrq_handle_gdb,
.help_msg = "Gdb",
.action_msg = "GDB",
};
static int gdb_register_sysrq(void)
{
printk("Registering GDB sysrq handler\n");
register_sysrq_key('g', &sysrq_gdb_op);
return 0;
}
module_init(gdb_register_sysrq);
#endif
......@@ -25,11 +25,8 @@
#include <asm/setup.h>
#include <asm/clock.h>
#ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h>
static int kgdb_parse_options(char *options);
#endif
extern void * __rd_start, * __rd_end;
/*
* Machine setup..
*/
......@@ -499,92 +496,3 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_SH_KGDB
/*
* Parse command-line kgdb options. By default KGDB is enabled,
* entered on error (or other action) using default serial info.
* The command-line option can include a serial port specification
* and an action to override default or configured behavior.
*/
struct kgdb_sermap kgdb_sci_sermap =
{ "ttySC", 5, kgdb_sci_setup, NULL };
struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
void kgdb_register_sermap(struct kgdb_sermap *map)
{
struct kgdb_sermap *last;
for (last = kgdb_serlist; last->next; last = last->next)
;
last->next = map;
if (!map->namelen) {
map->namelen = strlen(map->name);
}
}
static int __init kgdb_parse_options(char *options)
{
char c;
int baud;
/* Check for port spec (or use default) */
/* Determine port type and instance */
if (!memcmp(options, "tty", 3)) {
struct kgdb_sermap *map = kgdb_serlist;
while (map && memcmp(options, map->name, map->namelen))
map = map->next;
if (!map) {
KGDB_PRINTK("unknown port spec in %s\n", options);
return -1;
}
kgdb_porttype = map;
kgdb_serial_setup = map->setup_fn;
kgdb_portnum = options[map->namelen] - '0';
options += map->namelen + 1;
options = (*options == ',') ? options+1 : options;
/* Read optional parameters (baud/parity/bits) */
baud = simple_strtoul(options, &options, 10);
if (baud != 0) {
kgdb_baud = baud;
c = toupper(*options);
if (c == 'E' || c == 'O' || c == 'N') {
kgdb_parity = c;
options++;
}
c = *options;
if (c == '7' || c == '8') {
kgdb_bits = c;
options++;
}
options = (*options == ',') ? options+1 : options;
}
}
/* Check for action specification */
if (!memcmp(options, "halt", 4)) {
kgdb_halt = 1;
options += 4;
} else if (!memcmp(options, "disabled", 8)) {
kgdb_enabled = 0;
options += 8;
}
if (*options) {
KGDB_PRINTK("ignored unknown options: %s\n", options);
return 0;
}
return 1;
}
__setup("kgdb=", kgdb_parse_options);
#endif /* CONFIG_SH_KGDB */
......@@ -46,6 +46,7 @@
#endif
#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
#include <linux/ctype.h>
#include <asm/clock.h>
#include <asm/sh_bios.h>
#include <asm/kgdb.h>
......@@ -163,7 +164,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count)
usegdb |= sh_bios_in_gdb_mode();
#endif
#ifdef CONFIG_SH_KGDB
usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port));
usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port));
#endif
if (usegdb) {
......@@ -204,7 +205,7 @@ static int kgdb_sci_getchar(void)
int c;
/* Keep trying to read a character, this could be neater */
while ((c = get_char(kgdb_sci_port)) < 0)
while ((c = get_char(&kgdb_sci_port->port)) < 0)
cpu_relax();
return c;
......@@ -212,7 +213,7 @@ static int kgdb_sci_getchar(void)
static inline void kgdb_sci_putchar(int c)
{
put_char(kgdb_sci_port, c);
put_char(&kgdb_sci_port->port, c);
}
#endif /* CONFIG_SH_KGDB */
......@@ -738,7 +739,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
#ifdef CONFIG_SH_KGDB
/* Break into the debugger if a break is detected */
BREAKPOINT();
breakpoint();
#endif
sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
......@@ -971,7 +972,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct sci_port *s = &sci_ports[port->line];
unsigned int status, baud, smr_val;
unsigned long flags;
int t;
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
......@@ -989,12 +989,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
#else
t = SCBRR_VALUE(baud);
#endif
}
break;
}
}
spin_lock_irqsave(&port->lock, flags);
do {
status = sci_in(port, SCxSR);
} while (!(status & SCxSR_TEND(port)));
......@@ -1038,8 +1036,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
if ((termios->c_cflag & CREAD) != 0)
sci_start_rx(port,0);
spin_unlock_irqrestore(&port->lock, flags);
}
static const char *sci_type(struct uart_port *port)
......@@ -1220,8 +1216,6 @@ static int __init serial_console_setup(struct console *co, char *options)
if (!port->membase || !port->mapbase)
return -ENODEV;
spin_lock_init(&port->lock);
port->type = serial_console_port->type;
if (port->flags & UPF_IOREMAP)
......@@ -1247,7 +1241,7 @@ static struct console serial_console = {
.device = uart_console_device,
.write = serial_console_write,
.setup = serial_console_setup,
.flags = CON_PRINTBUFFER,
.flags = CON_PRINTBUFFER,
.index = -1,
.data = &sci_uart_driver,
};
......@@ -1292,11 +1286,23 @@ int __init kgdb_console_setup(struct console *co, char *options)
int parity = 'n';
int flow = 'n';
spin_lock_init(&port->lock);
if (co->index != kgdb_portnum)
co->index = kgdb_portnum;
kgdb_sci_port = &sci_ports[co->index];
port = &kgdb_sci_port->port;
/*
* Also need to check port->type, we don't actually have any
* UPIO_PORT ports, but uart_report_port() handily misreports
* it anyways if we don't have a port available by the time this is
* called.
*/
if (!port->type)
return -ENODEV;
if (!port->membase || !port->mapbase)
return -ENODEV;
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
......@@ -1311,11 +1317,12 @@ int __init kgdb_console_setup(struct console *co, char *options)
#ifdef CONFIG_SH_KGDB_CONSOLE
static struct console kgdb_console = {
.name = "ttySC",
.write = kgdb_console_write,
.setup = kgdb_console_setup,
.flags = CON_PRINTBUFFER | CON_ENABLED,
.index = -1,
.name = "ttySC",
.device = uart_console_device,
.write = kgdb_console_write,
.setup = kgdb_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
.data = &sci_uart_driver,
};
......@@ -1386,6 +1393,12 @@ static int __devinit sci_probe(struct platform_device *dev)
uart_add_one_port(&sci_uart_driver, &sciport->port);
}
#if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE)
kgdb_sci_port = &sci_ports[kgdb_portnum];
kgdb_getchar = kgdb_sci_getchar;
kgdb_putchar = kgdb_sci_putchar;
#endif
#ifdef CONFIG_CPU_FREQ
cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
dev_info(&dev->dev, "sci: CPU frequency notifier registered\n");
......
......@@ -17,6 +17,7 @@
#define __KGDB_H
#include <asm/ptrace.h>
#include <asm/cacheflush.h>
struct console;
......@@ -45,35 +46,21 @@ extern int kgdb_portnum;
extern int kgdb_baud;
extern char kgdb_parity;
extern char kgdb_bits;
extern int kgdb_console_setup(struct console *, char *);
/* Init and interface stuff */
extern int kgdb_init(void);
extern int (*kgdb_serial_setup)(void);
extern int (*kgdb_getchar)(void);
extern void (*kgdb_putchar)(int);
struct kgdb_sermap {
char *name;
int namelen;
int (*setup_fn)(struct console *, char *);
struct kgdb_sermap *next;
};
extern void kgdb_register_sermap(struct kgdb_sermap *map);
extern struct kgdb_sermap *kgdb_porttype;
/* Trap functions */
typedef void (kgdb_debug_hook_t)(struct pt_regs *regs);
typedef void (kgdb_debug_hook_t)(struct pt_regs *regs);
typedef void (kgdb_bus_error_hook_t)(void);
extern kgdb_debug_hook_t *kgdb_debug_hook;
extern kgdb_bus_error_hook_t *kgdb_bus_err_hook;
extern void breakpoint(void);
/* Console */
struct console;
void kgdb_console_write(struct console *co, const char *s, unsigned count);
void kgdb_console_init(void);
extern int kgdb_console_setup(struct console *, char *);
/* Prototypes for jmp fns */
#define _JBLEN 9
......@@ -81,11 +68,8 @@ typedef int jmp_buf[_JBLEN];
extern void longjmp(jmp_buf __jmpb, int __retval);
extern int setjmp(jmp_buf __jmpb);
/* Variadic macro to print our own message to the console */
#define KGDB_PRINTK(...) printk("KGDB: " __VA_ARGS__)
/* Forced breakpoint */
#define BREAKPOINT() \
#define breakpoint() \
do { \
if (kgdb_enabled) \
__asm__ __volatile__("trapa #0x3c"); \
......@@ -95,7 +79,6 @@ do { \
#if defined(CONFIG_CPU_SH4)
#define kgdb_flush_icache_range(start, end) \
{ \
extern void __flush_purge_region(void *, int); \
__flush_purge_region((void*)(start), (int)(end) - (int)(start));\
flush_icache_range((start), (end)); \
}
......@@ -103,31 +86,6 @@ do { \
#define kgdb_flush_icache_range(start, end) do { } while (0)
#endif
/* Kernel assert macros */
#ifdef CONFIG_KGDB_KERNEL_ASSERTS
/* Predefined conditions */
#define KA_VALID_ERRNO(errno) ((errno) > 0 && (errno) <= EMEDIUMTYPE)
#define KA_VALID_PTR_ERR(ptr) KA_VALID_ERRNO(-PTR_ERR(ptr))
#define KA_VALID_KPTR(ptr) (!(ptr) || \
((void *)(ptr) >= (void *)PAGE_OFFSET && \
(void *)(ptr) < ERR_PTR(-EMEDIUMTYPE)))
#define KA_VALID_PTRORERR(errptr) \
(KA_VALID_KPTR(errptr) || KA_VALID_PTR_ERR(errptr))
#define KA_HELD_GKL() (current->lock_depth >= 0)
/* The actual assert */
#define KGDB_ASSERT(condition, message) do { \
if (!(condition) && (kgdb_enabled)) { \
KGDB_PRINTK("Assertion failed at %s:%d: %s\n", \
__FILE__, __LINE__, message);\
BREAKPOINT(); \
} \
} while (0)
#else
#define KGDB_ASSERT(condition, message)
#endif
/* Taken from sh-stub.c of GDB 4.18 */
static const char hexchars[] = "0123456789abcdef";
......@@ -142,5 +100,4 @@ static inline char lowhex(const int x)
{
return hexchars[x & 0xf];
}
#endif
......@@ -65,6 +65,8 @@
#define IRQ_79C973 13
void init_7751se_IRQ(void);
#define __IO_PREFIX sh7751se
#include <asm/io_generic.h>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册