target/xtensa: clean up gdbstub register handling
- move register counting to xtensa/gdbstub.c - add symbolic names for register types and flags from GDB and use them in register counting and access functions. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
2becc8fd7e
commit
a7ac06fd41
@ -503,6 +503,8 @@ void xtensa_cpu_do_unassigned_access(CPUState *cpu, hwaddr addr,
|
||||
void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||
fprintf_function cpu_fprintf, int flags);
|
||||
hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||
void xtensa_count_regs(const XtensaConfig *config,
|
||||
unsigned *n_regs, unsigned *n_core_regs);
|
||||
int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
|
||||
|
@ -23,6 +23,42 @@
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
enum {
|
||||
xtRegisterTypeArRegfile = 1, /* Register File ar0..arXX. */
|
||||
xtRegisterTypeSpecialReg, /* CPU states, such as PS, Booleans, (rsr). */
|
||||
xtRegisterTypeUserReg, /* User defined registers (rur). */
|
||||
xtRegisterTypeTieRegfile, /* User define register files. */
|
||||
xtRegisterTypeTieState, /* TIE States (mapped on user regs). */
|
||||
xtRegisterTypeMapped, /* Mapped on Special Registers. */
|
||||
xtRegisterTypeUnmapped, /* Special case of masked registers. */
|
||||
xtRegisterTypeWindow, /* Live window registers (a0..a15). */
|
||||
xtRegisterTypeVirtual, /* PC, FP. */
|
||||
xtRegisterTypeUnknown
|
||||
};
|
||||
|
||||
#define XTENSA_REGISTER_FLAGS_PRIVILEGED 0x0001
|
||||
#define XTENSA_REGISTER_FLAGS_READABLE 0x0002
|
||||
#define XTENSA_REGISTER_FLAGS_WRITABLE 0x0004
|
||||
#define XTENSA_REGISTER_FLAGS_VOLATILE 0x0008
|
||||
|
||||
void xtensa_count_regs(const XtensaConfig *config,
|
||||
unsigned *n_regs, unsigned *n_core_regs)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; config->gdb_regmap.reg[i].targno >= 0; ++i) {
|
||||
if (config->gdb_regmap.reg[i].type != xtRegisterTypeTieState &&
|
||||
config->gdb_regmap.reg[i].type != xtRegisterTypeMapped &&
|
||||
config->gdb_regmap.reg[i].type != xtRegisterTypeUnmapped) {
|
||||
++*n_regs;
|
||||
if ((config->gdb_regmap.reg[i].flags &
|
||||
XTENSA_REGISTER_FLAGS_PRIVILEGED) == 0) {
|
||||
++*n_core_regs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
@ -40,21 +76,21 @@ int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
}
|
||||
|
||||
switch (reg->type) {
|
||||
case 9: /*pc*/
|
||||
case xtRegisterTypeVirtual: /*pc*/
|
||||
return gdb_get_reg32(mem_buf, env->pc);
|
||||
|
||||
case 1: /*ar*/
|
||||
case xtRegisterTypeArRegfile: /*ar*/
|
||||
xtensa_sync_phys_from_window(env);
|
||||
return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff)
|
||||
% env->config->nareg]);
|
||||
|
||||
case 2: /*SR*/
|
||||
case xtRegisterTypeSpecialReg: /*SR*/
|
||||
return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]);
|
||||
|
||||
case 3: /*UR*/
|
||||
case xtRegisterTypeUserReg: /*UR*/
|
||||
return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]);
|
||||
|
||||
case 4: /*f*/
|
||||
case xtRegisterTypeTieRegfile: /*f*/
|
||||
i = reg->targno & 0x0f;
|
||||
switch (reg->size) {
|
||||
case 4:
|
||||
@ -69,7 +105,7 @@ int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
return reg->size;
|
||||
}
|
||||
|
||||
case 8: /*a*/
|
||||
case xtRegisterTypeWindow: /*a*/
|
||||
return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);
|
||||
|
||||
default:
|
||||
@ -99,24 +135,24 @@ int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
tmp = ldl_p(mem_buf);
|
||||
|
||||
switch (reg->type) {
|
||||
case 9: /*pc*/
|
||||
case xtRegisterTypeVirtual: /*pc*/
|
||||
env->pc = tmp;
|
||||
break;
|
||||
|
||||
case 1: /*ar*/
|
||||
case xtRegisterTypeArRegfile: /*ar*/
|
||||
env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
|
||||
xtensa_sync_window_from_phys(env);
|
||||
break;
|
||||
|
||||
case 2: /*SR*/
|
||||
case xtRegisterTypeSpecialReg: /*SR*/
|
||||
env->sregs[reg->targno & 0xff] = tmp;
|
||||
break;
|
||||
|
||||
case 3: /*UR*/
|
||||
case xtRegisterTypeUserReg: /*UR*/
|
||||
env->uregs[reg->targno & 0xff] = tmp;
|
||||
break;
|
||||
|
||||
case 4: /*f*/
|
||||
case xtRegisterTypeTieRegfile: /*f*/
|
||||
switch (reg->size) {
|
||||
case 4:
|
||||
env->fregs[reg->targno & 0x0f].f32[FP_F32_LOW] = make_float32(tmp);
|
||||
@ -130,7 +166,7 @@ int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
return reg->size;
|
||||
}
|
||||
|
||||
case 8: /*a*/
|
||||
case xtRegisterTypeWindow: /*a*/
|
||||
env->regs[reg->targno & 0x0f] = tmp;
|
||||
break;
|
||||
|
||||
|
@ -95,20 +95,10 @@ void xtensa_finalize_config(XtensaConfig *config)
|
||||
|
||||
if (config->gdb_regmap.num_regs == 0 ||
|
||||
config->gdb_regmap.num_core_regs == 0) {
|
||||
unsigned i;
|
||||
unsigned n_regs = 0;
|
||||
unsigned n_core_regs = 0;
|
||||
|
||||
for (i = 0; config->gdb_regmap.reg[i].targno >= 0; ++i) {
|
||||
if (config->gdb_regmap.reg[i].type != 5 &&
|
||||
config->gdb_regmap.reg[i].type != 6 &&
|
||||
config->gdb_regmap.reg[i].type != 7) {
|
||||
++n_regs;
|
||||
if ((config->gdb_regmap.reg[i].flags & 0x1) == 0) {
|
||||
++n_core_regs;
|
||||
}
|
||||
}
|
||||
}
|
||||
xtensa_count_regs(config, &n_regs, &n_core_regs);
|
||||
if (config->gdb_regmap.num_regs == 0) {
|
||||
config->gdb_regmap.num_regs = n_regs;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user