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" 2233c11879SPaolo Bonzini #include "cpu.h" 235b50e790SAndreas Färber #include "exec/gdbstub.h" 24d19c87f4SAndreas Färber 25d19c87f4SAndreas Färber #ifdef TARGET_ABI32 26986a2998SAndreas Färber #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val) 27d19c87f4SAndreas Färber #else 28986a2998SAndreas Färber #define gdb_get_rega(buf, val) gdb_get_regl(buf, val) 29d19c87f4SAndreas Färber #endif 30d19c87f4SAndreas Färber 315b50e790SAndreas Färber int sparc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) 32d19c87f4SAndreas Färber { 335b50e790SAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 345b50e790SAndreas Färber CPUSPARCState *env = &cpu->env; 355b50e790SAndreas Färber 36d19c87f4SAndreas Färber if (n < 8) { 37d19c87f4SAndreas Färber /* g0..g7 */ 38986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->gregs[n]); 39d19c87f4SAndreas Färber } 40d19c87f4SAndreas Färber if (n < 32) { 41d19c87f4SAndreas Färber /* register window */ 42986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->regwptr[n - 8]); 43d19c87f4SAndreas Färber } 44d19c87f4SAndreas Färber #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) 45d19c87f4SAndreas Färber if (n < 64) { 46d19c87f4SAndreas Färber /* fprs */ 47d19c87f4SAndreas Färber if (n & 1) { 48986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); 49d19c87f4SAndreas Färber } else { 50986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); 51d19c87f4SAndreas Färber } 52d19c87f4SAndreas Färber } 53d19c87f4SAndreas Färber /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 54d19c87f4SAndreas Färber switch (n) { 55d19c87f4SAndreas Färber case 64: 56986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->y); 57d19c87f4SAndreas Färber case 65: 58986a2998SAndreas Färber return gdb_get_rega(mem_buf, cpu_get_psr(env)); 59d19c87f4SAndreas Färber case 66: 60986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->wim); 61d19c87f4SAndreas Färber case 67: 62986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->tbr); 63d19c87f4SAndreas Färber case 68: 64986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->pc); 65d19c87f4SAndreas Färber case 69: 66986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->npc); 67d19c87f4SAndreas Färber case 70: 68986a2998SAndreas Färber return gdb_get_rega(mem_buf, env->fsr); 69d19c87f4SAndreas Färber case 71: 70986a2998SAndreas Färber return gdb_get_rega(mem_buf, 0); /* csr */ 71d19c87f4SAndreas Färber default: 72986a2998SAndreas Färber return gdb_get_rega(mem_buf, 0); 73d19c87f4SAndreas Färber } 74d19c87f4SAndreas Färber #else 75d19c87f4SAndreas Färber if (n < 64) { 76d19c87f4SAndreas Färber /* f0-f31 */ 77d19c87f4SAndreas Färber if (n & 1) { 78986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); 79d19c87f4SAndreas Färber } else { 80986a2998SAndreas Färber return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); 81d19c87f4SAndreas Färber } 82d19c87f4SAndreas Färber } 83d19c87f4SAndreas Färber if (n < 80) { 84d19c87f4SAndreas Färber /* f32-f62 (double width, even numbers only) */ 85986a2998SAndreas Färber return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll); 86d19c87f4SAndreas Färber } 87d19c87f4SAndreas Färber switch (n) { 88d19c87f4SAndreas Färber case 80: 89986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->pc); 90d19c87f4SAndreas Färber case 81: 91986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->npc); 92d19c87f4SAndreas Färber case 82: 93986a2998SAndreas Färber return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) | 94d19c87f4SAndreas Färber ((env->asi & 0xff) << 24) | 95d19c87f4SAndreas Färber ((env->pstate & 0xfff) << 8) | 96d19c87f4SAndreas Färber cpu_get_cwp64(env)); 97d19c87f4SAndreas Färber case 83: 98986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->fsr); 99d19c87f4SAndreas Färber case 84: 100986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->fprs); 101d19c87f4SAndreas Färber case 85: 102986a2998SAndreas Färber return gdb_get_regl(mem_buf, env->y); 103d19c87f4SAndreas Färber } 104d19c87f4SAndreas Färber #endif 105d19c87f4SAndreas Färber return 0; 106d19c87f4SAndreas Färber } 107d19c87f4SAndreas Färber 1085b50e790SAndreas Färber int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 109d19c87f4SAndreas Färber { 1105b50e790SAndreas Färber SPARCCPU *cpu = SPARC_CPU(cs); 1115b50e790SAndreas Färber CPUSPARCState *env = &cpu->env; 112d19c87f4SAndreas Färber #if defined(TARGET_ABI32) 113d19c87f4SAndreas Färber abi_ulong tmp; 114d19c87f4SAndreas Färber 115d19c87f4SAndreas Färber tmp = ldl_p(mem_buf); 116d19c87f4SAndreas Färber #else 117d19c87f4SAndreas Färber target_ulong tmp; 118d19c87f4SAndreas Färber 119d19c87f4SAndreas Färber tmp = ldtul_p(mem_buf); 120d19c87f4SAndreas Färber #endif 121d19c87f4SAndreas Färber 122d19c87f4SAndreas Färber if (n < 8) { 123d19c87f4SAndreas Färber /* g0..g7 */ 124d19c87f4SAndreas Färber env->gregs[n] = tmp; 125d19c87f4SAndreas Färber } else if (n < 32) { 126d19c87f4SAndreas Färber /* register window */ 127d19c87f4SAndreas Färber env->regwptr[n - 8] = tmp; 128d19c87f4SAndreas Färber } 129d19c87f4SAndreas Färber #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) 130d19c87f4SAndreas Färber else if (n < 64) { 131d19c87f4SAndreas Färber /* fprs */ 132d19c87f4SAndreas Färber /* f0-f31 */ 133d19c87f4SAndreas Färber if (n & 1) { 134d19c87f4SAndreas Färber env->fpr[(n - 32) / 2].l.lower = tmp; 135d19c87f4SAndreas Färber } else { 136d19c87f4SAndreas Färber env->fpr[(n - 32) / 2].l.upper = tmp; 137d19c87f4SAndreas Färber } 138d19c87f4SAndreas Färber } else { 139d19c87f4SAndreas Färber /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 140d19c87f4SAndreas Färber switch (n) { 141d19c87f4SAndreas Färber case 64: 142d19c87f4SAndreas Färber env->y = tmp; 143d19c87f4SAndreas Färber break; 144d19c87f4SAndreas Färber case 65: 145d19c87f4SAndreas Färber cpu_put_psr(env, tmp); 146d19c87f4SAndreas Färber break; 147d19c87f4SAndreas Färber case 66: 148d19c87f4SAndreas Färber env->wim = tmp; 149d19c87f4SAndreas Färber break; 150d19c87f4SAndreas Färber case 67: 151d19c87f4SAndreas Färber env->tbr = tmp; 152d19c87f4SAndreas Färber break; 153d19c87f4SAndreas Färber case 68: 154d19c87f4SAndreas Färber env->pc = tmp; 155d19c87f4SAndreas Färber break; 156d19c87f4SAndreas Färber case 69: 157d19c87f4SAndreas Färber env->npc = tmp; 158d19c87f4SAndreas Färber break; 159d19c87f4SAndreas Färber case 70: 160d19c87f4SAndreas Färber env->fsr = tmp; 161d19c87f4SAndreas Färber break; 162d19c87f4SAndreas Färber default: 163d19c87f4SAndreas Färber return 0; 164d19c87f4SAndreas Färber } 165d19c87f4SAndreas Färber } 166d19c87f4SAndreas Färber return 4; 167d19c87f4SAndreas Färber #else 168d19c87f4SAndreas Färber else if (n < 64) { 169d19c87f4SAndreas Färber /* f0-f31 */ 170d19c87f4SAndreas Färber tmp = ldl_p(mem_buf); 171d19c87f4SAndreas Färber if (n & 1) { 172d19c87f4SAndreas Färber env->fpr[(n - 32) / 2].l.lower = tmp; 173d19c87f4SAndreas Färber } else { 174d19c87f4SAndreas Färber env->fpr[(n - 32) / 2].l.upper = tmp; 175d19c87f4SAndreas Färber } 176d19c87f4SAndreas Färber return 4; 177d19c87f4SAndreas Färber } else if (n < 80) { 178d19c87f4SAndreas Färber /* f32-f62 (double width, even numbers only) */ 179d19c87f4SAndreas Färber env->fpr[(n - 32) / 2].ll = tmp; 180d19c87f4SAndreas Färber } else { 181d19c87f4SAndreas Färber switch (n) { 182d19c87f4SAndreas Färber case 80: 183d19c87f4SAndreas Färber env->pc = tmp; 184d19c87f4SAndreas Färber break; 185d19c87f4SAndreas Färber case 81: 186d19c87f4SAndreas Färber env->npc = tmp; 187d19c87f4SAndreas Färber break; 188d19c87f4SAndreas Färber case 82: 189d19c87f4SAndreas Färber cpu_put_ccr(env, tmp >> 32); 190d19c87f4SAndreas Färber env->asi = (tmp >> 24) & 0xff; 191d19c87f4SAndreas Färber env->pstate = (tmp >> 8) & 0xfff; 192d19c87f4SAndreas Färber cpu_put_cwp64(env, tmp & 0xff); 193d19c87f4SAndreas Färber break; 194d19c87f4SAndreas Färber case 83: 195d19c87f4SAndreas Färber env->fsr = tmp; 196d19c87f4SAndreas Färber break; 197d19c87f4SAndreas Färber case 84: 198d19c87f4SAndreas Färber env->fprs = tmp; 199d19c87f4SAndreas Färber break; 200d19c87f4SAndreas Färber case 85: 201d19c87f4SAndreas Färber env->y = tmp; 202d19c87f4SAndreas Färber break; 203d19c87f4SAndreas Färber default: 204d19c87f4SAndreas Färber return 0; 205d19c87f4SAndreas Färber } 206d19c87f4SAndreas Färber } 207d19c87f4SAndreas Färber return 8; 208d19c87f4SAndreas Färber #endif 209d19c87f4SAndreas Färber } 210