linux/arch/nios2/kernel/kgdb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Nios2 KGDB support
   4 *
   5 * Copyright (C) 2015 Altera Corporation
   6 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
   7 *
   8 * Based on the code posted by Kazuyasu on the Altera Forum at:
   9 * http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
  10 */
  11#include <linux/ptrace.h>
  12#include <linux/kgdb.h>
  13#include <linux/kdebug.h>
  14#include <linux/io.h>
  15
  16static int wait_for_remote_debugger;
  17
  18struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
  19{
  20        { "zero", GDB_SIZEOF_REG, -1 },
  21        { "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, r1) },
  22        { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, r2) },
  23        { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, r3) },
  24        { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, r4) },
  25        { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, r5) },
  26        { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, r6) },
  27        { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, r7) },
  28        { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, r8) },
  29        { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, r9) },
  30        { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, r10) },
  31        { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, r11) },
  32        { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, r12) },
  33        { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, r13) },
  34        { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, r14) },
  35        { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, r15) },
  36        { "r16", GDB_SIZEOF_REG, -1 },
  37        { "r17", GDB_SIZEOF_REG, -1 },
  38        { "r18", GDB_SIZEOF_REG, -1 },
  39        { "r19", GDB_SIZEOF_REG, -1 },
  40        { "r20", GDB_SIZEOF_REG, -1 },
  41        { "r21", GDB_SIZEOF_REG, -1 },
  42        { "r22", GDB_SIZEOF_REG, -1 },
  43        { "r23", GDB_SIZEOF_REG, -1 },
  44        { "et", GDB_SIZEOF_REG, -1 },
  45        { "bt", GDB_SIZEOF_REG, -1 },
  46        { "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp) },
  47        { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
  48        { "fp", GDB_SIZEOF_REG, offsetof(struct pt_regs, fp) },
  49        { "ea", GDB_SIZEOF_REG, -1 },
  50        { "ba", GDB_SIZEOF_REG, -1 },
  51        { "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, ra) },
  52        { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, ea) },
  53        { "status", GDB_SIZEOF_REG, -1 },
  54        { "estatus", GDB_SIZEOF_REG, offsetof(struct pt_regs, estatus) },
  55        { "bstatus", GDB_SIZEOF_REG, -1 },
  56        { "ienable", GDB_SIZEOF_REG, -1 },
  57        { "ipending", GDB_SIZEOF_REG, -1},
  58        { "cpuid", GDB_SIZEOF_REG, -1 },
  59        { "ctl6", GDB_SIZEOF_REG, -1 },
  60        { "exception", GDB_SIZEOF_REG, -1 },
  61        { "pteaddr", GDB_SIZEOF_REG, -1 },
  62        { "tlbacc", GDB_SIZEOF_REG, -1 },
  63        { "tlbmisc", GDB_SIZEOF_REG, -1 },
  64        { "eccinj", GDB_SIZEOF_REG, -1 },
  65        { "badaddr", GDB_SIZEOF_REG, -1 },
  66        { "config", GDB_SIZEOF_REG, -1 },
  67        { "mpubase", GDB_SIZEOF_REG, -1 },
  68        { "mpuacc", GDB_SIZEOF_REG, -1 },
  69};
  70
  71char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
  72{
  73        if (regno >= DBG_MAX_REG_NUM || regno < 0)
  74                return NULL;
  75
  76        if (dbg_reg_def[regno].offset != -1)
  77                memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
  78                       dbg_reg_def[regno].size);
  79        else
  80                memset(mem, 0, dbg_reg_def[regno].size);
  81
  82        return dbg_reg_def[regno].name;
  83}
  84
  85int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
  86{
  87        if (regno >= DBG_MAX_REG_NUM || regno < 0)
  88                return -EINVAL;
  89
  90        if (dbg_reg_def[regno].offset != -1)
  91                memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
  92                       dbg_reg_def[regno].size);
  93
  94        return 0;
  95}
  96
  97void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
  98{
  99        memset((char *)gdb_regs, 0, NUMREGBYTES);
 100        gdb_regs[GDB_SP] = p->thread.kregs->sp;
 101        gdb_regs[GDB_PC] = p->thread.kregs->ea;
 102}
 103
 104void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
 105{
 106        regs->ea = pc;
 107}
 108
 109int kgdb_arch_handle_exception(int vector, int signo, int err_code,
 110                                char *remcom_in_buffer, char *remcom_out_buffer,
 111                                struct pt_regs *regs)
 112{
 113        char *ptr;
 114        unsigned long addr;
 115
 116        switch (remcom_in_buffer[0]) {
 117        case 's':
 118        case 'c':
 119                /* handle the optional parameters */
 120                ptr = &remcom_in_buffer[1];
 121                if (kgdb_hex2long(&ptr, &addr))
 122                        regs->ea = addr;
 123
 124                return 0;
 125        }
 126
 127        return -1; /* this means that we do not want to exit from the handler */
 128}
 129
 130asmlinkage void kgdb_breakpoint_c(struct pt_regs *regs)
 131{
 132        /*
 133         * The breakpoint entry code has moved the PC on by 4 bytes, so we must
 134         * move it back.  This could be done on the host but we do it here
 135         */
 136        if (!wait_for_remote_debugger)
 137                regs->ea -= 4;
 138        else    /* pass the first trap 30 code */
 139                wait_for_remote_debugger = 0;
 140
 141        kgdb_handle_exception(30, SIGTRAP, 0, regs);
 142}
 143
 144int kgdb_arch_init(void)
 145{
 146        wait_for_remote_debugger = 1;
 147        return 0;
 148}
 149
 150void kgdb_arch_exit(void)
 151{
 152        /* Nothing to do */
 153}
 154
 155const struct kgdb_arch arch_kgdb_ops = {
 156        /* Breakpoint instruction: trap 30 */
 157        .gdb_bpt_instr = { 0xba, 0x6f, 0x3b, 0x00 },
 158};
 159