Skip to content

Commit

Permalink
peci: Add timeouts to infinitely blocking waits
Browse files Browse the repository at this point in the history
Add timeouts to the legacy PECI implementation to prevent the EC locking
up when PECI stops working, such as during S0ix opportunistic suspend.

This is not the optimal solution, as PECI should not be available at all
to cause the lock up in the first place, but it at least prevents the
issue.

Signed-off-by: Tim Crawford <[email protected]>
  • Loading branch information
crawfxrd committed Oct 10, 2023
1 parent a3fb9e1 commit fcee9db
Showing 1 changed file with 33 additions and 7 deletions.
40 changes: 33 additions & 7 deletions src/board/system76/common/peci.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ int16_t peci_temp = 0;

#define PECI_TEMP(X) ((int16_t)(X))

// Maximum OOB channel response time in ms
#define PECI_ESPI_TIMEOUT 10

// clang-format off
#define FAN_POINT(T, D) { .temp = PECI_TEMP(T), .duty = PWM_DUTY(D) }
// clang-format on
Expand Down Expand Up @@ -90,9 +93,6 @@ bool peci_available(void) {

#if CONFIG_PECI_OVER_ESPI

// Maximum OOB channel response time in ms
#define PECI_ESPI_TIMEOUT 10

void peci_init(void) {}

// Returns true on success, false on error
Expand Down Expand Up @@ -291,7 +291,14 @@ void peci_init(void) {
// Returns true on success, false on error
bool peci_get_temp(int16_t *data) {
// Wait for any in-progress transaction to complete
while (HOSTAR & BIT(0)) {}
uint32_t start = time_get();
while (HOSTAR & BIT(0)) {
if ((time_get() - start) >= PECI_ESPI_TIMEOUT) {
DEBUG("%s: host timeout\n", __func__);
return false;
}
}

// Clear status
HOSTAR = HOSTAR;

Expand All @@ -309,7 +316,13 @@ bool peci_get_temp(int16_t *data) {
HOCTLR |= 1;

// Wait for command completion
while (!(HOSTAR & BIT(1))) {}
start = time_get();
while (!(HOSTAR & BIT(1))) {
if ((time_get() - start) >= PECI_ESPI_TIMEOUT) {
DEBUG("%s: command timeout\n", __func__);
return false;
}
}

uint8_t status = HOSTAR;
if (status & 0xEC) {
Expand All @@ -333,7 +346,14 @@ bool peci_get_temp(int16_t *data) {
// negative (0x1000 | status register) on PECI hardware error
int16_t peci_wr_pkg_config(uint8_t index, uint16_t param, uint32_t data) {
// Wait for any in-progress transaction to complete
while (HOSTAR & BIT(0)) {}
uint32_t start = time_get();
while (HOSTAR & BIT(0)) {
if ((time_get() - start) >= PECI_ESPI_TIMEOUT) {
DEBUG("%s: host timeout\n", __func__);
return false;
}
}

// Clear status
HOSTAR = HOSTAR;

Expand Down Expand Up @@ -365,7 +385,13 @@ int16_t peci_wr_pkg_config(uint8_t index, uint16_t param, uint32_t data) {
HOCTLR |= 1;

// Wait for command completion
while (!(HOSTAR & BIT(1))) {}
start = time_get();
while (!(HOSTAR & BIT(1))) {
if ((time_get() - start) >= PECI_ESPI_TIMEOUT) {
DEBUG("%s: command timeout\n", __func__);
return false;
}
}

uint8_t status = HOSTAR;
if (status & 0xEC) {
Expand Down

0 comments on commit fcee9db

Please sign in to comment.