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" 1388446cfeSInè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 */ 3088446cfeSInès Varhol #define SOC "/machine/soc" 3188446cfeSInès Varhol #define SYSCFG "/machine/soc/syscfg" 3288446cfeSInè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 { 4788446cfeSInès Varhol qtest_set_irq_in(global_qtest, SOC, NULL, num, level); 48a96bff61SInès Varhol } 49a96bff61SInès Varhol 50a96bff61SInès Varhol static void test_reset(void) 51a96bff61SInès Varhol { 52a96bff61SInès Varhol /* 53a96bff61SInès Varhol * Test that registers are initialized at the correct values 54a96bff61SInès Varhol */ 5558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 56a96bff61SInès Varhol 5758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001); 58a96bff61SInès Varhol 5958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 60a96bff61SInès Varhol 6158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 62a96bff61SInès Varhol 6358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 64a96bff61SInès Varhol 6558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 66a96bff61SInès Varhol 6758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SCSR), ==, 0x00000000); 68a96bff61SInès Varhol 6958045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000); 70a96bff61SInès Varhol 7158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0x00000000); 72a96bff61SInès Varhol 7358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 74a96bff61SInès Varhol 7558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0x00000000); 76a96bff61SInès Varhol } 77a96bff61SInès Varhol 78a96bff61SInès Varhol static void test_reserved_bits(void) 79a96bff61SInès Varhol { 80a96bff61SInès Varhol /* 81a96bff61SInès Varhol * Test that reserved bits stay at reset value 82a96bff61SInès Varhol * (which is 0 for all of them) by writing '1' 83a96bff61SInès Varhol * in all reserved bits (keeping reset value for 84a96bff61SInès Varhol * other bits) and checking that the 85a96bff61SInès Varhol * register is still at reset value 86a96bff61SInès Varhol */ 87a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0xFFFFFEF8); 8858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 89a96bff61SInès Varhol 90a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x7F00FEFF); 9158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x7C000001); 92a96bff61SInès Varhol 93a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0xFFFF0000); 9458045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 95a96bff61SInès Varhol 96a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0xFFFF0000); 9758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 98a96bff61SInès Varhol 99a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0xFFFF0000); 10058045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 101a96bff61SInès Varhol 102a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0xFFFF0000); 10358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 104a96bff61SInès Varhol 105a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0xFFFFFF00); 10658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 107a96bff61SInès Varhol } 108a96bff61SInès Varhol 109a96bff61SInès Varhol static void test_set_and_clear(void) 110a96bff61SInès Varhol { 111a96bff61SInès Varhol /* 112a96bff61SInès Varhol * Test that regular bits can be set and cleared 113a96bff61SInès Varhol */ 114a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0x00000107); 11558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000107); 116a96bff61SInès Varhol syscfg_writel(SYSCFG_MEMRMP, 0x00000000); 11758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_MEMRMP), ==, 0x00000000); 118a96bff61SInès Varhol 119a96bff61SInès Varhol /* cfgr1 bit 0 is clear only so we keep it set */ 120a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0xFCFF0101); 12158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0xFCFF0101); 122a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000001); 12358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000001); 124a96bff61SInès Varhol 125a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x0000FFFF); 12658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x0000FFFF); 127a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 12858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR1), ==, 0x00000000); 129a96bff61SInès Varhol 130a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0x0000FFFF); 13158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x0000FFFF); 132a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR2, 0x00000000); 13358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR2), ==, 0x00000000); 134a96bff61SInès Varhol 135a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0x0000FFFF); 13658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x0000FFFF); 137a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR3, 0x00000000); 13858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR3), ==, 0x00000000); 139a96bff61SInès Varhol 140a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0x0000FFFF); 14158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x0000FFFF); 142a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR4, 0x00000000); 14358045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_EXTICR4), ==, 0x00000000); 144a96bff61SInès Varhol 145a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0x000000FF); 14658045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x000000FF); 147a96bff61SInès Varhol syscfg_writel(SYSCFG_SKR, 0x00000000); 14858045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SKR), ==, 0x00000000); 149a96bff61SInès Varhol } 150a96bff61SInès Varhol 151a96bff61SInès Varhol static void test_clear_by_writing_1(void) 152a96bff61SInès Varhol { 153a96bff61SInès Varhol /* 154a96bff61SInès Varhol * Test that writing '1' doesn't set the bit 155a96bff61SInès Varhol */ 156a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x00000100); 15758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x00000000); 158a96bff61SInès Varhol } 159a96bff61SInès Varhol 160a96bff61SInès Varhol static void test_set_only_bits(void) 161a96bff61SInès Varhol { 162a96bff61SInès Varhol /* 163a96bff61SInès Varhol * Test that set only bits stay can't be cleared 164a96bff61SInès Varhol */ 165a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x0000000F); 166a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR2, 0x00000000); 16758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR2), ==, 0x0000000F); 168a96bff61SInès Varhol 169a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR, 0xFFFFFFFF); 170a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR, 0x00000000); 17158045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR), ==, 0xFFFFFFFF); 172a96bff61SInès Varhol 173a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR2, 0xFFFFFFFF); 174a96bff61SInès Varhol syscfg_writel(SYSCFG_SWPR2, 0x00000000); 17558045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_SWPR2), ==, 0xFFFFFFFF); 176a96bff61SInès Varhol 177*9881d3d1SPeter Maydell qtest_system_reset(global_qtest); 178a96bff61SInès Varhol } 179a96bff61SInès Varhol 180a96bff61SInès Varhol static void test_clear_only_bits(void) 181a96bff61SInès Varhol { 182a96bff61SInès Varhol /* 183a96bff61SInès Varhol * Test that clear only bits stay can't be set 184a96bff61SInès Varhol */ 185a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000000); 186a96bff61SInès Varhol syscfg_writel(SYSCFG_CFGR1, 0x00000001); 18758045186SInès Varhol g_assert_cmphex(syscfg_readl(SYSCFG_CFGR1), ==, 0x00000000); 188a96bff61SInès Varhol 189*9881d3d1SPeter Maydell qtest_system_reset(global_qtest); 190a96bff61SInès Varhol } 191a96bff61SInès Varhol 192a96bff61SInès Varhol static void test_interrupt(void) 193a96bff61SInès Varhol { 194a96bff61SInès Varhol /* 195a96bff61SInès Varhol * Test that GPIO rising lines result in an irq 196a96bff61SInès Varhol * with the right configuration 197a96bff61SInès Varhol */ 1985b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 199a96bff61SInès Varhol 200a96bff61SInès Varhol /* GPIOA is the default source for EXTI lines 0 to 15 */ 201a96bff61SInès Varhol 202a96bff61SInès Varhol syscfg_set_irq(0, 1); 203a96bff61SInès Varhol 204a96bff61SInès Varhol g_assert_true(get_irq(0)); 205a96bff61SInès Varhol 206a96bff61SInès Varhol 207a96bff61SInès Varhol syscfg_set_irq(15, 1); 208a96bff61SInès Varhol 209a96bff61SInès Varhol g_assert_true(get_irq(15)); 210a96bff61SInès Varhol 211a96bff61SInès Varhol /* Configure GPIOB[1] as the source input for EXTI1 */ 212a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000010); 213a96bff61SInès Varhol 214a96bff61SInès Varhol syscfg_set_irq(17, 1); 215a96bff61SInès Varhol 216a96bff61SInès Varhol g_assert_true(get_irq(1)); 217a96bff61SInès Varhol 218a96bff61SInès Varhol /* Clean the test */ 219a96bff61SInès Varhol syscfg_set_irq(0, 0); 2207d9b3c34SInès Varhol /* irq 15 is high at reset because GPIOA15 is high at reset */ 221a96bff61SInès Varhol syscfg_set_irq(17, 0); 22258c782deSInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 223a96bff61SInès Varhol } 224a96bff61SInès Varhol 225a96bff61SInès Varhol static void test_irq_pin_multiplexer(void) 226a96bff61SInès Varhol { 227a96bff61SInès Varhol /* 228a96bff61SInès Varhol * Test that syscfg irq sets the right exti irq 229a96bff61SInès Varhol */ 230a96bff61SInès Varhol 2315b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 232a96bff61SInès Varhol 233a96bff61SInès Varhol syscfg_set_irq(0, 1); 234a96bff61SInès Varhol 2357d9b3c34SInès Varhol /* Check that irq 0 was set and irq 2 wasn't */ 236a96bff61SInès Varhol g_assert_true(get_irq(0)); 2377d9b3c34SInès Varhol g_assert_false(get_irq(2)); 238a96bff61SInès Varhol 239a96bff61SInès Varhol /* Clean the test */ 240a96bff61SInès Varhol syscfg_set_irq(0, 0); 241a96bff61SInès Varhol 2427d9b3c34SInès Varhol syscfg_set_irq(2, 1); 243a96bff61SInès Varhol 2447d9b3c34SInès Varhol /* Check that irq 2 was set and irq 0 wasn't */ 2457d9b3c34SInès Varhol g_assert_true(get_irq(2)); 246a96bff61SInès Varhol g_assert_false(get_irq(0)); 247a96bff61SInès Varhol 248a96bff61SInès Varhol /* Clean the test */ 2497d9b3c34SInès Varhol syscfg_set_irq(2, 0); 250a96bff61SInès Varhol } 251a96bff61SInès Varhol 252a96bff61SInès Varhol static void test_irq_gpio_multiplexer(void) 253a96bff61SInès Varhol { 254a96bff61SInès Varhol /* 255a96bff61SInès Varhol * Test that an irq is generated only by the right GPIO 256a96bff61SInès Varhol */ 257a96bff61SInès Varhol 2585b5b014bSInès Varhol qtest_irq_intercept_in(global_qtest, EXTI); 259a96bff61SInès Varhol 260a96bff61SInès Varhol /* GPIOA is the default source for EXTI lines 0 to 15 */ 261a96bff61SInès Varhol 262a96bff61SInès Varhol /* Check that setting rising pin GPIOA[0] generates an irq */ 263a96bff61SInès Varhol syscfg_set_irq(0, 1); 264a96bff61SInès Varhol 265a96bff61SInès Varhol g_assert_true(get_irq(0)); 266a96bff61SInès Varhol 267a96bff61SInès Varhol /* Clean the test */ 268a96bff61SInès Varhol syscfg_set_irq(0, 0); 269a96bff61SInès Varhol 270a96bff61SInès Varhol /* Check that setting rising pin GPIOB[0] doesn't generate an irq */ 271a96bff61SInès Varhol syscfg_set_irq(16, 1); 272a96bff61SInès Varhol 273a96bff61SInès Varhol g_assert_false(get_irq(0)); 274a96bff61SInès Varhol 275a96bff61SInès Varhol /* Clean the test */ 276a96bff61SInès Varhol syscfg_set_irq(16, 0); 277a96bff61SInès Varhol 278a96bff61SInès Varhol /* Configure GPIOB[0] as the source input for EXTI0 */ 279a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000001); 280a96bff61SInès Varhol 281a96bff61SInès Varhol /* Check that setting rising pin GPIOA[0] doesn't generate an irq */ 282a96bff61SInès Varhol syscfg_set_irq(0, 1); 283a96bff61SInès Varhol 284a96bff61SInès Varhol g_assert_false(get_irq(0)); 285a96bff61SInès Varhol 286a96bff61SInès Varhol /* Clean the test */ 287a96bff61SInès Varhol syscfg_set_irq(0, 0); 288a96bff61SInès Varhol 289a96bff61SInès Varhol /* Check that setting rising pin GPIOB[0] generates an irq */ 290a96bff61SInès Varhol syscfg_set_irq(16, 1); 291a96bff61SInès Varhol 292a96bff61SInès Varhol g_assert_true(get_irq(0)); 293a96bff61SInès Varhol 294a96bff61SInès Varhol /* Clean the test */ 295a96bff61SInès Varhol syscfg_set_irq(16, 0); 296a96bff61SInès Varhol syscfg_writel(SYSCFG_EXTICR1, 0x00000000); 297a96bff61SInès Varhol } 298a96bff61SInès Varhol 29988446cfeSInès Varhol static void test_clock_enable(void) 30088446cfeSInès Varhol { 30188446cfeSInès Varhol g_assert_cmpuint(get_clock_period(global_qtest, SYSCFG_CLK), ==, 0); 30288446cfeSInès Varhol 30388446cfeSInès Varhol /* Enable SYSCFG clock */ 30488446cfeSInès Varhol writel(RCC_APB2ENR, readl(RCC_APB2ENR) | (0x1 << 0)); 30588446cfeSInès Varhol 30688446cfeSInès Varhol g_assert_cmpuint(get_clock_period(global_qtest, SYSCFG_CLK), ==, 30788446cfeSInès Varhol SYSCLK_PERIOD); 30888446cfeSInès Varhol } 30988446cfeSInès Varhol 310a96bff61SInès Varhol int main(int argc, char **argv) 311a96bff61SInès Varhol { 312a96bff61SInès Varhol int ret; 313a96bff61SInès Varhol 314a96bff61SInès Varhol g_test_init(&argc, &argv, NULL); 315a96bff61SInès Varhol g_test_set_nonfatal_assertions(); 316a96bff61SInès Varhol 317a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_reset", test_reset); 318a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_reserved_bits", 319a96bff61SInès Varhol test_reserved_bits); 320a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_set_and_clear", 321a96bff61SInès Varhol test_set_and_clear); 322a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clear_by_writing_1", 323a96bff61SInès Varhol test_clear_by_writing_1); 324a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_set_only_bits", 325a96bff61SInès Varhol test_set_only_bits); 326a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clear_only_bits", 327a96bff61SInès Varhol test_clear_only_bits); 328a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_interrupt", 329a96bff61SInès Varhol test_interrupt); 330a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_irq_pin_multiplexer", 331a96bff61SInès Varhol test_irq_pin_multiplexer); 332a96bff61SInès Varhol qtest_add_func("stm32l4x5/syscfg/test_irq_gpio_multiplexer", 333a96bff61SInès Varhol test_irq_gpio_multiplexer); 33488446cfeSInès Varhol qtest_add_func("stm32l4x5/syscfg/test_clock_enable", 33588446cfeSInès Varhol test_clock_enable); 336a96bff61SInès Varhol 337a96bff61SInès Varhol qtest_start("-machine b-l475e-iot01a"); 338a96bff61SInès Varhol ret = g_test_run(); 339a96bff61SInès Varhol qtest_end(); 340a96bff61SInès Varhol 341a96bff61SInès Varhol return ret; 342a96bff61SInès Varhol } 343