1a96bff61SInès Varhol /* 2a96bff61SInès Varhol * QTest testcase for STM32L4x5_SYSCFG 3a96bff61SInès Varhol * 4*5b5b014bSInès Varhol * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr> 5*5b5b014bSInès Varhol * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr> 6a96bff61SInès Varhol * 7a96bff61SInès Varhol * This work is licensed under the terms of the GNU GPL, version 2 or later. 8a96bff61SInès Varhol * See the COPYING file in the top-level directory. 9a96bff61SInès Varhol */ 10a96bff61SInès Varhol 11a96bff61SInès Varhol #include "qemu/osdep.h" 12a96bff61SInès Varhol #include "libqtest-single.h" 13a96bff61SInès Varhol 14a96bff61SInès Varhol #define SYSCFG_BASE_ADDR 0x40010000 15a96bff61SInès Varhol #define SYSCFG_MEMRMP 0x00 16a96bff61SInès Varhol #define SYSCFG_CFGR1 0x04 17a96bff61SInès Varhol #define SYSCFG_EXTICR1 0x08 18a96bff61SInès Varhol #define SYSCFG_EXTICR2 0x0C 19a96bff61SInès Varhol #define SYSCFG_EXTICR3 0x10 20a96bff61SInès Varhol #define SYSCFG_EXTICR4 0x14 21a96bff61SInès Varhol #define SYSCFG_SCSR 0x18 22a96bff61SInès Varhol #define SYSCFG_CFGR2 0x1C 23a96bff61SInès Varhol #define SYSCFG_SWPR 0x20 24a96bff61SInès Varhol #define SYSCFG_SKR 0x24 25a96bff61SInès Varhol #define SYSCFG_SWPR2 0x28 26a96bff61SInès Varhol #define INVALID_ADDR 0x2C 27a96bff61SInès Varhol 28*5b5b014bSInès Varhol /* SoC forwards GPIOs to SysCfg */ 29*5b5b014bSInès Varhol #define SYSCFG "/machine/soc" 30*5b5b014bSInès Varhol #define EXTI "/machine/soc/exti" 31*5b5b014bSInès Varhol 32a96bff61SInès Varhol static void syscfg_writel(unsigned int offset, uint32_t value) 33a96bff61SInès Varhol { 34a96bff61SInès Varhol writel(SYSCFG_BASE_ADDR + offset, value); 35a96bff61SInès Varhol } 36a96bff61SInès Varhol 37a96bff61SInès Varhol static uint32_t syscfg_readl(unsigned int offset) 38a96bff61SInès Varhol { 39a96bff61SInès Varhol return readl(SYSCFG_BASE_ADDR + offset); 40a96bff61SInès Varhol } 41a96bff61SInès Varhol 42a96bff61SInès Varhol static void syscfg_set_irq(int num, int level) 43a96bff61SInès Varhol { 44*5b5b014bSInès Varhol qtest_set_irq_in(global_qtest, SYSCFG, NULL, num, level); 45a96bff61SInès Varhol } 46a96bff61SInès Varhol 47a96bff61SInès Varhol static void system_reset(void) 48a96bff61SInès Varhol { 49a96bff61SInès Varhol QDict *response; 50a96bff61SInès Varhol response = qtest_qmp(global_qtest, "{'execute': 'system_reset'}"); 51a96bff61SInès Varhol g_assert(qdict_haskey(response, "return")); 52a96bff61SInès Varhol qobject_unref(response); 53a96bff61SInès Varhol } 54a96bff61SInès Varhol 55a96bff61SInès Varhol static void test_reset(void) 56a96bff61SInès Varhol { 57a96bff61SInès Varhol /* 58a96bff61SInès Varhol * Test that registers are initialized at the correct values 59a96bff61SInès Varhol */ 6058045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 61a96bff61SInès Varhol 6258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001); 63a96bff61SInès Varhol 6458045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 65a96bff61SInès Varhol 6658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 67a96bff61SInès Varhol 6858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 69a96bff61SInès Varhol 7058045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 71a96bff61SInès Varhol 7258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SCSR), ==, 0x00000000); 73a96bff61SInès Varhol 7458045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000); 75a96bff61SInès Varhol 7658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0x00000000); 77a96bff61SInès Varhol 7858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 79a96bff61SInès Varhol 8058045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0x00000000); 81a96bff61SInès Varhol } 82a96bff61SInès Varhol 83a96bff61SInès Varhol static void test_reserved_bits(void) 84a96bff61SInès Varhol { 85a96bff61SInès Varhol /* 86a96bff61SInès Varhol * Test that reserved bits stay at reset value 87a96bff61SInès Varhol * (which is 0 for all of them) by writing '1' 88a96bff61SInès Varhol * in all reserved bits (keeping reset value for 89a96bff61SInès Varhol * other bits) and checking that the 90a96bff61SInès Varhol * register is still at reset value 91a96bff61SInès Varhol */ 92a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0xFFFFFEF8); 9358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 94a96bff61SInès Varhol 95a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x7F00FEFF); 9658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001); 97a96bff61SInès Varhol 98a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0xFFFF0000); 9958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 100a96bff61SInès Varhol 101a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0xFFFF0000); 10258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 103a96bff61SInès Varhol 104a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0xFFFF0000); 10558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 106a96bff61SInès Varhol 107a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0xFFFF0000); 10858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 109a96bff61SInès Varhol 110a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0xFFFFFF00); 11158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 112a96bff61SInès Varhol } 113a96bff61SInès Varhol 114a96bff61SInès Varhol static void test_set_and_clear(void) 115a96bff61SInès Varhol { 116a96bff61SInès Varhol /* 117a96bff61SInès Varhol * Test that regular bits can be set and cleared 118a96bff61SInès Varhol */ 119a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0x00000107); 12058045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000107); 121a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0x00000000); 12258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 123a96bff61SInès Varhol 124a96bff61SInès Varhol /* cfgr1 bit 0 is clear only so we keep it set */ 125a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0xFCFF0101); 12658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0xFCFF0101); 127a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000001); 12858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000001); 129a96bff61SInès Varhol 130a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x0000FFFF); 13158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x0000FFFF); 132a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 13358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 134a96bff61SInès Varhol 135a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0x0000FFFF); 13658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x0000FFFF); 137a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0x00000000); 13858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 139a96bff61SInès Varhol 140a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0x0000FFFF); 14158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x0000FFFF); 142a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0x00000000); 14358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 144a96bff61SInès Varhol 145a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0x0000FFFF); 14658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x0000FFFF); 147a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0x00000000); 14858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 149a96bff61SInès Varhol 150a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0x000000FF); 15158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x000000FF); 152a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0x00000000); 15358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 154a96bff61SInès Varhol } 155a96bff61SInès Varhol 156a96bff61SInès Varhol static void test_clear_by_writing_1(void) 157a96bff61SInès Varhol { 158a96bff61SInès Varhol /* 159a96bff61SInès Varhol * Test that writing '1' doesn't set the bit 160a96bff61SInès Varhol */ 161a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x00000100); 16258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000); 163a96bff61SInès Varhol } 164a96bff61SInès Varhol 165a96bff61SInès Varhol static void test_set_only_bits(void) 166a96bff61SInès Varhol { 167a96bff61SInès Varhol /* 168a96bff61SInès Varhol * Test that set only bits stay can't be cleared 169a96bff61SInès Varhol */ 170a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x0000000F); 171a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x00000000); 17258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x0000000F); 173a96bff61SInès Varhol 174a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR, 0xFFFFFFFF); 175a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR, 0x00000000); 17658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0xFFFFFFFF); 177a96bff61SInès Varhol 178a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR2, 0xFFFFFFFF); 179a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR2, 0x00000000); 18058045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0xFFFFFFFF); 181a96bff61SInès Varhol 182a96bff61SInès Varhol system_reset(); 183a96bff61SInès Varhol } 184a96bff61SInès Varhol 185a96bff61SInès Varhol static void test_clear_only_bits(void) 186a96bff61SInès Varhol { 187a96bff61SInès Varhol /* 188a96bff61SInès Varhol * Test that clear only bits stay can't be set 189a96bff61SInès Varhol */ 190a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000000); 191a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000001); 19258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000000); 193a96bff61SInès Varhol 194a96bff61SInès Varhol system_reset(); 195a96bff61SInès Varhol } 196a96bff61SInès Varhol 197a96bff61SInès Varhol static void test_interrupt(void) 198a96bff61SInès Varhol { 199a96bff61SInès Varhol /* 200a96bff61SInès Varhol * Test that GPIO rising lines result in an irq 201a96bff61SInès Varhol * with the right configuration 202a96bff61SInès Varhol */ 203*5b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 204a96bff61SInès Varhol 205a96bff61SInès Varhol /* GPIOA is the default source for EXTI lines 0 to 15 */ 206a96bff61SInès Varhol 207a96bff61SInès Varhol syscfg_set_irq(0, 1); 208a96bff61SInès Varhol 209a96bff61SInès Varhol g_assert_true(get_irq(0)); 210a96bff61SInès Varhol 211a96bff61SInès Varhol 212a96bff61SInès Varhol syscfg_set_irq(15, 1); 213a96bff61SInès Varhol 214a96bff61SInès Varhol g_assert_true(get_irq(15)); 215a96bff61SInès Varhol 216a96bff61SInès Varhol /* Configure GPIOB[1] as the source input for EXTI1 */ 217a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000010); 218a96bff61SInès Varhol 219a96bff61SInès Varhol syscfg_set_irq(17, 1); 220a96bff61SInès Varhol 221a96bff61SInès Varhol g_assert_true(get_irq(1)); 222a96bff61SInès Varhol 223a96bff61SInès Varhol /* Clean the test */ 224a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 225a96bff61SInès Varhol syscfg_set_irq(0, 0); 226a96bff61SInès Varhol syscfg_set_irq(15, 0); 227a96bff61SInès Varhol syscfg_set_irq(17, 0); 228a96bff61SInès Varhol } 229a96bff61SInès Varhol 230a96bff61SInès Varhol static void test_irq_pin_multiplexer(void) 231a96bff61SInès Varhol { 232a96bff61SInès Varhol /* 233a96bff61SInès Varhol * Test that syscfg irq sets the right exti irq 234a96bff61SInès Varhol */ 235a96bff61SInès Varhol 236*5b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 237a96bff61SInès Varhol 238a96bff61SInès Varhol syscfg_set_irq(0, 1); 239a96bff61SInès Varhol 240a96bff61SInès Varhol /* Check that irq 0 was set and irq 15 wasn't */ 241a96bff61SInès Varhol g_assert_true(get_irq(0)); 242a96bff61SInès Varhol g_assert_false(get_irq(15)); 243a96bff61SInès Varhol 244a96bff61SInès Varhol /* Clean the test */ 245a96bff61SInès Varhol syscfg_set_irq(0, 0); 246a96bff61SInès Varhol 247a96bff61SInès Varhol syscfg_set_irq(15, 1); 248a96bff61SInès Varhol 249a96bff61SInès Varhol /* Check that irq 15 was set and irq 0 wasn't */ 250a96bff61SInès Varhol g_assert_true(get_irq(15)); 251a96bff61SInès Varhol g_assert_false(get_irq(0)); 252a96bff61SInès Varhol 253a96bff61SInès Varhol /* Clean the test */ 254a96bff61SInès Varhol syscfg_set_irq(15, 0); 255a96bff61SInès Varhol } 256a96bff61SInès Varhol 257a96bff61SInès Varhol static void test_irq_gpio_multiplexer(void) 258a96bff61SInès Varhol { 259a96bff61SInès Varhol /* 260a96bff61SInès Varhol * Test that an irq is generated only by the right GPIO 261a96bff61SInès Varhol */ 262a96bff61SInès Varhol 263*5b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 264a96bff61SInès Varhol 265a96bff61SInès Varhol /* GPIOA is the default source for EXTI lines 0 to 15 */ 266a96bff61SInès Varhol 267a96bff61SInès Varhol /* Check that setting rising pin GPIOA[0] generates an irq */ 268a96bff61SInès Varhol syscfg_set_irq(0, 1); 269a96bff61SInès Varhol 270a96bff61SInès Varhol g_assert_true(get_irq(0)); 271a96bff61SInès Varhol 272a96bff61SInès Varhol /* Clean the test */ 273a96bff61SInès Varhol syscfg_set_irq(0, 0); 274a96bff61SInès Varhol 275a96bff61SInès Varhol /* Check that setting rising pin GPIOB[0] doesn't generate an irq */ 276a96bff61SInès Varhol syscfg_set_irq(16, 1); 277a96bff61SInès Varhol 278a96bff61SInès Varhol g_assert_false(get_irq(0)); 279a96bff61SInès Varhol 280a96bff61SInès Varhol /* Clean the test */ 281a96bff61SInès Varhol syscfg_set_irq(16, 0); 282a96bff61SInès Varhol 283a96bff61SInès Varhol /* Configure GPIOB[0] as the source input for EXTI0 */ 284a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000001); 285a96bff61SInès Varhol 286a96bff61SInès Varhol /* Check that setting rising pin GPIOA[0] doesn't generate an irq */ 287a96bff61SInès Varhol syscfg_set_irq(0, 1); 288a96bff61SInès Varhol 289a96bff61SInès Varhol g_assert_false(get_irq(0)); 290a96bff61SInès Varhol 291a96bff61SInès Varhol /* Clean the test */ 292a96bff61SInès Varhol syscfg_set_irq(0, 0); 293a96bff61SInès Varhol 294a96bff61SInès Varhol /* Check that setting rising pin GPIOB[0] generates an irq */ 295a96bff61SInès Varhol syscfg_set_irq(16, 1); 296a96bff61SInès Varhol 297a96bff61SInès Varhol g_assert_true(get_irq(0)); 298a96bff61SInès Varhol 299a96bff61SInès Varhol /* Clean the test */ 300a96bff61SInès Varhol syscfg_set_irq(16, 0); 301a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 302a96bff61SInès Varhol } 303a96bff61SInès Varhol 304a96bff61SInès Varhol int main(int argc, char **argv) 305a96bff61SInès Varhol { 306a96bff61SInès Varhol int ret; 307a96bff61SInès Varhol 308a96bff61SInès Varhol g_test_init(&argc, &argv, NULL); 309a96bff61SInès Varhol g_test_set_nonfatal_assertions(); 310a96bff61SInès Varhol 311a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_reset", test_reset); 312a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_reserved_bits", 313a96bff61SInès Varhol test_reserved_bits); 314a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_set_and_clear", 315a96bff61SInès Varhol test_set_and_clear); 316a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clear_by_writing_1", 317a96bff61SInès Varhol test_clear_by_writing_1); 318a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_set_only_bits", 319a96bff61SInès Varhol test_set_only_bits); 320a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clear_only_bits", 321a96bff61SInès Varhol test_clear_only_bits); 322a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_interrupt", 323a96bff61SInès Varhol test_interrupt); 324a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_irq_pin_multiplexer", 325a96bff61SInès Varhol test_irq_pin_multiplexer); 326a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_irq_gpio_multiplexer", 327a96bff61SInès Varhol test_irq_gpio_multiplexer); 328a96bff61SInès Varhol 329a96bff61SInès Varhol qtest_start("-machine b-l475e-iot01a"); 330a96bff61SInès Varhol ret = g_test_run(); 331a96bff61SInès Varhol qtest_end(); 332a96bff61SInès Varhol 333a96bff61SInès Varhol return ret; 334a96bff61SInès Varhol } 335