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 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 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 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 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 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 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 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 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