xref: /qemu/tests/qtest/stm32l4x5_syscfg-test.c (revision 70ce076fa6dff60585c229a4b641b13e64bf03cf)
1 /*
2  * QTest testcase for STM32L4x5_SYSCFG
3  *
4  * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5  * Copyright (c) 2024 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 #include "stm32l4x5.h"
14 
15 #define SYSCFG_BASE_ADDR 0x40010000
16 #define SYSCFG_MEMRMP 0x00
17 #define SYSCFG_CFGR1 0x04
18 #define SYSCFG_EXTICR1 0x08
19 #define SYSCFG_EXTICR2 0x0C
20 #define SYSCFG_EXTICR3 0x10
21 #define SYSCFG_EXTICR4 0x14
22 #define SYSCFG_SCSR 0x18
23 #define SYSCFG_CFGR2 0x1C
24 #define SYSCFG_SWPR 0x20
25 #define SYSCFG_SKR 0x24
26 #define SYSCFG_SWPR2 0x28
27 #define INVALID_ADDR 0x2C
28 
29 /* SoC forwards GPIOs to SysCfg */
30 #define SOC "/machine/soc"
31 #define SYSCFG "/machine/soc/syscfg"
32 #define SYSCFG_CLK "/machine/soc/syscfg/clk"
33 #define EXTI "/machine/soc/exti"
34 
35 static void syscfg_writel(unsigned int offset, uint32_t value)
36 {
37     writel(SYSCFG_BASE_ADDR + offset, value);
38 }
39 
40 static uint32_t syscfg_readl(unsigned int offset)
41 {
42     return readl(SYSCFG_BASE_ADDR + offset);
43 }
44 
45 static void syscfg_set_irq(int num, int level)
46 {
47    qtest_set_irq_in(global_qtest, SOC, NULL, num, level);
48 }
49 
50 static void test_reset(void)
51 {
52     /*
53      * Test that registers are initialized at the correct values
54      */
55     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000);
56 
57     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001);
58 
59     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000);
60 
61     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000);
62 
63     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000);
64 
65     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000);
66 
67     g_assert_cmphex(syscfg_readl(SYSCFG_SCSR), ==, 0x00000000);
68 
69     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000);
70 
71     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0x00000000);
72 
73     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000);
74 
75     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0x00000000);
76 }
77 
78 static void test_reserved_bits(void)
79 {
80     /*
81      * Test that reserved bits stay at reset value
82      * (which is 0 for all of them) by writing '1'
83      * in all reserved bits (keeping reset value for
84      * other bits) and checking that the
85      * register is still at reset value
86      */
87     syscfg_writel(SYSCFG_MEMRMP, 0xFFFFFEF8);
88     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000);
89 
90     syscfg_writel(SYSCFG_CFGR1, 0x7F00FEFF);
91     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001);
92 
93     syscfg_writel(SYSCFG_EXTICR1, 0xFFFF0000);
94     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000);
95 
96     syscfg_writel(SYSCFG_EXTICR2, 0xFFFF0000);
97     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000);
98 
99     syscfg_writel(SYSCFG_EXTICR3, 0xFFFF0000);
100     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000);
101 
102     syscfg_writel(SYSCFG_EXTICR4, 0xFFFF0000);
103     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000);
104 
105     syscfg_writel(SYSCFG_SKR, 0xFFFFFF00);
106     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000);
107 }
108 
109 static void test_set_and_clear(void)
110 {
111     /*
112      * Test that regular bits can be set and cleared
113      */
114     syscfg_writel(SYSCFG_MEMRMP, 0x00000107);
115     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000107);
116     syscfg_writel(SYSCFG_MEMRMP, 0x00000000);
117     g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000);
118 
119     /* cfgr1 bit 0 is clear only so we keep it set */
120     syscfg_writel(SYSCFG_CFGR1, 0xFCFF0101);
121     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0xFCFF0101);
122     syscfg_writel(SYSCFG_CFGR1, 0x00000001);
123     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000001);
124 
125     syscfg_writel(SYSCFG_EXTICR1, 0x0000FFFF);
126     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x0000FFFF);
127     syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
128     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000);
129 
130     syscfg_writel(SYSCFG_EXTICR2, 0x0000FFFF);
131     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x0000FFFF);
132     syscfg_writel(SYSCFG_EXTICR2, 0x00000000);
133     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000);
134 
135     syscfg_writel(SYSCFG_EXTICR3, 0x0000FFFF);
136     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x0000FFFF);
137     syscfg_writel(SYSCFG_EXTICR3, 0x00000000);
138     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000);
139 
140     syscfg_writel(SYSCFG_EXTICR4, 0x0000FFFF);
141     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x0000FFFF);
142     syscfg_writel(SYSCFG_EXTICR4, 0x00000000);
143     g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000);
144 
145     syscfg_writel(SYSCFG_SKR, 0x000000FF);
146     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x000000FF);
147     syscfg_writel(SYSCFG_SKR, 0x00000000);
148     g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000);
149 }
150 
151 static void test_clear_by_writing_1(void)
152 {
153     /*
154      * Test that writing '1' doesn't set the bit
155      */
156     syscfg_writel(SYSCFG_CFGR2, 0x00000100);
157     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000);
158 }
159 
160 static void test_set_only_bits(void)
161 {
162     /*
163      * Test that set only bits stay can't be cleared
164      */
165     syscfg_writel(SYSCFG_CFGR2, 0x0000000F);
166     syscfg_writel(SYSCFG_CFGR2, 0x00000000);
167     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x0000000F);
168 
169     syscfg_writel(SYSCFG_SWPR, 0xFFFFFFFF);
170     syscfg_writel(SYSCFG_SWPR, 0x00000000);
171     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0xFFFFFFFF);
172 
173     syscfg_writel(SYSCFG_SWPR2, 0xFFFFFFFF);
174     syscfg_writel(SYSCFG_SWPR2, 0x00000000);
175     g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0xFFFFFFFF);
176 
177     qtest_system_reset(global_qtest);
178 }
179 
180 static void test_clear_only_bits(void)
181 {
182     /*
183      * Test that clear only bits stay can't be set
184      */
185     syscfg_writel(SYSCFG_CFGR1, 0x00000000);
186     syscfg_writel(SYSCFG_CFGR1, 0x00000001);
187     g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000000);
188 
189     qtest_system_reset(global_qtest);
190 }
191 
192 static void test_interrupt(void)
193 {
194     /*
195      * Test that GPIO rising lines result in an irq
196      * with the right configuration
197      */
198     qtest_irq_intercept_in(global_qtest, EXTI);
199 
200     /* GPIOA is the default source for EXTI lines 0 to 15 */
201 
202     syscfg_set_irq(0, 1);
203 
204     g_assert_true(get_irq(0));
205 
206 
207     syscfg_set_irq(15, 1);
208 
209     g_assert_true(get_irq(15));
210 
211     /* Configure GPIOB[1] as the source input for EXTI1 */
212     syscfg_writel(SYSCFG_EXTICR1, 0x00000010);
213 
214     syscfg_set_irq(17, 1);
215 
216     g_assert_true(get_irq(1));
217 
218     /* Clean the test */
219     syscfg_set_irq(0, 0);
220     /* irq 15 is high at reset because GPIOA15 is high at reset */
221     syscfg_set_irq(17, 0);
222     syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
223 }
224 
225 static void test_irq_pin_multiplexer(void)
226 {
227     /*
228      * Test that syscfg irq sets the right exti irq
229      */
230 
231     qtest_irq_intercept_in(global_qtest, EXTI);
232 
233     syscfg_set_irq(0, 1);
234 
235     /* Check that irq 0 was set and irq 2 wasn't */
236     g_assert_true(get_irq(0));
237     g_assert_false(get_irq(2));
238 
239     /* Clean the test */
240     syscfg_set_irq(0, 0);
241 
242     syscfg_set_irq(2, 1);
243 
244     /* Check that irq 2 was set and irq 0 wasn't */
245     g_assert_true(get_irq(2));
246     g_assert_false(get_irq(0));
247 
248     /* Clean the test */
249     syscfg_set_irq(2, 0);
250 }
251 
252 static void test_irq_gpio_multiplexer(void)
253 {
254     /*
255      * Test that an irq is generated only by the right GPIO
256      */
257 
258     qtest_irq_intercept_in(global_qtest, EXTI);
259 
260     /* GPIOA is the default source for EXTI lines 0 to 15 */
261 
262     /* Check that setting rising pin GPIOA[0] generates an irq */
263     syscfg_set_irq(0, 1);
264 
265     g_assert_true(get_irq(0));
266 
267     /* Clean the test */
268     syscfg_set_irq(0, 0);
269 
270     /* Check that setting rising pin GPIOB[0] doesn't generate an irq */
271     syscfg_set_irq(16, 1);
272 
273     g_assert_false(get_irq(0));
274 
275     /* Clean the test */
276     syscfg_set_irq(16, 0);
277 
278     /* Configure GPIOB[0] as the source input for EXTI0 */
279     syscfg_writel(SYSCFG_EXTICR1, 0x00000001);
280 
281     /* Check that setting rising pin GPIOA[0] doesn't generate an irq */
282     syscfg_set_irq(0, 1);
283 
284     g_assert_false(get_irq(0));
285 
286     /* Clean the test */
287     syscfg_set_irq(0, 0);
288 
289     /* Check that setting rising pin GPIOB[0] generates an irq */
290     syscfg_set_irq(16, 1);
291 
292     g_assert_true(get_irq(0));
293 
294     /* Clean the test */
295     syscfg_set_irq(16, 0);
296     syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
297 }
298 
299 static void test_clock_enable(void)
300 {
301     g_assert_cmpuint(get_clock_period(global_qtest, SYSCFG_CLK), ==, 0);
302 
303     /* Enable SYSCFG clock */
304     writel(RCC_APB2ENR, readl(RCC_APB2ENR) | (0x1 << 0));
305 
306     g_assert_cmpuint(get_clock_period(global_qtest, SYSCFG_CLK), ==,
307                                        SYSCLK_PERIOD);
308 }
309 
310 int main(int argc, char **argv)
311 {
312     int ret;
313 
314     g_test_init(&argc, &argv, NULL);
315     g_test_set_nonfatal_assertions();
316 
317     qtest_add_func("stm32l4x5/syscfg/test_reset", test_reset);
318     qtest_add_func("stm32l4x5/syscfg/test_reserved_bits",
319                    test_reserved_bits);
320     qtest_add_func("stm32l4x5/syscfg/test_set_and_clear",
321                    test_set_and_clear);
322     qtest_add_func("stm32l4x5/syscfg/test_clear_by_writing_1",
323                    test_clear_by_writing_1);
324     qtest_add_func("stm32l4x5/syscfg/test_set_only_bits",
325                    test_set_only_bits);
326     qtest_add_func("stm32l4x5/syscfg/test_clear_only_bits",
327                    test_clear_only_bits);
328     qtest_add_func("stm32l4x5/syscfg/test_interrupt",
329                    test_interrupt);
330     qtest_add_func("stm32l4x5/syscfg/test_irq_pin_multiplexer",
331                    test_irq_pin_multiplexer);
332     qtest_add_func("stm32l4x5/syscfg/test_irq_gpio_multiplexer",
333                    test_irq_gpio_multiplexer);
334     qtest_add_func("stm32l4x5/syscfg/test_clock_enable",
335                    test_clock_enable);
336 
337     qtest_start("-machine b-l475e-iot01a");
338     ret = g_test_run();
339     qtest_end();
340 
341     return ret;
342 }
343