Statistics
| Branch: | Revision:

root / target-sparc / gdbstub.c @ 986a2998

History | View | Annotate | Download (5.3 kB)

1
/*
2
 * SPARC 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 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

    
21
#ifdef TARGET_ABI32
22
#define gdb_get_rega(buf, val) gdb_get_reg32(buf, val)
23
#else
24
#define gdb_get_rega(buf, val) gdb_get_regl(buf, val)
25
#endif
26

    
27
static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
28
{
29
    if (n < 8) {
30
        /* g0..g7 */
31
        return gdb_get_rega(mem_buf, env->gregs[n]);
32
    }
33
    if (n < 32) {
34
        /* register window */
35
        return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
36
    }
37
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
38
    if (n < 64) {
39
        /* fprs */
40
        if (n & 1) {
41
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
42
        } else {
43
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
44
        }
45
    }
46
    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
47
    switch (n) {
48
    case 64:
49
        return gdb_get_rega(mem_buf, env->y);
50
    case 65:
51
        return gdb_get_rega(mem_buf, cpu_get_psr(env));
52
    case 66:
53
        return gdb_get_rega(mem_buf, env->wim);
54
    case 67:
55
        return gdb_get_rega(mem_buf, env->tbr);
56
    case 68:
57
        return gdb_get_rega(mem_buf, env->pc);
58
    case 69:
59
        return gdb_get_rega(mem_buf, env->npc);
60
    case 70:
61
        return gdb_get_rega(mem_buf, env->fsr);
62
    case 71:
63
        return gdb_get_rega(mem_buf, 0); /* csr */
64
    default:
65
        return gdb_get_rega(mem_buf, 0);
66
    }
67
#else
68
    if (n < 64) {
69
        /* f0-f31 */
70
        if (n & 1) {
71
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
72
        } else {
73
            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
74
        }
75
    }
76
    if (n < 80) {
77
        /* f32-f62 (double width, even numbers only) */
78
        return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
79
    }
80
    switch (n) {
81
    case 80:
82
        return gdb_get_regl(mem_buf, env->pc);
83
    case 81:
84
        return gdb_get_regl(mem_buf, env->npc);
85
    case 82:
86
        return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
87
                                     ((env->asi & 0xff) << 24) |
88
                                     ((env->pstate & 0xfff) << 8) |
89
                                     cpu_get_cwp64(env));
90
    case 83:
91
        return gdb_get_regl(mem_buf, env->fsr);
92
    case 84:
93
        return gdb_get_regl(mem_buf, env->fprs);
94
    case 85:
95
        return gdb_get_regl(mem_buf, env->y);
96
    }
97
#endif
98
    return 0;
99
}
100

    
101
static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
102
{
103
#if defined(TARGET_ABI32)
104
    abi_ulong tmp;
105

    
106
    tmp = ldl_p(mem_buf);
107
#else
108
    target_ulong tmp;
109

    
110
    tmp = ldtul_p(mem_buf);
111
#endif
112

    
113
    if (n < 8) {
114
        /* g0..g7 */
115
        env->gregs[n] = tmp;
116
    } else if (n < 32) {
117
        /* register window */
118
        env->regwptr[n - 8] = tmp;
119
    }
120
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
121
    else if (n < 64) {
122
        /* fprs */
123
        /* f0-f31 */
124
        if (n & 1) {
125
            env->fpr[(n - 32) / 2].l.lower = tmp;
126
        } else {
127
            env->fpr[(n - 32) / 2].l.upper = tmp;
128
        }
129
    } else {
130
        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
131
        switch (n) {
132
        case 64:
133
            env->y = tmp;
134
            break;
135
        case 65:
136
            cpu_put_psr(env, tmp);
137
            break;
138
        case 66:
139
            env->wim = tmp;
140
            break;
141
        case 67:
142
            env->tbr = tmp;
143
            break;
144
        case 68:
145
            env->pc = tmp;
146
            break;
147
        case 69:
148
            env->npc = tmp;
149
            break;
150
        case 70:
151
            env->fsr = tmp;
152
            break;
153
        default:
154
            return 0;
155
        }
156
    }
157
    return 4;
158
#else
159
    else if (n < 64) {
160
        /* f0-f31 */
161
        tmp = ldl_p(mem_buf);
162
        if (n & 1) {
163
            env->fpr[(n - 32) / 2].l.lower = tmp;
164
        } else {
165
            env->fpr[(n - 32) / 2].l.upper = tmp;
166
        }
167
        return 4;
168
    } else if (n < 80) {
169
        /* f32-f62 (double width, even numbers only) */
170
        env->fpr[(n - 32) / 2].ll = tmp;
171
    } else {
172
        switch (n) {
173
        case 80:
174
            env->pc = tmp;
175
            break;
176
        case 81:
177
            env->npc = tmp;
178
            break;
179
        case 82:
180
            cpu_put_ccr(env, tmp >> 32);
181
            env->asi = (tmp >> 24) & 0xff;
182
            env->pstate = (tmp >> 8) & 0xfff;
183
            cpu_put_cwp64(env, tmp & 0xff);
184
            break;
185
        case 83:
186
            env->fsr = tmp;
187
            break;
188
        case 84:
189
            env->fprs = tmp;
190
            break;
191
        case 85:
192
            env->y = tmp;
193
            break;
194
        default:
195
            return 0;
196
        }
197
    }
198
    return 8;
199
#endif
200
}