ACK: [PATCH v3 07/10] acpi: fadt: add SBBR compliance tests
Alex Hung
alex.hung at canonical.com
Wed Aug 23 18:53:56 UTC 2017
On 2017-08-23 07:20 AM, Sakar Arora wrote:
> From: Mahesh Bireddy <mahesh.reddybireddy at arm.com>
>
> Server Base Boot Requirements (SBBR) specification is intended for SBSA-
> compliant 64-bit ARMv8 servers. It defines the base firmware
> requirements for out-of-box support of any ARM SBSA-compatible
> Operating System or hypervisor. The requirements in this specification
> are expected to be minimal yet complete for booting a multi-core ARMv8
> server platform, while leaving plenty of room for OEM or ODM innovations
> and design details. For more information, download the SBBR
> specification here:
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044b/index.html
>
> This change introduces test cases as per SBBR specification to fadt acpi table.
> It adds additional tests:
> 1. Check FADT reduced HW.
> 2. Check the Profile.
> 3. Check PSCI Compliance.
>
> Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh at arm.com
> Signed-off-by: Mahesh Bireddy <mahesh.reddybireddy at arm.com>
> Signed-off-by: Sakar Arora <Sakar.Arora at arm.com>
> ---
> src/Makefile.am | 1 +
> src/sbbr/fadt/fadt.c | 418 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 419 insertions(+)
> create mode 100644 src/sbbr/fadt/fadt.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 4e9d774..23b362a 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -74,6 +74,7 @@ fwts_SOURCES = main.c \
> acpi/erst/erst.c \
> acpi/facs/facs.c \
> acpi/fadt/fadt.c \
> + sbbr/fadt/fadt.c \
> acpi/fan/fan.c \
> acpi/fpdt/fpdt.c \
> acpi/gpedump/gpedump.c \
> diff --git a/src/sbbr/fadt/fadt.c b/src/sbbr/fadt/fadt.c
> new file mode 100644
> index 0000000..691f122
> --- /dev/null
> +++ b/src/sbbr/fadt/fadt.c
> @@ -0,0 +1,418 @@
> +/*
> + * Copyright (C) 2010-2017 Canonical
> + * Copyright (C) 2017 ARM Ltd
> + * Portions of this code original from the Linux-ready Firmware Developer Kit
> + *
> + * 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.
> + *
> + */
> +#include "fwts.h"
> +
> +#if defined(FWTS_HAS_ACPI)
> +
> +#include "fwts_acpi_object_eval.h"
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <inttypes.h>
> +#include <string.h>
> +
> +static const fwts_acpi_table_fadt *fadt;
> +static int fadt_size;
> +
> +static int fadt_sbbr_init(fwts_framework *fw)
> +{
> + fwts_acpi_table_info *table;
> +
> + if (fwts_acpi_find_table(fw, "FACP", 0, &table) != FWTS_OK) {
> + fwts_log_error(fw, "Cannot read ACPI table FACP.");
> + return FWTS_ERROR;
> + }
> + if (table == NULL) {
> + fwts_log_error(fw, "ACPI table FACP does not exist!");
> + return FWTS_ERROR;
> + }
> + fadt = (const fwts_acpi_table_fadt *)table->data;
> + fadt_size = table->length;
> +
> + /* Not having a FADT is a failure on ARM SBBR Architecture */
> + if (fadt_size == 0) {
> + fwts_log_error(fw, "ACPI table FACP has zero length!");
> + return FWTS_ERROR;
> + }
> +
> + return FWTS_OK;
> +}
> +
> +static int fadt_sbbr_revision_test1(fwts_framework *fw)
> +{
> + const uint8_t SBBR_LATEST_MAJOR = 6;
> + const uint8_t SBBR_LATEST_MINOR = 0;
> + uint8_t major;
> + uint8_t minor;
> +
> + major = fadt->header.revision;
> + minor = 0;
> + if (major >= 5 && fadt->header.length >= 268)
> + minor = fadt->minor_version; /* field added ACPI 5.1 */
> +
> + fwts_log_info(fw, "FADT revision: %d.%d", major, minor);
> +
> + if (major >= SBBR_LATEST_MAJOR && minor >= SBBR_LATEST_MINOR)
> + fwts_passed(fw, "FADT revision is up to date.");
> + else {
> + fwts_failed(fw, LOG_LEVEL_CRITICAL, "fadt_revision:", "FADT revision is outdated: %d.%d",
> + major, minor);
> + }
> +
> + return FWTS_OK;
> +}
> +
> +static int fadt_sbbr_reduced_hw_test2(fwts_framework *fw)
> +{
> + bool rhw;
> + bool passed;
> + static const fwts_acpi_gas null_gas;
> + uint32_t flag_mask;
> +
> + rhw = fwts_acpi_is_reduced_hardware(fadt);
> + if (rhw == 0)
> + fwts_failed(fw, LOG_LEVEL_CRITICAL, "fadt_reduced_hw:", "FADT indicates ACPI is not in reduced hardware mode.");
> + else
> + fwts_passed(fw, "FADT indicates ACPI is in reduced hardware mode.");
> +
> +
> + if (!rhw)
> + return FWTS_OK;
> +
> + passed = true;
> +
> + /* check all the fields that will be ignored
> + * if the HW_REDUCED_ACPI flag in the table is set,
> + * OSPM will ignore fields related to the ACPI HW register interface:
> + * Fields at offsets 46 through 108 and 148 through 232, as well as
> + * FADT Flag bits 1, 2, 3,7,8,12,13, 14, 16 and 17
> + */
> +
> + if (fadt->sci_int != 0) {
> + passed = false;
> + fwts_log_warning(fw, "SCI_INT is non-zero: 0x%x",
> + fadt->smi_cmd);
> + }
> + if (fadt->smi_cmd != 0) {
> + passed = false;
> + fwts_log_warning(fw, "SMI_CMD is non-zero: 0x%x",
> + fadt->smi_cmd);
> + }
> + if (fadt->acpi_enable != 0) {
> + passed = false;
> + fwts_log_warning(fw, "ACPI_ENABLE is non-zero: 0x%x",
> + fadt->acpi_enable);
> + }
> + if (fadt->acpi_disable != 0) {
> + passed = false;
> + fwts_log_warning(fw, "ACPI_DISABLE is non-zero: 0x%x",
> + fadt->acpi_disable);
> + }
> + if (fadt->s4bios_req != 0) {
> + passed = false;
> + fwts_log_warning(fw, "S4BIOS_REQ is non-zero: 0x%x",
> + fadt->s4bios_req);
> + }
> + if (fadt->pstate_cnt != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PSTATE_CNT is non-zero: 0x%x",
> + fadt->pstate_cnt);
> + }
> + if (fadt->pm1a_evt_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM1A_EVT_BLK is non-zero: 0x%x",
> + fadt->pm1a_evt_blk);
> + }
> + if (fadt->pm1b_evt_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM1B_EVT_BLK is non-zero: 0x%x",
> + fadt->pm1b_evt_blk);
> + }
> + if (fadt->pm1a_cnt_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM1A_CNT_BLK is non-zero: 0x%x",
> + fadt->pm1a_cnt_blk);
> + }
> + if (fadt->pm1b_cnt_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM1B_CNT_BLK is non-zero: 0x%x",
> + fadt->pm1b_cnt_blk);
> + }
> + if (fadt->pm2_cnt_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM2_CNT_BLK is non-zero: 0x%x",
> + fadt->pm2_cnt_blk);
> + }
> + if (fadt->pm_tmr_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM_TMR_BLK is non-zero: 0x%x",
> + fadt->pm_tmr_blk);
> + }
> + if (fadt->gpe0_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "GPE0_BLK is non-zero: 0x%x",
> + fadt->gpe0_blk);
> + }
> + if (fadt->gpe1_blk != 0) {
> + passed = false;
> + fwts_log_warning(fw, "GPE1_BLK is non-zero: 0x%x",
> + fadt->gpe1_blk);
> + }
> + if (fadt->pm1_evt_len != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM1_EVT_LEN is non-zero: 0x%x",
> + fadt->pm1_evt_len);
> + }
> + if (fadt->pm1_cnt_len != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM1_CNT_LEN is non-zero: 0x%x",
> + fadt->pm1_cnt_len);
> + }
> + if (fadt->pm2_cnt_len != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM2_CNT_LEN is non-zero: 0x%x",
> + fadt->pm2_cnt_len);
> + }
> + if (fadt->pm_tmr_len != 0) {
> + passed = false;
> + fwts_log_warning(fw, "PM_TMR_LEN is non-zero: 0x%x",
> + fadt->pm_tmr_len);
> + }
> + if (fadt->gpe0_blk_len != 0) {
> + passed = false;
> + fwts_log_warning(fw, "GPE0_BLK_LEN is non-zero: 0x%x",
> + fadt->gpe0_blk_len);
> + }
> + if (fadt->gpe1_blk_len != 0) {
> + passed = false;
> + fwts_log_warning(fw, "GPE1_BLK_LEN is non-zero: 0x%x",
> + fadt->gpe1_blk_len);
> + }
> + if (fadt->gpe1_base != 0) {
> + passed = false;
> + fwts_log_warning(fw, "GPE1_BASE is non-zero: 0x%x",
> + fadt->gpe1_base);
> + }
> + if (fadt->cst_cnt != 0) {
> + passed = false;
> + fwts_log_warning(fw, "CST_CNT is non-zero: 0x%x",
> + fadt->cst_cnt);
> + }
> + if (fadt->p_lvl2_lat != 0) {
> + passed = false;
> + fwts_log_warning(fw, "P_LVL2_LAT is non-zero: 0x%x",
> + fadt->p_lvl2_lat);
> + }
> + if (fadt->p_lvl3_lat != 0) {
> + passed = false;
> + fwts_log_warning(fw, "P_LVL3_LAT is non-zero: 0x%x",
> + fadt->p_lvl3_lat);
> + }
> + if (fadt->flush_size != 0) {
> + passed = false;
> + fwts_log_warning(fw, "FLUSH_SIZE is non-zero: 0x%x",
> + fadt->flush_size);
> + }
> + if (fadt->flush_stride != 0) {
> + passed = false;
> + fwts_log_warning(fw, "FLUSH_STRIDE is non-zero: 0x%x",
> + fadt->flush_stride);
> + }
> + if (fadt->duty_offset != 0) {
> + passed = false;
> + fwts_log_warning(fw, "DUTY_OFFSET is non-zero: 0x%x",
> + fadt->duty_offset);
> + }
> + if (fadt->duty_width != 0) {
> + passed = false;
> + fwts_log_warning(fw, "DUTY_WIDTH is non-zero: 0x%x",
> + fadt->duty_width);
> + }
> + if (fadt->day_alrm != 0) {
> + passed = false;
> + fwts_log_warning(fw, "DAY_ALRM is non-zero: 0x%x",
> + fadt->day_alrm);
> + }
> + if (fadt->mon_alrm != 0) {
> + passed = false;
> + fwts_log_warning(fw, "MON_ALRM is non-zero: 0x%x",
> + fadt->mon_alrm);
> + }
> + if (fadt->century != 0) {
> + passed = false;
> + fwts_log_warning(fw, "CENTURY is non-zero: 0x%x",
> + fadt->century);
> + }
> + if (memcmp((void *)&fadt->x_pm1a_evt_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_PM1A_EVT_BLK is a non-zero general "
> + "address structure.");
> + }
> + if (memcmp((void *)&fadt->x_pm1b_evt_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_PM1B_EVT_BLK is a non-zero general "
> + "address structure.");
> + }
> + if (memcmp((void *)&fadt->x_pm1a_cnt_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_PM1A_CNT_BLK is a non-zero general "
> + "address structure.");
> + }
> + if (memcmp((void *)&fadt->x_pm1b_cnt_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_PM1B_CNT_BLK is a non-zero general "
> + "address structure.");
> + }
> + if (memcmp((void *)&fadt->x_pm2_cnt_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_PM2_CNT_BLK is a non-zero general "
> + "address structure.");
> + }
> + if (memcmp((void *)&fadt->x_pm_tmr_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_PM_TMR_BLK is a non-zero general "
> + "address structure.");
> + }
> + if (memcmp((void *)&fadt->x_gpe0_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_GPE0_BLK is a non-zero general "
> + "address structure.");
> + }
> + if (memcmp((void *)&fadt->x_gpe1_blk,
> + (void *)&null_gas,
> + sizeof(fwts_acpi_gas))) {
> + passed = false;
> + fwts_log_warning(fw,
> + "X_GPE1_BLK is a non-zero general "
> + "address structure.");
> + }
> +
> + if (passed)
> + fwts_passed(fw, "All FADT reduced hardware fields are zero.");
> + else
> + fwts_failed(fw, LOG_LEVEL_CRITICAL, "fadt_reduced_hw:",
> + "Some FADT reduced hardware fields are non-zero, but it will be ignored by OSPM.");
> +
> + /* now check all the reserved flags */
> + flag_mask = FWTS_FACP_FLAG_WBINVD_FLUSH |
> + FWTS_FACP_FLAG_PROC_C1 |
> + FWTS_FACP_FLAG_P_LVL2_UP |
> + FWTS_FACP_FLAG_RTC_S4 |
> + FWTS_FACP_FLAG_TMR_VAL_EXT |
> + FWTS_FACP_FLAG_CPU_SW_SLP |
> + FWTS_FACP_FLAG_PCI_EXP_WAK |
> + FWTS_FACP_FLAG_S4_RTC_STS_VALID |
> + FWTS_FACP_FLAG_REMOTE_POWER_ON_CAPABLE;
> +
> + if (fadt->flags & flag_mask)
> + fwts_failed(fw, LOG_LEVEL_CRITICAL, "fadt_reduced_hw:",
> + "Some FADT reduced hardware flags are set, but it will be ignored by OSPM.");
> + else
> + fwts_passed(fw, "All FADT reduced hardware flags are not set.");
> +
> +
> + if ((fadt->flags & FWTS_FACP_FLAG_FORCE_APIC_CLUSTER_MODEL) ||
> + (fadt->flags & FWTS_FACP_FLAG_FORCE_APIC_PHYSICAL_DESTINATION_MODE))
> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
> + "fadt_reduced_hw:",
> + "FADT APIC flags are set for reduced hardware "
> + "mode but may be irrelevant.");
> + else
> + fwts_passed(fw,
> + "FADT APIC flags are not set in reduced "
> + "hardware mode.");
> +
> + return FWTS_OK;
> +}
> +
> +static int fadt_sbbr_profile_test3(fwts_framework *fw)
> +{
> + const uint8_t SBBR_ENT_SERVER = 4;
> + const uint8_t SBBR_SOHO_SERVER = 5;
> + const uint8_t SBBR_PERF_SERVER = 7;
> +
> + fwts_log_info(fw, "FADT Preferred PM Profile: %hhu (%s)\n",
> + fadt->preferred_pm_profile,
> + FWTS_ACPI_FADT_PREFERRED_PM_PROFILE(fadt->preferred_pm_profile));
> +
> + if ((fadt->preferred_pm_profile == SBBR_ENT_SERVER) ||
> + (fadt->preferred_pm_profile == SBBR_SOHO_SERVER) ||
> + (fadt->preferred_pm_profile == SBBR_PERF_SERVER))
> + fwts_passed(fw, "FADT has a recommended server PM profile.");
> + else
> + fwts_failed(fw, LOG_LEVEL_MEDIUM, "fadt_profile:", "FADT preferred PM profile is not recommended.");
> +
> + return FWTS_OK;
> +}
> +
> +static int fadt_sbbr_boot_arch_psci_compliant_test4(fwts_framework *fw)
> +{
> + /* ARM SBBR 4.2.1.3 FADT */
> + if (fadt->arm_boot_flags & FWTS_FACP_ARM_BOOT_ARCH_PSCI_COMPLIANT)
> + fwts_passed(fw, "PSCI_COMPLIANT is set, PSCI is implemented.");
> + else
> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
> + "ARCH_PSCI_COMPLIANT:",
> + "PSCI is NOT implemented.");
> +
> + return FWTS_OK;
> +}
> +
> +static fwts_framework_minor_test fadt_sbbr_tests[] = {
> + { fadt_sbbr_revision_test1, "FADT Revision Test." },
> + { fadt_sbbr_reduced_hw_test2, "FADT Reduced HW Test." },
> + { fadt_sbbr_profile_test3, "FADT Server Profile Test." },
> + { fadt_sbbr_boot_arch_psci_compliant_test4, "FADT PSCI Compliant Test." },
> + { NULL, NULL }
> +};
> +
> +static fwts_framework_ops fadt_sbbr_ops = {
> + .description = "SBBR FADT Fixed ACPI Description Table tests.",
> + .init = fadt_sbbr_init,
> + .minor_tests = fadt_sbbr_tests
> +};
> +
> +FWTS_REGISTER("fadt_sbbr", &fadt_sbbr_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_TEST_SBBR)
> +#endif
>
Acked-by: Alex Hung <alex.hung at canonical.com>
More information about the fwts-devel
mailing list