2 * LOONGARCH gdb server stub
4 * Copyright (c) 2021 Loongson Technology Corporation Limited
6 * SPDX-License-Identifier: LGPL-2.1+
9 #include "qemu/osdep.h"
11 #include "internals.h"
12 #include "exec/gdbstub.h"
13 #include "gdbstub/helpers.h"
16 uint64_t read_fcc(CPULoongArchState
*env
)
20 for (int i
= 0; i
< 8; ++i
) {
21 ret
|= (uint64_t)env
->cf
[i
] << (i
* 8);
27 void write_fcc(CPULoongArchState
*env
, uint64_t val
)
29 for (int i
= 0; i
< 8; ++i
) {
30 env
->cf
[i
] = (val
>> (i
* 8)) & 1;
34 int loongarch_cpu_gdb_read_register(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
36 CPULoongArchState
*env
= cpu_env(cs
);
39 if (0 <= n
&& n
< 32) {
50 if (0 <= n
&& n
<= 34) {
52 return gdb_get_reg64(mem_buf
, val
);
54 return gdb_get_reg32(mem_buf
, val
);
60 int loongarch_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
62 CPULoongArchState
*env
= cpu_env(cs
);
75 if (0 <= n
&& n
< 32) {
85 static int loongarch_gdb_get_fpu(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
87 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
88 CPULoongArchState
*env
= &cpu
->env
;
90 if (0 <= n
&& n
< 32) {
91 return gdb_get_reg64(mem_buf
, env
->fpr
[n
].vreg
.D(0));
92 } else if (32 <= n
&& n
< 40) {
93 return gdb_get_reg8(mem_buf
, env
->cf
[n
- 32]);
95 return gdb_get_reg32(mem_buf
, env
->fcsr0
);
100 static int loongarch_gdb_set_fpu(CPUState
*cs
, uint8_t *mem_buf
, int n
)
102 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
103 CPULoongArchState
*env
= &cpu
->env
;
106 if (0 <= n
&& n
< 32) {
107 env
->fpr
[n
].vreg
.D(0) = ldq_p(mem_buf
);
109 } else if (32 <= n
&& n
< 40) {
110 env
->cf
[n
- 32] = ldub_p(mem_buf
);
112 } else if (n
== 40) {
113 env
->fcsr0
= ldl_p(mem_buf
);
122 static int loongarch_gdb_get_vec(CPUState
*cs
, GByteArray
*mem_buf
, int n
, int vl
)
124 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
125 CPULoongArchState
*env
= &cpu
->env
;
128 if (0 <= n
&& n
< VREG_NUM
) {
129 for (i
= 0; i
< vl
/ REG64_LEN
; i
++) {
130 length
+= gdb_get_reg64(mem_buf
, env
->fpr
[n
].vreg
.D(i
));
137 static int loongarch_gdb_set_vec(CPUState
*cs
, uint8_t *mem_buf
, int n
, int vl
)
139 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
140 CPULoongArchState
*env
= &cpu
->env
;
143 if (0 <= n
&& n
< VREG_NUM
) {
144 for (i
= 0; i
< vl
/ REG64_LEN
; i
++) {
145 env
->fpr
[n
].vreg
.D(i
) = ldq_le_p(mem_buf
+ 8 * i
);
153 static int loongarch_gdb_get_lsx(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
155 return loongarch_gdb_get_vec(cs
, mem_buf
, n
, LSX_LEN
);
158 static int loongarch_gdb_set_lsx(CPUState
*cs
, uint8_t *mem_buf
, int n
)
160 return loongarch_gdb_set_vec(cs
, mem_buf
, n
, LSX_LEN
);
163 static int loongarch_gdb_get_lasx(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
165 return loongarch_gdb_get_vec(cs
, mem_buf
, n
, LASX_LEN
);
168 static int loongarch_gdb_set_lasx(CPUState
*cs
, uint8_t *mem_buf
, int n
)
170 return loongarch_gdb_set_vec(cs
, mem_buf
, n
, LASX_LEN
);
173 void loongarch_cpu_register_gdb_regs_for_features(CPUState
*cs
)
175 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
176 CPULoongArchState
*env
= &cpu
->env
;
178 if (FIELD_EX32(env
->cpucfg
[2], CPUCFG2
, FP
)) {
179 gdb_register_coprocessor(cs
, loongarch_gdb_get_fpu
, loongarch_gdb_set_fpu
,
180 gdb_find_static_feature("loongarch-fpu.xml"), 0);
183 if (FIELD_EX32(env
->cpucfg
[2], CPUCFG2
, LSX
)) {
184 gdb_register_coprocessor(cs
, loongarch_gdb_get_lsx
, loongarch_gdb_set_lsx
,
185 gdb_find_static_feature("loongarch-lsx.xml"), 0);
188 if (FIELD_EX32(env
->cpucfg
[2], CPUCFG2
, LASX
)) {
189 gdb_register_coprocessor(cs
, loongarch_gdb_get_lasx
, loongarch_gdb_set_lasx
,
190 gdb_find_static_feature("loongarch-lasx.xml"), 0);