1 /* 2 * QTest testcase for STM32L4x5_GPIO 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 GPIO_BASE_ADDR 0x48000000 15 #define GPIO_SIZE 0x400 16 #define NUM_GPIOS 8 17 #define NUM_GPIO_PINS 16 18 19 #define GPIO_A 0x48000000 20 #define GPIO_B 0x48000400 21 #define GPIO_C 0x48000800 22 #define GPIO_D 0x48000C00 23 #define GPIO_E 0x48001000 24 #define GPIO_F 0x48001400 25 #define GPIO_G 0x48001800 26 #define GPIO_H 0x48001C00 27 28 #define MODER 0x00 29 #define OTYPER 0x04 30 #define PUPDR 0x0C 31 #define IDR 0x10 32 #define ODR 0x14 33 #define BSRR 0x18 34 #define BRR 0x28 35 36 #define MODER_INPUT 0 37 #define MODER_OUTPUT 1 38 39 #define PUPDR_NONE 0 40 #define PUPDR_PULLUP 1 41 #define PUPDR_PULLDOWN 2 42 43 #define OTYPER_PUSH_PULL 0 44 #define OTYPER_OPEN_DRAIN 1 45 46 const uint32_t moder_reset[NUM_GPIOS] = { 47 0xABFFFFFF, 48 0xFFFFFEBF, 49 0xFFFFFFFF, 50 0xFFFFFFFF, 51 0xFFFFFFFF, 52 0xFFFFFFFF, 53 0xFFFFFFFF, 54 0x0000000F 55 }; 56 57 const uint32_t pupdr_reset[NUM_GPIOS] = { 58 0x64000000, 59 0x00000100, 60 0x00000000, 61 0x00000000, 62 0x00000000, 63 0x00000000, 64 0x00000000, 65 0x00000000 66 }; 67 68 const uint32_t idr_reset[NUM_GPIOS] = { 69 0x0000A000, 70 0x00000010, 71 0x00000000, 72 0x00000000, 73 0x00000000, 74 0x00000000, 75 0x00000000, 76 0x00000000 77 }; 78 79 static uint32_t gpio_readl(unsigned int gpio, unsigned int offset) 80 { 81 return readl(gpio + offset); 82 } 83 84 static void gpio_writel(unsigned int gpio, unsigned int offset, uint32_t value) 85 { 86 writel(gpio + offset, value); 87 } 88 89 static void gpio_set_bit(unsigned int gpio, unsigned int reg, 90 unsigned int pin, uint32_t value) 91 { 92 uint32_t mask = 0xFFFFFFFF & ~(0x1 << pin); 93 gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << pin); 94 } 95 96 static void gpio_set_2bits(unsigned int gpio, unsigned int reg, 97 unsigned int pin, uint32_t value) 98 { 99 uint32_t offset = 2 * pin; 100 uint32_t mask = 0xFFFFFFFF & ~(0x3 << offset); 101 gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << offset); 102 } 103 104 static unsigned int get_gpio_id(uint32_t gpio_addr) 105 { 106 return (gpio_addr - GPIO_BASE_ADDR) / GPIO_SIZE; 107 } 108 109 static void gpio_set_irq(unsigned int gpio, int num, int level) 110 { 111 g_autofree char *name = g_strdup_printf("/machine/soc/gpio%c", 112 get_gpio_id(gpio) + 'a'); 113 qtest_set_irq_in(global_qtest, name, NULL, num, level); 114 } 115 116 static void disconnect_all_pins(unsigned int gpio) 117 { 118 g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c", 119 get_gpio_id(gpio) + 'a'); 120 QDict *r; 121 122 r = qtest_qmp(global_qtest, "{ 'execute': 'qom-set', 'arguments': " 123 "{ 'path': %s, 'property': 'disconnected-pins', 'value': %d } }", 124 path, 0xFFFF); 125 g_assert_false(qdict_haskey(r, "error")); 126 qobject_unref(r); 127 } 128 129 static uint32_t get_disconnected_pins(unsigned int gpio) 130 { 131 g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c", 132 get_gpio_id(gpio) + 'a'); 133 uint32_t disconnected_pins = 0; 134 QDict *r; 135 136 r = qtest_qmp(global_qtest, "{ 'execute': 'qom-get', 'arguments':" 137 " { 'path': %s, 'property': 'disconnected-pins'} }", path); 138 g_assert_false(qdict_haskey(r, "error")); 139 disconnected_pins = qdict_get_int(r, "return"); 140 qobject_unref(r); 141 return disconnected_pins; 142 } 143 144 static uint32_t reset(uint32_t gpio, unsigned int offset) 145 { 146 switch (offset) { 147 case MODER: 148 return moder_reset[get_gpio_id(gpio)]; 149 case PUPDR: 150 return pupdr_reset[get_gpio_id(gpio)]; 151 case IDR: 152 return idr_reset[get_gpio_id(gpio)]; 153 } 154 return 0x0; 155 } 156 157 static void system_reset(void) 158 { 159 QDict *r; 160 r = qtest_qmp(global_qtest, "{'execute': 'system_reset'}"); 161 g_assert_false(qdict_haskey(r, "error")); 162 qobject_unref(r); 163 } 164 165 static void test_idr_reset_value(void) 166 { 167 /* 168 * Checks that the values in MODER, OTYPER, PUPDR and ODR 169 * after reset are correct, and that the value in IDR is 170 * coherent. 171 * Since AF and analog modes aren't implemented, IDR reset 172 * values aren't the same as with a real board. 173 * 174 * Register IDR contains the actual values of all GPIO pins. 175 * Its value depends on the pins' configuration 176 * (intput/output/analog : register MODER, push-pull/open-drain : 177 * register OTYPER, pull-up/pull-down/none : register PUPDR) 178 * and on the values stored in register ODR 179 * (in case the pin is in output mode). 180 */ 181 182 gpio_writel(GPIO_A, MODER, 0xDEADBEEF); 183 gpio_writel(GPIO_A, ODR, 0xDEADBEEF); 184 gpio_writel(GPIO_A, OTYPER, 0xDEADBEEF); 185 gpio_writel(GPIO_A, PUPDR, 0xDEADBEEF); 186 187 gpio_writel(GPIO_B, MODER, 0xDEADBEEF); 188 gpio_writel(GPIO_B, ODR, 0xDEADBEEF); 189 gpio_writel(GPIO_B, OTYPER, 0xDEADBEEF); 190 gpio_writel(GPIO_B, PUPDR, 0xDEADBEEF); 191 192 gpio_writel(GPIO_C, MODER, 0xDEADBEEF); 193 gpio_writel(GPIO_C, ODR, 0xDEADBEEF); 194 gpio_writel(GPIO_C, OTYPER, 0xDEADBEEF); 195 gpio_writel(GPIO_C, PUPDR, 0xDEADBEEF); 196 197 gpio_writel(GPIO_H, MODER, 0xDEADBEEF); 198 gpio_writel(GPIO_H, ODR, 0xDEADBEEF); 199 gpio_writel(GPIO_H, OTYPER, 0xDEADBEEF); 200 gpio_writel(GPIO_H, PUPDR, 0xDEADBEEF); 201 202 system_reset(); 203 204 uint32_t moder = gpio_readl(GPIO_A, MODER); 205 uint32_t odr = gpio_readl(GPIO_A, ODR); 206 uint32_t otyper = gpio_readl(GPIO_A, OTYPER); 207 uint32_t pupdr = gpio_readl(GPIO_A, PUPDR); 208 uint32_t idr = gpio_readl(GPIO_A, IDR); 209 /* 15: AF, 14: AF, 13: AF, 12: Analog ... */ 210 /* here AF is the same as Analog and Input mode */ 211 g_assert_cmphex(moder, ==, reset(GPIO_A, MODER)); 212 g_assert_cmphex(odr, ==, reset(GPIO_A, ODR)); 213 g_assert_cmphex(otyper, ==, reset(GPIO_A, OTYPER)); 214 /* 15: pull-up, 14: pull-down, 13: pull-up, 12: neither ... */ 215 g_assert_cmphex(pupdr, ==, reset(GPIO_A, PUPDR)); 216 /* 15 : 1, 14: 0, 13: 1, 12 : reset value ... */ 217 g_assert_cmphex(idr, ==, reset(GPIO_A, IDR)); 218 219 moder = gpio_readl(GPIO_B, MODER); 220 odr = gpio_readl(GPIO_B, ODR); 221 otyper = gpio_readl(GPIO_B, OTYPER); 222 pupdr = gpio_readl(GPIO_B, PUPDR); 223 idr = gpio_readl(GPIO_B, IDR); 224 /* ... 5: Analog, 4: AF, 3: AF, 2: Analog ... */ 225 /* here AF is the same as Analog and Input mode */ 226 g_assert_cmphex(moder, ==, reset(GPIO_B, MODER)); 227 g_assert_cmphex(odr, ==, reset(GPIO_B, ODR)); 228 g_assert_cmphex(otyper, ==, reset(GPIO_B, OTYPER)); 229 /* ... 5: neither, 4: pull-up, 3: neither ... */ 230 g_assert_cmphex(pupdr, ==, reset(GPIO_B, PUPDR)); 231 /* ... 5 : reset value, 4 : 1, 3 : reset value ... */ 232 g_assert_cmphex(idr, ==, reset(GPIO_B, IDR)); 233 234 moder = gpio_readl(GPIO_C, MODER); 235 odr = gpio_readl(GPIO_C, ODR); 236 otyper = gpio_readl(GPIO_C, OTYPER); 237 pupdr = gpio_readl(GPIO_C, PUPDR); 238 idr = gpio_readl(GPIO_C, IDR); 239 /* Analog, same as Input mode*/ 240 g_assert_cmphex(moder, ==, reset(GPIO_C, MODER)); 241 g_assert_cmphex(odr, ==, reset(GPIO_C, ODR)); 242 g_assert_cmphex(otyper, ==, reset(GPIO_C, OTYPER)); 243 /* no pull-up or pull-down */ 244 g_assert_cmphex(pupdr, ==, reset(GPIO_C, PUPDR)); 245 /* reset value */ 246 g_assert_cmphex(idr, ==, reset(GPIO_C, IDR)); 247 248 moder = gpio_readl(GPIO_H, MODER); 249 odr = gpio_readl(GPIO_H, ODR); 250 otyper = gpio_readl(GPIO_H, OTYPER); 251 pupdr = gpio_readl(GPIO_H, PUPDR); 252 idr = gpio_readl(GPIO_H, IDR); 253 /* Analog, same as Input mode */ 254 g_assert_cmphex(moder, ==, reset(GPIO_H, MODER)); 255 g_assert_cmphex(odr, ==, reset(GPIO_H, ODR)); 256 g_assert_cmphex(otyper, ==, reset(GPIO_H, OTYPER)); 257 /* no pull-up or pull-down */ 258 g_assert_cmphex(pupdr, ==, reset(GPIO_H, PUPDR)); 259 /* reset value */ 260 g_assert_cmphex(idr, ==, reset(GPIO_H, IDR)); 261 } 262 263 static void test_gpio_output_mode(const void *data) 264 { 265 /* 266 * Checks that setting a bit in ODR sets the corresponding 267 * GPIO line high : it should set the right bit in IDR 268 * and send an irq to syscfg. 269 * Additionally, it checks that values written to ODR 270 * when not in output mode are stored and not discarded. 271 */ 272 unsigned int pin = ((uint64_t)data) & 0xF; 273 uint32_t gpio = ((uint64_t)data) >> 32; 274 unsigned int gpio_id = get_gpio_id(gpio); 275 276 qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); 277 278 /* Set a bit in ODR and check nothing happens */ 279 gpio_set_bit(gpio, ODR, pin, 1); 280 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 281 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 282 283 /* Configure the relevant line as output and check the pin is high */ 284 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); 285 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); 286 g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 287 288 /* Reset the bit in ODR and check the pin is low */ 289 gpio_set_bit(gpio, ODR, pin, 0); 290 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 291 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 292 293 /* Clean the test */ 294 gpio_writel(gpio, ODR, reset(gpio, ODR)); 295 gpio_writel(gpio, MODER, reset(gpio, MODER)); 296 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 297 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 298 } 299 300 static void test_gpio_input_mode(const void *data) 301 { 302 /* 303 * Test that setting a line high/low externally sets the 304 * corresponding GPIO line high/low : it should set the 305 * right bit in IDR and send an irq to syscfg. 306 */ 307 unsigned int pin = ((uint64_t)data) & 0xF; 308 uint32_t gpio = ((uint64_t)data) >> 32; 309 unsigned int gpio_id = get_gpio_id(gpio); 310 311 qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); 312 313 /* Configure a line as input, raise it, and check that the pin is high */ 314 gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); 315 gpio_set_irq(gpio, pin, 1); 316 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); 317 g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 318 319 /* Lower the line and check that the pin is low */ 320 gpio_set_irq(gpio, pin, 0); 321 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 322 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 323 324 /* Clean the test */ 325 gpio_writel(gpio, MODER, reset(gpio, MODER)); 326 disconnect_all_pins(gpio); 327 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 328 } 329 330 static void test_pull_up_pull_down(const void *data) 331 { 332 /* 333 * Test that a floating pin with pull-up sets the pin 334 * high and vice-versa. 335 */ 336 unsigned int pin = ((uint64_t)data) & 0xF; 337 uint32_t gpio = ((uint64_t)data) >> 32; 338 unsigned int gpio_id = get_gpio_id(gpio); 339 340 qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); 341 342 /* Configure a line as input with pull-up, check the line is set high */ 343 gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); 344 gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLUP); 345 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); 346 g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 347 348 /* Configure the line with pull-down, check the line is low */ 349 gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLDOWN); 350 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 351 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 352 353 /* Clean the test */ 354 gpio_writel(gpio, MODER, reset(gpio, MODER)); 355 gpio_writel(gpio, PUPDR, reset(gpio, PUPDR)); 356 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 357 } 358 359 static void test_push_pull(const void *data) 360 { 361 /* 362 * Test that configuring a line in push-pull output mode 363 * disconnects the pin, that the pin can't be set or reset 364 * externally afterwards. 365 */ 366 unsigned int pin = ((uint64_t)data) & 0xF; 367 uint32_t gpio = ((uint64_t)data) >> 32; 368 uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); 369 370 qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); 371 372 /* Setting a line high externally, configuring it in push-pull output */ 373 /* And checking the pin was disconnected */ 374 gpio_set_irq(gpio, pin, 1); 375 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); 376 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 377 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 378 379 /* Setting a line low externally, configuring it in push-pull output */ 380 /* And checking the pin was disconnected */ 381 gpio_set_irq(gpio2, pin, 0); 382 gpio_set_bit(gpio2, ODR, pin, 1); 383 gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT); 384 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF); 385 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin)); 386 387 /* Trying to set a push-pull output pin, checking it doesn't work */ 388 gpio_set_irq(gpio, pin, 1); 389 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 390 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 391 392 /* Trying to reset a push-pull output pin, checking it doesn't work */ 393 gpio_set_irq(gpio2, pin, 0); 394 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF); 395 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin)); 396 397 /* Clean the test */ 398 gpio_writel(gpio, MODER, reset(gpio, MODER)); 399 gpio_writel(gpio2, ODR, reset(gpio2, ODR)); 400 gpio_writel(gpio2, MODER, reset(gpio2, MODER)); 401 } 402 403 static void test_open_drain(const void *data) 404 { 405 /* 406 * Test that configuring a line in open-drain output mode 407 * disconnects a pin set high externally and that the pin 408 * can't be set high externally while configured in open-drain. 409 * 410 * However a pin set low externally shouldn't be disconnected, 411 * and it can be set low externally when in open-drain mode. 412 */ 413 unsigned int pin = ((uint64_t)data) & 0xF; 414 uint32_t gpio = ((uint64_t)data) >> 32; 415 uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); 416 417 qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg"); 418 419 /* Setting a line high externally, configuring it in open-drain output */ 420 /* And checking the pin was disconnected */ 421 gpio_set_irq(gpio, pin, 1); 422 gpio_set_bit(gpio, OTYPER, pin, OTYPER_OPEN_DRAIN); 423 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); 424 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 425 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 426 427 /* Setting a line low externally, configuring it in open-drain output */ 428 /* And checking the pin wasn't disconnected */ 429 gpio_set_irq(gpio2, pin, 0); 430 gpio_set_bit(gpio2, ODR, pin, 1); 431 gpio_set_bit(gpio2, OTYPER, pin, OTYPER_OPEN_DRAIN); 432 gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT); 433 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin)); 434 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, 435 reset(gpio2, IDR) & ~(1 << pin)); 436 437 /* Trying to set a open-drain output pin, checking it doesn't work */ 438 gpio_set_irq(gpio, pin, 1); 439 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 440 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 441 442 /* Trying to reset a open-drain output pin, checking it works */ 443 gpio_set_bit(gpio, ODR, pin, 1); 444 gpio_set_irq(gpio, pin, 0); 445 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin)); 446 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, 447 reset(gpio2, IDR) & ~(1 << pin)); 448 449 /* Clean the test */ 450 disconnect_all_pins(gpio2); 451 gpio_writel(gpio2, OTYPER, reset(gpio2, OTYPER)); 452 gpio_writel(gpio2, ODR, reset(gpio2, ODR)); 453 gpio_writel(gpio2, MODER, reset(gpio2, MODER)); 454 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR)); 455 disconnect_all_pins(gpio); 456 gpio_writel(gpio, OTYPER, reset(gpio, OTYPER)); 457 gpio_writel(gpio, ODR, reset(gpio, ODR)); 458 gpio_writel(gpio, MODER, reset(gpio, MODER)); 459 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 460 } 461 462 static void test_bsrr_brr(const void *data) 463 { 464 /* 465 * Test that writing a '1' in BSS and BSRR 466 * has the desired effect on ODR. 467 * In BSRR, BSx has priority over BRx. 468 */ 469 unsigned int pin = ((uint64_t)data) & 0xF; 470 uint32_t gpio = ((uint64_t)data) >> 32; 471 472 gpio_writel(gpio, BSRR, (1 << pin)); 473 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); 474 475 gpio_writel(gpio, BSRR, (1 << (pin + NUM_GPIO_PINS))); 476 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); 477 478 gpio_writel(gpio, BSRR, (1 << pin)); 479 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); 480 481 gpio_writel(gpio, BRR, (1 << pin)); 482 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); 483 484 /* BSx should have priority over BRx */ 485 gpio_writel(gpio, BSRR, (1 << pin) | (1 << (pin + NUM_GPIO_PINS))); 486 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); 487 488 gpio_writel(gpio, BRR, (1 << pin)); 489 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); 490 491 gpio_writel(gpio, ODR, reset(gpio, ODR)); 492 } 493 494 int main(int argc, char **argv) 495 { 496 int ret; 497 498 g_test_init(&argc, &argv, NULL); 499 g_test_set_nonfatal_assertions(); 500 qtest_add_func("stm32l4x5/gpio/test_idr_reset_value", 501 test_idr_reset_value); 502 /* 503 * The inputs for the tests (gpio and pin) can be changed, 504 * but the tests don't work for pins that are high at reset 505 * (GPIOA15, GPIO13 and GPIOB5). 506 * Specifically, rising the pin then checking `get_irq()` 507 * is problematic since the pin was already high. 508 */ 509 qtest_add_data_func("stm32l4x5/gpio/test_gpioc5_output_mode", 510 (void *)((uint64_t)GPIO_C << 32 | 5), 511 test_gpio_output_mode); 512 qtest_add_data_func("stm32l4x5/gpio/test_gpioh3_output_mode", 513 (void *)((uint64_t)GPIO_H << 32 | 3), 514 test_gpio_output_mode); 515 qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode1", 516 (void *)((uint64_t)GPIO_D << 32 | 6), 517 test_gpio_input_mode); 518 qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode2", 519 (void *)((uint64_t)GPIO_C << 32 | 10), 520 test_gpio_input_mode); 521 qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down1", 522 (void *)((uint64_t)GPIO_B << 32 | 5), 523 test_pull_up_pull_down); 524 qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down2", 525 (void *)((uint64_t)GPIO_F << 32 | 1), 526 test_pull_up_pull_down); 527 qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull1", 528 (void *)((uint64_t)GPIO_G << 32 | 6), 529 test_push_pull); 530 qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull2", 531 (void *)((uint64_t)GPIO_H << 32 | 3), 532 test_push_pull); 533 qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain1", 534 (void *)((uint64_t)GPIO_C << 32 | 4), 535 test_open_drain); 536 qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain2", 537 (void *)((uint64_t)GPIO_E << 32 | 11), 538 test_open_drain); 539 qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr1", 540 (void *)((uint64_t)GPIO_A << 32 | 12), 541 test_bsrr_brr); 542 qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr2", 543 (void *)((uint64_t)GPIO_D << 32 | 0), 544 test_bsrr_brr); 545 546 qtest_start("-machine b-l475e-iot01a"); 547 ret = g_test_run(); 548 qtest_end(); 549 550 return ret; 551 } 552