1 /*
2 * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "qemu/osdep.h"
19 #include "gdbstub/helpers.h"
20 #include "cpu.h"
21 #include "internal.h"
22
hexagon_gdb_read_register(CPUState * cs,GByteArray * mem_buf,int n)23 int hexagon_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
24 {
25 CPUHexagonState *env = cpu_env(cs);
26
27 if (n == HEX_REG_P3_0_ALIASED) {
28 uint32_t p3_0 = 0;
29 for (int i = 0; i < NUM_PREGS; i++) {
30 p3_0 = deposit32(p3_0, i * 8, 8, env->pred[i]);
31 }
32 return gdb_get_regl(mem_buf, p3_0);
33 }
34
35 if (n < TOTAL_PER_THREAD_REGS) {
36 return gdb_get_regl(mem_buf, env->gpr[n]);
37 }
38
39 n -= TOTAL_PER_THREAD_REGS;
40
41 if (n < NUM_PREGS) {
42 return gdb_get_reg8(mem_buf, env->pred[n]);
43 }
44
45 n -= NUM_PREGS;
46
47 g_assert_not_reached();
48 }
49
hexagon_gdb_write_register(CPUState * cs,uint8_t * mem_buf,int n)50 int hexagon_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
51 {
52 CPUHexagonState *env = cpu_env(cs);
53
54 if (n == HEX_REG_P3_0_ALIASED) {
55 uint32_t p3_0 = ldl_le_p(mem_buf);
56 for (int i = 0; i < NUM_PREGS; i++) {
57 env->pred[i] = extract32(p3_0, i * 8, 8);
58 }
59 return sizeof(target_ulong);
60 }
61
62 if (n < TOTAL_PER_THREAD_REGS) {
63 env->gpr[n] = ldl_le_p(mem_buf);
64 return sizeof(target_ulong);
65 }
66
67 n -= TOTAL_PER_THREAD_REGS;
68
69 if (n < NUM_PREGS) {
70 env->pred[n] = ldl_le_p(mem_buf) & 0xff;
71 return sizeof(uint8_t);
72 }
73
74 n -= NUM_PREGS;
75
76 g_assert_not_reached();
77 }
78
gdb_get_vreg(CPUHexagonState * env,GByteArray * mem_buf,int n)79 static int gdb_get_vreg(CPUHexagonState *env, GByteArray *mem_buf, int n)
80 {
81 int total = 0;
82 int i;
83 for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) {
84 total += gdb_get_regl(mem_buf, env->VRegs[n].uw[i]);
85 }
86 return total;
87 }
88
gdb_get_qreg(CPUHexagonState * env,GByteArray * mem_buf,int n)89 static int gdb_get_qreg(CPUHexagonState *env, GByteArray *mem_buf, int n)
90 {
91 int total = 0;
92 int i;
93 for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) {
94 total += gdb_get_regl(mem_buf, env->QRegs[n].uw[i]);
95 }
96 return total;
97 }
98
hexagon_hvx_gdb_read_register(CPUState * cs,GByteArray * mem_buf,int n)99 int hexagon_hvx_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
100 {
101 HexagonCPU *cpu = HEXAGON_CPU(cs);
102 CPUHexagonState *env = &cpu->env;
103
104 if (n < NUM_VREGS) {
105 return gdb_get_vreg(env, mem_buf, n);
106 }
107 n -= NUM_VREGS;
108
109 if (n < NUM_QREGS) {
110 return gdb_get_qreg(env, mem_buf, n);
111 }
112
113 g_assert_not_reached();
114 }
115
gdb_put_vreg(CPUHexagonState * env,uint8_t * mem_buf,int n)116 static int gdb_put_vreg(CPUHexagonState *env, uint8_t *mem_buf, int n)
117 {
118 int i;
119 for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) {
120 env->VRegs[n].uw[i] = ldl_le_p(mem_buf);
121 mem_buf += 4;
122 }
123 return MAX_VEC_SIZE_BYTES;
124 }
125
gdb_put_qreg(CPUHexagonState * env,uint8_t * mem_buf,int n)126 static int gdb_put_qreg(CPUHexagonState *env, uint8_t *mem_buf, int n)
127 {
128 int i;
129 for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) {
130 env->QRegs[n].uw[i] = ldl_le_p(mem_buf);
131 mem_buf += 4;
132 }
133 return MAX_VEC_SIZE_BYTES / 8;
134 }
135
hexagon_hvx_gdb_write_register(CPUState * cs,uint8_t * mem_buf,int n)136 int hexagon_hvx_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
137 {
138 HexagonCPU *cpu = HEXAGON_CPU(cs);
139 CPUHexagonState *env = &cpu->env;
140
141 if (n < NUM_VREGS) {
142 return gdb_put_vreg(env, mem_buf, n);
143 }
144 n -= NUM_VREGS;
145
146 if (n < NUM_QREGS) {
147 return gdb_put_qreg(env, mem_buf, n);
148 }
149
150 g_assert_not_reached();
151 }
152