1 | /* |
2 | * SuperH 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 "exec/gdbstub.h" |
23 | |
24 | /* Hint: Use "set architecture sh4" in GDB to see fpu registers */ |
25 | /* FIXME: We should use XML for this. */ |
26 | |
27 | int superh_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) |
28 | { |
29 | SuperHCPU *cpu = SUPERH_CPU(cs); |
30 | CPUSH4State *env = &cpu->env; |
31 | |
32 | switch (n) { |
33 | case 0 ... 7: |
34 | if ((env->sr & (1u << SR_MD)) && (env->sr & (1u << SR_RB))) { |
35 | return gdb_get_regl(mem_buf, env->gregs[n + 16]); |
36 | } else { |
37 | return gdb_get_regl(mem_buf, env->gregs[n]); |
38 | } |
39 | case 8 ... 15: |
40 | return gdb_get_regl(mem_buf, env->gregs[n]); |
41 | case 16: |
42 | return gdb_get_regl(mem_buf, env->pc); |
43 | case 17: |
44 | return gdb_get_regl(mem_buf, env->pr); |
45 | case 18: |
46 | return gdb_get_regl(mem_buf, env->gbr); |
47 | case 19: |
48 | return gdb_get_regl(mem_buf, env->vbr); |
49 | case 20: |
50 | return gdb_get_regl(mem_buf, env->mach); |
51 | case 21: |
52 | return gdb_get_regl(mem_buf, env->macl); |
53 | case 22: |
54 | return gdb_get_regl(mem_buf, cpu_read_sr(env)); |
55 | case 23: |
56 | return gdb_get_regl(mem_buf, env->fpul); |
57 | case 24: |
58 | return gdb_get_regl(mem_buf, env->fpscr); |
59 | case 25 ... 40: |
60 | if (env->fpscr & FPSCR_FR) { |
61 | stfl_p(mem_buf, env->fregs[n - 9]); |
62 | } else { |
63 | stfl_p(mem_buf, env->fregs[n - 25]); |
64 | } |
65 | return 4; |
66 | case 41: |
67 | return gdb_get_regl(mem_buf, env->ssr); |
68 | case 42: |
69 | return gdb_get_regl(mem_buf, env->spc); |
70 | case 43 ... 50: |
71 | return gdb_get_regl(mem_buf, env->gregs[n - 43]); |
72 | case 51 ... 58: |
73 | return gdb_get_regl(mem_buf, env->gregs[n - (51 - 16)]); |
74 | } |
75 | |
76 | return 0; |
77 | } |
78 | |
79 | int superh_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) |
80 | { |
81 | SuperHCPU *cpu = SUPERH_CPU(cs); |
82 | CPUSH4State *env = &cpu->env; |
83 | |
84 | switch (n) { |
85 | case 0 ... 7: |
86 | if ((env->sr & (1u << SR_MD)) && (env->sr & (1u << SR_RB))) { |
87 | env->gregs[n + 16] = ldl_p(mem_buf); |
88 | } else { |
89 | env->gregs[n] = ldl_p(mem_buf); |
90 | } |
91 | break; |
92 | case 8 ... 15: |
93 | env->gregs[n] = ldl_p(mem_buf); |
94 | break; |
95 | case 16: |
96 | env->pc = ldl_p(mem_buf); |
97 | break; |
98 | case 17: |
99 | env->pr = ldl_p(mem_buf); |
100 | break; |
101 | case 18: |
102 | env->gbr = ldl_p(mem_buf); |
103 | break; |
104 | case 19: |
105 | env->vbr = ldl_p(mem_buf); |
106 | break; |
107 | case 20: |
108 | env->mach = ldl_p(mem_buf); |
109 | break; |
110 | case 21: |
111 | env->macl = ldl_p(mem_buf); |
112 | break; |
113 | case 22: |
114 | cpu_write_sr(env, ldl_p(mem_buf)); |
115 | break; |
116 | case 23: |
117 | env->fpul = ldl_p(mem_buf); |
118 | break; |
119 | case 24: |
120 | env->fpscr = ldl_p(mem_buf); |
121 | break; |
122 | case 25 ... 40: |
123 | if (env->fpscr & FPSCR_FR) { |
124 | env->fregs[n - 9] = ldfl_p(mem_buf); |
125 | } else { |
126 | env->fregs[n - 25] = ldfl_p(mem_buf); |
127 | } |
128 | break; |
129 | case 41: |
130 | env->ssr = ldl_p(mem_buf); |
131 | break; |
132 | case 42: |
133 | env->spc = ldl_p(mem_buf); |
134 | break; |
135 | case 43 ... 50: |
136 | env->gregs[n - 43] = ldl_p(mem_buf); |
137 | break; |
138 | case 51 ... 58: |
139 | env->gregs[n - (51 - 16)] = ldl_p(mem_buf); |
140 | break; |
141 | default: |
142 | return 0; |
143 | } |
144 | |
145 | return 4; |
146 | } |
147 | |