1 /*
2  * QTest testcase for STM32L4x5_EXTI
3  *
4  * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5  * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2 or later.
8  * See the COPYING file in the top-level directory.
9  */
10 
11 #include "qemu/osdep.h"
12 #include "libqtest-single.h"
13 
14 #define EXTI_BASE_ADDR 0x40010400
15 #define EXTI_IMR1 0x00
16 #define EXTI_EMR1 0x04
17 #define EXTI_RTSR1 0x08
18 #define EXTI_FTSR1 0x0C
19 #define EXTI_SWIER1 0x10
20 #define EXTI_PR1 0x14
21 #define EXTI_IMR2 0x20
22 #define EXTI_EMR2 0x24
23 #define EXTI_RTSR2 0x28
24 #define EXTI_FTSR2 0x2C
25 #define EXTI_SWIER2 0x30
26 #define EXTI_PR2 0x34
27 
28 #define NVIC_ISER 0xE000E100
29 #define NVIC_ISPR 0xE000E200
30 #define NVIC_ICPR 0xE000E280
31 
32 #define EXTI0_IRQ 6
33 #define EXTI1_IRQ 7
34 #define EXTI5_9_IRQ 23
35 #define EXTI35_IRQ 1
36 
37 static void enable_nvic_irq(unsigned int n)
38 {
39     writel(NVIC_ISER, 1 << n);
40 }
41 
42 static void unpend_nvic_irq(unsigned int n)
43 {
44     writel(NVIC_ICPR, 1 << n);
45 }
46 
47 static bool check_nvic_pending(unsigned int n)
48 {
49     return readl(NVIC_ISPR) & (1 << n);
50 }
51 
52 static void exti_writel(unsigned int offset, uint32_t value)
53 {
54     writel(EXTI_BASE_ADDR + offset, value);
55 }
56 
57 static uint32_t exti_readl(unsigned int offset)
58 {
59     return readl(EXTI_BASE_ADDR + offset);
60 }
61 
62 static void exti_set_irq(int num, int level)
63 {
64    qtest_set_irq_in(global_qtest, "/machine/soc/exti", NULL,
65                     num, level);
66 }
67 
68 static void test_reg_write_read(void)
69 {
70     /* Test that non-reserved bits in xMR and xTSR can be set and cleared */
71 
72     exti_writel(EXTI_IMR1, 0xFFFFFFFF);
73     g_assert_cmphex(exti_readl(EXTI_IMR1), ==, 0xFFFFFFFF);
74     exti_writel(EXTI_IMR1, 0x00000000);
75     g_assert_cmphex(exti_readl(EXTI_IMR1), ==, 0x00000000);
76 
77     exti_writel(EXTI_EMR1, 0xFFFFFFFF);
78     g_assert_cmphex(exti_readl(EXTI_EMR1), ==, 0xFFFFFFFF);
79     exti_writel(EXTI_EMR1, 0x00000000);
80     g_assert_cmphex(exti_readl(EXTI_EMR1), ==, 0x00000000);
81 
82     exti_writel(EXTI_RTSR1, 0xFFFFFFFF);
83     g_assert_cmphex(exti_readl(EXTI_RTSR1), ==, 0x007DFFFF);
84     exti_writel(EXTI_RTSR1, 0x00000000);
85     g_assert_cmphex(exti_readl(EXTI_RTSR1), ==, 0x00000000);
86 
87     exti_writel(EXTI_FTSR1, 0xFFFFFFFF);
88     g_assert_cmphex(exti_readl(EXTI_FTSR1), ==, 0x007DFFFF);
89     exti_writel(EXTI_FTSR1, 0x00000000);
90     g_assert_cmphex(exti_readl(EXTI_FTSR1), ==, 0x00000000);
91 
92     exti_writel(EXTI_IMR2, 0xFFFFFFFF);
93     g_assert_cmphex(exti_readl(EXTI_IMR2), ==, 0x000000FF);
94     exti_writel(EXTI_IMR2, 0x00000000);
95     g_assert_cmphex(exti_readl(EXTI_IMR2), ==, 0x00000000);
96 
97     exti_writel(EXTI_EMR2, 0xFFFFFFFF);
98     g_assert_cmphex(exti_readl(EXTI_EMR2), ==, 0x000000FF);
99     exti_writel(EXTI_EMR2, 0x00000000);
100     g_assert_cmphex(exti_readl(EXTI_EMR2), ==, 0x00000000);
101 
102     exti_writel(EXTI_RTSR2, 0xFFFFFFFF);
103     g_assert_cmphex(exti_readl(EXTI_RTSR2), ==, 0x00000078);
104     exti_writel(EXTI_RTSR2, 0x00000000);
105     g_assert_cmphex(exti_readl(EXTI_RTSR2), ==, 0x00000000);
106 
107     exti_writel(EXTI_FTSR2, 0xFFFFFFFF);
108     g_assert_cmphex(exti_readl(EXTI_FTSR2), ==, 0x00000078);
109     exti_writel(EXTI_FTSR2, 0x00000000);
110     g_assert_cmphex(exti_readl(EXTI_FTSR2), ==, 0x00000000);
111 }
112 
113 static void test_direct_lines_write(void)
114 {
115     /* Test that direct lines reserved bits are not written to */
116 
117     exti_writel(EXTI_RTSR1, 0xFF820000);
118     g_assert_cmphex(exti_readl(EXTI_RTSR1), ==, 0x00000000);
119 
120     exti_writel(EXTI_FTSR1, 0xFF820000);
121     g_assert_cmphex(exti_readl(EXTI_FTSR1), ==, 0x00000000);
122 
123     exti_writel(EXTI_SWIER1, 0xFF820000);
124     g_assert_cmphex(exti_readl(EXTI_SWIER1), ==, 0x00000000);
125 
126     exti_writel(EXTI_PR1, 0xFF820000);
127     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
128 
129     exti_writel(EXTI_RTSR2, 0x00000087);
130     g_assert_cmphex(exti_readl(EXTI_RTSR2), ==, 0x00000000);
131 
132     exti_writel(EXTI_FTSR2, 0x00000087);
133     g_assert_cmphex(exti_readl(EXTI_FTSR2), ==, 0x00000000);
134 
135     exti_writel(EXTI_SWIER2, 0x00000087);
136     g_assert_cmphex(exti_readl(EXTI_SWIER2), ==, 0x00000000);
137 
138     exti_writel(EXTI_PR2, 0x00000087);
139     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000000);
140 }
141 
142 static void test_reserved_bits_write(void)
143 {
144     /* Test that reserved bits stay are not written to */
145 
146     exti_writel(EXTI_IMR2, 0xFFFFFF00);
147     g_assert_cmphex(exti_readl(EXTI_IMR2), ==, 0x00000000);
148 
149     exti_writel(EXTI_EMR2, 0xFFFFFF00);
150     g_assert_cmphex(exti_readl(EXTI_EMR2), ==, 0x00000000);
151 
152     exti_writel(EXTI_RTSR2, 0xFFFFFF00);
153     g_assert_cmphex(exti_readl(EXTI_RTSR2), ==, 0x00000000);
154 
155     exti_writel(EXTI_FTSR2, 0xFFFFFF00);
156     g_assert_cmphex(exti_readl(EXTI_FTSR2), ==, 0x00000000);
157 
158     exti_writel(EXTI_SWIER2, 0xFFFFFF00);
159     g_assert_cmphex(exti_readl(EXTI_SWIER2), ==, 0x00000000);
160 
161     exti_writel(EXTI_PR2, 0xFFFFFF00);
162     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000000);
163 }
164 
165 static void test_software_interrupt(void)
166 {
167     /*
168      * Test that we can launch a software irq by :
169      * - enabling its line in IMR
170      * - and then setting a bit from '0' to '1' in SWIER
171      *
172      * And that the interruption stays pending in NVIC
173      * even after clearing the pending bit in PR.
174      */
175 
176     /*
177      * Testing interrupt line EXTI0
178      * Bit 0 in EXTI_*1 registers (EXTI0) corresponds to GPIO Px_0
179      */
180 
181     enable_nvic_irq(EXTI0_IRQ);
182     /* Check that there are no interrupts already pending in PR */
183     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
184     /* Check that this specific interrupt isn't pending in NVIC */
185     g_assert_false(check_nvic_pending(EXTI0_IRQ));
186 
187     /* Enable interrupt line EXTI0 */
188     exti_writel(EXTI_IMR1, 0x00000001);
189     /* Set the right SWIER bit from '0' to '1' */
190     exti_writel(EXTI_SWIER1, 0x00000000);
191     exti_writel(EXTI_SWIER1, 0x00000001);
192 
193     /* Check that the write in SWIER was effective */
194     g_assert_cmphex(exti_readl(EXTI_SWIER1), ==, 0x00000001);
195     /* Check that the corresponding pending bit in PR is set */
196     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000001);
197     /* Check that the corresponding interrupt is pending in the NVIC */
198     g_assert_true(check_nvic_pending(EXTI0_IRQ));
199 
200     /* Clear the pending bit in PR */
201     exti_writel(EXTI_PR1, 0x00000001);
202 
203     /* Check that the write in PR was effective */
204     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
205     /* Check that the corresponding bit in SWIER was cleared */
206     g_assert_cmphex(exti_readl(EXTI_SWIER1), ==, 0x00000000);
207     /* Check that the interrupt is still pending in the NVIC */
208     g_assert_true(check_nvic_pending(EXTI0_IRQ));
209 
210     /*
211      * Testing interrupt line EXTI35
212      * Bit 3 in EXTI_*2 registers (EXTI35) corresponds to PVM 1 Wakeup
213      */
214 
215     enable_nvic_irq(EXTI35_IRQ);
216     /* Check that there are no interrupts already pending */
217     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000000);
218     g_assert_false(check_nvic_pending(EXTI35_IRQ));
219 
220     /* Enable interrupt line EXTI0 */
221     exti_writel(EXTI_IMR2, 0x00000008);
222     /* Set the right SWIER bit from '0' to '1' */
223     exti_writel(EXTI_SWIER2, 0x00000000);
224     exti_writel(EXTI_SWIER2, 0x00000008);
225 
226     /* Check that the write in SWIER was effective */
227     g_assert_cmphex(exti_readl(EXTI_SWIER2), ==, 0x00000008);
228     /* Check that the corresponding pending bit in PR is set */
229     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000008);
230     /* Check that the corresponding interrupt is pending in the NVIC */
231     g_assert_true(check_nvic_pending(EXTI35_IRQ));
232 
233     /* Clear the pending bit in PR */
234     exti_writel(EXTI_PR2, 0x00000008);
235 
236     /* Check that the write in PR was effective */
237     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000000);
238     /* Check that the corresponding bit in SWIER was cleared */
239     g_assert_cmphex(exti_readl(EXTI_SWIER2), ==, 0x00000000);
240     /* Check that the interrupt is still pending in the NVIC */
241     g_assert_true(check_nvic_pending(EXTI35_IRQ));
242 
243     /* Clean NVIC */
244     unpend_nvic_irq(EXTI0_IRQ);
245     g_assert_false(check_nvic_pending(EXTI0_IRQ));
246     unpend_nvic_irq(EXTI35_IRQ);
247     g_assert_false(check_nvic_pending(EXTI35_IRQ));
248 }
249 
250 static void test_edge_selector(void)
251 {
252     enable_nvic_irq(EXTI0_IRQ);
253 
254     /* Configure EXTI line 0 irq on rising edge */
255     exti_set_irq(0, 1);
256     exti_writel(EXTI_IMR1, 0x00000001);
257     exti_writel(EXTI_RTSR1, 0x00000001);
258     exti_writel(EXTI_FTSR1, 0x00000000);
259 
260     /* Test that an irq is raised on rising edge only */
261     exti_set_irq(0, 0);
262     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
263     g_assert_false(check_nvic_pending(EXTI0_IRQ));
264 
265     exti_set_irq(0, 1);
266     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000001);
267     g_assert_true(check_nvic_pending(EXTI0_IRQ));
268 
269     /* Clean the test */
270     exti_writel(EXTI_PR1, 0x00000001);
271     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
272     unpend_nvic_irq(EXTI0_IRQ);
273     g_assert_false(check_nvic_pending(EXTI0_IRQ));
274 
275     /* Configure EXTI line 0 irq on falling edge */
276     exti_set_irq(0, 0);
277     exti_writel(EXTI_IMR1, 0x00000001);
278     exti_writel(EXTI_RTSR1, 0x00000000);
279     exti_writel(EXTI_FTSR1, 0x00000001);
280 
281     /* Test that an irq is raised on falling edge only */
282     exti_set_irq(0, 1);
283     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
284     g_assert_false(check_nvic_pending(EXTI0_IRQ));
285 
286     exti_set_irq(0, 0);
287     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000001);
288     g_assert_true(check_nvic_pending(EXTI0_IRQ));
289 
290     /* Clean the test */
291     exti_writel(EXTI_PR1, 0x00000001);
292     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
293     unpend_nvic_irq(EXTI0_IRQ);
294     g_assert_false(check_nvic_pending(EXTI0_IRQ));
295 
296     /* Configure EXTI line 0 irq on falling and rising edge */
297     exti_writel(EXTI_IMR1, 0x00000001);
298     exti_writel(EXTI_RTSR1, 0x00000001);
299     exti_writel(EXTI_FTSR1, 0x00000001);
300 
301     /* Test that an irq is raised on rising edge */
302     exti_set_irq(0, 1);
303     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000001);
304     g_assert_true(check_nvic_pending(EXTI0_IRQ));
305 
306     /* Clean the test */
307     exti_writel(EXTI_PR1, 0x00000001);
308     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
309     unpend_nvic_irq(EXTI0_IRQ);
310     g_assert_false(check_nvic_pending(EXTI0_IRQ));
311 
312     /* Test that an irq is raised on falling edge */
313     exti_set_irq(0, 0);
314     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000001);
315     g_assert_true(check_nvic_pending(EXTI0_IRQ));
316 
317     /* Clean the test */
318     exti_writel(EXTI_PR1, 0x00000001);
319     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
320     unpend_nvic_irq(EXTI0_IRQ);
321     g_assert_false(check_nvic_pending(EXTI0_IRQ));
322 
323     /* Configure EXTI line 0 irq without selecting an edge trigger */
324     exti_writel(EXTI_IMR1, 0x00000001);
325     exti_writel(EXTI_RTSR1, 0x00000000);
326     exti_writel(EXTI_FTSR1, 0x00000000);
327 
328     /* Test that no irq is raised */
329     exti_set_irq(0, 1);
330     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
331     g_assert_false(check_nvic_pending(EXTI0_IRQ));
332 
333     exti_set_irq(0, 0);
334     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
335     g_assert_false(check_nvic_pending(EXTI0_IRQ));
336 }
337 
338 static void test_no_software_interrupt(void)
339 {
340     /*
341      * Test that software irq doesn't happen when :
342      * - corresponding bit in IMR isn't set
343      * - SWIER is set to 1 before IMR is set to 1
344      */
345 
346     /*
347      * Testing interrupt line EXTI0
348      * Bit 0 in EXTI_*1 registers (EXTI0) corresponds to GPIO Px_0
349      */
350 
351     enable_nvic_irq(EXTI0_IRQ);
352     /* Check that there are no interrupts already pending in PR */
353     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
354     /* Check that this specific interrupt isn't pending in NVIC */
355     g_assert_false(check_nvic_pending(EXTI0_IRQ));
356 
357     /* Mask interrupt line EXTI0 */
358     exti_writel(EXTI_IMR1, 0x00000000);
359     /* Set the corresponding SWIER bit from '0' to '1' */
360     exti_writel(EXTI_SWIER1, 0x00000000);
361     exti_writel(EXTI_SWIER1, 0x00000001);
362 
363     /* Check that the write in SWIER was effective */
364     g_assert_cmphex(exti_readl(EXTI_SWIER1), ==, 0x00000001);
365     /* Check that the pending bit in PR wasn't set */
366     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
367     /* Check that the interrupt isn't pending in NVIC */
368     g_assert_false(check_nvic_pending(EXTI0_IRQ));
369 
370     /* Enable interrupt line EXTI0 */
371     exti_writel(EXTI_IMR1, 0x00000001);
372 
373     /* Check that the pending bit in PR wasn't set */
374     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
375     /* Check that the interrupt isn't pending in NVIC */
376     g_assert_false(check_nvic_pending(EXTI0_IRQ));
377 
378     /*
379      * Testing interrupt line EXTI35
380      * Bit 3 in EXTI_*2 registers (EXTI35) corresponds to PVM 1 Wakeup
381      */
382 
383     enable_nvic_irq(EXTI35_IRQ);
384     /* Check that there are no interrupts already pending in PR */
385     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000000);
386     /* Check that this specific interrupt isn't pending in NVIC */
387     g_assert_false(check_nvic_pending(EXTI35_IRQ));
388 
389     /* Mask interrupt line EXTI35 */
390     exti_writel(EXTI_IMR2, 0x00000000);
391     /* Set the corresponding SWIER bit from '0' to '1' */
392     exti_writel(EXTI_SWIER2, 0x00000000);
393     exti_writel(EXTI_SWIER2, 0x00000008);
394 
395     /* Check that the write in SWIER was effective */
396     g_assert_cmphex(exti_readl(EXTI_SWIER2), ==, 0x00000008);
397     /* Check that the pending bit in PR wasn't set */
398     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000000);
399     /* Check that the interrupt isn't pending in NVIC */
400     g_assert_false(check_nvic_pending(EXTI35_IRQ));
401 
402     /* Enable interrupt line EXTI35 */
403     exti_writel(EXTI_IMR2, 0x00000008);
404 
405     /* Check that the pending bit in PR wasn't set */
406     g_assert_cmphex(exti_readl(EXTI_PR2), ==, 0x00000000);
407     /* Check that the interrupt isn't pending in NVIC */
408     g_assert_false(check_nvic_pending(EXTI35_IRQ));
409 }
410 
411 static void test_masked_interrupt(void)
412 {
413     /*
414      * Test that irq doesn't happen when :
415      * - corresponding bit in IMR isn't set
416      * - SWIER is set to 1 before IMR is set to 1
417      */
418 
419     /*
420      * Testing interrupt line EXTI1
421      * with rising edge from GPIOx pin 1
422      */
423 
424     enable_nvic_irq(EXTI1_IRQ);
425     /* Check that there are no interrupts already pending in PR */
426     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
427     /* Check that this specific interrupt isn't pending in NVIC */
428     g_assert_false(check_nvic_pending(EXTI1_IRQ));
429 
430     /* Mask interrupt line EXTI1 */
431     exti_writel(EXTI_IMR1, 0x00000000);
432 
433     /* Configure interrupt on rising edge */
434     exti_writel(EXTI_RTSR1, 0x00000002);
435 
436     /* Simulate rising edge from GPIO line 1 */
437     exti_set_irq(1, 1);
438 
439     /* Check that the pending bit in PR wasn't set */
440     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
441     /* Check that the interrupt isn't pending in NVIC */
442     g_assert_false(check_nvic_pending(EXTI1_IRQ));
443 
444     /* Enable interrupt line EXTI1 */
445     exti_writel(EXTI_IMR1, 0x00000002);
446 
447     /* Check that the pending bit in PR wasn't set */
448     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
449     /* Check that the interrupt isn't pending in NVIC */
450     g_assert_false(check_nvic_pending(EXTI1_IRQ));
451 
452     /* Clean EXTI */
453     exti_set_irq(1, 0);
454 }
455 
456 static void test_interrupt(void)
457 {
458     /*
459      * Test that we can launch an irq by :
460      * - enabling its line in IMR
461      * - configuring interrupt on rising edge
462      * - and then setting the input line from '0' to '1'
463      *
464      * And that the interruption stays pending in NVIC
465      * even after clearing the pending bit in PR.
466      */
467 
468     /*
469      * Testing interrupt line EXTI1
470      * with rising edge from GPIOx pin 1
471      */
472 
473     enable_nvic_irq(EXTI1_IRQ);
474     /* Check that there are no interrupts already pending in PR */
475     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
476     /* Check that this specific interrupt isn't pending in NVIC */
477     g_assert_false(check_nvic_pending(EXTI1_IRQ));
478 
479     /* Enable interrupt line EXTI1 */
480     exti_writel(EXTI_IMR1, 0x00000002);
481 
482     /* Configure interrupt on rising edge */
483     exti_writel(EXTI_RTSR1, 0x00000002);
484 
485     /* Simulate rising edge from GPIO line 1 */
486     exti_set_irq(1, 1);
487 
488     /* Check that the pending bit in PR was set */
489     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000002);
490     /* Check that the interrupt is pending in NVIC */
491     g_assert_true(check_nvic_pending(EXTI1_IRQ));
492 
493     /* Clear the pending bit in PR */
494     exti_writel(EXTI_PR1, 0x00000002);
495 
496     /* Check that the write in PR was effective */
497     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
498     /* Check that the interrupt is still pending in the NVIC */
499     g_assert_true(check_nvic_pending(EXTI1_IRQ));
500 
501     /* Clean NVIC */
502     unpend_nvic_irq(EXTI1_IRQ);
503     g_assert_false(check_nvic_pending(EXTI1_IRQ));
504 
505     /* Clean EXTI */
506     exti_set_irq(1, 0);
507 }
508 
509 static void test_orred_interrupts(void)
510 {
511     /*
512      * For lines EXTI5..9 (fanned-in to NVIC irq 23),
513      * test that raising the line pends interrupt
514      * 23 in NVIC.
515      */
516     enable_nvic_irq(EXTI5_9_IRQ);
517     /* Check that there are no interrupts already pending in PR */
518     g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
519     /* Check that this specific interrupt isn't pending in NVIC */
520     g_assert_false(check_nvic_pending(EXTI5_9_IRQ));
521 
522     /* Enable interrupt lines EXTI[5..9] */
523     exti_writel(EXTI_IMR1, (0x1F << 5));
524 
525     /* Configure interrupt on rising edge */
526     exti_writel(EXTI_RTSR1, (0x1F << 5));
527 
528     /* Raise GPIO line i, check that the interrupt is pending */
529     for (unsigned i = 5; i < 10; i++) {
530         exti_set_irq(i, 1);
531         g_assert_cmphex(exti_readl(EXTI_PR1), ==, 1 << i);
532         g_assert_true(check_nvic_pending(EXTI5_9_IRQ));
533 
534         exti_writel(EXTI_PR1, 1 << i);
535         g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
536         g_assert_true(check_nvic_pending(EXTI5_9_IRQ));
537 
538         unpend_nvic_irq(EXTI5_9_IRQ);
539         g_assert_false(check_nvic_pending(EXTI5_9_IRQ));
540 
541         exti_set_irq(i, 0);
542     }
543 }
544 
545 int main(int argc, char **argv)
546 {
547     int ret;
548 
549     g_test_init(&argc, &argv, NULL);
550     g_test_set_nonfatal_assertions();
551     qtest_add_func("stm32l4x5/exti/direct_lines", test_direct_lines_write);
552     qtest_add_func("stm32l4x5/exti/reserved_bits", test_reserved_bits_write);
553     qtest_add_func("stm32l4x5/exti/reg_write_read", test_reg_write_read);
554     qtest_add_func("stm32l4x5/exti/no_software_interrupt",
555                    test_no_software_interrupt);
556     qtest_add_func("stm32l4x5/exti/software_interrupt",
557                    test_software_interrupt);
558     qtest_add_func("stm32l4x5/exti/masked_interrupt", test_masked_interrupt);
559     qtest_add_func("stm32l4x5/exti/interrupt", test_interrupt);
560     qtest_add_func("stm32l4x5/exti/test_edge_selector", test_edge_selector);
561     qtest_add_func("stm32l4x5/exti/test_orred_interrupts",
562                    test_orred_interrupts);
563 
564     qtest_start("-machine b-l475e-iot01a");
565     ret = g_test_run();
566     qtest_end();
567 
568     return ret;
569 }
570