1/*-
2 * Copyright (c) 2004 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD$");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kdb.h>
33#include <sys/kernel.h>
34#include <sys/proc.h>
35#include <sys/signal.h>
36
37#include <machine/gdb_machdep.h>
38#include <machine/md_var.h>
39#include <machine/pcb.h>
40#include <machine/reg.h>
41
42#include <gdb/gdb.h>
43#include <gdb/gdb_int.h>
44
45void *
46gdb_cpu_getreg(int regnum, size_t *regsz)
47{
48	static uint64_t synth;
49	uint64_t cfm;
50
51	*regsz = gdb_cpu_regsz(regnum);
52	switch (regnum) {
53	/* Registers 0-127: general registers. */
54	case 1:  return (&kdb_thrctx->pcb_special.gp);
55	case 4:  return (&kdb_thrctx->pcb_preserved.gr4);
56	case 5:  return (&kdb_thrctx->pcb_preserved.gr5);
57	case 6:  return (&kdb_thrctx->pcb_preserved.gr6);
58	case 7:  return (&kdb_thrctx->pcb_preserved.gr7);
59	case 12: return (&kdb_thrctx->pcb_special.sp);
60	case 13: return (&kdb_thrctx->pcb_special.tp);
61	/* Registers 128-255: floating-point registers. */
62	case 130: return (&kdb_thrctx->pcb_preserved_fp.fr2);
63	case 131: return (&kdb_thrctx->pcb_preserved_fp.fr3);
64	case 132: return (&kdb_thrctx->pcb_preserved_fp.fr4);
65	case 133: return (&kdb_thrctx->pcb_preserved_fp.fr5);
66	case 144: return (&kdb_thrctx->pcb_preserved_fp.fr16);
67	case 145: return (&kdb_thrctx->pcb_preserved_fp.fr17);
68	case 146: return (&kdb_thrctx->pcb_preserved_fp.fr18);
69	case 147: return (&kdb_thrctx->pcb_preserved_fp.fr19);
70	case 148: return (&kdb_thrctx->pcb_preserved_fp.fr20);
71	case 149: return (&kdb_thrctx->pcb_preserved_fp.fr21);
72	case 150: return (&kdb_thrctx->pcb_preserved_fp.fr22);
73	case 151: return (&kdb_thrctx->pcb_preserved_fp.fr23);
74	case 152: return (&kdb_thrctx->pcb_preserved_fp.fr24);
75	case 153: return (&kdb_thrctx->pcb_preserved_fp.fr25);
76	case 154: return (&kdb_thrctx->pcb_preserved_fp.fr26);
77	case 155: return (&kdb_thrctx->pcb_preserved_fp.fr27);
78	case 156: return (&kdb_thrctx->pcb_preserved_fp.fr28);
79	case 157: return (&kdb_thrctx->pcb_preserved_fp.fr29);
80	case 158: return (&kdb_thrctx->pcb_preserved_fp.fr30);
81	case 159: return (&kdb_thrctx->pcb_preserved_fp.fr31);
82	/* Registers 320-327: branch registers. */
83	case 320:
84		if (kdb_thrctx->pcb_special.__spare == ~0UL)
85			return (&kdb_thrctx->pcb_special.rp);
86		break;
87	case 321: return (&kdb_thrctx->pcb_preserved.br1);
88	case 322: return (&kdb_thrctx->pcb_preserved.br2);
89	case 323: return (&kdb_thrctx->pcb_preserved.br3);
90	case 324: return (&kdb_thrctx->pcb_preserved.br4);
91	case 325: return (&kdb_thrctx->pcb_preserved.br5);
92	/* Registers 328-333: misc. other registers. */
93	case 330: return (&kdb_thrctx->pcb_special.pr);
94	case 331:
95		if (kdb_thrctx->pcb_special.__spare == ~0UL) {
96			synth = kdb_thrctx->pcb_special.iip;
97			synth += (kdb_thrctx->pcb_special.psr >> 41) & 3;
98			return (&synth);
99		}
100		return (&kdb_thrctx->pcb_special.rp);
101	case 333:
102		if (kdb_thrctx->pcb_special.__spare == ~0UL)
103			return (&kdb_thrctx->pcb_special.cfm);
104		return (&kdb_thrctx->pcb_special.pfs);
105	/* Registers 334-461: application registers. */
106	case 350: return (&kdb_thrctx->pcb_special.rsc);
107	case 351: /* bsp */
108	case 352: /* bspstore. */
109		synth = kdb_thrctx->pcb_special.bspstore;
110		if (kdb_thrctx->pcb_special.__spare == ~0UL) {
111			synth += kdb_thrctx->pcb_special.ndirty;
112		} else {
113			cfm = kdb_thrctx->pcb_special.pfs;
114			synth = ia64_bsp_adjust(synth,
115			    IA64_CFM_SOF(cfm) - IA64_CFM_SOL(cfm));
116		}
117		return (&synth);
118	case 353: return (&kdb_thrctx->pcb_special.rnat);
119	case 370: return (&kdb_thrctx->pcb_special.unat);
120	case 374: return (&kdb_thrctx->pcb_special.fpsr);
121	case 398:
122		if (kdb_thrctx->pcb_special.__spare == ~0UL)
123			return (&kdb_thrctx->pcb_special.pfs);
124		break;
125	case 399: return (&kdb_thrctx->pcb_preserved.lc);
126	}
127	return (NULL);
128}
129
130void
131gdb_cpu_setreg(int regnum, void *val)
132{
133
134	switch (regnum) {
135	case GDB_REG_PC: break;
136	}
137}
138
139int
140gdb_cpu_signal(int vector, int dummy __unused)
141{
142
143	if (vector == IA64_VEC_BREAK || vector == IA64_VEC_SINGLE_STEP_TRAP)
144		return (SIGTRAP);
145	/* Add 100 so GDB won't translate the vector into signal names. */
146	return (vector + 100);
147}
148
149int
150gdb_cpu_query(void)
151{
152#if 0
153	uint64_t bspstore, *kstack;
154#endif
155	uintmax_t slot;
156
157	if (!gdb_rx_equal("Part:dirty:read::"))
158		return (0);
159
160	if (gdb_rx_varhex(&slot) < 0) {
161		gdb_tx_err(EINVAL);
162		return (-1);
163	}
164
165	gdb_tx_err(EINVAL);
166	return (-1);
167
168#if 0
169	/* slot is unsigned. No need to test for negative values. */
170	if (slot >= (kdb_frame->tf_special.ndirty >> 3)) {
171		return (-1);
172	}
173
174	/*
175	 * If the trapframe describes a kernel entry, bspstore holds
176	 * the address of the user backing store. Calculate the right
177	 * kernel stack address. See also ptrace_machdep().
178	 */
179	bspstore = kdb_frame->tf_special.bspstore;
180	kstack = (bspstore >= VM_MAXUSER_ADDRESS) ? (uint64_t*)bspstore :
181	    (uint64_t*)(kdb_thread->td_kstack + (bspstore & 0x1ffUL));
182	gdb_tx_begin('\0');
183	gdb_tx_mem((void*)(kstack + slot), 8);
184	gdb_tx_end();
185	return (1);
186#endif
187}
188