[Pdbg] [PATCH 8/8] pdbg: Use new command parsing

Rashmica Gupta rashmica.g at gmail.com
Fri Jun 29 16:36:48 AEST 2018


On Wed, Jun 20, 2018, 3:35 PM Alistair Popple <alistair at popple.id.au> wrote:

> This switches all commands except the htm command to use the new
> command/option
> parsing code. For the moment we leave the usage help and generic targeting
> flag
> processing alone, but future changes should allow this to also use the
> common
> parsing code.
>
> Signed-off-by: Alistair Popple <alistair at popple.id.au>
> ---
>  Makefile.am  |   1 +
>  src/cfam.c   |  55 ++++++--------------
>  src/cfam.h   |  18 -------
>  src/main.c   | 125 ++++++++++++++++++++++++++++-----------------
>  src/mem.c    | 124 ++++++++------------------------------------
>  src/mem.h    |  20 --------
>  src/reg.c    | 164
> +++++++++++++++--------------------------------------------
>  src/reg.h    |  20 --------
>  src/ring.c   |  32 ++----------
>  src/ring.h   |  17 -------
>  src/scom.c   |  54 +++++---------------
>  src/scom.h   |  18 -------
>  src/thread.c |  87 ++++++++++++++++++++++---------
>  src/thread.h |  23 ---------
>  14 files changed, 237 insertions(+), 521 deletions(-)
>  delete mode 100644 src/cfam.h
>  delete mode 100644 src/mem.h
>  delete mode 100644 src/reg.h
>  delete mode 100644 src/ring.h
>  delete mode 100644 src/scom.h
>  delete mode 100644 src/thread.h
>
> diff --git a/Makefile.am b/Makefile.am
> index 23f2080..4e0dce2 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -39,6 +39,7 @@ pdbg_SOURCES = \
>         src/ring.c \
>         src/htm.c \
>         src/progress.c \
> +       src/parsers.c \
>         src/optcmd.c \
>         src/options_ at ARCH@.c
>
> diff --git a/src/cfam.c b/src/cfam.c
> index 269123e..6dab388 100644
> --- a/src/cfam.c
> +++ b/src/cfam.c
> @@ -20,8 +20,9 @@
>  #include <inttypes.h>
>
>  #include "main.h"
> +#include "optcmd.h"
>
> -static int getcfam(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *unused)
> +static int _getcfam(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *unused)
>  {
>         uint32_t value;
>
> @@ -33,7 +34,15 @@ static int getcfam(struct pdbg_target *target, uint32_t
> index, uint64_t *addr, u
>         return 1;
>  }
>
> -static int putcfam(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *data)
> +static int getcfam(uint32_t addr)
> +{
> +       uint64_t addr64 = addr;
> +
> +       return for_each_target("fsi", _getcfam, &addr64, NULL);
> +}
> +OPTCMD_DEFINE_CMD_WITH_ARGS(getcfam, getcfam, (ADDRESS32));
> +
> +static int _putcfam(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *data)
>  {
>         if (fsi_write(target, *addr, *data))
>                 return 0;
> @@ -41,44 +50,10 @@ static int putcfam(struct pdbg_target *target,
> uint32_t index, uint64_t *addr, u
>         return 1;
>  }
>
> -int handle_cfams(int optind, int argc, char *argv[])
> +static int putcfam(uint32_t addr, uint32_t data)
>  {
> -       uint64_t addr;
> -       char *endptr;
> -
> -       if (optind + 1 >= argc) {
> -               printf("%s: command '%s' requires an address\n", argv[0],
> argv[optind]);
> -               return -1;
> -       }
> -
> -       errno = 0;
> -       addr = strtoull(argv[optind + 1], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse address '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -               return -1;
> -       }
> +       uint64_t addr64 = addr, data64 = data;
>
> -       if (strcmp(argv[optind], "putcfam") == 0) {
> -               uint64_t data;
> -
> -               if (optind + 2 >= argc) {
> -                       printf("%s: command '%s' requires data\n",
> argv[0], argv[optind]);
> -                       return -1;
> -               }
> -
> -               errno = 0;
> -               data = strtoull(argv[optind + 2], &endptr, 0);
> -               if (errno || *endptr != '\0') {
> -                       printf("%s: command '%s' couldn't parse data
> '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -                       return -1;
> -               }
> -
> -               return for_each_target("fsi", putcfam, &addr, &data);
> -       }
> -
> -       return for_each_target("fsi", getcfam, &addr, NULL);
> +       return for_each_target("fsi", _putcfam, &addr64, &data64);
>  }
> -
> -
> +OPTCMD_DEFINE_CMD_WITH_ARGS(putcfam, putcfam, (ADDRESS32, DATA32));
> diff --git a/src/cfam.h b/src/cfam.h
> deleted file mode 100644
> index 997ed3d..0000000
> --- a/src/cfam.h
> +++ /dev/null
> @@ -1,18 +0,0 @@
> -/* Copyright 2017 IBM Corp.
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> - * implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -#include <inttypes.h>
> -
> -int handle_cfams(int optind, int argc, char *argv[]);
> diff --git a/src/main.c b/src/main.c
> index cf9a3b2..1cfaca7 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -34,14 +34,9 @@
>  #include <target.h>
>
>  #include "main.h"
> -#include "cfam.h"
> -#include "scom.h"
> -#include "reg.h"
> -#include "ring.h"
> -#include "mem.h"
> -#include "thread.h"
>  #include "htm.h"
>  #include "options.h"
> +#include "optcmd.h"
>
>  #define PR_ERROR(x, args...) \
>         pdbg_log(PDBG_ERROR, x, ##args)
> @@ -77,44 +72,64 @@ static int **processorsel[MAX_PROCESSORS];
>  static int *chipsel[MAX_PROCESSORS][MAX_CHIPS];
>  static int threadsel[MAX_PROCESSORS][MAX_CHIPS][MAX_THREADS];
>
> -static int handle_probe(int optind, int argc, char *argv[]);
> -static int handle_release(int optind, int argc, char *argv[]);
> +static int probe(void);
> +static int release(void);
> +
> +/* TODO: We are repeating ourselves here. A little bit more macro magic
> could
> + * easily fix this but I was hesitant to introduce too much magic all at
> + * once. */
> +extern struct optcmd_cmd
> +       optcmd_getscom, optcmd_putscom, optcmd_getcfam, optcmd_putcfam,
> +       optcmd_getgpr, optcmd_putgpr, optcmd_getspr, optcmd_putspr,
> +       optcmd_getnia, optcmd_putnia, optcmd_getmsr, optcmd_putmsr,
> +       optcmd_getring, optcmd_start, optcmd_stop, optcmd_step,
> +       optcmd_threadstatus, optcmd_sreset, optcmd_regs, optcmd_probe,
> +       optcmd_getmem, optcmd_putmem;
> +
> +static struct optcmd_cmd *cmds[] = {
> +       &optcmd_getscom, &optcmd_putscom, &optcmd_getcfam, &optcmd_putcfam,
> +       &optcmd_getgpr, &optcmd_putgpr, &optcmd_getspr, &optcmd_putspr,
> +       &optcmd_getnia, &optcmd_putnia, &optcmd_getmsr, &optcmd_putmsr,
> +       &optcmd_getring, &optcmd_start, &optcmd_stop, &optcmd_step,
> +       &optcmd_threadstatus, &optcmd_sreset, &optcmd_regs, &optcmd_probe,
> +       &optcmd_getmem, &optcmd_putmem,
> +};
>
> +/* Purely for printing usage text. We could integrate printing argument
> and flag
> + * help into optcmd if desired. */
>  struct action {
>         const char *name;
>         const char *args;
>         const char *desc;
> -       int (*fn)(int, int, char **);
>  };
>
>  static struct action actions[] = {
> -       { "getgpr",  "<gpr>", "Read General Purpose Register (GPR)",
> &handle_gpr },
> -       { "putgpr",  "<gpr> <value>", "Write General Purpose Register
> (GPR)", &handle_gpr },
> -       { "getnia",  "", "Get Next Instruction Address (NIA)", &handle_nia
> },
> -       { "putnia",  "<value>", "Write Next Instrution Address (NIA)",
> &handle_nia },
> -       { "getspr",  "<spr>", "Get Special Purpose Register (SPR)",
> &handle_spr },
> -       { "putspr",  "<spr> <value>", "Write Special Purpose Register
> (SPR)", &handle_spr },
> -       { "getmsr",  "", "Get Machine State Register (MSR)", &handle_msr },
> -       { "putmsr",  "<value>", "Write Machine State Register (MSR)",
> &handle_msr },
> -       { "getring", "<addr> <len>", "Read a ring. Length must be
> correct", &handle_getring },
> -       { "start",   "", "Start thread", &thread_start },
> -       { "step",    "<count>", "Set a thread <count> instructions",
> &thread_step },
> -       { "stop",    "", "Stop thread", &thread_stop },
> -       { "htm", "core|nest start|stop|status|reset|dump|trace|analyse",
> "Hardware Trace Macro", &run_htm },
> -       { "release", "", "Should be called after pdbg work is finished, to
> release special wakeups and other resources.", &handle_release},
> -       { "probe", "", "", &handle_probe },
> -       { "getcfam", "<address>", "Read system cfam", &handle_cfams },
> -       { "putcfam", "<address> <value> [<mask>]", "Write system cfam",
> &handle_cfams },
> -       { "getscom", "<address>", "Read system scom", &handle_scoms },
> -       { "putscom", "<address> <value> [<mask>]", "Write system scom",
> &handle_scoms },
> -       { "getmem",  "<address> <count>", "Read system memory",
> &handle_mem },
> -       { "putmem",  "<address>", "Write to system memory", &handle_mem },
> -       { "threadstatus", "", "Print the status of a thread",
> &thread_status_print },
> -       { "sreset",  "", "Reset", &thread_sreset },
> -       { "regs",  "", "State", &thread_state },
> +       { "getgpr",  "<gpr>", "Read General Purpose Register (GPR)" },
> +       { "putgpr",  "<gpr> <value>", "Write General Purpose Register
> (GPR)" },
> +       { "getnia",  "", "Get Next Instruction Address (NIA)" },
> +       { "putnia",  "<value>", "Write Next Instrution Address (NIA)" },
> +       { "getspr",  "<spr>", "Get Special Purpose Register (SPR)" },
> +       { "putspr",  "<spr> <value>", "Write Special Purpose Register
> (SPR)" },
> +       { "getmsr",  "", "Get Machine State Register (MSR)" },
> +       { "putmsr",  "<value>", "Write Machine State Register (MSR)" },
> +       { "getring", "<addr> <len>", "Read a ring. Length must be correct"
> },
> +       { "start",   "", "Start thread" },
> +       { "step",    "<count>", "Set a thread <count> instructions" },
> +       { "stop",    "", "Stop thread" },
> +       { "htm", "core|nest start|stop|status|reset|dump|trace|analyse",
> "Hardware Trace Macro" },
> +       { "release", "", "Should be called after pdbg work is finished" },
> +       { "probe", "", "" },
> +       { "getcfam", "<address>", "Read system cfam" },
> +       { "putcfam", "<address> <value> [<mask>]", "Write system cfam" },
> +       { "getscom", "<address>", "Read system scom" },
> +       { "putscom", "<address> <value> [<mask>]", "Write system scom" },
> +       { "getmem",  "<address> <count>", "Read system memory" },
> +       { "putmem",  "<address>", "Write to system memory" },
> +       { "threadstatus", "", "Print the status of a thread" },
> +       { "sreset",  "", "Reset" },
> +       { "regs",  "", "State" },
>  };
>
> -
>  static void print_usage(char *pname)
>  {
>         int i;
> @@ -600,7 +615,7 @@ static void release_target(struct pdbg_target *target)
>         pdbg_target_release(target);
>  }
>
> -static void do_release(void)
> +static int release(void)
>  {
>         struct pdbg_target_class *target_class;
>
> @@ -610,7 +625,10 @@ static void do_release(void)
>                 pdbg_for_each_class_target(target_class->name, target)
>                         release_target(target);
>         }
> +
> +       return 0;
>  }
> +OPTCMD_DEFINE_CMD(release, release);
>
>  void print_target(struct pdbg_target *target, int level)
>  {
> @@ -652,7 +670,7 @@ void print_target(struct pdbg_target *target, int
> level)
>         }
>  }
>
> -static int handle_probe(int optind, int argc, char *argv[])
> +static int probe(void)
>  {
>         struct pdbg_target *target;
>
> @@ -664,25 +682,21 @@ static int handle_probe(int optind, int argc, char
> *argv[])
>
>         return 1;
>  }
> +OPTCMD_DEFINE_CMD(probe, probe);
>
>  /*
>   * Release handler.
>   */
>  static void atexit_release(void)
>  {
> -       do_release();
> -}
> -
> -static int handle_release(int optind, int argc, char *argv[])
> -{
> -       do_release();
> -
> -       return 1;
> +       release();
>  }
>
>  int main(int argc, char *argv[])
>  {
>         int i, rc = 0;
> +       void **args, **flags;
> +       optcmd_cmd_t *cmd;
>
>         backend = default_backend();
>         device_node = default_target(backend);
> @@ -714,13 +728,28 @@ int main(int argc, char *argv[])
>
>         atexit(atexit_release);
>
> -       for (i = 0; i < ARRAY_SIZE(actions); i++) {
> -               if (strcmp(argv[optind], actions[i].name) == 0) {
> -                       rc = actions[i].fn(optind, argc, argv);
> -                       goto found_action;
> +       for (i = 0; i < ARRAY_SIZE(cmds); i++) {
> +               if (!strcmp(argv[optind], cmds[i]->cmd)) {
> +                       /* Found our command */
> +                       cmd = optcmd_parse(cmds[i], (const char **)
> &argv[optind + 1],
> +                                          argc - (optind + 1), &args,
> &flags);
> +                       if (cmd) {
> +                               rc = cmd(args, flags);
> +                               goto found_action;
> +                       } else {
> +                               /* Error parsing arguments so exit return
> directly */
> +                               return 1;
> +                       }
>                 }
>         }
>
> +       /* Process subcommands. Currently only 'htm'.
> +        * TODO: Move htm command parsing to optcmd once htm clean-up is
> complete */
> +       if (!strcmp(argv[optind], "htm")) {
> +               run_htm(optind, argc, argv);
> +               goto found_action;
> +       }
> +
>         PR_ERROR("Unsupported command: %s\n", argv[optind]);
>         return 1;
>
> diff --git a/src/mem.c b/src/mem.c
> index e0327d1..29fd21e 100644
> --- a/src/mem.c
> +++ b/src/mem.c
> @@ -20,21 +20,34 @@
>  #include <string.h>
>  #include <unistd.h>
>  #include <assert.h>
> +#include <stdbool.h>
>
>  #include <libpdbg.h>
>
>  #include "main.h"
>  #include "progress.h"
> +#include "optcmd.h"
> +#include "parsers.h"
>
>  #define PR_ERROR(x, args...) \
>         pdbg_log(PDBG_ERROR, x, ##args)
>
>  #define PUTMEM_BUF_SIZE 1024
> -static int getmem(uint64_t addr, uint64_t size, bool ci)
> +
> +struct mem_flags {
> +       bool ci;
> +};
> +
> +#define MEM_CI_FLAG ("--ci", ci, parse_flag_noarg, false)
> +
> +static int getmem(uint64_t addr, uint64_t size, struct mem_flags flags)
>  {
>         struct pdbg_target *target;
>         uint8_t *buf;
>         int rc = 0;
> +
> +       printf("getmem ci %d\n", flags.ci);
> +
>         buf = malloc(size);
>         assert(buf);
>         pdbg_for_each_class_target("adu", target) {
> @@ -43,7 +56,7 @@ static int getmem(uint64_t addr, uint64_t size, bool ci)
>
>                 pdbg_set_progress_tick(progress_tick);
>                 progress_init();
> -               if (!__adu_getmem(target, addr, buf, size, ci)) {
> +               if (!__adu_getmem(target, addr, buf, size, flags.ci)) {
>                         if (write(STDOUT_FILENO, buf, size) < 0)
>                                 PR_ERROR("Unable to write stdout.\n");
>                         else
> @@ -58,7 +71,10 @@ static int getmem(uint64_t addr, uint64_t size, bool ci)
>         return rc;
>
>  }
> -static int putmem(uint64_t addr, bool ci)
> +OPTCMD_DEFINE_CMD_WITH_FLAGS(getmem, getmem, (ADDRESS, DATA),
> +                            mem_flags, (MEM_CI_FLAG));
> +
> +static int putmem(uint64_t addr, struct mem_flags flags)
>  {
>         uint8_t *buf;
>         int read_size, rc = 0;
> @@ -76,7 +92,7 @@ static int putmem(uint64_t addr, bool ci)
>         progress_init();
>         do {
>                 read_size = read(STDIN_FILENO, buf, PUTMEM_BUF_SIZE);
> -               if (__adu_putmem(adu_target, addr, buf, read_size, ci)) {
> +               if (__adu_putmem(adu_target, addr, buf, read_size,
> flags.ci)) {
>                         rc = 0;
>                         printf("Unable to write memory.\n");
>                         break;
> @@ -89,101 +105,5 @@ static int putmem(uint64_t addr, bool ci)
>         free(buf);
>         return rc;
>  }
> -
> -static bool is_real_address(struct thread_regs *regs, uint64_t addr)
> -{
> -       return true;
> -       if ((addr & 0xf000000000000000ULL) == 0xc000000000000000ULL)
> -               return true;
> -       return false;
> -}
> -
> -static int load8(struct pdbg_target *target, uint64_t addr, uint64_t
> *value)
> -{
> -       if (adu_getmem(target, addr, (uint8_t *)value, 8)) {
> -               PR_ERROR("Unable to read memory address=%016" PRIx64
> ".\n", addr);
> -               return 0;
> -       }
> -
> -       return 1;
> -}
> -
> -int dump_stack(struct thread_regs *regs)
> -{
> -       struct pdbg_target *target;
> -       uint64_t sp = regs->gprs[1];
> -       uint64_t pc;
> -
> -       pdbg_for_each_class_target("adu", target) {
> -               if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
> -                       continue;
> -               break;
> -       }
> -
> -       printf("STACK:\n");
> -       if (!target)
> -               PR_ERROR("Unable to read memory (no ADU found)\n");
> -
> -       if (sp && is_real_address(regs, sp)) {
> -               if (!load8(target, sp, &sp))
> -                       return 1;
> -               while (sp && is_real_address(regs, sp)) {
> -                       if (!load8(target, sp + 16, &pc))
> -                               return 1;
> -
> -                       printf(" 0x%016" PRIx64 " 0x%16" PRIx64 "\n", sp,
> pc);
> -
> -                       if (!load8(target, sp, &sp))
> -                               return 1;
> -               }
> -       }
> -
> -       return 0;
> -}
> -
> -int handle_mem(int optind, int argc, char *argv[])
> -{
> -       uint64_t addr;
> -       char *endptr;
> -       bool ci = false;
> -
> -       if (optind + 1 >= argc) {
> -               printf("%s: command '%s' requires an address\n", argv[0],
> argv[optind]);
> -               return -1;
> -       }
> -
> -       errno = 0;
> -
> -       if (strcmp(argv[optind +1], "-ci") == 0) {
> -               /* Set cache-inhibited flag */
> -               ci = true;
> -       }
> -
> -       addr = strtoull(argv[optind + 1 + ci], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse address '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1 +
> ci]);
> -               return -1;
> -       }
> -
> -       if (strcmp(argv[optind], "getmem") == 0) {
> -               uint64_t size;
> -
> -               if (optind + 2 + ci >= argc) {
> -                       printf("%s: command '%s' requires data\n",
> argv[0], argv[optind]);
> -                       return -1;
> -               }
> -
> -               errno = 0;
> -               size = strtoull(argv[optind + 2 + ci], &endptr, 0);
> -               if (errno || *endptr != '\0') {
> -                       printf("%s: command '%s' couldn't parse data
> '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1 +
> ci]);
> -                       return -1;
> -               }
> -
> -               return getmem(addr, size, ci);
> -       }
> -
> -       return putmem(addr, ci);
> -}
> +OPTCMD_DEFINE_CMD_WITH_FLAGS(putmem, putmem, (ADDRESS),
> +                            mem_flags, (MEM_CI_FLAG));
> diff --git a/src/mem.h b/src/mem.h
> deleted file mode 100644
> index 42bdc04..0000000
> --- a/src/mem.h
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -/* Copyright 2017 IBM Corp.
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> - * implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -#include <inttypes.h>
> -#include <libpdbg.h>
> -
> -int dump_stack(struct thread_regs *regs);
> -int handle_mem(int optind, int argc, char *argv[]);
> diff --git a/src/reg.c b/src/reg.c
> index 21bec13..aa77a8a 100644
> --- a/src/reg.c
> +++ b/src/reg.c
> @@ -22,6 +22,7 @@
>  #include <libpdbg.h>
>
>  #include "main.h"
> +#include "optcmd.h"
>
>  #define REG_MEM -3
>  #define REG_MSR -2
> @@ -91,143 +92,58 @@ static int getprocreg(struct pdbg_target *target,
> uint32_t index, uint64_t *reg,
>         return !rc;
>  }
>
> -int handle_gpr(int optind, int argc, char *argv[])
> +static int getgpr(int gpr)
>  {
> -       char *endptr;
> -       uint64_t gpr;
> -
> -       if (optind + 1 >= argc) {
> -               printf("%s: command '%s' requires a GPR\n", argv[0],
> argv[optind]);
> -               return -1;
> -       }
> -
> -       errno = 0;
> -       gpr = strtoull(argv[optind + 1], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse GPR '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -               return -1;
> -       }
> -
> -       if (gpr > 31) {
> -               printf("A GPR must be between zero and 31 inclusive\n");
> -               return -1;
> -       }
> -
> -       if (strcmp(argv[optind], "putgpr") == 0) {
> -               uint64_t data;
> -
> -               if (optind + 2 >= argc) {
> -                       printf("%s: command '%s' requires data\n",
> argv[0], argv[optind]);
> -                       return -1;
> -               }
> -
> -               errno = 0;
> -               data = strtoull(argv[optind + 2], &endptr, 0);
> -               if (errno || *endptr != '\0') {
> -                       printf("%s: command '%s' couldn't parse data
> '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -                       return -1;
> -               }
> -
> -               return for_each_target("thread", putprocreg, &gpr, &data);
> -       }
> -
> -       return for_each_target("thread", getprocreg, &gpr, NULL);
> +       uint64_t reg = gpr;
> +       return for_each_target("thread", getprocreg, &reg, NULL);
>  }
> +OPTCMD_DEFINE_CMD_WITH_ARGS(getgpr, getgpr, (GPR));
>
> -int handle_nia(int optind, int argc, char *argv[])
> +static int putgpr(int gpr, uint64_t data)
>  {
> -       uint64_t reg = REG_NIA;
> -       char *endptr;
> -
> -       if (strcmp(argv[optind], "putnia") == 0) {
> -               uint64_t data;
> -
> -               if (optind + 1 >= argc) {
> -                       printf("%s: command '%s' requires data\n",
> argv[0], argv[optind]);
> -                       return -1;
> -               }
> -
> -               errno = 0;
> -               data = strtoull(argv[optind + 1], &endptr, 0);
> -               if (errno || *endptr != '\0') {
> -                       printf("%s: command '%s' couldn't parse data
> '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -                       return -1;
> -               }
> -
> -               return for_each_target("thread", putprocreg, &reg, &data);
> -       }
> +       uint64_t reg = gpr;
> +       return for_each_target("thread", putprocreg, &reg, &data);
> +}
> +OPTCMD_DEFINE_CMD_WITH_ARGS(putgpr, putgpr, (GPR, DATA));
>
> +static int getnia(void)
> +{
> +       uint64_t reg = REG_NIA;
>         return for_each_target("thread", getprocreg, &reg, NULL);
>  }
> +OPTCMD_DEFINE_CMD(getnia, getnia);
>
> -int handle_spr(int optind, int argc, char *argv[])
> +static int putnia(uint64_t nia)
>  {
> -       char *endptr;
> -       uint64_t spr;
> -
> -       if (optind + 1 >= argc) {
> -               printf("%s: command '%s' requires a GPR\n", argv[0],
> argv[optind]);
> -               return -1;
> -       }
> -
> -       errno = 0;
> -       spr = strtoull(argv[optind + 1], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse GPR '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -               return -1;
> -       }
> -
> -       spr += REG_R31;
> -
> -       if (strcmp(argv[optind], "putspr") == 0) {
> -               uint64_t data;
> -
> -               if (optind + 2 >= argc) {
> -                       printf("%s: command '%s' requires data\n",
> argv[0], argv[optind]);
> -                       return -1;
> -               }
> -
> -               errno = 0;
> -               data = strtoull(argv[optind + 2], &endptr, 0);
> -               if (errno || *endptr != '\0') {
> -                       printf("%s: command '%s' couldn't parse data
> '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -                       return -1;
> -               }
> -
> -               return for_each_target("thread", putprocreg, &spr, &data);
> -       }
> -
> -       return for_each_target("thread", getprocreg, &spr, NULL);
> +       uint64_t reg = REG_NIA;
> +       return for_each_target("thread", getprocreg, &reg, &nia);
>  }
>

I think this should be putprocreg. There is at least one more that I found
that seems to be using the wrong <put/get>procreg


+OPTCMD_DEFINE_CMD_WITH_ARGS(putnia, putnia, (DATA));
>
> -int handle_msr(int optind, int argc, char *argv[])
> +static int getspr(int spr)
>  {
> -       uint64_t msr = REG_MSR;
> -       char *endptr;
> -
> -       if (strcmp(argv[optind], "putmsr") == 0) {
> -               uint64_t data;
> -
> -               if (optind + 1 >= argc) {
> -                       printf("%s: command '%s' requires data\n",
> argv[0], argv[optind]);
> -                       return -1;
> -               }
> +       uint64_t reg = spr + REG_R31;
> +       return for_each_target("thread", getprocreg, &reg, NULL);
> +}
> +OPTCMD_DEFINE_CMD_WITH_ARGS(getspr, getspr, (SPR));
>
> -               errno = 0;
> -               data = strtoull(argv[optind + 1], &endptr, 0);
> -               if (errno || *endptr != '\0') {
> -                       printf("%s: command '%s' couldn't parse data
> '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -                       return -1;
> -               }
> +static int putspr(int spr, uint64_t data)
> +{
> +       uint64_t reg = spr + REG_R31;
> +       return for_each_target("thread", putprocreg, &reg, &data);
> +}
> +OPTCMD_DEFINE_CMD_WITH_ARGS(putspr, putspr, (SPR, DATA));
>
> -               return for_each_target("thread", putprocreg, &msr, &data);
> -       }
> +static int getmsr(void)
> +{
> +       uint64_t reg = REG_MSR;
> +       return for_each_target("thread", getprocreg, &reg, NULL);
> +}
> +OPTCMD_DEFINE_CMD(getmsr, getmsr);
>
> -       return for_each_target("thread", getprocreg, &msr, NULL);
> +static int putmsr(uint64_t data)
> +{
> +       uint64_t reg = REG_MSR;
> +       return for_each_target("thread", putprocreg, &reg, &data);
>  }
> +OPTCMD_DEFINE_CMD_WITH_ARGS(putmsr, putmsr, (DATA));
> diff --git a/src/reg.h b/src/reg.h
> deleted file mode 100644
> index ad41d9d..0000000
> --- a/src/reg.h
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -/* Copyright 2017 IBM Corp.
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> - * implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -
> -int handle_gpr(int optind, int argc, char *argv[]);
> -int handle_nia(int optind, int argc, char *argv[]);
> -int handle_spr(int optind, int argc, char *argv[]);
> -int handle_msr(int optind, int argc, char *argv[]);
> diff --git a/src/ring.c b/src/ring.c
> index b0c9376..58df4d1 100644
> --- a/src/ring.c
> +++ b/src/ring.c
> @@ -18,11 +18,12 @@
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> +#include <assert.h>
>
> -#include <target.h>
> -#include <operations.h>
> +#include <libpdbg.h>
>
>  #include "main.h"
> +#include "optcmd.h"
>
>  static int pdbg_getring(struct pdbg_target *target, uint32_t index,
> uint64_t *addr, uint64_t *len)
>  {
> @@ -51,31 +52,8 @@ static int pdbg_getring(struct pdbg_target *target,
> uint32_t index, uint64_t *ad
>         return 1;
>  }
>
> -int handle_getring(int optind, int argc, char *argv[])
> +static int _getring(uint64_t ring_addr, uint64_t ring_len)
>  {
> -       uint64_t ring_addr, ring_len;
> -       char *endptr;
> -
> -       if (optind + 2 >= argc) {
> -               printf("%s: command '%s' requires two arguments (address
> and length)\n",
> -                      argv[0], argv[optind]);
> -               return -1;
> -       }
> -
> -       errno = 0;
> -       ring_addr = strtoull(argv[optind + 1], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse ring address
> '%s'\n",
> -                      argv[0], argv[optind], argv[optind + 1]);
> -               return -1;
> -       }
> -
> -       ring_len = strtoull(argv[optind + 2], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse ring length
> '%s'\n",
> -                      argv[0], argv[optind], argv[optind + 2]);
> -               return -1;
> -       }
> -
>         return for_each_target("chiplet", pdbg_getring, &ring_addr,
> &ring_len);
>  }
> +OPTCMD_DEFINE_CMD_WITH_ARGS(getring, _getring, (ADDRESS, DATA));
> diff --git a/src/ring.h b/src/ring.h
> deleted file mode 100644
> index a72c875..0000000
> --- a/src/ring.h
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -/* Copyright 2018 IBM Corp.
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - *      http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> - * implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -
> -int handle_getring(int optind, int argc, char *argv[]);
> diff --git a/src/scom.c b/src/scom.c
> index 4c59e2a..2372e91 100644
> --- a/src/scom.c
> +++ b/src/scom.c
> @@ -22,8 +22,9 @@
>  #include <libpdbg.h>
>
>  #include "main.h"
> +#include "optcmd.h"
>
> -static int getscom(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *unused)
> +static int _getscom(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *unused)
>  {
>         uint64_t value;
>
> @@ -35,7 +36,13 @@ static int getscom(struct pdbg_target *target, uint32_t
> index, uint64_t *addr, u
>         return 1;
>  }
>
> -static int putscom(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *data)
> + int getscom(uint64_t addr)
> +{
> +       return for_each_target("pib", _getscom, &addr, NULL);
> +}
> +OPTCMD_DEFINE_CMD_WITH_ARGS(getscom, getscom, (ADDRESS));
> +
> +static int _putscom(struct pdbg_target *target, uint32_t index, uint64_t
> *addr, uint64_t *data)
>  {
>         if (pib_write(target, *addr, *data))
>                 return 0;
> @@ -43,44 +50,9 @@ static int putscom(struct pdbg_target *target, uint32_t
> index, uint64_t *addr, u
>         return 1;
>  }
>
> -
> -int handle_scoms(int optind, int argc, char *argv[])
> + int putscom(uint64_t addr, uint64_t data, uint64_t mask)
>  {
> -       uint64_t addr;
> -       char *endptr;
> -
> -       if (optind + 1 >= argc) {
> -               printf("%s: command '%s' requires an address\n", argv[0],
> argv[optind]);
> -               return -1;
> -       }
> -
> -       errno = 0;
> -       addr = strtoull(argv[optind + 1], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse address '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -               return -1;
> -       }
> -
> -       if (strcmp(argv[optind], "putscom") == 0) {
> -               uint64_t data;
> -
> -               if (optind + 2 >= argc) {
> -                       printf("%s: command '%s' requires data\n",
> argv[0], argv[optind]);
> -                       return -1;
> -               }
> -
> -               errno = 0;
> -               data = strtoull(argv[optind + 2], &endptr, 0);
> -               if (errno || *endptr != '\0') {
> -                       printf("%s: command '%s' couldn't parse data
> '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -                       return -1;
> -               }
> -
> -               return for_each_target("pib", putscom, &addr, &data);
> -       }
> -
> -       return for_each_target("pib", getscom, &addr, NULL);
> +       /* TODO: Restore the <mask> functionality */
> +       return for_each_target("pib", _putscom, &addr, &data);
>  }
> -
> +OPTCMD_DEFINE_CMD_WITH_ARGS(putscom, putscom, (ADDRESS, DATA,
> DEFAULT_DATA("0xffffffffffffffff")));
> diff --git a/src/scom.h b/src/scom.h
> deleted file mode 100644
> index d4325b5..0000000
> --- a/src/scom.h
> +++ /dev/null
> @@ -1,18 +0,0 @@
> -/* Copyright 2017 IBM Corp.
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> - * implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -#include <inttypes.h>
> -
> -int handle_scoms(int optind, int argc, char *argv[]);
> diff --git a/src/thread.c b/src/thread.c
> index e8b54cb..4b95636 100644
> --- a/src/thread.c
> +++ b/src/thread.c
> @@ -21,7 +21,7 @@
>  #include <libpdbg.h>
>
>  #include "main.h"
> -#include "mem.h"
> +#include "optcmd.h"
>
>  static int print_thread_status(struct pdbg_target *target, uint32_t
> index, uint64_t *arg, uint64_t *unused1)
>  {
> @@ -81,6 +81,57 @@ static int print_core_thread_status(struct pdbg_target
> *core_target, uint32_t in
>         return rc;
>  }
>
> +static bool is_real_address(struct thread_regs *regs, uint64_t addr)
> +{
> +       return true;
> +       if ((addr & 0xf000000000000000ULL) == 0xc000000000000000ULL)
> +               return true;
> +       return false;
> +}
> +
> +static int load8(struct pdbg_target *target, uint64_t addr, uint64_t
> *value)
> +{
> +       if (adu_getmem(target, addr, (uint8_t *)value, 8)) {
> +               pdbg_log(PDBG_ERROR, "Unable to read memory address=%016"
> PRIx64 ".\n", addr);
> +               return 0;
> +       }
> +
> +       return 1;
> +}
> +
> +static int dump_stack(struct thread_regs *regs)
> +{
> +       struct pdbg_target *target;
> +       uint64_t sp = regs->gprs[1];
> +       uint64_t pc;
> +
> +       pdbg_for_each_class_target("adu", target) {
> +               if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
> +                       continue;
> +               break;
> +       }
> +
> +       printf("STACK:\n");
> +       if (!target)
> +               pdbg_log(PDBG_ERROR, "Unable to read memory (no ADU
> found)\n");
> +
> +       if (sp && is_real_address(regs, sp)) {
> +               if (!load8(target, sp, &sp))
> +                       return 1;
> +               while (sp && is_real_address(regs, sp)) {
> +                       if (!load8(target, sp + 16, &pc))
> +                               return 1;
> +
> +                       printf(" 0x%016" PRIx64 " 0x%16" PRIx64 "\n", sp,
> pc);
> +
> +                       if (!load8(target, sp, &sp))
> +                               return 1;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
>  static int get_thread_max_index(struct pdbg_target *target, uint32_t
> index, uint64_t *maxindex, uint64_t *unused)
>  {
>         if (index > *maxindex)
> @@ -140,48 +191,37 @@ static int state_thread(struct pdbg_target
> *thread_target, uint32_t index, uint6
>         return 1;
>  }
>
> -int thread_start(int optind, int argc, char *argv[])
> +static int thread_start(void)
>  {
>         return for_each_target("thread", start_thread, NULL, NULL);
>  }
> +OPTCMD_DEFINE_CMD(start, thread_start);
>
> -int thread_step(int optind, int argc, char *argv[])
> +static int thread_step(uint64_t count)
>  {
> -       uint64_t count;
> -       char *endptr;
> -
> -       if (optind + 1 >= argc) {
> -               printf("%s: command '%s' requires a count\n", argv[0],
> argv[optind]);
> -               return -1;
> -       }
> -
> -       errno = 0;
> -       count = strtoull(argv[optind + 1], &endptr, 0);
> -       if (errno || *endptr != '\0') {
> -               printf("%s: command '%s' couldn't parse count '%s'\n",
> -                               argv[0], argv[optind], argv[optind + 1]);
> -               return -1;
> -       }
> -
>         return for_each_target("thread", step_thread, &count, NULL);
>  }
> +OPTCMD_DEFINE_CMD_WITH_ARGS(step, thread_step, (DATA));
>
> -int thread_stop(int optind, int argc, char *argv[])
> +static int thread_stop(void)
>  {
>         return for_each_target("thread", stop_thread, NULL, NULL);
>  }
> +OPTCMD_DEFINE_CMD(stop, thread_stop);
>
> -int thread_status_print(int optind, int argc, char *argv[])
> +static int thread_status_print(void)
>  {
>         return for_each_target("pib", print_proc_thread_status, NULL,
> NULL);
>  }
> +OPTCMD_DEFINE_CMD(threadstatus, thread_status_print);
>
> -int thread_sreset(int optind, int argc, char *argv[])
> +static int thread_sreset(void)
>  {
>         return for_each_target("thread", sreset_thread, NULL, NULL);
>  }
> +OPTCMD_DEFINE_CMD(sreset, thread_sreset);
>
> -int thread_state(int optind, int argc, char *argv[])
> +static int thread_state(void)
>  {
>         int err;
>
> @@ -191,3 +231,4 @@ int thread_state(int optind, int argc, char *argv[])
>
>         return err;
>  }
> +OPTCMD_DEFINE_CMD(regs, thread_state);
> diff --git a/src/thread.h b/src/thread.h
> deleted file mode 100644
> index 0c1caa2..0000000
> --- a/src/thread.h
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -/* Copyright 2017 IBM Corp.
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> - * implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -#include <inttypes.h>
> -
> -int thread_start(int optind, int argc, char *argv[]);
> -int thread_step(int optind, int argc, char *argv[]);
> -int thread_stop(int optind, int argc, char *argv[]);
> -int thread_status_print(int optind, int argc, char *argv[]);
> -int thread_sreset(int optind, int argc, char *argv[]);
> -int thread_state(int optind, int argc, char *argv[]);
> --
> 2.11.0
>
> --
> Pdbg mailing list
> Pdbg at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/pdbg
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/pdbg/attachments/20180629/71880bd7/attachment-0001.html>


More information about the Pdbg mailing list