From patchwork Wed Dec 27 04:08:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Hu X-Patchwork-Id: 1880409 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=fwts-devel-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T0J6r4Jhkz1ydd for ; Wed, 27 Dec 2023 15:09:07 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1rILE2-0007OF-1i; Wed, 27 Dec 2023 04:08:58 +0000 Received: from smtp-relay-canonical-1.internal ([10.131.114.174] helo=smtp-relay-canonical-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1rILE0-0007O7-4R for fwts-devel@lists.ubuntu.com; Wed, 27 Dec 2023 04:08:56 +0000 Received: from canonical.com (unknown [10.101.194.164]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-1.canonical.com (Postfix) with ESMTPSA id 532AF3F722 for ; Wed, 27 Dec 2023 04:08:55 +0000 (UTC) From: Ivan Hu To: fwts-devel@lists.ubuntu.com Subject: [PATCH] acpi: method: clarify TAD device methods requirements (mantis 2253) Date: Wed, 27 Dec 2023 12:08:51 +0800 Message-Id: <20231227040851.23354-1-ivan.hu@canonical.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: "fwts-devel" BugLink:https://bugs.launchpad.net/fwts/+bug/2047212 Clarify Time and Alarm Device methods requirements added in ACPI6.5 Signed-off-by: Ivan Hu --- src/acpi/method/method.c | 163 ++++++++++++++++++++++++++++++++++----- 1 file changed, 144 insertions(+), 19 deletions(-) diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c index 2885f3f1..93251d89 100644 --- a/src/acpi/method/method.c +++ b/src/acpi/method/method.c @@ -271,6 +271,7 @@ #define DEVICE_D3COLD 4 static bool fadt_mobile_platform; /* True if a mobile platform */ +static uint32_t gcp_return_value; #define method_test_integer(name, type) \ static int method_test ## name(fwts_framework *fw) \ @@ -296,6 +297,7 @@ static int method_init(fwts_framework *fw) bool got_fadt = false; fadt_mobile_platform = false; + gcp_return_value = 0; /* Some systems have multiple FADTs, sigh */ for (i = 0; i < 256; i++) { @@ -2907,11 +2909,94 @@ static int method_test_UPP(fwts_framework *fw) /* * Section 9.18 Wake Alarm Device */ +static void method_test_GCP_return( + fwts_framework *fw, + char *name, + ACPI_BUFFER *buf, + ACPI_OBJECT *obj, + void *private) +{ + uint32_t *mask = (uint32_t *) private; + bool failed = false; + + if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_INTEGER) != FWTS_OK) + return; + + gcp_return_value = obj->Integer.Value; + + if (gcp_return_value & *mask) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodIllegalReserved", + "%s returned value 0x%4.4" PRIx32 " and some of the " + "reserved bits are set when they should be zero.", + name, (uint32_t)obj->Integer.Value); + } + /* If wake on DC is supported (bit 1), then wake from AC (bit 0) must be supported */ + if (gcp_return_value & (1 << 1) && !(gcp_return_value & 1)) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if DC is supported(bit 1), " + "then wake from AC(bit 0) must be supported.", name, gcp_return_value); + } + /* If wake on AC from S5 is supported (bit 6), then wake on AC from S4 must be supported (bit 5) */ + if (gcp_return_value & (1 << 6) && !(gcp_return_value & (1 << 5))) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if wake on AC from S5 is supported(bit 6), " + "then wake on AC from S4 must be supported(bit 5).", name, gcp_return_value); + } + /* If wake on AC from S4 is supported (bit 5), then wake on AC must be supported (bit 0) */ + if (gcp_return_value & (1 << 5) && !(gcp_return_value & 1)) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if wake on AC from S4 is supported(bit 5), " + "then wake on AC must be supported(bit 0).", name, gcp_return_value); + } + /* If wake on DC from S5 is supported (bit 8), then wake on DC from S4 must be supported (bit 7) */ + if (gcp_return_value & (1 << 8) && !(gcp_return_value & (1 << 7))) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if wake on DC from S5 is supported(bit 8), " + "then wake on DC from S4 must be supported(bit 7).", name, gcp_return_value); + } + /* If wake on DC from S4 is supported (bit 7), then wake on DC must be supported (bit 1) */ + if (gcp_return_value & (1 << 7) && !(gcp_return_value & (1 << 1))) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if wake on DC from S4 is supported(bit 7), " + "then wake on DC must be supported(bit 1).", name, gcp_return_value); + } + /* If wake on DC from S4 is supported (bit 7), then wake on AC from S4 must be supported (bit 5) */ + if (gcp_return_value & (1 << 7) && !(gcp_return_value & (1 << 5))) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if wake on DC from S4 is supported(bit 7), " + "then wake on AC from S4 must be supported(bit 5).", name, gcp_return_value); + } + /* If wake on DC from S5 is supported (bit 8), then wake on AC from S5 must be supported (bit 6) */ + if (gcp_return_value & (1 << 8) && !(gcp_return_value & (1 << 6))) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if wake on DC from S5 is supported(bit 8), " + "then wake on AC from S5 must be supported(bit 6).", name, gcp_return_value); + } + /* If wake from S4/S5 is supported (bits 5-8), then _GWS must be supported (bit 4) */ + if (gcp_return_value & 0x1e0 && !(gcp_return_value & (1 << 4))) { + failed = true; + fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodBadSupport", + "%s returned value 0x%4.4" PRIx32 ", if wake from S4/S5 is supported(bits 5-8), " + "then _GWS must be supported(bit 4).", name, gcp_return_value); + } + + if (!failed) + fwts_passed(fw, "%s correctly returned an integer.", name); +} + static int method_test_GCP(fwts_framework *fw) { - uint64_t mask = ~0x1ff; + uint32_t mask = ~0x1ff; return method_evaluate_method(fw, METHOD_OPTIONAL, - "_GCP", NULL, 0, fwts_method_test_integer_reserved_bits_return, &mask); + "_GCP", NULL, 0, method_test_GCP_return, &mask); } static void method_test_GRT_return( @@ -2938,8 +3023,13 @@ static void method_test_GRT_return( static int method_test_GRT(fwts_framework *fw) { - return method_evaluate_method(fw, METHOD_OPTIONAL, - "_GRT", NULL, 0, method_test_GRT_return, NULL); + /* This object is required if the capabilities bit 2 is set to 1 */ + if (gcp_return_value & (1 << 2)) + return method_evaluate_method(fw, METHOD_MANDATORY, + "_GRT", NULL, 0, method_test_GRT_return, NULL); + else + return method_evaluate_method(fw, METHOD_OPTIONAL, + "_GRT", NULL, 0, method_test_GRT_return, NULL); } static int method_test_SRT(fwts_framework *fw) @@ -2959,9 +3049,13 @@ static int method_test_SRT(fwts_framework *fw) arg0.Type = ACPI_TYPE_BUFFER; arg0.Buffer.Length = time_size; arg0.Buffer.Pointer = (void *)&real_time; - - return method_evaluate_method(fw, METHOD_OPTIONAL, - "_SRT", &arg0, 1, fwts_method_test_integer_return, NULL); + /* This object is required if the capabilities bit 2 is set to 1 */ + if (gcp_return_value & (1 << 2)) + return method_evaluate_method(fw, METHOD_MANDATORY, + "_SRT", &arg0, 1, fwts_method_test_integer_return, NULL); + else + return method_evaluate_method(fw, METHOD_OPTIONAL, + "_SRT", &arg0, 1, fwts_method_test_integer_return, NULL); } static int method_test_GWS(fwts_framework *fw) @@ -2972,8 +3066,13 @@ static int method_test_GWS(fwts_framework *fw) arg[0].Type = ACPI_TYPE_INTEGER; arg[0].Integer.Value = 1; /* DC timer */ - return method_evaluate_method(fw, METHOD_OPTIONAL, - "_GWS", arg, 1, fwts_method_test_integer_reserved_bits_return, &mask); + /* This object is required if the capabilities bit 0 is set to 1 */ + if (gcp_return_value & 1) + return method_evaluate_method(fw, METHOD_MANDATORY, "_GWS", + arg, 1, fwts_method_test_integer_reserved_bits_return, &mask); + else + return method_evaluate_method(fw, METHOD_OPTIONAL, "_GWS", + arg, 1, fwts_method_test_integer_reserved_bits_return, &mask); } static void method_test_CWS_return( @@ -3005,8 +3104,13 @@ static int method_test_CWS(fwts_framework *fw) for (i = 0; i < 2; i++) { arg[0].Integer.Value = i; - ret = method_evaluate_method(fw, METHOD_OPTIONAL, - "_CWS", arg, 1, method_test_CWS_return, NULL); + /* This object is required if the capabilities bit 0 is set to 1 */ + if (gcp_return_value & 1) + ret = method_evaluate_method(fw, METHOD_MANDATORY, + "_CWS", arg, 1, method_test_CWS_return, NULL); + else + ret = method_evaluate_method(fw, METHOD_OPTIONAL, + "_CWS", arg, 1, method_test_CWS_return, NULL); if (ret != FWTS_OK) break; @@ -3024,8 +3128,13 @@ static int method_test_STP(fwts_framework *fw) arg[1].Type = ACPI_TYPE_INTEGER; arg[1].Integer.Value = 0; /* wake up instantly */ - return method_evaluate_method(fw, METHOD_OPTIONAL, - "_STP", arg, 2, fwts_method_test_passed_failed_return, "_STP"); + /* This object is required if the capabilities bit 0 is set to 1 */ + if (gcp_return_value & 1) + return method_evaluate_method(fw, METHOD_MANDATORY, "_STP", + arg, 2, fwts_method_test_passed_failed_return, "_STP"); + else + return method_evaluate_method(fw, METHOD_OPTIONAL, "_STP", + arg, 2, fwts_method_test_passed_failed_return, "_STP"); } static int method_test_STV(fwts_framework *fw) @@ -3037,8 +3146,13 @@ static int method_test_STV(fwts_framework *fw) arg[1].Type = ACPI_TYPE_INTEGER; arg[1].Integer.Value = 100; /* timer value */ - return method_evaluate_method(fw, METHOD_OPTIONAL, - "_STV", arg, 2, fwts_method_test_passed_failed_return, "_STV"); + /* This object is required if the capabilities bit 0 is set to 1 */ + if (gcp_return_value & 1) + return method_evaluate_method(fw, METHOD_MANDATORY, "_STV", + arg, 2, fwts_method_test_passed_failed_return, "_STV"); + else + return method_evaluate_method(fw, METHOD_OPTIONAL, "_STV", + arg, 2, fwts_method_test_passed_failed_return, "_STV"); } static int method_test_TIP(fwts_framework *fw) @@ -3048,8 +3162,13 @@ static int method_test_TIP(fwts_framework *fw) arg[0].Type = ACPI_TYPE_INTEGER; arg[0].Integer.Value = 1; /* DC timer */ - return method_evaluate_method(fw, METHOD_OPTIONAL, - "_TIP", arg, 1, fwts_method_test_integer_return, NULL); + /* This object is required if the capabilities bit 0 is set to 1 */ + if (gcp_return_value & 1) + return method_evaluate_method(fw, METHOD_MANDATORY, + "_TIP", arg, 1, fwts_method_test_integer_return, NULL); + else + return method_evaluate_method(fw, METHOD_OPTIONAL, + "_TIP", arg, 1, fwts_method_test_integer_return, NULL); } static int method_test_TIV(fwts_framework *fw) @@ -3059,8 +3178,14 @@ static int method_test_TIV(fwts_framework *fw) arg[0].Type = ACPI_TYPE_INTEGER; arg[0].Integer.Value = 1; /* DC timer */ - return method_evaluate_method(fw, METHOD_OPTIONAL, - "_TIV", arg, 1, fwts_method_test_integer_return, NULL); + /* This object is required if the capabilities bit 0 is set to 1 */ + if (gcp_return_value & 1) + return method_evaluate_method(fw, METHOD_MANDATORY, + "_TIV", arg, 1, fwts_method_test_integer_return, NULL); + else + return method_evaluate_method(fw, METHOD_OPTIONAL, + "_TIV", arg, 1, fwts_method_test_integer_return, NULL); + } /*