summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyril Bur <cyrilbur@gmail.com>2018-02-14 15:31:47 +1100
committerAlistair Popple <alistair@popple.id.au>2018-02-16 16:22:23 +1100
commit88a6d568b94c447f1ef354696bd68a4c82d0e26e (patch)
tree75a9c259964de6aeaec6c5a68d6bda22d5fabc46
parent8fb428320252d606658bbd25acfb1eadc516bdd2 (diff)
downloadpdbg-88a6d568b94c447f1ef354696bd68a4c82d0e26e.tar.gz
pdbg-88a6d568b94c447f1ef354696bd68a4c82d0e26e.zip
main: Attempt to automatically discover target
Signed-off-by: Cyril Bur <cyrilbur@gmail.com> Signed-off-by: Alistair Popple <alistair@popple.id.au>
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac8
-rw-r--r--src/main.c27
-rw-r--r--src/main.h2
-rw-r--r--src/options.h36
-rw-r--r--src/options_arm.c118
-rw-r--r--src/options_def.c50
-rw-r--r--src/options_ppc.c92
8 files changed, 331 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am
index 58666aa..4156b21 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,7 +12,8 @@ AM_CFLAGS = -I$(top_srcdir)/ccan/array_size -Wall -Werror
pdbg_SOURCES = \
src/main.c src/cfam.c src/scom.c src/reg.c src/mem.c src/thread.c \
- src/htm.c
+ src/htm.c src/options_@ARCH@.c
+
pdbg_LDADD = fake.dtb.o p8-fsi.dtb.o p8-i2c.dtb.o p9w-fsi.dtb.o p8-host.dtb.o \
p9z-fsi.dtb.o p9r-fsi.dtb.o p9-kernel.dtb.o libpdbg.la libfdt.la \
p9-host.dtb.o \
diff --git a/configure.ac b/configure.ac
index 43348d7..b73bf27 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,4 +8,12 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_LANG(C)
+
+case "$host" in
+ arm*-*-*) ARCH="arm" ;;
+ powerpc*-*-*) ARCH="ppc" ;;
+ *) ARCH="def" ;;
+esac
+AC_SUBST([ARCH])
+
AC_OUTPUT
diff --git a/src/main.c b/src/main.c
index 11b578e..121e4ad 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,6 +32,7 @@
#include <libpdbg.h>
+#include "main.h"
#include "bitutils.h"
#include "cfam.h"
#include "scom.h"
@@ -39,6 +40,7 @@
#include "mem.h"
#include "thread.h"
#include "htm.h"
+#include "options.h"
#undef PR_DEBUG
#define PR_DEBUG(...)
@@ -47,7 +49,6 @@
#define THREADS_PER_CORE 8
-enum backend { FSI, I2C, KERNEL, FAKE, HOST };
static enum backend backend = KERNEL;
static char const *device_node;
@@ -332,11 +333,11 @@ static int target_select(void)
}
if (!strcmp(device_node, "p8"))
pdbg_targets_init(&_binary_p8_fsi_dtb_o_start);
- else if (!strcmp(device_node, "p9w") || !strcmp(device_node, "witherspoon"))
+ else if (!strcmp(device_node, "p9w"))
pdbg_targets_init(&_binary_p9w_fsi_dtb_o_start);
- else if (!strcmp(device_node, "p9r") || !strcmp(device_node, "romulus"))
+ else if (!strcmp(device_node, "p9r"))
pdbg_targets_init(&_binary_p9r_fsi_dtb_o_start);
- else if (!strcmp(device_node, "p9z") || !strcmp(device_node, "zaius"))
+ else if (!strcmp(device_node, "p9z"))
pdbg_targets_init(&_binary_p9z_fsi_dtb_o_start);
else {
PR_ERROR("Invalid device type specified\n");
@@ -462,9 +463,27 @@ int main(int argc, char *argv[])
{
int i, rc = 0;
+ backend = default_backend();
+ device_node = default_target(backend);
+
if (parse_options(argc, argv))
return 1;
+ if (!backend_is_possible(backend)) {
+ fprintf(stderr, "Backend not possible\n");
+ print_backends(stderr);
+ print_usage(argv[0]);
+ return 1;
+ }
+
+ if (!target_is_possible(backend, device_node)) {
+ fprintf(stderr, "Target %s not possible\n",
+ device_node ? device_node : "(none)");
+ print_targets(stderr);
+ print_usage(argv[0]);
+ return 1;
+ }
+
if (optind >= argc) {
print_usage(argv[0]);
return 1;
diff --git a/src/main.h b/src/main.h
index 55fbdd4..71599ee 100644
--- a/src/main.h
+++ b/src/main.h
@@ -17,6 +17,8 @@
#include <target.h>
+enum backend { FSI, I2C, KERNEL, FAKE, HOST };
+
static inline bool target_is_disabled(struct pdbg_target *target)
{
return pdbg_target_status(target) == PDBG_TARGET_DISABLED;
diff --git a/src/options.h b/src/options.h
new file mode 100644
index 0000000..54436b6
--- /dev/null
+++ b/src/options.h
@@ -0,0 +1,36 @@
+/* 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.
+ */
+
+/* Default backend on this platform */
+enum backend default_backend(void);
+
+/* Print all possible backends on this platform */
+void print_backends(FILE *stream);
+
+/* Is this backend possible on this platform */
+bool backend_is_possible(enum backend backend);
+
+/* The default (perhaps only) target for this backend */
+const char *default_target(enum backend backend);
+
+/* Print all possible targets on this platform */
+void print_targets(FILE *stream);
+
+/*
+ * Does this platform backend support this target,
+ * there is an implied check of is_backend_possible()
+ */
+bool target_is_possible(enum backend backend, const char *target);
diff --git a/src/options_arm.c b/src/options_arm.c
new file mode 100644
index 0000000..c37d8d0
--- /dev/null
+++ b/src/options_arm.c
@@ -0,0 +1,118 @@
+/* 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "main.h"
+
+#define AMI_BMC "/proc/ractrends/Helper/FwInfo"
+#define OPENFSI_BMC "/sys/bus/platform/devices/gpio-fsi/fsi0/"
+
+static const char witherspoon[] = "p9w";
+static const char romulus[] = "p9r";
+static const char zaius[] = "p9z";
+
+enum backend default_backend(void)
+{
+ int rc;
+ rc = access(AMI_BMC, F_OK);
+ if (rc == 0) /* AMI BMC */
+ return I2C;
+
+ rc = access(OPENFSI_BMC, F_OK);
+ if (rc == 0) /* Kernel interface. OpenBMC */
+ return KERNEL;
+
+ /*
+ * "This should never be the default" - Apopple 2017
+ */
+ fprintf(stderr, "Couldn't locate a good backend.\n");
+ fprintf(stderr, "It is possible that the FSI backend will work.\n");
+ fprintf(stderr, "You will need to select this along with the correct\n");
+ fprintf(stderr, "target yourself on the commandline\n");
+ fprintf(stderr, "`pdbg -b fsi -d [p8 | p9w | p9r | p9z] ...`\n");
+ return FAKE;
+}
+
+void print_backends(FILE *stream)
+{
+ fprintf(stream, "I2C KERNEL FSI");
+}
+
+bool backend_is_possible(enum backend backend)
+{
+ if (backend == I2C && access(AMI_BMC, F_OK) == 0)
+ return true;
+ if (backend == KERNEL && access(OPENFSI_BMC, F_OK) == 0)
+ return true;
+
+ return backend == FSI;
+}
+
+void print_targets(FILE *stream)
+{
+ fprintf(stream, "KERNEL: No target is necessary\n");
+ fprintf(stream, "I2C: No target is necessary\n");
+ fprintf(stream, "FSI: p8 p9w p9r p9z\n");
+}
+
+const char *default_target(enum backend backend)
+{
+ FILE *dt_compatible;
+ char line[256];
+ char *p;
+
+ if (backend == I2C || backend == KERNEL) /* No target nessesary */
+ return NULL;
+
+ dt_compatible = fopen("/proc/device-tree/compatible", "r");
+ if (!dt_compatible)
+ return NULL;
+
+ p = fgets(line, sizeof(line), dt_compatible);
+ fclose(dt_compatible);
+ if (!p) /* Uh oh*/
+ return NULL;
+
+ if (strstr(line, "witherspoon"))
+ return witherspoon;
+
+ if (strstr(line, "romulus"))
+ return romulus;
+
+ if (strstr(line, "zaius"))
+ return zaius;
+
+ return NULL;
+}
+
+bool target_is_possible(enum backend backend, const char *target)
+{
+ const char *def;
+
+ if (!backend_is_possible(backend))
+ return false;
+
+ if (backend == I2C || backend == KERNEL) /* No target is nessesary */
+ return true;
+
+ def = default_target(backend);
+ if (!def || !target)
+ return false;
+
+ return strcmp(def, target) == 0;
+}
diff --git a/src/options_def.c b/src/options_def.c
new file mode 100644
index 0000000..719fcde
--- /dev/null
+++ b/src/options_def.c
@@ -0,0 +1,50 @@
+/* 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 <stdio.h>
+#include "main.h"
+
+enum backend default_backend(void)
+{
+ return FAKE;
+}
+
+bool backend_is_possible(enum backend backend)
+{
+ return backend == FAKE;
+}
+
+void print_backends(FILE *stream)
+{
+ fprintf(stream, "FAKE");
+}
+
+/* Theres no target for FAKE backend */
+const char *default_target(enum backend backend)
+{
+ return NULL;
+}
+
+void print_targets(FILE *stream)
+{
+ fprintf(stream, "FAKE: No target is necessary\n");
+}
+
+/* Theres no device for FAKE backend */
+bool target_is_possible(enum backend backend, const char *target)
+{
+ return target == NULL;
+}
diff --git a/src/options_ppc.c b/src/options_ppc.c
new file mode 100644
index 0000000..30ed5bb
--- /dev/null
+++ b/src/options_ppc.c
@@ -0,0 +1,92 @@
+/* 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 <stdio.h>
+#include <string.h>
+
+#include "main.h"
+
+static const char p8[] = "p8";
+static const char p9[] = "p9";
+
+enum backend default_backend(void)
+{
+ return HOST;
+}
+
+bool backend_is_possible(enum backend backend)
+{
+ /* TODO */
+ return backend == HOST;
+}
+
+void print_backends(FILE *stream)
+{
+ fprintf(stream, "HOST");
+}
+
+const char *default_target(enum backend backend)
+{
+ const char *pos = NULL;
+ char line[256];
+ FILE *cpuinfo;
+
+ cpuinfo = fopen("/proc/cpuinfo", "r");
+ if (!cpuinfo)
+ return NULL;
+
+ while ((pos = fgets(line, sizeof(line), cpuinfo)))
+ if (strncmp(line, "cpu", 3) == 0)
+ break;
+ fclose(cpuinfo);
+
+ if (!pos) /* Got to EOF without a break */
+ return NULL;
+
+ pos = strchr(line, ':');
+ if (!pos)
+ return NULL;
+
+ if (*(pos + 1) == '\0')
+ return NULL;
+ pos += 2;
+
+ if (strncmp(pos, "POWER8", 6) == 0)
+ return p8;
+
+ if (strncmp(pos, "POWER9", 6) == 0)
+ return p9;
+
+ return NULL;
+}
+
+void print_targets(FILE *stream)
+{
+ fprintf(stream, "HOST: p8 p9\n");
+}
+
+bool target_is_possible(enum backend backend, const char *target)
+{
+ const char *def;
+
+ if (!backend_is_possible(backend))
+ return false;
+
+ def = default_target(backend);
+ if (!def || !target)
+ return false;
+
+ return strcmp(def, target) == 0;
+}
OpenPOWER on IntegriCloud