186 changes: 173 additions & 13 deletions src/ec/google/chromeec/ec_commands.h
Expand Up @@ -9,10 +9,6 @@
#include <stdint.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef CHROMIUM_EC
/*
* CHROMIUM_EC is defined by the Makefile system of Chromium EC repository.
Expand Down Expand Up @@ -70,6 +66,10 @@ extern "C" {

#endif /* __KERNEL__ */

#ifdef __cplusplus
extern "C" {
#endif

/*
* Current version of this protocol
*
Expand Down Expand Up @@ -422,6 +422,50 @@ extern "C" {
*/
#define EC_ACPI_MEM_USB_PORT_POWER 0x13

/*
* USB Retimer firmware update.
* Read:
* Result of last operation AP requested
* Write:
* bits[3:0]: USB-C port number
* bits[7:4]: Operation requested by AP
*
* NDA (no device attached) case:
* To update retimer firmware, AP needs set up TBT Alt mode.
* AP requests operations in this sequence:
* 1. Get port information about which ports support retimer firmware update.
* In the query result, each bit represents one port.
* 2. Get current MUX mode, it's NDA.
* 3. Suspend specified PD port's task.
* 4. AP requests EC to enter USB mode -> enter Safe mode -> enter TBT mode ->
* update firmware -> disconnect MUX -> resume PD task.
*
* DA (device attached) cases:
* Retimer firmware update is not supported in DA cases.
* 1. Get port information about which ports support retimer firmware update
* 2. Get current MUX mode, it's DA.
* 3. AP continues. No more retimer firmware update activities.
*
*/
#define EC_ACPI_MEM_USB_RETIMER_FW_UPDATE 0x14

#define USB_RETIMER_FW_UPDATE_OP_SHIFT 4
#define USB_RETIMER_FW_UPDATE_ERR 0xfe
#define USB_RETIMER_FW_UPDATE_INVALID_MUX 0xff
/* Retimer firmware update operations */
#define USB_RETIMER_FW_UPDATE_QUERY_PORT 0 /* Which ports has retimer */
#define USB_RETIMER_FW_UPDATE_SUSPEND_PD 1 /* Suspend PD port */
#define USB_RETIMER_FW_UPDATE_RESUME_PD 2 /* Resume PD port */
#define USB_RETIMER_FW_UPDATE_GET_MUX 3 /* Read current USB MUX */
#define USB_RETIMER_FW_UPDATE_SET_USB 4 /* Set MUX to USB mode */
#define USB_RETIMER_FW_UPDATE_SET_SAFE 5 /* Set MUX to Safe mode */
#define USB_RETIMER_FW_UPDATE_SET_TBT 6 /* Set MUX to TBT mode */
#define USB_RETIMER_FW_UPDATE_DISCONNECT 7 /* Set MUX to disconnect */

#define EC_ACPI_MEM_USB_RETIMER_PORT(x) ((x) & 0x0f)
#define EC_ACPI_MEM_USB_RETIMER_OP(x) \
(((x) & 0xf0) >> USB_RETIMER_FW_UPDATE_OP_SHIFT)

/*
* ACPI addresses 0x20 - 0xff map to EC_MEMMAP offset 0x00 - 0xdf. This data
* is read-only from the AP. Added in EC_ACPI_MEM_VERSION 2.
Expand Down Expand Up @@ -592,13 +636,13 @@ enum ec_status {
BUILD_ASSERT(sizeof(enum ec_status) == sizeof(uint16_t));

/*
* Host event codes. Note these are 1-based, not 0-based, because ACPI query
* EC command uses code 0 to mean "no event pending". We explicitly specify
* each value in the enum listing so they won't change if we delete/insert an
* item or rearrange the list (it needs to be stable across platforms, not
* just within a single compiled instance).
* Host event codes. ACPI query EC command uses code 0 to mean "no event
* pending". We explicitly specify each value in the enum listing so they won't
* change if we delete/insert an item or rearrange the list (it needs to be
* stable across platforms, not just within a single compiled instance).
*/
enum host_event_code {
EC_HOST_EVENT_NONE = 0,
EC_HOST_EVENT_LID_CLOSED = 1,
EC_HOST_EVENT_LID_OPEN = 2,
EC_HOST_EVENT_POWER_BUTTON = 3,
Expand Down Expand Up @@ -1772,7 +1816,15 @@ struct ec_response_flash_region_info {
uint32_t size;
} __ec_align4;

/* Read/write VbNvContext */
/*
* Read/write VbNvContext
*
* Deprecated as of February 2021. No current devices use VBNV in EC
* BBRAM anymore, so this is guaranteed to fail.
*
* TODO(b/178689388): remove from this header once no external
* dependencies reference these constants.
*/
#define EC_CMD_VBNV_CONTEXT 0x0017
#define EC_VER_VBNV_CONTEXT 1
#define EC_VBNV_BLOCK_SIZE 16
Expand Down Expand Up @@ -2617,6 +2669,7 @@ enum motionsensor_chip {
MOTIONSENSE_CHIP_LIS2DS = 23,
MOTIONSENSE_CHIP_BMI260 = 24,
MOTIONSENSE_CHIP_ICM426XX = 25,
MOTIONSENSE_CHIP_ICM42607 = 26,
MOTIONSENSE_CHIP_MAX,
};

Expand Down Expand Up @@ -2715,6 +2768,8 @@ struct ec_motion_sense_activity {
#define MOTIONSENSE_SENSOR_FLAG_TABLET_MODE BIT(3)
#define MOTIONSENSE_SENSOR_FLAG_ODR BIT(4)

#define MOTIONSENSE_SENSOR_FLAG_BYPASS_FIFO BIT(7)

/*
* Send this value for the data element to only perform a read. If you
* send any other value, the EC will interpret it as data to set and will
Expand Down Expand Up @@ -3732,6 +3787,9 @@ enum ec_mkbp_event {
/* New online calibration values are available. */
EC_MKBP_EVENT_ONLINE_CALIBRATION = 11,

/* Peripheral device charger event */
EC_MKBP_EVENT_PCHG = 12,

/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
};
Expand Down Expand Up @@ -4375,7 +4433,7 @@ struct ec_response_power_info_v1 {
#define EC_I2C_STATUS_ERROR (EC_I2C_STATUS_NAK | EC_I2C_STATUS_TIMEOUT)

struct ec_params_i2c_passthru_msg {
uint16_t addr_flags; /* I2C slave address and flags */
uint16_t addr_flags; /* I2C peripheral address and flags */
uint16_t len; /* Number of bytes to read or write */
} __ec_align2;

Expand Down Expand Up @@ -5837,6 +5895,7 @@ enum cbi_data_tag {
CBI_TAG_PCB_SUPPLIER = 7, /* uint32_t or smaller */
/* Second Source Factory Cache */
CBI_TAG_SSFC = 8, /* uint32_t bit field */
CBI_TAG_REWORK_ID = 9, /* uint64_t or smaller */
CBI_TAG_COUNT,
};

Expand Down Expand Up @@ -6588,6 +6647,7 @@ enum tcpc_cc_polarity {

#define PD_STATUS_EVENT_SOP_DISC_DONE BIT(0)
#define PD_STATUS_EVENT_SOP_PRIME_DISC_DONE BIT(1)
#define PD_STATUS_EVENT_HARD_RESET BIT(2)

/*
* Encode and decode for BCD revision response
Expand Down Expand Up @@ -6743,6 +6803,11 @@ struct ec_response_pchg {
uint32_t error; /* enum pchg_error */
uint8_t state; /* enum pchg_state state */
uint8_t battery_percentage;
uint8_t unused0;
uint8_t unused1;
/* Fields added in version 1 */
uint32_t fw_version;
uint32_t dropped_event_count;
} __ec_align2;

enum pchg_state {
Expand All @@ -6752,10 +6817,20 @@ enum pchg_state {
PCHG_STATE_INITIALIZED,
/* Charger is enabled and ready to detect a device. */
PCHG_STATE_ENABLED,
/* Device is detected in proximity. */
/* Device is in proximity. */
PCHG_STATE_DETECTED,
/* Device is being charged. */
PCHG_STATE_CHARGING,
/* Device is fully charged. It implies DETECTED (& not charging). */
PCHG_STATE_FULL,
/* In download (a.k.a. firmware update) mode */
PCHG_STATE_DOWNLOAD,
/* In download mode. Ready for receiving data. */
PCHG_STATE_DOWNLOADING,
/* Device is ready for data communication. */
PCHG_STATE_CONNECTED,
/* Put no more entry below */
PCHG_STATE_COUNT,
};

#define EC_PCHG_STATE_TEXT { \
Expand All @@ -6764,8 +6839,93 @@ enum pchg_state {
[PCHG_STATE_ENABLED] = "ENABLED", \
[PCHG_STATE_DETECTED] = "DETECTED", \
[PCHG_STATE_CHARGING] = "CHARGING", \
[PCHG_STATE_FULL] = "FULL", \
[PCHG_STATE_DOWNLOAD] = "DOWNLOAD", \
[PCHG_STATE_DOWNLOADING] = "DOWNLOADING", \
[PCHG_STATE_CONNECTED] = "CONNECTED", \
}

/**
* Update firmware of peripheral chip
*/
#define EC_CMD_PCHG_UPDATE 0x0136

/* Port number is encoded in bit[28:31]. */
#define EC_MKBP_PCHG_PORT_SHIFT 28
/* Utility macro for converting MKBP event to port number. */
#define EC_MKBP_PCHG_EVENT_TO_PORT(e) (((e) >> EC_MKBP_PCHG_PORT_SHIFT) & 0xf)
/* Utility macro for extracting event bits. */
#define EC_MKBP_PCHG_EVENT_MASK(e) ((e) \
& GENMASK(EC_MKBP_PCHG_PORT_SHIFT-1, 0))

#define EC_MKBP_PCHG_UPDATE_OPENED BIT(0)
#define EC_MKBP_PCHG_WRITE_COMPLETE BIT(1)
#define EC_MKBP_PCHG_UPDATE_CLOSED BIT(2)
#define EC_MKBP_PCHG_UPDATE_ERROR BIT(3)

enum ec_pchg_update_cmd {
/* Reset chip to normal mode. */
EC_PCHG_UPDATE_CMD_RESET_TO_NORMAL = 0,
/* Reset and put a chip in update (a.k.a. download) mode. */
EC_PCHG_UPDATE_CMD_OPEN,
/* Write a block of data containing FW image. */
EC_PCHG_UPDATE_CMD_WRITE,
/* Close update session. */
EC_PCHG_UPDATE_CMD_CLOSE,
/* End of commands */
EC_PCHG_UPDATE_CMD_COUNT,
};

struct ec_params_pchg_update {
/* PCHG port number */
uint8_t port;
/* enum ec_pchg_update_cmd */
uint8_t cmd;
/* Padding */
uint8_t reserved0;
uint8_t reserved1;
/* Version of new firmware */
uint32_t version;
/* CRC32 of new firmware */
uint32_t crc32;
/* Address in chip memory where <data> is written to */
uint32_t addr;
/* Size of <data> */
uint32_t size;
/* Partial data of new firmware */
uint8_t data[];
} __ec_align4;

BUILD_ASSERT(EC_PCHG_UPDATE_CMD_COUNT
< BIT(sizeof(((struct ec_params_pchg_update *)0)->cmd)*8));

struct ec_response_pchg_update {
/* Block size */
uint32_t block_size;
} __ec_align4;


#define EC_CMD_DISPLAY_SOC 0x0137

struct ec_response_display_soc {
int16_t display_soc; /* Display charge in 10ths of a % (1000=100.0%) */
int16_t full_factor; /* Full factor in 10ths of a % (1000=100.0%) */
int16_t shutdown_soc; /* Shutdown SoC in 10ths of a % (1000=100.0%) */
} __ec_align2;


#define EC_CMD_SET_BASE_STATE 0x0138

struct ec_params_set_base_state {
uint8_t cmd; /* enum ec_set_base_state_cmd */
} __ec_align1;

enum ec_set_base_state_cmd {
EC_SET_BASE_STATE_DETACH = 0,
EC_SET_BASE_STATE_ATTACH,
EC_SET_BASE_STATE_RESET,
};

/*****************************************************************************/
/* The command range 0x200-0x2FF is reserved for Rotor. */

Expand Down Expand Up @@ -7168,7 +7328,7 @@ struct ec_response_battery_dynamic_info {
} __ec_align2;

/*
* Control charger chip. Used to control charger chip on the slave.
* Control charger chip. Used to control charger chip on the peripheral.
*/
#define EC_CMD_CHARGER_CONTROL 0x0602

Expand Down
4 changes: 2 additions & 2 deletions src/ec/google/chromeec/ec_i2c.c
Expand Up @@ -239,8 +239,8 @@ int google_chromeec_command(struct chromeec_command *cec_command)

#endif /* CONFIG_EC_GOOGLE_CHROMEEC_I2C_PROTO3 */

u8 google_chromeec_get_event(void)
enum host_event_code google_chromeec_get_event(void)
{
printk(BIOS_ERR, "%s: Not supported.\n", __func__);
return 0;
return EC_HOST_EVENT_NONE;
}
8 changes: 4 additions & 4 deletions src/ec/google/chromeec/ec_lpc.c
Expand Up @@ -461,24 +461,24 @@ static int google_chromeec_data_ready(u16 port)
EC_LPC_CMDR_DATA);
}

u8 google_chromeec_get_event(void)
enum host_event_code google_chromeec_get_event(void)
{
if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
printk(BIOS_ERR, "Timeout waiting for EC ready!\n");
return 0;
return EC_HOST_EVENT_NONE;
}

/* Issue the ACPI query-event command */
write_byte(EC_CMD_ACPI_QUERY_EVENT, EC_LPC_ADDR_ACPI_CMD);

if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
printk(BIOS_ERR, "Timeout waiting for EC QUERY_EVENT!\n");
return 0;
return EC_HOST_EVENT_NONE;
}

if (google_chromeec_data_ready(EC_LPC_ADDR_ACPI_CMD)) {
printk(BIOS_ERR, "Timeout waiting for data ready!\n");
return 0;
return EC_HOST_EVENT_NONE;
}

/* Event (or 0 if none) is returned directly in the data byte */
Expand Down
4 changes: 2 additions & 2 deletions src/ec/google/chromeec/ec_spi.c
Expand Up @@ -100,8 +100,8 @@ int google_chromeec_command(struct chromeec_command *cec_command)
return crosec_command_proto(cec_command, crosec_spi_io, &slave);
}

u8 google_chromeec_get_event(void)
enum host_event_code google_chromeec_get_event(void)
{
printk(BIOS_ERR, "%s: Not supported.\n", __func__);
return 0;
return EC_HOST_EVENT_NONE;
}
2 changes: 1 addition & 1 deletion src/ec/google/chromeec/smihandler.c
Expand Up @@ -37,7 +37,7 @@ static void clear_pending_events(void)
{
struct ec_response_get_next_event mkbp_event;

while (google_chromeec_get_event() != 0)
while (google_chromeec_get_event() != EC_HOST_EVENT_NONE)
;

printk(BIOS_DEBUG, "Clearing pending EC events. Error code EC_RES_UNAVAILABLE(9) is expected.\n");
Expand Down
1 change: 1 addition & 0 deletions src/ec/kontron/kempld/Makefile.inc
Expand Up @@ -2,3 +2,4 @@ bootblock-$(CONFIG_EC_KONTRON_KEMPLD) += early_kempld.c
ramstage-$(CONFIG_EC_KONTRON_KEMPLD) += early_kempld.c
ramstage-$(CONFIG_EC_KONTRON_KEMPLD) += kempld.c
ramstage-$(CONFIG_EC_KONTRON_KEMPLD) += kempld_i2c.c
ramstage-$(CONFIG_EC_KONTRON_KEMPLD) += kempld_gpio.c
11 changes: 10 additions & 1 deletion src/ec/kontron/kempld/chip.h
Expand Up @@ -3,7 +3,15 @@
#ifndef EC_KONTRON_KEMPLD_CHIP_H
#define EC_KONTRON_KEMPLD_CHIP_H

#define KEMPLD_NUM_UARTS 2
#define KEMPLD_NUM_UARTS 2
#define KEMPLD_NUM_GPIOS 16

enum kempld_gpio_mode {
KEMPLD_GPIO_DEFAULT = 0,
KEMPLD_GPIO_INPUT,
KEMPLD_GPIO_OUTPUT_LOW,
KEMPLD_GPIO_OUTPUT_HIGH,
};

enum kempld_uart_io {
KEMPLD_UART_3F8 = 0,
Expand All @@ -26,6 +34,7 @@ struct kempld_uart {

struct ec_kontron_kempld_config {
struct kempld_uart uart[KEMPLD_NUM_UARTS];
enum kempld_gpio_mode gpio[KEMPLD_NUM_GPIOS];
unsigned short i2c_frequency;
};

Expand Down
8 changes: 8 additions & 0 deletions src/ec/kontron/kempld/kempld.c
Expand Up @@ -93,6 +93,14 @@ static void kempld_enable_dev(struct device *const dev)
printk(BIOS_WARNING, "KEMPLD: Spurious device %s.\n", dev_path(dev));
break;
}
} else if (dev->path.type == DEVICE_PATH_GPIO) {
if (dev->path.gpio.id == 0) {
if (kempld_gpio_pads_config(dev) < 0)
printk(BIOS_ERR, "KEMPLD: GPIO configuration failed!\n");
} else {
printk(BIOS_WARNING, "KEMPLD: Spurious GPIO device %s.\n",
dev_path(dev));
}
}
}

Expand Down
71 changes: 71 additions & 0 deletions src/ec/kontron/kempld/kempld_gpio.c
@@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <stdint.h>
#include <arch/io.h>
#include <delay.h>
#include "chip.h"
#include "kempld.h"
#include "kempld_internal.h"

enum kempld_gpio_direction {
KEMPLD_GPIO_DIR_IN = 0,
KEMPLD_GPIO_DIR_OUT = 1
};

static void kempld_gpio_value_set(u8 pin_num, u8 value)
{
const u8 mask = KEMPLD_GPIO_MASK(pin_num);
u8 reg_val = kempld_read8(KEMPLD_GPIO_LVL(pin_num));
reg_val = value ? reg_val | mask : reg_val & ~mask;
kempld_write8(KEMPLD_GPIO_LVL(pin_num), reg_val);
}

static void kempld_gpio_direction_set(u8 pin_num, enum kempld_gpio_direction dir)
{
const u8 mask = KEMPLD_GPIO_MASK(pin_num);
u8 reg_val = kempld_read8(KEMPLD_GPIO_DIR(pin_num));
reg_val = dir == KEMPLD_GPIO_DIR_OUT ? reg_val | mask : reg_val & ~mask;
kempld_write8(KEMPLD_GPIO_DIR(pin_num), reg_val);
}

static int kempld_configure_gpio(u8 pin_num, enum kempld_gpio_mode mode)
{
if (kempld_get_mutex(100) < 0)
return -1;

switch (mode) {
case KEMPLD_GPIO_DEFAULT:
break;

case KEMPLD_GPIO_INPUT:
kempld_gpio_direction_set(pin_num, KEMPLD_GPIO_DIR_IN);
break;

case KEMPLD_GPIO_OUTPUT_LOW:
kempld_gpio_value_set(pin_num, 0);
kempld_gpio_direction_set(pin_num, KEMPLD_GPIO_DIR_OUT);
break;

case KEMPLD_GPIO_OUTPUT_HIGH:
kempld_gpio_value_set(pin_num, 1);
kempld_gpio_direction_set(pin_num, KEMPLD_GPIO_DIR_OUT);
break;
}

kempld_release_mutex();
return 0;
}

int kempld_gpio_pads_config(struct device *dev)
{
const struct ec_kontron_kempld_config *config = dev->chip_info;

if (!config)
return -1;

for (u8 i = 0; i < KEMPLD_NUM_GPIOS; ++i) {
if (kempld_configure_gpio(i, config->gpio[i]) < 0)
return -1;
}
return 0;
}
5 changes: 5 additions & 0 deletions src/ec/kontron/kempld/kempld_internal.h
Expand Up @@ -28,6 +28,11 @@

#define KEMPLD_CLK 33333333 /* 33MHz */

#define KEMPLD_GPIO_MASK(pin_num) (1 << ((pin_num) % 8))
#define KEMPLD_GPIO_DIR(pin_num) (0x40 + (pin_num) / 8)
#define KEMPLD_GPIO_LVL(pin_num) (0x42 + (pin_num) / 8)

void kempld_i2c_device_init(struct device *const dev);
int kempld_gpio_pads_config(struct device *dev);

#endif /* EC_KONTRON_KEMPLD_INTERNAL_H */
2 changes: 2 additions & 0 deletions src/include/acpi/acpigen.h
Expand Up @@ -415,6 +415,8 @@ inline void acpigen_write_if_end(void)
{
acpigen_pop_len();
}
/* Emits If (CondRefOf(NAME)) */
void acpigen_write_if_cond_ref_of(const char *namestring);
void acpigen_write_else(void);
void acpigen_write_shiftleft_op_int(uint8_t src_result, uint64_t count);
void acpigen_write_to_buffer(uint8_t src, uint8_t dst);
Expand Down
2 changes: 1 addition & 1 deletion src/include/assert.h
Expand Up @@ -94,7 +94,7 @@ extern void _dead_code_assertion_failed(void) __attribute__((noreturn));
*(type *)(uintptr_t)0; \
})

#ifdef __x86_64__
#if ENV_X86_64
#define pointer_to_uint32_safe(x) ({ \
if ((uintptr_t)(x) > 0xffffffffUL) \
die("Cast from pointer to uint32_t overflows"); \
Expand Down
3 changes: 0 additions & 3 deletions src/include/bootstate.h
Expand Up @@ -163,9 +163,6 @@ void boot_state_sched_entries(struct boot_state_init_entry *entries,
* success < 0 when the phase of the (state,seq) has already ran. */
int boot_state_block(boot_state_t state, boot_state_sequence_t seq);
int boot_state_unblock(boot_state_t state, boot_state_sequence_t seq);
/* Block/Unblock current state phase from transitioning. */
void boot_state_current_block(void);
void boot_state_current_unblock(void);

/* In order to schedule boot state callbacks at compile-time specify the
* entries in an array using the BOOT_STATE_INIT_ENTRIES and
Expand Down
6 changes: 0 additions & 6 deletions src/include/cbfs.h
Expand Up @@ -160,12 +160,6 @@ int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type);
int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name,
const char *name, uint32_t *type);

/* Return mapping of option ROM found in boot device. NULL on error. */
void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device);
/* Return mapping of option ROM with revision number. Returns NULL on error. */
void *cbfs_boot_map_optionrom_revision(uint16_t vendor, uint16_t device, uint8_t rev);


/**********************************************************************************************
* INTERNAL HELPERS FOR INLINES, DO NOT USE. *
**********************************************************************************************/
Expand Down
5 changes: 2 additions & 3 deletions src/include/cpu/amd/msr.h
Expand Up @@ -18,8 +18,8 @@
#define SMM_LOCK (1 << 0)
#define NB_CFG_MSR 0xC001001f
#define FidVidStatus 0xC0010042
#define MC1_CTL_MASK 0xC0010045
#define MC4_CTL_MASK 0xC0010048
#define MC0_CTL_MASK 0xC0010044
#define MC_CTL_MASK(bank) (MC0_CTL_MASK + (bank))
#define MSR_INTPEND 0xC0010055
#define MMIO_CONF_BASE 0xC0010058
#define MMIO_RANGE_EN (1 << 0)
Expand Down Expand Up @@ -80,7 +80,6 @@
#define S3_RESUME_EIP_MSR 0xC00110E0
#define PSP_ADDR_MSR 0xc00110a2

#define MSR_PATCH_LEVEL 0x0000008B
#define CORE_PERF_BOOST_CTRL 0x15c

#endif /* CPU_AMD_MSR_H */
57 changes: 57 additions & 0 deletions src/include/cpu/intel/cpu_ids.h
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef CPU_INTEL_CPU_IDS_H
#define CPU_INTEL_CPU_IDS_H

/* Supported CPUIDs for different Intel CPU */

#define CPUID_DENVERTON_A0_A1 0x506f0
#define CPUID_DENVERTON_B0 0x506f1
#define CPUID_COOPERLAKE_SP_A0 0x5065a
#define CPUID_COOPERLAKE_SP_A1 0x5065b
#define CPUID_SKYLAKE_SP_A0_A1 0x506f0
#define CPUID_SKYLAKE_SP_B0 0x506f1
#define CPUID_SKYLAKE_SP_4 0x50654
#define CPUID_SKYLAKE_C0 0x406e2
#define CPUID_SKYLAKE_D0 0x406e3
#define CPUID_SKYLAKE_HQ0 0x506e1
#define CPUID_SKYLAKE_HR0 0x506e3
#define CPUID_KABYLAKE_G0 0x406e8
#define CPUID_KABYLAKE_H0 0x806e9
#define CPUID_KABYLAKE_Y0 0x806ea
#define CPUID_KABYLAKE_HA0 0x506e8
#define CPUID_KABYLAKE_HB0 0x906e9
#define CPUID_CANNONLAKE_A0 0x60660
#define CPUID_CANNONLAKE_B0 0x60661
#define CPUID_CANNONLAKE_C0 0x60662
#define CPUID_CANNONLAKE_D0 0x60663
#define CPUID_APOLLOLAKE_A0 0x506c8
#define CPUID_APOLLOLAKE_B0 0x506c9
#define CPUID_APOLLOLAKE_E0 0x506ca
#define CPUID_GLK_A0 0x706a0
#define CPUID_GLK_B0 0x706a1
#define CPUID_GLK_R0 0x706a8
#define CPUID_WHISKEYLAKE_V0 0x806ec
#define CPUID_WHISKEYLAKE_W0 0x806eb
#define CPUID_COFFEELAKE_U0 0x906ea
#define CPUID_COFFEELAKE_B0 0x906eb
#define CPUID_COFFEELAKE_P0 0x906ec
#define CPUID_COFFEELAKE_R0 0x906ed
#define CPUID_ICELAKE_A0 0x706e0
#define CPUID_ICELAKE_B0 0x706e1
#define CPUID_JASPERLAKE_A0 0x906c0
#define CPUID_COMETLAKE_U_A0 0xa0660
#define CPUID_COMETLAKE_U_K0_S0 0xa0661
#define CPUID_COMETLAKE_H_S_6_2_G0 0xa0650
#define CPUID_COMETLAKE_H_S_6_2_G1 0xa0653
#define CPUID_COMETLAKE_H_S_10_2_P0 0xa0651
#define CPUID_COMETLAKE_H_S_10_2_Q0_P1 0xa0654
#define CPUID_TIGERLAKE_A0 0x806c0
#define CPUID_TIGERLAKE_B0 0x806c1
#define CPUID_ELKHARTLAKE_A0 0x90660
#define CPUID_ELKHARTLAKE_B0 0x90661
#define CPUID_ALDERLAKE_S_A0 0x90670
#define CPUID_ALDERLAKE_A0 0x906a0
#define CPUID_ALDERLAKE_A1 0x906a1
#define CPUID_ALDERLAKE_A2 0x906a2

#endif /* CPU_INTEL_CPU_IDS_H */
2 changes: 1 addition & 1 deletion src/include/cpu/x86/cr.h
Expand Up @@ -9,7 +9,7 @@

#define COMPILER_BARRIER "memory"

#ifdef __x86_64__
#if ENV_X86_64
#define CRx_TYPE uint64_t
#define CRx_IN "q"
#define CRx_RET "=q"
Expand Down
28 changes: 24 additions & 4 deletions src/include/cpu/x86/msr.h
Expand Up @@ -36,7 +36,7 @@
#define SMBASE_RO_MSR 0x98
#define IA32_SMM_MONITOR_VALID (1 << 0)
#define IA32_MCG_CAP 0x179
#define MCG_CTL_P (1 << 3)
#define MCG_CTL_P (1 << 8)
#define MCA_BANKS_MASK 0xff
#define IA32_PERF_STATUS 0x198
#define IA32_PERF_CTL 0x199
Expand All @@ -56,7 +56,9 @@
#define DCA_TYPE0_EN (1 << 0)
#define IA32_PAT 0x277
#define IA32_MC0_CTL 0x400
#define IA32_MC_CTL(bank) (IA32_MC0_CTL + 4 * (bank))
#define IA32_MC0_STATUS 0x401
#define IA32_MC_STATUS(bank) (IA32_MC0_STATUS + 4 * (bank))
#define MCA_STATUS_HI_VAL (1UL << (63 - 32))
#define MCA_STATUS_HI_OVERFLOW (1UL << (62 - 32))
#define MCA_STATUS_HI_UC (1UL << (61 - 32))
Expand All @@ -74,12 +76,13 @@
#define MCA_STATUS_LO_ERRCODE_EXT_SH 16
#define MCA_STATUS_LO_ERRCODE_EXT_MASK (0x3f << MCA_STATUS_LO_ERRCODE_EXT_SH)
#define MCA_STATUS_LO_ERRCODE_MASK (0xffff << 0)
#define IA32_MC0_ADDR 0x402
#define IA32_MC_ADDR(bank) (IA32_MC0_ADDR + 4 * (bank))
#define IA32_MC0_MISC 0x403
#define IA32_MC_MISC(bank) (IA32_MC0_MISC + 4 * (bank))
#define IA32_VMX_BASIC_MSR 0x480
#define VMX_BASIC_HI_DUAL_MONITOR (1UL << (49 - 32))
#define IA32_VMX_MISC_MSR 0x485
#define MC0_ADDR 0x402
#define MC0_MISC 0x403
#define MC0_CTL_MASK 0xC0010044

#define IA32_PM_ENABLE 0x770
#define IA32_HWP_CAPABILITIES 0x771
Expand Down Expand Up @@ -155,6 +158,23 @@ static __always_inline void wrmsr(unsigned int index, msr_t msr)

#endif /* CONFIG_SOC_SETS_MSRS */

/* Get MCA bank count from MSR */
static inline unsigned int mca_get_bank_count(void)
{
msr_t msr = rdmsr(IA32_MCG_CAP);
return msr.lo & MCA_BANKS_MASK;
}

/* Clear all MCA status registers */
static inline void mca_clear_status(void)
{
const unsigned int num_banks = mca_get_bank_count();
const msr_t msr = {.lo = 0, .hi = 0};

for (unsigned int i = 0 ; i < num_banks ; i++)
wrmsr(IA32_MC_STATUS(i), msr);
}

/* Helpers for interpreting MC[i]_STATUS */

static inline int mca_valid(msr_t msr)
Expand Down
14 changes: 0 additions & 14 deletions src/include/device/path.h
Expand Up @@ -19,8 +19,6 @@ enum device_path_type {
DEVICE_PATH_SPI,
DEVICE_PATH_USB,
DEVICE_PATH_MMIO,
DEVICE_PATH_ESPI,
DEVICE_PATH_LPC,
DEVICE_PATH_GPIO,

/*
Expand All @@ -45,8 +43,6 @@ enum device_path_type {
"DEVICE_PATH_SPI", \
"DEVICE_PATH_USB", \
"DEVICE_PATH_MMIO", \
"DEVICE_PATH_ESPI", \
"DEVICE_PATH_LPC", \
"DEVICE_PATH_GPIO", \
}

Expand Down Expand Up @@ -110,14 +106,6 @@ struct mmio_path {
uintptr_t addr;
};

struct espi_path {
uintptr_t addr;
};

struct lpc_path {
uintptr_t addr;
};

struct gpio_path {
unsigned int id;
};
Expand All @@ -138,8 +126,6 @@ struct device_path {
struct spi_path spi;
struct usb_path usb;
struct mmio_path mmio;
struct espi_path espi;
struct lpc_path lpc;
struct gpio_path gpio;
};
};
Expand Down
6 changes: 5 additions & 1 deletion src/include/device/pci_ids.h
Expand Up @@ -506,7 +506,8 @@
#define PCI_DEVICE_ID_ATI_FAM17H_MODEL18H_GPU 0x15D8
#define PCI_DEVICE_ID_ATI_FAM17H_MODEL60H_GPU 0x1636
#define PCI_DEVICE_ID_ATI_FAM17H_MODEL68H_GPU 0x164C
#define PCI_DEVICE_ID_ATI_FAM19H_MODEL51H_GPU 0x1638
#define PCI_DEVICE_ID_ATI_FAM19H_MODEL51H_GPU_CEZANNE 0x1638
#define PCI_DEVICE_ID_ATI_FAM19H_MODEL51H_GPU_BARCELO 0x15e7
#define PCI_DEVICE_ID_ATI_FAM17H_MODEL18H_HDA0 0x15DE
#define PCI_DEVICE_ID_ATI_FAM17H_MODEL60H_HDA0 0x1637

Expand Down Expand Up @@ -3525,6 +3526,8 @@
#define PCI_DEVICE_ID_INTEL_ADP_P_I2C3 0x51eb
#define PCI_DEVICE_ID_INTEL_ADP_P_I2C4 0x51c5
#define PCI_DEVICE_ID_INTEL_ADP_P_I2C5 0x51c6
#define PCI_DEVICE_ID_INTEL_ADP_P_I2C6 0x51d8
#define PCI_DEVICE_ID_INTEL_ADP_P_I2C7 0x51d9

#define PCI_DEVICE_ID_INTEL_ADP_S_I2C0 0x7acc
#define PCI_DEVICE_ID_INTEL_ADP_S_I2C1 0x7acd
Expand Down Expand Up @@ -3818,6 +3821,7 @@
#define PCI_DEVICE_ID_INTEL_ADL_P_GT2_3 0x46a3
#define PCI_DEVICE_ID_INTEL_ADL_P_GT2_4 0x46a8
#define PCI_DEVICE_ID_INTEL_ADL_P_GT2_5 0x46b3
#define PCI_DEVICE_ID_INTEL_ADL_P_GT2_6 0x46a6
#define PCI_DEVICE_ID_INTEL_ADL_S_GT1 0x4680
#define PCI_DEVICE_ID_INTEL_ADL_M_GT1 0x46c0

Expand Down
40 changes: 18 additions & 22 deletions src/include/device/resource.h
Expand Up @@ -63,31 +63,27 @@ struct resource {
/* Generic resource helper functions */
struct device;
struct bus;
extern void compact_resources(struct device *dev);
extern struct resource *probe_resource(const struct device *dev,
unsigned int index);
extern struct resource *new_resource(struct device *dev, unsigned int index);
extern struct resource *find_resource(const struct device *dev,
unsigned int index);
extern resource_t resource_end(struct resource *resource);
extern resource_t resource_max(struct resource *resource);
extern void report_resource_stored(struct device *dev,
struct resource *resource, const char *comment);

typedef void (*resource_search_t)(void *gp, struct device *dev,
struct resource *res);
extern void search_bus_resources(struct bus *bus,
unsigned long type_mask, unsigned long type,
resource_search_t search, void *gp);

extern void search_global_resources(
unsigned long type_mask, unsigned long type,
resource_search_t search, void *gp);
void compact_resources(struct device *dev);
struct resource *probe_resource(const struct device *dev, unsigned int index);
struct resource *new_resource(struct device *dev, unsigned int index);
struct resource *find_resource(const struct device *dev, unsigned int index);
resource_t resource_end(const struct resource *resource);
resource_t resource_max(const struct resource *resource);
void report_resource_stored(struct device *dev, const struct resource *resource,
const char *comment);

typedef void (*resource_search_t)(void *gp, struct device *dev, struct resource *res);

void search_bus_resources(struct bus *bus, unsigned long type_mask, unsigned long type,
resource_search_t search, void *gp);

void search_global_resources(unsigned long type_mask, unsigned long type,
resource_search_t search, void *gp);

#define RESOURCE_TYPE_MAX 20
extern const char *resource_type(struct resource *resource);
const char *resource_type(const struct resource *resource);

static inline void *res2mmio(struct resource *res, unsigned long offset,
static inline void *res2mmio(const struct resource *res, unsigned long offset,
unsigned long mask)
{
return (void *)(uintptr_t)((res->base + offset) & ~mask);
Expand Down
7 changes: 7 additions & 0 deletions src/include/program_loading.h
Expand Up @@ -154,6 +154,13 @@ void run_ramstage(void);

int payload_arch_usable_ram_quirk(uint64_t start, uint64_t size);

/*
* Asynchronously preloads the payload.
*
* This should be called early on to allow the payload to load before
* `payload_load` is called.
*/
void payload_preload(void);
/* Load payload into memory in preparation to run. */
void payload_load(void);

Expand Down
74 changes: 25 additions & 49 deletions src/include/smbios.h
Expand Up @@ -10,6 +10,10 @@ unsigned long smbios_write_tables(unsigned long start);
int smbios_add_string(u8 *start, const char *str);
int smbios_string_table_len(u8 *start);

struct smbios_header;
int smbios_full_table_len(struct smbios_header *header, u8 *str_table_start);
void *smbios_carve_table(unsigned long start, u8 type, u8 length, u16 handle);

/* Used by mainboard to add an on-board device */
enum misc_slot_type;
enum misc_slot_length;
Expand Down Expand Up @@ -276,10 +280,14 @@ struct smbios_entry30 {
u64 struct_table_address;
} __packed;

struct smbios_type0 {
struct smbios_header {
u8 type;
u8 length;
u16 handle;
} __packed;

struct smbios_type0 {
struct smbios_header header;
u8 vendor;
u8 bios_version;
u16 bios_start_segment;
Expand All @@ -297,9 +305,7 @@ struct smbios_type0 {
} __packed;

struct smbios_type1 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 manufacturer;
u8 product_name;
u8 version;
Expand Down Expand Up @@ -334,9 +340,7 @@ typedef enum {
} smbios_board_type;

struct smbios_type2 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 manufacturer;
u8 product_name;
u8 version;
Expand Down Expand Up @@ -389,9 +393,7 @@ typedef enum {
} smbios_enclosure_type;

struct smbios_type3 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 manufacturer;
u8 _type;
u8 version;
Expand All @@ -411,9 +413,7 @@ struct smbios_type3 {
} __packed;

struct smbios_type4 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 socket_designation;
u8 processor_type;
u8 processor_family;
Expand Down Expand Up @@ -524,9 +524,7 @@ enum smbios_cache_associativity {
#define SMBIOS_CACHE_OP_MODE_UNKNOWN 3

struct smbios_type7 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 socket_designation;
u16 cache_configuration;
u16 max_cache_size;
Expand Down Expand Up @@ -640,9 +638,7 @@ struct port_information {
};

struct smbios_type8 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 internal_reference_designator;
u8 internal_connector_type;
u8 external_reference_designator;
Expand Down Expand Up @@ -777,9 +773,7 @@ struct slot_peer_groups {
} __packed;

struct smbios_type9 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 slot_designation;
u8 slot_type;
u8 slot_data_bus_width;
Expand All @@ -798,17 +792,13 @@ struct smbios_type9 {
} __packed;

struct smbios_type11 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 count;
u8 eos[2];
} __packed;

struct smbios_type15 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u16 area_length;
u16 header_offset;
u16 data_offset;
Expand Down Expand Up @@ -838,9 +828,7 @@ enum {
#define SMBIOS_USE_EXTENDED_MAX_CAPACITY (1 << 31)

struct smbios_type16 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 location;
u8 use;
u8 memory_error_correction;
Expand All @@ -852,9 +840,7 @@ struct smbios_type16 {
} __packed;

struct smbios_type17 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u16 phys_memory_array_handle;
u16 memory_error_information_handle;
u16 total_width;
Expand All @@ -881,9 +867,7 @@ struct smbios_type17 {
} __packed;

struct smbios_type19 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u32 starting_address;
u32 ending_address;
u16 memory_array_handle;
Expand All @@ -894,18 +878,14 @@ struct smbios_type19 {
} __packed;

struct smbios_type32 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 reserved[6];
u8 boot_status;
u8 eos[2];
} __packed;

struct smbios_type38 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 interface_type;
u8 ipmi_rev;
u8 i2c_slave_addr;
Expand Down Expand Up @@ -940,9 +920,7 @@ typedef enum {
#define SMBIOS_DEVICE_TYPE_COUNT 10

struct smbios_type41 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 reference_designation;
u8 device_type: 7;
u8 device_status: 1;
Expand All @@ -955,9 +933,7 @@ struct smbios_type41 {
} __packed;

struct smbios_type127 {
u8 type;
u8 length;
u16 handle;
struct smbios_header header;
u8 eos[2];
} __packed;

Expand Down
5 changes: 3 additions & 2 deletions src/include/spi_flash.h
Expand Up @@ -88,8 +88,9 @@ struct spi_flash {
union {
u8 raw;
struct {
u8 dual_spi : 1;
u8 _reserved : 7;
u8 dual_output : 1;
u8 dual_io : 1;
u8 _reserved : 6;
};
} flags;
u16 model;
Expand Down
1 change: 1 addition & 0 deletions src/include/symbols.h
Expand Up @@ -52,6 +52,7 @@ 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
81 changes: 62 additions & 19 deletions src/include/thread.h
Expand Up @@ -2,9 +2,41 @@
#ifndef THREAD_H_
#define THREAD_H_

#include <stdint.h>
#include <bootstate.h>
#include <arch/cpu.h>
#include <bootstate.h>
#include <commonlib/bsd/cb_err.h>
#include <stdint.h>

struct thread_mutex {
bool locked;
};

enum thread_state {
THREAD_UNINITIALIZED,
THREAD_STARTED,
THREAD_DONE,
};

struct thread_handle {
enum thread_state state;
/* Only valid when state == THREAD_DONE */
enum cb_err error;
};

/* Run func(arg) on a new thread. Return 0 on successful start of thread, < 0
* when thread could not be started. The thread handle if populated, will
* reflect the state and return code of the thread.
*/
int thread_run(struct thread_handle *handle, enum cb_err (*func)(void *), void *arg);

/* thread_run_until is the same as thread_run() except that it blocks state
* transitions from occurring in the (state, seq) pair of the boot state
* machine. */
int thread_run_until(struct thread_handle *handle, enum cb_err (*func)(void *), void *arg,
boot_state_t state, boot_state_sequence_t seq);

/* Waits until the thread has terminated and returns the error code */
enum cb_err thread_join(struct thread_handle *handle);

#if ENV_RAMSTAGE && CONFIG(COOP_MULTITASKING)

Expand All @@ -13,9 +45,10 @@ struct thread {
uintptr_t stack_current;
uintptr_t stack_orig;
struct thread *next;
void (*entry)(void *);
enum cb_err (*entry)(void *);
void *entry_arg;
int can_yield;
struct thread_handle *handle;
};

void threads_initialize(void);
Expand All @@ -24,25 +57,28 @@ void threads_initialize(void);
* aligned to CONFIG_STACK_SIZE, or NULL.
*/
void *arch_get_thread_stackbase(void);
/* Run func(arrg) on a new thread. Return 0 on successful start of thread, < 0
* when thread could not be started. Note that the thread will block the
* current state in the boot state machine until it is complete. */
int thread_run(void (*func)(void *), void *arg);
/* thread_run_until is the same as thread_run() except that it blocks state
* transitions from occurring in the (state, seq) pair of the boot state
* machine. */
int thread_run_until(void (*func)(void *), void *arg,
boot_state_t state, boot_state_sequence_t seq);

/* Return 0 on successful yield, < 0 when thread did not yield. */
int thread_yield(void);

/* Return 0 on successful yield for the given amount of time, < 0 when thread
* did not yield. */
int thread_yield_microseconds(unsigned int microsecs);

/* Allow and prevent thread cooperation on current running thread. By default
* all threads are marked to be cooperative. That means a thread can yield
* to another thread at a pre-determined switch point. Current there is
* only a single place where switching may occur: a call to udelay(). */
void thread_cooperate(void);
void thread_prevent_coop(void);
* to another thread at a pre-determined switch point. i.e., udelay,
* thread_yield, or thread_yield_microseconds.
*
* These methods should be used to guard critical sections so a dead lock does
* not occur. The critical sections can be nested. Just make sure the methods
* are used in pairs.
*/
void thread_coop_enable(void);
void thread_coop_disable(void);

void thread_mutex_lock(struct thread_mutex *mutex);
void thread_mutex_unlock(struct thread_mutex *mutex);

static inline void thread_init_cpu_info_non_bsp(struct cpu_info *ci)
{
Expand All @@ -58,15 +94,22 @@ void arch_prepare_thread(struct thread *t,
asmlinkage void (*thread_entry)(void *), void *arg);
#else
static inline void threads_initialize(void) {}
static inline int thread_run(void (*func)(void *), void *arg) { return -1; }
static inline int thread_yield(void)
{
return -1;
}
static inline int thread_yield_microseconds(unsigned int microsecs)
{
return -1;
}
static inline void thread_cooperate(void) {}
static inline void thread_prevent_coop(void) {}
static inline void thread_coop_enable(void) {}
static inline void thread_coop_disable(void) {}
struct cpu_info;
static inline void thread_init_cpu_info_non_bsp(struct cpu_info *ci) { }

static inline void thread_mutex_lock(struct thread_mutex *mutex) {}

static inline void thread_mutex_unlock(struct thread_mutex *mutex) {}
#endif

#endif /* THREAD_H_ */
11 changes: 11 additions & 0 deletions src/lib/Kconfig
Expand Up @@ -98,3 +98,14 @@ config NO_CBFS_MCACHE
the associated CAR/SRAM size. In that case every single CBFS file
lookup must re-read the same CBFS directory entries from flash to find
the respective file.

config PAYLOAD_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.
40 changes: 0 additions & 40 deletions src/lib/cbfs.c
Expand Up @@ -264,46 +264,6 @@ static size_t cbfs_load_and_decompress(const struct region_device *rdev, void *b
}
}

static inline int tohex4(unsigned int c)
{
return (c <= 9) ? (c + '0') : (c - 10 + 'a');
}

static void tohex8(unsigned int val, char *dest)
{
dest[0] = tohex4((val >> 4) & 0xf);
dest[1] = tohex4(val & 0xf);
}

static void tohex16(unsigned int val, char *dest)
{
dest[0] = tohex4(val >> 12);
dest[1] = tohex4((val >> 8) & 0xf);
dest[2] = tohex4((val >> 4) & 0xf);
dest[3] = tohex4(val & 0xf);
}

void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device)
{
char name[17] = "pciXXXX,XXXX.rom";

tohex16(vendor, name + 3);
tohex16(device, name + 8);

return cbfs_map(name, NULL);
}

void *cbfs_boot_map_optionrom_revision(uint16_t vendor, uint16_t device, uint8_t rev)
{
char name[20] = "pciXXXX,XXXX,XX.rom";

tohex16(vendor, name + 3);
tohex16(device, name + 8);
tohex8(rev, name + 13);

return cbfs_map(name, NULL);
}

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
10 changes: 0 additions & 10 deletions src/lib/hardwaremain.c
Expand Up @@ -519,13 +519,3 @@ int boot_state_unblock(boot_state_t state, boot_state_sequence_t seq)

return 0;
}

void boot_state_current_block(void)
{
boot_state_block(current_phase.state_id, current_phase.seq);
}

void boot_state_current_unblock(void)
{
boot_state_unblock(current_phase.state_id, current_phase.seq);
}
58 changes: 52 additions & 6 deletions src/lib/prog_loaders.c
Expand Up @@ -13,6 +13,7 @@
#include <rmodule.h>
#include <stage_cache.h>
#include <symbols.h>
#include <thread.h>
#include <timestamp.h>
#include <security/vboot/vboot_common.h>

Expand Down Expand Up @@ -126,27 +127,71 @@ 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))
return;

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

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

timestamp_add_now(TS_LOAD_PAYLOAD);

if (prog_locate_hook(payload))
goto out;

payload->cbfs_type = CBFS_TYPE_QUERY;
void *mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type);
if (!mapping)
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;
}

if (!buffer)
goto out;

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

cbfs_unmap(mapping);
if (mapping)
cbfs_unmap(mapping);
out:
if (prog_entry(payload) == NULL)
die_with_post_code(POST_INVALID_ROM, "Payload not loaded.\n");
Expand Down
8 changes: 8 additions & 0 deletions src/lib/selfboot.c
Expand Up @@ -34,6 +34,14 @@ static void cbfs_decode_payload_segment(struct cbfs_payload_segment *segment,
static int segment_targets_type(void *dest, unsigned long memsz,
enum bootmem_type dest_type)
{
/* No bootmem to check in earlier stages, caller should not use
selfload_check(). */
if (!ENV_RAMSTAGE) {
printk(BIOS_ERR,
"Callers not supposed to call selfload_check() in romstage");
return 0;
}

uintptr_t d = (uintptr_t) dest;
if (bootmem_region_targets_type(d, memsz, dest_type))
return 1;
Expand Down
134 changes: 100 additions & 34 deletions src/lib/thread.c
@@ -1,14 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <arch/cpu.h>
#include <bootstate.h>
#include <commonlib/bsd/compiler.h>
#include <console/console.h>
#include <thread.h>
#include <timer.h>

static bool initialized;

static void idle_thread_init(void);

/* There needs to be at least one thread to run the ramstate state machine. */
Expand All @@ -29,7 +33,7 @@ static inline struct cpu_info *thread_cpu_info(const struct thread *t)

static inline int thread_can_yield(const struct thread *t)
{
return (t != NULL && t->can_yield);
return (t != NULL && t->can_yield > 0);
}

/* Assumes current CPU info can switch. */
Expand All @@ -40,6 +44,9 @@ static inline struct thread *cpu_info_to_thread(const struct cpu_info *ci)

static inline struct thread *current_thread(void)
{
if (!initialized)
return NULL;

return cpu_info_to_thread(cpu_info());
}

Expand Down Expand Up @@ -106,10 +113,10 @@ static inline void free_thread(struct thread *t)
/* The idle thread is ran whenever there isn't anything else that is runnable.
* It's sole responsibility is to ensure progress is made by running the timer
* callbacks. */
static void idle_thread(void *unused)
__noreturn static enum cb_err idle_thread(void *unused)
{
/* This thread never voluntarily yields. */
thread_prevent_coop();
thread_coop_disable();
while (1)
timers_run();
}
Expand All @@ -127,32 +134,32 @@ static void schedule(struct thread *t)
/* current is still runnable. */
push_runnable(current);
}

if (t->handle)
t->handle->state = THREAD_STARTED;

switch_to_thread(t->stack_current, &current->stack_current);
}

static void terminate_thread(struct thread *t)
static void terminate_thread(struct thread *t, enum cb_err error)
{
if (t->handle) {
t->handle->error = error;
t->handle->state = THREAD_DONE;
}

free_thread(t);
schedule(NULL);
}

static void asmlinkage call_wrapper(void *unused)
{
struct thread *current = current_thread();
enum cb_err error;

current->entry(current->entry_arg);
terminate_thread(current);
}

/* Block the current state transitions until thread is complete. */
static void asmlinkage call_wrapper_block_current(void *unused)
{
struct thread *current = current_thread();
error = current->entry(current->entry_arg);

boot_state_current_block();
current->entry(current->entry_arg);
boot_state_current_unblock();
terminate_thread(current);
terminate_thread(current, error);
}

struct block_boot_state {
Expand All @@ -165,18 +172,19 @@ static void asmlinkage call_wrapper_block_state(void *arg)
{
struct block_boot_state *bbs = arg;
struct thread *current = current_thread();
enum cb_err error;

boot_state_block(bbs->state, bbs->seq);
current->entry(current->entry_arg);
error = current->entry(current->entry_arg);
boot_state_unblock(bbs->state, bbs->seq);
terminate_thread(current);
terminate_thread(current, error);
}

/* Prepare a thread so that it starts by executing thread_entry(thread_arg).
* Within thread_entry() it will call func(arg). */
static void prepare_thread(struct thread *t, void *func, void *arg,
asmlinkage void (*thread_entry)(void *),
void *thread_arg)
static void prepare_thread(struct thread *t, struct thread_handle *handle,
enum cb_err (*func)(void *), void *arg,
asmlinkage void (*thread_entry)(void *), void *thread_arg)
{
/* Stash the function and argument to run. */
t->entry = func;
Expand All @@ -185,6 +193,9 @@ static void prepare_thread(struct thread *t, void *func, void *arg,
/* All new threads can yield by default. */
t->can_yield = 1;

/* Pointer used to publish the state of thread */
t->handle = handle;

arch_prepare_thread(t, thread_entry, thread_arg);
}

Expand All @@ -206,10 +217,8 @@ static void idle_thread_init(void)
die("No threads available for idle thread!\n");

/* Queue idle thread to run once all other threads have yielded. */
prepare_thread(t, idle_thread, NULL, call_wrapper, NULL);
prepare_thread(t, NULL, idle_thread, NULL, call_wrapper, NULL);
push_runnable(t);
/* Mark the currently executing thread to cooperate. */
thread_cooperate();
}

/* Don't inline this function so the timeout_callback won't have its storage
Expand Down Expand Up @@ -255,6 +264,7 @@ void threads_initialize(void)
ci->thread = t;
t->stack_orig = (uintptr_t)ci;
t->id = 0;
t->can_yield = 1;

stack_top = &thread_stacks[CONFIG_STACK_SIZE] - sizeof(struct cpu_info);
for (i = 1; i < TOTAL_NUM_THREADS; i++) {
Expand All @@ -266,9 +276,11 @@ void threads_initialize(void)
}

idle_thread_init();

initialized = 1;
}

int thread_run(void (*func)(void *), void *arg)
int thread_run(struct thread_handle *handle, enum cb_err (*func)(void *), void *arg)
{
struct thread *current;
struct thread *t;
Expand All @@ -288,13 +300,13 @@ int thread_run(void (*func)(void *), void *arg)
return -1;
}

prepare_thread(t, func, arg, call_wrapper_block_current, NULL);
prepare_thread(t, handle, func, arg, call_wrapper, NULL);
schedule(t);

return 0;
}

int thread_run_until(void (*func)(void *), void *arg,
int thread_run_until(struct thread_handle *handle, enum cb_err (*func)(void *), void *arg,
boot_state_t state, boot_state_sequence_t seq)
{
struct thread *current;
Expand All @@ -319,12 +331,17 @@ int thread_run_until(void (*func)(void *), void *arg,
bbs = thread_alloc_space(t, sizeof(*bbs));
bbs->state = state;
bbs->seq = seq;
prepare_thread(t, func, arg, call_wrapper_block_state, bbs);
prepare_thread(t, handle, func, arg, call_wrapper_block_state, bbs);
schedule(t);

return 0;
}

int thread_yield(void)
{
return thread_yield_microseconds(0);
}

int thread_yield_microseconds(unsigned int microsecs)
{
struct thread *current;
Expand All @@ -341,22 +358,71 @@ int thread_yield_microseconds(unsigned int microsecs)
return 0;
}

void thread_cooperate(void)
void thread_coop_enable(void)
{
struct thread *current;

current = current_thread();

if (current != NULL)
current->can_yield = 1;
if (current == NULL)
return;

assert(current->can_yield <= 0);

current->can_yield++;
}

void thread_prevent_coop(void)
void thread_coop_disable(void)
{
struct thread *current;

current = current_thread();

if (current != NULL)
current->can_yield = 0;
if (current == NULL)
return;

current->can_yield--;
}

enum cb_err thread_join(struct thread_handle *handle)
{
struct stopwatch sw;
struct thread *current = current_thread();

assert(handle);
assert(current);
assert(current->handle != handle);

if (handle->state == THREAD_UNINITIALIZED)
return CB_ERR_ARG;

stopwatch_init(&sw);

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

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

printk(BIOS_SPEW, "took %lu us\n", stopwatch_duration_usecs(&sw));

return handle->error;
}

void thread_mutex_lock(struct thread_mutex *mutex)
{
struct stopwatch sw;

stopwatch_init(&sw);

while (mutex->locked)
assert(thread_yield() == 0);
mutex->locked = true;

printk(BIOS_SPEW, "took %lu us to acquire mutex\n", stopwatch_duration_usecs(&sw));
}

void thread_mutex_unlock(struct thread_mutex *mutex)
{
assert(mutex->locked);
mutex->locked = 0;
}
2 changes: 2 additions & 0 deletions src/mainboard/asus/p8x7x-series/Kconfig
Expand Up @@ -21,13 +21,15 @@ config MAINBOARD_DIR

config VARIANT_DIR
string
default "p8c_ws" if BOARD_ASUS_P8C_WS
default "p8h77-v" if BOARD_ASUS_P8H77_V
default "p8z77-m_pro" if BOARD_ASUS_P8Z77_M_PRO
default "p8z77-v_lx2" if BOARD_ASUS_P8Z77_V_LX2
default "p8z77-v" if BOARD_ASUS_P8Z77_V

config MAINBOARD_PART_NUMBER
string
default "P8C WS" if BOARD_ASUS_P8C_WS
default "P8H77-V" if BOARD_ASUS_P8H77_V
default "P8Z77-M PRO" if BOARD_ASUS_P8Z77_M_PRO
default "P8Z77-V LX2" if BOARD_ASUS_P8Z77_V_LX2
Expand Down
8 changes: 8 additions & 0 deletions src/mainboard/asus/p8x7x-series/Kconfig.name
@@ -1,3 +1,11 @@
config BOARD_ASUS_P8C_WS
bool "P8C_WS"
select BOARD_ASUS_P8X7X_SERIES
select BOARD_ROMSIZE_KB_8192
select MAINBOARD_HAS_LPC_TPM
select SUPERIO_NUVOTON_NCT6776
select USE_NATIVE_RAMINIT

config BOARD_ASUS_P8H77_V
bool "P8H77-V"
select BOARD_ASUS_P8X7X_SERIES
Expand Down
3 changes: 3 additions & 0 deletions src/mainboard/asus/p8x7x-series/dsdt.asl
Expand Up @@ -22,5 +22,8 @@ DefinitionBlock(
{
#include <northbridge/intel/sandybridge/acpi/sandybridge.asl>
#include <southbridge/intel/bd82x6x/acpi/pch.asl>
#if CONFIG(BOARD_ASUS_P8C_WS)
#include "variants/p8c_ws/pci.asl"
#endif
}
}
@@ -0,0 +1,7 @@
Category: desktop
Board URL: https://www.asus.com/supportonly/p8c_ws/helpdesk_knowledge/
ROM package: DIP-8
ROM protocol: SPI
ROM socketed: y
Flashrom support: y
Release year: 2013
6 changes: 6 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/cmos.default
@@ -0,0 +1,6 @@
boot_option=Fallback
debug_level=Debug
nmi=Disable
power_on_after_fail=Disable
sata_mode=AHCI
gfx_uma_size=64M
86 changes: 86 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/cmos.layout
@@ -0,0 +1,86 @@
## SPDX-License-Identifier: GPL-2.0-only

# -----------------------------------------------------------------
entries

# -----------------------------------------------------------------
0 120 r 0 reserved_memory

# -----------------------------------------------------------------
# RTC_BOOT_BYTE (coreboot hardcoded)
384 1 e 2 boot_option
388 4 h 0 reboot_counter

# -----------------------------------------------------------------
# coreboot config options: console
395 4 e 3 debug_level

# coreboot config options: southbridge
408 1 e 1 nmi

409 2 e 4 power_on_after_fail
411 2 e 5 sata_mode

# coreboot config options: northbridge
416 5 e 6 gfx_uma_size

# coreboot config options: check sums
984 16 h 0 check_sum

# -----------------------------------------------------------------

enumerations
#ID value text

# Generic on/off enum
1 0 Disable
1 1 Enable

# boot_option
2 0 Fallback
2 1 Normal

# debug_level
3 0 Emergency
3 1 Alert
3 2 Critical
3 3 Error
3 4 Warning
3 5 Notice
3 6 Info
3 7 Debug
3 8 Spew

# power_on_after_fail
4 0 Disable
4 1 Enable
4 2 Keep

# sata_mode
5 0 AHCI
5 1 Compatible
5 2 Legacy

# gfx_uma_size (Intel IGP Video RAM size)
6 0 32M
6 1 64M
6 2 96M
6 3 128M
6 4 160M
6 5 192M
6 6 224M
6 7 256M
6 8 288M
6 9 320M
6 10 352M
6 11 384M
6 12 416M
6 13 448M
6 14 480M
6 15 512M
6 16 1024M

# -----------------------------------------------------------------
checksums

checksum 392 423 984
Binary file not shown.
62 changes: 62 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c
@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <bootblock_common.h>
#include <device/pnp_ops.h>
#include <northbridge/intel/sandybridge/raminit_native.h>
#include <southbridge/intel/bd82x6x/pch.h>
#include <superio/nuvoton/common/nuvoton.h>
#include <superio/nuvoton/nct6776/nct6776.h>

#define GLOBAL_DEV PNP_DEV(0x2e, 0)
#define SERIAL_DEV PNP_DEV(0x2e, NCT6776_SP1)
#define ACPI_DEV PNP_DEV(0x2e, NCT6776_ACPI)

const struct southbridge_usb_port mainboard_usb_ports[] = {
{ 1, 0, 0 },
{ 1, 0, 0 },
{ 1, 0, 1 },
{ 1, 0, 1 },
{ 1, 0, 2 },
{ 1, 0, 2 },
{ 1, 0, 3 },
{ 1, 0, 3 },
{ 1, 0, 4 },
{ 1, 0, 4 },
{ 1, 0, 6 },
{ 1, 0, 5 },
{ 1, 0, 5 },
{ 1, 0, 6 },
};

void bootblock_mainboard_early_init(void)
{
nuvoton_pnp_enter_conf_state(GLOBAL_DEV);

/* Select SIO pin states */
pnp_write_config(GLOBAL_DEV, 0x1a, 0xc8);
pnp_write_config(GLOBAL_DEV, 0x1b, 0x0e);
pnp_write_config(GLOBAL_DEV, 0x1c, 0x83);
pnp_write_config(GLOBAL_DEV, 0x24, 0x20);
pnp_write_config(GLOBAL_DEV, 0x27, 0x10);
pnp_write_config(GLOBAL_DEV, 0x2a, 0x68);
pnp_write_config(GLOBAL_DEV, 0x2c, 0x00);

/* Power RAM in S3 */
pnp_set_logical_device(ACPI_DEV);
pnp_write_config(ACPI_DEV, 0xe4, 0x10);

pnp_set_logical_device(SERIAL_DEV);

nuvoton_pnp_exit_conf_state(GLOBAL_DEV);

/* Enable UART */
nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
}

void mainboard_get_spd(spd_raw_data *spd, bool id_only)
{
read_spd(&spd[0], 0x50, id_only);
read_spd(&spd[1], 0x51, id_only);
read_spd(&spd[2], 0x52, id_only);
read_spd(&spd[3], 0x53, id_only);
}
16 changes: 16 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/gma-mainboard.ads
@@ -0,0 +1,16 @@
-- SPDX-License-Identifier: GPL-2.0-or-later

with HW.GFX.GMA;
with HW.GFX.GMA.Display_Probing;

use HW.GFX.GMA;
use HW.GFX.GMA.Display_Probing;

private package GMA.Mainboard is

ports : constant Port_List :=
(HDMI1,
Analog,
others => Disabled);

end GMA.Mainboard;
183 changes: 183 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/gpio.c
@@ -0,0 +1,183 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <southbridge/intel/common/gpio.h>

static const struct pch_gpio_set1 pch_gpio_set1_mode = {
.gpio0 = GPIO_MODE_GPIO,
.gpio1 = GPIO_MODE_GPIO,
.gpio2 = GPIO_MODE_NATIVE,
.gpio3 = GPIO_MODE_NATIVE,
.gpio4 = GPIO_MODE_NATIVE,
.gpio5 = GPIO_MODE_NATIVE,
.gpio6 = GPIO_MODE_GPIO,
.gpio7 = GPIO_MODE_GPIO,
.gpio8 = GPIO_MODE_GPIO,
.gpio9 = GPIO_MODE_NATIVE,
.gpio10 = GPIO_MODE_NATIVE,
.gpio11 = GPIO_MODE_NATIVE,
.gpio12 = GPIO_MODE_GPIO,
.gpio13 = GPIO_MODE_GPIO,
.gpio14 = GPIO_MODE_NATIVE,
.gpio15 = GPIO_MODE_GPIO,
.gpio16 = GPIO_MODE_GPIO,
.gpio17 = GPIO_MODE_GPIO,
.gpio18 = GPIO_MODE_NATIVE,
.gpio19 = GPIO_MODE_NATIVE,
.gpio20 = GPIO_MODE_NATIVE,
.gpio21 = GPIO_MODE_NATIVE,
.gpio22 = GPIO_MODE_GPIO,
.gpio23 = GPIO_MODE_NATIVE,
.gpio24 = GPIO_MODE_GPIO,
.gpio25 = GPIO_MODE_NATIVE,
.gpio26 = GPIO_MODE_NATIVE,
.gpio27 = GPIO_MODE_GPIO,
.gpio28 = GPIO_MODE_GPIO,
.gpio29 = GPIO_MODE_GPIO,
.gpio30 = GPIO_MODE_NATIVE,
.gpio31 = GPIO_MODE_GPIO,
};

static const struct pch_gpio_set1 pch_gpio_set1_direction = {
.gpio0 = GPIO_DIR_INPUT,
.gpio1 = GPIO_DIR_INPUT,
.gpio6 = GPIO_DIR_INPUT,
.gpio7 = GPIO_DIR_INPUT,
.gpio8 = GPIO_DIR_INPUT,
.gpio12 = GPIO_DIR_OUTPUT,
.gpio13 = GPIO_DIR_INPUT,
.gpio15 = GPIO_DIR_OUTPUT,
.gpio16 = GPIO_DIR_INPUT,
.gpio17 = GPIO_DIR_INPUT,
.gpio22 = GPIO_DIR_INPUT,
.gpio24 = GPIO_DIR_OUTPUT,
.gpio27 = GPIO_DIR_INPUT,
.gpio28 = GPIO_DIR_OUTPUT,
.gpio29 = GPIO_DIR_OUTPUT,
.gpio31 = GPIO_DIR_OUTPUT,
};

static const struct pch_gpio_set1 pch_gpio_set1_level = {
.gpio12 = GPIO_LEVEL_LOW,
.gpio15 = GPIO_LEVEL_LOW,
.gpio24 = GPIO_LEVEL_LOW,
.gpio28 = GPIO_LEVEL_LOW,
.gpio29 = GPIO_LEVEL_HIGH,
.gpio31 = GPIO_LEVEL_HIGH,
};

static const struct pch_gpio_set1 pch_gpio_set1_reset = {
};

static const struct pch_gpio_set1 pch_gpio_set1_invert = {
.gpio6 = GPIO_INVERT,
.gpio13 = GPIO_INVERT,
};

static const struct pch_gpio_set1 pch_gpio_set1_blink = {
};

static const struct pch_gpio_set2 pch_gpio_set2_mode = {
.gpio32 = GPIO_MODE_GPIO,
.gpio33 = GPIO_MODE_GPIO,
.gpio34 = GPIO_MODE_GPIO,
.gpio35 = GPIO_MODE_NATIVE,
.gpio36 = GPIO_MODE_NATIVE,
.gpio37 = GPIO_MODE_NATIVE,
.gpio38 = GPIO_MODE_GPIO,
.gpio39 = GPIO_MODE_GPIO,
.gpio40 = GPIO_MODE_NATIVE,
.gpio41 = GPIO_MODE_NATIVE,
.gpio42 = GPIO_MODE_NATIVE,
.gpio43 = GPIO_MODE_NATIVE,
.gpio44 = GPIO_MODE_NATIVE,
.gpio45 = GPIO_MODE_NATIVE,
.gpio46 = GPIO_MODE_NATIVE,
.gpio47 = GPIO_MODE_NATIVE,
.gpio48 = GPIO_MODE_GPIO,
.gpio49 = GPIO_MODE_GPIO,
.gpio50 = GPIO_MODE_NATIVE,
.gpio51 = GPIO_MODE_NATIVE,
.gpio52 = GPIO_MODE_NATIVE,
.gpio53 = GPIO_MODE_NATIVE,
.gpio54 = GPIO_MODE_NATIVE,
.gpio55 = GPIO_MODE_NATIVE,
.gpio56 = GPIO_MODE_NATIVE,
.gpio57 = GPIO_MODE_GPIO,
.gpio58 = GPIO_MODE_NATIVE,
.gpio59 = GPIO_MODE_NATIVE,
.gpio60 = GPIO_MODE_NATIVE,
.gpio61 = GPIO_MODE_NATIVE,
.gpio62 = GPIO_MODE_NATIVE,
.gpio63 = GPIO_MODE_NATIVE,
};

static const struct pch_gpio_set2 pch_gpio_set2_direction = {
.gpio32 = GPIO_DIR_OUTPUT,
.gpio33 = GPIO_DIR_OUTPUT,
.gpio34 = GPIO_DIR_INPUT,
.gpio38 = GPIO_DIR_INPUT,
.gpio39 = GPIO_DIR_INPUT,
.gpio48 = GPIO_DIR_OUTPUT,
.gpio49 = GPIO_DIR_INPUT,
.gpio57 = GPIO_DIR_INPUT,
};

static const struct pch_gpio_set2 pch_gpio_set2_level = {
.gpio32 = GPIO_LEVEL_HIGH,
.gpio33 = GPIO_LEVEL_HIGH,
.gpio48 = GPIO_LEVEL_LOW,
};

static const struct pch_gpio_set2 pch_gpio_set2_reset = {
};

static const struct pch_gpio_set3 pch_gpio_set3_mode = {
.gpio64 = GPIO_MODE_NATIVE,
.gpio65 = GPIO_MODE_NATIVE,
.gpio66 = GPIO_MODE_NATIVE,
.gpio67 = GPIO_MODE_NATIVE,
.gpio68 = GPIO_MODE_GPIO,
.gpio69 = GPIO_MODE_GPIO,
.gpio70 = GPIO_MODE_NATIVE,
.gpio71 = GPIO_MODE_NATIVE,
.gpio72 = GPIO_MODE_GPIO,
.gpio73 = GPIO_MODE_NATIVE,
.gpio74 = GPIO_MODE_NATIVE,
.gpio75 = GPIO_MODE_NATIVE,
};

static const struct pch_gpio_set3 pch_gpio_set3_direction = {
.gpio68 = GPIO_DIR_INPUT,
.gpio69 = GPIO_DIR_INPUT,
.gpio72 = GPIO_DIR_OUTPUT,
};

static const struct pch_gpio_set3 pch_gpio_set3_level = {
.gpio72 = GPIO_LEVEL_LOW,
};

static const struct pch_gpio_set3 pch_gpio_set3_reset = {
};

const struct pch_gpio_map mainboard_gpio_map = {
.set1 = {
.mode = &pch_gpio_set1_mode,
.direction = &pch_gpio_set1_direction,
.level = &pch_gpio_set1_level,
.blink = &pch_gpio_set1_blink,
.invert = &pch_gpio_set1_invert,
.reset = &pch_gpio_set1_reset,
},
.set2 = {
.mode = &pch_gpio_set2_mode,
.direction = &pch_gpio_set2_direction,
.level = &pch_gpio_set2_level,
.reset = &pch_gpio_set2_reset,
},
.set3 = {
.mode = &pch_gpio_set3_mode,
.direction = &pch_gpio_set3_direction,
.level = &pch_gpio_set3_level,
.reset = &pch_gpio_set3_reset,
},
};
29 changes: 29 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/hda_verb.c
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/azalia_device.h>

const u32 cim_verb_data[] = {
0x10ec0892, /* Codec Vendor / Device ID: Realtek ALC892 */
0x104384fb, /* Subsystem ID */
15, /* Number of 4 dword sets */
AZALIA_SUBVENDOR(0, 0x104384fb),
AZALIA_PIN_CFG(0, 0x11, 0x99430140),
AZALIA_PIN_CFG(0, 0x12, 0x411111f0),
AZALIA_PIN_CFG(0, 0x14, 0x01014010),
AZALIA_PIN_CFG(0, 0x15, 0x01011012),
AZALIA_PIN_CFG(0, 0x16, 0x01016011),
AZALIA_PIN_CFG(0, 0x17, 0x01012014),
AZALIA_PIN_CFG(0, 0x18, 0x01a19850),
AZALIA_PIN_CFG(0, 0x19, 0x02a19c60),
AZALIA_PIN_CFG(0, 0x1a, 0x0181305f),
AZALIA_PIN_CFG(0, 0x1b, 0x02214c20),
AZALIA_PIN_CFG(0, 0x1c, 0x411111f0),
AZALIA_PIN_CFG(0, 0x1d, 0x4005e601),
AZALIA_PIN_CFG(0, 0x1e, 0x014b6130),
AZALIA_PIN_CFG(0, 0x1f, 0x411111f0),

};

const u32 pc_beep_verbs[0] = {};

AZALIA_ARRAY_SIZES;
87 changes: 87 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/overridetree.cb
@@ -0,0 +1,87 @@
## SPDX-License-Identifier: GPL-2.0-only

chip northbridge/intel/sandybridge
device domain 0 on
device pci 01.1 on end # PCIEX16_2 (electrical x8)
device pci 06.0 on end # PCIEX16_3 (electrical x4)
subsystemid 0x1043 0x84ca inherit
chip southbridge/intel/bd82x6x
register "gen1_dec" = "0x000c0291"
device pci 1c.0 on end # RP #1: PCIEX16_4 (electrical x4)
device pci 1c.1 off end # RP #2:
device pci 1c.2 off end # RP #3:
device pci 1c.3 off end # RP #4:
device pci 1c.4 on end # RP #5: PCIEX1_1
device pci 1c.5 on end # RP #6: 82574 GbE #1
device pci 1c.6 on end # RP #7: 82574 GbE #2
device pci 1c.7 off end # RP #8:
device pci 1e.0 on end # PCI bridge
device pci 1f.0 on # LPC bridge
chip superio/nuvoton/nct6776
device pnp 2e.0 off end # Floppy
device pnp 2e.1 on # Parallel
io 0x60 = 0x0378
irq 0x70 = 5
drq 0x74 = 4 # No DMA
irq 0xf0 = 0x3c # Printer mode
end
device pnp 2e.2 on # UART A
io 0x60 = 0x03f8
irq 0x70 = 4
end
device pnp 2e.3 off end # UART B, IR
device pnp 2e.5 on # PS/2 KBC
io 0x60 = 0x0060
io 0x62 = 0x0064
irq 0x70 = 1 # Keyboard
irq 0x72 = 12 # Mouse
end
device pnp 2e.6 off end # CIR
device pnp 2e.7 off end # GPIO8
device pnp 2e.107 off end # GPIO9
device pnp 2e.8 off end # WDT
device pnp 2e.108 off end # GPIO0
device pnp 2e.208 off end # GPIOA
device pnp 2e.308 off end # GPIO base
device pnp 2e.109 off # GPIO1
irq 0xf0 = 0xfb
irq 0xf1 = 0x0
irq 0xf5 = 0xff
irq 0xf7 = 0xff
end
device pnp 2e.209 on # GPIO2
irq 0xe0 = 0xef
end
device pnp 2e.309 on # GPIO3
irq 0xea = 0xff
end
device pnp 2e.409 on end # GPIO4
device pnp 2e.509 on end # GPIO5
device pnp 2e.609 on end # GPIO6
device pnp 2e.709 off end # GPIO7
device pnp 2e.a on # ACPI
irq 0xe6 = 0x0c
irq 0xe7 = 0x11
irq 0xf2 = 0x5d
end
device pnp 2e.b on # HWM, LED
io 0x60 = 0x0290
io 0x62 = 0x0000
end
device pnp 2e.d off end # VID
device pnp 2e.e off end # CIR wake-up
device pnp 2e.f off # GPIO PP/OD
# Enable i2c slave to 0x1d
irq 0xf0 = 0x9d
end
device pnp 2e.14 off end # SVID
device pnp 2e.16 off end # Deep sleep
device pnp 2e.17 off end # GPIOA
end
chip drivers/pc80/tpm
device pnp c31.0 on end # TPM
end
end
end
end
end
29 changes: 29 additions & 0 deletions src/mainboard/asus/p8x7x-series/variants/p8c_ws/pci.asl
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-only */

// Intel PCI to PCI bridge 0:1e.0

Device (PCIB)
{
Name (_ADR, 0x001E0000) // _ADR: Address
Name (_PRW, Package(){ 13, 4 }) // Power Resources for Wake

Method (_PRT) // _PRT: PCI Interrupt Routing Table
{
If (PICM) {
Return (Package() {
Package() { 0x0000ffff, 0, 0, 0x10 },
Package() { 0x0000ffff, 1, 0, 0x11 },
Package() { 0x0000ffff, 2, 0, 0x12 },
Package() { 0x0000ffff, 3, 0, 0x13 },
Package() { 0x0003ffff, 0, 0, 0x13 },
})
}
Return (Package() {
Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 },
Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
})
}
}
2 changes: 1 addition & 1 deletion src/mainboard/clevo/cml-u/Kconfig
Expand Up @@ -39,7 +39,7 @@ config MAINBOARD_VERSION

config DEVICETREE
string
default "variants/$(CONFIG_VARIANT_DIR)/devicetree.cb"
default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb"

config CBFS_SIZE
hex
Expand Down
8 changes: 4 additions & 4 deletions src/mainboard/clevo/kbl-u/Kconfig
Expand Up @@ -49,14 +49,14 @@ config CBFS_SIZE

config DEVICETREE
string
default "variants/$(CONFIG_VARIANT_DIR)/devicetree.cb"
default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb"

config FMDFILE
string
default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/variants/$(CONFIG_VARIANT_DIR)/fmds/vboot-ro.fmd" if VBOOT && !VBOOT_SLOTS_RW_A
default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/fmds/vboot-ro.fmd" if VBOOT && !VBOOT_SLOTS_RW_A
# TODO
# default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/fmds/vboot-roa.fmd" if VBOOT_SLOTS_RW_A && !VBOOT_SLOTS_RW_AB
# default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/fmds/vboot-roab.fmd" if VBOOT_SLOTS_RW_AB
# default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/fmds/vboot-roa.fmd" if VBOOT_SLOTS_RW_A && !VBOOT_SLOTS_RW_AB
# default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/fmds/vboot-roab.fmd" if VBOOT_SLOTS_RW_AB

config DIMM_MAX
int
Expand Down
18 changes: 9 additions & 9 deletions src/mainboard/emulation/qemu-i440fx/fw_cfg.c
Expand Up @@ -393,14 +393,14 @@ static void fw_cfg_smbios_init(void)

static unsigned long smbios_next(unsigned long current)
{
struct smbios_type0 *t0;
struct smbios_header *header;
int l, count = 0;
char *s;

t0 = (void*)current;
current += t0->length;
header = (void *)current;
current += header->length;
for (;;) {
s = (void*)current;
s = (void *)current;
l = strlen(s);
if (!l)
return current + (count ? 1 : 2);
Expand All @@ -424,7 +424,7 @@ static unsigned long smbios_next(unsigned long current)
unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current)
{
FWCfgFile f;
struct smbios_type0 *t0;
struct smbios_header *header;
unsigned long start, end;
int ret, i, count = 1;
char *str;
Expand All @@ -446,8 +446,8 @@ unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current)
if (i == 16384)
return 0;
i += sizeof(struct smbios_type0) - 2;
t0 = (struct smbios_type0*)(*current - i);
if (t0->type != SMBIOS_BIOS_INFORMATION || t0->handle != 0)
header = (struct smbios_header *)(*current - i);
if (header->type != SMBIOS_BIOS_INFORMATION || header->handle != 0)
return 0;
printk(BIOS_DEBUG, "QEMU: coreboot type0 table found at 0x%lx.\n",
*current - i);
Expand All @@ -461,8 +461,8 @@ unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current)
fw_cfg_get(f.select, (void *)start, f.size);
end = start;
do {
t0 = (struct smbios_type0*)end;
if (t0->type == SMBIOS_END_OF_TABLE)
header = (struct smbios_header *)end;
if (header->type == SMBIOS_END_OF_TABLE)
break;
end = smbios_next(end);
count++;
Expand Down
17 changes: 10 additions & 7 deletions src/mainboard/emulation/qemu-i440fx/mainboard.c
Expand Up @@ -10,22 +10,25 @@ static const unsigned char qemu_i440fx_irqs[] = {
11, 10, 10, 11,
};

#define D0F0_PAM(x) (0x59 + (x)) /* 0-6 */

static void qemu_nb_init(struct device *dev)
{
/* Map memory at 0xc0000 - 0xfffff */
int i;
uint8_t v = pci_read_config8(dev, 0x59);
v |= 0x30;
pci_write_config8(dev, 0x59, v);
for (i = 0; i < 6; i++)
pci_write_config8(dev, 0x5a + i, 0x33);
pci_or_config8(dev, D0F0_PAM(0), 0x30);
for (i = 1; i <= 6; i++)
pci_write_config8(dev, D0F0_PAM(i), 0x33);

/* This sneaked in here, because Qemu does not emulate a SuperIO chip. */
pc_keyboard_init(NO_AUX_DEVICE);

/* setup IRQ routing */
for (i = 0; i < 32; i++)
pci_assign_irqs(pcidev_on_root(i, 0), qemu_i440fx_irqs + (i % 4));
for (i = 0; i < 32; i++) {
struct device *d = pcidev_on_root(i, 0);
if (d)
pci_assign_irqs(d, qemu_i440fx_irqs + (i % 4));
}
}

static void qemu_nb_read_resources(struct device *dev)
Expand Down
21 changes: 8 additions & 13 deletions src/mainboard/emulation/qemu-i440fx/northbridge.c
Expand Up @@ -165,31 +165,25 @@ static void cpu_pci_domain_read_resources(struct device *dev)
#if CONFIG(GENERATE_SMBIOS_TABLES)
static int qemu_get_smbios_data16(int handle, unsigned long *current)
{
struct smbios_type16 *t = (struct smbios_type16 *)*current;
int len = sizeof(struct smbios_type16);
struct smbios_type16 *t = smbios_carve_table(*current, SMBIOS_PHYS_MEMORY_ARRAY,
sizeof(*t), handle);

memset(t, 0, sizeof(struct smbios_type16));
t->type = SMBIOS_PHYS_MEMORY_ARRAY;
t->handle = handle;
t->length = len - 2;
t->location = MEMORY_ARRAY_LOCATION_SYSTEM_BOARD;
t->use = MEMORY_ARRAY_USE_SYSTEM;
t->memory_error_correction = MEMORY_ARRAY_ECC_NONE;
t->maximum_capacity = qemu_get_memory_size();

const int len = smbios_full_table_len(&t->header, t->eos);
*current += len;
return len;
}

static int qemu_get_smbios_data17(int handle, int parent_handle, unsigned long *current)
{
struct smbios_type17 *t = (struct smbios_type17 *)*current;
int len;
struct smbios_type17 *t = smbios_carve_table(*current, SMBIOS_MEMORY_DEVICE,
sizeof(*t), handle);

memset(t, 0, sizeof(struct smbios_type17));
t->type = SMBIOS_MEMORY_DEVICE;
t->handle = handle;
t->phys_memory_array_handle = parent_handle;
t->length = sizeof(struct smbios_type17) - 2;
t->size = qemu_get_memory_size() / 1024;
t->data_width = 64;
t->total_width = 64;
Expand All @@ -200,7 +194,8 @@ static int qemu_get_smbios_data17(int handle, int parent_handle, unsigned long *
t->speed = 200;
t->clock_speed = 200;
t->manufacturer = smbios_add_string(t->eos, CONFIG_MAINBOARD_VENDOR);
len = t->length + smbios_string_table_len(t->eos);

const int len = smbios_full_table_len(&t->header, t->eos);
*current += len;
return len;
}
Expand Down
14 changes: 10 additions & 4 deletions src/mainboard/emulation/qemu-q35/mainboard.c
Expand Up @@ -31,11 +31,17 @@ static void qemu_nb_init(struct device *dev)
pc_keyboard_init(NO_AUX_DEVICE);

/* setup IRQ routing for pci slots */
for (i = 0; i < 25; i++)
pci_assign_irqs(pcidev_on_root(i, 0), qemu_q35_irqs + (i % 4));
for (i = 0; i < 25; i++) {
struct device *d = pcidev_on_root(i, 0);
if (d)
pci_assign_irqs(d, qemu_q35_irqs + (i % 4));
}
/* setup IRQ routing southbridge devices */
for (i = 25; i < 32; i++)
pci_assign_irqs(pcidev_on_root(i, 0), qemu_q35_irqs);
for (i = 25; i < 32; i++) {
struct device *d = pcidev_on_root(i, 0);
if (d)
pci_assign_irqs(d, qemu_q35_irqs);
}
}

static void qemu_nb_read_resources(struct device *dev)
Expand Down
2 changes: 1 addition & 1 deletion src/mainboard/google/auron/ec.c
Expand Up @@ -23,7 +23,7 @@ void mainboard_ec_init(void)
google_chromeec_events_init(&info, s3_wakeup);
if (s3_wakeup) {
/* Clear pending events. */
while (google_chromeec_get_event() != 0)
while (google_chromeec_get_event() != EC_HOST_EVENT_NONE)
;
}

Expand Down
6 changes: 3 additions & 3 deletions src/mainboard/google/auron/smihandler.c
Expand Up @@ -97,7 +97,7 @@ void mainboard_smi_sleep(u8 slp_typ)
google_chromeec_set_sci_mask(0);

/* Clear pending events that may trigger immediate wake */
while (google_chromeec_get_event() != 0)
while (google_chromeec_get_event() != EC_HOST_EVENT_NONE)
;
}

Expand All @@ -107,14 +107,14 @@ int mainboard_smi_apmc(u8 apmc)
case APM_CNT_ACPI_ENABLE:
google_chromeec_set_smi_mask(0);
/* Clear all pending events */
while (google_chromeec_get_event() != 0)
while (google_chromeec_get_event() != EC_HOST_EVENT_NONE)
;
google_chromeec_set_sci_mask(MAINBOARD_EC_SCI_EVENTS);
break;
case APM_CNT_ACPI_DISABLE:
google_chromeec_set_sci_mask(0);
/* Clear all pending events */
while (google_chromeec_get_event() != 0)
while (google_chromeec_get_event() != EC_HOST_EVENT_NONE)
;
google_chromeec_set_smi_mask(MAINBOARD_EC_SMI_EVENTS);
break;
Expand Down
6 changes: 6 additions & 0 deletions src/mainboard/google/brya/Kconfig
Expand Up @@ -77,12 +77,18 @@ config MAINBOARD_PART_NUMBER
default "Brya" if BOARD_GOOGLE_BRYA0
default "Primus" if BOARD_GOOGLE_PRIMUS
default "Gimble" if BOARD_GOOGLE_GIMBLE
default "Redrix" if BOARD_GOOGLE_REDRIX
default "Kano" if BOARD_GOOGLE_KANO
default "Taeko" if BOARD_GOOGLE_TAEKO

config VARIANT_DIR
string
default "brya0" if BOARD_GOOGLE_BRYA0
default "primus" if BOARD_GOOGLE_PRIMUS
default "gimble" if BOARD_GOOGLE_GIMBLE
default "redrix" if BOARD_GOOGLE_REDRIX
default "kano" if BOARD_GOOGLE_KANO
default "taeko" if BOARD_GOOGLE_TAEKO

config DIMM_SPD_SIZE
int
Expand Down
15 changes: 15 additions & 0 deletions src/mainboard/google/brya/Kconfig.name
Expand Up @@ -7,6 +7,7 @@ config BOARD_GOOGLE_BRYA0
select DRIVERS_GENESYSLOGIC_GL9755
select DRIVERS_INTEL_MIPI_CAMERA
select SOC_INTEL_COMMON_BLOCK_IPU
select SOC_INTEL_CRASHLOG

config BOARD_GOOGLE_PRIMUS
bool "-> Primus"
Expand All @@ -17,3 +18,17 @@ config BOARD_GOOGLE_GIMBLE
bool "-> Gimble"
select BOARD_GOOGLE_BASEBOARD_BRYA
select BASEBOARD_BRYA_LAPTOP
select CHROMEOS_DSM_CALIB if CHROMEOS
select DRIVERS_I2C_MAX98390

config BOARD_GOOGLE_REDRIX
bool "-> Redrix"
select BOARD_GOOGLE_BASEBOARD_BRYA

config BOARD_GOOGLE_KANO
bool "-> Kano"
select BOARD_GOOGLE_BASEBOARD_BRYA

config BOARD_GOOGLE_TAEKO
bool "-> Taeko"
select BOARD_GOOGLE_BASEBOARD_BRYA
2 changes: 1 addition & 1 deletion src/mainboard/google/brya/bootblock.c
Expand Up @@ -3,10 +3,10 @@
#include <baseboard/variants.h>
#include <bootblock_common.h>
#include <console/console.h>
#include <intelblocks/mp_init.h>
#include <fmap.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <cpu/intel/cpu_ids.h>
#include <intelblocks/pmclib.h>
#include <cf9_reset.h>

Expand Down
11 changes: 11 additions & 0 deletions src/mainboard/google/brya/mainboard.c
Expand Up @@ -4,8 +4,19 @@
#include <baseboard/variants.h>
#include <device/device.h>
#include <ec/ec.h>
#include <soc/ramstage.h>
#include <vendorcode/google/chromeos/chromeos.h>

void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config)
{
variant_update_soc_chip_config(config);
}

__weak void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config)
{
/* default implementation does nothing */
}

static void mainboard_init(void *chip_info)
{
const struct pad_config *base_pads;
Expand Down
6 changes: 0 additions & 6 deletions src/mainboard/google/brya/variants/baseboard/devicetree.cb
Expand Up @@ -46,12 +46,6 @@ chip soc/intel/alderlake
register "usb2_ports[9]" = "USB2_PORT_MID(OC_SKIP)" # M.2 Bluetooth

register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC3)" # USB3/2 Type A port A0
# TODO(b/184324979): Workaround to enable TCSS ports. FSP v2081
# uses port enable for south XHCI ports to determine if TCSS
# ports should be enabled. Until FSP is fixed, enable south
# XHCI ports 1 and 2.
register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)"
register "usb3_ports[2]" = "USB3_PORT_DEFAULT(OC_SKIP)"
register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" # M.2 WWAN

register "tcss_ports[0]" = "TCSS_PORT_DEFAULT(OC0)"
Expand Down
15 changes: 14 additions & 1 deletion src/mainboard/google/brya/variants/baseboard/gpio.c
Expand Up @@ -58,7 +58,7 @@ static const struct pad_config gpio_table[] = {
/* B2 : VRALERT# ==> M2_SSD_PLA_L */
PAD_CFG_GPO(GPP_B2, 1, PLTRST),
/* B3 : PROC_GP2 ==> SAR2_INT_L */
PAD_CFG_GPI_INT(GPP_B3, NONE, PLTRST, LEVEL),
PAD_CFG_GPI_APIC(GPP_B3, NONE, PLTRST, LEVEL, NONE),
/* B4 : PROC_GP3 ==> SSD_PERST_L */
PAD_CFG_GPO(GPP_B4, 1, DEEP),
/* B5 : ISH_I2C0_SDA ==> PCH_I2C_MISC_SDA */
Expand Down Expand Up @@ -363,6 +363,19 @@ static const struct pad_config gpio_table[] = {
PAD_CFG_NF(GPD10, NONE, DEEP, NF1),
/* GPD11: LANPHYC ==> WWAN_CONFIG1 */
PAD_CFG_GPI(GPD11, NONE, DEEP),

/* Virtual GPIO */
/* Put unused Cnvi BT UART lines in NC mode since we use USB mode. */
PAD_NC(GPP_VGPIO_6, NONE),
PAD_NC(GPP_VGPIO_7, NONE),
PAD_NC(GPP_VGPIO_8, NONE),
PAD_NC(GPP_VGPIO_9, NONE),

/* Put unused Cnvi UART0 lines in NC mode since we use USB mode. */
PAD_NC(GPP_VGPIO_18, NONE),
PAD_NC(GPP_VGPIO_19, NONE),
PAD_NC(GPP_VGPIO_20, NONE),
PAD_NC(GPP_VGPIO_21, NONE),
};

/* Early pad configuration in bootblock */
Expand Down
Expand Up @@ -45,7 +45,9 @@
EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEY_PRESSED) |\
EC_HOST_EVENT_MASK(EC_HOST_EVENT_USB_MUX) |\
EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE))
#define MAINBOARD_EC_S0IX_WAKE_EVENTS (MAINBOARD_EC_S3_WAKE_EVENTS)
#define MAINBOARD_EC_S0IX_WAKE_EVENTS \
(MAINBOARD_EC_S3_WAKE_EVENTS |\
EC_HOST_EVENT_MASK(EC_HOST_EVENT_HANG_DETECT))
/* Log EC wake events plus EC shutdown events */
#define MAINBOARD_EC_LOG_EVENTS \
(EC_HOST_EVENT_MASK(EC_HOST_EVENT_THERMAL_SHUTDOWN) |\
Expand Down
Expand Up @@ -3,6 +3,7 @@
#ifndef __BASEBOARD_VARIANTS_H__
#define __BASEBOARD_VARIANTS_H__

#include <chip.h>
#include <soc/gpio.h>
#include <soc/meminit.h>
#include <stdint.h>
Expand All @@ -19,5 +20,6 @@ const struct cros_gpio *variant_cros_gpios(size_t *num);
const struct mb_cfg *variant_memory_params(void);
int variant_memory_sku(void);
bool variant_is_half_populated(void);
void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config);

#endif /*__BASEBOARD_VARIANTS_H__ */
88 changes: 78 additions & 10 deletions src/mainboard/google/brya/variants/brya0/overridetree.cb
Expand Up @@ -36,6 +36,12 @@ chip soc/intel/alderlake

register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A MLB port

# FIVR configurations for brya are disabled since the board doesn't have V1p05 and Vnn
# bypass rails implemented.
register "ext_fivr_settings" = "{
.configure_ext_fivr = 1,
}"

device domain 0 on
device ref dtt on
chip drivers/intel/dptf
Expand Down Expand Up @@ -126,7 +132,26 @@ chip soc/intel/alderlake
register "cio2_lanes_used" = "{4}" # 4 CSI Camera lanes are used
register "cio2_lane_endpoint[0]" = ""^I2C0.CAM0""
register "cio2_prt[0]" = "2"
device generic 0 on end
device generic 0 on
# MIPI lanes are split between UFC and WFC depending on
# whether the UFC is USB or MIPI hence probing UFC_USB
probe UFC UFC_USB
end
end
chip drivers/intel/mipi_camera
register "acpi_uid" = "0x50000"
register "acpi_name" = ""IPU0""
register "device_type" = "INTEL_ACPI_CAMERA_CIO2"

register "cio2_num_ports" = "2"
register "cio2_lanes_used" = "{4,2}" # 4 and 2 CSI Camera lanes are used
register "cio2_lane_endpoint[0]" = ""^I2C0.CAM0""
register "cio2_lane_endpoint[1]" = ""^I2C2.CAM1""
register "cio2_prt[0]" = "2"
register "cio2_prt[1]" = "1"
device generic 1 on
probe UFC UFC_MIPI_5675
end
end
end
device ref cnvi_wifi on
Expand All @@ -140,17 +165,15 @@ chip soc/intel/alderlake
end
device ref tcss_dma0 on
chip drivers/intel/usb4/retimer
register "dfp" = "{
[0] = {.power_gpio = ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4),
.group = ACPI_PLD_GROUP(1, 1),}}"
register "dfp[0].power_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4)"
use tcss_usb3_port1 as dfp[0].typec_port
device generic 0 on end
end
end
device ref tcss_dma1 on
chip drivers/intel/usb4/retimer
register "dfp" = "{
[0] = {.power_gpio = ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4),
.group = ACPI_PLD_GROUP(3, 1)}}"
register "dfp[0].power_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4)"
use tcss_usb3_port3 as dfp[0].typec_port
device generic 0 on end
end
end
Expand Down Expand Up @@ -307,7 +330,7 @@ chip soc/intel/alderlake
device ref i2c2 on
chip drivers/i2c/sx9324
register "desc" = ""SAR1 Proximity Sensor""
register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_H19_IRQ)"
register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
register "speed" = "I2C_SPEED_FAST"
register "uid" = "1"
register "reg_gnrl_ctrl0" = "0x16"
Expand Down Expand Up @@ -355,7 +378,7 @@ chip soc/intel/alderlake
end
chip drivers/i2c/sx9324
register "desc" = ""SAR2 Proximity Sensor""
register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_B3_IRQ)"
register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_H19_IRQ)"
register "speed" = "I2C_SPEED_FAST"
register "uid" = "2"
register "reg_gnrl_ctrl0" = "0x16"
Expand Down Expand Up @@ -401,6 +424,49 @@ chip soc/intel/alderlake
register "reg_adv_ctrl20" = "0xf0"
device i2c 2C on end
end
chip drivers/intel/mipi_camera
register "acpi_hid" = ""OVTI5675""
register "acpi_uid" = "0"
register "acpi_name" = ""CAM1""
register "chip_name" = ""Ov 5675 Camera""
register "device_type" = "INTEL_ACPI_CAMERA_SENSOR"

register "ssdb.lanes_used" = "2"
register "ssdb.link_used" = "1"
register "ssdb.vcm_type" = "0x0C"
register "vcm_name" = ""VCM0""
register "num_freq_entries" = "1"
register "link_freq[0]" = "DEFAULT_LINK_FREQ"
register "remote_name" = ""IPU0""

register "has_power_resource" = "1"
#Controls
register "clk_panel.clks[0].clknum" = "IMGCLKOUT_2"
register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ"

register "gpio_panel.gpio[0].gpio_num" = "GPP_C3" #PP3300_FCAM_X
register "gpio_panel.gpio[1].gpio_num" = "GPP_A17" #EN_UCAM_PWR
register "gpio_panel.gpio[2].gpio_num" = "GPP_F20" #reset

#_ON
register "on_seq.ops_cnt" = "5"
register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)"
register "on_seq.ops[1]" = "SEQ_OPS_GPIO_ENABLE(0, 5)"
register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(1, 5)"
register "on_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 5)"
register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(2, 5)"

#_OFF
register "off_seq.ops_cnt" = "4"
register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 0)"
register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(2, 0)"
register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)"
register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(0, 0)"

device i2c 36 on
probe UFC UFC_MIPI_5675
end
end
end
device ref i2c3 on end
device ref i2c5 on
Expand Down Expand Up @@ -538,7 +604,9 @@ chip soc/intel/alderlake
chip drivers/usb/acpi
register "desc" = ""USB2 Camera""
register "type" = "UPC_TYPE_INTERNAL"
device ref usb2_port6 on end
device ref usb2_port6 on
probe UFC UFC_USB
end
end
chip drivers/usb/acpi
register "desc" = ""USB2 Type-A Port (MLB)""
Expand Down
2 changes: 2 additions & 0 deletions src/mainboard/google/brya/variants/gimble/Makefile.inc
Expand Up @@ -2,3 +2,5 @@
bootblock-y += gpio.c

ramstage-y += gpio.c

ramstage-$(CONFIG_FW_CONFIG) += fw_config.c
56 changes: 56 additions & 0 deletions src/mainboard/google/brya/variants/gimble/fw_config.c
@@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <bootstate.h>
#include <console/console.h>
#include <fw_config.h>
#include <gpio.h>

static const struct pad_config dmic_enable_pads[] = {
PAD_CFG_NF(GPP_S2, NONE, DEEP, NF2), /* DMIC_CLK0_R */
PAD_CFG_NF(GPP_S3, NONE, DEEP, NF2), /* DMIC_DATA0_R */

};

static const struct pad_config dmic_disable_pads[] = {
PAD_NC(GPP_S2, NONE),
PAD_NC(GPP_S3, NONE),
};

static const struct pad_config i2s_enable_pads[] = {
PAD_CFG_NF(GPP_R0, NONE, DEEP, NF2), /* I2S_HP_SCLK_R */
PAD_CFG_NF(GPP_R1, NONE, DEEP, NF2), /* I2S_HP_SFRM_R */
PAD_CFG_NF(GPP_R2, DN_20K, DEEP, NF2), /* I2S_PCH_TX_HP_RX_STRAP */
PAD_CFG_NF(GPP_R3, NONE, DEEP, NF2), /* I2S_PCH_RX_HP_TX */
PAD_CFG_NF(GPP_R4, NONE, DEEP, NF2), /* I2S_SPKR_SCLK_R */
PAD_CFG_NF(GPP_R5, NONE, DEEP, NF2), /* I2S_SPKR_SFRM_R */
PAD_CFG_NF(GPP_R6, NONE, DEEP, NF2), /* I2S_PCH_TX_SPKR_RX_R */
PAD_CFG_NF(GPP_R7, NONE, DEEP, NF2), /* I2S_PCH_RX_SPKR_TX */
};

static const struct pad_config i2s_disable_pads[] = {
PAD_NC(GPP_R0, NONE),
PAD_NC(GPP_R1, NONE),
PAD_NC(GPP_R2, NONE),
PAD_NC(GPP_R3, NONE),
PAD_NC(GPP_R4, NONE),
PAD_NC(GPP_R5, NONE),
PAD_NC(GPP_R6, NONE),
PAD_NC(GPP_R7, NONE),
};

static void fw_config_handle(void *unused)
{
if (!fw_config_is_provisioned() || fw_config_probe(FW_CONFIG(AUDIO, AUDIO_UNKNOWN))) {
printk(BIOS_INFO, "Disable audio related GPIO pins.\n");
gpio_configure_pads(i2s_disable_pads, ARRAY_SIZE(i2s_disable_pads));
gpio_configure_pads(dmic_disable_pads, ARRAY_SIZE(dmic_disable_pads));
return;
}

if (fw_config_probe(FW_CONFIG(AUDIO, MAX98390_ALC5682I_I2S))) {
printk(BIOS_INFO, "Configure audio over I2S with MAX98390 ALC5682I.\n");
gpio_configure_pads(dmic_enable_pads, ARRAY_SIZE(dmic_enable_pads));
gpio_configure_pads(i2s_enable_pads, ARRAY_SIZE(i2s_enable_pads));
}
}
BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, fw_config_handle, NULL);
Expand Up @@ -2,5 +2,6 @@
## This is an auto-generated file. Do not edit!!

SPD_SOURCES =
SPD_SOURCES += lp4x-spd-1.hex # ID = 0(0b0000) Parts = MT53E512M32D2NP-046 WT:E, H9HCNNNBKMMLXR-NEE
SPD_SOURCES += lp4x-spd-1.hex # ID = 0(0b0000) Parts = MT53E512M32D2NP-046 WT:E, H9HCNNNBKMMLXR-NEE, K4U6E3S4AA-MGCR
SPD_SOURCES += lp4x-spd-3.hex # ID = 1(0b0001) Parts = H9HCNNNCPMMLXR-NEE
SPD_SOURCES += lp4x-spd-4.hex # ID = 2(0b0010) Parts = MT53E1G32D2NP-046 WT:A
Expand Up @@ -2,3 +2,5 @@ DRAM Part Name ID to assign
MT53E512M32D2NP-046 WT:E 0 (0000)
H9HCNNNCPMMLXR-NEE 1 (0001)
H9HCNNNBKMMLXR-NEE 0 (0000)
MT53E1G32D2NP-046 WT:A 2 (0010)
K4U6E3S4AA-MGCR 0 (0000)
@@ -1,3 +1,5 @@
MT53E512M32D2NP-046 WT:E
H9HCNNNCPMMLXR-NEE
H9HCNNNBKMMLXR-NEE
MT53E1G32D2NP-046 WT:A
K4U6E3S4AA-MGCR