xref: /openbmc/qemu/target/microblaze/gdbstub.c (revision d5657258)
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     CPUClass *cc = CPU_GET_CLASS(cs);
53     CPUMBState *env = &cpu->env;
54     uint32_t val;
55 
56     if (n > cc->gdb_num_core_regs) {
57         return 0;
58     }
59 
60     switch (n) {
61     case 1 ... 31:
62         val = env->regs[n];
63         break;
64     case GDB_PC:
65         val = env->pc;
66         break;
67     case GDB_MSR:
68         val = mb_cpu_read_msr(env);
69         break;
70     case GDB_EAR:
71         val = env->ear;
72         break;
73     case GDB_ESR:
74         val = env->esr;
75         break;
76     case GDB_FSR:
77         val = env->fsr;
78         break;
79     case GDB_BTR:
80         val = env->btr;
81         break;
82     case GDB_PVR0 ... GDB_PVR11:
83         /* PVR12 is intentionally skipped */
84         val = cpu->cfg.pvr_regs[n - GDB_PVR0];
85         break;
86     case GDB_EDR:
87         val = env->edr;
88         break;
89     default:
90         /* Other SRegs aren't modeled, so report a value of 0 */
91         val = 0;
92         break;
93     }
94     return gdb_get_reg32(mem_buf, val);
95 }
96 
97 int mb_cpu_gdb_read_stack_protect(CPUMBState *env, GByteArray *mem_buf, int n)
98 {
99     uint32_t val;
100 
101     switch (n) {
102     case GDB_SP_SHL:
103         val = env->slr;
104         break;
105     case GDB_SP_SHR:
106         val = env->shr;
107         break;
108     default:
109         return 0;
110     }
111     return gdb_get_reg32(mem_buf, val);
112 }
113 
114 int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
115 {
116     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
117     CPUClass *cc = CPU_GET_CLASS(cs);
118     CPUMBState *env = &cpu->env;
119     uint32_t tmp;
120 
121     if (n > cc->gdb_num_core_regs) {
122         return 0;
123     }
124 
125     tmp = ldl_p(mem_buf);
126 
127     switch (n) {
128     case 1 ... 31:
129         env->regs[n] = tmp;
130         break;
131     case GDB_PC:
132         env->pc = tmp;
133         break;
134     case GDB_MSR:
135         mb_cpu_write_msr(env, tmp);
136         break;
137     case GDB_EAR:
138         env->ear = tmp;
139         break;
140     case GDB_ESR:
141         env->esr = tmp;
142         break;
143     case GDB_FSR:
144         env->fsr = tmp;
145         break;
146     case GDB_BTR:
147         env->btr = tmp;
148         break;
149     case GDB_EDR:
150         env->edr = tmp;
151         break;
152     }
153     return 4;
154 }
155 
156 int mb_cpu_gdb_write_stack_protect(CPUMBState *env, uint8_t *mem_buf, int n)
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