xref: /freebsd/sys/arm/arm/gdb_machdep.c (revision fdafd315)
1be050429SOlivier Houchard /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3af3dc4a7SPedro F. Giffuni  *
4be050429SOlivier Houchard  * Copyright (c) 2006 Olivier Houchard
5be050429SOlivier Houchard  * All rights reserved.
6be050429SOlivier Houchard  *
7be050429SOlivier Houchard  * Redistribution and use in source and binary forms, with or without
8be050429SOlivier Houchard  * modification, are permitted provided that the following conditions
9be050429SOlivier Houchard  * are met:
10be050429SOlivier Houchard  *
11be050429SOlivier Houchard  * 1. Redistributions of source code must retain the above copyright
12be050429SOlivier Houchard  *    notice, this list of conditions and the following disclaimer.
13be050429SOlivier Houchard  * 2. Redistributions in binary form must reproduce the above copyright
14be050429SOlivier Houchard  *    notice, this list of conditions and the following disclaimer in the
15be050429SOlivier Houchard  *    documentation and/or other materials provided with the distribution.
16be050429SOlivier Houchard  *
17be050429SOlivier Houchard  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18be050429SOlivier Houchard  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19be050429SOlivier Houchard  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20be050429SOlivier Houchard  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21be050429SOlivier Houchard  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22be050429SOlivier Houchard  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23be050429SOlivier Houchard  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24be050429SOlivier Houchard  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25be050429SOlivier Houchard  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26be050429SOlivier Houchard  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27be050429SOlivier Houchard  */
28be050429SOlivier Houchard 
29be050429SOlivier Houchard #include <sys/param.h>
30be050429SOlivier Houchard #include <sys/systm.h>
31be050429SOlivier Houchard #include <sys/kdb.h>
32be050429SOlivier Houchard #include <sys/kernel.h>
33be050429SOlivier Houchard #include <sys/proc.h>
34be050429SOlivier Houchard #include <sys/signal.h>
35be050429SOlivier Houchard 
36be050429SOlivier Houchard #include <machine/gdb_machdep.h>
37be050429SOlivier Houchard #include <machine/db_machdep.h>
38be050429SOlivier Houchard #include <machine/vmparam.h>
39be050429SOlivier Houchard #include <machine/pcb.h>
40be050429SOlivier Houchard #include <machine/trap.h>
41be050429SOlivier Houchard #include <machine/frame.h>
42be050429SOlivier Houchard #include <machine/endian.h>
43be050429SOlivier Houchard 
44be050429SOlivier Houchard #include <gdb/gdb.h>
45be050429SOlivier Houchard 
46be050429SOlivier Houchard static register_t stacktest;
47be050429SOlivier Houchard 
48be050429SOlivier Houchard void *
gdb_cpu_getreg(int regnum,size_t * regsz)49be050429SOlivier Houchard gdb_cpu_getreg(int regnum, size_t *regsz)
50be050429SOlivier Houchard {
51be050429SOlivier Houchard 
52be050429SOlivier Houchard 	*regsz = gdb_cpu_regsz(regnum);
53be050429SOlivier Houchard 
54be050429SOlivier Houchard 	if (kdb_thread == curthread) {
550fc0793eSGrzegorz Bernacki 		if (regnum < 13)
564590f228SMarcel Moolenaar 			return (&kdb_frame->tf_r0 + regnum);
570fc0793eSGrzegorz Bernacki 		if (regnum == 13)
580fc0793eSGrzegorz Bernacki 			return (&kdb_frame->tf_svc_sp);
590fc0793eSGrzegorz Bernacki 		if (regnum == 14)
600fc0793eSGrzegorz Bernacki 			return (&kdb_frame->tf_svc_lr);
614590f228SMarcel Moolenaar 		if (regnum == 15)
624590f228SMarcel Moolenaar 			return (&kdb_frame->tf_pc);
63be050429SOlivier Houchard 		if (regnum == 25)
64be050429SOlivier Houchard 			return (&kdb_frame->tf_spsr);
65be050429SOlivier Houchard 	}
664590f228SMarcel Moolenaar 
67be050429SOlivier Houchard 	switch (regnum) {
68c4c27bc9SIan Lepore 	case 4:  return (&kdb_thrctx->pcb_regs.sf_r4);
69c4c27bc9SIan Lepore 	case 5:  return (&kdb_thrctx->pcb_regs.sf_r5);
70c4c27bc9SIan Lepore 	case 6:  return (&kdb_thrctx->pcb_regs.sf_r6);
71c4c27bc9SIan Lepore 	case 7:  return (&kdb_thrctx->pcb_regs.sf_r7);
72c4c27bc9SIan Lepore 	case 8:  return (&kdb_thrctx->pcb_regs.sf_r8);
73c4c27bc9SIan Lepore 	case 9:  return (&kdb_thrctx->pcb_regs.sf_r9);
74c4c27bc9SIan Lepore 	case 10:  return (&kdb_thrctx->pcb_regs.sf_r10);
75c4c27bc9SIan Lepore 	case 11:  return (&kdb_thrctx->pcb_regs.sf_r11);
76c4c27bc9SIan Lepore 	case 12:  return (&kdb_thrctx->pcb_regs.sf_r12);
77c4c27bc9SIan Lepore 	case 13:  stacktest = kdb_thrctx->pcb_regs.sf_sp + 5 * 4;
78be050429SOlivier Houchard 		  return (&stacktest);
79be050429SOlivier Houchard 	case 15:
80be050429SOlivier Houchard 		  /*
81be050429SOlivier Houchard 		   * On context switch, the PC is not put in the PCB, but
82be050429SOlivier Houchard 		   * we can retrieve it from the stack.
83be050429SOlivier Houchard 		   */
84c4c27bc9SIan Lepore 		  if (kdb_thrctx->pcb_regs.sf_sp > KERNBASE) {
85c4c27bc9SIan Lepore 			  kdb_thrctx->pcb_regs.sf_pc = *(register_t *)
86c4c27bc9SIan Lepore 			      (kdb_thrctx->pcb_regs.sf_sp + 4 * 4);
87c4c27bc9SIan Lepore 			  return (&kdb_thrctx->pcb_regs.sf_pc);
88be050429SOlivier Houchard 		  }
89be050429SOlivier Houchard 	}
904590f228SMarcel Moolenaar 
91be050429SOlivier Houchard 	return (NULL);
92be050429SOlivier Houchard }
93be050429SOlivier Houchard 
94be050429SOlivier Houchard void
gdb_cpu_setreg(int regnum,void * val)95be050429SOlivier Houchard gdb_cpu_setreg(int regnum, void *val)
96be050429SOlivier Houchard {
978bf82b34SMark Johnston 	if (kdb_thread != curthread)
988bf82b34SMark Johnston 		return;
99be050429SOlivier Houchard 
100be050429SOlivier Houchard 	switch (regnum) {
101be050429SOlivier Houchard 	case GDB_REG_PC:
102be050429SOlivier Houchard 		kdb_frame->tf_pc = *(register_t *)val;
1038bf82b34SMark Johnston 		break;
1048bf82b34SMark Johnston 	case GDB_REG_SP:
1058bf82b34SMark Johnston 		kdb_frame->tf_svc_sp = *(register_t *)val;
1068bf82b34SMark Johnston 		break;
1078bf82b34SMark Johnston 	case GDB_REG_LR:
1088bf82b34SMark Johnston 		kdb_frame->tf_svc_lr = *(register_t *)val;
1098bf82b34SMark Johnston 		break;
1108bf82b34SMark Johnston 	default:
1118bf82b34SMark Johnston 		/* Write to the general purpose registers r0-r12. */
1128bf82b34SMark Johnston 		if (regnum >= 0 && regnum <= 12) {
1138bf82b34SMark Johnston 			*(&kdb_frame->tf_r0 + regnum) = *(register_t *)val;
1148bf82b34SMark Johnston 		}
1158bf82b34SMark Johnston 		break;
116be050429SOlivier Houchard 	}
117be050429SOlivier Houchard }
118be050429SOlivier Houchard 
119be050429SOlivier Houchard int
gdb_cpu_signal(int type,int code)120be050429SOlivier Houchard gdb_cpu_signal(int type, int code)
121be050429SOlivier Houchard {
122be050429SOlivier Houchard 
123be050429SOlivier Houchard 	switch (type) {
124be050429SOlivier Houchard 	case T_BREAKPOINT: return (SIGTRAP);
125be050429SOlivier Houchard 	}
126be050429SOlivier Houchard 	return (SIGEMT);
127be050429SOlivier Houchard }
128