[PATCH 3/4] opal: cpu_info: Add OPAL CPU Info validation
Colin Ian King
colin.king at canonical.com
Fri Nov 11 09:45:56 UTC 2016
On 11/11/16 04:02, Deb McLemore wrote:
> Check that the CPU devices are properly setup in the device tree.
>
> Signed-off-by: Deb McLemore <debmc at linux.vnet.ibm.com>
> ---
> src/Makefile.am | 3 +
> src/opal/cpu_info.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 279 insertions(+)
> create mode 100644 src/opal/cpu_info.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 9c2975b..c1eb285 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -26,6 +26,8 @@ dt_tests = \
> devicetree/dt_sysinfo/dt_sysinfo.c
> mem_tests = \
> opal/mem_info.c
> +cpu_tests = \
> + opal/cpu_info.c
> endif
>
> if HAVE_LIBFDT
> @@ -161,6 +163,7 @@ fwts_SOURCES = main.c \
> uefi/esrt/esrt.c \
> $(pci_tests) \
> $(mem_tests) \
> + $(cpu_tests) \
> $(dt_tests)
>
> fwts_LDFLAGS = -lm `pkg-config --libs glib-2.0 gio-2.0`
> diff --git a/src/opal/cpu_info.c b/src/opal/cpu_info.c
> new file mode 100644
> index 0000000..9953c90
> --- /dev/null
> +++ b/src/opal/cpu_info.c
> @@ -0,0 +1,276 @@
> +/*
> + * Copyright (C) 2010-2016 Canonical
> + * Some of this work - Copyright (C) 2016 IBM
> + *
> + * 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 /* added for asprintf */
> +#include <fcntl.h>
> +#include <sys/ioctl.h>
> +#include <stdio.h>
> +
> +#include "fwts.h"
> +
> +#include <libfdt.h>
> +
> +static int get_xscom_property(fwts_framework *fw,
> + char *my_path,
> + bool hex,
> + char *property)
> +{
> + int node, prop_len, failures = 0;
> + const char *prop_buf;
> + char *prop_string = NULL;
> +
> + prop_string = strstr(my_path, "/xscom");
> + if (prop_string) {
> + node = fdt_path_offset(fw->fdt, prop_string);
> + if (node >= 0) {
> + prop_buf = fdt_getprop(fw->fdt, node,
> + property,
> + &prop_len);
> + if ((prop_len > 0) && (prop_buf)) {
> + fwts_log_nl(fw);
> + if ((hex) && (prop_len == 4)) {
> + fwts_passed(fw,
> + "OPAL CPU Info Property of"
> + "\"%s\" for \"%s\" is "
> + "\"0x%02X%02X%02X%02X\".",
> + property,
> + my_path,
> + prop_buf[0],
> + prop_buf[1],
> + prop_buf[2],
> + prop_buf[3]);
> + } else if (!hex) {
> + if (check_property_printable(fw,
> + property,
> + prop_buf,
> + prop_len)) {
> + failures ++;
> + }
> + fwts_passed(fw,
> + "OPAL CPU Info Property of"
> + " \"%s\" for \"%s\" "
> + "is \"%s\".",
> + property,
> + my_path,
> + prop_buf);
> + } else {
> + failures ++;
> + fwts_log_nl(fw);
> + fwts_failed(fw,
> + LOG_LEVEL_CRITICAL,
> + "OPAL CPU Info",
> + "Property of "
> + "\"%s\" for \"%s\" is not"
> + " properly formatted."
> + " Check your installation"
> + " for proper device tree "
> + "nodes.",
> + property,
> + my_path);
> + }
> + } else {
> + failures ++;
> + fwts_log_nl(fw);
> + fwts_failed(fw,
> + LOG_LEVEL_CRITICAL,
> + "OPAL CPU Info",
> + "Property of \"%s\" for \"%s\" was"
> + " not able to be retrieved. Check the"
> + " installation for the CPU device"
> + " config for missing nodes in the"
> + " device tree if you expect CPU"
> + " devices.",
> + property,
> + my_path);
> + }
> + } else {
> + failures ++;
> + fwts_log_nl(fw);
> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
> + "OPAL CPU Info",
> + "Failed to get node for xscom"
> + " \"%s/%s\", please check the system for"
> + " setup issues.",
> + my_path, property);
> + }
> + } else {
> + failures ++;
> + fwts_log_nl(fw);
> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
> + "OPAL CPU Info",
> + "Internal processing problem at strstr"
> + " my_path of \"%s\" for \"%s\", please check the"
> + " system for setup issues.",
> + my_path,
> + property);
> + }
> + if (failures) {
> + return FWTS_ERROR;
> + } else {
> + return FWTS_OK;
> + }
> +}
> +
> +static int get_linux_xscom_devices(fwts_framework *fw)
> +{
> + int count, i, failures = 0;
> + struct dirent **namelist;
> + bool found = false;
> +
> + count = scandir(DT_FS_PATH, &namelist, NULL, alphasort);
> + if (count < 0) {
> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
> + "OPAL CPU Info",
> + "Scan for CPU devices in '%s' is unable to find any"
> + " candidates. Check the installation for the CPU"
> + " device config for missing nodes in the device tree"
> + " (xscom at X) if you expect CPU devices.",
> + DT_FS_PATH);
> + return FWTS_ERROR;
> + }
> +
> + fwts_log_nl(fw);
> + fwts_log_info(fw, "STARTING checks of CPU'S");
> +
> + for (i = 0; i < count; i++) {
> + struct dirent *dirent;
> + char *cpus;
> + char *xscom_path;
> +
> + dirent = namelist[i];
> +
> + if (dirent->d_name[0] == '.' ||
> + asprintf(&cpus,
> + "%s",
> + dirent->d_name) < 0) {
> + /* asprintf must be last condition so when it */
> + /* evaluates cpus gets allocated */
> + free(namelist[i]);
> + continue;
> + }
> +
> + if (strstr(cpus, "xscom")) {
> + found = true;
> + if (asprintf(&xscom_path,
> + "%s/%s",
> + DT_FS_PATH,
> + cpus) < 0 ) {
> + fwts_log_nl(fw);
> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
> + "OPAL CPU Info",
> + "Internal processing problem at"
> + " cpus \"%s\", please"
> + " check the system for"
> + " setup issues.",
> + cpus);
> + free(cpus);
> + free(namelist[i]);
> + continue;
> + }
> + if (get_xscom_property(fw, xscom_path, false,
> + DT_PROPERTY_OPAL_SLOT_LOC)) {
> + failures ++;
> + }
> +
> + if (get_xscom_property(fw, xscom_path, false,
> + DT_PROPERTY_OPAL_PART_NUM)) {
> + failures ++;
> + }
> +
> + if (get_xscom_property(fw, xscom_path, false,
> + DT_PROPERTY_OPAL_SERIAL_NUM)) {
> + failures ++;
> + }
> +
> + if (get_xscom_property(fw, xscom_path, false,
> + DT_PROPERTY_OPAL_VENDOR)) {
> + failures ++;
> + }
> +
> + if (get_xscom_property(fw, xscom_path, false,
> + DT_PROPERTY_OPAL_BOARD_INFO)) {
> + failures ++;
> + }
> + fwts_log_nl(fw);
> + free(cpus);
> + free(namelist[i]);
> + }
> + }
> + free(namelist);
> +
> + fwts_log_nl(fw);
> + fwts_log_info(fw, "ENDING checks of CPU's");
> + fwts_log_nl(fw);
> +
> + if (!found) {
> + failures ++;
> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
> + "OPAL CPU Info",
> + "No CPU devices (xscom at X) were found in \"%s\"."
> + " Check the system for setup issues.",
> + DT_FS_PATH);
> + }
> +
> + if (failures) {
> + return FWTS_ERROR;
> + } else {
> + return FWTS_OK;
> + }
> +
> +}
> +
> +static int cpu_info_test1(fwts_framework *fw)
> +{
> + if (get_linux_xscom_devices(fw)) {
> +
> + /* errors logged earlier */
> + return FWTS_ERROR;
> + } else {
> + return FWTS_OK;
> + }
> +}
> +
> +static int cpu_info_init(fwts_framework *fw)
> +{
> + if (fw->firmware_type != FWTS_FIRMWARE_OPAL) {
> + fwts_skipped(fw,
> + "The firmware type detected was not set"
> + " to OPAL so skipping the OPAL CPU Info"
> + " checks.");
> + return FWTS_SKIP;
> + } else {
> + return FWTS_OK;
> + }
> +}
> +
> +static fwts_framework_minor_test cpu_info_tests[] = {
> + { cpu_info_test1, "OPAL CPU Info" },
> + { NULL, NULL }
> +};
> +
> +static fwts_framework_ops cpu_info_ops = {
> + .description = "OPAL CPU Info",
> + .init = cpu_info_init,
> + .minor_tests = cpu_info_tests
> +};
> +
> +FWTS_REGISTER_FEATURES("cpu_info", &cpu_info_ops, FWTS_TEST_ANYTIME,
> + FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV,
> + FWTS_FW_FEATURE_DEVICETREE);
>
Acked-by: Colin Ian King <colin.king at canonical.com>
More information about the fwts-devel
mailing list