1 /* 2 * Copyright(c) 2019-2021 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 g_assert_not_reached(); 40 } 41 42 int hexagon_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 43 { 44 CPUHexagonState *env = cpu_env(cs); 45 46 if (n == HEX_REG_P3_0_ALIASED) { 47 uint32_t p3_0 = ldtul_p(mem_buf); 48 for (int i = 0; i < NUM_PREGS; i++) { 49 env->pred[i] = extract32(p3_0, i * 8, 8); 50 } 51 return sizeof(target_ulong); 52 } 53 54 if (n < TOTAL_PER_THREAD_REGS) { 55 env->gpr[n] = ldtul_p(mem_buf); 56 return sizeof(target_ulong); 57 } 58 59 g_assert_not_reached(); 60 } 61 62 static int gdb_get_vreg(CPUHexagonState *env, GByteArray *mem_buf, int n) 63 { 64 int total = 0; 65 int i; 66 for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) { 67 total += gdb_get_regl(mem_buf, env->VRegs[n].uw[i]); 68 } 69 return total; 70 } 71 72 static int gdb_get_qreg(CPUHexagonState *env, GByteArray *mem_buf, int n) 73 { 74 int total = 0; 75 int i; 76 for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) { 77 total += gdb_get_regl(mem_buf, env->QRegs[n].uw[i]); 78 } 79 return total; 80 } 81 82 int hexagon_hvx_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 83 { 84 HexagonCPU *cpu = HEXAGON_CPU(cs); 85 CPUHexagonState *env = &cpu->env; 86 87 if (n < NUM_VREGS) { 88 return gdb_get_vreg(env, mem_buf, n); 89 } 90 n -= NUM_VREGS; 91 92 if (n < NUM_QREGS) { 93 return gdb_get_qreg(env, mem_buf, n); 94 } 95 96 g_assert_not_reached(); 97 } 98 99 static int gdb_put_vreg(CPUHexagonState *env, uint8_t *mem_buf, int n) 100 { 101 int i; 102 for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) { 103 env->VRegs[n].uw[i] = ldtul_p(mem_buf); 104 mem_buf += 4; 105 } 106 return MAX_VEC_SIZE_BYTES; 107 } 108 109 static int gdb_put_qreg(CPUHexagonState *env, uint8_t *mem_buf, int n) 110 { 111 int i; 112 for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) { 113 env->QRegs[n].uw[i] = ldtul_p(mem_buf); 114 mem_buf += 4; 115 } 116 return MAX_VEC_SIZE_BYTES / 8; 117 } 118 119 int hexagon_hvx_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 120 { 121 HexagonCPU *cpu = HEXAGON_CPU(cs); 122 CPUHexagonState *env = &cpu->env; 123 124 if (n < NUM_VREGS) { 125 return gdb_put_vreg(env, mem_buf, n); 126 } 127 n -= NUM_VREGS; 128 129 if (n < NUM_QREGS) { 130 return gdb_put_qreg(env, mem_buf, n); 131 } 132 133 g_assert_not_reached(); 134 } 135