blob: 6955191dc7a0c47f63ebceb2aaaa6e01dc7df76f [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
Boyan Karatotev32815d32025-06-23 09:21:54 +01002 * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
Antonio Nino Diaz09a00ef2019-01-11 13:12:58 +00008#include <drivers/arm/arm_gic.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02009#include <irq.h>
10#include <platform.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020011#include <tftf_lib.h>
12
13static volatile unsigned int counter;
14
15/*
16 * IRQ handler for SGI #0.
17 * Increment the test counter to prove it's been successfully called.
18 */
19static int increment_counter(void *data)
20{
21 counter++;
22 return 0;
23}
24
25#if !DEBUG
26static int set_counter_to_42(void *data)
27{
28 counter = 42;
29 return 0;
30}
31#endif
32
33/*
34 * @Test_Aim@ Test IRQ handling on lead CPU
35 *
36 * Check that IRQ enabling/disabling and IRQ handler registering/unregistering
37 * work as expected on the lead CPU.
38 */
39test_result_t test_validation_irq(void)
40{
41 unsigned int mpid = read_mpidr_el1();
42 unsigned int core_pos = platform_get_core_pos(mpid);
43 const unsigned int sgi_id = IRQ_NS_SGI_0;
44 int ret;
45
46 counter = 0;
47
48 /* Now register a handler */
Boyan Karatotev6d144db2025-06-23 15:04:53 +010049 ret = tftf_irq_register_handler_sgi(sgi_id, increment_counter);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020050 if (ret != 0) {
51 tftf_testcase_printf("Failed to register initial IRQ handler\n");
52 return TEST_RESULT_FAIL;
53 }
54
Boyan Karatotev6d144db2025-06-23 15:04:53 +010055 tftf_irq_enable_sgi(IRQ_NS_SGI_0, GIC_HIGHEST_NS_PRIORITY);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020056
57 /*
58 * Send the SGI to the calling core and check the IRQ handler has been
59 * successfully called
60 */
61 tftf_send_sgi(sgi_id, core_pos);
62
63 /* Wait till the handler is executed */
64 while (counter != 1)
65 ;
66
Boyan Karatotev6d144db2025-06-23 15:04:53 +010067 // TODO all this crap tests tftf itself. It's just slow. Drop?
68 // or add it to some test group that's not built/run by default.
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020069 /*
70 * Try to overwrite the IRQ handler. This should fail.
71 * In debug builds, it would trigger an assertion so we can't test that
72 * as it will stop the test session.
73 * In release builds though, it should just do nothing, i.e. it won't
74 * replace the existing handler and that's something that can be tested.
75 */
76#if !DEBUG
Boyan Karatotev6d144db2025-06-23 15:04:53 +010077 ret = tftf_irq_register_handler_sgi(sgi_id, set_counter_to_42);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020078 if (ret == 0) {
79 tftf_testcase_printf(
80 "Overwriting the IRQ handler should have failed\n");
81 return TEST_RESULT_FAIL;
82 }
83#endif
84
85 tftf_send_sgi(sgi_id, core_pos);
86 while (counter != 2)
87 ;
88
89 /* Unregister the IRQ handler */
Boyan Karatotev6d144db2025-06-23 15:04:53 +010090 ret = tftf_irq_unregister_handler_sgi(IRQ_NS_SGI_0);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020091 if (ret != 0) {
92 tftf_testcase_printf("Failed to unregister IRQ handler\n");
93 return TEST_RESULT_FAIL;
94 }
95
96 /*
97 * Send the SGI to the calling core and check the former IRQ handler
98 * has not been called, now that it has been unregistered.
99 */
100 tftf_send_sgi(sgi_id, core_pos);
101
102 /*
103 * Wait for some time so that SGI interrupts the processor, Normally it
104 * takes a small but finite time for the IRQ to be sent to processor
105 */
Boyan Karatotev32815d32025-06-23 09:21:54 +0100106 waitms(100);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200107
108 if (counter != 2) {
109 tftf_testcase_printf(
110 "IRQ handler hasn't been successfully unregistered\n");
111 return TEST_RESULT_FAIL;
112 }
113
114 /*
115 * Try to unregister the IRQ handler again. This should fail.
116 * In debug builds, it would trigger an assertion so we can't test that
117 * as it will stop the test session.
118 * In release builds though, it should just do nothing.
119 */
120#if !DEBUG
Boyan Karatotev6d144db2025-06-23 15:04:53 +0100121 ret = tftf_irq_unregister_handler_sgi(sgi_id);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200122 if (ret == 0) {
123 tftf_testcase_printf(
124 "Unregistering the IRQ handler again should have failed\n");
125 return TEST_RESULT_FAIL;
126 }
127#endif
128
Boyan Karatotev6d144db2025-06-23 15:04:53 +0100129 tftf_irq_disable_sgi(sgi_id);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200130
131 return TEST_RESULT_SUCCESS;
132}