diff mbox

[qemu,v4] monitor/target-ppc: Define target_get_monitor_def

Message ID 1443766573-47401-1-git-send-email-aik@ozlabs.ru
State New
Headers show

Commit Message

Alexey Kardashevskiy Oct. 2, 2015, 6:16 a.m. UTC
At the moment get_monitor_def() returns only registers from statically
defined monitor_defs array. However there is a lot of BOOK3S SPRs
which are not in the list and cannot be printed from the monitor.

This adds a new target platform hook - target_get_monitor_def().
The hook is called if a register was not found in the static
array returned by the target_monitor_defs() hook.

The hook is only defined for POWERPC, it returns registered
SPRs and fails on unregistered ones providing the user with information
on what is actually supported on the running CPU. The register value is
saved as uint64_t as it is the biggest supported register size;
target_ulong cannot be used because of the stub - it is in a "common"
code and cannot include "cpu.h", etc; this is also why the hook prototype
is redefined in the stub instead of being included from some header.

This replaces static descriptors for GPRs, FPRs, SRs with a helper which
looks for a value in a corresponding array in the CPUPPCState.
The immediate effect is that all 32 SRs can be printed now (instead of 16);
later this can be reused for VSX or TM registers.

While we are here, this adds "cr" as a synonym of "ccr".

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---

Does it make sense to split it into two patches?

---
Changes:
v4:
* rebased on the current upstream which moved MonitorDef to target-ppc
* reverted the change for registers other than GPR/FPR/SPR, such as
FPSCR/PC/MSR/...
* removed CPU hook and made it a stub

v3:
* removed the check for endptr as strtoul() always initializes it
* check if there is any number after r/f/sr and fail if none
* added tolower()/strncasecmp() to support both r/f/sr and R/F/SR

v2:
* handles r**, f**, sr** if their numbers  were parsed completely and correctly
* added "cr" as synonym of "ccr"
---
 include/monitor/hmp-target.h   |   1 +
 monitor.c                      |  10 +-
 stubs/Makefile.objs            |   1 +
 stubs/target-get-monitor-def.c |  31 ++++++
 target-ppc/cpu-qom.h           |   2 +
 target-ppc/monitor.c           | 219 ++++++++++++-----------------------------
 6 files changed, 105 insertions(+), 159 deletions(-)
 create mode 100644 stubs/target-get-monitor-def.c

Comments

Alexey Kardashevskiy Oct. 22, 2015, 7:31 a.m. UTC | #1
On 10/02/2015 04:16 PM, Alexey Kardashevskiy wrote:
> At the moment get_monitor_def() returns only registers from statically
> defined monitor_defs array. However there is a lot of BOOK3S SPRs
> which are not in the list and cannot be printed from the monitor.
>
> This adds a new target platform hook - target_get_monitor_def().
> The hook is called if a register was not found in the static
> array returned by the target_monitor_defs() hook.
>
> The hook is only defined for POWERPC, it returns registered
> SPRs and fails on unregistered ones providing the user with information
> on what is actually supported on the running CPU. The register value is
> saved as uint64_t as it is the biggest supported register size;
> target_ulong cannot be used because of the stub - it is in a "common"
> code and cannot include "cpu.h", etc; this is also why the hook prototype
> is redefined in the stub instead of being included from some header.
>
> This replaces static descriptors for GPRs, FPRs, SRs with a helper which
> looks for a value in a corresponding array in the CPUPPCState.
> The immediate effect is that all 32 SRs can be printed now (instead of 16);
> later this can be reused for VSX or TM registers.
>
> While we are here, this adds "cr" as a synonym of "ccr".
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>
> Does it make sense to split it into two patches?


Ping?


>
> ---
> Changes:
> v4:
> * rebased on the current upstream which moved MonitorDef to target-ppc
> * reverted the change for registers other than GPR/FPR/SPR, such as
> FPSCR/PC/MSR/...
> * removed CPU hook and made it a stub
>
> v3:
> * removed the check for endptr as strtoul() always initializes it
> * check if there is any number after r/f/sr and fail if none
> * added tolower()/strncasecmp() to support both r/f/sr and R/F/SR
>
> v2:
> * handles r**, f**, sr** if their numbers  were parsed completely and correctly
> * added "cr" as synonym of "ccr"
> ---
>   include/monitor/hmp-target.h   |   1 +
>   monitor.c                      |  10 +-
>   stubs/Makefile.objs            |   1 +
>   stubs/target-get-monitor-def.c |  31 ++++++
>   target-ppc/cpu-qom.h           |   2 +
>   target-ppc/monitor.c           | 219 ++++++++++++-----------------------------
>   6 files changed, 105 insertions(+), 159 deletions(-)
>   create mode 100644 stubs/target-get-monitor-def.c
>
> diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h
> index 213566c..bc2c9c0 100644
> --- a/include/monitor/hmp-target.h
> +++ b/include/monitor/hmp-target.h
> @@ -35,6 +35,7 @@ struct MonitorDef {
>   };
>
>   const MonitorDef *target_monitor_defs(void);
> +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval);
>
>   CPUArchState *mon_get_cpu_env(void);
>   CPUState *mon_get_cpu(void);
> diff --git a/monitor.c b/monitor.c
> index 4f1ba2f..83e126a 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2104,6 +2104,8 @@ static int get_monitor_def(target_long *pval, const char *name)
>   {
>       const MonitorDef *md = target_monitor_defs();
>       void *ptr;
> +    uint64_t tmp = 0;
> +    int ret;
>
>       if (md == NULL) {
>           return -1;
> @@ -2131,7 +2133,13 @@ static int get_monitor_def(target_long *pval, const char *name)
>               return 0;
>           }
>       }
> -    return -1;
> +
> +    ret = target_get_monitor_def(mon_get_cpu(), name, &tmp);
> +    if (!ret) {
> +        *pval = (target_long) tmp;
> +    }
> +
> +    return ret;
>   }
>
>   static void next(void)
> diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
> index 85e4e81..91bcdbb 100644
> --- a/stubs/Makefile.objs
> +++ b/stubs/Makefile.objs
> @@ -39,3 +39,4 @@ stub-obj-y += cpus.o
>   stub-obj-y += kvm.o
>   stub-obj-y += qmp_pc_dimm_device_list.o
>   stub-obj-y += target-monitor-defs.o
> +stub-obj-y += target-get-monitor-def.o
> diff --git a/stubs/target-get-monitor-def.c b/stubs/target-get-monitor-def.c
> new file mode 100644
> index 0000000..711a9ae
> --- /dev/null
> +++ b/stubs/target-get-monitor-def.c
> @@ -0,0 +1,31 @@
> +/*
> + *  Stub for target_get_monitor_def.
> + *
> + *  Copyright IBM Corp., 2015
> + *
> + *  Author: Alexey Kardashevskiy <aik@ozlabs.ru>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License,
> + *  or (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "stdint.h"
> +
> +typedef struct CPUState CPUState;
> +
> +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval);
> +
> +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
> +{
> +    return -1;
> +}
> diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
> index 6967a80..bc20504 100644
> --- a/target-ppc/cpu-qom.h
> +++ b/target-ppc/cpu-qom.h
> @@ -118,6 +118,8 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
>                           int flags);
>   void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
>                                fprintf_function cpu_fprintf, int flags);
> +int ppc_cpu_get_monitor_def(CPUState *cs, const char *name,
> +                            uint64_t *pval);
>   hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>   int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
>   int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
> diff --git a/target-ppc/monitor.c b/target-ppc/monitor.c
> index 9cb1fe9..98417f0 100644
> --- a/target-ppc/monitor.c
> +++ b/target-ppc/monitor.c
> @@ -76,176 +76,21 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
>       dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
>   }
>
> -
>   const MonitorDef monitor_defs[] = {
> -    /* General purpose registers */
> -    { "r0", offsetof(CPUPPCState, gpr[0]) },
> -    { "r1", offsetof(CPUPPCState, gpr[1]) },
> -    { "r2", offsetof(CPUPPCState, gpr[2]) },
> -    { "r3", offsetof(CPUPPCState, gpr[3]) },
> -    { "r4", offsetof(CPUPPCState, gpr[4]) },
> -    { "r5", offsetof(CPUPPCState, gpr[5]) },
> -    { "r6", offsetof(CPUPPCState, gpr[6]) },
> -    { "r7", offsetof(CPUPPCState, gpr[7]) },
> -    { "r8", offsetof(CPUPPCState, gpr[8]) },
> -    { "r9", offsetof(CPUPPCState, gpr[9]) },
> -    { "r10", offsetof(CPUPPCState, gpr[10]) },
> -    { "r11", offsetof(CPUPPCState, gpr[11]) },
> -    { "r12", offsetof(CPUPPCState, gpr[12]) },
> -    { "r13", offsetof(CPUPPCState, gpr[13]) },
> -    { "r14", offsetof(CPUPPCState, gpr[14]) },
> -    { "r15", offsetof(CPUPPCState, gpr[15]) },
> -    { "r16", offsetof(CPUPPCState, gpr[16]) },
> -    { "r17", offsetof(CPUPPCState, gpr[17]) },
> -    { "r18", offsetof(CPUPPCState, gpr[18]) },
> -    { "r19", offsetof(CPUPPCState, gpr[19]) },
> -    { "r20", offsetof(CPUPPCState, gpr[20]) },
> -    { "r21", offsetof(CPUPPCState, gpr[21]) },
> -    { "r22", offsetof(CPUPPCState, gpr[22]) },
> -    { "r23", offsetof(CPUPPCState, gpr[23]) },
> -    { "r24", offsetof(CPUPPCState, gpr[24]) },
> -    { "r25", offsetof(CPUPPCState, gpr[25]) },
> -    { "r26", offsetof(CPUPPCState, gpr[26]) },
> -    { "r27", offsetof(CPUPPCState, gpr[27]) },
> -    { "r28", offsetof(CPUPPCState, gpr[28]) },
> -    { "r29", offsetof(CPUPPCState, gpr[29]) },
> -    { "r30", offsetof(CPUPPCState, gpr[30]) },
> -    { "r31", offsetof(CPUPPCState, gpr[31]) },
> -    /* Floating point registers */
> -    { "f0", offsetof(CPUPPCState, fpr[0]) },
> -    { "f1", offsetof(CPUPPCState, fpr[1]) },
> -    { "f2", offsetof(CPUPPCState, fpr[2]) },
> -    { "f3", offsetof(CPUPPCState, fpr[3]) },
> -    { "f4", offsetof(CPUPPCState, fpr[4]) },
> -    { "f5", offsetof(CPUPPCState, fpr[5]) },
> -    { "f6", offsetof(CPUPPCState, fpr[6]) },
> -    { "f7", offsetof(CPUPPCState, fpr[7]) },
> -    { "f8", offsetof(CPUPPCState, fpr[8]) },
> -    { "f9", offsetof(CPUPPCState, fpr[9]) },
> -    { "f10", offsetof(CPUPPCState, fpr[10]) },
> -    { "f11", offsetof(CPUPPCState, fpr[11]) },
> -    { "f12", offsetof(CPUPPCState, fpr[12]) },
> -    { "f13", offsetof(CPUPPCState, fpr[13]) },
> -    { "f14", offsetof(CPUPPCState, fpr[14]) },
> -    { "f15", offsetof(CPUPPCState, fpr[15]) },
> -    { "f16", offsetof(CPUPPCState, fpr[16]) },
> -    { "f17", offsetof(CPUPPCState, fpr[17]) },
> -    { "f18", offsetof(CPUPPCState, fpr[18]) },
> -    { "f19", offsetof(CPUPPCState, fpr[19]) },
> -    { "f20", offsetof(CPUPPCState, fpr[20]) },
> -    { "f21", offsetof(CPUPPCState, fpr[21]) },
> -    { "f22", offsetof(CPUPPCState, fpr[22]) },
> -    { "f23", offsetof(CPUPPCState, fpr[23]) },
> -    { "f24", offsetof(CPUPPCState, fpr[24]) },
> -    { "f25", offsetof(CPUPPCState, fpr[25]) },
> -    { "f26", offsetof(CPUPPCState, fpr[26]) },
> -    { "f27", offsetof(CPUPPCState, fpr[27]) },
> -    { "f28", offsetof(CPUPPCState, fpr[28]) },
> -    { "f29", offsetof(CPUPPCState, fpr[29]) },
> -    { "f30", offsetof(CPUPPCState, fpr[30]) },
> -    { "f31", offsetof(CPUPPCState, fpr[31]) },
>       { "fpscr", offsetof(CPUPPCState, fpscr) },
>       /* Next instruction pointer */
>       { "nip|pc", offsetof(CPUPPCState, nip) },
>       { "lr", offsetof(CPUPPCState, lr) },
>       { "ctr", offsetof(CPUPPCState, ctr) },
> +    { "xer", offsetof(CPUPPCState, xer) },
> +    { "msr", offsetof(CPUPPCState, msr) },
>       { "decr", 0, &monitor_get_decr, },
> -    { "ccr", 0, &monitor_get_ccr, },
> +    { "ccr|cr", 0, &monitor_get_ccr, },
>       /* Machine state register */
>       { "msr", 0, &monitor_get_msr, },
>       { "xer", 0, &monitor_get_xer, },
>       { "tbu", 0, &monitor_get_tbu, },
>       { "tbl", 0, &monitor_get_tbl, },
> -    /* Segment registers */
> -    { "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) },
> -    { "sr0", offsetof(CPUPPCState, sr[0]) },
> -    { "sr1", offsetof(CPUPPCState, sr[1]) },
> -    { "sr2", offsetof(CPUPPCState, sr[2]) },
> -    { "sr3", offsetof(CPUPPCState, sr[3]) },
> -    { "sr4", offsetof(CPUPPCState, sr[4]) },
> -    { "sr5", offsetof(CPUPPCState, sr[5]) },
> -    { "sr6", offsetof(CPUPPCState, sr[6]) },
> -    { "sr7", offsetof(CPUPPCState, sr[7]) },
> -    { "sr8", offsetof(CPUPPCState, sr[8]) },
> -    { "sr9", offsetof(CPUPPCState, sr[9]) },
> -    { "sr10", offsetof(CPUPPCState, sr[10]) },
> -    { "sr11", offsetof(CPUPPCState, sr[11]) },
> -    { "sr12", offsetof(CPUPPCState, sr[12]) },
> -    { "sr13", offsetof(CPUPPCState, sr[13]) },
> -    { "sr14", offsetof(CPUPPCState, sr[14]) },
> -    { "sr15", offsetof(CPUPPCState, sr[15]) },
> -    /* Too lazy to put BATs... */
> -    { "pvr", offsetof(CPUPPCState, spr[SPR_PVR]) },
> -
> -    { "srr0", offsetof(CPUPPCState, spr[SPR_SRR0]) },
> -    { "srr1", offsetof(CPUPPCState, spr[SPR_SRR1]) },
> -    { "dar", offsetof(CPUPPCState, spr[SPR_DAR]) },
> -    { "dsisr", offsetof(CPUPPCState, spr[SPR_DSISR]) },
> -    { "cfar", offsetof(CPUPPCState, spr[SPR_CFAR]) },
> -    { "sprg0", offsetof(CPUPPCState, spr[SPR_SPRG0]) },
> -    { "sprg1", offsetof(CPUPPCState, spr[SPR_SPRG1]) },
> -    { "sprg2", offsetof(CPUPPCState, spr[SPR_SPRG2]) },
> -    { "sprg3", offsetof(CPUPPCState, spr[SPR_SPRG3]) },
> -    { "sprg4", offsetof(CPUPPCState, spr[SPR_SPRG4]) },
> -    { "sprg5", offsetof(CPUPPCState, spr[SPR_SPRG5]) },
> -    { "sprg6", offsetof(CPUPPCState, spr[SPR_SPRG6]) },
> -    { "sprg7", offsetof(CPUPPCState, spr[SPR_SPRG7]) },
> -    { "pid", offsetof(CPUPPCState, spr[SPR_BOOKE_PID]) },
> -    { "csrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR0]) },
> -    { "csrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR1]) },
> -    { "esr", offsetof(CPUPPCState, spr[SPR_BOOKE_ESR]) },
> -    { "dear", offsetof(CPUPPCState, spr[SPR_BOOKE_DEAR]) },
> -    { "mcsr", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSR]) },
> -    { "tsr", offsetof(CPUPPCState, spr[SPR_BOOKE_TSR]) },
> -    { "tcr", offsetof(CPUPPCState, spr[SPR_BOOKE_TCR]) },
> -    { "vrsave", offsetof(CPUPPCState, spr[SPR_VRSAVE]) },
> -    { "pir", offsetof(CPUPPCState, spr[SPR_BOOKE_PIR]) },
> -    { "mcsrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR0]) },
> -    { "mcsrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR1]) },
> -    { "decar", offsetof(CPUPPCState, spr[SPR_BOOKE_DECAR]) },
> -    { "ivpr", offsetof(CPUPPCState, spr[SPR_BOOKE_IVPR]) },
> -    { "epcr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPCR]) },
> -    { "sprg8", offsetof(CPUPPCState, spr[SPR_BOOKE_SPRG8]) },
> -    { "ivor0", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR0]) },
> -    { "ivor1", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR1]) },
> -    { "ivor2", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR2]) },
> -    { "ivor3", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR3]) },
> -    { "ivor4", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR4]) },
> -    { "ivor5", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR5]) },
> -    { "ivor6", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR6]) },
> -    { "ivor7", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR7]) },
> -    { "ivor8", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR8]) },
> -    { "ivor9", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR9]) },
> -    { "ivor10", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR10]) },
> -    { "ivor11", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR11]) },
> -    { "ivor12", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR12]) },
> -    { "ivor13", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR13]) },
> -    { "ivor14", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR14]) },
> -    { "ivor15", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR15]) },
> -    { "ivor32", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR32]) },
> -    { "ivor33", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR33]) },
> -    { "ivor34", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR34]) },
> -    { "ivor35", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR35]) },
> -    { "ivor36", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR36]) },
> -    { "ivor37", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR37]) },
> -    { "mas0", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS0]) },
> -    { "mas1", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS1]) },
> -    { "mas2", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS2]) },
> -    { "mas3", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS3]) },
> -    { "mas4", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS4]) },
> -    { "mas6", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS6]) },
> -    { "mas7", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS7]) },
> -    { "mmucfg", offsetof(CPUPPCState, spr[SPR_MMUCFG]) },
> -    { "tlb0cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB0CFG]) },
> -    { "tlb1cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB1CFG]) },
> -    { "epr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPR]) },
> -    { "eplc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPLC]) },
> -    { "epsc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPSC]) },
> -    { "svr", offsetof(CPUPPCState, spr[SPR_E500_SVR]) },
> -    { "mcar", offsetof(CPUPPCState, spr[SPR_Exxx_MCAR]) },
> -    { "pid1", offsetof(CPUPPCState, spr[SPR_BOOKE_PID1]) },
> -    { "pid2", offsetof(CPUPPCState, spr[SPR_BOOKE_PID2]) },
> -    { "hid0", offsetof(CPUPPCState, spr[SPR_HID0]) },
>       { NULL },
>   };
>
> @@ -253,3 +98,61 @@ const MonitorDef *target_monitor_defs(void)
>   {
>       return monitor_defs;
>   }
> +
> +static bool ppc_cpu_get_reg(target_ulong *regs, const char *numstr, int maxnum,
> +                            uint64_t *pval)
> +{
> +    char *endptr = NULL;
> +    int regnum;
> +
> +    if (!*numstr) {
> +        return false;
> +    }
> +
> +    regnum = strtoul(numstr, &endptr, 10);
> +    if (*endptr || (regnum >= maxnum)) {
> +        return false;
> +    }
> +    *pval = regs[regnum];
> +
> +    return true;
> +}
> +
> +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
> +{
> +    int i;
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +
> +    /* General purpose registers */
> +    if ((tolower(name[0]) == 'r') &&
> +        ppc_cpu_get_reg(env->gpr, name + 1, ARRAY_SIZE(env->gpr), pval)) {
> +        return 0;
> +    }
> +
> +    /* Floating point registers */
> +    if ((tolower(name[0]) == 'f') &&
> +        ppc_cpu_get_reg(env->fpr, name + 1, ARRAY_SIZE(env->fpr), pval)) {
> +        return 0;
> +    }
> +
> +    /* Special purpose registers */
> +    for (i = 0; i < ARRAY_SIZE(env->spr_cb); ++i) {
> +        ppc_spr_t *spr = &env->spr_cb[i];
> +
> +        if (spr->name && (strcasecmp(name, spr->name) == 0)) {
> +            *pval = env->spr[i];
> +            return 0;
> +        }
> +    }
> +
> +    /* Segment registers */
> +#if !defined(CONFIG_USER_ONLY)
> +    if ((strncasecmp(name, "sr", 2) == 0) &&
> +        ppc_cpu_get_reg(env->sr, name + 2, ARRAY_SIZE(env->sr), pval)) {
> +        return 0;
> +    }
> +#endif
> +
> +    return -EINVAL;
> +}
>
David Gibson Oct. 22, 2015, 9:20 a.m. UTC | #2
On Thu, Oct 22, 2015 at 06:31:56PM +1100, Alexey Kardashevskiy wrote:
> On 10/02/2015 04:16 PM, Alexey Kardashevskiy wrote:
> >At the moment get_monitor_def() returns only registers from statically
> >defined monitor_defs array. However there is a lot of BOOK3S SPRs
> >which are not in the list and cannot be printed from the monitor.
> >
> >This adds a new target platform hook - target_get_monitor_def().
> >The hook is called if a register was not found in the static
> >array returned by the target_monitor_defs() hook.
> >
> >The hook is only defined for POWERPC, it returns registered
> >SPRs and fails on unregistered ones providing the user with information
> >on what is actually supported on the running CPU. The register value is
> >saved as uint64_t as it is the biggest supported register size;
> >target_ulong cannot be used because of the stub - it is in a "common"
> >code and cannot include "cpu.h", etc; this is also why the hook prototype
> >is redefined in the stub instead of being included from some header.
> >
> >This replaces static descriptors for GPRs, FPRs, SRs with a helper which
> >looks for a value in a corresponding array in the CPUPPCState.
> >The immediate effect is that all 32 SRs can be printed now (instead of 16);
> >later this can be reused for VSX or TM registers.
> >
> >While we are here, this adds "cr" as a synonym of "ccr".
> >
> >Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> >---
> >
> >Does it make sense to split it into two patches?

I asked a while back if your patch or BenH's patch doing a similar
thing was the one I should be looking at, and I never got a reply.
Benjamin Herrenschmidt Oct. 23, 2015, 10:22 p.m. UTC | #3
On Thu, 2015-10-22 at 20:20 +1100, David Gibson wrote:
> I asked a while back if your patch or BenH's patch doing a similar
> thing was the one I should be looking at, and I never got a reply.

You must have missed it ... go for Alexey latest

Cheers,
Ben.
David Gibson Nov. 11, 2015, 2:27 a.m. UTC | #4
On Fri, Oct 02, 2015 at 04:16:13PM +1000, Alexey Kardashevskiy wrote:
> At the moment get_monitor_def() returns only registers from statically
> defined monitor_defs array. However there is a lot of BOOK3S SPRs
> which are not in the list and cannot be printed from the monitor.
> 
> This adds a new target platform hook - target_get_monitor_def().
> The hook is called if a register was not found in the static
> array returned by the target_monitor_defs() hook.
> 
> The hook is only defined for POWERPC, it returns registered
> SPRs and fails on unregistered ones providing the user with information
> on what is actually supported on the running CPU. The register value is
> saved as uint64_t as it is the biggest supported register size;
> target_ulong cannot be used because of the stub - it is in a "common"
> code and cannot include "cpu.h", etc; this is also why the hook prototype
> is redefined in the stub instead of being included from some header.
> 
> This replaces static descriptors for GPRs, FPRs, SRs with a helper which
> looks for a value in a corresponding array in the CPUPPCState.
> The immediate effect is that all 32 SRs can be printed now (instead of 16);
> later this can be reused for VSX or TM registers.
> 
> While we are here, this adds "cr" as a synonym of "ccr".

Sorry I've taken so long to look at this.

This is a big improvement over the current approach.

> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

(although I note one small nit below)

> ---
> 
> Does it make sense to split it into two patches?

Meaning one which adds the hook to the monitor, and another which
implements it for ppc?  Maybe.

I'd like to take this, but I'm not sure whether it's reasonable for
the small generic monitor change to go through the ppc tree.  Peter,
Paolo, opinion?


[snip]
> diff --git a/target-ppc/monitor.c b/target-ppc/monitor.c
> index 9cb1fe9..98417f0 100644
> --- a/target-ppc/monitor.c
> +++ b/target-ppc/monitor.c
> @@ -76,176 +76,21 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
>      dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
>  }
>  
> -
>  const MonitorDef monitor_defs[] = {
> -    /* General purpose registers */
> -    { "r0", offsetof(CPUPPCState, gpr[0]) },
> -    { "r1", offsetof(CPUPPCState, gpr[1]) },
> -    { "r2", offsetof(CPUPPCState, gpr[2]) },
> -    { "r3", offsetof(CPUPPCState, gpr[3]) },
> -    { "r4", offsetof(CPUPPCState, gpr[4]) },
> -    { "r5", offsetof(CPUPPCState, gpr[5]) },
> -    { "r6", offsetof(CPUPPCState, gpr[6]) },
> -    { "r7", offsetof(CPUPPCState, gpr[7]) },
> -    { "r8", offsetof(CPUPPCState, gpr[8]) },
> -    { "r9", offsetof(CPUPPCState, gpr[9]) },
> -    { "r10", offsetof(CPUPPCState, gpr[10]) },
> -    { "r11", offsetof(CPUPPCState, gpr[11]) },
> -    { "r12", offsetof(CPUPPCState, gpr[12]) },
> -    { "r13", offsetof(CPUPPCState, gpr[13]) },
> -    { "r14", offsetof(CPUPPCState, gpr[14]) },
> -    { "r15", offsetof(CPUPPCState, gpr[15]) },
> -    { "r16", offsetof(CPUPPCState, gpr[16]) },
> -    { "r17", offsetof(CPUPPCState, gpr[17]) },
> -    { "r18", offsetof(CPUPPCState, gpr[18]) },
> -    { "r19", offsetof(CPUPPCState, gpr[19]) },
> -    { "r20", offsetof(CPUPPCState, gpr[20]) },
> -    { "r21", offsetof(CPUPPCState, gpr[21]) },
> -    { "r22", offsetof(CPUPPCState, gpr[22]) },
> -    { "r23", offsetof(CPUPPCState, gpr[23]) },
> -    { "r24", offsetof(CPUPPCState, gpr[24]) },
> -    { "r25", offsetof(CPUPPCState, gpr[25]) },
> -    { "r26", offsetof(CPUPPCState, gpr[26]) },
> -    { "r27", offsetof(CPUPPCState, gpr[27]) },
> -    { "r28", offsetof(CPUPPCState, gpr[28]) },
> -    { "r29", offsetof(CPUPPCState, gpr[29]) },
> -    { "r30", offsetof(CPUPPCState, gpr[30]) },
> -    { "r31", offsetof(CPUPPCState, gpr[31]) },
> -    /* Floating point registers */
> -    { "f0", offsetof(CPUPPCState, fpr[0]) },
> -    { "f1", offsetof(CPUPPCState, fpr[1]) },
> -    { "f2", offsetof(CPUPPCState, fpr[2]) },
> -    { "f3", offsetof(CPUPPCState, fpr[3]) },
> -    { "f4", offsetof(CPUPPCState, fpr[4]) },
> -    { "f5", offsetof(CPUPPCState, fpr[5]) },
> -    { "f6", offsetof(CPUPPCState, fpr[6]) },
> -    { "f7", offsetof(CPUPPCState, fpr[7]) },
> -    { "f8", offsetof(CPUPPCState, fpr[8]) },
> -    { "f9", offsetof(CPUPPCState, fpr[9]) },
> -    { "f10", offsetof(CPUPPCState, fpr[10]) },
> -    { "f11", offsetof(CPUPPCState, fpr[11]) },
> -    { "f12", offsetof(CPUPPCState, fpr[12]) },
> -    { "f13", offsetof(CPUPPCState, fpr[13]) },
> -    { "f14", offsetof(CPUPPCState, fpr[14]) },
> -    { "f15", offsetof(CPUPPCState, fpr[15]) },
> -    { "f16", offsetof(CPUPPCState, fpr[16]) },
> -    { "f17", offsetof(CPUPPCState, fpr[17]) },
> -    { "f18", offsetof(CPUPPCState, fpr[18]) },
> -    { "f19", offsetof(CPUPPCState, fpr[19]) },
> -    { "f20", offsetof(CPUPPCState, fpr[20]) },
> -    { "f21", offsetof(CPUPPCState, fpr[21]) },
> -    { "f22", offsetof(CPUPPCState, fpr[22]) },
> -    { "f23", offsetof(CPUPPCState, fpr[23]) },
> -    { "f24", offsetof(CPUPPCState, fpr[24]) },
> -    { "f25", offsetof(CPUPPCState, fpr[25]) },
> -    { "f26", offsetof(CPUPPCState, fpr[26]) },
> -    { "f27", offsetof(CPUPPCState, fpr[27]) },
> -    { "f28", offsetof(CPUPPCState, fpr[28]) },
> -    { "f29", offsetof(CPUPPCState, fpr[29]) },
> -    { "f30", offsetof(CPUPPCState, fpr[30]) },
> -    { "f31", offsetof(CPUPPCState, fpr[31]) },
>      { "fpscr", offsetof(CPUPPCState, fpscr) },
>      /* Next instruction pointer */
>      { "nip|pc", offsetof(CPUPPCState, nip) },
>      { "lr", offsetof(CPUPPCState, lr) },
>      { "ctr", offsetof(CPUPPCState, ctr) },
> +    { "xer", offsetof(CPUPPCState, xer) },
> +    { "msr", offsetof(CPUPPCState, msr) },

Nit: "msr"  and "xer" are already listed below, so I think they're
listed twice after this patch.

>      { "decr", 0, &monitor_get_decr, },
> -    { "ccr", 0, &monitor_get_ccr, },
> +    { "ccr|cr", 0, &monitor_get_ccr, },
>      /* Machine state register */
>      { "msr", 0, &monitor_get_msr, },
>      { "xer", 0, &monitor_get_xer, },

..here.
Paolo Bonzini Nov. 11, 2015, 10:21 a.m. UTC | #5
On 11/11/2015 03:27, David Gibson wrote:
> Meaning one which adds the hook to the monitor, and another which
> implements it for ppc?  Maybe.
> 
> I'd like to take this, but I'm not sure whether it's reasonable for
> the small generic monitor change to go through the ppc tree.  Peter,
> Paolo, opinion?

I'm not a monitor maintainer, but I think it's okay since there is
none. :)

We probably should replace target_monitor_defs() with an implementation
of target_get_monitor_def on all targets.  It can just pass a MonitorDef
array to a common function, i.e.

int lookup_monitor_def(MonitorDef *def, void *base, const char *name, uint64_t *pval)

static int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
{
    return lookup_monitor_def(monitor_defs, cs->env_ptr, name, pval);
}

I don't want you to do it now, but we should add it to the wiki
BiteSizedTasks so we don't forget.

Paolo
diff mbox

Patch

diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h
index 213566c..bc2c9c0 100644
--- a/include/monitor/hmp-target.h
+++ b/include/monitor/hmp-target.h
@@ -35,6 +35,7 @@  struct MonitorDef {
 };
 
 const MonitorDef *target_monitor_defs(void);
+int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval);
 
 CPUArchState *mon_get_cpu_env(void);
 CPUState *mon_get_cpu(void);
diff --git a/monitor.c b/monitor.c
index 4f1ba2f..83e126a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2104,6 +2104,8 @@  static int get_monitor_def(target_long *pval, const char *name)
 {
     const MonitorDef *md = target_monitor_defs();
     void *ptr;
+    uint64_t tmp = 0;
+    int ret;
 
     if (md == NULL) {
         return -1;
@@ -2131,7 +2133,13 @@  static int get_monitor_def(target_long *pval, const char *name)
             return 0;
         }
     }
-    return -1;
+
+    ret = target_get_monitor_def(mon_get_cpu(), name, &tmp);
+    if (!ret) {
+        *pval = (target_long) tmp;
+    }
+
+    return ret;
 }
 
 static void next(void)
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 85e4e81..91bcdbb 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -39,3 +39,4 @@  stub-obj-y += cpus.o
 stub-obj-y += kvm.o
 stub-obj-y += qmp_pc_dimm_device_list.o
 stub-obj-y += target-monitor-defs.o
+stub-obj-y += target-get-monitor-def.o
diff --git a/stubs/target-get-monitor-def.c b/stubs/target-get-monitor-def.c
new file mode 100644
index 0000000..711a9ae
--- /dev/null
+++ b/stubs/target-get-monitor-def.c
@@ -0,0 +1,31 @@ 
+/*
+ *  Stub for target_get_monitor_def.
+ *
+ *  Copyright IBM Corp., 2015
+ *
+ *  Author: Alexey Kardashevskiy <aik@ozlabs.ru>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "stdint.h"
+
+typedef struct CPUState CPUState;
+
+int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval);
+
+int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
+{
+    return -1;
+}
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 6967a80..bc20504 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -118,6 +118,8 @@  void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
+int ppc_cpu_get_monitor_def(CPUState *cs, const char *name,
+                            uint64_t *pval);
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target-ppc/monitor.c b/target-ppc/monitor.c
index 9cb1fe9..98417f0 100644
--- a/target-ppc/monitor.c
+++ b/target-ppc/monitor.c
@@ -76,176 +76,21 @@  void hmp_info_tlb(Monitor *mon, const QDict *qdict)
     dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
 }
 
-
 const MonitorDef monitor_defs[] = {
-    /* General purpose registers */
-    { "r0", offsetof(CPUPPCState, gpr[0]) },
-    { "r1", offsetof(CPUPPCState, gpr[1]) },
-    { "r2", offsetof(CPUPPCState, gpr[2]) },
-    { "r3", offsetof(CPUPPCState, gpr[3]) },
-    { "r4", offsetof(CPUPPCState, gpr[4]) },
-    { "r5", offsetof(CPUPPCState, gpr[5]) },
-    { "r6", offsetof(CPUPPCState, gpr[6]) },
-    { "r7", offsetof(CPUPPCState, gpr[7]) },
-    { "r8", offsetof(CPUPPCState, gpr[8]) },
-    { "r9", offsetof(CPUPPCState, gpr[9]) },
-    { "r10", offsetof(CPUPPCState, gpr[10]) },
-    { "r11", offsetof(CPUPPCState, gpr[11]) },
-    { "r12", offsetof(CPUPPCState, gpr[12]) },
-    { "r13", offsetof(CPUPPCState, gpr[13]) },
-    { "r14", offsetof(CPUPPCState, gpr[14]) },
-    { "r15", offsetof(CPUPPCState, gpr[15]) },
-    { "r16", offsetof(CPUPPCState, gpr[16]) },
-    { "r17", offsetof(CPUPPCState, gpr[17]) },
-    { "r18", offsetof(CPUPPCState, gpr[18]) },
-    { "r19", offsetof(CPUPPCState, gpr[19]) },
-    { "r20", offsetof(CPUPPCState, gpr[20]) },
-    { "r21", offsetof(CPUPPCState, gpr[21]) },
-    { "r22", offsetof(CPUPPCState, gpr[22]) },
-    { "r23", offsetof(CPUPPCState, gpr[23]) },
-    { "r24", offsetof(CPUPPCState, gpr[24]) },
-    { "r25", offsetof(CPUPPCState, gpr[25]) },
-    { "r26", offsetof(CPUPPCState, gpr[26]) },
-    { "r27", offsetof(CPUPPCState, gpr[27]) },
-    { "r28", offsetof(CPUPPCState, gpr[28]) },
-    { "r29", offsetof(CPUPPCState, gpr[29]) },
-    { "r30", offsetof(CPUPPCState, gpr[30]) },
-    { "r31", offsetof(CPUPPCState, gpr[31]) },
-    /* Floating point registers */
-    { "f0", offsetof(CPUPPCState, fpr[0]) },
-    { "f1", offsetof(CPUPPCState, fpr[1]) },
-    { "f2", offsetof(CPUPPCState, fpr[2]) },
-    { "f3", offsetof(CPUPPCState, fpr[3]) },
-    { "f4", offsetof(CPUPPCState, fpr[4]) },
-    { "f5", offsetof(CPUPPCState, fpr[5]) },
-    { "f6", offsetof(CPUPPCState, fpr[6]) },
-    { "f7", offsetof(CPUPPCState, fpr[7]) },
-    { "f8", offsetof(CPUPPCState, fpr[8]) },
-    { "f9", offsetof(CPUPPCState, fpr[9]) },
-    { "f10", offsetof(CPUPPCState, fpr[10]) },
-    { "f11", offsetof(CPUPPCState, fpr[11]) },
-    { "f12", offsetof(CPUPPCState, fpr[12]) },
-    { "f13", offsetof(CPUPPCState, fpr[13]) },
-    { "f14", offsetof(CPUPPCState, fpr[14]) },
-    { "f15", offsetof(CPUPPCState, fpr[15]) },
-    { "f16", offsetof(CPUPPCState, fpr[16]) },
-    { "f17", offsetof(CPUPPCState, fpr[17]) },
-    { "f18", offsetof(CPUPPCState, fpr[18]) },
-    { "f19", offsetof(CPUPPCState, fpr[19]) },
-    { "f20", offsetof(CPUPPCState, fpr[20]) },
-    { "f21", offsetof(CPUPPCState, fpr[21]) },
-    { "f22", offsetof(CPUPPCState, fpr[22]) },
-    { "f23", offsetof(CPUPPCState, fpr[23]) },
-    { "f24", offsetof(CPUPPCState, fpr[24]) },
-    { "f25", offsetof(CPUPPCState, fpr[25]) },
-    { "f26", offsetof(CPUPPCState, fpr[26]) },
-    { "f27", offsetof(CPUPPCState, fpr[27]) },
-    { "f28", offsetof(CPUPPCState, fpr[28]) },
-    { "f29", offsetof(CPUPPCState, fpr[29]) },
-    { "f30", offsetof(CPUPPCState, fpr[30]) },
-    { "f31", offsetof(CPUPPCState, fpr[31]) },
     { "fpscr", offsetof(CPUPPCState, fpscr) },
     /* Next instruction pointer */
     { "nip|pc", offsetof(CPUPPCState, nip) },
     { "lr", offsetof(CPUPPCState, lr) },
     { "ctr", offsetof(CPUPPCState, ctr) },
+    { "xer", offsetof(CPUPPCState, xer) },
+    { "msr", offsetof(CPUPPCState, msr) },
     { "decr", 0, &monitor_get_decr, },
-    { "ccr", 0, &monitor_get_ccr, },
+    { "ccr|cr", 0, &monitor_get_ccr, },
     /* Machine state register */
     { "msr", 0, &monitor_get_msr, },
     { "xer", 0, &monitor_get_xer, },
     { "tbu", 0, &monitor_get_tbu, },
     { "tbl", 0, &monitor_get_tbl, },
-    /* Segment registers */
-    { "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) },
-    { "sr0", offsetof(CPUPPCState, sr[0]) },
-    { "sr1", offsetof(CPUPPCState, sr[1]) },
-    { "sr2", offsetof(CPUPPCState, sr[2]) },
-    { "sr3", offsetof(CPUPPCState, sr[3]) },
-    { "sr4", offsetof(CPUPPCState, sr[4]) },
-    { "sr5", offsetof(CPUPPCState, sr[5]) },
-    { "sr6", offsetof(CPUPPCState, sr[6]) },
-    { "sr7", offsetof(CPUPPCState, sr[7]) },
-    { "sr8", offsetof(CPUPPCState, sr[8]) },
-    { "sr9", offsetof(CPUPPCState, sr[9]) },
-    { "sr10", offsetof(CPUPPCState, sr[10]) },
-    { "sr11", offsetof(CPUPPCState, sr[11]) },
-    { "sr12", offsetof(CPUPPCState, sr[12]) },
-    { "sr13", offsetof(CPUPPCState, sr[13]) },
-    { "sr14", offsetof(CPUPPCState, sr[14]) },
-    { "sr15", offsetof(CPUPPCState, sr[15]) },
-    /* Too lazy to put BATs... */
-    { "pvr", offsetof(CPUPPCState, spr[SPR_PVR]) },
-
-    { "srr0", offsetof(CPUPPCState, spr[SPR_SRR0]) },
-    { "srr1", offsetof(CPUPPCState, spr[SPR_SRR1]) },
-    { "dar", offsetof(CPUPPCState, spr[SPR_DAR]) },
-    { "dsisr", offsetof(CPUPPCState, spr[SPR_DSISR]) },
-    { "cfar", offsetof(CPUPPCState, spr[SPR_CFAR]) },
-    { "sprg0", offsetof(CPUPPCState, spr[SPR_SPRG0]) },
-    { "sprg1", offsetof(CPUPPCState, spr[SPR_SPRG1]) },
-    { "sprg2", offsetof(CPUPPCState, spr[SPR_SPRG2]) },
-    { "sprg3", offsetof(CPUPPCState, spr[SPR_SPRG3]) },
-    { "sprg4", offsetof(CPUPPCState, spr[SPR_SPRG4]) },
-    { "sprg5", offsetof(CPUPPCState, spr[SPR_SPRG5]) },
-    { "sprg6", offsetof(CPUPPCState, spr[SPR_SPRG6]) },
-    { "sprg7", offsetof(CPUPPCState, spr[SPR_SPRG7]) },
-    { "pid", offsetof(CPUPPCState, spr[SPR_BOOKE_PID]) },
-    { "csrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR0]) },
-    { "csrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR1]) },
-    { "esr", offsetof(CPUPPCState, spr[SPR_BOOKE_ESR]) },
-    { "dear", offsetof(CPUPPCState, spr[SPR_BOOKE_DEAR]) },
-    { "mcsr", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSR]) },
-    { "tsr", offsetof(CPUPPCState, spr[SPR_BOOKE_TSR]) },
-    { "tcr", offsetof(CPUPPCState, spr[SPR_BOOKE_TCR]) },
-    { "vrsave", offsetof(CPUPPCState, spr[SPR_VRSAVE]) },
-    { "pir", offsetof(CPUPPCState, spr[SPR_BOOKE_PIR]) },
-    { "mcsrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR0]) },
-    { "mcsrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR1]) },
-    { "decar", offsetof(CPUPPCState, spr[SPR_BOOKE_DECAR]) },
-    { "ivpr", offsetof(CPUPPCState, spr[SPR_BOOKE_IVPR]) },
-    { "epcr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPCR]) },
-    { "sprg8", offsetof(CPUPPCState, spr[SPR_BOOKE_SPRG8]) },
-    { "ivor0", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR0]) },
-    { "ivor1", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR1]) },
-    { "ivor2", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR2]) },
-    { "ivor3", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR3]) },
-    { "ivor4", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR4]) },
-    { "ivor5", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR5]) },
-    { "ivor6", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR6]) },
-    { "ivor7", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR7]) },
-    { "ivor8", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR8]) },
-    { "ivor9", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR9]) },
-    { "ivor10", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR10]) },
-    { "ivor11", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR11]) },
-    { "ivor12", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR12]) },
-    { "ivor13", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR13]) },
-    { "ivor14", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR14]) },
-    { "ivor15", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR15]) },
-    { "ivor32", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR32]) },
-    { "ivor33", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR33]) },
-    { "ivor34", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR34]) },
-    { "ivor35", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR35]) },
-    { "ivor36", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR36]) },
-    { "ivor37", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR37]) },
-    { "mas0", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS0]) },
-    { "mas1", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS1]) },
-    { "mas2", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS2]) },
-    { "mas3", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS3]) },
-    { "mas4", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS4]) },
-    { "mas6", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS6]) },
-    { "mas7", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS7]) },
-    { "mmucfg", offsetof(CPUPPCState, spr[SPR_MMUCFG]) },
-    { "tlb0cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB0CFG]) },
-    { "tlb1cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB1CFG]) },
-    { "epr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPR]) },
-    { "eplc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPLC]) },
-    { "epsc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPSC]) },
-    { "svr", offsetof(CPUPPCState, spr[SPR_E500_SVR]) },
-    { "mcar", offsetof(CPUPPCState, spr[SPR_Exxx_MCAR]) },
-    { "pid1", offsetof(CPUPPCState, spr[SPR_BOOKE_PID1]) },
-    { "pid2", offsetof(CPUPPCState, spr[SPR_BOOKE_PID2]) },
-    { "hid0", offsetof(CPUPPCState, spr[SPR_HID0]) },
     { NULL },
 };
 
@@ -253,3 +98,61 @@  const MonitorDef *target_monitor_defs(void)
 {
     return monitor_defs;
 }
+
+static bool ppc_cpu_get_reg(target_ulong *regs, const char *numstr, int maxnum,
+                            uint64_t *pval)
+{
+    char *endptr = NULL;
+    int regnum;
+
+    if (!*numstr) {
+        return false;
+    }
+
+    regnum = strtoul(numstr, &endptr, 10);
+    if (*endptr || (regnum >= maxnum)) {
+        return false;
+    }
+    *pval = regs[regnum];
+
+    return true;
+}
+
+int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
+{
+    int i;
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    /* General purpose registers */
+    if ((tolower(name[0]) == 'r') &&
+        ppc_cpu_get_reg(env->gpr, name + 1, ARRAY_SIZE(env->gpr), pval)) {
+        return 0;
+    }
+
+    /* Floating point registers */
+    if ((tolower(name[0]) == 'f') &&
+        ppc_cpu_get_reg(env->fpr, name + 1, ARRAY_SIZE(env->fpr), pval)) {
+        return 0;
+    }
+
+    /* Special purpose registers */
+    for (i = 0; i < ARRAY_SIZE(env->spr_cb); ++i) {
+        ppc_spr_t *spr = &env->spr_cb[i];
+
+        if (spr->name && (strcasecmp(name, spr->name) == 0)) {
+            *pval = env->spr[i];
+            return 0;
+        }
+    }
+
+    /* Segment registers */
+#if !defined(CONFIG_USER_ONLY)
+    if ((strncasecmp(name, "sr", 2) == 0) &&
+        ppc_cpu_get_reg(env->sr, name + 2, ARRAY_SIZE(env->sr), pval)) {
+        return 0;
+    }
+#endif
+
+    return -EINVAL;
+}