root / target-mips / gdbstub.c @ 5b50e790
History | View | Annotate | Download (4.4 kB)
1 | 814ac26c | Andreas Färber | /*
|
---|---|---|---|
2 | 814ac26c | Andreas Färber | * MIPS gdb server stub
|
3 | 814ac26c | Andreas Färber | *
|
4 | 814ac26c | Andreas Färber | * Copyright (c) 2003-2005 Fabrice Bellard
|
5 | 814ac26c | Andreas Färber | * Copyright (c) 2013 SUSE LINUX Products GmbH
|
6 | 814ac26c | Andreas Färber | *
|
7 | 814ac26c | Andreas Färber | * This library is free software; you can redistribute it and/or
|
8 | 814ac26c | Andreas Färber | * modify it under the terms of the GNU Lesser General Public
|
9 | 814ac26c | Andreas Färber | * License as published by the Free Software Foundation; either
|
10 | 814ac26c | Andreas Färber | * version 2 of the License, or (at your option) any later version.
|
11 | 814ac26c | Andreas Färber | *
|
12 | 814ac26c | Andreas Färber | * This library is distributed in the hope that it will be useful,
|
13 | 814ac26c | Andreas Färber | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | 814ac26c | Andreas Färber | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 | 814ac26c | Andreas Färber | * Lesser General Public License for more details.
|
16 | 814ac26c | Andreas Färber | *
|
17 | 814ac26c | Andreas Färber | * You should have received a copy of the GNU Lesser General Public
|
18 | 814ac26c | Andreas Färber | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
19 | 814ac26c | Andreas Färber | */
|
20 | 5b50e790 | Andreas Färber | #include "config.h" |
21 | 5b50e790 | Andreas Färber | #include "qemu-common.h" |
22 | 5b50e790 | Andreas Färber | #include "exec/gdbstub.h" |
23 | 814ac26c | Andreas Färber | |
24 | 5b50e790 | Andreas Färber | int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) |
25 | 814ac26c | Andreas Färber | { |
26 | 5b50e790 | Andreas Färber | MIPSCPU *cpu = MIPS_CPU(cs); |
27 | 5b50e790 | Andreas Färber | CPUMIPSState *env = &cpu->env; |
28 | 5b50e790 | Andreas Färber | |
29 | 814ac26c | Andreas Färber | if (n < 32) { |
30 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, env->active_tc.gpr[n]);
|
31 | 814ac26c | Andreas Färber | } |
32 | 814ac26c | Andreas Färber | if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
33 | 814ac26c | Andreas Färber | if (n >= 38 && n < 70) { |
34 | 814ac26c | Andreas Färber | if (env->CP0_Status & (1 << CP0St_FR)) { |
35 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf,
|
36 | 986a2998 | Andreas Färber | env->active_fpu.fpr[n - 38].d);
|
37 | 814ac26c | Andreas Färber | } else {
|
38 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf,
|
39 | 986a2998 | Andreas Färber | env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
|
40 | 814ac26c | Andreas Färber | } |
41 | 814ac26c | Andreas Färber | } |
42 | 814ac26c | Andreas Färber | switch (n) {
|
43 | 814ac26c | Andreas Färber | case 70: |
44 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr31);
|
45 | 814ac26c | Andreas Färber | case 71: |
46 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0);
|
47 | 814ac26c | Andreas Färber | } |
48 | 814ac26c | Andreas Färber | } |
49 | 814ac26c | Andreas Färber | switch (n) {
|
50 | 814ac26c | Andreas Färber | case 32: |
51 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, (int32_t)env->CP0_Status);
|
52 | 814ac26c | Andreas Färber | case 33: |
53 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, env->active_tc.LO[0]); |
54 | 814ac26c | Andreas Färber | case 34: |
55 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, env->active_tc.HI[0]); |
56 | 814ac26c | Andreas Färber | case 35: |
57 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, env->CP0_BadVAddr);
|
58 | 814ac26c | Andreas Färber | case 36: |
59 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause);
|
60 | 814ac26c | Andreas Färber | case 37: |
61 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, env->active_tc.PC |
|
62 | 986a2998 | Andreas Färber | !!(env->hflags & MIPS_HFLAG_M16)); |
63 | 814ac26c | Andreas Färber | case 72: |
64 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, 0); /* fp */ |
65 | 814ac26c | Andreas Färber | case 89: |
66 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, (int32_t)env->CP0_PRid);
|
67 | 814ac26c | Andreas Färber | } |
68 | 814ac26c | Andreas Färber | if (n >= 73 && n <= 88) { |
69 | 814ac26c | Andreas Färber | /* 16 embedded regs. */
|
70 | 986a2998 | Andreas Färber | return gdb_get_regl(mem_buf, 0); |
71 | 814ac26c | Andreas Färber | } |
72 | 814ac26c | Andreas Färber | |
73 | 814ac26c | Andreas Färber | return 0; |
74 | 814ac26c | Andreas Färber | } |
75 | 814ac26c | Andreas Färber | |
76 | 814ac26c | Andreas Färber | /* convert MIPS rounding mode in FCR31 to IEEE library */
|
77 | 814ac26c | Andreas Färber | static unsigned int ieee_rm[] = { |
78 | 814ac26c | Andreas Färber | float_round_nearest_even, |
79 | 814ac26c | Andreas Färber | float_round_to_zero, |
80 | 814ac26c | Andreas Färber | float_round_up, |
81 | 814ac26c | Andreas Färber | float_round_down |
82 | 814ac26c | Andreas Färber | }; |
83 | 814ac26c | Andreas Färber | #define RESTORE_ROUNDING_MODE \
|
84 | 814ac26c | Andreas Färber | set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \
|
85 | 814ac26c | Andreas Färber | &env->active_fpu.fp_status) |
86 | 814ac26c | Andreas Färber | |
87 | 5b50e790 | Andreas Färber | int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) |
88 | 814ac26c | Andreas Färber | { |
89 | 5b50e790 | Andreas Färber | MIPSCPU *cpu = MIPS_CPU(cs); |
90 | 5b50e790 | Andreas Färber | CPUMIPSState *env = &cpu->env; |
91 | 814ac26c | Andreas Färber | target_ulong tmp; |
92 | 814ac26c | Andreas Färber | |
93 | 814ac26c | Andreas Färber | tmp = ldtul_p(mem_buf); |
94 | 814ac26c | Andreas Färber | |
95 | 814ac26c | Andreas Färber | if (n < 32) { |
96 | 814ac26c | Andreas Färber | env->active_tc.gpr[n] = tmp; |
97 | 814ac26c | Andreas Färber | return sizeof(target_ulong); |
98 | 814ac26c | Andreas Färber | } |
99 | 814ac26c | Andreas Färber | if (env->CP0_Config1 & (1 << CP0C1_FP) |
100 | 814ac26c | Andreas Färber | && n >= 38 && n < 73) { |
101 | 814ac26c | Andreas Färber | if (n < 70) { |
102 | 814ac26c | Andreas Färber | if (env->CP0_Status & (1 << CP0St_FR)) { |
103 | 814ac26c | Andreas Färber | env->active_fpu.fpr[n - 38].d = tmp;
|
104 | 814ac26c | Andreas Färber | } else {
|
105 | 814ac26c | Andreas Färber | env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
|
106 | 814ac26c | Andreas Färber | } |
107 | 814ac26c | Andreas Färber | } |
108 | 814ac26c | Andreas Färber | switch (n) {
|
109 | 814ac26c | Andreas Färber | case 70: |
110 | 814ac26c | Andreas Färber | env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
|
111 | 814ac26c | Andreas Färber | /* set rounding mode */
|
112 | 814ac26c | Andreas Färber | RESTORE_ROUNDING_MODE; |
113 | 814ac26c | Andreas Färber | break;
|
114 | 814ac26c | Andreas Färber | case 71: |
115 | 814ac26c | Andreas Färber | env->active_fpu.fcr0 = tmp; |
116 | 814ac26c | Andreas Färber | break;
|
117 | 814ac26c | Andreas Färber | } |
118 | 814ac26c | Andreas Färber | return sizeof(target_ulong); |
119 | 814ac26c | Andreas Färber | } |
120 | 814ac26c | Andreas Färber | switch (n) {
|
121 | 814ac26c | Andreas Färber | case 32: |
122 | 814ac26c | Andreas Färber | env->CP0_Status = tmp; |
123 | 814ac26c | Andreas Färber | break;
|
124 | 814ac26c | Andreas Färber | case 33: |
125 | 814ac26c | Andreas Färber | env->active_tc.LO[0] = tmp;
|
126 | 814ac26c | Andreas Färber | break;
|
127 | 814ac26c | Andreas Färber | case 34: |
128 | 814ac26c | Andreas Färber | env->active_tc.HI[0] = tmp;
|
129 | 814ac26c | Andreas Färber | break;
|
130 | 814ac26c | Andreas Färber | case 35: |
131 | 814ac26c | Andreas Färber | env->CP0_BadVAddr = tmp; |
132 | 814ac26c | Andreas Färber | break;
|
133 | 814ac26c | Andreas Färber | case 36: |
134 | 814ac26c | Andreas Färber | env->CP0_Cause = tmp; |
135 | 814ac26c | Andreas Färber | break;
|
136 | 814ac26c | Andreas Färber | case 37: |
137 | 814ac26c | Andreas Färber | env->active_tc.PC = tmp & ~(target_ulong)1;
|
138 | 814ac26c | Andreas Färber | if (tmp & 1) { |
139 | 814ac26c | Andreas Färber | env->hflags |= MIPS_HFLAG_M16; |
140 | 814ac26c | Andreas Färber | } else {
|
141 | 814ac26c | Andreas Färber | env->hflags &= ~(MIPS_HFLAG_M16); |
142 | 814ac26c | Andreas Färber | } |
143 | 814ac26c | Andreas Färber | break;
|
144 | 814ac26c | Andreas Färber | case 72: /* fp, ignored */ |
145 | 814ac26c | Andreas Färber | break;
|
146 | 814ac26c | Andreas Färber | default:
|
147 | 814ac26c | Andreas Färber | if (n > 89) { |
148 | 814ac26c | Andreas Färber | return 0; |
149 | 814ac26c | Andreas Färber | } |
150 | 814ac26c | Andreas Färber | /* Other registers are readonly. Ignore writes. */
|
151 | 814ac26c | Andreas Färber | break;
|
152 | 814ac26c | Andreas Färber | } |
153 | 814ac26c | Andreas Färber | |
154 | 814ac26c | Andreas Färber | return sizeof(target_ulong); |
155 | 814ac26c | Andreas Färber | } |