From patchwork Mon Jul 1 07:52:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Popple X-Patchwork-Id: 1125118 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45cfjH60BTz9s4V for ; Mon, 1 Jul 2019 17:52:19 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=popple.id.au Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 45cfjH4y5mzDqTG for ; Mon, 1 Jul 2019 17:52:19 +1000 (AEST) X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 45cfjC2FXszDqSx for ; Mon, 1 Jul 2019 17:52:15 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=popple.id.au Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.ozlabs.org (Postfix) with ESMTPSA id 45cfjC0140z9s3Z; Mon, 1 Jul 2019 17:52:15 +1000 (AEST) From: Alistair Popple To: pdbg@lists.ozlabs.org Date: Mon, 1 Jul 2019 17:52:08 +1000 Message-Id: <20190701075209.2226-1-alistair@popple.id.au> X-Mailer: git-send-email 2.11.0 Subject: [Pdbg] [PATCH 1/2] libpdbg: Add default device-tree selection to libpdbg X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" For portability reasons libpdbg intentionally did not deal with the selection and retrieval of the device tree for a given system. This means that by design each application was responsible for selecting and loading the correct device tree for the system it was on. This is convenient for embedded systems as it removes the dependency on some libc functions such as open. However there are currently no embedded users of libpdbg and forcing end user applications to select the correct device tree is likely to be error prone and inconsistent. Instead this patch adds the ability for applications to call pdbg_targets_init(NULL) and have libpdbg attempt to detect and load the correct device tree for the current system. This doesn't change any existing behaviour as applications may still pass an explicit device-tree to pdbg_targets_init() which will always be used. An environment variable is provided so users may override the auto-detected device-tree when the application does not provide one. This patch will bloat the overall size of the library as it will now include all the device-trees. It also likely makes things harder for embedded users. However if either of these is an issue we should be able to easily add a build time option to exclude this and/or only build in specific device-trees. Signed-off-by: Alistair Popple --- Makefile.am | 20 +++-- libpdbg/device.c | 10 +++ libpdbg/dtb.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libpdbg/libpdbg.h | 1 + 4 files changed, 241 insertions(+), 6 deletions(-) create mode 100644 libpdbg/dtb.c diff --git a/Makefile.am b/Makefile.am index 10c56b2..b421706 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,20 +55,22 @@ EXTRA_DIST = \ tests/test_driver.sh \ $(PDBG_TESTS) -if TARGET_ARM DT_ARM = p8-fsi.dts p8-i2c.dts p8-kernel.dts \ p9w-fsi.dts p9r-fsi.dts p9z-fsi.dts p9-kernel.dts + +if TARGET_ARM ARCH_FLAGS="-DTARGET_ARM=1" endif -if TARGET_PPC DT_PPC = p8-host.dts p9-host.dts + +if TARGET_PPC ARCH_FLAGS="-DTARGET_PPC=1" endif DT = fake.dts $(DT_ARM) $(DT_PPC) -DT_objects = $(DT:.dts=.dtb.o) +DT_objects = $(DT:.dts=.dtb.lo) DT_headers = $(DT:.dts=.dt.h) optcmd_test_SOURCES = src/optcmd.c src/parsers.c src/tests/optcmd_test.c @@ -127,6 +129,7 @@ pdbg_CFLAGS += -DDISABLE_GDBSERVER endif src/main.c: $(DT_headers) +libpdbg/dtb.c: $(DT_headers) src/pdbg-gdb_parser.$(OBJEXT): CFLAGS+=-Wno-unused-const-variable @@ -149,6 +152,7 @@ libpdbg_la_SOURCES = \ libpdbg/debug.c \ libpdbg/debug.h \ libpdbg/device.c \ + libpdbg/dtb.c \ libpdbg/fake.c \ libpdbg/host.c \ libpdbg/htm.c \ @@ -166,8 +170,10 @@ libpdbg_la_SOURCES = \ libpdbg/target.h \ libpdbg/xbus.c +libpdbg_la_LIBADD = $(DT_objects) + if BUILD_LIBFDT -libpdbg_la_LIBADD = libfdt/libfdt.la +libpdbg_la_LIBADD += libfdt/libfdt.la endif include_HEADERS = libpdbg/libpdbg.h @@ -242,8 +248,10 @@ p9z-fsi.dts: p9z-fsi.dts.m4 p9-fsi.dtsi %.dt.h: %.dts $(GEN_V)$(srcdir)/generate_dt_header.sh $< > $@ -%.dtb.o: %.dtb - $(AM_V_CC)$(CC) -c $(srcdir)/template.S -DSYMBOL_PREFIX=$(shell basename $@ | tr '.-' '_') -DFILENAME=\"$<\" -o $@ +%.dtb.lo: %.dtb + $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) -c $(srcdir)/template.S \ + -DSYMBOL_PREFIX=$(shell basename $@ | tr '.-' '_' | sed 's/lo/o/') -DFILENAME=\"$<\" -o $@ %.c: %.rl $(RAGEL_V)$(RAGEL) -o $@ $< diff --git a/libpdbg/device.c b/libpdbg/device.c index b7fd49f..ba9e05e 100644 --- a/libpdbg/device.c +++ b/libpdbg/device.c @@ -638,7 +638,17 @@ uint64_t pdbg_target_address(struct pdbg_target *target, uint64_t *out_size) void pdbg_targets_init(void *fdt) { + /* Root node needs to be valid when this function returns */ pdbg_dt_root = dt_new_node("", NULL, 0); + + if (!fdt) + fdt = pdbg_default_dtb(); + + if (!fdt) { + pdbg_log(PDBG_ERROR, "Could not find a system device tree\n"); + return; + } + dt_expand(fdt); } diff --git a/libpdbg/dtb.c b/libpdbg/dtb.c new file mode 100644 index 0000000..145b497 --- /dev/null +++ b/libpdbg/dtb.c @@ -0,0 +1,216 @@ +/* Copyright 2019 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libpdbg.h" + +#include "fake.dt.h" + +#include "p8-i2c.dt.h" +#include "p8-fsi.dt.h" +#include "p8-kernel.dt.h" +#include "p9w-fsi.dt.h" +#include "p9r-fsi.dt.h" +#include "p9z-fsi.dt.h" +#include "p9-kernel.dt.h" +#include "p8-host.dt.h" +#include "p9-host.dt.h" + +#define AMI_BMC "/proc/ractrends/Helper/FwInfo" +#define OPENFSI_BMC "/sys/bus/platform/devices/gpio-fsi/fsi0/" +#define FSI_CFAM_ID "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/cfam_id" +#define XSCOM_BASE_PATH "/sys/kernel/debug/powerpc/scom" + +#define CHIP_ID_P8 0xea +#define CHIP_ID_P8P 0xd3 +#define CHIP_ID_P9 0xd1 + +enum backend { FSI, I2C, KERNEL, FAKE, HOST }; + +/* Determines the most appropriate backend for the host system we are + * running on. */ +static enum backend default_backend(void) +{ + int rc; + + rc = access(XSCOM_BASE_PATH, F_OK); + if (rc == 0) /* PowerPC Host System */ + return HOST; + + 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; + + return FAKE; +} + +/* Try and determine what system type we are on by reading + * /proc/cpuinfo */ +static void *ppc_target(void) +{ + 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 */ + pdbg_log(PDBG_ERROR, "Unable to parse /proc/cpuinfo\n"); + return NULL; + } + + pos = strchr(line, ':'); + if (!pos || (*(pos + 1) == '\0')) { + pdbg_log(PDBG_ERROR, "Unable to parse /proc/cpuinfo\n"); + return NULL; + } + + pos += 2; + + if (strncmp(pos, "POWER8", 6) == 0) { + pdbg_log(PDBG_INFO, "Found a POWER8 PPC host system\n"); + return &_binary_p8_host_dtb_o_start; + } + + if (strncmp(pos, "POWER9", 6) == 0) { + pdbg_log(PDBG_INFO, "Found a POWER9 PPC host system\n"); + return &_binary_p9_host_dtb_o_start; + } + + pdbg_log(PDBG_ERROR, "Unsupported CPU type '%s'\n", pos); + return NULL; +} + +static void *bmc_target(void) +{ + FILE *cfam_id_file; + uint32_t cfam_id = 0; + int rc; + + /* Try and determine the correct device type */ + cfam_id_file = fopen(FSI_CFAM_ID, "r"); + if (!cfam_id_file) { + pdbg_log(PDBG_ERROR, "Unabled to open CFAM ID file\n"); + return NULL; + } + + rc = fscanf(cfam_id_file, "0x%" PRIx32, &cfam_id); + if (rc != 1) { + pdbg_log(PDBG_ERROR, "Unable to read CFAM ID: %s", strerror(errno)); + } + fclose(cfam_id_file); + + switch((cfam_id >> 4) & 0xff) { + case CHIP_ID_P9: + pdbg_log(PDBG_INFO, "Found a POWER9 OpenBMC based system\n"); + return &_binary_p9_kernel_dtb_o_start; + break; + + case CHIP_ID_P8: + case CHIP_ID_P8P: + pdbg_log(PDBG_INFO, "Found a POWER8/8+ OpenBMC based system\n"); + return &_binary_p8_kernel_dtb_o_start; + break; + } + + pdbg_log(PDBG_ERROR, "Unrecognised CFAM ID register 0x%08" PRIx32 "\n", cfam_id); + return NULL; +} + +/* Opens a dtb at the given path */ +static void *mmap_dtb(char *file) +{ + int fd; + void *dtb; + struct stat statbuf; + + fd = open(file, O_RDONLY); + if (fd < 0) { + pdbg_log(PDBG_ERROR, "Unable to open dtb file '%s'\n", file); + return NULL; + } + + if (fstat(fd, &statbuf) == -1) { + pdbg_log(PDBG_ERROR, "Failed to stat file '%s'\n", file); + goto fail; + } + + dtb = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (dtb == MAP_FAILED) { + pdbg_log(PDBG_ERROR, "Failed top mmap file '%s'\n", file); + goto fail; + } + + return dtb; + +fail: + close(fd); + return NULL; +} + +/* Determines what platform we are running on and returns a pointer to + * the fdt that is most likely to work on the system. */ +void *pdbg_default_dtb(void) +{ + char *dtb = getenv("LPDBG_DTB"); + + if (dtb) + return mmap_dtb(dtb); + + switch(default_backend()) { + case HOST: + return ppc_target(); + break; + + case I2C: + /* I2C is only supported on POWER8 */ + pdbg_log(PDBG_INFO, "Found a POWER8 AMI BMC based system\n"); + return &_binary_p8_i2c_dtb_o_start; + break; + + case KERNEL: + return bmc_target(); + break; + + default: + pdbg_log(PDBG_WARNING, "Unable to determine a valid default backend, using a fake one for testing purposes\n"); + return &_binary_fake_dtb_o_start; + break; + } +} diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h index 14a41ab..7030139 100644 --- a/libpdbg/libpdbg.h +++ b/libpdbg/libpdbg.h @@ -103,6 +103,7 @@ enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target); void pdbg_target_release(struct pdbg_target *target); enum pdbg_target_status pdbg_target_status(struct pdbg_target *target); void pdbg_target_status_set(struct pdbg_target *target, enum pdbg_target_status status); +void *pdbg_default_dtb(void); uint32_t pdbg_target_index(struct pdbg_target *target); char *pdbg_target_path(const struct pdbg_target *target); struct pdbg_target *pdbg_target_from_path(struct pdbg_target *target, const char *path); From patchwork Mon Jul 1 07:52:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Popple X-Patchwork-Id: 1125119 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45cfjN6Bn1z9s4V for ; Mon, 1 Jul 2019 17:52:24 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=popple.id.au Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 45cfjN51W1zDqTM for ; Mon, 1 Jul 2019 17:52:24 +1000 (AEST) X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [203.11.71.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 45cfjK0j1FzDqSx for ; Mon, 1 Jul 2019 17:52:21 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=popple.id.au Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.ozlabs.org (Postfix) with ESMTPSA id 45cfjJ6pCrz9s4V; Mon, 1 Jul 2019 17:52:20 +1000 (AEST) From: Alistair Popple To: pdbg@lists.ozlabs.org Date: Mon, 1 Jul 2019 17:52:09 +1000 Message-Id: <20190701075209.2226-2-alistair@popple.id.au> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190701075209.2226-1-alistair@popple.id.au> References: <20190701075209.2226-1-alistair@popple.id.au> Subject: [Pdbg] [PATCH 2/2] pdbg: Remove default_backend() selection X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Now that libpdbg can automatically select the correct device-tree the pdbg application doesn't need code to do the same thing. By default pdbg can just rely on the device-tree selected by libpdbg. Unfortunately to maintain backwards compatibility for users explicitly selecting a device-tree and device-tree node we need to retain most of the code and continue linking the device-trees into the application. It would be good to remove these one day so print a deprecation warning when a user does explicitly select a backend. Signed-off-by: Alistair Popple --- src/main.c | 41 ++++++++++++++++++++++++----------------- src/main.h | 2 +- src/options.h | 3 --- src/options_arm.c | 14 -------------- src/options_def.c | 5 ----- src/options_ppc.c | 5 ----- 6 files changed, 25 insertions(+), 45 deletions(-) diff --git a/src/main.c b/src/main.c index ad40d19..7cee57b 100644 --- a/src/main.c +++ b/src/main.c @@ -64,7 +64,7 @@ #define THREADS_PER_CORE 8 -static enum backend backend = KERNEL; +static enum backend backend = DEFAULT_BACKEND; static char const *device_node; static int i2c_addr = 0x50; @@ -607,17 +607,6 @@ static bool target_selection(void) return false; } - if (pathsel_count) { - if (!path_target_parse(pathsel, pathsel_count)) - return false; - } - - if (!path_target_present()) { - printf("No valid targets found or specified. Try adding -p/-c/-t options to specify a target.\n"); - printf("Alternatively run 'pdbg -a probe' to get a list of all valid targets\n"); - return false; - } - return true; } @@ -677,9 +666,7 @@ int main(int argc, char *argv[]) optcmd_cmd_t *cmd; struct pdbg_target *target; - backend = default_backend(); - - if (!device_node) + if (backend && !device_node) device_node = default_target(backend); if (!parse_options(argc, argv)) @@ -690,9 +677,29 @@ int main(int argc, char *argv[]) return 1; } - /* Disable unselected targets */ - if (!target_selection()) + if (backend) { + fprintf(stderr, "WARNING: Explicit backend selection should no longer be required\n"); + fprintf(stderr, " and will be deprecated in a future release.\n"); + fprintf(stderr, " Removing -b/-d command line options will remove this warning.\n"); + fprintf(stderr, " An explicit device-tree can still be selected using the\n"); + fprintf(stderr, " LPDBG_DTB environment variable instead.\n"); + + if (!target_selection()) + return 1; + } else { + pdbg_targets_init(NULL); + } + + if (pathsel_count) { + if (!path_target_parse(pathsel, pathsel_count)) + return false; + } + + if (!path_target_present()) { + printf("No valid targets found or specified. Try adding -p/-c/-t options to specify a target.\n"); + printf("Alternatively run 'pdbg -a probe' to get a list of all valid targets\n"); return 1; + } /* Probe all selected targets */ for_each_path_target(target) { diff --git a/src/main.h b/src/main.h index 78b4d92..1d5913e 100644 --- a/src/main.h +++ b/src/main.h @@ -19,7 +19,7 @@ #include -enum backend { FSI, I2C, KERNEL, FAKE, HOST }; +enum backend { DEFAULT_BACKEND = 0, FSI, I2C, KERNEL, FAKE, HOST }; static inline bool target_is_disabled(struct pdbg_target *target) { diff --git a/src/options.h b/src/options.h index 67f15a8..cf63cbe 100644 --- a/src/options.h +++ b/src/options.h @@ -14,9 +14,6 @@ * 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); diff --git a/src/options_arm.c b/src/options_arm.c index 0dbc731..99a2d3f 100644 --- a/src/options_arm.c +++ b/src/options_arm.c @@ -28,20 +28,6 @@ #define CHIP_ID_P9 0xd1 #define CHIP_ID_P8P 0xd3 -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; - - return FAKE; -} - void print_backends(FILE *stream) { fprintf(stream, "Valid backends: i2c kernel fsi fake\n"); diff --git a/src/options_def.c b/src/options_def.c index 4092cea..3fef60d 100644 --- a/src/options_def.c +++ b/src/options_def.c @@ -17,11 +17,6 @@ #include #include "main.h" -enum backend default_backend(void) -{ - return FAKE; -} - void print_backends(FILE *stream) { fprintf(stream, "Valid backends: fake\n"); diff --git a/src/options_ppc.c b/src/options_ppc.c index 62eb7b0..82f410b 100644 --- a/src/options_ppc.c +++ b/src/options_ppc.c @@ -21,11 +21,6 @@ static const char p8[] = "p8"; static const char p9[] = "p9"; -enum backend default_backend(void) -{ - return HOST; -} - void print_backends(FILE *stream) { fprintf(stream, "Valid backends: host fake\n");