Triggers LPIs through the INT command and test the latency. Mostly inherited form commit 0ef02cd6cbaa(arm/arm64: ITS: INT functional tests). Signed-off-by: Jingyi Wang <wangjingyi11@xxxxxxxxxx> --- arm/micro-bench.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/arm/micro-bench.c b/arm/micro-bench.c index 80d8db3..aeb60a7 100644 --- a/arm/micro-bench.c +++ b/arm/micro-bench.c @@ -20,6 +20,7 @@ */ #include <libcflat.h> #include <asm/gic.h> +#include <asm/gic-v3-its.h> #define NTIMES (1U << 16) @@ -145,6 +146,48 @@ static void ipi_exec(void) assert_msg(irq_received, "failed to receive IPI in time, but received %d successfully\n", received); } +static bool lpi_prep(void) +{ + struct its_collection *col1; + struct its_device *dev2; + + if (!gicv3_its_base()) + return false; + + its_enable_defaults(); + dev2 = its_create_device(2 /* dev id */, 8 /* nb_ites */); + col1 = its_create_collection(1 /* col id */, 1 /* target PE */); + gicv3_lpi_set_config(8199, LPI_PROP_DEFAULT); + + its_send_mapd_nv(dev2, true); + its_send_mapc_nv(col1, true); + its_send_invall_nv(col1); + its_send_mapti_nv(dev2, 8199 /* lpi id */, 20 /* event id */, col1); + + gic_prep_common(); + return true; +} + +static void lpi_exec(void) +{ + struct its_device *dev2; + unsigned tries = 1 << 28; + static int received = 0; + + irq_received = false; + + dev2 = its_get_device(2); + its_send_int_nv(dev2, 20); + + while (!irq_received && tries--) + cpu_relax(); + + if (irq_received) + ++received; + + assert_msg(irq_received, "failed to receive LPI in time, but received %d successfully\n", received); +} + static void hvc_exec(void) { asm volatile("mov w0, #0x4b000000; hvc #0" ::: "w0"); @@ -190,6 +233,7 @@ static struct exit_test tests[] = { {"eoi", NULL, eoi_exec, true}, {"ipi", ipi_prep, ipi_exec, true}, {"ipi_hw", ipi_hw_prep, ipi_exec, true}, + {"lpi", lpi_prep, lpi_exec, true}, }; struct ns_time { -- 2.19.1