diff options
-rw-r--r-- | arch/sparc/Kconfig | 1 | ||||
-rw-r--r-- | arch/sparc/defconfig | 139 | ||||
-rw-r--r-- | arch/sparc/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/entry.S | 125 | ||||
-rw-r--r-- | arch/sparc/kernel/head.S | 9 | ||||
-rw-r--r-- | arch/sparc/kernel/kgdb.c | 164 | ||||
-rw-r--r-- | arch/sparc/kernel/sparc-stub.c | 724 | ||||
-rw-r--r-- | arch/sparc64/Kconfig | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/sparc64/kernel/kgdb.c | 186 | ||||
-rw-r--r-- | arch/sparc64/kernel/misctrap.S | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/ttable.S | 2 | ||||
-rw-r--r-- | arch/sparc64/mm/ultra.S | 27 | ||||
-rw-r--r-- | include/asm-sparc/head.h | 11 | ||||
-rw-r--r-- | include/asm-sparc/kgdb.h | 116 | ||||
-rw-r--r-- | include/asm-sparc/system.h | 2 | ||||
-rw-r--r-- | include/asm-sparc64/kgdb.h | 1 | ||||
-rw-r--r-- | include/asm-sparc64/system.h | 5 | ||||
-rw-r--r-- | include/asm-sparc64/ttable.h | 6 |
20 files changed, 581 insertions, 960 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 49590f8fe98c..d211fdb24584 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -68,6 +68,7 @@ config SPARC default y select HAVE_IDE select HAVE_OPROFILE + select HAVE_ARCH_KGDB if !SMP # Identify this as a Sparc32 build config SPARC32 diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index 6a2c57a2fe71..2e3a149ea0e7 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.25 -# Sun Apr 20 01:49:51 2008 +# Tue Apr 29 01:28:58 2008 # CONFIG_MMU=y CONFIG_HIGHMEM=y @@ -217,12 +217,7 @@ CONFIG_IPV6_TUNNEL=m # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -CONFIG_SCTP_DBG_OBJCNT=y -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y +# CONFIG_IP_SCTP is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -245,9 +240,7 @@ CONFIG_NET_PKTGEN=m # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -CONFIG_AF_RXRPC=m -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_RXKAD is not set +# CONFIG_AF_RXRPC is not set # # Wireless @@ -390,7 +383,7 @@ CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set -CONFIG_TUN=m +# CONFIG_TUN is not set # CONFIG_VETH is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set @@ -544,6 +537,7 @@ CONFIG_SERIAL_SUNSU_CONSOLE=y # CONFIG_SERIAL_SUNSAB is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y @@ -595,6 +589,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set # # Multimedia devices @@ -645,10 +640,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -680,16 +671,12 @@ CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=m -CONFIG_XFS_QUOTA=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_RT=y +# CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_QUOTACTL=y CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m # CONFIG_FUSE_FS is not set @@ -725,11 +712,9 @@ CONFIG_SYSFS=y # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set @@ -744,7 +729,6 @@ CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y @@ -755,16 +739,10 @@ CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -CONFIG_AFS_FS=m -# CONFIG_AFS_DEBUG is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -821,6 +799,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -842,70 +821,105 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set +CONFIG_KGDB=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +CONFIG_KGDB_TESTS=y +# CONFIG_KGDB_TESTS_ON_BOOT is not set # CONFIG_DEBUG_STACK_USAGE is not set # # Security options # -CONFIG_KEYS=y -# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_BLKCIPHER=y -# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set -CONFIG_CRYPTO_NULL=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -# CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_AUTHENC=y # CONFIG_CRYPTO_LZO is not set # CONFIG_CRYPTO_HW is not set @@ -913,6 +927,7 @@ CONFIG_CRYPTO_AUTHENC=y # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 59700aaaae93..6e03a2a7863c 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_PCI) += ebus.o obj-$(CONFIG_SUN_PM) += apc.o pmc.o obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o obj-$(CONFIG_SPARC_LED) += led.o +obj-$(CONFIG_KGDB) += kgdb.o diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 484c83d23eef..57d1bbdd0bd2 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -12,7 +12,6 @@ #include <asm/head.h> #include <asm/asi.h> #include <asm/smp.h> -#include <asm/kgdb.h> #include <asm/contregs.h> #include <asm/ptrace.h> #include <asm/asm-offsets.h> @@ -45,91 +44,20 @@ _SV; _SV; _SV; _SV; _SV; _SV; _SV; \ _RS; _RS; _RS; _RS; _RS; _RS; _RS; -/* First, KGDB low level things. This is a rewrite - * of the routines found in the sparc-stub.c asm() statement - * from the gdb distribution. This is also dual-purpose - * as a software trap for userlevel programs. - */ - .data - .align 4 - -in_trap_handler: - .word 0 - .text - .align 4 -#if 0 /* kgdb is dropped from 2.5.33 */ -! This function is called when any SPARC trap (except window overflow or -! underflow) occurs. It makes sure that the invalid register window is still -! available before jumping into C code. It will also restore the world if you -! return from handle_exception. - - .globl trap_low -trap_low: - rd %wim, %l3 - SAVE_ALL - - sethi %hi(in_trap_handler), %l4 - ld [%lo(in_trap_handler) + %l4], %l5 - inc %l5 - st %l5, [%lo(in_trap_handler) + %l4] - - /* Make sure kgdb sees the same state we just saved. */ - LOAD_PT_GLOBALS(sp) - LOAD_PT_INS(sp) - ld [%sp + STACKFRAME_SZ + PT_Y], %l4 - ld [%sp + STACKFRAME_SZ + PT_WIM], %l3 - ld [%sp + STACKFRAME_SZ + PT_PSR], %l0 - ld [%sp + STACKFRAME_SZ + PT_PC], %l1 - ld [%sp + STACKFRAME_SZ + PT_NPC], %l2 - rd %tbr, %l5 /* Never changes... */ - - /* Make kgdb exception frame. */ - sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals - ! + hidden arg + arg spill - ! + doubleword alignment - ! + registers[72] local var - SAVE_KGDB_GLOBALS(sp) - SAVE_KGDB_INS(sp) - SAVE_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2) - - /* We are increasing PIL, so two writes. */ - or %l0, PSR_PIL, %l0 - wr %l0, 0, %psr - WRITE_PAUSE - wr %l0, PSR_ET, %psr - WRITE_PAUSE - - call handle_exception - add %sp, STACKFRAME_SZ, %o0 ! Pass address of registers - - /* Load new kgdb register set. */ - LOAD_KGDB_GLOBALS(sp) - LOAD_KGDB_INS(sp) - LOAD_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2) - wr %l4, 0x0, %y - - sethi %hi(in_trap_handler), %l4 - ld [%lo(in_trap_handler) + %l4], %l5 - dec %l5 - st %l5, [%lo(in_trap_handler) + %l4] - - add %sp,(16+1+6+1+72)*4,%sp ! Undo the kgdb trap frame. - - /* Now take what kgdb did and place it into the pt_regs - * frame which SparcLinux RESTORE_ALL understands., - */ - STORE_PT_INS(sp) - STORE_PT_GLOBALS(sp) - STORE_PT_YREG(sp, g2) - STORE_PT_PRIV(sp, l0, l1, l2) - - RESTORE_ALL +#ifdef CONFIG_KGDB + .align 4 + .globl arch_kgdb_breakpoint + .type arch_kgdb_breakpoint,#function +arch_kgdb_breakpoint: + ta 0x7d + retl + nop + .size arch_kgdb_breakpoint,.-arch_kgdb_breakpoint #endif #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) - .text .align 4 .globl floppy_hardint floppy_hardint: @@ -1596,6 +1524,23 @@ breakpoint_trap: RESTORE_ALL +#ifdef CONFIG_KGDB + .align 4 + .globl kgdb_trap_low + .type kgdb_trap_low,#function +kgdb_trap_low: + rd %wim,%l3 + SAVE_ALL + wr %l0, PSR_ET, %psr + WRITE_PAUSE + + call kgdb_trap + add %sp, STACKFRAME_SZ, %o0 + + RESTORE_ALL + .size kgdb_trap_low,.-kgdb_trap_low +#endif + .align 4 .globl __handle_exception, flush_patch_exception __handle_exception: @@ -1698,4 +1643,22 @@ pcic_nmi_trap_patch: #endif /* CONFIG_PCI */ + .globl flushw_all +flushw_all: + save %sp, -0x40, %sp + save %sp, -0x40, %sp + save %sp, -0x40, %sp + save %sp, -0x40, %sp + save %sp, -0x40, %sp + save %sp, -0x40, %sp + save %sp, -0x40, %sp + restore + restore + restore + restore + restore + restore + ret + restore + /* End of entry.S */ diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S index b7f1e81c8ff2..8bec05fa5795 100644 --- a/arch/sparc/kernel/head.S +++ b/arch/sparc/kernel/head.S @@ -191,7 +191,8 @@ t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xe t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) -t_badfc:BAD_TRAP(0xfc) BAD_TRAP(0xfd) +t_badfc:BAD_TRAP(0xfc) +t_kgdb: KGDB_TRAP(0xfd) dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */ dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */ @@ -267,7 +268,7 @@ trapbase_cpu1: BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) + BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) trapbase_cpu2: BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) @@ -335,7 +336,7 @@ trapbase_cpu2: BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) + BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) trapbase_cpu3: BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) @@ -403,7 +404,7 @@ trapbase_cpu3: BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) + BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) #endif .align PAGE_SIZE diff --git a/arch/sparc/kernel/kgdb.c b/arch/sparc/kernel/kgdb.c new file mode 100644 index 000000000000..757805ce02ee --- /dev/null +++ b/arch/sparc/kernel/kgdb.c @@ -0,0 +1,164 @@ +/* kgdb.c: KGDB support for 32-bit sparc. + * + * Copyright (C) 2008 David S. Miller <davem@davemloft.net> + */ + +#include <linux/kgdb.h> +#include <linux/kdebug.h> + +#include <asm/kdebug.h> +#include <asm/ptrace.h> +#include <asm/irq.h> + +extern unsigned long trapbase; + +void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) +{ + struct reg_window *win; + int i; + + gdb_regs[GDB_G0] = 0; + for (i = 0; i < 15; i++) + gdb_regs[GDB_G1 + i] = regs->u_regs[UREG_G1 + i]; + + win = (struct reg_window *) regs->u_regs[UREG_FP]; + for (i = 0; i < 8; i++) + gdb_regs[GDB_L0 + i] = win->locals[i]; + for (i = 0; i < 8; i++) + gdb_regs[GDB_I0 + i] = win->ins[i]; + + for (i = GDB_F0; i <= GDB_F31; i++) + gdb_regs[i] = 0; + + gdb_regs[GDB_Y] = regs->y; + gdb_regs[GDB_PSR] = regs->psr; + gdb_regs[GDB_WIM] = 0; + gdb_regs[GDB_TBR] = (unsigned long) &trapbase; + gdb_regs[GDB_PC] = regs->pc; + gdb_regs[GDB_NPC] = regs->npc; + gdb_regs[GDB_FSR] = 0; + gdb_regs[GDB_CSR] = 0; +} + +void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) +{ + struct thread_info *t = task_thread_info(p); + struct reg_window *win; + int i; + + for (i = GDB_G0; i < GDB_G6; i++) + gdb_regs[i] = 0; + gdb_regs[GDB_G6] = (unsigned long) t; + gdb_regs[GDB_G7] = 0; + for (i = GDB_O0; i < GDB_SP; i++) + gdb_regs[i] = 0; + gdb_regs[GDB_SP] = t->ksp; + gdb_regs[GDB_O7] = 0; + + win = (struct reg_window *) t->ksp; + for (i = 0; i < 8; i++) + gdb_regs[GDB_L0 + i] = win->locals[i]; + for (i = 0; i < 8; i++) + gdb_regs[GDB_I0 + i] = win->ins[i]; + + for (i = GDB_F0; i <= GDB_F31; i++) + gdb_regs[i] = 0; + + gdb_regs[GDB_Y] = 0; + + gdb_regs[GDB_PSR] = t->kpsr; + gdb_regs[GDB_WIM] = t->kwim; + gdb_regs[GDB_TBR] = (unsigned long) &trapbase; + gdb_regs[GDB_PC] = t->kpc; + gdb_regs[GDB_NPC] = t->kpc + 4; + gdb_regs[GDB_FSR] = 0; + gdb_regs[GDB_CSR] = 0; +} + +void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) +{ + struct reg_window *win; + int i; + + for (i = 0; i < 15; i++) + regs->u_regs[UREG_G1 + i] = gdb_regs[GDB_G1 + i]; + + /* If the PSR register is changing, we have to preserve + * the CWP field, otherwise window save/restore explodes. + */ + if (regs->psr != gdb_regs[GDB_PSR]) { + unsigned long cwp = regs->psr & PSR_CWP; + + regs->psr = (gdb_regs[GDB_PSR] & ~PSR_CWP) | cwp; + } + + regs->pc = gdb_regs[GDB_PC]; + regs->npc = gdb_regs[GDB_NPC]; + regs->y = gdb_regs[GDB_Y]; + + win = (struct reg_window *) regs->u_regs[UREG_FP]; + for (i = 0; i < 8; i++) + win->locals[i] = gdb_regs[GDB_L0 + i]; + for (i = 0; i < 8; i++) + win->ins[i] = gdb_regs[GDB_I0 + i]; +} + +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; + + switch (remcomInBuffer[0]) { + case 'c': + /* try to read optional parameter, pc unchanged if no parm */ + ptr = &remcomInBuffer[1]; + if (kgdb_hex2long(&ptr, &addr)) { + linux_regs->pc = addr; + linux_regs->npc = addr + 4; + } + /* fallthru */ + + case 'D': + case 'k': + if (linux_regs->pc == (unsigned long) arch_kgdb_breakpoint) { + linux_regs->pc = linux_regs->npc; + linux_regs->npc += 4; + } + return 0; + } + return -1; +} + +extern void do_hw_interrupt(struct pt_regs *regs, unsigned long type); + +asmlinkage void kgdb_trap(struct pt_regs *regs) +{ + unsigned long flags; + + if (user_mode(regs)) { + do_hw_interrupt(regs, 0xfd); + return; + } + + flushw_all(); + + local_irq_save(flags); + kgdb_handle_exception(0x172, 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: ta 0x7d */ + .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x7d }, +}; diff --git a/arch/sparc/kernel/sparc-stub.c b/arch/sparc/kernel/sparc-stub.c deleted file mode 100644 index e84f815e6903..000000000000 --- a/arch/sparc/kernel/sparc-stub.c +++ /dev/null @@ -1,724 +0,0 @@ -/* $Id: sparc-stub.c,v 1.28 2001/10/30 04:54:21 davem Exp $ - * sparc-stub.c: KGDB support for the Linux kernel. - * - * Modifications to run under Linux - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * - * This file originally came from the gdb sources, and the - * copyright notices have been retained below. - */ - -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or its performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for SPARC by Stu Grossman, Cygnus Support. - * - * This code has been extensively tested on the Fujitsu SPARClite demo board. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * bBB..BB Set baud rate to BB..BB OK or BNN, then sets - * baud rate - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $<packet info>#<checksum>. - * - * where - * <packet info> :: <characters representing the command or response> - * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <asm/system.h> -#include <asm/signal.h> -#include <asm/oplib.h> -#include <asm/head.h> -#include <asm/traps.h> -#include <asm/vac-ops.h> -#include <asm/kgdb.h> -#include <asm/pgalloc.h> -#include <asm/pgtable.h> -#include <asm/cacheflush.h> - -/* - * - * external low-level support routines - */ - -extern void putDebugChar(char); /* write a single character */ -extern char getDebugChar(void); /* read and return a single char */ - -/* - * BUFMAX defines the maximum number of characters in inbound/outbound buffers - * at least NUMREGBYTES*2 are needed for register packets - */ -#define BUFMAX 2048 - -static int initialized; /* !0 means we've been initialized */ - -static const char hexchars[]="0123456789abcdef"; - -#define NUMREGS 72 - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) -enum regnames {G0, G1, G2, G3, G4, G5, G6, G7, - O0, O1, O2, O3, O4, O5, SP, O7, - L0, L1, L2, L3, L4, L5, L6, L7, - I0, I1, I2, I3, I4, I5, FP, I7, - - F0, F1, F2, F3, F4, F5, F6, F7, - F8, F9, F10, F11, F12, F13, F14, F15, - F16, F17, F18, F19, F20, F21, F22, F23, - F24, F25, F26, F27, F28, F29, F30, F31, - Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR }; - - -extern void trap_low(void); /* In arch/sparc/kernel/entry.S */ - -unsigned long get_sun4cpte(unsigned long addr) -{ - unsigned long entry; - - __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : - "=r" (entry) : - "r" (addr), "i" (ASI_PTE)); - return entry; -} - -unsigned long get_sun4csegmap(unsigned long addr) -{ - unsigned long entry; - - __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : - "=r" (entry) : - "r" (addr), "i" (ASI_SEGMAP)); - return entry; -} - -#if 0 -/* Have to sort this out. This cannot be done after initialization. */ -static void flush_cache_all_nop(void) {} -#endif - -/* Place where we save old trap entries for restoration */ -struct tt_entry kgdb_savettable[256]; -typedef void (*trapfunc_t)(void); - -/* Helper routine for manipulation of kgdb_savettable */ -static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest) -{ - dest->inst_one = src->inst_one; - dest->inst_two = src->inst_two; - dest->inst_three = src->inst_three; - dest->inst_four = src->inst_four; -} - -/* Initialize the kgdb_savettable so that debugging can commence */ -static void eh_init(void) -{ - int i; - - for(i=0; i < 256; i++) - copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]); -} - -/* Install an exception handler for kgdb */ -static void exceptionHandler(int tnum, trapfunc_t trap_entry) -{ - unsigned long te_addr = (unsigned long) trap_entry; - - /* Make new vector */ - sparc_ttable[tnum].inst_one = - SPARC_BRANCH((unsigned long) te_addr, - (unsigned long) &sparc_ttable[tnum].inst_one); - sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0; - sparc_ttable[tnum].inst_three = SPARC_NOP; - sparc_ttable[tnum].inst_four = SPARC_NOP; -} - -/* Convert ch from a hex digit to an int */ -static int -hex(unsigned char ch) -{ - if (ch >= 'a' && ch <= 'f') - return ch-'a'+10; - if (ch >= '0' && ch <= '9') - return ch-'0'; - if (ch >= 'A' && ch <= 'F') - return ch-'A'+10; - return -1; -} - -/* scan for the sequence $<data>#<checksum> */ -static void -getpacket(char *buffer) -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do { - /* wait around for the start character, ignore all other characters */ - while ((ch = (getDebugChar() & 0x7f)) != '$') ; - - checksum = 0; - xmitcsum = -1; - - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) { - ch = getDebugChar() & 0x7f; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - - if (count >= BUFMAX) - continue; - - buffer[count] = 0; - - if (ch == '#') { - xmitcsum = hex(getDebugChar() & 0x7f) << 4; - xmitcsum |= hex(getDebugChar() & 0x7f); - if (checksum != xmitcsum) - putDebugChar('-'); /* failed checksum */ - else { - putDebugChar('+'); /* successful transfer */ - /* if a sequence char is present, reply the ID */ - if (buffer[2] == ':') { - putDebugChar(buffer[0]); - putDebugChar(buffer[1]); - /* remove sequence chars from buffer */ - count = strlen(buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; - } - } - } - } while (checksum != xmitcsum); -} - -/* send the packet in buffer. */ - -static void -putpacket(unsigned char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch, recv; - - /* $<packet info>#<checksum>. */ - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while ((ch = buffer[count])) { - putDebugChar(ch); - checksum += ch; - count += 1; - } - - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum & 0xf]); - recv = getDebugChar(); - } while ((recv & 0x7f) != '+'); -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -/* Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null), in case of mem fault, - * return 0. - */ - -static unsigned char * -mem2hex(char *mem, char *buf, int count) -{ - unsigned char ch; - - while (count-- > 0) { - /* This assembler code is basically: ch = *mem++; - * except that we use the SPARC/Linux exception table - * mechanism (see how "fixup" works in kernel_mna_trap_fault) - * to arrange for a "return 0" upon a memory fault - */ - __asm__( - "\n1:\n\t" - "ldub [%0], %1\n\t" - "inc %0\n\t" - ".section .fixup,#alloc,#execinstr\n\t" - ".align 4\n" - "2:\n\t" - "retl\n\t" - " mov 0, %%o0\n\t" - ".section __ex_table, #alloc\n\t" - ".align 4\n\t" - ".word 1b, 2b\n\t" - ".text\n" - : "=r" (mem), "=r" (ch) : "0" (mem)); - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch & 0xf]; - } - - *buf = 0; - return buf; -} - -/* convert the hex array pointed to by buf into binary to be placed in mem - * return a pointer to the character AFTER the last byte wri |