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