diff mbox series

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

Message ID 20210113193442.250993-1-alex.hung@canonical.com
State Superseded
Headers show
Series [V2] acpi: method: add a function to check type of sub-package elements | expand

Commit Message

Alex Hung Jan. 13, 2021, 7:34 p.m. UTC
The function name is fwts_method_check_element_type

Signed-off-by: Alex Hung <alex.hung@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(-)

Comments

Colin Ian King Jan. 13, 2021, 7:38 p.m. UTC | #1
On 13/01/2021 19:34, Alex Hung wrote:
> The function name is fwts_method_check_element_type
> 
> Signed-off-by: Alex Hung <alex.hung@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';
> +	}

obj_name probably needs to be set to something in the case where it is
not being updated because the caller just passes an uninitialized
obj_name that's on the stack and that could contain any garbage.

Colin

> +}
> +
> +/* 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
>
diff mbox series

Patch

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