1139731Simp/*-
2131899Smarcel * Copyright (c) 2004 Marcel Moolenaar
3131899Smarcel * All rights reserved.
4131899Smarcel *
5131899Smarcel * Redistribution and use in source and binary forms, with or without
6131899Smarcel * modification, are permitted provided that the following conditions
7131899Smarcel * are met:
8131899Smarcel *
9131899Smarcel * 1. Redistributions of source code must retain the above copyright
10131899Smarcel *    notice, this list of conditions and the following disclaimer.
11131899Smarcel * 2. Redistributions in binary form must reproduce the above copyright
12131899Smarcel *    notice, this list of conditions and the following disclaimer in the
13131899Smarcel *    documentation and/or other materials provided with the distribution.
14131899Smarcel *
15131899Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16131899Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17131899Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18131899Smarcel * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19131899Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20131899Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21131899Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22131899Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23131899Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24131899Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25131899Smarcel */
26131899Smarcel
27131899Smarcel#include <sys/cdefs.h>
28131899Smarcel__FBSDID("$FreeBSD$");
29131899Smarcel
30131899Smarcel#include <sys/param.h>
31131899Smarcel#include <sys/systm.h>
32131899Smarcel#include <sys/kdb.h>
33131899Smarcel#include <sys/kernel.h>
34131899Smarcel#include <sys/proc.h>
35131899Smarcel#include <sys/signal.h>
36131899Smarcel
37131899Smarcel#include <machine/frame.h>
38131899Smarcel#include <machine/gdb_machdep.h>
39138212Speter#include <machine/pcb.h>
40131899Smarcel#include <machine/psl.h>
41131899Smarcel#include <machine/reg.h>
42131899Smarcel#include <machine/trap.h>
43138212Speter#include <machine/frame.h>
44138212Speter#include <machine/endian.h>
45131899Smarcel
46131899Smarcel#include <gdb/gdb.h>
47131899Smarcel
48131899Smarcelvoid *
49131899Smarcelgdb_cpu_getreg(int regnum, size_t *regsz)
50131899Smarcel{
51290734Sjhb	static uint32_t _kcodesel = GSEL(GCODE_SEL, SEL_KPL);
52290734Sjhb	static uint32_t _kdatasel = GSEL(GDATA_SEL, SEL_KPL);
53131899Smarcel
54131899Smarcel	*regsz = gdb_cpu_regsz(regnum);
55138212Speter
56138212Speter	if (kdb_thread  == curthread) {
57138212Speter		switch (regnum) {
58138212Speter		case 0:	return (&kdb_frame->tf_rax);
59138212Speter		case 2:	return (&kdb_frame->tf_rcx);
60138212Speter		case 3:	return (&kdb_frame->tf_rdx);
61138212Speter		case 4:	return (&kdb_frame->tf_rsi);
62138212Speter		case 5:	return (&kdb_frame->tf_rdi);
63138212Speter		case 8: return (&kdb_frame->tf_r8);
64138212Speter		case 9: return (&kdb_frame->tf_r9);
65138212Speter		case 10: return (&kdb_frame->tf_r10);
66138212Speter		case 11: return (&kdb_frame->tf_r11);
67150647Speter		case 17: return (&kdb_frame->tf_rflags);
68138212Speter		case 18: return (&kdb_frame->tf_cs);
69138212Speter		case 19: return (&kdb_frame->tf_ss);
70138212Speter		}
71138212Speter	}
72131899Smarcel	switch (regnum) {
73138212Speter	case 1:  return (&kdb_thrctx->pcb_rbx);
74138212Speter	case 6:  return (&kdb_thrctx->pcb_rbp);
75138212Speter	case 7:  return (&kdb_thrctx->pcb_rsp);
76138212Speter	case 12: return (&kdb_thrctx->pcb_r12);
77138212Speter	case 13: return (&kdb_thrctx->pcb_r13);
78138212Speter	case 14: return (&kdb_thrctx->pcb_r14);
79138212Speter	case 15: return (&kdb_thrctx->pcb_r15);
80138212Speter	case 16: return (&kdb_thrctx->pcb_rip);
81290734Sjhb	case 18: return (&_kcodesel);
82290734Sjhb	case 19: return (&_kdatasel);
83131899Smarcel	}
84131899Smarcel	return (NULL);
85131899Smarcel}
86131899Smarcel
87131899Smarcelvoid
88138253Smarcelgdb_cpu_setreg(int regnum, void *val)
89131899Smarcel{
90131899Smarcel
91131899Smarcel	switch (regnum) {
92138212Speter	case GDB_REG_PC:
93138253Smarcel		kdb_thrctx->pcb_rip = *(register_t *)val;
94138212Speter		if (kdb_thread  == curthread)
95138253Smarcel			kdb_frame->tf_rip = *(register_t *)val;
96131899Smarcel	}
97131899Smarcel}
98157458Smarcel
99157458Smarcelint
100157458Smarcelgdb_cpu_signal(int type, int code)
101157458Smarcel{
102157458Smarcel
103157458Smarcel	switch (type & ~T_USER) {
104157458Smarcel	case 0: return (SIGFPE);	/* Divide by zero. */
105157458Smarcel	case 1: return (SIGTRAP);	/* Debug exception. */
106157458Smarcel	case 3: return (SIGTRAP);	/* Breakpoint. */
107157458Smarcel	case 4: return (SIGSEGV);	/* into instr. (overflow). */
108157458Smarcel	case 5: return (SIGURG);	/* bound instruction. */
109157458Smarcel	case 6: return (SIGILL);	/* Invalid opcode. */
110157458Smarcel	case 7: return (SIGFPE);	/* Coprocessor not present. */
111157458Smarcel	case 8: return (SIGEMT);	/* Double fault. */
112157458Smarcel	case 9: return (SIGSEGV);	/* Coprocessor segment overrun. */
113157458Smarcel	case 10: return (SIGTRAP);	/* Invalid TSS (also single-step). */
114157458Smarcel	case 11: return (SIGSEGV);	/* Segment not present. */
115157458Smarcel	case 12: return (SIGSEGV);	/* Stack exception. */
116157458Smarcel	case 13: return (SIGSEGV);	/* General protection. */
117157458Smarcel	case 14: return (SIGSEGV);	/* Page fault. */
118157458Smarcel	case 16: return (SIGEMT);	/* Coprocessor error. */
119157458Smarcel	}
120157458Smarcel	return (SIGEMT);
121157458Smarcel}
122