1 /* 2 * LOONGARCH gdb server stub 3 * 4 * Copyright (c) 2021 Loongson Technology Corporation Limited 5 * 6 * SPDX-License-Identifier: LGPL-2.1+ 7 */ 8 9 #include "qemu/osdep.h" 10 #include "cpu.h" 11 #include "internals.h" 12 #include "exec/gdbstub.h" 13 #include "gdbstub/helpers.h" 14 15 uint64_t read_fcc(CPULoongArchState *env) 16 { 17 uint64_t ret = 0; 18 19 for (int i = 0; i < 8; ++i) { 20 ret |= (uint64_t)env->cf[i] << (i * 8); 21 } 22 23 return ret; 24 } 25 26 void write_fcc(CPULoongArchState *env, uint64_t val) 27 { 28 for (int i = 0; i < 8; ++i) { 29 env->cf[i] = (val >> (i * 8)) & 1; 30 } 31 } 32 33 int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 34 { 35 LoongArchCPU *cpu = LOONGARCH_CPU(cs); 36 CPULoongArchState *env = &cpu->env; 37 38 if (0 <= n && n < 32) { 39 return gdb_get_regl(mem_buf, env->gpr[n]); 40 } else if (n == 32) { 41 /* orig_a0 */ 42 return gdb_get_regl(mem_buf, 0); 43 } else if (n == 33) { 44 return gdb_get_regl(mem_buf, env->pc); 45 } else if (n == 34) { 46 return gdb_get_regl(mem_buf, env->CSR_BADV); 47 } 48 return 0; 49 } 50 51 int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 52 { 53 LoongArchCPU *cpu = LOONGARCH_CPU(cs); 54 CPULoongArchState *env = &cpu->env; 55 target_ulong tmp = ldtul_p(mem_buf); 56 int length = 0; 57 58 if (0 <= n && n < 32) { 59 env->gpr[n] = tmp; 60 length = sizeof(target_ulong); 61 } else if (n == 33) { 62 env->pc = tmp; 63 length = sizeof(target_ulong); 64 } 65 return length; 66 } 67 68 static int loongarch_gdb_get_fpu(CPULoongArchState *env, 69 GByteArray *mem_buf, int n) 70 { 71 if (0 <= n && n < 32) { 72 return gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(0)); 73 } else if (n == 32) { 74 uint64_t val = read_fcc(env); 75 return gdb_get_reg64(mem_buf, val); 76 } else if (n == 33) { 77 return gdb_get_reg32(mem_buf, env->fcsr0); 78 } 79 return 0; 80 } 81 82 static int loongarch_gdb_set_fpu(CPULoongArchState *env, 83 uint8_t *mem_buf, int n) 84 { 85 int length = 0; 86 87 if (0 <= n && n < 32) { 88 env->fpr[n].vreg.D(0) = ldq_p(mem_buf); 89 length = 8; 90 } else if (n == 32) { 91 uint64_t val = ldq_p(mem_buf); 92 write_fcc(env, val); 93 length = 8; 94 } else if (n == 33) { 95 env->fcsr0 = ldl_p(mem_buf); 96 length = 4; 97 } 98 return length; 99 } 100 101 void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) 102 { 103 gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, 104 41, "loongarch-fpu.xml", 0); 105 } 106