sh: Generic kgdb stub support.
This migrates from the old bitrotted kgdb stub implementation and moves to the generic stub. In the process support for SH-2/SH-2A is also added, which the old stub never provided. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
d7b01f78a3
commit
ab6e570ba3
|
@ -27,6 +27,7 @@ config SUPERH32
|
|||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_ARCH_KGDB
|
||||
|
||||
config SUPERH64
|
||||
def_bool y if CPU_SH5
|
||||
|
|
|
@ -98,19 +98,6 @@ config IRQSTACKS
|
|||
for handling hard and soft interrupts. This can help avoid
|
||||
overflowing the process kernel stacks.
|
||||
|
||||
config SH_KGDB
|
||||
bool "Include KGDB kernel debugger"
|
||||
select FRAME_POINTER
|
||||
select DEBUG_INFO
|
||||
depends on CPU_SH3 || CPU_SH4
|
||||
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 SH_KGDB
|
||||
|
||||
config MORE_COMPILE_OPTIONS
|
||||
bool "Add any additional compile options"
|
||||
help
|
||||
|
@ -122,62 +109,6 @@ config COMPILE_OPTIONS
|
|||
string "Additional compile arguments"
|
||||
depends on MORE_COMPILE_OPTIONS
|
||||
|
||||
config KGDB_NMI
|
||||
def_bool n
|
||||
prompt "Enter KGDB on NMI"
|
||||
|
||||
config SH_KGDB_CONSOLE
|
||||
def_bool n
|
||||
prompt "Console messages through GDB"
|
||||
depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
|
||||
config KGDB_SYSRQ
|
||||
def_bool y
|
||||
prompt "Allow SysRq 'G' to enter KGDB"
|
||||
depends on MAGIC_SYSRQ
|
||||
|
||||
comment "Serial port setup"
|
||||
|
||||
config KGDB_DEFPORT
|
||||
int "Port number (ttySCn)"
|
||||
default "1"
|
||||
|
||||
config KGDB_DEFBAUD
|
||||
int "Baud rate"
|
||||
default "115200"
|
||||
|
||||
choice
|
||||
prompt "Parity"
|
||||
depends on SH_KGDB
|
||||
default KGDB_DEFPARITY_N
|
||||
|
||||
config KGDB_DEFPARITY_N
|
||||
bool "None"
|
||||
|
||||
config KGDB_DEFPARITY_E
|
||||
bool "Even"
|
||||
|
||||
config KGDB_DEFPARITY_O
|
||||
bool "Odd"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Data bits"
|
||||
depends on SH_KGDB
|
||||
default KGDB_DEFBITS_8
|
||||
|
||||
config KGDB_DEFBITS_8
|
||||
bool "8"
|
||||
|
||||
config KGDB_DEFBITS_7
|
||||
bool "7"
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
if SUPERH64
|
||||
|
||||
config SH64_SR_WATCH
|
||||
|
|
|
@ -1,21 +1,7 @@
|
|||
/*
|
||||
* May be copied or modified under the terms of the GNU General Public
|
||||
* License. See linux/COPYING for more information.
|
||||
*
|
||||
* Based on original code by Glenn Engel, Jim Kingdon,
|
||||
* David Grothe <dave@gcom.com>, Tigran Aivazian, <tigran@sco.com> and
|
||||
* Amit S. Kale <akale@veritas.com>
|
||||
*
|
||||
* Super-H port based on sh-stub.c (Ben Lee and Steve Chamberlain) by
|
||||
* Henry Bell <henry.bell@st.com>
|
||||
*
|
||||
* Header file for low-level support for remote debug using GDB.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __KGDB_H
|
||||
#define __KGDB_H
|
||||
#ifndef __ASM_SH_KGDB_H
|
||||
#define __ASM_SH_KGDB_H
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/* Same as pt_regs but has vbr in place of syscall_nr */
|
||||
|
@ -30,40 +16,26 @@ struct kgdb_regs {
|
|||
unsigned long vbr;
|
||||
};
|
||||
|
||||
enum regnames {
|
||||
GDB_R0, GDB_R1, GDB_R2, GDB_R3, GDB_R4, GDB_R5, GDB_R6, GDB_R7,
|
||||
GDB_R8, GDB_R9, GDB_R10, GDB_R11, GDB_R12, GDB_R13, GDB_R14, GDB_R15,
|
||||
|
||||
GDB_PC, GDB_PR, GDB_SR, GDB_GBR, GDB_MACH, GDB_MACL, GDB_VBR,
|
||||
};
|
||||
|
||||
#define NUMREGBYTES ((GDB_VBR + 1) * 4)
|
||||
|
||||
static inline void arch_kgdb_breakpoint(void)
|
||||
{
|
||||
__asm__ __volatile__ ("trapa #0x3c\n");
|
||||
}
|
||||
|
||||
/* State info */
|
||||
extern char kgdb_in_gdb_mode;
|
||||
extern int kgdb_nofault; /* Ignore bus errors (in gdb mem access) */
|
||||
extern char in_nmi; /* Debounce flag to prevent NMI reentry*/
|
||||
|
||||
/* SCI */
|
||||
extern int kgdb_portnum;
|
||||
extern int kgdb_baud;
|
||||
extern char kgdb_parity;
|
||||
extern char kgdb_bits;
|
||||
#define BUFMAX 2048
|
||||
|
||||
/* Init and interface stuff */
|
||||
extern int kgdb_init(void);
|
||||
extern int (*kgdb_getchar)(void);
|
||||
extern void (*kgdb_putchar)(int);
|
||||
#define CACHE_FLUSH_IS_SAFE 1
|
||||
#define BREAK_INSTR_SIZE 2
|
||||
|
||||
/* Trap functions */
|
||||
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;
|
||||
|
||||
/* Console */
|
||||
struct console;
|
||||
void kgdb_console_write(struct console *co, const char *s, unsigned count);
|
||||
extern int kgdb_console_setup(struct console *, char *);
|
||||
|
||||
/* Prototypes for jmp fns */
|
||||
#define _JBLEN 9
|
||||
typedef int jmp_buf[_JBLEN];
|
||||
extern void longjmp(jmp_buf __jmpb, int __retval);
|
||||
extern int setjmp(jmp_buf __jmpb);
|
||||
|
||||
/* Forced breakpoint */
|
||||
#define breakpoint() __asm__ __volatile__("trapa #0x3c")
|
||||
|
||||
#endif
|
||||
#endif /* __ASM_SH_KGDB_H */
|
||||
|
|
|
@ -175,6 +175,8 @@ asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs)
|
|||
BUILD_TRAP_HANDLER(address_error);
|
||||
BUILD_TRAP_HANDLER(debug);
|
||||
BUILD_TRAP_HANDLER(bug);
|
||||
BUILD_TRAP_HANDLER(breakpoint);
|
||||
BUILD_TRAP_HANDLER(singlestep);
|
||||
BUILD_TRAP_HANDLER(fpu_error);
|
||||
BUILD_TRAP_HANDLER(fpu_state_restore);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ obj-$(CONFIG_VSYSCALL) += vsyscall/
|
|||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
|
||||
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
|
||||
obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
* syscall #
|
||||
*
|
||||
*/
|
||||
#if defined(CONFIG_KGDB_NMI)
|
||||
#if defined(CONFIG_KGDB)
|
||||
NMI_VEC = 0x1c0 ! Must catch early for debounce
|
||||
#endif
|
||||
|
||||
|
@ -307,7 +307,7 @@ skip_restore:
|
|||
6: or k0, k2 ! Set the IMASK-bits
|
||||
ldc k2, ssr
|
||||
!
|
||||
#if defined(CONFIG_KGDB_NMI)
|
||||
#if defined(CONFIG_KGDB)
|
||||
! Clear in_nmi
|
||||
mov.l 6f, k0
|
||||
mov #0, k1
|
||||
|
@ -320,7 +320,7 @@ skip_restore:
|
|||
|
||||
.align 2
|
||||
5: .long 0x00001000 ! DSP
|
||||
#ifdef CONFIG_KGDB_NMI
|
||||
#ifdef CONFIG_KGDB
|
||||
6: .long in_nmi
|
||||
#endif
|
||||
7: .long 0x30000000
|
||||
|
@ -377,7 +377,7 @@ tlb_miss:
|
|||
.balign 512,0,512
|
||||
interrupt:
|
||||
mov.l 3f, k3
|
||||
#if defined(CONFIG_KGDB_NMI)
|
||||
#if defined(CONFIG_KGDB)
|
||||
mov.l 2f, k2
|
||||
! Debounce (filter nested NMI)
|
||||
mov.l @k2, k0
|
||||
|
@ -394,7 +394,7 @@ interrupt:
|
|||
5: .long NMI_VEC
|
||||
6: .long in_nmi
|
||||
0:
|
||||
#endif /* defined(CONFIG_KGDB_NMI) */
|
||||
#endif /* defined(CONFIG_KGDB) */
|
||||
bra handle_exception
|
||||
mov #-1, k2 ! interrupt exception marker
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#define fpu_error_trap_handler exception_error
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_KGDB_NMI)
|
||||
#if !defined(CONFIG_KGDB)
|
||||
#define kgdb_handle_exception exception_error
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Debug trap jump tables for SuperH
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
* Copyright (C) 2006 - 2008 Paul Mundt
|
||||
*
|
||||
* 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
|
||||
|
@ -12,12 +12,13 @@
|
|||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#if !defined(CONFIG_SH_KGDB)
|
||||
#define kgdb_handle_exception debug_trap_handler
|
||||
#if !defined(CONFIG_KGDB)
|
||||
#define breakpoint_trap_handler debug_trap_handler
|
||||
#define singlestep_trap_handler debug_trap_handler
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_SH_STANDARD_BIOS)
|
||||
#define sh_bios_handler debug_trap_handler
|
||||
#define sh_bios_handler debug_trap_handler
|
||||
#endif
|
||||
|
||||
.data
|
||||
|
@ -35,7 +36,7 @@ ENTRY(debug_trap_table)
|
|||
.long debug_trap_handler /* 0x39 */
|
||||
.long debug_trap_handler /* 0x3a */
|
||||
.long debug_trap_handler /* 0x3b */
|
||||
.long kgdb_handle_exception /* 0x3c */
|
||||
.long debug_trap_handler /* 0x3d */
|
||||
.long breakpoint_trap_handler /* 0x3c */
|
||||
.long singlestep_trap_handler /* 0x3d */
|
||||
.long bug_trap_handler /* 0x3e */
|
||||
.long sh_bios_handler /* 0x3f */
|
||||
|
|
|
@ -308,15 +308,19 @@ ENTRY(system_call)
|
|||
mov.l 1f, r9
|
||||
mov.l @r9, r8 ! Read from TRA (Trap Address) Register
|
||||
#endif
|
||||
|
||||
mov #OFF_TRA, r10
|
||||
add r15, r10
|
||||
mov.l r8, @r10 ! set TRA value to tra
|
||||
|
||||
/*
|
||||
* Check the trap type
|
||||
*/
|
||||
mov #((0x20 << 2) - 1), r9
|
||||
cmp/hi r9, r8
|
||||
bt/s debug_trap ! it's a debug trap..
|
||||
mov #OFF_TRA, r9
|
||||
add r15, r9
|
||||
mov.l r8, @r9 ! set TRA value to tra
|
||||
nop
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
mov.l 5f, r10
|
||||
jsr @r10
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* SuperH KGDB support
|
||||
*
|
||||
* Copyright (C) 2008 Paul Mundt
|
||||
*
|
||||
* Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
char in_nmi = 0; /* Set during NMI to prevent re-entry */
|
||||
|
||||
/* Macros for single step instruction identification */
|
||||
#define OPCODE_BT(op) (((op) & 0xff00) == 0x8900)
|
||||
#define OPCODE_BF(op) (((op) & 0xff00) == 0x8b00)
|
||||
#define OPCODE_BTF_DISP(op) (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
|
||||
(((op) & 0x7f ) << 1))
|
||||
#define OPCODE_BFS(op) (((op) & 0xff00) == 0x8f00)
|
||||
#define OPCODE_BTS(op) (((op) & 0xff00) == 0x8d00)
|
||||
#define OPCODE_BRA(op) (((op) & 0xf000) == 0xa000)
|
||||
#define OPCODE_BRA_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
|
||||
(((op) & 0x7ff) << 1))
|
||||
#define OPCODE_BRAF(op) (((op) & 0xf0ff) == 0x0023)
|
||||
#define OPCODE_BRAF_REG(op) (((op) & 0x0f00) >> 8)
|
||||
#define OPCODE_BSR(op) (((op) & 0xf000) == 0xb000)
|
||||
#define OPCODE_BSR_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
|
||||
(((op) & 0x7ff) << 1))
|
||||
#define OPCODE_BSRF(op) (((op) & 0xf0ff) == 0x0003)
|
||||
#define OPCODE_BSRF_REG(op) (((op) >> 8) & 0xf)
|
||||
#define OPCODE_JMP(op) (((op) & 0xf0ff) == 0x402b)
|
||||
#define OPCODE_JMP_REG(op) (((op) >> 8) & 0xf)
|
||||
#define OPCODE_JSR(op) (((op) & 0xf0ff) == 0x400b)
|
||||
#define OPCODE_JSR_REG(op) (((op) >> 8) & 0xf)
|
||||
#define OPCODE_RTS(op) ((op) == 0xb)
|
||||
#define OPCODE_RTE(op) ((op) == 0x2b)
|
||||
|
||||
#define SR_T_BIT_MASK 0x1
|
||||
#define STEP_OPCODE 0xc33d
|
||||
|
||||
/* Calculate the new address for after a step */
|
||||
static short *get_step_address(struct pt_regs *linux_regs)
|
||||
{
|
||||
opcode_t op = __raw_readw(linux_regs->pc);
|
||||
long addr;
|
||||
|
||||
/* BT */
|
||||
if (OPCODE_BT(op)) {
|
||||
if (linux_regs->sr & SR_T_BIT_MASK)
|
||||
addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
|
||||
else
|
||||
addr = linux_regs->pc + 2;
|
||||
}
|
||||
|
||||
/* BTS */
|
||||
else if (OPCODE_BTS(op)) {
|
||||
if (linux_regs->sr & SR_T_BIT_MASK)
|
||||
addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
|
||||
else
|
||||
addr = linux_regs->pc + 4; /* Not in delay slot */
|
||||
}
|
||||
|
||||
/* BF */
|
||||
else if (OPCODE_BF(op)) {
|
||||
if (!(linux_regs->sr & SR_T_BIT_MASK))
|
||||
addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
|
||||
else
|
||||
addr = linux_regs->pc + 2;
|
||||
}
|
||||
|
||||
/* BFS */
|
||||
else if (OPCODE_BFS(op)) {
|
||||
if (!(linux_regs->sr & SR_T_BIT_MASK))
|
||||
addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
|
||||
else
|
||||
addr = linux_regs->pc + 4; /* Not in delay slot */
|
||||
}
|
||||
|
||||
/* BRA */
|
||||
else if (OPCODE_BRA(op))
|
||||
addr = linux_regs->pc + 4 + OPCODE_BRA_DISP(op);
|
||||
|
||||
/* BRAF */
|
||||
else if (OPCODE_BRAF(op))
|
||||
addr = linux_regs->pc + 4
|
||||
+ linux_regs->regs[OPCODE_BRAF_REG(op)];
|
||||
|
||||
/* BSR */
|
||||
else if (OPCODE_BSR(op))
|
||||
addr = linux_regs->pc + 4 + OPCODE_BSR_DISP(op);
|
||||
|
||||
/* BSRF */
|
||||
else if (OPCODE_BSRF(op))
|
||||
addr = linux_regs->pc + 4
|
||||
+ linux_regs->regs[OPCODE_BSRF_REG(op)];
|
||||
|
||||
/* JMP */
|
||||
else if (OPCODE_JMP(op))
|
||||
addr = linux_regs->regs[OPCODE_JMP_REG(op)];
|
||||
|
||||
/* JSR */
|
||||
else if (OPCODE_JSR(op))
|
||||
addr = linux_regs->regs[OPCODE_JSR_REG(op)];
|
||||
|
||||
/* RTS */
|
||||
else if (OPCODE_RTS(op))
|
||||
addr = linux_regs->pr;
|
||||
|
||||
/* RTE */
|
||||
else if (OPCODE_RTE(op))
|
||||
addr = linux_regs->regs[15];
|
||||
|
||||
/* Other */
|
||||
else
|
||||
addr = linux_regs->pc + instruction_size(op);
|
||||
|
||||
flush_icache_range(addr, addr + instruction_size(op));
|
||||
return (short *)addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 with delay
|
||||
* slots (e.g. B[TF]S, BSR, BRA etc), where both the branch and the
|
||||
* instruction in the delay slot will be executed.
|
||||
*/
|
||||
|
||||
static unsigned long stepped_address;
|
||||
static opcode_t stepped_opcode;
|
||||
|
||||
static void do_single_step(struct pt_regs *linux_regs)
|
||||
{
|
||||
/* Determine where the target instruction will send us to */
|
||||
unsigned short *addr = get_step_address(linux_regs);
|
||||
|
||||
stepped_address = (int)addr;
|
||||
|
||||
/* Replace it */
|
||||
stepped_opcode = __raw_readw((long)addr);
|
||||
*addr = STEP_OPCODE;
|
||||
|
||||
/* Flush and return */
|
||||
flush_icache_range((long)addr, (long)addr +
|
||||
instruction_size(stepped_opcode));
|
||||
}
|
||||
|
||||
/* Undo a single step */
|
||||
static void undo_single_step(struct pt_regs *linux_regs)
|
||||
{
|
||||
/* If we have stepped, put back the old instruction */
|
||||
/* Use stepped_address in case we stopped elsewhere */
|
||||
if (stepped_opcode != 0) {
|
||||
__raw_writew(stepped_opcode, stepped_address);
|
||||
flush_icache_range(stepped_address, stepped_address + 2);
|
||||
}
|
||||
|
||||
stepped_opcode = 0;
|
||||
}
|
||||
|
||||
void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
gdb_regs[GDB_R0 + i] = regs->regs[i];
|
||||
|
||||
gdb_regs[GDB_PC] = regs->pc;
|
||||
gdb_regs[GDB_PR] = regs->pr;
|
||||
gdb_regs[GDB_SR] = regs->sr;
|
||||
gdb_regs[GDB_GBR] = regs->gbr;
|
||||
gdb_regs[GDB_MACH] = regs->mach;
|
||||
gdb_regs[GDB_MACL] = regs->macl;
|
||||
|
||||
__asm__ __volatile__ ("stc vbr, %0" : "=r" (gdb_regs[GDB_VBR]));
|
||||
}
|
||||
|
||||
void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
regs->regs[GDB_R0 + i] = gdb_regs[GDB_R0 + i];
|
||||
|
||||
regs->pc = gdb_regs[GDB_PC];
|
||||
regs->pr = gdb_regs[GDB_PR];
|
||||
regs->sr = gdb_regs[GDB_SR];
|
||||
regs->gbr = gdb_regs[GDB_GBR];
|
||||
regs->mach = gdb_regs[GDB_MACH];
|
||||
regs->macl = gdb_regs[GDB_MACL];
|
||||
|
||||
__asm__ __volatile__ ("ldc %0, vbr" : : "r" (gdb_regs[GDB_VBR]));
|
||||
}
|
||||
|
||||
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
{
|
||||
gdb_regs[GDB_R15] = p->thread.sp;
|
||||
gdb_regs[GDB_PC] = p->thread.pc;
|
||||
}
|
||||
|
||||
int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
|
||||
char *remcomInBuffer, char *remcomOutBuffer,
|
||||
struct pt_regs *linux_regs)
|
||||
{
|
||||
unsigned long addr;
|
||||
char *ptr;
|
||||
|
||||
/* Undo any stepping we may have done */
|
||||
undo_single_step(linux_regs);
|
||||
|
||||
switch (remcomInBuffer[0]) {
|
||||
case 'c':
|
||||
case 's':
|
||||
/* try to read optional parameter, pc unchanged if no parm */
|
||||
ptr = &remcomInBuffer[1];
|
||||
if (kgdb_hex2long(&ptr, &addr))
|
||||
linux_regs->pc = addr;
|
||||
case 'D':
|
||||
case 'k':
|
||||
atomic_set(&kgdb_cpu_doing_single_step, -1);
|
||||
|
||||
if (remcomInBuffer[0] == 's') {
|
||||
do_single_step(linux_regs);
|
||||
kgdb_single_step = 1;
|
||||
|
||||
atomic_set(&kgdb_cpu_doing_single_step,
|
||||
raw_smp_processor_id());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this means that we do not want to exit from the handler: */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The primary entry points for the kgdb debug trap table entries.
|
||||
*/
|
||||
BUILD_TRAP_HANDLER(singlestep)
|
||||
{
|
||||
unsigned long flags;
|
||||
TRAP_HANDLER_DECL;
|
||||
|
||||
local_irq_save(flags);
|
||||
regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
|
||||
kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
|
||||
BUILD_TRAP_HANDLER(breakpoint)
|
||||
{
|
||||
unsigned long flags;
|
||||
TRAP_HANDLER_DECL;
|
||||
|
||||
local_irq_save(flags);
|
||||
kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
int kgdb_arch_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kgdb_arch_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
struct kgdb_arch arch_kgdb_ops = {
|
||||
/* Breakpoint instruction: trapa #0x3c */
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
.gdb_bpt_instr = { 0x3c, 0xc3 },
|
||||
#else
|
||||
.gdb_bpt_instr = { 0xc3, 0x3c },
|
||||
#endif
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
#include <linux/linkage.h>
|
||||
|
||||
ENTRY(setjmp)
|
||||
add #(9*4), r4
|
||||
sts.l pr, @-r4
|
||||
mov.l r15, @-r4
|
||||
mov.l r14, @-r4
|
||||
mov.l r13, @-r4
|
||||
mov.l r12, @-r4
|
||||
mov.l r11, @-r4
|
||||
mov.l r10, @-r4
|
||||
mov.l r9, @-r4
|
||||
mov.l r8, @-r4
|
||||
rts
|
||||
mov #0, r0
|
||||
|
||||
ENTRY(longjmp)
|
||||
mov.l @r4+, r8
|
||||
mov.l @r4+, r9
|
||||
mov.l @r4+, r10
|
||||
mov.l @r4+, r11
|
||||
mov.l @r4+, r12
|
||||
mov.l @r4+, r13
|
||||
mov.l @r4+, r14
|
||||
mov.l @r4+, r15
|
||||
lds.l @r4+, pr
|
||||
mov r5, r0
|
||||
tst r0, r0
|
||||
bf 1f
|
||||
mov #1, r0 ! in case val==0
|
||||
1: rts
|
||||
nop
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -277,11 +277,4 @@ void __init time_init(void)
|
|||
((sh_hpt_frequency + 500) / 1000) / 1000,
|
||||
((sh_hpt_frequency + 500) / 1000) % 1000);
|
||||
|
||||
#if defined(CONFIG_SH_KGDB)
|
||||
/*
|
||||
* Set up kgdb as requested. We do it here because the serial
|
||||
* init uses the timer vars we just set up for figuring baud.
|
||||
*/
|
||||
kgdb_init();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -28,17 +28,6 @@
|
|||
#include <asm/fpu.h>
|
||||
#include <asm/kprobes.h>
|
||||
|
||||
#ifdef CONFIG_SH_KGDB
|
||||
#include <asm/kgdb.h>
|
||||
#define CHK_REMOTE_DEBUG(regs) \
|
||||
{ \
|
||||
if (kgdb_debug_hook && !user_mode(regs))\
|
||||
(*kgdb_debug_hook)(regs); \
|
||||
}
|
||||
#else
|
||||
#define CHK_REMOTE_DEBUG(regs)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_SH2
|
||||
# define TRAP_RESERVED_INST 4
|
||||
# define TRAP_ILLEGAL_SLOT_INST 6
|
||||
|
@ -94,7 +83,6 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
|
||||
printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
|
||||
|
||||
CHK_REMOTE_DEBUG(regs);
|
||||
print_modules();
|
||||
show_regs(regs);
|
||||
|
||||
|
@ -683,7 +671,6 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
|
|||
error_code = lookup_exception_vector();
|
||||
|
||||
local_irq_enable();
|
||||
CHK_REMOTE_DEBUG(regs);
|
||||
force_sig(SIGILL, tsk);
|
||||
die_if_no_fixup("reserved instruction", regs, error_code);
|
||||
}
|
||||
|
@ -761,7 +748,6 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
|
|||
inst = lookup_exception_vector();
|
||||
|
||||
local_irq_enable();
|
||||
CHK_REMOTE_DEBUG(regs);
|
||||
force_sig(SIGILL, tsk);
|
||||
die_if_no_fixup("illegal slot instruction", regs, inst);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <asm/system.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/kgdb.h>
|
||||
|
||||
/*
|
||||
* This routine handles page faults. It determines the address,
|
||||
|
@ -282,11 +281,6 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
|
|||
if (notify_page_fault(regs, lookup_exception_vector()))
|
||||
goto out;
|
||||
|
||||
#ifdef CONFIG_SH_KGDB
|
||||
if (kgdb_nofault && kgdb_bus_err_hook)
|
||||
kgdb_bus_err_hook();
|
||||
#endif
|
||||
|
||||
ret = 1;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue