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