diff --git a/docs/bsa/arm_bsa_testcase_checklist.md b/docs/bsa/arm_bsa_testcase_checklist.md index f14b5dda..a587ad6d 100644 --- a/docs/bsa/arm_bsa_testcase_checklist.md +++ b/docs/bsa/arm_bsa_testcase_checklist.md @@ -360,11 +360,47 @@ The checklist provides information about: - L1 - B_GIC_02 - B_GIC_02 + L1 + B_GIC_02 + B_GIC_02 202 - Check GICv2 Valid Configuration + Check GIC Valid Configuration + Yes + Yes + No + + + + + 229 + Check GICv2m SPI allocated to MSI Ctrl + Yes + Yes + No + + + + + 226 + Check MSI SPI are Edge Triggered + Yes + Yes + No + + + + + 228 + Check GICv2m MSI to SPI Generation + Yes + Yes + No + + + + + 227 + Check GICv2m MSI Frame Register Yes Yes No @@ -456,44 +492,6 @@ The checklist provides information about: - - L1 - B_GIC_02 - Appendix I.5 - 229 - Check GICv2m SPI allocated to MSI Ctrl - Yes - Yes - No - - - - Appendix I.6 - 226 - Check MSI SPI are Edge Triggered - Yes - Yes - No - - - - Appendix I.6 - 228 - Check GICv2m MSI to SPI Generation - Yes - Yes - No - - - - Appendix I.9 - 227 - Check GICv2m MSI Frame Register - Yes - Yes - No - - L1 B_SMMU_01 diff --git a/test_pool/gic/g002.c b/test_pool/gic/g002.c index 75557a72..704a7cb0 100644 --- a/test_pool/gic/g002.c +++ b/test_pool/gic/g002.c @@ -23,37 +23,68 @@ #define TEST_NUM (ACS_GIC_TEST_NUM_BASE + 2) #define TEST_RULE "B_GIC_02" -#define TEST_DESC "Check GICv2 Valid Configuration " +#define TEST_DESC "Check GIC Valid Configuration " + +#define GIC_V2_MAX_PE 8U +#define GIC_V3_MAX_PE (1U << 28) static void payload() { - /* PE Limitations are covered in PE Rules */ - /* GICv3 + No ITS is covered in RB_GIC_03 */ - - /* Check If PCIe Support and GicV2 -> Invalid Configuration */ - uint32_t gic_version; uint32_t num_msi_frame; + uint32_t num_its; + uint32_t lpi_support; + uint32_t pe_count; uint32_t num_ecam = 0; uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid()); + pe_count = val_pe_get_num(); num_ecam = val_pcie_get_info(PCIE_INFO_NUM_ECAM, 0); gic_version = val_gic_get_info(GIC_INFO_VERSION); num_msi_frame = val_gic_get_info(GIC_INFO_NUM_MSI_FRAME); + num_its = val_gic_get_info(GIC_INFO_NUM_ITS); val_print(TRACE, "\n Received GIC version = %4d ", gic_version); if (gic_version < 3) { + if (pe_count > GIC_V2_MAX_PE) { + val_print(ERROR, "\n GICv2 supports a maximum of %d PEs", GIC_V2_MAX_PE); + val_print(ERROR, ", but system has %d PEs", pe_count); + val_set_status(index, RESULT_FAIL(1)); + return; + } + if ((num_ecam > 0) && (num_msi_frame == 0)) { val_print(ERROR, "\n GICv2 with PCIe : Invalid Configuration"); - val_set_status(index, RESULT_FAIL(1)); + val_set_status(index, RESULT_FAIL(2)); return; } } else { - val_set_status(index, RESULT_SKIP(1)); - return; + if (pe_count > GIC_V3_MAX_PE) { + val_print(ERROR, "\n GICv3 supports a maximum of 2^28 PEs"); + val_print(ERROR, ", but system has %d PEs", pe_count); + val_set_status(index, RESULT_FAIL(3)); + return; + } + + if ((num_ecam > 0) && (num_its == 0)) { + val_print(ERROR, "\n GICv3 with PCIe and no ITS : Invalid Configuration"); + val_set_status(index, RESULT_FAIL(4)); + return; + } + + if (num_its > 0) { + lpi_support = VAL_EXTRACT_BITS( + val_mmio_read(val_get_gicd_base() + GICD_TYPER), + GICV3_LPIS_BIT, GICV3_LPIS_BIT); + if (lpi_support == 0) { + val_print(ERROR, "\n GICv3 with ITS does not support LPIs"); + val_set_status(index, RESULT_FAIL(5)); + return; + } + } } val_set_status(index, RESULT_PASS); diff --git a/test_pool/gic/g003.c b/test_pool/gic/g003.c index abb92a94..18462670 100644 --- a/test_pool/gic/g003.c +++ b/test_pool/gic/g003.c @@ -47,7 +47,8 @@ payload() return; } - data = VAL_EXTRACT_BITS(val_mmio_read(val_get_gicd_base() + GICD_TYPER), 17, 17); + data = VAL_EXTRACT_BITS(val_mmio_read(val_get_gicd_base() + GICD_TYPER), + GICV3_LPIS_BIT, GICV3_LPIS_BIT); if (data == 0) { val_print(ERROR, "\n GICv3 and PCIe : LPI Not Supported"); diff --git a/val/include/acs_gic.h b/val/include/acs_gic.h index 73da4af2..a553a34c 100644 --- a/val/include/acs_gic.h +++ b/val/include/acs_gic.h @@ -50,6 +50,8 @@ #define GICv2m_MSI_SETSPI 0x040 #define GICv2m_MSI_IIDR 0xFCC +#define GICV3_LPIS_BIT 17 + /** @brief structure instance for MSI Frame Entry **/ diff --git a/val/include/rule_based_execution_enum.h b/val/include/rule_based_execution_enum.h index f6814218..d8509d71 100644 --- a/val/include/rule_based_execution_enum.h +++ b/val/include/rule_based_execution_enum.h @@ -130,9 +130,6 @@ typedef enum { S_L5GI_01, S_L5PP_01, S_L8GI_01, - Appendix_I_5, /* Appendix I.5 remapped to a legal identifier */ - Appendix_I_6, /* Appendix I.6 remapped */ - Appendix_I_9, /* Appendix I.9 remapped */ P_L1GI_01, P_L1GI_02, P_L1GI_03, @@ -661,6 +658,7 @@ typedef enum { PE065_ENTRY, G001_ENTRY, G002_ENTRY, + B_GIC_02_ENTRY, G003_ENTRY, G004_ENTRY, G005_ENTRY, @@ -686,7 +684,6 @@ typedef enum { G015_ENTRY, V2M004_ENTRY, V2M001_ENTRY, - APPENDIX_I_6_ENTRY, V2M002_ENTRY, V2M003_ENTRY, D001_ENTRY, diff --git a/val/include/test_wrappers.h b/val/include/test_wrappers.h index 0f6f38f0..e9088c55 100644 --- a/val/include/test_wrappers.h +++ b/val/include/test_wrappers.h @@ -22,12 +22,12 @@ #ifndef TEST_WRAPPERS_H #define TEST_WRAPPERS_H +uint32_t b_gic_02_entry(uint32_t num_pe); uint32_t b_ppi_00_entry(uint32_t num_pe); uint32_t b_ppi_01_entry(uint32_t num_pe); uint32_t b_ppi_02_entry(uint32_t num_pe); uint32_t b_wak_03_07_entry(uint32_t num_pe); uint32_t s_l7mp_03_entry(uint32_t num_pe); -uint32_t appendix_i_6_entry(uint32_t num_pe); uint32_t p_l1pe_01_entry(uint32_t num_pe); uint32_t ie_reg_1_entry(uint32_t num_pe); uint32_t pci_ic_11_entry(uint32_t num_pe); diff --git a/val/include/val_interface.h b/val/include/val_interface.h index a4e8689d..224cc8bf 100644 --- a/val/include/val_interface.h +++ b/val/include/val_interface.h @@ -194,6 +194,7 @@ typedef enum { V2M_MSI_FLAGS } V2M_MSI_INFO_e; +uint32_t val_gic_is_v2m(void); uint32_t val_gic_v2m_parse_info(void); uint64_t val_gic_v2m_get_info(V2M_MSI_INFO_e type, uint32_t instance); void val_gic_free_info_table(void); diff --git a/val/src/acs_gic_v2m.c b/val/src/acs_gic_v2m.c index ad6ef52b..b4af8780 100644 --- a/val/src/acs_gic_v2m.c +++ b/val/src/acs_gic_v2m.c @@ -25,6 +25,13 @@ extern GIC_INFO_TABLE * g_gic_info_table; GICv2m_MSI_FRAME_INFO *g_v2m_msi_info; +uint32_t +val_gic_is_v2m(void) +{ + return ((val_gic_get_info(GIC_INFO_VERSION) == 2) && + (val_gic_get_info(GIC_INFO_NUM_MSI_FRAME) > 0)); +} + /** @brief This function parses the V2M MSI Information from gic info table 1. Caller - Validation Layer diff --git a/val/src/bsa_execute_test.c b/val/src/bsa_execute_test.c index fbc41af6..96830c47 100644 --- a/val/src/bsa_execute_test.c +++ b/val/src/bsa_execute_test.c @@ -195,7 +195,7 @@ val_bsa_gic_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) { uint32_t status, i; - uint32_t gic_version, num_msi_frame; + uint32_t gic_version; if (!(g_bsa_level >= 1 || g_bsa_only_level == 1)) return ACS_STATUS_SKIP; @@ -229,9 +229,7 @@ val_bsa_gic_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) /* B_GIC_01 and B_GIC_02 only for BSA */ if (!g_build_sbsa) { status |= g001_entry(num_pe); - /* Run B_GIC_02 test only if system has GICv2 */ - if (gic_version == 2) - status |= g002_entry(num_pe); + status |= g002_entry(num_pe); } if (gic_version > 2) { status |= g003_entry(num_pe); @@ -260,9 +258,7 @@ val_bsa_gic_execute_tests(uint32_t num_pe, uint32_t *g_sw_view) if (g_bsa_level >= 1 || g_bsa_only_level == 1) { /* Run GICv2m only if GIC Version is v2m. */ - num_msi_frame = val_gic_get_info(GIC_INFO_NUM_MSI_FRAME); - - if ((gic_version != 2) || (num_msi_frame == 0)) { + if (!val_gic_is_v2m()) { val_print(TRACE, "\n No GICv2m, Skipping all GICv2m tests\n"); goto its_test; } diff --git a/val/src/rule_enum_string_map.c b/val/src/rule_enum_string_map.c index c331f282..5954c14f 100644 --- a/val/src/rule_enum_string_map.c +++ b/val/src/rule_enum_string_map.c @@ -117,10 +117,6 @@ char *rule_id_string[RULE_ID_SENTINEL] = { [S_L5GI_01] = "S_L5GI_01", [S_L5PP_01] = "S_L5PP_01", [S_L8GI_01] = "S_L8GI_01", - [Appendix_I_5] = "Appendix_I_5", - [Appendix_I_6] = "Appendix_I_6", - [Appendix_I_9] = "Appendix_I_9", - /* PERIPHERAL rules */ [B_PER_01] = "B_PER_01", [B_PER_02] = "B_PER_02", diff --git a/val/src/rule_metadata.c b/val/src/rule_metadata.c index 7accc9ab..26b62e78 100644 --- a/val/src/rule_metadata.c +++ b/val/src/rule_metadata.c @@ -594,9 +594,9 @@ rule_test_map_t rule_test_map[RULE_ID_SENTINEL] = { .test_num = ACS_GIC_TEST_NUM_BASE + 1, }, [B_GIC_02] = { - .test_entry_id = G002_ENTRY, + .test_entry_id = B_GIC_02_ENTRY, .module_id = GIC, - .rule_desc = "Check GICv2 Valid Configuration", + .rule_desc = "Check GIC Valid Configuration", .platform_bitmask = PLATFORM_BAREMETAL | PLATFORM_UEFI, .flag = BASE_RULE, .test_num = ACS_GIC_TEST_NUM_BASE + 2, @@ -749,29 +749,6 @@ rule_test_map_t rule_test_map[RULE_ID_SENTINEL] = { .flag = BASE_RULE, .test_num = ACS_GIC_TEST_NUM_BASE + 15, }, - [Appendix_I_5] = { - .test_entry_id = V2M004_ENTRY, - .module_id = GIC, - .rule_desc = "Check GICv2m SPI allocated to MSI Ctrl", - .platform_bitmask = PLATFORM_BAREMETAL | PLATFORM_UEFI, - .flag = BASE_RULE, - .test_num = ACS_GIC_V2M_TEST_NUM_BASE + 4, - }, - [Appendix_I_6] = { - .test_entry_id = APPENDIX_I_6_ENTRY, - .module_id = GIC, - .rule_desc = "", - .platform_bitmask = PLATFORM_BAREMETAL | PLATFORM_UEFI, - .flag = BASE_RULE, - }, - [Appendix_I_9] = { - .test_entry_id = V2M002_ENTRY, - .module_id = GIC, - .rule_desc = "Check GICv2m MSI Frame Register", - .platform_bitmask = PLATFORM_BAREMETAL | PLATFORM_UEFI, - .flag = BASE_RULE, - .test_num = ACS_GIC_V2M_TEST_NUM_BASE + 2, - }, /* PERIPHERAL */ [B_PER_01] = { .test_entry_id = D001_ENTRY, @@ -3567,6 +3544,7 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [ETE009_ENTRY] = ete009_entry, [G001_ENTRY] = g001_entry, [G002_ENTRY] = g002_entry, + [B_GIC_02_ENTRY] = b_gic_02_entry, [G003_ENTRY] = g003_entry, [G004_ENTRY] = g004_entry, [G005_ENTRY] = g005_entry, @@ -3584,7 +3562,6 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [B_WAK_03_07_ENTRY] = b_wak_03_07_entry, [GPU_04_ENTRY] = gpu_04_entry, [S_L7MP_03_ENTRY] = s_l7mp_03_entry, - [APPENDIX_I_6_ENTRY] = appendix_i_6_entry, [IE_REG_1_ENTRY] = ie_reg_1_entry, [IE_REG_2_ENTRY] = ie_reg_2_entry, [IE_REG_3_ENTRY] = ie_reg_3_entry, @@ -3953,6 +3930,7 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [P_L1PE_01_ENTRY] = p_l1pe_01_entry, [G001_ENTRY] = g001_entry, [G002_ENTRY] = g002_entry, + [B_GIC_02_ENTRY] = b_gic_02_entry, [G003_ENTRY] = g003_entry, [G004_ENTRY] = g004_entry, [G005_ENTRY] = g005_entry, @@ -4292,7 +4270,6 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [B_PPI_02_ENTRY] = b_ppi_02_entry, [B_WAK_03_07_ENTRY] = b_wak_03_07_entry, [S_L7MP_03_ENTRY] = s_l7mp_03_entry, - [APPENDIX_I_6_ENTRY] = appendix_i_6_entry, [IE_REG_1_ENTRY] = ie_reg_1_entry, [IE_REG_2_ENTRY] = ie_reg_2_entry, [IE_REG_3_ENTRY] = ie_reg_3_entry, @@ -4319,6 +4296,7 @@ test_entry_fn_t test_entry_func_table[TEST_ENTRY_SENTINEL] = { [CXL_11_ENTRY] = cxl_11_entry, [CXL_12_ENTRY] = cxl_12_entry, [G002_ENTRY] = g002_entry, + [B_GIC_02_ENTRY] = b_gic_02_entry, [ITS002_ENTRY] = its002_entry, [ITS005_ENTRY] = its005_entry, [ITS006_ENTRY] = its006_entry, diff --git a/val/src/test_wrappers.c b/val/src/test_wrappers.c index 9c6a66a8..10879a90 100644 --- a/val/src/test_wrappers.c +++ b/val/src/test_wrappers.c @@ -117,6 +117,54 @@ static uint32_t run_pcie_static_and_exerciser(TEST_ENTRY_ID_e *static_list, return rule_status; } +/* B_GIC_02 */ +uint32_t +b_gic_02_entry(uint32_t num_pe) +{ +#if !defined(TARGET_LINUX) + uint32_t status = TEST_STATE_UNKNOWN; + uint32_t v2m_status = TEST_STATE_UNKNOWN; + uint32_t rule_status = TEST_STATE_UNKNOWN; + + TEST_ENTRY_ID_e gic_list[] = {G002_ENTRY, TEST_ENTRY_SENTINEL}; + TEST_ENTRY_ID_e gic_v2m_list[] = {V2M001_ENTRY, V2M002_ENTRY, + V2M003_ENTRY, V2M004_ENTRY, + TEST_ENTRY_SENTINEL}; + + status = run_test_entries(gic_list, num_pe); + + if (!val_gic_is_v2m()) { + return status; + } + + if (val_gic_v2m_parse_info()) { + val_print(ERROR, "\n GICv2m info mismatch, skipping GICv2m tests"); + return (GET_STATE(status) == TEST_PASS) ? RESULT_PARTIAL_COVERED : status; + } + + v2m_status = run_test_entries(gic_v2m_list, num_pe); + + /* Report partial coverage for mixed PASS+SKIP/WARN aggregated results. */ + if (((GET_STATE(status) == TEST_PASS) && + ((GET_STATE(v2m_status) == TEST_SKIP) || (GET_STATE(v2m_status) == TEST_WARNING))) || + ((GET_STATE(v2m_status) == TEST_PASS) && + ((GET_STATE(status) == TEST_SKIP) || (GET_STATE(status) == TEST_WARNING)))) + return RESULT_PARTIAL_COVERED; + + /* For all other combinations, fall back to severity-based aggregation. */ + rule_status = max_status(status, v2m_status); + /* If the combined result only saw WARN/SKIP outcomes, prefer WARN over SKIP. */ + if (((GET_STATE(status) == TEST_WARNING) || (GET_STATE(v2m_status) == TEST_WARNING)) && + (GET_STATE(rule_status) == TEST_SKIP)) { + rule_status = RESULT_WARNING(0); + } + return rule_status; +#else + // Test not applicable for Linux target + return RESULT_SKIP(0); +#endif +} + /* B_PPI_00 */ uint32_t b_ppi_00_entry(uint32_t num_pe) @@ -174,15 +222,6 @@ s_l7mp_03_entry(uint32_t num_pe) return run_test_entries(tst_entry_list, num_pe); } -/* Appendix I.6 */ -uint32_t -appendix_i_6_entry(uint32_t num_pe) -{ - TEST_ENTRY_ID_e tst_entry_list[] = {V2M001_ENTRY, V2M003_ENTRY, TEST_ENTRY_SENTINEL}; - - return run_test_entries(tst_entry_list, num_pe); -} - /* P_L1PE_01 */ uint32_t p_l1pe_01_entry(uint32_t num_pe)