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