xref: /openbmc/qemu/target/tricore/gdbstub.c (revision 7d87775f)
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 #include "cpu.h"
23 
24 
25 #define LCX_REGNUM         32
26 #define FCX_REGNUM         33
27 #define PCXI_REGNUM        34
28 #define TRICORE_PSW_REGNUM 35
29 #define TRICORE_PC_REGNUM  36
30 #define ICR_REGNUM         37
31 #define ISP_REGNUM         38
32 #define BTV_REGNUM         39
33 #define BIV_REGNUM         40
34 #define SYSCON_REGNUM      41
35 #define PMUCON0_REGNUM     42
36 #define DMUCON_REGNUM      43
37 
38 static uint32_t tricore_cpu_gdb_read_csfr(CPUTriCoreState *env, int n)
39 {
40     switch (n) {
41     case LCX_REGNUM:
42         return env->LCX;
43     case FCX_REGNUM:
44         return env->FCX;
45     case PCXI_REGNUM:
46         return env->PCXI;
47     case TRICORE_PSW_REGNUM:
48         return psw_read(env);
49     case TRICORE_PC_REGNUM:
50         return env->PC;
51     case ICR_REGNUM:
52         return env->ICR;
53     case ISP_REGNUM:
54         return env->ISP;
55     case BTV_REGNUM:
56         return env->BTV;
57     case BIV_REGNUM:
58         return env->BIV;
59     case SYSCON_REGNUM:
60         return env->SYSCON;
61     case PMUCON0_REGNUM:
62         return 0; /* PMUCON0 */
63     case DMUCON_REGNUM:
64         return 0; /* DMUCON0 */
65     default:
66         return 0;
67     }
68 }
69 
70 static void tricore_cpu_gdb_write_csfr(CPUTriCoreState *env, int n,
71                                        uint32_t val)
72 {
73     switch (n) {
74     case LCX_REGNUM:
75         env->LCX = val;
76         break;
77     case FCX_REGNUM:
78         env->FCX = val;
79         break;
80     case PCXI_REGNUM:
81         env->PCXI = val;
82         break;
83     case TRICORE_PSW_REGNUM:
84         psw_write(env, val);
85         break;
86     case TRICORE_PC_REGNUM:
87         env->PC = val;
88         break;
89     case ICR_REGNUM:
90         env->ICR = val;
91         break;
92     case ISP_REGNUM:
93         env->ISP = val;
94         break;
95     case BTV_REGNUM:
96         env->BTV = val;
97         break;
98     case BIV_REGNUM:
99         env->BIV = val;
100         break;
101     case SYSCON_REGNUM:
102         env->SYSCON = val;
103         break;
104     }
105 }
106 
107 
108 int tricore_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
109 {
110     CPUTriCoreState *env = cpu_env(cs);
111 
112     if (n < 16) { /* data registers */
113         return gdb_get_reg32(mem_buf, env->gpr_d[n]);
114     } else if (n < 32) { /* address registers */
115         return gdb_get_reg32(mem_buf, env->gpr_a[n - 16]);
116     } else { /* csfr */
117         return gdb_get_reg32(mem_buf, tricore_cpu_gdb_read_csfr(env, n));
118     }
119     return 0;
120 }
121 
122 int tricore_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
123 {
124     CPUTriCoreState *env = cpu_env(cs);
125     uint32_t tmp;
126 
127     tmp = ldl_le_p(mem_buf);
128 
129     if (n < 16) { /* data registers */
130         env->gpr_d[n] = tmp;
131     } else if (n < 32) { /* address registers */
132         env->gpr_a[n - 16] = tmp;
133     } else {
134         tricore_cpu_gdb_write_csfr(env, n, tmp);
135     }
136     return 4;
137 }
138