1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "qemu-common.h"
22#include "cpu.h"
23#include "exec/gdbstub.h"
24#include "qemu/log.h"
25
26int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
27{
28 XtensaCPU *cpu = XTENSA_CPU(cs);
29 CPUXtensaState *env = &cpu->env;
30 const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
31#ifdef CONFIG_USER_ONLY
32 int num_regs = env->config->gdb_regmap.num_core_regs;
33#else
34 int num_regs = env->config->gdb_regmap.num_regs;
35#endif
36 unsigned i;
37
38 if (n < 0 || n >= num_regs) {
39 return 0;
40 }
41
42 switch (reg->type) {
43 case 9:
44 return gdb_get_reg32(mem_buf, env->pc);
45
46 case 1:
47 xtensa_sync_phys_from_window(env);
48 return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff)
49 % env->config->nareg]);
50
51 case 2:
52 return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]);
53
54 case 3:
55 return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]);
56
57 case 4:
58 i = reg->targno & 0x0f;
59 switch (reg->size) {
60 case 4:
61 return gdb_get_reg32(mem_buf,
62 float32_val(env->fregs[i].f32[FP_F32_LOW]));
63 case 8:
64 return gdb_get_reg64(mem_buf, float64_val(env->fregs[i].f64));
65 default:
66 qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported size %d\n",
67 __func__, n, reg->size);
68 memset(mem_buf, 0, reg->size);
69 return reg->size;
70 }
71
72 case 8:
73 return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);
74
75 default:
76 qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported type %d\n",
77 __func__, n, reg->type);
78 memset(mem_buf, 0, reg->size);
79 return reg->size;
80 }
81}
82
83int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
84{
85 XtensaCPU *cpu = XTENSA_CPU(cs);
86 CPUXtensaState *env = &cpu->env;
87 uint32_t tmp;
88 const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
89#ifdef CONFIG_USER_ONLY
90 int num_regs = env->config->gdb_regmap.num_core_regs;
91#else
92 int num_regs = env->config->gdb_regmap.num_regs;
93#endif
94
95 if (n < 0 || n >= num_regs) {
96 return 0;
97 }
98
99 tmp = ldl_p(mem_buf);
100
101 switch (reg->type) {
102 case 9:
103 env->pc = tmp;
104 break;
105
106 case 1:
107 env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
108 xtensa_sync_window_from_phys(env);
109 break;
110
111 case 2:
112 env->sregs[reg->targno & 0xff] = tmp;
113 break;
114
115 case 3:
116 env->uregs[reg->targno & 0xff] = tmp;
117 break;
118
119 case 4:
120 switch (reg->size) {
121 case 4:
122 env->fregs[reg->targno & 0x0f].f32[FP_F32_LOW] = make_float32(tmp);
123 return 4;
124 case 8:
125 env->fregs[reg->targno & 0x0f].f64 = make_float64(tmp);
126 return 8;
127 default:
128 qemu_log_mask(LOG_UNIMP, "%s to reg %d of unsupported size %d\n",
129 __func__, n, reg->size);
130 return reg->size;
131 }
132
133 case 8:
134 env->regs[reg->targno & 0x0f] = tmp;
135 break;
136
137 default:
138 qemu_log_mask(LOG_UNIMP, "%s to reg %d of unsupported type %d\n",
139 __func__, n, reg->type);
140 return reg->size;
141 }
142
143 return 4;
144}
145