summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cfam.c55
-rw-r--r--src/cfam.h18
-rw-r--r--src/main.c125
-rw-r--r--src/mem.c122
-rw-r--r--src/mem.h20
-rw-r--r--src/reg.c164
-rw-r--r--src/reg.h20
-rw-r--r--src/ring.c32
-rw-r--r--src/ring.h17
-rw-r--r--src/scom.c54
-rw-r--r--src/scom.h18
-rw-r--r--src/thread.c87
-rw-r--r--src/thread.h23
13 files changed, 234 insertions, 521 deletions
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 d104404..f89db2f 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)
{
@@ -648,7 +666,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;
@@ -660,25 +678,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);
@@ -710,13 +724,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..b2ab917 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -20,21 +20,32 @@
#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;
+
buf = malloc(size);
assert(buf);
pdbg_for_each_class_target("adu", target) {
@@ -43,7 +54,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 +69,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 +90,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 +103,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);
}
+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[]);
OpenPOWER on IntegriCloud