soc/intel/alderlake: Factor out A0 stepping workaround

Move the `configure_pmc_descriptor()` function to SoC scope instead of
having two identical copies in mainboard scope. Add a Kconfig option to
allow mainboards to decide whether to implement this workaround.

Change-Id: Ib99073d8da91a93fae9c0cebdfd73e39456cdaa8
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/60940
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Sheng Lean Tan <sheng.tan@9elements.com>
Reviewed-by: Subrata Banik <subratabanik@google.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
Angel Pons
2022-01-08 13:16:38 +01:00
committed by Felix Held
parent 29e33551a9
commit 5e7f90bb4c
9 changed files with 106 additions and 173 deletions

View File

@@ -1,5 +1,6 @@
config BOARD_GOOGLE_BRYA_COMMON
def_bool n
select ALDERLAKE_A0_CONFIGURE_PMC_DESCRIPTOR
select BOARD_ROMSIZE_KB_32768
select DRIVERS_GENERIC_ALC1015
select DRIVERS_GENERIC_GPIO_KEYS

View File

@@ -1,88 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <arch/mmio.h>
#include <baseboard/variants.h>
#include <bootblock_common.h>
#include <console/console.h>
#include <fmap.h>
#include <commonlib/region.h>
#include <cpu/intel/cpu_ids.h>
#include <intelblocks/pmclib.h>
#include <cf9_reset.h>
#define SI_DESC_REGION "SI_DESC"
#define SI_DESC_REGION_SZ 4096
#define PMC_DESC_7_BYTE3 0xc32
/* Flash Master 1 : HOST/BIOS */
#define FLMSTR1 0x80
/* Flash signature Offset */
#define FLASH_SIGN_OFFSET 0x10
#define FLMSTR_WR_SHIFT_V2 20
#define FLASH_VAL_SIGN 0xFF0A55A
/* It checks whether host(Flash Master 1) has write access to the Descriptor Region or not */
static int is_descriptor_writeable(uint8_t *desc)
{
/* Check flash has valid signature */
if (read32((void *)(desc + FLASH_SIGN_OFFSET)) != FLASH_VAL_SIGN) {
printk(BIOS_DEBUG, "Flash Descriptor is not valid\n");
return 0;
}
/* Check host has write access to the Descriptor Region */
if (!((read32((void *)(desc + FLMSTR1)) >> FLMSTR_WR_SHIFT_V2) & BIT(0))) {
printk(BIOS_DEBUG, "Host doesn't have write access to Descriptor Region\n");
return 0;
}
return 1;
}
/* It updates PMC Descriptor in the Descriptor Region */
static void configure_pmc_descriptor(void)
{
uint8_t si_desc_buf[SI_DESC_REGION_SZ];
struct region_device desc_rdev;
if (fmap_locate_area_as_rdev_rw(SI_DESC_REGION, &desc_rdev) < 0) {
printk(BIOS_ERR, "Failed to locate %s in the FMAP\n", SI_DESC_REGION);
return;
}
if (rdev_readat(&desc_rdev, si_desc_buf, 0, SI_DESC_REGION_SZ) != SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to read Descriptor Region from SPI Flash\n");
return;
}
if (!is_descriptor_writeable(si_desc_buf))
return;
if (si_desc_buf[PMC_DESC_7_BYTE3] != 0x40) {
printk(BIOS_DEBUG, "Update of PMC Descriptor is not required!\n");
return;
}
si_desc_buf[PMC_DESC_7_BYTE3] = 0x44;
if (rdev_eraseat(&desc_rdev, 0, SI_DESC_REGION_SZ) != SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to erase Descriptor Region area\n");
return;
}
if (rdev_writeat(&desc_rdev, si_desc_buf, 0, SI_DESC_REGION_SZ)
!= SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to update Descriptor Region\n");
return;
}
printk(BIOS_DEBUG, "Update of PMC Descriptor successful, trigger GLOBAL RESET\n");
pmc_global_reset_enable(true);
do_full_reset();
die("Failed to trigger GLOBAL RESET\n");
}
void bootblock_mainboard_early_init(void)
{
@@ -91,9 +10,3 @@ void bootblock_mainboard_early_init(void)
pads = variant_early_gpio_table(&num);
gpio_configure_pads(pads, num);
}
void bootblock_mainboard_init(void)
{
if (cpu_get_cpuid() == CPUID_ALDERLAKE_A0)
configure_pmc_descriptor();
}

View File

@@ -1,5 +1,6 @@
config BOARD_INTEL_ADLRVP_COMMON
def_bool n
select ALDERLAKE_A0_CONFIGURE_PMC_DESCRIPTOR
select BOARD_ROMSIZE_KB_32768
select DRIVERS_I2C_GENERIC
select DRIVERS_I2C_HID

View File

@@ -1,95 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/mmio.h>
#include <baseboard/variants.h>
#include <bootblock_common.h>
#include <cf9_reset.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <cpu/intel/cpu_ids.h>
#include <fmap.h>
#include <intelblocks/pmclib.h>
#define SI_DESC_REGION "SI_DESC"
#define SI_DESC_REGION_SZ 4096
#define PMC_DESC_7_BYTE3 0xc32
/* Flash Master 1 : HOST/BIOS */
#define FLMSTR1 0x80
/* Flash signature Offset */
#define FLASH_SIGN_OFFSET 0x10
#define FLMSTR_WR_SHIFT_V2 20
#define FLASH_VAL_SIGN 0xFF0A55A
/* It checks whether host(Flash Master 1) has write access to the Descriptor Region or not */
static int is_descriptor_writeable(uint8_t *desc)
{
/* Check flash has valid signature */
if (read32((void *)(desc + FLASH_SIGN_OFFSET)) != FLASH_VAL_SIGN) {
printk(BIOS_DEBUG, "Flash Descriptor is not valid\n");
return 0;
}
/* Check host has write access to the Descriptor Region */
if (!((read32((void *)(desc + FLMSTR1)) >> FLMSTR_WR_SHIFT_V2) & BIT(0))) {
printk(BIOS_DEBUG, "Host doesn't have write access to Descriptor Region\n");
return 0;
}
return 1;
}
/* It updates PMC Descriptor in the Descriptor Region */
static void configure_pmc_descriptor(void)
{
uint8_t si_desc_buf[SI_DESC_REGION_SZ];
struct region_device desc_rdev;
if (fmap_locate_area_as_rdev_rw(SI_DESC_REGION, &desc_rdev) < 0) {
printk(BIOS_ERR, "Failed to locate %s in the FMAP\n", SI_DESC_REGION);
return;
}
if (rdev_readat(&desc_rdev, si_desc_buf, 0, SI_DESC_REGION_SZ) != SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to read Descriptor Region from SPI Flash\n");
return;
}
if (!is_descriptor_writeable(si_desc_buf))
return;
if (si_desc_buf[PMC_DESC_7_BYTE3] != 0x40) {
printk(BIOS_DEBUG, "Update of PMC Descriptor is not required!\n");
return;
}
si_desc_buf[PMC_DESC_7_BYTE3] = 0x44;
if (rdev_eraseat(&desc_rdev, 0, SI_DESC_REGION_SZ) != SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to erase Descriptor Region area\n");
return;
}
if (rdev_writeat(&desc_rdev, si_desc_buf, 0, SI_DESC_REGION_SZ)
!= SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to update Descriptor Region\n");
return;
}
printk(BIOS_DEBUG, "Update of PMC Descriptor successful, trigger GLOBAL RESET\n");
pmc_global_reset_enable(true);
do_full_reset();
die("Failed to trigger GLOBAL RESET\n");
}
void bootblock_mainboard_early_init(void)
{
variant_configure_early_gpio_pads();
}
void bootblock_mainboard_init(void)
{
if (cpu_get_cpuid() == CPUID_ALDERLAKE_A0)
configure_pmc_descriptor();
}

View File

@@ -102,6 +102,15 @@ config CPU_SPECIFIC_OPTIONS
select UDK_202005_BINDING
select DISPLAY_FSP_VERSION_INFO
config ALDERLAKE_A0_CONFIGURE_PMC_DESCRIPTOR
bool
help
Alder Lake stepping A0 needs a different value for a PMC setting in
the IFD. When this option is selected, coreboot will update the IFD
value at runtime, which allows using an IFD with the new value with
any CPU stepping. To apply this workaround, the IFD region needs to
be writable by the host.
config ALDERLAKE_CAR_ENHANCED_NEM
bool
default y if !INTEL_CAR_NEM

View File

@@ -16,6 +16,7 @@ bootblock-y += bootblock/report_platform.c
bootblock-y += espi.c
bootblock-y += gpio.c
bootblock-y += p2sb.c
bootblock-$(CONFIG_ALDERLAKE_A0_CONFIGURE_PMC_DESCRIPTOR) += bootblock/pmc_descriptor.c
romstage-y += espi.c
romstage-y += gpio.c

View File

@@ -25,6 +25,9 @@ void bootblock_soc_early_init(void)
void bootblock_soc_init(void)
{
if (CONFIG(ALDERLAKE_A0_CONFIGURE_PMC_DESCRIPTOR))
configure_pmc_descriptor();
report_platform_info();
bootblock_pch_init();

View File

@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <arch/cpu.h>
#include <arch/mmio.h>
#include <cf9_reset.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <cpu/intel/cpu_ids.h>
#include <fmap.h>
#include <intelblocks/pmclib.h>
#include <soc/bootblock.h>
#include <types.h>
#define SI_DESC_REGION "SI_DESC"
#define SI_DESC_REGION_SZ 4096
#define PMC_DESC_7_BYTE3 0xc32
/* Flash Master 1 : HOST/BIOS */
#define FLMSTR1 0x80
/* Flash signature Offset */
#define FLASH_SIGN_OFFSET 0x10
#define FLMSTR_WR_SHIFT_V2 20
#define FLASH_VAL_SIGN 0xFF0A55A
/* It checks whether host(Flash Master 1) has write access to the Descriptor Region or not */
static int is_descriptor_writeable(uint8_t *desc)
{
/* Check flash has valid signature */
if (read32((void *)(desc + FLASH_SIGN_OFFSET)) != FLASH_VAL_SIGN) {
printk(BIOS_DEBUG, "Flash Descriptor is not valid\n");
return 0;
}
/* Check host has write access to the Descriptor Region */
if (!((read32((void *)(desc + FLMSTR1)) >> FLMSTR_WR_SHIFT_V2) & BIT(0))) {
printk(BIOS_DEBUG, "Host doesn't have write access to Descriptor Region\n");
return 0;
}
return 1;
}
/* It updates PMC Descriptor in the Descriptor Region */
void configure_pmc_descriptor(void)
{
uint8_t si_desc_buf[SI_DESC_REGION_SZ];
struct region_device desc_rdev;
if (cpu_get_cpuid() != CPUID_ALDERLAKE_A0)
return;
if (fmap_locate_area_as_rdev_rw(SI_DESC_REGION, &desc_rdev) < 0) {
printk(BIOS_ERR, "Failed to locate %s in the FMAP\n", SI_DESC_REGION);
return;
}
if (rdev_readat(&desc_rdev, si_desc_buf, 0, SI_DESC_REGION_SZ) != SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to read Descriptor Region from SPI Flash\n");
return;
}
if (!is_descriptor_writeable(si_desc_buf))
return;
if (si_desc_buf[PMC_DESC_7_BYTE3] != 0x40) {
printk(BIOS_DEBUG, "Update of PMC Descriptor is not required!\n");
return;
}
si_desc_buf[PMC_DESC_7_BYTE3] = 0x44;
if (rdev_eraseat(&desc_rdev, 0, SI_DESC_REGION_SZ) != SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to erase Descriptor Region area\n");
return;
}
if (rdev_writeat(&desc_rdev, si_desc_buf, 0, SI_DESC_REGION_SZ)
!= SI_DESC_REGION_SZ) {
printk(BIOS_ERR, "Failed to update Descriptor Region\n");
return;
}
printk(BIOS_DEBUG, "Update of PMC Descriptor successful, trigger GLOBAL RESET\n");
pmc_global_reset_enable(true);
do_full_reset();
die("Failed to trigger GLOBAL RESET\n");
}

View File

@@ -17,4 +17,6 @@ void bootblock_pch_init(void);
void pch_early_iorange_init(void);
void report_platform_info(void);
void configure_pmc_descriptor(void);
#endif