[PATCH 1/2] acpi: aspt: update ASPT tests for official revision 1 specification

Ivan Hu ivan.hu at canonical.com
Thu Jun 5 07:43:49 UTC 2025


Buglink: https://bugs.launchpad.net/fwts/+bug/2112514

The current FWTS ASPT tests were implemented before the ASPT specification
was officially released. This update revises the tests to align with the
finalized ASPT specification revision 1.

https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58028_1_00-PUB.pdf

Signed-off-by: Ivan Hu <ivan.hu at canonical.com>
---
 src/acpi/aspt/aspt.c        | 97 ++++++++++++++++++++++++++-----------
 src/lib/include/fwts_acpi.h | 37 ++++++++++++--
 2 files changed, 100 insertions(+), 34 deletions(-)

diff --git a/src/acpi/aspt/aspt.c b/src/acpi/aspt/aspt.c
index a98fb66f..c39d7cdb 100644
--- a/src/acpi/aspt/aspt.c
+++ b/src/acpi/aspt/aspt.c
@@ -36,40 +36,79 @@ acpi_table_init(ASPT, &table)
 static int aspt_test1(fwts_framework *fw)
 {
 	bool passed = true;
+	uint32_t offset;
 	fwts_acpi_table_aspt *aspt = (fwts_acpi_table_aspt *)table->data;
 
-	if (!fwts_acpi_table_length(fw, "ASPT", table->length, sizeof(fwts_acpi_table_aspt))) {
-		passed = false;
-		goto done;
-	}
+	fwts_log_info_verbatim(fw, "AMD Secure Processor Table:");
+	fwts_log_info_simp_int(fw, "  ASP Register Structure Count:    ", aspt->asp_reg_count);
 
-	fwts_log_info_verbatim(fw, "ASPT Table:");
-	fwts_log_info_simp_int(fw, "  SPTT Start Address: ", aspt->sptt_addr_start);
-	fwts_log_info_simp_int(fw, "  SPTT End Address:   ", aspt->sptt_addr_end);
-	fwts_log_info_simp_int(fw, "  AMRT Start Address: ", aspt->amrt_addr_start);
-	fwts_log_info_simp_int(fw, "  AMRT End Address:   ", aspt->amrt_addr_end);
-	fwts_log_nl(fw);
+	offset = sizeof(aspt->header) + sizeof(aspt->asp_reg_count);
 
-	/*
-	 * Without a specification to work with there is very
-	 * little we can do to validate this apart from the
-	 * simplest sanity check
-	 */
-	if (aspt->sptt_addr_end < aspt->sptt_addr_start) {
-		fwts_failed(fw, LOG_LEVEL_HIGH,
-			"ASPTSpttEndError",
-			"ASPT SPTT end address is less than the SPTT start "
-			"address.");
-		passed = false;
-	}
-	if (aspt->amrt_addr_end < aspt->amrt_addr_start) {
-		fwts_failed(fw, LOG_LEVEL_HIGH,
-			"ASPTAmrtEndError",
-			"ASPT AMRT end address is less than the AMRT start "
-			"address.");
-		passed = false;
+	for (uint32_t i = 0; i <  aspt->asp_reg_count; i++) {
+		if ((offset + sizeof(fwts_aspt_sub_header)) > table->length) {
+			fwts_failed(fw, LOG_LEVEL_HIGH,
+			"ASPTOutOfRangeOffset",
+			"ASPT offset is out of range.");
+			return FWTS_OK;
+		}
+		uint16_t type = ((fwts_aspt_sub_header *)((uint8_t *)table->data + offset))->type;
+		switch (type) {
+			case 0:
+				fwts_acpi_table_asp_global *entry_global;
+				entry_global = (fwts_acpi_table_asp_global *)((uint8_t *)table->data + offset);
+				fwts_log_info_verbatim(fw, "  ASP Global Registers:");
+				fwts_log_info_simp_int(fw, "    Type:                              ", entry_global->header.type);
+				fwts_log_info_simp_int(fw, "    Length:                            ", entry_global->header.length);
+				fwts_log_info_simp_int(fw, "    Reserved:                          ", entry_global->reserved);
+				fwts_acpi_reserved_zero("ASPT", "Reserved", entry_global->reserved, &passed);
+				fwts_log_info_simp_int(fw, "    Feature Register Address:          ", entry_global->feature_reg_addr);
+				fwts_log_info_simp_int(fw, "    Interrupt Enable Register Address: ", entry_global->interrupt_enable_reg_addr);
+				fwts_log_info_simp_int(fw, "    Interrupt Status Register Address: ", entry_global->interrupt_stable_reg_addr);
+				offset += entry_global->header.length;
+				break;
+			case 1:
+				fwts_acpi_table_sev_mailbox *entry_sev;
+				entry_sev = (fwts_acpi_table_sev_mailbox *)((uint8_t *)table->data + offset);
+				fwts_log_info_verbatim(fw, "  SEV Mailbox Registers:");
+				fwts_log_info_simp_int(fw, "    Type:                              ", entry_sev->header.type);
+				fwts_log_info_simp_int(fw, "    Length:                            ", entry_sev->header.length);
+				fwts_log_info_simp_int(fw, "    Mailbox Interrupt ID:              ", entry_sev->mailbox_interrupt_id);
+				fwts_acpi_reserved_bits("ASPT", "Mailbox Interrupt ID",  entry_sev->mailbox_interrupt_id, 6, 7, &passed);
+				fwts_log_info_verbatim(fw, "    Reserved:");
+				fwts_hexdump_data_prefix_all(fw, entry_sev->reserved, "      ", sizeof(entry_sev->reserved));
+				fwts_acpi_reserved_zero_array(fw, "ASPT", "Reserved", entry_sev->reserved, sizeof(entry_sev->reserved), &passed);
+				fwts_log_info_simp_int(fw, "    CmdResp Register Address:          ", entry_sev->cmdresp_reg_addr);
+				fwts_log_info_simp_int(fw, "    CmdBufAddr_Lo Register Address:    ", entry_sev->cmdbufaddr_lo_reg_addr);
+				fwts_log_info_simp_int(fw, "    CmdBufAddr_Hi Register Address:    ", entry_sev->cmdbufaddr_hi_reg_addr);
+				offset += entry_sev->header.length;
+				break;
+			case 2:
+				fwts_acpi_table_acpi_mailbox *entry_acpi;
+				entry_acpi = (fwts_acpi_table_acpi_mailbox *)((uint8_t *)table->data + offset);
+				fwts_log_info_verbatim(fw, "  ACPI Mailbox Registers:");
+				fwts_log_info_simp_int(fw, "    Type:                              ", entry_acpi->header.type);
+				fwts_log_info_simp_int(fw, "    Length:                            ", entry_acpi->header.length);
+				fwts_log_info_simp_int(fw, "    Reserved:                          ", entry_acpi->reserved);
+				fwts_acpi_reserved_zero("ASPT", "Reserved", entry_acpi->reserved, &passed);
+				fwts_log_info_simp_int(fw, "    CmdResp Register Address:          ", entry_acpi->cmdresp_reg_addr);
+				fwts_log_info_verbatim(fw, "    Reserved:");
+				fwts_hexdump_data_prefix_all(fw, entry_acpi->reserved1, "      ", sizeof(entry_acpi->reserved1));
+				fwts_acpi_reserved_zero_array(fw, "ASPT", "Reserved", entry_acpi->reserved1, sizeof(entry_acpi->reserved1), &passed);
+				offset += entry_acpi->header.length;
+				break;
+			default:
+				passed = false;
+				fwts_failed(fw, LOG_LEVEL_HIGH,
+					"ASPTBadType",
+					"ASPT register structures must have type with 0, 1 "
+					"and 2, got %" PRIu16 " instead",
+					((fwts_aspt_sub_header *)((uint8_t *)table->data + offset))->type);
+				return FWTS_OK;
+				break;				
+			fwts_log_nl(fw);
+		}
 	}
-done:
+
 	if (passed)
 		fwts_passed(fw, "No issues found in ASPT table.");
 
diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h
index cfb42bda..43d1d7cd 100644
--- a/src/lib/include/fwts_acpi.h
+++ b/src/lib/include/fwts_acpi.h
@@ -2273,14 +2273,41 @@ typedef struct {
 
 /*
  *  ACPI ASPT
- *	determined by reverse engineering
+ *	https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58028_1_00-PUB.pdf
  */
+typedef struct {
+	uint16_t	type;
+	uint16_t	length;
+} __attribute__ ((packed)) fwts_aspt_sub_header;
+
+typedef struct {
+	fwts_aspt_sub_header header;
+	uint32_t	reserved;
+	uint64_t	feature_reg_addr;
+	uint64_t	interrupt_enable_reg_addr;
+	uint64_t	interrupt_stable_reg_addr;
+} __attribute__ ((packed)) fwts_acpi_table_asp_global;
+
+typedef struct {
+	fwts_aspt_sub_header header;
+	uint8_t		mailbox_interrupt_id;
+	uint8_t		reserved[3];
+	uint64_t	cmdresp_reg_addr;
+	uint64_t	cmdbufaddr_lo_reg_addr;
+	uint64_t	cmdbufaddr_hi_reg_addr;
+} __attribute__ ((packed)) fwts_acpi_table_sev_mailbox;
+
+typedef struct {
+	fwts_aspt_sub_header header;
+	uint32_t	reserved;
+	uint64_t	cmdresp_reg_addr;
+	uint8_t		reserved1[16];
+} __attribute__ ((packed)) fwts_acpi_table_acpi_mailbox;
+
 typedef struct {
 	fwts_acpi_table_header  header;
-	uint32_t	sptt_addr_start;
-	uint32_t	sptt_addr_end;
-	uint32_t	amrt_addr_start;
-	uint32_t	amrt_addr_end;
+	uint32_t	asp_reg_count;
+	uint8_t		asp_reg_structure[0];
 } __attribute__ ((packed)) fwts_acpi_table_aspt;
 
 /*
-- 
2.34.1




More information about the fwts-devel mailing list