0076-target-riscv-gdb-support-vector-registers-for-rv64-r.patch 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. From 2b5684000804bcda8519d35e51e015d436ac9c02 Mon Sep 17 00:00:00 2001
  2. From: Hsiangkai Wang <kai.wang@sifive.com>
  3. Date: Tue, 12 Jan 2021 16:44:49 +0800
  4. Subject: [PATCH 076/107] target/riscv: gdb: support vector registers for rv64
  5. & rv32
  6. Signed-off-by: Hsiangkai Wang <kai.wang@sifive.com>
  7. Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
  8. Signed-off-by: Frank Chang <frank.chang@sifive.com>
  9. ---
  10. target/riscv/cpu.c | 2 +
  11. target/riscv/cpu.h | 1 +
  12. target/riscv/gdbstub.c | 184 +++++++++++++++++++++++++++++++++++++++++
  13. 3 files changed, 187 insertions(+)
  14. diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
  15. index 4a29175e20..f6d79c5aa9 100644
  16. --- a/target/riscv/cpu.c
  17. +++ b/target/riscv/cpu.c
  18. @@ -577,6 +577,8 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
  19. if (strcmp(xmlname, "riscv-csr.xml") == 0) {
  20. return cpu->dyn_csr_xml;
  21. + } else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
  22. + return cpu->dyn_vreg_xml;
  23. }
  24. return NULL;
  25. diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
  26. index d613520211..e223ab550b 100644
  27. --- a/target/riscv/cpu.h
  28. +++ b/target/riscv/cpu.h
  29. @@ -279,6 +279,7 @@ struct RISCVCPU {
  30. CPURISCVState env;
  31. char *dyn_csr_xml;
  32. + char *dyn_vreg_xml;
  33. /* Configuration Settings */
  34. struct {
  35. diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
  36. index 5f96b7ea2a..dd883612c7 100644
  37. --- a/target/riscv/gdbstub.c
  38. +++ b/target/riscv/gdbstub.c
  39. @@ -20,6 +20,32 @@
  40. #include "exec/gdbstub.h"
  41. #include "cpu.h"
  42. +struct TypeSize {
  43. + const char *gdb_type;
  44. + const char *id;
  45. + int size;
  46. + const char suffix;
  47. +};
  48. +
  49. +static const struct TypeSize vec_lanes[] = {
  50. + /* quads */
  51. + { "uint128", "quads", 128, 'q' },
  52. + /* 64 bit */
  53. + { "uint64", "longs", 64, 'l' },
  54. + /* 32 bit */
  55. + { "uint32", "words", 32, 'w' },
  56. + /* 16 bit */
  57. + { "uint16", "shorts", 16, 's' },
  58. + /*
  59. + * TODO: currently there is no reliable way of telling
  60. + * if the remote gdb actually understands ieee_half so
  61. + * we don't expose it in the target description for now.
  62. + * { "ieee_half", 16, 'h', 'f' },
  63. + */
  64. + /* bytes */
  65. + { "uint8", "bytes", 8, 'b' },
  66. +};
  67. +
  68. int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
  69. {
  70. RISCVCPU *cpu = RISCV_CPU(cs);
  71. @@ -101,6 +127,96 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
  72. return 0;
  73. }
  74. +/*
  75. + * Convert register index number passed by GDB to the correspond
  76. + * vector CSR number. Vector CSRs are defined after vector registers
  77. + * in dynamic generated riscv-vector.xml, thus the starting register index
  78. + * of vector CSRs is 32.
  79. + * Return 0 if register index number is out of range.
  80. + */
  81. +static int riscv_gdb_vector_csrno(int num_regs)
  82. +{
  83. + /*
  84. + * The order of vector CSRs in the switch case
  85. + * should match with the order defined in csr_ops[].
  86. + */
  87. + switch (num_regs) {
  88. + case 32:
  89. + return CSR_VSTART;
  90. + case 33:
  91. + return CSR_VXSAT;
  92. + case 34:
  93. + return CSR_VXRM;
  94. + case 35:
  95. + return CSR_VCSR;
  96. + case 36:
  97. + return CSR_VL;
  98. + case 37:
  99. + return CSR_VTYPE;
  100. + case 38:
  101. + return CSR_VLENB;
  102. + default:
  103. + /* Unknown register. */
  104. + return 0;
  105. + }
  106. +}
  107. +
  108. +static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
  109. +{
  110. + uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
  111. + if (n < 32) {
  112. + int i;
  113. + int cnt = 0;
  114. + for (i = 0; i < vlenb; i += 8) {
  115. + cnt += gdb_get_reg64(buf,
  116. + env->vreg[(n * vlenb + i) / 8]);
  117. + }
  118. + return cnt;
  119. + }
  120. +
  121. + int csrno = riscv_gdb_vector_csrno(n);
  122. +
  123. + if (!csrno) {
  124. + return 0;
  125. + }
  126. +
  127. + target_ulong val = 0;
  128. + int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
  129. +
  130. + if (result == 0) {
  131. + return gdb_get_regl(buf, val);
  132. + }
  133. +
  134. + return 0;
  135. +}
  136. +
  137. +static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
  138. +{
  139. + uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
  140. + if (n < 32) {
  141. + int i;
  142. + for (i = 0; i < vlenb; i += 8) {
  143. + env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
  144. + }
  145. + return vlenb;
  146. + }
  147. +
  148. + int csrno = riscv_gdb_vector_csrno(n);
  149. +
  150. + if (!csrno) {
  151. + return 0;
  152. + }
  153. +
  154. + target_ulong val = ldtul_p(mem_buf);
  155. + int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
  156. +
  157. + if (result == 0) {
  158. + return sizeof(target_ulong);
  159. + }
  160. +
  161. + return 0;
  162. +}
  163. +
  164. static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
  165. {
  166. if (n < CSR_TABLE_SIZE) {
  167. @@ -187,6 +303,68 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
  168. return CSR_TABLE_SIZE;
  169. }
  170. +static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
  171. +{
  172. + RISCVCPU *cpu = RISCV_CPU(cs);
  173. + GString *s = g_string_new(NULL);
  174. + g_autoptr(GString) ts = g_string_new("");
  175. + int reg_width = cpu->cfg.vlen;
  176. + int num_regs = 0;
  177. + int i;
  178. +
  179. + g_string_printf(s, "<?xml version=\"1.0\"?>");
  180. + g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
  181. + g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.vector\">");
  182. +
  183. + /* First define types and totals in a whole VL */
  184. + for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
  185. + int count = reg_width / vec_lanes[i].size;
  186. + g_string_printf(ts, "%s", vec_lanes[i].id);
  187. + g_string_append_printf(s,
  188. + "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
  189. + ts->str, vec_lanes[i].gdb_type, count);
  190. + }
  191. +
  192. + /* Define unions */
  193. + g_string_append_printf(s, "<union id=\"riscv_vector\">");
  194. + for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
  195. + g_string_append_printf(s, "<field name=\"%c\" type=\"%s\"/>",
  196. + vec_lanes[i].suffix,
  197. + vec_lanes[i].id);
  198. + }
  199. + g_string_append(s, "</union>");
  200. +
  201. + /* Define vector registers */
  202. + for (i = 0; i < 32; i++) {
  203. + g_string_append_printf(s,
  204. + "<reg name=\"v%d\" bitsize=\"%d\""
  205. + " regnum=\"%d\" group=\"vector\""
  206. + " type=\"riscv_vector\"/>",
  207. + i, reg_width, base_reg++);
  208. + num_regs++;
  209. + }
  210. +
  211. + /* Define vector CSRs */
  212. + const char *vector_csrs[7] = {
  213. + "vstart", "vxsat", "vxrm", "vcsr",
  214. + "vl", "vtype", "vlenb"
  215. + };
  216. +
  217. + for (i = 0; i < 7; i++) {
  218. + g_string_append_printf(s,
  219. + "<reg name=\"%s\" bitsize=\"%d\""
  220. + " regnum=\"%d\" group=\"vector\""
  221. + " type=\"int\"/>",
  222. + vector_csrs[i], TARGET_LONG_BITS, base_reg++);
  223. + num_regs++;
  224. + }
  225. +
  226. + g_string_append_printf(s, "</feature>");
  227. +
  228. + cpu->dyn_vreg_xml = g_string_free(s, false);
  229. + return num_regs;
  230. +}
  231. +
  232. void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
  233. {
  234. RISCVCPU *cpu = RISCV_CPU(cs);
  235. @@ -198,6 +376,12 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
  236. gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
  237. 36, "riscv-32bit-fpu.xml", 0);
  238. }
  239. + if (env->misa & RVV) {
  240. + gdb_register_coprocessor(cs, riscv_gdb_get_vector, riscv_gdb_set_vector,
  241. + ricsv_gen_dynamic_vector_xml(cs,
  242. + cs->gdb_num_regs),
  243. + "riscv-vector.xml", 0);
  244. + }
  245. #if defined(TARGET_RISCV32)
  246. gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
  247. 1, "riscv-32bit-virtual.xml", 0);
  248. --
  249. 2.33.1