[PATCH][V2] acpi: method: add a function to check type of sub-package elements

Alex Hung alex.hung at canonical.com
Wed Jan 13 19:34:42 UTC 2021


The function name is fwts_method_check_element_type

Signed-off-by: Alex Hung <alex.hung at canonical.com>
---
 src/acpi/method/method.c                | 63 +++----------------
 src/lib/include/fwts_acpi_object_eval.h |  1 +
 src/lib/src/fwts_acpi_object_eval.c     | 80 +++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 55 deletions(-)

diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c
index 07916c7f..cf994343 100644
--- a/src/acpi/method/method.c
+++ b/src/acpi/method/method.c
@@ -698,14 +698,8 @@ static void method_test_DLM_return(
 			continue;
 		}
 
-		if (pkg->Package.Elements[0].Type != ACPI_TYPE_LOCAL_REFERENCE) {
-			fwts_failed(fw, LOG_LEVEL_MEDIUM,
-				"Method_DLMBadSubPackageReturnType",
-				"%s sub-package %" PRIu32
-				" element 0 is not a reference.",
-				name, i);
+		if (fwts_method_check_element_type(fw, name, pkg, i, 0, ACPI_TYPE_LOCAL_REFERENCE))
 			failed = true;
-		}
 
 		if (pkg->Package.Elements[1].Type != ACPI_TYPE_LOCAL_REFERENCE &&
 		    pkg->Package.Elements[1].Type != ACPI_TYPE_BUFFER) {
@@ -2371,15 +2365,8 @@ static void method_test_PSD_return(
 
 		/* Elements in Sub-packages are integers */
 		for (j = 0; j < 5; j++) {
-			if (pkg->Package.Elements[j].Type != ACPI_TYPE_INTEGER) {
-				fwts_failed(fw, LOG_LEVEL_MEDIUM,
-					"Method_PSDBadSubPackageReturnType",
-					"%s sub-package %" PRIu32
-					" element %" PRIu32 " is not "
-					"an integer.",
-					name, i, j);
+			if (fwts_method_check_element_type(fw, name, pkg, i, j, ACPI_TYPE_INTEGER))
 				elements_ok = false;
-			}
 		}
 
 		if (!elements_ok) {
@@ -4244,15 +4231,8 @@ static void method_test_FPS_return(
 
 		for (j = 0; j < 5; j++) {
 			/* TODO - field 0 and 1 can be related to other control method */
-			if (pkg->Package.Elements[j].Type != ACPI_TYPE_INTEGER) {
-				fwts_failed(fw, LOG_LEVEL_MEDIUM,
-					"Method_FPSBadSubPackageReturnType",
-					"%s sub-package %" PRIu32
-					" element %" PRIu32 " is not "
-					"an integer.",
-					name, i, j);
+			if (fwts_method_check_element_type(fw, name, pkg, i, j, ACPI_TYPE_INTEGER))
 				elements_ok = false;
-			}
 		}
 
 		if (!elements_ok) {
@@ -4448,27 +4428,14 @@ static void method_test_ART_return(
 
 		/* First two elements are references, and rests are integers */
 		for (j = 0; j < 2; j++) {
-			if (pkg->Package.Elements[j].Type != ACPI_TYPE_LOCAL_REFERENCE) {
-				fwts_failed(fw, LOG_LEVEL_MEDIUM,
-					"Method_ARTBadSubPackageReturnType",
-					"%s sub-package %" PRIu32
-					" element %" PRIu32 " is not "
-					"a reference.",
-					name, i, j);
+			if (fwts_method_check_element_type(fw, name, pkg, i, j, ACPI_TYPE_LOCAL_REFERENCE))
 				elements_ok = false;
-			}
 		}
 
 		for (j = 2; j < 13; j++) {
-			if (pkg->Package.Elements[j].Type != ACPI_TYPE_INTEGER) {
-				fwts_failed(fw, LOG_LEVEL_MEDIUM,
-					"Method_ARTBadSubPackageReturnType",
-					"%s sub-package %" PRIu32
-					" element %" PRIu32 " is not "
-					"an integer.",
-					name, i, j);
+			if (fwts_method_check_element_type(fw, name, pkg, i, j, ACPI_TYPE_INTEGER))
 				elements_ok = false;
-			}
+
 		}
 
 		if (!elements_ok) {
@@ -4525,27 +4492,13 @@ static void method_test_TRT_return(
 
 		/* First two elements are references, and rests are integers */
 		for (j = 0; j < 2; j++) {
-			if (pkg->Package.Elements[j].Type != ACPI_TYPE_LOCAL_REFERENCE) {
-				fwts_failed(fw, LOG_LEVEL_MEDIUM,
-					"Method_TRTBadSubPackageReturnType",
-					"%s sub-package %" PRIu32
-					" element %" PRIu32 " is not "
-					"a reference.",
-					name, i, j);
+			if (fwts_method_check_element_type(fw, name, pkg, i, j, ACPI_TYPE_LOCAL_REFERENCE))
 				elements_ok = false;
-			}
 		}
 
 		for (j = 2; j < 8; j++) {
-			if (pkg->Package.Elements[j].Type != ACPI_TYPE_INTEGER) {
-				fwts_failed(fw, LOG_LEVEL_MEDIUM,
-					"Method_TRTBadSubPackageReturnType",
-					"%s sub-package %" PRIu32
-					" element %" PRIu32 " is not "
-					"an integer.",
-					name, i, j);
+			if (fwts_method_check_element_type(fw, name, pkg, i, j, ACPI_TYPE_INTEGER))
 				elements_ok = false;
-			}
 		}
 
 		if (!elements_ok) {
diff --git a/src/lib/include/fwts_acpi_object_eval.h b/src/lib/include/fwts_acpi_object_eval.h
index 3d611916..472f91a1 100644
--- a/src/lib/include/fwts_acpi_object_eval.h
+++ b/src/lib/include/fwts_acpi_object_eval.h
@@ -110,6 +110,7 @@ typedef struct {
 	fwts_method_check_type__(fw, name, buf, type, #type)
 
 int fwts_method_check_type__(fwts_framework *fw, char *name, ACPI_BUFFER *buf, ACPI_OBJECT_TYPE type, char *type_name);
+int fwts_method_check_element_type(fwts_framework *fw, char *name, ACPI_OBJECT *obj, uint32_t subpkg, uint32_t element, ACPI_OBJECT_TYPE type);
 const char *fwts_method_type_name(const ACPI_OBJECT_TYPE type);
 void fwts_method_passed_sane(fwts_framework *fw, const char *name, const char *type);
 void fwts_method_passed_sane_uint64(fwts_framework *fw, const char *name, const uint64_t value);
diff --git a/src/lib/src/fwts_acpi_object_eval.c b/src/lib/src/fwts_acpi_object_eval.c
index e822a934..0e4b853d 100644
--- a/src/lib/src/fwts_acpi_object_eval.c
+++ b/src/lib/src/fwts_acpi_object_eval.c
@@ -495,6 +495,86 @@ int fwts_method_check_type__(
 	return FWTS_OK;
 }
 
+/*
+ *  get_object_name()
+ *	get objname from full path nanme
+ *		ex. _BCL from _SB.PCI0.GFX0.LCD0._BCL
+ */
+static void get_object_name(char *name, char* obj_name) {
+	/* obj_name must have length of 5 */
+	if (name != NULL && strlen(name) > 4) {
+		memcpy(obj_name, name + strlen(name) - 4, 4);
+		obj_name[4] = '\0';
+	}
+}
+
+/* See references in actypes.h */
+static const char *acpi_object_names[] = {
+	"Any",
+	"Integer",
+	"String",
+	"Buffer",
+	"Package",
+	"Field Unit",
+	"Device",
+	"Event",
+	"Method",
+	"Mutex",
+	"Region",
+	"Power",
+	"Processor",
+	"Thermal",
+	"Buffer Field",
+	"DDB Handle",
+	"Debug Object",
+	"Region Field",
+	"Bank Field",
+	"Index Field",
+	"Reference",
+	"Alias",
+	"Method Alias",
+	"Notify",
+	"Address Handler",
+	"Resource",
+	"Resource Field",
+	"Scope"
+};
+
+/*
+ *  fwts_method_check_element_type()
+ *	check a element type of a sub-package
+ */
+int fwts_method_check_element_type(
+	fwts_framework *fw,
+	char *name,
+	ACPI_OBJECT *obj,
+	uint32_t subpkg,
+	uint32_t element,
+	ACPI_OBJECT_TYPE type)
+{
+	if (obj->Package.Elements[element].Type != type) {
+		char obj_name[5];
+		char tmp[128];
+
+		get_object_name(name, obj_name);
+		snprintf(tmp, sizeof(tmp), "Method%sBadSubPackageReturnType", obj_name);
+
+		if (type > FWTS_ARRAY_SIZE(acpi_object_names) - 1) {
+			fwts_warning(fw, "Unknown ACPI object type detected");
+			return FWTS_ERROR;
+		}
+
+		fwts_failed(fw, LOG_LEVEL_HIGH, tmp,
+			"%s sub-package %" PRIu32 " element %" PRIu32 " is a %s, "
+			"expected a %s", name, subpkg, element,
+			acpi_object_names[obj->Package.Elements[element].Type],
+			acpi_object_names[type]);
+
+		return FWTS_ERROR;
+	}
+	return FWTS_OK;
+}
+
 /*
  *  Common types that can be returned. This is not a complete
  *  list but it does cover the types we expect to return from
-- 
2.25.1




More information about the fwts-devel mailing list