1a96bff61SInès Varhol /* 2a96bff61SInès Varhol * QTest testcase for STM32L4x5_SYSCFG 3a96bff61SInès Varhol * 45b5b014bSInès Varhol * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr> 55b5b014bSInè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" 13*88446cfeSInès Varhol #include "stm32l4x5.h" 14a96bff61SInès Varhol 15a96bff61SInès Varhol #define SYSCFG_BASE_ADDR 0x40010000 16a96bff61SInès Varhol #define SYSCFG_MEMRMP 0x00 17a96bff61SInès Varhol #define SYSCFG_CFGR1 0x04 18a96bff61SInès Varhol #define SYSCFG_EXTICR1 0x08 19a96bff61SInès Varhol #define SYSCFG_EXTICR2 0x0C 20a96bff61SInès Varhol #define SYSCFG_EXTICR3 0x10 21a96bff61SInès Varhol #define SYSCFG_EXTICR4 0x14 22a96bff61SInès Varhol #define SYSCFG_SCSR 0x18 23a96bff61SInès Varhol #define SYSCFG_CFGR2 0x1C 24a96bff61SInès Varhol #define SYSCFG_SWPR 0x20 25a96bff61SInès Varhol #define SYSCFG_SKR 0x24 26a96bff61SInès Varhol #define SYSCFG_SWPR2 0x28 27a96bff61SInès Varhol #define INVALID_ADDR 0x2C 28a96bff61SInès Varhol 295b5b014bSInès Varhol /* SoC forwards GPIOs to SysCfg */ 30*88446cfeSInès Varhol #define SOC "/machine/soc" 31*88446cfeSInès Varhol #define SYSCFG "/machine/soc/syscfg" 32*88446cfeSInès Varhol #define SYSCFG_CLK "/machine/soc/syscfg/clk" 335b5b014bSInès Varhol #define EXTI "/machine/soc/exti" 345b5b014bSInès Varhol 35a96bff61SInès Varhol static void syscfg_writel(unsigned int offset, uint32_t value) 36a96bff61SInès Varhol { 37a96bff61SInès Varhol writel(SYSCFG_BASE_ADDR + offset, value); 38a96bff61SInès Varhol } 39a96bff61SInès Varhol 40a96bff61SInès Varhol static uint32_t syscfg_readl(unsigned int offset) 41a96bff61SInès Varhol { 42a96bff61SInès Varhol return readl(SYSCFG_BASE_ADDR + offset); 43a96bff61SInès Varhol } 44a96bff61SInès Varhol 45a96bff61SInès Varhol static void syscfg_set_irq(int num, int level) 46a96bff61SInès Varhol { 47*88446cfeSInès Varhol qtest_set_irq_in(global_qtest, SOC, NULL, num, level); 48a96bff61SInès Varhol } 49a96bff61SInès Varhol 50a96bff61SInès Varhol static void system_reset(void) 51a96bff61SInès Varhol { 52a96bff61SInès Varhol QDict *response; 53a96bff61SInès Varhol response = qtest_qmp(global_qtest, "{'execute': 'system_reset'}"); 54a96bff61SInès Varhol g_assert(qdict_haskey(response, "return")); 55a96bff61SInès Varhol qobject_unref(response); 56a96bff61SInès Varhol } 57a96bff61SInès Varhol 58a96bff61SInès Varhol static void test_reset(void) 59a96bff61SInès Varhol { 60a96bff61SInès Varhol /* 61a96bff61SInès Varhol * Test that registers are initialized at the correct values 62a96bff61SInès Varhol */ 6358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 64a96bff61SInès Varhol 6558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001); 66a96bff61SInès Varhol 6758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 68a96bff61SInès Varhol 6958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 70a96bff61SInès Varhol 7158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 72a96bff61SInès Varhol 7358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 74a96bff61SInès Varhol 7558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SCSR), ==, 0x00000000); 76a96bff61SInès Varhol 7758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000); 78a96bff61SInès Varhol 7958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0x00000000); 80a96bff61SInès Varhol 8158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 82a96bff61SInès Varhol 8358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0x00000000); 84a96bff61SInès Varhol } 85a96bff61SInès Varhol 86a96bff61SInès Varhol static void test_reserved_bits(void) 87a96bff61SInès Varhol { 88a96bff61SInès Varhol /* 89a96bff61SInès Varhol * Test that reserved bits stay at reset value 90a96bff61SInès Varhol * (which is 0 for all of them) by writing '1' 91a96bff61SInès Varhol * in all reserved bits (keeping reset value for 92a96bff61SInès Varhol * other bits) and checking that the 93a96bff61SInès Varhol * register is still at reset value 94a96bff61SInès Varhol */ 95a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0xFFFFFEF8); 9658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 97a96bff61SInès Varhol 98a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x7F00FEFF); 9958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001); 100a96bff61SInès Varhol 101a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0xFFFF0000); 10258045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 103a96bff61SInès Varhol 104a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0xFFFF0000); 10558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 106a96bff61SInès Varhol 107a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0xFFFF0000); 10858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 109a96bff61SInès Varhol 110a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0xFFFF0000); 11158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 112a96bff61SInès Varhol 113a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0xFFFFFF00); 11458045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 115a96bff61SInès Varhol } 116a96bff61SInès Varhol 117a96bff61SInès Varhol static void test_set_and_clear(void) 118a96bff61SInès Varhol { 119a96bff61SInès Varhol /* 120a96bff61SInès Varhol * Test that regular bits can be set and cleared 121a96bff61SInès Varhol */ 122a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0x00000107); 12358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000107); 124a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0x00000000); 12558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 126a96bff61SInès Varhol 127a96bff61SInès Varhol /* cfgr1 bit 0 is clear only so we keep it set */ 128a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0xFCFF0101); 12958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0xFCFF0101); 130a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000001); 13158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000001); 132a96bff61SInès Varhol 133a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x0000FFFF); 13458045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x0000FFFF); 135a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 13658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 137a96bff61SInès Varhol 138a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0x0000FFFF); 13958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x0000FFFF); 140a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0x00000000); 14158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 142a96bff61SInès Varhol 143a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0x0000FFFF); 14458045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x0000FFFF); 145a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0x00000000); 14658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 147a96bff61SInès Varhol 148a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0x0000FFFF); 14958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x0000FFFF); 150a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0x00000000); 15158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 152a96bff61SInès Varhol 153a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0x000000FF); 15458045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x000000FF); 155a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0x00000000); 15658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 157a96bff61SInès Varhol } 158a96bff61SInès Varhol 159a96bff61SInès Varhol static void test_clear_by_writing_1(void) 160a96bff61SInès Varhol { 161a96bff61SInès Varhol /* 162a96bff61SInès Varhol * Test that writing '1' doesn't set the bit 163a96bff61SInès Varhol */ 164a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x00000100); 16558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000); 166a96bff61SInès Varhol } 167a96bff61SInès Varhol 168a96bff61SInès Varhol static void test_set_only_bits(void) 169a96bff61SInès Varhol { 170a96bff61SInès Varhol /* 171a96bff61SInès Varhol * Test that set only bits stay can't be cleared 172a96bff61SInès Varhol */ 173a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x0000000F); 174a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x00000000); 17558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x0000000F); 176a96bff61SInès Varhol 177a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR, 0xFFFFFFFF); 178a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR, 0x00000000); 17958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0xFFFFFFFF); 180a96bff61SInès Varhol 181a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR2, 0xFFFFFFFF); 182a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR2, 0x00000000); 18358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0xFFFFFFFF); 184a96bff61SInès Varhol 185a96bff61SInès Varhol system_reset(); 186a96bff61SInès Varhol } 187a96bff61SInès Varhol 188a96bff61SInès Varhol static void test_clear_only_bits(void) 189a96bff61SInès Varhol { 190a96bff61SInès Varhol /* 191a96bff61SInès Varhol * Test that clear only bits stay can't be set 192a96bff61SInès Varhol */ 193a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000000); 194a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000001); 19558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000000); 196a96bff61SInès Varhol 197a96bff61SInès Varhol system_reset(); 198a96bff61SInès Varhol } 199a96bff61SInès Varhol 200a96bff61SInès Varhol static void test_interrupt(void) 201a96bff61SInès Varhol { 202a96bff61SInès Varhol /* 203a96bff61SInès Varhol * Test that GPIO rising lines result in an irq 204a96bff61SInès Varhol * with the right configuration 205a96bff61SInès Varhol */ 2065b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 207a96bff61SInès Varhol 208a96bff61SInès Varhol /* GPIOA is the default source for EXTI lines 0 to 15 */ 209a96bff61SInès Varhol 210a96bff61SInès Varhol syscfg_set_irq(0, 1); 211a96bff61SInès Varhol 212a96bff61SInès Varhol g_assert_true(get_irq(0)); 213a96bff61SInès Varhol 214a96bff61SInès Varhol 215a96bff61SInès Varhol syscfg_set_irq(15, 1); 216a96bff61SInès Varhol 217a96bff61SInès Varhol g_assert_true(get_irq(15)); 218a96bff61SInès Varhol 219a96bff61SInès Varhol /* Configure GPIOB[1] as the source input for EXTI1 */ 220a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000010); 221a96bff61SInès Varhol 222a96bff61SInès Varhol syscfg_set_irq(17, 1); 223a96bff61SInès Varhol 224a96bff61SInès Varhol g_assert_true(get_irq(1)); 225a96bff61SInès Varhol 226a96bff61SInès Varhol /* Clean the test */ 227a96bff61SInès Varhol syscfg_set_irq(0, 0); 2287d9b3c34SInès Varhol /* irq 15 is high at reset because GPIOA15 is high at reset */ 229a96bff61SInès Varhol syscfg_set_irq(17, 0); 23058c782deSInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 231a96bff61SInès Varhol } 232a96bff61SInès Varhol 233a96bff61SInès Varhol static void test_irq_pin_multiplexer(void) 234a96bff61SInès Varhol { 235a96bff61SInès Varhol /* 236a96bff61SInès Varhol * Test that syscfg irq sets the right exti irq 237a96bff61SInès Varhol */ 238a96bff61SInès Varhol 2395b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 240a96bff61SInès Varhol 241a96bff61SInès Varhol syscfg_set_irq(0, 1); 242a96bff61SInès Varhol 2437d9b3c34SInès Varhol /* Check that irq 0 was set and irq 2 wasn't */ 244a96bff61SInès Varhol g_assert_true(get_irq(0)); 2457d9b3c34SInès Varhol g_assert_false(get_irq(2)); 246a96bff61SInès Varhol 247a96bff61SInès Varhol /* Clean the test */ 248a96bff61SInès Varhol syscfg_set_irq(0, 0); 249a96bff61SInès Varhol 2507d9b3c34SInès Varhol syscfg_set_irq(2, 1); 251a96bff61SInès Varhol 2527d9b3c34SInès Varhol /* Check that irq 2 was set and irq 0 wasn't */ 2537d9b3c34SInès Varhol g_assert_true(get_irq(2)); 254a96bff61SInès Varhol g_assert_false(get_irq(0)); 255a96bff61SInès Varhol 256a96bff61SInès Varhol /* Clean the test */ 2577d9b3c34SInès Varhol syscfg_set_irq(2, 0); 258a96bff61SInès Varhol } 259a96bff61SInès Varhol 260a96bff61SInès Varhol static void test_irq_gpio_multiplexer(void) 261a96bff61SInès Varhol { 262a96bff61SInès Varhol /* 263a96bff61SInès Varhol * Test that an irq is generated only by the right GPIO 264a96bff61SInès Varhol */ 265a96bff61SInès Varhol 2665b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 267a96bff61SInès Varhol 268a96bff61SInès Varhol /* GPIOA is the default source for EXTI lines 0 to 15 */ 269a96bff61SInès Varhol 270a96bff61SInès Varhol /* Check that setting rising pin GPIOA[0] generates an irq */ 271a96bff61SInès Varhol syscfg_set_irq(0, 1); 272a96bff61SInès Varhol 273a96bff61SInès Varhol g_assert_true(get_irq(0)); 274a96bff61SInès Varhol 275a96bff61SInès Varhol /* Clean the test */ 276a96bff61SInès Varhol syscfg_set_irq(0, 0); 277a96bff61SInès Varhol 278a96bff61SInès Varhol /* Check that setting rising pin GPIOB[0] doesn't generate an irq */ 279a96bff61SInès Varhol syscfg_set_irq(16, 1); 280a96bff61SInès Varhol 281a96bff61SInès Varhol g_assert_false(get_irq(0)); 282a96bff61SInès Varhol 283a96bff61SInès Varhol /* Clean the test */ 284a96bff61SInès Varhol syscfg_set_irq(16, 0); 285a96bff61SInès Varhol 286a96bff61SInès Varhol /* Configure GPIOB[0] as the source input for EXTI0 */ 287a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000001); 288a96bff61SInès Varhol 289a96bff61SInès Varhol /* Check that setting rising pin GPIOA[0] doesn't generate an irq */ 290a96bff61SInès Varhol syscfg_set_irq(0, 1); 291a96bff61SInès Varhol 292a96bff61SInès Varhol g_assert_false(get_irq(0)); 293a96bff61SInès Varhol 294a96bff61SInès Varhol /* Clean the test */ 295a96bff61SInès Varhol syscfg_set_irq(0, 0); 296a96bff61SInès Varhol 297a96bff61SInès Varhol /* Check that setting rising pin GPIOB[0] generates an irq */ 298a96bff61SInès Varhol syscfg_set_irq(16, 1); 299a96bff61SInès Varhol 300a96bff61SInès Varhol g_assert_true(get_irq(0)); 301a96bff61SInès Varhol 302a96bff61SInès Varhol /* Clean the test */ 303a96bff61SInès Varhol syscfg_set_irq(16, 0); 304a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 305a96bff61SInès Varhol } 306a96bff61SInès Varhol 307*88446cfeSInès Varhol static void test_clock_enable(void) 308*88446cfeSInès Varhol { 309*88446cfeSInès Varhol g_assert_cmpuint(get_clock_period(global_qtest, SYSCFG_CLK), ==, 0); 310*88446cfeSInès Varhol 311*88446cfeSInès Varhol /* Enable SYSCFG clock */ 312*88446cfeSInès Varhol writel(RCC_APB2ENR, readl(RCC_APB2ENR) | (0x1 << 0)); 313*88446cfeSInès Varhol 314*88446cfeSInès Varhol g_assert_cmpuint(get_clock_period(global_qtest, SYSCFG_CLK), ==, 315*88446cfeSInès Varhol SYSCLK_PERIOD); 316*88446cfeSInès Varhol } 317*88446cfeSInès Varhol 318a96bff61SInès Varhol int main(int argc, char **argv) 319a96bff61SInès Varhol { 320a96bff61SInès Varhol int ret; 321a96bff61SInès Varhol 322a96bff61SInès Varhol g_test_init(&argc, &argv, NULL); 323a96bff61SInès Varhol g_test_set_nonfatal_assertions(); 324a96bff61SInès Varhol 325a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_reset", test_reset); 326a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_reserved_bits", 327a96bff61SInès Varhol test_reserved_bits); 328a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_set_and_clear", 329a96bff61SInès Varhol test_set_and_clear); 330a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clear_by_writing_1", 331a96bff61SInès Varhol test_clear_by_writing_1); 332a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_set_only_bits", 333a96bff61SInès Varhol test_set_only_bits); 334a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clear_only_bits", 335a96bff61SInès Varhol test_clear_only_bits); 336a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_interrupt", 337a96bff61SInès Varhol test_interrupt); 338a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_irq_pin_multiplexer", 339a96bff61SInès Varhol test_irq_pin_multiplexer); 340a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_irq_gpio_multiplexer", 341a96bff61SInès Varhol test_irq_gpio_multiplexer); 342*88446cfeSInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clock_enable", 343*88446cfeSInès Varhol test_clock_enable); 344a96bff61SInès Varhol 345a96bff61SInès Varhol qtest_start("-machine b-l475e-iot01a"); 346a96bff61SInès Varhol ret = g_test_run(); 347a96bff61SInès Varhol qtest_end(); 348a96bff61SInès Varhol 349a96bff61SInès Varhol return ret; 350a96bff61SInès Varhol } 351