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