xref: /openbmc/qemu/target/sparc/gdbstub.c (revision fcf5ef2ab52c621a4617ebbef36bf43b4003f4c0)
1*fcf5ef2aSThomas Huth /*
2*fcf5ef2aSThomas Huth  * SPARC gdb server stub
3*fcf5ef2aSThomas Huth  *
4*fcf5ef2aSThomas Huth  * Copyright (c) 2003-2005 Fabrice Bellard
5*fcf5ef2aSThomas Huth  * Copyright (c) 2013 SUSE LINUX Products GmbH
6*fcf5ef2aSThomas Huth  *
7*fcf5ef2aSThomas Huth  * This library is free software; you can redistribute it and/or
8*fcf5ef2aSThomas Huth  * modify it under the terms of the GNU Lesser General Public
9*fcf5ef2aSThomas Huth  * License as published by the Free Software Foundation; either
10*fcf5ef2aSThomas Huth  * version 2 of the License, or (at your option) any later version.
11*fcf5ef2aSThomas Huth  *
12*fcf5ef2aSThomas Huth  * This library is distributed in the hope that it will be useful,
13*fcf5ef2aSThomas Huth  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*fcf5ef2aSThomas Huth  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15*fcf5ef2aSThomas Huth  * Lesser General Public License for more details.
16*fcf5ef2aSThomas Huth  *
17*fcf5ef2aSThomas Huth  * You should have received a copy of the GNU Lesser General Public
18*fcf5ef2aSThomas Huth  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19*fcf5ef2aSThomas Huth  */
20*fcf5ef2aSThomas Huth #include "qemu/osdep.h"
21*fcf5ef2aSThomas Huth #include "qemu-common.h"
22*fcf5ef2aSThomas Huth #include "cpu.h"
23*fcf5ef2aSThomas Huth #include "exec/gdbstub.h"
24*fcf5ef2aSThomas Huth 
25*fcf5ef2aSThomas Huth #ifdef TARGET_ABI32
26*fcf5ef2aSThomas Huth #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val)
27*fcf5ef2aSThomas Huth #else
28*fcf5ef2aSThomas Huth #define gdb_get_rega(buf, val) gdb_get_regl(buf, val)
29*fcf5ef2aSThomas Huth #endif
30*fcf5ef2aSThomas Huth 
31*fcf5ef2aSThomas Huth int sparc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
32*fcf5ef2aSThomas Huth {
33*fcf5ef2aSThomas Huth     SPARCCPU *cpu = SPARC_CPU(cs);
34*fcf5ef2aSThomas Huth     CPUSPARCState *env = &cpu->env;
35*fcf5ef2aSThomas Huth 
36*fcf5ef2aSThomas Huth     if (n < 8) {
37*fcf5ef2aSThomas Huth         /* g0..g7 */
38*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->gregs[n]);
39*fcf5ef2aSThomas Huth     }
40*fcf5ef2aSThomas Huth     if (n < 32) {
41*fcf5ef2aSThomas Huth         /* register window */
42*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
43*fcf5ef2aSThomas Huth     }
44*fcf5ef2aSThomas Huth #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
45*fcf5ef2aSThomas Huth     if (n < 64) {
46*fcf5ef2aSThomas Huth         /* fprs */
47*fcf5ef2aSThomas Huth         if (n & 1) {
48*fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
49*fcf5ef2aSThomas Huth         } else {
50*fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
51*fcf5ef2aSThomas Huth         }
52*fcf5ef2aSThomas Huth     }
53*fcf5ef2aSThomas Huth     /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
54*fcf5ef2aSThomas Huth     switch (n) {
55*fcf5ef2aSThomas Huth     case 64:
56*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->y);
57*fcf5ef2aSThomas Huth     case 65:
58*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, cpu_get_psr(env));
59*fcf5ef2aSThomas Huth     case 66:
60*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->wim);
61*fcf5ef2aSThomas Huth     case 67:
62*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->tbr);
63*fcf5ef2aSThomas Huth     case 68:
64*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->pc);
65*fcf5ef2aSThomas Huth     case 69:
66*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->npc);
67*fcf5ef2aSThomas Huth     case 70:
68*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->fsr);
69*fcf5ef2aSThomas Huth     case 71:
70*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, 0); /* csr */
71*fcf5ef2aSThomas Huth     default:
72*fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, 0);
73*fcf5ef2aSThomas Huth     }
74*fcf5ef2aSThomas Huth #else
75*fcf5ef2aSThomas Huth     if (n < 64) {
76*fcf5ef2aSThomas Huth         /* f0-f31 */
77*fcf5ef2aSThomas Huth         if (n & 1) {
78*fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
79*fcf5ef2aSThomas Huth         } else {
80*fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
81*fcf5ef2aSThomas Huth         }
82*fcf5ef2aSThomas Huth     }
83*fcf5ef2aSThomas Huth     if (n < 80) {
84*fcf5ef2aSThomas Huth         /* f32-f62 (double width, even numbers only) */
85*fcf5ef2aSThomas Huth         return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
86*fcf5ef2aSThomas Huth     }
87*fcf5ef2aSThomas Huth     switch (n) {
88*fcf5ef2aSThomas Huth     case 80:
89*fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->pc);
90*fcf5ef2aSThomas Huth     case 81:
91*fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->npc);
92*fcf5ef2aSThomas Huth     case 82:
93*fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
94*fcf5ef2aSThomas Huth                                      ((env->asi & 0xff) << 24) |
95*fcf5ef2aSThomas Huth                                      ((env->pstate & 0xfff) << 8) |
96*fcf5ef2aSThomas Huth                                      cpu_get_cwp64(env));
97*fcf5ef2aSThomas Huth     case 83:
98*fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->fsr);
99*fcf5ef2aSThomas Huth     case 84:
100*fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->fprs);
101*fcf5ef2aSThomas Huth     case 85:
102*fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->y);
103*fcf5ef2aSThomas Huth     }
104*fcf5ef2aSThomas Huth #endif
105*fcf5ef2aSThomas Huth     return 0;
106*fcf5ef2aSThomas Huth }
107*fcf5ef2aSThomas Huth 
108*fcf5ef2aSThomas Huth int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
109*fcf5ef2aSThomas Huth {
110*fcf5ef2aSThomas Huth     SPARCCPU *cpu = SPARC_CPU(cs);
111*fcf5ef2aSThomas Huth     CPUSPARCState *env = &cpu->env;
112*fcf5ef2aSThomas Huth #if defined(TARGET_ABI32)
113*fcf5ef2aSThomas Huth     abi_ulong tmp;
114*fcf5ef2aSThomas Huth 
115*fcf5ef2aSThomas Huth     tmp = ldl_p(mem_buf);
116*fcf5ef2aSThomas Huth #else
117*fcf5ef2aSThomas Huth     target_ulong tmp;
118*fcf5ef2aSThomas Huth 
119*fcf5ef2aSThomas Huth     tmp = ldtul_p(mem_buf);
120*fcf5ef2aSThomas Huth #endif
121*fcf5ef2aSThomas Huth 
122*fcf5ef2aSThomas Huth     if (n < 8) {
123*fcf5ef2aSThomas Huth         /* g0..g7 */
124*fcf5ef2aSThomas Huth         env->gregs[n] = tmp;
125*fcf5ef2aSThomas Huth     } else if (n < 32) {
126*fcf5ef2aSThomas Huth         /* register window */
127*fcf5ef2aSThomas Huth         env->regwptr[n - 8] = tmp;
128*fcf5ef2aSThomas Huth     }
129*fcf5ef2aSThomas Huth #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
130*fcf5ef2aSThomas Huth     else if (n < 64) {
131*fcf5ef2aSThomas Huth         /* fprs */
132*fcf5ef2aSThomas Huth         /* f0-f31 */
133*fcf5ef2aSThomas Huth         if (n & 1) {
134*fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.lower = tmp;
135*fcf5ef2aSThomas Huth         } else {
136*fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.upper = tmp;
137*fcf5ef2aSThomas Huth         }
138*fcf5ef2aSThomas Huth     } else {
139*fcf5ef2aSThomas Huth         /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
140*fcf5ef2aSThomas Huth         switch (n) {
141*fcf5ef2aSThomas Huth         case 64:
142*fcf5ef2aSThomas Huth             env->y = tmp;
143*fcf5ef2aSThomas Huth             break;
144*fcf5ef2aSThomas Huth         case 65:
145*fcf5ef2aSThomas Huth             cpu_put_psr(env, tmp);
146*fcf5ef2aSThomas Huth             break;
147*fcf5ef2aSThomas Huth         case 66:
148*fcf5ef2aSThomas Huth             env->wim = tmp;
149*fcf5ef2aSThomas Huth             break;
150*fcf5ef2aSThomas Huth         case 67:
151*fcf5ef2aSThomas Huth             env->tbr = tmp;
152*fcf5ef2aSThomas Huth             break;
153*fcf5ef2aSThomas Huth         case 68:
154*fcf5ef2aSThomas Huth             env->pc = tmp;
155*fcf5ef2aSThomas Huth             break;
156*fcf5ef2aSThomas Huth         case 69:
157*fcf5ef2aSThomas Huth             env->npc = tmp;
158*fcf5ef2aSThomas Huth             break;
159*fcf5ef2aSThomas Huth         case 70:
160*fcf5ef2aSThomas Huth             env->fsr = tmp;
161*fcf5ef2aSThomas Huth             break;
162*fcf5ef2aSThomas Huth         default:
163*fcf5ef2aSThomas Huth             return 0;
164*fcf5ef2aSThomas Huth         }
165*fcf5ef2aSThomas Huth     }
166*fcf5ef2aSThomas Huth     return 4;
167*fcf5ef2aSThomas Huth #else
168*fcf5ef2aSThomas Huth     else if (n < 64) {
169*fcf5ef2aSThomas Huth         /* f0-f31 */
170*fcf5ef2aSThomas Huth         tmp = ldl_p(mem_buf);
171*fcf5ef2aSThomas Huth         if (n & 1) {
172*fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.lower = tmp;
173*fcf5ef2aSThomas Huth         } else {
174*fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.upper = tmp;
175*fcf5ef2aSThomas Huth         }
176*fcf5ef2aSThomas Huth         return 4;
177*fcf5ef2aSThomas Huth     } else if (n < 80) {
178*fcf5ef2aSThomas Huth         /* f32-f62 (double width, even numbers only) */
179*fcf5ef2aSThomas Huth         env->fpr[(n - 32) / 2].ll = tmp;
180*fcf5ef2aSThomas Huth     } else {
181*fcf5ef2aSThomas Huth         switch (n) {
182*fcf5ef2aSThomas Huth         case 80:
183*fcf5ef2aSThomas Huth             env->pc = tmp;
184*fcf5ef2aSThomas Huth             break;
185*fcf5ef2aSThomas Huth         case 81:
186*fcf5ef2aSThomas Huth             env->npc = tmp;
187*fcf5ef2aSThomas Huth             break;
188*fcf5ef2aSThomas Huth         case 82:
189*fcf5ef2aSThomas Huth             cpu_put_ccr(env, tmp >> 32);
190*fcf5ef2aSThomas Huth             env->asi = (tmp >> 24) & 0xff;
191*fcf5ef2aSThomas Huth             env->pstate = (tmp >> 8) & 0xfff;
192*fcf5ef2aSThomas Huth             cpu_put_cwp64(env, tmp & 0xff);
193*fcf5ef2aSThomas Huth             break;
194*fcf5ef2aSThomas Huth         case 83:
195*fcf5ef2aSThomas Huth             env->fsr = tmp;
196*fcf5ef2aSThomas Huth             break;
197*fcf5ef2aSThomas Huth         case 84:
198*fcf5ef2aSThomas Huth             env->fprs = tmp;
199*fcf5ef2aSThomas Huth             break;
200*fcf5ef2aSThomas Huth         case 85:
201*fcf5ef2aSThomas Huth             env->y = tmp;
202*fcf5ef2aSThomas Huth             break;
203*fcf5ef2aSThomas Huth         default:
204*fcf5ef2aSThomas Huth             return 0;
205*fcf5ef2aSThomas Huth         }
206*fcf5ef2aSThomas Huth     }
207*fcf5ef2aSThomas Huth     return 8;
208*fcf5ef2aSThomas Huth #endif
209*fcf5ef2aSThomas Huth }
210