xref: /qemu/target/microblaze/gdbstub.c (revision 9ea920dc)
1 /*
2  * MicroBlaze gdb server stub
3  *
4  * Copyright (c) 2003-2005 Fabrice Bellard
5  * Copyright (c) 2013 SUSE LINUX Products GmbH
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "gdbstub/helpers.h"
23 
24 /*
25  * GDB expects SREGs in the following order:
26  * PC, MSR, EAR, ESR, FSR, BTR, EDR, PID, ZPR, TLBX, TLBSX, TLBLO, TLBHI.
27  *
28  * PID, ZPR, TLBx, TLBsx, TLBLO, and TLBHI aren't modeled, so we don't
29  * map them to anything and return a value of 0 instead.
30  */
31 
32 enum {
33     GDB_PC    = 32 + 0,
34     GDB_MSR   = 32 + 1,
35     GDB_EAR   = 32 + 2,
36     GDB_ESR   = 32 + 3,
37     GDB_FSR   = 32 + 4,
38     GDB_BTR   = 32 + 5,
39     GDB_PVR0  = 32 + 6,
40     GDB_PVR11 = 32 + 17,
41     GDB_EDR   = 32 + 18,
42 };
43 
44 enum {
45     GDB_SP_SHL,
46     GDB_SP_SHR,
47 };
48 
49 int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
50 {
51     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
52     CPUMBState *env = &cpu->env;
53     uint32_t val;
54 
55     switch (n) {
56     case 1 ... 31:
57         val = env->regs[n];
58         break;
59     case GDB_PC:
60         val = env->pc;
61         break;
62     case GDB_MSR:
63         val = mb_cpu_read_msr(env);
64         break;
65     case GDB_EAR:
66         val = env->ear;
67         break;
68     case GDB_ESR:
69         val = env->esr;
70         break;
71     case GDB_FSR:
72         val = env->fsr;
73         break;
74     case GDB_BTR:
75         val = env->btr;
76         break;
77     case GDB_PVR0 ... GDB_PVR11:
78         /* PVR12 is intentionally skipped */
79         val = cpu->cfg.pvr_regs[n - GDB_PVR0];
80         break;
81     case GDB_EDR:
82         val = env->edr;
83         break;
84     default:
85         /* Other SRegs aren't modeled, so report a value of 0 */
86         val = 0;
87         break;
88     }
89     return gdb_get_reg32(mem_buf, val);
90 }
91 
92 int mb_cpu_gdb_read_stack_protect(CPUState *cs, GByteArray *mem_buf, int n)
93 {
94     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
95     CPUMBState *env = &cpu->env;
96     uint32_t val;
97 
98     switch (n) {
99     case GDB_SP_SHL:
100         val = env->slr;
101         break;
102     case GDB_SP_SHR:
103         val = env->shr;
104         break;
105     default:
106         return 0;
107     }
108     return gdb_get_reg32(mem_buf, val);
109 }
110 
111 int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
112 {
113     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
114     CPUClass *cc = CPU_GET_CLASS(cs);
115     CPUMBState *env = &cpu->env;
116     uint32_t tmp;
117 
118     if (n > cc->gdb_num_core_regs) {
119         return 0;
120     }
121 
122     tmp = ldl_p(mem_buf);
123 
124     switch (n) {
125     case 1 ... 31:
126         env->regs[n] = tmp;
127         break;
128     case GDB_PC:
129         env->pc = tmp;
130         break;
131     case GDB_MSR:
132         mb_cpu_write_msr(env, tmp);
133         break;
134     case GDB_EAR:
135         env->ear = tmp;
136         break;
137     case GDB_ESR:
138         env->esr = tmp;
139         break;
140     case GDB_FSR:
141         env->fsr = tmp;
142         break;
143     case GDB_BTR:
144         env->btr = tmp;
145         break;
146     case GDB_EDR:
147         env->edr = tmp;
148         break;
149     }
150     return 4;
151 }
152 
153 int mb_cpu_gdb_write_stack_protect(CPUState *cs, uint8_t *mem_buf, int n)
154 {
155     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
156     CPUMBState *env = &cpu->env;
157 
158     switch (n) {
159     case GDB_SP_SHL:
160         env->slr = ldl_p(mem_buf);
161         break;
162     case GDB_SP_SHR:
163         env->shr = ldl_p(mem_buf);
164         break;
165     default:
166         return 0;
167     }
168     return 4;
169 }
170