Message ID | 1461116570-6693-2-git-send-email-jk@ozlabs.org |
---|---|
State | Accepted |
Headers | show |
On 2016-04-20 09:42 AM, Jeremy Kerr wrote: > This change introduces a little infrastructure for tests that consume > data from the device tree. This involves a few things: > > An autoconf check for libfdt. If this is available, we define the > HAVE_LIBFDT makefile variable and config define. > > A new member of fwts_framework to hold device tree data. > > A new source (fwts_devicetree.{c,h}) in the fwts core code. At present, > this has one function to load & parse a device tree. We call this before > running tests, so that the device tree data is available to the tests. > > Using the makefile variable, we conditionally compile tests that may > require libfdt. This way, we don't introduce a dependency for building > fwts for non-devicetree platforms. > > Signed-off-by: Jeremy Kerr <jk@ozlabs.org> > Acked-by: Colin Ian King <colin.king@canonical.com> > --- > configure.ac | 5 +++ > src/Makefile.am | 7 ++++- > src/lib/include/fwts.h | 1 + > src/lib/include/fwts_devicetree.h | 43 +++++++++++++++++++++++++ > src/lib/include/fwts_framework.h | 1 + > src/lib/src/Makefile.am | 7 ++++- > src/lib/src/fwts_devicetree.c | 66 +++++++++++++++++++++++++++++++++++++++ > src/lib/src/fwts_framework.c | 3 ++ > 8 files changed, 131 insertions(+), 2 deletions(-) > create mode 100644 src/lib/include/fwts_devicetree.h > create mode 100644 src/lib/src/fwts_devicetree.c > > diff --git a/configure.ac b/configure.ac > index 5035e67..2922b5e 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -64,6 +64,11 @@ > AC_CHECK_HEADERS([glib.h]) > AC_CHECK_HEADERS([gio/gio.h]) > #AC_CHECK_LIB(pcre, pcre_compile) > + AC_SEARCH_LIBS([fdt_check_header], [fdt], [ > + AC_DEFINE([HAVE_LIBFDT], [1], [Define if we have libfdt]) > + ]) > + AM_CONDITIONAL([HAVE_LIBFDT], > + [test "x$ac_cv_search_fdt_check_header" != "xno"]) > AC_FUNC_MALLOC > AC_FUNC_FORK > AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK > diff --git a/src/Makefile.am b/src/Makefile.am > index afe7323..9889d84 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -20,6 +20,10 @@ bin_PROGRAMS = fwts > > fwts_CPPFLAGS = $(AM_CPPFLAGS) -DACPI_DEBUG_OUTPUT > > +if HAVE_LIBFDT > +dt_tests = > +endif > + > # > # fwts main + tests > # > @@ -132,7 +136,8 @@ fwts_SOURCES = main.c \ > uefi/uefibootpath/uefibootpath.c \ > uefi/uefirtauthvar/uefirtauthvar.c \ > uefi/esrtdump/esrtdump.c \ > - uefi/esrt/esrt.c > + uefi/esrt/esrt.c \ > + $(dt_tests) > > fwts_LDFLAGS = -lm `pkg-config --libs glib-2.0 gio-2.0` > > diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h > index cbc417e..fb6dafa 100644 > --- a/src/lib/include/fwts.h > +++ b/src/lib/include/fwts.h > @@ -102,5 +102,6 @@ > #include "fwts_release.h" > #include "fwts_pci.h" > #include "fwts_safe_mem.h" > +#include "fwts_devicetree.h" > > #endif > diff --git a/src/lib/include/fwts_devicetree.h b/src/lib/include/fwts_devicetree.h > new file mode 100644 > index 0000000..7c67dc5 > --- /dev/null > +++ b/src/lib/include/fwts_devicetree.h > @@ -0,0 +1,43 @@ > +/* > + * Copyright (C) 2016 IBM Corporation > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > + > +#ifndef __FWTS_DEVICETREE_H__ > +#define __FWTS_DEVICETREE_H__ > + > +#include "fwts.h" > + > +#ifdef HAVE_LIBFDT > +#define FWTS_HAS_DEVICETREE 1 > +#else > +#define FWTS_HAS_DEVICETREE 0 > +#endif > + > +#if FWTS_HAS_DEVICETREE > + > +int fwts_devicetree_read(fwts_framework *fwts); > + > +#else /* !FWTS_HAS_DEVICETREE */ > +static inline int fwts_devicetree_read(fwts_framework *fwts > + __attribute__((unused))) > +{ > + return FWTS_OK; > +} > +#endif > + > +#endif > diff --git a/src/lib/include/fwts_framework.h b/src/lib/include/fwts_framework.h > index 6c2332a..f7d5b69 100644 > --- a/src/lib/include/fwts_framework.h > +++ b/src/lib/include/fwts_framework.h > @@ -151,6 +151,7 @@ typedef struct fwts_framework { > bool error_filtered_out; /* True if a klog message has been filtered out */ > fwts_acpica_mode acpica_mode; /* ACPICA mode flags */ > void *rsdp; /* ACPI RSDP address */ > + void *fdt; /* Flattened device tree data */ > fwts_pm_method pm_method; > fwts_architecture host_arch; /* arch FWTS was built for */ > fwts_architecture target_arch; /* arch being tested */ > diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am > index 5302851..d9e5a8d 100644 > --- a/src/lib/src/Makefile.am > +++ b/src/lib/src/Makefile.am > @@ -18,6 +18,10 @@ libfwts_la_LDFLAGS = \ > > libfwts_la_CPPFLAGS = $(AM_CPPFLAGS) -DACPI_DEBUG_OUTPUT > > +if HAVE_LIBFDT > +dt_sources = fwts_devicetree.c > +endif > + > # > # Components of the fwts core helper library libfwts > # > @@ -79,4 +83,5 @@ libfwts_la_SOURCES = \ > fwts_uefi.c \ > fwts_wakealarm.c \ > fwts_pm_method.c \ > - fwts_safe_mem.c > + fwts_safe_mem.c \ > + $(dt_sources) > diff --git a/src/lib/src/fwts_devicetree.c b/src/lib/src/fwts_devicetree.c > new file mode 100644 > index 0000000..41cee54 > --- /dev/null > +++ b/src/lib/src/fwts_devicetree.c > @@ -0,0 +1,66 @@ > +/* > + * Copyright (C) 2016 IBM Corporation > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > + > +#define _GNU_SOURCE > + > +#include <stdio.h> > + > +#include "fwts.h" > + > +static const char *devicetree_fs_path = "/sys/firmware/devicetree/base"; > + > +int fwts_devicetree_read(fwts_framework *fwts) > +{ > + char *command, *data; > + int fd, rc, status; > + ssize_t len; > + pid_t pid; > + > + if (!fwts_firmware_has_features(FWTS_FW_FEATURE_DEVICETREE)) > + return FWTS_OK; > + > + rc = asprintf(&command, "dtc -I fs -O dtb %s", devicetree_fs_path); > + if (rc < 0) > + return FWTS_ERROR; > + > + fd = fwts_pipe_open(command, &pid); > + if (fd < 0) { > + free(command); > + return FWTS_ERROR; > + } > + free(command); > + > + data = fwts_pipe_read(fd, &len); > + if (data == NULL) { > + fwts_pipe_close(fd, pid); > + return FWTS_ERROR; > + } > + > + status = fwts_pipe_close(fd, pid); > + > + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { > + fprintf(stderr, "Cannot read devicetree data: dtc failed\n"); > + return FWTS_ERROR; > + } > + > + fwts->fdt = data; > + > + return FWTS_OK; > +} > + > diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c > index 2bfc753..d0979c9 100644 > --- a/src/lib/src/fwts_framework.c > +++ b/src/lib/src/fwts_framework.c > @@ -1524,6 +1524,9 @@ int fwts_framework_args(const int argc, char **argv) > goto tidy_close; > } > > + /* Init firmware data required by tests */ > + fwts_devicetree_read(fw); > + > /* Collect up tests to run */ > for (i = optind; i < argc; i++) { > fwts_framework_test *test; > Acked-by: Alex Hung <alex.hung@canonical.com>
diff --git a/configure.ac b/configure.ac index 5035e67..2922b5e 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,11 @@ AC_CHECK_HEADERS([glib.h]) AC_CHECK_HEADERS([gio/gio.h]) #AC_CHECK_LIB(pcre, pcre_compile) + AC_SEARCH_LIBS([fdt_check_header], [fdt], [ + AC_DEFINE([HAVE_LIBFDT], [1], [Define if we have libfdt]) + ]) + AM_CONDITIONAL([HAVE_LIBFDT], + [test "x$ac_cv_search_fdt_check_header" != "xno"]) AC_FUNC_MALLOC AC_FUNC_FORK AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK diff --git a/src/Makefile.am b/src/Makefile.am index afe7323..9889d84 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,10 @@ bin_PROGRAMS = fwts fwts_CPPFLAGS = $(AM_CPPFLAGS) -DACPI_DEBUG_OUTPUT +if HAVE_LIBFDT +dt_tests = +endif + # # fwts main + tests # @@ -132,7 +136,8 @@ fwts_SOURCES = main.c \ uefi/uefibootpath/uefibootpath.c \ uefi/uefirtauthvar/uefirtauthvar.c \ uefi/esrtdump/esrtdump.c \ - uefi/esrt/esrt.c + uefi/esrt/esrt.c \ + $(dt_tests) fwts_LDFLAGS = -lm `pkg-config --libs glib-2.0 gio-2.0` diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h index cbc417e..fb6dafa 100644 --- a/src/lib/include/fwts.h +++ b/src/lib/include/fwts.h @@ -102,5 +102,6 @@ #include "fwts_release.h" #include "fwts_pci.h" #include "fwts_safe_mem.h" +#include "fwts_devicetree.h" #endif diff --git a/src/lib/include/fwts_devicetree.h b/src/lib/include/fwts_devicetree.h new file mode 100644 index 0000000..7c67dc5 --- /dev/null +++ b/src/lib/include/fwts_devicetree.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __FWTS_DEVICETREE_H__ +#define __FWTS_DEVICETREE_H__ + +#include "fwts.h" + +#ifdef HAVE_LIBFDT +#define FWTS_HAS_DEVICETREE 1 +#else +#define FWTS_HAS_DEVICETREE 0 +#endif + +#if FWTS_HAS_DEVICETREE + +int fwts_devicetree_read(fwts_framework *fwts); + +#else /* !FWTS_HAS_DEVICETREE */ +static inline int fwts_devicetree_read(fwts_framework *fwts + __attribute__((unused))) +{ + return FWTS_OK; +} +#endif + +#endif diff --git a/src/lib/include/fwts_framework.h b/src/lib/include/fwts_framework.h index 6c2332a..f7d5b69 100644 --- a/src/lib/include/fwts_framework.h +++ b/src/lib/include/fwts_framework.h @@ -151,6 +151,7 @@ typedef struct fwts_framework { bool error_filtered_out; /* True if a klog message has been filtered out */ fwts_acpica_mode acpica_mode; /* ACPICA mode flags */ void *rsdp; /* ACPI RSDP address */ + void *fdt; /* Flattened device tree data */ fwts_pm_method pm_method; fwts_architecture host_arch; /* arch FWTS was built for */ fwts_architecture target_arch; /* arch being tested */ diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am index 5302851..d9e5a8d 100644 --- a/src/lib/src/Makefile.am +++ b/src/lib/src/Makefile.am @@ -18,6 +18,10 @@ libfwts_la_LDFLAGS = \ libfwts_la_CPPFLAGS = $(AM_CPPFLAGS) -DACPI_DEBUG_OUTPUT +if HAVE_LIBFDT +dt_sources = fwts_devicetree.c +endif + # # Components of the fwts core helper library libfwts # @@ -79,4 +83,5 @@ libfwts_la_SOURCES = \ fwts_uefi.c \ fwts_wakealarm.c \ fwts_pm_method.c \ - fwts_safe_mem.c + fwts_safe_mem.c \ + $(dt_sources) diff --git a/src/lib/src/fwts_devicetree.c b/src/lib/src/fwts_devicetree.c new file mode 100644 index 0000000..41cee54 --- /dev/null +++ b/src/lib/src/fwts_devicetree.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2016 IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#define _GNU_SOURCE + +#include <stdio.h> + +#include "fwts.h" + +static const char *devicetree_fs_path = "/sys/firmware/devicetree/base"; + +int fwts_devicetree_read(fwts_framework *fwts) +{ + char *command, *data; + int fd, rc, status; + ssize_t len; + pid_t pid; + + if (!fwts_firmware_has_features(FWTS_FW_FEATURE_DEVICETREE)) + return FWTS_OK; + + rc = asprintf(&command, "dtc -I fs -O dtb %s", devicetree_fs_path); + if (rc < 0) + return FWTS_ERROR; + + fd = fwts_pipe_open(command, &pid); + if (fd < 0) { + free(command); + return FWTS_ERROR; + } + free(command); + + data = fwts_pipe_read(fd, &len); + if (data == NULL) { + fwts_pipe_close(fd, pid); + return FWTS_ERROR; + } + + status = fwts_pipe_close(fd, pid); + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + fprintf(stderr, "Cannot read devicetree data: dtc failed\n"); + return FWTS_ERROR; + } + + fwts->fdt = data; + + return FWTS_OK; +} + diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c index 2bfc753..d0979c9 100644 --- a/src/lib/src/fwts_framework.c +++ b/src/lib/src/fwts_framework.c @@ -1524,6 +1524,9 @@ int fwts_framework_args(const int argc, char **argv) goto tidy_close; } + /* Init firmware data required by tests */ + fwts_devicetree_read(fw); + /* Collect up tests to run */ for (i = optind; i < argc; i++) { fwts_framework_test *test;