1 1.10 skrll /* $NetBSD: kgdb_machdep.c,v 1.10 2020/06/20 15:45:22 skrll Exp $ */ 2 1.1 briggs 3 1.1 briggs /* 4 1.1 briggs * Copyright (c) 1996 Matthias Pfaller. 5 1.1 briggs * All rights reserved. 6 1.1 briggs * 7 1.1 briggs * Redistribution and use in source and binary forms, with or without 8 1.1 briggs * modification, are permitted provided that the following conditions 9 1.1 briggs * are met: 10 1.1 briggs * 1. Redistributions of source code must retain the above copyright 11 1.1 briggs * notice, this list of conditions and the following disclaimer. 12 1.1 briggs * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 briggs * notice, this list of conditions and the following disclaimer in the 14 1.1 briggs * documentation and/or other materials provided with the distribution. 15 1.1 briggs * 16 1.1 briggs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 briggs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 briggs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 briggs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 briggs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 briggs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 briggs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 briggs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 briggs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 briggs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 briggs */ 27 1.2 lukem 28 1.2 lukem #include <sys/cdefs.h> 29 1.10 skrll __KERNEL_RCSID(0, "$NetBSD: kgdb_machdep.c,v 1.10 2020/06/20 15:45:22 skrll Exp $"); 30 1.1 briggs 31 1.1 briggs #include "opt_ddb.h" 32 1.1 briggs #include "opt_kgdb.h" 33 1.1 briggs 34 1.1 briggs #include <sys/param.h> 35 1.9 skrll 36 1.9 skrll #include <sys/kgdb.h> 37 1.1 briggs #include <sys/systm.h> 38 1.1 briggs 39 1.1 briggs #include <uvm/uvm_extern.h> 40 1.1 briggs 41 1.1 briggs #include <machine/frame.h> 42 1.1 briggs #include <machine/reg.h> 43 1.1 briggs #include <machine/trap.h> 44 1.1 briggs 45 1.1 briggs /* 46 1.1 briggs * Determine if the memory at va..(va+len) is valid. 47 1.1 briggs */ 48 1.1 briggs int 49 1.6 dsl kgdb_acc(vaddr_t va, size_t len) 50 1.1 briggs { 51 1.1 briggs vaddr_t last_va; 52 1.1 briggs 53 1.1 briggs last_va = va + len; 54 1.1 briggs va &= ~PGOFSET; 55 1.1 briggs last_va &= ~PGOFSET; 56 1.1 briggs 57 1.1 briggs do { 58 1.1 briggs if (db_validate_address(va)) 59 1.10 skrll return 0; 60 1.1 briggs va += PAGE_SIZE; 61 1.1 briggs } while (va < last_va); 62 1.1 briggs 63 1.10 skrll return 1; 64 1.1 briggs } 65 1.1 briggs 66 1.1 briggs /* 67 1.1 briggs * Translate a trap number into a unix compatible signal value. 68 1.1 briggs * (gdb only understands unix signal numbers). 69 1.1 briggs */ 70 1.8 skrll int 71 1.6 dsl kgdb_signal(int type) 72 1.1 briggs { 73 1.1 briggs 74 1.1 briggs switch (type) { 75 1.1 briggs case T_BREAKPOINT: 76 1.1 briggs return(SIGTRAP); 77 1.1 briggs case -1: 78 1.1 briggs return(SIGSEGV); 79 1.1 briggs default: 80 1.1 briggs return(SIGINT); 81 1.1 briggs } 82 1.1 briggs } 83 1.1 briggs 84 1.1 briggs /* 85 1.1 briggs * Definitions exported from gdb. 86 1.1 briggs */ 87 1.1 briggs 88 1.1 briggs /* 89 1.1 briggs * Translate the values stored in the kernel regs struct to the format 90 1.1 briggs * understood by gdb. 91 1.1 briggs */ 92 1.1 briggs void 93 1.6 dsl kgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs) 94 1.1 briggs { 95 1.1 briggs 96 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 0] = regs->tf_r0; 97 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 1] = regs->tf_r1; 98 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 2] = regs->tf_r2; 99 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 3] = regs->tf_r3; 100 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 4] = regs->tf_r4; 101 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 5] = regs->tf_r5; 102 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 6] = regs->tf_r6; 103 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 7] = regs->tf_r7; 104 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 8] = regs->tf_r8; 105 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 9] = regs->tf_r9; 106 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 10] = regs->tf_r10; 107 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 11] = regs->tf_r11; 108 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 12] = regs->tf_r12; 109 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 13] = regs->tf_svc_sp; 110 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 14] = regs->tf_svc_lr; 111 1.1 briggs gdb_regs[KGDB_REGNUM_R0 + 15] = regs->tf_pc; 112 1.1 briggs 113 1.1 briggs gdb_regs[KGDB_REGNUM_SPSR] = regs->tf_spsr; 114 1.1 briggs } 115 1.1 briggs 116 1.1 briggs /* 117 1.1 briggs * Reverse the above. 118 1.1 briggs */ 119 1.1 briggs void 120 1.6 dsl kgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs) 121 1.1 briggs { 122 1.1 briggs regs->tf_r0 = gdb_regs[KGDB_REGNUM_R0 + 0]; 123 1.1 briggs regs->tf_r1 = gdb_regs[KGDB_REGNUM_R0 + 1]; 124 1.1 briggs regs->tf_r2 = gdb_regs[KGDB_REGNUM_R0 + 2]; 125 1.1 briggs regs->tf_r3 = gdb_regs[KGDB_REGNUM_R0 + 3]; 126 1.1 briggs regs->tf_r4 = gdb_regs[KGDB_REGNUM_R0 + 4]; 127 1.1 briggs regs->tf_r5 = gdb_regs[KGDB_REGNUM_R0 + 5]; 128 1.1 briggs regs->tf_r6 = gdb_regs[KGDB_REGNUM_R0 + 6]; 129 1.1 briggs regs->tf_r7 = gdb_regs[KGDB_REGNUM_R0 + 7]; 130 1.1 briggs regs->tf_r8 = gdb_regs[KGDB_REGNUM_R0 + 8]; 131 1.1 briggs regs->tf_r9 = gdb_regs[KGDB_REGNUM_R0 + 9]; 132 1.1 briggs regs->tf_r10 = gdb_regs[KGDB_REGNUM_R0 + 10]; 133 1.1 briggs regs->tf_r11 = gdb_regs[KGDB_REGNUM_R0 + 11]; 134 1.1 briggs regs->tf_r12 = gdb_regs[KGDB_REGNUM_R0 + 12]; 135 1.1 briggs regs->tf_svc_sp = gdb_regs[KGDB_REGNUM_R0 + 13]; 136 1.1 briggs regs->tf_svc_lr = gdb_regs[KGDB_REGNUM_R0 + 14]; 137 1.1 briggs regs->tf_pc = gdb_regs[KGDB_REGNUM_R0 + 15]; 138 1.1 briggs 139 1.1 briggs regs->tf_spsr = gdb_regs[KGDB_REGNUM_SPSR]; 140 1.8 skrll } 141 1.1 briggs 142 1.1 briggs /* 143 1.1 briggs * Trap into kgdb to wait for debugger to connect, 144 1.1 briggs * noting on the console why nothing else is going on. 145 1.1 briggs */ 146 1.1 briggs void 147 1.5 cegger kgdb_connect(int verbose) 148 1.1 briggs { 149 1.1 briggs 150 1.5 cegger if (kgdb_dev == NODEV) 151 1.1 briggs return; 152 1.1 briggs 153 1.1 briggs if (verbose) 154 1.1 briggs printf("kgdb waiting..."); 155 1.1 briggs 156 1.4 perry __asm volatile(KBPT_ASM); 157 1.1 briggs 158 1.1 briggs if (verbose) 159 1.1 briggs printf("connected.\n"); 160 1.1 briggs 161 1.1 briggs kgdb_debug_panic = 1; 162 1.1 briggs } 163 1.1 briggs 164 1.1 briggs /* 165 1.1 briggs * Decide what to do on panic. 166 1.1 briggs * (This is called by panic, like Debugger()) 167 1.1 briggs */ 168 1.1 briggs void 169 1.5 cegger kgdb_panic(void) 170 1.1 briggs { 171 1.1 briggs 172 1.5 cegger if (kgdb_dev != NODEV && kgdb_debug_panic) { 173 1.1 briggs printf("entering kgdb\n"); 174 1.1 briggs kgdb_connect(kgdb_active == 0); 175 1.1 briggs } 176 1.1 briggs } 177