diff --git a/apps/uefi/Bsa.inf b/apps/uefi/Bsa.inf index 5e0d3f06..065ef1f7 100644 --- a/apps/uefi/Bsa.inf +++ b/apps/uefi/Bsa.inf @@ -78,6 +78,7 @@ ../../test_pool/gic/its003.c ../../test_pool/gic/its004.c ../../test_pool/gic/its005.c + ../../test_pool/gic/its006.c ../../test_pool/timer/t001.c ../../test_pool/timer/t002.c ../../test_pool/timer/t003.c diff --git a/apps/uefi/Mem.inf b/apps/uefi/Mem.inf index cc8f4fa4..aa8a5e07 100644 --- a/apps/uefi/Mem.inf +++ b/apps/uefi/Mem.inf @@ -78,6 +78,7 @@ ../../test_pool/gic/its003.c ../../test_pool/gic/its004.c ../../test_pool/gic/its005.c + ../../test_pool/gic/its006.c ../../test_pool/timer/t001.c ../../test_pool/timer/t002.c ../../test_pool/timer/t003.c diff --git a/apps/uefi/Sbsa.inf b/apps/uefi/Sbsa.inf index beb1bf7c..9274b607 100644 --- a/apps/uefi/Sbsa.inf +++ b/apps/uefi/Sbsa.inf @@ -81,6 +81,7 @@ ../../test_pool/gic/its003.c ../../test_pool/gic/its004.c ../../test_pool/gic/its005.c + ../../test_pool/gic/its006.c ../../test_pool/timer/t001.c ../../test_pool/timer/t002.c ../../test_pool/timer/t003.c diff --git a/apps/uefi/Vbsa.inf b/apps/uefi/Vbsa.inf index aeab2678..44a04432 100644 --- a/apps/uefi/Vbsa.inf +++ b/apps/uefi/Vbsa.inf @@ -80,6 +80,7 @@ ../../test_pool/gic/its003.c ../../test_pool/gic/its004.c ../../test_pool/gic/its005.c + ../../test_pool/gic/its006.c ../../test_pool/timer/t001.c ../../test_pool/timer/t002.c ../../test_pool/timer/t003.c diff --git a/apps/uefi/pc_bsa.inf b/apps/uefi/pc_bsa.inf index a444a559..72180e1a 100644 --- a/apps/uefi/pc_bsa.inf +++ b/apps/uefi/pc_bsa.inf @@ -81,6 +81,7 @@ ../../test_pool/gic/its003.c ../../test_pool/gic/its004.c ../../test_pool/gic/its005.c + ../../test_pool/gic/its006.c ../../test_pool/timer/t001.c ../../test_pool/timer/t002.c ../../test_pool/timer/t003.c diff --git a/apps/uefi/xbsa_acpi.inf b/apps/uefi/xbsa_acpi.inf index 4ec27c86..0a76177e 100644 --- a/apps/uefi/xbsa_acpi.inf +++ b/apps/uefi/xbsa_acpi.inf @@ -80,6 +80,7 @@ ../../test_pool/gic/its003.c ../../test_pool/gic/its004.c ../../test_pool/gic/its005.c + ../../test_pool/gic/its006.c ../../test_pool/timer/t001.c ../../test_pool/timer/t002.c ../../test_pool/timer/t003.c diff --git a/docs/bsa/arm_bsa_testcase_checklist.md b/docs/bsa/arm_bsa_testcase_checklist.md index 8db46c43..d7e5cde1 100644 --- a/docs/bsa/arm_bsa_testcase_checklist.md +++ b/docs/bsa/arm_bsa_testcase_checklist.md @@ -1686,12 +1686,12 @@ The checklist provides information about: ITS_08 - Not Covered - - - - - + 1548 + ITS blocks in group observe same DeviceID + Yes + Yes + No + Exerciser VIP required ITS_DEV_1 @@ -1731,11 +1731,11 @@ The checklist provides information about: ITS_DEV_5 - Not Covered - - - - + 256 + MSI-capable devices have DeviceID + Yes + Yes + No @@ -2204,12 +2204,12 @@ The checklist provides information about: ITS_08 - Not Covered - - - - - + 1548 + ITS blocks in group observe same DeviceID + Yes + Yes + No + Exerciser VIP required ITS_DEV_1 @@ -2249,11 +2249,11 @@ The checklist provides information about: ITS_DEV_5 - Not Covered - - - - + 256 + MSI-capable devices have DeviceID + Yes + Yes + No @@ -2980,12 +2980,12 @@ The checklist provides information about: ITS_08 - Not Covered - - - - - + 1548 + ITS blocks in group observe same DeviceID + Yes + Yes + No + Exerciser VIP required ITS_DEV_1 @@ -3025,11 +3025,11 @@ The checklist provides information about: ITS_DEV_5 - Not Covered - - - - + 256 + MSI-capable devices have DeviceID + Yes + Yes + No @@ -3765,6 +3765,8 @@ The checklist provides information about: - Updated PCI_MM_02 coverage with test 906. - Added direct B_PER_07 UART Non-secure register access coverage (test 605). - Updated B_PER_08 to include ITS Rules. +- Updated ITS_08, ITS_DEV_5 + - **RI_ Added:** RI_PWR_1 - Updated B_WD_02. - Updated checklist to be consistent with I-VGLFZ. diff --git a/docs/sbsa/arm_sbsa_testcase_checklist.md b/docs/sbsa/arm_sbsa_testcase_checklist.md index 298168c0..d91c2784 100644 --- a/docs/sbsa/arm_sbsa_testcase_checklist.md +++ b/docs/sbsa/arm_sbsa_testcase_checklist.md @@ -871,12 +871,12 @@ The checklist provides information about: ITS_08 - Not Covered - - - - - + 1548 + ITS blocks in group observe same DeviceID + Yes + Yes + No + Exerciser VIP required ITS_DEV_1 @@ -916,11 +916,11 @@ The checklist provides information about: ITS_DEV_5 - Not Covered - - - - + 256 + MSI-capable devices have DeviceID + Yes + Yes + No @@ -1647,12 +1647,12 @@ The checklist provides information about: ITS_08 - Not Covered - - - - - + 1548 + ITS blocks in group observe same DeviceID + Yes + Yes + No + Exerciser VIP required ITS_DEV_1 @@ -1692,11 +1692,11 @@ The checklist provides information about: ITS_DEV_5 - Not Covered - - - - + 256 + MSI-capable devices have DeviceID + Yes + Yes + No @@ -3678,6 +3678,7 @@ The checklist provides information about: - Updated PCI_MM_02 coverage with test 907. - Updated S_L5SM_04, S_L6PE_08, S_L6SM_04 - Added rule S_L5PE_03 +- Updated ITS_08, ITS_DEV_5 ### v26.03_SBSA_8.0.1 - **FR Added:** LVQBC, KBRZG diff --git a/test_pool/exerciser/e035.c b/test_pool/exerciser/e035.c index 27bcb488..8bdd92a5 100644 --- a/test_pool/exerciser/e035.c +++ b/test_pool/exerciser/e035.c @@ -26,9 +26,15 @@ #define TEST_RULE "ITS_04" #define TEST_DESC "MSI-cap device can target any ITS blk " +#define TEST_NUM_2 (ACS_EXERCISER_TEST_NUM_BASE + 48) +#define TEST_RULE_2 "ITS_08" +#define TEST_DESC_2 "ITS blocks in group observe same DeviceID" + static uint32_t irq_pending; static uint32_t base_lpi_id = 0x204C; static uint32_t instance; +static uint32_t its_04_result = RESULT_SKIP(0); +static uint32_t its_04_result_valid; static void @@ -191,19 +197,29 @@ payload (void) uint32_t e035_entry(uint32_t num_pe) { + uint32_t index; uint32_t status = ACS_STATUS_FAIL; /* Run test on single PE */ num_pe = 1; + index = val_pe_get_index_mpid(val_pe_get_mpid()); + its_04_result_valid = 0; val_log_context((char8_t *)__FILE__, (char8_t *)__func__, __LINE__); status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); if (status != ACS_STATUS_SKIP) { - if (val_exerciser_test_init() != ACS_STATUS_PASS) - return val_exerciser_get_init_result(TEST_RULE); + if (val_exerciser_test_init() != ACS_STATUS_PASS) { + status = val_exerciser_get_init_result(TEST_RULE); + its_04_result = status; + its_04_result_valid = 1; + return status; + } val_run_test_payload(TEST_NUM, num_pe, payload, 0); } + its_04_result = val_get_status(index); + its_04_result_valid = 1; + /* get the result from all PE and check for failure */ status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); @@ -211,3 +227,44 @@ e035_entry(uint32_t num_pe) return status; } + +/* Entry for ITS_08 rule. + 1. ITS_04 verifies that an MSI-capable device can target every ITS block in its ITS group. + 2. The test programs each ITS block with the same DeviceID for the given device and then + triggers an MSI. + 3. If any ITS block in the group does not observe that same DeviceID, the MSI mapping or + delivery through that ITS block is expected to fail. + 4. Therefore, the ITS_04 runtime result also provides coverage for ITS_08. +*/ +uint32_t +e048_entry(uint32_t num_pe) +{ + uint32_t index; + uint32_t status = ACS_STATUS_FAIL; + + /* Run test on single PE */ + num_pe = 1; + index = val_pe_get_index_mpid(val_pe_get_mpid()); + + val_log_context((char8_t *)__FILE__, (char8_t *)__func__, __LINE__); + status = val_initialize_test(TEST_NUM_2, TEST_DESC_2, num_pe); + if (status != ACS_STATUS_SKIP) { + /* ITS_08 uses the test result already collected by e035/ITS_04. + If a valid result is not available, then run the payload for ITS_08 */ + if (its_04_result_valid) + val_set_status(index, its_04_result); + else { + if (val_exerciser_test_init() != ACS_STATUS_PASS) + val_set_status(index, val_exerciser_get_init_result(TEST_RULE_2)); + else + val_run_test_payload(TEST_NUM_2, num_pe, payload, 0); + } + } + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM_2, num_pe, TEST_RULE_2); + + val_report_status(0, ACS_END(TEST_NUM_2), NULL); + + return status; +} diff --git a/test_pool/gic/its006.c b/test_pool/gic/its006.c new file mode 100644 index 00000000..607ec617 --- /dev/null +++ b/test_pool/gic/its006.c @@ -0,0 +1,112 @@ +/** @file + * Copyright (c) 2026, Arm Limited or its affiliates. All rights reserved. + * SPDX-License-Identifier : Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +#include "acs_val.h" +#include "acs_iovirt.h" +#include "acs_pcie.h" + +#define TEST_NUM (ACS_GIC_ITS_TEST_NUM_BASE + 6) +#define TEST_RULE "ITS_DEV_5" +#define TEST_DESC "MSI-capable devices have DeviceID " + +static +void +payload(void) +{ + uint32_t bdf; + uint32_t status; + uint32_t pe_index; + uint32_t tbl_index; + uint32_t device_id; + uint32_t stream_id; + uint32_t its_id; + uint32_t grp_id; + uint32_t cap_base; + uint32_t test_skip = 1; + uint32_t test_fails = 0; + pcie_device_bdf_table *bdf_tbl_ptr; + + pe_index = val_pe_get_index_mpid(val_pe_get_mpid()); + bdf_tbl_ptr = val_pcie_bdf_table_ptr(); + + if ((!bdf_tbl_ptr) || (!bdf_tbl_ptr->num_entries)) { + val_print(DEBUG, "\n No entries in BDF table"); + val_set_status(pe_index, RESULT_SKIP(1)); + return; + } + + /* Check all enumerated PCIe functions that can originate MSI/MSI-X. */ + for (tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries; tbl_index++) + { + bdf = bdf_tbl_ptr->device[tbl_index].bdf; + + if ((val_pcie_find_capability(bdf, PCIE_CAP, CID_MSI, &cap_base) == + PCIE_CAP_NOT_FOUND) && + (val_pcie_find_capability(bdf, PCIE_CAP, CID_MSIX, &cap_base) == + PCIE_CAP_NOT_FOUND)) + continue; + + test_skip = 0; + val_print(DEBUG, "\n Checking DeviceID association for BDF : 0x%x", bdf); + + /* Every device that is expected to originate MSIs is associated with a DeviceID */ + status = val_iovirt_get_device_info(PCIE_CREATE_BDF_PACKED(bdf), + PCIE_EXTRACT_BDF_SEG(bdf), + &device_id, &stream_id, &its_id); + if (status) { + val_print(ERROR, "\n DeviceID mapping not found for BDF : 0x%x", bdf); + test_fails++; + continue; + } + + /* We get ITS ID associated with the device. Now check if ITS ID belongs to valid ITS grp */ + status = val_iovirt_get_its_info(ITS_GET_GRP_INDEX_FOR_ID, 0, its_id, &grp_id); + if (status) { + /* Not a failure acc to this rule but an IORT violation */ + val_print(ERROR, "\n ITS group not found for BDF : 0x%x", bdf); + val_print(ERROR, " ITS ID : 0x%x", its_id); + } + } + + /* Partially covered, because this test only checks PCIe devices that advertise MSI/MSI-X support. + The rule, however, applies to all MSI-originating devices, not just PCIe devices. */ + if (test_skip) + val_set_status(pe_index, RESULT_SKIP(2)); + else if (test_fails) + val_set_status(pe_index, RESULT_FAIL(test_fails)); + else + val_set_status(pe_index, RESULT_PARTIAL_COVERED); + +} + +uint32_t +its006_entry(uint32_t num_pe) +{ + uint32_t status = ACS_STATUS_FAIL; + + num_pe = 1; //This ITS test is run on single processor + + val_log_context((char8_t *)__FILE__, (char8_t *)__func__, __LINE__); + status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe); + if (status != ACS_STATUS_SKIP) + val_run_test_payload(TEST_NUM, num_pe, payload, 0); + + /* get the result from all PE and check for failure */ + status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE); + + val_report_status(0, ACS_END(TEST_NUM), NULL); + + return status; +} diff --git a/tools/cmake/infra/bsa_test.txt b/tools/cmake/infra/bsa_test.txt index 31138c04..ec21f421 100644 --- a/tools/cmake/infra/bsa_test.txt +++ b/tools/cmake/infra/bsa_test.txt @@ -44,6 +44,7 @@ its002.c its003.c its004.c its005.c +its006.c t001.c t002.c t003.c diff --git a/val/include/acs_exerciser.h b/val/include/acs_exerciser.h index 556c17cd..8669666c 100644 --- a/val/include/acs_exerciser.h +++ b/val/include/acs_exerciser.h @@ -173,5 +173,6 @@ uint32_t e044_entry(uint32_t num_pe); uint32_t e045_entry(uint32_t num_pe); uint32_t e046_entry(uint32_t num_pe); uint32_t e047_entry(uint32_t num_pe); +uint32_t e048_entry(uint32_t num_pe); #endif diff --git a/val/include/acs_gic.h b/val/include/acs_gic.h index 65337aa9..73da4af2 100644 --- a/val/include/acs_gic.h +++ b/val/include/acs_gic.h @@ -1,5 +1,5 @@ /** @file - * Copyright (c) 2016-2018, 2021, 2023-2025, Arm Limited or its affiliates. All rights reserved. + * Copyright (c) 2016-2018, 2021, 2023-2026, Arm Limited or its affiliates. All rights reserved. * SPDX-License-Identifier : Apache-2.0 * Licensed under the Apache License, Version 2.0 (the "License"); @@ -103,6 +103,7 @@ uint32_t its002_entry(uint32_t num_pe); uint32_t its003_entry(uint32_t num_pe); uint32_t its004_entry(uint32_t num_pe); uint32_t its005_entry(uint32_t num_pe); +uint32_t its006_entry(uint32_t num_pe); uint32_t g012_entry(uint32_t num_pe); uint32_t g013_entry(uint32_t num_pe); diff --git a/val/include/rule_based_execution_enum.h b/val/include/rule_based_execution_enum.h index f6c41c96..f6814218 100644 --- a/val/include/rule_based_execution_enum.h +++ b/val/include/rule_based_execution_enum.h @@ -669,6 +669,7 @@ typedef enum { ITS003_ENTRY, ITS004_ENTRY, ITS005_ENTRY, + ITS006_ENTRY, G006_ENTRY, G007_ENTRY, G009_ENTRY, @@ -961,6 +962,7 @@ typedef enum { E045_ENTRY, E046_ENTRY, E047_ENTRY, + E048_ENTRY, P094_ENTRY, P096_ENTRY, P097_ENTRY, diff --git a/val/src/bsa_execute_test.c b/val/src/bsa_execute_test.c index a5b61a8d..ffad06f9 100644 --- a/val/src/bsa_execute_test.c +++ b/val/src/bsa_execute_test.c @@ -297,6 +297,7 @@ val_bsa_gic_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) status |= its003_entry(num_pe); status |= its004_entry(num_pe); status |= its005_entry(num_pe); + status |= its006_entry(num_pe); } view_print_info(MODULE_END); } @@ -901,6 +902,7 @@ val_bsa_exerciser_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) status |= e012_entry(num_pe); status |= e013_entry(num_pe); status |= e035_entry(num_pe); + status |= e048_entry(num_pe); } status |= e014_entry(num_pe); diff --git a/val/src/rule_metadata.c b/val/src/rule_metadata.c index 211373d5..9c60fcb0 100644 --- a/val/src/rule_metadata.c +++ b/val/src/rule_metadata.c @@ -642,6 +642,14 @@ rule_test_map_t rule_test_map[RULE_ID_SENTINEL] = { .flag = BASE_RULE, .test_num = ACS_GIC_ITS_TEST_NUM_BASE + 3, }, + [ITS_DEV_5] = { + .test_entry_id = ITS006_ENTRY, + .module_id = GIC, + .rule_desc = "MSI-capable devices have DeviceID", + .platform_bitmask = PLATFORM_BAREMETAL | PLATFORM_UEFI, + .flag = BASE_RULE, + .test_num = ACS_GIC_ITS_TEST_NUM_BASE + 6, + }, [ITS_DEV_7] = { .test_entry_id = ITS004_ENTRY, .module_id = GIC, @@ -1750,6 +1758,14 @@ rule_test_map_t rule_test_map[RULE_ID_SENTINEL] = { .flag = BASE_RULE, .test_num = ACS_EXERCISER_TEST_NUM_BASE + 12, }, + [ITS_08] = { + .test_entry_id = E048_ENTRY, + .module_id = PCIE, + .rule_desc = "ITS blocks in group observe same DeviceID", + .platform_bitmask = PLATFORM_BAREMETAL | PLATFORM_UEFI, + .flag = BASE_RULE, + .test_num = ACS_EXERCISER_TEST_NUM_BASE + 48, + }, [ITS_DEV_4] = { .test_entry_id = E013_ENTRY, .module_id = PCIE, @@ -3257,18 +3273,12 @@ rule_test_map_t rule_test_map[RULE_ID_SENTINEL] = { [ITS_07] = { .module_id = PCIE, }, - [ITS_08] = { - .module_id = PCIE, - }, [ITS_DEV_1] = { .module_id = PCIE, }, [ITS_DEV_3] = { .module_id = PCIE, }, - [ITS_DEV_5] = { - .module_id = PCIE, - }, [ITS_DEV_9] = { .module_id = PCIE, }, @@ -3541,6 +3551,7 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [E045_ENTRY] = e045_entry, // used for CXL_06. [E046_ENTRY] = e046_entry, [E047_ENTRY] = e047_entry, + [E048_ENTRY] = e048_entry, [ETE001_ENTRY] = ete001_entry, [ETE002_ENTRY] = ete002_entry, [ETE003_ENTRY] = ete003_entry, @@ -3640,6 +3651,7 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [ITS003_ENTRY] = its003_entry, [ITS004_ENTRY] = its004_entry, [ITS005_ENTRY] = its005_entry, + [ITS006_ENTRY] = its006_entry, [M001_ENTRY] = m001_entry, [M002_ENTRY] = m002_entry, [M003_ENTRY] = m003_entry, @@ -4302,6 +4314,7 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [G002_ENTRY] = g002_entry, [ITS002_ENTRY] = its002_entry, [ITS005_ENTRY] = its005_entry, + [ITS006_ENTRY] = its006_entry, [ITS001_ENTRY] = its001_entry, [G005_ENTRY] = g005_entry, [G006_ENTRY] = g006_entry, // used in wrapper. @@ -4367,6 +4380,7 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [E006_ENTRY] = e006_entry, // used in wrapper. [E046_ENTRY] = e046_entry, [E047_ENTRY] = e047_entry, + [E048_ENTRY] = e048_entry, [E015_ENTRY] = e015_entry, // used in wrapper. [E001_ENTRY] = e001_entry, // used in wrapper. [U005_ENTRY] = u005_entry, // used in wrapper.