[PATCH] fwts/madt: Add processor UID checking to madt tests

Prarit Bhargava prarit at redhat.com
Fri Jul 22 14:34:00 UTC 2016


The current madt test does not do any processor UID comparisons.  They are
marked as TODOs in the file.

This patchset implements two ACPI searches (one for old-style Processor
Declaration operator, and another for the new Processor Device operator)
that populate a list of UID entries, which can be queried for each MADT
struct's UID.

Signed-off-by: Prarit Bhargava <prarit at redhat.com>
---
 src/acpi/madt/madt.c |  132 ++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 107 insertions(+), 25 deletions(-)

diff --git a/src/acpi/madt/madt.c b/src/acpi/madt/madt.c
index e260222a8b75..0d21fb2a2180 100644
--- a/src/acpi/madt/madt.c
+++ b/src/acpi/madt/madt.c
@@ -17,6 +17,8 @@
 
 #if defined(FWTS_HAS_ACPI)
 
+#include "fwts_acpi_object_eval.h"
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -203,6 +205,95 @@ static fwts_acpi_table_info *ftable;
 
 static fwts_list msi_frame_ids;
 static fwts_list its_ids;
+static fwts_list processor_uids;
+
+struct acpi_processor {
+	ACPI_OBJECT_TYPE type;
+	uint32_t proc_id;
+	ACPI_IO_ADDRESS pblk_address;
+	uint32_t pblk_length;
+};
+
+struct acpi_integer {
+	ACPI_OBJECT_TYPE type;
+	uint64_t value;
+};
+
+struct list_integer {
+	uint64_t value;
+};
+
+static ACPI_STATUS madt_processor_handler(ACPI_HANDLE ObjHandle, uint32_t level,
+					  void *context, void **returnvalue)
+{
+	ACPI_OBJECT_TYPE acpi_type;
+	ACPI_STATUS status;
+	struct acpi_processor processor;
+	struct acpi_integer integer;
+	struct acpi_buffer pbuf = {sizeof(struct acpi_processor), &processor};
+	struct acpi_buffer ibuf = {sizeof(struct acpi_integer), &integer};
+	struct list_integer *listint;
+
+	/* Prevent -Werror=unused-parameter from complaining */
+	FWTS_UNUSED(level);
+	FWTS_UNUSED(context);
+	FWTS_UNUSED(returnvalue);
+
+	listint = malloc(sizeof(struct list_integer));
+	if (!listint)
+		return (!AE_OK);
+
+	status = AcpiGetType(ObjHandle, &acpi_type);
+	if (ACPI_FAILURE(status))
+		return (!AE_OK);
+
+	switch(acpi_type) {
+		case ACPI_TYPE_PROCESSOR:
+			status = AcpiEvaluateObject(ObjHandle, NULL, NULL,
+						    &pbuf);
+			if (ACPI_FAILURE(status))
+				return status;
+			listint->value = processor.proc_id;
+			break;
+		case ACPI_TYPE_DEVICE:
+			status = AcpiEvaluateObject(ObjHandle, "_UID", NULL,
+						     &ibuf);
+			if (ACPI_FAILURE(status))
+				return status;
+			listint->value = integer.value;
+			break;
+		default:
+			return (!AE_OK);
+	}
+	fwts_list_append(&processor_uids, listint);
+
+	return (AE_OK);
+}
+
+static void madt_find_processor_uid(fwts_framework *fw, uint64_t uid,
+				    char *table_name)
+{
+	char table_label[64];
+	fwts_list_link *item;
+	struct list_integer *listint;
+
+	/* TODO: is UID = 0 an error? */
+
+	fwts_list_foreach(item, &processor_uids) {
+		listint = fwts_list_data(struct list_integer *, item);
+		if (uid == listint->value) {
+			fwts_passed(fw, "MADT %s has matching processor "
+				    "UID %lu.", table_name, uid);
+			return;
+		}
+	}
+
+	sprintf(table_label, "MADT%sUidMismatch", table_name);
+	fwts_failed(fw, LOG_LEVEL_MEDIUM,
+		    table_label, "%s has no matching processor UID %lu",
+		    table_name, uid);
+	return;
+}
 
 static int madt_init(fwts_framework *fw)
 {
@@ -270,6 +361,14 @@ static int madt_init(fwts_framework *fw)
 	 */
 	fwts_list_init(&msi_frame_ids);
 	fwts_list_init(&its_ids);
+	fwts_list_init(&processor_uids);
+
+	if (fwts_acpica_init(fw) != FWTS_OK)
+		return FWTS_ERROR;
+
+	AcpiWalkNamespace(0x0c, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+			  madt_processor_handler, NULL, NULL, NULL);
+	AcpiGetDevices("ACPI0007", madt_processor_handler, NULL, NULL);
 
 	return (spec_data) ? FWTS_OK : FWTS_ERROR;
 }
@@ -412,11 +511,7 @@ static int madt_local_apic(fwts_framework *fw,
 	fwts_acpi_madt_processor_local_apic *lapic =
 		(fwts_acpi_madt_processor_local_apic *)data;
 
-	/*
-	 *  TODO: verify UID field has a corresponding
-	 *  Processor device object with a matching
-	 *  _UID result
-	 */
+	madt_find_processor_uid(fw, lapic->acpi_processor_id, "LAPIC");
 
 	if (lapic->flags & 0xfffffffe)
 		fwts_failed(fw, LOG_LEVEL_MEDIUM,
@@ -527,11 +622,7 @@ static int madt_local_apic_nmi(fwts_framework *fw,
 	fwts_acpi_madt_local_apic_nmi *nmi =
 		(fwts_acpi_madt_local_apic_nmi *)data;
 
-	/*
-	 *  TODO: verify UID field has a corresponding
-	 *  Processor device object with a matching
-	 *  _UID result
-	 */
+	madt_find_processor_uid(fw, nmi->acpi_processor_id, "LAPICNMI");
 
 	if (nmi->flags & 0xfffffff0)
 		fwts_failed(fw, LOG_LEVEL_MEDIUM,
@@ -693,11 +784,7 @@ static int madt_local_sapic(fwts_framework *fw,
 			    "reserved and properly set to zero.",
 			    madt_sub_names[hdr->type]);
 
-	/*
-	 *  TODO: verify UID field has a corresponding
-	 *  Processor device object with a matching
-	 *  _UID result (or Processor object ID?)
-	 */
+	madt_find_processor_uid(fw, lsapic->acpi_processor_id, "LSAPIC");
 
 	for (tmp = 0, ii = 0; ii < (int)strlen(lsapic->uid_string); ii++)
 		if (isascii(lsapic->uid_string[ii]))
@@ -817,11 +904,7 @@ static int madt_local_x2apic(fwts_framework *fw,
 			    "reserved and properly set to zero.",
 			    madt_sub_names[hdr->type]);
 
-	/*
-	 *  TODO: verify UID field has a corresponding
-	 *  Processor device object with a matching
-	 *  _UID result
-	 */
+	madt_find_processor_uid(fw, lx2apic->processor_uid, "X2APIC");
 
 	return (hdr->length - sizeof(fwts_acpi_madt_sub_table_header));
 }
@@ -869,11 +952,7 @@ static int madt_gicc(fwts_framework *fw,
 			    "MADT %s reserved field properly set to zero.",
 			    madt_sub_names[hdr->type]);
 
-	/*
-	 *  TODO: verify UID field has a corresponding
-	 *  Processor device object with a matching
-	 *  _UID result
-	 */
+	madt_find_processor_uid(fw, gic->processor_uid, "GICC");
 
 	mask = 0xfffffffc;
 	start = 2;
@@ -1395,9 +1474,12 @@ static int madt_subtables(fwts_framework *fw)
 
 static int madt_deinit(fwts_framework *fw)
 {
+	fwts_acpica_deinit();
+
 	/* only minor clean up needed */
 	fwts_list_free_items(&msi_frame_ids, NULL);
 	fwts_list_free_items(&its_ids, NULL);
+	fwts_list_free_items(&processor_uids, NULL);
 
 	return (fw) ? FWTS_ERROR : FWTS_OK;
 }
-- 
1.7.9.3




More information about the fwts-devel mailing list