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