aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/arm/gic/gic_v2.c12
-rw-r--r--include/drivers/arm/gic_v2.h5
-rw-r--r--tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c9
3 files changed, 23 insertions, 3 deletions
diff --git a/drivers/arm/gic/gic_v2.c b/drivers/arm/gic/gic_v2.c
index 7904ed127..ef930074e 100644
--- a/drivers/arm/gic/gic_v2.c
+++ b/drivers/arm/gic/gic_v2.c
@@ -44,6 +44,11 @@ static unsigned int core_pos_to_gic_id(unsigned int core_pos)
/*******************************************************************************
* GIC Distributor interface accessors for reading entire registers
******************************************************************************/
+uint8_t gicd_read_itargetsr_byte(unsigned int base, unsigned int interrupt_id)
+{
+ return mmio_read_8(base + GICD_ITARGETSR + interrupt_id);
+}
+
unsigned int gicd_read_itargetsr(unsigned int base, unsigned int interrupt_id)
{
unsigned n = interrupt_id >> ITARGETSR_SHIFT;
@@ -266,12 +271,19 @@ void gicv2_set_itargetsr(unsigned int num, unsigned int core_pos)
gicd_set_itargetsr(gicd_base_addr, num, gic_cpu_id);
}
+uint8_t gicv2_read_itargetsr_value(unsigned int num)
+{
+ return gicd_read_itargetsr_byte(gicd_base_addr, num);
+}
+
void gicv2_set_itargetsr_value(unsigned int num, unsigned int val)
{
assert(gicd_base_addr);
assert(IS_SPI(num));
gicd_write_itargetsr_byte(gicd_base_addr, num, val);
+
+ assert(gicv2_read_itargetsr_value(num) == val);
}
unsigned int gicv2_gicd_get_isenabler(unsigned int num)
diff --git a/include/drivers/arm/gic_v2.h b/include/drivers/arm/gic_v2.h
index 8432a3fc6..6e7b7646e 100644
--- a/include/drivers/arm/gic_v2.h
+++ b/include/drivers/arm/gic_v2.h
@@ -242,6 +242,11 @@ unsigned int gicv2_gicd_get_ispendr(unsigned int interrupt_id);
unsigned int gicv2_gicc_read_iar(void);
/*
+ * Read and return the target core mask of interrupt ID `num`.
+ */
+uint8_t gicv2_read_itargetsr_value(unsigned int num);
+
+/*
* Set the bit corresponding to `num` in the GICD ICENABLER register.
*/
void gicv2_gicd_set_icenabler(unsigned int num);
diff --git a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
index 16ed371d3..eae5ccd8a 100644
--- a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
+++ b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
@@ -22,7 +22,8 @@
#define TEST_SPURIOUS_ITERATIONS_COUNT 1000000
-#define TEST_SPI_ID (MIN_SPI_ID + 2)
+#define TEST_SPI_ID (MIN_SPI_ID + 2)
+#define CPU_TARGET_FIELD ((1 << PLATFORM_CORE_COUNT) - 1)
static event_t cpu_ready[PLATFORM_CORE_COUNT];
static volatile int requested_irq_received[PLATFORM_CORE_COUNT];
@@ -47,7 +48,8 @@ static int test_handler(void *data)
/* Dummy handler that increases a variable to check if it has been called. */
static int test_spurious_handler(void *data)
{
- unsigned int core_pos = platform_get_core_pos(read_mpidr_el1());
+ u_register_t core_mpid = read_mpidr_el1() & MPID_MASK;
+ unsigned int core_pos = platform_get_core_pos(core_mpid);
spurious_count[core_pos]++;
@@ -194,6 +196,7 @@ test_result_t test_multicore_spurious_interrupt(void)
test_finished_flag = 1;
return TEST_RESULT_SKIPPED;
}
+ mp_printf("CPU 0x%x powered on\n", (unsigned int)cpu_mpid);
}
/* Wait for non-lead CPUs to enter the test */
@@ -226,7 +229,7 @@ test_result_t test_multicore_spurious_interrupt(void)
tftf_irq_enable(TEST_SPI_ID, GIC_HIGHEST_NS_PRIORITY);
/* Route interrupts to all CPUs */
- gicv2_set_itargetsr_value(TEST_SPI_ID, 0xFF);
+ gicv2_set_itargetsr_value(TEST_SPI_ID, CPU_TARGET_FIELD);
for (j = 0; j < TEST_SPURIOUS_ITERATIONS_COUNT; j++) {