From patchwork Fri Jun 16 10:04:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ivanhu X-Patchwork-Id: 1795810 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=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=fwts-devel-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=EEkh9Np+; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (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 4QjFBQ72Nwz20Wy for ; Fri, 16 Jun 2023 20:04:29 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1qA6JZ-00085N-G4; Fri, 16 Jun 2023 10:04:21 +0000 Received: from smtp-relay-canonical-1.internal ([10.131.114.174] helo=smtp-relay-canonical-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1qA6JX-00085G-EE for fwts-devel@lists.ubuntu.com; Fri, 16 Jun 2023 10:04:19 +0000 Received: from canonical.com (unknown [106.104.136.95]) (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 3EA623F180 for ; Fri, 16 Jun 2023 10:04:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1686909858; bh=ne9psSNLVoIMDHwEuOyQq7dD/tT2e+oO7S0a4Z9oq9Q=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=EEkh9Np+eqRxKB7npjt8p5pGXLo1DFt+CA/owmMKuBIkvvh6RVb9lsUiMEcu+Wk+5 c2Da2scaH+ocBxTPsrWM9LjYhpdMkW3MGfGqzF9DxLMIbV/rJwewHJ1RmZcxhyE95G 9rsDiDJUe2I/vxGlHbUPHPKiQGwahEejBDzzQ3u7nxqOzunpWBKaPDLx4JDBb7/a7s ryd52JDE5TC+s/Yad0B7M1AVpHL+9AZEziGFuNULHGsguBbvZL7HRQVeEg+9wzaIj3 NjQ33VGpgCBQwsUkwHJDzxscOAXUM+I4yPelZqRv2uvDQQRnamJNATqBoINcjkrzuU QshIE7fHuXoIg== From: Ivan Hu To: fwts-devel@lists.ubuntu.com Subject: [PATCH] acpi: mpam: add test for ACPI MPAM table Date: Fri, 16 Jun 2023 18:04:06 +0800 Message-Id: <20230616100406.4272-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/2023358 New table on ACPI specification 6.4 The MPAM(Memory Resource Partitioning and Monitoring table) specification link: https://developer.arm.com/documentation/ddi0598/latest/ Signed-off-by: Ivan Hu --- src/Makefile.am | 1 + src/acpi/mpam/mpam.c | 183 ++++++++++++++++++++++++++++++++++++ src/lib/include/fwts_acpi.h | 55 +++++++++++ 3 files changed, 239 insertions(+) create mode 100644 src/acpi/mpam/mpam.c diff --git a/src/Makefile.am b/src/Makefile.am index c6dcd421..f3c2b2be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,6 +113,7 @@ fwts_SOURCES = main.c \ acpi/madt/madt.c \ acpi/mcfg/mcfg.c \ acpi/mchi/mchi.c \ + acpi/mpam/mpam.c \ acpi/mpst/mpst.c \ acpi/msct/msct.c \ acpi/msdm/msdm.c \ diff --git a/src/acpi/mpam/mpam.c b/src/acpi/mpam/mpam.c new file mode 100644 index 00000000..3c927602 --- /dev/null +++ b/src/acpi/mpam/mpam.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2023 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include "fwts.h" + +#if defined(FWTS_HAS_ACPI) + +#include +#include +#include +#include +#include + +static fwts_acpi_table_info *table; +acpi_table_init(MPAM, &table) + +static int mpam_test1(fwts_framework *fw) +{ + fwts_acpi_mpam_msc_node *node; + bool passed = true; + uint32_t offset; + + fwts_log_info_verbatim(fw, "MPAM Memory System Resource Partitioning And Monitoring Table:"); + + offset = sizeof(fwts_acpi_table_mpam); + node = (fwts_acpi_mpam_msc_node *)(table->data + offset); + while (offset < table->length) { + + if (fwts_acpi_structure_length_zero(fw, "MPAM", node->length, offset)) { + passed = false; + break; + } + + fwts_log_info_verbatim(fw, "MPAM MSC node:"); + fwts_log_info_simp_int(fw, " Length: ", node->length); + fwts_log_info_simp_int(fw, " Interface type: ", node->interface_type); + fwts_log_info_simp_int(fw, " Reserved: ", node->reserved); + fwts_log_info_simp_int(fw, " Identifier: ", node->identifier); + fwts_log_info_simp_int(fw, " Base address: ", node->base_address); + fwts_log_info_simp_int(fw, " MMIO size: ", node->mmio_size); + fwts_log_info_simp_int(fw, " Overflow interrupt: ", node->overflow_interrupt); + fwts_log_info_simp_int(fw, " Overflow interrupt flags: ", node->overflow_interrupt_flags); + fwts_log_info_simp_int(fw, " Reserved1: ", node->reserved1); + fwts_log_info_simp_int(fw, " Overflow interrupt affinity: ", node->overflow_interrupt_affinity); + fwts_log_info_simp_int(fw, " Error interrupt: ", node->error_interrupt); + fwts_log_info_simp_int(fw, " Error interrupt flags: ", node->error_interrupt_flags); + fwts_log_info_simp_int(fw, " Reserved2: ", node->reserved2); + fwts_log_info_simp_int(fw, " Error interrupt affinity: ", node->error_interrupt_affinity); + fwts_log_info_simp_int(fw, " MAX_NRDY_USEC: ", node->max_nrdy_usec); + fwts_log_info_simp_int(fw, " Hardware ID of linked device: ", node->hardware_id_linked_device); + fwts_log_info_simp_int(fw, " Instance ID of linked device: ", node->instance_id_linked_device); + fwts_log_info_simp_int(fw, " Number of resource nodes: ", node->num_resouce_nodes); + + if (node->interface_type != 0 && node->interface_type != 0x0a) { + passed = false; + fwts_failed(fw, LOG_LEVEL_HIGH, + "MPAMBadInterfaceType", + "MPAM MSC node interface type must have value with 0 or 0x0a, got " + "0x%2.2" PRIx8 " instead", node->interface_type); + } + + fwts_acpi_reserved_zero("MPAM", "Reserved", node->reserved, &passed); + fwts_acpi_reserved_bits("MPAM", "Overflow interrupt flags", node->overflow_interrupt_flags, 1, 2, &passed); + fwts_acpi_reserved_bits("MPAM", "Overflow interrupt flags", node->overflow_interrupt_flags, 5, 31, &passed); + fwts_acpi_reserved_zero("MPAM", "Reserved1", node->reserved1, &passed); + fwts_acpi_reserved_bits("MPAM", "Error interrupt flags", node->error_interrupt_flags, 1, 2, &passed); + fwts_acpi_reserved_bits("MPAM", "Error interrupt flags", node->error_interrupt_flags, 5, 31, &passed); + fwts_acpi_reserved_zero("MPAM", "Reserved2", node->reserved2, &passed); + + uint32_t msc_offset = sizeof(fwts_acpi_mpam_msc_node); + + for (uint32_t i = 0; i < node->num_resouce_nodes; i++) { + fwts_acpi_mpam_resource_node *res_node = (fwts_acpi_mpam_resource_node *)(table->data + offset + msc_offset); + fwts_log_info_verbatim(fw, " List of resource nodes: "); + fwts_log_info_simp_int(fw, " Identifier: ", res_node->identifier); + fwts_log_info_simp_int(fw, " RIS Index: ", res_node->ris_index); + fwts_log_info_simp_int(fw, " Reserved1: ", res_node->reserved1); + fwts_log_info_simp_int(fw, " Locator type: ", res_node->locator_type); + fwts_log_info_verbatim(fw, " Locator:"); + + switch(res_node->locator_type) { + case FWTS_MPAM_PROCESSOR_CACHE: + fwts_log_info_verbatim(fw, " Processor cache locator:"); + fwts_hexdump_data_prefix_all(fw, res_node->locator, " ", sizeof(res_node->locator)); + fwts_acpi_reserved_zero_array(fw, "MPAM", "Locator", res_node->locator + 8, 4, &passed); + break; + case FWTS_MPAM_MEMORY: + fwts_log_info_verbatim(fw, " Memory locator:"); + fwts_hexdump_data_prefix_all(fw, res_node->locator, " ", sizeof(res_node->locator)); + fwts_acpi_reserved_zero_array(fw, "MPAM", "Locator", res_node->locator + 8, 4, &passed); + break; + case FWTS_MPAM_SMMU: + fwts_log_info_verbatim(fw, " SMMU locator:"); + fwts_hexdump_data_prefix_all(fw, res_node->locator, " ", sizeof(res_node->locator)); + fwts_acpi_reserved_zero_array(fw, "MPAM", "Locator", res_node->locator + 8, 4, &passed); + break; + case FWTS_MPAM_MEMORY_CACHE: + fwts_log_info_verbatim(fw, " Memory-side cache locator:"); + fwts_hexdump_data_prefix_all(fw, res_node->locator, " ", sizeof(res_node->locator)); + fwts_acpi_reserved_zero_array(fw, "MPAM", "Locator", res_node->locator, 7, &passed); + break; + case FWTS_MPAM_ACPI_DEVICE: + fwts_log_info_verbatim(fw, " ACPI device locator:"); + fwts_hexdump_data_prefix_all(fw, res_node->locator, " ", sizeof(res_node->locator)); + break; + case FWTS_MPAM_INTERCONNECT: + fwts_log_info_verbatim(fw, " Interconnect locator:"); + fwts_hexdump_data_prefix_all(fw, res_node->locator, " ", sizeof(res_node->locator)); + fwts_acpi_reserved_zero_array(fw, "MPAM", "Locator", res_node->locator + 8, 4, &passed); + break; + case FWTS_MPAM_UNKNOWN: + fwts_log_info_verbatim(fw, " Unknown locator:"); + fwts_hexdump_data_prefix_all(fw, res_node->locator, " ", sizeof(res_node->locator)); + break; + default: + passed = false; + fwts_failed(fw, LOG_LEVEL_HIGH, + "MPAMBadLocaterType", + "MPAM MPAM MSC locator type must not have the value 0x06..0xfe, got " + "0x%2.2" PRIx8 "instead", res_node->locator_type); + break; + } + + fwts_log_info_simp_int(fw, " Number of functional dependencies: ", res_node->num_functional_deps); + + fwts_acpi_reserved_zero("MPAM", "Reserved1", res_node->reserved1, &passed); + + msc_offset += sizeof(fwts_acpi_mpam_resource_node); + + for (uint32_t j = 0; j < res_node->num_functional_deps; j++) { + fwts_acpi_mpam_func_deps *fun_deps = (fwts_acpi_mpam_func_deps *)(table->data + offset + msc_offset); + fwts_log_info_verbatim(fw, " Functional dependency descriptor: "); + fwts_log_info_simp_int(fw, " Producer: ", fun_deps->producer); + fwts_log_info_simp_int(fw, " Reserved: ", fun_deps->reserved); + + fwts_acpi_reserved_zero("MPAM", "Reserved1", fun_deps->reserved, &passed); + + msc_offset += sizeof(fwts_acpi_mpam_func_deps); + } + } + + if (node->length > msc_offset) { + fwts_log_info_verbatim(fw, " Resource-specific data: "); + fwts_hexdump_data_prefix_all(fw, (uint8_t *)(table->data + offset + msc_offset), " ", node->length - msc_offset); + } + + offset += node->length; + + node = (fwts_acpi_mpam_msc_node *)(table->data + offset); + fwts_log_nl(fw); + } + + if (passed) + fwts_passed(fw, "No issues found in MPAM table."); + + return FWTS_OK; +} + +static fwts_framework_minor_test mpam_tests[] = { + { mpam_test1, "Validate MPAM table." }, + { NULL, NULL } +}; + +static fwts_framework_ops mpam_ops = { + .description = "MPAM Memory System Resource Partitioning And Monitoring Table test.", + .init = MPAM_init, + .minor_tests = mpam_tests +}; + +FWTS_REGISTER("mpam", &mpam_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_BATCH | FWTS_FLAG_ACPI) + +#endif diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h index 7d8d4682..297673a6 100644 --- a/src/lib/include/fwts_acpi.h +++ b/src/lib/include/fwts_acpi.h @@ -2522,4 +2522,59 @@ typedef struct { uint64_t mem_block_len; } __attribute__ ((packed)) fwts_acpi_table_ivmd; +/* + * ACPI MPAM(Memory System Resource Partitioning And Monitoring) + * https://developer.arm.com/documentation/ddi0598/latest/ + */ +typedef enum { + FWTS_MPAM_PROCESSOR_CACHE = 0, + FWTS_MPAM_MEMORY = 1, + FWTS_MPAM_SMMU = 2, + FWTS_MPAM_MEMORY_CACHE = 3, + FWTS_MPAM_ACPI_DEVICE = 4, + FWTS_MPAM_INTERCONNECT = 5, + FWTS_MPAM_UNKNOWN = 0xFF +} fwts_mpam_location_types; + +typedef struct +{ + uint32_t producer; + uint32_t reserved; +} __attribute__ ((packed)) fwts_acpi_mpam_func_deps; + +typedef struct { + uint32_t identifier; + uint8_t ris_index; + uint16_t reserved1; + uint8_t locator_type; + uint8_t locator[12]; + uint32_t num_functional_deps; +} __attribute__ ((packed)) fwts_acpi_mpam_resource_node; + +typedef struct +{ + uint16_t length; + uint8_t interface_type; + uint8_t reserved; + uint32_t identifier; + uint64_t base_address; + uint32_t mmio_size; + uint32_t overflow_interrupt; + uint32_t overflow_interrupt_flags; + uint32_t reserved1; + uint32_t overflow_interrupt_affinity; + uint32_t error_interrupt; + uint32_t error_interrupt_flags; + uint32_t reserved2; + uint32_t error_interrupt_affinity; + uint32_t max_nrdy_usec; + uint64_t hardware_id_linked_device; + uint32_t instance_id_linked_device; + uint32_t num_resouce_nodes; +} __attribute__ ((packed)) fwts_acpi_mpam_msc_node; + +typedef struct { + fwts_acpi_table_header header; +} __attribute__ ((packed)) fwts_acpi_table_mpam; + #endif