379 changes: 0 additions & 379 deletions src/ec/starlabs/it8987/acpi/ec.asl

This file was deleted.

251 changes: 0 additions & 251 deletions src/ec/starlabs/it8987/acpi/hid.asl

This file was deleted.

63 changes: 0 additions & 63 deletions src/ec/starlabs/it8987/acpi/keyboard.asl

This file was deleted.

47 changes: 0 additions & 47 deletions src/ec/starlabs/it8987/acpi/lid.asl

This file was deleted.

14 changes: 0 additions & 14 deletions src/ec/starlabs/it8987/acpi/thermal.asl

This file was deleted.

10 changes: 0 additions & 10 deletions src/ec/starlabs/it8987/chip.h

This file was deleted.

83 changes: 0 additions & 83 deletions src/ec/starlabs/it8987/ec.c

This file was deleted.

48 changes: 0 additions & 48 deletions src/ec/starlabs/it8987/ec.h

This file was deleted.

1 change: 1 addition & 0 deletions src/include/bootmode.h
Expand Up @@ -11,6 +11,7 @@ int get_recovery_mode_retrain_switch(void);
int clear_recovery_mode_switch(void);
int get_wipeout_mode_switch(void);
int get_lid_switch(void);
int get_ec_is_trusted(void);

/* Return 1 if display initialization is required. 0 if not. */
int display_init_required(void);
Expand Down
92 changes: 87 additions & 5 deletions src/include/cbfs.h
Expand Up @@ -7,6 +7,7 @@
#include <commonlib/bsd/cbfs_mdata.h>
#include <commonlib/cbfs.h>
#include <commonlib/mem_pool.h>
#include <commonlib/region.h>
#include <program_loading.h>
#include <types.h>
#include <vb2_sha.h>
Expand Down Expand Up @@ -97,26 +98,50 @@ static inline void *cbfs_type_cbmem_alloc(const char *name, uint32_t cbmem_id, s
static inline void *cbfs_ro_type_cbmem_alloc(const char *name, uint32_t cbmem_id,
size_t *size_out, enum cbfs_type *type);

/*
* Starts the processes of preloading a file into RAM.
*
* This method depends on COOP_MULTITASKING to parallelize the loading. This method is only
* effective when the underlying rdev supports DMA operations.
*
* When `cbfs_load`, `cbfs_alloc`, or `cbfs_map` are called after a preload has been started,
* they will wait for the preload to complete (if it hasn't already) and then perform
* verification and/or decompression.
*
* This method does not have a return value because the system should boot regardless if this
* method succeeds or fails.
*/
void cbfs_preload(const char *name);

/* Removes a previously allocated CBFS mapping. Should try to unmap mappings in strict LIFO
order where possible, since mapping backends often don't support more complicated cases. */
void cbfs_unmap(void *mapping);

/* Load stage into memory filling in prog. Return 0 on success. < 0 on error. */
int cbfs_prog_stage_load(struct prog *prog);

/* Returns the size of a CBFS file, or 0 on error. Avoid using this function to allocate space,
and instead use cbfs_alloc() so the file only needs to be looked up once. */
static inline size_t cbfs_get_size(const char *name);
static inline size_t cbfs_ro_get_size(const char *name);

/* Returns the type of a CBFS file, or CBFS_TYPE_NULL on error. Use cbfs_type_load() instead of
this where possible to avoid looking up the file more than once. */
static inline enum cbfs_type cbfs_get_type(const char *name);
static inline enum cbfs_type cbfs_ro_get_type(const char *name);

/* Check whether a CBFS file exists. */
static inline bool cbfs_file_exists(const char *name);
static inline bool cbfs_ro_file_exists(const char *name);


/**********************************************************************************************
* BOOT DEVICE HELPER APIs *
**********************************************************************************************/

/*
* The shared memory pool for backing mapped CBFS files, and other CBFS allocation needs.
* On x86 platforms, this would only be needed to transparently map compressed files, but it
* would require a permanent CBMEM carveout to be safe to use during S3 resume. Since it's not
* clear whether this feature is necessary or worth the wasted memory, it is currently disabled
* but could be added behind a Kconfig later if desired.
*/
#define CBFS_CACHE_AVAILABLE (!CONFIG(ARCH_X86))
extern struct mem_pool cbfs_cache;

/*
Expand Down Expand Up @@ -163,6 +188,9 @@ int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name,
/**********************************************************************************************
* INTERNAL HELPERS FOR INLINES, DO NOT USE. *
**********************************************************************************************/
cb_err_t _cbfs_boot_lookup(const char *name, bool force_ro,
union cbfs_mdata *mdata, struct region_device *rdev);

void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
size_t *size_out, bool force_ro, enum cbfs_type *type);

Expand Down Expand Up @@ -277,4 +305,58 @@ static inline void *cbfs_ro_type_cbmem_alloc(const char *name, uint32_t cbmem_id
size_out, type);
}

static inline size_t cbfs_get_size(const char *name)
{
union cbfs_mdata mdata;
struct region_device rdev;
if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
return 0;
return be32toh(mdata.h.len);
}

static inline size_t cbfs_ro_get_size(const char *name)
{
union cbfs_mdata mdata;
struct region_device rdev;
if (_cbfs_boot_lookup(name, true, &mdata, &rdev) != CB_SUCCESS)
return 0;
return be32toh(mdata.h.len);
}

static inline enum cbfs_type cbfs_get_type(const char *name)
{
union cbfs_mdata mdata;
struct region_device rdev;
if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
return CBFS_TYPE_NULL;
return be32toh(mdata.h.type);
}

static inline enum cbfs_type cbfs_ro_get_type(const char *name)
{
union cbfs_mdata mdata;
struct region_device rdev;
if (_cbfs_boot_lookup(name, true, &mdata, &rdev) != CB_SUCCESS)
return CBFS_TYPE_NULL;
return be32toh(mdata.h.type);
}

static inline bool cbfs_file_exists(const char *name)
{
union cbfs_mdata mdata;
struct region_device rdev;
if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
return false;
return true;
}

static inline bool cbfs_ro_file_exists(const char *name)
{
union cbfs_mdata mdata;
struct region_device rdev;
if (_cbfs_boot_lookup(name, true, &mdata, &rdev) != CB_SUCCESS)
return false;
return true;
}

#endif
23 changes: 0 additions & 23 deletions src/include/cbfs_private.h

This file was deleted.

15 changes: 10 additions & 5 deletions src/include/cpu/amd/mtrr.h
Expand Up @@ -43,7 +43,6 @@
#include <cpu/x86/msr.h>
#include <stdint.h>

void amd_setup_mtrrs(void);
struct device;
void add_uma_resource_below_tolm(struct device *nb, int idx);

Expand All @@ -67,10 +66,16 @@ static __always_inline void wrmsr_amd(unsigned int index, msr_t msr)
);
}

/* To distribute topmem MSRs to APs. */
void setup_bsp_ramtop(void);
uint64_t bsp_topmem(void);
uint64_t bsp_topmem2(void);
static inline uint64_t amd_topmem(void)
{
return rdmsr(TOP_MEM).lo;
}

static inline uint64_t amd_topmem2(void)
{
msr_t msr = rdmsr(TOP_MEM2);
return (uint64_t)msr.hi << 32 | msr.lo;
}
#endif

#endif /* CPU_AMD_MTRR_H */
45 changes: 24 additions & 21 deletions src/include/device/azalia_device.h
Expand Up @@ -23,6 +23,8 @@ int azalia_enter_reset(u8 *base);
int azalia_exit_reset(u8 *base);
u32 azalia_find_verb(const u32 *verb_table, u32 verb_table_bytes, u32 viddid, const u32 **verb);
int azalia_program_verb_table(u8 *base, const u32 *verbs, u32 verb_size);
void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes);
void azalia_codecs_init(u8 *base, u16 codec_mask);
void azalia_audio_init(struct device *dev);
extern struct device_operations default_azalia_audio_ops;

Expand Down Expand Up @@ -126,26 +128,27 @@ enum azalia_pin_location_2 {
ARRAY_SIZE(pc_beep_verbs); \
const u32 cim_verb_data_size = sizeof(cim_verb_data)

#define AZALIA_PIN_CFG(codec, pin, val) \
(((codec) << 28) | ((pin) << 20) | (0x71c << 8) \
| ((val) & 0xff)), \
(((codec) << 28) | ((pin) << 20) | (0x71d << 8) \
| (((val) >> 8) & 0xff)), \
(((codec) << 28) | ((pin) << 20) | (0x71e << 8) \
| (((val) >> 16) & 0xff)), \
(((codec) << 28) | ((pin) << 20) | (0x71f << 8) \
| (((val) >> 24) & 0xff))

#define AZALIA_PIN_CFG_NC(n) (0x411111f0 | (n & 0xf))

#define AZALIA_RESET(pin) \
(((pin) << 20) | 0x7ff00), (((pin) << 20) | 0x7ff00), \
(((pin) << 20) | 0x7ff00), (((pin) << 20) | 0x7ff00)

#define AZALIA_SUBVENDOR(codec, val) \
(((codec) << 28) | (0x01720 << 8) | ((val) & 0xff)), \
(((codec) << 28) | (0x01721 << 8) | (((val) >> 8) & 0xff)), \
(((codec) << 28) | (0x01722 << 8) | (((val) >> 16) & 0xff)), \
(((codec) << 28) | (0x01723 << 8) | (((val) >> 24) & 0xff))
#define AZALIA_VERB_12B(codec, pin, verb, val) \
((codec) << 28 | (pin) << 20 | (verb) << 8 | (val))

#define AZALIA_PIN_CFG(codec, pin, val) \
AZALIA_VERB_12B(codec, pin, 0x71c, ((val) >> 0) & 0xff), \
AZALIA_VERB_12B(codec, pin, 0x71d, ((val) >> 8) & 0xff), \
AZALIA_VERB_12B(codec, pin, 0x71e, ((val) >> 16) & 0xff), \
AZALIA_VERB_12B(codec, pin, 0x71f, ((val) >> 24) & 0xff)

#define AZALIA_PIN_CFG_NC(n) (0x411111f0 | ((n) & 0xf))

#define AZALIA_RESET(pin) \
AZALIA_VERB_12B(0, pin, 0x7ff, 0), \
AZALIA_VERB_12B(0, pin, 0x7ff, 0), \
AZALIA_VERB_12B(0, pin, 0x7ff, 0), \
AZALIA_VERB_12B(0, pin, 0x7ff, 0)

#define AZALIA_SUBVENDOR(codec, val) \
AZALIA_VERB_12B(codec, 1, 0x720, ((val) >> 0) & 0xff), \
AZALIA_VERB_12B(codec, 1, 0x721, ((val) >> 8) & 0xff), \
AZALIA_VERB_12B(codec, 1, 0x722, ((val) >> 16) & 0xff), \
AZALIA_VERB_12B(codec, 1, 0x723, ((val) >> 24) & 0xff)

#endif /* DEVICE_AZALIA_H */
11 changes: 11 additions & 0 deletions src/include/device/device.h
Expand Up @@ -148,6 +148,17 @@ struct device {
u8 smbios_slot_data_width;
u8 smbios_slot_length;
const char *smbios_slot_designation;

#if CONFIG(SMBIOS_TYPE41_PROVIDED_BY_DEVTREE)
/*
* These fields are intentionally guarded so that attempts to use
* the corresponding devicetree syntax without selecting the Kconfig
* option result in build-time errors. Smaller size is a side effect.
*/
bool smbios_instance_id_valid;
u8 smbios_instance_id;
const char *smbios_refdes;
#endif
#endif
#endif
DEVTREE_CONST void *chip_info;
Expand Down
10 changes: 10 additions & 0 deletions src/include/device/dram/spd.h
Expand Up @@ -3,8 +3,18 @@
#ifndef DEVICE_DRAM_SPD_H
#define DEVICE_DRAM_SPD_H

#include <smbios.h>
#include <types.h>

const char *spd_manufacturer_name(const uint16_t mod_id);

struct spd_info {
uint16_t type_detail;
uint8_t form_factor;
};

void get_spd_info(smbios_memory_type memory_type, uint8_t module_type, struct spd_info *info);
uint8_t convert_form_factor_to_module_type(smbios_memory_type memory_type,
smbios_memory_form_factor form_factor);

#endif /* DEVICE_DRAM_SPD_H */
6 changes: 4 additions & 2 deletions src/include/device/pci_ids.h
Expand Up @@ -620,8 +620,6 @@
#define PCI_DEVICE_ID_AMD_FAM17H_SATA_AHCI_RAID_VER0 0x7916
#define PCI_DEVICE_ID_AMD_FAM17H_SATA_AHCI_RAID_VER1 0x7917
#define PCI_DEVICE_ID_AMD_FAM17H_MODEL18H_SD 0x7906
#define PCI_DEVICE_ID_AMD_FAM17H_SMBUS 0x790B
#define PCI_DEVICE_ID_AMD_FAM17H_LPC 0x790E
#define PCI_DEVICE_ID_AMD_FAM17H_MODEL18H_GBE 0x1458
#define PCI_DEVICE_ID_AMD_FAM17H_MODEL60H_GBE 0x1641
#define PCI_DEVICE_ID_AMD_FAM17H_I2S_AC97 0x1644
Expand Down Expand Up @@ -3334,6 +3332,10 @@
#define PCI_DEVICE_ID_INTEL_MCC_PCIE_RP6 0x4b3d
#define PCI_DEVICE_ID_INTEL_MCC_PCIE_RP7 0x4b3e

#define PCI_DEVICE_ID_INTEL_ADL_P_PCIE_RP1 0x464d
#define PCI_DEVICE_ID_INTEL_ADL_P_PCIE_RP2 0x460d
#define PCI_DEVICE_ID_INTEL_ADL_P_PCIE_RP3 0x463d

#define PCI_DEVICE_ID_INTEL_ADP_P_PCIE_RP1 0x51b8
#define PCI_DEVICE_ID_INTEL_ADP_P_PCIE_RP2 0x51b9
#define PCI_DEVICE_ID_INTEL_ADP_P_PCIE_RP3 0x51ba
Expand Down
91 changes: 28 additions & 63 deletions src/include/device/pci_mmio_cfg.h
Expand Up @@ -7,10 +7,6 @@
#include <device/mmio.h>
#include <device/pci_type.h>

/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we
* prevent some sub-optimal constant folding. */
extern u8 *const pci_mmconf;

/* Using a unique datatype for MMIO writes makes the pointers to _not_
* qualify for pointer aliasing with any other objects in memory.
*
Expand All @@ -29,44 +25,66 @@ union pci_bank {
uint32_t reg32[4096 / sizeof(uint32_t)];
};

#if CONFIG(ECAM_MMCONF_SUPPORT)

#if CONFIG_ECAM_MMCONF_BASE_ADDRESS == 0
#error "CONFIG_ECAM_MMCONF_BASE_ADDRESS undefined!"
#endif

#if CONFIG_ECAM_MMCONF_BUS_NUMBER * MiB != CONFIG_ECAM_MMCONF_LENGTH
#error "CONFIG_ECAM_MMCONF_LENGTH does not correspond with CONFIG_ECAM_MMCONF_BUS_NUMBER!"
#endif

/* By not assigning this to CONFIG_ECAM_MMCONF_BASE_ADDRESS here we
prevent some sub-optimal constant folding. */
extern u8 *const pci_mmconf;

static __always_inline
volatile union pci_bank *pcicfg(pci_devfn_t dev)
{
return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)];
}

#endif

/*
* Avoid name collisions as different stages have different signature
* for these functions. The _s_ stands for simple, fundamental IO or
* MMIO variant.
*/

static __always_inline
uint8_t pci_mmio_read_config8(pci_devfn_t dev, uint16_t reg)
uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg)
{
return pcicfg(dev)->reg8[reg];
}

static __always_inline
uint16_t pci_mmio_read_config16(pci_devfn_t dev, uint16_t reg)
uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
{
return pcicfg(dev)->reg16[reg / sizeof(uint16_t)];
}

static __always_inline
uint32_t pci_mmio_read_config32(pci_devfn_t dev, uint16_t reg)
uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
{
return pcicfg(dev)->reg32[reg / sizeof(uint32_t)];
}

static __always_inline
void pci_mmio_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
{
pcicfg(dev)->reg8[reg] = value;
}

static __always_inline
void pci_mmio_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
{
pcicfg(dev)->reg16[reg / sizeof(uint16_t)] = value;
}

static __always_inline
void pci_mmio_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
{
pcicfg(dev)->reg32[reg / sizeof(uint32_t)] = value;
}
Expand Down Expand Up @@ -95,57 +113,4 @@ uint32_t *pci_mmio_config32_addr(pci_devfn_t dev, uint16_t reg)
return (uint32_t *)&pcicfg(dev)->reg32[reg / sizeof(uint32_t)];
}

#if CONFIG(MMCONF_SUPPORT)

#if CONFIG_MMCONF_BASE_ADDRESS == 0
#error "CONFIG_MMCONF_BASE_ADDRESS undefined!"
#endif

#if CONFIG_MMCONF_BUS_NUMBER * MiB != CONFIG_MMCONF_LENGTH
#error "CONFIG_MMCONF_LENGTH does not correspond with CONFIG_MMCONF_BUS_NUMBER!"
#endif

/* Avoid name collisions as different stages have different signature
* for these functions. The _s_ stands for simple, fundamental IO or
* MMIO variant.
*/

static __always_inline
uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg)
{
return pci_mmio_read_config8(dev, reg);
}

static __always_inline
uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
{
return pci_mmio_read_config16(dev, reg);
}

static __always_inline
uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
{
return pci_mmio_read_config32(dev, reg);
}

static __always_inline
void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
{
pci_mmio_write_config8(dev, reg, value);
}

static __always_inline
void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
{
pci_mmio_write_config16(dev, reg, value);
}

static __always_inline
void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
{
pci_mmio_write_config32(dev, reg, value);
}

#endif

#endif /* _PCI_MMIO_CFG_H */
1 change: 1 addition & 0 deletions src/include/device/pci_rom.h
Expand Up @@ -35,6 +35,7 @@ struct pci_data {
uint16_t reserved_2;
};

void vga_oprom_preload(void);
struct rom_header *pci_rom_probe(const struct device *dev);
struct rom_header *pci_rom_load(struct device *dev,
struct rom_header *rom_header);
Expand Down
5 changes: 5 additions & 0 deletions src/include/device/usbc_mux.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __USBC_MUX_H__
#define __USBC_MUX_H__

/* struct to hold all USB-C mux related variables */
struct usbc_mux_info {
bool dp; /* DP connected */
Expand Down Expand Up @@ -67,3 +70,5 @@ struct usbc_ops {
};

const struct usbc_ops *usbc_get_ops(void);

#endif /* __USBC_MUX_H__ */
6 changes: 3 additions & 3 deletions src/include/dimm_info_util.h
Expand Up @@ -12,7 +12,7 @@
* Use this when setting dimm_info.bus_width if the raw SPD values are not
* available.
*/
uint8_t smbios_bus_width_to_spd_width(uint16_t total_width,
uint8_t smbios_bus_width_to_spd_width(uint8_t ddr_type, uint16_t total_width,
uint16_t data_width);

/**
Expand All @@ -28,7 +28,7 @@ uint32_t smbios_memory_size_to_mib(uint16_t memory_size,
*
* Use this when setting dimm_info.mod_type.
*/
uint8_t
smbios_form_factor_to_spd_mod_type(smbios_memory_form_factor form_factor);
uint8_t smbios_form_factor_to_spd_mod_type(smbios_memory_type memory_type,
smbios_memory_form_factor form_factor);

#endif
48 changes: 48 additions & 0 deletions src/include/dp_aux.h
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _DP_AUX_H_
#define _DP_AUX_H_

#include <types.h>

enum {
EDID_LENGTH = 128,
EDID_I2C_ADDR = 0x50,
EDID_EXTENSION_FLAG = 0x7e,
};

enum i2c_over_aux {
I2C_OVER_AUX_WRITE_MOT_0 = 0x0,
I2C_OVER_AUX_READ_MOT_0 = 0x1,
I2C_OVER_AUX_WRITE_STATUS_UPDATE_0 = 0x2,
I2C_OVER_AUX_WRITE_MOT_1 = 0x4,
I2C_OVER_AUX_READ_MOT_1 = 0x5,
I2C_OVER_AUX_WRITE_STATUS_UPDATE_1 = 0x6,
NATIVE_AUX_WRITE = 0x8,
NATIVE_AUX_READ = 0x9,
};

enum aux_request {
DPCD_READ,
DPCD_WRITE,
I2C_RAW_READ,
I2C_RAW_WRITE,
I2C_RAW_READ_AND_STOP,
I2C_RAW_WRITE_AND_STOP,
};

/* Backlight configuration */
#define DP_BACKLIGHT_MODE_SET 0x721
#define DP_BACKLIGHT_CONTROL_MODE_MASK 0x3
#define DP_BACKLIGHT_CONTROL_MODE_DPCD 0x2
#define DP_DISPLAY_CONTROL_REGISTER 0x720
#define DP_BACKLIGHT_ENABLE 0x1
#define DP_BACKLIGHT_BRIGHTNESS_MSB 0x722

#define DP_AUX_MAX_PAYLOAD_BYTES 16


bool dp_aux_request_is_write(enum aux_request request);
enum i2c_over_aux dp_get_aux_cmd(enum aux_request request, uint32_t remaining_after_this);

#endif
2 changes: 2 additions & 0 deletions src/include/list.h
Expand Up @@ -15,6 +15,8 @@ void list_remove(struct list_node *node);
void list_insert_after(struct list_node *node, struct list_node *after);
// Insert list_node node before list_node before in a doubly linked list.
void list_insert_before(struct list_node *node, struct list_node *before);
// Appends the node to the end of the list.
void list_append(struct list_node *node, struct list_node *head);

#define list_for_each(ptr, head, member) \
for ((ptr) = container_of((head).next, typeof(*(ptr)), member); \
Expand Down
7 changes: 7 additions & 0 deletions src/include/program_loading.h
Expand Up @@ -145,6 +145,13 @@ int legacy_romstage_select_and_load(struct prog *romstage);
* RAMSTAGE LOADING *
************************/

/*
* Asynchronously preloads ramstage.
*
* This should be called early on to allow ramstage to load before
* `run_ramstage` is called.
*/
void preload_ramstage(void);
/* Run ramstage from romstage. */
void run_ramstage(void);

Expand Down
11 changes: 11 additions & 0 deletions src/include/rules.h
Expand Up @@ -292,6 +292,17 @@
#define ENV_INITIAL_STAGE ENV_BOOTBLOCK
#endif

#if ENV_X86
#define STAGE_HAS_SPINLOCKS !ENV_ROMSTAGE_OR_BEFORE
#elif ENV_RISCV
#define STAGE_HAS_SPINLOCKS 1
#else
#define STAGE_HAS_SPINLOCKS 0
#endif

/* When set <arch/smp/spinlock.h> is included for the spinlock implementation. */
#define ENV_STAGE_SUPPORTS_SMP (CONFIG(SMP) && STAGE_HAS_SPINLOCKS)

/**
* For pre-DRAM stages and post-CAR always build with simple device model, ie.
* PCI, PNP and CPU functions operate without use of devicetree. The reason
Expand Down
2 changes: 2 additions & 0 deletions src/include/smbios.h
Expand Up @@ -192,6 +192,8 @@ typedef enum {
MEMORY_TYPE_LOGICAL_NON_VOLATILE_DEVICE = 0x1f,
MEMORY_TYPE_HBM = 0x20,
MEMORY_TYPE_HBM2 = 0x21,
MEMORY_TYPE_DDR5 = 0x22,
MEMORY_TYPE_LPDDR5 = 0x23,
} smbios_memory_type;

typedef enum {
Expand Down
2 changes: 1 addition & 1 deletion src/include/smp/spinlock.h
@@ -1,7 +1,7 @@
#ifndef SMP_SPINLOCK_H
#define SMP_SPINLOCK_H

#if CONFIG(SMP)
#if ENV_STAGE_SUPPORTS_SMP
#include <arch/smp/spinlock.h>
#else /* !CONFIG_SMP */

Expand Down
73 changes: 63 additions & 10 deletions src/include/spd.h
Expand Up @@ -197,17 +197,70 @@ enum spd_memory_type {
#define MODULE_BUFFERED 1
#define MODULE_REGISTERED 2

/* Byte 3: Module type information */
#define SPD_UNDEFINED 0x00
#define SPD_RDIMM 0x01
#define SPD_UDIMM 0x02
#define SPD_SODIMM 0x04
#define SPD_72B_SO_CDIMM 0x06
#define SPD_72B_SO_RDIMM 0x07
#define SPD_MICRO_DIMM 0x08
#define SPD_MINI_RDIMM 0x10
#define SPD_MINI_UDIMM 0x20

#define SPD_ECC_8BIT (1<<3)
#define SPD_ECC_8BIT_LP5_DDR5 (1<<4)

/* Byte 3: Module type information */
enum ddr2_module_type {
DDR2_SPD_RDIMM = 0x01,
DDR2_SPD_UDIMM = 0x02,
DDR2_SPD_SODIMM = 0x04,
DDR2_SPD_72B_SO_CDIMM = 0x06,
DDR2_SPD_72B_SO_RDIMM = 0x07,
DDR2_SPD_MICRO_DIMM = 0x08,
DDR2_SPD_MINI_RDIMM = 0x10,
DDR2_SPD_MINI_UDIMM = 0x20,
};

enum ddr3_module_type {
DDR3_SPD_RDIMM = 0x01,
DDR3_SPD_UDIMM = 0x02,
DDR3_SPD_SODIMM = 0x03,
DDR3_SPD_MICRO_DIMM = 0x04,
DDR3_SPD_MINI_RDIMM = 0x05,
DDR3_SPD_MINI_UDIMM = 0x06,
DDR3_SPD_MINI_CDIMM = 0x07,
DDR3_SPD_72B_SO_UDIMM = 0x08,
DDR3_SPD_72B_SO_RDIMM = 0x09,
DDR3_SPD_72B_SO_CDIMM = 0x0a,
DDR3_SPD_LRDIMM = 0x0b,
DDR3_SPD_16B_SO_DIMM = 0x0c,
DDR3_SPD_32B_SO_RDIMM = 0x0d,
};

enum ddr4_module_type {
DDR4_SPD_RDIMM = 0x01,
DDR4_SPD_UDIMM = 0x02,
DDR4_SPD_SODIMM = 0x03,
DDR4_SPD_LRDIMM = 0x04,
DDR4_SPD_MINI_RDIMM = 0x05,
DDR4_SPD_MINI_UDIMM = 0x06,
DDR4_SPD_72B_SO_UDIMM = 0x08,
DDR4_SPD_72B_SO_RDIMM = 0x09,
DDR4_SPD_16B_SO_DIMM = 0x0c,
DDR4_SPD_32B_SO_RDIMM = 0x0d,
};

enum ddr5_module_type {
DDR5_SPD_RDIMM = 0x01,
DDR5_SPD_UDIMM = 0x02,
DDR5_SPD_SODIMM = 0x03,
DDR5_SPD_LRDIMM = 0x04,
DDR5_SPD_MINI_RDIMM = 0x05,
DDR5_SPD_MINI_UDIMM = 0x06,
DDR5_SPD_72B_SO_UDIMM = 0x08,
DDR5_SPD_72B_SO_RDIMM = 0x09,
DDR5_SPD_SOLDERED_DOWN = 0x0b,
DDR5_SPD_16B_SO_DIMM = 0x0c,
DDR5_SPD_32B_SO_RDIMM = 0x0d,
DDR5_SPD_1DPC = 0x0e,
DDR5_SPD_2DPC = 0x0f,
};

enum lpx_module_type {
LPX_SPD_LPDIMM = 0x07,
LPX_SPD_NONDIMM = 0x0e,
};

#endif
1 change: 0 additions & 1 deletion src/include/symbols.h
Expand Up @@ -52,7 +52,6 @@ DECLARE_REGION(asan_shadow)

/* Regions for execution units. */

DECLARE_REGION(payload_preload_cache)
DECLARE_REGION(payload)
/* "program" always refers to the current execution unit. */
DECLARE_REGION(program)
Expand Down
2 changes: 1 addition & 1 deletion src/include/thread.h
Expand Up @@ -5,7 +5,7 @@
#include <arch/cpu.h>
#include <bootstate.h>
#include <commonlib/bsd/cb_err.h>
#include <stdint.h>
#include <types.h>

struct thread_mutex {
bool locked;
Expand Down
21 changes: 13 additions & 8 deletions src/lib/Kconfig
Expand Up @@ -70,7 +70,7 @@ config HWBASE_DYNAMIC_MMIO

config HWBASE_DEFAULT_MMCONF
hex
default MMCONF_BASE_ADDRESS
default ECAM_MMCONF_BASE_ADDRESS

config HWBASE_DIRECT_PCIDEV
def_bool y
Expand Down Expand Up @@ -99,13 +99,18 @@ config NO_CBFS_MCACHE
lookup must re-read the same CBFS directory entries from flash to find
the respective file.

config PAYLOAD_PRELOAD
config CBFS_CACHE_ALIGN
int
default 8
help
Sets the alignment of the buffers returned by the cbfs_cache.

config CBFS_PRELOAD
bool
depends on COOP_MULTITASKING
help
On some systems with SPI DMA controllers, it is possible to preload
the payload while ramstage is executing. This can be selected by the
SoC to enable payload preloading.

The SoC needs to define a payload_preload_cache region where the
raw payload can be placed.
When enabled it will be possible to preload CBFS files into the
cbfs_cache. This helps reduce boot time by loading the files
in the background before they are actually required. This feature
depends on the read-only boot_device having a DMA controller to
perform the background transfer.
5 changes: 4 additions & 1 deletion src/lib/Makefile.inc
Expand Up @@ -28,6 +28,8 @@ CFLAGS_ramstage += $(CFLAGS_asan)
$(obj)/ramstage/lib/asan.o: CFLAGS_asan =
endif

all-y += list.c

decompressor-y += decompressor.c
$(call src-to-obj,decompressor,$(dir)/decompressor.c): $(objcbfs)/bootblock.lz4
$(call src-to-obj,decompressor,$(dir)/decompressor.c): CCACHE_EXTRAFILES=$(objcbfs)/bootblock.lz4
Expand Down Expand Up @@ -110,6 +112,7 @@ romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
romstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c

romstage-y += compute_ip_checksum.c
romstage-y += dimm_info_util.c
ifeq ($(CONFIG_COMPILER_GCC),y)
bootblock-$(CONFIG_ARCH_BOOTBLOCK_X86_32) += gcc.c
verstage-$(CONFIG_ARCH_VERSTAGE_X86_32) += gcc.c
Expand Down Expand Up @@ -146,14 +149,14 @@ ramstage-$(CONFIG_BOOTSPLASH) += bootsplash.c
ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
ramstage-$(CONFIG_COVERAGE) += libgcov.c
ramstage-y += dp_aux.c
ramstage-y += edid.c
ramstage-y += edid_fill_fb.c
ramstage-y += memrange.c
ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c
ramstage-y += b64_decode.c
ramstage-$(CONFIG_ACPI_NHLT) += nhlt.c
ramstage-y += list.c
ramstage-$(CONFIG_FLATTENED_DEVICE_TREE) += device_tree.c
ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit.c
ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit_payload.c
Expand Down
210 changes: 188 additions & 22 deletions src/lib/cbfs.c
Expand Up @@ -3,35 +3,40 @@
#include <assert.h>
#include <boot_device.h>
#include <cbfs.h>
#include <cbfs_private.h>
#include <cbmem.h>
#include <commonlib/bsd/cbfs_private.h>
#include <commonlib/bsd/compression.h>
#include <commonlib/endian.h>
#include <console/console.h>
#include <fmap.h>
#include <lib.h>
#include <list.h>
#include <metadata_hash.h>
#include <security/tpm/tspi/crtm.h>
#include <security/vboot/vboot_common.h>
#include <stdlib.h>
#include <string.h>
#include <symbols.h>
#include <thread.h>
#include <timestamp.h>

#if CBFS_CACHE_AVAILABLE
struct mem_pool cbfs_cache = MEM_POOL_INIT(_cbfs_cache, REGION_SIZE(cbfs_cache));
#if ENV_STAGE_HAS_DATA_SECTION
struct mem_pool cbfs_cache =
MEM_POOL_INIT(_cbfs_cache, REGION_SIZE(cbfs_cache), CONFIG_CBFS_CACHE_ALIGN);
#else
struct mem_pool cbfs_cache = MEM_POOL_INIT(NULL, 0, 0);
#endif

static void switch_to_postram_cache(int unused)
{
if (_preram_cbfs_cache != _postram_cbfs_cache)
mem_pool_init(&cbfs_cache, _postram_cbfs_cache,
REGION_SIZE(postram_cbfs_cache));
mem_pool_init(&cbfs_cache, _postram_cbfs_cache, REGION_SIZE(postram_cbfs_cache),
CONFIG_CBFS_CACHE_ALIGN);
}
ROMSTAGE_CBMEM_INIT_HOOK(switch_to_postram_cache);
#endif

cb_err_t cbfs_boot_lookup(const char *name, bool force_ro,
union cbfs_mdata *mdata, struct region_device *rdev)
cb_err_t _cbfs_boot_lookup(const char *name, bool force_ro,
union cbfs_mdata *mdata, struct region_device *rdev)
{
const struct cbfs_boot_device *cbd = cbfs_get_boot_device(force_ro);
if (!cbd)
Expand Down Expand Up @@ -60,7 +65,7 @@ cb_err_t cbfs_boot_lookup(const char *name, bool force_ro,

if (CONFIG(VBOOT_ENABLE_CBFS_FALLBACK) && !force_ro && err == CB_CBFS_NOT_FOUND) {
printk(BIOS_INFO, "CBFS: Fall back to RO region for %s\n", name);
return cbfs_boot_lookup(name, true, mdata, rdev);
return _cbfs_boot_lookup(name, true, mdata, rdev);
}
if (err) {
if (err == CB_CBFS_NOT_FOUND)
Expand All @@ -85,7 +90,7 @@ cb_err_t cbfs_boot_lookup(const char *name, bool force_ro,

int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type)
{
if (cbfs_boot_lookup(name, false, &fh->mdata, &fh->data))
if (_cbfs_boot_lookup(name, false, &fh->mdata, &fh->data))
return -1;

size_t msize = be32toh(fh->mdata.h.offset);
Expand All @@ -111,8 +116,7 @@ void cbfs_unmap(void *mapping)
* that requires a free() for the boot_device, they need to implement it via the
* cbfs_cache mem_pool.
*/
if (CBFS_CACHE_AVAILABLE)
mem_pool_free(&cbfs_cache, mapping);
mem_pool_free(&cbfs_cache, mapping);
}

int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name,
Expand Down Expand Up @@ -264,17 +268,161 @@ static size_t cbfs_load_and_decompress(const struct region_device *rdev, void *b
}
}

struct cbfs_preload_context {
struct region_device rdev;
struct thread_handle handle;
struct list_node list_node;
void *buffer;
char name[];
};

static struct list_node cbfs_preload_context_list;

static struct cbfs_preload_context *alloc_cbfs_preload_context(size_t additional)
{
struct cbfs_preload_context *context;
size_t size = sizeof(*context) + additional;

context = mem_pool_alloc(&cbfs_cache, size);

if (!context)
return NULL;

memset(context, 0, size);

return context;
}

static void append_cbfs_preload_context(struct cbfs_preload_context *context)
{
list_append(&context->list_node, &cbfs_preload_context_list);
}

static void free_cbfs_preload_context(struct cbfs_preload_context *context)
{
list_remove(&context->list_node);

mem_pool_free(&cbfs_cache, context);
}

static enum cb_err cbfs_preload_thread_entry(void *arg)
{
struct cbfs_preload_context *context = arg;

if (rdev_readat_full(&context->rdev, context->buffer) < 0) {
ERROR("%s(name='%s') readat failed\n", __func__, context->name);
return CB_ERR;
}

return CB_SUCCESS;
}

void cbfs_preload(const char *name)
{
struct region_device rdev;
union cbfs_mdata mdata;
struct cbfs_preload_context *context;
bool force_ro = false;
size_t size;

if (!CONFIG(CBFS_PRELOAD))
dead_code();

DEBUG("%s(name='%s')\n", __func__, name);

if (_cbfs_boot_lookup(name, force_ro, &mdata, &rdev))
return;

size = region_device_sz(&rdev);

context = alloc_cbfs_preload_context(strlen(name) + 1);
if (!context) {
ERROR("%s(name='%s') failed to allocate preload context\n", __func__, name);
return;
}

context->buffer = mem_pool_alloc(&cbfs_cache, size);
if (context->buffer == NULL) {
ERROR("%s(name='%s') failed to allocate %zu bytes for preload buffer\n",
__func__, name, size);
goto out;
}

context->rdev = rdev;
strcpy(context->name, name);

append_cbfs_preload_context(context);

if (thread_run(&context->handle, cbfs_preload_thread_entry, context) == 0)
return;

ERROR("%s(name='%s') failed to start preload thread\n", __func__, name);
mem_pool_free(&cbfs_cache, context->buffer);

out:
free_cbfs_preload_context(context);
}

static struct cbfs_preload_context *find_cbfs_preload_context(const char *name)
{
struct cbfs_preload_context *context;

list_for_each(context, cbfs_preload_context_list, list_node) {
if (strcmp(context->name, name) == 0)
return context;
}

return NULL;
}

static enum cb_err get_preload_rdev(struct region_device *rdev, const char *name)
{
enum cb_err err;
struct cbfs_preload_context *context;

if (!CONFIG(CBFS_PRELOAD) || (!ENV_RAMSTAGE && !ENV_ROMSTAGE))
return CB_ERR_ARG;

context = find_cbfs_preload_context(name);
if (!context)
return CB_ERR_ARG;

err = thread_join(&context->handle);
if (err != CB_SUCCESS) {
ERROR("%s(name='%s') Preload thread failed: %u\n", __func__, name, err);

goto out;
}

if (rdev_chain_mem(rdev, context->buffer, region_device_sz(&context->rdev)) != 0) {
ERROR("%s(name='%s') chaining failed\n", __func__, name);

err = CB_ERR;
goto out;
}

err = CB_SUCCESS;

DEBUG("%s(name='%s') preload successful\n", __func__, name);

out:
free_cbfs_preload_context(context);

return err;
}

void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
size_t *size_out, bool force_ro, enum cbfs_type *type)
{
struct region_device rdev;
bool preload_successful = false;
union cbfs_mdata mdata;
void *loc;
void *loc = NULL;

DEBUG("%s(name='%s', alloc=%p(%p), force_ro=%s, type=%d)\n", __func__, name, allocator,
arg, force_ro ? "true" : "false", type ? *type : -1);

if (cbfs_boot_lookup(name, force_ro, &mdata, &rdev))
if (_cbfs_boot_lookup(name, force_ro, &mdata, &rdev))
return NULL;

if (type) {
Expand Down Expand Up @@ -304,36 +452,54 @@ void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
if (CONFIG(CBFS_VERIFICATION))
file_hash = cbfs_file_hash(&mdata);

/* Update the rdev with the preload content */
if (!force_ro && get_preload_rdev(&rdev, name) == CB_SUCCESS)
preload_successful = true;

/* allocator == NULL means do a cbfs_map() */
if (allocator) {
loc = allocator(arg, size, &mdata);
} else if (compression == CBFS_COMPRESS_NONE) {
void *mapping = rdev_mmap_full(&rdev);

if (!mapping)
return NULL;
goto out;

if (cbfs_file_hash_mismatch(mapping, size, file_hash)) {
rdev_munmap(&rdev, mapping);
return NULL;
goto out;
}

return mapping;
} else if (!CBFS_CACHE_AVAILABLE) {
ERROR("Cannot map compressed file %s on x86\n", mdata.h.filename);
return NULL;
} else if (!cbfs_cache.size) {
/*
* In order to use the cbfs_cache you need to add a CBFS_CACHE to your
* memlayout. For stages that don't have .data sections (x86 pre-RAM),
* it is not possible to add a CBFS_CACHE.
*/
ERROR("Cannot map compressed file %s without cbfs_cache\n", mdata.h.filename);
goto out;
} else {
loc = mem_pool_alloc(&cbfs_cache, size);
}

if (!loc) {
ERROR("'%s' allocation failure\n", mdata.h.filename);
return NULL;
goto out;
}

size = cbfs_load_and_decompress(&rdev, loc, size, compression, file_hash);

if (!size)
return NULL;
loc = NULL;

out:
/*
* When using cbfs_preload we need to free the preload buffer after populating the
* destination buffer.
*/
if (preload_successful)
cbfs_unmap(rdev_mmap_full(&rdev));

return loc;
}
Expand All @@ -359,7 +525,7 @@ cb_err_t cbfs_prog_stage_load(struct prog *pstage)

prog_locate_hook(pstage);

if ((err = cbfs_boot_lookup(prog_name(pstage), false, &mdata, &rdev)))
if ((err = _cbfs_boot_lookup(prog_name(pstage), false, &mdata, &rdev)))
return err;

assert(be32toh(mdata.h.type) == CBFS_TYPE_STAGE);
Expand Down
25 changes: 10 additions & 15 deletions src/lib/dimm_info_util.c
@@ -1,11 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/dram/spd.h>
#include <dimm_info_util.h>
#include <smbios.h>
#include <spd.h>
#include <console/console.h>

uint8_t smbios_bus_width_to_spd_width(uint16_t total_width, uint16_t data_width)
uint8_t smbios_bus_width_to_spd_width(uint8_t ddr_type, uint16_t total_width,
uint16_t data_width)
{
uint8_t out;

Expand Down Expand Up @@ -38,7 +40,10 @@ uint8_t smbios_bus_width_to_spd_width(uint16_t total_width, uint16_t data_width)

switch (extension_bits) {
case 8:
out |= SPD_ECC_8BIT;
if (ddr_type == MEMORY_TYPE_DDR5 || ddr_type == MEMORY_TYPE_LPDDR5)
out |= SPD_ECC_8BIT_LP5_DDR5;
else
out |= SPD_ECC_8BIT;
break;
case 0:
/* No extension bits */
Expand Down Expand Up @@ -68,18 +73,8 @@ uint32_t smbios_memory_size_to_mib(uint16_t memory_size, uint32_t extended_size)
return memory_size;
}

uint8_t
smbios_form_factor_to_spd_mod_type(smbios_memory_form_factor form_factor)
uint8_t smbios_form_factor_to_spd_mod_type(smbios_memory_type memory_type,
smbios_memory_form_factor form_factor)
{
/* This switch reverses the switch in smbios.c */
switch (form_factor) {
case MEMORY_FORMFACTOR_DIMM:
return SPD_UDIMM;
case MEMORY_FORMFACTOR_RIMM:
return SPD_RDIMM;
case MEMORY_FORMFACTOR_SODIMM:
return SPD_SODIMM;
default:
return SPD_UNDEFINED;
}
return convert_form_factor_to_module_type(memory_type, form_factor);
}
41 changes: 41 additions & 0 deletions src/lib/dp_aux.c
@@ -0,0 +1,41 @@
/* SPDX-License-Identifier: GPL-2.0-only */

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

bool dp_aux_request_is_write(enum aux_request request)
{
switch (request) {
case I2C_RAW_WRITE_AND_STOP:
case I2C_RAW_WRITE:
case DPCD_WRITE:
return true;
default:
return false;
}
}

enum i2c_over_aux dp_get_aux_cmd(enum aux_request request, uint32_t remaining_after_this)
{
switch (request) {
case I2C_RAW_WRITE_AND_STOP:
if (!remaining_after_this)
return I2C_OVER_AUX_WRITE_MOT_0;
/* fallthrough */
case I2C_RAW_WRITE:
return I2C_OVER_AUX_WRITE_MOT_1;
case I2C_RAW_READ_AND_STOP:
if (!remaining_after_this)
return I2C_OVER_AUX_READ_MOT_0;
/* fallthrough */
case I2C_RAW_READ:
return I2C_OVER_AUX_READ_MOT_1;
case DPCD_WRITE:
return NATIVE_AUX_WRITE;
case DPCD_READ:
default:
return NATIVE_AUX_READ;
}
}
14 changes: 8 additions & 6 deletions src/lib/fmap.c
Expand Up @@ -8,6 +8,7 @@
#include <stddef.h>
#include <string.h>
#include <symbols.h>
#include <endian.h>

#include "fmap_config.h"

Expand Down Expand Up @@ -49,7 +50,8 @@ static void report(const struct fmap *fmap)
print_once(BIOS_DEBUG, "FMAP: Found \"%s\" version %d.%d at %#x.\n",
fmap->name, fmap->ver_major, fmap->ver_minor, FMAP_OFFSET);
print_once(BIOS_DEBUG, "FMAP: base = %#llx size = %#x #areas = %d\n",
(long long)fmap->base, fmap->size, fmap->nareas);
(long long)le64toh(fmap->base), le32toh(fmap->size),
le16toh(fmap->nareas));
fmap_print_once = 1;
}

Expand Down Expand Up @@ -188,10 +190,10 @@ int fmap_locate_area(const char *name, struct region *ar)
}

printk(BIOS_DEBUG, "FMAP: area %s found @ %x (%d bytes)\n",
name, area->offset, area->size);
name, le32toh(area->offset), le32toh(area->size));

ar->offset = area->offset;
ar->size = area->size;
ar->offset = le32toh(area->offset);
ar->size = le32toh(area->size);

rdev_munmap(&fmrd, area);

Expand Down Expand Up @@ -226,8 +228,8 @@ int fmap_find_region_name(const struct region * const ar,
if (area == NULL)
return -1;

if ((ar->offset != area->offset) ||
(ar->size != area->size)) {
if ((ar->offset != le32toh(area->offset)) ||
(ar->size != le32toh(area->size))) {
rdev_munmap(&fmrd, area);
offset += sizeof(struct fmap_area);
continue;
Expand Down
41 changes: 26 additions & 15 deletions src/lib/fw_config.c
Expand Up @@ -11,6 +11,7 @@
#include <lib.h>
#include <stdbool.h>
#include <stdint.h>
#include <drivers/vpd/vpd.h>

uint64_t fw_config_get(void)
{
Expand All @@ -21,30 +22,40 @@ uint64_t fw_config_get(void)
if (fw_config_value_initialized)
return fw_config_value;
fw_config_value_initialized = true;
fw_config_value = UNDEFINED_FW_CONFIG;

/* Read the value from EC CBI. */
if (CONFIG(FW_CONFIG_SOURCE_CHROMEEC_CBI)) {
if (google_chromeec_cbi_get_fw_config(&fw_config_value))
printk(BIOS_WARNING, "%s: Could not get fw_config from CBI\n",
__func__);
else
printk(BIOS_INFO, "FW_CONFIG value from CBI is 0x%" PRIx64 "\n",
fw_config_value);
}

/* Look in CBFS to allow override of value. */
if (CONFIG(FW_CONFIG_SOURCE_CBFS)) {
if (CONFIG(FW_CONFIG_SOURCE_CBFS) && fw_config_value == UNDEFINED_FW_CONFIG) {
if (cbfs_load(CONFIG_CBFS_PREFIX "/fw_config", &fw_config_value,
sizeof(fw_config_value)) != sizeof(fw_config_value)) {
sizeof(fw_config_value)) != sizeof(fw_config_value))
printk(BIOS_WARNING, "%s: Could not get fw_config from CBFS\n",
__func__);
fw_config_value = UNDEFINED_FW_CONFIG;
} else {
__func__);
else
printk(BIOS_INFO, "FW_CONFIG value from CBFS is 0x%" PRIx64 "\n",
fw_config_value);
return fw_config_value;
}
fw_config_value);
}

/* Read the value from EC CBI. */
if (CONFIG(FW_CONFIG_SOURCE_CHROMEEC_CBI)) {
if (google_chromeec_cbi_get_fw_config(&fw_config_value)) {
printk(BIOS_WARNING, "%s: Could not get fw_config from EC\n", __func__);
fw_config_value = UNDEFINED_FW_CONFIG;
}
if (CONFIG(FW_CONFIG_SOURCE_VPD) && fw_config_value == UNDEFINED_FW_CONFIG) {
int vpd_value;
if (vpd_get_int("fw_config", VPD_RW_THEN_RO, &vpd_value)) {
fw_config_value = vpd_value;
printk(BIOS_INFO, "FW_CONFIG value from VPD is 0x%" PRIx64 "\n",
fw_config_value);
} else
printk(BIOS_WARNING, "%s: Could not get fw_config from vpd\n",
__func__);
}

printk(BIOS_INFO, "FW_CONFIG value is 0x%" PRIx64 "\n", fw_config_value);
return fw_config_value;
}

Expand Down
5 changes: 5 additions & 0 deletions src/lib/hardwaremain.c
Expand Up @@ -290,6 +290,9 @@ static void bs_call_callbacks(struct boot_state *state,
mono_time_diff_microseconds(&mt_start, &mt_stop)
/ USECS_PER_MSEC);
}

bs_run_timers(0);

continue;
}

Expand Down Expand Up @@ -355,6 +358,8 @@ static void bs_walk_state_machine(void)

bs_sample_time(state);

bs_run_timers(0);

bs_call_callbacks(state, current_phase.seq);

if (CONFIG(DEBUG_BOOT_STATE))
Expand Down
8 changes: 8 additions & 0 deletions src/lib/list.c
Expand Up @@ -28,3 +28,11 @@ void list_insert_before(struct list_node *node, struct list_node *before)
if (node->prev)
node->prev->next = node;
}

void list_append(struct list_node *node, struct list_node *head)
{
while (head->next)
head = head->next;

list_insert_after(node, head);
}
61 changes: 17 additions & 44 deletions src/lib/prog_loaders.c
Expand Up @@ -75,7 +75,15 @@ static int load_relocatable_ramstage(struct prog *ramstage)

return rmodule_stage_load(&rmod_ram);
}
void preload_ramstage(void)
{
if (!CONFIG(CBFS_PRELOAD))
return;

printk(BIOS_DEBUG, "Preloading ramstage\n");

cbfs_preload(CONFIG_CBFS_PREFIX "/ramstage");
}
void run_ramstage(void)
{
struct prog ramstage =
Expand Down Expand Up @@ -127,71 +135,37 @@ void run_ramstage(void)
static struct prog global_payload =
PROG_INIT(PROG_PAYLOAD, CONFIG_CBFS_PREFIX "/payload");

static struct thread_handle payload_preload_handle;

static enum cb_err payload_preload_thread_entry(void *arg)
{
size_t size;
struct prog *payload = &global_payload;

printk(BIOS_DEBUG, "Preloading payload\n");

payload->cbfs_type = CBFS_TYPE_QUERY;

size = cbfs_type_load(prog_name(payload), _payload_preload_cache,
REGION_SIZE(payload_preload_cache), &payload->cbfs_type);

if (!size) {
printk(BIOS_ERR, "ERROR: Preloading payload failed\n");
return CB_ERR;
}

printk(BIOS_DEBUG, "Preloading payload complete\n");

return CB_SUCCESS;
}

void payload_preload(void)
{
struct thread_handle *handle = &payload_preload_handle;

if (!CONFIG(PAYLOAD_PRELOAD))
if (!CONFIG(CBFS_PRELOAD))
return;

if (thread_run(handle, payload_preload_thread_entry, NULL))
printk(BIOS_ERR, "ERROR: Failed to start payload preload thread\n");
cbfs_preload(global_payload.name);
}

void payload_load(void)
{
struct prog *payload = &global_payload;
struct thread_handle *handle = &payload_preload_handle;
void *mapping = NULL;
void *buffer;
void *mapping;

timestamp_add_now(TS_LOAD_PAYLOAD);

if (prog_locate_hook(payload))
goto out;

if (CONFIG(PAYLOAD_PRELOAD) && thread_join(handle) == CB_SUCCESS) {
buffer = _payload_preload_cache;
} else {
payload->cbfs_type = CBFS_TYPE_QUERY;
mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type);
buffer = mapping;
}
payload->cbfs_type = CBFS_TYPE_QUERY;
mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type);

if (!buffer)
if (!mapping)
goto out;

switch (prog_cbfs_type(payload)) {
case CBFS_TYPE_SELF: /* Simple ELF */
selfload_mapped(payload, buffer, BM_MEM_RAM);
selfload_mapped(payload, mapping, BM_MEM_RAM);
break;
case CBFS_TYPE_FIT: /* Flattened image tree */
if (CONFIG(PAYLOAD_FIT_SUPPORT)) {
fit_payload(payload, buffer);
fit_payload(payload, mapping);
break;
} /* else fall-through */
default:
Expand All @@ -200,8 +174,7 @@ void payload_load(void)
break;
}

if (mapping)
cbfs_unmap(mapping);
cbfs_unmap(mapping);
out:
if (prog_entry(payload) == NULL)
die_with_post_code(POST_INVALID_ROM, "Payload not loaded.\n");
Expand Down
12 changes: 6 additions & 6 deletions src/lib/thread.c
Expand Up @@ -284,14 +284,14 @@ int thread_run(struct thread_handle *handle, enum cb_err (*func)(void *), void *

if (!thread_can_yield(current)) {
printk(BIOS_ERR,
"thread_run() called from non-yielding context!\n");
"ERROR: %s() called from non-yielding context!\n", __func__);
return -1;
}

t = get_free_thread();

if (t == NULL) {
printk(BIOS_ERR, "thread_run() No more threads!\n");
printk(BIOS_ERR, "ERROR: %s: No more threads!\n", __func__);
return -1;
}

Expand Down Expand Up @@ -319,14 +319,14 @@ int thread_run_until(struct thread_handle *handle, enum cb_err (*func)(void *),

if (!thread_can_yield(current)) {
printk(BIOS_ERR,
"thread_run() called from non-yielding context!\n");
"ERROR: %s() called from non-yielding context!\n", __func__);
return -1;
}

t = get_free_thread();

if (t == NULL) {
printk(BIOS_ERR, "thread_run() No more threads!\n");
printk(BIOS_ERR, "ERROR: %s: No more threads!\n", __func__);
return -1;
}

Expand Down Expand Up @@ -398,10 +398,10 @@ enum cb_err thread_join(struct thread_handle *handle)
if (handle->state == THREAD_UNINITIALIZED)
return CB_ERR_ARG;

stopwatch_init(&sw);

printk(BIOS_SPEW, "waiting for thread\n");

stopwatch_init(&sw);

while (handle->state != THREAD_DONE)
assert(thread_yield() == 0);

Expand Down
8 changes: 8 additions & 0 deletions src/mainboard/amd/gardenia/Kconfig
Expand Up @@ -34,4 +34,12 @@ config STONEYRIDGE_LEGACY_FREE
bool
default y

if !EM100
config EFS_SPI_READ_MODE
default 4 # Dual IO (1-2-2)

config EFS_SPI_SPEED
default 0 # 66MHz
endif

endif # BOARD_AMD_GARDENIA
2 changes: 2 additions & 0 deletions src/mainboard/amd/majolica/chromeos.c
@@ -1,7 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <bootmode.h>
#include <boot/coreboot_tables.h>
#include <gpio.h>
#include <types.h>
#include <vendorcode/google/chromeos/chromeos.h>

void fill_lb_gpios(struct lb_gpios *gpios)
Expand Down
8 changes: 8 additions & 0 deletions src/mainboard/amd/padmelon/Kconfig
Expand Up @@ -58,4 +58,12 @@ config HWM_PORT
If changed, make sure fan_init.c IO window setting. The HWM
(Hardware Monitor) is used for fan control within padmelon.

if !EM100
config EFS_SPI_READ_MODE
default 4 # Dual IO (1-2-2)

config EFS_SPI_SPEED
default 0 # 66MHz
endif

endif # BOARD_AMD_PADMELON
Expand Up @@ -85,7 +85,7 @@ void mainboard_fill_pei_data(struct pei_data *pei_data)
.mchbar = CONFIG_FIXED_MCHBAR_MMIO_BASE,
.dmibar = CONFIG_FIXED_DMIBAR_MMIO_BASE,
.epbar = CONFIG_FIXED_EPBAR_MMIO_BASE,
.pciexbar = CONFIG_MMCONF_BASE_ADDRESS,
.pciexbar = CONFIG_ECAM_MMCONF_BASE_ADDRESS,
.smbusbar = CONFIG_FIXED_SMBUS_IO_BASE,
.wdbbar = 0x4000000,
.wdbsize = 0x1000,
Expand Down
3 changes: 1 addition & 2 deletions src/mainboard/emulation/qemu-i440fx/Kconfig
Expand Up @@ -3,7 +3,7 @@ if BOARD_EMULATION_QEMU_X86_I440FX
config BOARD_SPECIFIC_OPTIONS
def_bool y
select CPU_QEMU_X86
select NO_MMCONF_SUPPORT
select NO_ECAM_MMCONF_SUPPORT
select SOUTHBRIDGE_INTEL_I82371EB
select HAVE_OPTION_TABLE
select HAVE_CMOS_DEFAULT
Expand All @@ -21,7 +21,6 @@ config VBOOT
select VBOOT_MUST_REQUEST_DISPLAY
select VBOOT_STARTS_IN_BOOTBLOCK
select VBOOT_VBNV_CMOS
select VBOOT_NO_BOARD_SUPPORT
select GBB_FLAG_DISABLE_LID_SHUTDOWN
select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC
select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC
Expand Down
6 changes: 3 additions & 3 deletions src/mainboard/emulation/qemu-i440fx/Makefile.inc
@@ -1,10 +1,10 @@
romstage-y += fw_cfg.c
romstage-y += memmap.c

postcar-y += fw_cfg.c
postcar-y += memmap.c
postcar-y += exit_car.S

ramstage-y += fw_cfg.c
ramstage-y += memmap.c
ramstage-y += northbridge.c

all-y += fw_cfg.c
all-y += bootmode.c
29 changes: 29 additions & 0 deletions src/mainboard/emulation/qemu-i440fx/bootmode.c
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <bootmode.h>
#include <console/console.h>
#include "fw_cfg.h"

/*
* Enable recovery mode with fw_cfg option to qemu:
* -fw_cfg name=opt/cros/recovery,string=1
*/
int get_recovery_mode_switch(void)
{
FWCfgFile f;

if (!fw_cfg_check_file(&f, "opt/cros/recovery")) {
uint8_t rec_mode;
if (f.size != 1) {
printk(BIOS_ERR, "opt/cros/recovery invalid size %d\n", f.size);
return 0;
}
fw_cfg_get(f.select, &rec_mode, f.size);
if (rec_mode == '1') {
printk(BIOS_INFO, "Recovery is enabled.\n");
return 1;
}
}

return 0;
}
2 changes: 1 addition & 1 deletion src/mainboard/emulation/qemu-i440fx/fw_cfg.c
Expand Up @@ -133,7 +133,7 @@ int fw_cfg_max_cpus(void)
unsigned short max_cpus;

if (!fw_cfg_present())
return -1;
return 0;

fw_cfg_get(FW_CFG_MAX_CPUS, &max_cpus, sizeof(max_cpus));
return max_cpus;
Expand Down
4 changes: 2 additions & 2 deletions src/mainboard/emulation/qemu-i440fx/northbridge.c
Expand Up @@ -265,11 +265,11 @@ static void cpu_bus_init(struct device *dev)

static void cpu_bus_scan(struct device *bus)
{
int max_cpus = fw_cfg_max_cpus();
unsigned int max_cpus = fw_cfg_max_cpus();
struct device *cpu;
int i;

if (max_cpus < 0)
if (max_cpus == 0)
return;
/*
* Do not install more CPUs than supported by coreboot.
Expand Down
5 changes: 2 additions & 3 deletions src/mainboard/emulation/qemu-q35/Kconfig
Expand Up @@ -21,7 +21,6 @@ config VBOOT
select VBOOT_MUST_REQUEST_DISPLAY
select VBOOT_STARTS_IN_BOOTBLOCK
select VBOOT_VBNV_CMOS
select VBOOT_NO_BOARD_SUPPORT if !CHROMEOS
select GBB_FLAG_DISABLE_LID_SHUTDOWN
select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC
select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC
Expand Down Expand Up @@ -57,10 +56,10 @@ config MAINBOARD_DIR
config MAINBOARD_PART_NUMBER
default "QEMU x86 q35/ich9"

config MMCONF_BASE_ADDRESS
config ECAM_MMCONF_BASE_ADDRESS
default 0xb0000000

config MMCONF_BUS_NUMBER
config ECAM_MMCONF_BUS_NUMBER
int
default 256

Expand Down
8 changes: 3 additions & 5 deletions src/mainboard/emulation/qemu-q35/Makefile.inc
@@ -1,23 +1,21 @@
bootblock-y += bootblock.c
bootblock-y += memmap.c

romstage-y += ../qemu-i440fx/fw_cfg.c
romstage-y += ../qemu-i440fx/memmap.c
romstage-y += memmap.c

postcar-y += ../qemu-i440fx/fw_cfg.c
postcar-y += ../qemu-i440fx/memmap.c
postcar-y += ../qemu-i440fx/exit_car.S
postcar-y += memmap.c

ramstage-y += ../qemu-i440fx/fw_cfg.c
ramstage-y += ../qemu-i440fx/memmap.c
ramstage-y += ../qemu-i440fx/northbridge.c
ramstage-y += memmap.c
ramstage-y += cpu.c

verstage-$(CONFIG_CHROMEOS) += chromeos.c
verstage-$(CONFIG_CHROMEOS) += ../qemu-i440fx/fw_cfg.c
all-y += ../qemu-i440fx/fw_cfg.c
all-y += ../qemu-i440fx/bootmode.c

ramstage-$(CONFIG_CHROMEOS) += chromeos.c

smm-y += smi.c
Expand Down
4 changes: 2 additions & 2 deletions src/mainboard/emulation/qemu-q35/bootblock.c
Expand Up @@ -11,12 +11,12 @@ static void bootblock_northbridge_init(void)
{
/*
* The "io" variant of the config access is explicitly used to
* setup the PCIEXBAR because CONFIG(MMCONF_SUPPORT) is set to
* setup the PCIEXBAR because CONFIG(ECAM_MMCONF_SUPPORT) is set to
* to true. That way all subsequent non-explicit config accesses use
* MCFG. This code also assumes that bootblock_northbridge_init() is
* the first thing called in the non-asm boot block code. The final
* assumption is that no assembly code is using the
* CONFIG(MMCONF_SUPPORT) option to do PCI config accesses.
* CONFIG(ECAM_MMCONF_SUPPORT) option to do PCI config accesses.
*
* The PCIEXBAR is assumed to live in the memory mapped IO space under
* 4GiB.
Expand Down
40 changes: 9 additions & 31 deletions src/mainboard/emulation/qemu-q35/chromeos.c
@@ -1,9 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <bootmode.h>
#include <boot/coreboot_tables.h>
#include <console/console.h>
#include <types.h>
#include <vendorcode/google/chromeos/chromeos.h>
#include "../qemu-i440fx/fw_cfg.h"

void fill_lb_gpios(struct lb_gpios *gpios)
{
Expand All @@ -16,35 +16,6 @@ void fill_lb_gpios(struct lb_gpios *gpios)
lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
}

int get_write_protect_state(void)
{
return 0;
}

/*
* Enable recovery mode with fw_cfg option to qemu:
* -fw_cfg name=opt/cros/recovery,string=1
*/
int get_recovery_mode_switch(void)
{
FWCfgFile f;

if (!fw_cfg_check_file(&f, "opt/cros/recovery")) {
uint8_t rec_mode;
if (f.size != 1) {
printk(BIOS_ERR, "opt/cros/recovery invalid size %d\n", f.size);
return 0;
}
fw_cfg_get(f.select, &rec_mode, f.size);
if (rec_mode == '1') {
printk(BIOS_INFO, "Recovery is enabled.\n");
return 1;
}
}

return 0;
}

static const struct cros_gpio cros_gpios[] = {
CROS_GPIO_REC_AL(CROS_GPIO_VIRTUAL, "QEMU"),
};
Expand All @@ -53,3 +24,10 @@ void mainboard_chromeos_acpi_generate(void)
{
chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
}

int get_ec_is_trusted(void)
{
/* Do not have a Chrome EC involved in entering recovery mode;
Always return trusted. */
return 1;
}
4 changes: 2 additions & 2 deletions src/mainboard/emulation/qemu-q35/memmap.c
Expand Up @@ -14,7 +14,7 @@

static uint32_t encode_pciexbar_length(void)
{
switch (CONFIG_MMCONF_BUS_NUMBER) {
switch (CONFIG_ECAM_MMCONF_BUS_NUMBER) {
case 256: return 0 << 1;
case 128: return 1 << 1;
case 64: return 2 << 1;
Expand All @@ -24,7 +24,7 @@ static uint32_t encode_pciexbar_length(void)

uint32_t make_pciexbar(void)
{
return CONFIG_MMCONF_BASE_ADDRESS | encode_pciexbar_length() | 1;
return CONFIG_ECAM_MMCONF_BASE_ADDRESS | encode_pciexbar_length() | 1;
}

/* Check that MCFG is active. If it's not, QEMU was started for machine PC */
Expand Down
3 changes: 0 additions & 3 deletions src/mainboard/facebook/fbg1701/acpi_tables.c
Expand Up @@ -15,9 +15,6 @@ void mainboard_fill_gnvs(struct global_nvs *gnvs)
gnvs->s5u0 = 0;
gnvs->s5u1 = 0;

/* Disable DPTF */
gnvs->dpte = 0;

/* PMIC is configured in I2C1, hide it for the OS */
struct device_nvs *dev_nvs = acpi_get_device_nvs();
dev_nvs->lpss_en[LPSS_NVS_I2C2] = 0;
Expand Down
6 changes: 6 additions & 0 deletions src/mainboard/google/asurada/chromeos.c
Expand Up @@ -40,3 +40,9 @@ int tis_plat_irq_status(void)
{
return gpio_eint_poll(GPIO_H1_AP_INT);
}

int get_ec_is_trusted(void)
{
/* EC is trusted if not in RW. This is active low. */
return !!gpio_get(GPIO_EC_IN_RW);
}
70 changes: 2 additions & 68 deletions src/mainboard/google/asurada/mainboard.c
Expand Up @@ -142,72 +142,6 @@ static bool configure_display(void)
return true;
}

static void configure_emmc(void)
{
void *gpio_base = (void *)IOCFG_TL_BASE;
int i;

const gpio_t emmc_pu_pin[] = {
GPIO(MSDC0_DAT0), GPIO(MSDC0_DAT1),
GPIO(MSDC0_DAT2), GPIO(MSDC0_DAT3),
GPIO(MSDC0_DAT4), GPIO(MSDC0_DAT5),
GPIO(MSDC0_DAT6), GPIO(MSDC0_DAT7),
GPIO(MSDC0_CMD), GPIO(MSDC0_RSTB),
};

const gpio_t emmc_pd_pin[] = {
GPIO(MSDC0_DSL), GPIO(MSDC0_CLK),
};

for (i = 0; i < ARRAY_SIZE(emmc_pu_pin); i++)
gpio_set_pull(emmc_pu_pin[i], GPIO_PULL_ENABLE, GPIO_PULL_UP);

for (i = 0; i < ARRAY_SIZE(emmc_pd_pin); i++)
gpio_set_pull(emmc_pd_pin[i], GPIO_PULL_ENABLE, GPIO_PULL_DOWN);

/* set eMMC cmd/dat/clk/ds/rstb pins driving to 10mA */
clrsetbits32(gpio_base, MSDC0_DRV_MASK, MSDC0_DRV_VALUE);

mtk_emmc_early_init((void *)MSDC0_BASE, (void *)MSDC0_TOP_BASE);
}

static void configure_sdcard(void)
{
void *gpio_base = (void *)IOCFG_RM_BASE;
void *gpio_mode0_base = (void *)MSDC1_GPIO_MODE0_BASE;
void *gpio_mode1_base = (void *)MSDC1_GPIO_MODE1_BASE;
uint8_t enable = 1;
int i;

const gpio_t sdcard_pu_pin[] = {
GPIO(MSDC1_DAT0), GPIO(MSDC1_DAT1),
GPIO(MSDC1_DAT2), GPIO(MSDC1_DAT3),
GPIO(MSDC1_CMD),
};

const gpio_t sdcard_pd_pin[] = {
GPIO(MSDC1_CLK),
};

for (i = 0; i < ARRAY_SIZE(sdcard_pu_pin); i++)
gpio_set_pull(sdcard_pu_pin[i], GPIO_PULL_ENABLE, GPIO_PULL_UP);

for (i = 0; i < ARRAY_SIZE(sdcard_pd_pin); i++)
gpio_set_pull(sdcard_pd_pin[i], GPIO_PULL_ENABLE, GPIO_PULL_DOWN);

/* set sdcard cmd/dat/clk pins driving to 8mA */
clrsetbits32(gpio_base, MSDC1_DRV_MASK, MSDC1_DRV_VALUE);

/* set sdcard dat2/dat0/dat3/cmd/clk pins to msdc1 mode */
clrsetbits32(gpio_mode0_base, MSDC1_GPIO_MODE0_MASK, MSDC1_GPIO_MODE0_VALUE);

/* set sdcard dat1 pin to msdc1 mode */
clrsetbits32(gpio_mode1_base, MSDC1_GPIO_MODE1_MASK, MSDC1_GPIO_MODE1_VALUE);

mainboard_enable_regulator(MTK_REGULATOR_VCC, enable);
mainboard_enable_regulator(MTK_REGULATOR_VCCQ, enable);
}

static void configure_audio(void)
{
/* Audio PWR */
Expand All @@ -222,8 +156,8 @@ static void configure_audio(void)

static void mainboard_init(struct device *dev)
{
configure_emmc();
configure_sdcard();
mtk_msdc_configure_emmc(true);
mtk_msdc_configure_sdcard();
configure_audio();
setup_usb_host();

Expand Down
18 changes: 16 additions & 2 deletions src/mainboard/google/auron/chromeos.c
@@ -1,12 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <bootmode.h>
#include <boot/coreboot_tables.h>
#include <types.h>
#include <vendorcode/google/chromeos/chromeos.h>
#include <soc/chromeos.h>
#include <southbridge/intel/lynxpoint/lp_gpio.h>

/* SPI Write protect is GPIO 16 */
#define CROS_WP_GPIO 58
#include "onboard.h"

/* EC_IN_RW is GPIO 25 in samus and 14 otherwise */
#if CONFIG(BOARD_GOOGLE_SAMUS)
#define EC_IN_RW_GPIO 25
#else
#define EC_IN_RW_GPIO 14
#endif

void fill_lb_gpios(struct lb_gpios *gpios)
{
Expand All @@ -32,3 +40,9 @@ void mainboard_chromeos_acpi_generate(void)
{
chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
}

int get_ec_is_trusted(void)
{
/* EC is trusted if not in RW. */
return !get_gpio(EC_IN_RW_GPIO);
}
1 change: 0 additions & 1 deletion src/mainboard/google/auron/ec.c
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <vendorcode/google/chromeos/chromeos.h>
#include <console/console.h>
#include <ec/google/chromeec/ec.h>
#include "ec.h"
Expand Down
9 changes: 9 additions & 0 deletions src/mainboard/google/auron/onboard.h
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef AURON_ONBOARD_H
#define AURON_ONBOARD_H

/* SPI Write protect is GPIO 58 */
#define CROS_WP_GPIO 58

#endif
26 changes: 21 additions & 5 deletions src/mainboard/google/beltino/chromeos.c
Expand Up @@ -6,10 +6,9 @@
#include <device/device.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include <southbridge/intel/common/gpio.h>
#include <types.h>
#include <vendorcode/google/chromeos/chromeos.h>

#define GPIO_SPI_WP 58
#define GPIO_REC_MODE 12
#include "onboard.h"

#define FLAG_SPI_WP 0
#define FLAG_REC_MODE 1
Expand All @@ -26,6 +25,16 @@ void fill_lb_gpios(struct lb_gpios *gpios)
lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
}

static bool raw_write_protect_state(void)
{
return get_gpio(GPIO_SPI_WP);
}

static bool raw_recovery_mode_switch(void)
{
return !get_gpio(GPIO_REC_MODE);
}

int get_write_protect_state(void)
{
const pci_devfn_t dev = PCI_DEV(0, 0x1f, 2);
Expand All @@ -44,11 +53,11 @@ void init_bootmode_straps(void)
const pci_devfn_t dev = PCI_DEV(0, 0x1f, 2);

/* Write Protect: GPIO58 = GPIO_SPI_WP, active high */
if (get_gpio(GPIO_SPI_WP))
if (raw_write_protect_state())
flags |= (1 << FLAG_SPI_WP);

/* Recovery: GPIO12 = RECOVERY_L, active low */
if (!get_gpio(GPIO_REC_MODE))
if (raw_recovery_mode_switch())
flags |= (1 << FLAG_REC_MODE);

/* Developer: Virtual */
Expand All @@ -65,3 +74,10 @@ void mainboard_chromeos_acpi_generate(void)
{
chromeos_acpi_gpio_generate(cros_gpios, ARRAY_SIZE(cros_gpios));
}

int get_ec_is_trusted(void)
{
/* Do not have a Chrome EC involved in entering recovery mode;
Always return trusted. */
return 1;
}
6 changes: 6 additions & 0 deletions src/mainboard/google/beltino/onboard.h
Expand Up @@ -16,6 +16,12 @@
/* WLAN wake is GPIO 10 */
#define WLAN_WAKE_GPIO 10

/* Recovery: GPIO12 = RECOVERY_L, active low */
#define GPIO_REC_MODE 12

/* Write Protect: GPIO58 = GPIO_SPI_WP, active high */
#define GPIO_SPI_WP 58

/* IT8772F defs */
#define IT8772F_BASE 0x2e
#define IT8772F_SERIAL_DEV PNP_DEV(IT8772F_BASE, IT8772F_SP1)
Expand Down
10 changes: 9 additions & 1 deletion src/mainboard/google/brya/Kconfig
Expand Up @@ -14,12 +14,15 @@ config BOARD_GOOGLE_BRYA_COMMON
def_bool y
select BOARD_ROMSIZE_KB_32768
select DRIVERS_GENERIC_ALC1015
select DRIVERS_GENERIC_GPIO_KEYS
select DRIVERS_GENERIC_MAX98357A
select DRIVERS_I2C_GENERIC
select DRIVERS_I2C_HID
select DRIVERS_I2C_NAU8825
select DRIVERS_I2C_SX9324
select DRIVERS_INTEL_DPTF
select PMC_IPC_ACPI_INTERFACE
select DRIVERS_INTEL_DPTF_SUPPORTS_TPCH
select DRIVERS_INTEL_PMC
select DRIVERS_INTEL_SOUNDWIRE
select DRIVERS_INTEL_USB4_RETIMER
Expand Down Expand Up @@ -54,7 +57,6 @@ config BASEBOARD_DIR
config CHROMEOS
select EC_GOOGLE_CHROMEEC_SWITCHES
select HAS_RECOVERY_MRC_CACHE
select VBOOT_LID_SWITCH

config CHROMEOS_WIFI_SAR
bool "Enable SAR options for Chrome OS build"
Expand Down Expand Up @@ -100,6 +102,7 @@ config MAINBOARD_PART_NUMBER
default "Taeko" if BOARD_GOOGLE_TAEKO
default "Felwinter" if BOARD_GOOGLE_FELWINTER
default "Anahera" if BOARD_GOOGLE_ANAHERA
default "Vell" if BOARD_GOOGLE_VELL

config VARIANT_DIR
default "brya0" if BOARD_GOOGLE_BRYA0
Expand All @@ -111,6 +114,11 @@ config VARIANT_DIR
default "taeko" if BOARD_GOOGLE_TAEKO
default "felwinter" if BOARD_GOOGLE_FELWINTER
default "anahera" if BOARD_GOOGLE_ANAHERA
default "vell" if BOARD_GOOGLE_VELL

config VBOOT
select VBOOT_EARLY_EC_SYNC
select VBOOT_LID_SWITCH

config DIMM_SPD_SIZE
default 512
Expand Down
8 changes: 8 additions & 0 deletions src/mainboard/google/brya/Kconfig.name
Expand Up @@ -12,6 +12,7 @@ config BOARD_GOOGLE_BRYA0
config BOARD_GOOGLE_BRASK
bool "-> Brask"
select BOARD_GOOGLE_BASEBOARD_BRASK
select DRIVERS_GENESYSLOGIC_GL9755
select SOC_INTEL_CRASHLOG
select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES

Expand All @@ -26,6 +27,7 @@ config BOARD_GOOGLE_GIMBLE
bool "-> Gimble"
select BOARD_GOOGLE_BASEBOARD_BRYA
select CHROMEOS_DSM_CALIB if CHROMEOS
select CHROMEOS_DSM_PARAM_FILE_NAME if CHROMEOS
select DRIVERS_I2C_MAX98390

config BOARD_GOOGLE_REDRIX
Expand All @@ -40,6 +42,7 @@ config BOARD_GOOGLE_REDRIX
select DRIVERS_GENESYSLOGIC_GL9755
select DRIVERS_GFX_GENERIC
select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES
select HAVE_WWAN_POWER_SEQUENCE

config BOARD_GOOGLE_KANO
bool "-> Kano"
Expand All @@ -58,10 +61,15 @@ config BOARD_GOOGLE_TAEKO
config BOARD_GOOGLE_FELWINTER
bool "-> Felwinter"
select BOARD_GOOGLE_BASEBOARD_BRYA
select DRIVERS_GENERIC_GPIO_KEYS

config BOARD_GOOGLE_ANAHERA
bool "-> Anahera"
select BOARD_GOOGLE_BASEBOARD_BRYA
select DRIVERS_GENESYSLOGIC_GL9763E
select DRIVERS_GFX_GENERIC
select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES

config BOARD_GOOGLE_VELL
bool "-> Vell"
select BOARD_GOOGLE_BASEBOARD_BRYA
8 changes: 8 additions & 0 deletions src/mainboard/google/brya/chromeos.c
Expand Up @@ -2,8 +2,10 @@

#include <baseboard/gpio.h>
#include <baseboard/variants.h>
#include <bootmode.h>
#include <boot/coreboot_tables.h>
#include <gpio.h>
#include <types.h>
#include <vendorcode/google/chromeos/chromeos.h>

void fill_lb_gpios(struct lb_gpios *gpios)
Expand All @@ -29,3 +31,9 @@ void mainboard_chromeos_acpi_generate(void)
gpios = variant_cros_gpios(&num);
chromeos_acpi_gpio_generate(gpios, num);
}

int get_ec_is_trusted(void)
{
/* EC is trusted if not in RW. */
return !gpio_get(GPIO_EC_IN_RW);
}
1 change: 0 additions & 1 deletion src/mainboard/google/brya/variants/anahera/gpio.c
Expand Up @@ -4,7 +4,6 @@
#include <baseboard/variants.h>
#include <commonlib/helpers.h>
#include <soc/gpio.h>
#include <vendorcode/google/chromeos/chromeos.h>

/* Pad configuration in ramstage */
static const struct pad_config override_gpio_table[] = {
Expand Down
11 changes: 11 additions & 0 deletions src/mainboard/google/brya/variants/anahera/overridetree.cb
Expand Up @@ -22,6 +22,17 @@ fw_config
end
end
chip soc/intel/alderlake
# This disables autonomous GPIO power management, otherwise
# old cr50 FW only supports short pulses; need to clarify
# the minimum PCH IRQ pulse width with Intel, b/180111628
register "gpio_override_pm" = "1"
register "gpio_pm[COMM_0]" = "0"
register "gpio_pm[COMM_1]" = "0"
register "gpio_pm[COMM_2]" = "0"
register "gpio_pm[COMM_3]" = "0"
register "gpio_pm[COMM_4]" = "0"
register "gpio_pm[COMM_5]" = "0"

# Intel Common SoC Config
#+-------------------+---------------------------+
#| Field | Value |
Expand Down
Expand Up @@ -68,6 +68,9 @@ chip soc/intel/alderlake
register "PchHdaIDispLinkFrequency" = "HDA_LINKFREQ_96MHZ"
register "PchHdaIDispCodecEnable" = "1"

# FIVR RFI Spread Spectrum 1.5%
register "FivrSpreadSpectrum" = "FIVR_SS_1_5"

# Intel Common SoC Config
#+-------------------+---------------------------+
#| Field | Value |
Expand Down