1ca61e750SXiaojuan Yang /* 2ca61e750SXiaojuan Yang * LOONGARCH gdb server stub 3ca61e750SXiaojuan Yang * 4ca61e750SXiaojuan Yang * Copyright (c) 2021 Loongson Technology Corporation Limited 5ca61e750SXiaojuan Yang * 6ca61e750SXiaojuan Yang * SPDX-License-Identifier: LGPL-2.1+ 7ca61e750SXiaojuan Yang */ 8ca61e750SXiaojuan Yang 9ca61e750SXiaojuan Yang #include "qemu/osdep.h" 10ca61e750SXiaojuan Yang #include "cpu.h" 11ca61e750SXiaojuan Yang #include "internals.h" 12ca61e750SXiaojuan Yang #include "exec/gdbstub.h" 13ca61e750SXiaojuan Yang 14ca61e750SXiaojuan Yang int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 15ca61e750SXiaojuan Yang { 16ca61e750SXiaojuan Yang LoongArchCPU *cpu = LOONGARCH_CPU(cs); 17ca61e750SXiaojuan Yang CPULoongArchState *env = &cpu->env; 18ca61e750SXiaojuan Yang 19ca61e750SXiaojuan Yang if (0 <= n && n < 32) { 20ca61e750SXiaojuan Yang return gdb_get_regl(mem_buf, env->gpr[n]); 21ca61e750SXiaojuan Yang } else if (n == 32) { 22ca61e750SXiaojuan Yang return gdb_get_regl(mem_buf, env->pc); 23ca61e750SXiaojuan Yang } else if (n == 33) { 24*fffca8f2SSong Gao return gdb_get_regl(mem_buf, env->CSR_BADV); 25ca61e750SXiaojuan Yang } 26ca61e750SXiaojuan Yang return 0; 27ca61e750SXiaojuan Yang } 28ca61e750SXiaojuan Yang 29ca61e750SXiaojuan Yang int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 30ca61e750SXiaojuan Yang { 31ca61e750SXiaojuan Yang LoongArchCPU *cpu = LOONGARCH_CPU(cs); 32ca61e750SXiaojuan Yang CPULoongArchState *env = &cpu->env; 33ca61e750SXiaojuan Yang target_ulong tmp = ldtul_p(mem_buf); 34ca61e750SXiaojuan Yang int length = 0; 35ca61e750SXiaojuan Yang 36ca61e750SXiaojuan Yang if (0 <= n && n < 32) { 37ca61e750SXiaojuan Yang env->gpr[n] = tmp; 38ca61e750SXiaojuan Yang length = sizeof(target_ulong); 39ca61e750SXiaojuan Yang } else if (n == 32) { 40ca61e750SXiaojuan Yang env->pc = tmp; 41ca61e750SXiaojuan Yang length = sizeof(target_ulong); 42ca61e750SXiaojuan Yang } 43ca61e750SXiaojuan Yang return length; 44ca61e750SXiaojuan Yang } 45ca61e750SXiaojuan Yang 46ca61e750SXiaojuan Yang static int loongarch_gdb_get_fpu(CPULoongArchState *env, 47ca61e750SXiaojuan Yang GByteArray *mem_buf, int n) 48ca61e750SXiaojuan Yang { 49ca61e750SXiaojuan Yang if (0 <= n && n < 32) { 50ca61e750SXiaojuan Yang return gdb_get_reg64(mem_buf, env->fpr[n]); 51ca61e750SXiaojuan Yang } else if (32 <= n && n < 40) { 52ca61e750SXiaojuan Yang return gdb_get_reg8(mem_buf, env->cf[n - 32]); 53ca61e750SXiaojuan Yang } else if (n == 40) { 54ca61e750SXiaojuan Yang return gdb_get_reg32(mem_buf, env->fcsr0); 55ca61e750SXiaojuan Yang } 56ca61e750SXiaojuan Yang return 0; 57ca61e750SXiaojuan Yang } 58ca61e750SXiaojuan Yang 59ca61e750SXiaojuan Yang static int loongarch_gdb_set_fpu(CPULoongArchState *env, 60ca61e750SXiaojuan Yang uint8_t *mem_buf, int n) 61ca61e750SXiaojuan Yang { 62ca61e750SXiaojuan Yang int length = 0; 63ca61e750SXiaojuan Yang 64ca61e750SXiaojuan Yang if (0 <= n && n < 32) { 65ca61e750SXiaojuan Yang env->fpr[n] = ldq_p(mem_buf); 66ca61e750SXiaojuan Yang length = 8; 67ca61e750SXiaojuan Yang } else if (32 <= n && n < 40) { 68ca61e750SXiaojuan Yang env->cf[n - 32] = ldub_p(mem_buf); 69ca61e750SXiaojuan Yang length = 1; 70ca61e750SXiaojuan Yang } else if (n == 40) { 71ca61e750SXiaojuan Yang env->fcsr0 = ldl_p(mem_buf); 72ca61e750SXiaojuan Yang length = 4; 73ca61e750SXiaojuan Yang } 74ca61e750SXiaojuan Yang return length; 75ca61e750SXiaojuan Yang } 76ca61e750SXiaojuan Yang 77ca61e750SXiaojuan Yang void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) 78ca61e750SXiaojuan Yang { 79ca61e750SXiaojuan Yang gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, 80ca61e750SXiaojuan Yang 41, "loongarch-fpu64.xml", 0); 81ca61e750SXiaojuan Yang } 82