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) { 22*1fe8ac35SSong Gao /* orig_a0 */ 23*1fe8ac35SSong Gao return gdb_get_regl(mem_buf, 0); 24ca61e750SXiaojuan Yang } else if (n == 33) { 25*1fe8ac35SSong Gao return gdb_get_regl(mem_buf, env->pc); 26*1fe8ac35SSong Gao } else if (n == 34) { 27fffca8f2SSong Gao return gdb_get_regl(mem_buf, env->CSR_BADV); 28ca61e750SXiaojuan Yang } 29ca61e750SXiaojuan Yang return 0; 30ca61e750SXiaojuan Yang } 31ca61e750SXiaojuan Yang 32ca61e750SXiaojuan Yang int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 33ca61e750SXiaojuan Yang { 34ca61e750SXiaojuan Yang LoongArchCPU *cpu = LOONGARCH_CPU(cs); 35ca61e750SXiaojuan Yang CPULoongArchState *env = &cpu->env; 36ca61e750SXiaojuan Yang target_ulong tmp = ldtul_p(mem_buf); 37ca61e750SXiaojuan Yang int length = 0; 38ca61e750SXiaojuan Yang 39ca61e750SXiaojuan Yang if (0 <= n && n < 32) { 40ca61e750SXiaojuan Yang env->gpr[n] = tmp; 41ca61e750SXiaojuan Yang length = sizeof(target_ulong); 42*1fe8ac35SSong Gao } else if (n == 33) { 43ca61e750SXiaojuan Yang env->pc = tmp; 44ca61e750SXiaojuan Yang length = sizeof(target_ulong); 45ca61e750SXiaojuan Yang } 46ca61e750SXiaojuan Yang return length; 47ca61e750SXiaojuan Yang } 48ca61e750SXiaojuan Yang 49ca61e750SXiaojuan Yang static int loongarch_gdb_get_fpu(CPULoongArchState *env, 50ca61e750SXiaojuan Yang GByteArray *mem_buf, int n) 51ca61e750SXiaojuan Yang { 52ca61e750SXiaojuan Yang if (0 <= n && n < 32) { 53ca61e750SXiaojuan Yang return gdb_get_reg64(mem_buf, env->fpr[n]); 54ca61e750SXiaojuan Yang } else if (32 <= n && n < 40) { 55ca61e750SXiaojuan Yang return gdb_get_reg8(mem_buf, env->cf[n - 32]); 56ca61e750SXiaojuan Yang } else if (n == 40) { 57ca61e750SXiaojuan Yang return gdb_get_reg32(mem_buf, env->fcsr0); 58ca61e750SXiaojuan Yang } 59ca61e750SXiaojuan Yang return 0; 60ca61e750SXiaojuan Yang } 61ca61e750SXiaojuan Yang 62ca61e750SXiaojuan Yang static int loongarch_gdb_set_fpu(CPULoongArchState *env, 63ca61e750SXiaojuan Yang uint8_t *mem_buf, int n) 64ca61e750SXiaojuan Yang { 65ca61e750SXiaojuan Yang int length = 0; 66ca61e750SXiaojuan Yang 67ca61e750SXiaojuan Yang if (0 <= n && n < 32) { 68ca61e750SXiaojuan Yang env->fpr[n] = ldq_p(mem_buf); 69ca61e750SXiaojuan Yang length = 8; 70ca61e750SXiaojuan Yang } else if (32 <= n && n < 40) { 71ca61e750SXiaojuan Yang env->cf[n - 32] = ldub_p(mem_buf); 72ca61e750SXiaojuan Yang length = 1; 73ca61e750SXiaojuan Yang } else if (n == 40) { 74ca61e750SXiaojuan Yang env->fcsr0 = ldl_p(mem_buf); 75ca61e750SXiaojuan Yang length = 4; 76ca61e750SXiaojuan Yang } 77ca61e750SXiaojuan Yang return length; 78ca61e750SXiaojuan Yang } 79ca61e750SXiaojuan Yang 80ca61e750SXiaojuan Yang void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) 81ca61e750SXiaojuan Yang { 82ca61e750SXiaojuan Yang gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, 83ca61e750SXiaojuan Yang 41, "loongarch-fpu64.xml", 0); 84ca61e750SXiaojuan Yang } 85