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