xref: /qemu/tests/qtest/stm32l4x5_syscfg-test.c (revision 5b5b014b32458d68b69fe08e31e4d7b2c570836a)
1a96bff61SInès Varhol /*
2a96bff61SInès Varhol  * QTest testcase for STM32L4x5_SYSCFG
3a96bff61SInès Varhol  *
4*5b5b014bSInès Varhol  * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5*5b5b014bSInès Varhol  * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
6a96bff61SInès Varhol  *
7a96bff61SInès Varhol  * This work is licensed under the terms of the GNU GPL, version 2 or later.
8a96bff61SInès Varhol  * See the COPYING file in the top-level directory.
9a96bff61SInès Varhol  */
10a96bff61SInès Varhol 
11a96bff61SInès Varhol #include "qemu/osdep.h"
12a96bff61SInès Varhol #include "libqtest-single.h"
13a96bff61SInès Varhol 
14a96bff61SInès Varhol #define SYSCFG_BASE_ADDR 0x40010000
15a96bff61SInès Varhol #define SYSCFG_MEMRMP 0x00
16a96bff61SInès Varhol #define SYSCFG_CFGR1 0x04
17a96bff61SInès Varhol #define SYSCFG_EXTICR1 0x08
18a96bff61SInès Varhol #define SYSCFG_EXTICR2 0x0C
19a96bff61SInès Varhol #define SYSCFG_EXTICR3 0x10
20a96bff61SInès Varhol #define SYSCFG_EXTICR4 0x14
21a96bff61SInès Varhol #define SYSCFG_SCSR 0x18
22a96bff61SInès Varhol #define SYSCFG_CFGR2 0x1C
23a96bff61SInès Varhol #define SYSCFG_SWPR 0x20
24a96bff61SInès Varhol #define SYSCFG_SKR 0x24
25a96bff61SInès Varhol #define SYSCFG_SWPR2 0x28
26a96bff61SInès Varhol #define INVALID_ADDR 0x2C
27a96bff61SInès Varhol 
28*5b5b014bSInès Varhol /* SoC forwards GPIOs to SysCfg */
29*5b5b014bSInès Varhol #define SYSCFG "/machine/soc"
30*5b5b014bSInès Varhol #define EXTI "/machine/soc/exti"
31*5b5b014bSInès Varhol 
32a96bff61SInès Varhol static void syscfg_writel(unsigned int offset, uint32_t value)
33a96bff61SInès Varhol {
34a96bff61SInès Varhol     writel(SYSCFG_BASE_ADDR + offset, value);
35a96bff61SInès Varhol }
36a96bff61SInès Varhol 
37a96bff61SInès Varhol static uint32_t syscfg_readl(unsigned int offset)
38a96bff61SInès Varhol {
39a96bff61SInès Varhol     return readl(SYSCFG_BASE_ADDR + offset);
40a96bff61SInès Varhol }
41a96bff61SInès Varhol 
42a96bff61SInès Varhol static void syscfg_set_irq(int num, int level)
43a96bff61SInès Varhol {
44*5b5b014bSInès Varhol    qtest_set_irq_in(global_qtest, SYSCFG, NULL, num, level);
45a96bff61SInès Varhol }
46a96bff61SInès Varhol 
47a96bff61SInès Varhol static void system_reset(void)
48a96bff61SInès Varhol {
49a96bff61SInès Varhol     QDict *response;
50a96bff61SInès Varhol     response = qtest_qmp(global_qtest, "{'execute': 'system_reset'}");
51a96bff61SInès Varhol     g_assert(qdict_haskey(response, "return"));
52a96bff61SInès Varhol     qobject_unref(response);
53a96bff61SInès Varhol }
54a96bff61SInès Varhol 
55a96bff61SInès Varhol static void test_reset(void)
56a96bff61SInès Varhol {
57a96bff61SInès Varhol     /*
58a96bff61SInès Varhol      * Test that registers are initialized at the correct values
59a96bff61SInès Varhol      */
6058045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000);
61a96bff61SInès Varhol 
6258045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001);
63a96bff61SInès Varhol 
6458045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000);
65a96bff61SInès Varhol 
6658045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000);
67a96bff61SInès Varhol 
6858045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000);
69a96bff61SInès Varhol 
7058045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000);
71a96bff61SInès Varhol 
7258045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SCSR), ==, 0x00000000);
73a96bff61SInès Varhol 
7458045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000);
75a96bff61SInès Varhol 
7658045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0x00000000);
77a96bff61SInès Varhol 
7858045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000);
79a96bff61SInès Varhol 
8058045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0x00000000);
81a96bff61SInès Varhol }
82a96bff61SInès Varhol 
83a96bff61SInès Varhol static void test_reserved_bits(void)
84a96bff61SInès Varhol {
85a96bff61SInès Varhol     /*
86a96bff61SInès Varhol      * Test that reserved bits stay at reset value
87a96bff61SInès Varhol      * (which is 0 for all of them) by writing '1'
88a96bff61SInès Varhol      * in all reserved bits (keeping reset value for
89a96bff61SInès Varhol      * other bits) and checking that the
90a96bff61SInès Varhol      * register is still at reset value
91a96bff61SInès Varhol      */
92a96bff61SInès Varhol     syscfg_writel(SYSCFG_MEMRMP, 0xFFFFFEF8);
9358045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000);
94a96bff61SInès Varhol 
95a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR1, 0x7F00FEFF);
9658045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001);
97a96bff61SInès Varhol 
98a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR1, 0xFFFF0000);
9958045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000);
100a96bff61SInès Varhol 
101a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR2, 0xFFFF0000);
10258045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000);
103a96bff61SInès Varhol 
104a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR3, 0xFFFF0000);
10558045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000);
106a96bff61SInès Varhol 
107a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR4, 0xFFFF0000);
10858045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000);
109a96bff61SInès Varhol 
110a96bff61SInès Varhol     syscfg_writel(SYSCFG_SKR, 0xFFFFFF00);
11158045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000);
112a96bff61SInès Varhol }
113a96bff61SInès Varhol 
114a96bff61SInès Varhol static void test_set_and_clear(void)
115a96bff61SInès Varhol {
116a96bff61SInès Varhol     /*
117a96bff61SInès Varhol      * Test that regular bits can be set and cleared
118a96bff61SInès Varhol      */
119a96bff61SInès Varhol     syscfg_writel(SYSCFG_MEMRMP, 0x00000107);
12058045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000107);
121a96bff61SInès Varhol     syscfg_writel(SYSCFG_MEMRMP, 0x00000000);
12258045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000);
123a96bff61SInès Varhol 
124a96bff61SInès Varhol     /* cfgr1 bit 0 is clear only so we keep it set */
125a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR1, 0xFCFF0101);
12658045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0xFCFF0101);
127a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR1, 0x00000001);
12858045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000001);
129a96bff61SInès Varhol 
130a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR1, 0x0000FFFF);
13158045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x0000FFFF);
132a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
13358045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000);
134a96bff61SInès Varhol 
135a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR2, 0x0000FFFF);
13658045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x0000FFFF);
137a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR2, 0x00000000);
13858045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000);
139a96bff61SInès Varhol 
140a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR3, 0x0000FFFF);
14158045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x0000FFFF);
142a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR3, 0x00000000);
14358045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000);
144a96bff61SInès Varhol 
145a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR4, 0x0000FFFF);
14658045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x0000FFFF);
147a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR4, 0x00000000);
14858045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000);
149a96bff61SInès Varhol 
150a96bff61SInès Varhol     syscfg_writel(SYSCFG_SKR, 0x000000FF);
15158045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x000000FF);
152a96bff61SInès Varhol     syscfg_writel(SYSCFG_SKR, 0x00000000);
15358045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000);
154a96bff61SInès Varhol }
155a96bff61SInès Varhol 
156a96bff61SInès Varhol static void test_clear_by_writing_1(void)
157a96bff61SInès Varhol {
158a96bff61SInès Varhol     /*
159a96bff61SInès Varhol      * Test that writing '1' doesn't set the bit
160a96bff61SInès Varhol      */
161a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR2, 0x00000100);
16258045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000);
163a96bff61SInès Varhol }
164a96bff61SInès Varhol 
165a96bff61SInès Varhol static void test_set_only_bits(void)
166a96bff61SInès Varhol {
167a96bff61SInès Varhol     /*
168a96bff61SInès Varhol      * Test that set only bits stay can't be cleared
169a96bff61SInès Varhol      */
170a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR2, 0x0000000F);
171a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR2, 0x00000000);
17258045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x0000000F);
173a96bff61SInès Varhol 
174a96bff61SInès Varhol     syscfg_writel(SYSCFG_SWPR, 0xFFFFFFFF);
175a96bff61SInès Varhol     syscfg_writel(SYSCFG_SWPR, 0x00000000);
17658045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0xFFFFFFFF);
177a96bff61SInès Varhol 
178a96bff61SInès Varhol     syscfg_writel(SYSCFG_SWPR2, 0xFFFFFFFF);
179a96bff61SInès Varhol     syscfg_writel(SYSCFG_SWPR2, 0x00000000);
18058045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0xFFFFFFFF);
181a96bff61SInès Varhol 
182a96bff61SInès Varhol     system_reset();
183a96bff61SInès Varhol }
184a96bff61SInès Varhol 
185a96bff61SInès Varhol static void test_clear_only_bits(void)
186a96bff61SInès Varhol {
187a96bff61SInès Varhol     /*
188a96bff61SInès Varhol      * Test that clear only bits stay can't be set
189a96bff61SInès Varhol      */
190a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR1, 0x00000000);
191a96bff61SInès Varhol     syscfg_writel(SYSCFG_CFGR1, 0x00000001);
19258045186SInès Varhol     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000000);
193a96bff61SInès Varhol 
194a96bff61SInès Varhol     system_reset();
195a96bff61SInès Varhol }
196a96bff61SInès Varhol 
197a96bff61SInès Varhol static void test_interrupt(void)
198a96bff61SInès Varhol {
199a96bff61SInès Varhol     /*
200a96bff61SInès Varhol      * Test that GPIO rising lines result in an irq
201a96bff61SInès Varhol      * with the right configuration
202a96bff61SInès Varhol      */
203*5b5b014bSInès Varhol     qtest_irq_intercept_in(global_qtest, EXTI);
204a96bff61SInès Varhol 
205a96bff61SInès Varhol     /* GPIOA is the default source for EXTI lines 0 to 15 */
206a96bff61SInès Varhol 
207a96bff61SInès Varhol     syscfg_set_irq(0, 1);
208a96bff61SInès Varhol 
209a96bff61SInès Varhol     g_assert_true(get_irq(0));
210a96bff61SInès Varhol 
211a96bff61SInès Varhol 
212a96bff61SInès Varhol     syscfg_set_irq(15, 1);
213a96bff61SInès Varhol 
214a96bff61SInès Varhol     g_assert_true(get_irq(15));
215a96bff61SInès Varhol 
216a96bff61SInès Varhol     /* Configure GPIOB[1] as the source input for EXTI1 */
217a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR1, 0x00000010);
218a96bff61SInès Varhol 
219a96bff61SInès Varhol     syscfg_set_irq(17, 1);
220a96bff61SInès Varhol 
221a96bff61SInès Varhol     g_assert_true(get_irq(1));
222a96bff61SInès Varhol 
223a96bff61SInès Varhol     /* Clean the test */
224a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
225a96bff61SInès Varhol     syscfg_set_irq(0, 0);
226a96bff61SInès Varhol     syscfg_set_irq(15, 0);
227a96bff61SInès Varhol     syscfg_set_irq(17, 0);
228a96bff61SInès Varhol }
229a96bff61SInès Varhol 
230a96bff61SInès Varhol static void test_irq_pin_multiplexer(void)
231a96bff61SInès Varhol {
232a96bff61SInès Varhol     /*
233a96bff61SInès Varhol      * Test that syscfg irq sets the right exti irq
234a96bff61SInès Varhol      */
235a96bff61SInès Varhol 
236*5b5b014bSInès Varhol     qtest_irq_intercept_in(global_qtest, EXTI);
237a96bff61SInès Varhol 
238a96bff61SInès Varhol     syscfg_set_irq(0, 1);
239a96bff61SInès Varhol 
240a96bff61SInès Varhol     /* Check that irq 0 was set and irq 15 wasn't */
241a96bff61SInès Varhol     g_assert_true(get_irq(0));
242a96bff61SInès Varhol     g_assert_false(get_irq(15));
243a96bff61SInès Varhol 
244a96bff61SInès Varhol     /* Clean the test */
245a96bff61SInès Varhol     syscfg_set_irq(0, 0);
246a96bff61SInès Varhol 
247a96bff61SInès Varhol     syscfg_set_irq(15, 1);
248a96bff61SInès Varhol 
249a96bff61SInès Varhol     /* Check that irq 15 was set and irq 0 wasn't */
250a96bff61SInès Varhol     g_assert_true(get_irq(15));
251a96bff61SInès Varhol     g_assert_false(get_irq(0));
252a96bff61SInès Varhol 
253a96bff61SInès Varhol     /* Clean the test */
254a96bff61SInès Varhol     syscfg_set_irq(15, 0);
255a96bff61SInès Varhol }
256a96bff61SInès Varhol 
257a96bff61SInès Varhol static void test_irq_gpio_multiplexer(void)
258a96bff61SInès Varhol {
259a96bff61SInès Varhol     /*
260a96bff61SInès Varhol      * Test that an irq is generated only by the right GPIO
261a96bff61SInès Varhol      */
262a96bff61SInès Varhol 
263*5b5b014bSInès Varhol     qtest_irq_intercept_in(global_qtest, EXTI);
264a96bff61SInès Varhol 
265a96bff61SInès Varhol     /* GPIOA is the default source for EXTI lines 0 to 15 */
266a96bff61SInès Varhol 
267a96bff61SInès Varhol     /* Check that setting rising pin GPIOA[0] generates an irq */
268a96bff61SInès Varhol     syscfg_set_irq(0, 1);
269a96bff61SInès Varhol 
270a96bff61SInès Varhol     g_assert_true(get_irq(0));
271a96bff61SInès Varhol 
272a96bff61SInès Varhol     /* Clean the test */
273a96bff61SInès Varhol     syscfg_set_irq(0, 0);
274a96bff61SInès Varhol 
275a96bff61SInès Varhol     /* Check that setting rising pin GPIOB[0] doesn't generate an irq */
276a96bff61SInès Varhol     syscfg_set_irq(16, 1);
277a96bff61SInès Varhol 
278a96bff61SInès Varhol     g_assert_false(get_irq(0));
279a96bff61SInès Varhol 
280a96bff61SInès Varhol     /* Clean the test */
281a96bff61SInès Varhol     syscfg_set_irq(16, 0);
282a96bff61SInès Varhol 
283a96bff61SInès Varhol     /* Configure GPIOB[0] as the source input for EXTI0 */
284a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR1, 0x00000001);
285a96bff61SInès Varhol 
286a96bff61SInès Varhol     /* Check that setting rising pin GPIOA[0] doesn't generate an irq */
287a96bff61SInès Varhol     syscfg_set_irq(0, 1);
288a96bff61SInès Varhol 
289a96bff61SInès Varhol     g_assert_false(get_irq(0));
290a96bff61SInès Varhol 
291a96bff61SInès Varhol     /* Clean the test */
292a96bff61SInès Varhol     syscfg_set_irq(0, 0);
293a96bff61SInès Varhol 
294a96bff61SInès Varhol     /* Check that setting rising pin GPIOB[0] generates an irq */
295a96bff61SInès Varhol     syscfg_set_irq(16, 1);
296a96bff61SInès Varhol 
297a96bff61SInès Varhol     g_assert_true(get_irq(0));
298a96bff61SInès Varhol 
299a96bff61SInès Varhol     /* Clean the test */
300a96bff61SInès Varhol     syscfg_set_irq(16, 0);
301a96bff61SInès Varhol     syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
302a96bff61SInès Varhol }
303a96bff61SInès Varhol 
304a96bff61SInès Varhol int main(int argc, char **argv)
305a96bff61SInès Varhol {
306a96bff61SInès Varhol     int ret;
307a96bff61SInès Varhol 
308a96bff61SInès Varhol     g_test_init(&argc, &argv, NULL);
309a96bff61SInès Varhol     g_test_set_nonfatal_assertions();
310a96bff61SInès Varhol 
311a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_reset", test_reset);
312a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_reserved_bits",
313a96bff61SInès Varhol                    test_reserved_bits);
314a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_set_and_clear",
315a96bff61SInès Varhol                    test_set_and_clear);
316a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_clear_by_writing_1",
317a96bff61SInès Varhol                    test_clear_by_writing_1);
318a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_set_only_bits",
319a96bff61SInès Varhol                    test_set_only_bits);
320a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_clear_only_bits",
321a96bff61SInès Varhol                    test_clear_only_bits);
322a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_interrupt",
323a96bff61SInès Varhol                    test_interrupt);
324a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_irq_pin_multiplexer",
325a96bff61SInès Varhol                    test_irq_pin_multiplexer);
326a96bff61SInès Varhol     qtest_add_func("stm32l4x5/syscfg/test_irq_gpio_multiplexer",
327a96bff61SInès Varhol                    test_irq_gpio_multiplexer);
328a96bff61SInès Varhol 
329a96bff61SInès Varhol     qtest_start("-machine b-l475e-iot01a");
330a96bff61SInès Varhol     ret = g_test_run();
331a96bff61SInès Varhol     qtest_end();
332a96bff61SInès Varhol 
333a96bff61SInès Varhol     return ret;
334a96bff61SInès Varhol }
335