xref: /openbmc/qemu/target/tricore/gdbstub.c (revision 13af3af1)
1 /*
2  * TriCore gdb server stub
3  *
4  * Copyright (c) 2019 Bastian Koppelmann, Paderborn University
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "gdbstub/helpers.h"
22 
23 
24 #define LCX_REGNUM         32
25 #define FCX_REGNUM         33
26 #define PCXI_REGNUM        34
27 #define TRICORE_PSW_REGNUM 35
28 #define TRICORE_PC_REGNUM  36
29 #define ICR_REGNUM         37
30 #define ISP_REGNUM         38
31 #define BTV_REGNUM         39
32 #define BIV_REGNUM         40
33 #define SYSCON_REGNUM      41
34 #define PMUCON0_REGNUM     42
35 #define DMUCON_REGNUM      43
36 
37 static uint32_t tricore_cpu_gdb_read_csfr(CPUTriCoreState *env, int n)
38 {
39     switch (n) {
40     case LCX_REGNUM:
41         return env->LCX;
42     case FCX_REGNUM:
43         return env->FCX;
44     case PCXI_REGNUM:
45         return env->PCXI;
46     case TRICORE_PSW_REGNUM:
47         return psw_read(env);
48     case TRICORE_PC_REGNUM:
49         return env->PC;
50     case ICR_REGNUM:
51         return env->ICR;
52     case ISP_REGNUM:
53         return env->ISP;
54     case BTV_REGNUM:
55         return env->BTV;
56     case BIV_REGNUM:
57         return env->BIV;
58     case SYSCON_REGNUM:
59         return env->SYSCON;
60     case PMUCON0_REGNUM:
61         return 0; /* PMUCON0 */
62     case DMUCON_REGNUM:
63         return 0; /* DMUCON0 */
64     default:
65         return 0;
66     }
67 }
68 
69 static void tricore_cpu_gdb_write_csfr(CPUTriCoreState *env, int n,
70                                        uint32_t val)
71 {
72     switch (n) {
73     case LCX_REGNUM:
74         env->LCX = val;
75         break;
76     case FCX_REGNUM:
77         env->FCX = val;
78         break;
79     case PCXI_REGNUM:
80         env->PCXI = val;
81         break;
82     case TRICORE_PSW_REGNUM:
83         psw_write(env, val);
84         break;
85     case TRICORE_PC_REGNUM:
86         env->PC = val;
87         break;
88     case ICR_REGNUM:
89         env->ICR = val;
90         break;
91     case ISP_REGNUM:
92         env->ISP = val;
93         break;
94     case BTV_REGNUM:
95         env->BTV = val;
96         break;
97     case BIV_REGNUM:
98         env->BIV = val;
99         break;
100     case SYSCON_REGNUM:
101         env->SYSCON = val;
102         break;
103     }
104 }
105 
106 
107 int tricore_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
108 {
109     CPUTriCoreState *env = cpu_env(cs);
110 
111     if (n < 16) { /* data registers */
112         return gdb_get_reg32(mem_buf, env->gpr_d[n]);
113     } else if (n < 32) { /* address registers */
114         return gdb_get_reg32(mem_buf, env->gpr_a[n - 16]);
115     } else { /* csfr */
116         return gdb_get_reg32(mem_buf, tricore_cpu_gdb_read_csfr(env, n));
117     }
118     return 0;
119 }
120 
121 int tricore_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
122 {
123     CPUTriCoreState *env = cpu_env(cs);
124     uint32_t tmp;
125 
126     tmp = ldl_p(mem_buf);
127 
128     if (n < 16) { /* data registers */
129         env->gpr_d[n] = tmp;
130     } else if (n < 32) { /* address registers */
131         env->gpr_a[n - 16] = tmp;
132     } else {
133         tricore_cpu_gdb_write_csfr(env, n, tmp);
134     }
135     return 4;
136 }
137