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
);
38 if (0 <= n
&& n
<= 34) {
48 } else /* if (n == 34) */ {
53 return gdb_get_reg64(mem_buf
, val
);
55 return gdb_get_reg32(mem_buf
, val
);
62 int loongarch_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
64 CPULoongArchState
*env
= cpu_env(cs
);
70 tmp
= ldq_le_p(mem_buf
);
73 tmp
= ldl_le_p(mem_buf
);
77 if (0 <= n
&& n
< 32) {
87 static int loongarch_gdb_get_fpu(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
89 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
90 CPULoongArchState
*env
= &cpu
->env
;
92 if (0 <= n
&& n
< 32) {
93 return gdb_get_reg64(mem_buf
, env
->fpr
[n
].vreg
.D(0));
94 } else if (32 <= n
&& n
< 40) {
95 return gdb_get_reg8(mem_buf
, env
->cf
[n
- 32]);
97 return gdb_get_reg32(mem_buf
, env
->fcsr0
);
102 static int loongarch_gdb_set_fpu(CPUState
*cs
, uint8_t *mem_buf
, int n
)
104 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
105 CPULoongArchState
*env
= &cpu
->env
;
108 if (0 <= n
&& n
< 32) {
109 env
->fpr
[n
].vreg
.D(0) = ldq_le_p(mem_buf
);
111 } else if (32 <= n
&& n
< 40) {
112 env
->cf
[n
- 32] = ldub_p(mem_buf
);
114 } else if (n
== 40) {
115 env
->fcsr0
= ldl_le_p(mem_buf
);
124 static int loongarch_gdb_get_vec(CPUState
*cs
, GByteArray
*mem_buf
, int n
, int vl
)
126 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
127 CPULoongArchState
*env
= &cpu
->env
;
130 if (0 <= n
&& n
< VREG_NUM
) {
131 for (i
= 0; i
< vl
/ REG64_LEN
; i
++) {
132 length
+= gdb_get_reg64(mem_buf
, env
->fpr
[n
].vreg
.D(i
));
139 static int loongarch_gdb_set_vec(CPUState
*cs
, uint8_t *mem_buf
, int n
, int vl
)
141 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
142 CPULoongArchState
*env
= &cpu
->env
;
145 if (0 <= n
&& n
< VREG_NUM
) {
146 for (i
= 0; i
< vl
/ REG64_LEN
; i
++) {
147 env
->fpr
[n
].vreg
.D(i
) = ldq_le_p(mem_buf
+ 8 * i
);
155 static int loongarch_gdb_get_lsx(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
157 return loongarch_gdb_get_vec(cs
, mem_buf
, n
, LSX_LEN
);
160 static int loongarch_gdb_set_lsx(CPUState
*cs
, uint8_t *mem_buf
, int n
)
162 return loongarch_gdb_set_vec(cs
, mem_buf
, n
, LSX_LEN
);
165 static int loongarch_gdb_get_lasx(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
167 return loongarch_gdb_get_vec(cs
, mem_buf
, n
, LASX_LEN
);
170 static int loongarch_gdb_set_lasx(CPUState
*cs
, uint8_t *mem_buf
, int n
)
172 return loongarch_gdb_set_vec(cs
, mem_buf
, n
, LASX_LEN
);
175 void loongarch_cpu_register_gdb_regs_for_features(CPUState
*cs
)
177 LoongArchCPU
*cpu
= LOONGARCH_CPU(cs
);
178 CPULoongArchState
*env
= &cpu
->env
;
180 if (FIELD_EX32(env
->cpucfg
[2], CPUCFG2
, FP
)) {
181 gdb_register_coprocessor(cs
, loongarch_gdb_get_fpu
, loongarch_gdb_set_fpu
,
182 gdb_find_static_feature("loongarch-fpu.xml"), 0);
185 if (FIELD_EX32(env
->cpucfg
[2], CPUCFG2
, LSX
)) {
186 gdb_register_coprocessor(cs
, loongarch_gdb_get_lsx
, loongarch_gdb_set_lsx
,
187 gdb_find_static_feature("loongarch-lsx.xml"), 0);
190 if (FIELD_EX32(env
->cpucfg
[2], CPUCFG2
, LASX
)) {
191 gdb_register_coprocessor(cs
, loongarch_gdb_get_lasx
, loongarch_gdb_set_lasx
,
192 gdb_find_static_feature("loongarch-lasx.xml"), 0);