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.1 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 "gdbstub/helpers.h" 22 23 24 #define LCX_REGNUM 32 25 #define FCX_REGNUM 33 26 #define PCXI_REGNUM 34 27 #define TRICORE_PSW_REGNUM 35 28 #define TRICORE_PC_REGNUM 36 29 #define ICR_REGNUM 37 30 #define ISP_REGNUM 38 31 #define BTV_REGNUM 39 32 #define BIV_REGNUM 40 33 #define SYSCON_REGNUM 41 34 #define PMUCON0_REGNUM 42 35 #define DMUCON_REGNUM 43 36 37 static uint32_t tricore_cpu_gdb_read_csfr(CPUTriCoreState *env, int n) 38 { 39 switch (n) { 40 case LCX_REGNUM: 41 return env->LCX; 42 case FCX_REGNUM: 43 return env->FCX; 44 case PCXI_REGNUM: 45 return env->PCXI; 46 case TRICORE_PSW_REGNUM: 47 return psw_read(env); 48 case TRICORE_PC_REGNUM: 49 return env->PC; 50 case ICR_REGNUM: 51 return env->ICR; 52 case ISP_REGNUM: 53 return env->ISP; 54 case BTV_REGNUM: 55 return env->BTV; 56 case BIV_REGNUM: 57 return env->BIV; 58 case SYSCON_REGNUM: 59 return env->SYSCON; 60 case PMUCON0_REGNUM: 61 return 0; /* PMUCON0 */ 62 case DMUCON_REGNUM: 63 return 0; /* DMUCON0 */ 64 default: 65 return 0; 66 } 67 } 68 69 static void tricore_cpu_gdb_write_csfr(CPUTriCoreState *env, int n, 70 uint32_t val) 71 { 72 switch (n) { 73 case LCX_REGNUM: 74 env->LCX = val; 75 break; 76 case FCX_REGNUM: 77 env->FCX = val; 78 break; 79 case PCXI_REGNUM: 80 env->PCXI = val; 81 break; 82 case TRICORE_PSW_REGNUM: 83 psw_write(env, val); 84 break; 85 case TRICORE_PC_REGNUM: 86 env->PC = val; 87 break; 88 case ICR_REGNUM: 89 env->ICR = val; 90 break; 91 case ISP_REGNUM: 92 env->ISP = val; 93 break; 94 case BTV_REGNUM: 95 env->BTV = val; 96 break; 97 case BIV_REGNUM: 98 env->BIV = val; 99 break; 100 case SYSCON_REGNUM: 101 env->SYSCON = val; 102 break; 103 } 104 } 105 106 107 int tricore_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 108 { 109 TriCoreCPU *cpu = TRICORE_CPU(cs); 110 CPUTriCoreState *env = &cpu->env; 111 112 if (n < 16) { /* data registers */ 113 return gdb_get_reg32(mem_buf, env->gpr_d[n]); 114 } else if (n < 32) { /* address registers */ 115 return gdb_get_reg32(mem_buf, env->gpr_a[n - 16]); 116 } else { /* csfr */ 117 return gdb_get_reg32(mem_buf, tricore_cpu_gdb_read_csfr(env, n)); 118 } 119 return 0; 120 } 121 122 int tricore_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 123 { 124 TriCoreCPU *cpu = TRICORE_CPU(cs); 125 CPUTriCoreState *env = &cpu->env; 126 uint32_t tmp; 127 128 tmp = ldl_p(mem_buf); 129 130 if (n < 16) { /* data registers */ 131 env->gpr_d[n] = tmp; 132 } else if (n < 32) { /* address registers */ 133 env->gpr_a[n - 16] = tmp; 134 } else { 135 tricore_cpu_gdb_write_csfr(env, n, tmp); 136 } 137 return 4; 138 } 139