1 /* 2 * TriCore gdb server stub 3 * 4 * Copyright (c) 2019 Bastian Koppelmann, Paderborn University 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "qemu-common.h" 22 #include "exec/gdbstub.h" 23 24 25 #define LCX_REGNUM 32 26 #define FCX_REGNUM 33 27 #define PCXI_REGNUM 34 28 #define TRICORE_PSW_REGNUM 35 29 #define TRICORE_PC_REGNUM 36 30 #define ICR_REGNUM 37 31 #define ISP_REGNUM 38 32 #define BTV_REGNUM 39 33 #define BIV_REGNUM 40 34 #define SYSCON_REGNUM 41 35 #define PMUCON0_REGNUM 42 36 #define DMUCON_REGNUM 43 37 38 static uint32_t tricore_cpu_gdb_read_csfr(CPUTriCoreState *env, int n) 39 { 40 switch (n) { 41 case LCX_REGNUM: 42 return env->LCX; 43 case FCX_REGNUM: 44 return env->FCX; 45 case PCXI_REGNUM: 46 return env->PCXI; 47 case TRICORE_PSW_REGNUM: 48 return psw_read(env); 49 case TRICORE_PC_REGNUM: 50 return env->PC; 51 case ICR_REGNUM: 52 return env->ICR; 53 case ISP_REGNUM: 54 return env->ISP; 55 case BTV_REGNUM: 56 return env->BTV; 57 case BIV_REGNUM: 58 return env->BIV; 59 case SYSCON_REGNUM: 60 return env->SYSCON; 61 case PMUCON0_REGNUM: 62 return 0; /* PMUCON0 */ 63 case DMUCON_REGNUM: 64 return 0; /* DMUCON0 */ 65 default: 66 return 0; 67 } 68 } 69 70 static void tricore_cpu_gdb_write_csfr(CPUTriCoreState *env, int n, 71 uint32_t val) 72 { 73 switch (n) { 74 case LCX_REGNUM: 75 env->LCX = val; 76 break; 77 case FCX_REGNUM: 78 env->FCX = val; 79 break; 80 case PCXI_REGNUM: 81 env->PCXI = val; 82 break; 83 case TRICORE_PSW_REGNUM: 84 psw_write(env, val); 85 break; 86 case TRICORE_PC_REGNUM: 87 env->PC = val; 88 break; 89 case ICR_REGNUM: 90 env->ICR = val; 91 break; 92 case ISP_REGNUM: 93 env->ISP = val; 94 break; 95 case BTV_REGNUM: 96 env->BTV = val; 97 break; 98 case BIV_REGNUM: 99 env->BIV = val; 100 break; 101 case SYSCON_REGNUM: 102 env->SYSCON = val; 103 break; 104 } 105 } 106 107 108 int tricore_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 109 { 110 TriCoreCPU *cpu = TRICORE_CPU(cs); 111 CPUTriCoreState *env = &cpu->env; 112 113 if (n < 16) { /* data registers */ 114 return gdb_get_reg32(mem_buf, env->gpr_d[n]); 115 } else if (n < 32) { /* address registers */ 116 return gdb_get_reg32(mem_buf, env->gpr_a[n - 16]); 117 } else { /* csfr */ 118 return gdb_get_reg32(mem_buf, tricore_cpu_gdb_read_csfr(env, n)); 119 } 120 return 0; 121 } 122 123 int tricore_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 124 { 125 TriCoreCPU *cpu = TRICORE_CPU(cs); 126 CPUTriCoreState *env = &cpu->env; 127 uint32_t tmp; 128 129 tmp = ldl_p(mem_buf); 130 131 if (n < 16) { /* data registers */ 132 env->gpr_d[n] = tmp; 133 } else if (n < 32) { /* address registers */ 134 env->gpr_d[n - 16] = tmp; 135 } else { 136 tricore_cpu_gdb_write_csfr(env, n, tmp); 137 } 138 return 4; 139 } 140