qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

gdbstub.c (2552B)


      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 
     14 uint64_t read_fcc(CPULoongArchState *env)
     15 {
     16     uint64_t ret = 0;
     17 
     18     for (int i = 0; i < 8; ++i) {
     19         ret |= (uint64_t)env->cf[i] << (i * 8);
     20     }
     21 
     22     return ret;
     23 }
     24 
     25 void write_fcc(CPULoongArchState *env, uint64_t val)
     26 {
     27     for (int i = 0; i < 8; ++i) {
     28         env->cf[i] = (val >> (i * 8)) & 1;
     29     }
     30 }
     31 
     32 int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
     33 {
     34     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
     35     CPULoongArchState *env = &cpu->env;
     36 
     37     if (0 <= n && n < 32) {
     38         return gdb_get_regl(mem_buf, env->gpr[n]);
     39     } else if (n == 32) {
     40         /* orig_a0 */
     41         return gdb_get_regl(mem_buf, 0);
     42     } else if (n == 33) {
     43         return gdb_get_regl(mem_buf, env->pc);
     44     } else if (n == 34) {
     45         return gdb_get_regl(mem_buf, env->CSR_BADV);
     46     }
     47     return 0;
     48 }
     49 
     50 int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
     51 {
     52     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
     53     CPULoongArchState *env = &cpu->env;
     54     target_ulong tmp = ldtul_p(mem_buf);
     55     int length = 0;
     56 
     57     if (0 <= n && n < 32) {
     58         env->gpr[n] = tmp;
     59         length = sizeof(target_ulong);
     60     } else if (n == 33) {
     61         env->pc = tmp;
     62         length = sizeof(target_ulong);
     63     }
     64     return length;
     65 }
     66 
     67 static int loongarch_gdb_get_fpu(CPULoongArchState *env,
     68                                  GByteArray *mem_buf, int n)
     69 {
     70     if (0 <= n && n < 32) {
     71         return gdb_get_reg64(mem_buf, env->fpr[n]);
     72     } else if (n == 32) {
     73         uint64_t val = read_fcc(env);
     74         return gdb_get_reg64(mem_buf, val);
     75     } else if (n == 33) {
     76         return gdb_get_reg32(mem_buf, env->fcsr0);
     77     }
     78     return 0;
     79 }
     80 
     81 static int loongarch_gdb_set_fpu(CPULoongArchState *env,
     82                                  uint8_t *mem_buf, int n)
     83 {
     84     int length = 0;
     85 
     86     if (0 <= n && n < 32) {
     87         env->fpr[n] = ldq_p(mem_buf);
     88         length = 8;
     89     } else if (n == 32) {
     90         uint64_t val = ldq_p(mem_buf);
     91         write_fcc(env, val);
     92         length = 8;
     93     } else if (n == 33) {
     94         env->fcsr0 = ldl_p(mem_buf);
     95         length = 4;
     96     }
     97     return length;
     98 }
     99 
    100 void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs)
    101 {
    102     gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu,
    103                              41, "loongarch-fpu.xml", 0);
    104 }