1*fcf5ef2aSThomas Huth /* 2*fcf5ef2aSThomas Huth * SPARC gdb server stub 3*fcf5ef2aSThomas Huth * 4*fcf5ef2aSThomas Huth * Copyright (c) 2003-2005 Fabrice Bellard 5*fcf5ef2aSThomas Huth * Copyright (c) 2013 SUSE LINUX Products GmbH 6*fcf5ef2aSThomas Huth * 7*fcf5ef2aSThomas Huth * This library is free software; you can redistribute it and/or 8*fcf5ef2aSThomas Huth * modify it under the terms of the GNU Lesser General Public 9*fcf5ef2aSThomas Huth * License as published by the Free Software Foundation; either 10*fcf5ef2aSThomas Huth * version 2 of the License, or (at your option) any later version. 11*fcf5ef2aSThomas Huth * 12*fcf5ef2aSThomas Huth * This library is distributed in the hope that it will be useful, 13*fcf5ef2aSThomas Huth * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*fcf5ef2aSThomas Huth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*fcf5ef2aSThomas Huth * Lesser General Public License for more details. 16*fcf5ef2aSThomas Huth * 17*fcf5ef2aSThomas Huth * You should have received a copy of the GNU Lesser General Public 18*fcf5ef2aSThomas Huth * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19*fcf5ef2aSThomas Huth */ 20*fcf5ef2aSThomas Huth #include "qemu/osdep.h" 21*fcf5ef2aSThomas Huth #include "qemu-common.h" 22*fcf5ef2aSThomas Huth #include "cpu.h" 23*fcf5ef2aSThomas Huth #include "exec/gdbstub.h" 24*fcf5ef2aSThomas Huth 25*fcf5ef2aSThomas Huth #ifdef TARGET_ABI32 26*fcf5ef2aSThomas Huth #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val) 27*fcf5ef2aSThomas Huth #else 28*fcf5ef2aSThomas Huth #define gdb_get_rega(buf, val) gdb_get_regl(buf, val) 29*fcf5ef2aSThomas Huth #endif 30*fcf5ef2aSThomas Huth 31*fcf5ef2aSThomas Huth int sparc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) 32*fcf5ef2aSThomas Huth { 33*fcf5ef2aSThomas Huth SPARCCPU *cpu = SPARC_CPU(cs); 34*fcf5ef2aSThomas Huth CPUSPARCState *env = &cpu->env; 35*fcf5ef2aSThomas Huth 36*fcf5ef2aSThomas Huth if (n < 8) { 37*fcf5ef2aSThomas Huth /* g0..g7 */ 38*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->gregs[n]); 39*fcf5ef2aSThomas Huth } 40*fcf5ef2aSThomas Huth if (n < 32) { 41*fcf5ef2aSThomas Huth /* register window */ 42*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->regwptr[n - 8]); 43*fcf5ef2aSThomas Huth } 44*fcf5ef2aSThomas Huth #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) 45*fcf5ef2aSThomas Huth if (n < 64) { 46*fcf5ef2aSThomas Huth /* fprs */ 47*fcf5ef2aSThomas Huth if (n & 1) { 48*fcf5ef2aSThomas Huth return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); 49*fcf5ef2aSThomas Huth } else { 50*fcf5ef2aSThomas Huth return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); 51*fcf5ef2aSThomas Huth } 52*fcf5ef2aSThomas Huth } 53*fcf5ef2aSThomas Huth /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 54*fcf5ef2aSThomas Huth switch (n) { 55*fcf5ef2aSThomas Huth case 64: 56*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->y); 57*fcf5ef2aSThomas Huth case 65: 58*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, cpu_get_psr(env)); 59*fcf5ef2aSThomas Huth case 66: 60*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->wim); 61*fcf5ef2aSThomas Huth case 67: 62*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->tbr); 63*fcf5ef2aSThomas Huth case 68: 64*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->pc); 65*fcf5ef2aSThomas Huth case 69: 66*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->npc); 67*fcf5ef2aSThomas Huth case 70: 68*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, env->fsr); 69*fcf5ef2aSThomas Huth case 71: 70*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, 0); /* csr */ 71*fcf5ef2aSThomas Huth default: 72*fcf5ef2aSThomas Huth return gdb_get_rega(mem_buf, 0); 73*fcf5ef2aSThomas Huth } 74*fcf5ef2aSThomas Huth #else 75*fcf5ef2aSThomas Huth if (n < 64) { 76*fcf5ef2aSThomas Huth /* f0-f31 */ 77*fcf5ef2aSThomas Huth if (n & 1) { 78*fcf5ef2aSThomas Huth return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); 79*fcf5ef2aSThomas Huth } else { 80*fcf5ef2aSThomas Huth return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); 81*fcf5ef2aSThomas Huth } 82*fcf5ef2aSThomas Huth } 83*fcf5ef2aSThomas Huth if (n < 80) { 84*fcf5ef2aSThomas Huth /* f32-f62 (double width, even numbers only) */ 85*fcf5ef2aSThomas Huth return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll); 86*fcf5ef2aSThomas Huth } 87*fcf5ef2aSThomas Huth switch (n) { 88*fcf5ef2aSThomas Huth case 80: 89*fcf5ef2aSThomas Huth return gdb_get_regl(mem_buf, env->pc); 90*fcf5ef2aSThomas Huth case 81: 91*fcf5ef2aSThomas Huth return gdb_get_regl(mem_buf, env->npc); 92*fcf5ef2aSThomas Huth case 82: 93*fcf5ef2aSThomas Huth return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) | 94*fcf5ef2aSThomas Huth ((env->asi & 0xff) << 24) | 95*fcf5ef2aSThomas Huth ((env->pstate & 0xfff) << 8) | 96*fcf5ef2aSThomas Huth cpu_get_cwp64(env)); 97*fcf5ef2aSThomas Huth case 83: 98*fcf5ef2aSThomas Huth return gdb_get_regl(mem_buf, env->fsr); 99*fcf5ef2aSThomas Huth case 84: 100*fcf5ef2aSThomas Huth return gdb_get_regl(mem_buf, env->fprs); 101*fcf5ef2aSThomas Huth case 85: 102*fcf5ef2aSThomas Huth return gdb_get_regl(mem_buf, env->y); 103*fcf5ef2aSThomas Huth } 104*fcf5ef2aSThomas Huth #endif 105*fcf5ef2aSThomas Huth return 0; 106*fcf5ef2aSThomas Huth } 107*fcf5ef2aSThomas Huth 108*fcf5ef2aSThomas Huth int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 109*fcf5ef2aSThomas Huth { 110*fcf5ef2aSThomas Huth SPARCCPU *cpu = SPARC_CPU(cs); 111*fcf5ef2aSThomas Huth CPUSPARCState *env = &cpu->env; 112*fcf5ef2aSThomas Huth #if defined(TARGET_ABI32) 113*fcf5ef2aSThomas Huth abi_ulong tmp; 114*fcf5ef2aSThomas Huth 115*fcf5ef2aSThomas Huth tmp = ldl_p(mem_buf); 116*fcf5ef2aSThomas Huth #else 117*fcf5ef2aSThomas Huth target_ulong tmp; 118*fcf5ef2aSThomas Huth 119*fcf5ef2aSThomas Huth tmp = ldtul_p(mem_buf); 120*fcf5ef2aSThomas Huth #endif 121*fcf5ef2aSThomas Huth 122*fcf5ef2aSThomas Huth if (n < 8) { 123*fcf5ef2aSThomas Huth /* g0..g7 */ 124*fcf5ef2aSThomas Huth env->gregs[n] = tmp; 125*fcf5ef2aSThomas Huth } else if (n < 32) { 126*fcf5ef2aSThomas Huth /* register window */ 127*fcf5ef2aSThomas Huth env->regwptr[n - 8] = tmp; 128*fcf5ef2aSThomas Huth } 129*fcf5ef2aSThomas Huth #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) 130*fcf5ef2aSThomas Huth else if (n < 64) { 131*fcf5ef2aSThomas Huth /* fprs */ 132*fcf5ef2aSThomas Huth /* f0-f31 */ 133*fcf5ef2aSThomas Huth if (n & 1) { 134*fcf5ef2aSThomas Huth env->fpr[(n - 32) / 2].l.lower = tmp; 135*fcf5ef2aSThomas Huth } else { 136*fcf5ef2aSThomas Huth env->fpr[(n - 32) / 2].l.upper = tmp; 137*fcf5ef2aSThomas Huth } 138*fcf5ef2aSThomas Huth } else { 139*fcf5ef2aSThomas Huth /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 140*fcf5ef2aSThomas Huth switch (n) { 141*fcf5ef2aSThomas Huth case 64: 142*fcf5ef2aSThomas Huth env->y = tmp; 143*fcf5ef2aSThomas Huth break; 144*fcf5ef2aSThomas Huth case 65: 145*fcf5ef2aSThomas Huth cpu_put_psr(env, tmp); 146*fcf5ef2aSThomas Huth break; 147*fcf5ef2aSThomas Huth case 66: 148*fcf5ef2aSThomas Huth env->wim = tmp; 149*fcf5ef2aSThomas Huth break; 150*fcf5ef2aSThomas Huth case 67: 151*fcf5ef2aSThomas Huth env->tbr = tmp; 152*fcf5ef2aSThomas Huth break; 153*fcf5ef2aSThomas Huth case 68: 154*fcf5ef2aSThomas Huth env->pc = tmp; 155*fcf5ef2aSThomas Huth break; 156*fcf5ef2aSThomas Huth case 69: 157*fcf5ef2aSThomas Huth env->npc = tmp; 158*fcf5ef2aSThomas Huth break; 159*fcf5ef2aSThomas Huth case 70: 160*fcf5ef2aSThomas Huth env->fsr = tmp; 161*fcf5ef2aSThomas Huth break; 162*fcf5ef2aSThomas Huth default: 163*fcf5ef2aSThomas Huth return 0; 164*fcf5ef2aSThomas Huth } 165*fcf5ef2aSThomas Huth } 166*fcf5ef2aSThomas Huth return 4; 167*fcf5ef2aSThomas Huth #else 168*fcf5ef2aSThomas Huth else if (n < 64) { 169*fcf5ef2aSThomas Huth /* f0-f31 */ 170*fcf5ef2aSThomas Huth tmp = ldl_p(mem_buf); 171*fcf5ef2aSThomas Huth if (n & 1) { 172*fcf5ef2aSThomas Huth env->fpr[(n - 32) / 2].l.lower = tmp; 173*fcf5ef2aSThomas Huth } else { 174*fcf5ef2aSThomas Huth env->fpr[(n - 32) / 2].l.upper = tmp; 175*fcf5ef2aSThomas Huth } 176*fcf5ef2aSThomas Huth return 4; 177*fcf5ef2aSThomas Huth } else if (n < 80) { 178*fcf5ef2aSThomas Huth /* f32-f62 (double width, even numbers only) */ 179*fcf5ef2aSThomas Huth env->fpr[(n - 32) / 2].ll = tmp; 180*fcf5ef2aSThomas Huth } else { 181*fcf5ef2aSThomas Huth switch (n) { 182*fcf5ef2aSThomas Huth case 80: 183*fcf5ef2aSThomas Huth env->pc = tmp; 184*fcf5ef2aSThomas Huth break; 185*fcf5ef2aSThomas Huth case 81: 186*fcf5ef2aSThomas Huth env->npc = tmp; 187*fcf5ef2aSThomas Huth break; 188*fcf5ef2aSThomas Huth case 82: 189*fcf5ef2aSThomas Huth cpu_put_ccr(env, tmp >> 32); 190*fcf5ef2aSThomas Huth env->asi = (tmp >> 24) & 0xff; 191*fcf5ef2aSThomas Huth env->pstate = (tmp >> 8) & 0xfff; 192*fcf5ef2aSThomas Huth cpu_put_cwp64(env, tmp & 0xff); 193*fcf5ef2aSThomas Huth break; 194*fcf5ef2aSThomas Huth case 83: 195*fcf5ef2aSThomas Huth env->fsr = tmp; 196*fcf5ef2aSThomas Huth break; 197*fcf5ef2aSThomas Huth case 84: 198*fcf5ef2aSThomas Huth env->fprs = tmp; 199*fcf5ef2aSThomas Huth break; 200*fcf5ef2aSThomas Huth case 85: 201*fcf5ef2aSThomas Huth env->y = tmp; 202*fcf5ef2aSThomas Huth break; 203*fcf5ef2aSThomas Huth default: 204*fcf5ef2aSThomas Huth return 0; 205*fcf5ef2aSThomas Huth } 206*fcf5ef2aSThomas Huth } 207*fcf5ef2aSThomas Huth return 8; 208*fcf5ef2aSThomas Huth #endif 209*fcf5ef2aSThomas Huth } 210