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)