qemu/target/loongarch/gdbstub.c
<<
>>
Prefs
   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
  14uint64_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
  25void 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
  32int 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
  50int 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
  67static 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
  81static 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
 100void 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}
 105