Skip to content

Commit

Permalink
arm64: KGDB: Add Basic KGDB support
Browse files Browse the repository at this point in the history
Add KGDB debug support for kernel debugging.
With this patch, basic KGDB debugging is possible.GDB register
layout is updated and GDB tool can establish connection with
target and can set/clear breakpoints.

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
  • Loading branch information
Vijaya Kumar K authored and ctmarinas committed Feb 26, 2014
1 parent c7db4ff commit bcf5763
Show file tree
Hide file tree
Showing 4 changed files with 420 additions and 0 deletions.
47 changes: 47 additions & 0 deletions arch/arm64/include/asm/debug-monitors.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,53 @@
#define DBG_ESR_EVT_HWWP 0x2
#define DBG_ESR_EVT_BRK 0x6

/*
* Break point instruction encoding
*/
#define BREAK_INSTR_SIZE 4

/*
* ESR values expected for dynamic and compile time BRK instruction
*/
#define DBG_ESR_VAL_BRK(x) (0xf2000000 | ((x) & 0xfffff))

/*
* #imm16 values used for BRK instruction generation
* Allowed values for kgbd are 0x400 - 0x7ff
* 0x400: for dynamic BRK instruction
* 0x401: for compile time BRK instruction
*/
#define KGDB_DYN_DGB_BRK_IMM 0x400
#define KDBG_COMPILED_DBG_BRK_IMM 0x401

/*
* BRK instruction encoding
* The #imm16 value should be placed at bits[20:5] within BRK ins
*/
#define AARCH64_BREAK_MON 0xd4200000

/*
* Extract byte from BRK instruction
*/
#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \
((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff)

/*
* Extract byte from BRK #imm16
*/
#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \
(((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff)

#define KGDB_DYN_DGB_BRK_BYTE(x) \
(KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x))

#define KGDB_DYN_BRK_INS_BYTE0 KGDB_DYN_DGB_BRK_BYTE(0)
#define KGDB_DYN_BRK_INS_BYTE1 KGDB_DYN_DGB_BRK_BYTE(1)
#define KGDB_DYN_BRK_INS_BYTE2 KGDB_DYN_DGB_BRK_BYTE(2)
#define KGDB_DYN_BRK_INS_BYTE3 KGDB_DYN_DGB_BRK_BYTE(3)

#define CACHE_FLUSH_IS_SAFE 1

enum debug_el {
DBG_ACTIVE_EL0 = 0,
DBG_ACTIVE_EL1,
Expand Down
84 changes: 84 additions & 0 deletions arch/arm64/include/asm/kgdb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* AArch64 KGDB support
*
* Based on arch/arm/include/kgdb.h
*
* Copyright (C) 2013 Cavium Inc.
* Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __ARM_KGDB_H
#define __ARM_KGDB_H

#include <linux/ptrace.h>
#include <asm/debug-monitors.h>

#ifndef __ASSEMBLY__

static inline void arch_kgdb_breakpoint(void)
{
asm ("brk %0" : : "I" (KDBG_COMPILED_DBG_BRK_IMM));
}

extern void kgdb_handle_bus_error(void);
extern int kgdb_fault_expected;

#endif /* !__ASSEMBLY__ */

/*
* gdb is expecting the following registers layout.
*
* General purpose regs:
* r0-r30: 64 bit
* sp,pc : 64 bit
* pstate : 64 bit
* Total: 34
* FPU regs:
* f0-f31: 128 bit
* Total: 32
* Extra regs
* fpsr & fpcr: 32 bit
* Total: 2
*
*/

#define _GP_REGS 34
#define _FP_REGS 32
#define _EXTRA_REGS 2
/*
* general purpose registers size in bytes.
* pstate is only 4 bytes. subtract 4 bytes
*/
#define GP_REG_BYTES (_GP_REGS * 8)
#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)

/*
* Size of I/O buffer for gdb packet.
* considering to hold all register contents, size is set
*/

#define BUFMAX 2048

/*
* Number of bytes required for gdb_regs buffer.
* _GP_REGS: 8 bytes, _FP_REGS: 16 bytes and _EXTRA_REGS: 4 bytes each
* GDB fails to connect for size beyond this with error
* "'g' packet reply is too long"
*/

#define NUMREGBYTES ((_GP_REGS * 8) + (_FP_REGS * 16) + \
(_EXTRA_REGS * 4))

#endif /* __ASM_KGDB_H */
1 change: 1 addition & 0 deletions arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
arm64-obj-$(CONFIG_KGDB) += kgdb.o

obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
Expand Down
Loading

0 comments on commit bcf5763

Please sign in to comment.