[Pdbg] [PATCH 16/29] main: Use new command handling for registers

Cyril Bur cyrilbur at gmail.com
Fri Feb 9 15:38:44 AEDT 2018


Signed-off-by: Cyril Bur <cyrilbur at gmail.com>
---
 src/main.c |  66 ++++----------------------
 src/reg.c  | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/reg.h  |  12 ++---
 3 files changed, 165 insertions(+), 68 deletions(-)

diff --git a/src/main.c b/src/main.c
index c7ce171..4c618c9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -90,6 +90,14 @@ static struct {
 	{ "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 },
+	{ "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 },
 };
 
 static void print_usage(char *pname)
@@ -150,31 +158,7 @@ enum command parse_cmd(char *optarg)
 {
 	cmd_max_arg_count = 0;
 
-	if (strcmp(optarg, "getgpr") == 0) {
-		cmd = GETGPR;
-		cmd_min_arg_count = 1;
-	} else if (strcmp(optarg, "putgpr") == 0) {
-		cmd = PUTGPR;
-		cmd_min_arg_count = 2;
-	} else if (strcmp(optarg, "getnia") == 0) {
-		cmd = GETNIA;
-		cmd_min_arg_count = 0;
-	} else if (strcmp(optarg, "putnia") == 0) {
-		cmd = PUTNIA;
-		cmd_min_arg_count = 1;
-	} else if (strcmp(optarg, "getspr") == 0) {
-		cmd = GETSPR;
-		cmd_min_arg_count = 1;
-	} else if (strcmp(optarg, "putspr") == 0) {
-		cmd = PUTSPR;
-		cmd_min_arg_count = 2;
-	} else if (strcmp(optarg, "getmsr") == 0) {
-		cmd = GETMSR;
-		cmd_min_arg_count = 0;
-	} else if (strcmp(optarg, "putmsr") == 0) {
-		cmd = PUTMSR;
-		cmd_min_arg_count = 1;
-	} else if (strcmp(optarg, "getvmem") == 0) {
+	if (strcmp(optarg, "getvmem") == 0) {
 		cmd = GETVMEM;
 		cmd_min_arg_count = 1;
 	} else if (strcmp(optarg, "start") == 0) {
@@ -602,38 +586,6 @@ int main(int argc, char *argv[])
 		return -1;
 
 	switch(cmd) {
-	case GETGPR:
-		rc = for_each_target("thread", getprocreg, &cmd_args[0], NULL);
-		break;
-	case PUTGPR:
-		rc = for_each_target("thread", putprocreg, &cmd_args[0], &cmd_args[1]);
-		break;
-	case GETNIA:
-		cmd_args[0] = REG_NIA;
-		rc = for_each_target("thread", getprocreg, &cmd_args[0], NULL);
-		break;
-	case PUTNIA:
-		cmd_args[1] = cmd_args[0];
-		cmd_args[0] = REG_NIA;
-		rc = for_each_target("thread", putprocreg, &cmd_args[0], &cmd_args[1]);
-		break;
-	case GETSPR:
-		cmd_args[0] += REG_R31;
-		rc = for_each_target("thread", getprocreg, &cmd_args[0], NULL);
-		break;
-	case PUTSPR:
-		cmd_args[0] += REG_R31;
-		rc = for_each_target("thread", putprocreg, &cmd_args[0], &cmd_args[1]);
-		break;
-	case GETMSR:
-		cmd_args[0] = REG_MSR;
-		rc = for_each_target("thread", getprocreg, &cmd_args[0], NULL);
-		break;
-	case PUTMSR:
-		cmd_args[1] = cmd_args[0];
-		cmd_args[0] = REG_MSR;
-		rc = for_each_target("thread", putprocreg, &cmd_args[0], &cmd_args[1]);
-		break;
 	case THREADSTATUS:
 		rc = for_each_target("pib", print_proc_thread_status, NULL, NULL);
 		break;
diff --git a/src/reg.c b/src/reg.c
index 02835c7..d094fbe 100644
--- a/src/reg.c
+++ b/src/reg.c
@@ -13,13 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <errno.h>
 #include <inttypes.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <target.h>
 #include <operations.h>
 
-#include "reg.h"
+#include "main.h"
+
+#define REG_MEM -3
+#define REG_MSR -2
+#define REG_NIA -1
+#define REG_R31 31
 
 static void print_proc_reg(struct pdbg_target *target, uint64_t reg, uint64_t value, int rc)
 {
@@ -47,7 +55,7 @@ static void print_proc_reg(struct pdbg_target *target, uint64_t reg, uint64_t va
 		printf("0x%016" PRIx64 "\n", value);
 }
 
-int putprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *value)
+static int putprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *value)
 {
 	int rc;
 
@@ -65,7 +73,7 @@ int putprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64
 	return 0;
 }
 
-int getprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *unused)
+static int getprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *unused)
 {
 	int rc;
 	uint64_t value;
@@ -83,3 +91,144 @@ int getprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64
 
 	return !rc;
 }
+
+int handle_gpr(int optind, int argc, char *argv[])
+{
+	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);
+}
+
+int handle_nia(int optind, int argc, char *argv[])
+{
+	uint64_t reg = REG_NIA;
+	char *endptr;
+
+	if (strcmp(argv[optind], "putnia") == 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, &reg, &data);
+	}
+
+	return for_each_target("thread", getprocreg, &reg, NULL);
+}
+
+int handle_spr(int optind, int argc, char *argv[])
+{
+	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);
+}
+
+int handle_msr(int optind, int argc, char *argv[])
+{
+	uint64_t msr = REG_MSR;
+	char *endptr;
+
+	if (strcmp(argv[optind], "putmsr") == 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, &msr, &data);
+	}
+
+	return for_each_target("thread", getprocreg, &msr, NULL);
+}
diff --git a/src/reg.h b/src/reg.h
index c80df57..ad41d9d 100644
--- a/src/reg.h
+++ b/src/reg.h
@@ -13,12 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <inttypes.h>
 
-#define REG_MEM -3
-#define REG_MSR -2
-#define REG_NIA -1
-#define REG_R31 31
-
-int putprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *value);
-int getprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *unused);
+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[]);
-- 
2.16.1



More information about the Pdbg mailing list