1/* 2 * Microblaze KGDB support 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file "COPYING" in the main directory of this archive 6 * for more details. 7 */ 8 9#include <linux/kgdb.h> 10#include <linux/kdebug.h> 11#include <linux/irq.h> 12#include <linux/io.h> 13#include <asm/cacheflush.h> 14#include <asm/asm-offsets.h> 15#include <asm/pvr.h> 16 17#define GDB_REG 0 18#define GDB_PC 32 19#define GDB_MSR 33 20#define GDB_EAR 34 21#define GDB_ESR 35 22#define GDB_FSR 36 23#define GDB_BTR 37 24#define GDB_PVR 38 25#define GDB_REDR 50 26#define GDB_RPID 51 27#define GDB_RZPR 52 28#define GDB_RTLBX 53 29#define GDB_RTLBSX 54 /* mfs can't read it */ 30#define GDB_RTLBLO 55 31#define GDB_RTLBHI 56 32 33/* keep pvr separately because it is unchangeble */ 34struct pvr_s pvr; 35 36void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 37{ 38 int i; 39 unsigned long *pt_regb = (unsigned long *)regs; 40 int temp; 41 /* registers r0 - r31, pc, msr, ear, esr, fsr + do not save pt_mode */ 42 for (i = 0; i < (sizeof(struct pt_regs) / 4) - 1; i++) 43 gdb_regs[i] = pt_regb[i]; 44 45 /* Branch target register can't be changed */ 46 __asm__ __volatile__ ("mfs %0, rbtr;" : "=r"(temp) : ); 47 gdb_regs[GDB_BTR] = temp; 48 49 /* pvr part - we have 11 pvr regs */ 50 for (i = 0; i < sizeof(struct pvr_s)/4; i++) 51 gdb_regs[GDB_PVR + i] = pvr.pvr[i]; 52 53 /* read special registers - can't be changed */ 54 __asm__ __volatile__ ("mfs %0, redr;" : "=r"(temp) : ); 55 gdb_regs[GDB_REDR] = temp; 56 __asm__ __volatile__ ("mfs %0, rpid;" : "=r"(temp) : ); 57 gdb_regs[GDB_RPID] = temp; 58 __asm__ __volatile__ ("mfs %0, rzpr;" : "=r"(temp) : ); 59 gdb_regs[GDB_RZPR] = temp; 60 __asm__ __volatile__ ("mfs %0, rtlbx;" : "=r"(temp) : ); 61 gdb_regs[GDB_RTLBX] = temp; 62 __asm__ __volatile__ ("mfs %0, rtlblo;" : "=r"(temp) : ); 63 gdb_regs[GDB_RTLBLO] = temp; 64 __asm__ __volatile__ ("mfs %0, rtlbhi;" : "=r"(temp) : ); 65 gdb_regs[GDB_RTLBHI] = temp; 66} 67 68void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) 69{ 70 int i; 71 unsigned long *pt_regb = (unsigned long *)regs; 72 73 /* pt_regs and gdb_regs have the same 37 values. 74 * The rest of gdb_regs are unused and can't be changed. 75 * r0 register value can't be changed too. */ 76 for (i = 1; i < (sizeof(struct pt_regs) / 4) - 1; i++) 77 pt_regb[i] = gdb_regs[i]; 78} 79 80void microblaze_kgdb_break(struct pt_regs *regs) 81{ 82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) 83 return 0; 84 85 /* Jump over the first arch_kgdb_breakpoint which is barrier to 86 * get kgdb work. The same solution is used for powerpc */ 87 if (*(u32 *) (regs->pc) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) 88 regs->pc += BREAK_INSTR_SIZE; 89} 90 91/* untested */ 92void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) 93{ 94 int i; 95 unsigned long *pt_regb = (unsigned long *)(p->thread.regs); 96 97 /* registers r0 - r31, pc, msr, ear, esr, fsr + do not save pt_mode */ 98 for (i = 0; i < (sizeof(struct pt_regs) / 4) - 1; i++) 99 gdb_regs[i] = pt_regb[i]; 100 101 /* pvr part - we have 11 pvr regs */ 102 for (i = 0; i < sizeof(struct pvr_s)/4; i++) 103 gdb_regs[GDB_PVR + i] = pvr.pvr[i]; 104} 105 106void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) 107{ 108 regs->pc = ip; 109} 110 111int kgdb_arch_handle_exception(int vector, int signo, int err_code, 112 char *remcom_in_buffer, char *remcom_out_buffer, 113 struct pt_regs *regs) 114{ 115 char *ptr; 116 unsigned long address; 117 int cpu = smp_processor_id(); 118 119 switch (remcom_in_buffer[0]) { 120 case 'c': 121 /* handle the optional parameter */ 122 ptr = &remcom_in_buffer[1]; 123 if (kgdb_hex2long(&ptr, &address)) 124 regs->pc = address; 125 126 return 0; 127 } 128 return -1; /* this means that we do not want to exit from the handler */ 129} 130 131int kgdb_arch_init(void) 132{ 133 get_pvr(&pvr); /* Fill PVR structure */ 134 return 0; 135} 136 137void kgdb_arch_exit(void) 138{ 139 /* Nothing to do */ 140} 141 142/* 143 * Global data 144 */ 145struct kgdb_arch arch_kgdb_ops = { 146 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */ 147}; 148