soc/intel: Assert if pmc_/gpe0_dwX values are not unique

This commit adds an assertion to ensure that the values of
pmc_/gpe0_dw0, pmc_/gpe0_dw1, and pmc_/gpe0_dw2 in the
soc_intel_<soc>_config structure are unique.

This check helps to catch potential configuration errors early on,
preventing unexpected behavior during system initialization.

TEST=Built and booted normally. No assertion failure observed.

Able to catch the hidden issue due to overlapping Tier 1 GPE
configuration.

[DEBUG]  CPU: Intel(R) Core(TM) 3 N355
[DEBUG]  CPU: ID b06e0, Alderlake-N Platform, ucode: 0000001a
[DEBUG]  CPU: AES supported, TXT supported, VT supported
...
...
[DEBUG]  MCH: device id 4617 (rev 00) is Alderlake-N
[DEBUG]  PCH: device id 5481 (rev 00) is Alderlake-N SKU
[DEBUG]  IGD: device id 46d3 (rev 00) is Twinlake GT1
[EMERG]  ASSERTION ERROR: file 'src/soc/intel/alderlake/pmutil.c',
         line 163

Change-Id: I6b4f2f90a858b9ec85145bce0542f1ce61d080be
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85161
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Eric Lai <ericllai@google.com>
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
This commit is contained in:
Subrata Banik 2024-11-16 09:54:14 +05:30
commit 640a41f3ee
9 changed files with 100 additions and 0 deletions

View file

@ -154,12 +154,23 @@ uint32_t *soc_pmc_etr_addr(void)
return (uint32_t *)(soc_read_pmc_base() + ETR);
}
static void pmc_gpe0_different_values(const struct soc_intel_alderlake_config *config)
{
bool result = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) &&
(config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) &&
(config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_alderlake_config *config;
config = config_of_soc();
pmc_gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->pmc_gpe0_dw0;
*dw1 = config->pmc_gpe0_dw1;

View file

@ -138,12 +138,23 @@ void soc_clear_pm_registers(uintptr_t pmc_bar)
write32p(pmc_bar + GEN_PMCON1, gen_pmcon1 & ~RPS);
}
static void gpe0_different_values(const struct soc_intel_apollolake_config *config)
{
bool result = (config->gpe0_dw1 != config->gpe0_dw2) &&
(config->gpe0_dw1 != config->gpe0_dw3) &&
(config->gpe0_dw2 != config->gpe0_dw3);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_apollolake_config *config;
config = config_of_soc();
gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->gpe0_dw1;
*dw1 = config->gpe0_dw2;

View file

@ -148,11 +148,22 @@ uint32_t *soc_pmc_etr_addr(void)
return (uint32_t *)(soc_read_pmc_base() + ETR);
}
static void gpe0_different_values(const struct soc_intel_cannonlake_config *config)
{
bool result = (config->gpe0_dw0 != config->gpe0_dw1) &&
(config->gpe0_dw0 != config->gpe0_dw2) &&
(config->gpe0_dw1 != config->gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_cannonlake_config *config;
config = config_of_soc();
gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->gpe0_dw0;
*dw1 = config->gpe0_dw1;

View file

@ -147,12 +147,23 @@ uint32_t *soc_pmc_etr_addr(void)
return (uint32_t *)(soc_read_pmc_base() + ETR);
}
static void pmc_gpe0_different_values(const struct soc_intel_elkhartlake_config *config)
{
bool result = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) &&
(config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) &&
(config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_elkhartlake_config *config;
config = config_of_soc();
pmc_gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->pmc_gpe0_dw0;
*dw1 = config->pmc_gpe0_dw1;

View file

@ -147,12 +147,23 @@ uint32_t *soc_pmc_etr_addr(void)
return (uint32_t *)(soc_read_pmc_base() + ETR);
}
static void pmc_gpe0_different_values(const struct soc_intel_jasperlake_config *config)
{
bool result = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) &&
(config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) &&
(config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_jasperlake_config *config;
config = config_of_soc();
pmc_gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->pmc_gpe0_dw0;
*dw1 = config->pmc_gpe0_dw1;

View file

@ -150,12 +150,23 @@ uint32_t *soc_pmc_etr_addr(void)
return (uint32_t *)(soc_read_pmc_base() + ETR);
}
static void pmc_gpe0_different_values(const struct soc_intel_meteorlake_config *config)
{
bool result = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) &&
(config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) &&
(config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_meteorlake_config *config;
config = config_of_soc();
pmc_gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->pmc_gpe0_dw0;
*dw1 = config->pmc_gpe0_dw1;

View file

@ -145,6 +145,15 @@ uint32_t *soc_pmc_etr_addr(void)
return (uint32_t *)(soc_read_pmc_base() + ETR);
}
static void pmc_gpe0_different_values(const struct soc_intel_pantherlake_config *config)
{
bool result = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) &&
(config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) &&
(config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_pantherlake_config *config;
@ -154,6 +163,9 @@ void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
printk(BIOS_ERR, "Configuration could not be retrieved.\n");
return;
}
pmc_gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->pmc_gpe0_dw0;
*dw1 = config->pmc_gpe0_dw1;

View file

@ -154,12 +154,23 @@ uint32_t *soc_pmc_etr_addr(void)
return pci_mmio_config32_addr(PCH_DEVFN_PMC << 12, ETR);
}
static void gpe0_different_values(const struct soc_intel_skylake_config *config)
{
bool result = (config->gpe0_dw0 != config->gpe0_dw1) &&
(config->gpe0_dw0 != config->gpe0_dw2) &&
(config->gpe0_dw1 != config->gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_skylake_config *config;
config = config_of_soc();
gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->gpe0_dw0;
*dw1 = config->gpe0_dw1;

View file

@ -153,12 +153,23 @@ uint32_t *soc_pmc_etr_addr(void)
return (uint32_t *)(soc_read_pmc_base() + ETR);
}
static void pmc_gpe0_different_values(const struct soc_intel_tigerlake_config *config)
{
bool result = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) &&
(config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) &&
(config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2);
assert(result);
}
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
{
DEVTREE_CONST struct soc_intel_tigerlake_config *config;
config = config_of_soc();
pmc_gpe0_different_values(config);
/* Assign to out variable */
*dw0 = config->pmc_gpe0_dw0;
*dw1 = config->pmc_gpe0_dw1;