mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 06:43:53 -06:00
cpu: Introduce CPUState::gdb_num_regs and CPUClass::gdb_num_core_regs
CPUState::gdb_num_regs replaces num_g_regs. CPUClass::gdb_num_core_regs replaces NUM_CORE_REGS. Allows building gdb_register_coprocessor() for xtensa, too. As a side effect this should fix coprocessor register numbering for SMP. Acked-by: Michael Walle <michael@walle.cc> (for lm32) Acked-by: Max Filippov <jcmvbkbc@gmail.com> (for xtensa) Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
parent
19a77215f1
commit
a0e372f0c4
18 changed files with 66 additions and 65 deletions
83
gdbstub.c
83
gdbstub.c
|
@ -530,8 +530,6 @@ static const int gpr_map[16] = {
|
|||
#endif
|
||||
static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
#define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25)
|
||||
|
||||
#define IDX_IP_REG CPU_NB_REGS
|
||||
#define IDX_FLAGS_REG (IDX_IP_REG + 1)
|
||||
#define IDX_SEG_REGS (IDX_FLAGS_REG + 1)
|
||||
|
@ -732,7 +730,6 @@ static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n)
|
|||
historical mishap the FP registers appear in between core integer
|
||||
regs and PC, MSR, CR, and so forth. We hack round this by giving the
|
||||
FP regs zero size when talking to a newer gdb. */
|
||||
#define NUM_CORE_REGS 71
|
||||
#if defined (TARGET_PPC64)
|
||||
#define GDB_CORE_XML "power64-core.xml"
|
||||
#else
|
||||
|
@ -837,12 +834,6 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n)
|
|||
|
||||
#elif defined (TARGET_SPARC)
|
||||
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
#define NUM_CORE_REGS 86
|
||||
#else
|
||||
#define NUM_CORE_REGS 72
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
#define GET_REGA(val) GET_REG32(val)
|
||||
#else
|
||||
|
@ -1030,7 +1021,6 @@ static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
|
|||
the FPA registers appear in between core integer regs and the CPSR.
|
||||
We hack round this by giving the FPA regs zero size when talking to a
|
||||
newer gdb. */
|
||||
#define NUM_CORE_REGS 26
|
||||
#define GDB_CORE_XML "arm-core.xml"
|
||||
|
||||
static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n)
|
||||
|
@ -1104,8 +1094,6 @@ static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n)
|
|||
|
||||
#elif defined (TARGET_M68K)
|
||||
|
||||
#define NUM_CORE_REGS 18
|
||||
|
||||
#define GDB_CORE_XML "cf-core.xml"
|
||||
|
||||
static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n)
|
||||
|
@ -1157,8 +1145,6 @@ static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#elif defined (TARGET_MIPS)
|
||||
|
||||
#define NUM_CORE_REGS 73
|
||||
|
||||
static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
|
@ -1285,8 +1271,6 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#elif defined(TARGET_OPENRISC)
|
||||
|
||||
#define NUM_CORE_REGS (32 + 3)
|
||||
|
||||
static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
|
@ -1312,9 +1296,11 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
|
|||
static int cpu_gdb_write_register(CPUOpenRISCState *env,
|
||||
uint8_t *mem_buf, int n)
|
||||
{
|
||||
OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
uint32_t tmp;
|
||||
|
||||
if (n > NUM_CORE_REGS) {
|
||||
if (n > cc->gdb_num_core_regs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1347,8 +1333,6 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env,
|
|||
/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
|
||||
/* FIXME: We should use XML for this. */
|
||||
|
||||
#define NUM_CORE_REGS 59
|
||||
|
||||
static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
switch (n) {
|
||||
|
@ -1465,8 +1449,6 @@ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#elif defined (TARGET_MICROBLAZE)
|
||||
|
||||
#define NUM_CORE_REGS (32 + 5)
|
||||
|
||||
static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
|
@ -1479,9 +1461,11 @@ static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
|
|||
|
||||
static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
MicroBlazeCPU *cpu = mb_env_get_cpu(env);
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
uint32_t tmp;
|
||||
|
||||
if (n > NUM_CORE_REGS) {
|
||||
if (n > cc->gdb_num_core_regs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1496,8 +1480,6 @@ static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#elif defined (TARGET_CRIS)
|
||||
|
||||
#define NUM_CORE_REGS 49
|
||||
|
||||
static int
|
||||
read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
|
@ -1605,8 +1587,6 @@ static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#elif defined (TARGET_ALPHA)
|
||||
|
||||
#define NUM_CORE_REGS 67
|
||||
|
||||
static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
uint64_t val;
|
||||
|
@ -1675,8 +1655,6 @@ static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#elif defined (TARGET_S390X)
|
||||
|
||||
#define NUM_CORE_REGS S390_NUM_REGS
|
||||
|
||||
static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
uint64_t val;
|
||||
|
@ -1740,7 +1718,6 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
|
|||
#elif defined (TARGET_LM32)
|
||||
|
||||
#include "hw/lm32/lm32_pic.h"
|
||||
#define NUM_CORE_REGS (32 + 7)
|
||||
|
||||
static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
|
@ -1770,9 +1747,11 @@ static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
|
|||
|
||||
static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
LM32CPU *cpu = lm32_env_get_cpu(env);
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
uint32_t tmp;
|
||||
|
||||
if (n > NUM_CORE_REGS) {
|
||||
if (n > cc->gdb_num_core_regs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1806,14 +1785,6 @@ static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#elif defined(TARGET_XTENSA)
|
||||
|
||||
/* Use num_core_regs to see only non-privileged registers in an unmodified gdb.
|
||||
* Use num_regs to see all registers. gdb modification is required for that:
|
||||
* reset bit 0 in the 'flags' field of the registers definitions in the
|
||||
* gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
|
||||
*/
|
||||
#define NUM_CORE_REGS (env->config->gdb_regmap.num_regs)
|
||||
#define num_g_regs NUM_CORE_REGS
|
||||
|
||||
static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
|
||||
|
@ -1896,8 +1867,6 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
|
|||
}
|
||||
#else
|
||||
|
||||
#define NUM_CORE_REGS 0
|
||||
|
||||
static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1910,10 +1879,6 @@ static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n)
|
|||
|
||||
#endif
|
||||
|
||||
#if !defined(TARGET_XTENSA)
|
||||
static int num_g_regs = NUM_CORE_REGS;
|
||||
#endif
|
||||
|
||||
#ifdef GDB_CORE_XML
|
||||
/* Encode data using the encoding for 'x' packets. */
|
||||
static int memtox(char *buf, const char *mem, int len)
|
||||
|
@ -1982,11 +1947,13 @@ static const char *get_feature_xml(const char *p, const char **newp)
|
|||
|
||||
static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
GDBRegisterState *r;
|
||||
|
||||
if (reg < NUM_CORE_REGS)
|
||||
if (reg < cc->gdb_num_core_regs) {
|
||||
return cpu_gdb_read_register(env, mem_buf, reg);
|
||||
}
|
||||
|
||||
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
||||
|
@ -1998,11 +1965,13 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
|||
|
||||
static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
GDBRegisterState *r;
|
||||
|
||||
if (reg < NUM_CORE_REGS)
|
||||
if (reg < cc->gdb_num_core_regs) {
|
||||
return cpu_gdb_write_register(env, mem_buf, reg);
|
||||
}
|
||||
|
||||
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
||||
|
@ -2012,7 +1981,6 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(TARGET_XTENSA)
|
||||
/* Register a supplemental set of CPU registers. If g_pos is nonzero it
|
||||
specifies the first register number and these registers are included in
|
||||
a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
|
||||
|
@ -2025,7 +1993,6 @@ void gdb_register_coprocessor(CPUState *cpu,
|
|||
{
|
||||
GDBRegisterState *s;
|
||||
GDBRegisterState **p;
|
||||
static int last_reg = NUM_CORE_REGS;
|
||||
|
||||
p = &cpu->gdb_regs;
|
||||
while (*p) {
|
||||
|
@ -2036,25 +2003,22 @@ void gdb_register_coprocessor(CPUState *cpu,
|
|||
}
|
||||
|
||||
s = g_new0(GDBRegisterState, 1);
|
||||
s->base_reg = last_reg;
|
||||
s->base_reg = cpu->gdb_num_regs;
|
||||
s->num_regs = num_regs;
|
||||
s->get_reg = get_reg;
|
||||
s->set_reg = set_reg;
|
||||
s->xml = xml;
|
||||
|
||||
/* Add to end of list. */
|
||||
last_reg += num_regs;
|
||||
cpu->gdb_num_regs += num_regs;
|
||||
*p = s;
|
||||
if (g_pos) {
|
||||
if (g_pos != s->base_reg) {
|
||||
fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
|
||||
"Expected %d got %d\n", xml, g_pos, s->base_reg);
|
||||
} else {
|
||||
num_g_regs = last_reg;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static const int xlat_gdb_type[] = {
|
||||
|
@ -2184,9 +2148,6 @@ static CPUState *find_cpu(uint32_t thread_id)
|
|||
|
||||
static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
{
|
||||
#ifdef TARGET_XTENSA
|
||||
CPUArchState *env;
|
||||
#endif
|
||||
CPUState *cpu;
|
||||
const char *p;
|
||||
uint32_t thread;
|
||||
|
@ -2334,11 +2295,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
|||
break;
|
||||
case 'g':
|
||||
cpu_synchronize_state(s->g_cpu);
|
||||
#ifdef TARGET_XTENSA
|
||||
env = s->g_cpu->env_ptr;
|
||||
#endif
|
||||
len = 0;
|
||||
for (addr = 0; addr < num_g_regs; addr++) {
|
||||
for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
|
||||
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
|
||||
len += reg_size;
|
||||
}
|
||||
|
@ -2347,13 +2305,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
|||
break;
|
||||
case 'G':
|
||||
cpu_synchronize_state(s->g_cpu);
|
||||
#ifdef TARGET_XTENSA
|
||||
env = s->g_cpu->env_ptr;
|
||||
#endif
|
||||
registers = mem_buf;
|
||||
len = strlen(p) / 2;
|
||||
hextomem((uint8_t *)registers, p, len);
|
||||
for (addr = 0; addr < num_g_regs && len > 0; addr++) {
|
||||
for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
|
||||
reg_size = gdb_write_register(s->g_cpu, registers, addr);
|
||||
len -= reg_size;
|
||||
registers += reg_size;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue