[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, ®, 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, ®, &data);
> - }
> + uint64_t reg = gpr;
> + return for_each_target("thread", putprocreg, ®, &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, ®, 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, ®, &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, ®, 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, ®, &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, ®, 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, ®, &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