freebsd-nq/sys/ia64/ia64/gdb_machdep.c
Marcel Moolenaar 72d44f31a6 Introduce the GDB debugger backend for the new KDB framework. The
backend improves over the old GDB support in the following ways:
o  Unified implementation with minimal MD code.
o  A simple interface for devices to register themselves as debug
   ports, ala consoles.
o  Compression by using run-length encoding.
o  Implements GDB threading support.
2004-07-10 17:47:22 +00:00

178 lines
5.8 KiB
C

/*
* 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/signal.h>
#include <machine/gdb_machdep.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/reg.h>
#include <gdb/gdb.h>
#include <gdb/gdb_int.h>
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, register_t val)
{
switch (regnum) {
case GDB_REG_PC: break;
}
}
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 >= IA64_RR_BASE(5)) ? (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
}