1814ac26cSAndreas Färber /* 2814ac26cSAndreas Färber * MIPS gdb server stub 3814ac26cSAndreas Färber * 4814ac26cSAndreas Färber * Copyright (c) 2003-2005 Fabrice Bellard 5814ac26cSAndreas Färber * Copyright (c) 2013 SUSE LINUX Products GmbH 6814ac26cSAndreas Färber * 7814ac26cSAndreas Färber * This library is free software; you can redistribute it and/or 8814ac26cSAndreas Färber * modify it under the terms of the GNU Lesser General Public 9814ac26cSAndreas Färber * License as published by the Free Software Foundation; either 10814ac26cSAndreas Färber * version 2 of the License, or (at your option) any later version. 11814ac26cSAndreas Färber * 12814ac26cSAndreas Färber * This library is distributed in the hope that it will be useful, 13814ac26cSAndreas Färber * but WITHOUT ANY WARRANTY; without even the implied warranty of 14814ac26cSAndreas Färber * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15814ac26cSAndreas Färber * Lesser General Public License for more details. 16814ac26cSAndreas Färber * 17814ac26cSAndreas Färber * You should have received a copy of the GNU Lesser General Public 18814ac26cSAndreas Färber * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19814ac26cSAndreas Färber */ 20c684822aSPeter Maydell #include "qemu/osdep.h" 2133c11879SPaolo Bonzini #include "cpu.h" 2226aa3d9aSPhilippe Mathieu-Daudé #include "internal.h" 235b50e790SAndreas Färber #include "exec/gdbstub.h" 24814ac26cSAndreas Färber 25*a010bdbeSAlex Bennée int mips_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 26814ac26cSAndreas Färber { 275b50e790SAndreas Färber MIPSCPU *cpu = MIPS_CPU(cs); 285b50e790SAndreas Färber CPUMIPSState *env = &cpu->env; 295b50e790SAndreas Färber 30814ac26cSAndreas Färber if (n < 32) { 31986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); 32814ac26cSAndreas Färber } 33cbb26c9aSMaciej W. Rozycki if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) { 34cbb26c9aSMaciej W. Rozycki switch (n) { 35cbb26c9aSMaciej W. Rozycki case 70: 36cbb26c9aSMaciej W. Rozycki return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr31); 37cbb26c9aSMaciej W. Rozycki case 71: 38cbb26c9aSMaciej W. Rozycki return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0); 39cbb26c9aSMaciej W. Rozycki default: 40814ac26cSAndreas Färber if (env->CP0_Status & (1 << CP0St_FR)) { 41d1cc1533SLibo Zhou return gdb_get_regl(mem_buf, 42986a2998SAndreas Färber env->active_fpu.fpr[n - 38].d); 43814ac26cSAndreas Färber } else { 44986a2998SAndreas Färber return gdb_get_regl(mem_buf, 45986a2998SAndreas Färber env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]); 46814ac26cSAndreas Färber } 47814ac26cSAndreas Färber } 48814ac26cSAndreas Färber } 49814ac26cSAndreas Färber switch (n) { 50814ac26cSAndreas Färber case 32: 51986a2998SAndreas Färber return gdb_get_regl(mem_buf, (int32_t)env->CP0_Status); 52814ac26cSAndreas Färber case 33: 53986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->active_tc.LO[0]); 54814ac26cSAndreas Färber case 34: 55986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->active_tc.HI[0]); 56814ac26cSAndreas Färber case 35: 57986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->CP0_BadVAddr); 58814ac26cSAndreas Färber case 36: 59986a2998SAndreas Färber return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause); 60814ac26cSAndreas Färber case 37: 61986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->active_tc.PC | 62986a2998SAndreas Färber !!(env->hflags & MIPS_HFLAG_M16)); 63814ac26cSAndreas Färber case 72: 64986a2998SAndreas Färber return gdb_get_regl(mem_buf, 0); /* fp */ 65814ac26cSAndreas Färber case 89: 66986a2998SAndreas Färber return gdb_get_regl(mem_buf, (int32_t)env->CP0_PRid); 67cbb26c9aSMaciej W. Rozycki default: 68cbb26c9aSMaciej W. Rozycki if (n > 89) { 69cbb26c9aSMaciej W. Rozycki return 0; 70814ac26cSAndreas Färber } 71814ac26cSAndreas Färber /* 16 embedded regs. */ 72986a2998SAndreas Färber return gdb_get_regl(mem_buf, 0); 73814ac26cSAndreas Färber } 74814ac26cSAndreas Färber 75814ac26cSAndreas Färber return 0; 76814ac26cSAndreas Färber } 77814ac26cSAndreas Färber 785b50e790SAndreas Färber int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 79814ac26cSAndreas Färber { 805b50e790SAndreas Färber MIPSCPU *cpu = MIPS_CPU(cs); 815b50e790SAndreas Färber CPUMIPSState *env = &cpu->env; 82814ac26cSAndreas Färber target_ulong tmp; 83814ac26cSAndreas Färber 84814ac26cSAndreas Färber tmp = ldtul_p(mem_buf); 85814ac26cSAndreas Färber 86814ac26cSAndreas Färber if (n < 32) { 87814ac26cSAndreas Färber env->active_tc.gpr[n] = tmp; 88814ac26cSAndreas Färber return sizeof(target_ulong); 89814ac26cSAndreas Färber } 90cbb26c9aSMaciej W. Rozycki if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) { 91814ac26cSAndreas Färber switch (n) { 92814ac26cSAndreas Färber case 70: 93599bc5e8SAleksandar Markovic env->active_fpu.fcr31 = (tmp & env->active_fpu.fcr31_rw_bitmask) | 94599bc5e8SAleksandar Markovic (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask)); 95599bc5e8SAleksandar Markovic restore_fp_status(env); 96814ac26cSAndreas Färber break; 97814ac26cSAndreas Färber case 71: 98c7d4d98aSMaciej W. Rozycki /* FIR is read-only. Ignore writes. */ 99814ac26cSAndreas Färber break; 100cbb26c9aSMaciej W. Rozycki default: 101cbb26c9aSMaciej W. Rozycki if (env->CP0_Status & (1 << CP0St_FR)) { 102cbb26c9aSMaciej W. Rozycki env->active_fpu.fpr[n - 38].d = tmp; 103cbb26c9aSMaciej W. Rozycki } else { 104cbb26c9aSMaciej W. Rozycki env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp; 105cbb26c9aSMaciej W. Rozycki } 106cbb26c9aSMaciej W. Rozycki break; 107814ac26cSAndreas Färber } 108814ac26cSAndreas Färber return sizeof(target_ulong); 109814ac26cSAndreas Färber } 110814ac26cSAndreas Färber switch (n) { 111814ac26cSAndreas Färber case 32: 11281a423e6SMaciej W. Rozycki #ifndef CONFIG_USER_ONLY 11381a423e6SMaciej W. Rozycki cpu_mips_store_status(env, tmp); 11481a423e6SMaciej W. Rozycki #endif 115814ac26cSAndreas Färber break; 116814ac26cSAndreas Färber case 33: 117814ac26cSAndreas Färber env->active_tc.LO[0] = tmp; 118814ac26cSAndreas Färber break; 119814ac26cSAndreas Färber case 34: 120814ac26cSAndreas Färber env->active_tc.HI[0] = tmp; 121814ac26cSAndreas Färber break; 122814ac26cSAndreas Färber case 35: 123814ac26cSAndreas Färber env->CP0_BadVAddr = tmp; 124814ac26cSAndreas Färber break; 125814ac26cSAndreas Färber case 36: 12681a423e6SMaciej W. Rozycki #ifndef CONFIG_USER_ONLY 12781a423e6SMaciej W. Rozycki cpu_mips_store_cause(env, tmp); 12881a423e6SMaciej W. Rozycki #endif 129814ac26cSAndreas Färber break; 130814ac26cSAndreas Färber case 37: 131814ac26cSAndreas Färber env->active_tc.PC = tmp & ~(target_ulong)1; 132814ac26cSAndreas Färber if (tmp & 1) { 133814ac26cSAndreas Färber env->hflags |= MIPS_HFLAG_M16; 134814ac26cSAndreas Färber } else { 135814ac26cSAndreas Färber env->hflags &= ~(MIPS_HFLAG_M16); 136814ac26cSAndreas Färber } 137814ac26cSAndreas Färber break; 138814ac26cSAndreas Färber case 72: /* fp, ignored */ 139814ac26cSAndreas Färber break; 140814ac26cSAndreas Färber default: 141814ac26cSAndreas Färber if (n > 89) { 142814ac26cSAndreas Färber return 0; 143814ac26cSAndreas Färber } 144814ac26cSAndreas Färber /* Other registers are readonly. Ignore writes. */ 145814ac26cSAndreas Färber break; 146814ac26cSAndreas Färber } 147814ac26cSAndreas Färber 148814ac26cSAndreas Färber return sizeof(target_ulong); 149814ac26cSAndreas Färber } 150