1 change: 1 addition & 0 deletions src/drivers/intel/fsp2_0/memory_init.c
Expand Up @@ -379,6 +379,7 @@ void fsp_memory_init(bool s3wake)
_car_unallocated_start - _car_region_start, 0);
memranges_insert(memmap, (uintptr_t)_program, REGION_SIZE(program), 0);

timestamp_add_now(TS_FSP_MEMORY_INIT_LOAD);
if (fsp_load_component(&fspld, hdr) != CB_SUCCESS)
die("FSPM not available or failed to load!\n");

Expand Down
1 change: 1 addition & 0 deletions src/drivers/intel/fsp2_0/silicon_init.c
Expand Up @@ -220,6 +220,7 @@ void fsps_load(void)

void fsp_silicon_init(void)
{
timestamp_add_now(TS_FSP_SILICON_INIT_LOAD);
fsps_load();
do_silicon_init(&fsps_hdr);
}
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/intel/fsp2_0/temp_ram_exit.c
Expand Up @@ -7,7 +7,7 @@
#include <cbfs.h>
#include <types.h>

void fsp_temp_ram_exit(void)
static void fsp_temp_ram_exit(void)
{
struct fsp_header hdr;
uint32_t status;
Expand Down
68 changes: 44 additions & 24 deletions src/drivers/intel/gma/opregion.c
Expand Up @@ -218,46 +218,66 @@ static enum cb_err locate_vbt_vbios_cbfs(struct region_device *rdev)
return locate_vbt_vbios(oprom, rdev);
}

/* Initialize IGD OpRegion, called from ACPI code and OS drivers */
enum cb_err intel_gma_init_igd_opregion(void)
/*
* Try to locate VBT in possible locations and return if found.
* VBT can be possibly in one of 3 regions:
* 1. Stitched directly into CBFS region as VBT
* 2. Part of pci8086 option ROM within CBFS
* 3. part of VBIOS at location 0xC0000.
*/
static enum cb_err find_vbt_location(struct region_device *rdev)
{
igd_opregion_t *opregion;
struct region_device rdev;
optionrom_vbt_t *vbt = NULL;
optionrom_vbt_t *ext_vbt;
bool found = false;

if (acpi_is_wakeup_s3())
return intel_gma_restore_opregion();

/* Search for vbt.bin in CBFS. */
if (locate_vbt_cbfs(&rdev) == CB_SUCCESS &&
vbt_validate(&rdev) == CB_SUCCESS) {
found = true;
if (locate_vbt_cbfs(rdev) == CB_SUCCESS &&
vbt_validate(rdev) == CB_SUCCESS) {
printk(BIOS_INFO, "GMA: Found valid VBT in CBFS\n");
return CB_SUCCESS;
}
/* Search for pci8086,XXXX.rom in CBFS. */
else if (locate_vbt_vbios_cbfs(&rdev) == CB_SUCCESS &&
vbt_validate(&rdev) == CB_SUCCESS) {
found = true;
else if (locate_vbt_vbios_cbfs(rdev) == CB_SUCCESS &&
vbt_validate(rdev) == CB_SUCCESS) {
printk(BIOS_INFO, "GMA: Found valid VBT in VBIOS\n");
return CB_SUCCESS;
}
/*
* Try to locate Intel VBIOS at 0xc0000. It might have been placed by
* Native Graphics Init as fake Option ROM or when coreboot did run the
* VBIOS on legacy platforms.
* TODO: Place generated fake VBT in CBMEM and get rid of this.
*/
else if (locate_vbt_vbios((u8 *)0xc0000, &rdev) == CB_SUCCESS &&
vbt_validate(&rdev) == CB_SUCCESS) {
found = true;
else if (locate_vbt_vbios((u8 *)0xc0000, rdev) == CB_SUCCESS &&
vbt_validate(rdev) == CB_SUCCESS) {
printk(BIOS_INFO, "GMA: Found valid VBT in legacy area\n");
return CB_SUCCESS;
}

if (!found) {
printk(BIOS_ERR, "GMA: VBT couldn't be found\n");
printk(BIOS_ERR, "GMA: VBT couldn't be found\n");
return CB_ERR;
}

/*
* Function to determine if we need to use extended VBT region to pass
* VBT pointer. If VBT size > 6 KiB then we need to use extended VBT
* region.
*/
static inline bool is_ext_vbt_required(igd_opregion_t *opregion, optionrom_vbt_t *vbt)
{
return (vbt->hdr_vbt_size > sizeof(opregion->vbt.gvd1));
}

/* Initialize IGD OpRegion, called from ACPI code and OS drivers */
enum cb_err intel_gma_init_igd_opregion(void)
{
igd_opregion_t *opregion;
struct region_device rdev;
optionrom_vbt_t *vbt = NULL;
optionrom_vbt_t *ext_vbt = NULL;

if (acpi_is_wakeup_s3())
return intel_gma_restore_opregion();

if (find_vbt_location(&rdev) != CB_SUCCESS)
return CB_ERR;
}

vbt = rdev_mmap_full(&rdev);
if (!vbt) {
Expand All @@ -284,7 +304,7 @@ enum cb_err intel_gma_init_igd_opregion(void)
memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild,
ARRAY_SIZE(vbt->coreblock_biosbuild));
/* Extended VBT support */
if (vbt->hdr_vbt_size > sizeof(opregion->vbt.gvd1)) {
if (is_ext_vbt_required(opregion, vbt)) {
ext_vbt = cbmem_add(CBMEM_ID_EXT_VBT, vbt->hdr_vbt_size);

if (ext_vbt == NULL) {
Expand Down
22 changes: 15 additions & 7 deletions src/drivers/intel/mipi_camera/chip.h
Expand Up @@ -14,6 +14,14 @@
#define MAX_GPIO_CONFIGS 4
#define MAX_PWR_OPS 5
#define MAX_GUARDED_RESOURCES 10
#define IMGCLKOUT_0 0
#define IMGCLKOUT_1 1
#define IMGCLKOUT_2 2
#define IMGCLKOUT_3 3
#define IMGCLKOUT_4 4
#define IMGCLKOUT_5 5
#define FREQ_24_MHZ 0
#define FREQ_19_2_MHZ 1

#define SEQ_OPS_CLK_ENABLE(ind, delay) \
{ .type = IMGCLK, .index = (ind), .action = ENABLE, .delay_ms = (delay) }
Expand Down Expand Up @@ -106,31 +114,31 @@ struct clk_config {
uint8_t clknum;
/* frequency setting: 0:24Mhz, 1:19.2 Mhz */
uint8_t freq;
} __packed;
};

struct gpio_config {
uint8_t gpio_num;
} __packed;
uint16_t gpio_num;
};

struct clock_ctrl_panel {
struct clk_config clks[MAX_CLK_CONFIGS];
} __packed;
};

struct gpio_ctrl_panel {
struct gpio_config gpio[MAX_GPIO_CONFIGS];
} __packed;
};

struct operation_type {
enum ctrl_type type;
uint8_t index;
enum action_type action;
uint32_t delay_ms;
} __packed;
};

struct operation_seq {
struct operation_type ops[MAX_PWR_OPS];
uint8_t ops_cnt;
} __packed;
};

struct intel_ssdb {
uint8_t version; /* Current version */
Expand Down
8 changes: 8 additions & 0 deletions src/drivers/intel/pmc_mux/conn/chip.h
Expand Up @@ -23,4 +23,12 @@ struct drivers_intel_pmc_mux_conn_config {
enum typec_orientation hsl_orientation;
};

/*
* Method verifies input "conn" device.
* Returns 'true' if device passed is Intel PMC MUX Conn device else returns 'false'.
* Method also outputs the usb2 and usb3 port numbers associated with the 'conn' device
*/
bool intel_pmc_mux_conn_get_ports(const struct device *conn, unsigned int *usb2_port,
unsigned int *usb3_port);

#endif /* __DRIVERS_INTEL_PMC_MUX_CONN_H__ */
15 changes: 15 additions & 0 deletions src/drivers/intel/pmc_mux/conn/conn.c
Expand Up @@ -85,3 +85,18 @@ struct chip_operations drivers_intel_pmc_mux_conn_ops = {
CHIP_NAME("Intel PMC MUX CONN Driver")
.enable_dev = conn_enable,
};

bool intel_pmc_mux_conn_get_ports(const struct device *conn, unsigned int *usb2_port,
unsigned int *usb3_port)
{
const struct drivers_intel_pmc_mux_conn_config *mux_config;

if (!conn->chip_info || conn->chip_ops != &drivers_intel_pmc_mux_conn_ops)
return false;

mux_config = conn->chip_info;
*usb2_port = mux_config->usb2_port_number;
*usb3_port = mux_config->usb3_port_number;

return true;
};
17 changes: 13 additions & 4 deletions src/drivers/pc80/rtc/mc146818rtc.c
Expand Up @@ -175,6 +175,15 @@ static void wait_uip(void)
;
}

/* Perform a sanity check of current date and time. */
static int cmos_date_invalid(void)
{
struct rtc_time now;

rtc_get(&now);
return rtc_invalid(&now);
}

/*
* If the CMOS is cleared, the rtc_reg has the invalid date. That
* hurts some OSes. Even if we don't set USE_OPTION_TABLE, we need
Expand All @@ -190,11 +199,11 @@ void cmos_check_update_date(void)
year = cmos_read(RTC_CLK_YEAR);

/*
* TODO: If century is 0xFF, 100% that the CMOS is cleared.
* Other than that, so far rtc_year is the only entry to check
* if the date is valid.
* If century is 0xFF, 100% that the CMOS is cleared.
* In addition, check the sanity of all values and reset the date in case of
* insane values.
*/
if (century > 0x99 || year > 0x99) /* Invalid date */
if (century > 0x99 || year > 0x99 || cmos_date_invalid()) /* Invalid date */
cmos_reset_date();
}

Expand Down
6 changes: 6 additions & 0 deletions src/drivers/pcie/rtd3/device/Kconfig
@@ -0,0 +1,6 @@
config DRIVERS_PCIE_RTD3_DEVICE
bool
depends on HAVE_ACPI_TABLES
help
When enabled, this driver will add support for ACPI controlled
Runtime D3 using GPIOs for power/reset control of the PCIe device.
1 change: 1 addition & 0 deletions src/drivers/pcie/rtd3/device/Makefile.inc
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_PCIE_RTD3_DEVICE) += chip.c
169 changes: 169 additions & 0 deletions src/drivers/pcie/rtd3/device/chip.c
@@ -0,0 +1,169 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <acpi/acpigen_pci.h>
#include <assert.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include "chip.h"

/*
* This UUID and the resulting ACPI Device Property is defined by the
* Power Management for Storage Hardware Devices:
*
* https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/power-management-for-storage-hardware-devices-intro
*/
#define PCIE_RTD3_STORAGE_UUID "5025030F-842F-4AB4-A561-99A5189762D0"
#define PCIE_RTD3_STORAGE_PROPERTY "StorageD3Enable"

/*
* Writes the ACPI power resources for a PCI device so it can enter D3Cold.
*
* If the device is a storage class, then the StorageD3Enable _DSD will
* also be added.
*
* e.g.,
*
* Scope (\_SB.PCI0.GP14)
* {
* Device (NVME)
* {
* Name (_PR0, Package (0x01) // _PR0: Power Resources for D0
* {
* PRIC
* })
* Name (_PR3, Package (0x01) // _PR3: Power Resources for D3hot
* {
* PRIC
* })
* PowerResource (PRIC, 0x00, 0x0000)
* {
* Method (_STA, 0, NotSerialized) // _STA: Status
* {
* ...
* }
*
* Method (_ON, 0, Serialized) // _ON_: Power On
* {
* ...
* }
*
* Method (_OFF, 0, Serialized) // _OFF: Power Off
* {
* ...
* }
* }
*
* Name (_ADR, 0x0000000000000000) // _ADR: Address
* Method (_STA, 0, NotSerialized) // _STA: Status
* {
* Return (0x0F)
* }
*
* Name (_DSD, Package (0x02) // _DSD: Device-Specific Data
* {
* ToUUID ("5025030f-842f-4ab4-a561-99a5189762d0"),
* Package (0x01)
* {
* Package (0x02)
* {
* "StorageD3Enable",
* One
* }
* }
* })
* }
* }
*/
static void pcie_rtd3_device_acpi_fill_ssdt(const struct device *dev)
{
struct acpi_dp *dsd, *pkg;
const struct drivers_pcie_rtd3_device_config *config = config_of(dev);
/* Copy the GPIOs to avoid discards 'const' qualifier error */
struct acpi_gpio reset_gpio = config->reset_gpio;
struct acpi_gpio enable_gpio = config->enable_gpio;
const struct acpi_power_res_params power_res_params = {
.reset_gpio = &reset_gpio,
.reset_delay_ms = config->reset_delay_ms,
.reset_off_delay_ms = config->reset_off_delay_ms,
.enable_gpio = &enable_gpio,
.enable_delay_ms = config->enable_delay_ms,
.enable_off_delay_ms = config->enable_off_delay_ms,
.use_gpio_for_status = true,
};
const char *scope = acpi_device_scope(dev);
const char *name = acpi_device_name(dev);

assert(name);
assert(scope);

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

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

acpi_device_add_power_res(&power_res_params);

acpigen_write_ADR_pci_device(dev);
acpigen_write_STA(acpi_device_status(dev));

/* Storage devices won't enter D3 without this property */
if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) {
dsd = acpi_dp_new_table("_DSD");
pkg = acpi_dp_new_table(PCIE_RTD3_STORAGE_UUID);
acpi_dp_add_integer(pkg, PCIE_RTD3_STORAGE_PROPERTY, 1);
acpi_dp_add_package(dsd, pkg);
acpi_dp_write(dsd);

printk(BIOS_INFO, "%s.%s: Added StorageD3Enable property\n", scope, name);
}

acpigen_write_device_end();
acpigen_write_scope_end();

/* Call the default PCI acpi_fill_ssdt */
pci_rom_ssdt(dev);
}

static const char *pcie_rtd3_device_acpi_name(const struct device *dev)
{
const struct drivers_pcie_rtd3_device_config *config = config_of(dev);

return config->name;
}

static struct device_operations pcie_rtd3_device_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = pci_dev_init,
.ops_pci = &pci_dev_ops_pci,
.write_acpi_tables = pci_rom_write_acpi_tables,
.acpi_fill_ssdt = pcie_rtd3_device_acpi_fill_ssdt,
.acpi_name = pcie_rtd3_device_acpi_name,
};

static void pcie_rtd3_device_enable(struct device *dev)
{
struct drivers_pcie_rtd3_device_config *config = dev ? dev->chip_info : NULL;

if (!config)
return;

if (dev->path.type != DEVICE_PATH_PCI) {
printk(BIOS_ERR, "%s: Invalid device type\n", dev_path(dev));
return;
}

dev->ops = &pcie_rtd3_device_ops;
}

struct chip_operations drivers_pcie_rtd3_device_ops = {
CHIP_NAME("PCIe Device w/ Runtime D3")
.enable_dev = pcie_rtd3_device_enable
};
28 changes: 28 additions & 0 deletions src/drivers/pcie/rtd3/device/chip.h
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __DRIVERS_PCIE_RTD3_DEVICE_CHIP_H__
#define __DRIVERS_PCIE_RTD3_DEVICE_CHIP_H__

#include <acpi/acpi_device.h>

/* Adds a GPIO controlled ACPI PowerResource for a PCIe device. */
struct drivers_pcie_rtd3_device_config {
/* Name of ACPI node for the device */
const char *name;

/* GPIO used to enable device. */
struct acpi_gpio enable_gpio;
/* Delay to be inserted after device is enabled. */
unsigned int enable_delay_ms;
/* Delay to be inserted after device is disabled. */
unsigned int enable_off_delay_ms;

/* GPIO used to take device out of reset or to put it into reset. */
struct acpi_gpio reset_gpio;
/* Delay to be inserted after device is taken out of reset. */
unsigned int reset_delay_ms;
/* Delay to be inserted after device is put into reset. */
unsigned int reset_off_delay_ms;
};

#endif /* __DRIVERS_PCIE_RTD3_DEVICE_CHIP_H__ */
1 change: 1 addition & 0 deletions src/drivers/smmstore/Kconfig
Expand Up @@ -9,6 +9,7 @@ config SMMSTORE
config SMMSTORE_V2
bool "Use version 2 of SMMSTORE API"
depends on SMMSTORE
default y if TIANOCORE_UEFIPAYLOAD
default n
help
Version 2 of SMMSTORE allows secure communication with SMM and
Expand Down
8 changes: 8 additions & 0 deletions src/drivers/spi/winbond.c
Expand Up @@ -190,6 +190,14 @@ static const struct spi_flash_part_id flash_table[] = {
.protection_granularity_shift = 18,
.bp_bits = 3,
},
{
/* W25Q512NW-IM */
.id[0] = 0x8020,
.nr_sectors_shift = 11,
.fast_read_dual_output_support = 1,
.protection_granularity_shift = 16,
.bp_bits = 4,
},
{
/* W25Q256_V */
.id[0] = 0x4019,
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/tpm/Kconfig
@@ -1,6 +1,6 @@
config TPM_INIT_RAMSTAGE
bool
default y if TPM1 || TPM2
default y if TPM
depends on !VBOOT && !VENDORCODE_ELTAN_VBOOT && !VENDORCODE_ELTAN_MBOOT \
&& !TPM_MEASURED_BOOT_INIT_BOOTBLOCK
help
Expand All @@ -9,7 +9,7 @@ config TPM_INIT_RAMSTAGE

config TPM_PPI
bool "Generate ACPI code to implement TPM physical presence interface"
depends on TPM1 || TPM2
depends on TPM
depends on HAVE_ACPI_TABLES
depends on !CHROMEOS
default y if PAYLOAD_TIANOCORE
Expand Down
5 changes: 5 additions & 0 deletions src/ec/google/chromeec/Makefile.inc
Expand Up @@ -13,6 +13,11 @@ smm-$(CONFIG_EC_GOOGLE_CHROMEEC_SKUID) += ec_skuid.c
romstage-$(CONFIG_EC_GOOGLE_CHROMEEC_SKUID) += ec_skuid.c
ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC_SKUID) += ec_skuid.c

ifeq ($(CONFIG_GENERATE_SMBIOS_TABLES),y)
romstage-$(CONFIG_EC_GOOGLE_CHROMEEC_SKUID) += ec_smbios.c
ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC_SKUID) += ec_smbios.c
endif

bootblock-y += ec.c
bootblock-$(CONFIG_EC_GOOGLE_CHROMEEC_LPC) += ec_lpc.c
ramstage-y += ec.c crosec_proto.c vstore.c
Expand Down
2 changes: 1 addition & 1 deletion src/ec/google/chromeec/ec_lpc.c
Expand Up @@ -465,7 +465,7 @@ u8 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 1;
return 0;
}

/* Issue the ACPI query-event command */
Expand Down
36 changes: 0 additions & 36 deletions src/ec/google/chromeec/ec_skuid.c
@@ -1,11 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <stddef.h>
#include <boardid.h>
#include <ec/google/chromeec/ec.h>
#include <console/console.h>
#include <string.h>
#include <smbios.h>

uint32_t google_chromeec_get_board_sku(void)
{
Expand All @@ -19,35 +15,3 @@ uint32_t google_chromeec_get_board_sku(void)

return sku_id;
}

const char *google_chromeec_smbios_system_sku(void)
{
static char sku_str[14]; /* sku{0..2147483647} */
uint32_t sku_id = google_chromeec_get_board_sku();
snprintf(sku_str, sizeof(sku_str), "sku%u", sku_id);
return sku_str;
}

const char *smbios_system_sku(void)
{
return google_chromeec_smbios_system_sku();
}

const char *smbios_mainboard_manufacturer(void)
{
static char oem_name[32];
static const char *manuf;

if (manuf)
return manuf;

if (google_chromeec_cbi_get_oem_name(&oem_name[0],
ARRAY_SIZE(oem_name)) < 0) {
printk(BIOS_ERR, "Couldn't obtain OEM name from CBI\n");
manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
} else {
manuf = &oem_name[0];
}

return manuf;
}
39 changes: 39 additions & 0 deletions src/ec/google/chromeec/ec_smbios.c
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <stddef.h>
#include <ec/google/chromeec/ec.h>
#include <console/console.h>
#include <string.h>
#include <smbios.h>

const char *google_chromeec_smbios_system_sku(void)
{
static char sku_str[14]; /* sku{0..2147483647} */
uint32_t sku_id = google_chromeec_get_board_sku();
snprintf(sku_str, sizeof(sku_str), "sku%u", sku_id);
return sku_str;
}

const char *smbios_system_sku(void)
{
return google_chromeec_smbios_system_sku();
}

const char *smbios_mainboard_manufacturer(void)
{
static char oem_name[32];
static const char *manuf;

if (manuf)
return manuf;

if (google_chromeec_cbi_get_oem_name(&oem_name[0],
ARRAY_SIZE(oem_name)) < 0) {
printk(BIOS_ERR, "Couldn't obtain OEM name from CBI\n");
manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
} else {
manuf = &oem_name[0];
}

return manuf;
}
7 changes: 7 additions & 0 deletions src/ec/google/wilco/Kconfig
Expand Up @@ -7,6 +7,13 @@ config EC_GOOGLE_WILCO
help
Google Wilco Embedded Controller interface.

Note, the Wilco EC firmware is a modified version of Dell's
typical Latitude EC firmware, that implements a custom mailbox
protocol similar to the one used in the Chromium EC.

This particular EC firmware is not open source, just the
host-side interfaces (kernel and firmware drivers) are.

if EC_GOOGLE_WILCO

config EC_BASE_ACPI_DATA
Expand Down
2 changes: 1 addition & 1 deletion src/ec/google/wilco/acpi/vbtn.asl
Expand Up @@ -5,7 +5,7 @@
* the Linux kernel at drivers/platform/x86/intel-vbtn.c
*
* For tablet/laptop and dock/undock events to work the board must
* select SYSTEM_TYPE_CONVERTIBLE for the SMBIOS enclosure type to
* have SMBIOS_ENCLOSURE_CONVERTIBLE for the SMBIOS enclosure type to
* indicate the device is a convertible.
*/

Expand Down
4 changes: 2 additions & 2 deletions src/ec/kontron/kempld/kempld_internal.h
Expand Up @@ -12,8 +12,8 @@

/* indexed registers */
#define KEMPLD_SPEC 0x06
#define KEMPLD_SPEC_GET_MINOR(x) (x & 0x0f)
#define KEMPLD_SPEC_GET_MAJOR(x) (x >> 4 & 0x0f)
#define KEMPLD_SPEC_GET_MINOR(x) ((x) & 0x0f)
#define KEMPLD_SPEC_GET_MAJOR(x) ((x) >> 4 & 0x0f)

#define KEMPLD_CFG 0x37
#define KEMPLD_CFG_GPIO_I2C_MUX (1 << 0)
Expand Down
8 changes: 5 additions & 3 deletions src/ec/purism/librem/acpi/ec.asl
Expand Up @@ -176,12 +176,14 @@ Device (EC)
Notify (\_SB.SLPB, 0x80)
}

/* KEY_F13 (Touchpad Enable/Disable) */
Method (_Q34)
/* KEY_F13 (Touchpad Enable/Disable) /*
/* Disabled since enabling breaks functionality
with Linux topstar driver */
/* Method (_Q34)
{
TPSN (0x87)
^TPAD ^= 1
}
} */

/* KEY_WLAN */
Method (_Q35)
Expand Down
7 changes: 7 additions & 0 deletions src/ec/starlabs/it8987/Kconfig
@@ -0,0 +1,7 @@
## SPDX-License-Identifier: GPL-2.0-only

config EC_STARLABS_IT8987
bool
select EC_ACPI
help
Interface to IT8987 embedded controller principally in Star Labs notebooks.
26 changes: 26 additions & 0 deletions src/ec/starlabs/it8987/Makefile.inc
@@ -0,0 +1,26 @@
## SPDX-License-Identifier: GPL-2.0-only

PHONY+=add_ite_fw
INTERMEDIATE+=add_ite_fw

ifeq ($(CONFIG_EC_STARLABS_IT8987),y)
all-y += ec.c
smm-$(CONFIG_DEBUG_SMI) += ec.c
endif

ifeq ($(CONFIG_EC_STARLABS_IT8987_BIN),y)

ifeq ($(CONFIG_EC_STARLABS_IT8987_BIN_PATH),)
files_added:: warn_no_ite_fw
endif

add_ite_fw: $(obj)/coreboot.pre
$(CBFSTOOL) $(obj)/coreboot.pre write -r EC -f $(CONFIG_EC_STARLABS_IT8987_BIN_PATH) -u
endif

PHONY+=warn_no_ite_fw
warn_no_ite_fw:
printf "\n\t** WARNING **\n"
printf "coreboot has been built without the IT8987 EC Firmware.\n"
printf "Do not flash this image. Your LabTop Mk IV's power button\n"
printf "may not respond when you press it.\n\n"
60 changes: 60 additions & 0 deletions src/ec/starlabs/it8987/acpi/ac.asl
@@ -0,0 +1,60 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Device (ADP1)
{
Name (_HID, "ACPI0003")
Name (_PCL, Package () { \_SB })

Method (_STA, 0, NotSerialized) // _STA: Status
{
If (ECON == 1)
{
Local0 = 0x0F
}
Else
{
Local0 = 0
}
Return (Local0)
}

Method (_PSR, 0, NotSerialized) // _PSR: Power Source
{
If (ECWR & 0x01)
{
\PWRS = 1
}
Else
{
\PWRS = 0
}
Return (\PWRS)
}
}

Method (_QA0, 0, NotSerialized) // AC Power Connected
{
If (ECWR & 0x01)
{
\PWRS = 1
}
Else
{
\PWRS = 0
}

// 500ms delay - Not used in coreboot
// Sleep (500)
Notify (BAT0, 0x81)
// Sleep (500)
Notify (ADP1, 0x80)
}

Method(_Q0B, 0, NotSerialized) // Battery Connected
{
// 500ms delay - Not used in coreboot
// Sleep (500)
Notify (BAT0, 0x81)
// Sleep (500)
Notify (BAT0, 0x80)
}
77 changes: 77 additions & 0 deletions src/ec/starlabs/it8987/acpi/battery.asl
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Device (BAT0)
{
Name (_HID, EISAID ("PNP0C0A"))
Name (_UID, 1)
Name (_PCL, Package () { \_SB })

// Battery Slot Status
Method (_STA, 0, Serialized)
{
If (ECWR & 0x02)
{
Return (0x1F)
}
Return (0x0F)
}

// Default Static Battery Information
Name (BPKG, Package (13)
{
1, // 0: Power Unit
0xFFFFFFFF, // 1: Design Capacity
0xFFFFFFFF, // 2: Last Full Charge Capacity
1, // 3: Battery Technology(Rechargeable)
0xFFFFFFFF, // 4: Design Voltage 10.8V
0, // 5: Design capacity of warning
0, // 6: Design capacity of low
0x64, // 7: Battery capacity granularity 1
0, // 8: Battery capacity granularity 2
"CN6613-2S3P", // 9: Model Number
"6UA3", // 10: Serial Number
"Real", // 11: Battery Type
"GDPT" // 12: OEM Information
})

Method (_BIF, 0, Serialized)
{
BPKG[1] = B1DC
BPKG[2] = B1FC
BPKG[4] = B1FV
If (B1FC)
{
BPKG[5] = B1FC / 10
BPKG[6] = B1FC / 25
BPKG[7] = B1DC / 100
}

Return (BPKG)
}

Name (PKG1, Package (4)
{
0xFFFFFFFF, // Battery State
0xFFFFFFFF, // Battery Present Rate
0xFFFFFFFF, // Battery Remaining Capacity
0xFFFFFFFF, // Battery Present Voltage
})

Method (_BST, 0, Serialized)
{


PKG1[0] = B1ST & 0x07
If (B1ST & 0x01)
{
PKG1[1] = B1CR
}
Else
{
PKG1[1] = B1CR
}
PKG1[2] = B1RC
PKG1[3] = B1VT
Return (PKG1)
}
}
18 changes: 18 additions & 0 deletions src/ec/starlabs/it8987/acpi/cmos.asl
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */

OperationRegion (CMOS, SystemIO, 0x70, 0x02)
Field (CMOS, ByteAcc, NoLock, Preserve)
{
NVRI, 8,
NVRD, 8
}

IndexField (NVRI, NVRD, ByteAcc, NoLock, Preserve)
{
Offset (0x40),
KBBL, 8, // Keyboard backlight timeout
FNSW, 8, // Ctrl Fn Reverse (make keyboard Apple-like)

Offset (0x7D),
FNLC, 8 // Current state of Fn Lock key.
}
379 changes: 379 additions & 0 deletions src/ec/starlabs/it8987/acpi/ec.asl
@@ -0,0 +1,379 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#define ASL_PVOL_DEFOF_NUM 0xe8

Scope(\)
{
// These fields come from the Global NVS area
Field (GNVS,AnyAcc,Lock,Preserve)
{
Offset(33),
B2SC, 8, // (33) Battery 2 Stored Capacity
Offset(36),
B2SS, 8 // (36) Battery 2 Stored Status
}
}

Scope (\_SB)
{
#include "hid.asl"
}

Scope (\_SB.PCI0)
{
// Add the entries for the PS/2 keyboard and mouse.
#include <drivers/pc80/pc/ps2_controller.asl>
}

Scope (\_SB.PCI0.LPCB)
{
// Include the definitions for accessing CMOS.
#include "cmos.asl"

// Our embedded controller device.
Device (H_EC)
{
Name (_HID, EISAID ("PNP0C09")) // ACPI Embedded Controller
Name (_UID, 1)
Name (_GPE, EC_GPE_SCI)

// ECDT (Embedded Controller Boot Resources Table) Check to correct
// ECAV flag in the beginning
Name(ECTK, 1)
Name(ECFG, 0)
Name(WIBT, 0)
Name(APST, 0)

Name(ECON, 1) // AC debug
Name(BNUM, 0) // Number Of Batteries Present
Name(PVOL, ASL_PVOL_DEFOF_NUM)
Name(B1CC, 0)
Name(B2CC, 0)

Name(B2ST, 0)
Name(CFAN, 0)
Name(CMDR, 0)
Name(DOCK, 0)
Name(EJET, 0)
Name(MCAP, 0)
Name(PLMX, 0)
Name(PECH, 0)
Name(PECL, 0)
Name(PENV, 0)
Name(PINV, 0)
Name(PPSH, 0)
Name(PPSL, 0)
Name(PSTP, 0)
Name(RPWR, 0)
Name(LIDS, 0)
Name(SLPC, 0)
Name(VPWR, 0)
Name(WTMS, 0)
Name(AWT2, 0)
Name(AWT1, 0)
Name(AWT0, 0)
Name(DLED, 0)
Name(IBT1, 0)
Name(ECAV, 1) // Support DPTF feature
Name(SPT2, 0)
Name(PB10, 0)
Name(IWCW, 0)
Name(IWCR, 0)
Name(BTEN, 0)
Mutex(ECMT, 0)

Method (_CRS, 0, Serialized)
{
Name (BFFR, ResourceTemplate()
{
IO (Decode16, 0x62, 0x62, 0x00, 0x01)
IO (Decode16, 0x66, 0x66, 0x00, 0x01)
})
Return (BFFR)
}

Method (_STA, 0, NotSerialized)
{
If ((ECON == 1))
{
Return (0x0F)
}

Return (0x00)
}

Name (ECOK, Zero)
Method(_REG, 2, NotSerialized)
{
If ((Arg0 == 0x03) && (Arg1 == 0x01))
{
ECOS = 1
ECAV = 1

// Unconditionally fix up the Battery and Power State.

// Initialize the Number of Present Batteries.
// 1 = Real Battery 1 is present
// 2 = Real Battery 2 is present
// 3 = Real Battery 1 and 2 are present
BNUM = 0
BNUM |= ((ECRD (RefOf (ECWR)) & 0x02) >> 1)

// Save the current Power State for later.
// Store (PWRS, Local0)

// Initialize the Power State.
// BNUM = 0 = Virtual Power State
// BNUM > 0 = Real Power State
If (BNUM == 0x00)
{
\PWRS = ECRD (RefOf (VPWR))
}
Else
{
\PWRS = (ECRD (RefOf (ECWR)) & 0x01)
}
PNOT()

/* Initialize LID switch state */
\LIDS = LIDS
}

// Flag that the OS supports ACPI.
\_SB.PCI0.LPCB.H_EC.ECOS = 1
}

Name (S3OS, Zero)
Method (PTS, 1, Serialized)
{
Debug = Concatenate("EC: PTS: ", ToHexString(Arg0))
If (ECOK) {
S3OS = ECOS
}
\_SB.PCI0.LPCB.H_EC.ECOS = 0
}

Method (WAK, 1, Serialized)
{
Debug = Concatenate("EC: WAK: ", ToHexString(Arg0))
If (ECOK) {
ECOS = S3OS
}
\_SB.PCI0.LPCB.H_EC.ECOS = 1
}

OperationRegion (SIPR, SystemIO, 0xB2, 0x1)
Field (SIPR, ByteAcc, Lock, Preserve)
{
SMB2, 8
}

// EC RAM fields
OperationRegion(ECF2, EmbeddedControl, 0, 0xFF)
Field (ECF2, ByteAcc, Lock, Preserve)
{
XXX0, 8, // EC Firmware main- version number.
XXX1, 8, // EC Firmware sub- version number.
XXX2, 8, // EC Firmware test- version number.

Offset(0x06),
SKID, 8, // SKU ID

Offset(0x11),
KBCD, 8, // Key / Touch Pad disable/enable bit
ECOS, 8, // Enter OS flag
HDAO, 8,
ECHK, 8, // Hot keys flag

Offset(0x18),
KLBS, 8, // Keyboard backlight begin.
KLBE, 8, // Keyboard backlight status.

Offset(0x1A),
KBLT, 8, // Keyboard Backlight Timeout
PWPF, 8, // Power Profile

Offset(0x1E),
BTHP,8, // Health Battery Percentage

Offset(0x20),
RCMD, 8, // Same function as IO 66 port to send EC command
RCST, 8, // Report status for the result of command execution

Offset(0x2C),
FNST, 8, // FN LOCK key status.

Offset(0x3F),
SFAN, 8, // Set Fan Speed.
BTMP, 16, // Battery Temperature.
BCNT, 16, // Battery Cycle Count.
FRMP, 16, // Fan Current Speed.

Offset(0x60),
TSR1, 8, // Thermal Sensor Register 1 [CPU VR (IMVP) Temp on RVP]
TSR2, 8, // Thermal Sensor Register 2 [Heat exchanger fan temp on RVP]
TER4, 8, // Thermal Sensor Register 3 (skin temperature)

Offset(0x63),
TSI,4, // [0..3] 0 = SEN1 - CPU VR temperature sensor
// 1 = SEN2 - Heat Exchanger temperature sensor
// 2 = SEN3 - Skin temperature sensor
// 3 = SEN4 - Ambient temperature sensor
// 4 = SEN5 - DIMM temperature sensor [IR sensor 1 on WSB]
// 5 = SEN6 - not used on RVP
HYST, 4, // [4..7] - Hysteresis in degC.
TSHT, 8, // Thermal Sensor (N) high trip point(set default value =70)
TSLT, 8, // Thermal Sensor (N) low trip point (set default value =70)
TSSR, 8, // TSSR- thermal sensor status register (set bit2 =1)
// BIT0:SEN1 - CPU VR Temp Sensor Trip Flag
// BIT1:SEN2 - Fan Temp Sensor Trip Flag
// BIT2:SEN3 - Skin Temp Sensor Trip Flag
// BIT3:SEN4 - Ambient Temp Sensor Trip Flag
// BIT4:Reserved
// BIT5:Reserved
// BIT6:Reserved
// BIT7:Reserved
CHGR, 16, // Charge Rate

Offset(0x70),
CPTM, 8, // CPU Temperature

Offset(0x72),
TER2, 8, // Charger Temperature, Charger thermistor support

Offset(0x7F),
LSTE, 1, // Lid feature
// BIT0LID GPI
, 7, // Reserved

Offset(0x80),
ECWR, 8, // AC & Battery status
XX10, 8, // Battery#1 Model Number Code
XX11, 16, // Battery#1 Serial Number
B1DC, 16, // Battery#1 Design Capacity
B1FV, 16, // Battery#1 Design Voltage
B1FC, 16, // Battery#1 Last Full Charge Capacity
XX15, 16, // Battery#1 Trip Point
B1ST, 8, // Battery#1 State
B1CR, 16, // Battery#1 Present Rate
B1RC, 16, // Battery#1 Remaining Capacity
B1VT, 16, // Battery#1 Present Voltage
BPCN, 8, // Battery#1 Remaining percentage

// USB Type C Mailbox Interface// PPM->OPM Message In
Offset(0xc0),
MGI0, 8,
MGI1, 8,
MGI2, 8,
MGI3, 8,
MGI4, 8,
MGI5, 8,
MGI6, 8,
MGI7, 8,
MGI8, 8,
MGI9, 8,
MGIA, 8,
MGIB, 8,
MGIC, 8,
MGID, 8,
MGIE, 8,
MGIF, 8,

// USB Type C Mailbox Interface// OPM->PPM Message Out
MGO0, 8,
MGO1, 8,
MGO2, 8,
MGO3, 8,
MGO4, 8,
MGO5, 8,
MGO6, 8,
MGO7, 8,
MGO8, 8,
MGO9, 8,
MGOA, 8,
MGOB, 8,
MGOC, 8,
MGOD, 8,
MGOE, 8,
MGOF, 8,

// USB Type C UCSI DATA Structure.
VER1, 8,
VER2, 8,
RSV1, 8,
RSV2, 8,

// PPM->OPM CCI indicator
CCI0, 8,
CCI1, 8,
CCI2, 8,
CCI3, 8,

// OPM->PPM Control message
CTL0, 8,
CTL1, 8,
CTL2, 8,
CTL3, 8,
CTL4, 8,
CTL5, 8,
CTL6, 8,
CTL7, 8,

Offset(0xF0),
, 3,// BIT0 .. BIT2 Reserved
TPCC, 1,// BIT3 TypeC connection bit
, 2,// BIT4 .. BIT5 Reserved
DRMD, 1,// Bit6 Dual Role Mode. 0->DFP: Host mode; 1->UFP: Device Mode.
, 1,// BIT7 Reserved
}

Method (ECMD, 0, Serialized)
{
}

Method (ECWT, 2, Serialized,,, {IntObj, FieldUnitObj})
{
Local0 = Acquire (ECMT, 1000)
If (Local0 == 0x00)
{
If (ECAV)
{
// Execute write to Embedded Controller
Arg1 = Arg0
}
Release (ECMT)
}
}

Method (ECRD, 1, Serialized, 0, IntObj, FieldUnitObj)
{
Local0 = Acquire (ECMT, 1000)
If (Local0 == 0)
{
If (ECAV)
{
// Execute read from Embedded Controller
Local1 = DerefOf (Arg0)
Release (ECMT)
Return (Local1)
}
Else
{
Release (ECMT)
}
}
Return (Local1)
}

// Include the other parts of the Embedded Controller ASL.
#include "keyboard.asl"
#include "battery.asl"
#include "ac.asl"
#include "lid.asl"

// Method(_Q45) // SMM Mode - Not used in coreboot
// {
// SMB2 = 0xC1
// }
}
}
251 changes: 251 additions & 0 deletions src/ec/starlabs/it8987/acpi/hid.asl
@@ -0,0 +1,251 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Device (HIDD)
{
Name (_HID, "INT33D5")
Name (HBSY, Zero)
Name (HIDX, Zero)
Name (HMDE, Zero)
Name (HRDY, Zero)
Name (BTLD, Zero)
Name (BTS1, Zero)
Name (HEB1, 0x3003)

Method (_STA, 0, Serialized) // _STA: Status
{
If ((OSYS >= 0x07DD))
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}

Method (HDDM, 0, Serialized)
{
Store ("-----> HDDM", Debug)
Name (DPKG, Package (0x04)
{
0x11111111,
0x22222222,
0x33333333,
0x44444444
})
Return (DPKG)
}

Method (HDEM, 0, Serialized)
{
Store ("-----> HDEM", Debug)
HBSY = Zero
If ((HMDE == Zero))
{
Return (HIDX)
}
Return (HMDE)
}

Method (HDMM, 0, Serialized)
{
Store ("-----> HDMM", Debug)
Return (HMDE)
}

Method (HDSM, 1, Serialized)
{
Store ("-----> HDSM", Debug)
HRDY = Arg0
}

Method (HPEM, 1, Serialized)
{
Store ("-----> HPEM", Debug)
HBSY = One
HIDX = Arg0

Notify (HIDD, 0xC0)
Local0 = Zero
While ((Local0 < 0xFA) && HBSY)
{
Sleep (0x04)
Local0++
}

If (HBSY == One)
{
HBSY = Zero
HIDX = Zero
Return (One)
}
Else
{
Return (Zero)
}
}

Method (BTNL, 0, Serialized)
{
Store ("-----> BTNL", Debug)
If (CondRefOf (\_SB.PWRB.PBST))
{
\_SB.PWRB.PBST = Zero
Notify (PWRB, One) // Device Check
}

BTLD = One
// If ((AEAB == One))
// {
BTS1 = 0x1F
\_SB.PCI0.LPCB.H_EC.ECWT (BTS1, RefOf (\_SB.PCI0.LPCB.H_EC.BTEN))
// }
// Else
// {
// BTS1 = Zero
// }
}

Method (BTNE, 1, Serialized)
{
Store ("-----> BTNE", Debug)
// If ((AEAB == One))
// {
BTS1 = ((Arg0 & 0x1E) | One)
\_SB.PCI0.LPCB.H_EC.ECWT (BTS1, RefOf (\_SB.PCI0.LPCB.H_EC.BTEN))
// }
}

Method (BTNS, 0, Serialized)
{
Store ("-----> BTNS", Debug)
// If ((AEAB == One))
// {
BTS1 = \_SB.PCI0.LPCB.H_EC.ECRD (RefOf (\_SB.PCI0.LPCB.H_EC.BTEN))
// }
Return (BTS1)
}

Method (BTNC, 0, Serialized)
{
Store ("-----> BTNC", Debug)
// If ((AEAB == One))
// {
Return (0x1F)
// }
// Else
// {
// Return (Zero)
// }
}

Name (HEB2, Zero)
Method (HEBC, 0, Serialized)
{
Store ("-----> HEBC", Debug)
// If ((AHDB == One))
// {
// Return (\HEB1)
// }
// Else
// {
Return (Zero)
// }
}

Method (H2BC, 0, Serialized)
{
Store ("-----> H2BC", Debug)
// If ((AHDB == One))
// {
// Return (\HEB1)
// }
// Else
// {
Return (Zero)
// }
}

Method (HEEC, 0, Serialized)
{
Store ("-----> HEEC", Debug)
// If ((AHDB == One))
// {
Return (HEB2) /* \_SB_.HIDD.HEB2 */
// }
// Else
// {
// Return (Zero)
// }
}

Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method
{
If ((Arg0 == ToUUID ("eeec56b3-4442-408f-a792-4edd4d758054")))
{
If ((One == ToInteger (Arg1)))
{
Switch (ToInteger (Arg2))
{
Case (Zero)
{
Return (Buffer (0x02)
{
0xFF, 0x03
})
}
Case (One)
{
BTNL ()
}
Case (0x02)
{
Return (HDMM ())
}
Case (0x03)
{
HDSM (DerefOf (Arg3 [Zero]))
}
Case (0x04)
{
Return (HDEM ())
}
Case (0x05)
{
Return (BTNS ())
}
Case (0x06)
{
BTNE (DerefOf (Arg3 [Zero]))
}
Case (0x07)
{
Return (HEBC ())
}
Case (0x08)
{
}
Case (0x09)
{
Return (H2BC ())
}
}
}
}

Return (Buffer (One)
{
0x00
})
}
}

Method (PWPR, 0, Serialized)
{
Notify (HIDD, 0xCE)
}

Method (PWRR, 0, Serialized)
{
Notify (HIDD, 0xCF)
}
63 changes: 63 additions & 0 deletions src/ec/starlabs/it8987/acpi/keyboard.asl
@@ -0,0 +1,63 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Method(_Q80) // Volume up
{
Store ("-----> _Q80", Debug)
Notify (\_SB.HIDD, 0xC4)
Notify (\_SB.HIDD, 0xC5)
Store ("<----- _Q80", Debug)
}

Method(_Q81) // Volume down
{
Store ("-----> _Q81", Debug)
Notify (\_SB.HIDD, 0xC6)
Notify (\_SB.HIDD, 0xC7)
Store ("<----- _Q81", Debug)
}

Method(_Q99) // Wireless mode
{
Store ("-----> _Q99", Debug)
\_SB.HIDD.HPEM(8)
Store ("<----- _Q80", Debug)
}

Method(_Q06) // Brightness decrease
{
\_SB.PCI0.GFX0.DECB()
}

Method(_Q07) // Brightness increase
{
\_SB.PCI0.GFX0.INCB()
}

Method(_Q08) // FN lock QEvent
{
FNLC = FNST
}

Method(_Q54) // Power Button Event
{
Store ("-----> _Q54", Debug)
If (CondRefOf (\_SB.PWRB))
{
Notify(\_SB.PWRB, 0x80)
}
Store ("<----- _Q54", Debug)
}

Method(_QD5) // 10 second power button press
{
Store ("-----> _QD5", Debug)
\_SB.PWPR()
Store ("<----- _QD5", Debug)
}

Method(_QD6) // 10 second power button de-press
{
Store ("-----> _QD6", Debug)
\_SB.PWRR()
Store ("<----- _QD6", Debug)
}
47 changes: 47 additions & 0 deletions src/ec/starlabs/it8987/acpi/lid.asl
@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Device (LID0)
{
Name (_HID, EisaId ("PNP0C0D"))

Method (_STA, 0, NotSerialized)
{
DEBUG = "---> IT8987 LID: _STA"
Return (0x0F)
}

Method (_PSW, 1, NotSerialized)
{
DEBUG = Concatenate ("---> IT8987 LID: _PSW", ToHexString(Arg0))
}

Method (_LID, 0, NotSerialized)
{
DEBUG = "---> IT8987 LID: _LID"
If (\_SB.PCI0.LPCB.H_EC.ECRD (RefOf (\_SB.PCI0.LPCB.H_EC.LSTE)) == 0x01)
{
Local0 = 1
}
else
{
Local0 = 0
}
Return (Local0)
}
}

Method (_Q0C, 0, NotSerialized) // Lid close event
{
DEBUG = "---> IT8987 LID: Q0C (close event)"
LIDS = 0
\LIDS = LIDS
Notify (LID0, 0x80)
}

Method (_Q0D, 0, NotSerialized) // Lid open event
{
DEBUG = "---> IT8987 LID: Q0D (open event)"
LIDS = 1
\LIDS = LIDS
Notify (LID0, 0x80)
}
14 changes: 14 additions & 0 deletions src/ec/starlabs/it8987/acpi/thermal.asl
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-only */

Method(_QF0) // Thermal event.
{
If (LEqual (DBGS, 0x00))
{
/* Only handle the numerous thermal events if we are */
/* NOT doing ACPI Debugging. */
If (CondRefOf (\_TZ.TZ01))
{
Notify (\_TZ.TZ01, 0x80)
}
}
}
10 changes: 10 additions & 0 deletions src/ec/starlabs/it8987/chip.h
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _EC_STARLABS_IT8987_CHIP_H
#define _EC_STARLABS_IT8987_CHIP_H

struct ec_starlabs_it8987_config {
u8 cpuhot_limit; /* temperature in °C which asserts PROCHOT# */
};

#endif /* _EC_STARLABS_IT8987_CHIP_H */
83 changes: 83 additions & 0 deletions src/ec/starlabs/it8987/ec.c
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <device/device.h>
#include <device/pnp.h>
#include <pc80/keyboard.h>
#include <ec/acpi/ec.h>
#include <delay.h>
#include <option.h>

#include "ec.h"
#include "chip.h"

u16 it8987_get_version(void)
{
return (ec_read(0x00) << 8) | ec_read(0x01);
}

static void it8987_init(struct device *dev)
{
if (!dev->enabled)
return;

/*
* The address/data IO port pair for the IT8987 EC are configurable
* through the EC domain and are fixed by the EC's firmware blob. If
* the value(s) passed through the "dev" structure don't match the
* expected values then output severe warnings.
*/
if (dev->path.pnp.port != IT8987E_FIXED_ADDR) {
printk(BIOS_ERR, "IT8987: Incorrect ports defined in devicetree.cb.\n");
printk(BIOS_ERR, "IT8987: Serious operational issues will arise.\n");
return;
}

u8 chipid1 = pnp_read_index(dev->path.pnp.port, IT8987_CHIPID1);
u8 chipid2 = pnp_read_index(dev->path.pnp.port, IT8987_CHIPID2);
if (chipid1 != IT8987_CHIPID1_VAL || chipid2 != IT8987_CHIPID2_VAL) {
printk(BIOS_DEBUG, "IT8987: Device not found.\n");
return;
}

printk(BIOS_DEBUG, "IT8987: Initializing keyboard.\n");
pc_keyboard_init(NO_AUX_DEVICE);

/* Enable the keyboard backlight support. */
ec_write(0x18, 0xaa);
ec_write(0x19, 0xdd);

/* Set the timeout for the keyboard backlight. */
ec_write(ECRAM_KBL_TIMEOUT, get_uint_option("kbl_timeout", 0));

/*
* Set the correct state for the Ctrl Fn Reverse option. This
* swaps the Ctrl and Fn keys to make it like an Apple keyboard.
*/
ec_write(ECRAM_FN_CTRL_REVERSE, get_uint_option("fn_ctrl_swap", 0));
/*
* Copy the stored state of the fn_lock_state CMOS variable to the
* corresponding location within the EC RAM.
*/
ec_write(ECRAM_FN_LOCK_STATE, get_uint_option("fn_lock_state", 0));
}

static struct device_operations ops = {
.init = it8987_init,
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
};

static struct pnp_info pnp_dev_info[] = {
{ NULL, 0, 0, 0, }
};

static void enable_dev(struct device *dev)
{
pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
}

struct chip_operations ec_starlabs_it8987_ops = {
CHIP_NAME("ITE IT8987 EC")
.enable_dev = enable_dev
};
48 changes: 48 additions & 0 deletions src/ec/starlabs/it8987/ec.h
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* EC communication interface for ITE IT8987 Embedded Controller.
*/

#ifndef _EC_STARLABS_IT8987_H
#define _EC_STARLABS_IT8987_H

/*
* Define the expected value of the PNP base address that is fixed through
* the BADRSEL register controlled within the EC domain by the binary blob.
*/
#define IT8987E_FIXED_ADDR 0x4e

/* Logical device number (LDN) assignments. */
#define IT8987E_SP1 0x01 /* Com1 */
#define IT8987E_SP2 0x02 /* Com2 */
#define IT8987E_SWUC 0x04 /* System Wake-Up */
#define IT8987E_KBCM 0x05 /* PS/2 mouse */
#define IT8987E_KBCK 0x06 /* PS/2 keyboard */
#define IT8987E_IR 0x0a /* Consumer IR */
#define IT8987E_SMFI 0x0f /* Shared Memory/Flash Interface */
#define IT8987E_RTCT 0x10 /* RTC-like Timer */
#define IT8987E_PMC1 0x11 /* Power Management Channel 1 */
#define IT8987E_PMC2 0x12 /* Power Management Channel 2 */
#define IT8987E_SSPI 0x13 /* Serial Peripheral Interface */
#define IT8987E_PECI 0x14 /* Platform EC Interface */
#define IT8987E_PMC3 0x17 /* Power Management Channel 3 */
#define IT8987E_PMC4 0x18 /* Power Management Channel 4 */
#define IT8987E_PMC5 0x19 /* Power Management Channel 5 */

/* Host domain registers. */
#define IT8987_CHIPID1 0x20 /* Device ID register 1 */
#define IT8987_CHIPID2 0x21 /* Device ID register 2 */

/* IT8987 chip ID byte values. */
#define IT8987_CHIPID1_VAL 0x89
#define IT8987_CHIPID2_VAL 0x87

/* EC RAM offsets. */
#define ECRAM_KBL_TIMEOUT 0x07
#define ECRAM_FN_CTRL_REVERSE 0x08
#define ECRAM_FN_LOCK_STATE 0x2C

u16 it8987_get_version(void);

#endif
6 changes: 3 additions & 3 deletions src/include/acpi/acpi.h
Expand Up @@ -1253,6 +1253,7 @@ void soc_fill_fadt(acpi_fadt_t *fadt);
void mainboard_fill_fadt(acpi_fadt_t *fadt);

void acpi_fill_gnvs(void);
void acpi_fill_cnvs(void);

void update_ssdt(void *ssdt);
void update_ssdtx(void *ssdtx, int i);
Expand Down Expand Up @@ -1384,9 +1385,8 @@ unsigned long acpi_create_hest_error_source(acpi_hest_t *hest,
void acpi_create_lpit(acpi_lpit_t *lpit);
unsigned long acpi_create_lpi_desc_ncst(acpi_lpi_desc_ncst_t *lpi_desc, uint16_t uid);

/* For crashlog. */
bool acpi_is_boot_error_src_present(void);
void acpi_soc_fill_bert(acpi_bert_t *bert, void **region, size_t *length);
/* chipsets that select ACPI_BERT must implement this function */
enum cb_err acpi_soc_get_bert_region(void **region, size_t *length);

/* For ACPI S3 support. */
void __noreturn acpi_resume(void *wake_vec);
Expand Down
6 changes: 6 additions & 0 deletions src/include/acpi/acpi_device.h
Expand Up @@ -456,6 +456,12 @@ struct acpi_power_res_params {
* (_OFF method delay)
*/
unsigned int stop_off_delay_ms;

/* Write a _STA method that uses the state of the GPIOs to determine if
* the PowerResource is ON or OFF. If this is false, the _STA method
* will always return ON.
*/
bool use_gpio_for_status;
};

/*
Expand Down
2 changes: 2 additions & 0 deletions src/include/acpi/acpi_gnvs.h
Expand Up @@ -8,6 +8,8 @@
struct global_nvs;

void acpi_create_gnvs(void);
size_t size_of_dnvs(void);

#if CONFIG(ACPI_SOC_NVS)
void *acpi_get_gnvs(void);
void *acpi_get_device_nvs(void);
Expand Down
10 changes: 10 additions & 0 deletions src/include/bootstate.h
Expand Up @@ -2,6 +2,7 @@
#ifndef BOOTSTATE_H
#define BOOTSTATE_H

#include <assert.h>
#include <string.h>
#include <stddef.h>
/* Only declare main() when in ramstage. */
Expand Down Expand Up @@ -105,6 +106,15 @@ struct boot_state_callback {
#endif
};

static inline const char *bscb_location(const struct boot_state_callback *bscb)
{
#if CONFIG(DEBUG_BOOT_STATE)
return bscb->location;
#else
return dead_code_t(const char *);
#endif
}

#if CONFIG(DEBUG_BOOT_STATE)
#define BOOT_STATE_CALLBACK_LOC __FILE__ ":" STRINGIFY(__LINE__)
#define BOOT_STATE_CALLBACK_INIT_DEBUG .location = BOOT_STATE_CALLBACK_LOC,
Expand Down
29 changes: 20 additions & 9 deletions src/include/cbmem.h
Expand Up @@ -108,37 +108,48 @@ void cbmem_add_records_to_cbtable(struct lb_header *header);

#if ENV_RAMSTAGE
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_rom_ = init_fn_;
#define RAMSTAGE_CBMEM_INIT_HOOK(init_fn_) \
static cbmem_init_hook_t init_fn_ ## _ptr_ __attribute__((used, \
section(".rodata.cbmem_init_hooks"))) = init_fn_;
#define POSTCAR_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused2_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_pc_ = init_fn_;
#elif ENV_ROMSTAGE
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_) \
static cbmem_init_hook_t init_fn_ ## _ptr_ __attribute__((used, \
section(".rodata.cbmem_init_hooks"))) = init_fn_;
#define RAMSTAGE_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_ram_ = init_fn_;
#define POSTCAR_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused2_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_pc_ = init_fn_;
#elif ENV_POSTCAR
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused2_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_rom_ = init_fn_;
#define RAMSTAGE_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_ram_ = init_fn_;
#define POSTCAR_CBMEM_INIT_HOOK(init_fn_) \
static cbmem_init_hook_t init_fn_ ## _ptr_ __attribute__((used, \
section(".rodata.cbmem_init_hooks"))) = init_fn_;
#else
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_rom_ = init_fn_;
#define RAMSTAGE_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused2_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_ram_ = init_fn_;
#define POSTCAR_CBMEM_INIT_HOOK(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused3_ = init_fn_;
static cbmem_init_hook_t init_fn_ ## _unused_pc_ = init_fn_;
#endif /* ENV_RAMSTAGE */

/* Early hooks get executed before other hooks. Use sparingly for hooks that create
CBMEM regions which need to remain in a constant location across boot modes. */
#if ENV_ROMSTAGE
#define ROMSTAGE_CBMEM_INIT_HOOK_EARLY(init_fn_) \
static cbmem_init_hook_t init_fn_ ## _ptr_ __attribute__((used, \
section(".rodata.cbmem_init_hooks_early"))) = init_fn_;
#else
#define ROMSTAGE_CBMEM_INIT_HOOK_EARLY(init_fn_) __attribute__((unused)) \
static cbmem_init_hook_t init_fn_ ## _unused_rom_ = init_fn_;
#endif /* ENV_ROMSTAGE */

/*
* Returns 0 for the stages where we know that cbmem does not come online.
* Even if this function returns 1 for romstage, depending upon the point in
Expand Down
25 changes: 21 additions & 4 deletions src/include/cpu/intel/msr.h
@@ -1,19 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef CPU_INTEL_MSR_H
#define CPU_INTEL_MSR_H

/*
* Common MSRs for Intel CPUs
*/

#define MSR_FEATURE_CONFIG 0x13c
#define AESNI_DISABLE (1 << 1)
#define AESNI_LOCK (1 << 0)

#define MSR_PIC_MSG_CONTROL 0x2e
#define TPR_UPDATES_DISABLE (1 << 10)

#define MSR_PLATFORM_INFO 0xce

#define MSR_BC_PBEC 0x139
#define B_STOP_PBET (1 << 0)

#define MSR_BOOT_GUARD_SACM_INFO 0x13a
#define V_TPM_PRESENT_MASK 0x06
#define B_BOOT_GUARD_SACM_INFO_NEM_ENABLED (1 << 0)
#define B_BOOT_GUARD_SACM_INFO_TPM_SUCCESS (1 << 3)
#define B_BOOT_GUARD_SACM_INFO_MEASURED_BOOT (1 << 5)
#define B_BOOT_GUARD_SACM_INFO_VERIFIED_BOOT (1 << 6)
#define B_BOOT_GUARD_SACM_INFO_REVOKED (1 << 7)
#define B_BOOT_GUARD_SACM_INFO_BTG_CAPABILITY (1ull << 32)
#define B_BOOT_GUARD_SACM_INFO_TXT_CAPABILITY (1ull << 34)

#define MSR_FEATURE_CONFIG 0x13c
#define AESNI_DISABLE (1 << 1)
#define AESNI_LOCK (1 << 0)

#define MSR_SPCL_CHIPSET_USAGE 0x1fe

#define MSR_PKG_C10_RESIDENCY 0x632

#endif /* CPU_INTEL_MSR_H */
169 changes: 99 additions & 70 deletions src/include/cpu/x86/lapic.h
Expand Up @@ -8,72 +8,130 @@
#include <halt.h>
#include <stdint.h>

static inline bool is_x2apic_mode(void)
static __always_inline uint32_t xapic_read(unsigned int reg)
{
return read32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg));
}

static __always_inline void xapic_write(unsigned int reg, uint32_t v)
{
write32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg), v);
}

static inline void xapic_write_atomic(unsigned long reg, uint32_t v)
{
volatile uint32_t *ptr;

ptr = (volatile uint32_t *)(LAPIC_DEFAULT_BASE + reg);

asm volatile ("xchgl %0, %1\n"
: "+r" (v), "+m" (*(ptr))
: : "memory", "cc");
}

static __always_inline void xapic_send_ipi(uint32_t icrlow, uint32_t apicid)
{
xapic_write_atomic(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
xapic_write_atomic(LAPIC_ICR, icrlow);
}

static __always_inline int xapic_busy(void)
{
return xapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
}

static __always_inline uint32_t x2apic_read(unsigned int reg)
{
uint32_t value, index;
msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR);
return ((msr.lo & LAPIC_BASE_X2APIC_ENABLED) == LAPIC_BASE_X2APIC_ENABLED);

index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
msr = rdmsr(index);
value = msr.lo;
return value;
}

static inline void x2apic_send_ipi(uint32_t icrlow, uint32_t apicid)
static __always_inline void x2apic_write(unsigned int reg, uint32_t v)
{
uint32_t index;
msr_t msr;

index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
msr.hi = 0x0;
msr.lo = v;
wrmsr(index, msr);
}

static __always_inline void x2apic_send_ipi(uint32_t icrlow, uint32_t apicid)
{
msr_t icr;
icr.hi = apicid;
icr.lo = icrlow;
wrmsr(X2APIC_MSR_ICR_ADDRESS, icr);
}

static __always_inline uint32_t lapic_read(unsigned int reg)
static inline bool is_x2apic_mode(void)
{
uint32_t value, index;
if (CONFIG(XAPIC_ONLY))
return false;

if (CONFIG(X2APIC_ONLY))
return true;

msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR);
return ((msr.lo & LAPIC_BASE_X2APIC_ENABLED) == LAPIC_BASE_X2APIC_ENABLED);
}

if (is_x2apic_mode()) {
index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
msr = rdmsr(index);
value = msr.lo;
} else {
value = read32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg));
}
return value;
static __always_inline uint32_t lapic_read(unsigned int reg)
{
if (is_x2apic_mode())
return x2apic_read(reg);
else
return xapic_read(reg);
}

static __always_inline void lapic_write(unsigned int reg, uint32_t v)
{
msr_t msr;
uint32_t index;
if (is_x2apic_mode())
x2apic_write(reg, v);
else
xapic_write(reg, v);
}

static __always_inline void lapic_update32(unsigned int reg, uint32_t mask, uint32_t or)
{
if (is_x2apic_mode()) {
uint32_t index;
msr_t msr;
index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
msr.hi = 0x0;
msr.lo = v;
msr = rdmsr(index);
msr.lo &= mask;
msr.lo |= or;
wrmsr(index, msr);
} else {
write32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg), v);
uint32_t value;
value = xapic_read(reg);
value &= mask;
value |= or;
xapic_write_atomic(reg, value);
}
}

static __always_inline void lapic_wait_icr_idle(void)
static __always_inline void lapic_send_ipi(uint32_t icrlow, uint32_t apicid)
{
do { } while (lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY);
}

static inline void enable_lapic(void)
{
msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR);
msr.hi &= 0xffffff00;
msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
msr.lo |= LAPIC_DEFAULT_BASE;
msr.lo |= LAPIC_BASE_MSR_ENABLE;
wrmsr(LAPIC_BASE_MSR, msr);
if (is_x2apic_mode())
x2apic_send_ipi(icrlow, apicid);
else
xapic_send_ipi(icrlow, apicid);
}

static inline void disable_lapic(void)
static __always_inline int lapic_busy(void)
{
msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR);
msr.lo &= ~LAPIC_BASE_MSR_ENABLE;
wrmsr(LAPIC_BASE_MSR, msr);
if (is_x2apic_mode())
return 0;
else
return xapic_busy();
}

static __always_inline unsigned int initial_lapicid(void)
Expand All @@ -98,7 +156,7 @@ static __always_inline unsigned int lapicid(void)

#if !CONFIG(AP_IN_SIPI_WAIT)
/* If we need to go back to sipi wait, we use the long non-inlined version of
* this function in lapic_cpu_init.c
* this function in lapic_cpu_stop.c
*/
static __always_inline void stop_this_cpu(void)
{
Expand All @@ -109,37 +167,8 @@ static __always_inline void stop_this_cpu(void)
void stop_this_cpu(void);
#endif

static inline void lapic_write_atomic(unsigned long reg, uint32_t v)
{
volatile uint32_t *ptr;

ptr = (volatile uint32_t *)(LAPIC_DEFAULT_BASE + reg);

asm volatile ("xchgl %0, %1\n"
: "+r" (v), "+m" (*(ptr))
: : "memory", "cc");
}

# define lapic_read_around(x) lapic_read(x)
# define lapic_write_around(x, y) lapic_write_atomic((x), (y))

void lapic_virtual_wire_mode_init(void);

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

static inline void setup_lapic(void)
{
if (need_lapic_init())
lapic_virtual_wire_mode_init();
else
disable_lapic();
}

struct device;
int start_cpu(struct device *cpu);
void enable_lapic(void);
void disable_lapic(void);
void setup_lapic(void);

#endif /* CPU_X86_LAPIC_H */
7 changes: 1 addition & 6 deletions src/include/cpu/x86/lapic_def.h
Expand Up @@ -9,12 +9,7 @@
(LAPIC_BASE_MSR_X2APIC_MODE | LAPIC_BASE_MSR_ENABLE)
#define LAPIC_BASE_MSR_ADDR_MASK 0xFFFFF000

#ifndef LOCAL_APIC_ADDR
#define LOCAL_APIC_ADDR 0xfee00000
#endif
#ifndef LAPIC_DEFAULT_BASE
#define LAPIC_DEFAULT_BASE LOCAL_APIC_ADDR
#endif
#define LAPIC_DEFAULT_BASE 0xfee00000

#define LAPIC_ID 0x020
#define LAPIC_LVR 0x030
Expand Down
2 changes: 1 addition & 1 deletion src/include/cpu/x86/post_code.h
Expand Up @@ -3,7 +3,7 @@

#include <console/post_codes.h>

#if CONFIG(POST_IO)
#if CONFIG(POST_IO) && !(ENV_BOOTBLOCK && CONFIG(NO_EARLY_BOOTBLOCK_POSTCODES))
#define post_code(value) \
movb $value, %al; \
outb %al, $CONFIG_POST_IO_PORT
Expand Down
1 change: 1 addition & 0 deletions src/include/cpu/x86/smm.h
Expand Up @@ -49,6 +49,7 @@ void southbridge_smi_handler(void);
void mainboard_smi_gpi(u32 gpi_sts);
int mainboard_smi_apmc(u8 data);
void mainboard_smi_sleep(u8 slp_typ);
void mainboard_smi_finalize(void);

/* This is the SMM handler. */
extern unsigned char _binary_smm_start[];
Expand Down
3 changes: 3 additions & 0 deletions src/include/device/device.h
Expand Up @@ -178,6 +178,8 @@ void dev_initialize(void);
void dev_optimize(void);
void dev_finalize(void);
void dev_finalize_chips(void);
/* Function used to override device state */
void devfn_disable(const struct bus *bus, unsigned int devfn);

/* Generic device helper functions */
int reset_bus(struct bus *bus);
Expand All @@ -192,6 +194,7 @@ void disable_children(struct bus *bus);
bool dev_is_active_bridge(struct device *dev);
void add_more_links(struct device *dev, unsigned int total_links);
bool is_dev_enabled(const struct device *const dev);
bool is_devfn_enabled(unsigned int devfn);

/* Option ROM helper functions */
void run_bios(struct device *dev, unsigned long addr);
Expand Down
20 changes: 20 additions & 0 deletions src/include/device/dram/lpddr4.h
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef DEVICE_DRAM_LPDDR4_H
#define DEVICE_DRAM_LPDDR4_H

/**
* @file lpddr4.h
*
* \brief Utilities for decoding LPDDR4 info
*/

#include <device/dram/common.h>
#include <types.h>

/**
* Converts LPDDR4 clock speed in MHz to the standard reported speed in MT/s
*/
uint16_t lpddr4_speed_mhz_to_reported_mts(uint16_t speed_mhz);

#endif /* DEVICE_DRAM_LPDDR4_H */
4 changes: 4 additions & 0 deletions src/include/device/pci_def.h
Expand Up @@ -233,6 +233,10 @@
#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
#define PCI_PM_CTRL 4 /* PM control and status register */
#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
#define PCI_PM_CTRL_POWER_STATE_D0 0x0
#define PCI_PM_CTRL_POWER_STATE_D1 0x1
#define PCI_PM_CTRL_POWER_STATE_D2 0x2
#define PCI_PM_CTRL_POWER_STATE_D3HOT 0x3
#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
Expand Down
2 changes: 2 additions & 0 deletions src/include/device/pci_ids.h
Expand Up @@ -3816,6 +3816,8 @@
#define PCI_DEVICE_ID_INTEL_ADL_P_GT2_1 0x46b0
#define PCI_DEVICE_ID_INTEL_ADL_P_GT2_2 0x46a1
#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_S_GT1 0x4680
#define PCI_DEVICE_ID_INTEL_ADL_M_GT1 0x46c0

Expand Down
1 change: 1 addition & 0 deletions src/include/device/pnp.h
Expand Up @@ -13,6 +13,7 @@
/* Primitive PNP resource manipulation */
void pnp_write_config(struct device *dev, u8 reg, u8 value);
u8 pnp_read_config(struct device *dev, u8 reg);
void pnp_unset_and_set_config(struct device *dev, u8 reg, u8 unset, u8 set);
void pnp_set_logical_device(struct device *dev);
void pnp_set_enable(struct device *dev, int enable);
int pnp_read_enable(struct device *dev);
Expand Down
20 changes: 20 additions & 0 deletions src/include/limits.h
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef LIMITS_H
#define LIMITS_H

#define USHRT_MAX ((unsigned short)~0U)
#define SHRT_MAX ((short)(USHRT_MAX >> 1))
#define SHRT_MIN ((short)(-SHRT_MAX - 1))
#define INT_MAX ((int)(~0U >> 1))
#define INT_MIN (-INT_MAX - 1)
#define UINT_MAX (~0U)
#define LONG_MAX ((long)(~0UL >> 1))
#define LONG_MIN (-LONG_MAX - 1)
#define ULONG_MAX (~0UL)
#define LLONG_MAX ((long long)(~0ULL >> 1))
#define LLONG_MIN (-LLONG_MAX - 1)
#define ULLONG_MAX (~0ULL)
#define UINTPTR_MAX ULONG_MAX

#endif /* LIMITS_H */
6 changes: 3 additions & 3 deletions src/include/option.h
Expand Up @@ -7,7 +7,7 @@

void sanitize_cmos(void);

#if !CONFIG(USE_OPTION_TABLE)
#if CONFIG(OPTION_BACKEND_NONE)

static inline unsigned int get_uint_option(const char *name, const unsigned int fallback)
{
Expand All @@ -19,11 +19,11 @@ static inline enum cb_err set_uint_option(const char *name, unsigned int value)
return CB_CMOS_OTABLE_DISABLED;
}

#else /* USE_OPTION_TABLE */
#else /* !OPTION_BACKEND_NONE */

unsigned int get_uint_option(const char *name, const unsigned int fallback);
enum cb_err set_uint_option(const char *name, unsigned int value);

#endif /* USE_OPTION_TABLE? */
#endif /* OPTION_BACKEND_NONE? */

#endif /* _OPTION_H_ */
1 change: 1 addition & 0 deletions src/include/rtc.h
Expand Up @@ -21,5 +21,6 @@ int rtc_get(struct rtc_time *time);
int rtc_to_tm(int tim, struct rtc_time *tm);
unsigned long rtc_mktime(const struct rtc_time *tm);
void rtc_display(const struct rtc_time *tm);
int rtc_invalid(const struct rtc_time *tm);

#endif /* _RTC_H_ */
9 changes: 3 additions & 6 deletions src/include/stddef.h
Expand Up @@ -3,10 +3,7 @@

#include <commonlib/helpers.h>

typedef long ptrdiff_t;
#ifndef __SIZE_TYPE__
#define __SIZE_TYPE__ unsigned long
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __SIZE_TYPE__ size_t;
/* There is a GCC macro for a size_t type, but not
* for a ssize_t type. Below construct tricks GCC
Expand All @@ -16,8 +13,8 @@ typedef __SIZE_TYPE__ size_t;
typedef __SIZE_TYPE__ ssize_t;
#undef unsigned

typedef int wchar_t;
typedef unsigned int wint_t;
typedef __WCHAR_TYPE__ wchar_t;
typedef __WINT_TYPE__ wint_t;

#define NULL ((void *)0)

Expand Down
1 change: 1 addition & 0 deletions src/lib/Makefile.inc
Expand Up @@ -59,6 +59,7 @@ bootblock-y += memchr.c
bootblock-y += memcmp.c
bootblock-y += boot_device.c
bootblock-y += fmap.c
bootblcok-y += rtc.c

verstage-y += prog_loaders.c
verstage-y += prog_ops.c
Expand Down
6 changes: 5 additions & 1 deletion src/lib/cbmem_console.c
Expand Up @@ -145,7 +145,11 @@ static void cbmemc_reinit(int is_recovery)
init_console_ptr(cbmem_cons_p, size);
copy_console_buffer(previous_cons_p);
}
ROMSTAGE_CBMEM_INIT_HOOK(cbmemc_reinit)

/* Run the romstage hook early so that the console region is one of the earliest created, and
therefore more likely to stay in the same place even across different boot modes where some
other regions may sometimes not get created (e.g. RW_MCACHE in vboot recovery mode). */
ROMSTAGE_CBMEM_INIT_HOOK_EARLY(cbmemc_reinit)
RAMSTAGE_CBMEM_INIT_HOOK(cbmemc_reinit)
POSTCAR_CBMEM_INIT_HOOK(cbmemc_reinit)

Expand Down
1 change: 1 addition & 0 deletions src/lib/coreboot_table.c
Expand Up @@ -246,6 +246,7 @@ static void add_cbmem_pointers(struct lb_header *header)
{CBMEM_ID_TIMESTAMP, LB_TAG_TIMESTAMPS},
{CBMEM_ID_CONSOLE, LB_TAG_CBMEM_CONSOLE},
{CBMEM_ID_ACPI_GNVS, LB_TAG_ACPI_GNVS},
{CBMEM_ID_ACPI_CNVS, LB_TAG_ACPI_CNVS},
{CBMEM_ID_VPD, LB_TAG_VPD},
{CBMEM_ID_WIFI_CALIBRATION, LB_TAG_WIFI_CALIBRATION},
{CBMEM_ID_TCPA_LOG, LB_TAG_TCPA_LOG},
Expand Down
21 changes: 17 additions & 4 deletions src/lib/hardwaremain.c
Expand Up @@ -24,6 +24,7 @@
#include <timer.h>
#include <timestamp.h>
#include <thread.h>
#include <vendorcode/google/chromeos/gnvs.h>

static boot_state_t bs_pre_device(void *arg);
static boot_state_t bs_dev_init_chips(void *arg);
Expand Down Expand Up @@ -264,6 +265,7 @@ static void bs_call_callbacks(struct boot_state *state,
boot_state_sequence_t seq)
{
struct boot_phase *phase = &state->phases[seq];
struct mono_time mt_start, mt_stop;

while (1) {
if (phase->callbacks != NULL) {
Expand All @@ -274,11 +276,19 @@ static void bs_call_callbacks(struct boot_state *state,
phase->callbacks = bscb->next;
bscb->next = NULL;

#if CONFIG(DEBUG_BOOT_STATE)
printk(BIOS_DEBUG, "BS: callback (%p) @ %s.\n",
bscb, bscb->location);
#endif
if (CONFIG(DEBUG_BOOT_STATE)) {
printk(BIOS_DEBUG, "BS: callback (%p) @ %s.\n",
bscb, bscb_location(bscb));
timer_monotonic_get(&mt_start);
}
bscb->callback(bscb->arg);
if (CONFIG(DEBUG_BOOT_STATE)) {
timer_monotonic_get(&mt_stop);
printk(BIOS_DEBUG, "BS: callback (%p) @ %s (%ld ms).\n", bscb,
bscb_location(bscb),
mono_time_diff_microseconds(&mt_start, &mt_stop)
/ USECS_PER_MSEC);
}
continue;
}

Expand Down Expand Up @@ -452,6 +462,9 @@ void main(void)
if (CONFIG(ACPI_SOC_NVS))
acpi_create_gnvs();

if (CONFIG(CHROMEOS_NVS))
chromeos_init_chromeos_acpi();

/* Schedule the static boot state entries. */
boot_state_schedule_static_entries();

Expand Down
1 change: 1 addition & 0 deletions src/lib/program.ld
Expand Up @@ -27,6 +27,7 @@
#if ENV_RAMSTAGE || ENV_ROMSTAGE || ENV_POSTCAR
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
_cbmem_init_hooks = .;
KEEP(*(.rodata.cbmem_init_hooks_early));
KEEP(*(.rodata.cbmem_init_hooks));
_ecbmem_init_hooks = .;
RECORD_SIZE(cbmem_init_hooks)
Expand Down
16 changes: 16 additions & 0 deletions src/lib/rtc.c
Expand Up @@ -121,3 +121,19 @@ void rtc_display(const struct rtc_time *tm)
(tm->wday < 0 || tm->wday > 6) ? "unknown " : weekdays[tm->wday],
tm->hour, tm->min, tm->sec);
}

static int rtc_month_days(unsigned int month, unsigned int year)
{
int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

return month_days[month] + (LEAP_YEAR(year) && month == 2);
}

int rtc_invalid(const struct rtc_time *tm)
{
if (tm->sec > 59 || tm->min > 59 || tm->hour > 23 || tm->mon == 0 || tm->mon > 12 ||
tm->year < 1970 || tm->mday > rtc_month_days(tm->mon - 1, tm->year))
return 1;
else
return 0;
}
60 changes: 22 additions & 38 deletions src/mainboard/amd/bilby/devicetree.cb
Expand Up @@ -136,52 +136,36 @@ chip soc/amd/picasso
register "gpp_clk_config[5]" = "GPP_CLK_REQ"
register "gpp_clk_config[6]" = "GPP_CLK_REQ"

device cpu_cluster 0 on
device lapic 0 on end
end
register "pspp_policy" = "DXIO_PSPP_BALANCED"

device domain 0 on
subsystemid 0x1022 0x1510 inherit
device pci 0.0 on end # Root Complex
device pci 0.2 on end # IOMMU
device pci 1.0 on end # Dummy Host Bridge
device pci 1.1 on end # GPP Bridge 0
device pci 1.2 on end # GPP Bridge 1
device pci 1.5 on end # NVMe
device pci 8.0 on end # Dummy Host Bridge
device pci 8.1 on # Bridge to Bus A
device pci 0.0 on end # Internal GPU
device pci 0.1 on end # Display HDA
device pci 0.2 on end # Crypto Coprocessor
device pci 0.3 on end # USB 3.1
device pci 0.4 off end # USB 3.1
device pci 0.5 on end # Audio
device pci 0.6 on end # HDA
device pci 0.7 on end # non-Sensor Fusion Hub device
device ref iommu on end
device ref gpp_bridge_0 on end
device ref gpp_bridge_1 on end
device ref gpp_bridge_4 on end # NVMe
device ref internal_bridge_a on
device ref gfx on end # Internal GPU
device ref gfx_hda on end # Display HDA
device ref crypto on end # Crypto Coprocessor
device ref xhci_0 on end # USB 3.1
device ref xhci_1 off end # USB 3.1
device ref acp on end # Audio
device ref hda on end # HDA
device ref mp2 on end # non-Sensor Fusion Hub device
end
device pci 8.2 on # Bridge to Bus B
device pci 0.0 off end # AHCI
device pci 0.1 off end # integrated Ethernet MAC
device pci 0.2 off end # integrated Ethernet MAC
device ref internal_bridge_b on
device ref sata off end # AHCI
device ref xgbe_0 off end # integrated Ethernet MAC
device ref xgbe_1 off end # integrated Ethernet MAC
end
device pci 14.0 on end # SMBus
device pci 14.3 on # D14F3 bridge
device ref lpc_bridge on
chip superio/smsc/sio1036 # optional debug card
end
end
device pci 14.6 off end # SDHCI
device pci 18.0 on end # Data fabric [0-7]
device pci 18.1 on end
device pci 18.2 on end
device pci 18.3 on end
device pci 18.4 on end
device pci 18.5 on end
device pci 18.6 on end
device pci 18.7 on end
end # domain

device mmio 0xfedc9000 on end # UART0
device mmio 0xfedca000 on end # UART1
device mmio 0xfedce000 off end # UART2
device mmio 0xfedcf000 off end # UART3
device ref uart_0 on end # console
device ref uart_1 on end

end # chip soc/amd/picasso
7 changes: 7 additions & 0 deletions src/mainboard/amd/majolica/devicetree.cb
Expand Up @@ -13,6 +13,12 @@ chip soc/amd/cezanne
.flash_ch_en = 0,
}"

# I2C Pad Control RX Select Configuration
register "i2c_pad_ctrl_rx_sel[0]" = "I2C_PAD_CTRL_RX_SEL_3_3V"
register "i2c_pad_ctrl_rx_sel[1]" = "I2C_PAD_CTRL_RX_SEL_3_3V"
register "i2c_pad_ctrl_rx_sel[2]" = "I2C_PAD_CTRL_RX_SEL_3_3V"
register "i2c_pad_ctrl_rx_sel[3]" = "I2C_PAD_CTRL_RX_SEL_3_3V"

register "s0ix_enable" = "true"

register "pspp_policy" = "DXIO_PSPP_BALANCED"
Expand All @@ -27,6 +33,7 @@ chip soc/amd/cezanne
device ref gpp_bridge_5 on end
device ref gpp_bridge_a on # Internal GPP Bridge 0 to Bus A
device ref gfx on end # Internal GPU (GFX)
device ref crypto on end # Crypto Coprocessor
device ref xhci_0 on # USB 3.1 (USB0)
chip drivers/usb/acpi
device ref xhci_0_root_hub on
Expand Down
56 changes: 20 additions & 36 deletions src/mainboard/amd/mandolin/variants/cereme/devicetree.cb
Expand Up @@ -136,50 +136,34 @@ chip soc/amd/picasso
register "gpp_clk_config[5]" = "GPP_CLK_OFF"
register "gpp_clk_config[6]" = "GPP_CLK_OFF"

device cpu_cluster 0 on
device lapic 0 on end
end
register "pspp_policy" = "DXIO_PSPP_BALANCED"

device domain 0 on
subsystemid 0x1022 0x1510 inherit
device pci 0.0 on end # Root Complex
device pci 0.2 on end # IOMMU
device pci 1.0 on end # Dummy Host Bridge
device pci 1.1 on end # Bridge to PCIe Ethernet chip
device pci 8.0 on end # Dummy Host Bridge
device pci 8.1 on # Bridge to Bus A
device pci 0.0 on end # Internal GPU
device pci 0.1 on end # Display HDA
device pci 0.2 on end # Crypto Coprocessor
device pci 0.3 on end # USB 3.1
device pci 0.4 off end # USB 3.1
device pci 0.5 on end # Audio
device pci 0.6 on end # HDA
device pci 0.7 on end # non-Sensor Fusion Hub device
device ref iommu on end
device ref gpp_bridge_0 on end # Bridge to PCIe Ethernet chip
device ref internal_bridge_a on
device ref gfx on end # Internal GPU
device ref gfx_hda on end # Display HDA
device ref crypto on end # Crypto Coprocessor
device ref xhci_0 on end # USB 3.1
device ref xhci_1 off end # USB 3.1
device ref acp on end # Audio
device ref hda on end # HDA
device ref mp2 on end # non-Sensor Fusion Hub device
end
device pci 8.2 on # Bridge to Bus B
device pci 0.0 off end # AHCI
device pci 0.1 off end # integrated Ethernet MAC
device pci 0.2 off end # integrated Ethernet MAC
device ref internal_bridge_b on
device ref sata off end # AHCI
device ref xgbe_0 off end # integrated Ethernet MAC
device ref xgbe_1 off end # integrated Ethernet MAC
end
device pci 14.0 on end # SMBus
device pci 14.3 on # D14F3 bridge
device ref lpc_bridge on
chip superio/smsc/sio1036 # optional debug card
end
end
device pci 14.6 off end # SDHCI
device pci 18.0 on end # Data fabric [0-7]
device pci 18.1 on end
device pci 18.2 on end
device pci 18.3 on end
device pci 18.4 on end
device pci 18.5 on end
device pci 18.6 on end
device pci 18.7 on end
end # domain

device mmio 0xfedc9000 on end # UART0
device mmio 0xfedca000 on end # UART1
device mmio 0xfedce000 off end # UART2
device mmio 0xfedcf000 off end # UART3
device ref uart_0 on end # console
device ref uart_1 on end

end # chip soc/amd/picasso
56 changes: 20 additions & 36 deletions src/mainboard/amd/mandolin/variants/mandolin/devicetree.cb
Expand Up @@ -136,50 +136,34 @@ chip soc/amd/picasso
register "gpp_clk_config[5]" = "GPP_CLK_REQ"
register "gpp_clk_config[6]" = "GPP_CLK_REQ"

device cpu_cluster 0 on
device lapic 0 on end
end
register "pspp_policy" = "DXIO_PSPP_BALANCED"

device domain 0 on
subsystemid 0x1022 0x1510 inherit
device pci 0.0 on end # Root Complex
device pci 0.2 on end # IOMMU
device pci 1.0 on end # Dummy Host Bridge
device pci 1.3 on end # Bridge to PCIe Ethernet chip
device pci 8.0 on end # Dummy Host Bridge
device pci 8.1 on # Bridge to Bus A
device pci 0.0 on end # Internal GPU
device pci 0.1 on end # Display HDA
device pci 0.2 on end # Crypto Coprocessor
device pci 0.3 on end # USB 3.1
device pci 0.4 on end # USB 3.1
device pci 0.5 on end # Audio
device pci 0.6 on end # HDA
device pci 0.7 on end # non-Sensor Fusion Hub device
device ref iommu on end
device ref gpp_bridge_2 on end # Bridge to PCIe Ethernet chip
device ref internal_bridge_a on
device ref gfx on end # Internal GPU
device ref gfx_hda on end # Display HDA
device ref crypto on end # Crypto Coprocessor
device ref xhci_0 on end # USB 3.1
device ref xhci_1 on end # USB 3.1
device ref acp on end # Audio
device ref hda on end # HDA
device ref mp2 on end # non-Sensor Fusion Hub device
end
device pci 8.2 on # Bridge to Bus B
device pci 0.0 on end # AHCI
device pci 0.1 off end # integrated Ethernet MAC
device pci 0.2 off end # integrated Ethernet MAC
device ref internal_bridge_b on
device ref sata on end # AHCI
device ref xgbe_0 off end # integrated Ethernet MAC
device ref xgbe_1 off end # integrated Ethernet MAC
end
device pci 14.0 on end # SMBus
device pci 14.3 on # D14F3 bridge
device ref lpc_bridge on
chip superio/smsc/sio1036 # optional debug card
end
end
device pci 14.6 off end # SDHCI
device pci 18.0 on end # Data fabric [0-7]
device pci 18.1 on end
device pci 18.2 on end
device pci 18.3 on end
device pci 18.4 on end
device pci 18.5 on end
device pci 18.6 on end
device pci 18.7 on end
end # domain

device mmio 0xfedc9000 on end # UART0
device mmio 0xfedca000 on end # UART1
device mmio 0xfedce000 off end # UART2
device mmio 0xfedcf000 off end # UART3
device ref uart_0 on end # console
device ref uart_1 on end

end # chip soc/amd/picasso
36 changes: 18 additions & 18 deletions src/mainboard/apple/macbook21/mptable.c
Expand Up @@ -11,35 +11,35 @@ static void *smp_write_config_table(void *v)

mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);

mptable_init(mc, LOCAL_APIC_ADDR);
mptable_init(mc);

smp_write_processors(mc);

mptable_write_buses(mc, NULL, &isa_bus);

/* I/O APICs: APIC ID Version State Address */
smp_write_ioapic(mc, 2, 0x20, VIO_APIC_VADDR);
u8 ioapic_id = smp_write_ioapic_from_hw(mc, VIO_APIC_VADDR);

/* Legacy Interrupts */
mptable_add_isa_interrupts(mc, isa_bus, 0x2, 0);
mptable_add_isa_interrupts(mc, isa_bus, ioapic_id, 0);

smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, isa_bus, 0x00, MP_APIC_ALL, 0x00);
smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x00, MP_APIC_ALL, 0x01);
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x01, 0x00, 0x02, 0x10); /* PCIe root 0.01.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x02, 0x00, 0x02, 0x10); /* VGA 0.02.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1b, 0x00, 0x02, 0x16); /* HD Audio 0:1b.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x00, 0x02, 0x11); /* PCIe 0:1c.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x01, 0x02, 0x10); /* PCIe 0:1c.1 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x02, 0x02, 0x12); /* PCIe 0:1c.2 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x03, 0x02, 0x13); /* PCIe 0:1c.3 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x00, 0x02, 0x15); /* USB 0:1d.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x01, 0x02, 0x13); /* USB 0:1d.1 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x02, 0x02, 0x12); /* USB 0:1d.2 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x03, 0x02, 0x10); /* USB 0:1d.3 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1f, 0x00, 0x02, 0x12); /* LPC 0:1f.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1f, 0x01, 0x02, 0x13); /* IDE 0:1f.1 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1f, 0x03, 0x02, 0x10); /* SATA 0:1f.3 */
smp_write_pci_intsrc(mc, mp_INT, 0x03, 0x03, 0x00, 0x02, 0x13); /* Firewire 3:03.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x01, 0x00, ioapic_id, 0x10); /* PCIe root 0.01.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x02, 0x00, ioapic_id, 0x10); /* VGA 0.02.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1b, 0x00, ioapic_id, 0x16); /* HD Audio 0:1b.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x00, ioapic_id, 0x11); /* PCIe 0:1c.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x01, ioapic_id, 0x10); /* PCIe 0:1c.1 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x02, ioapic_id, 0x12); /* PCIe 0:1c.2 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1c, 0x03, ioapic_id, 0x13); /* PCIe 0:1c.3 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x00, ioapic_id, 0x15); /* USB 0:1d.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x01, ioapic_id, 0x13); /* USB 0:1d.1 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x02, ioapic_id, 0x12); /* USB 0:1d.2 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1d, 0x03, ioapic_id, 0x10); /* USB 0:1d.3 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1f, 0x00, ioapic_id, 0x12); /* LPC 0:1f.0 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1f, 0x01, ioapic_id, 0x13); /* IDE 0:1f.1 */
smp_write_pci_intsrc(mc, mp_INT, 0x00, 0x1f, 0x03, ioapic_id, 0x10); /* SATA 0:1f.3 */
smp_write_pci_intsrc(mc, mp_INT, 0x03, 0x03, 0x00, ioapic_id, 0x13); /* Firewire 3:03.0 */

mptable_lintsrc(mc, isa_bus);
return mptable_finalize(mc);
Expand Down
1 change: 0 additions & 1 deletion src/mainboard/apple/macbookair4_2/Kconfig
Expand Up @@ -12,7 +12,6 @@ config BOARD_SPECIFIC_OPTIONS
select SERIRQ_CONTINUOUS_MODE
select SOUTHBRIDGE_INTEL_BD82X6X
select SYSTEM_TYPE_LAPTOP
select GFX_GMA_PANEL_1_ON_EDP
select MAINBOARD_HAS_LIBGFXINIT
select HAVE_CMOS_DEFAULT
select HAVE_OPTION_TABLE
Expand Down
1 change: 0 additions & 1 deletion src/mainboard/apple/macbookair4_2/devicetree.cb
Expand Up @@ -25,7 +25,6 @@ chip northbridge/intel/sandybridge

device domain 0 on
chip southbridge/intel/bd82x6x # Intel Series 6 Cougar Point PCH
register "c2_latency" = "0x0065"
register "docking_supported" = "0"
register "gen1_dec" = "0x000c0681"
register "gen2_dec" = "0x000c1641"
Expand Down
1 change: 0 additions & 1 deletion src/mainboard/asrock/b75pro3-m/devicetree.cb
Expand Up @@ -33,7 +33,6 @@ chip northbridge/intel/sandybridge
subsystemid 0x1849 0x0152
end
chip southbridge/intel/bd82x6x
register "c2_latency" = "0x0065"
register "docking_supported" = "0"
register "gen1_dec" = "0x000c0291"
register "gen2_dec" = "0x000c0241"
Expand Down
18 changes: 7 additions & 11 deletions src/mainboard/asus/a88xm-e/mptable.c
Expand Up @@ -29,17 +29,9 @@ static void *smp_write_config_table(void *v)
struct mp_config_table *mc;
int bus_isa;

/*
* By the time this function gets called, the IOAPIC registers
* have been written so they can be read to get the correct
* APIC ID and Version
*/
u8 ioapic_id = (io_apic_read(VIO_APIC_VADDR, 0x00) >> 24);
u8 ioapic_ver = (io_apic_read(VIO_APIC_VADDR, 0x01) & 0xFF);

mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);

mptable_init(mc, LOCAL_APIC_ADDR);
mptable_init(mc);
memcpy(mc->mpc_oem, "AMD ", 8);

smp_write_processors(mc);
Expand All @@ -50,8 +42,12 @@ static void *smp_write_config_table(void *v)
bus_isa = 0x02;
my_smp_write_bus(mc, bus_isa, "ISA ");

/* I/O APICs: APIC ID Version State Address */
smp_write_ioapic(mc, ioapic_id, ioapic_ver, VIO_APIC_VADDR);
/*
* By the time this function gets called, the IOAPIC registers
* have been written so they can be read to get the correct
* APIC ID and Version
*/
u8 ioapic_id = smp_write_ioapic_from_hw(mc, VIO_APIC_VADDR);

/* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
#define IO_LOCAL_INT(type, intr, apicid, pin) \
Expand Down
2 changes: 2 additions & 0 deletions src/mainboard/asus/h61-series/Kconfig
Expand Up @@ -24,13 +24,15 @@ config VARIANT_DIR
default "p8h61-m_lx" if BOARD_ASUS_P8H61_M_LX
default "p8h61-m_lx3_r2_0" if BOARD_ASUS_P8H61_M_LX3_R2_0
default "p8h61-m_pro" if BOARD_ASUS_P8H61_M_PRO
default "p8h61-m_pro_cm6630" if BOARD_ASUS_P8H61_M_PRO_CM6630

config MAINBOARD_PART_NUMBER
string
default "H61M-CS" if BOARD_ASUS_H61M_CS
default "P8H61-M LX" if BOARD_ASUS_P8H61_M_LX
default "P8H61-M LX3 R2.0" if BOARD_ASUS_P8H61_M_LX3_R2_0
default "P8H61-M PRO" if BOARD_ASUS_P8H61_M_PRO
default "P8H61-M PRO CM6630" if BOARD_ASUS_P8H61_M_PRO_CM6630

config OVERRIDE_DEVICETREE
string
Expand Down
12 changes: 12 additions & 0 deletions src/mainboard/asus/h61-series/Kconfig.name
Expand Up @@ -38,3 +38,15 @@ config BOARD_ASUS_P8H61_M_PRO
select REALTEK_8168_RESET
select RT8168_SET_LED_MODE
select SUPERIO_NUVOTON_NCT6776

config BOARD_ASUS_P8H61_M_PRO_CM6630
bool "P8H61-M PRO CM6630"
select BOARD_ASUS_H61_SERIES
select BOARD_ROMSIZE_KB_4096
select DRIVERS_ASMEDIA_ASPM_BLACKLIST
select HAVE_CMOS_DEFAULT
select HAVE_OPTION_TABLE
select MAINBOARD_HAS_LPC_TPM
select REALTEK_8168_RESET
select RT8168_SET_LED_MODE
select SUPERIO_NUVOTON_NCT6776
1 change: 0 additions & 1 deletion src/mainboard/asus/h61-series/devicetree.cb
Expand Up @@ -16,7 +16,6 @@ chip northbridge/intel/sandybridge
device pci 02.0 on end # iGPU

chip southbridge/intel/bd82x6x
register "c2_latency" = "0x0065"
register "sata_port_map" = "0x33"
register "spi_lvscc" = "0x2005"
register "spi_uvscc" = "0x2005"
Expand Down
@@ -0,0 +1,6 @@
Category: desktop
Board URL: https://www.asus.com/Desktop/Entertainment/CM6630
ROM package: DIP-8
ROM protocol: SPI
ROM socketed: y
Flashrom support: y
@@ -0,0 +1,6 @@
boot_option=Fallback
debug_level=Debug
power_on_after_fail=Enable
nmi=Enable
sata_mode=AHCI
gfx_uma_size=32M
@@ -0,0 +1,65 @@
## SPDX-License-Identifier: GPL-2.0-only

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

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

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

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

# coreboot config options: southbridge
408 1 e 1 nmi
409 2 e 7 power_on_after_fail

421 2 e 9 sata_mode

# coreboot config options: northbridge
432 3 e 11 gfx_uma_size

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

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

enumerations

#ID value text
1 0 Disable
1 1 Enable
4 0 Fallback
4 1 Normal
6 0 Emergency
6 1 Alert
6 2 Critical
6 3 Error
6 4 Warning
6 5 Notice
6 6 Info
6 7 Debug
6 8 Spew
7 0 Disable
7 1 Enable
7 2 Keep
9 0 AHCI
9 1 Compatible
9 2 Legacy
11 0 32M
11 1 64M
11 2 96M
11 3 128M
11 4 160M
11 5 192M
11 6 224M

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

checksum 392 439 984
Binary file not shown.
@@ -0,0 +1,57 @@
/* 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, 0x1c, 0x83);
pnp_write_config(GLOBAL_DEV, 0x24, 0x30);
pnp_write_config(GLOBAL_DEV, 0x27, 0x40);
pnp_write_config(GLOBAL_DEV, 0x2a, 0x20);

/* 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], 0x51, id_only);
read_spd(&spd[2], 0x53, id_only);
}
@@ -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 :=
(HDMI3, -- mainboard HDMI port
Analog,
others => Disabled);

end GMA.Mainboard;