|
64 | 64 | #include <fcntl.h> |
65 | 65 | #include <unistd.h> |
66 | 66 | #include <errno.h> |
| 67 | + #ifdef WOLFTPM_HAL_RESET |
| 68 | + /* GPIO character-device uAPI for optional nRST control */ |
| 69 | + #include <linux/gpio.h> |
| 70 | + #endif |
67 | 71 |
|
68 | 72 | #ifdef WOLFTPM_I2C |
69 | 73 | /* I2C - (Only tested with SLB9673 and ST33 I2C) */ |
|
415 | 419 | return ret; |
416 | 420 | } |
417 | 421 | #endif /* WOLFTPM_I2C */ |
| 422 | + |
| 423 | +#ifdef WOLFTPM_HAL_RESET |
| 424 | + /* Pulse the TPM nRST (active low) via the Linux GPIO char device (raw GPIO |
| 425 | + * v2 uAPI, no libgpiod). Default line: Raspberry Pi ST33 = GPIO24 (pin 18), |
| 426 | + * Nuvoton = GPIO4; override with WOLFTPM_RESET_GPIOCHIP / WOLFTPM_RESET_LINE. */ |
| 427 | + #ifndef WOLFTPM_RESET_GPIOCHIP |
| 428 | + #define WOLFTPM_RESET_GPIOCHIP "/dev/gpiochip0" |
| 429 | + #endif |
| 430 | + #ifndef WOLFTPM_RESET_LINE |
| 431 | + #if defined(WOLFTPM_NUVOTON) |
| 432 | + #define WOLFTPM_RESET_LINE 4 |
| 433 | + #else |
| 434 | + #define WOLFTPM_RESET_LINE 24 |
| 435 | + #endif |
| 436 | + #endif |
| 437 | + #ifndef WOLFTPM_RESET_HOLD_US |
| 438 | + #define WOLFTPM_RESET_HOLD_US 300000 /* reset asserted 300ms */ |
| 439 | + #endif |
| 440 | + #ifndef WOLFTPM_RESET_SETTLE_US |
| 441 | + #define WOLFTPM_RESET_SETTLE_US 1000000 /* TPM boot settle 1s */ |
| 442 | + #endif |
| 443 | + |
| 444 | + int TPM2_IoCb_Linux_Reset(TPM2_CTX* ctx, void* userCtx) |
| 445 | + { |
| 446 | + int ret = TPM_RC_FAILURE; |
| 447 | + int chipFd, reqFd; |
| 448 | + struct gpio_v2_line_request req; |
| 449 | + struct gpio_v2_line_values vals; |
| 450 | + |
| 451 | + (void)ctx; |
| 452 | + (void)userCtx; |
| 453 | + |
| 454 | + chipFd = open(WOLFTPM_RESET_GPIOCHIP, O_RDONLY); |
| 455 | + if (chipFd < 0) { |
| 456 | + #ifdef DEBUG_WOLFTPM |
| 457 | + printf("TPM Reset: open %s failed (errno %d)\n", |
| 458 | + WOLFTPM_RESET_GPIOCHIP, errno); |
| 459 | + #endif |
| 460 | + return TPM_RC_FAILURE; |
| 461 | + } |
| 462 | + |
| 463 | + /* Acquire the line as an output driven low (assert reset) */ |
| 464 | + XMEMSET(&req, 0, sizeof(req)); |
| 465 | + req.offsets[0] = (unsigned int)WOLFTPM_RESET_LINE; |
| 466 | + req.num_lines = 1; |
| 467 | + req.config.flags = GPIO_V2_LINE_FLAG_OUTPUT; |
| 468 | + req.config.num_attrs = 1; |
| 469 | + req.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES; |
| 470 | + req.config.attrs[0].attr.values = 0; /* drive low (assert reset) */ |
| 471 | + req.config.attrs[0].mask = 1; /* applies to line index 0 */ |
| 472 | + XMEMCPY(req.consumer, "wolfTPM-reset", sizeof("wolfTPM-reset")); |
| 473 | + |
| 474 | + if (ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req) < 0 || req.fd < 0) { |
| 475 | + #ifdef DEBUG_WOLFTPM |
| 476 | + printf("TPM Reset: GET_LINE ioctl failed (errno %d)\n", errno); |
| 477 | + #endif |
| 478 | + close(chipFd); |
| 479 | + return TPM_RC_FAILURE; |
| 480 | + } |
| 481 | + close(chipFd); |
| 482 | + reqFd = req.fd; |
| 483 | + |
| 484 | + /* Hold reset asserted, then release (drive high) and let the TPM boot */ |
| 485 | + usleep(WOLFTPM_RESET_HOLD_US); |
| 486 | + |
| 487 | + XMEMSET(&vals, 0, sizeof(vals)); |
| 488 | + vals.mask = 1; |
| 489 | + vals.bits = 1; /* drive high = release reset */ |
| 490 | + if (ioctl(reqFd, GPIO_V2_LINE_SET_VALUES_IOCTL, &vals) < 0) { |
| 491 | + #ifdef DEBUG_WOLFTPM |
| 492 | + printf("TPM Reset: SET_VALUES ioctl failed (errno %d)\n", errno); |
| 493 | + #endif |
| 494 | + } |
| 495 | + else { |
| 496 | + ret = TPM_RC_SUCCESS; |
| 497 | + #ifdef DEBUG_WOLFTPM |
| 498 | + printf("TPM Reset: pulsed nRST on %s line %d\n", |
| 499 | + WOLFTPM_RESET_GPIOCHIP, (int)WOLFTPM_RESET_LINE); |
| 500 | + #endif |
| 501 | + } |
| 502 | + |
| 503 | + usleep(WOLFTPM_RESET_SETTLE_US); |
| 504 | + close(reqFd); |
| 505 | + |
| 506 | + return ret; |
| 507 | + } |
| 508 | +#endif /* WOLFTPM_HAL_RESET */ |
| 509 | + |
418 | 510 | #endif /* __linux__ */ |
419 | 511 | #endif /* !(WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI) */ |
420 | 512 | #endif /* WOLFTPM_INCLUDE_IO_FILE */ |
|
0 commit comments