3 changes: 2 additions & 1 deletion src/cpu/amd/agesa/family16kb/fixme.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/hpet.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/msr.h>
#include <cpu/amd/mtrr.h>
Expand Down Expand Up @@ -28,7 +29,7 @@ void amd_initcpuio(void)
PciData |= 1 << 7; /* set NP (non-posted) bit */
LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x80);
PciData = (0xFED00000 >> 8) | 3; /* lowest NP address is HPET at FED00000 */
PciData = (HPET_BASE_ADDRESS >> 8) | 3; /* lowest NP address is HPET at FED00000 */
LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);

/* Map the remaining PCI hole as posted MMIO */
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/amd/agesa/family16kb/model_16_init.c
Expand Up @@ -7,7 +7,6 @@
#include <cpu/amd/mtrr.h>
#include <device/device.h>
#include <cpu/x86/pae.h>
#include <cpu/x86/lapic.h>
#include <cpu/cpu.h>
#include <cpu/x86/cache.h>
#include <acpi/acpi.h>
Expand Down Expand Up @@ -57,9 +56,6 @@ static void model_16_init(struct device *dev)
/* zero the machine check error status registers */
mca_clear_status();

/* Enable the local CPU APICs */
setup_lapic();

#if CONFIG(LOGICAL_CPUS)
siblings = cpuid_ecx(0x80000008) & 0xff;

Expand Down
3 changes: 2 additions & 1 deletion src/cpu/amd/pi/00730F01/fixme.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/hpet.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/msr.h>
#include <cpu/amd/mtrr.h>
Expand Down Expand Up @@ -32,7 +33,7 @@ void amd_initcpuio(void)
LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
PciAddress.AddressValue = MAKE_SBDFO(0, 0, 0x18, 1, 0x80);
/* lowest NP address is HPET at FED00000 */
PciData = (0xFED00000 >> 8) | 3;
PciData = (HPET_BASE_ADDRESS >> 8) | 3;
LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);

/* Map the remaining PCI hole as posted MMIO */
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/amd/pi/00730F01/model_16_init.c
Expand Up @@ -11,7 +11,6 @@
#include <device/device.h>
#include <device/pci.h>
#include <cpu/x86/pae.h>
#include <cpu/x86/lapic.h>
#include <cpu/cpu.h>
#include <cpu/x86/cache.h>
#include <smp/node.h>
Expand All @@ -26,9 +25,6 @@ static void model_16_init(struct device *dev)
/* zero the machine check error status registers */
mca_clear_status();

/* Enable the local CPU APICs */
setup_lapic();

if (CONFIG(LOGICAL_CPUS)) {
siblings = cpuid_ecx(0x80000008) & 0xff;

Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/smm/Makefile.inc
@@ -1,2 +1,2 @@

ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smm_init.c
ramstage-y += smm_init.c
1 change: 1 addition & 0 deletions src/cpu/intel/common/common.h
Expand Up @@ -8,6 +8,7 @@

void set_vmx_and_lock(void);
void set_feature_ctrl_vmx(void);
void set_feature_ctrl_vmx_arg(bool enable);
void set_feature_ctrl_lock(void);

/*
Expand Down
10 changes: 7 additions & 3 deletions src/cpu/intel/common/common_init.c
Expand Up @@ -4,7 +4,6 @@
#include <arch/cpu.h>
#include <console/console.h>
#include <cpu/intel/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/msr.h>
#include "common.h"

Expand All @@ -16,11 +15,10 @@ void set_vmx_and_lock(void)
set_feature_ctrl_lock();
}

void set_feature_ctrl_vmx(void)
void set_feature_ctrl_vmx_arg(bool enable)
{
msr_t msr;
uint32_t feature_flag;
int enable = CONFIG(ENABLE_VMX);

feature_flag = cpu_get_feature_flags_ecx();
/* Check that the VMX is supported before reading or writing the MSR. */
Expand Down Expand Up @@ -62,6 +60,12 @@ void set_feature_ctrl_vmx(void)
printk(BIOS_DEBUG, "VMX status: %s\n",
enable ? "enabled" : "disabled");
}

void set_feature_ctrl_vmx(void)
{
set_feature_ctrl_vmx_arg(CONFIG(ENABLE_VMX));
}

void set_feature_ctrl_lock(void)
{
msr_t msr;
Expand Down
3 changes: 0 additions & 3 deletions src/cpu/intel/haswell/haswell_init.c
Expand Up @@ -7,7 +7,6 @@
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mp.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/speedstep.h>
Expand Down Expand Up @@ -541,9 +540,7 @@ static void cpu_core_init(struct device *cpu)
/* Clear out pending MCEs */
configure_mca();

/* Enable the local CPU APICs */
enable_lapic_tpr();
setup_lapic();

/* Set virtualization based on Kconfig option */
set_vmx_and_lock();
Expand Down
19 changes: 0 additions & 19 deletions src/cpu/intel/model_1067x/model_1067x_init.c
Expand Up @@ -4,26 +4,13 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/speedstep.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
#include <cpu/intel/smm_reloc.h>

#include "chip.h"

static void init_timer(void)
{
/* Set the APIC timer to no interrupts and periodic mode */
lapic_write(LAPIC_LVTT, (1 << 17) | (1 << 16) | (0 << 12) | (0 << 0));

/* Set the divider to 1, no divider */
lapic_write(LAPIC_TDCR, LAPIC_TDR_DIV_1);

/* Set the initial counter to 0xffffffff */
lapic_write(LAPIC_TMICT, 0xffffffff);
}

#define MSR_BBL_CR_CTL3 0x11e

static void configure_c_states(const int quad)
Expand Down Expand Up @@ -268,12 +255,6 @@ static void model_1067x_init(struct device *cpu)
fill_processor_name(processor_name);
printk(BIOS_INFO, "CPU: %s.\n", processor_name);

/* Enable the local CPU APICs */
setup_lapic();

/* Initialize the APIC timer */
init_timer();

/* Configure C States */
configure_c_states(quad);

Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/model_106cx/Kconfig
Expand Up @@ -8,6 +8,5 @@ config CPU_INTEL_MODEL_106CX
select AP_IN_SIPI_WAIT
select TSC_SYNC_MFENCE
select SUPPORT_CPU_UCODE_IN_CBFS
select SERIALIZED_SMM_INITIALIZATION
select CPU_INTEL_COMMON
select CPU_INTEL_COMMON_TIMEBASE
4 changes: 0 additions & 4 deletions src/cpu/intel/model_106cx/model_106cx_init.c
Expand Up @@ -4,7 +4,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/speedstep.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
Expand Down Expand Up @@ -67,9 +66,6 @@ static void model_106cx_init(struct device *cpu)
fill_processor_name(processor_name);
printk(BIOS_INFO, "CPU: %s.\n", processor_name);

/* Enable the local CPU APICs */
setup_lapic();

/* Configure C States */
configure_c_states();

Expand Down
1 change: 1 addition & 0 deletions src/cpu/intel/model_2065x/model_2065x.h
Expand Up @@ -20,6 +20,7 @@

#define MSR_MISC_PWR_MGMT 0x1aa
#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0)
#define MSR_TURBO_POWER_CURRENT_LIMIT 0x1ac
#define MSR_TURBO_RATIO_LIMIT 0x1ad
#define MSR_POWER_CTL 0x1fc

Expand Down
2 changes: 0 additions & 2 deletions src/cpu/intel/model_2065x/model_2065x_init.c
Expand Up @@ -91,9 +91,7 @@ static void model_2065x_init(struct device *cpu)
/* Setup Page Attribute Tables (PAT) */
// TODO set up PAT

/* Enable the local CPU APICs */
enable_lapic_tpr();
setup_lapic();

/* Set virtualization based on Kconfig option */
set_vmx_and_lock();
Expand Down
3 changes: 0 additions & 3 deletions src/cpu/intel/model_206ax/model_206ax_init.c
Expand Up @@ -7,7 +7,6 @@
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/mp.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/speedstep.h>
Expand Down Expand Up @@ -338,9 +337,7 @@ static void model_206ax_init(struct device *cpu)
/* Setup Page Attribute Tables (PAT) */
// TODO set up PAT

/* Enable the local CPU APICs */
enable_lapic_tpr();
setup_lapic();

/* Set virtualization based on Kconfig option */
set_vmx_and_lock();
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_65x/model_65x_init.c
Expand Up @@ -3,7 +3,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cache.h>
#include <cpu/intel/l2_cache.h>
Expand All @@ -19,9 +18,6 @@ static void model_65x_init(struct device *dev)
enable_cache();
x86_setup_mtrrs();
x86_mtrr_check();

/* Enable the local CPU APICs */
setup_lapic();
};

static struct device_operations cpu_dev_ops = {
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_67x/model_67x_init.c
Expand Up @@ -3,7 +3,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cache.h>
#include <cpu/intel/l2_cache.h>
Expand All @@ -22,9 +21,6 @@ static void model_67x_init(struct device *cpu)
/* Setup MTRRs */
x86_setup_mtrrs();
x86_mtrr_check();

/* Enable the local CPU APICs */
setup_lapic();
}

static struct device_operations cpu_dev_ops = {
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_68x/model_68x_init.c
Expand Up @@ -4,7 +4,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
Expand All @@ -26,9 +25,6 @@ static void model_68x_init(struct device *cpu)
/* Setup MTRRs */
x86_setup_mtrrs();
x86_mtrr_check();

/* Enable the local CPU APICs */
setup_lapic();
}

static struct device_operations cpu_dev_ops = {
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_6bx/model_6bx_init.c
Expand Up @@ -4,7 +4,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
Expand All @@ -26,9 +25,6 @@ static void model_6bx_init(struct device *cpu)
/* Setup MTRRs */
x86_setup_mtrrs();
x86_mtrr_check();

/* Enable the local CPU APICs */
setup_lapic();
}

static struct device_operations cpu_dev_ops = {
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_6ex/model_6ex_init.c
Expand Up @@ -4,7 +4,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/speedstep.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
Expand Down Expand Up @@ -106,9 +105,6 @@ static void model_6ex_init(struct device *cpu)
/* Setup Page Attribute Tables (PAT) */
// TODO set up PAT

/* Enable the local CPU APICs */
setup_lapic();

/* Configure C States */
configure_c_states();

Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_6fx/model_6fx_init.c
Expand Up @@ -4,7 +4,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/speedstep.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
Expand Down Expand Up @@ -120,9 +119,6 @@ static void model_6fx_init(struct device *cpu)
/* Setup Page Attribute Tables (PAT) */
// TODO set up PAT

/* Enable the local CPU APICs */
setup_lapic();

/* Configure C States */
configure_c_states();

Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_6xx/model_6xx_init.c
Expand Up @@ -3,7 +3,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cache.h>

Expand All @@ -16,9 +15,6 @@ static void model_6xx_init(struct device *dev)

/* Update the microcode */
intel_update_microcode_from_cbfs();

/* Enable the local CPU APICs */
setup_lapic();
};

static struct device_operations cpu_dev_ops = {
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_f2x/model_f2x_init.c
Expand Up @@ -3,7 +3,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/hyperthreading.h>
#include <cpu/intel/common/common.h>
Expand All @@ -23,9 +22,6 @@ static void model_f2x_init(struct device *cpu)
intel_update_microcode_from_cbfs();
}

/* Enable the local CPU APICs */
setup_lapic();

/* Start up my CPU siblings */
intel_sibling_init(cpu);
};
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_f3x/model_f3x_init.c
Expand Up @@ -3,7 +3,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/hyperthreading.h>
#include <cpu/intel/common/common.h>
Expand All @@ -23,9 +22,6 @@ static void model_f3x_init(struct device *cpu)
intel_update_microcode_from_cbfs();
}

/* Enable the local CPU APICs */
setup_lapic();

/* Start up my CPU siblings */
if (!CONFIG(PARALLEL_MP))
intel_sibling_init(cpu);
Expand Down
4 changes: 0 additions & 4 deletions src/cpu/intel/model_f4x/model_f4x_init.c
Expand Up @@ -2,16 +2,12 @@

#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/cache.h>

static void model_f4x_init(struct device *cpu)
{
/* Turn on caching if we haven't already */
enable_cache();

/* Enable the local CPU APICs */
setup_lapic();
};

static struct device_operations cpu_dev_ops = {
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/socket_FCBGA559/Kconfig
Expand Up @@ -9,7 +9,6 @@ config SOCKET_SPECIFIC_OPTIONS
def_bool y
select CPU_INTEL_MODEL_106CX
select MMX
select SSE
select CPU_HAS_L2_ENABLE_MSR

config DCACHE_RAM_BASE
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/socket_LGA775/Kconfig
Expand Up @@ -10,7 +10,6 @@ config SOCKET_SPECIFIC_OPTIONS
select CPU_INTEL_MODEL_F4X
select CPU_INTEL_MODEL_1067X
select MMX
select SSE
select SIPI_VECTOR_IN_ROM

config DCACHE_RAM_SIZE
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/socket_m/Kconfig
Expand Up @@ -8,7 +8,6 @@ config SOCKET_SPECIFIC_OPTIONS
select CPU_INTEL_MODEL_6EX
select CPU_INTEL_MODEL_6FX
select MMX
select SSE

config DCACHE_RAM_BASE
hex
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/socket_p/Kconfig
Expand Up @@ -3,7 +3,6 @@ config CPU_INTEL_SOCKET_P
select CPU_INTEL_MODEL_1067X
select CPU_INTEL_MODEL_6FX
select MMX
select SSE

if CPU_INTEL_SOCKET_P

Expand Down
8 changes: 8 additions & 0 deletions src/cpu/power9/Kconfig
@@ -0,0 +1,8 @@
## SPDX-License-Identifier: GPL-2.0-only

config CPU_POWER9
bool
select ARCH_BOOTBLOCK_PPC64
select ARCH_VERSTAGE_PPC64
select ARCH_ROMSTAGE_PPC64
select ARCH_RAMSTAGE_PPC64
6 changes: 6 additions & 0 deletions src/cpu/power9/Makefile.inc
@@ -0,0 +1,6 @@
## SPDX-License-Identifier: GPL-2.0-or-later

ramstage-y += power9.c

bootblock-y += scom.c
romstage-y += scom.c
20 changes: 20 additions & 0 deletions src/cpu/power9/power9.c
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <cpu/cpu.h>
#include <device/device.h>

static void power9_cpu_init(struct device *dev)
{
}

static struct device_operations cpu_dev_ops = {
.init = power9_cpu_init,
};

static const struct cpu_driver driver __cpu_driver = {
.ops = &cpu_dev_ops,
};

struct chip_operations cpu_power8_qemu_ops = {
CHIP_NAME("POWER9 CPU")
};
135 changes: 135 additions & 0 deletions src/cpu/power9/scom.c
@@ -0,0 +1,135 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <cpu/power/scom.h>
#include <cpu/power/spr.h> // HMER
#include <console/console.h>

#define XSCOM_DATA_IND_READ PPC_BIT(0)
#define XSCOM_DATA_IND_COMPLETE PPC_BIT(32)
#define XSCOM_DATA_IND_ERR PPC_BITMASK(33, 35)
#define XSCOM_DATA_IND_DATA PPC_BITMASK(48, 63)
#define XSCOM_DATA_IND_FORM1_DATA PPC_BITMASK(12, 63)
#define XSCOM_IND_MAX_RETRIES 10

#define XSCOM_RCVED_STAT_REG 0x00090018
#define XSCOM_LOG_REG 0x00090012
#define XSCOM_ERR_REG 0x00090013

uint64_t read_scom_direct(uint64_t reg_address)
{
uint64_t val;
uint64_t hmer = 0;
do {
/*
* Clearing HMER on every SCOM access seems to slow down CCS up
* to a point where it starts hitting timeout on "less ideal"
* DIMMs for write centering. Clear it only if this do...while
* executes more than once.
*/
if ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED)
clear_hmer();

eieio();
asm volatile(
"ldcix %0, %1, %2" :
"=r"(val) :
"b"(MMIO_GROUP0_CHIP0_SCOM_BASE_ADDR),
"r"(reg_address << 3));
eieio();
hmer = read_hmer();
} while ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED);

if (hmer & SPR_HMER_XSCOM_STATUS) {
reset_scom_engine();
/*
* All F's are returned in case of error, but code polls for a set bit
* after changes that can make such error appear (e.g. clock settings).
* Return 0 so caller won't have to test for all F's in that case.
*/
return 0;
}
return val;
}

void write_scom_direct(uint64_t reg_address, uint64_t data)
{
uint64_t hmer = 0;
do {
/* See comment in read_scom_direct() */
if ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED)
clear_hmer();

eieio();
asm volatile(
"stdcix %0, %1, %2"::
"r"(data),
"b"(MMIO_GROUP0_CHIP0_SCOM_BASE_ADDR),
"r"(reg_address << 3));
eieio();
hmer = read_hmer();
} while ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED);

if (hmer & SPR_HMER_XSCOM_STATUS)
reset_scom_engine();
}

void write_scom_indirect(uint64_t reg_address, uint64_t value)
{
uint64_t addr;
uint64_t data;
addr = reg_address & 0x7FFFFFFF;
data = reg_address & XSCOM_ADDR_IND_ADDR;
data |= value & XSCOM_ADDR_IND_DATA;

write_scom_direct(addr, data);

for (int retries = 0; retries < XSCOM_IND_MAX_RETRIES; ++retries) {
data = read_scom_direct(addr);
if ((data & XSCOM_DATA_IND_COMPLETE) && ((data & XSCOM_DATA_IND_ERR) == 0)) {
return;
} else if (data & XSCOM_DATA_IND_COMPLETE) {
printk(BIOS_EMERG, "SCOM WR error %16.16llx = %16.16llx : %16.16llx\n",
reg_address, value, data);
}
// TODO: delay?
}
}

uint64_t read_scom_indirect(uint64_t reg_address)
{
uint64_t addr;
uint64_t data;
addr = reg_address & 0x7FFFFFFF;
data = XSCOM_DATA_IND_READ | (reg_address & XSCOM_ADDR_IND_ADDR);

write_scom_direct(addr, data);

for (int retries = 0; retries < XSCOM_IND_MAX_RETRIES; ++retries) {
data = read_scom_direct(addr);
if ((data & XSCOM_DATA_IND_COMPLETE) && ((data & XSCOM_DATA_IND_ERR) == 0)) {
break;
} else if (data & XSCOM_DATA_IND_COMPLETE) {
printk(BIOS_EMERG, "SCOM RD error %16.16llx : %16.16llx\n",
reg_address, data);
}
// TODO: delay?
}

return data & XSCOM_DATA_IND_DATA;
}

/* This function should be rarely called, don't make it inlined */
void reset_scom_engine(void)
{
/*
* With cross-CPU SCOM accesses, first register should be cleared on the
* executing CPU, the other two on target CPU. In that case it may be
* necessary to do the remote writes in assembly directly to skip checking
* HMER and possibly end in a loop.
*/
write_scom_direct(XSCOM_RCVED_STAT_REG, 0);
write_scom_direct(XSCOM_LOG_REG, 0);
write_scom_direct(XSCOM_ERR_REG, 0);
clear_hmer();
eieio();
}
2 changes: 0 additions & 2 deletions src/cpu/qemu-x86/qemu.c
Expand Up @@ -2,11 +2,9 @@

#include <cpu/cpu.h>
#include <device/device.h>
#include <cpu/x86/lapic.h>

static void qemu_cpu_init(struct device *dev)
{
setup_lapic();
}

static struct device_operations cpu_dev_ops = {
Expand Down
19 changes: 7 additions & 12 deletions src/cpu/x86/Kconfig
Expand Up @@ -114,7 +114,13 @@ config SMM_TSEG
default y
depends on !(NO_SMM || SMM_ASEG)

if SMM_TSEG
config SMM_LEGACY_ASEG
bool
default y if HAVE_SMI_HANDLER && SMM_ASEG && LEGACY_SMP_INIT
help
SMM support without PARALLEL_MP, to be deprecated.

if HAVE_SMI_HANDLER && !SMM_LEGACY_ASEG

config SMM_MODULE_HEAP_SIZE
hex
Expand Down Expand Up @@ -147,17 +153,6 @@ config SMM_LAPIC_REMAP_MITIGATION
default y if NORTHBRIDGE_INTEL_IRONLAKE
default n

config SERIALIZED_SMM_INITIALIZATION
bool
default n
help
On some CPUs, there is a race condition in SMM.
This can occur when both hyperthreads change SMM state
variables in parallel without coordination.
Setting this option serializes the SMM initialization
to avoid an ugly hang in the boot process at the cost
of a slightly longer boot time.

config X86_AMD_FIXED_MTRRS
bool
default n
Expand Down
3 changes: 3 additions & 0 deletions src/cpu/x86/Makefile.inc
Expand Up @@ -8,7 +8,10 @@ all-$(CONFIG_ARCH_ALL_STAGES_X86_64) += 64bit/mode_switch.S

subdirs-$(CONFIG_PARALLEL_MP) += name
ramstage-$(CONFIG_PARALLEL_MP) += mp_init.c

ramstage-y += backup_default_smm.c
ramstage-y += smi_trigger.c
smm-y += smi_trigger.c

subdirs-$(CONFIG_CPU_INTEL_COMMON_SMM) += ../intel/smm

Expand Down
66 changes: 38 additions & 28 deletions src/cpu/x86/lapic/lapic.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <cpu/cpu.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/lapic_def.h>
Expand All @@ -10,23 +11,52 @@

void enable_lapic(void)
{
uintptr_t apic_base;
bool use_x2apic;
msr_t msr;

msr = rdmsr(LAPIC_BASE_MSR);
msr.hi &= 0xffffff00;
msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
msr.lo |= LAPIC_DEFAULT_BASE;
msr.lo |= LAPIC_BASE_MSR_ENABLE;
wrmsr(LAPIC_BASE_MSR, msr);
if (!(msr.lo & LAPIC_BASE_MSR_ENABLE)) {
msr.hi &= 0xffffff00;
msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
msr.lo |= LAPIC_DEFAULT_BASE;
msr.lo |= LAPIC_BASE_MSR_ENABLE;
wrmsr(LAPIC_BASE_MSR, msr);
msr = rdmsr(LAPIC_BASE_MSR);
}

ASSERT(msr.lo & LAPIC_BASE_MSR_ENABLE);

apic_base = msr.lo & LAPIC_BASE_MSR_ADDR_MASK;
ASSERT(apic_base == LAPIC_DEFAULT_BASE);

if (CONFIG(XAPIC_ONLY)) {
use_x2apic = false;
} else {
use_x2apic = !!(cpu_get_feature_flags_ecx() & CPUID_X2APIC);
ASSERT(CONFIG(X2APIC_RUNTIME) || use_x2apic);
}

if (use_x2apic == !!(msr.lo & LAPIC_BASE_MSR_X2APIC_MODE)) {
printk(BIOS_INFO, "LAPIC 0x%x in %s mode.\n", lapicid(),
use_x2apic ? "X2APIC" : "XAPIC");
} else if (use_x2apic) {
msr.lo |= LAPIC_BASE_MSR_X2APIC_MODE;
wrmsr(LAPIC_BASE_MSR, msr);
msr = rdmsr(LAPIC_BASE_MSR);
ASSERT(!!(msr.lo & LAPIC_BASE_MSR_X2APIC_MODE));
printk(BIOS_INFO, "LAPIC 0x%x switched to X2APIC mode.\n", lapicid());
} else {
die("Switching from X2APIC to XAPIC mode is not implemented.");
}

printk(BIOS_INFO, "Setting up local APIC 0x%x\n", lapicid());
}

void disable_lapic(void)
{
msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR);
msr.lo &= ~LAPIC_BASE_MSR_ENABLE;
msr.lo &= ~(LAPIC_BASE_MSR_ENABLE | LAPIC_BASE_MSR_X2APIC_MODE);
wrmsr(LAPIC_BASE_MSR, msr);
}

Expand All @@ -35,13 +65,7 @@ uintptr_t cpu_get_lapic_addr(void)
return LAPIC_DEFAULT_BASE;
}

/* See if I need to initialize the local APIC */
static int need_lapic_init(void)
{
return CONFIG(SMP) || CONFIG(IOAPIC);
}

static void lapic_virtual_wire_mode_init(void)
void setup_lapic_interrupts(void)
{
/*
* Set Task Priority to 'accept all'.
Expand All @@ -64,17 +88,3 @@ static void lapic_virtual_wire_mode_init(void)

lapic_update32(LAPIC_LVT1, ~mask, LAPIC_DELIVERY_MODE_NMI);
}

void setup_lapic(void)
{
/* Enable the local APIC */
if (need_lapic_init())
enable_lapic();
else if (!CONFIG(UDELAY_LAPIC))
disable_lapic();

/* This programming is for PIC mode i8259 interrupts to be delivered to CPU
while LAPIC is enabled. */
if (need_lapic_init())
lapic_virtual_wire_mode_init();
}
59 changes: 13 additions & 46 deletions src/cpu/x86/lapic/lapic_cpu_init.c
Expand Up @@ -298,6 +298,11 @@ asmlinkage void secondary_cpu_init(unsigned int index)
cr4_val |= (CR4_OSFXSR | CR4_OSXMMEXCPT);
write_cr4(cr4_val);
#endif

/* Ensure the local APIC is enabled */
enable_lapic();
setup_lapic_interrupts();

cpu_initialize(index);

spin_unlock(&start_cpu_lock);
Expand Down Expand Up @@ -332,37 +337,6 @@ static void start_other_cpus(struct bus *cpu_bus, struct device *bsp_cpu)

}

static void smm_other_cpus(struct bus *cpu_bus, struct device *bsp_cpu)
{
struct device *cpu;
int pre_count = atomic_read(&active_cpus);

/* Loop through the cpus once to let them run through SMM relocator */

for (cpu = cpu_bus->children; cpu; cpu = cpu->sibling) {
if (cpu->path.type != DEVICE_PATH_APIC)
continue;

printk(BIOS_ERR, "considering CPU 0x%02x for SMM init\n",
cpu->path.apic.apic_id);

if (cpu == bsp_cpu)
continue;

if (!cpu->enabled)
continue;

if (!start_cpu(cpu))
/* Record the error in cpu? */
printk(BIOS_ERR, "CPU 0x%02x would not start!\n",
cpu->path.apic.apic_id);

/* FIXME: endless loop */
while (atomic_read(&active_cpus) != pre_count)
;
}
}

static void wait_other_cpus_stop(struct bus *cpu_bus)
{
struct device *cpu;
Expand Down Expand Up @@ -407,8 +381,12 @@ void initialize_cpus(struct bus *cpu_bus)
info = cpu_info();

/* Ensure the local APIC is enabled */
if (is_smp_boot())
if (is_smp_boot()) {
enable_lapic();
setup_lapic_interrupts();
} else {
disable_lapic();
}

/* Get the device path of the boot CPU */
cpu_path.type = DEVICE_PATH_APIC;
Expand All @@ -422,7 +400,7 @@ void initialize_cpus(struct bus *cpu_bus)
if (is_smp_boot())
copy_secondary_start_to_lowest_1M();

if (!CONFIG(SERIALIZED_SMM_INITIALIZATION))
if (CONFIG(SMM_LEGACY_ASEG))
smm_init();

/* Initialize the bootstrap processor */
Expand All @@ -435,19 +413,8 @@ void initialize_cpus(struct bus *cpu_bus)
if (is_smp_boot())
wait_other_cpus_stop(cpu_bus);

if (CONFIG(SERIALIZED_SMM_INITIALIZATION)) {
/* At this point, all APs are sleeping:
* smm_init() will queue a pending SMI on all cpus
* and smm_other_cpus() will start them one by one */
smm_init();

if (is_smp_boot()) {
last_cpu_index = 0;
smm_other_cpus(cpu_bus, info->cpu);
}
}

smm_init_completion();
if (CONFIG(SMM_LEGACY_ASEG))
smm_init_completion();

if (is_smp_boot())
recover_lowest_1M();
Expand Down
4 changes: 2 additions & 2 deletions src/cpu/x86/lapic/lapic_cpu_stop.c
Expand Up @@ -55,15 +55,15 @@ void stop_this_cpu(void)
printk(BIOS_DEBUG, "CPU %ld going down...\n", id);

/* send an LAPIC INIT to myself */
lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT, id);
lapic_send_ipi_self(LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT);
wait_for_ipi_completion_without_printk(timeout_100ms);

mdelay(10);

dprintk(BIOS_SPEW, "Deasserting INIT.\n");

/* Deassert the LAPIC INIT */
lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT, id);
lapic_send_ipi_self(LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
wait_for_ipi_completion_without_printk(timeout_100ms);

halt();
Expand Down
41 changes: 17 additions & 24 deletions src/cpu/x86/mp_init.c
Expand Up @@ -185,6 +185,7 @@ static void asmlinkage ap_init(void)

/* Ensure the local APIC is enabled */
enable_lapic();
setup_lapic_interrupts();

info->cpu = cpus_dev[info->index];

Expand Down Expand Up @@ -423,8 +424,7 @@ static enum cb_err send_sipi_to_aps(int ap_count, atomic_t *num_aps, int sipi_ve
printk(BIOS_DEBUG, "done.\n");
}

lapic_send_ipi(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_STARTUP | sipi_vector,
0);
lapic_send_ipi_others(LAPIC_INT_ASSERT | LAPIC_DM_STARTUP | sipi_vector);
printk(BIOS_DEBUG, "Waiting for SIPI to complete...\n");
if (apic_wait_timeout(10000 /* 10 ms */, 50 /* us */) != CB_SUCCESS) {
printk(BIOS_ERR, "timed out.\n");
Expand Down Expand Up @@ -454,9 +454,6 @@ static enum cb_err start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_ap

printk(BIOS_DEBUG, "Attempting to start %d APs\n", ap_count);

int x2apic_mode = is_x2apic_mode();
printk(BIOS_DEBUG, "Starting CPUs in %s mode\n", x2apic_mode ? "x2apic" : "xapic");

if (lapic_busy()) {
printk(BIOS_DEBUG, "Waiting for ICR not to be busy...\n");
if (apic_wait_timeout(1000 /* 1 ms */, 50) != CB_SUCCESS) {
Expand All @@ -467,7 +464,7 @@ static enum cb_err start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_ap
}

/* Send INIT IPI to all but self. */
lapic_send_ipi(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT, 0);
lapic_send_ipi_others(LAPIC_INT_ASSERT | LAPIC_DM_INIT);

if (!CONFIG(X86_INIT_NEED_1_SIPI)) {
printk(BIOS_DEBUG, "Waiting for 10ms after sending INIT.\n");
Expand Down Expand Up @@ -547,6 +544,7 @@ static void init_bsp(struct bus *cpu_bus)

/* Ensure the local APIC is enabled */
enable_lapic();
setup_lapic_interrupts();

/* Set the device path of the boot CPU. */
cpu_path.type = DEVICE_PATH_APIC;
Expand Down Expand Up @@ -652,7 +650,7 @@ void smm_initiate_relocation_parallel(void)
printk(BIOS_DEBUG, "done.\n");
}

lapic_send_ipi(LAPIC_INT_ASSERT | LAPIC_DM_SMI, lapicid());
lapic_send_ipi_self(LAPIC_INT_ASSERT | LAPIC_DM_SMI);

if (lapic_busy()) {
if (apic_wait_timeout(1000 /* 1 ms */, 100 /* us */) != CB_SUCCESS) {
Expand Down Expand Up @@ -762,22 +760,17 @@ static void adjust_smm_apic_id_map(struct smm_loader_params *smm_params)
}

static enum cb_err install_relocation_handler(int num_cpus, size_t real_save_state_size,
size_t save_state_size, uintptr_t perm_smbase)
size_t save_state_size)
{
struct smm_loader_params smm_params = {
.per_cpu_stack_size = CONFIG_SMM_STUB_STACK_SIZE,
.num_concurrent_stacks = num_cpus,
.num_cpus = num_cpus,
.real_cpu_save_state_size = real_save_state_size,
.per_cpu_save_state_size = save_state_size,
.num_concurrent_save_states = 1,
.handler = smm_do_relocation,
};

/* Allow callback to override parameters. */
if (mp_state.ops.adjust_smm_params != NULL)
mp_state.ops.adjust_smm_params(&smm_params, 0);

if (smm_setup_relocation_handler((void *)perm_smbase, &smm_params)) {
if (smm_setup_relocation_handler(&smm_params)) {
printk(BIOS_ERR, "%s: smm setup failed\n", __func__);
return CB_ERR;
}
Expand All @@ -800,20 +793,15 @@ static enum cb_err install_permanent_handler(int num_cpus, uintptr_t smbase,
* size and save state size for each CPU.
*/
struct smm_loader_params smm_params = {
.per_cpu_stack_size = CONFIG_SMM_MODULE_STACK_SIZE,
.num_concurrent_stacks = num_cpus,
.num_cpus = num_cpus,
.real_cpu_save_state_size = real_save_state_size,
.per_cpu_save_state_size = save_state_size,
.num_concurrent_save_states = num_cpus,
};

/* Allow callback to override parameters. */
if (mp_state.ops.adjust_smm_params != NULL)
mp_state.ops.adjust_smm_params(&smm_params, 1);

printk(BIOS_DEBUG, "Installing permanent SMM handler to 0x%08lx\n", smbase);

if (smm_load_module((void *)smbase, smsize, &smm_params))
if (smm_load_module(smbase, smsize, &smm_params))
return CB_ERR;

adjust_smm_apic_id_map(&smm_params);
Expand All @@ -831,10 +819,15 @@ static void load_smm_handlers(void)
if (!is_smm_enabled())
return;

if (smm_setup_stack(mp_state.perm_smbase, mp_state.perm_smsize, mp_state.cpu_count,
CONFIG_SMM_MODULE_STACK_SIZE)) {
printk(BIOS_ERR, "Unable to install SMM relocation handler.\n");
smm_disable();
}

/* Install handlers. */
if (install_relocation_handler(mp_state.cpu_count, real_save_state_size,
smm_save_state_size, mp_state.perm_smbase) !=
CB_SUCCESS) {
smm_save_state_size) != CB_SUCCESS) {
printk(BIOS_ERR, "Unable to install SMM relocation handler.\n");
smm_disable();
}
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/x86/mtrr/mtrr.c
Expand Up @@ -409,7 +409,7 @@ static void prep_var_mtrr(struct var_mtrr_state *var_state,
resource_t mask;

if (var_state->mtrr_index >= total_mtrrs) {
printk(BIOS_ERR, "ERROR: Not enough MTRRs available! MTRR index is %d with %d MTRRs in total.\n",
printk(BIOS_ERR, "Not enough MTRRs available! MTRR index is %d with %d MTRRs in total.\n",
var_state->mtrr_index, total_mtrrs);
return;
}
Expand Down
File renamed without changes.
12 changes: 8 additions & 4 deletions src/cpu/x86/smm/Makefile.inc
@@ -1,7 +1,6 @@
## SPDX-License-Identifier: GPL-2.0-only

ramstage-y += smm_module_loader.c
ramstage-y += smi_trigger.c

ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
$(eval $(call create_class_compiler,smm,x86_32))
Expand Down Expand Up @@ -29,14 +28,17 @@ ramstage-srcs += $(obj)/cpu/x86/smm/smm.manual
endif

smm-y += save_state.c
smm-y += smi_trigger.c

ifeq ($(CONFIG_SMM_TSEG),y)

ramstage-y += tseg_region.c
romstage-y += tseg_region.c
postcar-y += tseg_region.c

endif

ifeq ($(CONFIG_PARALLEL_MP),y)

smmstub-y += smm_stub.S

smm-y += smm_module_handler.c
Expand Down Expand Up @@ -73,7 +75,9 @@ endif
$(obj)/smm/smm: $(obj)/smm/smm.elf.rmod
$(OBJCOPY_smm) -O binary $< $@

else # CONFIG_SMM_TSEG
endif

ifeq ($(CONFIG_SMM_LEGACY_ASEG),y)

smm-y += smm.ld

Expand All @@ -85,4 +89,4 @@ $(obj)/smm/smm: $(obj)/smm/smm.o $(call src-to-obj,smm,$(src)/cpu/x86/smm/smm.ld
smm-y += smmhandler.S
smm-y += smihandler.c

endif # CONFIG_SMM_TSEG
endif # CONFIG_SMM_LEGACY_ASEG
4 changes: 2 additions & 2 deletions src/cpu/x86/smm/smm_module_handler.c
Expand Up @@ -193,8 +193,8 @@ RMODULE_ENTRY(smm_handler_start);
* are linked at. */
int __weak mainboard_io_trap_handler(int smif) { return 0; }
void __weak cpu_smi_handler(void) {}
void __weak northbridge_smi_handler() {}
void __weak southbridge_smi_handler() {}
void __weak northbridge_smi_handler(void) {}
void __weak southbridge_smi_handler(void) {}
void __weak mainboard_smi_gpi(u32 gpi_sts) {}
int __weak mainboard_smi_apmc(u8 data) { return 0; }
void __weak mainboard_smi_sleep(u8 slp_typ) {}
Expand Down
261 changes: 164 additions & 97 deletions src/cpu/x86/smm/smm_module_loader.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/cpu/x86/smm/tseg_region.c
Expand Up @@ -61,7 +61,7 @@ int smm_subregion(int sub, uintptr_t *start, size_t *size)
void stage_cache_external_region(void **base, size_t *size)
{
if (smm_subregion(SMM_SUBREGION_CACHE, (uintptr_t *)base, size)) {
printk(BIOS_ERR, "ERROR: No cache SMM subregion.\n");
printk(BIOS_ERR, "No cache SMM subregion.\n");
*base = NULL;
*size = 0;
}
Expand Down
37 changes: 29 additions & 8 deletions src/device/Kconfig
Expand Up @@ -527,14 +527,6 @@ config AZALIA_PLUGIN_SUPPORT
bool
default n

config AZALIA_MAX_CODECS
int
depends on AZALIA_PLUGIN_SUPPORT
default 3
range 1 15
help
The maximum number of codecs supported on a single HD Audio controller.

config AZALIA_LOCK_DOWN_R_WO_GCAP
def_bool n
depends on AZALIA_PLUGIN_SUPPORT
Expand Down Expand Up @@ -632,6 +624,35 @@ config PCIEXP_L1_SUB_STATE
help
Detect and enable ASPM on PCIe links.

config PCIEXP_SUPPORT_RESIZABLE_BARS
prompt "Support PCIe Resizable BARs"
bool
depends on (ECAM_MMCONF_SUPPORT || PCI_IO_CFG_EXT)
default n
help
When enabled, this will check PCIe devices for Resizable BAR support,
and if found, will use this to discover the preferred BAR sizes of
the device in preference over the traditional moving bits method. The
amount of address space given out to devices in this manner (since
it can range up to 8 EB) can be limited with the
PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS Kconfig setting below.

if PCIEXP_SUPPORT_RESIZABLE_BARS

config PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS
int "Bits of address space to give to Resizable BARs"
range 20 63 # 1 MiB - 8 EiB
default 29 # 512 MiB
help
This is the maximum number of bits of address space to allocate for
PCIe devices with resizable BARs. For instance, if a device requests
30 bits of address space (1 GiB), but this field is set to 29, then
the device will only be allocated 29 bits worth of address space (512
MiB). Valid values range from 20 (1 MiB) to 63 (8 EiB); these come
from the Resizable BAR portion of the PCIe spec (7.8.6).

endif # PCIEXP_SUPPORT_RESIZABLE_BARS

config PCIEXP_HOTPLUG
prompt "Enable PCIe Hotplug Support"
bool
Expand Down
11 changes: 5 additions & 6 deletions src/device/azalia_device.c
Expand Up @@ -50,7 +50,6 @@ int azalia_exit_reset(u8 *base)
static u16 codec_detect(u8 *base)
{
struct stopwatch sw;
const u16 codec_mask = (1 << CONFIG_AZALIA_MAX_CODECS) - 1;
u16 reg16;

if (azalia_exit_reset(base) < 0)
Expand All @@ -61,9 +60,9 @@ static u16 codec_detect(u8 *base)
write16(base + HDA_GCAP_REG, read16(base + HDA_GCAP_REG));
}

/* clear STATESTS bits (BAR + 0xe)[2:0] */
/* clear STATESTS bits (BAR + 0x0e)[14:0] */
reg16 = read16(base + HDA_STATESTS_REG);
reg16 |= codec_mask;
reg16 |= 0x7fff;
write16(base + HDA_STATESTS_REG, reg16);

/* Wait for readback of register to
Expand All @@ -86,9 +85,9 @@ static u16 codec_detect(u8 *base)
if (azalia_exit_reset(base) < 0)
goto no_codec;

/* Read in Codec location (BAR + 0xe)[2..0] */
/* Read in Codec location (BAR + 0x0e)[14:0] */
reg16 = read16(base + HDA_STATESTS_REG);
reg16 &= codec_mask;
reg16 &= 0x7fff;
if (!reg16)
goto no_codec;

Expand Down Expand Up @@ -274,7 +273,7 @@ void azalia_codecs_init(u8 *base, u16 codec_mask)
{
int i;

for (i = CONFIG_AZALIA_MAX_CODECS - 1; i >= 0; i--) {
for (i = 14; i >= 0; i--) {
if (codec_mask & (1 << i))
azalia_codec_init(base, i, cim_verb_data, cim_verb_data_size);
}
Expand Down
9 changes: 4 additions & 5 deletions src/device/dram/ddr2.c
Expand Up @@ -322,22 +322,21 @@ int spd_decode_ddr2(struct dimm_attr_ddr2_st *dimm, u8 spd[SPD_SIZE_MAX_DDR2])
printram("SPD contains 0x%02x bytes\n", spd_size);

if (spd_size < 64 || eeprom_size < 64) {
printk(BIOS_WARNING, "ERROR: SPD to small\n");
printk(BIOS_ERR, "SPD too small\n");
dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
return SPD_STATUS_INVALID;
}

if (spd_ddr2_calc_checksum(spd, spd_size) != spd[63]) {
printk(BIOS_WARNING, "ERROR: SPD checksum error\n");
printk(BIOS_ERR, "SPD checksum error\n");
dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
return SPD_STATUS_CRC_ERROR;
}
dimm->checksum = spd[63];

reg8 = spd[62];
if ((reg8 & 0xf0) != 0x10) {
printk(BIOS_WARNING,
"ERROR: Unsupported SPD revision %01x.%01x\n",
printk(BIOS_ERR, "Unsupported SPD revision %01x.%01x\n",
reg8 >> 4, reg8 & 0xf);
dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
return SPD_STATUS_INVALID;
Expand All @@ -348,7 +347,7 @@ int spd_decode_ddr2(struct dimm_attr_ddr2_st *dimm, u8 spd[SPD_SIZE_MAX_DDR2])
reg8 = spd[2];
printram(" Type : 0x%02x\n", reg8);
if (reg8 != 0x08) {
printk(BIOS_WARNING, "ERROR: Unsupported SPD type %x\n", reg8);
printk(BIOS_ERR, "Unsupported SPD type %x\n", reg8);
dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
return SPD_STATUS_INVALID;
}
Expand Down
2 changes: 1 addition & 1 deletion src/device/dram/ddr4.c
Expand Up @@ -143,7 +143,7 @@ uint16_t ddr4_speed_mhz_to_reported_mts(uint16_t speed_mhz)
return speed_attr->reported_mts;
}
}
printk(BIOS_ERR, "ERROR: DDR4 speed of %d MHz is out of range\n", speed_mhz);
printk(BIOS_ERR, "DDR4 speed of %d MHz is out of range\n", speed_mhz);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/device/dram/lpddr4.c
Expand Up @@ -94,6 +94,6 @@ uint16_t lpddr4_speed_mhz_to_reported_mts(uint16_t speed_mhz)
return speed_attr->reported_mts;
}
}
printk(BIOS_ERR, "ERROR: LPDDR4 speed of %d MHz is out of range\n", speed_mhz);
printk(BIOS_ERR, "LPDDR4 speed of %d MHz is out of range\n", speed_mhz);
return 0;
}
2 changes: 1 addition & 1 deletion src/device/oprom/realmode/x86.c
Expand Up @@ -233,7 +233,7 @@ static u8 vbe_get_ctrl_info(vbe_info_block *info)
0x0000, buffer_seg, buffer_adr);
/* If the VBE function completed successfully, 0x0 is returned in AH */
if (X86_AH) {
printk(BIOS_WARNING, "Warning: Error from VGA BIOS in %s\n", __func__);
printk(BIOS_WARNING, "Error from VGA BIOS in %s\n", __func__);
return 1;
}
memcpy(info, buffer, sizeof(vbe_info_block));
Expand Down
2 changes: 1 addition & 1 deletion src/device/oprom/yabel/pmm.c
Expand Up @@ -104,7 +104,7 @@ u8 pmm_setup(u16 segment, u16 offset)
/* handle the selfdefined interrupt, this is executed, when the PMM Entry Point
* is executed, it must handle all PMM requests
*/
void pmm_handleInt()
void pmm_handleInt(void)
{
u32 rval = 0;
u16 function, flags;
Expand Down
149 changes: 142 additions & 7 deletions src/device/pci_device.c
Expand Up @@ -19,6 +19,7 @@
#include <device/pci_ids.h>
#include <device/pcix.h>
#include <device/pciexp.h>
#include <lib.h>
#include <pc80/i8259.h>
#include <security/vboot/vbnv.h>
#include <timestamp.h>
Expand Down Expand Up @@ -309,6 +310,127 @@ struct msix_entry *pci_msix_get_table(struct device *dev)
return (struct msix_entry *)((uintptr_t)res->base + offset);
}

static unsigned int get_rebar_offset(const struct device *dev, unsigned long index)
{
uint32_t offset = pciexp_find_extended_cap(dev, PCIE_EXT_CAP_RESIZABLE_BAR);
if (!offset)
return 0;

/* Convert PCI_BASE_ADDRESS_0, ..._1, ..._2 into 0, 1, 2... */
const unsigned int find_bar_idx = (index - PCI_BASE_ADDRESS_0) /
sizeof(uint32_t);

/* Although all of the Resizable BAR Control Registers contain an
"NBARs" field, it is only valid in the Control Register for BAR 0 */
const uint32_t rebar_ctrl0 = pci_read_config32(dev, offset + PCI_REBAR_CTRL_OFFSET);
const unsigned int nbars = (rebar_ctrl0 & PCI_REBAR_CTRL_NBARS_MASK) >>
PCI_REBAR_CTRL_NBARS_SHIFT;

for (unsigned int i = 0; i < nbars; i++, offset += sizeof(uint64_t)) {
const uint32_t rebar_ctrl = pci_read_config32(
dev, offset + PCI_REBAR_CTRL_OFFSET);
const uint32_t bar_idx = rebar_ctrl & PCI_REBAR_CTRL_IDX_MASK;
if (bar_idx == find_bar_idx)
return offset;
}

return 0;
}

/* Bit 20 = 1 MiB, bit 21 = 2 MiB, bit 22 = 4 MiB, ... bit 63 = 8 EiB */
static uint64_t get_rebar_sizes_mask(const struct device *dev,
unsigned long index)
{
uint64_t size_mask = 0ULL;
const uint32_t offset = get_rebar_offset(dev, index);
if (!offset)
return 0;

/* Get 1 MB - 128 TB support from CAP register */
const uint32_t cap = pci_read_config32(dev, offset + PCI_REBAR_CAP_OFFSET);
/* Shift the bits from 4-31 to 0-27 (i.e., down by 4 bits) */
size_mask |= ((cap & PCI_REBAR_CAP_SIZE_MASK) >> 4);

/* Get 256 TB - 8 EB support from CTRL register and store it in bits 28-43 */
const uint64_t ctrl = pci_read_config32(dev, offset + PCI_REBAR_CTRL_OFFSET);
/* Shift ctrl mask from bit 16 to bit 28, so that the two
masks (fom cap and ctrl) form a contiguous bitmask when
concatenated (i.e., up by 12 bits). */
size_mask |= ((ctrl & PCI_REBAR_CTRL_SIZE_MASK) << 12);

/* Now that the mask occupies bits 0-43, shift it up to 20-63, so they
represent the actual powers of 2. */
return size_mask << 20;
}

static void pci_store_rebar_size(const struct device *dev,
const struct resource *resource)
{
const unsigned int num_bits = __fls64(resource->size);
const uint32_t offset = get_rebar_offset(dev, resource->index);
if (!offset)
return;

pci_update_config32(dev, offset + PCI_REBAR_CTRL_OFFSET,
~PCI_REBAR_CTRL_SIZE_MASK,
num_bits << PCI_REBAR_CTRL_SIZE_SHIFT);
}

static void configure_adjustable_base(const struct device *dev,
unsigned long index,
struct resource *res)
{
/*
* Excerpt from an implementation note from the PCIe spec:
*
* System software uses this capability in place of the above mentioned
* method of determining the resource size[0], and prior to assigning
* the base address to the BAR. Potential usable resource sizes are
* reported by the Function via its Resizable BAR Capability and Control
* registers. It is intended that the software allocate the largest of
* the reported sizes that it can, since allocating less address space
* than the largest reported size can result in lower
* performance. Software then writes the size to the Resizable BAR
* Control register for the appropriate BAR for the Function. Following
* this, the base address is written to the BAR.
*
* [0] Referring to using the moving bits in the BAR to determine the
* requested size of the MMIO region
*/
const uint64_t size_mask = get_rebar_sizes_mask(dev, index);
if (!size_mask)
return;

int max_requested_bits = __fls64(size_mask);
if (max_requested_bits > CONFIG_PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS) {
printk(BIOS_WARNING, "WARNING: Device %s requests a BAR with"
"%u bits of address space, which coreboot is not"
"configured to hand out, truncating to %u bits\n",
dev_path(dev), max_requested_bits,
CONFIG_PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS);
max_requested_bits = CONFIG_PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS;
}

if (!(res->flags & IORESOURCE_PCI64) && max_requested_bits > 32) {
printk(BIOS_ERR, "ERROR: Resizable BAR requested"
"above 32 bits, but PCI function reported a"
"32-bit BAR.");
return;
}

/* Configure the resource parameters for the adjustable BAR */
res->size = 1ULL << max_requested_bits;
res->align = max_requested_bits;
res->gran = max_requested_bits;
res->limit = (res->flags & IORESOURCE_PCI64) ? UINT64_MAX : UINT32_MAX;
res->flags |= IORESOURCE_PCIE_RESIZABLE_BAR;

printk(BIOS_INFO, "%s: Adjusting resource index %lu: base: %llx size: %llx "
"align: %d gran: %d limit: %llx\n",
dev_path(dev), res->index, res->base, res->size,
res->align, res->gran, res->limit);
}

/**
* Read the base address registers for a given device.
*
Expand All @@ -323,6 +445,11 @@ static void pci_read_bases(struct device *dev, unsigned int howmany)
(index < PCI_BASE_ADDRESS_0 + (howmany << 2));) {
struct resource *resource;
resource = pci_get_resource(dev, index);

const bool is_pcie = pci_find_capability(dev, PCI_CAP_ID_PCIE) != 0;
if (CONFIG(PCIEXP_SUPPORT_RESIZABLE_BARS) && is_pcie)
configure_adjustable_base(dev, index, resource);

index += (resource->flags & IORESOURCE_PCI64) ? 8 : 4;
}

Expand Down Expand Up @@ -497,7 +624,7 @@ static void pci_store_bridge_resource(const struct device *const dev,
} else {
/* Don't let me think I stored the resource. */
resource->flags &= ~IORESOURCE_STORED;
printk(BIOS_ERR, "ERROR: invalid resource->index %lx\n", resource->index);
printk(BIOS_ERR, "invalid resource->index %lx\n", resource->index);
}
}

Expand All @@ -510,7 +637,7 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
we can treat it like an empty resource. */
resource->size = 0;
} else {
printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx not assigned\n",
printk(BIOS_ERR, "%s %02lx %s size: 0x%010llx not assigned\n",
dev_path(dev), resource->index,
resource_type(resource), resource->size);
return;
Expand Down Expand Up @@ -547,11 +674,17 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
/* Now store the resource. */
resource->flags |= IORESOURCE_STORED;

if (resource->flags & IORESOURCE_PCI_BRIDGE)
pci_store_bridge_resource(dev, resource);
else
if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
if (CONFIG(PCIEXP_SUPPORT_RESIZABLE_BARS) &&
(resource->flags & IORESOURCE_PCIE_RESIZABLE_BAR))
pci_store_rebar_size(dev, resource);

pci_store_resource(dev, resource);

} else {
pci_store_bridge_resource(dev, resource);
}

report_resource_stored(dev, resource, "");
}

Expand Down Expand Up @@ -1219,6 +1352,9 @@ static bool pci_bus_only_one_child(struct bus *bus)
if (!bridge)
return false;

if (bridge->path.type != DEVICE_PATH_PCI)
return false;

pcie_pos = pci_find_capability(bridge, PCI_CAP_ID_PCIE);
if (!pcie_pos)
return false;
Expand Down Expand Up @@ -1617,8 +1753,7 @@ int get_pci_irq_pins(struct device *dev, struct device **parent_bdg)

/* Make sure the swizzle returned valid structures */
if (parent_bdg == NULL) {
printk(BIOS_WARNING,
"Warning: Could not find parent bridge for this device!\n");
printk(BIOS_WARNING, "Could not find parent bridge for this device!\n");
return -2;
}
} else { /* Device is not behind a bridge */
Expand Down
32 changes: 21 additions & 11 deletions src/device/pciexp_device.c
Expand Up @@ -10,29 +10,39 @@

#include "mainboard/pcengines/apu2/bios_knobs.h"

unsigned int pciexp_find_extended_cap(const struct device *dev, unsigned int cap)
static unsigned int pciexp_get_ext_cap_offset(const struct device *dev, unsigned int cap,
unsigned int offset)
{
unsigned int this_cap_offset, next_cap_offset;
unsigned int this_cap, cafe;

this_cap_offset = PCIE_EXT_CAP_OFFSET;
unsigned int this_cap_offset = offset;
unsigned int next_cap_offset, this_cap, cafe;
do {
this_cap = pci_read_config32(dev, this_cap_offset);
next_cap_offset = this_cap >> 20;
this_cap &= 0xffff;
cafe = pci_read_config32(dev, this_cap_offset + 4);
cafe &= 0xffff;
if (this_cap == cap)
if ((this_cap & 0xffff) == cap) {
return this_cap_offset;
else if (cafe == cap)
} else if ((cafe & 0xffff) == cap) {
return this_cap_offset + 4;
else
} else {
next_cap_offset = this_cap >> 20;
this_cap_offset = next_cap_offset;
}
} while (next_cap_offset != 0);

return 0;
}

unsigned int pciexp_find_next_extended_cap(const struct device *dev, unsigned int cap,
unsigned int pos)
{
const unsigned int next_cap_offset = pci_read_config32(dev, pos) >> 20;
return pciexp_get_ext_cap_offset(dev, cap, next_cap_offset);
}

unsigned int pciexp_find_extended_cap(const struct device *dev, unsigned int cap)
{
return pciexp_get_ext_cap_offset(dev, cap, PCIE_EXT_CAP_OFFSET);
}

/*
* Re-train a PCIe link
*/
Expand Down
11 changes: 5 additions & 6 deletions src/device/pnp_device.c
Expand Up @@ -126,12 +126,12 @@ static void pnp_set_resource(struct device *dev, struct resource *resource)
if (resource->flags & IORESOURCE_IRQ &&
(resource->index != PNP_IDX_IRQ0) &&
(resource->index != PNP_IDX_IRQ1))
printk(BIOS_WARNING, "WARNING: %s %02lx %s size: "
printk(BIOS_WARNING, "%s %02lx %s size: "
"0x%010llx not assigned in devicetree\n", dev_path(dev),
resource->index, resource_type(resource),
resource->size);
else
printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx "
printk(BIOS_ERR, "%s %02lx %s size: 0x%010llx "
"not assigned in devicetree\n", dev_path(dev), resource->index,
resource_type(resource), resource->size);
return;
Expand All @@ -145,7 +145,7 @@ static void pnp_set_resource(struct device *dev, struct resource *resource)
} else if (resource->flags & IORESOURCE_IRQ) {
pnp_set_irq(dev, resource->index, resource->base);
} else {
printk(BIOS_ERR, "ERROR: %s %02lx unknown resource type\n",
printk(BIOS_ERR, "%s %02lx unknown resource type\n",
dev_path(dev), resource->index);
return;
}
Expand Down Expand Up @@ -213,7 +213,7 @@ static void pnp_get_ioresource(struct device *dev, u8 index, u16 mask)
/* If none of the mask bits is set, the resource would occupy the whole
IO space leading to IO resource conflicts with the other devices */
if (!mask) {
printk(BIOS_ERR, "ERROR: device %s index %d has no mask.\n",
printk(BIOS_ERR, "device %s index %d has no mask.\n",
dev_path(dev), index);
return;
}
Expand Down Expand Up @@ -241,8 +241,7 @@ static void pnp_get_ioresource(struct device *dev, u8 index, u16 mask)
If there is any zero in between the block of ones, it is ignored
in the calculation of the resource size and limit. */
if (mask != (resource->limit ^ (resource->size - 1)))
printk(BIOS_WARNING,
"WARNING: mask of device %s index %d is wrong.\n",
printk(BIOS_WARNING, "mask of device %s index %d is wrong.\n",
dev_path(dev), index);
}

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/amd/agesa/mtrr_fixme.c
Expand Up @@ -20,7 +20,7 @@ static void set_range_uc(u32 base, u32 size)
for (i = 0; i < max_var_mtrrs; i++) {
msr = rdmsr(MTRR_PHYS_MASK(i));
if (!(msr.lo & MTRR_PHYS_MASK_VALID))
break;
break;
}
if (i == max_var_mtrrs)
die("Run out of unused MTRRs\n");
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/analogix/anx7625/anx7625.c
Expand Up @@ -11,7 +11,7 @@
#include "anx7625.h"

#define ANXERROR(format, ...) \
printk(BIOS_ERR, "ERROR: %s: " format, __func__, ##__VA_ARGS__)
printk(BIOS_ERR, "%s: " format, __func__, ##__VA_ARGS__)
#define ANXINFO(format, ...) \
printk(BIOS_INFO, "%s: " format, __func__, ##__VA_ARGS__)
#define ANXDEBUG(format, ...) \
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/aspeed/common/ast_main.c
Expand Up @@ -212,7 +212,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
ast->dp501_fw_addr = NULL;
}
}
/* fallthrough */
__fallthrough;
case 0x0c:
ast->tx_chip_type = AST_TX_DP501;
}
Expand Down
115 changes: 58 additions & 57 deletions src/drivers/i2c/designware/dw_i2c.c
Expand Up @@ -8,6 +8,7 @@
#include <device/i2c_simple.h>
#include <string.h>
#include <timer.h>
#include <types.h>
#include "dw_i2c.h"

/* Use a ~10ms timeout for various operations */
Expand Down Expand Up @@ -42,7 +43,7 @@ struct freq {
enum {
CONTROL_MASTER_MODE = (1 << 0),
CONTROL_SPEED_SS = (1 << 1),
CONTROL_SPEED_FS = (1 << 2),
CONTROL_SPEED_FS = (2 << 1),
CONTROL_SPEED_HS = (3 << 1),
CONTROL_SPEED_MASK = (3 << 1),
CONTROL_10BIT_SLAVE = (1 << 3),
Expand Down Expand Up @@ -264,7 +265,7 @@ static void dw_i2c_enable(struct dw_i2c_regs *regs)
}

/* Disable this I2C controller */
static int dw_i2c_disable(struct dw_i2c_regs *regs)
static enum cb_err dw_i2c_disable(struct dw_i2c_regs *regs)
{
uint32_t enable = read32(&regs->enable);

Expand All @@ -277,14 +278,14 @@ static int dw_i2c_disable(struct dw_i2c_regs *regs)
stopwatch_init_usecs_expire(&sw, DW_I2C_TIMEOUT_US);
while (read32(&regs->enable_status) & ENABLE_CONTROLLER)
if (stopwatch_expired(&sw))
return -1;
return CB_ERR;
}

return 0;
return CB_SUCCESS;
}

/* Wait for this I2C controller to go idle for transmit */
static int dw_i2c_wait_for_bus_idle(struct dw_i2c_regs *regs)
static enum cb_err dw_i2c_wait_for_bus_idle(struct dw_i2c_regs *regs)
{
struct stopwatch sw;

Expand All @@ -300,17 +301,17 @@ static int dw_i2c_wait_for_bus_idle(struct dw_i2c_regs *regs)

/* Check for TX FIFO empty to indicate TX idle */
if (status & STATUS_TX_FIFO_EMPTY)
return 0;
return CB_SUCCESS;
}

/* Timed out while waiting for bus to go idle */
return -1;
return CB_ERR;
}

/* Transfer one byte of one segment, sending stop bit if requested */
static int dw_i2c_transfer_byte(struct dw_i2c_regs *regs,
const struct i2c_msg *segment,
size_t byte, int send_stop)
static enum cb_err dw_i2c_transfer_byte(struct dw_i2c_regs *regs,
const struct i2c_msg *segment,
size_t byte, int send_stop)
{
struct stopwatch sw;
uint32_t cmd = CMD_DATA_CMD; /* Read op */
Expand All @@ -322,7 +323,7 @@ static int dw_i2c_transfer_byte(struct dw_i2c_regs *regs,
while (!(read32(&regs->status) & STATUS_TX_FIFO_NOT_FULL)) {
if (stopwatch_expired(&sw)) {
printk(BIOS_ERR, "I2C transmit timeout\n");
return -1;
return CB_ERR;
}
}
cmd = segment->buf[byte];
Expand All @@ -339,27 +340,27 @@ static int dw_i2c_transfer_byte(struct dw_i2c_regs *regs,
while (!(read32(&regs->status) & STATUS_RX_FIFO_NOT_EMPTY)) {
if (stopwatch_expired(&sw)) {
printk(BIOS_ERR, "I2C receive timeout\n");
return -1;
return CB_ERR;
}
}
segment->buf[byte] = read32(&regs->cmd_data);
}

return 0;
return CB_SUCCESS;
}

static int _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
size_t count)
static enum cb_err _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
size_t count)
{
struct stopwatch sw;
struct dw_i2c_regs *regs;
size_t byte;
int ret = -1;
enum cb_err ret = CB_ERR;

regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
if (!regs) {
printk(BIOS_ERR, "I2C bus %u base address not found\n", bus);
return -1;
return CB_ERR;
}

/* The assumption is that the host controller is disabled -- either
Expand Down Expand Up @@ -387,8 +388,8 @@ static int _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
* Repeated start will be automatically generated
* by the controller on R->W or W->R switch.
*/
if (dw_i2c_transfer_byte(regs, segments, byte,
count == 0) < 0) {
if (dw_i2c_transfer_byte(regs, segments, byte, count == 0) !=
CB_SUCCESS) {
printk(BIOS_ERR, "I2C %s failed: bus %u "
"addr 0x%02x\n",
(segments->flags & I2C_M_RD) ?
Expand Down Expand Up @@ -429,7 +430,7 @@ static int _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
}

/* Wait for the bus to go idle */
if (dw_i2c_wait_for_bus_idle(regs)) {
if (dw_i2c_wait_for_bus_idle(regs) != CB_SUCCESS) {
printk(BIOS_ERR, "I2C timeout waiting for bus %u idle\n", bus);
goto out;
}
Expand All @@ -444,15 +445,15 @@ static int _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
read32(&regs->cmd_data);
}

ret = 0;
ret = CB_SUCCESS;

out:
read32(&regs->clear_intr);
dw_i2c_disable(regs);
return ret;
}

int dw_i2c_transfer(unsigned int bus, const struct i2c_msg *msg, size_t count)
static enum cb_err dw_i2c_transfer(unsigned int bus, const struct i2c_msg *msg, size_t count)
{
const struct i2c_msg *orig_msg = msg;
size_t i;
Expand All @@ -467,8 +468,8 @@ int dw_i2c_transfer(unsigned int bus, const struct i2c_msg *msg, size_t count)

for (i = 0, start = 0; i < count; i++, msg++) {
if (addr != msg->slave) {
if (_dw_i2c_transfer(bus, &orig_msg[start], i - start))
return -1;
if (_dw_i2c_transfer(bus, &orig_msg[start], i - start) != CB_SUCCESS)
return CB_ERR;
start = i;
addr = msg->slave;
}
Expand All @@ -480,22 +481,22 @@ int dw_i2c_transfer(unsigned int bus, const struct i2c_msg *msg, size_t count)
/* Global I2C bus handler, defined in include/device/i2c_simple.h */
int platform_i2c_transfer(unsigned int bus, struct i2c_msg *msg, int count)
{
return dw_i2c_transfer(bus, msg, count < 0 ? 0 : count);
return dw_i2c_transfer(bus, msg, count < 0 ? 0 : count) == CB_SUCCESS ? 0 : -1;
}

static int dw_i2c_set_speed_config(unsigned int bus,
const struct dw_i2c_speed_config *config)
static enum cb_err dw_i2c_set_speed_config(unsigned int bus,
const struct dw_i2c_speed_config *config)
{
struct dw_i2c_regs *regs;
void *hcnt_reg, *lcnt_reg;

regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
if (!regs || !config)
return -1;
return CB_ERR;

/* Nothing to do if no values are set */
if (!config->scl_lcnt && !config->scl_hcnt && !config->sda_hold)
return 0;
return CB_SUCCESS;

if (config->speed >= I2C_SPEED_HIGH) {
/* High and Fast Ultra speed */
Expand All @@ -521,14 +522,14 @@ static int dw_i2c_set_speed_config(unsigned int bus,
if (config->sda_hold)
write32(&regs->sda_hold, config->sda_hold);

return 0;
return CB_SUCCESS;
}

static int dw_i2c_gen_config_rise_fall_time(struct dw_i2c_regs *regs,
enum i2c_speed speed,
const struct dw_i2c_bus_config *bcfg,
int ic_clk,
struct dw_i2c_speed_config *config)
static enum cb_err dw_i2c_gen_config_rise_fall_time(struct dw_i2c_regs *regs,
enum i2c_speed speed,
const struct dw_i2c_bus_config *bcfg,
int ic_clk,
struct dw_i2c_speed_config *config)
{
const struct i2c_descriptor *bus;
const struct soc_clock *soc;
Expand All @@ -541,13 +542,13 @@ static int dw_i2c_gen_config_rise_fall_time(struct dw_i2c_regs *regs,

if (bus == NULL) {
printk(BIOS_ERR, "dw_i2c: invalid bus speed %d\n", speed);
return -1;
return CB_ERR;
}

if (soc == NULL) {
printk(BIOS_ERR, "dw_i2c: invalid SoC clock speed %d MHz\n",
ic_clk);
return -1;
return CB_ERR;
}

/* Get the proper spike suppression count based on target speed. */
Expand Down Expand Up @@ -582,7 +583,7 @@ static int dw_i2c_gen_config_rise_fall_time(struct dw_i2c_regs *regs,
if (hcnt < 0 || lcnt < 0) {
printk(BIOS_ERR, "dw_i2c: bad counts. hcnt = %d lcnt = %d\n",
hcnt, lcnt);
return -1;
return CB_ERR;
}

/* Now add things back up to ensure the period is hit. If off,
Expand Down Expand Up @@ -611,10 +612,10 @@ static int dw_i2c_gen_config_rise_fall_time(struct dw_i2c_regs *regs,
printk(DW_I2C_DEBUG, "dw_i2c: hcnt = %d lcnt = %d sda hold = %d\n",
hcnt, lcnt, config->sda_hold);

return 0;
return CB_SUCCESS;
}

int dw_i2c_gen_speed_config(uintptr_t dw_i2c_addr,
enum cb_err dw_i2c_gen_speed_config(uintptr_t dw_i2c_addr,
enum i2c_speed speed,
const struct dw_i2c_bus_config *bcfg,
struct dw_i2c_speed_config *config)
Expand All @@ -633,15 +634,15 @@ int dw_i2c_gen_speed_config(uintptr_t dw_i2c_addr,
if (bcfg->speed_config[i].speed != speed)
continue;
memcpy(config, &bcfg->speed_config[i], sizeof(*config));
return 0;
return CB_SUCCESS;
}

/* Use the time calculation. */
return dw_i2c_gen_config_rise_fall_time(regs, speed, bcfg, ic_clk, config);
}

static int dw_i2c_set_speed(unsigned int bus, enum i2c_speed speed,
const struct dw_i2c_bus_config *bcfg)
static enum cb_err dw_i2c_set_speed(unsigned int bus, enum i2c_speed speed,
const struct dw_i2c_bus_config *bcfg)
{
struct dw_i2c_regs *regs;
struct dw_i2c_speed_config config;
Expand All @@ -650,7 +651,7 @@ static int dw_i2c_set_speed(unsigned int bus, enum i2c_speed speed,
/* Clock must be provided by Kconfig */
regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
if (!regs || !speed)
return -1;
return CB_ERR;

control = read32(&regs->control);
control &= ~CONTROL_SPEED_MASK;
Expand All @@ -667,16 +668,16 @@ static int dw_i2c_set_speed(unsigned int bus, enum i2c_speed speed,
}

/* Generate speed config based on clock */
if (dw_i2c_gen_speed_config((uintptr_t)regs, speed, bcfg, &config) < 0)
return -1;
if (dw_i2c_gen_speed_config((uintptr_t)regs, speed, bcfg, &config) != CB_SUCCESS)
return CB_ERR;

/* Select this speed in the control register */
write32(&regs->control, control);

/* Write the speed config that was generated earlier */
dw_i2c_set_speed_config(bus, &config);

return 0;
return CB_SUCCESS;
}

/*
Expand All @@ -685,43 +686,43 @@ static int dw_i2c_set_speed(unsigned int bus, enum i2c_speed speed,
* The bus speed can be passed in Hz or using values from device/i2c.h and
* will default to I2C_SPEED_FAST if it is not provided.
*/
int dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg)
enum cb_err dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg)
{
struct dw_i2c_regs *regs;
enum i2c_speed speed;

if (!bcfg)
return -1;
return CB_ERR;

speed = bcfg->speed ? : I2C_SPEED_FAST;

regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
if (!regs) {
printk(BIOS_ERR, "I2C bus %u base address not found\n", bus);
return -1;
return CB_ERR;
}

if (read32(&regs->comp_type) != DW_I2C_COMP_TYPE) {
printk(BIOS_ERR, "I2C bus %u has unknown type 0x%x.\n", bus,
read32(&regs->comp_type));
return -1;
return CB_ERR;
}

printk(BIOS_DEBUG, "I2C bus %u version 0x%x\n", bus, read32(&regs->comp_version));

if (dw_i2c_disable(regs) < 0) {
if (dw_i2c_disable(regs) != CB_SUCCESS) {
printk(BIOS_ERR, "I2C timeout disabling bus %u\n", bus);
return -1;
return CB_ERR;
}

/* Put controller in master mode with restart enabled */
write32(&regs->control, CONTROL_MASTER_MODE | CONTROL_SLAVE_DISABLE |
CONTROL_RESTART_ENABLE);

/* Set bus speed to FAST by default */
if (dw_i2c_set_speed(bus, speed, bcfg) < 0) {
if (dw_i2c_set_speed(bus, speed, bcfg) != CB_SUCCESS) {
printk(BIOS_ERR, "I2C failed to set speed for bus %u\n", bus);
return -1;
return CB_ERR;
}

/* Set RX/TX thresholds to smallest values */
Expand All @@ -734,7 +735,7 @@ int dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg)
printk(BIOS_INFO, "DW I2C bus %u at %p (%u KHz)\n",
bus, regs, speed / KHz);

return 0;
return CB_SUCCESS;
}

/*
Expand Down Expand Up @@ -828,7 +829,7 @@ void dw_i2c_acpi_fill_ssdt(const struct device *dev)

/* Report currently used timing values for the OS driver */
acpigen_write_scope(path);
if (dw_i2c_gen_speed_config(dw_i2c_addr, speed, bcfg, &sgen) >= 0) {
if (dw_i2c_gen_speed_config(dw_i2c_addr, speed, bcfg, &sgen) == CB_SUCCESS) {
dw_i2c_acpi_write_speed_config(&sgen);
}
/* Now check if there are more speed settings available and report them as well. */
Expand Down
22 changes: 3 additions & 19 deletions src/drivers/i2c/designware/dw_i2c.h
Expand Up @@ -5,7 +5,7 @@

#include <device/device.h>
#include <device/i2c.h>
#include <stdint.h>
#include <types.h>

#if CONFIG(DRIVERS_I2C_DESIGNWARE_DEBUG)
#define DW_I2C_DEBUG BIOS_DEBUG
Expand Down Expand Up @@ -95,33 +95,17 @@ uintptr_t dw_i2c_base_address(unsigned int bus);

/*
* Initialize this bus controller and set the speed
* Return value:
* -1 = failure
* 0 = success
*/
int dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg);
enum cb_err dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg);

/*
* Generate speed config based on clock
* Return value:
* -1 = failure
* 0 = success
*/
int dw_i2c_gen_speed_config(uintptr_t dw_i2c_addr,
enum cb_err dw_i2c_gen_speed_config(uintptr_t dw_i2c_addr,
enum i2c_speed speed,
const struct dw_i2c_bus_config *bcfg,
struct dw_i2c_speed_config *config);

/*
* Process given I2C segments in a single transfer
* Return value:
* -1 = failure
* 0 = success
*/
int dw_i2c_transfer(unsigned int bus,
const struct i2c_msg *segments,
size_t count);

/*
* Map an i2c host controller device to a logical bus number.
* Return value:
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/max98390/max98390.c
Expand Up @@ -73,7 +73,7 @@ static void max98390_fill_ssdt(const struct device *dev)
CONFIG_MAINBOARD_PART_NUMBER);

if (chars >= sizeof(dsm_name))
printk(BIOS_ERR, "ERROR: String too long in %s\n", __func__);
printk(BIOS_ERR, "String too long in %s\n", __func__);

acpi_dp_add_string(dp, "maxim,dsm_param_name", dsm_name);
}
Expand Down
55 changes: 26 additions & 29 deletions src/drivers/i2c/tpm/cr50.c
Expand Up @@ -49,7 +49,7 @@ __weak int tis_plat_irq_status(void)
static int warning_displayed;

if (!warning_displayed) {
printk(BIOS_WARNING, "WARNING: %s() not implemented, wasting 20ms to wait on"
printk(BIOS_WARNING, "%s() not implemented, wasting 20ms to wait on"
" Cr50!\n", __func__);
warning_displayed = 1;
}
Expand All @@ -59,7 +59,7 @@ __weak int tis_plat_irq_status(void)
}

/* Wait for interrupt to indicate the TPM is ready */
static int cr50_i2c_wait_tpm_ready(struct tpm_chip *chip)
static int cr50_i2c_wait_tpm_ready(void)
{
struct stopwatch sw;

Expand All @@ -76,7 +76,6 @@ static int cr50_i2c_wait_tpm_ready(struct tpm_chip *chip)
/*
* cr50_i2c_read() - read from TPM register
*
* @chip: TPM chip information
* @addr: register address to read from
* @buffer: provided by caller
* @len: number of bytes to read
Expand All @@ -87,8 +86,7 @@ static int cr50_i2c_wait_tpm_ready(struct tpm_chip *chip)
*
* Return -1 on error, 0 on success.
*/
static int cr50_i2c_read(struct tpm_chip *chip, uint8_t addr,
uint8_t *buffer, size_t len)
static int cr50_i2c_read(uint8_t addr, uint8_t *buffer, size_t len)
{
if (tpm_dev.addr == 0)
return -1;
Expand All @@ -103,7 +101,7 @@ static int cr50_i2c_read(struct tpm_chip *chip, uint8_t addr,
}

/* Wait for TPM to be ready with response data */
if (cr50_i2c_wait_tpm_ready(chip) < 0)
if (cr50_i2c_wait_tpm_ready() < 0)
return -1;

/* Read response data from the TPM */
Expand All @@ -118,7 +116,6 @@ static int cr50_i2c_read(struct tpm_chip *chip, uint8_t addr,
/*
* cr50_i2c_write() - write to TPM register
*
* @chip: TPM chip information
* @addr: register address to write to
* @buffer: data to write
* @len: number of bytes to write
Expand All @@ -129,8 +126,7 @@ static int cr50_i2c_read(struct tpm_chip *chip, uint8_t addr,
*
* Returns -1 on error, 0 on success.
*/
static int cr50_i2c_write(struct tpm_chip *chip,
uint8_t addr, uint8_t *buffer, size_t len)
static int cr50_i2c_write(uint8_t addr, uint8_t *buffer, size_t len)
{
if (tpm_dev.addr == 0)
return -1;
Expand All @@ -151,7 +147,7 @@ static int cr50_i2c_write(struct tpm_chip *chip,
}

/* Wait for TPM to be ready */
return cr50_i2c_wait_tpm_ready(chip);
return cr50_i2c_wait_tpm_ready();
}

/*
Expand All @@ -161,7 +157,7 @@ static int cr50_i2c_write(struct tpm_chip *chip,
* This function will make sure that the AP does not proceed with boot until
* TPM finished reset processing.
*/
static int process_reset(struct tpm_chip *chip)
static int process_reset(void)
{
struct stopwatch sw;
int rv = 0;
Expand All @@ -180,7 +176,7 @@ static int process_reset(struct tpm_chip *chip)
const uint8_t mask =
TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY;

rv = cr50_i2c_read(chip, TPM_ACCESS(0),
rv = cr50_i2c_read(TPM_ACCESS(0),
&access, sizeof(access));
if (rv || ((access & mask) == mask)) {
/*
Expand Down Expand Up @@ -212,12 +208,12 @@ static int process_reset(struct tpm_chip *chip)
* the RO did not release it), or not yet claimed, if this is verstage or the
* older RO did release it.
*/
static int claim_locality(struct tpm_chip *chip)
static int claim_locality(void)
{
uint8_t access;
const uint8_t mask = TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY;

if (cr50_i2c_read(chip, TPM_ACCESS(0), &access, sizeof(access)))
if (cr50_i2c_read(TPM_ACCESS(0), &access, sizeof(access)))
return -1;

if ((access & mask) == mask) {
Expand All @@ -226,11 +222,11 @@ static int claim_locality(struct tpm_chip *chip)
}

access = TPM_ACCESS_REQUEST_USE;
if (cr50_i2c_write(chip, TPM_ACCESS(0),
if (cr50_i2c_write(TPM_ACCESS(0),
&access, sizeof(access)))
return -1;

if (cr50_i2c_read(chip, TPM_ACCESS(0), &access, sizeof(access)))
if (cr50_i2c_read(TPM_ACCESS(0), &access, sizeof(access)))
return -1;

if ((access & mask) != mask) {
Expand All @@ -245,7 +241,7 @@ static int claim_locality(struct tpm_chip *chip)
static uint8_t cr50_i2c_tis_status(struct tpm_chip *chip)
{
uint8_t buf[4];
if (cr50_i2c_read(chip, TPM_STS(chip->vendor.locality),
if (cr50_i2c_read(TPM_STS(chip->vendor.locality),
buf, sizeof(buf)) < 0) {
printk(BIOS_ERR, "%s: Failed to read status\n", __func__);
return 0;
Expand All @@ -257,7 +253,7 @@ static uint8_t cr50_i2c_tis_status(struct tpm_chip *chip)
static void cr50_i2c_tis_ready(struct tpm_chip *chip)
{
uint8_t buf[4] = { TPM_STS_COMMAND_READY };
cr50_i2c_write(chip, TPM_STS(chip->vendor.locality), buf, sizeof(buf));
cr50_i2c_write(TPM_STS(chip->vendor.locality), buf, sizeof(buf));
mdelay(CR50_TIMEOUT_SHORT_MS);
}

Expand All @@ -272,7 +268,7 @@ static int cr50_i2c_wait_burststs(struct tpm_chip *chip, uint8_t mask,
stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS);

while (!stopwatch_expired(&sw)) {
if (cr50_i2c_read(chip, TPM_STS(chip->vendor.locality),
if (cr50_i2c_read(TPM_STS(chip->vendor.locality),
buf, sizeof(buf)) != 0) {
mdelay(CR50_TIMEOUT_SHORT_MS);
continue;
Expand Down Expand Up @@ -310,7 +306,7 @@ static int cr50_i2c_tis_recv(struct tpm_chip *chip, uint8_t *buf,
}

/* Read first chunk of burstcnt bytes */
if (cr50_i2c_read(chip, addr, buf, burstcnt) != 0) {
if (cr50_i2c_read(addr, buf, burstcnt) != 0) {
printk(BIOS_ERR, "%s: Read failed\n", __func__);
goto out_err;
}
Expand All @@ -331,7 +327,7 @@ static int cr50_i2c_tis_recv(struct tpm_chip *chip, uint8_t *buf,
goto out_err;

len = MIN(burstcnt, expected - current);
if (cr50_i2c_read(chip, addr, buf + current, len) != 0) {
if (cr50_i2c_read(addr, buf + current, len) != 0) {
printk(BIOS_ERR, "%s: Read failed\n", __func__);
goto out_err;
}
Expand Down Expand Up @@ -390,7 +386,7 @@ static int cr50_i2c_tis_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
/* Use burstcnt - 1 to account for the address byte
* that is inserted by cr50_i2c_write() */
limit = MIN(burstcnt - 1, len);
if (cr50_i2c_write(chip, TPM_DATA_FIFO(chip->vendor.locality),
if (cr50_i2c_write(TPM_DATA_FIFO(chip->vendor.locality),
&buf[sent], limit) != 0) {
printk(BIOS_ERR, "%s: Write failed\n", __func__);
goto out_err;
Expand All @@ -409,7 +405,7 @@ static int cr50_i2c_tis_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
}

/* Start the TPM command */
if (cr50_i2c_write(chip, TPM_STS(chip->vendor.locality), tpm_go,
if (cr50_i2c_write(TPM_STS(chip->vendor.locality), tpm_go,
sizeof(tpm_go)) < 0) {
printk(BIOS_ERR, "%s: Start command failed\n", __func__);
goto out_err;
Expand Down Expand Up @@ -445,16 +441,17 @@ static int cr50_i2c_probe(struct tpm_chip *chip, uint32_t *did_vid)
int retries;

/*
* 200 ms should be enough to synchronize with the TPM even under the
* 1s should be enough to synchronize with the TPM even under the
* worst nested reset request conditions. In vast majority of cases
* there would be no wait at all.
* there would be no wait at all. If this probe fails, boot likely
* cannot proceed, so an extra long timeout is appropriate.
*/
printk(BIOS_INFO, "Probing TPM I2C: ");

for (retries = 20; retries > 0; retries--) {
for (retries = 100; retries > 0; retries--) {
int rc;

rc = cr50_i2c_read(chip, TPM_DID_VID(0), (uint8_t *)did_vid, 4);
rc = cr50_i2c_read(TPM_DID_VID(0), (uint8_t *)did_vid, 4);

/* Exit once DID and VID verified */
if (!rc && (*did_vid == CR50_DID_VID)) {
Expand Down Expand Up @@ -492,10 +489,10 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
return -1;

if (ENV_SEPARATE_VERSTAGE || ENV_BOOTBLOCK)
if (process_reset(chip))
if (process_reset())
return -1;

if (claim_locality(chip))
if (claim_locality())
return -1;

printk(BIOS_DEBUG, "cr50 TPM 2.0 (i2c %u:0x%02x id 0x%x)\n",
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/intel/fsp1_1/fsp_relocate.c
Expand Up @@ -15,14 +15,14 @@ int fsp_relocate(struct prog *fsp_relocd)
void *new_loc = cbfs_cbmem_alloc(prog_name(fsp_relocd),
CBMEM_ID_REFCODE, &size);
if (new_loc == NULL) {
printk(BIOS_ERR, "ERROR: Unable to load FSP into memory.\n");
printk(BIOS_ERR, "Unable to load FSP into memory.\n");
return -1;
}

fih_offset = fsp1_1_relocate((uintptr_t)new_loc, new_loc, size);

if (fih_offset <= 0) {
printk(BIOS_ERR, "ERROR: FSP relocation failure.\n");
printk(BIOS_ERR, "FSP relocation failure.\n");
return -1;
}

Expand Down
8 changes: 3 additions & 5 deletions src/drivers/intel/fsp1_1/raminit.c
Expand Up @@ -193,8 +193,7 @@ void raminit(struct romstage_params *params)

/* Verify all the HOBs are present */
if (fsp_verification_failure)
printk(BIOS_ERR,
"ERROR - Missing one or more required FSP HOBs!\n");
printk(BIOS_ERR, "Missing one or more required FSP HOBs!\n");

/* Display the HOBs */
if (CONFIG(DISPLAY_HOBS))
Expand All @@ -209,16 +208,15 @@ void raminit(struct romstage_params *params)
if ((fsp_memory != NULL) && (cbmem_root != NULL) &&
(cbmem_root->PhysicalStart <= fsp_memory->PhysicalStart)) {
fsp_verification_failure = 1;
printk(BIOS_ERR,
"ERROR - FSP reserved memory above CBMEM root!\n");
printk(BIOS_ERR, "FSP reserved memory above CBMEM root!\n");
}

/* Verify that the FSP memory was properly reserved */
if ((fsp_memory != NULL) && ((fsp_reserved_memory_area == NULL) ||
(fsp_memory->PhysicalStart !=
(unsigned int)fsp_reserved_memory_area))) {
fsp_verification_failure = 1;
printk(BIOS_ERR, "ERROR - Reserving FSP memory area!\n");
printk(BIOS_ERR, "Reserving FSP memory area!\n");

if (CONFIG(HAVE_SMI_HANDLER) && cbmem_root != NULL) {
size_t delta_bytes = smm_base
Expand Down
5 changes: 2 additions & 3 deletions src/drivers/intel/fsp1_1/ramstage.c
Expand Up @@ -20,7 +20,7 @@ static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)

/* Verify the HOBs */
if (hob_list_ptr == NULL) {
printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n");
printk(BIOS_ERR, "HOB pointer is NULL!\n");
return;
}

Expand All @@ -41,8 +41,7 @@ static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
!get_next_guid_hob(&graphics_info_guid, hob_list_ptr) &&
CONFIG(DISPLAY_HOBS)) {
printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
printk(BIOS_ERR,
"ERROR - Missing one or more required FSP HOBs!\n");
printk(BIOS_ERR, "Missing one or more required FSP HOBs!\n");
}
}

Expand Down
42 changes: 42 additions & 0 deletions src/drivers/intel/fsp2_0/Kconfig
Expand Up @@ -310,4 +310,46 @@ config FSPS_USE_MULTI_PHASE_INIT
SoC users to select this Kconfig to set EnableMultiPhaseSiliconInit to enable and
execute FspMultiPhaseSiInit() API.

config USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM
bool
help
The FSP API is used to notify the FSP about different phases in the boot process.
The current FSP specification supports three notify phases:
- Post PCI enumeration
- Ready to Boot
- End of Firmware
This option allows FSP to execute Notify Phase API (Post PCI enumeration).
SoC users can override this config to use coreboot native implementations
to perform the required lock down and chipset register configuration prior
to executing any 3rd-party code during PCI enumeration (i.e. Option ROM).

coreboot native implementation to skip FSP Notify Phase (Post PCI enumeration)
is still WIP.

config USE_FSP_NOTIFY_PHASE_READY_TO_BOOT
bool
help
The FSP API is used to notify the FSP about different phases in the boot process.
The current FSP specification supports three notify phases:
- Post PCI enumeration
- Ready to Boot
- End of Firmware
This option allows FSP to execute Notify Phase API (Ready to Boot).
SoC users can override this config to use coreboot native implementations
to perform the required lock down and chipset register configuration prior
boot to payload.

config USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE
bool
help
The FSP API is used to notify the FSP about different phases in the boot process.
The current FSP specification supports three notify phases:
- Post PCI enumeration
- Ready to Boot
- End of Firmware
This option allows FSP to execute Notify Phase API (End of Firmware).
SoC users can override this config to use coreboot native implementations
to perform the required lock down and chipset register configuration prior
boot to payload.

endif
2 changes: 1 addition & 1 deletion src/drivers/intel/fsp2_0/debug.c
Expand Up @@ -64,7 +64,7 @@ enum fsp_log_level fsp_map_console_log_level(void)
}

if (!CONFIG(DEBUG_RAM_SETUP))
fsp_debug_level = MIN(fsp_debug_level, FSP_LOG_LEVEL_ERR_WARN);
fsp_debug_level = MIN(fsp_debug_level, FSP_LOG_LEVEL_ERR_WARN_INFO);

return fsp_debug_level;
}
Expand Down
2 changes: 0 additions & 2 deletions src/drivers/intel/fsp2_0/hand_off_block.c
Expand Up @@ -286,7 +286,6 @@ void fsp_display_fvi_version_hob(void)
{
const uint8_t *hob_uuid;
const struct hob_header *hob = fsp_get_hob_list();
size_t size;

if (!hob)
return;
Expand All @@ -300,7 +299,6 @@ void fsp_display_fvi_version_hob(void)
hob_uuid = hob_header_to_struct(hob);

if (fsp_guid_compare(hob_uuid, uuid_fv_info)) {
size = hob->length - (HOB_HEADER_LEN + 16);
display_fsp_version_info_hob(hob);
}
}
Expand Down
21 changes: 14 additions & 7 deletions src/drivers/intel/fsp2_0/header_display.c
Expand Up @@ -8,13 +8,14 @@ void fsp_print_header_info(const struct fsp_header *hdr)
union fsp_revision revision;
union extended_fsp_revision ext_revision;
ext_revision.val = 0;
int i;

/* For FSP 2.3 and later use extended image revision field present in header
* for build number and revision calculation */
if (CONFIG(PLATFORM_USES_FSP2_3))
ext_revision.val = hdr->extended_fsp_revision;
ext_revision.val = hdr->extended_image_revision;

revision.val = hdr->fsp_revision;
revision.val = hdr->image_revision;
printk(BIOS_SPEW, "Spec version: v%u.%u\n", (hdr->spec_version >> 4),
hdr->spec_version & 0xf);
printk(BIOS_SPEW, "Revision: %u.%u.%u, Build Number %u\n",
Expand All @@ -25,22 +26,28 @@ void fsp_print_header_info(const struct fsp_header *hdr)
printk(BIOS_SPEW, "Type: %s/%s\n",
(hdr->component_attribute & 1) ? "release" : "debug",
(hdr->component_attribute & 2) ? "official" : "test");
printk(BIOS_SPEW, "image ID: %s, base 0x%zx + 0x%zx\n",
hdr->image_id, (size_t)hdr->image_base, (size_t)hdr->image_size);

printk(BIOS_SPEW, "image ID: ");
for (i = 0; i < FSP_IMAGE_ID_LENGTH; i++)
printk(BIOS_SPEW, "%c", hdr->image_id[i]);
printk(BIOS_SPEW, "\n");

printk(BIOS_SPEW, " base 0x%zx + 0x%zx\n",
(size_t)hdr->image_base, (size_t)hdr->image_size);
printk(BIOS_SPEW, "\tConfig region 0x%zx + 0x%zx\n",
(size_t)hdr->cfg_region_offset, (size_t)hdr->cfg_region_size);

if ((hdr->component_attribute >> 12) == FSP_HDR_ATTRIB_FSPM) {
printk(BIOS_SPEW, "\tMemory init offset 0x%zx\n",
(size_t)hdr->memory_init_entry_offset);
(size_t)hdr->fsp_memory_init_entry_offset);
}

if ((hdr->component_attribute >> 12) == FSP_HDR_ATTRIB_FSPS) {
printk(BIOS_SPEW, "\tSilicon init offset 0x%zx\n",
(size_t)hdr->silicon_init_entry_offset);
(size_t)hdr->fsp_silicon_init_entry_offset);
if (CONFIG(PLATFORM_USES_FSP2_2))
printk(BIOS_SPEW, "\tMultiPhaseSiInit offset 0x%zx\n",
(size_t)hdr->multi_phase_si_init_entry_offset);
(size_t)hdr->fsp_multi_phase_si_init_entry_offset);
printk(BIOS_SPEW, "\tNotify phase offset 0x%zx\n",
(size_t)hdr->notify_phase_entry_offset);
}
Expand Down
43 changes: 25 additions & 18 deletions src/drivers/intel/fsp2_0/include/fsp/info_header.h
Expand Up @@ -10,27 +10,34 @@
#define FSP_HDR_ATTRIB_FSPT 1
#define FSP_HDR_ATTRIB_FSPM 2
#define FSP_HDR_ATTRIB_FSPS 3
#define FSP_IMAGE_ID_LENGTH 8

#if CONFIG(PLATFORM_USES_FSP2_X86_32)
struct fsp_header {
uint32_t fsp_revision;
uint16_t extended_fsp_revision;
uint32_t image_size;
uint32_t image_base;
uint16_t image_attribute;
uint8_t spec_version;
uint16_t component_attribute;
uint32_t cfg_region_offset;
uint32_t cfg_region_size;
uint32_t temp_ram_init_entry;
uint32_t temp_ram_exit_entry;
uint32_t notify_phase_entry_offset;
uint32_t memory_init_entry_offset;
uint32_t silicon_init_entry_offset;
uint32_t multi_phase_si_init_entry_offset;
char image_id[sizeof(uint64_t) + 1];
uint8_t revision;
} __packed;
uint32_t signature; //FSPH
uint32_t header_length;
uint8_t res1[2];
uint8_t spec_version;
uint8_t header_revision;
uint32_t image_revision;
char image_id[FSP_IMAGE_ID_LENGTH]; // not zero terminated
uint32_t image_size;
uint32_t image_base;
uint16_t image_attribute;
uint16_t component_attribute;
uint32_t cfg_region_offset;
uint32_t cfg_region_size;
uint32_t res2;
uint32_t temp_ram_init_entry_offset; //initial stack
uint32_t res3;
uint32_t notify_phase_entry_offset;
uint32_t fsp_memory_init_entry_offset;
uint32_t temp_ram_exit_entry_offset;
uint32_t fsp_silicon_init_entry_offset;
uint32_t fsp_multi_phase_si_init_entry_offset;
uint16_t extended_image_revision;
uint16_t res4;
} __packed;
#else
#error You need to implement this struct for x86_64 FSP
#endif
Expand Down
10 changes: 5 additions & 5 deletions src/drivers/intel/fsp2_0/memory_init.c
Expand Up @@ -36,7 +36,7 @@ static void save_memory_training_data(bool s3wake, uint32_t fsp_version)

mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
if (!mrc_data) {
printk(BIOS_ERR, "ERROR: FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
printk(BIOS_ERR, "FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
return;
}

Expand All @@ -48,7 +48,7 @@ static void save_memory_training_data(bool s3wake, uint32_t fsp_version)
*/
if (mrc_cache_stash_data(MRC_TRAINING_DATA, fsp_version, mrc_data,
mrc_data_size) < 0)
printk(BIOS_ERR, "ERROR: Failed to stash MRC data\n");
printk(BIOS_ERR, "Failed to stash MRC data\n");
}

static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
Expand All @@ -64,7 +64,7 @@ static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
} else if (cbmem_initialize_id_size(CBMEM_ID_FSP_RESERVED_MEMORY,
range_entry_size(&fsp_mem))) {
if (CONFIG(HAVE_ACPI_RESUME)) {
printk(BIOS_ERR, "ERROR: Failed to recover CBMEM in S3 resume.\n");
printk(BIOS_ERR, "Failed to recover CBMEM in S3 resume.\n");
/* Failed S3 resume, reset to come up cleanly */
/* FIXME: A "system" reset is likely enough: */
full_reset();
Expand Down Expand Up @@ -206,7 +206,7 @@ uint8_t fsp_memory_soc_version(void)
static uint32_t fsp_memory_settings_version(const struct fsp_header *hdr)
{
/* Use the full FSP version by default. */
uint32_t ver = hdr->fsp_revision;
uint32_t ver = hdr->image_revision;

if (!CONFIG(FSP_PLATFORM_MEMORY_SETTINGS_VERSIONS))
return ver;
Expand Down Expand Up @@ -291,7 +291,7 @@ static void do_fsp_memory_init(const struct fspm_context *context, bool s3wake)
post_code(POST_MEM_PREINIT_PREP_END);

/* Call FspMemoryInit */
fsp_raminit = (void *)(uintptr_t)(hdr->image_base + hdr->memory_init_entry_offset);
fsp_raminit = (void *)(uintptr_t)(hdr->image_base + hdr->fsp_memory_init_entry_offset);
fsp_debug_before_memory_init(fsp_raminit, upd, &fspm_upd);

post_code(POST_FSP_MEMORY_INIT);
Expand Down
9 changes: 9 additions & 0 deletions src/drivers/intel/fsp2_0/notify.c
Expand Up @@ -10,6 +10,7 @@

struct fsp_notify_phase_data {
enum fsp_notify_phase notify_phase;
bool skip;
uint8_t post_code_before;
uint8_t post_code_after;
enum timestamp_id timestamp_before;
Expand All @@ -19,20 +20,23 @@ struct fsp_notify_phase_data {
static const struct fsp_notify_phase_data notify_data[] = {
{
.notify_phase = AFTER_PCI_ENUM,
.skip = !CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM),
.post_code_before = POST_FSP_NOTIFY_BEFORE_ENUMERATE,
.post_code_after = POST_FSP_NOTIFY_AFTER_ENUMERATE,
.timestamp_before = TS_FSP_BEFORE_ENUMERATE,
.timestamp_after = TS_FSP_AFTER_ENUMERATE,
},
{
.notify_phase = READY_TO_BOOT,
.skip = !CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT),
.post_code_before = POST_FSP_NOTIFY_BEFORE_FINALIZE,
.post_code_after = POST_FSP_NOTIFY_AFTER_FINALIZE,
.timestamp_before = TS_FSP_BEFORE_FINALIZE,
.timestamp_after = TS_FSP_AFTER_FINALIZE,
},
{
.notify_phase = END_OF_FIRMWARE,
.skip = !CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE),
.post_code_before = POST_FSP_NOTIFY_BEFORE_END_OF_FIRMWARE,
.post_code_after = POST_FSP_NOTIFY_AFTER_END_OF_FIRMWARE,
.timestamp_before = TS_FSP_BEFORE_END_OF_FIRMWARE,
Expand All @@ -56,6 +60,11 @@ static void fsp_notify(enum fsp_notify_phase phase)
fsp_notify_fn fspnotify;
uint32_t ret;

if (data->skip) {
printk(BIOS_INFO, "coreboot skipped calling FSP notify phase: %08x.\n", phase);
return;
}

if (!fsps_hdr.notify_phase_entry_offset)
die("Notify_phase_entry_offset is zero!\n");

Expand Down
6 changes: 3 additions & 3 deletions src/drivers/intel/fsp2_0/silicon_init.c
Expand Up @@ -75,7 +75,7 @@ static void fsps_return_value_handler(enum fsp_silicon_init_phases phases, uint3
bool fsp_is_multi_phase_init_enabled(void)
{
return CONFIG(FSPS_USE_MULTI_PHASE_INIT) &&
(fsps_hdr.multi_phase_si_init_entry_offset != 0);
(fsps_hdr.fsp_multi_phase_si_init_entry_offset != 0);
}

static void fsp_fill_common_arch_params(FSPS_UPD *supd)
Expand Down Expand Up @@ -127,7 +127,7 @@ static void do_silicon_init(struct fsp_header *hdr)

/* Call SiliconInit */
silicon_init = (void *) (uintptr_t)(hdr->image_base +
hdr->silicon_init_entry_offset);
hdr->fsp_silicon_init_entry_offset);
fsp_debug_before_silicon_init(silicon_init, supd, upd);

timestamp_add_now(TS_FSP_SILICON_INIT_START);
Expand Down Expand Up @@ -162,7 +162,7 @@ static void do_silicon_init(struct fsp_header *hdr)

/* Call MultiPhaseSiInit */
multi_phase_si_init = (void *) (uintptr_t)(hdr->image_base +
hdr->multi_phase_si_init_entry_offset);
hdr->fsp_multi_phase_si_init_entry_offset);

/* Implementing multi_phase_si_init() is optional as per FSP 2.2 spec */
if (multi_phase_si_init == NULL)
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/fsp2_0/temp_ram_exit.c
Expand Up @@ -25,7 +25,7 @@ static void fsp_temp_ram_exit(void)
if (fsp_validate_component(&hdr, mapping, size) != CB_SUCCESS)
die("Invalid FSPM header!\n");

temp_ram_exit = (void *)(hdr.image_base + hdr.temp_ram_exit_entry);
temp_ram_exit = (void *)(hdr.image_base + hdr.temp_ram_exit_entry_offset);
printk(BIOS_DEBUG, "Calling TempRamExit: %p\n", temp_ram_exit);
status = temp_ram_exit(NULL);

Expand Down
38 changes: 7 additions & 31 deletions src/drivers/intel/fsp2_0/util.c
Expand Up @@ -26,11 +26,9 @@ static uint32_t fsp_hdr_get_expected_min_length(void)
return dead_code_t(uint32_t);
}

static bool looks_like_fsp_header(const uint8_t *raw_hdr)
static bool looks_like_fsp_header(struct fsp_header *hdr)
{
uint32_t fsp_header_length = read32(raw_hdr + 4);

if (memcmp(raw_hdr, FSP_HDR_SIGNATURE, 4)) {
if (memcmp(&hdr->signature, FSP_HDR_SIGNATURE, 4)) {
printk(BIOS_ALERT, "Did not find a valid FSP signature\n");
return false;
}
Expand All @@ -39,8 +37,8 @@ static bool looks_like_fsp_header(const uint8_t *raw_hdr)
fields in FSP_INFO_HEADER. The new fields will be ignored based on the reported FSP
version. This check ensures that the reported header length is at least what the
reported FSP version requires so that we do not access any out-of-bound bytes. */
if (fsp_header_length < fsp_hdr_get_expected_min_length()) {
printk(BIOS_ALERT, "FSP header has invalid length: %d\n", fsp_header_length);
if (hdr->header_length < fsp_hdr_get_expected_min_length()) {
printk(BIOS_ALERT, "FSP header has invalid length: %d\n", hdr->header_length);
return false;
}

Expand All @@ -49,32 +47,10 @@ static bool looks_like_fsp_header(const uint8_t *raw_hdr)

enum cb_err fsp_identify(struct fsp_header *hdr, const void *fsp_blob)
{
const uint8_t *raw_hdr = fsp_blob;

if (!looks_like_fsp_header(raw_hdr))
memcpy(hdr, fsp_blob, sizeof(struct fsp_header));
if (!looks_like_fsp_header(hdr))
return CB_ERR;

hdr->spec_version = read8(raw_hdr + 10);
hdr->revision = read8(raw_hdr + 11);
hdr->fsp_revision = read32(raw_hdr + 12);
memcpy(hdr->image_id, raw_hdr + 16, ARRAY_SIZE(hdr->image_id));
hdr->image_id[ARRAY_SIZE(hdr->image_id) - 1] = '\0';
hdr->image_size = read32(raw_hdr + 24);
hdr->image_base = read32(raw_hdr + 28);
hdr->image_attribute = read16(raw_hdr + 32);
hdr->component_attribute = read16(raw_hdr + 34);
hdr->cfg_region_offset = read32(raw_hdr + 36);
hdr->cfg_region_size = read32(raw_hdr + 40);
hdr->temp_ram_init_entry = read32(raw_hdr + 48);
hdr->temp_ram_exit_entry = read32(raw_hdr + 64);
hdr->notify_phase_entry_offset = read32(raw_hdr + 56);
hdr->memory_init_entry_offset = read32(raw_hdr + 60);
hdr->silicon_init_entry_offset = read32(raw_hdr + 68);
if (CONFIG(PLATFORM_USES_FSP2_2))
hdr->multi_phase_si_init_entry_offset = read32(raw_hdr + 72);
if (CONFIG(PLATFORM_USES_FSP2_3))
hdr->extended_fsp_revision = read16(raw_hdr + 76);

return CB_SUCCESS;
}

Expand Down Expand Up @@ -192,7 +168,7 @@ void fsp_get_version(char *buf)
struct fsp_header *hdr = &fsps_hdr;
union fsp_revision revision;

revision.val = hdr->fsp_revision;
revision.val = hdr->image_revision;
snprintf(buf, FSP_VER_LEN, "%u.%u-%u.%u.%u.%u", (hdr->spec_version >> 4),
hdr->spec_version & 0xf, revision.rev.major,
revision.rev.minor, revision.rev.revision, revision.rev.bld_num);
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/intel/gma/Makefile.inc
Expand Up @@ -8,17 +8,17 @@ endif
ramstage-$(CONFIG_INTEL_GMA_ACPI) += acpi.c
ramstage-$(CONFIG_INTEL_GMA_ACPI) += opregion.c

ifeq ($(CONFIG_INTEL_GMA_ADD_VBT),y)
# add_vbt_to_cbfs, first argument is the filename in cbfs, the second one
# is the filename in the coreboot tree.
add_vbt_to_cbfs= \
$(eval cbfs-files-y += $1) \
$(eval $1-file := $2) \
$(eval $1-type := raw) \
$(eval $1-compression := lzma)
endif

ifeq ($(CONFIG_INTEL_GMA_ADD_VBT),y)
$(call add_vbt_to_cbfs, vbt.bin, $(call strip_quotes,$(CONFIG_INTEL_GMA_VBT_FILE)))
endif

ifeq ($(CONFIG_GFX_GMA),y)

Expand Down
3 changes: 2 additions & 1 deletion src/drivers/intel/mipi_camera/camera.c
Expand Up @@ -138,7 +138,8 @@ static void camera_fill_cio2(const struct device *dev)
port_name[i] = strdup(name);
if (CONFIG(ACPI_ADL_IPU_ES_SUPPORT)) {
u32 cpu_id = cpu_get_cpuid();
if (cpu_id == CPUID_ALDERLAKE_A0 || cpu_id == CPUID_ALDERLAKE_A1)
if (cpu_id == CPUID_ALDERLAKE_A0 || cpu_id == CPUID_ALDERLAKE_A1 ||
cpu_id == CPUID_ALDERLAKE_N_A0)
acpi_dp_add_integer(dsd, "is_es", 1);
else
acpi_dp_add_integer(dsd, "is_es", 0);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/mipi_camera/chip.h
Expand Up @@ -12,7 +12,7 @@
#define MAX_LINK_FREQ_ENTRIES 4
#define MAX_CLK_CONFIGS 2
#define MAX_GPIO_CONFIGS 4
#define MAX_PWR_OPS 5
#define MAX_PWR_OPS 6
#define MAX_GUARDED_RESOURCES 10
#define IMGCLKOUT_0 0
#define IMGCLKOUT_1 1
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/intel/pmc_mux/conn/conn.c
Expand Up @@ -56,7 +56,7 @@ static void conn_write_cbmem_entry(struct device *dev)

info = conn_get_cbmem_buffer();
if (!info || (info->port_count >= total_conn_count)) {
printk(BIOS_ERR, "ERROR: No space for Type-C port info!\n");
printk(BIOS_ERR, "No space for Type-C port info!\n");
return;
}

Expand All @@ -67,7 +67,7 @@ static void conn_write_cbmem_entry(struct device *dev)
port_info->sbu_orientation = config->sbu_orientation;
port_info->data_orientation = config->hsl_orientation;

printk(BIOS_INFO, "added type-c port%ld info to cbmem: usb2:%d usb3:%d sbu:%d data:%d\n",
printk(BIOS_INFO, "added type-c port%zu info to cbmem: usb2:%d usb3:%d sbu:%d data:%d\n",
count, port_info->usb2_port_number, port_info->usb3_port_number,
port_info->sbu_orientation, port_info->data_orientation);

Expand Down
4 changes: 2 additions & 2 deletions src/drivers/intel/usb4/retimer/retimer.c
Expand Up @@ -370,7 +370,7 @@ static void usb4_retimer_fill_ssdt(const struct device *dev)
if (ec_port == -1) {
printk(BIOS_ERR, "%s: No relative EC port found for TC port %d\n",
__func__, usb_port);
continue;
continue;
}
/* DFPx */
snprintf(dfp, sizeof(dfp), "DFP%1d", ec_port);
Expand Down Expand Up @@ -415,7 +415,7 @@ static void usb4_retimer_fill_ssdt(const struct device *dev)
acpigen_pop_len(); /* Host Router */
acpigen_pop_len(); /* Scope */

printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
printk(BIOS_INFO, "%s.HR: %s at %s\n", usb4_retimer_scope, dev->chip_ops->name,
dev_path(dev));
}

Expand Down
4 changes: 2 additions & 2 deletions src/drivers/ipmi/ipmi_kcs_ops.c
Expand Up @@ -247,7 +247,7 @@ ipmi_write_acpi_tables(const struct device *dev, unsigned long current,
break;
default:
printk(BIOS_ERR, "IPMI: Unsupported register spacing for SPMI\n");
/* fall through */
__fallthrough;
case 1:
addr.bit_offset = 8;
break;
Expand Down Expand Up @@ -369,7 +369,7 @@ static int ipmi_smbios_data(struct device *dev, int *handle,
break;
default:
printk(BIOS_ERR, "IPMI: Unsupported register spacing for SMBIOS\n");
/* fall through */
__fallthrough;
case 1:
register_spacing = 0 << 6;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/mrc_cache/mrc_cache.c
Expand Up @@ -255,7 +255,7 @@ static int mrc_cache_get_latest_slot_info(const char *name,

/* No data to return. */
if (region_file_data(cache_file, rdev) < 0) {
printk(BIOS_ERR, "MRC: no data in '%s'\n", name);
printk(BIOS_NOTICE, "MRC: no data in '%s'\n", name);
return fail_bad_data ? -1 : 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/net/atl1e.c
Expand Up @@ -30,7 +30,7 @@ static u8 get_hex_digit(const u8 c)
ret = c - 'a' + 0x0a;
}
if (ret > 0x0f) {
printk(BIOS_ERR, "Error: Invalid hex digit found: "
printk(BIOS_ERR, "Invalid hex digit found: "
"%c - 0x%02x\n", (char)c, c);
ret = 0;
}
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/net/chip.h
Expand Up @@ -31,6 +31,9 @@ struct drivers_net_config {
* the device number is and the valid range is [1-10].
*/
uint8_t device_index;

/* Allow kernel driver to enable ASPM L1.2. */
bool enable_aspm_l1_2;
};

#endif /* __DRIVERS_R8168_CHIP_H__ */
3 changes: 1 addition & 2 deletions src/drivers/net/ne2k.c
Expand Up @@ -84,7 +84,7 @@ static void eth_pio_write(unsigned char *src, unsigned int dst, unsigned int cnt
outb(D8390_COMMAND_RD1 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);

while (cnt--) {
outb(*(src++), eth_nic_base + NE_ASIC_OFFSET + NE_DATA);
outb(*(src++), eth_nic_base + NE_ASIC_OFFSET + NE_DATA);
}
/*
#warning "Add timeout"
Expand Down Expand Up @@ -307,7 +307,6 @@ static void read_resources(struct device *dev)
res->limit = res->base + res->size - 1;
res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_STORED |
IORESOURCE_ASSIGNED;
return;
}

static struct device_operations ne2k_ops = {
Expand Down
27 changes: 23 additions & 4 deletions src/drivers/net/r8168.c
Expand Up @@ -36,6 +36,8 @@
#define CFG_9346 0x50
#define CFG_9346_LOCK 0x00
#define CFG_9346_UNLOCK 0xc0
#define CMD_REG_ASPM 0xb0
#define ASPM_L1_2_MASK 0xe059000f

#define DEVICE_INDEX_BYTE 12
#define MAX_DEVICE_SUPPORT 10
Expand Down Expand Up @@ -76,7 +78,7 @@ static u8 get_hex_digit(const u8 c)
ret = c - 'a' + 0x0a;
}
if (ret > 0x0f) {
printk(BIOS_ERR, "Error: Invalid hex digit found: "
printk(BIOS_ERR, "Invalid hex digit found: "
"%c - 0x%02x\n", (char)c, c);
ret = 0;
}
Expand All @@ -94,7 +96,7 @@ static enum cb_err fetch_mac_vpd_key(u8 *macstrbuf, const char *vpd_key)
size_t offset;

if (fmap_locate_area_as_rdev("RO_VPD", &rdev)) {
printk(BIOS_ERR, "Error: Couldn't find RO_VPD region.");
printk(BIOS_ERR, "Couldn't find RO_VPD region.");
return CB_ERR;
}
search_address = rdev_mmap_full(&rdev);
Expand All @@ -108,8 +110,7 @@ static enum cb_err fetch_mac_vpd_key(u8 *macstrbuf, const char *vpd_key)
search_length);

if (offset == search_length) {
printk(BIOS_ERR,
"Error: Could not locate '%s' in VPD\n", vpd_key);
printk(BIOS_ERR, "Could not locate '%s' in VPD\n", vpd_key);
rdev_munmap(&rdev, search_address);
return CB_ERR;
}
Expand Down Expand Up @@ -245,6 +246,20 @@ static void program_mac_address(struct device *dev, u16 io_base)
printk(BIOS_DEBUG, "done\n");
}

static void enable_aspm_l1_2(u16 io_base)
{
printk(BIOS_INFO, "rtl: Enable ASPM L1.2\n");

/* Disable register protection */
outb(CFG_9346_UNLOCK, io_base + CFG_9346);

/* Enable ASPM_L1.2 */
outl(ASPM_L1_2_MASK, io_base + CMD_REG_ASPM);

/* Lock config regs */
outb(CFG_9346_LOCK, io_base + CFG_9346);
}

static void r8168_set_customized_led(struct device *dev, u16 io_base)
{
struct drivers_net_config *config = dev->chip_info;
Expand Down Expand Up @@ -339,6 +354,10 @@ static void r8168_init(struct device *dev)
/* Program customized LED mode */
if (CONFIG(RT8168_SET_LED_MODE))
r8168_set_customized_led(dev, io_base);

struct drivers_net_config *config = dev->chip_info;
if (CONFIG(PCIEXP_ASPM) && config->enable_aspm_l1_2)
enable_aspm_l1_2(io_base);
}

#if CONFIG(HAVE_ACPI_TABLES)
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/pc80/rtc/option.c
Expand Up @@ -100,7 +100,7 @@ static enum cb_err cmos_get_uint_option(unsigned int *dest, const char *name)
}

if (ce->config != 'e' && ce->config != 'h') {
printk(BIOS_ERR, "ERROR: CMOS option '%s' is not of integer type.\n", name);
printk(BIOS_ERR, "CMOS option '%s' is not of integer type.\n", name);
return CB_ERR_ARG;
}

Expand Down Expand Up @@ -176,7 +176,7 @@ static enum cb_err cmos_set_uint_option(const char *name, unsigned int *value)
}

if (ce->config != 'e' && ce->config != 'h') {
printk(BIOS_ERR, "ERROR: CMOS option '%s' is not of integer type.\n", name);
printk(BIOS_ERR, "CMOS option '%s' is not of integer type.\n", name);
return CB_ERR_ARG;
}

Expand Down
11 changes: 11 additions & 0 deletions src/drivers/pcie/generic/Kconfig
@@ -0,0 +1,11 @@
config DRIVERS_PCIE_GENERIC
bool
default n
depends on HAVE_ACPI_TABLES
help
This driver allows attaching arbitrary ACPI properties to
arbitrary PCI root ports or devices. Currently it supports one
property, "UntrustedDevice". This property indicates to the
operating system that the PCIe device may be considered
untrusted, and appropriate policies, e.g. IOMMU isolation,
should take place.
1 change: 1 addition & 0 deletions src/drivers/pcie/generic/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_PCIE_GENERIC) += generic.c
12 changes: 12 additions & 0 deletions src/drivers/pcie/generic/chip.h
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _PCIE_GENERIC_H_
#define _PCIE_GENERIC_H_

#include <types.h>

struct drivers_pcie_generic_config {
bool is_untrusted;
};

#endif /* _PCIE_GENERIC_H_ */
65 changes: 65 additions & 0 deletions src/drivers/pcie/generic/generic.c
@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <acpi/acpigen.h>
#include <acpi/acpigen_pci.h>
#include <device/device.h>
#include <device/pci.h>
#include "chip.h"

static const char *pcie_generic_acpi_name(const struct device *dev)
{
return "DEV0";
}

static void pcie_generic_fill_ssdt(const struct device *dev)
{
struct drivers_pcie_generic_config *config;
struct acpi_dp *dsd;

if (!is_dev_enabled(dev))
return;

pci_rom_ssdt(dev);

config = dev->chip_info;
if (!config || !config->is_untrusted || !dev->bus || !dev->bus->dev)
return;

const char *scope = acpi_device_path(dev->bus->dev);
const char *name = acpi_device_name(dev);

acpigen_write_scope(scope);
acpigen_write_device(name);
acpigen_write_ADR_pci_device(dev);

dsd = acpi_dp_new_table("_DSD");
acpi_dp_add_integer(dsd, "UntrustedDevice", 1);
acpi_dp_write(dsd);

acpigen_write_device_end();
acpigen_write_scope_end();

printk(BIOS_INFO, "%s.%s: Enable ACPI properties for %s (%s)\n", scope, name,
dev_path(dev), dev->chip_ops->name);
}

struct device_operations pcie_generic_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = pci_dev_init,
.ops_pci = &pci_dev_ops_pci,
.acpi_name = pcie_generic_acpi_name,
.acpi_fill_ssdt = pcie_generic_fill_ssdt,
};

static void pcie_generic_enable(struct device *dev)
{
dev->ops = &pcie_generic_ops;
}

struct chip_operations drivers_pcie_generic_ops = {
CHIP_NAME("PCIe Device")
.enable_dev = pcie_generic_enable
};
5 changes: 5 additions & 0 deletions src/drivers/smmstore/Makefile.inc
@@ -1,4 +1,9 @@
ramstage-$(CONFIG_SMMSTORE) += store.c

ifeq ($(CONFIG_SMMSTORE),y)
$(call src-to-obj,ramstage,$(dir)/store.c) : $(obj)/fmap_config.h
$(call src-to-obj,smm,$(dir)/store.c) : $(obj)/fmap_config.h
endif
ramstage-$(CONFIG_SMMSTORE_V2) += ramstage.c

smm-$(CONFIG_SMMSTORE) += store.c smi.c
8 changes: 8 additions & 0 deletions src/drivers/smmstore/store.c
Expand Up @@ -2,6 +2,7 @@

#include <boot_device.h>
#include <fmap.h>
#include <fmap_config.h>
#include <commonlib/helpers.h>
#include <commonlib/region.h>
#include <console/console.h>
Expand All @@ -10,6 +11,13 @@

#define SMMSTORE_REGION "SMMSTORE"


_Static_assert(IS_ALIGNED(FMAP_SECTION_SMMSTORE_START, SMM_BLOCK_SIZE),
"SMMSTORE FMAP region not aligned to 64K");

_Static_assert(SMM_BLOCK_SIZE <= FMAP_SECTION_SMMSTORE_SIZE,
"SMMSTORE FMAP region must be at least 64K");

/*
* The region format is still not finalized, but so far it looks like this:
* (
Expand Down