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