137 changes: 137 additions & 0 deletions src/commonlib/bsd/include/commonlib/bsd/cbfs_private.h
@@ -0,0 +1,137 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */

#ifndef _COMMONLIB_BSD_CBFS_PRIVATE_H_
#define _COMMONLIB_BSD_CBFS_PRIVATE_H_


#include <commonlib/bsd/cb_err.h>
#include <commonlib/bsd/cbfs_serialized.h>
#include <endian.h>
#include <stdbool.h>
#include <stdint.h>
#include <vb2_sha.h>

/*
* This header implements low-level CBFS access APIs that can be shared across different
* host applications (e.g. coreboot, libpayload, cbfstool). For verification purposes it
* implements the metadata hashing part but not the file hashing part, so the host application
* will need to verify file hashes itself after loading each file. Host applications that use
* verification should implement wrapper APIs that combine the lookup, loading and hashing steps
* into a single, safe function call and outside of the code implementing those APIs should not
* be accessing the low-level APIs in this file directly (e.g. coreboot SoC/driver code should
* never directly #include this file, and always use the higher level APIs in src/lib/cbfs.c).
*
* <cbfs_glue.h> needs to be provided by the host application using this CBFS library. It must
* define the following type, macros and functions:
*
* cbfs_dev_t An opaque type representing a CBFS storage backend.
* CBFS_ENABLE_HASHING Should be 0 to avoid linking hashing features, 1 otherwise. (Only for
* metadata hashing. Host application needs to check file hashes itself.)
* ERROR(...) printf-style macro to print errors.
* LOG(...) printf-style macro to print normal-operation log messages.
* DEBUG(...) printf-style macro to print detailed debug output.
*
* ssize_t cbfs_dev_read(cbfs_dev_t dev, void *buffer, size_t offset, size_t size);
* Read |size| bytes starting at |offset| from |dev| into |buffer|.
* Returns amount of bytes read on success and < 0 on error.
* This function *MUST* sanity-check offset/size on its own.
*
* size_t cbfs_dev_size(cbfs_dev_t dev);
* Return the total size in bytes of the CBFS storage (actual CBFS area).
*/
#include <cbfs_glue.h>

/*
* Helper structure to allocate space for a blob of metadata on the stack.
* NOTE: The fields in any union cbfs_mdata or any of its substructures from cbfs_serialized.h
* should always remain in the same byte order as they are stored on flash (= big endian). To
* avoid byte-order confusion, fields should always and only be converted to host byte order at
* exactly the time they are read from one of these structures into their own separate variable.
*/
#define CBFS_METADATA_MAX_SIZE 256
union cbfs_mdata {
struct {
struct cbfs_file h;
char filename[];
};
uint8_t raw[CBFS_METADATA_MAX_SIZE];
};

/* Flags that modify behavior of cbfs_walk(). */
enum cbfs_walk_flags {
/* Write the calculated hash back out to |metadata_hash->hash| rather than comparing it.
|metadata_hash->algo| must still have been initialized by the caller. */
CBFS_WALK_WRITEBACK_HASH = (1 << 0),
/* Call |walker| for empty file entries (i.e. entries with one of the CBFS_TYPE_DELETED
types that mark free space in the CBFS). Otherwise, those entries will be skipped.
Either way, these entries are never included in the metadata_hash calculation. */
CBFS_WALK_INCLUDE_EMPTY = (1 << 1),
};

/*
* Traverse a CBFS and call a |walker| callback function for every file. Can additionally
* calculate a hash over the metadata of all files in the CBFS. If |metadata_hash| is NULL,
* hashing is disabled. If |walker| is NULL, will just traverse and hash the CBFS without
* invoking any callbacks (and always return CB_CBFS_NOT_FOUND unless there was another error).
*
* |arg| and |dev| will be passed through to |walker| unmodified. |offset| is the absolute
* offset in |dev| at which the current file metadata starts. |mdata| is a temporary buffer
* (only valid for the duration of this call to |walker|) containing already read metadata from
* the current file, up to |already_read| bytes. This will always at least contain the header
* fields and filename, but may contain more (i.e. attributes), depending on whether hashing is
* enabled. |walker| should call into cbfs_copy_fill_medadata() to copy the metadata of a file
* to a persistent buffer and automatically load remaining metadata from |dev| as needed based
* on the value of |already_read|.
*
* |walker| should return CB_CBFS_NOT_FOUND if it wants to continue being called for further
* files. Any other return code will be used as the final return code for cbfs_walk(). It will
* return immediately unless it needs to calculate a hash in which case it will still traverse
* the remaining CBFS (but not call |walker| anymore).
*
* Returns, from highest to lowest priority:
* CB_CBFS_IO - There was an IO error with the CBFS device (always considered fatal)
* CB_CBFS_HASH_MISMATCH - |metadata_hash| was provided and did not match the CBFS
* CB_SUCCESS/<other> - First non-CB_CBFS_NOT_FOUND code returned by walker()
* CB_CBFS_NOT_FOUND - walker() returned CB_CBFS_NOT_FOUND for every file in the CBFS
*/
cb_err_t cbfs_walk(cbfs_dev_t dev, cb_err_t (*walker)(cbfs_dev_t dev, size_t offset,
const union cbfs_mdata *mdata,
size_t already_read, void *arg),
void *arg, struct vb2_hash *metadata_hash, enum cbfs_walk_flags);

/*
* Helper function that can be used by a |walker| callback to cbfs_walk() to copy the metadata
* of a file into a permanent buffer. Will copy the |already_read| metadata from |src| into
* |dst| and load remaining metadata from |dev| as required.
*/
cb_err_t cbfs_copy_fill_metadata(union cbfs_mdata *dst, const union cbfs_mdata *src,
size_t already_read, cbfs_dev_t dev, size_t offset);

/* Find a file named |name| in the CBFS on |dev|. Copy its metadata (including attributes)
* into |mdata_out| and pass out the offset to the file data on the CBFS device.
* Verify the metadata with |metadata_hash| if provided. */
cb_err_t cbfs_lookup(cbfs_dev_t dev, const char *name, union cbfs_mdata *mdata_out,
size_t *data_offset_out, struct vb2_hash *metadata_hash);

/* Both base address and size of CBFS mcaches must be aligned to this value! */
#define CBFS_MCACHE_ALIGNMENT sizeof(uint32_t) /* Largest data type used in CBFS */

/* Build an in-memory CBFS metadata cache out of the CBFS on |dev| into a |mcache_size| bytes
* memory area at |mcache|. Also verify |metadata_hash| unless it is NULL. If this returns
* CB_CBFS_CACHE_FULL, the mcache is still valid and can be used, but lookups may return
* CB_CBFS_CACHE_FULL for files that didn't fit to indicate that the caller needs to fall back
* to cbfs_lookup(). */
cb_err_t cbfs_mcache_build(cbfs_dev_t dev, void *mcache, size_t mcache_size,
struct vb2_hash *metadata_hash);

/*
* Find a file named |name| in a CBFS metadata cache and copy its metadata into |mdata_out|.
* Pass out offset to the file data (on the original CBFS device used for cbfs_mcache_build()).
*/
cb_err_t cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name,
union cbfs_mdata *mdata_out, size_t *data_offset_out);

/* Returns the amount of bytes actually used by the CBFS metadata cache in |mcache|. */
size_t cbfs_mcache_real_size(const void *mcache, size_t mcache_size);

#endif /* _COMMONLIB_BSD_CBFS_PRIVATE_H_ */
6 changes: 3 additions & 3 deletions src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h
Expand Up @@ -4,6 +4,7 @@
#define _CBFS_SERIALIZED_H_

#include <stdint.h>
#include <vb2_sha.h>

/** These are standard values for the known compression
algorithms that coreboot knows about for stages and
Expand Down Expand Up @@ -124,12 +125,11 @@ struct cbfs_file_attr_compression {
uint32_t decompressed_size;
} __packed;

/* Actual size in CBFS may be larger/smaller than struct size! */
struct cbfs_file_attr_hash {
uint32_t tag;
uint32_t len;
uint32_t hash_type;
/* hash_data is len - sizeof(struct) bytes */
uint8_t hash_data[];
struct vb2_hash hash;
} __packed;

struct cbfs_file_attr_position {
Expand Down
15 changes: 0 additions & 15 deletions src/commonlib/cbfs.c
Expand Up @@ -7,21 +7,6 @@
#include <string.h>
#include <vb2_sha.h>

#if !defined(LOG)
#define LOG(x...) printk(BIOS_INFO, "CBFS: " x)
#endif
#if defined(CONFIG)

#if CONFIG(DEBUG_CBFS)
#define DEBUG(x...) printk(BIOS_SPEW, "CBFS: " x)
#else
#define DEBUG(x...)
#endif

#elif !defined(DEBUG)
#define DEBUG(x...)
#endif

static size_t cbfs_next_offset(const struct region_device *cbfs,
const struct cbfsf *f)
{
Expand Down
3 changes: 2 additions & 1 deletion src/commonlib/include/commonlib/cbfs.h
Expand Up @@ -3,14 +3,15 @@
#ifndef _COMMONLIB_CBFS_H_
#define _COMMONLIB_CBFS_H_

#include <commonlib/bsd/cbfs_serialized.h>
#include <commonlib/bsd/cbfs_private.h>
#include <commonlib/region.h>
#include <vb2_api.h>

/* Object representing cbfs files. */
struct cbfsf {
struct region_device metadata;
struct region_device data;
union cbfs_mdata mdata;
};

/* Locate file by name and optional type. Returns 0 on success else < 0 on
Expand Down
6 changes: 5 additions & 1 deletion src/commonlib/include/commonlib/cbmem_id.h
Expand Up @@ -68,6 +68,8 @@
#define CBMEM_ID_ROM2 0x524f4d32
#define CBMEM_ID_ROM3 0x524f4d33
#define CBMEM_ID_FMAP 0x464d4150
#define CBMEM_ID_CBFS_RO_MCACHE 0x524d5346
#define CBMEM_ID_CBFS_RW_MCACHE 0x574d5346
#define CBMEM_ID_FSP_LOGO 0x4c4f474f
#define CBMEM_ID_SMM_COMBUFFER 0x53534d32

Expand Down Expand Up @@ -131,5 +133,7 @@
{ CBMEM_ID_ROM1, "VGA ROM #1 "}, \
{ CBMEM_ID_ROM2, "VGA ROM #2 "}, \
{ CBMEM_ID_ROM3, "VGA ROM #3 "}, \
{ CBMEM_ID_FMAP, "FMAP "},
{ CBMEM_ID_FMAP, "FMAP "}, \
{ CBMEM_ID_CBFS_RO_MCACHE, "RO MCACHE "}, \
{ CBMEM_ID_CBFS_RW_MCACHE, "RW MCACHE "}
#endif /* _CBMEM_ID_H_ */
24 changes: 15 additions & 9 deletions src/commonlib/include/commonlib/coreboot_tables.h
Expand Up @@ -62,15 +62,15 @@ enum {
LB_TAG_DMA = 0x0022,
LB_TAG_RAM_OOPS = 0x0023,
LB_TAG_ACPI_GNVS = 0x0024,
LB_TAG_BOARD_ID = 0x0025,
LB_TAG_BOARD_ID = 0x0025, /* deprecated */
LB_TAG_VERSION_TIMESTAMP = 0x0026,
LB_TAG_WIFI_CALIBRATION = 0x0027,
LB_TAG_RAM_CODE = 0x0028,
LB_TAG_RAM_CODE = 0x0028, /* deprecated */
LB_TAG_SPI_FLASH = 0x0029,
LB_TAG_SERIALNO = 0x002a,
LB_TAG_MTC = 0x002b,
LB_TAG_VPD = 0x002c,
LB_TAG_SKU_ID = 0x002d,
LB_TAG_SKU_ID = 0x002d, /* deprecated */
LB_TAG_BOOT_MEDIA_PARAMS = 0x0030,
LB_TAG_CBMEM_ENTRY = 0x0031,
LB_TAG_TSC_INFO = 0x0032,
Expand All @@ -81,6 +81,8 @@ enum {
LB_TAG_FMAP = 0x0037,
LB_TAG_PLATFORM_BLOB_VERSION = 0x0038,
LB_TAG_SMMSTOREV2 = 0x0039,
LB_TAG_BOARD_CONFIG = 0x0040,
/* The following options are CMOS-related */
LB_TAG_CMOS_OPTION_TABLE = 0x00c8,
LB_TAG_OPTION = 0x00c9,
LB_TAG_OPTION_ENUM = 0x00ca,
Expand Down Expand Up @@ -347,12 +349,6 @@ struct lb_x86_rom_mtrr {
uint32_t index;
};

struct lb_strapping_id {
uint32_t tag;
uint32_t size;
uint32_t id_code;
};

struct lb_spi_flash {
uint32_t tag;
uint32_t size;
Expand Down Expand Up @@ -416,6 +412,16 @@ struct lb_macs {
struct mac_address mac_addrs[0];
};

struct lb_board_config {
uint32_t tag;
uint32_t size;

struct lb_uint64 fw_config;
uint32_t board_id;
uint32_t ram_code;
uint32_t sku_id;
};

#define MAX_SERIALNO_LENGTH 32

/* The following structures are for the CMOS definitions table */
Expand Down
4 changes: 4 additions & 0 deletions src/commonlib/include/commonlib/timestamp_serialized.h
Expand Up @@ -52,6 +52,8 @@ enum timestamp_id {
TS_SELFBOOT_JUMP = 99,
TS_START_POSTCAR = 100,
TS_END_POSTCAR = 101,
TS_DELAY_START = 110,
TS_DELAY_END = 111,

/* 500+ reserved for vendorcode extensions (500-600: google/chromeos) */
TS_START_COPYVER = 501,
Expand Down Expand Up @@ -177,6 +179,8 @@ static const struct timestamp_id_to_name {
{ TS_LOAD_PAYLOAD, "load payload" },
{ TS_ACPI_WAKE_JUMP, "ACPI wake jump" },
{ TS_SELFBOOT_JUMP, "selfboot jump" },
{ TS_DELAY_START, "Forced delay start" },
{ TS_DELAY_END, "Forced delay end" },

{ TS_START_COPYVER, "starting to load verstage" },
{ TS_END_COPYVER, "finished loading verstage" },
Expand Down
10 changes: 10 additions & 0 deletions src/console/Kconfig
Expand Up @@ -58,6 +58,14 @@ if CONSOLE_SERIAL
comment "device-specific UART"
depends on HAVE_UART_SPECIAL

config OVERRIDE_UART_FOR_CONSOLE
bool
help
Set to "y" when the platform overrides the index of uart port by providing
a get_uart_for_console routine.

if !OVERRIDE_UART_FOR_CONSOLE

config UART_FOR_CONSOLE
int
prompt "Index for UART port to use for console" if !FIXED_UART_FOR_CONSOLE
Expand Down Expand Up @@ -87,6 +95,8 @@ depends on DRIVERS_UART_8250IO && UART_FOR_CONSOLE = 2
comment "Serial port base address = 0x2e8"
depends on DRIVERS_UART_8250IO && UART_FOR_CONSOLE = 3

endif

config UART_OVERRIDE_BAUDRATE
bool
help
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/agesa/family14/model_14_init.c
Expand Up @@ -52,7 +52,7 @@ static void model_14_init(struct device *dev)
msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
wrmsr(SYSCFG_MSR, msr);

if (acpi_is_wakeup())
if (acpi_is_wakeup_s3())
restore_mtrr();

x86_mtrr_check();
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/agesa/family15tn/model_15_init.c
Expand Up @@ -51,7 +51,7 @@ static void model_15_init(struct device *dev)
msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
wrmsr(SYSCFG_MSR, msr);

if (acpi_is_wakeup())
if (acpi_is_wakeup_s3())
restore_mtrr();

x86_mtrr_check();
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/agesa/family16kb/model_16_init.c
Expand Up @@ -49,7 +49,7 @@ static void model_16_init(struct device *dev)
msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
wrmsr(SYSCFG_MSR, msr);

if (acpi_is_wakeup())
if (acpi_is_wakeup_s3())
restore_mtrr();

x86_mtrr_check();
Expand Down
2 changes: 0 additions & 2 deletions src/cpu/amd/microcode/Makefile.inc

This file was deleted.

13 changes: 0 additions & 13 deletions src/cpu/amd/pi/00660F01/Kconfig

This file was deleted.

14 changes: 0 additions & 14 deletions src/cpu/amd/pi/00660F01/Makefile.inc

This file was deleted.

65 changes: 0 additions & 65 deletions src/cpu/amd/pi/00660F01/acpi/cpu.asl

This file was deleted.

7 changes: 0 additions & 7 deletions src/cpu/amd/pi/00660F01/chip_name.c

This file was deleted.

55 changes: 0 additions & 55 deletions src/cpu/amd/pi/00660F01/fixme.c

This file was deleted.

119 changes: 0 additions & 119 deletions src/cpu/amd/pi/00660F01/model_15_init.c

This file was deleted.

2 changes: 0 additions & 2 deletions src/cpu/amd/pi/Kconfig
Expand Up @@ -4,7 +4,6 @@ config CPU_AMD_PI
bool
default y if CPU_AMD_PI_00630F01
default y if CPU_AMD_PI_00730F01
default y if CPU_AMD_PI_00660F01
default n
select ARCH_ALL_STAGES_X86_32
select DRIVERS_AMD_PI
Expand Down Expand Up @@ -46,4 +45,3 @@ endif # CPU_AMD_PI

source "src/cpu/amd/pi/00630F01/Kconfig"
source "src/cpu/amd/pi/00730F01/Kconfig"
source "src/cpu/amd/pi/00660F01/Kconfig"
1 change: 0 additions & 1 deletion src/cpu/amd/pi/Makefile.inc
Expand Up @@ -2,4 +2,3 @@

subdirs-$(CONFIG_CPU_AMD_PI_00630F01) += 00630F01
subdirs-$(CONFIG_CPU_AMD_PI_00730F01) += 00730F01
subdirs-$(CONFIG_CPU_AMD_PI_00660F01) += 00660F01
6 changes: 3 additions & 3 deletions src/cpu/intel/Makefile.inc
Expand Up @@ -10,9 +10,9 @@ subdirs-$(CONFIG_CPU_INTEL_SOCKET_FCBGA559) += socket_FCBGA559
subdirs-$(CONFIG_CPU_INTEL_SOCKET_M) += socket_m
subdirs-$(CONFIG_CPU_INTEL_SOCKET_P) += socket_p
subdirs-$(CONFIG_CPU_INTEL_SOCKET_MPGA604) += socket_mPGA604
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IRONLAKE) += model_2065x
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += model_206ax
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell
subdirs-$(CONFIG_CPU_INTEL_MODEL_2065X) += model_2065x
subdirs-$(CONFIG_CPU_INTEL_MODEL_206AX) += model_206ax
subdirs-$(CONFIG_CPU_INTEL_HASWELL) += haswell
subdirs-$(CONFIG_CPU_INTEL_SLOT_1) += slot_1
subdirs-$(CONFIG_CPU_INTEL_SOCKET_LGA775) += socket_LGA775

Expand Down
20 changes: 20 additions & 0 deletions src/cpu/intel/car/cache_as_ram_symbols.inc
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/* Trick the linker into supporting x86_64 relocations in 32bit code */
#if ENV_X86_64
#define uintptr_t quad
#else
#define uintptr_t long
#endif

rom_mtrr_mask:
.uintptr_t _rom_mtrr_mask

rom_mtrr_base:
.uintptr_t _rom_mtrr_base

car_mtrr_mask:
.uintptr_t _car_mtrr_mask

car_mtrr_start:
.uintptr_t _car_mtrr_start
25 changes: 19 additions & 6 deletions src/cpu/intel/car/non-evict/cache_as_ram.S
Expand Up @@ -9,6 +9,8 @@

.global bootblock_pre_c_entry

#include <cpu/intel/car/cache_as_ram_symbols.inc>

.code32
_cache_as_ram_setup:

Expand Down Expand Up @@ -83,11 +85,10 @@ addrsize_set_high:
movl $MTRR_PHYS_MASK(1), %ecx
wrmsr


post_code(0x23)
/* Set Cache-as-RAM base address. */
movl $(MTRR_PHYS_BASE(0)), %ecx
movl $_car_mtrr_start, %eax
movl car_mtrr_start, %eax
orl $MTRR_TYPE_WRBACK, %eax
xorl %edx, %edx
wrmsr
Expand All @@ -96,20 +97,20 @@ addrsize_set_high:
/* Set Cache-as-RAM mask. */
movl $(MTRR_PHYS_MASK(0)), %ecx
rdmsr
movl $_car_mtrr_mask, %eax
mov car_mtrr_mask, %eax
orl $MTRR_PHYS_MASK_VALID, %eax
wrmsr

/* Enable cache for our code in Flash because we do XIP here */
movl $MTRR_PHYS_BASE(1), %ecx
xorl %edx, %edx
movl $_rom_mtrr_base, %eax
mov rom_mtrr_base, %eax
orl $MTRR_TYPE_WRPROT, %eax
wrmsr

movl $MTRR_PHYS_MASK(1), %ecx
rdmsr
movl $_rom_mtrr_mask, %eax
mov rom_mtrr_mask, %eax
orl $MTRR_PHYS_MASK_VALID, %eax
wrmsr

Expand Down Expand Up @@ -207,15 +208,27 @@ end_microcode_update:
/* Need to align stack to 16 bytes at call instruction. Account for
the pushes below. */
andl $0xfffffff0, %esp
subl $4, %esp

#if ENV_X86_64

#include <cpu/x86/64bit/entry64.inc>

movd %mm2, %rdi
shlq $32, %rdi
movd %mm1, %rsi
or %rsi, %rdi
movd %mm0, %rsi

#else
subl $4, %esp
/* push TSC and BIST to stack */
movd %mm0, %eax
pushl %eax /* BIST */
movd %mm2, %eax
pushl %eax /* tsc[63:32] */
movd %mm1, %eax
pushl %eax /* tsc[31:0] */
#endif

before_c_entry:
post_code(0x29)
Expand Down
3 changes: 3 additions & 0 deletions src/cpu/intel/common/Kconfig
Expand Up @@ -32,6 +32,9 @@ config CPU_INTEL_COMMON_TIMEBASE

endif

config CPU_INTEL_COMMON_VOLTAGE
bool

config CPU_INTEL_COMMON_SMM
bool
default y if CPU_INTEL_COMMON
1 change: 1 addition & 0 deletions src/cpu/intel/common/Makefile.inc
@@ -1,5 +1,6 @@
ramstage-$(CONFIG_CPU_INTEL_COMMON) += common_init.c
ramstage-$(CONFIG_CPU_INTEL_COMMON) += hyperthreading.c
ramstage-$(CONFIG_CPU_INTEL_COMMON_VOLTAGE) += voltage.c

ifeq ($(CONFIG_CPU_INTEL_COMMON_TIMEBASE),y)
bootblock-y += fsb.c
Expand Down
16 changes: 9 additions & 7 deletions src/cpu/intel/common/common_init.c
Expand Up @@ -130,13 +130,6 @@ void cpu_init_cppc_config(struct cppc_config *config, u32 version)
*/
config->regs[CPPC_HIGHEST_PERF] = msr;

/*
* Nominal Performance -> Guaranteed Performance:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x771, 0x04,)},
*/
msr.bit_offset = 8;
config->regs[CPPC_NOMINAL_PERF] = msr;

/*
* Lowest Nonlinear Performance -> Most Efficient Performance:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x10, 0x771, 0x04,)},
Expand All @@ -158,6 +151,15 @@ void cpu_init_cppc_config(struct cppc_config *config, u32 version)
msr.bit_offset = 8;
config->regs[CPPC_GUARANTEED_PERF] = msr;

msr.addrl = MSR_PLATFORM_INFO;

/*
* Nominal Performance -> Maximum Non-Turbo Ratio:
* ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0xce, 0x04,)},
*/
msr.bit_offset = 8;
config->regs[CPPC_NOMINAL_PERF] = msr;

msr.addrl = IA32_HWP_REQUEST;

/*
Expand Down
12 changes: 12 additions & 0 deletions src/cpu/intel/common/voltage.c
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <cpu/x86/msr.h>
#include <smbios.h>

/* This is not an architectural MSR. */
#define MSR_PERF_STATUS 0x198

unsigned int smbios_cpu_get_voltage(void)
{
return (rdmsr(MSR_PERF_STATUS).hi & 0xffff) * 10 / 8192;
}
2 changes: 1 addition & 1 deletion src/cpu/intel/fit/Kconfig
Expand Up @@ -5,7 +5,7 @@ config CPU_INTEL_FIRMWARE_INTERFACE_TABLE

config CPU_INTEL_NUM_FIT_ENTRIES
int
default 16 if INTEL_TXT
default 16 if INTEL_TXT || INTEL_CBNT_SUPPORT
default 4
depends on CPU_INTEL_FIRMWARE_INTERFACE_TABLE
help
Expand Down
1 change: 1 addition & 0 deletions src/cpu/intel/haswell/Kconfig
Expand Up @@ -20,6 +20,7 @@ config CPU_SPECIFIC_OPTIONS
select CPU_INTEL_COMMON
select CPU_INTEL_COMMON_TIMEBASE
select HAVE_ASAN_IN_ROMSTAGE
select CPU_INTEL_COMMON_VOLTAGE

config SMM_TSEG_SIZE
hex
Expand Down
22 changes: 21 additions & 1 deletion src/cpu/intel/haswell/haswell.h
Expand Up @@ -76,6 +76,26 @@
#define MSR_CONFIG_TDP_CONTROL 0x64b
#define MSR_TURBO_ACTIVATION_RATIO 0x64c

#define SMM_MCA_CAP_MSR 0x17d
#define SMM_CPU_SVRSTR_BIT 57
#define SMM_CPU_SVRSTR_MASK (1 << (SMM_CPU_SVRSTR_BIT - 32))

#define MSR_PRMRR_PHYS_BASE 0x1f4
#define MSR_PRMRR_PHYS_MASK 0x1f5
#define MSR_UNCORE_PRMRR_PHYS_BASE 0x2f4
#define MSR_UNCORE_PRMRR_PHYS_MASK 0x2f5

#define SMM_FEATURE_CONTROL_MSR 0x4e0
#define SMM_CPU_SAVE_EN (1 << 1)

/* SMM save state MSRs */
#define SMBASE_MSR 0xc20
#define IEDBASE_MSR 0xc22

/* MTRR_CAP_MSR bit definitions */
#define SMRR_SUPPORTED (1 << 11)
#define PRMRR_SUPPORTED (1 << 12)

/* P-state configuration */
#define PSS_MAX_ENTRIES 8
#define PSS_RATIO_STEP 2
Expand All @@ -84,7 +104,7 @@

/* PCODE MMIO communications live in the MCHBAR. */
#define BIOS_MAILBOX_INTERFACE 0x5da4
#define MAILBOX_RUN_BUSY (1UL << 31)
#define MAILBOX_RUN_BUSY (1 << 31)
#define MAILBOX_BIOS_CMD_READ_PCS 1
#define MAILBOX_BIOS_CMD_WRITE_PCS 2
#define MAILBOX_BIOS_CMD_READ_CALIBRATION 0x509
Expand Down
16 changes: 0 additions & 16 deletions src/cpu/intel/haswell/smmrelocate.c
Expand Up @@ -17,22 +17,6 @@
#include <smp/node.h>
#include "haswell.h"

#define MSR_PRMRR_PHYS_BASE 0x1f4
#define MSR_PRMRR_PHYS_MASK 0x1f5
#define MSR_UNCORE_PRMRR_PHYS_BASE 0x2f4
#define MSR_UNCORE_PRMRR_PHYS_MASK 0x2f5
#define SMM_MCA_CAP_MSR 0x17d
#define SMM_CPU_SVRSTR_BIT 57
#define SMM_CPU_SVRSTR_MASK (1 << (SMM_CPU_SVRSTR_BIT - 32))
#define SMM_FEATURE_CONTROL_MSR 0x4e0
#define SMM_CPU_SAVE_EN (1 << 1)
/* SMM save state MSRs */
#define SMBASE_MSR 0xc20
#define IEDBASE_MSR 0xc22

#define SMRR_SUPPORTED (1 << 11)
#define PRMRR_SUPPORTED (1 << 12)

static void update_save_state(int cpu, uintptr_t curr_smbase,
uintptr_t staggered_smbase,
struct smm_relocation_params *relo_params)
Expand Down
20 changes: 20 additions & 0 deletions src/cpu/intel/model_206ax/model_206ax_init.c
Expand Up @@ -18,6 +18,7 @@
#include "chip.h"
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/common/common.h>
#include <smbios.h>

/*
* List of supported C-states in this processor
Expand Down Expand Up @@ -360,6 +361,25 @@ static void set_max_ratio(void)
((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
}

unsigned int smbios_cpu_get_max_speed_mhz(void)
{
msr_t msr;
msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
return (msr.lo & 0xff) * SANDYBRIDGE_BCLK;
}

unsigned int smbios_cpu_get_current_speed_mhz(void)
{
msr_t msr;
msr = rdmsr(MSR_PLATFORM_INFO);
return ((msr.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK;
}

unsigned int smbios_processor_external_clock(void)
{
return SANDYBRIDGE_BCLK;
}

static void configure_mca(void)
{
msr_t msr;
Expand Down
4 changes: 2 additions & 2 deletions src/cpu/intel/smm/gen1/smmrelocate.c
Expand Up @@ -59,8 +59,8 @@ static void write_smrr_alt(struct smm_relocation_params *relo_params)
printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->smrr_base.lo, relo_params->smrr_mask.lo);

wrmsr(MSR_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(MSR_SMRR_PHYS_MASK, relo_params->smrr_mask);
wrmsr(CORE2_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(CORE2_SMRR_PHYS_MASK, relo_params->smrr_mask);
}

static void fill_in_relocation_params(struct smm_relocation_params *params)
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/socket_441/Kconfig
Expand Up @@ -12,7 +12,7 @@ config SOCKET_SPECIFIC_OPTIONS # dummy

config C_ENV_BOOTBLOCK_SIZE
hex
default 0x4000
default 0x8000

config DCACHE_RAM_BASE
hex
Expand Down
12 changes: 7 additions & 5 deletions src/cpu/x86/16bit/reset16.ld
@@ -1,13 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/* _RESET_VECTOR: typically the top of the ROM */
/*
* _ROMTOP : The top of the ROM used where we
* need to put the reset vector.
*/

SECTIONS {
/* Trigger an error if I have an unuseable start address */
_TOO_LOW = CONFIG_X86_RESET_VECTOR - 0xfff0;
_bogus = ASSERT(_start16bit >= _TOO_LOW, "_start16bit too low. Please report.");

. = CONFIG_X86_RESET_VECTOR;
_bogus = ASSERT(_start16bit >= 0xffff0000, "_start16bit too low. Please report.");
_ROMTOP = 0xfffffff0;
. = _ROMTOP;
.reset . : {
*(.reset);
. = 15;
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/x86/lapic/lapic.c
Expand Up @@ -4,7 +4,7 @@
#include <console/console.h>
#include <smp/node.h>

void do_lapic_init(void)
void lapic_virtual_wire_mode_init(void)
{
const uint32_t lvt0_mask = LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER |
LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY |
Expand Down
22 changes: 11 additions & 11 deletions src/cpu/x86/mp_init.c
Expand Up @@ -112,7 +112,7 @@ extern char _binary_sipi_vector_start[];
/* The SIPI vector is loaded at the SMM_DEFAULT_BASE. The reason is at the
* memory range is already reserved so the OS cannot use it. That region is
* free to use for AP bringup before SMM is initialized. */
static const uint32_t sipi_vector_location = SMM_DEFAULT_BASE;
static const uintptr_t sipi_vector_location = SMM_DEFAULT_BASE;
static const int sipi_vector_location_size = SMM_DEFAULT_SIZE;

struct mp_flight_plan {
Expand Down Expand Up @@ -338,16 +338,16 @@ static atomic_t *load_sipi_vector(struct mp_params *mp_params)

setup_default_sipi_vector_params(sp);
/* Setup MSR table. */
sp->msr_table_ptr = (uint32_t)&mod_loc[module_size];
sp->msr_table_ptr = (uintptr_t)&mod_loc[module_size];
sp->msr_count = num_msrs;
/* Provide pointer to microcode patch. */
sp->microcode_ptr = (uint32_t)mp_params->microcode_pointer;
sp->microcode_ptr = (uintptr_t)mp_params->microcode_pointer;
/* Pass on ability to load microcode in parallel. */
if (mp_params->parallel_microcode_load)
sp->microcode_lock = 0;
else
sp->microcode_lock = ~0;
sp->c_handler = (uint32_t)&ap_init;
sp->c_handler = (uintptr_t)&ap_init;
ap_count = &sp->ap_count;
atomic_set(ap_count, 0);

Expand Down Expand Up @@ -434,7 +434,7 @@ static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps)
if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
if (apic_wait_timeout(1000 /* 1 ms */, 50)) {
printk(BIOS_DEBUG, "timed out. Aborting.\n");
printk(BIOS_ERR, "timed out. Aborting.\n");
return -1;
}
printk(BIOS_DEBUG, "done.\n");
Expand All @@ -451,7 +451,7 @@ static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps)
if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
if (apic_wait_timeout(1000 /* 1 ms */, 50)) {
printk(BIOS_DEBUG, "timed out. Aborting.\n");
printk(BIOS_ERR, "timed out. Aborting.\n");
return -1;
}
printk(BIOS_DEBUG, "done.\n");
Expand All @@ -462,7 +462,7 @@ static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps)
LAPIC_DM_STARTUP | sipi_vector);
printk(BIOS_DEBUG, "Waiting for 1st SIPI to complete...");
if (apic_wait_timeout(10000 /* 10 ms */, 50 /* us */)) {
printk(BIOS_DEBUG, "timed out.\n");
printk(BIOS_ERR, "timed out.\n");
return -1;
}
printk(BIOS_DEBUG, "done.\n");
Expand All @@ -477,7 +477,7 @@ static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps)
if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
if (apic_wait_timeout(1000 /* 1 ms */, 50)) {
printk(BIOS_DEBUG, "timed out. Aborting.\n");
printk(BIOS_ERR, "timed out. Aborting.\n");
return -1;
}
printk(BIOS_DEBUG, "done.\n");
Expand All @@ -488,14 +488,14 @@ static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps)
LAPIC_DM_STARTUP | sipi_vector);
printk(BIOS_DEBUG, "Waiting for 2nd SIPI to complete...");
if (apic_wait_timeout(10000 /* 10 ms */, 50 /* us */)) {
printk(BIOS_DEBUG, "timed out.\n");
printk(BIOS_ERR, "timed out.\n");
return -1;
}
printk(BIOS_DEBUG, "done.\n");

/* Wait for CPUs to check in. */
if (wait_for_aps(num_aps, ap_count, 10000 /* 10 ms */, 50 /* us */)) {
printk(BIOS_DEBUG, "Not all APs checked in: %d/%d.\n",
if (wait_for_aps(num_aps, ap_count, 100000 /* 100 ms */, 50 /* us */)) {
printk(BIOS_ERR, "Not all APs checked in: %d/%d.\n",
atomic_read(num_aps), ap_count);
return -1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/cpu/x86/mtrr/mtrr.c
Expand Up @@ -484,9 +484,9 @@ static void calc_var_mtrr_range(struct var_mtrr_state *var_state,
* size. The maximum size is calculated by a function of the
* min base bit set and maximum size bit set. */
if (addr_lsb > size_msb)
mtrr_size = 1 << size_msb;
mtrr_size = 1ULL << size_msb;
else
mtrr_size = 1 << addr_lsb;
mtrr_size = 1ULL << addr_lsb;

if (var_state->prepare_msrs)
prep_var_mtrr(var_state, base, mtrr_size, mtrr_type);
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/x86/sipi_vector.S
Expand Up @@ -121,7 +121,7 @@ _start:

/* Protect microcode loading. */
lock_microcode:
lock bts $0, microcode_lock
lock btsl $0, microcode_lock
jc lock_microcode

load_microcode:
Expand Down
10 changes: 7 additions & 3 deletions src/cpu/x86/smm/Makefile.inc
Expand Up @@ -20,7 +20,7 @@ smm-generic-ccopts += -D__SMM__
smm-c-deps:=$$(OPTION_TABLE_H)

$(obj)/smm/smm.o: $$(smm-objs) $(COMPILER_RT_smm)
$(LD_smm) -nostdlib -r -o $@ $(COMPILER_RT_FLAGS_smm) --whole-archive --start-group $(smm-objs) --no-whole-archive $(COMPILER_RT_smm) --end-group
$(LD_smm) -nostdlib -r -o $@ $(COMPILER_RT_FLAGS_smm) --whole-archive --start-group $(filter-out %.ld, $(smm-objs)) --no-whole-archive $(COMPILER_RT_smm) --end-group

# change to the target path because objcopy will use the path name in its
# ELF symbol names.
Expand All @@ -32,6 +32,8 @@ ifeq ($(CONFIG_HAVE_SMI_HANDLER),y)
ramstage-srcs += $(obj)/cpu/x86/smm/smm.manual
endif

smm-y += save_state.c

ifeq ($(CONFIG_SMM_TSEG),y)

ramstage-y += tseg_region.c
Expand Down Expand Up @@ -76,8 +78,10 @@ $(obj)/smm/smm: $(obj)/smm/smm.elf.rmod

else # CONFIG_SMM_TSEG

$(obj)/smm/smm: $(obj)/smm/smm.o $(src)/cpu/x86/smm/smm.ld
$(LD_smm) $(LDFLAGS_smm) -o $(obj)/smm/smm.elf -T $(src)/cpu/x86/smm/smm.ld $(obj)/smm/smm.o
smm-y += smm.ld

$(obj)/smm/smm: $(obj)/smm/smm.o $(call src-to-obj,smm,$(src)/cpu/x86/smm/smm.ld)
$(LD_smm) $(LDFLAGS_smm) -o $(obj)/smm/smm.elf -T $(call src-to-obj,smm,$(src)/cpu/x86/smm/smm.ld) $(obj)/smm/smm.o
$(NM_smm) -n $(obj)/smm/smm.elf | sort > $(obj)/smm/smm.map
$(OBJCOPY_smm) -O binary $(obj)/smm/smm.elf $@

Expand Down
77 changes: 77 additions & 0 deletions src/cpu/x86/smm/save_state.c
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <cpu/x86/smm.h>
#include <cpu/x86/save_state.h>

/* These are weakly linked such that platforms can link only the save state
ops they actually require. */
const struct smm_save_state_ops *legacy_ops __weak = NULL;
const struct smm_save_state_ops *em64t100_ops __weak = NULL;
const struct smm_save_state_ops *em64t101_ops __weak = NULL;
const struct smm_save_state_ops *amd64_ops __weak = NULL;

static const struct smm_save_state_ops *save_state;

/* Returns -1 on failure, 0 on success */
static int init_save_state(void)
{
const uint32_t revision = smm_revision();
int i;
static bool initialized = false;
const struct smm_save_state_ops *save_state_ops[] = {
legacy_ops,
em64t100_ops,
em64t101_ops,
amd64_ops,
};

if (initialized)
return 0;

for (i = 0; i < ARRAY_SIZE(save_state_ops); i++) {
const struct smm_save_state_ops *ops = save_state_ops[i];
const uint32_t *rev;

if (ops == NULL)
continue;

for (rev = ops->revision_table; *rev != SMM_REV_INVALID; rev++)
if (*rev == revision) {
save_state = ops;
initialized = true;
return 0;
}
}

return -1;
}

int get_apmc_node(u8 cmd)
{
if (init_save_state())
return -1;

return save_state->apmc_node(cmd);
}

int get_save_state_reg(const enum cpu_reg reg, const int node, void *out, const uint8_t length)
{
if (init_save_state())
return -1;

if (node > CONFIG_MAX_CPUS)
return -1;

return save_state->get_reg(reg, node, out, length);
}

int set_save_state_reg(const enum cpu_reg reg, const int node, void *in, const uint8_t length)
{
if (init_save_state())
return -1;

if (node > CONFIG_MAX_CPUS)
return -1;

return save_state->set_reg(reg, node, in, length);
}
54 changes: 4 additions & 50 deletions src/cpu/x86/smm/smihandler.c
Expand Up @@ -14,23 +14,6 @@
#include <spi-generic.h>
#endif

typedef enum {
AMD64,
EM64T100,
EM64T101,
LEGACY
} save_state_type_t;

typedef struct {
save_state_type_t type;
union {
amd64_smm_state_save_area_t *amd64_state_save;
em64t100_smm_state_save_area_t *em64t100_state_save;
em64t101_smm_state_save_area_t *em64t101_state_save;
legacy_smm_state_save_area_t *legacy_state_save;
};
} smm_state_save_area_t;

static int do_driver_init = 1;

typedef enum { SMI_LOCKED, SMI_UNLOCKED } smi_semaphore;
Expand Down Expand Up @@ -162,9 +145,6 @@ bool smm_region_overlaps_handler(const struct region *r)
void smi_handler(void)
{
unsigned int node;
const uint32_t smm_rev = smm_revision();
smm_state_save_area_t state_save;
u32 smm_base = SMM_BASE; /* ASEG */

/* Are we ok to execute the handler? */
if (!smi_obtain_lock()) {
Expand All @@ -190,36 +170,10 @@ void smi_handler(void)

printk(BIOS_SPEW, "\nSMI# #%d\n", node);

switch (smm_rev) {
case 0x00030002:
case 0x00030007:
state_save.type = LEGACY;
state_save.legacy_state_save =
smm_save_state(smm_base,
SMM_LEGACY_ARCH_OFFSET, node);
break;
case 0x00030100:
state_save.type = EM64T100;
state_save.em64t100_state_save =
smm_save_state(smm_base,
SMM_EM64T100_ARCH_OFFSET, node);
break;
case 0x00030101: /* SandyBridge, IvyBridge, and Haswell */
state_save.type = EM64T101;
state_save.em64t101_state_save =
smm_save_state(smm_base,
SMM_EM64T101_ARCH_OFFSET, node);
break;
case 0x00020064:
case 0x00030064:
state_save.type = AMD64;
state_save.amd64_state_save =
smm_save_state(smm_base,
SMM_AMD64_ARCH_OFFSET, node);
break;
default:
printk(BIOS_DEBUG, "smm_revision: 0x%08x\n", smm_rev);
printk(BIOS_DEBUG, "SMI# not supported on your CPU\n");
/* Use smm_get_save_state() to see if the smm revision is supported */
if (smm_get_save_state(node) == NULL) {
printk(BIOS_WARNING, "smm_revision: 0x%08x\n", smm_revision());
printk(BIOS_WARNING, "SMI# not supported on your CPU\n");
/* Don't release lock, so no further SMI will happen,
* if we don't handle it anyways.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/cpu/x86/smm/smm.ld
Expand Up @@ -2,6 +2,9 @@

/* Maximum number of CPUs/cores */
CPUS = 4;

_ = ASSERT(CPUS >= CONFIG_MAX_CPUS, "The ASEG SMM code only supports up to 4 CPUS");

ENTRY(smm_handler_start);

SECTIONS
Expand Down
6 changes: 6 additions & 0 deletions src/cpu/x86/smm/smm_module_loader.c
Expand Up @@ -209,6 +209,12 @@ static int smm_module_setup_stub(void *smbase, size_t smm_size,
smm_stub_size = rmodule_memory_size(&smm_stub);
stub_entry_offset = rmodule_entry_offset(&smm_stub);

if (smm_stub_size > params->per_cpu_save_state_size) {
printk(BIOS_ERR, "SMM Module: SMM stub size larger than save state size\n");
printk(BIOS_ERR, "SMM Module: Staggered entry points will overlap stub\n");
return -1;
}

/* Assume the stub is always small enough to live within upper half of
* SMRAM region after the save state space has been allocated. */
smm_stub_loc = &base[SMM_ENTRY_OFFSET];
Expand Down
18 changes: 13 additions & 5 deletions src/cpu/x86/smm/smm_module_loaderv2.c
Expand Up @@ -134,6 +134,12 @@ static int smm_create_map(uintptr_t smbase, unsigned int num_cpus,
return 0;
}

if (stub_size > ss_size) {
printk(BIOS_ERR, "%s: Save state larger than SMM stub size\n", __func__);
printk(BIOS_ERR, " Decrease stub size or increase the size allocated for the save state\n");
return 0;
}

for (i = 0; i < num_cpus; i++) {
cpus[i].smbase = base;
cpus[i].entry = base + smm_entry_offset;
Expand Down Expand Up @@ -407,12 +413,14 @@ static int smm_module_setup_stub(void *smbase, size_t smm_size,
* for default handler, but for relocated handler it lives at the beginning
* of SMRAM which is TSEG base
*/
size = params->num_concurrent_stacks * params->per_cpu_stack_size;
stacks_top = smm_stub_place_stacks((char *)params->smram_start, size, params);
const size_t total_stack_size = params->num_concurrent_stacks *
params->per_cpu_stack_size;
stacks_top = smm_stub_place_stacks((char *)params->smram_start, total_stack_size,
params);
if (stacks_top == NULL) {
printk(BIOS_ERR, "%s: not enough space for stacks\n", __func__);
printk(BIOS_ERR, "%s: ....need -> %p : available -> %zx\n", __func__,
base, size);
base, total_stack_size);
return -1;
}
params->stack_top = stacks_top;
Expand Down Expand Up @@ -440,8 +448,8 @@ static int smm_module_setup_stub(void *smbase, size_t smm_size,
stub_params->runtime.save_state_size = params->per_cpu_save_state_size;
stub_params->runtime.num_cpus = params->num_concurrent_stacks;

printk(BIOS_DEBUG, "%s: stack_end = 0x%x\n",
__func__, stub_params->runtime.smbase);
printk(BIOS_DEBUG, "%s: stack_end = 0x%lx\n",
__func__, stub_params->stack_top - total_stack_size);
printk(BIOS_DEBUG,
"%s: stack_top = 0x%x\n", __func__, stub_params->stack_top);
printk(BIOS_DEBUG, "%s: stack_size = 0x%x\n",
Expand Down
36 changes: 23 additions & 13 deletions src/device/Kconfig
Expand Up @@ -491,18 +491,6 @@ config MMCONF_SUPPORT
bool
default !NO_MMCONF_SUPPORT

config HYPERTRANSPORT_PLUGIN_SUPPORT
bool
default n

config HT_CHAIN_UNITID_BASE
int
default 0

config HT_CHAIN_END_UNITID_BASE
int
default 0

config PCIX_PLUGIN_SUPPORT
bool
default y
Expand All @@ -520,7 +508,7 @@ config PCIEXP_PLUGIN_SUPPORT
default y

config PCI_ALLOW_BUS_MASTER
bool "Allow PCI bus master bit to be enabled by coreboot"
bool "Allow coreboot to set optional PCI bus master bits"
default y
help
For security reasons, bus mastering should be enabled as late as
Expand All @@ -532,6 +520,28 @@ config PCI_ALLOW_BUS_MASTER
instance, for libpayload based payloads as the drivers don't enable
bus mastering for PCI bridges.

if PCI_ALLOW_BUS_MASTER

config PCI_SET_BUS_MASTER_PCI_BRIDGES
bool "PCI bridges"
default y
help
Let coreboot configure bus mastering for PCI bridges. Enabling bus
mastering for a PCI bridge also allows it to forward requests from
downstream devices. Currently, payloads ignore this and only enable
bus mastering for the downstream device. Hence, this option is needed
for compatibility until payloads are fixed.

config PCI_ALLOW_BUS_MASTER_ANY_DEVICE
bool "Any devices"
default y
select PCI_SET_BUS_MASTER_PCI_BRIDGES
help
Allow coreboot to enable PCI bus mastering for any device. The actual
selection of devices depends on the various PCI drivers in coreboot.

endif # PCI_ALLOW_BUS_MASTER

endif # PCI

if PCIEXP_PLUGIN_SUPPORT
Expand Down
1 change: 0 additions & 1 deletion src/device/Makefile.inc
Expand Up @@ -35,7 +35,6 @@ postcar-y += pci_ops.c
ramstage-y += pci_ops.c
smm-y += pci_ops.c

ramstage-$(CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT) += hypertransport.c
ramstage-$(CONFIG_PCIX_PLUGIN_SUPPORT) += pcix_device.c
ramstage-$(CONFIG_PCIEXP_PLUGIN_SUPPORT) += pciexp_device.c
ramstage-$(CONFIG_CARDBUS_PLUGIN_SUPPORT) += cardbus_device.c
Expand Down
14 changes: 7 additions & 7 deletions src/device/azalia_device.c
Expand Up @@ -40,7 +40,7 @@ static int codec_detect(u8 *base)
int count;

/* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
if (set_bits(base + HDA_GCTL_REG, 1, HDA_GCTL_CRST) == -1)
if (set_bits(base + HDA_GCTL_REG, 1, HDA_GCTL_CRST) < 0)
goto no_codec;

/* clear STATESTS bits (BAR + 0xe)[2:0] */
Expand All @@ -62,11 +62,11 @@ static int codec_detect(u8 *base)
goto no_codec;

/* Set Bit 0 to 0 to enter reset state (BAR + 0x8)[0] */
if (set_bits(base + HDA_GCTL_REG, 1, 0) == -1)
if (set_bits(base + HDA_GCTL_REG, 1, 0) < 0)
goto no_codec;

/* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
if (set_bits(base + HDA_GCTL_REG, 1, HDA_GCTL_CRST) == -1)
if (set_bits(base + HDA_GCTL_REG, 1, HDA_GCTL_CRST) < 0)
goto no_codec;

/* Read in Codec location (BAR + 0xe)[2..0] */
Expand Down Expand Up @@ -166,15 +166,15 @@ static void codec_init(struct device *dev, u8 *base, int addr)
printk(BIOS_DEBUG, "azalia_audio: Initializing codec #%d\n", addr);

/* 1 */
if (wait_for_ready(base) == -1) {
if (wait_for_ready(base) < 0) {
printk(BIOS_DEBUG, " codec not ready.\n");
return;
}

reg32 = (addr << 28) | 0x000f0000;
write32(base + HDA_IC_REG, reg32);

if (wait_for_valid(base) == -1) {
if (wait_for_valid(base) < 0) {
printk(BIOS_DEBUG, " codec not valid.\n");
return;
}
Expand All @@ -192,12 +192,12 @@ static void codec_init(struct device *dev, u8 *base, int addr)

/* 3 */
for (i = 0; i < verb_size; i++) {
if (wait_for_ready(base) == -1)
if (wait_for_ready(base) < 0)
return;

write32(base + HDA_IC_REG, verb[i]);

if (wait_for_valid(base) == -1)
if (wait_for_valid(base) < 0)
return;
}
printk(BIOS_DEBUG, "azalia_audio: verb loaded.\n");
Expand Down
499 changes: 0 additions & 499 deletions src/device/hypertransport.c

This file was deleted.

49 changes: 11 additions & 38 deletions src/device/pci_device.c
Expand Up @@ -19,7 +19,6 @@
#include <device/pci_ids.h>
#include <device/pcix.h>
#include <device/pciexp.h>
#include <device/hypertransport.h>
#include <pc80/i8259.h>
#include <security/vboot/vbnv.h>
#include <timestamp.h>
Expand Down Expand Up @@ -542,7 +541,8 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
dev->command |= PCI_COMMAND_MEMORY;
if (resource->flags & IORESOURCE_IO)
dev->command |= PCI_COMMAND_IO;
if (resource->flags & IORESOURCE_PCI_BRIDGE)
if (resource->flags & IORESOURCE_PCI_BRIDGE &&
CONFIG(PCI_SET_BUS_MASTER_PCI_BRIDGES))
dev->command |= PCI_COMMAND_MASTER;
}

Expand Down Expand Up @@ -861,19 +861,6 @@ static struct device_operations *get_pci_bridge_ops(struct device *dev)
return &default_pcix_ops_bus;
}
#endif
#if CONFIG(HYPERTRANSPORT_PLUGIN_SUPPORT)
unsigned int htpos = 0;
while ((htpos = pci_find_next_capability(dev, PCI_CAP_ID_HT, htpos))) {
u16 flags;
flags = pci_read_config16(dev, htpos + PCI_CAP_FLAGS);
if ((flags >> 13) == 1) {
/* Host or Secondary Interface */
printk(BIOS_DEBUG, "%s subordinate bus HT\n",
dev_path(dev));
return &default_ht_ops_bus;
}
}
#endif
#if CONFIG(PCIEXP_PLUGIN_SUPPORT)
unsigned int pciexpos;
pciexpos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
Expand Down Expand Up @@ -953,13 +940,16 @@ static void set_pci_ops(struct device *dev)
if ((driver->vendor == dev->vendor) &&
device_id_match(driver, dev->device)) {
dev->ops = (struct device_operations *)driver->ops;
printk(BIOS_SPEW, "%s [%04x/%04x] %sops\n",
dev_path(dev), driver->vendor, driver->device,
(driver->ops->scan_bus ? "bus " : ""));
return;
break;
}
}

if (dev->ops) {
printk(BIOS_SPEW, "%s [%04x/%04x] %sops\n", dev_path(dev),
driver->vendor, driver->device, (driver->ops->scan_bus ? "bus " : ""));
return;
}

/* If I don't have a specific driver use the default operations. */
switch (dev->hdr_type & 0x7f) { /* Header type */
case PCI_HEADER_TYPE_NORMAL:
Expand Down Expand Up @@ -1128,7 +1118,8 @@ struct device *pci_probe_dev(struct device *dev, struct bus *bus,
dev->class = class >> 8;

/* Architectural/System devices always need to be bus masters. */
if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM)
if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM &&
CONFIG(PCI_ALLOW_BUS_MASTER_ANY_DEVICE))
dev->command |= PCI_COMMAND_MASTER;

/*
Expand Down Expand Up @@ -1648,21 +1639,3 @@ void pci_dev_disable_bus_master(const struct device *dev)
pci_update_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MASTER, 0x0);
}
#endif

bool pci_dev_is_wake_source(const struct device *dev)
{
unsigned int pm_cap;
uint16_t pmcs;

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

pm_cap = pci_find_capability(dev, PCI_CAP_ID_PM);
if (!pm_cap)
return false;

pmcs = pci_read_config16(dev, pm_cap + PCI_PM_CTRL);

/* PCI Device is a wake source if PME_ENABLE and PME_STATUS are set in PMCS register. */
return (pmcs & PCI_PM_CTRL_PME_ENABLE) && (pmcs & PCI_PM_CTRL_PME_STATUS);
}
18 changes: 18 additions & 0 deletions src/device/pci_ops.c
Expand Up @@ -78,3 +78,21 @@ void __noreturn pcidev_die(void)
{
die("PCI: dev is NULL!\n");
}

bool pci_dev_is_wake_source(const struct device *dev)
{
unsigned int pm_cap;
uint16_t pmcs;

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

pm_cap = pci_find_capability(dev, PCI_CAP_ID_PM);
if (!pm_cap)
return false;

pmcs = pci_s_read_config16(PCI_BDF(dev), pm_cap + PCI_PM_CTRL);

/* PCI Device is a wake source if PME_ENABLE and PME_STATUS are set in PMCS register. */
return (pmcs & PCI_PM_CTRL_PME_ENABLE) && (pmcs & PCI_PM_CTRL_PME_STATUS);
}
2 changes: 2 additions & 0 deletions src/drivers/aspeed/common/ast_mode_corebootfb.c
Expand Up @@ -2,6 +2,8 @@
/*
* Copied from Linux drivers/gpu/drm/ast/ast_mode.c
*/

#include <console/console.h>
#include <edid.h>
#include <device/pci_def.h>

Expand Down
1 change: 1 addition & 0 deletions src/drivers/aspeed/common/ast_post.c
Expand Up @@ -2,6 +2,7 @@

#define COREBOOT_AST_FAILOVER_TIMEOUT 10000000

#include <console/console.h>
#include <delay.h>

#include "ast_drv.h"
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/generic/adau7002/adau7002.c
Expand Up @@ -17,7 +17,7 @@ static void adau7002_fill_ssdt(const struct device *dev)
struct drivers_generic_adau7002_config *config;
struct acpi_dp *dp;

if (!dev || !dev->enabled)
if (!dev)
return;

const char *scope = acpi_device_scope(dev);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/generic/gpio_keys/gpio_keys.c
Expand Up @@ -57,7 +57,7 @@ static void gpio_keys_fill_ssdt_generator(const struct device *dev)
const char *drv_string = config->is_polled ? "gpio-keys-polled"
: "gpio-keys";

if (!dev->enabled || !scope || !path || !config->gpio.pin_count)
if (!scope || !path || !config->gpio.pin_count)
return;

/* Device */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/generic/max98357a/max98357a.c
Expand Up @@ -18,7 +18,7 @@ static void max98357a_fill_ssdt(const struct device *dev)
const char *path;
struct acpi_dp *dp;

if (!dev->enabled || !config)
if (!config)
return;

const char *scope = acpi_device_scope(dev);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/gfx/generic/generic.c
Expand Up @@ -106,7 +106,7 @@ static void gfx_fill_ssdt_generator(const struct device *dev)

const char *scope = acpi_device_scope(dev);

if (!scope || !dev->enabled)
if (!scope)
return;

acpigen_write_scope(scope);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/da7219/da7219.c
Expand Up @@ -27,7 +27,7 @@ static void da7219_fill_ssdt(const struct device *dev)
};
struct acpi_dp *dsd, *aad;

if (!dev->enabled || !scope)
if (!scope)
return;

/* Device */
Expand Down
16 changes: 11 additions & 5 deletions src/drivers/i2c/designware/dw_i2c.c
Expand Up @@ -419,6 +419,15 @@ static int _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
/* Read to clear INTR_STAT_STOP_DET */
read32(&regs->clear_stop_det_intr);

/* Check TX abort */
if (read32(&regs->raw_intr_stat) & INTR_STAT_TX_ABORT) {
printk(BIOS_ERR, "I2C TX abort detected (%08x)\n",
read32(&regs->tx_abort_source));
/* clear INTR_STAT_TX_ABORT */
read32(&regs->clear_tx_abrt_intr);
goto out;
}

/* Wait for the bus to go idle */
if (dw_i2c_wait_for_bus_idle(regs)) {
printk(BIOS_ERR, "I2C timeout waiting for bus %u idle\n", bus);
Expand Down Expand Up @@ -747,8 +756,8 @@ int dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg)
write32(&regs->rx_thresh, 0);
write32(&regs->tx_thresh, 0);

/* Enable stop detection interrupt */
write32(&regs->intr_mask, INTR_STAT_STOP_DET);
/* Enable stop detection and TX abort interrupt */
write32(&regs->intr_mask, INTR_STAT_STOP_DET | INTR_STAT_TX_ABORT);

printk(BIOS_INFO, "DW I2C bus %u at %p (%u KHz)\n",
bus, regs, speed / KHz);
Expand Down Expand Up @@ -824,9 +833,6 @@ void dw_i2c_acpi_fill_ssdt(const struct device *dev)
const char *path;
unsigned int speed;

if (!dev->enabled)
return;

bus = dw_i2c_soc_dev_to_bus(dev);

if (bus < 0)
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/designware/dw_i2c.h
Expand Up @@ -17,7 +17,7 @@

/*
* Timing values are in units of clock period, with the clock speed
* provided by the SOC in CONFIG_DRIVERS_I2C_DESIGNWARE_I2C_CLOCK_MHZ
* provided by the SOC in CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ
* Automatic configuration is done based on requested speed, but the
* values may need tuned depending on the board and the number of
* devices present on the bus.
Expand Down
5 changes: 3 additions & 2 deletions src/drivers/i2c/generic/generic.c
Expand Up @@ -57,7 +57,7 @@ void i2c_generic_fill_ssdt(const struct device *dev,
int reset_gpio_index = -1, enable_gpio_index = -1, irq_gpio_index = -1;
const char *path = acpi_device_path(dev);

if (!dev->enabled || !scope)
if (!scope)
return;

if (!config->hid) {
Expand All @@ -72,7 +72,8 @@ void i2c_generic_fill_ssdt(const struct device *dev,
if (config->cid)
acpigen_write_name_string("_CID", config->cid);
acpigen_write_name_integer("_UID", config->uid);
acpigen_write_name_string("_DDN", config->desc);
if (config->desc)
acpigen_write_name_string("_DDN", config->desc);
acpigen_write_STA(acpi_device_status(dev));

/* Resources */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/gpiomux/bus/bus.c
Expand Up @@ -22,7 +22,7 @@ static void i2c_gpiomux_bus_fill_ssdt(const struct device *dev)
const char *scope = acpi_device_scope(dev);
const char *path = acpi_device_path(dev);

if (!dev || !dev->enabled || !scope || !path)
if (!dev || !scope || !path)
return;

/* Device */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/gpiomux/mux/mux.c
Expand Up @@ -27,7 +27,7 @@ static void i2c_gpiomux_mux_fill_ssdt(const struct device *dev)
struct acpi_gpio_res_params param[MAX_NUM_MUX_GPIOS];
int i;

if (!dev->enabled || !scope || !path)
if (!scope || !path)
return;

/* Device */
Expand Down
4 changes: 4 additions & 0 deletions src/drivers/i2c/hid/hid.c
Expand Up @@ -28,6 +28,10 @@ static void i2c_hid_fill_ssdt_generator(const struct device *dev)
static const char *i2c_hid_acpi_name(const struct device *dev)
{
static char name[5];
struct drivers_i2c_hid_config *config = dev->chip_info;
if (config->generic.name)
return config->generic.name;

snprintf(name, sizeof(name), "H%03.3X", dev->path.i2c.device);
name[4] = '\0';
return name;
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/max98373/max98373.c
Expand Up @@ -24,7 +24,7 @@ static void max98373_fill_ssdt(const struct device *dev)
};
struct acpi_dp *dp;

if (!dev->enabled || !scope) {
if (!scope) {
printk(BIOS_ERR, "%s: dev not enabled\n", __func__);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/max98390/max98390.c
Expand Up @@ -28,7 +28,7 @@ static void max98390_fill_ssdt(const struct device *dev)
struct acpi_dp *dp;
uint64_t r0_value, temp_value;

if (!dev->enabled || !scope)
if (!scope)
return;

/* Device */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/max98927/max98927.c
Expand Up @@ -24,7 +24,7 @@ static void max98927_fill_ssdt(const struct device *dev)
};
struct acpi_dp *dp;

if (!dev->enabled || !scope)
if (!scope)
return;

/* Device */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/nau8825/nau8825.c
Expand Up @@ -30,7 +30,7 @@ static void nau8825_fill_ssdt(const struct device *dev)
};
struct acpi_dp *dp = NULL;

if (!dev->enabled || !scope)
if (!scope)
return;
if (config->sar_threshold_num > NAU8825_MAX_BUTTONS)
return;
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/rt1011/rt1011.c
Expand Up @@ -28,7 +28,7 @@ static void rt1011_fill_ssdt(const struct device *dev)
struct acpi_dp *dp;
uint64_t r0_value, temp_value;

if (!dev->enabled || !scope)
if (!scope)
return;

/* Device */
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/rt5663/rt5663.c
Expand Up @@ -27,7 +27,7 @@ static void rt5663_fill_ssdt(const struct device *dev)
};
struct acpi_dp *dp;

if (!dev->enabled || !scope)
if (!scope)
return;

/* Device */
Expand Down
1 change: 1 addition & 0 deletions src/drivers/i2c/rx6110sa/chip.h
Expand Up @@ -3,6 +3,7 @@
#include "rx6110sa.h"

struct drivers_i2c_rx6110sa_config {
unsigned int bus_speed; /* Bus clock in Hz (default 400 kHz)*/
/* The day (of the week) is indicated by 7 bits, bit 0 to bit 6. */
unsigned char user_weekday; /* User day of the week to set */
unsigned char user_day; /* User day to set */
Expand Down
66 changes: 64 additions & 2 deletions src/drivers/i2c/rx6110sa/rx6110sa.c
@@ -1,7 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/i2c_bus.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <device/device.h>
#include <device/i2c.h>
#include <device/i2c_bus.h>
#include <version.h>
#include <console/console.h>
#include <bcd.h>
Expand Down Expand Up @@ -163,11 +166,70 @@ static void rx6110sa_init(struct device *dev)
rx6110sa_write(dev, CTRL_REG, reg);
}

#if CONFIG(HAVE_ACPI_TABLES)
static void rx6110sa_fill_ssdt(const struct device *dev)
{
struct drivers_i2c_rx6110sa_config *config = dev->chip_info;
const char *scope = acpi_device_scope(dev);
enum i2c_speed bus_speed;

if (!scope)
return;

switch (config->bus_speed) {
case I2C_SPEED_STANDARD:
case I2C_SPEED_FAST:
bus_speed = config->bus_speed;
break;
default:
printk(BIOS_INFO, "%s: Bus speed unsupported, fall back to %d kHz!\n",
dev_path(dev), I2C_SPEED_STANDARD / 1000);
bus_speed = I2C_SPEED_STANDARD;
break;
}

struct acpi_i2c i2c = {
.address = dev->path.i2c.device,
.mode_10bit = dev->path.i2c.mode_10bit,
.speed = bus_speed,
.resource = scope,
};

/* Device */
acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));
acpigen_write_name_string("_DDN", RX6110SA_HID_DESC);
acpigen_write_STA(acpi_device_status(dev));

/* Resources */
acpigen_write_name("_CRS");
acpigen_write_resourcetemplate_header();
acpi_device_write_i2c(&i2c);

acpigen_write_resourcetemplate_footer();

acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */

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

static const char *rx6110sa_acpi_name(const struct device *dev)
{
return RX6110SA_ACPI_NAME;
}
#endif

static struct device_operations rx6110sa_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.init = rx6110sa_init,
.final = rx6110sa_final
.final = rx6110sa_final,
#if CONFIG(HAVE_ACPI_TABLES)
.acpi_name = rx6110sa_acpi_name,
.acpi_fill_ssdt = rx6110sa_fill_ssdt,
#endif
};

static void rx6110sa_enable(struct device *dev)
Expand Down
5 changes: 2 additions & 3 deletions src/drivers/i2c/rx6110sa/rx6110sa.h
Expand Up @@ -3,9 +3,8 @@
#ifndef _I2C_RX6110SA_H_
#define _I2C_RX6110SA_H_

/* The address of this RTC is fixed. */
#define RX6110SA_SLAVE_ADR 0x32
#define RX6110SA_I2C_CONTROLLER 0
#define RX6110SA_ACPI_NAME "ERX6"
#define RX6110SA_HID_DESC "Real Time Clock"

/* Register layout */
#define SECOND_REG 0x10
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/i2c/sx9310/sx9310.c
Expand Up @@ -28,7 +28,7 @@ static void i2c_sx9310_fill_ssdt(const struct device *dev)
};
struct acpi_dp *dsd;

if (!dev->enabled || !scope || !config)
if (!scope || !config)
return;

if (config->speed)
Expand Down
6 changes: 6 additions & 0 deletions src/drivers/i2c/sx9324/Kconfig
@@ -0,0 +1,6 @@
config DRIVERS_I2C_SX9324
bool
default n
depends on HAVE_ACPI_TABLES
help
Board has a Semtech SX9324 proximity sensor.
1 change: 1 addition & 0 deletions src/drivers/i2c/sx9324/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_I2C_SX9324) += sx9324.c
31 changes: 31 additions & 0 deletions src/drivers/i2c/sx9324/chip.h
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __DRIVERS_I2C_SX9324_CHIP_H__
#define __DRIVERS_I2C_SX9324_CHIP_H__

#include <acpi/acpi_device.h>
#include <device/i2c_simple.h>

#define REGISTER(NAME) uint8_t NAME

struct drivers_i2c_sx9324_config {
/* Device Description */
const char *desc;

/* ACPI _UID */
unsigned int uid;

/* Bus speed in Hz, default is I2C_SPEED_FAST */
enum i2c_speed speed;

/* Use GPIO-based interrupt instead of IO-APIC */
struct acpi_gpio irq_gpio;

/* IO-APIC interrupt */
struct acpi_irq irq;
#include "registers.h"
};

#undef REGISTER

#endif /* __DRIVERS_I2C_SX9324_CHIP_H__ */
50 changes: 50 additions & 0 deletions src/drivers/i2c/sx9324/registers.h
@@ -0,0 +1,50 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef REGISTER
#error "define REGISTER(NAME) before including this file"
#endif

REGISTER(reg_gnrl_ctrl0);
REGISTER(reg_gnrl_ctrl1);

REGISTER(reg_afe_ctrl0);
REGISTER(reg_afe_ctrl1);
REGISTER(reg_afe_ctrl2);
REGISTER(reg_afe_ctrl3);
REGISTER(reg_afe_ctrl4);
REGISTER(reg_afe_ctrl5);
REGISTER(reg_afe_ctrl6);
REGISTER(reg_afe_ctrl7);
REGISTER(reg_afe_ctrl8);
REGISTER(reg_afe_ctrl9);

REGISTER(reg_prox_ctrl0);
REGISTER(reg_prox_ctrl1);
REGISTER(reg_prox_ctrl2);
REGISTER(reg_prox_ctrl3);
REGISTER(reg_prox_ctrl4);
REGISTER(reg_prox_ctrl5);
REGISTER(reg_prox_ctrl6);
REGISTER(reg_prox_ctrl7);

REGISTER(reg_adv_ctrl0);
REGISTER(reg_adv_ctrl1);
REGISTER(reg_adv_ctrl2);
REGISTER(reg_adv_ctrl3);
REGISTER(reg_adv_ctrl4);
REGISTER(reg_adv_ctrl5);
REGISTER(reg_adv_ctrl6);
REGISTER(reg_adv_ctrl7);
REGISTER(reg_adv_ctrl8);
REGISTER(reg_adv_ctrl9);
REGISTER(reg_adv_ctrl10);
REGISTER(reg_adv_ctrl11);
REGISTER(reg_adv_ctrl12);
REGISTER(reg_adv_ctrl13);
REGISTER(reg_adv_ctrl14);
REGISTER(reg_adv_ctrl15);
REGISTER(reg_adv_ctrl16);
REGISTER(reg_adv_ctrl17);
REGISTER(reg_adv_ctrl18);
REGISTER(reg_adv_ctrl19);
REGISTER(reg_adv_ctrl20);
104 changes: 104 additions & 0 deletions src/drivers/i2c/sx9324/sx9324.c
@@ -0,0 +1,104 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
#include <device/i2c_simple.h>
#include <device/device.h>
#include <device/path.h>
#include <string.h>
#include "chip.h"

#define I2C_SX9324_ACPI_ID "STH9324"
#define I2C_SX9324_CHIP_NAME "Semtech SX9324"

#define REGISTER(NAME) acpi_dp_add_integer(dsd, \
I2C_SX9324_ACPI_ID "," #NAME, \
config->NAME)

static void i2c_sx9324_fill_ssdt(const struct device *dev)
{
struct drivers_i2c_sx9324_config *config = dev->chip_info;
const char *scope = acpi_device_scope(dev);
struct acpi_i2c i2c = {
.address = dev->path.i2c.device,
.mode_10bit = dev->path.i2c.mode_10bit,
.speed = I2C_SPEED_FAST,
.resource = scope,
};
struct acpi_dp *dsd;

if (!scope || !config)
return;

if (config->speed)
i2c.speed = config->speed;

/* Device */
acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));
acpigen_write_name_string("_HID", I2C_SX9324_ACPI_ID);
acpigen_write_name_integer("_UID", config->uid);
acpigen_write_name_string("_DDN", config->desc);
acpigen_write_STA(acpi_device_status(dev));

/* Resources */
acpigen_write_name("_CRS");
acpigen_write_resourcetemplate_header();
acpi_device_write_i2c(&i2c);

if (config->irq_gpio.pin_count)
acpi_device_write_gpio(&config->irq_gpio);
else
acpi_device_write_interrupt(&config->irq);

acpigen_write_resourcetemplate_footer();

/* DSD */
dsd = acpi_dp_new_table("_DSD");
#include "registers.h"
acpi_dp_write(dsd);

acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */

printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev),
config->desc ? : dev->chip_ops->name, dev_path(dev));
}

#undef REGISTER

static const char *i2c_sx9324_acpi_name(const struct device *dev)
{
static char name[5];

snprintf(name, sizeof(name), "SX%02.2X", dev->path.i2c.device);
return name;
}

static struct device_operations i2c_sx9324_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.acpi_name = i2c_sx9324_acpi_name,
.acpi_fill_ssdt = i2c_sx9324_fill_ssdt,
};

static void i2c_sx9324_enable(struct device *dev)
{
struct drivers_i2c_sx9324_config *config = dev->chip_info;

if (!config) {
dev->enabled = 0;
return;
}

dev->ops = &i2c_sx9324_ops;

if (config->desc)
dev->name = config->desc;
}

struct chip_operations drivers_i2c_sx9324_ops = {
CHIP_NAME(I2C_SX9324_CHIP_NAME)
.enable_dev = i2c_sx9324_enable
};
2 changes: 1 addition & 1 deletion src/drivers/i2c/tpm/chip.c
Expand Up @@ -20,7 +20,7 @@ static void i2c_tpm_fill_ssdt(const struct device *dev)
.resource = scope,
};

if (!dev->enabled || !scope)
if (!scope)
return;

if (!config->hid) {
Expand Down
5 changes: 0 additions & 5 deletions src/drivers/i2c/tpm/tpm.c
Expand Up @@ -424,11 +424,6 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
if (burstcnt > (len-1-count))
burstcnt = len-1-count;

#ifdef CONFIG_TPM_I2C_BURST_LIMITATION
if (burstcnt > CONFIG_TPM_I2C_BURST_LIMITATION)
burstcnt = CONFIG_TPM_I2C_BURST_LIMITATION;
#endif /* CONFIG_TPM_I2C_BURST_LIMITATION */

if (iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
&(buf[count]), burstcnt) == 0)
count += burstcnt;
Expand Down
3 changes: 2 additions & 1 deletion src/drivers/intel/fsp1_1/Makefile.inc
Expand Up @@ -4,11 +4,12 @@ ifeq ($(CONFIG_PLATFORM_USES_FSP1_1),y)

verstage-y += car.c
verstage-y += fsp_util.c
verstage-$(CONFIG_SEPARATE_VERSTAGE) += verstage.c
verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += verstage.c

bootblock-$(CONFIG_USE_GENERIC_FSP_CAR_INC) += cache_as_ram.S
bootblock-y += fsp_util.c
bootblock-y += ../../../cpu/intel/microcode/microcode_asm.S
bootblock-y += fsp_report.c

romstage-y += car.c
romstage-y += fsp_util.c
Expand Down
26 changes: 19 additions & 7 deletions src/drivers/intel/fsp1_1/cache_as_ram.S
Expand Up @@ -133,7 +133,7 @@ CAR_init_done:
jne halt2

/* Setup bootloader stack */
movl %edx, %esp
movl $_ecar_stack, %esp

/*
* ebp: FSP_INFO_HEADER address
Expand All @@ -145,16 +145,28 @@ CAR_init_done:
* mm1: high 32-bits of TSC value
*/

/* coreboot assumes stack/heap region will be zero */
/*
* temp_memory_start/end reside in the .bss section, which gets cleared
* below. Save the FSP return value to the stack before writing those
* variables.
*/
push %ecx
push %edx

/* clear .bss section */
cld
movl %ecx, %edi
neg %ecx
/* Clear up to Temp Ram top. */
add %edx, %ecx
xor %eax, %eax
movl $(_ebss), %ecx
movl $(_bss), %edi
sub %edi, %ecx
shrl $2, %ecx
xorl %eax, %eax
rep stosl

pop %edx
movl %edx, temp_memory_end
pop %ecx
movl %ecx, temp_memory_start

/* Need to align stack to 16 bytes at call instruction. Account for
the pushes below. */
andl $0xfffffff0, %esp
Expand Down
27 changes: 27 additions & 0 deletions src/drivers/intel/fsp1_1/fsp_report.c
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/symbols.h>
#include <console/console.h>
#include <fsp/util.h>

/* filled in assembly after FSP-T ran */
uintptr_t temp_memory_start;
uintptr_t temp_memory_end;

void report_fsp_output(void)
{
const struct region fsp_car_region = {
.offset = temp_memory_start,
.size = temp_memory_end - temp_memory_start,
};
const struct region coreboot_car_region = {
.offset = (uintptr_t)_car_region_start,
.size = (uintptr_t)_car_region_size,
};
printk(BIOS_DEBUG, "FSP: reported temp_mem region: [0x%08lx,0x%08lx)\n",
temp_memory_start, temp_memory_end);
if (!region_is_subregion(&fsp_car_region, &coreboot_car_region)) {
printk(BIOS_ERR, "Wrong CAR region used!\n");
printk(BIOS_ERR, "Adapt DCACHE_RAM_BASE and DCACHE_RAM_SIZE to match FSP-T\n");
}
}
1 change: 1 addition & 0 deletions src/drivers/intel/fsp1_1/include/fsp/util.h
Expand Up @@ -31,6 +31,7 @@ void *get_next_resource_hob(const EFI_GUID *guid, const void *hob_start);
void *get_first_resource_hob(const EFI_GUID *guid);
void fsp_display_upd_value(const char *name, uint32_t size, uint64_t old,
uint64_t new);
void report_fsp_output(void);

/* Return version of FSP associated with fih. */
static inline uint32_t fsp_version(FSP_INFO_HEADER *fih)
Expand Down
48 changes: 21 additions & 27 deletions src/drivers/intel/fsp1_1/romstage.c
Expand Up @@ -41,35 +41,29 @@ static void raminit_common(struct romstage_params *params)
params->saved_data_size = 0;
params->saved_data = NULL;
if (!params->disable_saved_data) {
if (vboot_recovery_mode_enabled()) {
/* Recovery mode does not use MRC cache */
/* Assume boot device is memory mapped. */
assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));

params->saved_data = NULL;
if (CONFIG(CACHE_MRC_SETTINGS))
params->saved_data =
mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
params->fsp_version,
&mrc_size);
if (params->saved_data) {
/* MRC cache found */
params->saved_data_size = mrc_size;

} else if (s3wake) {
/* Waking from S3 and no cache. */
printk(BIOS_DEBUG,
"Recovery mode: not using MRC cache.\n");
"No MRC cache "
"found in S3 resume path.\n");
post_code(POST_RESUME_FAILURE);
/* FIXME: A "system" reset is likely enough: */
full_reset();
} else {
/* Assume boot device is memory mapped. */
assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));

params->saved_data = NULL;
if (CONFIG(CACHE_MRC_SETTINGS))
params->saved_data =
mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
params->fsp_version,
&mrc_size);
if (params->saved_data) {
/* MRC cache found */
params->saved_data_size = mrc_size;

} else if (s3wake) {
/* Waking from S3 and no cache. */
printk(BIOS_DEBUG,
"No MRC cache "
"found in S3 resume path.\n");
post_code(POST_RESUME_FAILURE);
/* FIXME: A "system" reset is likely enough: */
full_reset();
} else {
printk(BIOS_DEBUG, "No MRC cache found.\n");
}
printk(BIOS_DEBUG, "No MRC cache found.\n");
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/drivers/intel/fsp2_0/Kconfig
Expand Up @@ -228,6 +228,7 @@ config FSP_STATUS_GLOBAL_RESET_REQUIRED_8

config FSP_STATUS_GLOBAL_RESET
hex
depends on SOC_INTEL_COMMON_FSP_RESET
default 0x40000003 if FSP_STATUS_GLOBAL_RESET_REQUIRED_3
default 0x40000004 if FSP_STATUS_GLOBAL_RESET_REQUIRED_4
default 0x40000005 if FSP_STATUS_GLOBAL_RESET_REQUIRED_5
Expand All @@ -240,6 +241,13 @@ config FSP_STATUS_GLOBAL_RESET
reset type from SoC Kconfig based on available Kconfig options
FSP_STATUS_GLOBAL_RESET_REQUIRED_X. Default is unsupported.

config SOC_INTEL_COMMON_FSP_RESET
bool
help
Common code block to handle platform reset request raised by FSP. The FSP
will use the FSP EAS v2.0 section 12.2.2 (OEM Status Code) to indicate that
a reset is required.

if FSP_PEIM_TO_PEIM_INTERFACE
source "src/drivers/intel/fsp2_0/ppi/Kconfig"
endif
Expand Down
2 changes: 2 additions & 0 deletions src/drivers/intel/fsp2_0/Makefile.inc
Expand Up @@ -2,6 +2,8 @@

ifeq ($(CONFIG_PLATFORM_USES_FSP2_0),y)

bootblock-$(CONFIG_FSP_CAR) += fspt_report.c

romstage-y += debug.c
romstage-y += hand_off_block.c
romstage-$(CONFIG_DISPLAY_FSP_HEADER) += header_display.c
Expand Down
27 changes: 27 additions & 0 deletions src/drivers/intel/fsp2_0/fspt_report.c
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/symbols.h>
#include <console/console.h>
#include <fsp/util.h>

/* filled in assembly after FSP-T ran */
uintptr_t temp_memory_start;
uintptr_t temp_memory_end;

void report_fspt_output(void)
{
const struct region fsp_car_region = {
.offset = temp_memory_start,
.size = temp_memory_end - temp_memory_start,
};
const struct region coreboot_car_region = {
.offset = (uintptr_t)_car_region_start,
.size = (uintptr_t)_car_region_size,
};
printk(BIOS_DEBUG, "FSP-T: reported temp_mem region: [0x%08lx,0x%08lx)\n",
temp_memory_start, temp_memory_end);
if (!region_is_subregion(&fsp_car_region, &coreboot_car_region)) {
printk(BIOS_ERR, "Wrong CAR region used!\n");
printk(BIOS_ERR, "Adapt CONFIG_DCACHE_RAM_BASE and CONFIG_DCACHE_RAM_SIZE to match FSP-T\n");
}
}
10 changes: 1 addition & 9 deletions src/drivers/intel/fsp2_0/header_display.c
Expand Up @@ -5,15 +5,7 @@

void fsp_print_header_info(const struct fsp_header *hdr)
{
union {
uint32_t val;
struct {
uint8_t bld_num;
uint8_t revision;
uint8_t minor;
uint8_t major;
} rev;
} revision;
union fsp_revision revision;

revision.val = hdr->fsp_revision;

Expand Down
12 changes: 12 additions & 0 deletions src/drivers/intel/fsp2_0/include/fsp/util.h
Expand Up @@ -42,6 +42,16 @@ struct hob_resource {
uint64_t length;
} __packed;

union fsp_revision {
uint32_t val;
struct {
uint8_t bld_num;
uint8_t revision;
uint8_t minor;
uint8_t major;
} rev;
};

#if CONFIG_UDK_VERSION < CONFIG_UDK_2017_VERSION
enum resource_type {
EFI_RESOURCE_SYSTEM_MEMORY = 0,
Expand Down Expand Up @@ -89,6 +99,8 @@ bool fsp_guid_compare(const uint8_t guid1[16], const uint8_t guid2[16]);
void fsp_find_bootloader_tolum(struct range_entry *re);
void fsp_get_version(char *buf);
void lb_string_platform_blob_version(struct lb_header *header);
void report_fspt_output(void);
void soc_validate_fsp_version(const struct fsp_header *hdr);

/* Fill in header and validate sanity of component within region device. */
enum cb_err fsp_validate_component(struct fsp_header *hdr,
Expand Down
12 changes: 0 additions & 12 deletions src/drivers/intel/fsp2_0/memory_init.c
Expand Up @@ -92,18 +92,6 @@ static void fsp_fill_mrc_cache(FSPM_ARCH_UPD *arch_upd, uint32_t fsp_version)
if (!CONFIG(CACHE_MRC_SETTINGS))
return;

/*
* In recovery mode, force retraining:
* 1. Recovery cache is not supported, or
* 2. Memory retrain switch is set.
*/
if (vboot_recovery_mode_enabled()) {
if (!CONFIG(HAS_RECOVERY_MRC_CACHE))
return;
if (get_recovery_mode_retrain_switch())
return;
}

/* Assume boot device is memory mapped. */
assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));

Expand Down
18 changes: 9 additions & 9 deletions src/drivers/intel/fsp2_0/util.c
Expand Up @@ -85,6 +85,9 @@ enum cb_err fsp_validate_component(struct fsp_header *hdr,
return CB_ERR;
}

if (ENV_ROMSTAGE)
soc_validate_fsp_version(hdr);

return CB_SUCCESS;
}

Expand Down Expand Up @@ -213,15 +216,7 @@ enum cb_err fsp_load_component(struct fsp_load_descriptor *fspld, struct fsp_hea
void fsp_get_version(char *buf)
{
struct fsp_header *hdr = &fsps_hdr;
union {
uint32_t val;
struct {
uint8_t bld_num;
uint8_t revision;
uint8_t minor;
uint8_t major;
} rev;
} revision;
union fsp_revision revision;

revision.val = hdr->fsp_revision;
snprintf(buf, FSP_VER_LEN, "%u.%u-%u.%u.%u.%u", (hdr->spec_version >> 4),
Expand All @@ -243,3 +238,8 @@ void lb_string_platform_blob_version(struct lb_header *header)
rec->size = ALIGN_UP(sizeof(*rec) + len + 1, 8);
memcpy(rec->string, fsp_version, len+1);
}

__weak void soc_validate_fsp_version(const struct fsp_header *hdr)
{
printk(BIOS_DEBUG, "%s not implemented.\n", __func__);
}
4 changes: 4 additions & 0 deletions src/drivers/intel/gma/Kconfig
Expand Up @@ -59,6 +59,10 @@ config INTEL_GMA_SWSMISCI
config INTEL_GMA_LIBGFXINIT_EDID
bool

config VBT_DATA_SIZE_KB
int
default 8

config GFX_GMA_ANALOG_I2C_HDMI_B
bool

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/gma/opregion.c
Expand Up @@ -19,7 +19,7 @@ const char *mainboard_vbt_filename(void)
return "vbt.bin";
}

static char vbt_data[9 * KiB];
static char vbt_data[CONFIG_VBT_DATA_SIZE_KB * KiB];
static size_t vbt_data_sz;

void *locate_vbt(size_t *vbt_size)
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/ish/ish.c
Expand Up @@ -13,7 +13,7 @@ static void ish_fill_ssdt_generator(const struct device *dev)
struct device *root = dev->bus->dev;
struct acpi_dp *dsd;

if (!dev->enabled || !config || !config->firmware_name)
if (!config || !config->firmware_name)
return;

acpigen_write_scope(acpi_device_path(root));
Expand Down
3 changes: 0 additions & 3 deletions src/drivers/intel/mipi_camera/camera.c
Expand Up @@ -909,9 +909,6 @@ static void camera_fill_ssdt(const struct device *dev)
const char *scope = NULL;
const struct device *pdev;

if (!dev->enabled)
return;

if (config->has_power_resource) {
pdev = dev->bus->dev;
if (!pdev || !pdev->enabled)
Expand Down
3 changes: 0 additions & 3 deletions src/drivers/intel/pmc_mux/conn/conn.c
Expand Up @@ -32,9 +32,6 @@ static void conn_fill_ssdt(const struct device *dev)
const char *scope;
const char *name;

if (!dev->enabled)
return;

/* Reference the existing scope and write CONx device */
scope = acpi_device_scope(dev);
name = acpi_device_name(dev);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/soundwire/soundwire.c
Expand Up @@ -50,7 +50,7 @@ static void intel_soundwire_fill_ssdt(const struct device *dev)
struct intel_soundwire_controller *controller;
const char *scope = acpi_device_scope(dev);

if (!dev->enabled || !scope)
if (!scope)
return;

if (soc_fill_soundwire_controller(&controller) < 0 || !controller)
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/usb4/retimer/retimer.c
Expand Up @@ -101,7 +101,7 @@ static void usb4_retimer_fill_ssdt(const struct device *dev)
const struct drivers_intel_usb4_retimer_config *config = dev->chip_info;
const char *scope = acpi_device_scope(dev);

if (!dev->enabled || !scope || !config)
if (!scope || !config)
return;

if (!config->power_gpio.pin_count) {
Expand Down
5 changes: 0 additions & 5 deletions src/drivers/mrc_cache/Kconfig
Expand Up @@ -17,11 +17,6 @@ config HAS_RECOVERY_MRC_CACHE
bool
default n

config MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN
bool
depends on VBOOT_STARTS_IN_BOOTBLOCK
default n

config MRC_SETTINGS_VARIABLE_DATA
bool
default n
Expand Down
74 changes: 60 additions & 14 deletions src/drivers/mrc_cache/mrc_cache.c
Expand Up @@ -69,7 +69,20 @@ static const struct cache_region normal_training = {
.type = MRC_TRAINING_DATA,
.elog_slot = ELOG_MEM_CACHE_UPDATE_SLOT_NORMAL,
.tpm_hash_index = MRC_RW_HASH_NV_INDEX,
#if CONFIG(VBOOT_STARTS_IN_ROMSTAGE)
/*
* If VBOOT_STARTS_IN_ROMSTAGE is selected, this means that
* memory training happens before vboot (in RO) and the
* mrc_cache data is always safe to use.
*/
.flags = NORMAL_FLAG | RECOVERY_FLAG,
#else
/*
* If !VBOOT_STARTS_IN_ROMSTAGE, this means that memory training happens after
* vboot (in RW code) and is never safe to use in recovery.
*/
.flags = NORMAL_FLAG,
#endif
};

static const struct cache_region variable_data = {
Expand All @@ -78,7 +91,20 @@ static const struct cache_region variable_data = {
.type = MRC_VARIABLE_DATA,
.elog_slot = ELOG_MEM_CACHE_UPDATE_SLOT_VARIABLE,
.tpm_hash_index = 0,
#if CONFIG(VBOOT_STARTS_IN_ROMSTAGE)
/*
* If VBOOT_STARTS_IN_ROMSTAGE is selected, this means that
* memory training happens before vboot (in RO) and the
* mrc_cache data is always safe to use.
*/
.flags = NORMAL_FLAG | RECOVERY_FLAG,
#else
/*
* If !VBOOT_STARTS_IN_ROMSTAGE, this means that memory training happens after
* vboot (in RW code) and is never safe to use in recovery.
*/
.flags = NORMAL_FLAG,
#endif
};

/* Order matters here for priority in matching. */
Expand Down Expand Up @@ -255,6 +281,13 @@ static int mrc_cache_find_current(int type, uint32_t version,
const size_t md_size = sizeof(*md);
const bool fail_bad_data = true;

/*
* In recovery mode, force retraining if the memory retrain
* switch is set.
*/
if (vboot_recovery_mode_enabled() && get_recovery_mode_retrain_switch())
return -1;

cr = lookup_region(&region, type);

if (cr == NULL)
Expand Down Expand Up @@ -337,10 +370,10 @@ static bool mrc_cache_needs_update(const struct region_device *rdev,
const void *new_data, size_t new_data_size)
{
void *mapping, *data_mapping;
size_t size = region_device_sz(rdev);
size_t old_data_size = region_device_sz(rdev) - sizeof(struct mrc_metadata);
bool need_update = false;

if (new_data_size != size)
if (new_data_size != old_data_size)
return true;

mapping = rdev_mmap_full(rdev);
Expand Down Expand Up @@ -566,10 +599,24 @@ static void invalidate_normal_cache(void)
const char *name = DEFAULT_MRC_CACHE;
const uint32_t invalid = ~MRC_DATA_SIGNATURE;

/* Invalidate only on recovery mode with retraining enabled. */
/*
* If !HAS_RECOVERY_MRC_CACHE and VBOOT_STARTS_IN_ROMSTAGE is
* selected, this means that memory training occurs before
* verified boot (in RO), so normal mode cache does not need
* to be invalidated.
*/
if (!CONFIG(HAS_RECOVERY_MRC_CACHE) && CONFIG(VBOOT_STARTS_IN_ROMSTAGE))
return;

/* We only invalidate the normal cache in recovery mode. */
if (!vboot_recovery_mode_enabled())
return;
if (!get_recovery_mode_retrain_switch())

/*
* For platforms with a recovery mrc_cache, no need to
* invalidate when retrain switch is not set.
*/
if (CONFIG(HAS_RECOVERY_MRC_CACHE) && !get_recovery_mode_retrain_switch())
return;

if (fmap_locate_area_as_rdev_rw(name, &rdev) < 0) {
Expand Down Expand Up @@ -599,7 +646,7 @@ static void update_mrc_cache_from_cbmem(int type)
cr = lookup_region(&region, type);

if (cr == NULL) {
printk(BIOS_ERR, "MRC: could not find cache_region type %d\n", type);
printk(BIOS_INFO, "MRC: could not find cache_region type %d\n", type);
return;
}

Expand Down Expand Up @@ -631,8 +678,7 @@ static void finalize_mrc_cache(void *unused)
update_mrc_cache_from_cbmem(MRC_VARIABLE_DATA);
}

if (CONFIG(MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN))
invalidate_normal_cache();
invalidate_normal_cache();

protect_mrc_region();
}
Expand All @@ -642,13 +688,6 @@ int mrc_cache_stash_data(int type, uint32_t version, const void *data,
{
const struct cache_region *cr;

cr = lookup_region_type(type);
if (cr == NULL) {
printk(BIOS_ERR, "MRC: failed to add to cbmem for type %d.\n",
type);
return -1;
}

struct mrc_metadata md = {
.signature = MRC_DATA_SIGNATURE,
.data_size = size,
Expand All @@ -664,6 +703,13 @@ int mrc_cache_stash_data(int type, uint32_t version, const void *data,
size_t cbmem_size;
cbmem_size = sizeof(*cbmem_md) + size;

cr = lookup_region_type(type);
if (cr == NULL) {
printk(BIOS_INFO, "MRC: No region type found. Skip adding to cbmem for type %d.\n",
type);
return 0;
}

cbmem_md = cbmem_add(cr->cbmem_id, cbmem_size);

if (cbmem_md == NULL) {
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/ocp/dmi/smbios.c
Expand Up @@ -9,7 +9,7 @@
#include <stdio.h>
#include <string.h>
#include <soc/soc_util.h>
#include <soc/cpu.h>
#include <soc/util.h>
#include <smbios.h>

#include "ocp_dmi.h"
Expand Down
128 changes: 6 additions & 122 deletions src/drivers/pc80/tpm/tis.c
Expand Up @@ -21,13 +21,11 @@
#include <console/console.h>
#include <security/tpm/tis.h>
#include <device/pnp.h>
#include <drivers/tpm/tpm_ppi.h>
#include "chip.h"

#define PREFIX "lpc_tpm: "
/* TCG Physical Presence Interface */
#define TPM_PPI_UUID "3dddfaa6-361b-4eb4-a424-8d10089d1653"
/* TCG Memory Clear Interface */
#define TPM_MCI_UUID "376054ed-cc13-4675-901c-4756d7f2d45d"

/* coreboot wrapper for TPM driver (start) */
#define TPM_DEBUG(fmt, args...) \
if (CONFIG(DEBUG_TPM)) { \
Expand Down Expand Up @@ -777,104 +775,9 @@ static void lpc_tpm_set_resources(struct device *dev)
}

#if CONFIG(HAVE_ACPI_TABLES)

static void tpm_ppi_func0_cb(void *arg)
{
/* Functions 1-8. */
u8 buf[] = {0xff, 0x01};
acpigen_write_return_byte_buffer(buf, 2);
}

static void tpm_ppi_func1_cb(void *arg)
{
if (CONFIG(TPM2))
/* Interface version: 2.0 */
acpigen_write_return_string("2.0");
else
/* Interface version: 1.2 */
acpigen_write_return_string("1.2");
}

static void tpm_ppi_func2_cb(void *arg)
{
/* Submit operations: drop on the floor and return success. */
acpigen_write_return_byte(0);
}

static void tpm_ppi_func3_cb(void *arg)
{
/* Pending operation: none. */
acpigen_emit_byte(RETURN_OP);
acpigen_write_package(2);
acpigen_write_byte(0);
acpigen_write_byte(0);
acpigen_pop_len();
}
static void tpm_ppi_func4_cb(void *arg)
{
/* Pre-OS transition method: reboot. */
acpigen_write_return_byte(2);
}
static void tpm_ppi_func5_cb(void *arg)
{
/* Operation response: no operation executed. */
acpigen_emit_byte(RETURN_OP);
acpigen_write_package(3);
acpigen_write_byte(0);
acpigen_write_byte(0);
acpigen_write_byte(0);
acpigen_pop_len();
}
static void tpm_ppi_func6_cb(void *arg)
{
/*
* Set preferred user language: deprecated and must return 3 aka
* "not implemented".
*/
acpigen_write_return_byte(3);
}
static void tpm_ppi_func7_cb(void *arg)
{
/* Submit operations: deny. */
acpigen_write_return_byte(3);
}
static void tpm_ppi_func8_cb(void *arg)
{
/* All actions are forbidden. */
acpigen_write_return_byte(1);
}
static void (*tpm_ppi_callbacks[])(void *) = {
tpm_ppi_func0_cb,
tpm_ppi_func1_cb,
tpm_ppi_func2_cb,
tpm_ppi_func3_cb,
tpm_ppi_func4_cb,
tpm_ppi_func5_cb,
tpm_ppi_func6_cb,
tpm_ppi_func7_cb,
tpm_ppi_func8_cb,
};

static void tpm_mci_func0_cb(void *arg)
{
/* Function 1. */
acpigen_write_return_singleton_buffer(0x3);
}
static void tpm_mci_func1_cb(void *arg)
{
/* Just return success. */
acpigen_write_return_byte(0);
}

static void (*tpm_mci_callbacks[])(void *) = {
tpm_mci_func0_cb,
tpm_mci_func1_cb,
};

static void lpc_tpm_fill_ssdt(const struct device *dev)
{
const char *path = acpi_device_path(dev->bus->dev);
u32 arg;

if (!path) {
path = "\\_SB_.PCI0.LPCB";
Expand Down Expand Up @@ -938,31 +841,12 @@ static void lpc_tpm_fill_ssdt(const struct device *dev)
acpi_device_write_interrupt(&tpm_irq);
}


acpigen_write_resourcetemplate_footer();

if (!CONFIG(CHROMEOS)) {
/*
* _DSM method
*/
struct dsm_uuid ids[] = {
/* Physical presence interface.
* This is used to submit commands like "Clear TPM" to
* be run at next reboot provided that user confirms
* them. Spec allows user to cancel all commands and/or
* configure BIOS to reject commands. So we pretend that
* user did just this: cancelled everything. If user
* really wants to clear TPM the only option now is to
* do it manually in payload.
*/
DSM_UUID(TPM_PPI_UUID, &tpm_ppi_callbacks[0],
ARRAY_SIZE(tpm_ppi_callbacks), (void *) &arg),
/* Memory clearing on boot: just a dummy. */
DSM_UUID(TPM_MCI_UUID, &tpm_mci_callbacks[0],
ARRAY_SIZE(tpm_mci_callbacks), (void *) &arg),
};

acpigen_write_dsm_uuid_arr(ids, ARRAY_SIZE(ids));
}
if (!CONFIG(CHROMEOS))
tpm_ppi_acpi_fill_ssdt(dev);

acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/soundwire/alc5682/alc5682.c
Expand Up @@ -128,7 +128,7 @@ static void soundwire_alc5682_fill_ssdt(const struct device *dev)
const char *scope = acpi_device_scope(dev);
struct acpi_dp *dsd;

if (!dev->enabled || !scope)
if (!scope)
return;

acpigen_write_scope(scope);
Expand Down
2 changes: 2 additions & 0 deletions src/drivers/soundwire/alc711/Kconfig
@@ -0,0 +1,2 @@
config DRIVERS_SOUNDWIRE_ALC711
bool
1 change: 1 addition & 0 deletions src/drivers/soundwire/alc711/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_SOUNDWIRE_ALC711) += alc711.c
156 changes: 156 additions & 0 deletions src/drivers/soundwire/alc711/alc711.c
@@ -0,0 +1,156 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpigen.h>
#include <acpi/acpi_device.h>
#include <acpi/acpi_soundwire.h>
#include <device/device.h>
#include <device/path.h>
#include <device/mipi_ids.h>
#include <device/soundwire.h>
#include <stdio.h>

#include "chip.h"

static struct soundwire_address alc711_address = {
.version = SOUNDWIRE_VERSION_1_1,
.manufacturer_id = MIPI_MFG_ID_REALTEK,
.part_id = MIPI_DEV_ID_REALTEK_ALC711,
.class = MIPI_CLASS_NONE
};

static struct soundwire_slave alc711_slave = {
.wake_up_unavailable = false,
.test_mode_supported = false,
.clock_stop_mode1_supported = true,
.simplified_clockstopprepare_sm_supported = true,
.clockstopprepare_hard_reset_behavior = false,
.highPHY_capable = false,
.paging_supported = false,
.bank_delay_supported = false,
.port15_read_behavior = false,
.source_port_list = SOUNDWIRE_PORT(2),
.sink_port_list = SOUNDWIRE_PORT(1),
};

static struct soundwire_audio_mode alc711_audio_mode = {
/* Bus frequency must be 1/2/4/8 divider of supported input frequencies. */
.bus_frequency_configs_count = 12,
.bus_frequency_configs = {
9600 * KHz,
4800 * KHz,
2400 * KHz,
1200 * KHz,
12000 * KHz,
6000 * KHz,
3000 * KHz,
1500 * KHz,
12288 * KHz,
6144 * KHz,
3072 * KHz,
1536 * KHz
},
/* Support 16 KHz to 192 KHz sampling frequency */
.sampling_frequency_configs_count = 9,
.sampling_frequency_configs = {
16 * KHz,
22.05 * KHz,
24 * KHz,
32 * KHz,
44.1 * KHz,
48 * KHz,
88.2 * KHz,
96 * KHz,
192 * KHz
},
.prepare_channel_behavior = CHANNEL_PREPARE_ANY_FREQUENCY
};

static struct soundwire_dpn alc711_dp = {
.port_wordlength_configs_count = 1,
.port_wordlength_configs = { 32 },
.data_port_type = FULL_DATA_PORT,
.max_grouping_supported = BLOCK_GROUP_COUNT_1,
.simplified_channelprepare_sm = false,
.imp_def_dpn_interrupts_supported = 0,
.min_channel_number = 1,
.max_channel_number = 2,
.modes_supported = MODE_ISOCHRONOUS | MODE_TX_CONTROLLED |
MODE_RX_CONTROLLED | MODE_FULL_ASYNCHRONOUS,
.block_packing_mode = true,
.port_audio_mode_count = 1,
.port_audio_mode_list = { 0 }
};

static const struct soundwire_codec alc711_codec = {
.slave = &alc711_slave,
.audio_mode = { &alc711_audio_mode },
.dpn = {
{
/* Data Input for Speaker Path */
.port = 1,
.sink = &alc711_dp
},
{
/* Data Output for DSP Path */
.port = 2,
.source = &alc711_dp
}
}

};

static void soundwire_alc711_fill_ssdt(const struct device *dev)
{
struct drivers_soundwire_alc711_config *config = dev->chip_info;
const char *scope = acpi_device_scope(dev);
struct acpi_dp *dsd;

if (!scope)
return;

acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));

/* Set codec address IDs. */
alc711_address.link_id = dev->path.generic.id;
alc711_address.unique_id = dev->path.generic.subid;

acpigen_write_ADR_soundwire_device(&alc711_address);
acpigen_write_name_string("_DDN", config->desc ? : dev->chip_ops->name);
acpigen_write_STA(acpi_device_status(dev));

dsd = acpi_dp_new_table("_DSD");
soundwire_gen_codec(dsd, &alc711_codec, NULL);
acpi_dp_write(dsd);

acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */
}

static const char *soundwire_alc711_acpi_name(const struct device *dev)
{
struct drivers_soundwire_alc711_config *config = dev->chip_info;
static char name[5];

if (config->name)
return config->name;
snprintf(name, sizeof(name), "SW%1X%1X", dev->path.generic.id, dev->path.generic.subid);
return name;
}

static struct device_operations soundwire_alc711_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.acpi_name = soundwire_alc711_acpi_name,
.acpi_fill_ssdt = soundwire_alc711_fill_ssdt,
};

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

struct chip_operations drivers_soundwire_alc711_ops = {
CHIP_NAME("Realtek ALC711 SoundWire Codec")
.enable_dev = soundwire_alc711_enable
};
11 changes: 11 additions & 0 deletions src/drivers/soundwire/alc711/chip.h
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __DRIVERS_SOUNDWIRE_ALC711_CHIP_H__
#define __DRIVERS_SOUNDWIRE_ALC711_CHIP_H__

struct drivers_soundwire_alc711_config {
const char *name;
const char *desc;
};

#endif /* __DRIVERS_SOUNDWIRE_ALC711_CHIP_H__ */
2 changes: 1 addition & 1 deletion src/drivers/soundwire/max98373/max98373.c
Expand Up @@ -114,7 +114,7 @@ static void soundwire_max98373_fill_ssdt(const struct device *dev)
const char *scope = acpi_device_scope(dev);
struct acpi_dp *dsd;

if (!dev->enabled || !scope)
if (!scope)
return;

acpigen_write_scope(scope);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/spi/acpi/acpi.c
Expand Up @@ -77,7 +77,7 @@ static void spi_acpi_fill_ssdt_generator(const struct device *dev)
int reset_gpio_index = -1;
int enable_gpio_index = -1;

if (!dev->enabled || !scope)
if (!scope)
return;

if (spi_acpi_get_bus(dev) == -1) {
Expand Down