soc/intel/common/block/acpi: Fill PEP S0 mask on failure

There is a bug floating around where communciation with the PMC fails
after transitions through S3/S4/S5. This CL does not address that issue.
However in working with error cases presented by a failing PMC, we're
forced into an early return in read_pmc_lpm_requirements(), which sets
up _DSM buffers in the SSDT for the PEP device.

The function itself returns void, so the error is swallowed regardless.
However returning early is not the appropriate action because it causes
the size of the buffer written into the _DSM method to change. This causes
the SSDT to change size and layout across an S3 or S4 transition, which
results in mayhem in the kernel, as the kernel is not expecting these
tables to change out from under it.

Instead of returning early, it's better to simply print the error and
keep going, attaching a zeroed out buffer for the substate requirements.
This results in an empty requirements mask for all states. From what I
can see in the kernel this is no more broken than today's behavior, as
this buffer seems to only be used for printing a debugfs file.

In fact in this particular case the kernel doesn't even notice, as this
buffer is copied out at boot, and not refreshed at resume.

BUG=b:230031158
TEST=hibernate and resume on Primus4ES

Signed-off-by: Evan Green <evgreen@chromium.org>
Change-Id: Ibe35d50b350b1b96dea313dfcbd00745970c16ab
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63790
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-by: Subrata Banik <subratabanik@google.com>
This commit is contained in:
Evan Green 2022-04-22 10:55:15 -07:00 committed by Felix Held
parent e6c677ce94
commit db6d1983da
1 changed files with 0 additions and 2 deletions

View File

@ -56,8 +56,6 @@ static void read_pmc_lpm_requirements(const struct soc_pmc_lpm *lpm,
if (result != CB_SUCCESS) {
printk(BIOS_ERR, "Failed to retrieve LPM substate registers"
"from LPM, substate %zu, reg %zu\n", i, j);
free(reg);
return;
}
uint32_t *ptr = reg + i * lpm->num_req_regs + j;