/*- * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include void * gdb_cpu_getreg(int regnum, size_t *regsz) { static uint64_t synth; uint64_t cfm; *regsz = gdb_cpu_regsz(regnum); switch (regnum) { /* Registers 0-127: general registers. */ case 1: return (&kdb_thrctx->pcb_special.gp); case 4: return (&kdb_thrctx->pcb_preserved.gr4); case 5: return (&kdb_thrctx->pcb_preserved.gr5); case 6: return (&kdb_thrctx->pcb_preserved.gr6); case 7: return (&kdb_thrctx->pcb_preserved.gr7); case 12: return (&kdb_thrctx->pcb_special.sp); case 13: return (&kdb_thrctx->pcb_special.tp); /* Registers 128-255: floating-point registers. */ case 130: return (&kdb_thrctx->pcb_preserved_fp.fr2); case 131: return (&kdb_thrctx->pcb_preserved_fp.fr3); case 132: return (&kdb_thrctx->pcb_preserved_fp.fr4); case 133: return (&kdb_thrctx->pcb_preserved_fp.fr5); case 144: return (&kdb_thrctx->pcb_preserved_fp.fr16); case 145: return (&kdb_thrctx->pcb_preserved_fp.fr17); case 146: return (&kdb_thrctx->pcb_preserved_fp.fr18); case 147: return (&kdb_thrctx->pcb_preserved_fp.fr19); case 148: return (&kdb_thrctx->pcb_preserved_fp.fr20); case 149: return (&kdb_thrctx->pcb_preserved_fp.fr21); case 150: return (&kdb_thrctx->pcb_preserved_fp.fr22); case 151: return (&kdb_thrctx->pcb_preserved_fp.fr23); case 152: return (&kdb_thrctx->pcb_preserved_fp.fr24); case 153: return (&kdb_thrctx->pcb_preserved_fp.fr25); case 154: return (&kdb_thrctx->pcb_preserved_fp.fr26); case 155: return (&kdb_thrctx->pcb_preserved_fp.fr27); case 156: return (&kdb_thrctx->pcb_preserved_fp.fr28); case 157: return (&kdb_thrctx->pcb_preserved_fp.fr29); case 158: return (&kdb_thrctx->pcb_preserved_fp.fr30); case 159: return (&kdb_thrctx->pcb_preserved_fp.fr31); /* Registers 320-327: branch registers. */ case 320: if (kdb_thrctx->pcb_special.__spare == ~0UL) return (&kdb_thrctx->pcb_special.rp); break; case 321: return (&kdb_thrctx->pcb_preserved.br1); case 322: return (&kdb_thrctx->pcb_preserved.br2); case 323: return (&kdb_thrctx->pcb_preserved.br3); case 324: return (&kdb_thrctx->pcb_preserved.br4); case 325: return (&kdb_thrctx->pcb_preserved.br5); /* Registers 328-333: misc. other registers. */ case 330: return (&kdb_thrctx->pcb_special.pr); case 331: if (kdb_thrctx->pcb_special.__spare == ~0UL) { synth = kdb_thrctx->pcb_special.iip; synth += (kdb_thrctx->pcb_special.psr >> 41) & 3; return (&synth); } return (&kdb_thrctx->pcb_special.rp); case 333: if (kdb_thrctx->pcb_special.__spare == ~0UL) return (&kdb_thrctx->pcb_special.cfm); return (&kdb_thrctx->pcb_special.pfs); /* Registers 334-461: application registers. */ case 350: return (&kdb_thrctx->pcb_special.rsc); case 351: /* bsp */ case 352: /* bspstore. */ synth = kdb_thrctx->pcb_special.bspstore; if (kdb_thrctx->pcb_special.__spare == ~0UL) { synth += kdb_thrctx->pcb_special.ndirty; } else { cfm = kdb_thrctx->pcb_special.pfs; synth = ia64_bsp_adjust(synth, IA64_CFM_SOF(cfm) - IA64_CFM_SOL(cfm)); } return (&synth); case 353: return (&kdb_thrctx->pcb_special.rnat); case 370: return (&kdb_thrctx->pcb_special.unat); case 374: return (&kdb_thrctx->pcb_special.fpsr); case 398: if (kdb_thrctx->pcb_special.__spare == ~0UL) return (&kdb_thrctx->pcb_special.pfs); break; case 399: return (&kdb_thrctx->pcb_preserved.lc); } return (NULL); } void gdb_cpu_setreg(int regnum, void *val) { switch (regnum) { case GDB_REG_PC: break; } } int gdb_cpu_signal(int vector, int dummy __unused) { if (vector == IA64_VEC_BREAK || vector == IA64_VEC_SINGLE_STEP_TRAP) return (SIGTRAP); /* Add 100 so GDB won't translate the vector into signal names. */ return (vector + 100); } int gdb_cpu_query(void) { #if 0 uint64_t bspstore, *kstack; #endif uintmax_t slot; if (!gdb_rx_equal("Part:dirty:read::")) return (0); if (gdb_rx_varhex(&slot) < 0) { gdb_tx_err(EINVAL); return (-1); } gdb_tx_err(EINVAL); return (-1); #if 0 /* slot is unsigned. No need to test for negative values. */ if (slot >= (kdb_frame->tf_special.ndirty >> 3)) { return (-1); } /* * If the trapframe describes a kernel entry, bspstore holds * the address of the user backing store. Calculate the right * kernel stack address. See also ptrace_machdep(). */ bspstore = kdb_frame->tf_special.bspstore; kstack = (bspstore >= VM_MAXUSER_ADDRESS) ? (uint64_t*)bspstore : (uint64_t*)(kdb_thread->td_kstack + (bspstore & 0x1ffUL)); gdb_tx_begin('\0'); gdb_tx_mem((void*)(kstack + slot), 8); gdb_tx_end(); return (1); #endif }