When CONFIG_SEPARATE_VERSTAGE=n, all verstage code gets linked into the appropriate calling stage (bootblock or romstage). This means that ENV_VERSTAGE is actually 0, and instead ENV_BOOTBLOCK or ENV_ROMSTAGE are 1. This keeps tripping up people who are just trying to write a simple "are we in verstage (i.e. wherever the vboot init logic runs)" check, e.g. for TPM init functions which may run in "verstage" or ramstage depending on whether vboot is enabled. Those checks will not work as intended for CONFIG_SEPARATE_VERSTAGE=n. This patch renames ENV_VERSTAGE to ENV_SEPARATE_VERSTAGE to try to clarify that this macro can really only be used to check whether code is running in a *separate* verstage, and clue people in that they may need to cover the linked-in verstage case as well. Signed-off-by: Julius Werner <jwerner@chromium.org> Change-Id: I2ff3a3c3513b3db44b3cff3d93398330cd3632ea Reviewed-on: https://review.coreboot.org/c/coreboot/+/40582 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
114 lines
2.8 KiB
C
114 lines
2.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/* This file is part of the coreboot project. */
|
|
|
|
#include <arch/acpi.h>
|
|
#include <boot/coreboot_tables.h>
|
|
#include <gpio.h>
|
|
#include <soc/gpio.h>
|
|
#include <variant/gpio.h>
|
|
#include <vendorcode/google/chromeos/chromeos.h>
|
|
#include <security/tpm/tss.h>
|
|
#include <device/device.h>
|
|
#include <intelblocks/pmclib.h>
|
|
#include <soc/pmc.h>
|
|
#include <soc/pci_devs.h>
|
|
|
|
enum rec_mode_state {
|
|
REC_MODE_UNINITIALIZED,
|
|
REC_MODE_NOT_REQUESTED,
|
|
REC_MODE_REQUESTED,
|
|
};
|
|
|
|
void fill_lb_gpios(struct lb_gpios *gpios)
|
|
{
|
|
struct lb_gpio chromeos_gpios[] = {
|
|
{-1, ACTIVE_HIGH, get_lid_switch(), "lid"},
|
|
{-1, ACTIVE_HIGH, 0, "power"},
|
|
{-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"},
|
|
{-1, ACTIVE_HIGH, 0, "EC in RW"},
|
|
};
|
|
lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
|
|
}
|
|
|
|
static int cros_get_gpio_value(int type)
|
|
{
|
|
const struct cros_gpio *cros_gpios;
|
|
size_t i, num_gpios = 0;
|
|
|
|
cros_gpios = variant_cros_gpios(&num_gpios);
|
|
|
|
for (i = 0; i < num_gpios; i++) {
|
|
const struct cros_gpio *gpio = &cros_gpios[i];
|
|
if (gpio->type == type) {
|
|
int state = gpio_get(gpio->gpio_num);
|
|
if (gpio->polarity == CROS_GPIO_ACTIVE_LOW)
|
|
return !state;
|
|
else
|
|
return state;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void mainboard_chromeos_acpi_generate(void)
|
|
{
|
|
const struct cros_gpio *cros_gpios;
|
|
size_t num_gpios = 0;
|
|
|
|
cros_gpios = variant_cros_gpios(&num_gpios);
|
|
|
|
chromeos_acpi_gpio_generate(cros_gpios, num_gpios);
|
|
}
|
|
|
|
int get_write_protect_state(void)
|
|
{
|
|
return cros_get_gpio_value(CROS_GPIO_WP);
|
|
}
|
|
|
|
int get_recovery_mode_switch(void)
|
|
{
|
|
static enum rec_mode_state saved_rec_mode = REC_MODE_UNINITIALIZED;
|
|
enum rec_mode_state state = REC_MODE_NOT_REQUESTED;
|
|
uint8_t cr50_state = 0;
|
|
|
|
/* Check cached state, since TPM will only tell us the first time */
|
|
if (saved_rec_mode != REC_MODE_UNINITIALIZED)
|
|
return saved_rec_mode == REC_MODE_REQUESTED;
|
|
|
|
/*
|
|
* Read one-time recovery request from cr50 in verstage only since
|
|
* the TPM driver won't be set up in time for other stages like romstage
|
|
* and the value from the TPM would be wrong anyway since the verstage
|
|
* read would have cleared the value on the TPM.
|
|
*
|
|
* The TPM recovery request is passed between stages through vboot data
|
|
* or cbmem depending on stage.
|
|
*/
|
|
if (ENV_SEPARATE_VERSTAGE &&
|
|
tlcl_cr50_get_recovery_button(&cr50_state) == TPM_SUCCESS &&
|
|
cr50_state)
|
|
state = REC_MODE_REQUESTED;
|
|
|
|
/* Read state from the GPIO controlled by servo. */
|
|
if (cros_get_gpio_value(CROS_GPIO_REC))
|
|
state = REC_MODE_REQUESTED;
|
|
|
|
/* Store the state in case this is called again in verstage. */
|
|
saved_rec_mode = state;
|
|
|
|
return state == REC_MODE_REQUESTED;
|
|
}
|
|
|
|
int get_lid_switch(void)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void mainboard_prepare_cr50_reset(void)
|
|
{
|
|
#if ENV_RAMSTAGE
|
|
/* Ensure system powers up after CR50 reset */
|
|
pmc_soc_set_afterg3_en(true);
|
|
#endif
|
|
}
|