1160332Scognet/*-
2160332Scognet * Copyright (c) 2006 Olivier Houchard
3160332Scognet * All rights reserved.
4160332Scognet *
5160332Scognet * Redistribution and use in source and binary forms, with or without
6160332Scognet * modification, are permitted provided that the following conditions
7160332Scognet * are met:
8160332Scognet *
9160332Scognet * 1. Redistributions of source code must retain the above copyright
10160332Scognet *    notice, this list of conditions and the following disclaimer.
11160332Scognet * 2. Redistributions in binary form must reproduce the above copyright
12160332Scognet *    notice, this list of conditions and the following disclaimer in the
13160332Scognet *    documentation and/or other materials provided with the distribution.
14160332Scognet *
15160332Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16160332Scognet * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17160332Scognet * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18160332Scognet * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19160332Scognet * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20160332Scognet * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21160332Scognet * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22160332Scognet * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23160332Scognet * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24160332Scognet * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25160332Scognet */
26160332Scognet
27160332Scognet#include <sys/cdefs.h>
28160332Scognet__FBSDID("$FreeBSD$");
29160332Scognet
30160332Scognet
31160332Scognet#include <sys/param.h>
32160332Scognet#include <sys/systm.h>
33160332Scognet#include <sys/kdb.h>
34160332Scognet#include <sys/kernel.h>
35160332Scognet#include <sys/proc.h>
36160332Scognet#include <sys/signal.h>
37160332Scognet
38160332Scognet#include <machine/gdb_machdep.h>
39160332Scognet#include <machine/db_machdep.h>
40160332Scognet#include <machine/vmparam.h>
41160332Scognet#include <machine/pcb.h>
42160332Scognet#include <machine/trap.h>
43160332Scognet#include <machine/frame.h>
44160332Scognet#include <machine/endian.h>
45160332Scognet
46160332Scognet#include <gdb/gdb.h>
47160332Scognet
48160332Scognetstatic register_t stacktest;
49160332Scognet
50160332Scognetvoid *
51160332Scognetgdb_cpu_getreg(int regnum, size_t *regsz)
52160332Scognet{
53160332Scognet
54160332Scognet	*regsz = gdb_cpu_regsz(regnum);
55160332Scognet
56198944Smarcel	if (kdb_thread == curthread) {
57235908Sgber		if (regnum < 13)
58198944Smarcel			return (&kdb_frame->tf_r0 + regnum);
59235908Sgber		if (regnum == 13)
60235908Sgber			return (&kdb_frame->tf_svc_sp);
61235908Sgber		if (regnum == 14)
62235908Sgber			return (&kdb_frame->tf_svc_lr);
63198944Smarcel		if (regnum == 15)
64198944Smarcel			return (&kdb_frame->tf_pc);
65160332Scognet		if (regnum == 25)
66160332Scognet			return (&kdb_frame->tf_spsr);
67160332Scognet	}
68198944Smarcel
69160332Scognet	switch (regnum) {
70276190Sian	case 4:  return (&kdb_thrctx->pcb_regs.sf_r4);
71276190Sian	case 5:  return (&kdb_thrctx->pcb_regs.sf_r5);
72276190Sian	case 6:  return (&kdb_thrctx->pcb_regs.sf_r6);
73276190Sian	case 7:  return (&kdb_thrctx->pcb_regs.sf_r7);
74276190Sian	case 8:  return (&kdb_thrctx->pcb_regs.sf_r8);
75276190Sian	case 9:  return (&kdb_thrctx->pcb_regs.sf_r9);
76276190Sian	case 10:  return (&kdb_thrctx->pcb_regs.sf_r10);
77276190Sian	case 11:  return (&kdb_thrctx->pcb_regs.sf_r11);
78276190Sian	case 12:  return (&kdb_thrctx->pcb_regs.sf_r12);
79276190Sian	case 13:  stacktest = kdb_thrctx->pcb_regs.sf_sp + 5 * 4;
80160332Scognet		  return (&stacktest);
81236991Simp	case 15:
82236991Simp		  /*
83160332Scognet		   * On context switch, the PC is not put in the PCB, but
84160332Scognet		   * we can retrieve it from the stack.
85160332Scognet		   */
86276190Sian		  if (kdb_thrctx->pcb_regs.sf_sp > KERNBASE) {
87276190Sian			  kdb_thrctx->pcb_regs.sf_pc = *(register_t *)
88276190Sian			      (kdb_thrctx->pcb_regs.sf_sp + 4 * 4);
89276190Sian			  return (&kdb_thrctx->pcb_regs.sf_pc);
90160332Scognet		  }
91160332Scognet	}
92198944Smarcel
93160332Scognet	return (NULL);
94160332Scognet}
95160332Scognet
96160332Scognetvoid
97160332Scognetgdb_cpu_setreg(int regnum, void *val)
98160332Scognet{
99160332Scognet
100160332Scognet	switch (regnum) {
101160332Scognet	case GDB_REG_PC:
102160332Scognet		if (kdb_thread  == curthread)
103160332Scognet			kdb_frame->tf_pc = *(register_t *)val;
104160332Scognet	}
105160332Scognet}
106160332Scognet
107160332Scognetint
108160332Scognetgdb_cpu_signal(int type, int code)
109160332Scognet{
110160332Scognet
111160332Scognet	switch (type) {
112160332Scognet	case T_BREAKPOINT: return (SIGTRAP);
113160332Scognet	}
114160332Scognet	return (SIGEMT);
115160332Scognet}
116