xref: /qemu/target/microblaze/gdbstub.c (revision 4a1babe5)
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     CPUClass *cc = CPU_GET_CLASS(cs);
114     CPUMBState *env = cpu_env(cs);
115     uint32_t tmp;
116 
117     if (n > cc->gdb_num_core_regs) {
118         return 0;
119     }
120 
121     tmp = ldl_p(mem_buf);
122 
123     switch (n) {
124     case 1 ... 31:
125         env->regs[n] = tmp;
126         break;
127     case GDB_PC:
128         env->pc = tmp;
129         break;
130     case GDB_MSR:
131         mb_cpu_write_msr(env, tmp);
132         break;
133     case GDB_EAR:
134         env->ear = tmp;
135         break;
136     case GDB_ESR:
137         env->esr = tmp;
138         break;
139     case GDB_FSR:
140         env->fsr = tmp;
141         break;
142     case GDB_BTR:
143         env->btr = tmp;
144         break;
145     case GDB_EDR:
146         env->edr = tmp;
147         break;
148     }
149     return 4;
150 }
151 
152 int mb_cpu_gdb_write_stack_protect(CPUState *cs, uint8_t *mem_buf, int n)
153 {
154     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
155     CPUMBState *env = &cpu->env;
156 
157     switch (n) {
158     case GDB_SP_SHL:
159         env->slr = ldl_p(mem_buf);
160         break;
161     case GDB_SP_SHR:
162         env->shr = ldl_p(mem_buf);
163         break;
164     default:
165         return 0;
166     }
167     return 4;
168 }
169