From patchwork Tue Feb 9 01:32:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Stone X-Patchwork-Id: 61464 Delivered-To: patches@linaro.org Received: by 10.112.43.199 with SMTP id y7csp1766755lbl; Mon, 8 Feb 2016 17:33:58 -0800 (PST) X-Received: by 10.182.153.166 with SMTP id vh6mr27306775obb.76.1454981629889; Mon, 08 Feb 2016 17:33:49 -0800 (PST) Return-Path: Received: from mail-ob0-x232.google.com (mail-ob0-x232.google.com. [2607:f8b0:4003:c01::232]) by mx.google.com with ESMTPS id v5si18729066oei.13.2016.02.08.17.33.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Feb 2016 17:33:49 -0800 (PST) Received-SPF: pass (google.com: domain of al.stone@linaro.org designates 2607:f8b0:4003:c01::232 as permitted sender) client-ip=2607:f8b0:4003:c01::232; Authentication-Results: mx.google.com; spf=pass (google.com: domain of al.stone@linaro.org designates 2607:f8b0:4003:c01::232 as permitted sender) smtp.mailfrom=al.stone@linaro.org; dkim=pass header.i=@linaro.org Received: by mail-ob0-x232.google.com with SMTP id ba1so173676632obb.3 for ; Mon, 08 Feb 2016 17:33:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3REJGi7whuCnDAskk9DrkgT02myNE0eubH5EkTJZlJ4=; b=dJq7cGHvGYY55gFDJgNdVlMiNV+5TUg4LjLyHnZJify5i7NSMXJ/xHwldnITA0j/VG 4GOnOWROKmsxabtq8odUpnFVMhif9I2xP/xU8H/NmMmuRcIz5Gz+6z2CuH5WFOm7b8B/ c9lxKi1nloSZDnMI8Xt1qwiDFZ9XI3c+fmHI8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3REJGi7whuCnDAskk9DrkgT02myNE0eubH5EkTJZlJ4=; b=gc7QC2cCMnhJqiGaxx4sWo7cdZC217n6/57OmBOZ7WiLbdKMbKojp6LZiGXGiOPrLk d4N8o1ljZD5RE6vbhn2pnYuPOo+eI0rnBrzP9I/7BOaUiPE7yE4rXMjTBKHF8zkXjCtq ORhuxn8GXxXPqBCJsxgxKIpTlSD83ErBl2wqr7/63OM6gve+q1bQU19yTpsjqNM/E2Lr TqKDdqN5X9c3D77LARKN57yla4DwsL1jXhQzQ6fj5mxZkVQk2Knchr4XjwPUIoSNzz1m C14TxgmudXpnskhUuX2dv6bj7HiX1E35XLeJZoxMhyG+YKoglxV21EAM8e/X+ERn3Tfd IPHw== X-Gm-Message-State: AG10YOSrcIJbPEZLUj0AyHg7s2rKVXtMToTkiV+vEhLnD56T/WUAO8GERUv/P0HLBbk3hKdtldM= X-Received: by 10.60.162.102 with SMTP id xz6mr16246435oeb.62.1454981629573; Mon, 08 Feb 2016 17:33:49 -0800 (PST) Return-Path: Received: from fidelio.ahs3 (c-50-134-239-249.hsd1.co.comcast.net. [50.134.239.249]) by smtp.googlemail.com with ESMTPSA id qp4sm19097135obc.9.2016.02.08.17.33.47 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 08 Feb 2016 17:33:48 -0800 (PST) From: Al Stone To: fwts-devel@lists.ubuntu.com Cc: linaro-acpi@lists.linaro.org, patches@linaro.org, Al Stone Subject: [PATCH 11/21] FADT: add compliance tests for reserved fields, PM profile, reduced hardware Date: Mon, 8 Feb 2016 18:32:53 -0700 Message-Id: <1454981583-31872-12-git-send-email-al.stone@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1454981583-31872-1-git-send-email-al.stone@linaro.org> References: <1454981583-31872-1-git-send-email-al.stone@linaro.org> Add three new compliance tests that verify that the FADT reserved fields are zero as they should be, that the PM (Power Management) profile is a legal value, and that all of the fields and flags that are to be ignored when the OSPM is in reduced hardware mode are zero. Note that the spec says to ignore many FADT fields when in reduced hardware mode. As of 6.1, it does not explicitly state that they must be zero. But, zero seems to be a reasonable value -- or at least not destructive -- on the OSPMs that use them when they should be ignored. The case can also be made that the fields should be zero; section 5.2.1.4 indicates ignored fields should be treated the same as reserved fields, which _are_ required to be zero. As a practical matter, some vendors may have chosen to sidestep the spec here and set reduced hardware mode but used the ignored field anyway. Signed-off-by: Al Stone --- src/acpi/fadt/fadt.c | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) -- 2.5.0 diff --git a/src/acpi/fadt/fadt.c b/src/acpi/fadt/fadt.c index b21653d..fd430ec 100644 --- a/src/acpi/fadt/fadt.c +++ b/src/acpi/fadt/fadt.c @@ -359,6 +359,306 @@ static void acpi_table_check_fadt_dsdt(fwts_framework *fw) } } +static void acpi_table_check_fadt_reserved(fwts_framework *fw) +{ + if (fadt->reserved == (uint8_t)0) + fwts_passed(fw, "FADT first reserved field is zero."); + else + fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTReservedZero", + "FADT first reserved field is not zero: 0x%02x", + fadt->reserved); + + if (fadt->reserved1 == (uint8_t)0) + fwts_passed(fw, "FADT second reserved field is zero."); + else + fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTReservedZero", + "FADT second reserved field is not zero: 0x%02x", + fadt->reserved1); +} + +static void acpi_table_check_fadt_pm_profile(fwts_framework *fw) +{ + 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 <= 8) + fwts_passed(fw, "FADT has a valid preferred PM profile."); + else + fwts_failed(fw, LOG_LEVEL_MEDIUM, "FADTPMProfile", + "FADT preferred PM profile is invalid."); +} + +static void acpi_table_check_fadt_reduced_hardware(fwts_framework *fw) +{ + const char *IS = "IS"; + const char *IS_NOT = "IS NOT"; + bool rhw; + bool passed; + const fwts_acpi_gas null_gas = { 0 }; + uint32_t flag_mask; + + rhw = fwts_acpi_is_reduced_hardware(fadt); + fwts_log_info(fw, "FADT indicates ACPI %s in reduced hardware mode.", + rhw ? IS : IS_NOT); + + if (!rhw) + return; + + passed = true; + + /* check all the fields that will be ignored */ + if (fadt->smi_cmd != 0) { + passed = false; + fwts_log_info(fw, "SMI_CMD is non-zero: 0x%x", + fadt->smi_cmd); + } + if (fadt->acpi_enable != 0) { + passed = false; + fwts_log_info(fw, "ACPI_ENABLE is non-zero: 0x%x", + fadt->acpi_enable); + } + if (fadt->acpi_disable != 0) { + passed = false; + fwts_log_info(fw, "ACPI_DISABLE is non-zero: 0x%x", + fadt->acpi_disable); + } + if (fadt->s4bios_req != 0) { + passed = false; + fwts_log_info(fw, "S4BIOS_REQ is non-zero: 0x%x", + fadt->s4bios_req); + } + if (fadt->pstate_cnt != 0) { + passed = false; + fwts_log_info(fw, "PSTATE_CNT is non-zero: 0x%x", + fadt->pstate_cnt); + } + if (fadt->pm1a_evt_blk != 0) { + passed = false; + fwts_log_info(fw, "PM1A_EVT_BLK is non-zero: 0x%x", + fadt->pm1a_evt_blk); + } + if (fadt->pm1b_evt_blk != 0) { + passed = false; + fwts_log_info(fw, "PM1B_EVT_BLK is non-zero: 0x%x", + fadt->pm1b_evt_blk); + } + if (fadt->pm1a_cnt_blk != 0) { + passed = false; + fwts_log_info(fw, "PM1A_CNT_BLK is non-zero: 0x%x", + fadt->pm1a_cnt_blk); + } + if (fadt->pm1b_cnt_blk != 0) { + passed = false; + fwts_log_info(fw, "PM1B_CNT_BLK is non-zero: 0x%x", + fadt->pm1b_cnt_blk); + } + if (fadt->pm2_cnt_blk != 0) { + passed = false; + fwts_log_info(fw, "PM2_CNT_BLK is non-zero: 0x%x", + fadt->pm2_cnt_blk); + } + if (fadt->pm_tmr_blk != 0) { + passed = false; + fwts_log_info(fw, "PM_TMR_BLK is non-zero: 0x%x", + fadt->pm_tmr_blk); + } + if (fadt->gpe0_blk != 0) { + passed = false; + fwts_log_info(fw, "GPE0_BLK is non-zero: 0x%x", + fadt->gpe0_blk); + } + if (fadt->gpe1_blk != 0) { + passed = false; + fwts_log_info(fw, "GPE1_BLK is non-zero: 0x%x", + fadt->gpe1_blk); + } + if (fadt->pm1_evt_len != 0) { + passed = false; + fwts_log_info(fw, "PM1_EVT_LEN is non-zero: 0x%x", + fadt->pm1_evt_len); + } + if (fadt->pm1_cnt_len != 0) { + passed = false; + fwts_log_info(fw, "PM1_CNT_LEN is non-zero: 0x%x", + fadt->pm1_cnt_len); + } + if (fadt->pm2_cnt_len != 0) { + passed = false; + fwts_log_info(fw, "PM2_CNT_LEN is non-zero: 0x%x", + fadt->pm2_cnt_len); + } + if (fadt->pm_tmr_len != 0) { + passed = false; + fwts_log_info(fw, "PM_TMR_LEN is non-zero: 0x%x", + fadt->pm_tmr_len); + } + if (fadt->gpe0_blk_len != 0) { + passed = false; + fwts_log_info(fw, "GPE0_BLK_LEN is non-zero: 0x%x", + fadt->gpe0_blk_len); + } + if (fadt->gpe1_blk_len != 0) { + passed = false; + fwts_log_info(fw, "GPE1_BLK_LEN is non-zero: 0x%x", + fadt->gpe1_blk_len); + } + if (fadt->gpe1_base != 0) { + passed = false; + fwts_log_info(fw, "GPE1_BASE is non-zero: 0x%x", + fadt->gpe1_base); + } + if (fadt->cst_cnt != 0) { + passed = false; + fwts_log_info(fw, "CST_CNT is non-zero: 0x%x", + fadt->cst_cnt); + } + if (fadt->p_lvl2_lat != 0) { + passed = false; + fwts_log_info(fw, "P_LVL2_LAT is non-zero: 0x%x", + fadt->p_lvl2_lat); + } + if (fadt->p_lvl3_lat != 0) { + passed = false; + fwts_log_info(fw, "P_LVL3_LAT is non-zero: 0x%x", + fadt->p_lvl3_lat); + } + if (fadt->flush_size != 0) { + passed = false; + fwts_log_info(fw, "FLUSH_SIZE is non-zero: 0x%x", + fadt->flush_size); + } + if (fadt->flush_stride != 0) { + passed = false; + fwts_log_info(fw, "FLUSH_STRIDE is non-zero: 0x%x", + fadt->flush_stride); + } + if (fadt->duty_offset != 0) { + passed = false; + fwts_log_info(fw, "DUTY_OFFSET is non-zero: 0x%x", + fadt->duty_offset); + } + if (fadt->duty_width != 0) { + passed = false; + fwts_log_info(fw, "DUTY_WIDTH is non-zero: 0x%x", + fadt->duty_width); + } + if (fadt->day_alrm != 0) { + passed = false; + fwts_log_info(fw, "DAY_ALRM is non-zero: 0x%x", + fadt->day_alrm); + } + if (fadt->mon_alrm != 0) { + passed = false; + fwts_log_info(fw, "MON_ALRM is non-zero: 0x%x", + fadt->mon_alrm); + } + if (fadt->century != 0) { + passed = false; + fwts_log_info(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_info(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_info(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_info(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_info(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_info(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_info(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_info(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_info(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_MEDIUM, "FADTRHWNonZero", + "Some FADT reduced hardware fields are non-zero."); + + /* 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_HEADLESS | + 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_MEDIUM, "FADTRHWFlagsNonZero", + "Some FADT reduced hardware flags are set."); + 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_MEDIUM, + "FADTRHWAPICFlags", + "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."); +} static void acpi_table_check_fadt_smi( fwts_framework *fw, @@ -545,6 +845,9 @@ static int fadt_test1(fwts_framework *fw) acpi_table_check_fadt_firmware_ctrl(fw); acpi_table_check_fadt_dsdt(fw); + acpi_table_check_fadt_reserved(fw); + acpi_table_check_fadt_pm_profile(fw); + acpi_table_check_fadt_reduced_hardware(fw); acpi_table_check_fadt_smi(fw, fadt, &passed); acpi_table_check_fadt_pm_tmr(fw, fadt, &passed); acpi_table_check_fadt_gpe(fw, fadt, &passed);