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