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