diff options
-rw-r--r-- | drivers/arm/gic/gic_v2.c | 12 | ||||
-rw-r--r-- | include/drivers/arm/gic_v2.h | 5 | ||||
-rw-r--r-- | tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c | 9 |
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++) { |