From patchwork Fri Feb 19 23:39:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Stone X-Patchwork-Id: 585487 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id A72B71402D8; Sat, 20 Feb 2016 10:41:12 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b=PKKd2E54; dkim-atps=neutral Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1aWuff-0005OP-Ia; Fri, 19 Feb 2016 23:41:11 +0000 Received: from mail-ob0-f178.google.com ([209.85.214.178]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.76) (envelope-from ) id 1aWufP-0005ID-Fl for fwts-devel@lists.ubuntu.com; Fri, 19 Feb 2016 23:40:55 +0000 Received: by mail-ob0-f178.google.com with SMTP id ts10so6495073obc.1 for ; Fri, 19 Feb 2016 15:40:55 -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=DbOGFzeV+mkksHKEUHyywDQpyJTm85LFcvjldA86v/o=; b=PKKd2E54lQC08/D+bMxNNx1UhmNXmmqCgI1BkVVrVsjoCPVMbksY/+tEsVnrfNKJ/p OxU7ktJrXBGBJVn9/U4lHFec/GSbT/Q47OB7vLwuMsRJQ/ngxmP7CyQ2YhNVtY8Okq4V Fn+ozEMFIhuDkHSivr3sjs74+BZjPVDtoqAn0= 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=DbOGFzeV+mkksHKEUHyywDQpyJTm85LFcvjldA86v/o=; b=B29Sa642DhHrFdA/d7hxgabHNrcTGkzd4686Q3LyyASFZoh+etptjrzxNUXewnIysT 0kGfjLsn3aHrabaSTmJyz+Za0h42DrCybXMx0T9aKYOQf1zBizQsHNd4fQUoAWeCH8x7 8Pqg+3FCjMnMmMa1VRf4ONWawyYPBnoBmQTuNsfqlVlAqTmJI94xXoa7XYC76653zMok olK4kvX3TzXV2HBB8RB3T7GLj/+Ozd+zDrbBTq3wpagq6CPuhTbnu9BM3HudarrMNbz/ stikpflaETrQP/Oloaw4TVEWJuV2ivrrI7/gIRPzVS46y9Z2yS9nD6SRuUbIsZixneG1 gTbw== X-Gm-Message-State: AG10YOSR5eRG9421SK4+17iJPXGwDqs3ot0OU+ZjWKFLUbYSzqPh0lNQ9/PkLzl4TWv6R4Pv X-Received: by 10.60.50.98 with SMTP id b2mr13683670oeo.38.1455925254434; Fri, 19 Feb 2016 15:40:54 -0800 (PST) Received: from fidelio.ahs3.com (c-50-134-239-249.hsd1.co.comcast.net. [50.134.239.249]) by smtp.googlemail.com with ESMTPSA id kg7sm8655217obb.27.2016.02.19.15.40.52 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 19 Feb 2016 15:40:53 -0800 (PST) From: Al Stone To: fwts-devel@lists.ubuntu.com Subject: [PATCH v2 11/23] FADT: add compliance tests for reserved fields, PM profile, reduced hardware Date: Fri, 19 Feb 2016 16:39:47 -0700 Message-Id: <1455925199-8587-12-git-send-email-al.stone@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1455925199-8587-1-git-send-email-al.stone@linaro.org> References: <1455925199-8587-1-git-send-email-al.stone@linaro.org> Cc: patches@linaro.org, linaro-acpi@lists.linaro.org X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: fwts-devel-bounces@lists.ubuntu.com 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 Acked-by: Colin Ian King Acked-by: Alex Hung --- src/acpi/fadt/fadt.c | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) diff --git a/src/acpi/fadt/fadt.c b/src/acpi/fadt/fadt.c index 4a39c01..5b126fb 100644 --- a/src/acpi/fadt/fadt.c +++ b/src/acpi/fadt/fadt.c @@ -383,6 +383,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, @@ -569,6 +869,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);