]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/riscv/riscv/gdb_machdep.c
busdma: tidy bus_dma_run_filter() functions
[FreeBSD/FreeBSD.git] / sys / riscv / riscv / gdb_machdep.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021 Mitchell Horne <mhorne@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kdb.h>
32 #include <sys/kernel.h>
33 #include <sys/proc.h>
34 #include <sys/signal.h>
35
36 #include <machine/frame.h>
37 #include <machine/gdb_machdep.h>
38 #include <machine/pcb.h>
39 #include <machine/riscvreg.h>
40
41 #include <gdb/gdb.h>
42
43 void *
44 gdb_cpu_getreg(int regnum, size_t *regsz)
45 {
46         *regsz = gdb_cpu_regsz(regnum);
47
48         if (kdb_thread == curthread) {
49                 switch (regnum) {
50                 case GDB_REG_RA:        return (&kdb_frame->tf_ra);
51                 case GDB_REG_PC:        return (&kdb_frame->tf_sepc);
52                 case GDB_REG_SSTATUS:   return (&kdb_frame->tf_sstatus);
53                 case GDB_REG_STVAL:     return (&kdb_frame->tf_stval);
54                 case GDB_REG_SCAUSE:    return (&kdb_frame->tf_scause);
55                 default:
56                         if (regnum >= GDB_REG_A0 && regnum < GDB_REG_S2)
57                                 return (&kdb_frame->tf_a[regnum - GDB_REG_A0]);
58                         if (regnum >= GDB_REG_T0 && regnum < GDB_REG_FP)
59                                 return (&kdb_frame->tf_t[regnum - GDB_REG_T0]);
60                         if (regnum >= GDB_REG_T3 && regnum < GDB_REG_PC)
61                                 return (&kdb_frame->tf_t[regnum - GDB_REG_T3]);
62                         break;
63                 }
64         }
65         switch (regnum) {
66         case GDB_REG_PC: /* FALLTHROUGH */
67         case GDB_REG_RA: return (&kdb_thrctx->pcb_ra);
68         case GDB_REG_SP: return (&kdb_thrctx->pcb_sp);
69         case GDB_REG_GP: return (&kdb_thrctx->pcb_gp);
70         case GDB_REG_TP: return (&kdb_thrctx->pcb_tp);
71         case GDB_REG_FP: return (&kdb_thrctx->pcb_s[0]);
72         case GDB_REG_S1: return (&kdb_thrctx->pcb_s[1]);
73         default:
74                 if (regnum >= GDB_REG_S2 && regnum < GDB_REG_T3)
75                         return (&kdb_thrctx->pcb_s[regnum - GDB_REG_S2]);
76                 break;
77         }
78
79         return (NULL);
80 }
81
82 void
83 gdb_cpu_setreg(int regnum, void *val)
84 {
85         register_t regval = *(register_t *)val;
86
87         /* For curthread, keep the pcb and trapframe in sync. */
88         if (kdb_thread == curthread) {
89                 switch (regnum) {
90                 case GDB_REG_PC:        kdb_frame->tf_sepc = regval; break;
91                 case GDB_REG_RA:        kdb_frame->tf_ra = regval; break;
92                 case GDB_REG_SP:        kdb_frame->tf_sp = regval; break;
93                 case GDB_REG_GP:        kdb_frame->tf_gp = regval; break;
94                 case GDB_REG_TP:        kdb_frame->tf_tp = regval; break;
95                 case GDB_REG_FP:        kdb_frame->tf_s[0] = regval; break;
96                 case GDB_REG_S1:        kdb_frame->tf_s[1] = regval; break;
97                 case GDB_REG_SSTATUS:   kdb_frame->tf_sstatus = regval; break;
98                 case GDB_REG_STVAL:     kdb_frame->tf_stval = regval; break;
99                 case GDB_REG_SCAUSE:    kdb_frame->tf_scause = regval; break;
100                 default:
101                         if (regnum >= GDB_REG_A0 && regnum < GDB_REG_S2)
102                                 kdb_frame->tf_a[regnum - GDB_REG_A0] = regval;
103                         if (regnum >= GDB_REG_S2 && regnum < GDB_REG_T3)
104                                 kdb_frame->tf_s[regnum - GDB_REG_S2] = regval;
105                         if (regnum >= GDB_REG_T0 && regnum < GDB_REG_FP)
106                                 kdb_frame->tf_t[regnum - GDB_REG_T0] = regval;
107                         if (regnum >= GDB_REG_T3 && regnum < GDB_REG_PC)
108                                 kdb_frame->tf_t[regnum - GDB_REG_T3] = regval;
109                         break;
110                 }
111         }
112         switch (regnum) {
113         case GDB_REG_PC: /* FALLTHROUGH */
114         case GDB_REG_RA: kdb_thrctx->pcb_ra = regval; break;
115         case GDB_REG_SP: kdb_thrctx->pcb_sp = regval; break;
116         case GDB_REG_GP: kdb_thrctx->pcb_gp = regval; break;
117         case GDB_REG_TP: kdb_thrctx->pcb_tp = regval; break;
118         case GDB_REG_FP: kdb_thrctx->pcb_s[0] = regval; break;
119         case GDB_REG_S1: kdb_thrctx->pcb_s[1] = regval; break;
120         default:
121                 if (regnum >= GDB_REG_S2 && regnum < GDB_REG_T3)
122                         kdb_thrctx->pcb_s[regnum - GDB_REG_S2] = regval;
123                 break;
124         }
125 }
126
127 int
128 gdb_cpu_signal(int type, int code)
129 {
130
131         if (type == SCAUSE_BREAKPOINT)
132                 return (SIGTRAP);
133
134         return (SIGEMT);
135 }